diff --git a/Completer.php b/Completer.php new file mode 100644 index 0000000..f0808ac --- /dev/null +++ b/Completer.php @@ -0,0 +1,46 @@ +classNameCompleter = $completer; + } + public function getEntries(Project $project, Context $context) + { + list($type, $isThis, $types) = $context->getData(); + if (is_array($types)) { + $fqcn = array_pop($types); + if ($fqcn instanceof FQCN + && $fqcn->toString() === 'DI\\Container' + ) { + return array_map( + [$this, 'wrapEntry'], + $this->classNameCompleter->getEntries($project, $context) + ); + } + } + return []; + } + + public function wrapEntry($entry) + { + return new Entry( + sprintf('"%s"', $entry->getName()), + $entry->getSignature(), + $entry->getDesc(), + $entry->getMenu() + ); + } + + private $classNameCompleter; +} diff --git a/Plugin.php b/Plugin.php index 620effd..21344cf 100644 --- a/Plugin.php +++ b/Plugin.php @@ -4,60 +4,49 @@ use Symfony\Component\EventDispatcher\EventDispatcher; use Complete\Resolver\NodeTypeResolver; -use Complete\Resolver\TypeResolveEvent; -use Entity\FQCN; -use PhpParser\Node\Arg; -use PhpParser\Node\Scalar\String_; +use Complete\Completer\CompleterFactory; use Parser\UseParser; class Plugin { public function __construct( EventDispatcher $dispatcher, - UseParser $useParser + TypeResolver $resolver, + Completer $completer ) { $this->dispatcher = $dispatcher; - $this->useParser = $useParser; + $this->resolver = $resolver; + $this->completer = $completer; } - public function load() + public function init() { - if ($this->isLoaded) { - return; - } - $this->isLoaded = true; - $plugin = $this; $this->dispatcher->addListener( NodeTypeResolver::BLOCK_START, - function (TypeResolveEvent $e) use ($plugin) { - $plugin->parentType = $e->getType(); - } + [$this->resolver, 'handleParentTypeEvent'] ); $this->dispatcher->addListener( NodeTypeResolver::BLOCK_END, - function (TypeResolveEvent $e) use ($plugin) { - $parentType = $plugin->parentType; - if ($parentType instanceof FQCN - && $parentType->toString() === 'DI\\Container' - ) { - /** @var \Entity\Chain\MethodCall */ - $chain = $e->getChain(); - if ($chain->getType() === 'method' && count($chain->getArgs()) > 0) { - $firstArg = array_pop($chain->getArgs())->value; - if ($firstArg instanceof String_) { - $className = $firstArg->value; - $fqcn = $plugin->useParser->parseFQCN($className); - $e->setType($fqcn); - } - } - } - } + [$this->resolver, 'handleTypeResolveEvent'] + ); + $this->dispatcher->addListener( + CompleterFactory::CUSTOM_COMPLETER, + [$this, 'handleCompleteEvent'] ); } - private $parentType; + public function handleCompleteEvent($e) + { + $context = $e->context; + if ($context->isMethodCall()) { + $e->completer = $this->completer; + } + } + + /** @var Completer */ + private $completer; + /** @var TypeResolver */ + private $resolver; /** @var EventDispatcher */ private $dispatcher; - private $useParser; - private $isLoaded = false; } diff --git a/TypeResolver.php b/TypeResolver.php new file mode 100644 index 0000000..cd27b01 --- /dev/null +++ b/TypeResolver.php @@ -0,0 +1,46 @@ +useParser = $useParser; + } + + public function handleParentTypeEvent(TypeResolveEvent $e) + { + $this->parentType = $e->getType(); + } + + public function handleTypeResolveEvent(TypeResolveEvent $e) + { + $parentType = $this->parentType; + if ($parentType instanceof FQCN + && $parentType->toString() === 'DI\\Container' + ) { + /** @var \Entity\Chain\MethodCall */ + $chain = $e->getChain(); + if ($chain->getType() === 'method' && count($chain->getArgs()) > 0) { + $firstArg = array_pop($chain->getArgs())->value; + if ($firstArg instanceof String_) { + $className = $firstArg->value; + $fqcn = $this->useParser->parseFQCN($className); + $e->setType($fqcn); + } + } + } + } + + /** @var UseParser */ + private $useParser; + private $parentType; +}