Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
intellij-neon autocompletion mapping ideas
<?php
/**
* Inspired by Factory methods (http://confluence.jetbrains.com/display/PhpStorm/PhpStorm+Advanced+Metadata)
* which are now built in PhpStorm.
*
* We use meta-PHP code as a config - so we can use existing API to analyse it.
* The specific format is chosen also to facilitate existing editor features to help as much as possible
* - completion works in places when you enter class references
* - references are resolved and thus clickable
* - usage search and refactoring will work too
*
* But keep in mind it's not evaluated as PHP! We use our own analyser to get out the meaning.
*
* You can help us:
* - have a look at it, provide comments whether you can understand it; or note places which are not clear
* - try to add more metadata for your compiler extensions, so that we can see
* whether it will work for other use cases as well
* - provide any comments, suggestions, ideas...
*
* Thanks!
*/
// e.g. temp/.phpstorm.meta.php
namespace NEON_META { // we want to avoid the pollution
$CONFIG_KEYS = [
'dibi' => [ 'host' => '', 'dbname' => '', 'user' => '', 'password' => '' ], // unobstrusive static definition
'nette' => \Nette\Config\Extensions\NetteExtension::$defaults, // no problem the property is actually not static
'nette' => [
'session' => [
'autoStart' => 'smart', // true|false|smart -- enum autocompletion
],
'database' => [
// indexed by anything
'' => \Nette\Config\Extensions\NetteExtension::$databaseDefaults, // provides some defaults
// add more defaults metadata, which can't be part of the property itself
'' => [
'autowired' => FALSE, // make it automacally available... -- tooltip
'reflection' instanceof \Nette\Database\IReflection,
],
],
'database' => $CONFIG_KEYS['nette']['database'][''], // database identifier is not necessary, squash the tooltips also to this namespace (can reference only $CONFIG_KEYS)
'latte' => [
'macros' => [ // this looks like it requires a hashmap, is it ok? Probably yep, because the typehint is for values
'' instanceof \Nette\Latte\IMacro, // like above, indexed by anything, or not indexed at all
],
],
],
'services' => [
'' => [ // any key
'class' => '', // TODO: how shall we say it needs to be a valid class name?
'autowired' => FALSE,
'factory' => '', // TODO: how shall we say it needs to be a valid callable?
]
]
];
// can be defined in several places, e.g. each extension can have it's own definition
$CONFIG_KEYS = [
// there are several drivers that can be configured to several parameters; these will be referenced later, wait for it
'Kdyby\Doctrine\DI\OrmExtension::cacheDriver' => 'default', // apc|array|memcache|redis|xcache
'Kdyby\Doctrine\DI\OrmExtension::cacheDriver' => new Nette\NeonEntity('apc', []),
'Kdyby\Doctrine\DI\OrmExtension::cacheDriver' => new Nette\NeonEntity('memcache', []),
'Kdyby\Doctrine\DI\OrmExtension::cacheDriver' => new Nette\NeonEntity('redis', []),
'Kdyby\Doctrine\DI\OrmExtension::cacheDriver' => new Nette\NeonEntity('xcache', []),
// the defaults for manager and connection are intersected, i.e. merge all these into one section in neon
'Kdyby\Doctrine\DI\OrmExtension' => \Kdyby\Doctrine\DI\OrmExtension::$managerDefaults,
'Kdyby\Doctrine\DI\OrmExtension' => \Kdyby\Doctrine\DI\OrmExtension::$connectionDefaults,
'Kdyby\Doctrine\DI\OrmExtension' => [
// every doctrine section can have metadata
'metadata' => [ // the metadata is indexed by namespace --- tooltip
// it can be a directory with annotation mappings
// Kdyby: %appDir%
'' => /** @Path(type=dir) */ '', // -- value is any string, autocompetion provides directories
// array of directories with annotation mappings
// Kdyby: [%appDir%, ...]
'' => [/** @Path(type=dir) */ '', ],
// neon entity where its name is driver name and args are directories
// Kdyby: yml(%appDir%, ...)
'' => new Nette\NeonEntity('static|yml|xml|db', [/** @Path(type=dir) */ '', ]),
],
// the cache configuration is same for several keys, therefore it references the value defined before
// -- perhaps a normal variable would be more readable here, than referencing part of $CONFIG_KEYS ?? What do you think?
'metadataCache' => $CONFIG_KEYS['Kdyby\Doctrine\DI\OrmExtension::cacheDriver'],
'queryCache' => $CONFIG_KEYS['Kdyby\Doctrine\DI\OrmExtension::cacheDriver'],
'resultCache' => $CONFIG_KEYS['Kdyby\Doctrine\DI\OrmExtension::cacheDriver'],
'hydrationCache' => $CONFIG_KEYS['Kdyby\Doctrine\DI\OrmExtension::cacheDriver'],
'resultCache' => $CONFIG_KEYS['Kdyby\Doctrine\DI\OrmExtension::cacheDriver'],
// this section extends the DQL language in several sections
'dql' => [
// functions are in pairs [name => astFunction\className] in each section
'string' => ['' => '' instanceof Doctrine\ORM\Query\AST\Functions\FunctionNode, ],
'numeric' => ['' => '' instanceof Doctrine\ORM\Query\AST\Functions\FunctionNode, ],
'datetime' => ['' => '' instanceof Doctrine\ORM\Query\AST\Functions\FunctionNode, ],
],
// hydrators are in pairs [name => ormhydrator\className]
'hydrators' => ['' => '' instanceof Doctrine\ORM\Internal\Hydration\AbstractHydrator, ],
// hydrators are in pairs [name => queryFilter\className]
'filters' => ['' => '' instanceof Doctrine\ORM\Query\Filter\SQLFilter, ],
// hydrators are in pairs [namespace => aliasName]
'namespaceAlias' => ['' => ''],
// hydrators are in pairs [name => dbalType\className]
'types' => ['' => '' instanceof Doctrine\DBAL\Types\Type]
],
'doctrine' => [
// everything can be named, so there can be several database connections, entitymanagers, etc.
'' => $CONFIG_KEYS['Kdyby\Doctrine\DI\OrmExtension']
],
// if the configuration is not named, it's in default section automatically
'doctrine' => $CONFIG_KEYS['Kdyby\Doctrine\DI\OrmExtension'] ]
];
// or if the extension name is optional / can differ
$CONFIG_KEYS = [
'Kdyby\Doctrine\DI\OrmExtension' => [ // this key will actually never be used
// the definition would be here
],
'orm' => $CONFIG_KEYS['Kdyby\Doctrine\DI\OrmExtension'],
'blah' => $CONFIG_KEYS['Kdyby\Doctrine\DI\OrmExtension'],
];
// more ideas
$CONFIG_KEYS = [
'console' => [
// this is for validation
/**
* @Format url
*/
'url' => '', // URL for router, when your app runs from CLI --- this is comment / hint / tooltip
],
'nette' => [
'database' => [
'' => [
// a template can be provided, similar to live templates
/**
* @Template mysql:host=$HOST$;dbname=$DBNAME$
*/
'dsn' => '',
]
]
],
'my_custom' => [
'menu' => [ // map of title-to-display-in-admin => unified-id
// this will eval php code in context of the application; the method outputs array; the values will be autocompleted
/**
* @ValueProvider Pd\Helpers\UIdHelper::getAvailableUIds('Page')
*/
'' => '', // any key, value is any string
],
'paginator' => [
/**
* @Pattern \d+
*/
'' => 0,
],
'imageResizer' => [
// image type -> params
'' => [
// the value must be in given range
/**
* @Range 128-1024
*/
'width' => 0,
'height' => 0,
// will autocomplete any paths from a directory
/**
* @Path baseDir="www/images/", pattern="*.jpg"
*/
'watermark' => '',
// will autocomplete directories
/**
* @Dir baseDir="www/images/temp"
*/
'baseDir' => '', // where loads the images from, when relative path is used
]
]
],
'services' => [
'' => [
'setup' => [
/**
* @MethodProvider of ../class -- nooo, too magic. Implement it in Java in intellij-nette
*/
'', // no key given, because it's not a hashmap
]
]
]
];
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment