diff --git a/.travis.yml b/.travis.yml index 9b247b3..cb4bcbf 100644 --- a/.travis.yml +++ b/.travis.yml @@ -9,10 +9,6 @@ git: depth: 10 submodules: false -env: - global: - - BUILD_LEADER_ID=4 - cache: directories: - $HOME/Library/Caches/Homebrew @@ -38,21 +34,20 @@ jobs: - brew tap homebrew/homebrew-php - brew install php71 - brew install homebrew/php/php71-xdebug - - curl https://getcomposer.org/installer | php + - php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');" + - php composer-setup.php - ln -s "`pwd`/composer.phar" /usr/local/bin/composer - stage: release php: '7.0' services: - docker install: - - git config --replace-all remote.origin.fetch +refs/heads/*:refs/remotes/origin/* - - git fetch --tags - composer install --prefer-dist --no-interaction - nvm install 8 - nvm use 8 - npm install - script: skip - after_success: + script: + - docker build -t felixfbecker/php-language-server . - npm run semantic-release stages: @@ -61,5 +56,5 @@ stages: if: branch = master AND type = push AND fork = false branches: - except: - - /^v\d+\.\d+\.\d+$/ + only: + - master diff --git a/README.md b/README.md index b25680e..5d95d61 100644 --- a/README.md +++ b/README.md @@ -19,6 +19,12 @@ and an [event loop](http://sabre.io/event/loop/) for concurrency. ## Features +### [Completion](https://github.com/Microsoft/language-server-protocol/blob/master/protocol.md#textDocument_completion) +![Completion search demo](images/completion.gif) + +### [Signature Help](https://github.com/Microsoft/language-server-protocol/blob/master/protocol.md#textDocument_signatureHelp) +![Signature help demo](images/signatureHelp.gif) + ### [Go To Definition](https://github.com/Microsoft/language-server-protocol/blob/master/protocol.md#goto-definition-request) ![Go To Definition demo](images/definition.gif) @@ -180,6 +186,7 @@ Example: - [Eclipse Che](https://eclipse.org/che/) - [Eclipse IDE (LSP4E-PHP)](https://github.com/eclipselabs/lsp4e-php) - NeoVim: [LanguageServer-php-neovim](https://github.com/roxma/LanguageServer-php-neovim) with [LanguageClient neovim](https://github.com/autozimu/LanguageClient-neovim) + - Atom: [ide-php](https://github.com/atom/ide-php) ## Contributing diff --git a/appveyor.yml b/appveyor.yml index fa6d26a..7d0525c 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,5 +1,6 @@ version: '{build}' +image: Visual Studio 2017 platform: - x64 diff --git a/benchmarks/parsing.php b/benchmarks/parsing.php index 8eaae6a..e68bc1b 100644 --- a/benchmarks/parsing.php +++ b/benchmarks/parsing.php @@ -14,7 +14,7 @@ use RecursiveIteratorIterator; $totalSize = 0; -$frameworks = ["drupal", "wordpress", "php-language-server", "tolerant-php-parser", "math-php", "symfony", "CodeIgniter", "cakephp"]; +$frameworks = ["drupal", "wordpress", "php-language-server", "tolerant-php-parser", "math-php", "symfony", "codeigniter", "cakephp"]; foreach($frameworks as $framework) { $iterator = new RecursiveDirectoryIterator(__DIR__ . "/../validation/frameworks/$framework"); diff --git a/dependencies.yml b/dependencies.yml index 320ae87..bf6bd77 100644 --- a/dependencies.yml +++ b/dependencies.yml @@ -1,10 +1,20 @@ collectors: +# pull requests for new major versions - type: php-composer path: / actors: - # pull requests for new major versions - type: php-composer versions: "Y.0.0" settings: commit_message_prefix: "chore: " +- type: js-npm + path: / + settings: + dist_tags: + semantic-release: next + actors: + - type: js-npm + versions: "Y.0.0" + settings: + commit_message_prefix: "chore: " diff --git a/fixtures/completion/foreach.php b/fixtures/completion/foreach.php new file mode 100644 index 0000000..84bafd1 --- /dev/null +++ b/fixtures/completion/foreach.php @@ -0,0 +1,46 @@ +test(); +$array1 = [new Bar(), new \stdClass()]; +$array2 = ['foo' => $bar, $bar]; +$array3 = ['foo' => $bar, 'baz' => $bar]; + +foreach ($bars as $value) { + $v + $value-> +} + +foreach ($array1 as $key => $value) { + $ +} + +foreach ($array2 as $key => $value) { + $ +} + +foreach ($array3 as $key => $value) { + $ +} + +foreach ($bar->test() as $value) { + $ +} + +foreach ($unknownArray as $member->access => $unknown) { + $unkno + +foreach ($loop as $loop) { +} + +foreach ($loop->getArray() as $loop) { +} diff --git a/fixtures/diagnostics/errors/this_in_function.php b/fixtures/diagnostics/errors/this_in_function.php deleted file mode 100644 index db6139d..0000000 --- a/fixtures/diagnostics/errors/this_in_function.php +++ /dev/null @@ -1,6 +0,0 @@ -foo(); +$t->foo(1, +$t->foo(1,); +$t->baz(); + +foo( + 1, + foo(1, 2, +); + +Test::bar(); + +new $foo(); +new $foo(1, ); + +new NotExist(); diff --git a/images/completion.gif b/images/completion.gif new file mode 100644 index 0000000..b43d2f9 Binary files /dev/null and b/images/completion.gif differ diff --git a/images/signatureHelp.gif b/images/signatureHelp.gif new file mode 100644 index 0000000..9f921ff Binary files /dev/null and b/images/signatureHelp.gif differ diff --git a/package.json b/package.json index 75f02e1..828931f 100644 --- a/package.json +++ b/package.json @@ -4,13 +4,15 @@ "private": true, "scripts": { "commitmsg": "validate-commit-msg", - "semantic-release": "semantic-release pre && php release-docker.php && semantic-release post" + "semantic-release": "semantic-release" }, "devDependencies": { + "@semantic-release/github": "^2.0.0", + "@semantic-release/last-release-git-tag": "^2.0.0", "cz-conventional-changelog": "^2.0.0", "husky": "^0.14.3", - "last-release-git": "0.0.3", - "semantic-release": "^8.2.0", + "semantic-release": "^11.0.0", + "semantic-release-docker": "^2.0.0", "validate-commit-msg": "^2.14.0" }, "config": { @@ -19,7 +21,18 @@ } }, "release": { - "getLastRelease": "last-release-git" + "verifyConditions": [ + "@semantic-release/github", + "semantic-release-docker" + ], + "getLastRelease": "@semantic-release/last-release-git-tag", + "publish": [ + "@semantic-release/github", + { + "path": "semantic-release-docker", + "name": "felixfbecker/php-language-server" + } + ] }, "repository": { "type": "git", diff --git a/release-docker.php b/release-docker.php deleted file mode 100755 index f833d60..0000000 --- a/release-docker.php +++ /dev/null @@ -1,12 +0,0 @@ -version; - -system("docker login -e=$dockerEmail -u=$dockerUsername -p=$dockerPassword"); -system("docker build -t felixfbecker/php-language-server:latest ."); -system("docker tag felixfbecker/php-language-server:latest felixfbecker/php-language-server:$version ."); -system("docker push felixfbecker/php-language-server:$version"); -system("docker push felixfbecker/php-language-server:latest"); diff --git a/src/CompletionProvider.php b/src/CompletionProvider.php index 18f00ef..fe00c71 100644 --- a/src/CompletionProvider.php +++ b/src/CompletionProvider.php @@ -482,6 +482,14 @@ class CompletionProvider if ($this->isAssignmentToVariableWithPrefix($node, $namePrefix)) { $vars[] = $node->leftOperand; + } elseif ($node instanceof Node\ForeachKey || $node instanceof Node\ForeachValue) { + foreach ($node->getDescendantNodes() as $descendantNode) { + if ($descendantNode instanceof Node\Expression\Variable + && ($namePrefix === '' || strpos($descendantNode->getName(), $namePrefix) !== false) + ) { + $vars[] = $descendantNode; + } + } } else { // Get all descendent variables, then filter to ones that start with $namePrefix. // Avoiding closure usage in tight loop diff --git a/src/Definition.php b/src/Definition.php index c27f871..0d157cb 100644 --- a/src/Definition.php +++ b/src/Definition.php @@ -99,6 +99,13 @@ class Definition */ public $documentation; + /** + * Signature information if this definition is for a FunctionLike, for use in textDocument/signatureHelp + * + * @var SignatureInformation + */ + public $signatureInformation; + /** * Yields the definitons of all ancestor classes (the Definition fqn is yielded as key) * diff --git a/src/DefinitionResolver.php b/src/DefinitionResolver.php index c9d1400..990c196 100644 --- a/src/DefinitionResolver.php +++ b/src/DefinitionResolver.php @@ -7,6 +7,7 @@ use LanguageServer\Index\ReadableIndex; use LanguageServer\Protocol\SymbolInformation; use Microsoft\PhpParser; use Microsoft\PhpParser\Node; +use Microsoft\PhpParser\FunctionLike; use phpDocumentor\Reflection\{ DocBlock, DocBlockFactory, Fqsen, Type, TypeResolver, Types }; @@ -34,6 +35,13 @@ class DefinitionResolver */ private $docBlockFactory; + /** + * Creates SignatureInformation + * + * @var SignatureInformationFactory + */ + private $signatureInformationFactory; + /** * @param ReadableIndex $index */ @@ -42,6 +50,7 @@ class DefinitionResolver $this->index = $index; $this->typeResolver = new TypeResolver; $this->docBlockFactory = DocBlockFactory::createInstance(); + $this->signatureInformationFactory = new SignatureInformationFactory($this); } /** @@ -232,6 +241,10 @@ class DefinitionResolver $def->documentation = $this->getDocumentationFromNode($node); } + if ($node instanceof FunctionLike) { + $def->signatureInformation = $this->signatureInformationFactory->create($node); + } + return $def; } @@ -513,6 +526,20 @@ class DefinitionResolver return (string)$classNode->getNamespacedName(); } + /** + * Returns the type of the class a node is contained in + * Returns null if the class is anonymous or the node is not contained in a class + * + * @param Node $node The node used to find the containing class + * + * @return Types\Object_|null + */ + private function getContainingClassType(Node $node) + { + $classFqn = $this->getContainingClassFqn($node); + return $classFqn ? new Types\Object_(new Fqsen('\\' . $classFqn)) : null; + } + /** * Returns the assignment or parameter node where a variable was defined * @@ -532,6 +559,15 @@ class DefinitionResolver } else { throw new \InvalidArgumentException('$var must be Variable, Param or ClosureUse, not ' . get_class($var)); } + if (empty($name)) { + return null; + } + + $shouldDescend = function ($nodeToDescand) { + // Make sure not to decend into functions or classes (they represent a scope boundary) + return !($nodeToDescand instanceof PhpParser\FunctionLike || $nodeToDescand instanceof PhpParser\ClassLike); + }; + // Traverse the AST up do { // If a function is met, check the parameters and use statements @@ -555,24 +591,56 @@ class DefinitionResolver } break; } - // Check each previous sibling node for a variable assignment to that variable + + // Check each previous sibling node and their descendents for a variable assignment to that variable + // Each previous sibling could contain a declaration of the variable while (($prevSibling = $n->getPreviousSibling()) !== null && $n = $prevSibling) { - if ($n instanceof Node\Statement\ExpressionStatement) { - $n = $n->expression; - } - if ( - // TODO - clean this up - ($n instanceof Node\Expression\AssignmentExpression && $n->operator->kind === PhpParser\TokenKind::EqualsToken) - && $n->leftOperand instanceof Node\Expression\Variable && $n->leftOperand->getName() === $name - ) { + + // Check the sibling itself + if (self::isVariableDeclaration($n, $name)) { return $n; } + + // Check descendant of this sibling (e.g. the children of a previous if block) + foreach ($n->getDescendantNodes($shouldDescend) as $descendant) { + if (self::isVariableDeclaration($descendant, $name)) { + return $descendant; + } + } } } while (isset($n) && $n = $n->parent); // Return null if nothing was found return null; } + /** + * Checks whether the given Node declares the given variable name + * + * @param Node $n The Node to check + * @param string $name The name of the wanted variable + * @return bool + */ + private static function isVariableDeclaration(Node $n, string $name) + { + if ( + // TODO - clean this up + ($n instanceof Node\Expression\AssignmentExpression && $n->operator->kind === PhpParser\TokenKind::EqualsToken) + && $n->leftOperand instanceof Node\Expression\Variable && $n->leftOperand->getName() === $name + ) { + return true; + } + + if ( + ($n instanceof Node\ForeachValue || $n instanceof Node\ForeachKey) + && $n->expression instanceof Node\Expression\Variable + && $n->expression->getName() === $name + ) { + return true; + } + + return false; + } + /** * Given an expression node, resolves that expression recursively to a type. * If the type could not be resolved, returns Types\Mixed_. @@ -606,6 +674,9 @@ class DefinitionResolver if ($defNode instanceof Node\Expression\AssignmentExpression || $defNode instanceof Node\UseVariableName) { return $this->resolveExpressionNodeToType($defNode); } + if ($defNode instanceof Node\ForeachKey || $defNode instanceof Node\ForeachValue) { + return $this->getTypeFromNode($defNode); + } if ($defNode instanceof Node\Parameter) { return $this->getTypeFromNode($defNode); } @@ -699,7 +770,7 @@ class DefinitionResolver foreach ($classDef->getAncestorDefinitions($this->index, true) as $fqn => $def) { $def = $this->index->getDefinition($fqn . $add); if ($def !== null) { - if ($def->type instanceof Types\This) { + if ($def->type instanceof Types\This || $def->type instanceof Types\Self_) { return new Types\Object_(new Fqsen('\\' . $classFqn)); } return $def->type; @@ -887,7 +958,7 @@ class DefinitionResolver $keyTypes[] = $item->elementKey ? $this->resolveExpressionNodeToType($item->elementKey) : new Types\Integer; } } - $valueTypes = array_unique($keyTypes); + $valueTypes = array_unique($valueTypes); $keyTypes = array_unique($keyTypes); if (empty($valueTypes)) { $valueType = null; @@ -1053,13 +1124,25 @@ class DefinitionResolver && $returnTags[0]->getType() !== null ) { // Use @return tag - return $returnTags[0]->getType(); + $returnType = $returnTags[0]->getType(); + if ($returnType instanceof Types\Self_) { + $selfType = $this->getContainingClassType($node); + if ($selfType) { + return $selfType; + } + } + return $returnType; } if ($node->returnType !== null && !($node->returnType instanceof PhpParser\MissingToken)) { // Use PHP7 return type hint if ($node->returnType instanceof PhpParser\Token) { // Resolve a string like "bool" to a type object return $this->typeResolver->resolve($node->returnType->getText($node->getFileContents())); + } elseif ($node->returnType->getResolvedName() === 'self') { + $selfType = $this->getContainingClassType($node); + if ($selfType !== null) { + return $selfType; + } } return new Types\Object_(new Fqsen('\\' . (string)$node->returnType->getResolvedName())); } @@ -1067,6 +1150,28 @@ class DefinitionResolver return new Types\Mixed_; } + // FOREACH KEY/VARIABLE + if ($node instanceof Node\ForeachKey || $node->parent instanceof Node\ForeachKey) { + $foreach = $node->getFirstAncestor(Node\Statement\ForeachStatement::class); + $collectionType = $this->resolveExpressionNodeToType($foreach->forEachCollectionName); + if ($collectionType instanceof Types\Array_) { + return $collectionType->getKeyType(); + } + return new Types\Mixed_(); + } + + // FOREACH VALUE/VARIABLE + if ($node instanceof Node\ForeachValue + || ($node instanceof Node\Expression\Variable && $node->parent instanceof Node\ForeachValue) + ) { + $foreach = $node->getFirstAncestor(Node\Statement\ForeachStatement::class); + $collectionType = $this->resolveExpressionNodeToType($foreach->forEachCollectionName); + if ($collectionType instanceof Types\Array_) { + return $collectionType->getValueType(); + } + return new Types\Mixed_(); + } + // PROPERTIES, CONSTS, CLASS CONSTS, ASSIGNMENT EXPRESSIONS // Get the documented type the assignment resolves to. if ( diff --git a/src/LanguageServer.php b/src/LanguageServer.php index 73560f4..46281f5 100644 --- a/src/LanguageServer.php +++ b/src/LanguageServer.php @@ -9,7 +9,8 @@ use LanguageServer\Protocol\{ TextDocumentSyncKind, Message, InitializeResult, - CompletionOptions + CompletionOptions, + SignatureHelpOptions }; use LanguageServer\FilesFinder\{FilesFinder, ClientFilesFinder, FileSystemFilesFinder}; use LanguageServer\ContentRetriever\{ContentRetriever, ClientContentRetriever, FileSystemContentRetriever}; @@ -275,6 +276,10 @@ class LanguageServer extends AdvancedJsonRpc\Dispatcher $serverCapabilities->completionProvider = new CompletionOptions; $serverCapabilities->completionProvider->resolveProvider = false; $serverCapabilities->completionProvider->triggerCharacters = ['$', '>']; + + $serverCapabilities->signatureHelpProvider = new SignatureHelpOptions(); + $serverCapabilities->signatureHelpProvider->triggerCharacters = ['(', ',']; + // Support global references $serverCapabilities->xworkspaceReferencesProvider = true; $serverCapabilities->xdefinitionProvider = true; diff --git a/src/Protocol/CompletionContext.php b/src/Protocol/CompletionContext.php index ff18bd1..f538867 100644 --- a/src/Protocol/CompletionContext.php +++ b/src/Protocol/CompletionContext.php @@ -22,7 +22,7 @@ class CompletionContext */ public $triggerCharacter; - public function __construct(int $triggerKind, string $triggerCharacter = null) + public function __construct(int $triggerKind = null, string $triggerCharacter = null) { $this->triggerKind = $triggerKind; $this->triggerCharacter = $triggerCharacter; diff --git a/src/Protocol/ParameterInformation.php b/src/Protocol/ParameterInformation.php index 89b5e53..fa9b7bf 100644 --- a/src/Protocol/ParameterInformation.php +++ b/src/Protocol/ParameterInformation.php @@ -23,4 +23,17 @@ class ParameterInformation * @var string|null */ public $documentation; + + /** + * Create ParameterInformation + * + * @param string $label The label of this signature. Will be shown in the UI. + * @param string $documentation The human-readable doc-comment of this signature. Will be shown in the UI but can + * be omitted. + */ + public function __construct(string $label, string $documentation = null) + { + $this->label = $label; + $this->documentation = $documentation; + } } diff --git a/src/Protocol/SignatureHelp.php b/src/Protocol/SignatureHelp.php index 407b25a..f7aec6f 100644 --- a/src/Protocol/SignatureHelp.php +++ b/src/Protocol/SignatureHelp.php @@ -29,4 +29,18 @@ class SignatureHelp * @var int|null */ public $activeParameter; + + /** + * Create a SignatureHelp + * + * @param SignatureInformation[] $signatures List of signature information + * @param int|null $activeSignature The active signature, zero based + * @param int|null $activeParameter The active parameter, zero based + */ + public function __construct(array $signatures = [], $activeSignature = null, int $activeParameter = null) + { + $this->signatures = $signatures; + $this->activeSignature = $activeSignature; + $this->activeParameter = $activeParameter; + } } diff --git a/src/Protocol/SignatureInformation.php b/src/Protocol/SignatureInformation.php index 77e152c..d545f65 100644 --- a/src/Protocol/SignatureInformation.php +++ b/src/Protocol/SignatureInformation.php @@ -31,4 +31,19 @@ class SignatureInformation * @var ParameterInformation[]|null */ public $parameters; + + /** + * Create a SignatureInformation + * + * @param string $label The label of this signature. Will be shown in the UI. + * @param ParameterInformation[]|null The parameters of this signature + * @param string|null The human-readable doc-comment of this signature. Will be shown in the UI + * but can be omitted. + */ + public function __construct(string $label, array $parameters = null, string $documentation = null) + { + $this->label = $label; + $this->parameters = $parameters; + $this->documentation = $documentation; + } } diff --git a/src/Server/TextDocument.php b/src/Server/TextDocument.php index 0ad2d81..362dc34 100644 --- a/src/Server/TextDocument.php +++ b/src/Server/TextDocument.php @@ -4,7 +4,7 @@ declare(strict_types = 1); namespace LanguageServer\Server; use LanguageServer\{ - CompletionProvider, LanguageClient, PhpDocument, PhpDocumentLoader, DefinitionResolver + CompletionProvider, SignatureHelpProvider, LanguageClient, PhpDocument, PhpDocumentLoader, DefinitionResolver }; use LanguageServer\Index\ReadableIndex; use LanguageServer\Protocol\{ @@ -59,6 +59,11 @@ class TextDocument */ protected $completionProvider; + /** + * @var SignatureHelpProvider + */ + protected $signatureHelpProvider; + /** * @var ReadableIndex */ @@ -94,6 +99,7 @@ class TextDocument $this->client = $client; $this->definitionResolver = $definitionResolver; $this->completionProvider = new CompletionProvider($this->definitionResolver, $index); + $this->signatureHelpProvider = new SignatureHelpProvider($this->definitionResolver, $index, $documentLoader); $this->index = $index; $this->composerJson = $composerJson; $this->composerLock = $composerLock; @@ -238,6 +244,23 @@ class TextDocument }); } + /** + * The signature help request is sent from the client to the server to request signature information at a given + * cursor position. + * + * @param TextDocumentIdentifier $textDocument The text document + * @param Position $position The position inside the text document + * + * @return Promise + */ + public function signatureHelp(TextDocumentIdentifier $textDocument, Position $position): Promise + { + return coroutine(function () use ($textDocument, $position) { + $document = yield $this->documentLoader->getOrLoad($textDocument->uri); + return $this->signatureHelpProvider->getSignatureHelp($document, $position); + }); + } + /** * The goto definition request is sent from the client to the server to resolve the definition location of a symbol * at a given text document position. @@ -315,6 +338,7 @@ class TextDocument if ($def === null) { return new Hover([], $range); } + $contents = []; if ($def->declarationLine) { $contents[] = new MarkedString('php', "declarationLine); } diff --git a/src/SignatureHelpProvider.php b/src/SignatureHelpProvider.php new file mode 100644 index 0000000..aba02b4 --- /dev/null +++ b/src/SignatureHelpProvider.php @@ -0,0 +1,189 @@ +definitionResolver = $definitionResolver; + $this->index = $index; + $this->documentLoader = $documentLoader; + } + + /** + * Finds signature help for a callable position + * + * @param PhpDocument $doc The document the position belongs to + * @param Position $position The position to detect a call from + * + * @return Promise + */ + public function getSignatureHelp(PhpDocument $doc, Position $position): Promise + { + return coroutine(function () use ($doc, $position) { + // Find the node under the cursor + $node = $doc->getNodeAtPosition($position); + + // Find the definition of the item being called + list($def, $argumentExpressionList) = yield $this->getCallingInfo($node); + + if (!$def || !$def->signatureInformation) { + return new SignatureHelp(); + } + + // Find the active parameter + $activeParam = $argumentExpressionList + ? $this->findActiveParameter($argumentExpressionList, $position, $doc) + : 0; + + return new SignatureHelp([$def->signatureInformation], 0, $activeParam); + }); + } + + /** + * Given a node that could be a callable, finds the definition of the call and the argument expression list of + * the node + * + * @param Node $node The node to find calling information from + * + * @return Promise + */ + private function getCallingInfo(Node $node) + { + return coroutine(function () use ($node) { + $fqn = null; + $callingNode = null; + if ($node instanceof Node\DelimitedList\ArgumentExpressionList) { + // Cursor is already inside a ( + $argumentExpressionList = $node; + if ($node->parent instanceof Node\Expression\ObjectCreationExpression) { + // Constructing something + $callingNode = $node->parent->classTypeDesignator; + if (!$callingNode instanceof Node\QualifiedName) { + // We only support constructing from a QualifiedName + return null; + } + $fqn = $this->definitionResolver->resolveReferenceNodeToFqn($callingNode); + $fqn = "{$fqn}->__construct()"; + } else { + $callingNode = $node->parent->getFirstChildNode( + Node\Expression\MemberAccessExpression::class, + Node\Expression\ScopedPropertyAccessExpression::class, + Node\QualifiedName::class + ); + } + } elseif ($node instanceof Node\Expression\CallExpression) { + $argumentExpressionList = $node->getFirstChildNode(Node\DelimitedList\ArgumentExpressionList::class); + $callingNode = $node->getFirstChildNode( + Node\Expression\MemberAccessExpression::class, + Node\Expression\ScopedPropertyAccessExpression::class, + Node\QualifiedName::class + ); + } elseif ($node instanceof Node\Expression\ObjectCreationExpression) { + $argumentExpressionList = $node->getFirstChildNode(Node\DelimitedList\ArgumentExpressionList::class); + $callingNode = $node->classTypeDesignator; + if (!$callingNode instanceof Node\QualifiedName) { + // We only support constructing from a QualifiedName + return null; + } + // Manually build the __construct fqn + $fqn = $this->definitionResolver->resolveReferenceNodeToFqn($callingNode); + $fqn = "{$fqn}->__construct()"; + } + + if (!$callingNode) { + return null; + } + + // Now find the definition of the call + $fqn = $fqn ?: DefinitionResolver::getDefinedFqn($callingNode); + while (true) { + if ($fqn) { + $def = $this->index->getDefinition($fqn); + } else { + $def = $this->definitionResolver->resolveReferenceNodeToDefinition($callingNode); + } + if ($def !== null || $this->index->isComplete()) { + break; + } + yield waitForEvent($this->index, 'definition-added'); + } + + if (!$def) { + return null; + } + + return [$def, $argumentExpressionList]; + }); + } + + /** + * Given a position and arguments, finds the "active" argument at the position + * + * @param Node\DelimitedList\ArgumentExpressionList $argumentExpressionList The argument expression list + * @param Position $position The position to detect the active argument from + * @param PhpDocument $doc The document that contains the expression + * + * @return int + */ + private function findActiveParameter( + Node\DelimitedList\ArgumentExpressionList $argumentExpressionList, + Position $position, + PhpDocument $doc + ): int { + $args = $argumentExpressionList->children; + $i = 0; + $found = null; + foreach ($args as $arg) { + if ($arg instanceof Node) { + $start = $arg->getFullStart(); + $end = $arg->getEndPosition(); + } else { + $start = $arg->fullStart; + $end = $start + $arg->length; + } + $offset = $position->toOffset($doc->getContent()); + if ($offset >= $start && $offset <= $end) { + $found = $i; + break; + } + if ($arg instanceof Node) { + ++$i; + } + } + if ($found === null) { + $found = $i; + } + return $found; + } +} diff --git a/src/SignatureInformationFactory.php b/src/SignatureInformationFactory.php new file mode 100644 index 0000000..6b8a1f0 --- /dev/null +++ b/src/SignatureInformationFactory.php @@ -0,0 +1,91 @@ +definitionResolver = $definitionResolver; + } + + /** + * Create a SignatureInformation from a FunctionLike node + * + * @param FunctionLike $node Node to create signature information from + * + * @return SignatureInformation + */ + public function create(FunctionLike $node): SignatureInformation + { + $params = $this->createParameters($node); + $label = $this->createLabel($params); + return new SignatureInformation( + $label, + $params, + $this->definitionResolver->getDocumentationFromNode($node) + ); + } + + /** + * Gets parameters from a FunctionLike node + * + * @param FunctionLike $node Node to get parameters from + * + * @return ParameterInformation[] + */ + private function createParameters(FunctionLike $node): array + { + $params = []; + if ($node->parameters) { + foreach ($node->parameters->getElements() as $element) { + $param = (string) $this->definitionResolver->getTypeFromNode($element); + $param .= ' '; + if ($element->dotDotDotToken) { + $param .= '...'; + } + $param .= '$' . $element->getName(); + if ($element->default) { + $param .= ' = ' . $element->default->getText(); + } + $params[] = new ParameterInformation( + $param, + $this->definitionResolver->getDocumentationFromNode($element) + ); + } + } + return $params; + } + + /** + * Creates a signature information label from parameters + * + * @param ParameterInformation[] $params Parameters to create the label from + * + * @return string + */ + private function createLabel(array $params): string + { + $label = '('; + if ($params) { + foreach ($params as $param) { + $label .= $param->label . ', '; + } + $label = substr($label, 0, -2); + } + $label .= ')'; + return $label; + } +} diff --git a/src/TreeAnalyzer.php b/src/TreeAnalyzer.php index 37e2c16..465f5bb 100644 --- a/src/TreeAnalyzer.php +++ b/src/TreeAnalyzer.php @@ -99,11 +99,9 @@ class TreeAnalyzer // Find the first ancestor that's a class method. Return an error // if there is none, or if the method is static. $method = $node->getFirstAncestor(Node\MethodDeclaration::class); - if ($method === null || $method->isStatic()) { + if ($method && $method->isStatic()) { $this->diagnostics[] = new Diagnostic( - $method === null - ? "\$this can only be used in an object context." - : "\$this can not be used in static methods.", + "\$this can not be used in static methods.", Range::fromNode($node), null, DiagnosticSeverity::ERROR, diff --git a/tests/Diagnostics/InvalidThisUsageTest.php b/tests/Diagnostics/InvalidThisUsageTest.php index 7542918..b7e8196 100644 --- a/tests/Diagnostics/InvalidThisUsageTest.php +++ b/tests/Diagnostics/InvalidThisUsageTest.php @@ -71,42 +71,6 @@ class InvalidThisUsageTest extends TestCase ); } - public function testThisInFunctionProducesError() - { - $diagnostics = $this->collectDiagnostics( - __DIR__ . '/../../fixtures/diagnostics/errors/this_in_function.php' - ); - - $this->assertCount(1, $diagnostics); - $this->assertDiagnostic( - $diagnostics[0], - '$this can only be used in an object context.', - DiagnosticSeverity::ERROR, - new Range( - new Position(4, 11), - new Position(4, 16) - ) - ); - } - - public function testThisInRoot() - { - $diagnostics = $this->collectDiagnostics( - __DIR__ . '/../../fixtures/diagnostics/errors/this_in_root.php' - ); - - $this->assertCount(1, $diagnostics); - $this->assertDiagnostic( - $diagnostics[0], - '$this can only be used in an object context.', - DiagnosticSeverity::ERROR, - new Range( - new Position(2, 5), - new Position(2, 10) - ) - ); - } - public function testThisInMethodProducesNoError() { $diagnostics = $this->collectDiagnostics( diff --git a/tests/LanguageServerTest.php b/tests/LanguageServerTest.php index 5d58172..52963e6 100644 --- a/tests/LanguageServerTest.php +++ b/tests/LanguageServerTest.php @@ -14,7 +14,8 @@ use LanguageServer\Protocol\{ TextDocumentIdentifier, InitializeResult, ServerCapabilities, - CompletionOptions + CompletionOptions, + SignatureHelpOptions }; use AdvancedJsonRpc; use Webmozart\Glob\Glob; @@ -40,6 +41,8 @@ class LanguageServerTest extends TestCase $serverCapabilities->completionProvider = new CompletionOptions; $serverCapabilities->completionProvider->resolveProvider = false; $serverCapabilities->completionProvider->triggerCharacters = ['$', '>']; + $serverCapabilities->signatureHelpProvider = new SignatureHelpOptions; + $serverCapabilities->signatureHelpProvider->triggerCharacters = ['(', ',']; $serverCapabilities->xworkspaceReferencesProvider = true; $serverCapabilities->xdefinitionProvider = true; $serverCapabilities->xdependenciesProvider = true; diff --git a/tests/Server/TextDocument/CompletionTest.php b/tests/Server/TextDocument/CompletionTest.php index 9716578..8e55263 100644 --- a/tests/Server/TextDocument/CompletionTest.php +++ b/tests/Server/TextDocument/CompletionTest.php @@ -554,6 +554,161 @@ class CompletionTest extends TestCase ], true), $items); } + /** + * @dataProvider foreachProvider + */ + public function testForeach(Position $position, array $expectedItems) + { + $completionUri = pathToUri(__DIR__ . '/../../../fixtures/completion/foreach.php'); + $this->loader->open($completionUri, file_get_contents($completionUri)); + $items = $this->textDocument->completion( + new TextDocumentIdentifier($completionUri), + $position + )->wait(); + $this->assertCompletionsListSubset(new CompletionList($expectedItems, true), $items); + } + + public function foreachProvider(): array + { + return [ + 'foreach value' => [ + new Position(18, 6), + [ + new CompletionItem( + '$value', + CompletionItemKind::VARIABLE, + '\\Foo\\Bar', + null, + null, + null, + null, + new TextEdit(new Range(new Position(18, 6), new Position(18, 6)), 'alue') + ), + ] + ], + 'foreach value resolved' => [ + new Position(19, 12), + [ + new CompletionItem( + 'foo', + CompletionItemKind::PROPERTY, + 'mixed' + ), + new CompletionItem( + 'test', + CompletionItemKind::METHOD, + '\\Foo\\Bar[]' + ), + ] + ], + 'array creation with multiple objects' => [ + new Position(23, 5), + [ + new CompletionItem( + '$value', + CompletionItemKind::VARIABLE, + '\\Foo\\Bar|\\stdClass', + null, + null, + null, + null, + new TextEdit(new Range(new Position(23, 5), new Position(23, 5)), 'value') + ), + new CompletionItem( + '$key', + CompletionItemKind::VARIABLE, + 'int', + null, + null, + null, + null, + new TextEdit(new Range(new Position(23, 5), new Position(23, 5)), 'key') + ), + ] + ], + 'array creation with string/int keys and object values' => [ + new Position(27, 5), + [ + new CompletionItem( + '$value', + CompletionItemKind::VARIABLE, + '\\Foo\\Bar', + null, + null, + null, + null, + new TextEdit(new Range(new Position(27, 5), new Position(27, 5)), 'value') + ), + new CompletionItem( + '$key', + CompletionItemKind::VARIABLE, + 'string|int', + null, + null, + null, + null, + new TextEdit(new Range(new Position(27, 5), new Position(27, 5)), 'key') + ), + ] + ], + 'array creation with only string keys' => [ + new Position(31, 5), + [ + new CompletionItem( + '$value', + CompletionItemKind::VARIABLE, + '\\Foo\\Bar', + null, + null, + null, + null, + new TextEdit(new Range(new Position(31, 5), new Position(31, 5)), 'value') + ), + new CompletionItem( + '$key', + CompletionItemKind::VARIABLE, + 'string', + null, + null, + null, + null, + new TextEdit(new Range(new Position(31, 5), new Position(31, 5)), 'key') + ), + ] + ], + 'foreach function call' => [ + new Position(35, 5), + [ + new CompletionItem( + '$value', + CompletionItemKind::VARIABLE, + '\\Foo\\Bar', + null, + null, + null, + null, + new TextEdit(new Range(new Position(35, 5), new Position(35, 5)), 'value') + ), + ] + ], + 'foreach unknown type' => [ + new Position(39, 10), + [ + new CompletionItem( + '$unknown', + CompletionItemKind::VARIABLE, + 'mixed', + null, + null, + null, + null, + new TextEdit(new Range(new Position(39, 10), new Position(39, 10)), 'wn') + ), + ] + ], + ]; + } + public function testMethodReturnType() { $completionUri = pathToUri(__DIR__ . '/../../../fixtures/completion/method_return_type.php'); diff --git a/tests/Server/TextDocument/SignatureHelpTest.php b/tests/Server/TextDocument/SignatureHelpTest.php new file mode 100644 index 0000000..2004aae --- /dev/null +++ b/tests/Server/TextDocument/SignatureHelpTest.php @@ -0,0 +1,199 @@ +loader = new PhpDocumentLoader($contentRetriever, $projectIndex, $definitionResolver); + $this->textDocument = new Server\TextDocument($this->loader, $definitionResolver, $client, $projectIndex); + $index->setComplete(); + } + + /** + * @dataProvider signatureHelpProvider + */ + public function testSignatureHelp(Position $position, SignatureHelp $expectedSignature) + { + $callsUri = pathToUri(__DIR__ . '/../../../fixtures/signature_help/calls.php'); + $this->loader->open($callsUri, file_get_contents($callsUri)); + $signatureHelp = $this->textDocument->signatureHelp( + new TextDocumentIdentifier($callsUri), + $position + )->wait(); + $this->assertEquals($expectedSignature, $signatureHelp); + } + + public function signatureHelpProvider(): array + { + return [ + 'member call' => [ + new Position(50, 9), + new SignatureHelp( + [ + new SignatureInformation( + '(\\Foo\\SomethingElse $a, int|null $b = null)', + [ + new ParameterInformation('\\Foo\\SomethingElse $a', 'A param with a different doc type'), + new ParameterInformation('int|null $b = null', 'Param with default value'), + ], + 'Function doc' + ) + ], + 0, + 0 + ), + ], + 'member call 2nd param active' => [ + new Position(51, 12), + new SignatureHelp( + [ + new SignatureInformation( + '(\\Foo\\SomethingElse $a, int|null $b = null)', + [ + new ParameterInformation('\\Foo\\SomethingElse $a', 'A param with a different doc type'), + new ParameterInformation('int|null $b = null', 'Param with default value'), + ], + 'Function doc' + ) + ], + 0, + 1 + ), + ], + 'member call 2nd param active and closing )' => [ + new Position(52, 11), + new SignatureHelp( + [ + new SignatureInformation( + '(\\Foo\\SomethingElse $a, int|null $b = null)', + [ + new ParameterInformation('\\Foo\\SomethingElse $a', 'A param with a different doc type'), + new ParameterInformation('int|null $b = null', 'Param with default value'), + ], + 'Function doc' + ) + ], + 0, + 1 + ), + ], + 'method with no params' => [ + new Position(53, 9), + new SignatureHelp([new SignatureInformation('()', [], 'Method with no params', 0, 0)]), + ], + 'constructor' => [ + new Position(48, 14), + new SignatureHelp( + [ + new SignatureInformation( + '(string $first, int $second, \Foo\Test $third)', + [ + new ParameterInformation('string $first', 'First param'), + new ParameterInformation('int $second', 'Second param'), + new ParameterInformation('\Foo\Test $third', 'Third param with a longer description'), + ], + 'Constructor comment goes here' + ) + ], + 0, + 0 + ), + ], + 'constructor argument expression list' => [ + new Position(49, 16), + new SignatureHelp( + [ + new SignatureInformation( + '(string $first, int $second, \Foo\Test $third)', + [ + new ParameterInformation('string $first', 'First param'), + new ParameterInformation('int $second', 'Second param'), + new ParameterInformation('\Foo\Test $third', 'Third param with a longer description'), + ], + 'Constructor comment goes here' + ) + ], + 0, + 1 + ), + ], + 'global function' => [ + new Position(57, 15), + new SignatureHelp( + [ + new SignatureInformation( + '(int $i, bool $b = false, \Foo\Test|null ...$things = null)', + [ + new ParameterInformation('int $i', 'Global function param one'), + new ParameterInformation('bool $b = false', 'Default false param'), + new ParameterInformation('\Foo\Test|null ...$things = null', 'Test things'), + ] + ), + ], + 0, + 2 + ) + ], + 'static method' => [ + new Position(60, 10), + new SignatureHelp( + [new SignatureInformation('(mixed $a)', [new ParameterInformation('mixed $a')])], + 0, + 0 + ), + ], + 'no signature help' => [ + new Position(0, 0), + new SignatureHelp([]), + ], + 'construct from non fqn (not supported)' => [ + new Position(62, 9), + new SignatureHelp([]), + ], + 'construct from non fqn (not supported) argument expression' => [ + new Position(63, 11), + new SignatureHelp([]), + ], + 'invalid var' => [ + new Position(65, 13), + new SignatureHelp([]), + ], + ]; + } +} diff --git a/tests/Validation/cases/WithReturnTypehints.php.expected.json b/tests/Validation/cases/WithReturnTypehints.php.expected.json index 8c6b092..2eb8218 100644 --- a/tests/Validation/cases/WithReturnTypehints.php.expected.json +++ b/tests/Validation/cases/WithReturnTypehints.php.expected.json @@ -31,7 +31,8 @@ }, "type": null, "declarationLine": "namespace Fixtures\\Prophecy;", - "documentation": null + "documentation": null, + "signatureInformation": null }, "Fixtures\\Prophecy\\WithReturnTypehints": { "fqn": "Fixtures\\Prophecy\\WithReturnTypehints", @@ -52,7 +53,8 @@ }, "type": null, "declarationLine": "class WithReturnTypehints extends EmptyClass", - "documentation": null + "documentation": null, + "signatureInformation": null }, "Fixtures\\Prophecy\\WithReturnTypehints->getSelf()": { "fqn": "Fixtures\\Prophecy\\WithReturnTypehints->getSelf()", @@ -69,10 +71,15 @@ }, "containerName": "Fixtures\\Prophecy\\WithReturnTypehints" }, - "type__tostring": "\\self", + "type__tostring": "\\Fixtures\\Prophecy\\WithReturnTypehints", "type": {}, "declarationLine": "public function getSelf(): self {", - "documentation": null + "documentation": null, + "signatureInformation": { + "label": "()", + "documentation": null, + "parameters": [] + } }, "Fixtures\\Prophecy\\WithReturnTypehints->getName()": { "fqn": "Fixtures\\Prophecy\\WithReturnTypehints->getName()", @@ -92,7 +99,12 @@ "type__tostring": "string", "type": {}, "declarationLine": "public function getName(): string {", - "documentation": null + "documentation": null, + "signatureInformation": { + "label": "()", + "documentation": null, + "parameters": [] + } }, "Fixtures\\Prophecy\\WithReturnTypehints->getParent()": { "fqn": "Fixtures\\Prophecy\\WithReturnTypehints->getParent()", @@ -112,7 +124,12 @@ "type__tostring": "\\parent", "type": {}, "declarationLine": "public function getParent(): parent {", - "documentation": null + "documentation": null, + "signatureInformation": { + "label": "()", + "documentation": null, + "parameters": [] + } } } } \ No newline at end of file diff --git a/tests/Validation/cases/anonymousClassMembersShouldNotBeSymbols.php.expected.json b/tests/Validation/cases/anonymousClassMembersShouldNotBeSymbols.php.expected.json index 51343f1..f5fbba9 100644 --- a/tests/Validation/cases/anonymousClassMembersShouldNotBeSymbols.php.expected.json +++ b/tests/Validation/cases/anonymousClassMembersShouldNotBeSymbols.php.expected.json @@ -18,7 +18,8 @@ }, "type": null, "declarationLine": "namespace MyNamespace;", - "documentation": null + "documentation": null, + "signatureInformation": null } } } \ No newline at end of file diff --git a/tests/Validation/cases/arrayValueShouldBeBoolean.php.expected.json b/tests/Validation/cases/arrayValueShouldBeBoolean.php.expected.json index 107877e..f0cdb24 100644 --- a/tests/Validation/cases/arrayValueShouldBeBoolean.php.expected.json +++ b/tests/Validation/cases/arrayValueShouldBeBoolean.php.expected.json @@ -18,7 +18,8 @@ }, "type": null, "declarationLine": "class A {", - "documentation": null + "documentation": null, + "signatureInformation": null }, "A->foo": { "fqn": "A->foo", @@ -35,10 +36,11 @@ }, "containerName": "A" }, - "type__tostring": "string[]", + "type__tostring": "bool[]", "type": {}, "declarationLine": "protected $foo;", - "documentation": null + "documentation": null, + "signatureInformation": null } } } \ No newline at end of file diff --git a/tests/Validation/cases/caseStatement1.php.expected.json b/tests/Validation/cases/caseStatement1.php.expected.json index 9746749..4b2f07b 100644 --- a/tests/Validation/cases/caseStatement1.php.expected.json +++ b/tests/Validation/cases/caseStatement1.php.expected.json @@ -25,7 +25,8 @@ }, "type": null, "declarationLine": "namespace MyNamespace;", - "documentation": null + "documentation": null, + "signatureInformation": null } } } \ No newline at end of file diff --git a/tests/Validation/cases/classDefinition1.php.expected.json b/tests/Validation/cases/classDefinition1.php.expected.json index 670b5de..211a12f 100644 --- a/tests/Validation/cases/classDefinition1.php.expected.json +++ b/tests/Validation/cases/classDefinition1.php.expected.json @@ -25,7 +25,8 @@ }, "type": null, "declarationLine": "namespace TestNamespace;", - "documentation": null + "documentation": null, + "signatureInformation": null }, "TestNamespace\\A": { "fqn": "TestNamespace\\A", @@ -44,7 +45,8 @@ }, "type": null, "declarationLine": "class A {", - "documentation": null + "documentation": null, + "signatureInformation": null }, "TestNamespace\\A->a": { "fqn": "TestNamespace\\A->a", @@ -64,7 +66,8 @@ "type__tostring": "int", "type": {}, "declarationLine": "public $a;", - "documentation": null + "documentation": null, + "signatureInformation": null } } } \ No newline at end of file diff --git a/tests/Validation/cases/classProperty1.php.expected.json b/tests/Validation/cases/classProperty1.php.expected.json index 921bf0b..f5ae22a 100644 --- a/tests/Validation/cases/classProperty1.php.expected.json +++ b/tests/Validation/cases/classProperty1.php.expected.json @@ -25,7 +25,8 @@ }, "type": null, "declarationLine": "namespace TestNamespace;", - "documentation": null + "documentation": null, + "signatureInformation": null }, "TestNamespace\\TestClass": { "fqn": "TestNamespace\\TestClass", @@ -44,7 +45,8 @@ }, "type": null, "declarationLine": "class TestClass", - "documentation": null + "documentation": null, + "signatureInformation": null }, "TestNamespace\\TestClass->testProperty": { "fqn": "TestNamespace\\TestClass->testProperty", @@ -64,7 +66,8 @@ "type__tostring": "mixed", "type": {}, "declarationLine": "public $testProperty;", - "documentation": null + "documentation": null, + "signatureInformation": null }, "TestNamespace\\TestClass->testMethod()": { "fqn": "TestNamespace\\TestClass->testMethod()", @@ -84,7 +87,17 @@ "type__tostring": "mixed", "type": {}, "declarationLine": "public function testMethod($testParameter)", - "documentation": null + "documentation": null, + "signatureInformation": { + "label": "(mixed $testParameter)", + "documentation": null, + "parameters": [ + { + "label": "mixed $testParameter", + "documentation": null + } + ] + } } } } \ No newline at end of file diff --git a/tests/Validation/cases/constants.php.expected.json b/tests/Validation/cases/constants.php.expected.json index a76c059..3fcc367 100644 --- a/tests/Validation/cases/constants.php.expected.json +++ b/tests/Validation/cases/constants.php.expected.json @@ -25,7 +25,8 @@ }, "type": null, "declarationLine": "namespace MyNamespace;", - "documentation": null + "documentation": null, + "signatureInformation": null }, "MyNamespace\\A": { "fqn": "MyNamespace\\A", @@ -44,7 +45,8 @@ }, "type": null, "declarationLine": "class A", - "documentation": null + "documentation": null, + "signatureInformation": null }, "MyNamespace\\A::suite()": { "fqn": "MyNamespace\\A::suite()", @@ -64,7 +66,12 @@ "type__tostring": "mixed", "type": {}, "declarationLine": "public static function suite()", - "documentation": null + "documentation": null, + "signatureInformation": { + "label": "()", + "documentation": null, + "parameters": [] + } } } } \ No newline at end of file diff --git a/tests/Validation/cases/constants2.php.expected.json b/tests/Validation/cases/constants2.php.expected.json index ae5a2ce..0837b67 100644 --- a/tests/Validation/cases/constants2.php.expected.json +++ b/tests/Validation/cases/constants2.php.expected.json @@ -25,7 +25,8 @@ }, "type": null, "declarationLine": "namespace MyNamespace;", - "documentation": null + "documentation": null, + "signatureInformation": null }, "MyNamespace\\A": { "fqn": "MyNamespace\\A", @@ -44,7 +45,8 @@ }, "type": null, "declarationLine": "class A", - "documentation": null + "documentation": null, + "signatureInformation": null }, "MyNamespace\\A::suite()": { "fqn": "MyNamespace\\A::suite()", @@ -64,7 +66,12 @@ "type__tostring": "mixed", "type": {}, "declarationLine": "public static function suite()", - "documentation": null + "documentation": null, + "signatureInformation": { + "label": "()", + "documentation": null, + "parameters": [] + } } } } \ No newline at end of file diff --git a/tests/Validation/cases/constants3.php.expected.json b/tests/Validation/cases/constants3.php.expected.json index c6ad922..4b780a0 100644 --- a/tests/Validation/cases/constants3.php.expected.json +++ b/tests/Validation/cases/constants3.php.expected.json @@ -25,7 +25,8 @@ }, "type": null, "declarationLine": "namespace MyNamespace;", - "documentation": null + "documentation": null, + "signatureInformation": null }, "MyNamespace\\A": { "fqn": "MyNamespace\\A", @@ -44,7 +45,8 @@ }, "type": null, "declarationLine": "class A", - "documentation": null + "documentation": null, + "signatureInformation": null }, "MyNamespace\\A::suite()": { "fqn": "MyNamespace\\A::suite()", @@ -64,7 +66,12 @@ "type__tostring": "mixed", "type": {}, "declarationLine": "public static function suite()", - "documentation": null + "documentation": null, + "signatureInformation": { + "label": "()", + "documentation": null, + "parameters": [] + } } } } \ No newline at end of file diff --git a/tests/Validation/cases/constants4.php.expected.json b/tests/Validation/cases/constants4.php.expected.json index bc46cf1..1f2bcd5 100644 --- a/tests/Validation/cases/constants4.php.expected.json +++ b/tests/Validation/cases/constants4.php.expected.json @@ -25,7 +25,8 @@ }, "type": null, "declarationLine": "namespace MyNamespace;", - "documentation": null + "documentation": null, + "signatureInformation": null }, "MyNamespace\\A": { "fqn": "MyNamespace\\A", @@ -44,7 +45,8 @@ }, "type": null, "declarationLine": "class A", - "documentation": null + "documentation": null, + "signatureInformation": null }, "MyNamespace\\A->suite()": { "fqn": "MyNamespace\\A->suite()", @@ -64,7 +66,12 @@ "type__tostring": "mixed", "type": {}, "declarationLine": "public function suite()", - "documentation": null + "documentation": null, + "signatureInformation": { + "label": "()", + "documentation": null, + "parameters": [] + } } } } \ No newline at end of file diff --git a/tests/Validation/cases/constants5.php.expected.json b/tests/Validation/cases/constants5.php.expected.json index 6bd7b8e..6b93043 100644 --- a/tests/Validation/cases/constants5.php.expected.json +++ b/tests/Validation/cases/constants5.php.expected.json @@ -22,7 +22,8 @@ }, "type": null, "declarationLine": "namespace MyNamespace;", - "documentation": null + "documentation": null, + "signatureInformation": null }, "MyNamespace\\Mbstring": { "fqn": "MyNamespace\\Mbstring", @@ -41,7 +42,8 @@ }, "type": null, "declarationLine": "class Mbstring", - "documentation": null + "documentation": null, + "signatureInformation": null }, "MyNamespace\\Mbstring::MB_CASE_FOLD": { "fqn": "MyNamespace\\Mbstring::MB_CASE_FOLD", @@ -61,7 +63,8 @@ "type__tostring": "\\MyNamespace\\PHP_INT_MAX", "type": {}, "declarationLine": "const MB_CASE_FOLD = PHP_INT_MAX;", - "documentation": null + "documentation": null, + "signatureInformation": null } } } \ No newline at end of file diff --git a/tests/Validation/cases/constantsInFunctionParamDefault.php.expected.json b/tests/Validation/cases/constantsInFunctionParamDefault.php.expected.json index b49f5a9..0a34c36 100644 --- a/tests/Validation/cases/constantsInFunctionParamDefault.php.expected.json +++ b/tests/Validation/cases/constantsInFunctionParamDefault.php.expected.json @@ -22,7 +22,8 @@ }, "type": null, "declarationLine": "interface A {", - "documentation": null + "documentation": null, + "signatureInformation": null }, "A->b()": { "fqn": "A->b()", @@ -42,7 +43,17 @@ "type__tostring": "mixed", "type": {}, "declarationLine": "function b ($a = MY_CONSTANT);", - "documentation": null + "documentation": null, + "signatureInformation": { + "label": "(\\MY_CONSTANT $a = MY_CONSTANT)", + "documentation": null, + "parameters": [ + { + "label": "\\MY_CONSTANT $a = MY_CONSTANT", + "documentation": null + } + ] + } } } } \ No newline at end of file diff --git a/tests/Validation/cases/docBlocksOnNamespaceDefinition.php.expected.json b/tests/Validation/cases/docBlocksOnNamespaceDefinition.php.expected.json index dd1737a..27f5df9 100644 --- a/tests/Validation/cases/docBlocksOnNamespaceDefinition.php.expected.json +++ b/tests/Validation/cases/docBlocksOnNamespaceDefinition.php.expected.json @@ -18,7 +18,8 @@ }, "type": null, "declarationLine": "namespace MyNamespace;", - "documentation": null + "documentation": null, + "signatureInformation": null } } } \ No newline at end of file diff --git a/tests/Validation/cases/exceptions1.php.expected.json b/tests/Validation/cases/exceptions1.php.expected.json index c1ee1bd..2dc57b3 100644 --- a/tests/Validation/cases/exceptions1.php.expected.json +++ b/tests/Validation/cases/exceptions1.php.expected.json @@ -22,7 +22,8 @@ }, "type": null, "declarationLine": "namespace MyNamespace;", - "documentation": null + "documentation": null, + "signatureInformation": null } } } \ No newline at end of file diff --git a/tests/Validation/cases/ifStatement1.php.expected.json b/tests/Validation/cases/ifStatement1.php.expected.json index 98e6572..e422270 100644 --- a/tests/Validation/cases/ifStatement1.php.expected.json +++ b/tests/Validation/cases/ifStatement1.php.expected.json @@ -25,7 +25,8 @@ }, "type": null, "declarationLine": "namespace MyNamespace;", - "documentation": null + "documentation": null, + "signatureInformation": null } } } \ No newline at end of file diff --git a/tests/Validation/cases/interfaceProperty.php.expected.json b/tests/Validation/cases/interfaceProperty.php.expected.json index 10c49f0..d22d028 100644 --- a/tests/Validation/cases/interfaceProperty.php.expected.json +++ b/tests/Validation/cases/interfaceProperty.php.expected.json @@ -18,7 +18,8 @@ }, "type": null, "declarationLine": "interface A {", - "documentation": null + "documentation": null, + "signatureInformation": null } } } \ No newline at end of file diff --git a/tests/Validation/cases/magicConstantsShouldBeGlobal.php.expected.json b/tests/Validation/cases/magicConstantsShouldBeGlobal.php.expected.json index a9c2162..5b04b54 100644 --- a/tests/Validation/cases/magicConstantsShouldBeGlobal.php.expected.json +++ b/tests/Validation/cases/magicConstantsShouldBeGlobal.php.expected.json @@ -25,7 +25,8 @@ }, "type": null, "declarationLine": "namespace B;", - "documentation": null + "documentation": null, + "signatureInformation": null } } } \ No newline at end of file diff --git a/tests/Validation/cases/magicConsts.php.expected.json b/tests/Validation/cases/magicConsts.php.expected.json index 6f863b9..27608e5 100644 --- a/tests/Validation/cases/magicConsts.php.expected.json +++ b/tests/Validation/cases/magicConsts.php.expected.json @@ -22,7 +22,8 @@ }, "type": null, "declarationLine": "class A {", - "documentation": null + "documentation": null, + "signatureInformation": null }, "A::$deprecationsTriggered": { "fqn": "A::$deprecationsTriggered", @@ -39,10 +40,11 @@ }, "containerName": "A" }, - "type__tostring": "\\__CLASS__[]", + "type__tostring": "bool[]", "type": {}, "declarationLine": "private static $deprecationsTriggered;", - "documentation": null + "documentation": null, + "signatureInformation": null } } } \ No newline at end of file diff --git a/tests/Validation/cases/memberAccess1.php.expected.json b/tests/Validation/cases/memberAccess1.php.expected.json index c039e5e..f0286c3 100644 --- a/tests/Validation/cases/memberAccess1.php.expected.json +++ b/tests/Validation/cases/memberAccess1.php.expected.json @@ -25,7 +25,8 @@ }, "type": null, "declarationLine": "namespace MyNamespace;", - "documentation": null + "documentation": null, + "signatureInformation": null }, "MyNamespace\\A": { "fqn": "MyNamespace\\A", @@ -44,7 +45,8 @@ }, "type": null, "declarationLine": "class A {", - "documentation": null + "documentation": null, + "signatureInformation": null }, "MyNamespace\\A::a()": { "fqn": "MyNamespace\\A::a()", @@ -64,7 +66,12 @@ "type__tostring": "mixed", "type": {}, "declarationLine": "static function a() {", - "documentation": null + "documentation": null, + "signatureInformation": { + "label": "()", + "documentation": null, + "parameters": [] + } } } } \ No newline at end of file diff --git a/tests/Validation/cases/memberAccess2.php.expected.json b/tests/Validation/cases/memberAccess2.php.expected.json index 50902a1..6060e8e 100644 --- a/tests/Validation/cases/memberAccess2.php.expected.json +++ b/tests/Validation/cases/memberAccess2.php.expected.json @@ -25,7 +25,8 @@ }, "type": null, "declarationLine": "namespace MyNamespace;", - "documentation": null + "documentation": null, + "signatureInformation": null }, "MyNamespace\\A": { "fqn": "MyNamespace\\A", @@ -44,7 +45,8 @@ }, "type": null, "declarationLine": "class A {", - "documentation": null + "documentation": null, + "signatureInformation": null }, "MyNamespace\\A::a()": { "fqn": "MyNamespace\\A::a()", @@ -64,7 +66,12 @@ "type__tostring": "mixed", "type": {}, "declarationLine": "static function a() {", - "documentation": null + "documentation": null, + "signatureInformation": { + "label": "()", + "documentation": null, + "parameters": [] + } } } } \ No newline at end of file diff --git a/tests/Validation/cases/memberAccess3.php.expected.json b/tests/Validation/cases/memberAccess3.php.expected.json index d91b27d..b0af5aa 100644 --- a/tests/Validation/cases/memberAccess3.php.expected.json +++ b/tests/Validation/cases/memberAccess3.php.expected.json @@ -40,7 +40,8 @@ }, "type": null, "declarationLine": "namespace MyNamespace;", - "documentation": null + "documentation": null, + "signatureInformation": null }, "MyNamespace\\A": { "fqn": "MyNamespace\\A", @@ -59,7 +60,8 @@ }, "type": null, "declarationLine": "class A {", - "documentation": null + "documentation": null, + "signatureInformation": null }, "MyNamespace\\A::getInitializer()": { "fqn": "MyNamespace\\A::getInitializer()", @@ -79,7 +81,17 @@ "type__tostring": "mixed", "type": {}, "declarationLine": "public static function getInitializer(ClassLoader $loader)", - "documentation": null + "documentation": null, + "signatureInformation": { + "label": "(\\MyNamespace\\ClassLoader $loader)", + "documentation": null, + "parameters": [ + { + "label": "\\MyNamespace\\ClassLoader $loader", + "documentation": null + } + ] + } } } } \ No newline at end of file diff --git a/tests/Validation/cases/memberAccess4.php.expected.json b/tests/Validation/cases/memberAccess4.php.expected.json index 0b7e1bf..951cacd 100644 --- a/tests/Validation/cases/memberAccess4.php.expected.json +++ b/tests/Validation/cases/memberAccess4.php.expected.json @@ -31,7 +31,8 @@ }, "type": null, "declarationLine": "namespace MyNamespace;", - "documentation": null + "documentation": null, + "signatureInformation": null }, "MyNamespace\\A": { "fqn": "MyNamespace\\A", @@ -50,7 +51,8 @@ }, "type": null, "declarationLine": "class A {", - "documentation": null + "documentation": null, + "signatureInformation": null }, "MyNamespace\\A->testRequest()": { "fqn": "MyNamespace\\A->testRequest()", @@ -70,7 +72,12 @@ "type__tostring": "mixed", "type": {}, "declarationLine": "public function testRequest()", - "documentation": null + "documentation": null, + "signatureInformation": { + "label": "()", + "documentation": null, + "parameters": [] + } } } } \ No newline at end of file diff --git a/tests/Validation/cases/memberAccess5.php.expected.json b/tests/Validation/cases/memberAccess5.php.expected.json index 050cf3b..d4e9104 100644 --- a/tests/Validation/cases/memberAccess5.php.expected.json +++ b/tests/Validation/cases/memberAccess5.php.expected.json @@ -22,7 +22,8 @@ }, "type": null, "declarationLine": "namespace MyNamespace;", - "documentation": null + "documentation": null, + "signatureInformation": null }, "MyNamespace\\ParseErrorsTest": { "fqn": "MyNamespace\\ParseErrorsTest", @@ -41,7 +42,8 @@ }, "type": null, "declarationLine": "class ParseErrorsTest {", - "documentation": null + "documentation": null, + "signatureInformation": null }, "MyNamespace\\ParseErrorsTest->setUp()": { "fqn": "MyNamespace\\ParseErrorsTest->setUp()", @@ -61,7 +63,12 @@ "type__tostring": "mixed", "type": {}, "declarationLine": "public function setUp()", - "documentation": null + "documentation": null, + "signatureInformation": { + "label": "()", + "documentation": null, + "parameters": [] + } } } } \ No newline at end of file diff --git a/tests/Validation/cases/memberCall1.php.expected.json b/tests/Validation/cases/memberCall1.php.expected.json index d02d7e3..50e91d1 100644 --- a/tests/Validation/cases/memberCall1.php.expected.json +++ b/tests/Validation/cases/memberCall1.php.expected.json @@ -28,7 +28,8 @@ }, "type": null, "declarationLine": "namespace MyNamespace;", - "documentation": null + "documentation": null, + "signatureInformation": null }, "MyNamespace\\ParseErrorsTest": { "fqn": "MyNamespace\\ParseErrorsTest", @@ -47,7 +48,8 @@ }, "type": null, "declarationLine": "class ParseErrorsTest", - "documentation": null + "documentation": null, + "signatureInformation": null }, "MyNamespace\\ParseErrorsTest->setAccount()": { "fqn": "MyNamespace\\ParseErrorsTest->setAccount()", @@ -67,7 +69,17 @@ "type__tostring": "mixed", "type": {}, "declarationLine": "public function setAccount(AccountInterface $account)", - "documentation": null + "documentation": null, + "signatureInformation": { + "label": "(\\MyNamespace\\AccountInterface $account)", + "documentation": null, + "parameters": [ + { + "label": "\\MyNamespace\\AccountInterface $account", + "documentation": null + } + ] + } } } } \ No newline at end of file diff --git a/tests/Validation/cases/methodReturnType.php b/tests/Validation/cases/methodReturnType.php index b4b937d..824314a 100644 --- a/tests/Validation/cases/methodReturnType.php +++ b/tests/Validation/cases/methodReturnType.php @@ -4,4 +4,7 @@ class FooClass { public function foo(): FooClass { return $this; } + + /** @return self */ + public function bar() { } } diff --git a/tests/Validation/cases/methodReturnType.php.expected.json b/tests/Validation/cases/methodReturnType.php.expected.json index 2c89994..4abbb07 100644 --- a/tests/Validation/cases/methodReturnType.php.expected.json +++ b/tests/Validation/cases/methodReturnType.php.expected.json @@ -22,7 +22,8 @@ }, "type": null, "declarationLine": "class FooClass {", - "documentation": null + "documentation": null, + "signatureInformation": null }, "FooClass->foo()": { "fqn": "FooClass->foo()", @@ -42,7 +43,37 @@ "type__tostring": "\\FooClass", "type": {}, "declarationLine": "public function foo(): FooClass {", - "documentation": null + "documentation": null, + "signatureInformation": { + "label": "()", + "documentation": null, + "parameters": [] + } + }, + "FooClass->bar()": { + "fqn": "FooClass->bar()", + "extends": [], + "isMember": true, + "roamed": false, + "isStatic": false, + "canBeInstantiated": false, + "symbolInformation": { + "name": "bar", + "kind": 6, + "location": { + "uri": "./methodReturnType.php" + }, + "containerName": "FooClass" + }, + "type__tostring": "\\FooClass", + "type": {}, + "declarationLine": "public function bar() { }", + "documentation": "", + "signatureInformation": { + "label": "()", + "documentation": "", + "parameters": [] + } } } } \ No newline at end of file diff --git a/tests/Validation/cases/multipleNamespaces.php.expected.json b/tests/Validation/cases/multipleNamespaces.php.expected.json index fa51f2d..c308cf9 100644 --- a/tests/Validation/cases/multipleNamespaces.php.expected.json +++ b/tests/Validation/cases/multipleNamespaces.php.expected.json @@ -31,7 +31,8 @@ }, "type": null, "declarationLine": "namespace MyNamespace1;", - "documentation": null + "documentation": null, + "signatureInformation": null }, "MyNamespace1\\B": { "fqn": "MyNamespace1\\B", @@ -50,7 +51,8 @@ }, "type": null, "declarationLine": "class B {", - "documentation": null + "documentation": null, + "signatureInformation": null }, "MyNamespace1\\B->b()": { "fqn": "MyNamespace1\\B->b()", @@ -70,7 +72,12 @@ "type__tostring": "mixed", "type": {}, "declarationLine": "function b() {", - "documentation": null + "documentation": null, + "signatureInformation": { + "label": "()", + "documentation": null, + "parameters": [] + } }, "MyNamespace2": { "fqn": "MyNamespace2", @@ -89,7 +96,8 @@ }, "type": null, "declarationLine": "namespace MyNamespace2;", - "documentation": null + "documentation": null, + "signatureInformation": null }, "MyNamespace2\\A": { "fqn": "MyNamespace2\\A", @@ -110,7 +118,8 @@ }, "type": null, "declarationLine": "class A extends MyNamespace1\\B {", - "documentation": null + "documentation": null, + "signatureInformation": null }, "MyNamespace2\\A->a()": { "fqn": "MyNamespace2\\A->a()", @@ -130,7 +139,12 @@ "type__tostring": "mixed", "type": {}, "declarationLine": "function a () {", - "documentation": null + "documentation": null, + "signatureInformation": { + "label": "()", + "documentation": null, + "parameters": [] + } } } } \ No newline at end of file diff --git a/tests/Validation/cases/multiplePreceedingComments.php.expected.json b/tests/Validation/cases/multiplePreceedingComments.php.expected.json index 96cbb4a..2bca2b6 100644 --- a/tests/Validation/cases/multiplePreceedingComments.php.expected.json +++ b/tests/Validation/cases/multiplePreceedingComments.php.expected.json @@ -18,7 +18,8 @@ }, "type": null, "declarationLine": "class Foo", - "documentation": null + "documentation": null, + "signatureInformation": null }, "Foo->fn()": { "fqn": "Foo->fn()", @@ -38,7 +39,12 @@ "type__tostring": "\\Iterator", "type": {}, "declarationLine": "public function fn()", - "documentation": "Foo" + "documentation": "Foo", + "signatureInformation": { + "label": "()", + "documentation": "Foo", + "parameters": [] + } } } } \ No newline at end of file diff --git a/tests/Validation/cases/nameToken.php.expected.json b/tests/Validation/cases/nameToken.php.expected.json index 37cb4ca..c52d483 100644 --- a/tests/Validation/cases/nameToken.php.expected.json +++ b/tests/Validation/cases/nameToken.php.expected.json @@ -22,7 +22,8 @@ }, "type": null, "declarationLine": "class A {", - "documentation": null + "documentation": null, + "signatureInformation": null }, "A->b()": { "fqn": "A->b()", @@ -42,7 +43,12 @@ "type__tostring": "mixed", "type": {}, "declarationLine": "function b() {", - "documentation": null + "documentation": null, + "signatureInformation": { + "label": "()", + "documentation": null, + "parameters": [] + } } } } \ No newline at end of file diff --git a/tests/Validation/cases/namespaces2.php.expected.json b/tests/Validation/cases/namespaces2.php.expected.json index 0dffc9f..cd0ade5 100644 --- a/tests/Validation/cases/namespaces2.php.expected.json +++ b/tests/Validation/cases/namespaces2.php.expected.json @@ -31,7 +31,8 @@ }, "type": null, "declarationLine": "namespace MyNamespace1;", - "documentation": null + "documentation": null, + "signatureInformation": null } } } \ No newline at end of file diff --git a/tests/Validation/cases/namespaces5.php.expected.json b/tests/Validation/cases/namespaces5.php.expected.json index e609ca2..7ad96f3 100644 --- a/tests/Validation/cases/namespaces5.php.expected.json +++ b/tests/Validation/cases/namespaces5.php.expected.json @@ -40,7 +40,8 @@ }, "type": null, "declarationLine": "namespace B;", - "documentation": null + "documentation": null, + "signatureInformation": null } } } \ No newline at end of file diff --git a/tests/Validation/cases/namespaces6.php.expected.json b/tests/Validation/cases/namespaces6.php.expected.json index bf5a045..6c559a3 100644 --- a/tests/Validation/cases/namespaces6.php.expected.json +++ b/tests/Validation/cases/namespaces6.php.expected.json @@ -18,7 +18,8 @@ }, "type": null, "declarationLine": "namespace A \\ B;", - "documentation": null + "documentation": null, + "signatureInformation": null } } } \ No newline at end of file diff --git a/tests/Validation/cases/namespaces8.php.expected.json b/tests/Validation/cases/namespaces8.php.expected.json index d303647..95c5019 100644 --- a/tests/Validation/cases/namespaces8.php.expected.json +++ b/tests/Validation/cases/namespaces8.php.expected.json @@ -28,7 +28,8 @@ }, "type": null, "declarationLine": "namespace LanguageServer\\Tests\\Utils;", - "documentation": null + "documentation": null, + "signatureInformation": null } } } \ No newline at end of file diff --git a/tests/Validation/cases/objectCreation.php.expected.json b/tests/Validation/cases/objectCreation.php.expected.json index 8fec38f..90ad0f5 100644 --- a/tests/Validation/cases/objectCreation.php.expected.json +++ b/tests/Validation/cases/objectCreation.php.expected.json @@ -22,7 +22,8 @@ }, "type": null, "declarationLine": "namespace MyNamespace;", - "documentation": null + "documentation": null, + "signatureInformation": null }, "MyNamespace\\A": { "fqn": "MyNamespace\\A", @@ -41,7 +42,8 @@ }, "type": null, "declarationLine": "class A {", - "documentation": null + "documentation": null, + "signatureInformation": null }, "MyNamespace\\A->a()": { "fqn": "MyNamespace\\A->a()", @@ -61,7 +63,12 @@ "type__tostring": "mixed", "type": {}, "declarationLine": "function a () {", - "documentation": null + "documentation": null, + "signatureInformation": { + "label": "()", + "documentation": null, + "parameters": [] + } } } } \ No newline at end of file diff --git a/tests/Validation/cases/objectCreation2.php.expected.json b/tests/Validation/cases/objectCreation2.php.expected.json index e546528..b6f69a3 100644 --- a/tests/Validation/cases/objectCreation2.php.expected.json +++ b/tests/Validation/cases/objectCreation2.php.expected.json @@ -25,7 +25,8 @@ }, "type": null, "declarationLine": "namespace MyNamespace;", - "documentation": null + "documentation": null, + "signatureInformation": null }, "MyNamespace\\B": { "fqn": "MyNamespace\\B", @@ -44,7 +45,8 @@ }, "type": null, "declarationLine": "class B {", - "documentation": null + "documentation": null, + "signatureInformation": null }, "MyNamespace\\A": { "fqn": "MyNamespace\\A", @@ -63,7 +65,8 @@ }, "type": null, "declarationLine": "class A {", - "documentation": null + "documentation": null, + "signatureInformation": null }, "MyNamespace\\A->a()": { "fqn": "MyNamespace\\A->a()", @@ -83,7 +86,12 @@ "type__tostring": "mixed", "type": {}, "declarationLine": "function a () {", - "documentation": null + "documentation": null, + "signatureInformation": { + "label": "()", + "documentation": null, + "parameters": [] + } } } } \ No newline at end of file diff --git a/tests/Validation/cases/objectCreation3.php.expected.json b/tests/Validation/cases/objectCreation3.php.expected.json index d2d3e2f..a5f389b 100644 --- a/tests/Validation/cases/objectCreation3.php.expected.json +++ b/tests/Validation/cases/objectCreation3.php.expected.json @@ -22,7 +22,8 @@ }, "type": null, "declarationLine": "class A {", - "documentation": null + "documentation": null, + "signatureInformation": null }, "A->a()": { "fqn": "A->a()", @@ -42,7 +43,12 @@ "type__tostring": "mixed", "type": {}, "declarationLine": "function a () {", - "documentation": null + "documentation": null, + "signatureInformation": { + "label": "()", + "documentation": null, + "parameters": [] + } } } } \ No newline at end of file diff --git a/tests/Validation/cases/param1.php.expected.json b/tests/Validation/cases/param1.php.expected.json index 40cfbd1..dd7c2a6 100644 --- a/tests/Validation/cases/param1.php.expected.json +++ b/tests/Validation/cases/param1.php.expected.json @@ -22,7 +22,8 @@ }, "type": null, "declarationLine": "namespace MyNamespace;", - "documentation": null + "documentation": null, + "signatureInformation": null }, "MyNamespace\\init()": { "fqn": "MyNamespace\\init()", @@ -42,7 +43,17 @@ "type__tostring": "mixed", "type": {}, "declarationLine": "function init(Hi $view)", - "documentation": null + "documentation": null, + "signatureInformation": { + "label": "(\\MyNamespace\\Hi $view)", + "documentation": null, + "parameters": [ + { + "label": "\\MyNamespace\\Hi $view", + "documentation": null + } + ] + } } } } \ No newline at end of file diff --git a/tests/Validation/cases/parent1.php.expected.json b/tests/Validation/cases/parent1.php.expected.json index 56d7e61..661f631 100644 --- a/tests/Validation/cases/parent1.php.expected.json +++ b/tests/Validation/cases/parent1.php.expected.json @@ -22,7 +22,8 @@ }, "type": null, "declarationLine": "namespace MyNamespace;", - "documentation": null + "documentation": null, + "signatureInformation": null }, "MyNamespace\\B": { "fqn": "MyNamespace\\B", @@ -41,7 +42,8 @@ }, "type": null, "declarationLine": "class B {", - "documentation": null + "documentation": null, + "signatureInformation": null }, "MyNamespace\\B->b()": { "fqn": "MyNamespace\\B->b()", @@ -61,7 +63,12 @@ "type__tostring": "mixed", "type": {}, "declarationLine": "function b() {", - "documentation": null + "documentation": null, + "signatureInformation": { + "label": "()", + "documentation": null, + "parameters": [] + } }, "MyNamespace\\A": { "fqn": "MyNamespace\\A", @@ -82,7 +89,8 @@ }, "type": null, "declarationLine": "class A extends B {", - "documentation": null + "documentation": null, + "signatureInformation": null }, "MyNamespace\\A->a()": { "fqn": "MyNamespace\\A->a()", @@ -102,7 +110,12 @@ "type__tostring": "mixed", "type": {}, "declarationLine": "function a () {", - "documentation": null + "documentation": null, + "signatureInformation": { + "label": "()", + "documentation": null, + "parameters": [] + } } } } \ No newline at end of file diff --git a/tests/Validation/cases/parent3.php.expected.json b/tests/Validation/cases/parent3.php.expected.json index 3954754..9ad39f8 100644 --- a/tests/Validation/cases/parent3.php.expected.json +++ b/tests/Validation/cases/parent3.php.expected.json @@ -25,7 +25,8 @@ }, "type": null, "declarationLine": "namespace MyNamespace;", - "documentation": null + "documentation": null, + "signatureInformation": null }, "MyNamespace\\B": { "fqn": "MyNamespace\\B", @@ -44,7 +45,8 @@ }, "type": null, "declarationLine": "class B {", - "documentation": null + "documentation": null, + "signatureInformation": null }, "MyNamespace\\B->b()": { "fqn": "MyNamespace\\B->b()", @@ -64,7 +66,12 @@ "type__tostring": "mixed", "type": {}, "declarationLine": "function b() {", - "documentation": null + "documentation": null, + "signatureInformation": { + "label": "()", + "documentation": null, + "parameters": [] + } }, "MyNamespace\\A": { "fqn": "MyNamespace\\A", @@ -85,7 +92,8 @@ }, "type": null, "declarationLine": "class A extends B {", - "documentation": null + "documentation": null, + "signatureInformation": null }, "MyNamespace\\A->a()": { "fqn": "MyNamespace\\A->a()", @@ -105,7 +113,12 @@ "type__tostring": "mixed", "type": {}, "declarationLine": "function a () {", - "documentation": null + "documentation": null, + "signatureInformation": { + "label": "()", + "documentation": null, + "parameters": [] + } } } } \ No newline at end of file diff --git a/tests/Validation/cases/propertyName1.php.expected.json b/tests/Validation/cases/propertyName1.php.expected.json index cc31ed6..d43cabf 100644 --- a/tests/Validation/cases/propertyName1.php.expected.json +++ b/tests/Validation/cases/propertyName1.php.expected.json @@ -18,7 +18,8 @@ }, "type": null, "declarationLine": "class MyClass", - "documentation": null + "documentation": null, + "signatureInformation": null }, "MyClass->mainPropertyName": { "fqn": "MyClass->mainPropertyName", @@ -38,7 +39,8 @@ "type__tostring": "string", "type": {}, "declarationLine": "protected $mainPropertyName;", - "documentation": "The name of the main property, or NULL if there is none." + "documentation": "The name of the main property, or NULL if there is none.", + "signatureInformation": null } } } \ No newline at end of file diff --git a/tests/Validation/cases/propertyName2.php.expected.json b/tests/Validation/cases/propertyName2.php.expected.json index d4efb42..4b5bd9b 100644 --- a/tests/Validation/cases/propertyName2.php.expected.json +++ b/tests/Validation/cases/propertyName2.php.expected.json @@ -18,7 +18,8 @@ }, "type": null, "declarationLine": "class MyClass", - "documentation": null + "documentation": null, + "signatureInformation": null }, "MyClass->mainPropertyName": { "fqn": "MyClass->mainPropertyName", @@ -38,7 +39,8 @@ "type__tostring": "string", "type": {}, "declarationLine": "protected $mainPropertyName;", - "documentation": "The name of the main property, or NULL if there is none." + "documentation": "The name of the main property, or NULL if there is none.", + "signatureInformation": null } } } \ No newline at end of file diff --git a/tests/Validation/cases/returnType.php.expected.json b/tests/Validation/cases/returnType.php.expected.json index 20cdadf..17a4802 100644 --- a/tests/Validation/cases/returnType.php.expected.json +++ b/tests/Validation/cases/returnType.php.expected.json @@ -25,7 +25,8 @@ }, "type": null, "declarationLine": "namespace TestNamespace;", - "documentation": null + "documentation": null, + "signatureInformation": null }, "TestNamespace\\whatever()": { "fqn": "TestNamespace\\whatever()", @@ -45,7 +46,17 @@ "type__tostring": "\\TestNamespace\\TestClass", "type": {}, "declarationLine": "function whatever(TestClass $param): TestClass2 {", - "documentation": "Aute duis elit reprehenderit tempor cillum proident anim laborum eu laboris reprehenderit ea incididunt." + "documentation": "Aute duis elit reprehenderit tempor cillum proident anim laborum eu laboris reprehenderit ea incididunt.", + "signatureInformation": { + "label": "(\\TestNamespace\\TestClass $param)", + "documentation": "Aute duis elit reprehenderit tempor cillum proident anim laborum eu laboris reprehenderit ea incididunt.", + "parameters": [ + { + "label": "\\TestNamespace\\TestClass $param", + "documentation": "Adipisicing non non cillum sint incididunt cillum enim mollit." + } + ] + } } } } \ No newline at end of file diff --git a/tests/Validation/cases/scopedPropertyAccess.php.expected.json b/tests/Validation/cases/scopedPropertyAccess.php.expected.json index ec50c7a..6020ee8 100644 --- a/tests/Validation/cases/scopedPropertyAccess.php.expected.json +++ b/tests/Validation/cases/scopedPropertyAccess.php.expected.json @@ -25,7 +25,8 @@ }, "type": null, "declarationLine": "namespace MyNamespace;", - "documentation": null + "documentation": null, + "signatureInformation": null }, "MyNamespace\\A": { "fqn": "MyNamespace\\A", @@ -44,7 +45,8 @@ }, "type": null, "declarationLine": "class A {", - "documentation": null + "documentation": null, + "signatureInformation": null }, "MyNamespace\\A::a()": { "fqn": "MyNamespace\\A::a()", @@ -64,7 +66,12 @@ "type__tostring": "mixed", "type": {}, "declarationLine": "static function a() {", - "documentation": null + "documentation": null, + "signatureInformation": { + "label": "()", + "documentation": null, + "parameters": [] + } } } } \ No newline at end of file diff --git a/tests/Validation/cases/scopedPropertyAccess2.php.expected.json b/tests/Validation/cases/scopedPropertyAccess2.php.expected.json index e1712cd..664d790 100644 --- a/tests/Validation/cases/scopedPropertyAccess2.php.expected.json +++ b/tests/Validation/cases/scopedPropertyAccess2.php.expected.json @@ -22,7 +22,8 @@ }, "type": null, "declarationLine": "namespace MyNamespace;", - "documentation": null + "documentation": null, + "signatureInformation": null } } } \ No newline at end of file diff --git a/tests/Validation/cases/scopedPropertyAccess3.php.expected.json b/tests/Validation/cases/scopedPropertyAccess3.php.expected.json index 913721b..54ca5f1 100644 --- a/tests/Validation/cases/scopedPropertyAccess3.php.expected.json +++ b/tests/Validation/cases/scopedPropertyAccess3.php.expected.json @@ -25,7 +25,8 @@ }, "type": null, "declarationLine": "class A {", - "documentation": null + "documentation": null, + "signatureInformation": null }, "A::$a": { "fqn": "A::$a", @@ -45,7 +46,8 @@ "type__tostring": "string", "type": {}, "declarationLine": "static $a;", - "documentation": null + "documentation": null, + "signatureInformation": null } } } \ No newline at end of file diff --git a/tests/Validation/cases/scopedPropertyAccess5.php.expected.json b/tests/Validation/cases/scopedPropertyAccess5.php.expected.json index 7e56123..ee944ed 100644 --- a/tests/Validation/cases/scopedPropertyAccess5.php.expected.json +++ b/tests/Validation/cases/scopedPropertyAccess5.php.expected.json @@ -31,7 +31,8 @@ }, "type": null, "declarationLine": "class TestClass implements TestInterface {", - "documentation": null + "documentation": null, + "signatureInformation": null }, "TestClass::$testProperty": { "fqn": "TestClass::$testProperty", @@ -51,7 +52,8 @@ "type__tostring": "\\TestClass[]", "type": {}, "declarationLine": "public static $testProperty;", - "documentation": "Lorem excepteur officia sit anim velit veniam enim." + "documentation": "Lorem excepteur officia sit anim velit veniam enim.", + "signatureInformation": null } } } \ No newline at end of file diff --git a/tests/Validation/cases/self1.php.expected.json b/tests/Validation/cases/self1.php.expected.json index fe2bc63..899df1c 100644 --- a/tests/Validation/cases/self1.php.expected.json +++ b/tests/Validation/cases/self1.php.expected.json @@ -28,7 +28,8 @@ }, "type": null, "declarationLine": "namespace MyNamespace;", - "documentation": null + "documentation": null, + "signatureInformation": null }, "MyNamespace\\B": { "fqn": "MyNamespace\\B", @@ -47,7 +48,8 @@ }, "type": null, "declarationLine": "class B {", - "documentation": null + "documentation": null, + "signatureInformation": null }, "MyNamespace\\B->b()": { "fqn": "MyNamespace\\B->b()", @@ -67,7 +69,12 @@ "type__tostring": "mixed", "type": {}, "declarationLine": "function b() {", - "documentation": null + "documentation": null, + "signatureInformation": { + "label": "()", + "documentation": null, + "parameters": [] + } }, "MyNamespace\\A": { "fqn": "MyNamespace\\A", @@ -88,7 +95,8 @@ }, "type": null, "declarationLine": "class A extends B {", - "documentation": null + "documentation": null, + "signatureInformation": null }, "MyNamespace\\A->a()": { "fqn": "MyNamespace\\A->a()", @@ -108,7 +116,12 @@ "type__tostring": "mixed", "type": {}, "declarationLine": "function a () {", - "documentation": null + "documentation": null, + "signatureInformation": { + "label": "()", + "documentation": null, + "parameters": [] + } } } } \ No newline at end of file diff --git a/tests/Validation/cases/self2.php.expected.json b/tests/Validation/cases/self2.php.expected.json index 60ab062..1c1ef87 100644 --- a/tests/Validation/cases/self2.php.expected.json +++ b/tests/Validation/cases/self2.php.expected.json @@ -28,7 +28,8 @@ }, "type": null, "declarationLine": "namespace MyNamespace;", - "documentation": null + "documentation": null, + "signatureInformation": null }, "MyNamespace\\B": { "fqn": "MyNamespace\\B", @@ -47,7 +48,8 @@ }, "type": null, "declarationLine": "class B {", - "documentation": null + "documentation": null, + "signatureInformation": null }, "MyNamespace\\B->b()": { "fqn": "MyNamespace\\B->b()", @@ -67,7 +69,12 @@ "type__tostring": "mixed", "type": {}, "declarationLine": "function b() {", - "documentation": null + "documentation": null, + "signatureInformation": { + "label": "()", + "documentation": null, + "parameters": [] + } }, "MyNamespace\\A": { "fqn": "MyNamespace\\A", @@ -88,7 +95,8 @@ }, "type": null, "declarationLine": "class A extends B {", - "documentation": null + "documentation": null, + "signatureInformation": null }, "MyNamespace\\A->a()": { "fqn": "MyNamespace\\A->a()", @@ -108,7 +116,12 @@ "type__tostring": "mixed", "type": {}, "declarationLine": "function a () {", - "documentation": null + "documentation": null, + "signatureInformation": { + "label": "()", + "documentation": null, + "parameters": [] + } } } } \ No newline at end of file diff --git a/tests/Validation/cases/self3.php.expected.json b/tests/Validation/cases/self3.php.expected.json index 7d66c2b..0a43146 100644 --- a/tests/Validation/cases/self3.php.expected.json +++ b/tests/Validation/cases/self3.php.expected.json @@ -28,7 +28,8 @@ }, "type": null, "declarationLine": "namespace MyNamespace;", - "documentation": null + "documentation": null, + "signatureInformation": null }, "MyNamespace\\B": { "fqn": "MyNamespace\\B", @@ -47,7 +48,8 @@ }, "type": null, "declarationLine": "class B {", - "documentation": null + "documentation": null, + "signatureInformation": null }, "MyNamespace\\B->b()": { "fqn": "MyNamespace\\B->b()", @@ -67,7 +69,12 @@ "type__tostring": "mixed", "type": {}, "declarationLine": "function b() {", - "documentation": null + "documentation": null, + "signatureInformation": { + "label": "()", + "documentation": null, + "parameters": [] + } }, "MyNamespace\\A": { "fqn": "MyNamespace\\A", @@ -88,7 +95,8 @@ }, "type": null, "declarationLine": "class A extends B {", - "documentation": null + "documentation": null, + "signatureInformation": null }, "MyNamespace\\A->a()": { "fqn": "MyNamespace\\A->a()", @@ -108,7 +116,12 @@ "type__tostring": "mixed", "type": {}, "declarationLine": "function a () {", - "documentation": null + "documentation": null, + "signatureInformation": { + "label": "()", + "documentation": null, + "parameters": [] + } } } } \ No newline at end of file diff --git a/tests/Validation/cases/self4.php.expected.json b/tests/Validation/cases/self4.php.expected.json index 64765b7..b925fdd 100644 --- a/tests/Validation/cases/self4.php.expected.json +++ b/tests/Validation/cases/self4.php.expected.json @@ -37,7 +37,8 @@ }, "type": null, "declarationLine": "namespace MyNamespace;", - "documentation": null + "documentation": null, + "signatureInformation": null }, "MyNamespace\\A": { "fqn": "MyNamespace\\A", @@ -56,7 +57,8 @@ }, "type": null, "declarationLine": "class A", - "documentation": null + "documentation": null, + "signatureInformation": null }, "MyNamespace\\A::suite()": { "fqn": "MyNamespace\\A::suite()", @@ -76,7 +78,12 @@ "type__tostring": "mixed", "type": {}, "declarationLine": "public static function suite()", - "documentation": null + "documentation": null, + "signatureInformation": { + "label": "()", + "documentation": null, + "parameters": [] + } } } } \ No newline at end of file diff --git a/tests/Validation/cases/self5.php.expected.json b/tests/Validation/cases/self5.php.expected.json index eb41832..10ba7fb 100644 --- a/tests/Validation/cases/self5.php.expected.json +++ b/tests/Validation/cases/self5.php.expected.json @@ -22,7 +22,8 @@ }, "type": null, "declarationLine": "namespace MyNamespace;", - "documentation": null + "documentation": null, + "signatureInformation": null }, "MyNamespace\\A": { "fqn": "MyNamespace\\A", @@ -41,7 +42,8 @@ }, "type": null, "declarationLine": "class A", - "documentation": null + "documentation": null, + "signatureInformation": null }, "MyNamespace\\A->typesProvider()": { "fqn": "MyNamespace\\A->typesProvider()", @@ -61,7 +63,12 @@ "type__tostring": "mixed", "type": {}, "declarationLine": "public function typesProvider()", - "documentation": null + "documentation": null, + "signatureInformation": { + "label": "()", + "documentation": null, + "parameters": [] + } } } } \ No newline at end of file diff --git a/tests/Validation/cases/static1.php.expected.json b/tests/Validation/cases/static1.php.expected.json index db1a0d2..c71c7c2 100644 --- a/tests/Validation/cases/static1.php.expected.json +++ b/tests/Validation/cases/static1.php.expected.json @@ -28,7 +28,8 @@ }, "type": null, "declarationLine": "namespace MyNamespace;", - "documentation": null + "documentation": null, + "signatureInformation": null }, "MyNamespace\\B": { "fqn": "MyNamespace\\B", @@ -47,7 +48,8 @@ }, "type": null, "declarationLine": "class B {", - "documentation": null + "documentation": null, + "signatureInformation": null }, "MyNamespace\\B->b()": { "fqn": "MyNamespace\\B->b()", @@ -67,7 +69,12 @@ "type__tostring": "mixed", "type": {}, "declarationLine": "function b() {", - "documentation": null + "documentation": null, + "signatureInformation": { + "label": "()", + "documentation": null, + "parameters": [] + } }, "MyNamespace\\A": { "fqn": "MyNamespace\\A", @@ -88,7 +95,8 @@ }, "type": null, "declarationLine": "class A extends B {", - "documentation": null + "documentation": null, + "signatureInformation": null }, "MyNamespace\\A->a()": { "fqn": "MyNamespace\\A->a()", @@ -108,7 +116,12 @@ "type__tostring": "mixed", "type": {}, "declarationLine": "function a () {", - "documentation": null + "documentation": null, + "signatureInformation": { + "label": "()", + "documentation": null, + "parameters": [] + } } } } \ No newline at end of file diff --git a/tests/Validation/cases/static2.php.expected.json b/tests/Validation/cases/static2.php.expected.json index bb662cb..5b5a706 100644 --- a/tests/Validation/cases/static2.php.expected.json +++ b/tests/Validation/cases/static2.php.expected.json @@ -28,7 +28,8 @@ }, "type": null, "declarationLine": "namespace MyNamespace;", - "documentation": null + "documentation": null, + "signatureInformation": null }, "MyNamespace\\B": { "fqn": "MyNamespace\\B", @@ -47,7 +48,8 @@ }, "type": null, "declarationLine": "class B {", - "documentation": null + "documentation": null, + "signatureInformation": null }, "MyNamespace\\B->b()": { "fqn": "MyNamespace\\B->b()", @@ -67,7 +69,12 @@ "type__tostring": "mixed", "type": {}, "declarationLine": "function b() {", - "documentation": null + "documentation": null, + "signatureInformation": { + "label": "()", + "documentation": null, + "parameters": [] + } }, "MyNamespace\\A": { "fqn": "MyNamespace\\A", @@ -88,7 +95,8 @@ }, "type": null, "declarationLine": "class A extends B {", - "documentation": null + "documentation": null, + "signatureInformation": null }, "MyNamespace\\A->a()": { "fqn": "MyNamespace\\A->a()", @@ -108,7 +116,12 @@ "type__tostring": "mixed", "type": {}, "declarationLine": "function a () {", - "documentation": null + "documentation": null, + "signatureInformation": { + "label": "()", + "documentation": null, + "parameters": [] + } } } } \ No newline at end of file diff --git a/tests/Validation/cases/static3.php.expected.json b/tests/Validation/cases/static3.php.expected.json index 34d3851..a88f554 100644 --- a/tests/Validation/cases/static3.php.expected.json +++ b/tests/Validation/cases/static3.php.expected.json @@ -28,7 +28,8 @@ }, "type": null, "declarationLine": "namespace MyNamespace;", - "documentation": null + "documentation": null, + "signatureInformation": null }, "MyNamespace\\B": { "fqn": "MyNamespace\\B", @@ -47,7 +48,8 @@ }, "type": null, "declarationLine": "class B {", - "documentation": null + "documentation": null, + "signatureInformation": null }, "MyNamespace\\B->b()": { "fqn": "MyNamespace\\B->b()", @@ -67,7 +69,12 @@ "type__tostring": "mixed", "type": {}, "declarationLine": "function b() {", - "documentation": null + "documentation": null, + "signatureInformation": { + "label": "()", + "documentation": null, + "parameters": [] + } }, "MyNamespace\\A": { "fqn": "MyNamespace\\A", @@ -88,7 +95,8 @@ }, "type": null, "declarationLine": "class A extends B {", - "documentation": null + "documentation": null, + "signatureInformation": null }, "MyNamespace\\A->a()": { "fqn": "MyNamespace\\A->a()", @@ -108,7 +116,12 @@ "type__tostring": "mixed", "type": {}, "declarationLine": "function a () {", - "documentation": null + "documentation": null, + "signatureInformation": { + "label": "()", + "documentation": null, + "parameters": [] + } } } } \ No newline at end of file diff --git a/tests/Validation/cases/static4.php.expected.json b/tests/Validation/cases/static4.php.expected.json index de71d41..adc75a9 100644 --- a/tests/Validation/cases/static4.php.expected.json +++ b/tests/Validation/cases/static4.php.expected.json @@ -25,7 +25,8 @@ }, "type": null, "declarationLine": "namespace MyNamespace;", - "documentation": null + "documentation": null, + "signatureInformation": null }, "MyNamespace\\A": { "fqn": "MyNamespace\\A", @@ -46,7 +47,8 @@ }, "type": null, "declarationLine": "class A extends B {", - "documentation": null + "documentation": null, + "signatureInformation": null }, "MyNamespace\\A->a()": { "fqn": "MyNamespace\\A->a()", @@ -66,7 +68,12 @@ "type__tostring": "mixed", "type": {}, "declarationLine": "function a () {", - "documentation": null + "documentation": null, + "signatureInformation": { + "label": "()", + "documentation": null, + "parameters": [] + } } } } \ No newline at end of file diff --git a/tests/Validation/cases/staticMethodReturnType.php b/tests/Validation/cases/staticMethodReturnType.php index 325738a..0ce2654 100644 --- a/tests/Validation/cases/staticMethodReturnType.php +++ b/tests/Validation/cases/staticMethodReturnType.php @@ -5,5 +5,7 @@ class FooClass { return new FooClass(); } + public static function staticSelf(): self { } + public function bar() { } } diff --git a/tests/Validation/cases/staticMethodReturnType.php.expected.json b/tests/Validation/cases/staticMethodReturnType.php.expected.json index e6661ec..041042a 100644 --- a/tests/Validation/cases/staticMethodReturnType.php.expected.json +++ b/tests/Validation/cases/staticMethodReturnType.php.expected.json @@ -22,7 +22,8 @@ }, "type": null, "declarationLine": "class FooClass {", - "documentation": null + "documentation": null, + "signatureInformation": null }, "FooClass::staticFoo()": { "fqn": "FooClass::staticFoo()", @@ -42,7 +43,37 @@ "type__tostring": "\\FooClass", "type": {}, "declarationLine": "public static function staticFoo(): FooClass {", - "documentation": null + "documentation": null, + "signatureInformation": { + "label": "()", + "documentation": null, + "parameters": [] + } + }, + "FooClass::staticSelf()": { + "fqn": "FooClass::staticSelf()", + "extends": [], + "isMember": true, + "roamed": false, + "isStatic": true, + "canBeInstantiated": false, + "symbolInformation": { + "name": "staticSelf", + "kind": 6, + "location": { + "uri": "./staticMethodReturnType.php" + }, + "containerName": "FooClass" + }, + "type__tostring": "\\FooClass", + "type": {}, + "declarationLine": "public static function staticSelf(): self { }", + "documentation": null, + "signatureInformation": { + "label": "()", + "documentation": null, + "parameters": [] + } }, "FooClass->bar()": { "fqn": "FooClass->bar()", @@ -62,7 +93,12 @@ "type__tostring": "mixed", "type": {}, "declarationLine": "public function bar() { }", - "documentation": null + "documentation": null, + "signatureInformation": { + "label": "()", + "documentation": null, + "parameters": [] + } } } } \ No newline at end of file diff --git a/tests/Validation/cases/stringVariable.php.expected.json b/tests/Validation/cases/stringVariable.php.expected.json index 1d4c7e3..6372c89 100644 --- a/tests/Validation/cases/stringVariable.php.expected.json +++ b/tests/Validation/cases/stringVariable.php.expected.json @@ -22,7 +22,8 @@ }, "type": null, "declarationLine": "class B", - "documentation": null + "documentation": null, + "signatureInformation": null }, "B->hi": { "fqn": "B->hi", @@ -42,7 +43,8 @@ "type__tostring": "int", "type": {}, "declarationLine": "public $hi;", - "documentation": null + "documentation": null, + "signatureInformation": null }, "B->a()": { "fqn": "B->a()", @@ -62,7 +64,12 @@ "type__tostring": "mixed", "type": {}, "declarationLine": "function a () {", - "documentation": null + "documentation": null, + "signatureInformation": { + "label": "()", + "documentation": null, + "parameters": [] + } } } } \ No newline at end of file diff --git a/tests/Validation/cases/testQualifiedNameOutsideOfNamespace.php.expected.json b/tests/Validation/cases/testQualifiedNameOutsideOfNamespace.php.expected.json index 509907c..7966afb 100644 --- a/tests/Validation/cases/testQualifiedNameOutsideOfNamespace.php.expected.json +++ b/tests/Validation/cases/testQualifiedNameOutsideOfNamespace.php.expected.json @@ -22,7 +22,8 @@ }, "type": null, "declarationLine": "namespace SomeNamespace { }", - "documentation": null + "documentation": null, + "signatureInformation": null } } } \ No newline at end of file diff --git a/tests/Validation/cases/verifyFqsenOnClassProperty.php.expected.json b/tests/Validation/cases/verifyFqsenOnClassProperty.php.expected.json index 662a7ed..a434cf2 100644 --- a/tests/Validation/cases/verifyFqsenOnClassProperty.php.expected.json +++ b/tests/Validation/cases/verifyFqsenOnClassProperty.php.expected.json @@ -25,7 +25,8 @@ }, "type": null, "declarationLine": "class Foo {", - "documentation": null + "documentation": null, + "signatureInformation": null }, "Foo->bar": { "fqn": "Foo->bar", @@ -45,7 +46,8 @@ "type__tostring": "\\", "type": {}, "declarationLine": "protected $bar;", - "documentation": null + "documentation": null, + "signatureInformation": null }, "Foo->foo()": { "fqn": "Foo->foo()", @@ -65,7 +67,12 @@ "type__tostring": "mixed", "type": {}, "declarationLine": "public function foo () {", - "documentation": null + "documentation": null, + "signatureInformation": { + "label": "()", + "documentation": null, + "parameters": [] + } } } } \ No newline at end of file