From 42d0c7b714f91d272207380737eb075ee2d46b8a Mon Sep 17 00:00:00 2001 From: Jens Hausdorf Date: Fri, 9 Jun 2017 22:12:32 +0200 Subject: [PATCH 01/14] Improve handling of abstract classes (#391) --- src/DefinitionResolver.php | 8 ++++++-- src/LanguageServer.php | 4 ++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/DefinitionResolver.php b/src/DefinitionResolver.php index 0570ed1..cf2f8a6 100644 --- a/src/DefinitionResolver.php +++ b/src/DefinitionResolver.php @@ -114,7 +114,7 @@ class DefinitionResolver // For everything else, get the doc block summary corresponding to the current node. $docBlock = $this->getDocBlock($node); if ($docBlock !== null) { - // check wether we have a description, when true, add a new paragraph + // check whether we have a description, when true, add a new paragraph // with the description $description = $docBlock->getDescription()->render(); @@ -174,7 +174,11 @@ class DefinitionResolver $def->fqn = $fqn; // Determines whether the suggestion will show after "new" - $def->canBeInstantiated = $node instanceof Node\Statement\ClassDeclaration; + $def->canBeInstantiated = ( + $node instanceof Node\Statement\ClassDeclaration && + // check whether it is not an abstract class + ($node->abstractOrFinalModifier === null || $node->abstractOrFinalModifier->kind !== PhpParser\TokenKind::AbstractKeyword) + ); // Interfaces, classes, traits, namespaces, functions, and global const elements $def->isGlobal = ( diff --git a/src/LanguageServer.php b/src/LanguageServer.php index 173abfe..118dd93 100644 --- a/src/LanguageServer.php +++ b/src/LanguageServer.php @@ -106,7 +106,7 @@ class LanguageServer extends AdvancedJsonRpc\Dispatcher protected $definitionResolver; /** - * @param PotocolReader $reader + * @param ProtocolReader $reader * @param ProtocolWriter $writer */ public function __construct(ProtocolReader $reader, ProtocolWriter $writer) @@ -132,7 +132,7 @@ class LanguageServer extends AdvancedJsonRpc\Dispatcher // If a ResponseError is thrown, send it back in the Response $error = $e; } catch (Throwable $e) { - // If an unexpected error occured, send back an INTERNAL_ERROR error response + // If an unexpected error occurred, send back an INTERNAL_ERROR error response $error = new AdvancedJsonRpc\Error( (string)$e, AdvancedJsonRpc\ErrorCode::INTERNAL_ERROR, From 7b72b38fd9533b3daedd5af17eeab3a6b14a3e5e Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Sat, 10 Jun 2017 01:55:41 -0700 Subject: [PATCH 02/14] Assert that references array is equal, not a subset, and update expected.json files (#395) --- tests/Validation/ValidationTest.php | 7 +------ .../cases/WithReturnTypehints.php.expected.json | 6 ++++++ tests/Validation/cases/exceptions1.php.expected.json | 6 +++++- tests/Validation/cases/functionUse2.php.expected.json | 3 +++ .../cases/magicConstantsShouldBeGlobal.php.expected.json | 9 ++++++++- tests/Validation/cases/magicConsts.php.expected.json | 6 +++++- tests/Validation/cases/memberAccess5.php.expected.json | 6 +++++- tests/Validation/cases/namespaces8.php.expected.json | 6 ++++++ tests/Validation/cases/self4.php.expected.json | 6 ++++++ 9 files changed, 45 insertions(+), 10 deletions(-) diff --git a/tests/Validation/ValidationTest.php b/tests/Validation/ValidationTest.php index 649e947..8fa7442 100644 --- a/tests/Validation/ValidationTest.php +++ b/tests/Validation/ValidationTest.php @@ -64,12 +64,7 @@ class ValidationTest extends TestCase try { $this->assertEquals($expectedValues['definitions'], $actualValues['definitions']); - - try { - $this->assertArraySubset((array)$expectedValues['references'], (array)$actualValues['references'], false, 'references don\'t match.'); - } catch (\Throwable $e) { - $this->assertEquals((array)$expectedValues['references'], (array)$actualValues['references'], 'references don\'t match.'); - } + $this->assertEquals((array)$expectedValues['references'], (array)$actualValues['references'], 'references don\'t match.'); } catch (\Throwable $e) { $outputFile = getExpectedValuesFile($testCaseFile); file_put_contents($outputFile, json_encode($actualValues, JSON_PRETTY_PRINT|JSON_UNESCAPED_SLASHES)); diff --git a/tests/Validation/cases/WithReturnTypehints.php.expected.json b/tests/Validation/cases/WithReturnTypehints.php.expected.json index 50801d9..166786a 100644 --- a/tests/Validation/cases/WithReturnTypehints.php.expected.json +++ b/tests/Validation/cases/WithReturnTypehints.php.expected.json @@ -6,6 +6,12 @@ "self": [ "./WithReturnTypehints.php" ], + "Fixtures\\Prophecy\\__CLASS__": [ + "./WithReturnTypehints.php" + ], + "__CLASS__": [ + "./WithReturnTypehints.php" + ], "parent": [ "./WithReturnTypehints.php" ] diff --git a/tests/Validation/cases/exceptions1.php.expected.json b/tests/Validation/cases/exceptions1.php.expected.json index d74deff..4a13354 100644 --- a/tests/Validation/cases/exceptions1.php.expected.json +++ b/tests/Validation/cases/exceptions1.php.expected.json @@ -1,5 +1,9 @@ { - "references": [], + "references": { + "MyNamespace\\Exception": [ + "./exceptions1.php" + ] + }, "definitions": { "MyNamespace": { "fqn": "MyNamespace", diff --git a/tests/Validation/cases/functionUse2.php.expected.json b/tests/Validation/cases/functionUse2.php.expected.json index f3609bd..320cc41 100644 --- a/tests/Validation/cases/functionUse2.php.expected.json +++ b/tests/Validation/cases/functionUse2.php.expected.json @@ -3,6 +3,9 @@ "LanguageServer": [ "./functionUse2.php" ], + "LanguageServer\\pathToUri()": [ + "./functionUse2.php" + ], "LanguageServer\\timeout()": [ "./functionUse2.php" ] diff --git a/tests/Validation/cases/magicConstantsShouldBeGlobal.php.expected.json b/tests/Validation/cases/magicConstantsShouldBeGlobal.php.expected.json index 36a2942..b61333f 100644 --- a/tests/Validation/cases/magicConstantsShouldBeGlobal.php.expected.json +++ b/tests/Validation/cases/magicConstantsShouldBeGlobal.php.expected.json @@ -1,5 +1,12 @@ { - "references": [], + "references": { + "B\\__FILE__": [ + "./magicConstantsShouldBeGlobal.php" + ], + "__FILE__": [ + "./magicConstantsShouldBeGlobal.php" + ] + }, "definitions": { "B": { "fqn": "B", diff --git a/tests/Validation/cases/magicConsts.php.expected.json b/tests/Validation/cases/magicConsts.php.expected.json index c017d49..6641af3 100644 --- a/tests/Validation/cases/magicConsts.php.expected.json +++ b/tests/Validation/cases/magicConsts.php.expected.json @@ -1,5 +1,9 @@ { - "references": [], + "references": { + "__CLASS__": [ + "./magicConsts.php" + ] + }, "definitions": { "A": { "fqn": "A", diff --git a/tests/Validation/cases/memberAccess5.php.expected.json b/tests/Validation/cases/memberAccess5.php.expected.json index ae2b4ac..5023cd6 100644 --- a/tests/Validation/cases/memberAccess5.php.expected.json +++ b/tests/Validation/cases/memberAccess5.php.expected.json @@ -1,5 +1,9 @@ { - "references": [], + "references": { + "MyNamespace\\ParseErrorsTest->args": [ + "./memberAccess5.php" + ] + }, "definitions": { "MyNamespace": { "fqn": "MyNamespace", diff --git a/tests/Validation/cases/namespaces8.php.expected.json b/tests/Validation/cases/namespaces8.php.expected.json index 2fbd1fb..7a77f7c 100644 --- a/tests/Validation/cases/namespaces8.php.expected.json +++ b/tests/Validation/cases/namespaces8.php.expected.json @@ -2,6 +2,12 @@ "references": { "LanguageServer": [ "./namespaces8.php" + ], + "LanguageServer\\pathToUri()": [ + "./namespaces8.php" + ], + "LanguageServer\\uriToPath()": [ + "./namespaces8.php" ] }, "definitions": { diff --git a/tests/Validation/cases/self4.php.expected.json b/tests/Validation/cases/self4.php.expected.json index 5fac53f..9a01912 100644 --- a/tests/Validation/cases/self4.php.expected.json +++ b/tests/Validation/cases/self4.php.expected.json @@ -6,6 +6,12 @@ "MyNamespace\\A->addTestFile()": [ "./self4.php" ], + "MyNamespace\\__DIR__": [ + "./self4.php" + ], + "__DIR__": [ + "./self4.php" + ], "MyNamespace\\DS": [ "./self4.php" ], From f10680e4419758e8986393c57cc78a7d9f2cbbbe Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Sat, 10 Jun 2017 02:10:15 -0700 Subject: [PATCH 03/14] Fix variable type from method return value, add tests (#393) --- fixtures/completion/method_return_type.php | 11 ++++ .../completion/static_method_return_type.php | 12 ++++ src/DefinitionResolver.php | 10 +++ tests/LanguageServerTest.php | 4 +- tests/Server/TextDocument/CompletionTest.php | 44 +++++++++++++ tests/Validation/ValidationTest.php | 3 +- .../WithReturnTypehints.php.expected.json | 6 +- ...rrayValueShouldBeBoolean.php.expected.json | 2 +- .../cases/classDefinition1.php.expected.json | 2 +- .../cases/classProperty1.php.expected.json | 4 +- .../cases/constants.php.expected.json | 2 +- .../cases/constants2.php.expected.json | 2 +- .../cases/constants3.php.expected.json | 2 +- .../cases/constants4.php.expected.json | 2 +- .../cases/constants5.php.expected.json | 2 +- ...tsInFunctionParamDefault.php.expected.json | 2 +- .../cases/magicConsts.php.expected.json | 2 +- .../cases/memberAccess1.php.expected.json | 2 +- .../cases/memberAccess2.php.expected.json | 2 +- .../cases/memberAccess3.php.expected.json | 2 +- .../cases/memberAccess4.php.expected.json | 2 +- .../cases/memberAccess5.php.expected.json | 2 +- .../cases/memberCall1.php.expected.json | 2 +- tests/Validation/cases/methodReturnType.php | 7 ++ .../cases/methodReturnType.php.expected.json | 46 +++++++++++++ .../multipleNamespaces.php.expected.json | 4 +- ...ltiplePreceedingComments.php.expected.json | 2 +- .../cases/nameToken.php.expected.json | 2 +- .../cases/objectCreation.php.expected.json | 2 +- .../cases/objectCreation2.php.expected.json | 2 +- .../cases/objectCreation3.php.expected.json | 2 +- .../Validation/cases/param1.php.expected.json | 2 +- .../cases/parent1.php.expected.json | 4 +- .../cases/parent3.php.expected.json | 4 +- .../cases/propertyName1.php.expected.json | 2 +- .../cases/propertyName2.php.expected.json | 2 +- .../cases/returnType.php.expected.json | 2 +- .../scopedPropertyAccess.php.expected.json | 2 +- .../scopedPropertyAccess3.php.expected.json | 2 +- .../scopedPropertyAccess5.php.expected.json | 2 +- .../Validation/cases/self1.php.expected.json | 4 +- .../Validation/cases/self2.php.expected.json | 4 +- .../Validation/cases/self3.php.expected.json | 4 +- .../Validation/cases/self4.php.expected.json | 2 +- .../Validation/cases/self5.php.expected.json | 2 +- .../cases/static1.php.expected.json | 4 +- .../cases/static2.php.expected.json | 4 +- .../cases/static3.php.expected.json | 4 +- .../cases/static4.php.expected.json | 2 +- .../cases/staticMethodReturnType.php | 9 +++ .../staticMethodReturnType.php.expected.json | 65 +++++++++++++++++++ .../cases/stringVariable.php.expected.json | 4 +- ...rifyFqsenOnClassProperty.php.expected.json | 4 +- 53 files changed, 264 insertions(+), 61 deletions(-) create mode 100644 fixtures/completion/method_return_type.php create mode 100644 fixtures/completion/static_method_return_type.php create mode 100644 tests/Validation/cases/methodReturnType.php create mode 100644 tests/Validation/cases/methodReturnType.php.expected.json create mode 100644 tests/Validation/cases/staticMethodReturnType.php create mode 100644 tests/Validation/cases/staticMethodReturnType.php.expected.json diff --git a/fixtures/completion/method_return_type.php b/fixtures/completion/method_return_type.php new file mode 100644 index 0000000..b168f65 --- /dev/null +++ b/fixtures/completion/method_return_type.php @@ -0,0 +1,11 @@ +foo(); +$foo-> \ No newline at end of file diff --git a/fixtures/completion/static_method_return_type.php b/fixtures/completion/static_method_return_type.php new file mode 100644 index 0000000..06cafdd --- /dev/null +++ b/fixtures/completion/static_method_return_type.php @@ -0,0 +1,12 @@ + \ No newline at end of file diff --git a/src/DefinitionResolver.php b/src/DefinitionResolver.php index cf2f8a6..32defab 100644 --- a/src/DefinitionResolver.php +++ b/src/DefinitionResolver.php @@ -623,6 +623,16 @@ class DefinitionResolver } } + // MEMBER CALL EXPRESSION/SCOPED PROPERTY CALL EXPRESSION + // The type of the member/scoped property call expression is the type of the method, so resolve the + // type of the callable expression. + if ($expr instanceof Node\Expression\CallExpression && ( + $expr->callableExpression instanceof Node\Expression\MemberAccessExpression || + $expr->callableExpression instanceof Node\Expression\ScopedPropertyAccessExpression) + ) { + return $this->resolveExpressionNodeToType($expr->callableExpression); + } + // MEMBER ACCESS EXPRESSION if ($expr instanceof Node\Expression\MemberAccessExpression) { if ($expr->memberName instanceof Node\Expression) { diff --git a/tests/LanguageServerTest.php b/tests/LanguageServerTest.php index fb52ef6..5d03451 100644 --- a/tests/LanguageServerTest.php +++ b/tests/LanguageServerTest.php @@ -57,7 +57,7 @@ class LanguageServerTest extends TestCase if ($msg->body->method === 'window/logMessage' && $promise->state === Promise::PENDING) { if ($msg->body->params->type === MessageType::ERROR) { $promise->reject(new Exception($msg->body->params->message)); - } else if (strpos($msg->body->params->message, 'All 27 PHP files parsed') !== false) { + } else if (preg_match('/All \d+ PHP files parsed/', $msg->body->params->message)) { $promise->fulfill(); } } @@ -103,7 +103,7 @@ class LanguageServerTest extends TestCase if ($promise->state === Promise::PENDING) { $promise->reject(new Exception($msg->body->params->message)); } - } else if (strpos($msg->body->params->message, 'All 27 PHP files parsed') !== false) { + } else if (preg_match('/All \d+ PHP files parsed/', $msg->body->params->message)) { $promise->fulfill(); } } diff --git a/tests/Server/TextDocument/CompletionTest.php b/tests/Server/TextDocument/CompletionTest.php index 03ba3d8..923acc1 100644 --- a/tests/Server/TextDocument/CompletionTest.php +++ b/tests/Server/TextDocument/CompletionTest.php @@ -499,6 +499,50 @@ class CompletionTest extends TestCase ], true), $items); } + public function testMethodReturnType() + { + $completionUri = pathToUri(__DIR__ . '/../../../fixtures/completion/method_return_type.php'); + $this->loader->open($completionUri, file_get_contents($completionUri)); + $items = $this->textDocument->completion( + new TextDocumentIdentifier($completionUri), + new Position(10, 6) + )->wait(); + $this->assertCompletionsListSubset(new CompletionList([ + new CompletionItem( + 'foo', + CompletionItemKind::METHOD, + '\FooClass', + null, + null, + null, + null, + null + ) + ], true), $items); + } + + public function testStaticMethodReturnType() + { + $completionUri = pathToUri(__DIR__ . '/../../../fixtures/completion/static_method_return_type.php'); + $this->loader->open($completionUri, file_get_contents($completionUri)); + $items = $this->textDocument->completion( + new TextDocumentIdentifier($completionUri), + new Position(11, 6) + )->wait(); + $this->assertCompletionsListSubset(new CompletionList([ + new CompletionItem( + 'bar', + CompletionItemKind::METHOD, + 'mixed', + null, + null, + null, + null, + null + ) + ], true), $items); + } + private function assertCompletionsListSubset(CompletionList $subsetList, CompletionList $list) { foreach ($subsetList->items as $expectedItem) { diff --git a/tests/Validation/ValidationTest.php b/tests/Validation/ValidationTest.php index 8fa7442..3fc7429 100644 --- a/tests/Validation/ValidationTest.php +++ b/tests/Validation/ValidationTest.php @@ -132,8 +132,7 @@ class ValidationTest extends TestCase } elseif ($propertyName === 'extends') { $definition->$propertyName = $definition->$propertyName ?? []; } elseif ($propertyName === 'type' && $definition->type !== null) { - // Class info is not captured by json_encode. It's important for 'type'. - $defsForAssert[$fqn]['type__class'] = get_class($definition->type); + $defsForAssert[$fqn]['type__tostring'] = (string)$definition->type; } $defsForAssert[$fqn][$propertyName] = $definition->$propertyName; diff --git a/tests/Validation/cases/WithReturnTypehints.php.expected.json b/tests/Validation/cases/WithReturnTypehints.php.expected.json index 166786a..271c203 100644 --- a/tests/Validation/cases/WithReturnTypehints.php.expected.json +++ b/tests/Validation/cases/WithReturnTypehints.php.expected.json @@ -69,7 +69,7 @@ }, "containerName": "Fixtures\\Prophecy\\WithReturnTypehints" }, - "type__class": "phpDocumentor\\Reflection\\Types\\Object_", + "type__tostring": "\\self", "type": {}, "declarationLine": "public function getSelf(): self {", "documentation": null @@ -88,7 +88,7 @@ }, "containerName": "Fixtures\\Prophecy\\WithReturnTypehints" }, - "type__class": "phpDocumentor\\Reflection\\Types\\String_", + "type__tostring": "string", "type": {}, "declarationLine": "public function getName(): string {", "documentation": null @@ -107,7 +107,7 @@ }, "containerName": "Fixtures\\Prophecy\\WithReturnTypehints" }, - "type__class": "phpDocumentor\\Reflection\\Types\\Object_", + "type__tostring": "\\parent", "type": {}, "declarationLine": "public function getParent(): parent {", "documentation": null diff --git a/tests/Validation/cases/arrayValueShouldBeBoolean.php.expected.json b/tests/Validation/cases/arrayValueShouldBeBoolean.php.expected.json index c9b02d0..1bb66e1 100644 --- a/tests/Validation/cases/arrayValueShouldBeBoolean.php.expected.json +++ b/tests/Validation/cases/arrayValueShouldBeBoolean.php.expected.json @@ -33,7 +33,7 @@ }, "containerName": "A" }, - "type__class": "phpDocumentor\\Reflection\\Types\\Array_", + "type__tostring": "string[]", "type": {}, "declarationLine": "protected $foo;", "documentation": null diff --git a/tests/Validation/cases/classDefinition1.php.expected.json b/tests/Validation/cases/classDefinition1.php.expected.json index aad36bb..5167a4c 100644 --- a/tests/Validation/cases/classDefinition1.php.expected.json +++ b/tests/Validation/cases/classDefinition1.php.expected.json @@ -58,7 +58,7 @@ }, "containerName": "TestNamespace\\A" }, - "type__class": "phpDocumentor\\Reflection\\Types\\Integer", + "type__tostring": "int", "type": {}, "declarationLine": "public $a;", "documentation": null diff --git a/tests/Validation/cases/classProperty1.php.expected.json b/tests/Validation/cases/classProperty1.php.expected.json index 671c019..05d90c1 100644 --- a/tests/Validation/cases/classProperty1.php.expected.json +++ b/tests/Validation/cases/classProperty1.php.expected.json @@ -58,7 +58,7 @@ }, "containerName": "TestNamespace\\TestClass" }, - "type__class": "phpDocumentor\\Reflection\\Types\\Mixed", + "type__tostring": "mixed", "type": {}, "declarationLine": "public $testProperty;", "documentation": null @@ -77,7 +77,7 @@ }, "containerName": "TestNamespace\\TestClass" }, - "type__class": "phpDocumentor\\Reflection\\Types\\Mixed", + "type__tostring": "mixed", "type": {}, "declarationLine": "public function testMethod($testParameter)", "documentation": null diff --git a/tests/Validation/cases/constants.php.expected.json b/tests/Validation/cases/constants.php.expected.json index eef5cdd..ba80e25 100644 --- a/tests/Validation/cases/constants.php.expected.json +++ b/tests/Validation/cases/constants.php.expected.json @@ -58,7 +58,7 @@ }, "containerName": "MyNamespace\\A" }, - "type__class": "phpDocumentor\\Reflection\\Types\\Mixed", + "type__tostring": "mixed", "type": {}, "declarationLine": "public static function suite()", "documentation": null diff --git a/tests/Validation/cases/constants2.php.expected.json b/tests/Validation/cases/constants2.php.expected.json index 6ecb2a6..e08408e 100644 --- a/tests/Validation/cases/constants2.php.expected.json +++ b/tests/Validation/cases/constants2.php.expected.json @@ -58,7 +58,7 @@ }, "containerName": "MyNamespace\\A" }, - "type__class": "phpDocumentor\\Reflection\\Types\\Mixed", + "type__tostring": "mixed", "type": {}, "declarationLine": "public static function suite()", "documentation": null diff --git a/tests/Validation/cases/constants3.php.expected.json b/tests/Validation/cases/constants3.php.expected.json index d49903c..dbbb959 100644 --- a/tests/Validation/cases/constants3.php.expected.json +++ b/tests/Validation/cases/constants3.php.expected.json @@ -58,7 +58,7 @@ }, "containerName": "MyNamespace\\A" }, - "type__class": "phpDocumentor\\Reflection\\Types\\Mixed", + "type__tostring": "mixed", "type": {}, "declarationLine": "public static function suite()", "documentation": null diff --git a/tests/Validation/cases/constants4.php.expected.json b/tests/Validation/cases/constants4.php.expected.json index 2c01864..24523a8 100644 --- a/tests/Validation/cases/constants4.php.expected.json +++ b/tests/Validation/cases/constants4.php.expected.json @@ -58,7 +58,7 @@ }, "containerName": "MyNamespace\\A" }, - "type__class": "phpDocumentor\\Reflection\\Types\\Mixed", + "type__tostring": "mixed", "type": {}, "declarationLine": "public function suite()", "documentation": null diff --git a/tests/Validation/cases/constants5.php.expected.json b/tests/Validation/cases/constants5.php.expected.json index a0876b5..1498165 100644 --- a/tests/Validation/cases/constants5.php.expected.json +++ b/tests/Validation/cases/constants5.php.expected.json @@ -55,7 +55,7 @@ }, "containerName": "MyNamespace\\Mbstring" }, - "type__class": "phpDocumentor\\Reflection\\Types\\Object_", + "type__tostring": "\\MyNamespace\\PHP_INT_MAX", "type": {}, "declarationLine": "const MB_CASE_FOLD = PHP_INT_MAX;", "documentation": null diff --git a/tests/Validation/cases/constantsInFunctionParamDefault.php.expected.json b/tests/Validation/cases/constantsInFunctionParamDefault.php.expected.json index 98aa7cd..3ff0ca1 100644 --- a/tests/Validation/cases/constantsInFunctionParamDefault.php.expected.json +++ b/tests/Validation/cases/constantsInFunctionParamDefault.php.expected.json @@ -37,7 +37,7 @@ }, "containerName": "A" }, - "type__class": "phpDocumentor\\Reflection\\Types\\Mixed", + "type__tostring": "mixed", "type": {}, "declarationLine": "function b ($a = MY_CONSTANT);", "documentation": null diff --git a/tests/Validation/cases/magicConsts.php.expected.json b/tests/Validation/cases/magicConsts.php.expected.json index 6641af3..74cf36b 100644 --- a/tests/Validation/cases/magicConsts.php.expected.json +++ b/tests/Validation/cases/magicConsts.php.expected.json @@ -37,7 +37,7 @@ }, "containerName": "A" }, - "type__class": "phpDocumentor\\Reflection\\Types\\Array_", + "type__tostring": "\\__CLASS__[]", "type": {}, "declarationLine": "private static $deprecationsTriggered;", "documentation": null diff --git a/tests/Validation/cases/memberAccess1.php.expected.json b/tests/Validation/cases/memberAccess1.php.expected.json index ff4868b..efe4d3a 100644 --- a/tests/Validation/cases/memberAccess1.php.expected.json +++ b/tests/Validation/cases/memberAccess1.php.expected.json @@ -58,7 +58,7 @@ }, "containerName": "MyNamespace\\A" }, - "type__class": "phpDocumentor\\Reflection\\Types\\Mixed", + "type__tostring": "mixed", "type": {}, "declarationLine": "static function a() {", "documentation": null diff --git a/tests/Validation/cases/memberAccess2.php.expected.json b/tests/Validation/cases/memberAccess2.php.expected.json index a6707d0..1725a5b 100644 --- a/tests/Validation/cases/memberAccess2.php.expected.json +++ b/tests/Validation/cases/memberAccess2.php.expected.json @@ -58,7 +58,7 @@ }, "containerName": "MyNamespace\\A" }, - "type__class": "phpDocumentor\\Reflection\\Types\\Mixed", + "type__tostring": "mixed", "type": {}, "declarationLine": "static function a() {", "documentation": null diff --git a/tests/Validation/cases/memberAccess3.php.expected.json b/tests/Validation/cases/memberAccess3.php.expected.json index df58d1e..9b1b4ee 100644 --- a/tests/Validation/cases/memberAccess3.php.expected.json +++ b/tests/Validation/cases/memberAccess3.php.expected.json @@ -73,7 +73,7 @@ }, "containerName": "MyNamespace\\A" }, - "type__class": "phpDocumentor\\Reflection\\Types\\Mixed", + "type__tostring": "mixed", "type": {}, "declarationLine": "public static function getInitializer(ClassLoader $loader)", "documentation": null diff --git a/tests/Validation/cases/memberAccess4.php.expected.json b/tests/Validation/cases/memberAccess4.php.expected.json index 1cfabb3..3e26d72 100644 --- a/tests/Validation/cases/memberAccess4.php.expected.json +++ b/tests/Validation/cases/memberAccess4.php.expected.json @@ -64,7 +64,7 @@ }, "containerName": "MyNamespace\\A" }, - "type__class": "phpDocumentor\\Reflection\\Types\\Mixed", + "type__tostring": "mixed", "type": {}, "declarationLine": "public function testRequest()", "documentation": null diff --git a/tests/Validation/cases/memberAccess5.php.expected.json b/tests/Validation/cases/memberAccess5.php.expected.json index 5023cd6..c7158b6 100644 --- a/tests/Validation/cases/memberAccess5.php.expected.json +++ b/tests/Validation/cases/memberAccess5.php.expected.json @@ -55,7 +55,7 @@ }, "containerName": "MyNamespace\\ParseErrorsTest" }, - "type__class": "phpDocumentor\\Reflection\\Types\\Mixed", + "type__tostring": "mixed", "type": {}, "declarationLine": "public function setUp()", "documentation": null diff --git a/tests/Validation/cases/memberCall1.php.expected.json b/tests/Validation/cases/memberCall1.php.expected.json index 4cf2cd8..bd31b2f 100644 --- a/tests/Validation/cases/memberCall1.php.expected.json +++ b/tests/Validation/cases/memberCall1.php.expected.json @@ -61,7 +61,7 @@ }, "containerName": "MyNamespace\\ParseErrorsTest" }, - "type__class": "phpDocumentor\\Reflection\\Types\\Mixed", + "type__tostring": "mixed", "type": {}, "declarationLine": "public function setAccount(AccountInterface $account)", "documentation": null diff --git a/tests/Validation/cases/methodReturnType.php b/tests/Validation/cases/methodReturnType.php new file mode 100644 index 0000000..b4b937d --- /dev/null +++ b/tests/Validation/cases/methodReturnType.php @@ -0,0 +1,7 @@ +foo()": { + "fqn": "FooClass->foo()", + "extends": [], + "isGlobal": false, + "isStatic": false, + "canBeInstantiated": false, + "symbolInformation": { + "name": "foo", + "kind": 6, + "location": { + "uri": "./methodReturnType.php" + }, + "containerName": "FooClass" + }, + "type__tostring": "\\FooClass", + "type": {}, + "declarationLine": "public function foo(): FooClass {", + "documentation": null + } + } +} \ 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 2ed59de..3533e8c 100644 --- a/tests/Validation/cases/multipleNamespaces.php.expected.json +++ b/tests/Validation/cases/multipleNamespaces.php.expected.json @@ -64,7 +64,7 @@ }, "containerName": "MyNamespace1\\B" }, - "type__class": "phpDocumentor\\Reflection\\Types\\Mixed", + "type__tostring": "mixed", "type": {}, "declarationLine": "function b() {", "documentation": null @@ -121,7 +121,7 @@ }, "containerName": "MyNamespace2\\A" }, - "type__class": "phpDocumentor\\Reflection\\Types\\Mixed", + "type__tostring": "mixed", "type": {}, "declarationLine": "function a () {", "documentation": null diff --git a/tests/Validation/cases/multiplePreceedingComments.php.expected.json b/tests/Validation/cases/multiplePreceedingComments.php.expected.json index ca97671..c331b5e 100644 --- a/tests/Validation/cases/multiplePreceedingComments.php.expected.json +++ b/tests/Validation/cases/multiplePreceedingComments.php.expected.json @@ -33,7 +33,7 @@ }, "containerName": "Foo" }, - "type__class": "phpDocumentor\\Reflection\\Types\\Object_", + "type__tostring": "\\Iterator", "type": {}, "declarationLine": "public function fn()", "documentation": "Foo" diff --git a/tests/Validation/cases/nameToken.php.expected.json b/tests/Validation/cases/nameToken.php.expected.json index 1bd944d..af73f78 100644 --- a/tests/Validation/cases/nameToken.php.expected.json +++ b/tests/Validation/cases/nameToken.php.expected.json @@ -33,7 +33,7 @@ }, "containerName": "A" }, - "type__class": "phpDocumentor\\Reflection\\Types\\Mixed", + "type__tostring": "mixed", "type": {}, "declarationLine": "function b() {", "documentation": null diff --git a/tests/Validation/cases/objectCreation.php.expected.json b/tests/Validation/cases/objectCreation.php.expected.json index cea0343..a0e8f72 100644 --- a/tests/Validation/cases/objectCreation.php.expected.json +++ b/tests/Validation/cases/objectCreation.php.expected.json @@ -55,7 +55,7 @@ }, "containerName": "MyNamespace\\A" }, - "type__class": "phpDocumentor\\Reflection\\Types\\Mixed", + "type__tostring": "mixed", "type": {}, "declarationLine": "function a () {", "documentation": null diff --git a/tests/Validation/cases/objectCreation2.php.expected.json b/tests/Validation/cases/objectCreation2.php.expected.json index 7f856b1..0119bf7 100644 --- a/tests/Validation/cases/objectCreation2.php.expected.json +++ b/tests/Validation/cases/objectCreation2.php.expected.json @@ -76,7 +76,7 @@ }, "containerName": "MyNamespace\\A" }, - "type__class": "phpDocumentor\\Reflection\\Types\\Mixed", + "type__tostring": "mixed", "type": {}, "declarationLine": "function a () {", "documentation": null diff --git a/tests/Validation/cases/objectCreation3.php.expected.json b/tests/Validation/cases/objectCreation3.php.expected.json index c6dcab9..75cc011 100644 --- a/tests/Validation/cases/objectCreation3.php.expected.json +++ b/tests/Validation/cases/objectCreation3.php.expected.json @@ -37,7 +37,7 @@ }, "containerName": "A" }, - "type__class": "phpDocumentor\\Reflection\\Types\\Mixed", + "type__tostring": "mixed", "type": {}, "declarationLine": "function a () {", "documentation": null diff --git a/tests/Validation/cases/param1.php.expected.json b/tests/Validation/cases/param1.php.expected.json index adbe002..ee952f3 100644 --- a/tests/Validation/cases/param1.php.expected.json +++ b/tests/Validation/cases/param1.php.expected.json @@ -37,7 +37,7 @@ }, "containerName": "MyNamespace" }, - "type__class": "phpDocumentor\\Reflection\\Types\\Mixed", + "type__tostring": "mixed", "type": {}, "declarationLine": "function init(Hi $view)", "documentation": null diff --git a/tests/Validation/cases/parent1.php.expected.json b/tests/Validation/cases/parent1.php.expected.json index 3391cd4..961b35b 100644 --- a/tests/Validation/cases/parent1.php.expected.json +++ b/tests/Validation/cases/parent1.php.expected.json @@ -58,7 +58,7 @@ }, "containerName": "MyNamespace\\B" }, - "type__class": "phpDocumentor\\Reflection\\Types\\Mixed", + "type__tostring": "mixed", "type": {}, "declarationLine": "function b() {", "documentation": null @@ -97,7 +97,7 @@ }, "containerName": "MyNamespace\\A" }, - "type__class": "phpDocumentor\\Reflection\\Types\\Mixed", + "type__tostring": "mixed", "type": {}, "declarationLine": "function a () {", "documentation": null diff --git a/tests/Validation/cases/parent3.php.expected.json b/tests/Validation/cases/parent3.php.expected.json index 2c4915d..e2cf2c6 100644 --- a/tests/Validation/cases/parent3.php.expected.json +++ b/tests/Validation/cases/parent3.php.expected.json @@ -61,7 +61,7 @@ }, "containerName": "MyNamespace\\B" }, - "type__class": "phpDocumentor\\Reflection\\Types\\Mixed", + "type__tostring": "mixed", "type": {}, "declarationLine": "function b() {", "documentation": null @@ -100,7 +100,7 @@ }, "containerName": "MyNamespace\\A" }, - "type__class": "phpDocumentor\\Reflection\\Types\\Mixed", + "type__tostring": "mixed", "type": {}, "declarationLine": "function a () {", "documentation": null diff --git a/tests/Validation/cases/propertyName1.php.expected.json b/tests/Validation/cases/propertyName1.php.expected.json index 8032ecc..0a37c20 100644 --- a/tests/Validation/cases/propertyName1.php.expected.json +++ b/tests/Validation/cases/propertyName1.php.expected.json @@ -33,7 +33,7 @@ }, "containerName": "MyClass" }, - "type__class": "phpDocumentor\\Reflection\\Types\\String_", + "type__tostring": "string", "type": {}, "declarationLine": "protected $mainPropertyName;", "documentation": "The name of the main property, or NULL if there is none." diff --git a/tests/Validation/cases/propertyName2.php.expected.json b/tests/Validation/cases/propertyName2.php.expected.json index a70c515..9cba945 100644 --- a/tests/Validation/cases/propertyName2.php.expected.json +++ b/tests/Validation/cases/propertyName2.php.expected.json @@ -33,7 +33,7 @@ }, "containerName": "MyClass" }, - "type__class": "phpDocumentor\\Reflection\\Types\\String_", + "type__tostring": "string", "type": {}, "declarationLine": "protected $mainPropertyName;", "documentation": "The name of the main property, or NULL if there is none." diff --git a/tests/Validation/cases/returnType.php.expected.json b/tests/Validation/cases/returnType.php.expected.json index 9515a6b..6ddca7e 100644 --- a/tests/Validation/cases/returnType.php.expected.json +++ b/tests/Validation/cases/returnType.php.expected.json @@ -40,7 +40,7 @@ }, "containerName": "TestNamespace" }, - "type__class": "phpDocumentor\\Reflection\\Types\\Object_", + "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." diff --git a/tests/Validation/cases/scopedPropertyAccess.php.expected.json b/tests/Validation/cases/scopedPropertyAccess.php.expected.json index 6797a0e..3eeda77 100644 --- a/tests/Validation/cases/scopedPropertyAccess.php.expected.json +++ b/tests/Validation/cases/scopedPropertyAccess.php.expected.json @@ -58,7 +58,7 @@ }, "containerName": "MyNamespace\\A" }, - "type__class": "phpDocumentor\\Reflection\\Types\\Mixed", + "type__tostring": "mixed", "type": {}, "declarationLine": "static function a() {", "documentation": null diff --git a/tests/Validation/cases/scopedPropertyAccess3.php.expected.json b/tests/Validation/cases/scopedPropertyAccess3.php.expected.json index d29387a..81cbfb6 100644 --- a/tests/Validation/cases/scopedPropertyAccess3.php.expected.json +++ b/tests/Validation/cases/scopedPropertyAccess3.php.expected.json @@ -40,7 +40,7 @@ }, "containerName": "A" }, - "type__class": "phpDocumentor\\Reflection\\Types\\String_", + "type__tostring": "string", "type": {}, "declarationLine": "static $a;", "documentation": null diff --git a/tests/Validation/cases/scopedPropertyAccess5.php.expected.json b/tests/Validation/cases/scopedPropertyAccess5.php.expected.json index ab1e214..27f0509 100644 --- a/tests/Validation/cases/scopedPropertyAccess5.php.expected.json +++ b/tests/Validation/cases/scopedPropertyAccess5.php.expected.json @@ -46,7 +46,7 @@ }, "containerName": "TestClass" }, - "type__class": "phpDocumentor\\Reflection\\Types\\Array_", + "type__tostring": "\\TestClass[]", "type": {}, "declarationLine": "public static $testProperty;", "documentation": "Lorem excepteur officia sit anim velit veniam enim." diff --git a/tests/Validation/cases/self1.php.expected.json b/tests/Validation/cases/self1.php.expected.json index 6531b53..41525d8 100644 --- a/tests/Validation/cases/self1.php.expected.json +++ b/tests/Validation/cases/self1.php.expected.json @@ -61,7 +61,7 @@ }, "containerName": "MyNamespace\\B" }, - "type__class": "phpDocumentor\\Reflection\\Types\\Mixed", + "type__tostring": "mixed", "type": {}, "declarationLine": "function b() {", "documentation": null @@ -100,7 +100,7 @@ }, "containerName": "MyNamespace\\A" }, - "type__class": "phpDocumentor\\Reflection\\Types\\Mixed", + "type__tostring": "mixed", "type": {}, "declarationLine": "function a () {", "documentation": null diff --git a/tests/Validation/cases/self2.php.expected.json b/tests/Validation/cases/self2.php.expected.json index 8300de2..eb31aba 100644 --- a/tests/Validation/cases/self2.php.expected.json +++ b/tests/Validation/cases/self2.php.expected.json @@ -61,7 +61,7 @@ }, "containerName": "MyNamespace\\B" }, - "type__class": "phpDocumentor\\Reflection\\Types\\Mixed", + "type__tostring": "mixed", "type": {}, "declarationLine": "function b() {", "documentation": null @@ -100,7 +100,7 @@ }, "containerName": "MyNamespace\\A" }, - "type__class": "phpDocumentor\\Reflection\\Types\\Mixed", + "type__tostring": "mixed", "type": {}, "declarationLine": "function a () {", "documentation": null diff --git a/tests/Validation/cases/self3.php.expected.json b/tests/Validation/cases/self3.php.expected.json index 3d5d4ad..f50b80c 100644 --- a/tests/Validation/cases/self3.php.expected.json +++ b/tests/Validation/cases/self3.php.expected.json @@ -61,7 +61,7 @@ }, "containerName": "MyNamespace\\B" }, - "type__class": "phpDocumentor\\Reflection\\Types\\Mixed", + "type__tostring": "mixed", "type": {}, "declarationLine": "function b() {", "documentation": null @@ -100,7 +100,7 @@ }, "containerName": "MyNamespace\\A" }, - "type__class": "phpDocumentor\\Reflection\\Types\\Mixed", + "type__tostring": "mixed", "type": {}, "declarationLine": "function a () {", "documentation": null diff --git a/tests/Validation/cases/self4.php.expected.json b/tests/Validation/cases/self4.php.expected.json index 9a01912..4946001 100644 --- a/tests/Validation/cases/self4.php.expected.json +++ b/tests/Validation/cases/self4.php.expected.json @@ -70,7 +70,7 @@ }, "containerName": "MyNamespace\\A" }, - "type__class": "phpDocumentor\\Reflection\\Types\\Mixed", + "type__tostring": "mixed", "type": {}, "declarationLine": "public static function suite()", "documentation": null diff --git a/tests/Validation/cases/self5.php.expected.json b/tests/Validation/cases/self5.php.expected.json index 781cd24..e1c99af 100644 --- a/tests/Validation/cases/self5.php.expected.json +++ b/tests/Validation/cases/self5.php.expected.json @@ -55,7 +55,7 @@ }, "containerName": "MyNamespace\\A" }, - "type__class": "phpDocumentor\\Reflection\\Types\\Mixed", + "type__tostring": "mixed", "type": {}, "declarationLine": "public function typesProvider()", "documentation": null diff --git a/tests/Validation/cases/static1.php.expected.json b/tests/Validation/cases/static1.php.expected.json index b0323b2..ca49245 100644 --- a/tests/Validation/cases/static1.php.expected.json +++ b/tests/Validation/cases/static1.php.expected.json @@ -61,7 +61,7 @@ }, "containerName": "MyNamespace\\B" }, - "type__class": "phpDocumentor\\Reflection\\Types\\Mixed", + "type__tostring": "mixed", "type": {}, "declarationLine": "function b() {", "documentation": null @@ -100,7 +100,7 @@ }, "containerName": "MyNamespace\\A" }, - "type__class": "phpDocumentor\\Reflection\\Types\\Mixed", + "type__tostring": "mixed", "type": {}, "declarationLine": "function a () {", "documentation": null diff --git a/tests/Validation/cases/static2.php.expected.json b/tests/Validation/cases/static2.php.expected.json index c8d81fb..06a0627 100644 --- a/tests/Validation/cases/static2.php.expected.json +++ b/tests/Validation/cases/static2.php.expected.json @@ -61,7 +61,7 @@ }, "containerName": "MyNamespace\\B" }, - "type__class": "phpDocumentor\\Reflection\\Types\\Mixed", + "type__tostring": "mixed", "type": {}, "declarationLine": "function b() {", "documentation": null @@ -100,7 +100,7 @@ }, "containerName": "MyNamespace\\A" }, - "type__class": "phpDocumentor\\Reflection\\Types\\Mixed", + "type__tostring": "mixed", "type": {}, "declarationLine": "function a () {", "documentation": null diff --git a/tests/Validation/cases/static3.php.expected.json b/tests/Validation/cases/static3.php.expected.json index bb556bf..745bd56 100644 --- a/tests/Validation/cases/static3.php.expected.json +++ b/tests/Validation/cases/static3.php.expected.json @@ -61,7 +61,7 @@ }, "containerName": "MyNamespace\\B" }, - "type__class": "phpDocumentor\\Reflection\\Types\\Mixed", + "type__tostring": "mixed", "type": {}, "declarationLine": "function b() {", "documentation": null @@ -100,7 +100,7 @@ }, "containerName": "MyNamespace\\A" }, - "type__class": "phpDocumentor\\Reflection\\Types\\Mixed", + "type__tostring": "mixed", "type": {}, "declarationLine": "function a () {", "documentation": null diff --git a/tests/Validation/cases/static4.php.expected.json b/tests/Validation/cases/static4.php.expected.json index 6a28028..67c677a 100644 --- a/tests/Validation/cases/static4.php.expected.json +++ b/tests/Validation/cases/static4.php.expected.json @@ -60,7 +60,7 @@ }, "containerName": "MyNamespace\\A" }, - "type__class": "phpDocumentor\\Reflection\\Types\\Mixed", + "type__tostring": "mixed", "type": {}, "declarationLine": "function a () {", "documentation": null diff --git a/tests/Validation/cases/staticMethodReturnType.php b/tests/Validation/cases/staticMethodReturnType.php new file mode 100644 index 0000000..325738a --- /dev/null +++ b/tests/Validation/cases/staticMethodReturnType.php @@ -0,0 +1,9 @@ +bar()": { + "fqn": "FooClass->bar()", + "extends": [], + "isGlobal": false, + "isStatic": false, + "canBeInstantiated": false, + "symbolInformation": { + "name": "bar", + "kind": 6, + "location": { + "uri": "./staticMethodReturnType.php" + }, + "containerName": "FooClass" + }, + "type__tostring": "mixed", + "type": {}, + "declarationLine": "public function bar() { }", + "documentation": null + } + } +} \ 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 5ac910b..982dba5 100644 --- a/tests/Validation/cases/stringVariable.php.expected.json +++ b/tests/Validation/cases/stringVariable.php.expected.json @@ -33,7 +33,7 @@ }, "containerName": "B" }, - "type__class": "phpDocumentor\\Reflection\\Types\\Integer", + "type__tostring": "int", "type": {}, "declarationLine": "public $hi;", "documentation": null @@ -52,7 +52,7 @@ }, "containerName": "B" }, - "type__class": "phpDocumentor\\Reflection\\Types\\Mixed", + "type__tostring": "mixed", "type": {}, "declarationLine": "function a () {", "documentation": null diff --git a/tests/Validation/cases/verifyFqsenOnClassProperty.php.expected.json b/tests/Validation/cases/verifyFqsenOnClassProperty.php.expected.json index f072722..d40ef63 100644 --- a/tests/Validation/cases/verifyFqsenOnClassProperty.php.expected.json +++ b/tests/Validation/cases/verifyFqsenOnClassProperty.php.expected.json @@ -40,7 +40,7 @@ }, "containerName": "Foo" }, - "type__class": "phpDocumentor\\Reflection\\Types\\Object_", + "type__tostring": "\\", "type": {}, "declarationLine": "protected $bar;", "documentation": null @@ -59,7 +59,7 @@ }, "containerName": "Foo" }, - "type__class": "phpDocumentor\\Reflection\\Types\\Mixed", + "type__tostring": "mixed", "type": {}, "declarationLine": "public function foo () {", "documentation": null From cc3f0da21ae5e83402652acae417cf8aa9939dbb Mon Sep 17 00:00:00 2001 From: Stephan Unverwerth Date: Sat, 10 Jun 2017 11:37:39 +0200 Subject: [PATCH 04/14] Fix 'find references' for unused symbols (#392) * Add tests for unused symbols * Fix tests for unused symbols --- fixtures/global_symbols.php | 12 ++++++ tests/Server/ServerTestCase.php | 3 ++ .../TextDocument/References/GlobalTest.php | 39 +++++++++++++++++++ tests/Server/Workspace/SymbolTest.php | 6 ++- 4 files changed, 59 insertions(+), 1 deletion(-) diff --git a/fixtures/global_symbols.php b/fixtures/global_symbols.php index ac93b68..25b928b 100644 --- a/fixtures/global_symbols.php +++ b/fixtures/global_symbols.php @@ -105,3 +105,15 @@ class ChildClass extends TestClass {} define('TEST_DEFINE_CONSTANT', false); print TEST_DEFINE_CONSTANT ? 'true' : 'false'; + +/** + * Neither this class nor its members are referenced anywhere + */ +class UnusedClass +{ + public $unusedProperty; + + public function unusedMethod() + { + } +} diff --git a/tests/Server/ServerTestCase.php b/tests/Server/ServerTestCase.php index d8203c3..04e5976 100644 --- a/tests/Server/ServerTestCase.php +++ b/tests/Server/ServerTestCase.php @@ -85,6 +85,9 @@ abstract class ServerTestCase extends TestCase 'TestClass::staticTestMethod()' => new Location($globalSymbolsUri, new Range(new Position(46, 4), new Position(49, 5))), 'TestClass::testMethod()' => new Location($globalSymbolsUri, new Range(new Position(57, 4), new Position(60, 5))), 'test_function()' => new Location($globalSymbolsUri, new Range(new Position(78, 0), new Position(81, 1))), + 'UnusedClass' => new Location($globalSymbolsUri, new Range(new Position(111, 0), new Position(118, 1))), + 'UnusedClass::unusedProperty' => new Location($globalSymbolsUri, new Range(new Position(113,11), new Position(113, 26))), + 'UnusedClass::unusedMethod' => new Location($globalSymbolsUri, new Range(new Position(115, 4), new Position(117, 5))), 'whatever()' => new Location($globalReferencesUri, new Range(new Position(21, 0), new Position(23, 1))), // Namespaced diff --git a/tests/Server/TextDocument/References/GlobalTest.php b/tests/Server/TextDocument/References/GlobalTest.php index 4febaf3..fcb6e71 100644 --- a/tests/Server/TextDocument/References/GlobalTest.php +++ b/tests/Server/TextDocument/References/GlobalTest.php @@ -159,4 +159,43 @@ class GlobalTest extends ServerTestCase )->wait(); $this->assertEquals($this->getReferenceLocations('TestClass'), $result); } + + public function testReferencesForUnusedClass() + { + // class UnusedClass + // Get references for UnusedClass + $symbolsUri = pathToUri(realpath(__DIR__ . '/../../../../fixtures/global_symbols.php')); + $result = $this->textDocument->references( + new ReferenceContext, + new TextDocumentIdentifier($symbolsUri), + new Position(111, 10) + )->wait(); + $this->assertEquals([], $result); + } + + public function testReferencesForUnusedProperty() + { + // public $unusedProperty + // Get references for unusedProperty + $symbolsUri = pathToUri(realpath(__DIR__ . '/../../../../fixtures/global_symbols.php')); + $result = $this->textDocument->references( + new ReferenceContext, + new TextDocumentIdentifier($symbolsUri), + new Position(113, 18) + )->wait(); + $this->assertEquals([], $result); + } + + public function testReferencesForUnusedMethod() + { + // public function unusedMethod() + // Get references for unusedMethod + $symbolsUri = pathToUri(realpath(__DIR__ . '/../../../../fixtures/global_symbols.php')); + $result = $this->textDocument->references( + new ReferenceContext, + new TextDocumentIdentifier($symbolsUri), + new Position(115, 26) + )->wait(); + $this->assertEquals([], $result); + } } diff --git a/tests/Server/Workspace/SymbolTest.php b/tests/Server/Workspace/SymbolTest.php index 8f2680d..765841b 100644 --- a/tests/Server/Workspace/SymbolTest.php +++ b/tests/Server/Workspace/SymbolTest.php @@ -27,6 +27,7 @@ class SymbolTest extends ServerTestCase // Request symbols $result = $this->workspace->symbol('')->wait(); $referencesUri = pathToUri(realpath(__DIR__ . '/../../../fixtures/references.php')); + // @codingStandardsIgnoreStart $this->assertEquals([ new SymbolInformation('TestNamespace', SymbolKind::NAMESPACE, new Location($referencesUri, new Range(new Position(2, 0), new Position(2, 24))), ''), @@ -59,9 +60,12 @@ class SymbolTest extends ServerTestCase new SymbolInformation('test_function', SymbolKind::FUNCTION, $this->getDefinitionLocation('test_function()'), ''), new SymbolInformation('ChildClass', SymbolKind::CLASS_, $this->getDefinitionLocation('ChildClass'), ''), new SymbolInformation('TEST_DEFINE_CONSTANT', SymbolKind::CONSTANT, $this->getDefinitionLocation('TEST_DEFINE_CONSTANT'), ''), + new SymbolInformation('UnusedClass', SymbolKind::CLASS_, $this->getDefinitionLocation('UnusedClass'), ''), + new SymbolInformation('unusedProperty', SymbolKind::PROPERTY, $this->getDefinitionLocation('UnusedClass::unusedProperty'), 'UnusedClass'), + new SymbolInformation('unusedMethod', SymbolKind::METHOD, $this->getDefinitionLocation('UnusedClass::unusedMethod'), 'UnusedClass'), new SymbolInformation('whatever', SymbolKind::FUNCTION, $this->getDefinitionLocation('whatever()'), ''), - new SymbolInformation('SecondTestNamespace', SymbolKind::NAMESPACE, $this->getDefinitionLocation('SecondTestNamespace'), '') + new SymbolInformation('SecondTestNamespace', SymbolKind::NAMESPACE, $this->getDefinitionLocation('SecondTestNamespace'), ''), ], $result); // @codingStandardsIgnoreEnd } From 4c1d7bd1bc82652a97fb9c7a1b87c24e43691d5c Mon Sep 17 00:00:00 2001 From: Jens Hausdorf Date: Sat, 10 Jun 2017 18:47:19 +0200 Subject: [PATCH 05/14] Add true, false, null to keywords (#396) --- src/CompletionProvider.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/CompletionProvider.php b/src/CompletionProvider.php index 160798d..0c160aa 100644 --- a/src/CompletionProvider.php +++ b/src/CompletionProvider.php @@ -49,6 +49,7 @@ class CompletionProvider 'eval', 'exit', 'extends', + 'false', 'final', 'finally', 'for', @@ -67,6 +68,7 @@ class CompletionProvider 'list', 'namespace', 'new', + 'null', 'or', 'print', 'private', @@ -79,6 +81,7 @@ class CompletionProvider 'switch', 'throw', 'trait', + 'true', 'try', 'unset', 'use', From fe7e9d580041238682f1952d3429569f183afd23 Mon Sep 17 00:00:00 2001 From: Felix Becker Date: Sat, 10 Jun 2017 21:36:16 +0200 Subject: [PATCH 06/14] Rename $stmts to $sourceFileNode everywhere The root node is now a SourceFileNode, not an array --- src/PhpDocument.php | 18 +++++++++--------- src/TreeAnalyzer.php | 20 ++++++++++---------- tests/DefinitionResolverTest.php | 16 ++++++++-------- 3 files changed, 27 insertions(+), 27 deletions(-) diff --git a/src/PhpDocument.php b/src/PhpDocument.php index f7b813e..7820701 100644 --- a/src/PhpDocument.php +++ b/src/PhpDocument.php @@ -56,9 +56,9 @@ class PhpDocument /** * The AST of the document * - * @var Node + * @var Node\SourceFileNode */ - private $stmts; + private $sourceFileNode; /** * Map from fully qualified name (FQN) to Definition @@ -172,7 +172,7 @@ class PhpDocument $this->index->addReferenceUri($fqn, $this->uri); } - $this->stmts = $treeAnalyzer->getStmts(); + $this->sourceFileNode = $treeAnalyzer->getSourceFileNode(); } /** @@ -221,11 +221,11 @@ class PhpDocument /** * Returns the AST of the document * - * @return Node | null + * @return Node\SourceFileNode|null */ - public function getStmts() + public function getSourceFileNode() { - return $this->stmts; + return $this->sourceFileNode; } /** @@ -236,12 +236,12 @@ class PhpDocument */ public function getNodeAtPosition(Position $position) { - if ($this->stmts === null) { + if ($this->sourceFileNode === null) { return null; } - $offset = $position->toOffset($this->stmts->getFileContents()); - $node = $this->stmts->getDescendantNodeAtPosition($offset); + $offset = $position->toOffset($this->sourceFileNode->getFileContents()); + $node = $this->sourceFileNode->getDescendantNodeAtPosition($offset); if ($node !== null && $node->getStart() > $offset) { return null; } diff --git a/src/TreeAnalyzer.php b/src/TreeAnalyzer.php index 08c60b0..3296ae8 100644 --- a/src/TreeAnalyzer.php +++ b/src/TreeAnalyzer.php @@ -15,8 +15,8 @@ class TreeAnalyzer /** @var PhpParser\Parser */ private $parser; - /** @var Node */ - private $stmts; + /** @var Node\SourceFileNode */ + private $sourceFileNode; /** @var Diagnostic[] */ private $diagnostics; @@ -46,17 +46,17 @@ class TreeAnalyzer $this->docBlockFactory = $docBlockFactory; $this->definitionResolver = $definitionResolver; $this->content = $content; - $this->stmts = $this->parser->parseSourceFile($content, $uri); + $this->sourceFileNode = $this->parser->parseSourceFile($content, $uri); // TODO - docblock errors - $this->collectDefinitionsAndReferences($this->stmts); + $this->collectDefinitionsAndReferences($this->sourceFileNode); } - private function collectDefinitionsAndReferences(Node $stmts) + private function collectDefinitionsAndReferences(Node $sourceFileNode) { - foreach ($stmts::CHILD_NAMES as $name) { - $node = $stmts->$name; + foreach ($sourceFileNode::CHILD_NAMES as $name) { + $node = $sourceFileNode->$name; if ($node === null) { continue; @@ -200,10 +200,10 @@ class TreeAnalyzer } /** - * @return Node[] + * @return Node\SourceFileNode */ - public function getStmts() + public function getSourceFileNode() { - return $this->stmts; + return $this->sourceFileNode; } } diff --git a/tests/DefinitionResolverTest.php b/tests/DefinitionResolverTest.php index e7d8b78..0397e71 100644 --- a/tests/DefinitionResolverTest.php +++ b/tests/DefinitionResolverTest.php @@ -14,11 +14,11 @@ class DefinitionResolverTest extends TestCase { $parser = new PhpParser\Parser; $doc = new MockPhpDocument; - $stmts = $parser->parseSourceFile("getUri()); + $sourceFileNode = $parser->parseSourceFile("getUri()); $index = new Index; $definitionResolver = new DefinitionResolver($index); - $def = $definitionResolver->createDefinitionFromNode($stmts->statementList[1]->expression, '\TEST_DEFINE'); + $def = $definitionResolver->createDefinitionFromNode($sourceFileNode->statementList[1]->expression, '\TEST_DEFINE'); $this->assertInstanceOf(\phpDocumentor\Reflection\Types\Boolean::class, $def->type); } @@ -27,11 +27,11 @@ class DefinitionResolverTest extends TestCase { $parser = new PhpParser\Parser; $doc = new MockPhpDocument; - $stmts = $parser->parseSourceFile("getUri()); + $sourceFileNode = $parser->parseSourceFile("getUri()); $index = new Index; $definitionResolver = new DefinitionResolver($index); - $type = $definitionResolver->getTypeFromNode($stmts->statementList[1]->expression); + $type = $definitionResolver->getTypeFromNode($sourceFileNode->statementList[1]->expression); $this->assertInstanceOf(\phpDocumentor\Reflection\Types\Boolean::class, $type); } @@ -41,11 +41,11 @@ class DefinitionResolverTest extends TestCase // define('XXX') (only one argument) must not introduce a new symbol $parser = new PhpParser\Parser; $doc = new MockPhpDocument; - $stmts = $parser->parseSourceFile("getUri()); + $sourceFileNode = $parser->parseSourceFile("getUri()); $index = new Index; $definitionResolver = new DefinitionResolver($index); - $fqn = $definitionResolver->getDefinedFqn($stmts->statementList[1]->expression); + $fqn = $definitionResolver->getDefinedFqn($sourceFileNode->statementList[1]->expression); $this->assertNull($fqn); } @@ -54,11 +54,11 @@ class DefinitionResolverTest extends TestCase { $parser = new PhpParser\Parser; $doc = new MockPhpDocument; - $stmts = $parser->parseSourceFile("getUri()); + $sourceFileNode = $parser->parseSourceFile("getUri()); $index = new Index; $definitionResolver = new DefinitionResolver($index); - $fqn = $definitionResolver->getDefinedFqn($stmts->statementList[1]->expression); + $fqn = $definitionResolver->getDefinedFqn($sourceFileNode->statementList[1]->expression); $this->assertEquals('TEST_DEFINE', $fqn); } From 8d1732ed02b59554f3a71055b4b8a210ebcd3726 Mon Sep 17 00:00:00 2001 From: Nicholas Narsing Date: Sun, 11 Jun 2017 17:24:17 -0400 Subject: [PATCH 07/14] Exclude directory paths from file system search (#401) * Exclude directories from file system search Directories can also match the glob search pattern if their names end in ".php", which will cause a read error later since the ContentRetriever implementers are expecting files. As far as I know, the only way to fix this is to do an additional check to ensure the URI is not of a directory. This resolves #306. --- src/FilesFinder/FileSystemFilesFinder.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/FilesFinder/FileSystemFilesFinder.php b/src/FilesFinder/FileSystemFilesFinder.php index 52df4b6..a26b5d8 100644 --- a/src/FilesFinder/FileSystemFilesFinder.php +++ b/src/FilesFinder/FileSystemFilesFinder.php @@ -22,7 +22,11 @@ class FileSystemFilesFinder implements FilesFinder return coroutine(function () use ($glob) { $uris = []; foreach (new GlobIterator($glob) as $path) { - $uris[] = pathToUri($path); + // Exclude any directories that also match the glob pattern + if (!is_dir($path)) { + $uris[] = pathToUri($path); + } + yield timeout(); } return $uris; From 3b633369a709c1548bbdf50eb79414dce9cdd248 Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Thu, 15 Jun 2017 03:44:03 -0700 Subject: [PATCH 08/14] Fix error getting completions for 'new static' type (#405) --- src/DefinitionResolver.php | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/DefinitionResolver.php b/src/DefinitionResolver.php index 32defab..d331cba 100644 --- a/src/DefinitionResolver.php +++ b/src/DefinitionResolver.php @@ -906,11 +906,12 @@ class DefinitionResolver // Anonymous class return new Types\Object_; } - $className = (string)$class->getResolvedName(); - - if ($className === 'static') { + if ($class instanceof PhpParser\Token && $class->kind === PhpParser\TokenKind::StaticKeyword) { + // `new static` return new Types\Static_; } + $className = (string)$class->getResolvedName(); + if ($className === 'self' || $className === 'parent') { $classNode = $class->getFirstAncestor(Node\Statement\ClassDeclaration::class); if ($className === 'parent') { From 4a98afe5404c249144785333ec1b0f66b7ad5905 Mon Sep 17 00:00:00 2001 From: Felix Becker Date: Thu, 15 Jun 2017 17:03:25 +0200 Subject: [PATCH 09/14] Fix docblock union types --- src/DefinitionResolver.php | 16 ++++++++-------- src/ParserHelpers.php | 4 ++-- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/DefinitionResolver.php b/src/DefinitionResolver.php index d331cba..c936ba3 100644 --- a/src/DefinitionResolver.php +++ b/src/DefinitionResolver.php @@ -54,7 +54,7 @@ class DefinitionResolver { // If node is part of a declaration list, build a declaration line that discludes other elements in the list // - [PropertyDeclaration] // public $a, [$b = 3], $c; => public $b = 3; - // - [ConstDeclaration | ClassConstDeclaration] // "const A = 3, [B = 4];" => "const B = 4;" + // - [ConstDeclaration|ClassConstDeclaration] // "const A = 3, [B = 4];" => "const B = 4;" if ( ($declaration = ParserHelpers\tryGetPropertyDeclaration($node)) && ($elements = $declaration->propertyElements) || ($declaration = ParserHelpers\tryGetConstOrClassConstDeclaration($node)) && ($elements = $declaration->constElements) @@ -131,7 +131,7 @@ class DefinitionResolver * Gets Doc Block with resolved names for a Node * * @param Node $node - * @return DocBlock | null + * @return DocBlock|null */ private function getDocBlock(Node $node) { @@ -482,8 +482,8 @@ class DefinitionResolver /** * Returns the assignment or parameter node where a variable was defined * - * @param Node\Expression\Variable | Node\Expression\ClosureUse $var The variable access - * @return Node\Expression\Assign | Node\Expression\AssignOp|Node\Param | Node\Expression\ClosureUse|null + * @param Node\Expression\Variable|Node\Expression\ClosureUse $var The variable access + * @return Node\Expression\Assign|Node\Expression\AssignOp|Node\Param|Node\Expression\ClosureUse|null */ public function resolveVariableToNode($var) { @@ -894,7 +894,7 @@ class DefinitionResolver * Takes any class name node (from a static method call, or new node) and returns a Type object * Resolves keywords like self, static and parent * - * @param Node | PhpParser\Token $class + * @param Node|PhpParser\Token $class * @return Type */ public function resolveClassNameToType($class): Type @@ -1191,9 +1191,9 @@ class DefinitionResolver } /** - * @param DocBlock | null $docBlock - * @param string | null $variableName - * @return DocBlock\Tags\Param | null + * @param DocBlock|null $docBlock + * @param string|null $variableName + * @return DocBlock\Tags\Param|null */ private function tryGetDocBlockTagForParameter($docBlock, $variableName) { diff --git a/src/ParserHelpers.php b/src/ParserHelpers.php index 5025ae3..0ea210a 100644 --- a/src/ParserHelpers.php +++ b/src/ParserHelpers.php @@ -77,7 +77,7 @@ function isBooleanExpression($expression) : bool /** * Tries to get the parent property declaration given a Node * @param Node $node - * @return Node\PropertyDeclaration | null $node + * @return Node\PropertyDeclaration|null $node */ function tryGetPropertyDeclaration(Node $node) { @@ -93,7 +93,7 @@ function tryGetPropertyDeclaration(Node $node) /** * Tries to get the parent ConstDeclaration or ClassConstDeclaration given a Node * @param Node $node - * @return Node\Statement\ConstDeclaration | Node\ClassConstDeclaration | null $node + * @return Node\Statement\ConstDeclaration|Node\ClassConstDeclaration|null $node */ function tryGetConstOrClassConstDeclaration(Node $node) { From 663ccd5f2396489ffd49a09b196150de51e6711a Mon Sep 17 00:00:00 2001 From: Felix Becker Date: Thu, 15 Jun 2017 17:11:57 +0200 Subject: [PATCH 10/14] Update CodeSniffer --- composer.json | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/composer.json b/composer.json index 93dec97..5375d79 100644 --- a/composer.json +++ b/composer.json @@ -31,7 +31,7 @@ "phpdocumentor/reflection-docblock": "^3.0", "sabre/event": "^5.0", "felixfbecker/advanced-json-rpc": "^2.0", - "squizlabs/php_codesniffer" : "3.0.0RC3", + "squizlabs/php_codesniffer" : "^3.0", "netresearch/jsonmapper": "^1.0", "webmozart/path-util": "^2.3", "webmozart/glob": "^4.1", @@ -49,7 +49,8 @@ "files" : [ "src/utils.php", "src/FqnUtilities.php", - "src/ParserHelpers.php" + "src/ParserHelpers.php", + "vendor/squizlabs/php_codesniffer/autoload.php" ] }, "autoload-dev": { From 0e3727a8d629eae2f5c732b8ecdecd346db22547 Mon Sep 17 00:00:00 2001 From: Felix Becker Date: Fri, 16 Jun 2017 20:31:13 +0200 Subject: [PATCH 11/14] Improve CompletionProvider (#412) - Better performance - More documentation - Add field to Definition for global namespace fallback Fixes #380 --- .../inside_namespace_and_method.php | 11 + phpcs.xml.dist | 2 + src/CompletionProvider.php | 221 +++++++++++------- src/Definition.php | 7 + src/DefinitionResolver.php | 10 + tests/Server/TextDocument/CompletionTest.php | 30 ++- .../WithReturnTypehints.php.expected.json | 5 + ...embersShouldNotBeSymbols.php.expected.json | 1 + ...rrayValueShouldBeBoolean.php.expected.json | 2 + .../cases/caseStatement1.php.expected.json | 1 + .../cases/classDefinition1.php.expected.json | 3 + .../cases/classProperty1.php.expected.json | 4 + .../cases/constants.php.expected.json | 3 + .../cases/constants2.php.expected.json | 3 + .../cases/constants3.php.expected.json | 3 + .../cases/constants4.php.expected.json | 3 + .../cases/constants5.php.expected.json | 3 + ...tsInFunctionParamDefault.php.expected.json | 2 + ...cksOnNamespaceDefinition.php.expected.json | 1 + .../cases/exceptions1.php.expected.json | 1 + .../cases/ifStatement1.php.expected.json | 1 + .../cases/interfaceProperty.php.expected.json | 1 + ...cConstantsShouldBeGlobal.php.expected.json | 1 + .../cases/magicConsts.php.expected.json | 2 + .../cases/memberAccess1.php.expected.json | 3 + .../cases/memberAccess2.php.expected.json | 3 + .../cases/memberAccess3.php.expected.json | 3 + .../cases/memberAccess4.php.expected.json | 3 + .../cases/memberAccess5.php.expected.json | 3 + .../cases/memberCall1.php.expected.json | 3 + .../cases/methodReturnType.php.expected.json | 2 + .../multipleNamespaces.php.expected.json | 6 + ...ltiplePreceedingComments.php.expected.json | 2 + .../cases/nameToken.php.expected.json | 2 + .../cases/namespaces2.php.expected.json | 1 + .../cases/namespaces5.php.expected.json | 1 + .../cases/namespaces6.php.expected.json | 1 + .../cases/namespaces8.php.expected.json | 1 + .../cases/objectCreation.php.expected.json | 3 + .../cases/objectCreation2.php.expected.json | 4 + .../cases/objectCreation3.php.expected.json | 2 + .../Validation/cases/param1.php.expected.json | 2 + .../cases/parent1.php.expected.json | 5 + .../cases/parent3.php.expected.json | 5 + .../cases/propertyName1.php.expected.json | 2 + .../cases/propertyName2.php.expected.json | 2 + .../cases/returnType.php.expected.json | 2 + .../scopedPropertyAccess.php.expected.json | 3 + .../scopedPropertyAccess2.php.expected.json | 1 + .../scopedPropertyAccess3.php.expected.json | 2 + .../scopedPropertyAccess5.php.expected.json | 2 + .../Validation/cases/self1.php.expected.json | 5 + .../Validation/cases/self2.php.expected.json | 5 + .../Validation/cases/self3.php.expected.json | 5 + .../Validation/cases/self4.php.expected.json | 3 + .../Validation/cases/self5.php.expected.json | 3 + .../cases/static1.php.expected.json | 5 + .../cases/static2.php.expected.json | 5 + .../cases/static3.php.expected.json | 5 + .../cases/static4.php.expected.json | 3 + .../staticMethodReturnType.php.expected.json | 3 + .../cases/stringVariable.php.expected.json | 3 + ...edNameOutsideOfNamespace.php.expected.json | 1 + ...rifyFqsenOnClassProperty.php.expected.json | 3 + 64 files changed, 353 insertions(+), 86 deletions(-) create mode 100644 fixtures/completion/inside_namespace_and_method.php diff --git a/fixtures/completion/inside_namespace_and_method.php b/fixtures/completion/inside_namespace_and_method.php new file mode 100644 index 0000000..698ac4a --- /dev/null +++ b/fixtures/completion/inside_namespace_and_method.php @@ -0,0 +1,11 @@ + + + diff --git a/src/CompletionProvider.php b/src/CompletionProvider.php index 0c160aa..f4f091d 100644 --- a/src/CompletionProvider.php +++ b/src/CompletionProvider.php @@ -128,6 +128,7 @@ class CompletionProvider // This can be made much more performant if the tree follows specific invariants. $node = $doc->getNodeAtPosition($pos); + // Get the node at the position under the cursor $offset = $node === null ? -1 : $pos->toOffset($node->getFileContents()); if ( $node !== null @@ -148,22 +149,31 @@ class CompletionProvider $node = $node->parent; } + // Inspect the type of expression under the cursor + if ($node === null || $node instanceof Node\Statement\InlineHtml || $pos == new Position(0, 0)) { + // HTML, beginning of file + + // Inside HTML and at the beginning of the file, propose textEdit = new TextEdit( new Range($pos, $pos), stripStringOverlap($doc->getRange(new Range(new Position(0, 0), $pos)), 'items[] = $item; - } /* - VARIABLES */ - elseif ( - $node instanceof Node\Expression\Variable && - !( - $node->parent instanceof Node\Expression\ScopedPropertyAccessExpression && - $node->parent->memberName === $node) + } elseif ( + $node instanceof Node\Expression\Variable + && !( + $node->parent instanceof Node\Expression\ScopedPropertyAccessExpression + && $node->parent->memberName === $node + ) ) { + // Variables + // + // $| + // $a| + // Find variables, parameters and use statements in the scope $namePrefix = $node->getName() ?? ''; foreach ($this->suggestVariablesAtNode($node, $namePrefix) as $var) { @@ -178,23 +188,28 @@ class CompletionProvider ); $list->items[] = $item; } - } /* - MEMBER ACCESS EXPRESSIONS - $a->c# - $a-># */ - elseif ($node instanceof Node\Expression\MemberAccessExpression) { + } elseif ($node instanceof Node\Expression\MemberAccessExpression) { + // Member access expressions + // + // $a->c| + // $a->| + + // Multiple prefixes for all possible types $prefixes = FqnUtilities\getFqnsFromType( $this->definitionResolver->resolveExpressionNodeToType($node->dereferencableExpression) ); + + // Include parent classes $prefixes = $this->expandParentFqns($prefixes); + // Add the object access operator to only get members foreach ($prefixes as &$prefix) { $prefix .= '->'; } - unset($prefix); + // Collect all definitions that match any of the prefixes foreach ($this->index->getDefinitions() as $fqn => $def) { foreach ($prefixes as $prefix) { if (substr($fqn, 0, strlen($prefix)) === $prefix && !$def->isGlobal) { @@ -202,30 +217,35 @@ class CompletionProvider } } } - } /* - SCOPED PROPERTY ACCESS EXPRESSIONS - A\B\C::$a# - A\B\C::# - A\B\C::$# - A\B\C::foo# - TODO: $a::# */ - elseif ( + } elseif ( ($scoped = $node->parent) instanceof Node\Expression\ScopedPropertyAccessExpression || ($scoped = $node) instanceof Node\Expression\ScopedPropertyAccessExpression ) { + // Static class members and constants + // + // A\B\C::$a| + // A\B\C::| + // A\B\C::$| + // A\B\C::foo| + // + // TODO: $a::| + + // Resolve all possible types to FQNs $prefixes = FqnUtilities\getFqnsFromType( $classType = $this->definitionResolver->resolveExpressionNodeToType($scoped->scopeResolutionQualifier) ); + // Add parent classes $prefixes = $this->expandParentFqns($prefixes); + // Append :: operator to only get static members foreach ($prefixes as &$prefix) { $prefix .= '::'; } - unset($prefix); + // Collect all definitions that match any of the prefixes foreach ($this->index->getDefinitions() as $fqn => $def) { foreach ($prefixes as $prefix) { if (substr(strtolower($fqn), 0, strlen($prefix)) === strtolower($prefix) && !$def->isGlobal) { @@ -233,83 +253,124 @@ class CompletionProvider } } } - } elseif (ParserHelpers\isConstantFetch($node) || - ($creation = $node->parent) instanceof Node\Expression\ObjectCreationExpression || - (($creation = $node) instanceof Node\Expression\ObjectCreationExpression)) { - $class = isset($creation) ? $creation->classTypeDesignator : $node; - $prefix = $class instanceof Node\QualifiedName - ? (string)PhpParser\ResolvedName::buildName($class->nameParts, $class->getFileContents()) - : $class->getText($node->getFileContents()); + } elseif ( + ParserHelpers\isConstantFetch($node) + // Creation gets set in case of an instantiation (`new` expression) + || ($creation = $node->parent) instanceof Node\Expression\ObjectCreationExpression + || (($creation = $node) instanceof Node\Expression\ObjectCreationExpression) + ) { + // Class instantiations, function calls, constant fetches, class names + // + // new MyCl| + // my_func| + // MY_CONS| + // MyCla| - $namespaceDefinition = $node->getNamespaceDefinition(); + // The name Node under the cursor + $nameNode = isset($creation) ? $creation->classTypeDesignator : $node; - list($namespaceImportTable,,) = $node->getImportTablesForCurrentScope(); - foreach ($namespaceImportTable as $alias => $name) { - $namespaceImportTable[$alias] = (string)$name; + /** The typed name */ + $prefix = $nameNode instanceof Node\QualifiedName + ? (string)PhpParser\ResolvedName::buildName($nameNode->nameParts, $nameNode->getFileContents()) + : $nameNode->getText($node->getFileContents()); + $prefixLen = strlen($prefix); + + /** Whether the prefix is qualified (contains at least one backslash) */ + $isQualified = $nameNode instanceof Node\QualifiedName && $nameNode->isQualifiedName(); + + /** Whether the prefix is fully qualified (begins with a backslash) */ + $isFullyQualified = $nameNode instanceof Node\QualifiedName && $nameNode->isFullyQualifiedName(); + + /** The closest NamespaceDefinition Node */ + $namespaceNode = $node->getNamespaceDefinition(); + + /** @var string The name of the namespace */ + $namespacedPrefix = null; + if ($namespaceNode) { + $namespacedPrefix = (string)PhpParser\ResolvedName::buildName($namespaceNode->name->nameParts, $node->getFileContents()) . '\\' . $prefix; + $namespacedPrefixLen = strlen($namespacedPrefix); } - foreach ($this->index->getDefinitions() as $fqn => $def) { - $fqnStartsWithPrefix = substr($fqn, 0, strlen($prefix)) === $prefix; - $fqnContainsPrefix = empty($prefix) || strpos($fqn, $prefix) !== false; - if (($def->canBeInstantiated || ($def->isGlobal && !isset($creation))) && $fqnContainsPrefix) { - if ($namespaceDefinition !== null && $namespaceDefinition->name !== null) { - $namespacePrefix = (string)PhpParser\ResolvedName::buildName($namespaceDefinition->name->nameParts, $node->getFileContents()); + // Get the namespace use statements + // TODO: use function statements, use const statements - $isAliased = false; + /** @var string[] $aliases A map from local alias to fully qualified name */ + list($aliases,,) = $node->getImportTablesForCurrentScope(); - $isNotFullyQualified = !($class instanceof Node\QualifiedName) || !$class->isFullyQualifiedName(); - if ($isNotFullyQualified) { - foreach ($namespaceImportTable as $alias => $name) { - if (substr($fqn, 0, strlen($name)) === $name) { - $fqn = $alias; - $isAliased = true; - break; - } - } - } + foreach ($aliases as $alias => $name) { + $aliases[$alias] = (string)$name; + } - $prefixWithNamespace = $namespacePrefix . "\\" . $prefix; - $fqnMatchesPrefixWithNamespace = substr($fqn, 0, strlen($prefixWithNamespace)) === $prefixWithNamespace; - $isFullyQualifiedAndPrefixMatches = !$isNotFullyQualified && ($fqnStartsWithPrefix || $fqnMatchesPrefixWithNamespace); - if (!$isFullyQualifiedAndPrefixMatches && !$isAliased) { - if (!array_search($fqn, array_values($namespaceImportTable))) { - if (empty($prefix)) { - $fqn = '\\' . $fqn; - } elseif ($fqnMatchesPrefixWithNamespace) { - $fqn = substr($fqn, strlen($namespacePrefix) + 1); - } else { - continue; - } - } else { - continue; - } - } - } elseif ($fqnStartsWithPrefix && $class instanceof Node\QualifiedName && $class->isFullyQualifiedName()) { - $fqn = '\\' . $fqn; + // If there is a prefix that does not start with a slash, suggest `use`d symbols + if ($prefix && !$isFullyQualified) { + foreach ($aliases as $alias => $fqn) { + // Suggest symbols that have been `use`d and match the prefix + if (substr($alias, 0, $prefixLen) === $prefix && ($def = $this->index->getDefinition($fqn))) { + $list->items[] = CompletionItem::fromDefinition($def); } + } + } + // Suggest global symbols that either + // - start with the current namespace + prefix, if the Name node is not fully qualified + // - start with just the prefix, if the Name node is fully qualified + foreach ($this->index->getDefinitions() as $fqn => $def) { + + $fqnStartsWithPrefix = substr($fqn, 0, $prefixLen) === $prefix; + + if ( + // Exclude methods, properties etc. + $def->isGlobal + && ( + !$prefix + || ( + // Either not qualified, but a matching prefix with global fallback + ($def->roamed && !$isQualified && $fqnStartsWithPrefix) + // Or not in a namespace or a fully qualified name or AND matching the prefix + || ((!$namespaceNode || $isFullyQualified) && $fqnStartsWithPrefix) + // Or in a namespace, not fully qualified and matching the prefix + current namespace + || ( + $namespaceNode + && !$isFullyQualified + && substr($fqn, 0, $namespacedPrefixLen) === $namespacedPrefix + ) + ) + ) + // Only suggest classes for `new` + && (!isset($creation) || $def->canBeInstantiated) + ) { $item = CompletionItem::fromDefinition($def); - - $item->insertText = $fqn; + // Find the shortest name to reference the symbol + if ($namespaceNode && ($alias = array_search($fqn, $aliases, true)) !== false) { + // $alias is the name under which this definition is aliased in the current namespace + $item->insertText = $alias; + } else if ($namespaceNode && !($prefix && $isFullyQualified)) { + // Insert the global FQN with leading backslash + $item->insertText = '\\' . $fqn; + } else { + // Insert the FQN without leading backlash + $item->insertText = $fqn; + } + // Don't insert the parenthesis for functions + // TODO return a snippet and put the cursor inside + if (substr($item->insertText, -2) === '()') { + $item->insertText = substr($item->insertText, 0, -2); + } $list->items[] = $item; } } + // If not a class instantiation, also suggest keywords if (!isset($creation)) { foreach (self::KEYWORDS as $keyword) { - $item = new CompletionItem($keyword, CompletionItemKind::KEYWORD); - $item->insertText = $keyword . ' '; - $list->items[] = $item; + if (substr($keyword, 0, $prefixLen) === $prefix) { + $item = new CompletionItem($keyword, CompletionItemKind::KEYWORD); + $item->insertText = $keyword; + $list->items[] = $item; + } } } - } elseif (ParserHelpers\isConstantFetch($node)) { - $prefix = (string) ($node->getResolvedName() ?? PhpParser\ResolvedName::buildName($node->nameParts, $node->getFileContents())); - foreach (self::KEYWORDS as $keyword) { - $item = new CompletionItem($keyword, CompletionItemKind::KEYWORD); - $item->insertText = $keyword . ' '; - $list->items[] = $item; - } } return $list; diff --git a/src/Definition.php b/src/Definition.php index e302f71..cf0f574 100644 --- a/src/Definition.php +++ b/src/Definition.php @@ -44,6 +44,13 @@ class Definition */ public $isGlobal; + /** + * True if this definition is affected by global namespace fallback (global function or global constant) + * + * @var bool + */ + public $roamed; + /** * False for instance methods and properties * diff --git a/src/DefinitionResolver.php b/src/DefinitionResolver.php index c936ba3..7772990 100644 --- a/src/DefinitionResolver.php +++ b/src/DefinitionResolver.php @@ -193,6 +193,16 @@ class DefinitionResolver ($node instanceof Node\ConstElement && $node->parent->parent instanceof Node\Statement\ConstDeclaration) ); + // Definition is affected by global namespace fallback if it is a global constant or a global function + $def->roamed = ( + $fqn !== null + && strpos($fqn, '\\') === false + && ( + ($node instanceof Node\ConstElement && $node->parent->parent instanceof Node\Statement\ConstDeclaration) + || $node instanceof Node\Statement\FunctionDeclaration + ) + ); + // Static methods and static property declarations $def->isStatic = ( ($node instanceof Node\MethodDeclaration && $node->isStatic()) || diff --git a/tests/Server/TextDocument/CompletionTest.php b/tests/Server/TextDocument/CompletionTest.php index 923acc1..be34200 100644 --- a/tests/Server/TextDocument/CompletionTest.php +++ b/tests/Server/TextDocument/CompletionTest.php @@ -69,6 +69,27 @@ class CompletionTest extends TestCase ], true), $items); } + public function testGlobalFunctionInsideNamespaceAndClass() + { + $completionUri = pathToUri(__DIR__ . '/../../../fixtures/completion/inside_namespace_and_method.php'); + $this->loader->open($completionUri, file_get_contents($completionUri)); + $items = $this->textDocument->completion( + new TextDocumentIdentifier($completionUri), + new Position(8, 11) + )->wait(); + $this->assertCompletionsListSubset(new CompletionList([ + new CompletionItem( + 'test_function', + CompletionItemKind::FUNCTION, + 'void', // Return type + 'Officia aliquip adipisicing et nulla et laboris dolore labore.', + null, + null, + '\test_function' + ) + ], true), $items); + } + public function testPropertyAndMethodWithoutPrefix() { $completionUri = pathToUri(__DIR__ . '/../../../fixtures/completion/property.php'); @@ -234,10 +255,7 @@ class CompletionTest extends TestCase 'laboris commodo ad commodo velit mollit qui non officia id. Nulla duis veniam' . "\n" . 'veniam officia deserunt et non dolore mollit ea quis eiusmod sit non. Occaecat' . "\n" . 'consequat sunt culpa exercitation pariatur id reprehenderit nisi incididunt Lorem' . "\n" . - 'sint. Officia culpa pariatur laborum nostrud cupidatat consequat mollit.', - null, - null, - 'TestClass' + 'sint. Officia culpa pariatur laborum nostrud cupidatat consequat mollit.' ) ], true), $items); } @@ -397,8 +415,8 @@ class CompletionTest extends TestCase new Position(2, 1) )->wait(); $this->assertCompletionsListSubset(new CompletionList([ - new CompletionItem('class', CompletionItemKind::KEYWORD, null, null, null, null, 'class '), - new CompletionItem('clone', CompletionItemKind::KEYWORD, null, null, null, null, 'clone ') + new CompletionItem('class', CompletionItemKind::KEYWORD, null, null, null, null, 'class'), + new CompletionItem('clone', CompletionItemKind::KEYWORD, null, null, null, null, 'clone') ], true), $items); } diff --git a/tests/Validation/cases/WithReturnTypehints.php.expected.json b/tests/Validation/cases/WithReturnTypehints.php.expected.json index 271c203..26b00e2 100644 --- a/tests/Validation/cases/WithReturnTypehints.php.expected.json +++ b/tests/Validation/cases/WithReturnTypehints.php.expected.json @@ -21,6 +21,7 @@ "fqn": "Fixtures\\Prophecy", "extends": [], "isGlobal": true, + "roamed": false, "isStatic": false, "canBeInstantiated": false, "symbolInformation": { @@ -41,6 +42,7 @@ "Fixtures\\Prophecy\\EmptyClass" ], "isGlobal": true, + "roamed": false, "isStatic": false, "canBeInstantiated": true, "symbolInformation": { @@ -59,6 +61,7 @@ "fqn": "Fixtures\\Prophecy\\WithReturnTypehints->getSelf()", "extends": [], "isGlobal": false, + "roamed": false, "isStatic": false, "canBeInstantiated": false, "symbolInformation": { @@ -78,6 +81,7 @@ "fqn": "Fixtures\\Prophecy\\WithReturnTypehints->getName()", "extends": [], "isGlobal": false, + "roamed": false, "isStatic": false, "canBeInstantiated": false, "symbolInformation": { @@ -97,6 +101,7 @@ "fqn": "Fixtures\\Prophecy\\WithReturnTypehints->getParent()", "extends": [], "isGlobal": false, + "roamed": false, "isStatic": false, "canBeInstantiated": false, "symbolInformation": { diff --git a/tests/Validation/cases/anonymousClassMembersShouldNotBeSymbols.php.expected.json b/tests/Validation/cases/anonymousClassMembersShouldNotBeSymbols.php.expected.json index 189d154..b0625d7 100644 --- a/tests/Validation/cases/anonymousClassMembersShouldNotBeSymbols.php.expected.json +++ b/tests/Validation/cases/anonymousClassMembersShouldNotBeSymbols.php.expected.json @@ -5,6 +5,7 @@ "fqn": "MyNamespace", "extends": [], "isGlobal": true, + "roamed": false, "isStatic": false, "canBeInstantiated": false, "symbolInformation": { diff --git a/tests/Validation/cases/arrayValueShouldBeBoolean.php.expected.json b/tests/Validation/cases/arrayValueShouldBeBoolean.php.expected.json index 1bb66e1..d58986d 100644 --- a/tests/Validation/cases/arrayValueShouldBeBoolean.php.expected.json +++ b/tests/Validation/cases/arrayValueShouldBeBoolean.php.expected.json @@ -5,6 +5,7 @@ "fqn": "A", "extends": [], "isGlobal": true, + "roamed": false, "isStatic": false, "canBeInstantiated": true, "symbolInformation": { @@ -23,6 +24,7 @@ "fqn": "A->foo", "extends": [], "isGlobal": false, + "roamed": false, "isStatic": false, "canBeInstantiated": false, "symbolInformation": { diff --git a/tests/Validation/cases/caseStatement1.php.expected.json b/tests/Validation/cases/caseStatement1.php.expected.json index 7b6dbf2..573dd17 100644 --- a/tests/Validation/cases/caseStatement1.php.expected.json +++ b/tests/Validation/cases/caseStatement1.php.expected.json @@ -12,6 +12,7 @@ "fqn": "MyNamespace", "extends": [], "isGlobal": true, + "roamed": false, "isStatic": false, "canBeInstantiated": false, "symbolInformation": { diff --git a/tests/Validation/cases/classDefinition1.php.expected.json b/tests/Validation/cases/classDefinition1.php.expected.json index 5167a4c..6c418b7 100644 --- a/tests/Validation/cases/classDefinition1.php.expected.json +++ b/tests/Validation/cases/classDefinition1.php.expected.json @@ -12,6 +12,7 @@ "fqn": "TestNamespace", "extends": [], "isGlobal": true, + "roamed": false, "isStatic": false, "canBeInstantiated": false, "symbolInformation": { @@ -30,6 +31,7 @@ "fqn": "TestNamespace\\A", "extends": [], "isGlobal": true, + "roamed": false, "isStatic": false, "canBeInstantiated": true, "symbolInformation": { @@ -48,6 +50,7 @@ "fqn": "TestNamespace\\A->a", "extends": [], "isGlobal": false, + "roamed": false, "isStatic": false, "canBeInstantiated": false, "symbolInformation": { diff --git a/tests/Validation/cases/classProperty1.php.expected.json b/tests/Validation/cases/classProperty1.php.expected.json index 05d90c1..e00107e 100644 --- a/tests/Validation/cases/classProperty1.php.expected.json +++ b/tests/Validation/cases/classProperty1.php.expected.json @@ -12,6 +12,7 @@ "fqn": "TestNamespace", "extends": [], "isGlobal": true, + "roamed": false, "isStatic": false, "canBeInstantiated": false, "symbolInformation": { @@ -30,6 +31,7 @@ "fqn": "TestNamespace\\TestClass", "extends": [], "isGlobal": true, + "roamed": false, "isStatic": false, "canBeInstantiated": true, "symbolInformation": { @@ -48,6 +50,7 @@ "fqn": "TestNamespace\\TestClass->testProperty", "extends": [], "isGlobal": false, + "roamed": false, "isStatic": false, "canBeInstantiated": false, "symbolInformation": { @@ -67,6 +70,7 @@ "fqn": "TestNamespace\\TestClass->testMethod()", "extends": [], "isGlobal": false, + "roamed": false, "isStatic": false, "canBeInstantiated": false, "symbolInformation": { diff --git a/tests/Validation/cases/constants.php.expected.json b/tests/Validation/cases/constants.php.expected.json index ba80e25..d629870 100644 --- a/tests/Validation/cases/constants.php.expected.json +++ b/tests/Validation/cases/constants.php.expected.json @@ -12,6 +12,7 @@ "fqn": "MyNamespace", "extends": [], "isGlobal": true, + "roamed": false, "isStatic": false, "canBeInstantiated": false, "symbolInformation": { @@ -30,6 +31,7 @@ "fqn": "MyNamespace\\A", "extends": [], "isGlobal": true, + "roamed": false, "isStatic": false, "canBeInstantiated": true, "symbolInformation": { @@ -48,6 +50,7 @@ "fqn": "MyNamespace\\A::suite()", "extends": [], "isGlobal": false, + "roamed": false, "isStatic": true, "canBeInstantiated": false, "symbolInformation": { diff --git a/tests/Validation/cases/constants2.php.expected.json b/tests/Validation/cases/constants2.php.expected.json index e08408e..66c678f 100644 --- a/tests/Validation/cases/constants2.php.expected.json +++ b/tests/Validation/cases/constants2.php.expected.json @@ -12,6 +12,7 @@ "fqn": "MyNamespace", "extends": [], "isGlobal": true, + "roamed": false, "isStatic": false, "canBeInstantiated": false, "symbolInformation": { @@ -30,6 +31,7 @@ "fqn": "MyNamespace\\A", "extends": [], "isGlobal": true, + "roamed": false, "isStatic": false, "canBeInstantiated": true, "symbolInformation": { @@ -48,6 +50,7 @@ "fqn": "MyNamespace\\A::suite()", "extends": [], "isGlobal": false, + "roamed": false, "isStatic": true, "canBeInstantiated": false, "symbolInformation": { diff --git a/tests/Validation/cases/constants3.php.expected.json b/tests/Validation/cases/constants3.php.expected.json index dbbb959..03f00ba 100644 --- a/tests/Validation/cases/constants3.php.expected.json +++ b/tests/Validation/cases/constants3.php.expected.json @@ -12,6 +12,7 @@ "fqn": "MyNamespace", "extends": [], "isGlobal": true, + "roamed": false, "isStatic": false, "canBeInstantiated": false, "symbolInformation": { @@ -30,6 +31,7 @@ "fqn": "MyNamespace\\A", "extends": [], "isGlobal": true, + "roamed": false, "isStatic": false, "canBeInstantiated": true, "symbolInformation": { @@ -48,6 +50,7 @@ "fqn": "MyNamespace\\A::suite()", "extends": [], "isGlobal": false, + "roamed": false, "isStatic": true, "canBeInstantiated": false, "symbolInformation": { diff --git a/tests/Validation/cases/constants4.php.expected.json b/tests/Validation/cases/constants4.php.expected.json index 24523a8..62ce430 100644 --- a/tests/Validation/cases/constants4.php.expected.json +++ b/tests/Validation/cases/constants4.php.expected.json @@ -12,6 +12,7 @@ "fqn": "MyNamespace", "extends": [], "isGlobal": true, + "roamed": false, "isStatic": false, "canBeInstantiated": false, "symbolInformation": { @@ -30,6 +31,7 @@ "fqn": "MyNamespace\\A", "extends": [], "isGlobal": true, + "roamed": false, "isStatic": false, "canBeInstantiated": true, "symbolInformation": { @@ -48,6 +50,7 @@ "fqn": "MyNamespace\\A->suite()", "extends": [], "isGlobal": false, + "roamed": false, "isStatic": false, "canBeInstantiated": false, "symbolInformation": { diff --git a/tests/Validation/cases/constants5.php.expected.json b/tests/Validation/cases/constants5.php.expected.json index 1498165..bb441c8 100644 --- a/tests/Validation/cases/constants5.php.expected.json +++ b/tests/Validation/cases/constants5.php.expected.json @@ -9,6 +9,7 @@ "fqn": "MyNamespace", "extends": [], "isGlobal": true, + "roamed": false, "isStatic": false, "canBeInstantiated": false, "symbolInformation": { @@ -27,6 +28,7 @@ "fqn": "MyNamespace\\Mbstring", "extends": [], "isGlobal": true, + "roamed": false, "isStatic": false, "canBeInstantiated": true, "symbolInformation": { @@ -45,6 +47,7 @@ "fqn": "MyNamespace\\Mbstring::MB_CASE_FOLD", "extends": [], "isGlobal": false, + "roamed": false, "isStatic": false, "canBeInstantiated": false, "symbolInformation": { diff --git a/tests/Validation/cases/constantsInFunctionParamDefault.php.expected.json b/tests/Validation/cases/constantsInFunctionParamDefault.php.expected.json index 3ff0ca1..8f9a212 100644 --- a/tests/Validation/cases/constantsInFunctionParamDefault.php.expected.json +++ b/tests/Validation/cases/constantsInFunctionParamDefault.php.expected.json @@ -9,6 +9,7 @@ "fqn": "A", "extends": [], "isGlobal": true, + "roamed": false, "isStatic": false, "canBeInstantiated": false, "symbolInformation": { @@ -27,6 +28,7 @@ "fqn": "A->b()", "extends": [], "isGlobal": false, + "roamed": false, "isStatic": false, "canBeInstantiated": false, "symbolInformation": { diff --git a/tests/Validation/cases/docBlocksOnNamespaceDefinition.php.expected.json b/tests/Validation/cases/docBlocksOnNamespaceDefinition.php.expected.json index d73ecb5..73f6bee 100644 --- a/tests/Validation/cases/docBlocksOnNamespaceDefinition.php.expected.json +++ b/tests/Validation/cases/docBlocksOnNamespaceDefinition.php.expected.json @@ -5,6 +5,7 @@ "fqn": "MyNamespace", "extends": [], "isGlobal": true, + "roamed": false, "isStatic": false, "canBeInstantiated": false, "symbolInformation": { diff --git a/tests/Validation/cases/exceptions1.php.expected.json b/tests/Validation/cases/exceptions1.php.expected.json index 4a13354..a4a71d1 100644 --- a/tests/Validation/cases/exceptions1.php.expected.json +++ b/tests/Validation/cases/exceptions1.php.expected.json @@ -9,6 +9,7 @@ "fqn": "MyNamespace", "extends": [], "isGlobal": true, + "roamed": false, "isStatic": false, "canBeInstantiated": false, "symbolInformation": { diff --git a/tests/Validation/cases/ifStatement1.php.expected.json b/tests/Validation/cases/ifStatement1.php.expected.json index 4375a2a..18efe9f 100644 --- a/tests/Validation/cases/ifStatement1.php.expected.json +++ b/tests/Validation/cases/ifStatement1.php.expected.json @@ -12,6 +12,7 @@ "fqn": "MyNamespace", "extends": [], "isGlobal": true, + "roamed": false, "isStatic": false, "canBeInstantiated": false, "symbolInformation": { diff --git a/tests/Validation/cases/interfaceProperty.php.expected.json b/tests/Validation/cases/interfaceProperty.php.expected.json index 896d09e..178834d 100644 --- a/tests/Validation/cases/interfaceProperty.php.expected.json +++ b/tests/Validation/cases/interfaceProperty.php.expected.json @@ -5,6 +5,7 @@ "fqn": "A", "extends": [], "isGlobal": true, + "roamed": false, "isStatic": false, "canBeInstantiated": false, "symbolInformation": { diff --git a/tests/Validation/cases/magicConstantsShouldBeGlobal.php.expected.json b/tests/Validation/cases/magicConstantsShouldBeGlobal.php.expected.json index b61333f..f62d214 100644 --- a/tests/Validation/cases/magicConstantsShouldBeGlobal.php.expected.json +++ b/tests/Validation/cases/magicConstantsShouldBeGlobal.php.expected.json @@ -12,6 +12,7 @@ "fqn": "B", "extends": [], "isGlobal": true, + "roamed": false, "isStatic": false, "canBeInstantiated": false, "symbolInformation": { diff --git a/tests/Validation/cases/magicConsts.php.expected.json b/tests/Validation/cases/magicConsts.php.expected.json index 74cf36b..a37791b 100644 --- a/tests/Validation/cases/magicConsts.php.expected.json +++ b/tests/Validation/cases/magicConsts.php.expected.json @@ -9,6 +9,7 @@ "fqn": "A", "extends": [], "isGlobal": true, + "roamed": false, "isStatic": false, "canBeInstantiated": true, "symbolInformation": { @@ -27,6 +28,7 @@ "fqn": "A::$deprecationsTriggered", "extends": [], "isGlobal": false, + "roamed": false, "isStatic": true, "canBeInstantiated": false, "symbolInformation": { diff --git a/tests/Validation/cases/memberAccess1.php.expected.json b/tests/Validation/cases/memberAccess1.php.expected.json index efe4d3a..7f9630a 100644 --- a/tests/Validation/cases/memberAccess1.php.expected.json +++ b/tests/Validation/cases/memberAccess1.php.expected.json @@ -12,6 +12,7 @@ "fqn": "MyNamespace", "extends": [], "isGlobal": true, + "roamed": false, "isStatic": false, "canBeInstantiated": false, "symbolInformation": { @@ -30,6 +31,7 @@ "fqn": "MyNamespace\\A", "extends": [], "isGlobal": true, + "roamed": false, "isStatic": false, "canBeInstantiated": true, "symbolInformation": { @@ -48,6 +50,7 @@ "fqn": "MyNamespace\\A::a()", "extends": [], "isGlobal": false, + "roamed": false, "isStatic": true, "canBeInstantiated": false, "symbolInformation": { diff --git a/tests/Validation/cases/memberAccess2.php.expected.json b/tests/Validation/cases/memberAccess2.php.expected.json index 1725a5b..7b3ce1d 100644 --- a/tests/Validation/cases/memberAccess2.php.expected.json +++ b/tests/Validation/cases/memberAccess2.php.expected.json @@ -12,6 +12,7 @@ "fqn": "MyNamespace", "extends": [], "isGlobal": true, + "roamed": false, "isStatic": false, "canBeInstantiated": false, "symbolInformation": { @@ -30,6 +31,7 @@ "fqn": "MyNamespace\\A", "extends": [], "isGlobal": true, + "roamed": false, "isStatic": false, "canBeInstantiated": true, "symbolInformation": { @@ -48,6 +50,7 @@ "fqn": "MyNamespace\\A::a()", "extends": [], "isGlobal": false, + "roamed": false, "isStatic": true, "canBeInstantiated": false, "symbolInformation": { diff --git a/tests/Validation/cases/memberAccess3.php.expected.json b/tests/Validation/cases/memberAccess3.php.expected.json index 9b1b4ee..520dae8 100644 --- a/tests/Validation/cases/memberAccess3.php.expected.json +++ b/tests/Validation/cases/memberAccess3.php.expected.json @@ -27,6 +27,7 @@ "fqn": "MyNamespace", "extends": [], "isGlobal": true, + "roamed": false, "isStatic": false, "canBeInstantiated": false, "symbolInformation": { @@ -45,6 +46,7 @@ "fqn": "MyNamespace\\A", "extends": [], "isGlobal": true, + "roamed": false, "isStatic": false, "canBeInstantiated": true, "symbolInformation": { @@ -63,6 +65,7 @@ "fqn": "MyNamespace\\A::getInitializer()", "extends": [], "isGlobal": false, + "roamed": false, "isStatic": true, "canBeInstantiated": false, "symbolInformation": { diff --git a/tests/Validation/cases/memberAccess4.php.expected.json b/tests/Validation/cases/memberAccess4.php.expected.json index 3e26d72..1d51b85 100644 --- a/tests/Validation/cases/memberAccess4.php.expected.json +++ b/tests/Validation/cases/memberAccess4.php.expected.json @@ -18,6 +18,7 @@ "fqn": "MyNamespace", "extends": [], "isGlobal": true, + "roamed": false, "isStatic": false, "canBeInstantiated": false, "symbolInformation": { @@ -36,6 +37,7 @@ "fqn": "MyNamespace\\A", "extends": [], "isGlobal": true, + "roamed": false, "isStatic": false, "canBeInstantiated": true, "symbolInformation": { @@ -54,6 +56,7 @@ "fqn": "MyNamespace\\A->testRequest()", "extends": [], "isGlobal": false, + "roamed": false, "isStatic": false, "canBeInstantiated": false, "symbolInformation": { diff --git a/tests/Validation/cases/memberAccess5.php.expected.json b/tests/Validation/cases/memberAccess5.php.expected.json index c7158b6..57aca0a 100644 --- a/tests/Validation/cases/memberAccess5.php.expected.json +++ b/tests/Validation/cases/memberAccess5.php.expected.json @@ -9,6 +9,7 @@ "fqn": "MyNamespace", "extends": [], "isGlobal": true, + "roamed": false, "isStatic": false, "canBeInstantiated": false, "symbolInformation": { @@ -27,6 +28,7 @@ "fqn": "MyNamespace\\ParseErrorsTest", "extends": [], "isGlobal": true, + "roamed": false, "isStatic": false, "canBeInstantiated": true, "symbolInformation": { @@ -45,6 +47,7 @@ "fqn": "MyNamespace\\ParseErrorsTest->setUp()", "extends": [], "isGlobal": false, + "roamed": false, "isStatic": false, "canBeInstantiated": false, "symbolInformation": { diff --git a/tests/Validation/cases/memberCall1.php.expected.json b/tests/Validation/cases/memberCall1.php.expected.json index bd31b2f..416a705 100644 --- a/tests/Validation/cases/memberCall1.php.expected.json +++ b/tests/Validation/cases/memberCall1.php.expected.json @@ -15,6 +15,7 @@ "fqn": "MyNamespace", "extends": [], "isGlobal": true, + "roamed": false, "isStatic": false, "canBeInstantiated": false, "symbolInformation": { @@ -33,6 +34,7 @@ "fqn": "MyNamespace\\ParseErrorsTest", "extends": [], "isGlobal": true, + "roamed": false, "isStatic": false, "canBeInstantiated": true, "symbolInformation": { @@ -51,6 +53,7 @@ "fqn": "MyNamespace\\ParseErrorsTest->setAccount()", "extends": [], "isGlobal": false, + "roamed": false, "isStatic": false, "canBeInstantiated": false, "symbolInformation": { diff --git a/tests/Validation/cases/methodReturnType.php.expected.json b/tests/Validation/cases/methodReturnType.php.expected.json index 860f276..54d79d6 100644 --- a/tests/Validation/cases/methodReturnType.php.expected.json +++ b/tests/Validation/cases/methodReturnType.php.expected.json @@ -9,6 +9,7 @@ "fqn": "FooClass", "extends": [], "isGlobal": true, + "roamed": false, "isStatic": false, "canBeInstantiated": true, "symbolInformation": { @@ -27,6 +28,7 @@ "fqn": "FooClass->foo()", "extends": [], "isGlobal": false, + "roamed": false, "isStatic": false, "canBeInstantiated": false, "symbolInformation": { diff --git a/tests/Validation/cases/multipleNamespaces.php.expected.json b/tests/Validation/cases/multipleNamespaces.php.expected.json index 3533e8c..30fe596 100644 --- a/tests/Validation/cases/multipleNamespaces.php.expected.json +++ b/tests/Validation/cases/multipleNamespaces.php.expected.json @@ -18,6 +18,7 @@ "fqn": "MyNamespace1", "extends": [], "isGlobal": true, + "roamed": false, "isStatic": false, "canBeInstantiated": false, "symbolInformation": { @@ -36,6 +37,7 @@ "fqn": "MyNamespace1\\B", "extends": [], "isGlobal": true, + "roamed": false, "isStatic": false, "canBeInstantiated": true, "symbolInformation": { @@ -54,6 +56,7 @@ "fqn": "MyNamespace1\\B->b()", "extends": [], "isGlobal": false, + "roamed": false, "isStatic": false, "canBeInstantiated": false, "symbolInformation": { @@ -73,6 +76,7 @@ "fqn": "MyNamespace2", "extends": [], "isGlobal": true, + "roamed": false, "isStatic": false, "canBeInstantiated": false, "symbolInformation": { @@ -93,6 +97,7 @@ "MyNamespace2\\MyNamespace1\\B" ], "isGlobal": true, + "roamed": false, "isStatic": false, "canBeInstantiated": true, "symbolInformation": { @@ -111,6 +116,7 @@ "fqn": "MyNamespace2\\A->a()", "extends": [], "isGlobal": false, + "roamed": false, "isStatic": false, "canBeInstantiated": false, "symbolInformation": { diff --git a/tests/Validation/cases/multiplePreceedingComments.php.expected.json b/tests/Validation/cases/multiplePreceedingComments.php.expected.json index c331b5e..5ca3dd7 100644 --- a/tests/Validation/cases/multiplePreceedingComments.php.expected.json +++ b/tests/Validation/cases/multiplePreceedingComments.php.expected.json @@ -5,6 +5,7 @@ "fqn": "Foo", "extends": [], "isGlobal": true, + "roamed": false, "isStatic": false, "canBeInstantiated": true, "symbolInformation": { @@ -23,6 +24,7 @@ "fqn": "Foo->fn()", "extends": [], "isGlobal": false, + "roamed": false, "isStatic": false, "canBeInstantiated": false, "symbolInformation": { diff --git a/tests/Validation/cases/nameToken.php.expected.json b/tests/Validation/cases/nameToken.php.expected.json index af73f78..0ecd53f 100644 --- a/tests/Validation/cases/nameToken.php.expected.json +++ b/tests/Validation/cases/nameToken.php.expected.json @@ -5,6 +5,7 @@ "fqn": "A", "extends": [], "isGlobal": true, + "roamed": false, "isStatic": false, "canBeInstantiated": true, "symbolInformation": { @@ -23,6 +24,7 @@ "fqn": "A->b()", "extends": [], "isGlobal": false, + "roamed": false, "isStatic": false, "canBeInstantiated": false, "symbolInformation": { diff --git a/tests/Validation/cases/namespaces2.php.expected.json b/tests/Validation/cases/namespaces2.php.expected.json index 903d544..42243e5 100644 --- a/tests/Validation/cases/namespaces2.php.expected.json +++ b/tests/Validation/cases/namespaces2.php.expected.json @@ -18,6 +18,7 @@ "fqn": "MyNamespace1", "extends": [], "isGlobal": true, + "roamed": false, "isStatic": false, "canBeInstantiated": false, "symbolInformation": { diff --git a/tests/Validation/cases/namespaces5.php.expected.json b/tests/Validation/cases/namespaces5.php.expected.json index ccc22fd..5ffe02d 100644 --- a/tests/Validation/cases/namespaces5.php.expected.json +++ b/tests/Validation/cases/namespaces5.php.expected.json @@ -27,6 +27,7 @@ "fqn": "B", "extends": [], "isGlobal": true, + "roamed": false, "isStatic": false, "canBeInstantiated": false, "symbolInformation": { diff --git a/tests/Validation/cases/namespaces6.php.expected.json b/tests/Validation/cases/namespaces6.php.expected.json index 874ee7f..1657f28 100644 --- a/tests/Validation/cases/namespaces6.php.expected.json +++ b/tests/Validation/cases/namespaces6.php.expected.json @@ -5,6 +5,7 @@ "fqn": "A\\B", "extends": [], "isGlobal": true, + "roamed": false, "isStatic": false, "canBeInstantiated": false, "symbolInformation": { diff --git a/tests/Validation/cases/namespaces8.php.expected.json b/tests/Validation/cases/namespaces8.php.expected.json index 7a77f7c..71017d9 100644 --- a/tests/Validation/cases/namespaces8.php.expected.json +++ b/tests/Validation/cases/namespaces8.php.expected.json @@ -15,6 +15,7 @@ "fqn": "LanguageServer\\Tests\\Utils", "extends": [], "isGlobal": true, + "roamed": false, "isStatic": false, "canBeInstantiated": false, "symbolInformation": { diff --git a/tests/Validation/cases/objectCreation.php.expected.json b/tests/Validation/cases/objectCreation.php.expected.json index a0e8f72..a8fce0f 100644 --- a/tests/Validation/cases/objectCreation.php.expected.json +++ b/tests/Validation/cases/objectCreation.php.expected.json @@ -9,6 +9,7 @@ "fqn": "MyNamespace", "extends": [], "isGlobal": true, + "roamed": false, "isStatic": false, "canBeInstantiated": false, "symbolInformation": { @@ -27,6 +28,7 @@ "fqn": "MyNamespace\\A", "extends": [], "isGlobal": true, + "roamed": false, "isStatic": false, "canBeInstantiated": true, "symbolInformation": { @@ -45,6 +47,7 @@ "fqn": "MyNamespace\\A->a()", "extends": [], "isGlobal": false, + "roamed": false, "isStatic": false, "canBeInstantiated": false, "symbolInformation": { diff --git a/tests/Validation/cases/objectCreation2.php.expected.json b/tests/Validation/cases/objectCreation2.php.expected.json index 0119bf7..2ec8314 100644 --- a/tests/Validation/cases/objectCreation2.php.expected.json +++ b/tests/Validation/cases/objectCreation2.php.expected.json @@ -12,6 +12,7 @@ "fqn": "MyNamespace", "extends": [], "isGlobal": true, + "roamed": false, "isStatic": false, "canBeInstantiated": false, "symbolInformation": { @@ -30,6 +31,7 @@ "fqn": "MyNamespace\\B", "extends": [], "isGlobal": true, + "roamed": false, "isStatic": false, "canBeInstantiated": true, "symbolInformation": { @@ -48,6 +50,7 @@ "fqn": "MyNamespace\\A", "extends": [], "isGlobal": true, + "roamed": false, "isStatic": false, "canBeInstantiated": true, "symbolInformation": { @@ -66,6 +69,7 @@ "fqn": "MyNamespace\\A->a()", "extends": [], "isGlobal": false, + "roamed": false, "isStatic": false, "canBeInstantiated": false, "symbolInformation": { diff --git a/tests/Validation/cases/objectCreation3.php.expected.json b/tests/Validation/cases/objectCreation3.php.expected.json index 75cc011..f0cc31a 100644 --- a/tests/Validation/cases/objectCreation3.php.expected.json +++ b/tests/Validation/cases/objectCreation3.php.expected.json @@ -9,6 +9,7 @@ "fqn": "A", "extends": [], "isGlobal": true, + "roamed": false, "isStatic": false, "canBeInstantiated": true, "symbolInformation": { @@ -27,6 +28,7 @@ "fqn": "A->a()", "extends": [], "isGlobal": false, + "roamed": false, "isStatic": false, "canBeInstantiated": false, "symbolInformation": { diff --git a/tests/Validation/cases/param1.php.expected.json b/tests/Validation/cases/param1.php.expected.json index ee952f3..33c99db 100644 --- a/tests/Validation/cases/param1.php.expected.json +++ b/tests/Validation/cases/param1.php.expected.json @@ -9,6 +9,7 @@ "fqn": "MyNamespace", "extends": [], "isGlobal": true, + "roamed": false, "isStatic": false, "canBeInstantiated": false, "symbolInformation": { @@ -27,6 +28,7 @@ "fqn": "MyNamespace\\init()", "extends": [], "isGlobal": true, + "roamed": false, "isStatic": false, "canBeInstantiated": false, "symbolInformation": { diff --git a/tests/Validation/cases/parent1.php.expected.json b/tests/Validation/cases/parent1.php.expected.json index 961b35b..eab232e 100644 --- a/tests/Validation/cases/parent1.php.expected.json +++ b/tests/Validation/cases/parent1.php.expected.json @@ -12,6 +12,7 @@ "fqn": "MyNamespace", "extends": [], "isGlobal": true, + "roamed": false, "isStatic": false, "canBeInstantiated": false, "symbolInformation": { @@ -30,6 +31,7 @@ "fqn": "MyNamespace\\B", "extends": [], "isGlobal": true, + "roamed": false, "isStatic": false, "canBeInstantiated": true, "symbolInformation": { @@ -48,6 +50,7 @@ "fqn": "MyNamespace\\B->b()", "extends": [], "isGlobal": false, + "roamed": false, "isStatic": false, "canBeInstantiated": false, "symbolInformation": { @@ -69,6 +72,7 @@ "MyNamespace\\B" ], "isGlobal": true, + "roamed": false, "isStatic": false, "canBeInstantiated": true, "symbolInformation": { @@ -87,6 +91,7 @@ "fqn": "MyNamespace\\A->a()", "extends": [], "isGlobal": false, + "roamed": false, "isStatic": false, "canBeInstantiated": false, "symbolInformation": { diff --git a/tests/Validation/cases/parent3.php.expected.json b/tests/Validation/cases/parent3.php.expected.json index e2cf2c6..aedb4b2 100644 --- a/tests/Validation/cases/parent3.php.expected.json +++ b/tests/Validation/cases/parent3.php.expected.json @@ -15,6 +15,7 @@ "fqn": "MyNamespace", "extends": [], "isGlobal": true, + "roamed": false, "isStatic": false, "canBeInstantiated": false, "symbolInformation": { @@ -33,6 +34,7 @@ "fqn": "MyNamespace\\B", "extends": [], "isGlobal": true, + "roamed": false, "isStatic": false, "canBeInstantiated": true, "symbolInformation": { @@ -51,6 +53,7 @@ "fqn": "MyNamespace\\B->b()", "extends": [], "isGlobal": false, + "roamed": false, "isStatic": false, "canBeInstantiated": false, "symbolInformation": { @@ -72,6 +75,7 @@ "MyNamespace\\B" ], "isGlobal": true, + "roamed": false, "isStatic": false, "canBeInstantiated": true, "symbolInformation": { @@ -90,6 +94,7 @@ "fqn": "MyNamespace\\A->a()", "extends": [], "isGlobal": false, + "roamed": false, "isStatic": false, "canBeInstantiated": false, "symbolInformation": { diff --git a/tests/Validation/cases/propertyName1.php.expected.json b/tests/Validation/cases/propertyName1.php.expected.json index 0a37c20..42b2ee9 100644 --- a/tests/Validation/cases/propertyName1.php.expected.json +++ b/tests/Validation/cases/propertyName1.php.expected.json @@ -5,6 +5,7 @@ "fqn": "MyClass", "extends": [], "isGlobal": true, + "roamed": false, "isStatic": false, "canBeInstantiated": true, "symbolInformation": { @@ -23,6 +24,7 @@ "fqn": "MyClass->mainPropertyName", "extends": [], "isGlobal": false, + "roamed": false, "isStatic": false, "canBeInstantiated": false, "symbolInformation": { diff --git a/tests/Validation/cases/propertyName2.php.expected.json b/tests/Validation/cases/propertyName2.php.expected.json index 9cba945..5a5c914 100644 --- a/tests/Validation/cases/propertyName2.php.expected.json +++ b/tests/Validation/cases/propertyName2.php.expected.json @@ -5,6 +5,7 @@ "fqn": "MyClass", "extends": [], "isGlobal": true, + "roamed": false, "isStatic": false, "canBeInstantiated": true, "symbolInformation": { @@ -23,6 +24,7 @@ "fqn": "MyClass->mainPropertyName", "extends": [], "isGlobal": false, + "roamed": false, "isStatic": false, "canBeInstantiated": false, "symbolInformation": { diff --git a/tests/Validation/cases/returnType.php.expected.json b/tests/Validation/cases/returnType.php.expected.json index 6ddca7e..cf9cc63 100644 --- a/tests/Validation/cases/returnType.php.expected.json +++ b/tests/Validation/cases/returnType.php.expected.json @@ -12,6 +12,7 @@ "fqn": "TestNamespace", "extends": [], "isGlobal": true, + "roamed": false, "isStatic": false, "canBeInstantiated": false, "symbolInformation": { @@ -30,6 +31,7 @@ "fqn": "TestNamespace\\whatever()", "extends": [], "isGlobal": true, + "roamed": false, "isStatic": false, "canBeInstantiated": false, "symbolInformation": { diff --git a/tests/Validation/cases/scopedPropertyAccess.php.expected.json b/tests/Validation/cases/scopedPropertyAccess.php.expected.json index 3eeda77..52b6e7a 100644 --- a/tests/Validation/cases/scopedPropertyAccess.php.expected.json +++ b/tests/Validation/cases/scopedPropertyAccess.php.expected.json @@ -12,6 +12,7 @@ "fqn": "MyNamespace", "extends": [], "isGlobal": true, + "roamed": false, "isStatic": false, "canBeInstantiated": false, "symbolInformation": { @@ -30,6 +31,7 @@ "fqn": "MyNamespace\\A", "extends": [], "isGlobal": true, + "roamed": false, "isStatic": false, "canBeInstantiated": true, "symbolInformation": { @@ -48,6 +50,7 @@ "fqn": "MyNamespace\\A::a()", "extends": [], "isGlobal": false, + "roamed": false, "isStatic": true, "canBeInstantiated": false, "symbolInformation": { diff --git a/tests/Validation/cases/scopedPropertyAccess2.php.expected.json b/tests/Validation/cases/scopedPropertyAccess2.php.expected.json index 69ac4c7..e5f6850 100644 --- a/tests/Validation/cases/scopedPropertyAccess2.php.expected.json +++ b/tests/Validation/cases/scopedPropertyAccess2.php.expected.json @@ -9,6 +9,7 @@ "fqn": "MyNamespace", "extends": [], "isGlobal": true, + "roamed": false, "isStatic": false, "canBeInstantiated": false, "symbolInformation": { diff --git a/tests/Validation/cases/scopedPropertyAccess3.php.expected.json b/tests/Validation/cases/scopedPropertyAccess3.php.expected.json index 81cbfb6..aa508bc 100644 --- a/tests/Validation/cases/scopedPropertyAccess3.php.expected.json +++ b/tests/Validation/cases/scopedPropertyAccess3.php.expected.json @@ -12,6 +12,7 @@ "fqn": "A", "extends": [], "isGlobal": true, + "roamed": false, "isStatic": false, "canBeInstantiated": true, "symbolInformation": { @@ -30,6 +31,7 @@ "fqn": "A::$a", "extends": [], "isGlobal": false, + "roamed": false, "isStatic": true, "canBeInstantiated": false, "symbolInformation": { diff --git a/tests/Validation/cases/scopedPropertyAccess5.php.expected.json b/tests/Validation/cases/scopedPropertyAccess5.php.expected.json index 27f0509..bd4ee70 100644 --- a/tests/Validation/cases/scopedPropertyAccess5.php.expected.json +++ b/tests/Validation/cases/scopedPropertyAccess5.php.expected.json @@ -18,6 +18,7 @@ "fqn": "TestClass", "extends": [], "isGlobal": true, + "roamed": false, "isStatic": false, "canBeInstantiated": true, "symbolInformation": { @@ -36,6 +37,7 @@ "fqn": "TestClass::$testProperty", "extends": [], "isGlobal": false, + "roamed": false, "isStatic": true, "canBeInstantiated": false, "symbolInformation": { diff --git a/tests/Validation/cases/self1.php.expected.json b/tests/Validation/cases/self1.php.expected.json index 41525d8..eb37fc7 100644 --- a/tests/Validation/cases/self1.php.expected.json +++ b/tests/Validation/cases/self1.php.expected.json @@ -15,6 +15,7 @@ "fqn": "MyNamespace", "extends": [], "isGlobal": true, + "roamed": false, "isStatic": false, "canBeInstantiated": false, "symbolInformation": { @@ -33,6 +34,7 @@ "fqn": "MyNamespace\\B", "extends": [], "isGlobal": true, + "roamed": false, "isStatic": false, "canBeInstantiated": true, "symbolInformation": { @@ -51,6 +53,7 @@ "fqn": "MyNamespace\\B->b()", "extends": [], "isGlobal": false, + "roamed": false, "isStatic": false, "canBeInstantiated": false, "symbolInformation": { @@ -72,6 +75,7 @@ "MyNamespace\\B" ], "isGlobal": true, + "roamed": false, "isStatic": false, "canBeInstantiated": true, "symbolInformation": { @@ -90,6 +94,7 @@ "fqn": "MyNamespace\\A->a()", "extends": [], "isGlobal": false, + "roamed": false, "isStatic": false, "canBeInstantiated": false, "symbolInformation": { diff --git a/tests/Validation/cases/self2.php.expected.json b/tests/Validation/cases/self2.php.expected.json index eb31aba..2280b1a 100644 --- a/tests/Validation/cases/self2.php.expected.json +++ b/tests/Validation/cases/self2.php.expected.json @@ -15,6 +15,7 @@ "fqn": "MyNamespace", "extends": [], "isGlobal": true, + "roamed": false, "isStatic": false, "canBeInstantiated": false, "symbolInformation": { @@ -33,6 +34,7 @@ "fqn": "MyNamespace\\B", "extends": [], "isGlobal": true, + "roamed": false, "isStatic": false, "canBeInstantiated": true, "symbolInformation": { @@ -51,6 +53,7 @@ "fqn": "MyNamespace\\B->b()", "extends": [], "isGlobal": false, + "roamed": false, "isStatic": false, "canBeInstantiated": false, "symbolInformation": { @@ -72,6 +75,7 @@ "MyNamespace\\B" ], "isGlobal": true, + "roamed": false, "isStatic": false, "canBeInstantiated": true, "symbolInformation": { @@ -90,6 +94,7 @@ "fqn": "MyNamespace\\A->a()", "extends": [], "isGlobal": false, + "roamed": false, "isStatic": false, "canBeInstantiated": false, "symbolInformation": { diff --git a/tests/Validation/cases/self3.php.expected.json b/tests/Validation/cases/self3.php.expected.json index f50b80c..3f69299 100644 --- a/tests/Validation/cases/self3.php.expected.json +++ b/tests/Validation/cases/self3.php.expected.json @@ -15,6 +15,7 @@ "fqn": "MyNamespace", "extends": [], "isGlobal": true, + "roamed": false, "isStatic": false, "canBeInstantiated": false, "symbolInformation": { @@ -33,6 +34,7 @@ "fqn": "MyNamespace\\B", "extends": [], "isGlobal": true, + "roamed": false, "isStatic": false, "canBeInstantiated": true, "symbolInformation": { @@ -51,6 +53,7 @@ "fqn": "MyNamespace\\B->b()", "extends": [], "isGlobal": false, + "roamed": false, "isStatic": false, "canBeInstantiated": false, "symbolInformation": { @@ -72,6 +75,7 @@ "MyNamespace\\B" ], "isGlobal": true, + "roamed": false, "isStatic": false, "canBeInstantiated": true, "symbolInformation": { @@ -90,6 +94,7 @@ "fqn": "MyNamespace\\A->a()", "extends": [], "isGlobal": false, + "roamed": false, "isStatic": false, "canBeInstantiated": false, "symbolInformation": { diff --git a/tests/Validation/cases/self4.php.expected.json b/tests/Validation/cases/self4.php.expected.json index 4946001..ec3ae07 100644 --- a/tests/Validation/cases/self4.php.expected.json +++ b/tests/Validation/cases/self4.php.expected.json @@ -24,6 +24,7 @@ "fqn": "MyNamespace", "extends": [], "isGlobal": true, + "roamed": false, "isStatic": false, "canBeInstantiated": false, "symbolInformation": { @@ -42,6 +43,7 @@ "fqn": "MyNamespace\\A", "extends": [], "isGlobal": true, + "roamed": false, "isStatic": false, "canBeInstantiated": true, "symbolInformation": { @@ -60,6 +62,7 @@ "fqn": "MyNamespace\\A::suite()", "extends": [], "isGlobal": false, + "roamed": false, "isStatic": true, "canBeInstantiated": false, "symbolInformation": { diff --git a/tests/Validation/cases/self5.php.expected.json b/tests/Validation/cases/self5.php.expected.json index e1c99af..6727689 100644 --- a/tests/Validation/cases/self5.php.expected.json +++ b/tests/Validation/cases/self5.php.expected.json @@ -9,6 +9,7 @@ "fqn": "MyNamespace", "extends": [], "isGlobal": true, + "roamed": false, "isStatic": false, "canBeInstantiated": false, "symbolInformation": { @@ -27,6 +28,7 @@ "fqn": "MyNamespace\\A", "extends": [], "isGlobal": true, + "roamed": false, "isStatic": false, "canBeInstantiated": true, "symbolInformation": { @@ -45,6 +47,7 @@ "fqn": "MyNamespace\\A->typesProvider()", "extends": [], "isGlobal": false, + "roamed": false, "isStatic": false, "canBeInstantiated": false, "symbolInformation": { diff --git a/tests/Validation/cases/static1.php.expected.json b/tests/Validation/cases/static1.php.expected.json index ca49245..69f8de0 100644 --- a/tests/Validation/cases/static1.php.expected.json +++ b/tests/Validation/cases/static1.php.expected.json @@ -15,6 +15,7 @@ "fqn": "MyNamespace", "extends": [], "isGlobal": true, + "roamed": false, "isStatic": false, "canBeInstantiated": false, "symbolInformation": { @@ -33,6 +34,7 @@ "fqn": "MyNamespace\\B", "extends": [], "isGlobal": true, + "roamed": false, "isStatic": false, "canBeInstantiated": true, "symbolInformation": { @@ -51,6 +53,7 @@ "fqn": "MyNamespace\\B->b()", "extends": [], "isGlobal": false, + "roamed": false, "isStatic": false, "canBeInstantiated": false, "symbolInformation": { @@ -72,6 +75,7 @@ "MyNamespace\\B" ], "isGlobal": true, + "roamed": false, "isStatic": false, "canBeInstantiated": true, "symbolInformation": { @@ -90,6 +94,7 @@ "fqn": "MyNamespace\\A->a()", "extends": [], "isGlobal": false, + "roamed": false, "isStatic": false, "canBeInstantiated": false, "symbolInformation": { diff --git a/tests/Validation/cases/static2.php.expected.json b/tests/Validation/cases/static2.php.expected.json index 06a0627..17f9a66 100644 --- a/tests/Validation/cases/static2.php.expected.json +++ b/tests/Validation/cases/static2.php.expected.json @@ -15,6 +15,7 @@ "fqn": "MyNamespace", "extends": [], "isGlobal": true, + "roamed": false, "isStatic": false, "canBeInstantiated": false, "symbolInformation": { @@ -33,6 +34,7 @@ "fqn": "MyNamespace\\B", "extends": [], "isGlobal": true, + "roamed": false, "isStatic": false, "canBeInstantiated": true, "symbolInformation": { @@ -51,6 +53,7 @@ "fqn": "MyNamespace\\B->b()", "extends": [], "isGlobal": false, + "roamed": false, "isStatic": false, "canBeInstantiated": false, "symbolInformation": { @@ -72,6 +75,7 @@ "MyNamespace\\B" ], "isGlobal": true, + "roamed": false, "isStatic": false, "canBeInstantiated": true, "symbolInformation": { @@ -90,6 +94,7 @@ "fqn": "MyNamespace\\A->a()", "extends": [], "isGlobal": false, + "roamed": false, "isStatic": false, "canBeInstantiated": false, "symbolInformation": { diff --git a/tests/Validation/cases/static3.php.expected.json b/tests/Validation/cases/static3.php.expected.json index 745bd56..f6e5189 100644 --- a/tests/Validation/cases/static3.php.expected.json +++ b/tests/Validation/cases/static3.php.expected.json @@ -15,6 +15,7 @@ "fqn": "MyNamespace", "extends": [], "isGlobal": true, + "roamed": false, "isStatic": false, "canBeInstantiated": false, "symbolInformation": { @@ -33,6 +34,7 @@ "fqn": "MyNamespace\\B", "extends": [], "isGlobal": true, + "roamed": false, "isStatic": false, "canBeInstantiated": true, "symbolInformation": { @@ -51,6 +53,7 @@ "fqn": "MyNamespace\\B->b()", "extends": [], "isGlobal": false, + "roamed": false, "isStatic": false, "canBeInstantiated": false, "symbolInformation": { @@ -72,6 +75,7 @@ "MyNamespace\\B" ], "isGlobal": true, + "roamed": false, "isStatic": false, "canBeInstantiated": true, "symbolInformation": { @@ -90,6 +94,7 @@ "fqn": "MyNamespace\\A->a()", "extends": [], "isGlobal": false, + "roamed": false, "isStatic": false, "canBeInstantiated": false, "symbolInformation": { diff --git a/tests/Validation/cases/static4.php.expected.json b/tests/Validation/cases/static4.php.expected.json index 67c677a..e1e371f 100644 --- a/tests/Validation/cases/static4.php.expected.json +++ b/tests/Validation/cases/static4.php.expected.json @@ -12,6 +12,7 @@ "fqn": "MyNamespace", "extends": [], "isGlobal": true, + "roamed": false, "isStatic": false, "canBeInstantiated": false, "symbolInformation": { @@ -32,6 +33,7 @@ "MyNamespace\\B" ], "isGlobal": true, + "roamed": false, "isStatic": false, "canBeInstantiated": true, "symbolInformation": { @@ -50,6 +52,7 @@ "fqn": "MyNamespace\\A->a()", "extends": [], "isGlobal": false, + "roamed": false, "isStatic": false, "canBeInstantiated": false, "symbolInformation": { diff --git a/tests/Validation/cases/staticMethodReturnType.php.expected.json b/tests/Validation/cases/staticMethodReturnType.php.expected.json index 21c989c..c178f0a 100644 --- a/tests/Validation/cases/staticMethodReturnType.php.expected.json +++ b/tests/Validation/cases/staticMethodReturnType.php.expected.json @@ -9,6 +9,7 @@ "fqn": "FooClass", "extends": [], "isGlobal": true, + "roamed": false, "isStatic": false, "canBeInstantiated": true, "symbolInformation": { @@ -27,6 +28,7 @@ "fqn": "FooClass::staticFoo()", "extends": [], "isGlobal": false, + "roamed": false, "isStatic": true, "canBeInstantiated": false, "symbolInformation": { @@ -46,6 +48,7 @@ "fqn": "FooClass->bar()", "extends": [], "isGlobal": false, + "roamed": false, "isStatic": false, "canBeInstantiated": false, "symbolInformation": { diff --git a/tests/Validation/cases/stringVariable.php.expected.json b/tests/Validation/cases/stringVariable.php.expected.json index 982dba5..61669c8 100644 --- a/tests/Validation/cases/stringVariable.php.expected.json +++ b/tests/Validation/cases/stringVariable.php.expected.json @@ -5,6 +5,7 @@ "fqn": "B", "extends": [], "isGlobal": true, + "roamed": false, "isStatic": false, "canBeInstantiated": true, "symbolInformation": { @@ -23,6 +24,7 @@ "fqn": "B->hi", "extends": [], "isGlobal": false, + "roamed": false, "isStatic": false, "canBeInstantiated": false, "symbolInformation": { @@ -42,6 +44,7 @@ "fqn": "B->a()", "extends": [], "isGlobal": false, + "roamed": false, "isStatic": false, "canBeInstantiated": false, "symbolInformation": { diff --git a/tests/Validation/cases/testQualifiedNameOutsideOfNamespace.php.expected.json b/tests/Validation/cases/testQualifiedNameOutsideOfNamespace.php.expected.json index 1f71b37..f686093 100644 --- a/tests/Validation/cases/testQualifiedNameOutsideOfNamespace.php.expected.json +++ b/tests/Validation/cases/testQualifiedNameOutsideOfNamespace.php.expected.json @@ -9,6 +9,7 @@ "fqn": "SomeNamespace", "extends": [], "isGlobal": true, + "roamed": false, "isStatic": false, "canBeInstantiated": false, "symbolInformation": { diff --git a/tests/Validation/cases/verifyFqsenOnClassProperty.php.expected.json b/tests/Validation/cases/verifyFqsenOnClassProperty.php.expected.json index d40ef63..f6851bf 100644 --- a/tests/Validation/cases/verifyFqsenOnClassProperty.php.expected.json +++ b/tests/Validation/cases/verifyFqsenOnClassProperty.php.expected.json @@ -12,6 +12,7 @@ "fqn": "Foo", "extends": [], "isGlobal": true, + "roamed": false, "isStatic": false, "canBeInstantiated": true, "symbolInformation": { @@ -30,6 +31,7 @@ "fqn": "Foo->bar", "extends": [], "isGlobal": false, + "roamed": false, "isStatic": false, "canBeInstantiated": false, "symbolInformation": { @@ -49,6 +51,7 @@ "fqn": "Foo->foo()", "extends": [], "isGlobal": false, + "roamed": false, "isStatic": false, "canBeInstantiated": false, "symbolInformation": { From a772d9a2d70e223efbc8147518c8756607dbae70 Mon Sep 17 00:00:00 2001 From: Felix Becker Date: Fri, 16 Jun 2017 20:31:29 +0200 Subject: [PATCH 12/14] Remove content (#413) --- src/PhpDocument.php | 25 +++++++------------------ src/TreeAnalyzer.php | 3 +-- 2 files changed, 8 insertions(+), 20 deletions(-) diff --git a/src/PhpDocument.php b/src/PhpDocument.php index 7820701..ff3cf8b 100644 --- a/src/PhpDocument.php +++ b/src/PhpDocument.php @@ -46,13 +46,6 @@ class PhpDocument */ private $uri; - /** - * The content of the document - * - * @var string - */ - private $content; - /** * The AST of the document * @@ -133,8 +126,6 @@ class PhpDocument */ public function updateContent(string $content) { - $this->content = $content; - // Unregister old definitions if (isset($this->definitions)) { foreach ($this->definitions as $fqn => $definition) { @@ -182,10 +173,10 @@ class PhpDocument */ public function getFormattedText() { - if (empty($this->content)) { + if (empty($this->getContent())) { return []; } - return Formatter::format($this->content, $this->uri); + return Formatter::format($this->getContent(), $this->uri); } /** @@ -195,7 +186,7 @@ class PhpDocument */ public function getContent() { - return $this->content; + return $this->sourceFileNode->fileContents; } /** @@ -256,12 +247,10 @@ class PhpDocument */ public function getRange(Range $range) { - if ($this->content === null) { - return null; - } - $start = $range->start->toOffset($this->content); - $length = $range->end->toOffset($this->content) - $start; - return substr($this->content, $start, $length); + $content = $this->getContent(); + $start = $range->start->toOffset($content); + $length = $range->end->toOffset($content) - $start; + return substr($content, $start, $length); } /** diff --git a/src/TreeAnalyzer.php b/src/TreeAnalyzer.php index 3296ae8..2e34aa6 100644 --- a/src/TreeAnalyzer.php +++ b/src/TreeAnalyzer.php @@ -45,7 +45,6 @@ class TreeAnalyzer $this->parser = $parser; $this->docBlockFactory = $docBlockFactory; $this->definitionResolver = $definitionResolver; - $this->content = $content; $this->sourceFileNode = $this->parser->parseSourceFile($content, $uri); // TODO - docblock errors @@ -76,7 +75,7 @@ class TreeAnalyzer } if (($error = PhpParser\DiagnosticsProvider::checkDiagnostics($node)) !== null) { - $range = PhpParser\PositionUtilities::getRangeFromPosition($error->start, $error->length, $this->content); + $range = PhpParser\PositionUtilities::getRangeFromPosition($error->start, $error->length, $this->sourceFileNode->fileContents); $this->diagnostics[] = new Diagnostic( $error->message, From 548120314d96d5c58a8e3fcb36f1576aa54f721f Mon Sep 17 00:00:00 2001 From: Felix Becker Date: Fri, 16 Jun 2017 20:39:32 +0200 Subject: [PATCH 13/14] Revert "Update CodeSniffer" This reverts commit 663ccd5f2396489ffd49a09b196150de51e6711a. --- composer.json | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/composer.json b/composer.json index 5375d79..93dec97 100644 --- a/composer.json +++ b/composer.json @@ -31,7 +31,7 @@ "phpdocumentor/reflection-docblock": "^3.0", "sabre/event": "^5.0", "felixfbecker/advanced-json-rpc": "^2.0", - "squizlabs/php_codesniffer" : "^3.0", + "squizlabs/php_codesniffer" : "3.0.0RC3", "netresearch/jsonmapper": "^1.0", "webmozart/path-util": "^2.3", "webmozart/glob": "^4.1", @@ -49,8 +49,7 @@ "files" : [ "src/utils.php", "src/FqnUtilities.php", - "src/ParserHelpers.php", - "vendor/squizlabs/php_codesniffer/autoload.php" + "src/ParserHelpers.php" ] }, "autoload-dev": { From f97105740d68e185a71d378d974951855da2cbd1 Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Sat, 17 Jun 2017 01:53:08 -0700 Subject: [PATCH 14/14] Bump tolerant-php-parser (#415) * Bump tolerant-php-parser * Update test for new parser static support --- composer.json | 2 +- tests/Validation/cases/static4.php.expected.json | 3 --- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/composer.json b/composer.json index 93dec97..3b5d58a 100644 --- a/composer.json +++ b/composer.json @@ -38,7 +38,7 @@ "sabre/uri": "^2.0", "jetbrains/phpstorm-stubs": "dev-master", "composer/composer": "^1.3", - "Microsoft/tolerant-php-parser": "^0.0.2" + "Microsoft/tolerant-php-parser": "^0.0.3" }, "minimum-stability": "dev", "prefer-stable": true, diff --git a/tests/Validation/cases/static4.php.expected.json b/tests/Validation/cases/static4.php.expected.json index e1e371f..3d05ede 100644 --- a/tests/Validation/cases/static4.php.expected.json +++ b/tests/Validation/cases/static4.php.expected.json @@ -2,9 +2,6 @@ "references": { "MyNamespace\\B": [ "./static4.php" - ], - "static": [ - "./static4.php" ] }, "definitions": {