From 3dfe50572719c9fc37f228b6c0aa8cc3579c85ed Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Wed, 24 May 2017 11:26:53 -0700 Subject: [PATCH] Remove "Tolerant" alias - Now unnecessary - Makes type annotations more readable --- Performance.php | 4 +- src/CompletionProvider.php | 59 ++-- src/ComposerScripts.php | 4 +- src/DefinitionResolver.php | 303 +++++++++--------- src/FqnUtilities.php | 2 +- src/ParserHelpers.php | 111 +++---- src/PhpDocument.php | 23 +- src/PhpDocumentLoader.php | 6 +- src/Protocol/Location.php | 7 +- src/Protocol/Range.php | 7 +- src/Protocol/SymbolInformation.php | 41 +-- src/Server/TextDocument.php | 17 +- src/TreeAnalyzer.php | 43 +-- tests/DefinitionResolverTest.php | 10 +- tests/NodeVisitor/DefinitionCollectorTest.php | 37 +-- tests/PhpDocumentTest.php | 7 +- tests/Validation/ValidationTest.php | 4 +- 17 files changed, 348 insertions(+), 337 deletions(-) diff --git a/Performance.php b/Performance.php index 3a04bc7..312b726 100644 --- a/Performance.php +++ b/Performance.php @@ -8,7 +8,7 @@ use LanguageServer\Index\Index; use LanguageServer\ParserKind; use LanguageServer\PhpDocument; use LanguageServer\DefinitionResolver; -use Microsoft\PhpParser as Tolerant; +use Microsoft\PhpParser; use phpDocumentor\Reflection\DocBlockFactory; use RecursiveDirectoryIterator; use RecursiveIteratorIterator; @@ -58,7 +58,7 @@ foreach($frameworks as $framework) { $definitions = []; $definitionResolver = new DefinitionResolver($index); - $parser = new Tolerant\Parser(); + $parser = new PhpParser\Parser(); try { $document = new PhpDocument($testCaseFile, $fileContents, $index, $parser, $docBlockFactory, $definitionResolver); diff --git a/src/CompletionProvider.php b/src/CompletionProvider.php index 2b08496..fef59c2 100644 --- a/src/CompletionProvider.php +++ b/src/CompletionProvider.php @@ -13,7 +13,8 @@ use LanguageServer\Protocol\{ CompletionItemKind }; use function LanguageServer\{strStartsWith}; -use Microsoft\PhpParser as Tolerant; +use Microsoft\PhpParser; +use Microsoft\PhpParser\Node; class CompletionProvider { @@ -127,7 +128,7 @@ class CompletionProvider $offset = $node === null ? -1 : $pos->toOffset($node->getFileContents()); if ($node !== null && $offset > $node->getEndPosition() && - $node->parent->getLastChild() instanceof Tolerant\MissingToken + $node->parent->getLastChild() instanceof PhpParser\MissingToken ) { $node = $node->parent; } @@ -135,14 +136,14 @@ class CompletionProvider $list = new CompletionList; $list->isIncomplete = true; - if ($node instanceof Tolerant\Node\Expression\Variable && - $node->parent instanceof Tolerant\Node\Expression\ObjectCreationExpression && - $node->name instanceof Tolerant\MissingToken + if ($node instanceof Node\Expression\Variable && + $node->parent instanceof Node\Expression\ObjectCreationExpression && + $node->name instanceof PhpParser\MissingToken ) { $node = $node->parent; } - if ($node === null || $node instanceof Tolerant\Node\Statement\InlineHtml || $pos == new Position(0, 0)) { + if ($node === null || $node instanceof Node\Statement\InlineHtml || $pos == new Position(0, 0)) { $item = new CompletionItem('textEdit = new TextEdit( new Range($pos, $pos), @@ -152,9 +153,9 @@ class CompletionProvider } // VARIABLES elseif ( - $node instanceof Tolerant\Node\Expression\Variable && + $node instanceof Node\Expression\Variable && !( - $node->parent instanceof Tolerant\Node\Expression\ScopedPropertyAccessExpression && + $node->parent instanceof Node\Expression\ScopedPropertyAccessExpression && $node->parent->memberName === $node) ) { // Find variables, parameters and use statements in the scope @@ -176,7 +177,7 @@ class CompletionProvider // MEMBER ACCESS EXPRESSIONS // $a->c# // $a-># - elseif ($node instanceof Tolerant\Node\Expression\MemberAccessExpression) { + elseif ($node instanceof Node\Expression\MemberAccessExpression) { $prefixes = FqnUtilities::getFqnsFromType( $this->definitionResolver->resolveExpressionNodeToType($node->dereferencableExpression) ); @@ -204,8 +205,8 @@ class CompletionProvider // A\B\C::foo# // TODO: $a::# elseif ( - ($scoped = $node->parent) instanceof Tolerant\Node\Expression\ScopedPropertyAccessExpression || - ($scoped = $node) instanceof Tolerant\Node\Expression\ScopedPropertyAccessExpression + ($scoped = $node->parent) instanceof Node\Expression\ScopedPropertyAccessExpression || + ($scoped = $node) instanceof Node\Expression\ScopedPropertyAccessExpression ) { $prefixes = FqnUtilities::getFqnsFromType( $classType = $this->definitionResolver->resolveExpressionNodeToType($scoped->scopeResolutionQualifier) @@ -227,13 +228,13 @@ class CompletionProvider } } } elseif (ParserHelpers::isConstantFetch($node) || - ($creation = $node->parent) instanceof Tolerant\Node\Expression\ObjectCreationExpression || - (($creation = $node) instanceof Tolerant\Node\Expression\ObjectCreationExpression)) { + ($creation = $node->parent) instanceof Node\Expression\ObjectCreationExpression || + (($creation = $node) instanceof Node\Expression\ObjectCreationExpression)) { $class = isset($creation) ? $creation->classTypeDesignator : $node; - $prefix = $class instanceof Tolerant\Node\QualifiedName - ? (string)Tolerant\ResolvedName::buildName($class->nameParts, $class->getFileContents()) + $prefix = $class instanceof Node\QualifiedName + ? (string)PhpParser\ResolvedName::buildName($class->nameParts, $class->getFileContents()) : $class->getText($node->getFileContents()); $namespaceDefinition = $node->getNamespaceDefinition(); @@ -248,11 +249,11 @@ class CompletionProvider $fqnContainsPrefix = empty($prefix) || strpos($fqn, $prefix) !== false; if (($def->canBeInstantiated || ($def->isGlobal && !isset($creation))) && $fqnContainsPrefix) { if ($namespaceDefinition !== null && $namespaceDefinition->name !== null) { - $namespacePrefix = (string)Tolerant\ResolvedName::buildName($namespaceDefinition->name->nameParts, $node->getFileContents()); + $namespacePrefix = (string)PhpParser\ResolvedName::buildName($namespaceDefinition->name->nameParts, $node->getFileContents()); $isAliased = false; - $isNotFullyQualified = !($class instanceof Tolerant\Node\QualifiedName) || !$class->isFullyQualifiedName(); + $isNotFullyQualified = !($class instanceof Node\QualifiedName) || !$class->isFullyQualifiedName(); if ($isNotFullyQualified) { foreach ($namespaceImportTable as $alias => $name) { if (strStartsWith($fqn, $name)) { @@ -297,7 +298,7 @@ class CompletionProvider } } } elseif (ParserHelpers::isConstantFetch($node)) { - $prefix = (string) ($node->getResolvedName() ?? Tolerant\ResolvedName::buildName($node->nameParts, $node->getFileContents())); + $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 . ' '; @@ -333,11 +334,11 @@ class CompletionProvider * and at each level walk all previous siblings and their children to search for definitions * of that variable * - * @param Tolerant\Node $node + * @param Node $node * @param string $namePrefix Prefix to filter - * @return array + * @return array */ - private function suggestVariablesAtNode(Tolerant\Node $node, string $namePrefix = ''): array + private function suggestVariablesAtNode(Node $node, string $namePrefix = ''): array { $vars = []; @@ -375,7 +376,7 @@ class CompletionProvider } } - if ($level instanceof Tolerant\Node\Expression\AnonymousFunctionCreationExpression && $level->anonymousFunctionUseClause !== null) { + if ($level instanceof Node\Expression\AnonymousFunctionCreationExpression && $level->anonymousFunctionUseClause !== null) { foreach ($level->anonymousFunctionUseClause->useVariableNameList->getValues() as $use) { $useName = $use->getName(); if (empty($namePrefix) || strpos($useName, $namePrefix) !== false) { @@ -393,24 +394,24 @@ class CompletionProvider * * @param Node $node * @param string $namePrefix Prefix to filter - * @return Tolerant\Node\Expression\Variable[] + * @return Node\Expression\Variable[] */ - private function findVariableDefinitionsInNode(Tolerant\Node $node, string $namePrefix = ''): array + private function findVariableDefinitionsInNode(Node $node, string $namePrefix = ''): array { $vars = []; // If the child node is a variable assignment, save it $isAssignmentToVariable = function ($node) use ($namePrefix) { - return $node instanceof Tolerant\Node\Expression\AssignmentExpression - && $node->leftOperand instanceof Tolerant\Node\Expression\Variable + return $node instanceof Node\Expression\AssignmentExpression + && $node->leftOperand instanceof Node\Expression\Variable && (empty($namePrefix) || strpos($node->leftOperand->getName(), $namePrefix) !== false); }; $isNotFunctionLike = function($node) { return !( ParserHelpers::isFunctionLike($node) || - $node instanceof Tolerant\Node\Statement\ClassDeclaration || - $node instanceof Tolerant\Node\Statement\InterfaceDeclaration || - $node instanceof Tolerant\Node\Statement\TraitDeclaration + $node instanceof Node\Statement\ClassDeclaration || + $node instanceof Node\Statement\InterfaceDeclaration || + $node instanceof Node\Statement\TraitDeclaration ); }; diff --git a/src/ComposerScripts.php b/src/ComposerScripts.php index 11f0433..487c39d 100644 --- a/src/ComposerScripts.php +++ b/src/ComposerScripts.php @@ -10,7 +10,7 @@ use phpDocumentor\Reflection\DocBlockFactory; use Webmozart\PathUtil\Path; use Sabre\Uri; use function Sabre\Event\coroutine; -use Microsoft\PhpParser as Tolerant; +use Microsoft\PhpParser; foreach ([__DIR__ . '/../../../autoload.php', __DIR__ . '/../autoload.php', __DIR__ . '/../vendor/autoload.php'] as $file) { if (file_exists($file)) { @@ -30,7 +30,7 @@ class ComposerScripts $finder = new FileSystemFilesFinder; $contentRetriever = new FileSystemContentRetriever; $docBlockFactory = DocBlockFactory::createInstance(); - $parser = new Tolerant\Parser(); + $parser = new PhpParser\Parser(); $definitionResolver = new DefinitionResolver($index); $stubsLocation = null; diff --git a/src/DefinitionResolver.php b/src/DefinitionResolver.php index 9452507..abce69e 100644 --- a/src/DefinitionResolver.php +++ b/src/DefinitionResolver.php @@ -5,7 +5,8 @@ namespace LanguageServer; use LanguageServer\Index\ReadableIndex; use LanguageServer\Protocol\SymbolInformation; -use Microsoft\PhpParser as Tolerant; +use Microsoft\PhpParser; +use Microsoft\PhpParser\Node; use phpDocumentor\Reflection\{ DocBlock, DocBlockFactory, Fqsen, Type, TypeResolver, Types }; @@ -46,7 +47,7 @@ class DefinitionResolver /** * Builds the declaration line for a given node. Declarations with multiple lines are trimmed. * - * @param Tolerant\Node $node + * @param Node $node * @return string */ public function getDeclarationLineFromNode($node): string @@ -82,13 +83,13 @@ class DefinitionResolver /** * Gets the documentation string for a node, if it has one * - * @param Tolerant\Node $node + * @param Node $node * @return string|null */ public function getDocumentationFromNode($node) { // Any NamespaceDefinition comments likely apply to the file, not the declaration itself. - if ($node instanceof Tolerant\Node\Statement\NamespaceDefinition) { + if ($node instanceof Node\Statement\NamespaceDefinition) { return null; } @@ -100,7 +101,7 @@ class DefinitionResolver } // For parameters, parse the function-like declaration to get documentation for a parameter - if ($node instanceof Tolerant\Node\Parameter) { + if ($node instanceof Node\Parameter) { $variableName = $node->getName(); $functionLikeDeclaration = ParserHelpers::getFunctionLikeDeclarationFromParameter($node); @@ -129,10 +130,10 @@ class DefinitionResolver /** * Gets Doc Block with resolved names for a Node * - * @param Tolerant\Node $node + * @param Node $node * @return DocBlock | null */ - private function getDocBlock(Tolerant\Node $node) + private function getDocBlock(Node $node) { // TODO make more efficient (caching, ensure import table is in right format to begin with) $docCommentText = $node->getDocCommentText(); @@ -161,7 +162,7 @@ class DefinitionResolver /** * Create a Definition for a definition node * - * @param Tolerant\Node $node + * @param Node $node * @param string $fqn * @return Definition */ @@ -171,30 +172,30 @@ class DefinitionResolver $def->fqn = $fqn; // Determines whether the suggestion will show after "new" - $def->canBeInstantiated = $node instanceof Tolerant\Node\Statement\ClassDeclaration; + $def->canBeInstantiated = $node instanceof Node\Statement\ClassDeclaration; // Interfaces, classes, traits, namespaces, functions, and global const elements $def->isGlobal = ( - $node instanceof Tolerant\Node\Statement\InterfaceDeclaration || - $node instanceof Tolerant\Node\Statement\ClassDeclaration || - $node instanceof Tolerant\Node\Statement\TraitDeclaration || + $node instanceof Node\Statement\InterfaceDeclaration || + $node instanceof Node\Statement\ClassDeclaration || + $node instanceof Node\Statement\TraitDeclaration || - ($node instanceof Tolerant\Node\Statement\NamespaceDefinition && $node->name !== null) || + ($node instanceof Node\Statement\NamespaceDefinition && $node->name !== null) || - $node instanceof Tolerant\Node\Statement\FunctionDeclaration || + $node instanceof Node\Statement\FunctionDeclaration || - ($node instanceof Tolerant\Node\ConstElement && $node->parent->parent instanceof Tolerant\Node\Statement\ConstDeclaration) + ($node instanceof Node\ConstElement && $node->parent->parent instanceof Node\Statement\ConstDeclaration) ); // Static methods and static property declarations $def->isStatic = ( - ($node instanceof Tolerant\Node\MethodDeclaration && $node->isStatic()) || + ($node instanceof Node\MethodDeclaration && $node->isStatic()) || (($propertyDeclaration = ParserHelpers::tryGetPropertyDeclaration($node)) !== null && $propertyDeclaration->isStatic()) ); - if ($node instanceof Tolerant\Node\Statement\ClassDeclaration && + if ($node instanceof Node\Statement\ClassDeclaration && // TODO - this should be bette rrpreented in the parser API $node->classBaseClause !== null && $node->classBaseClause->baseClass !== null) { @@ -202,7 +203,7 @@ class DefinitionResolver // TODO - why is this represented as an array? // TODO interface implementations. } elseif ( - $node instanceof Tolerant\Node\Statement\InterfaceDeclaration && + $node instanceof Node\Statement\InterfaceDeclaration && // TODO - this should be better represented in the parser API $node->interfaceBaseClause !== null && $node->interfaceBaseClause->interfaceNameList !== null ) { @@ -226,7 +227,7 @@ class DefinitionResolver /** * Given any node, returns the Definition object of the symbol that is referenced * - * @param Tolerant\Node $node Any reference node + * @param Node $node Any reference node * @return Definition|null */ public function resolveReferenceNodeToDefinition($node) @@ -235,8 +236,8 @@ class DefinitionResolver // Variables are not indexed globally, as they stay in the file scope anyway. // Ignore variable nodes that are part of ScopedPropertyAccessExpression, // as the scoped property access expression node is handled separately. - if ($node instanceof Tolerant\Node\Expression\Variable && - !($parent instanceof Tolerant\Node\Expression\ScopedPropertyAccessExpression)) + if ($node instanceof Node\Expression\Variable && + !($parent instanceof Node\Expression\ScopedPropertyAccessExpression)) { // Resolve $this to the containing class definition. if ($node->getName() === 'this' && $fqn = $this->getContainingClassFqn($node)) { @@ -259,7 +260,7 @@ class DefinitionResolver // If the node is a function or constant, it could be namespaced, but PHP falls back to global // http://php.net/manual/en/language.namespaces.fallback.php // TODO - verify that this is not a method - $globalFallback = ParserHelpers::isConstantFetch($node) || $parent instanceof Tolerant\Node\Expression\CallExpression; + $globalFallback = ParserHelpers::isConstantFetch($node) || $parent instanceof Node\Expression\CallExpression; // Return the Definition object from the index index return $this->index->getDefinition($fqn, $globalFallback); } @@ -273,11 +274,11 @@ class DefinitionResolver */ public function resolveReferenceNodeToFqn($node) { // TODO all name tokens should be a part of a node - if ($node instanceof Tolerant\Node\QualifiedName) { + if ($node instanceof Node\QualifiedName) { return $this->resolveQualifiedNameNodeToFqn($node); } - else if ($node instanceof Tolerant\Node\Expression\MemberAccessExpression) { + else if ($node instanceof Node\Expression\MemberAccessExpression) { return $this->resolveMemberAccessExpressionNodeToFqn($node); } else if (ParserHelpers::isConstantFetch($node)) { @@ -285,13 +286,13 @@ class DefinitionResolver } else if ( // A\B::C - constant access expression - $node instanceof Tolerant\Node\Expression\ScopedPropertyAccessExpression - && !($node->memberName instanceof Tolerant\Node\Expression\Variable) + $node instanceof Node\Expression\ScopedPropertyAccessExpression + && !($node->memberName instanceof Node\Expression\Variable) ) { return $this->resolveScopedPropertyAccessExpressionNodeToFqn($node); } else if ( // A\B::$c - static property access expression - $node->parent instanceof Tolerant\Node\Expression\ScopedPropertyAccessExpression + $node->parent instanceof Node\Expression\ScopedPropertyAccessExpression ) { return $this->resolveScopedPropertyAccessExpressionNodeToFqn($node->parent); } @@ -299,36 +300,36 @@ class DefinitionResolver return null; } - private function resolveQualifiedNameNodeToFqn(Tolerant\Node\QualifiedName $node) { + private function resolveQualifiedNameNodeToFqn(Node\QualifiedName $node) { $parent = $node->parent; - if ($parent instanceof Tolerant\Node\TraitSelectOrAliasClause) { + if ($parent instanceof Node\TraitSelectOrAliasClause) { return null; } // Add use clause references - if (($useClause = $parent) instanceof Tolerant\Node\NamespaceUseGroupClause - || $useClause instanceof Tolerant\Node\NamespaceUseClause + if (($useClause = $parent) instanceof Node\NamespaceUseGroupClause + || $useClause instanceof Node\NamespaceUseClause ) { $contents = $node->getFileContents(); - if ($useClause instanceof Tolerant\Node\NamespaceUseGroupClause) { + if ($useClause instanceof Node\NamespaceUseGroupClause) { $prefix = $useClause->parent->parent->namespaceName; if ($prefix === null) { return null; } - $name = Tolerant\ResolvedName::buildName($prefix->nameParts, $contents); + $name = PhpParser\ResolvedName::buildName($prefix->nameParts, $contents); $name->addNameParts($node->nameParts, $contents); $name = (string)$name; if ($useClause->functionOrConst === null) { - $useClause = $node->getFirstAncestor(Tolerant\Node\Statement\NamespaceUseDeclaration::class); - if ($useClause->functionOrConst !== null && $useClause->functionOrConst->kind === Tolerant\TokenKind::FunctionKeyword) { + $useClause = $node->getFirstAncestor(Node\Statement\NamespaceUseDeclaration::class); + if ($useClause->functionOrConst !== null && $useClause->functionOrConst->kind === PhpParser\TokenKind::FunctionKeyword) { $name .= '()'; } } return $name; } else { - $name = (string) Tolerant\ResolvedName::buildName($node->nameParts, $contents); - if ($useClause->groupClauses === null && $useClause->parent->parent->functionOrConst !== null && $useClause->parent->parent->functionOrConst->kind === Tolerant\TokenKind::FunctionKeyword) { + $name = (string) PhpParser\ResolvedName::buildName($node->nameParts, $contents); + if ($useClause->groupClauses === null && $useClause->parent->parent->functionOrConst !== null && $useClause->parent->parent->functionOrConst->kind === PhpParser\TokenKind::FunctionKeyword) { $name .= '()'; } } @@ -339,14 +340,14 @@ class DefinitionResolver // For extends, implements, type hints and classes of classes of static calls use the name directly $name = (string) ($node->getResolvedName() ?? $node->getNamespacedName()); - if ($node->parent instanceof Tolerant\Node\Expression\CallExpression) { + if ($node->parent instanceof Node\Expression\CallExpression) { $name .= '()'; } return $name; } - private function resolveMemberAccessExpressionNodeToFqn(Tolerant\Node\Expression\MemberAccessExpression $access) { - if ($access->memberName instanceof Tolerant\Node\Expression) { + private function resolveMemberAccessExpressionNodeToFqn(Node\Expression\MemberAccessExpression $access) { + if ($access->memberName instanceof Node\Expression) { // Cannot get definition if right-hand side is expression return null; } @@ -382,7 +383,7 @@ class DefinitionResolver $classFqn = substr((string)$varType->getFqsen(), 1); } $memberSuffix = '->' . (string)($access->memberName->getText() ?? $access->memberName->getText($access->getFileContents())); - if ($access->parent instanceof Tolerant\Node\Expression\CallExpression) { + if ($access->parent instanceof Node\Expression\CallExpression) { $memberSuffix .= '()'; } @@ -412,14 +413,14 @@ class DefinitionResolver return $classFqn . $memberSuffix; } - private function resolveScopedPropertyAccessExpressionNodeToFqn(Tolerant\Node\Expression\ScopedPropertyAccessExpression $scoped) { - if ($scoped->scopeResolutionQualifier instanceof Tolerant\Node\Expression\Variable) { + private function resolveScopedPropertyAccessExpressionNodeToFqn(Node\Expression\ScopedPropertyAccessExpression $scoped) { + if ($scoped->scopeResolutionQualifier instanceof Node\Expression\Variable) { $varType = $this->getTypeFromNode($scoped->scopeResolutionQualifier); if ($varType === null) { return null; } $className = substr((string)$varType->getFqsen(), 1); - } elseif ($scoped->scopeResolutionQualifier instanceof Tolerant\Node\QualifiedName) { + } elseif ($scoped->scopeResolutionQualifier instanceof Node\QualifiedName) { $className = (string)$scoped->scopeResolutionQualifier->getResolvedName(); } else { return null; @@ -427,7 +428,7 @@ class DefinitionResolver if ($className === 'self' || $className === 'static' || $className === 'parent') { // self and static are resolved to the containing class - $classNode = $scoped->getFirstAncestor(Tolerant\Node\Statement\ClassDeclaration::class); + $classNode = $scoped->getFirstAncestor(Node\Statement\ClassDeclaration::class); if ($classNode === null) { return null; } @@ -440,11 +441,11 @@ class DefinitionResolver } else { $className = (string)$classNode->getNamespacedName(); } - } elseif ($scoped->scopeResolutionQualifier instanceof Tolerant\Node\QualifiedName) { + } elseif ($scoped->scopeResolutionQualifier instanceof Node\QualifiedName) { $className = $scoped->scopeResolutionQualifier->getResolvedName(); } - if ($scoped->memberName instanceof Tolerant\Node\Expression\Variable) { - if ($scoped->parent instanceof Tolerant\Node\Expression\CallExpression) { + if ($scoped->memberName instanceof Node\Expression\Variable) { + if ($scoped->parent instanceof Node\Expression\CallExpression) { return null; } $memberName = $scoped->memberName->getName(); @@ -455,7 +456,7 @@ class DefinitionResolver } else { $name = (string)$className . '::' . $scoped->memberName->getText($scoped->getFileContents()); } - if ($scoped->parent instanceof Tolerant\Node\Expression\CallExpression) { + if ($scoped->parent instanceof Node\Expression\CallExpression) { $name .= '()'; } return $name; @@ -465,12 +466,12 @@ class DefinitionResolver * Returns FQN of the class a node is contained in * Returns null if the class is anonymous or the node is not contained in a class * - * @param Tolerant\Node $node + * @param Node $node * @return string|null */ - private static function getContainingClassFqn(Tolerant\Node $node) + private static function getContainingClassFqn(Node $node) { - $classNode = $node->getFirstAncestor(Tolerant\Node\Statement\ClassDeclaration::class); + $classNode = $node->getFirstAncestor(Node\Statement\ClassDeclaration::class); if ($classNode === null) { return null; } @@ -480,18 +481,18 @@ class DefinitionResolver /** * Returns the assignment or parameter node where a variable was defined * - * @param Tolerant\Node\Expression\Variable | Tolerant\Node\Expression\ClosureUse $var The variable access - * @return Tolerant\Node\Expression\Assign | Tolerant\Node\Expression\AssignOp|Node\Param | Tolerant\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) { $n = $var; // When a use is passed, start outside the closure to not return immediately // Use variable vs variable parsing? - if ($var instanceof Tolerant\Node\UseVariableName) { - $n = $var->getFirstAncestor(Tolerant\Node\Expression\AnonymousFunctionCreationExpression::class)->parent; + if ($var instanceof Node\UseVariableName) { + $n = $var->getFirstAncestor(Node\Expression\AnonymousFunctionCreationExpression::class)->parent; $name = $var->getName(); - } else if ($var instanceof Tolerant\Node\Expression\Variable || $var instanceof Tolerant\Node\Parameter) { + } else if ($var instanceof Node\Expression\Variable || $var instanceof Node\Parameter) { $name = $var->getName(); } else { throw new \InvalidArgumentException('$var must be Variable, Param or ClosureUse, not ' . get_class($var)); @@ -509,7 +510,7 @@ class DefinitionResolver } } // If it is a closure, also check use statements - if ($n instanceof Tolerant\Node\Expression\AnonymousFunctionCreationExpression && + if ($n instanceof Node\Expression\AnonymousFunctionCreationExpression && $n->anonymousFunctionUseClause !== null && $n->anonymousFunctionUseClause->useVariableNameList !== null) { foreach ($n->anonymousFunctionUseClause->useVariableNameList->getElements() as $use @@ -523,13 +524,13 @@ class DefinitionResolver } // Check each previous sibling node for a variable assignment to that variable while (($prevSibling = $n->getPreviousSibling()) !== null && $n = $prevSibling) { - if ($n instanceof Tolerant\Node\Statement\ExpressionStatement) { + if ($n instanceof Node\Statement\ExpressionStatement) { $n = $n->expression; } if ( // TODO - clean this up - ($n instanceof Tolerant\Node\Expression\AssignmentExpression && $n->operator->kind === Tolerant\TokenKind::EqualsToken) - && $n->leftOperand instanceof Tolerant\Node\Expression\Variable && $n->leftOperand->getName() === $name + ($n instanceof Node\Expression\AssignmentExpression && $n->operator->kind === PhpParser\TokenKind::EqualsToken) + && $n->leftOperand instanceof Node\Expression\Variable && $n->leftOperand->getName() === $name ) { return $n; } @@ -543,12 +544,12 @@ class DefinitionResolver * Given an expression node, resolves that expression recursively to a type. * If the type could not be resolved, returns Types\Mixed. * - * @param Tolerant\Node\Expression $expr + * @param Node\Expression $expr * @return \phpDocumentor\Reflection\Type|null */ public function resolveExpressionNodeToType($expr) { - if ($expr == null || $expr instanceof Tolerant\MissingToken || $expr instanceof Tolerant\SkippedToken) { + if ($expr == null || $expr instanceof PhpParser\MissingToken || $expr instanceof PhpParser\SkippedToken) { // TODO some members are null or Missing/SkippedToken // How do we handle this more generally? return new Types\Mixed; @@ -556,42 +557,42 @@ class DefinitionResolver // PARENTHESIZED EXPRESSION // Retrieve inner expression from parenthesized expression - while ($expr instanceof Tolerant\Node\Expression\ParenthesizedExpression) { + while ($expr instanceof Node\Expression\ParenthesizedExpression) { $expr = $expr->expression; } // VARIABLE // $this -> Type\this // $myVariable -> type of corresponding assignment expression - if ($expr instanceof Tolerant\Node\Expression\Variable || $expr instanceof Tolerant\Node\UseVariableName) { + if ($expr instanceof Node\Expression\Variable || $expr instanceof Node\UseVariableName) { if ($expr->getName() === 'this') { return new Types\This; } // Find variable definition (parameter or assignment expression) $defNode = $this->resolveVariableToNode($expr); - if ($defNode instanceof Tolerant\Node\Expression\AssignmentExpression || $defNode instanceof Tolerant\Node\UseVariableName) { + if ($defNode instanceof Node\Expression\AssignmentExpression || $defNode instanceof Node\UseVariableName) { return $this->resolveExpressionNodeToType($defNode); } - if ($defNode instanceof Tolerant\Node\Parameter) { + if ($defNode instanceof Node\Parameter) { return $this->getTypeFromNode($defNode); } } // FUNCTION CALL // Function calls are resolved to type corresponding to their FQN - if ($expr instanceof Tolerant\Node\Expression\CallExpression && + if ($expr instanceof Node\Expression\CallExpression && !( - $expr->callableExpression instanceof Tolerant\Node\Expression\ScopedPropertyAccessExpression || - $expr->callableExpression instanceof Tolerant\Node\Expression\MemberAccessExpression) + $expr->callableExpression instanceof Node\Expression\ScopedPropertyAccessExpression || + $expr->callableExpression instanceof Node\Expression\MemberAccessExpression) ) { // Find the function definition - if ($expr->callableExpression instanceof Tolerant\Node\Expression) { + if ($expr->callableExpression instanceof Node\Expression) { // Cannot get type for dynamic function call return new Types\Mixed; } - if ($expr->callableExpression instanceof Tolerant\Node\QualifiedName) { + if ($expr->callableExpression instanceof Node\QualifiedName) { $fqn = $expr->callableExpression->getResolvedName() ?? $expr->callableExpression->getNamespacedName(); $fqn .= '()'; $def = $this->index->getDefinition($fqn, true); @@ -603,13 +604,13 @@ class DefinitionResolver // TRUE / FALSE / NULL // Resolve true and false reserved words to Types\Boolean - if ($expr instanceof Tolerant\Node\ReservedWord) { + if ($expr instanceof Node\ReservedWord) { $token = $expr->children->kind; - if ($token === Tolerant\TokenKind::TrueReservedWord || $token === Tolerant\TokenKind::FalseReservedWord) { + if ($token === PhpParser\TokenKind::TrueReservedWord || $token === PhpParser\TokenKind::FalseReservedWord) { return new Types\Boolean; } - if ($token === Tolerant\TokenKind::NullReservedWord) { + if ($token === PhpParser\TokenKind::NullReservedWord) { return new Types\Null_; } } @@ -625,8 +626,8 @@ class DefinitionResolver } // MEMBER ACCESS EXPRESSION - if ($expr instanceof Tolerant\Node\Expression\MemberAccessExpression) { - if ($expr->memberName instanceof Tolerant\Node\Expression) { + if ($expr instanceof Node\Expression\MemberAccessExpression) { + if ($expr->memberName instanceof Node\Expression) { return new Types\Mixed; } $var = $expr->dereferencableExpression; @@ -648,7 +649,7 @@ class DefinitionResolver $classFqn = substr((string)$t->getFqsen(), 1); } $fqn = $classFqn . '->' . $expr->memberName->getText($expr->getFileContents()); - if ($expr->parent instanceof Tolerant\Node\Expression\CallExpression) { + if ($expr->parent instanceof Node\Expression\CallExpression) { $fqn .= '()'; } $def = $this->index->getDefinition($fqn); @@ -659,7 +660,7 @@ class DefinitionResolver } // SCOPED PROPERTY ACCESS EXPRESSION - if ($expr instanceof Tolerant\Node\Expression\ScopedPropertyAccessExpression) { + if ($expr instanceof Node\Expression\ScopedPropertyAccessExpression) { $classType = $this->resolveClassNameToType($expr->scopeResolutionQualifier); if (!($classType instanceof Types\Object_) || $classType->getFqsen() === null) { return new Types\Mixed; @@ -668,7 +669,7 @@ class DefinitionResolver // TODO is there a cleaner way to do this? $fqn .= $expr->memberName->getText() ?? $expr->memberName->getText($expr->getFileContents()); - if ($expr->parent instanceof Tolerant\Node\Expression\CallExpression) { + if ($expr->parent instanceof Node\Expression\CallExpression) { $fqn .= '()'; } @@ -682,26 +683,26 @@ class DefinitionResolver // OBJECT CREATION EXPRESSION // new A() => resolves to the type of the class type designator (A) // TODO: new $this->a => resolves to the string represented by "a" - if ($expr instanceof Tolerant\Node\Expression\ObjectCreationExpression) { + if ($expr instanceof Node\Expression\ObjectCreationExpression) { return $this->resolveClassNameToType($expr->classTypeDesignator); } // CLONE EXPRESSION // clone($a) => resolves to the type of $a - if ($expr instanceof Tolerant\Node\Expression\CloneExpression) { + if ($expr instanceof Node\Expression\CloneExpression) { return $this->resolveExpressionNodeToType($expr->expression); } // ASSIGNMENT EXPRESSION // $a = $myExpression => resolves to the type of the right-hand operand - if ($expr instanceof Tolerant\Node\Expression\AssignmentExpression) { + if ($expr instanceof Node\Expression\AssignmentExpression) { return $this->resolveExpressionNodeToType($expr->rightOperand); } // TERNARY EXPRESSION // $condition ? $ifExpression : $elseExpression => reslves to type of $ifCondition or $elseExpression // $condition ?: $elseExpression => resolves to type of $condition or $elseExpression - if ($expr instanceof Tolerant\Node\Expression\TernaryExpression) { + if ($expr instanceof Node\Expression\TernaryExpression) { // ?: if ($expr->ifExpression === null) { return new Types\Compound([ @@ -718,7 +719,7 @@ class DefinitionResolver // NULL COALLESCE // $rightOperand ?? $leftOperand => resolves to type of $rightOperand or $leftOperand - if ($expr instanceof Tolerant\Node\Expression\BinaryExpression && $expr->operator->kind === Tolerant\TokenKind::QuestionQuestionToken) { + if ($expr instanceof Node\Expression\BinaryExpression && $expr->operator->kind === PhpParser\TokenKind::QuestionQuestionToken) { // ?? operator return new Types\Compound([ $this->resolveExpressionNodeToType($expr->leftOperand), @@ -735,10 +736,10 @@ class DefinitionResolver if ( ParserHelpers::isBooleanExpression($expr) - || ($expr instanceof Tolerant\Node\Expression\CastExpression && $expr->castType->kind === Tolerant\TokenKind::BoolCastToken) - || ($expr instanceof Tolerant\Node\Expression\UnaryOpExpression && $expr->operator->kind === Tolerant\TokenKind::ExclamationToken) - || $expr instanceof Tolerant\Node\Expression\EmptyIntrinsicExpression - || $expr instanceof Tolerant\Node\Expression\IssetIntrinsicExpression + || ($expr instanceof Node\Expression\CastExpression && $expr->castType->kind === PhpParser\TokenKind::BoolCastToken) + || ($expr instanceof Node\Expression\UnaryOpExpression && $expr->operator->kind === PhpParser\TokenKind::ExclamationToken) + || $expr instanceof Node\Expression\EmptyIntrinsicExpression + || $expr instanceof Node\Expression\IssetIntrinsicExpression ) { return new Types\Boolean; } @@ -750,10 +751,10 @@ class DefinitionResolver // // TODO: Magic constants (__CLASS__, __DIR__, __FUNCTION__, __METHOD__, __NAMESPACE__, __TRAIT__, __FILE__) if ( - ($expr instanceof Tolerant\Node\Expression\BinaryExpression && - ($expr->operator->kind === Tolerant\TokenKind::DotToken || $expr->operator->kind === Tolerant\TokenKind::DotEqualsToken)) || - $expr instanceof Tolerant\Node\StringLiteral || - ($expr instanceof Tolerant\Node\Expression\CastExpression && $expr->castType->kind === Tolerant\TokenKind::StringCastToken) + ($expr instanceof Node\Expression\BinaryExpression && + ($expr->operator->kind === PhpParser\TokenKind::DotToken || $expr->operator->kind === PhpParser\TokenKind::DotEqualsToken)) || + $expr instanceof Node\StringLiteral || + ($expr instanceof Node\Expression\CastExpression && $expr->castType->kind === PhpParser\TokenKind::StringCastToken) ) { return new Types\String_; } @@ -765,18 +766,18 @@ class DefinitionResolver // Resolve to Types\Float // [assignment] /= if ( - $expr instanceof Tolerant\Node\Expression\BinaryExpression && + $expr instanceof Node\Expression\BinaryExpression && ($operator = $expr->operator->kind) - && ($operator === Tolerant\TokenKind::PlusToken || - $operator === Tolerant\TokenKind::AsteriskAsteriskToken || - $operator === Tolerant\TokenKind::AsteriskToken || - $operator === Tolerant\TokenKind::MinusToken || + && ($operator === PhpParser\TokenKind::PlusToken || + $operator === PhpParser\TokenKind::AsteriskAsteriskToken || + $operator === PhpParser\TokenKind::AsteriskToken || + $operator === PhpParser\TokenKind::MinusToken || // Assignment expressions (TODO: consider making this a type of AssignmentExpression rather than kind of BinaryExpression) - $operator === Tolerant\TokenKind::AsteriskEqualsToken|| - $operator === Tolerant\TokenKind::AsteriskAsteriskEqualsToken || - $operator === Tolerant\TokenKind::MinusEqualsToken || - $operator === Tolerant\TokenKind::PlusEqualsToken + $operator === PhpParser\TokenKind::AsteriskEqualsToken|| + $operator === PhpParser\TokenKind::AsteriskAsteriskEqualsToken || + $operator === PhpParser\TokenKind::MinusEqualsToken || + $operator === PhpParser\TokenKind::PlusEqualsToken ) ) { if ( @@ -787,8 +788,8 @@ class DefinitionResolver } return new Types\Float_; } else if ( - $expr instanceof Tolerant\Node\Expression\BinaryExpression && - $expr->operator->kind === Tolerant\TokenKind::SlashEqualsToken + $expr instanceof Node\Expression\BinaryExpression && + $expr->operator->kind === PhpParser\TokenKind::SlashEqualsToken ) { return new Types\Float_; } @@ -799,13 +800,13 @@ class DefinitionResolver // TODO: Magic constants (__LINE__) if ( // TODO: consider different Node types of float/int, also better property name (not "children") - ($expr instanceof Tolerant\Node\NumericLiteral && $expr->children->kind === Tolerant\TokenKind::IntegerLiteralToken) || - $expr instanceof Tolerant\Node\Expression\BinaryExpression && ( + ($expr instanceof Node\NumericLiteral && $expr->children->kind === PhpParser\TokenKind::IntegerLiteralToken) || + $expr instanceof Node\Expression\BinaryExpression && ( ($operator = $expr->operator->kind) - && ($operator === Tolerant\TokenKind::LessThanEqualsGreaterThanToken || - $operator === Tolerant\TokenKind::AmpersandToken || - $operator === Tolerant\TokenKind::CaretToken || - $operator === Tolerant\TokenKind::BarToken) + && ($operator === PhpParser\TokenKind::LessThanEqualsGreaterThanToken || + $operator === PhpParser\TokenKind::AmpersandToken || + $operator === PhpParser\TokenKind::CaretToken || + $operator === PhpParser\TokenKind::BarToken) ) ) { return new Types\Integer; @@ -816,9 +817,9 @@ class DefinitionResolver // [operator] / // [cast] (double) if ( - $expr instanceof Tolerant\Node\NumericLiteral && $expr->children->kind === Tolerant\TokenKind::FloatingLiteralToken || - ($expr instanceof Tolerant\Node\Expression\CastExpression && $expr->castType->kind === Tolerant\TokenKind::DoubleCastToken) || - ($expr instanceof Tolerant\Node\Expression\BinaryExpression && $expr->operator->kind === Tolerant\TokenKind::SlashToken) + $expr instanceof Node\NumericLiteral && $expr->children->kind === PhpParser\TokenKind::FloatingLiteralToken || + ($expr instanceof Node\Expression\CastExpression && $expr->castType->kind === PhpParser\TokenKind::DoubleCastToken) || + ($expr instanceof Node\Expression\BinaryExpression && $expr->operator->kind === PhpParser\TokenKind::SlashToken) ) { return new Types\Float_; } @@ -827,7 +828,7 @@ class DefinitionResolver // Resolve to Types\Array (Types\Compound of value and key types) // [a, b, c] // [1=>"hello", "hi"=>1, 4=>[]]s - if ($expr instanceof Tolerant\Node\Expression\ArrayCreationExpression) { + if ($expr instanceof Node\Expression\ArrayCreationExpression) { $valueTypes = []; $keyTypes = []; if ($expr->arrayElements !== null) { @@ -858,7 +859,7 @@ class DefinitionResolver // SUBSCRIPT EXPRESSION // $myArray[3] // $myArray{"hello"} - if ($expr instanceof Tolerant\Node\Expression\SubscriptExpression) { + if ($expr instanceof Node\Expression\SubscriptExpression) { $varType = $this->resolveExpressionNodeToType($expr->postfixExpression); if (!($varType instanceof Types\Array_)) { return new Types\Mixed; @@ -868,12 +869,12 @@ class DefinitionResolver // SCRIPT INCLUSION EXPRESSION // include, require, include_once, require_once - if ($expr instanceof Tolerant\Node\Expression\ScriptInclusionExpression) { + if ($expr instanceof Node\Expression\ScriptInclusionExpression) { // TODO: resolve path to PhpDocument and find return statement return new Types\Mixed; } - if ($expr instanceof Tolerant\Node\QualifiedName) { + if ($expr instanceof Node\QualifiedName) { return $this->resolveClassNameToType($expr); } @@ -885,15 +886,15 @@ 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 Tolerant\Node || Tolerant\Token $class + * @param Node || PhpParser\Token $class * @return Type */ public function resolveClassNameToType($class): Type { - if ($class instanceof Tolerant\Node\Expression) { + if ($class instanceof Node\Expression) { return new Types\Mixed; } - if ($class instanceof Tolerant\Token && $class->kind === Tolerant\TokenKind::ClassKeyword) { + if ($class instanceof PhpParser\Token && $class->kind === PhpParser\TokenKind::ClassKeyword) { // Anonymous class return new Types\Object_; } @@ -903,7 +904,7 @@ class DefinitionResolver return new Types\Static_; } if ($className === 'self' || $className === 'parent') { - $classNode = $class->getFirstAncestor(Tolerant\Node\Statement\ClassDeclaration::class); + $classNode = $class->getFirstAncestor(Node\Statement\ClassDeclaration::class); if ($className === 'parent') { if ($classNode === null || $classNode->classBaseClause === null) { return new Types\Object_; @@ -933,7 +934,7 @@ class DefinitionResolver * If it is unknown, will be Types\Mixed. * Returns null if the node does not have a type. * - * @param Tolerant\Node $node + * @param Node $node * @return \phpDocumentor\Reflection\Type|null */ public function getTypeFromNode($node) @@ -948,7 +949,7 @@ class DefinitionResolver // Get the type of the parameter: // 1. Doc block // 2. Parameter type and default - if ($node instanceof Tolerant\Node\Parameter) { + if ($node instanceof Node\Parameter) { // Parameters // Get the doc block for the the function call // /** @@ -968,7 +969,7 @@ class DefinitionResolver // function foo(MyClass $a) if ($node->typeDeclaration !== null) { // Use PHP7 return type hint - if ($node->typeDeclaration instanceof Tolerant\Token) { + if ($node->typeDeclaration instanceof PhpParser\Token) { // Resolve a string like "bool" to a type object $type = $this->typeResolver->resolve($node->typeDeclaration->getText($node->getFileContents())); } else { @@ -1003,9 +1004,9 @@ class DefinitionResolver // Use @return tag return $returnTags[0]->getType(); } - if ($node->returnType !== null && !($node->returnType instanceof Tolerant\MissingToken)) { + if ($node->returnType !== null && !($node->returnType instanceof PhpParser\MissingToken)) { // Use PHP7 return type hint - if ($node->returnType instanceof Tolerant\Token) { + if ($node->returnType instanceof PhpParser\Token) { // Resolve a string like "bool" to a type object return $this->typeResolver->resolve($node->returnType->getText($node->getFileContents())); } @@ -1022,7 +1023,7 @@ class DefinitionResolver ParserHelpers::tryGetPropertyDeclaration($node) ?? ParserHelpers::tryGetConstOrClassConstDeclaration($node) ) !== null || - ($node = $node->parent) instanceof Tolerant\Node\Expression\AssignmentExpression) + ($node = $node->parent) instanceof Node\Expression\AssignmentExpression) { $declarationNode = $declarationNode ?? $node; @@ -1037,14 +1038,14 @@ class DefinitionResolver } // Resolve the expression - if ($declarationNode instanceof Tolerant\Node\PropertyDeclaration) { + if ($declarationNode instanceof Node\PropertyDeclaration) { // TODO should have default if (isset($node->parent->rightOperand)) { return $this->resolveExpressionNodeToType($node->parent->rightOperand); } - } else if ($node instanceof Tolerant\Node\ConstElement) { + } else if ($node instanceof Node\ConstElement) { return $this->resolveExpressionNodeToType($node->assignment); - } else if ($node instanceof Tolerant\Node\Expression\AssignmentExpression) { + } else if ($node instanceof Node\Expression\AssignmentExpression) { return $this->resolveExpressionNodeToType($node->rightOperand); } // TODO: read @property tags of class @@ -1061,7 +1062,7 @@ class DefinitionResolver * Returns the fully qualified name (FQN) that is defined by a node * Returns null if the node does not declare any symbol that can be referenced by an FQN * - * @param Tolerant\Node $node + * @param Node $node * @return string|null */ public static function getDefinedFqn($node) @@ -1074,23 +1075,23 @@ class DefinitionResolver // interface C { } A\B\C // trait C { } A\B\C if ( - $node instanceof Tolerant\Node\Statement\ClassDeclaration || - $node instanceof Tolerant\Node\Statement\InterfaceDeclaration || - $node instanceof Tolerant\Node\Statement\TraitDeclaration + $node instanceof Node\Statement\ClassDeclaration || + $node instanceof Node\Statement\InterfaceDeclaration || + $node instanceof Node\Statement\TraitDeclaration ) { return (string) $node->getNamespacedName(); } // INPUT OUTPUT: // namespace A\B; A\B - else if ($node instanceof Tolerant\Node\Statement\NamespaceDefinition && $node->name instanceof Tolerant\Node\QualifiedName) { - $name = (string) Tolerant\ResolvedName::buildName($node->name->nameParts, $node->getFileContents()); + else if ($node instanceof Node\Statement\NamespaceDefinition && $node->name instanceof Node\QualifiedName) { + $name = (string) PhpParser\ResolvedName::buildName($node->name->nameParts, $node->getFileContents()); return \count($name) > 0 ? $name : null; } // INPUT OUTPUT: // namespace A\B; // function a(); A\B\a(); - else if ($node instanceof Tolerant\Node\Statement\FunctionDeclaration) { + else if ($node instanceof Node\Statement\FunctionDeclaration) { // Function: use functionName() as the name $name = (string)$node->getNamespacedName(); return \count($name) > 0 ? $name . '()' : null; @@ -1101,13 +1102,13 @@ class DefinitionResolver // function a () {} A\B\C->a() // static function b() {} A\B\C::b() // } - else if ($node instanceof Tolerant\Node\MethodDeclaration) { + else if ($node instanceof Node\MethodDeclaration) { // Class method: use ClassName->methodName() as name $class = $node->getFirstAncestor( - Tolerant\Node\Expression\ObjectCreationExpression::class, - Tolerant\Node\Statement\ClassDeclaration::class, - Tolerant\Node\Statement\InterfaceDeclaration::class, - Tolerant\Node\Statement\TraitDeclaration::class + Node\Expression\ObjectCreationExpression::class, + Node\Statement\ClassDeclaration::class, + Node\Statement\InterfaceDeclaration::class, + Node\Statement\TraitDeclaration::class ); if (!isset($class->name)) { // Ignore anonymous classes @@ -1130,10 +1131,10 @@ class DefinitionResolver ($propertyDeclaration = ParserHelpers::tryGetPropertyDeclaration($node)) !== null && ($classDeclaration = $node->getFirstAncestor( - Tolerant\Node\Expression\ObjectCreationExpression::class, - Tolerant\Node\Statement\ClassDeclaration::class, - Tolerant\Node\Statement\InterfaceDeclaration::class, - Tolerant\Node\Statement\TraitDeclaration::class + Node\Expression\ObjectCreationExpression::class, + Node\Statement\ClassDeclaration::class, + Node\Statement\InterfaceDeclaration::class, + Node\Statement\TraitDeclaration::class ) ) !== null && isset($classDeclaration->name)) { @@ -1154,17 +1155,17 @@ class DefinitionResolver // const $a, $b = 4 A\B\C::$a(), A\B\C::$b // } else if (($constDeclaration = ParserHelpers::tryGetConstOrClassConstDeclaration($node)) !== null) { - if ($constDeclaration instanceof Tolerant\Node\Statement\ConstDeclaration) { + if ($constDeclaration instanceof Node\Statement\ConstDeclaration) { // Basic constant: use CONSTANT_NAME as name return (string)$node->getNamespacedName(); } // Class constant: use ClassName::CONSTANT_NAME as name $classDeclaration = $constDeclaration->getFirstAncestor( - Tolerant\Node\Expression\ObjectCreationExpression::class, - Tolerant\Node\Statement\ClassDeclaration::class, - Tolerant\Node\Statement\InterfaceDeclaration::class, - Tolerant\Node\Statement\TraitDeclaration::class + Node\Expression\ObjectCreationExpression::class, + Node\Statement\ClassDeclaration::class, + Node\Statement\InterfaceDeclaration::class, + Node\Statement\TraitDeclaration::class ); if (!isset($classDeclaration->name)) { diff --git a/src/FqnUtilities.php b/src/FqnUtilities.php index a569d9b..c7d45a6 100644 --- a/src/FqnUtilities.php +++ b/src/FqnUtilities.php @@ -3,7 +3,7 @@ namespace LanguageServer; use phpDocumentor\Reflection\{Type, Types}; -use Microsoft\PhpParser as Tolerant; +use Microsoft\PhpParser; class FqnUtilities { diff --git a/src/ParserHelpers.php b/src/ParserHelpers.php index b734769..d1916f2 100644 --- a/src/ParserHelpers.php +++ b/src/ParserHelpers.php @@ -3,68 +3,69 @@ declare(strict_types=1); namespace LanguageServer; -use Microsoft\PhpParser as Tolerant; +use Microsoft\PhpParser; +use Microsoft\PhpParser\Node; class ParserHelpers { - public static function isConstantFetch(Tolerant\Node $node) : bool { + public static function isConstantFetch(Node $node) : bool { $parent = $node->parent; return ( - $node instanceof Tolerant\Node\QualifiedName && + $node instanceof Node\QualifiedName && ( -// $node->parent instanceof Tolerant\Node\Statement\ExpressionStatement || - $parent instanceof Tolerant\Node\Expression || - $parent instanceof Tolerant\Node\DelimitedList\ExpressionList || - $parent instanceof Tolerant\Node\ArrayElement || - ($parent instanceof Tolerant\Node\Parameter && $node->parent->default === $node) || - $parent instanceof Tolerant\Node\StatementNode || - $parent instanceof Tolerant\Node\CaseStatementNode +// $node->parent instanceof Node\Statement\ExpressionStatement || + $parent instanceof Node\Expression || + $parent instanceof Node\DelimitedList\ExpressionList || + $parent instanceof Node\ArrayElement || + ($parent instanceof Node\Parameter && $node->parent->default === $node) || + $parent instanceof Node\StatementNode || + $parent instanceof Node\CaseStatementNode ) && !( - $parent instanceof Tolerant\Node\Expression\MemberAccessExpression || - $parent instanceof Tolerant\Node\Expression\CallExpression || - $parent instanceof Tolerant\Node\Expression\ObjectCreationExpression || - $parent instanceof Tolerant\Node\Expression\ScopedPropertyAccessExpression || + $parent instanceof Node\Expression\MemberAccessExpression || + $parent instanceof Node\Expression\CallExpression || + $parent instanceof Node\Expression\ObjectCreationExpression || + $parent instanceof Node\Expression\ScopedPropertyAccessExpression || self::isFunctionLike($parent) || ( - $parent instanceof Tolerant\Node\Expression\BinaryExpression && - $parent->operator->kind === Tolerant\TokenKind::InstanceOfKeyword + $parent instanceof Node\Expression\BinaryExpression && + $parent->operator->kind === PhpParser\TokenKind::InstanceOfKeyword ) )); } - public static function getFunctionLikeDeclarationFromParameter(Tolerant\Node\Parameter $node) { + public static function getFunctionLikeDeclarationFromParameter(Node\Parameter $node) { return $node->parent->parent; } - public static function isFunctionLike(Tolerant\Node $node) { + public static function isFunctionLike(Node $node) { return - $node instanceof Tolerant\Node\Statement\FunctionDeclaration || - $node instanceof Tolerant\Node\MethodDeclaration || - $node instanceof Tolerant\Node\Expression\AnonymousFunctionCreationExpression; + $node instanceof Node\Statement\FunctionDeclaration || + $node instanceof Node\MethodDeclaration || + $node instanceof Node\Expression\AnonymousFunctionCreationExpression; } public static function isBooleanExpression($expression) : bool { - if (!($expression instanceof Tolerant\Node\Expression\BinaryExpression)) { + if (!($expression instanceof Node\Expression\BinaryExpression)) { return false; } switch ($expression->operator->kind) { - case Tolerant\TokenKind::InstanceOfKeyword: - case Tolerant\TokenKind::GreaterThanToken: - case Tolerant\TokenKind::GreaterThanEqualsToken: - case Tolerant\TokenKind::LessThanToken: - case Tolerant\TokenKind::LessThanEqualsToken: - case Tolerant\TokenKind::AndKeyword: - case Tolerant\TokenKind::AmpersandAmpersandToken: - case Tolerant\TokenKind::LessThanEqualsGreaterThanToken: - case Tolerant\TokenKind::OrKeyword: - case Tolerant\TokenKind::BarBarToken: - case Tolerant\TokenKind::XorKeyword: - case Tolerant\TokenKind::ExclamationEqualsEqualsToken: - case Tolerant\TokenKind::ExclamationEqualsToken: - case Tolerant\TokenKind::CaretToken: - case Tolerant\TokenKind::EqualsEqualsEqualsToken: - case Tolerant\TokenKind::EqualsToken: + case PhpParser\TokenKind::InstanceOfKeyword: + case PhpParser\TokenKind::GreaterThanToken: + case PhpParser\TokenKind::GreaterThanEqualsToken: + case PhpParser\TokenKind::LessThanToken: + case PhpParser\TokenKind::LessThanEqualsToken: + case PhpParser\TokenKind::AndKeyword: + case PhpParser\TokenKind::AmpersandAmpersandToken: + case PhpParser\TokenKind::LessThanEqualsGreaterThanToken: + case PhpParser\TokenKind::OrKeyword: + case PhpParser\TokenKind::BarBarToken: + case PhpParser\TokenKind::XorKeyword: + case PhpParser\TokenKind::ExclamationEqualsEqualsToken: + case PhpParser\TokenKind::ExclamationEqualsToken: + case PhpParser\TokenKind::CaretToken: + case PhpParser\TokenKind::EqualsEqualsEqualsToken: + case PhpParser\TokenKind::EqualsToken: return true; } return false; @@ -73,13 +74,13 @@ class ParserHelpers { /** * Tries to get the parent property declaration given a Node - * @param Tolerant\Node $node - * @return Tolerant\Node\PropertyDeclaration | null $node + * @param Node $node + * @return Node\PropertyDeclaration | null $node */ - public static function tryGetPropertyDeclaration(Tolerant\Node $node) { - if ($node instanceof Tolerant\Node\Expression\Variable && - (($propertyDeclaration = $node->parent->parent) instanceof Tolerant\Node\PropertyDeclaration || - ($propertyDeclaration = $propertyDeclaration->parent) instanceof Tolerant\Node\PropertyDeclaration) + public static function tryGetPropertyDeclaration(Node $node) { + if ($node instanceof Node\Expression\Variable && + (($propertyDeclaration = $node->parent->parent) instanceof Node\PropertyDeclaration || + ($propertyDeclaration = $propertyDeclaration->parent) instanceof Node\PropertyDeclaration) ) { return $propertyDeclaration; } @@ -88,14 +89,14 @@ class ParserHelpers { /** * Tries to get the parent ConstDeclaration or ClassConstDeclaration given a Node - * @param Tolerant\Node $node - * @return Tolerant\Node\Statement\ConstDeclaration | Tolerant\Node\ClassConstDeclaration | null $node + * @param Node $node + * @return Node\Statement\ConstDeclaration | Node\ClassConstDeclaration | null $node */ - public static function tryGetConstOrClassConstDeclaration(Tolerant\Node $node) { + public static function tryGetConstOrClassConstDeclaration(Node $node) { if ( - $node instanceof Tolerant\Node\ConstElement && ( - ($constDeclaration = $node->parent->parent) instanceof Tolerant\Node\ClassConstDeclaration || - $constDeclaration instanceof Tolerant\Node\Statement\ConstDeclaration ) + $node instanceof Node\ConstElement && ( + ($constDeclaration = $node->parent->parent) instanceof Node\ClassConstDeclaration || + $constDeclaration instanceof Node\Statement\ConstDeclaration ) ) { return $constDeclaration; } @@ -105,15 +106,15 @@ class ParserHelpers { /** * Returns true if the node is a usage of `define`. * e.g. define('TEST_DEFINE_CONSTANT', false); - * @param Tolerant\Node $node + * @param Node $node * @return bool */ - public static function isConstDefineExpression(Tolerant\Node $node): bool { - return $node instanceof Tolerant\Node\Expression\CallExpression - && $node->callableExpression instanceof Tolerant\Node\QualifiedName + public static function isConstDefineExpression(Node $node): bool { + return $node instanceof Node\Expression\CallExpression + && $node->callableExpression instanceof Node\QualifiedName && strtolower($node->callableExpression->getText()) === 'define' && isset($node->argumentExpressionList->children[0]) - && $node->argumentExpressionList->children[0]->expression instanceof Tolerant\Node\StringLiteral + && $node->argumentExpressionList->children[0]->expression instanceof Node\StringLiteral && isset($node->argumentExpressionList->children[2]); } } \ No newline at end of file diff --git a/src/PhpDocument.php b/src/PhpDocument.php index 77c9aac..f7b813e 100644 --- a/src/PhpDocument.php +++ b/src/PhpDocument.php @@ -7,7 +7,8 @@ use LanguageServer\Index\Index; use LanguageServer\Protocol\{ Diagnostic, Position, Range }; -use Microsoft\PhpParser as Tolerant; +use Microsoft\PhpParser; +use Microsoft\PhpParser\Node; use phpDocumentor\Reflection\DocBlockFactory; class PhpDocument @@ -15,7 +16,7 @@ class PhpDocument /** * The PHPParser instance * - * @var Tolerant\Parser + * @var PhpParser\Parser */ private $parser; @@ -55,7 +56,7 @@ class PhpDocument /** * The AST of the document * - * @var Tolerant\Node + * @var Node */ private $stmts; @@ -69,14 +70,14 @@ class PhpDocument /** * Map from fully qualified name (FQN) to Node * - * @var Tolerant\Node + * @var Node */ private $definitionNodes; /** * Map from fully qualified name (FQN) to array of nodes that reference the symbol * - * @var Tolerant\Node[][] + * @var Node[][] */ private $referenceNodes; @@ -91,7 +92,7 @@ class PhpDocument * @param string $uri The URI of the document * @param string $content The content of the document * @param Index $index The Index to register definitions and references to - * @param Tolerant\Parser $parser The PhpParser instance + * @param PhpParser\Parser $parser The PhpParser instance * @param DocBlockFactory $docBlockFactory The DocBlockFactory instance to parse docblocks * @param DefinitionResolver $definitionResolver The DefinitionResolver to resolve definitions to symbols in the workspace */ @@ -115,7 +116,7 @@ class PhpDocument * Get all references of a fully qualified name * * @param string $fqn The fully qualified name of the symbol - * @return Tolerant\Node[] + * @return Node[] */ public function getReferenceNodesByFqn(string $fqn) { @@ -220,7 +221,7 @@ class PhpDocument /** * Returns the AST of the document * - * @return Tolerant\Node | null + * @return Node | null */ public function getStmts() { @@ -231,7 +232,7 @@ class PhpDocument * Returns the node at a specified position * * @param Position $position - * @return Tolerant\Node|null + * @return Node|null */ public function getNodeAtPosition(Position $position) { @@ -267,7 +268,7 @@ class PhpDocument * Returns the definition node for a fully qualified name * * @param string $fqn - * @return Tolerant\Node|null + * @return Node|null */ public function getDefinitionNodeByFqn(string $fqn) { @@ -277,7 +278,7 @@ class PhpDocument /** * Returns a map from fully qualified name (FQN) to Nodes defined in this document * - * @return Tolerant\Node[] + * @return Node[] */ public function getDefinitionNodes() { diff --git a/src/PhpDocumentLoader.php b/src/PhpDocumentLoader.php index 0c5bbca..57a7e9c 100644 --- a/src/PhpDocumentLoader.php +++ b/src/PhpDocumentLoader.php @@ -8,7 +8,7 @@ use LanguageServer\Index\ProjectIndex; use phpDocumentor\Reflection\DocBlockFactory; use Sabre\Event\Promise; use function Sabre\Event\coroutine; -use Microsoft\PhpParser as Tolerant; +use Microsoft\PhpParser; /** * Takes care of loading documents and managing "open" documents @@ -38,7 +38,7 @@ class PhpDocumentLoader private $parser; /** - * @var Tolerant\Parser + * @var PhpParser\Parser */ private $tolerantParser; @@ -66,7 +66,7 @@ class PhpDocumentLoader $this->contentRetriever = $contentRetriever; $this->projectIndex = $projectIndex; $this->definitionResolver = $definitionResolver; - $this->parser = new Tolerant\Parser(); + $this->parser = new PhpParser\Parser(); $this->docBlockFactory = DocBlockFactory::createInstance(); } diff --git a/src/Protocol/Location.php b/src/Protocol/Location.php index 0de3c38..50fedfa 100644 --- a/src/Protocol/Location.php +++ b/src/Protocol/Location.php @@ -2,7 +2,8 @@ namespace LanguageServer\Protocol; -use Microsoft\PhpParser as Tolerant; +use Microsoft\PhpParser; +use Microsoft\PhpParser\Node; /** * Represents a location inside a resource, such as a line inside a text file. @@ -22,12 +23,12 @@ class Location /** * Returns the location of the node * - * @param Tolerant\Node $node + * @param Node $node * @return self */ public static function fromNode($node) { - $range = Tolerant\PositionUtilities::getRangeFromPosition($node->getStart(), $node->getWidth(), $node->getFileContents()); + $range = PhpParser\PositionUtilities::getRangeFromPosition($node->getStart(), $node->getWidth(), $node->getFileContents()); return new self($node->getUri(), new Range( new Position($range->start->line, $range->start->character), new Position($range->end->line, $range->end->character) diff --git a/src/Protocol/Range.php b/src/Protocol/Range.php index de2011b..482004a 100644 --- a/src/Protocol/Range.php +++ b/src/Protocol/Range.php @@ -2,7 +2,8 @@ namespace LanguageServer\Protocol; -use Microsoft\PhpParser as Tolerant; +use Microsoft\PhpParser; +use Microsoft\PhpParser\Node; /** * A range in a text document expressed as (zero-based) start and end positions. @@ -26,12 +27,12 @@ class Range /** * Returns the range the node spans * - * @param Tolerant\Node $node + * @param Node $node * @return self */ public static function fromNode($node) { - $range = Tolerant\PositionUtilities::getRangeFromPosition($node->getStart(), $node->getWidth(), $node->getFileContents()); + $range = PhpParser\PositionUtilities::getRangeFromPosition($node->getStart(), $node->getWidth(), $node->getFileContents()); return new self( new Position($range->start->line, $range->start->character), diff --git a/src/Protocol/SymbolInformation.php b/src/Protocol/SymbolInformation.php index ec8730c..895830a 100644 --- a/src/Protocol/SymbolInformation.php +++ b/src/Protocol/SymbolInformation.php @@ -2,7 +2,8 @@ namespace LanguageServer\Protocol; -use Microsoft\PhpParser as Tolerant; +use Microsoft\PhpParser; +use Microsoft\PhpParser\Node; use Exception; /** @@ -42,16 +43,16 @@ class SymbolInformation /** * Converts a Node to a SymbolInformation * - * @param Tolerant\Node $node + * @param Node $node * @param string $fqn If given, $containerName will be extracted from it * @return SymbolInformation|null */ public static function fromNode($node, string $fqn = null) { $symbol = new self; - if ($node instanceof Tolerant\Node\Statement\ClassDeclaration) { + if ($node instanceof Node\Statement\ClassDeclaration) { $symbol->kind = SymbolKind::CLASS_; - } else if ($node instanceof Tolerant\Node\Statement\TraitDeclaration) { + } else if ($node instanceof Node\Statement\TraitDeclaration) { $symbol->kind = SymbolKind::CLASS_; } else if (\LanguageServer\ParserHelpers::isConstDefineExpression($node)) { @@ -59,49 +60,49 @@ class SymbolInformation // define('TEST_DEFINE_CONSTANT', false); $symbol->kind = SymbolKind::CONSTANT; $symbol->name = $node->argumentExpressionList->children[0]->expression->getStringContentsText(); - } else if ($node instanceof Tolerant\Node\Statement\InterfaceDeclaration) { + } else if ($node instanceof Node\Statement\InterfaceDeclaration) { $symbol->kind = SymbolKind::INTERFACE; - } else if ($node instanceof Tolerant\Node\Statement\NamespaceDefinition) { + } else if ($node instanceof Node\Statement\NamespaceDefinition) { $symbol->kind = SymbolKind::NAMESPACE; - } else if ($node instanceof Tolerant\Node\Statement\FunctionDeclaration) { + } else if ($node instanceof Node\Statement\FunctionDeclaration) { $symbol->kind = SymbolKind::FUNCTION; - } else if ($node instanceof Tolerant\Node\MethodDeclaration) { + } else if ($node instanceof Node\MethodDeclaration) { $nameText = $node->getName(); if ($nameText === '__construct' || $nameText === '__destruct') { $symbol->kind = SymbolKind::CONSTRUCTOR; } else { $symbol->kind = SymbolKind::METHOD; } - } else if ($node instanceof Tolerant\Node\Expression\Variable && $node->getFirstAncestor(Tolerant\Node\PropertyDeclaration::class) !== null) { + } else if ($node instanceof Node\Expression\Variable && $node->getFirstAncestor(Node\PropertyDeclaration::class) !== null) { $symbol->kind = SymbolKind::PROPERTY; - } else if ($node instanceof Tolerant\Node\ConstElement) { + } else if ($node instanceof Node\ConstElement) { $symbol->kind = SymbolKind::CONSTANT; } else if ( ( - ($node instanceof Tolerant\Node\Expression\AssignmentExpression) - && $node->leftOperand instanceof Tolerant\Node\Expression\Variable + ($node instanceof Node\Expression\AssignmentExpression) + && $node->leftOperand instanceof Node\Expression\Variable ) - || $node instanceof Tolerant\Node\UseVariableName - || $node instanceof Tolerant\Node\Parameter + || $node instanceof Node\UseVariableName + || $node instanceof Node\Parameter ) { $symbol->kind = SymbolKind::VARIABLE; } else { return null; } - if ($node instanceof Tolerant\Node\Expression\AssignmentExpression) { - if ($node->leftOperand instanceof Tolerant\Node\Expression\Variable) { + if ($node instanceof Node\Expression\AssignmentExpression) { + if ($node->leftOperand instanceof Node\Expression\Variable) { $symbol->name = $node->leftOperand->getName(); - } elseif ($node->leftOperand instanceof Tolerant\Token) { + } elseif ($node->leftOperand instanceof PhpParser\Token) { $symbol->name = trim($node->leftOperand->getText($node->getFileContents()), "$"); } - } else if ($node instanceof Tolerant\Node\UseVariableName) { + } else if ($node instanceof Node\UseVariableName) { $symbol->name = $node->getName(); } else if (isset($node->name)) { - if ($node->name instanceof Tolerant\Node\QualifiedName) { - $symbol->name = (string)Tolerant\ResolvedName::buildName($node->name->nameParts, $node->getFileContents()); + if ($node->name instanceof Node\QualifiedName) { + $symbol->name = (string)PhpParser\ResolvedName::buildName($node->name->nameParts, $node->getFileContents()); } else { $symbol->name = ltrim((string)$node->name->getText($node->getFileContents()), "$"); } diff --git a/src/Server/TextDocument.php b/src/Server/TextDocument.php index 6dadf2f..d00ebfa 100644 --- a/src/Server/TextDocument.php +++ b/src/Server/TextDocument.php @@ -10,7 +10,8 @@ use LanguageServer\Index\ReadableIndex; use LanguageServer\Protocol\{ FormattingOptions, Hover, Location, MarkedString, Position, Range, ReferenceContext, SymbolDescriptor, SymbolLocationInformation, TextDocumentIdentifier, TextDocumentItem, VersionedTextDocumentIdentifier }; -use Microsoft\PhpParser as Tolerant; +use Microsoft\PhpParser; +use Microsoft\PhpParser\Node; use Sabre\Event\Promise; use Sabre\Uri; use function LanguageServer\{ @@ -183,24 +184,24 @@ class TextDocument // by traversing the AST if ( - ($node instanceof Tolerant\Node\Expression\Variable && !($node->getParent()->getParent() instanceof Tolerant\Node\PropertyDeclaration)) - || $node instanceof Tolerant\Node\Parameter - || $node instanceof Tolerant\Node\UseVariableName + ($node instanceof Node\Expression\Variable && !($node->getParent()->getParent() instanceof Node\PropertyDeclaration)) + || $node instanceof Node\Parameter + || $node instanceof Node\UseVariableName ) { - if (isset($node->name) && $node->name instanceof Tolerant\Node\Expression) { + if (isset($node->name) && $node->name instanceof Node\Expression) { return null; } // Find function/method/closure scope $n = $node; - $n = $n->getFirstAncestor(Tolerant\Node\Statement\FunctionDeclaration::class, Tolerant\Node\MethodDeclaration::class, Tolerant\Node\Expression\AnonymousFunctionCreationExpression::class, Tolerant\Node\SourceFileNode::class); + $n = $n->getFirstAncestor(Node\Statement\FunctionDeclaration::class, Node\MethodDeclaration::class, Node\Expression\AnonymousFunctionCreationExpression::class, Node\SourceFileNode::class); if ($n === null) { - $n = $node->getFirstAncestor(Tolerant\Node\Statement\ExpressionStatement::class)->getParent(); + $n = $node->getFirstAncestor(Node\Statement\ExpressionStatement::class)->getParent(); } foreach ($n->getDescendantNodes() as $descendantNode) { - if ($descendantNode instanceof Tolerant\Node\Expression\Variable && + if ($descendantNode instanceof Node\Expression\Variable && $descendantNode->getName() === $node->getName() ) { $locations[] = Location::fromNode($descendantNode); diff --git a/src/TreeAnalyzer.php b/src/TreeAnalyzer.php index e4cd788..6f7cdc0 100644 --- a/src/TreeAnalyzer.php +++ b/src/TreeAnalyzer.php @@ -7,12 +7,13 @@ use LanguageServer\Protocol\{Diagnostic, DiagnosticSeverity, Range, Position, Te use LanguageServer\Index\Index; use phpDocumentor\Reflection\DocBlockFactory; use Sabre\Uri; -use Microsoft\PhpParser as Tolerant; +use Microsoft\PhpParser; +use Microsoft\PhpParser\Node; class TreeAnalyzer { private $parser; - /** @var Tolerant\Node */ + /** @var Node */ private $stmts; private $diagnostics; @@ -21,7 +22,7 @@ class TreeAnalyzer { /** * TreeAnalyzer constructor. - * @param Tolerant\Parser $parser + * @param PhpParser\Parser $parser * @param $content * @param $docBlockFactory * @param DefinitionResolver $definitionResolver @@ -40,7 +41,7 @@ class TreeAnalyzer { $this->collectDefinitionsAndReferences($this->stmts); } - public function collectDefinitionsAndReferences(Tolerant\Node $stmts) { + public function collectDefinitionsAndReferences(Node $stmts) { foreach ($stmts::CHILD_NAMES as $name) { $node = $stmts->$name; @@ -50,19 +51,19 @@ class TreeAnalyzer { if (\is_array($node)) { foreach ($node as $child) { - if ($child instanceof Tolerant\Node) { + if ($child instanceof Node) { $this->update($child); } } continue; } - if ($node instanceof Tolerant\Node) { + if ($node instanceof Node) { $this->update($node); } - if (($_error = Tolerant\DiagnosticsProvider::checkDiagnostics($node)) !== null) { - $range = Tolerant\PositionUtilities::getRangeFromPosition($_error->start, $_error->length, $this->content); + if (($_error = PhpParser\DiagnosticsProvider::checkDiagnostics($node)) !== null) { + $range = PhpParser\PositionUtilities::getRangeFromPosition($_error->start, $_error->length, $this->content); $this->diagnostics[] = new Diagnostic( $_error->message, @@ -88,14 +89,14 @@ class TreeAnalyzer { $parent = $node->parent; if (!( ( - // $node->parent instanceof Tolerant\Node\Expression\ScopedPropertyAccessExpression || - ($node instanceof Tolerant\Node\Expression\ScopedPropertyAccessExpression || - $node instanceof Tolerant\Node\Expression\MemberAccessExpression) + // $node->parent instanceof Node\Expression\ScopedPropertyAccessExpression || + ($node instanceof Node\Expression\ScopedPropertyAccessExpression || + $node instanceof Node\Expression\MemberAccessExpression) && !( - $node->parent instanceof Tolerant\Node\Expression\CallExpression || - $node->memberName instanceof Tolerant\Token + $node->parent instanceof Node\Expression\CallExpression || + $node->memberName instanceof PhpParser\Token )) - || ($parent instanceof Tolerant\Node\Statement\NamespaceDefinition && $parent->name !== null && $parent->name->getStart() === $node->getStart())) + || ($parent instanceof Node\Statement\NamespaceDefinition && $parent->name !== null && $parent->name->getStart() === $node->getStart())) ) { $fqn = $this->definitionResolver->resolveReferenceNodeToFqn($node); @@ -103,9 +104,9 @@ class TreeAnalyzer { $this->addReference($fqn, $node); if ( - $node instanceof Tolerant\Node\QualifiedName - && ($node->isQualifiedName() || $node->parent instanceof Tolerant\Node\NamespaceUseClause) - && !($parent instanceof Tolerant\Node\Statement\NamespaceDefinition && $parent->name->getStart() === $node->getStart() + $node instanceof Node\QualifiedName + && ($node->isQualifiedName() || $node->parent instanceof Node\NamespaceUseClause) + && !($parent instanceof Node\Statement\NamespaceDefinition && $parent->name->getStart() === $node->getStart() ) ) { // Add references for each referenced namespace @@ -120,10 +121,10 @@ class TreeAnalyzer { // to the global version because PHP falls back to global at runtime // http://php.net/manual/en/language.namespaces.fallback.php if (ParserHelpers::isConstantFetch($node) || - ($parent instanceof Tolerant\Node\Expression\CallExpression + ($parent instanceof Node\Expression\CallExpression && !( - $node instanceof Tolerant\Node\Expression\ScopedPropertyAccessExpression || - $node instanceof Tolerant\Node\Expression\MemberAccessExpression + $node instanceof Node\Expression\ScopedPropertyAccessExpression || + $node instanceof Node\Expression\MemberAccessExpression ))) { $parts = explode('\\', $fqn); if (count($parts) > 1) { @@ -141,7 +142,7 @@ class TreeAnalyzer { return $this->diagnostics ?? []; } - private function addReference(string $fqn, Tolerant\Node $node) + private function addReference(string $fqn, Node $node) { if (!isset($this->referenceNodes[$fqn])) { $this->referenceNodes[$fqn] = []; diff --git a/tests/DefinitionResolverTest.php b/tests/DefinitionResolverTest.php index dc287cb..e7d8b78 100644 --- a/tests/DefinitionResolverTest.php +++ b/tests/DefinitionResolverTest.php @@ -6,13 +6,13 @@ namespace LanguageServer\Tests; use PHPUnit\Framework\TestCase; use LanguageServer\Index\Index; use LanguageServer\DefinitionResolver; -use Microsoft\PhpParser as Tolerant; +use Microsoft\PhpParser; class DefinitionResolverTest extends TestCase { public function testCreateDefinitionFromNode() { - $parser = new Tolerant\Parser; + $parser = new PhpParser\Parser; $doc = new MockPhpDocument; $stmts = $parser->parseSourceFile("getUri()); @@ -25,7 +25,7 @@ class DefinitionResolverTest extends TestCase public function testGetTypeFromNode() { - $parser = new Tolerant\Parser; + $parser = new PhpParser\Parser; $doc = new MockPhpDocument; $stmts = $parser->parseSourceFile("getUri()); @@ -39,7 +39,7 @@ class DefinitionResolverTest extends TestCase public function testGetDefinedFqnForIncompleteDefine() { // define('XXX') (only one argument) must not introduce a new symbol - $parser = new Tolerant\Parser; + $parser = new PhpParser\Parser; $doc = new MockPhpDocument; $stmts = $parser->parseSourceFile("getUri()); @@ -52,7 +52,7 @@ class DefinitionResolverTest extends TestCase public function testGetDefinedFqnForDefine() { - $parser = new Tolerant\Parser; + $parser = new PhpParser\Parser; $doc = new MockPhpDocument; $stmts = $parser->parseSourceFile("getUri()); diff --git a/tests/NodeVisitor/DefinitionCollectorTest.php b/tests/NodeVisitor/DefinitionCollectorTest.php index fa47185..604f30d 100644 --- a/tests/NodeVisitor/DefinitionCollectorTest.php +++ b/tests/NodeVisitor/DefinitionCollectorTest.php @@ -10,7 +10,8 @@ use LanguageServer\{ }; use LanguageServer\Index\{Index}; use function LanguageServer\pathToUri; -use Microsoft\PhpParser as Tolerant; +use Microsoft\PhpParser; +use Microsoft\PhpParser\Node; class DefinitionCollectorTest extends TestCase { @@ -37,21 +38,21 @@ class DefinitionCollectorTest extends TestCase 'TestNamespace\\Example->__destruct()' ], array_keys($defNodes)); - $this->assertInstanceOf(Tolerant\Node\ConstElement::class, $defNodes['TestNamespace\\TEST_CONST']); - $this->assertInstanceOf(Tolerant\Node\Statement\ClassDeclaration::class, $defNodes['TestNamespace\\TestClass']); - $this->assertInstanceOf(Tolerant\Node\ConstElement::class, $defNodes['TestNamespace\\TestClass::TEST_CLASS_CONST']); + $this->assertInstanceOf(Node\ConstElement::class, $defNodes['TestNamespace\\TEST_CONST']); + $this->assertInstanceOf(Node\Statement\ClassDeclaration::class, $defNodes['TestNamespace\\TestClass']); + $this->assertInstanceOf(Node\ConstElement::class, $defNodes['TestNamespace\\TestClass::TEST_CLASS_CONST']); // TODO - should we parse properties more strictly? - $this->assertInstanceOf(Tolerant\Node\Expression\Variable::class, $defNodes['TestNamespace\\TestClass::$staticTestProperty']); - $this->assertInstanceOf(Tolerant\Node\Expression\Variable::class, $defNodes['TestNamespace\\TestClass->testProperty']); - $this->assertInstanceOf(Tolerant\Node\MethodDeclaration::class, $defNodes['TestNamespace\\TestClass::staticTestMethod()']); - $this->assertInstanceOf(Tolerant\Node\MethodDeclaration::class, $defNodes['TestNamespace\\TestClass->testMethod()']); - $this->assertInstanceOf(Tolerant\Node\Statement\TraitDeclaration::class, $defNodes['TestNamespace\\TestTrait']); - $this->assertInstanceOf(Tolerant\Node\Statement\InterfaceDeclaration::class, $defNodes['TestNamespace\\TestInterface']); - $this->assertInstanceOf(Tolerant\Node\Statement\FunctionDeclaration::class, $defNodes['TestNamespace\\test_function()']); - $this->assertInstanceOf(Tolerant\Node\Statement\ClassDeclaration::class, $defNodes['TestNamespace\\ChildClass']); - $this->assertInstanceOf(Tolerant\Node\Statement\ClassDeclaration::class, $defNodes['TestNamespace\\Example']); - $this->assertInstanceOf(Tolerant\Node\MethodDeclaration::class, $defNodes['TestNamespace\\Example->__construct()']); - $this->assertInstanceOf(Tolerant\Node\MethodDeclaration::class, $defNodes['TestNamespace\\Example->__destruct()']); + $this->assertInstanceOf(Node\Expression\Variable::class, $defNodes['TestNamespace\\TestClass::$staticTestProperty']); + $this->assertInstanceOf(Node\Expression\Variable::class, $defNodes['TestNamespace\\TestClass->testProperty']); + $this->assertInstanceOf(Node\MethodDeclaration::class, $defNodes['TestNamespace\\TestClass::staticTestMethod()']); + $this->assertInstanceOf(Node\MethodDeclaration::class, $defNodes['TestNamespace\\TestClass->testMethod()']); + $this->assertInstanceOf(Node\Statement\TraitDeclaration::class, $defNodes['TestNamespace\\TestTrait']); + $this->assertInstanceOf(Node\Statement\InterfaceDeclaration::class, $defNodes['TestNamespace\\TestInterface']); + $this->assertInstanceOf(Node\Statement\FunctionDeclaration::class, $defNodes['TestNamespace\\test_function()']); + $this->assertInstanceOf(Node\Statement\ClassDeclaration::class, $defNodes['TestNamespace\\ChildClass']); + $this->assertInstanceOf(Node\Statement\ClassDeclaration::class, $defNodes['TestNamespace\\Example']); + $this->assertInstanceOf(Node\MethodDeclaration::class, $defNodes['TestNamespace\\Example->__construct()']); + $this->assertInstanceOf(Node\MethodDeclaration::class, $defNodes['TestNamespace\\Example->__destruct()']); } public function testDoesNotCollectReferences() @@ -60,8 +61,8 @@ class DefinitionCollectorTest extends TestCase $defNodes = $this->collectDefinitions($path); $this->assertEquals(['TestNamespace', 'TestNamespace\\whatever()'], array_keys($defNodes)); - $this->assertInstanceOf(Tolerant\Node\Statement\NamespaceDefinition::class, $defNodes['TestNamespace']); - $this->assertInstanceOf(Tolerant\Node\Statement\FunctionDeclaration::class, $defNodes['TestNamespace\\whatever()']); + $this->assertInstanceOf(Node\Statement\NamespaceDefinition::class, $defNodes['TestNamespace']); + $this->assertInstanceOf(Node\Statement\FunctionDeclaration::class, $defNodes['TestNamespace\\whatever()']); } /** @@ -70,7 +71,7 @@ class DefinitionCollectorTest extends TestCase private function collectDefinitions($path): array { $uri = pathToUri($path); - $parser = new Tolerant\Parser(); + $parser = new PhpParser\Parser(); $docBlockFactory = DocBlockFactory::createInstance(); $index = new Index; diff --git a/tests/PhpDocumentTest.php b/tests/PhpDocumentTest.php index 926cb9d..167aea1 100644 --- a/tests/PhpDocumentTest.php +++ b/tests/PhpDocumentTest.php @@ -12,7 +12,8 @@ use LanguageServer\Index\{ use LanguageServer\Protocol\{ Position }; -use Microsoft\PhpParser as Tolerant; +use Microsoft\PhpParser; +use Microsoft\PhpParser\Node; use phpDocumentor\Reflection\DocBlockFactory; use PHPUnit\Framework\TestCase; use function LanguageServer\isVendored; @@ -21,7 +22,7 @@ class PhpDocumentTest extends TestCase { public function createDocument(string $uri, string $content) { - $parser = new Tolerant\Parser(); + $parser = new PhpParser\Parser(); $docBlockFactory = DocBlockFactory::createInstance(); $index = new Index; $definitionResolver = new DefinitionResolver($index); @@ -44,7 +45,7 @@ class PhpDocumentTest extends TestCase } private function assertQualifiedName($node) { - $this->assertInstanceOf(Tolerant\Node\QualifiedName::class, $node); + $this->assertInstanceOf(Node\QualifiedName::class, $node); } public function testIsVendored() diff --git a/tests/Validation/ValidationTest.php b/tests/Validation/ValidationTest.php index 06e97ed..3703083 100644 --- a/tests/Validation/ValidationTest.php +++ b/tests/Validation/ValidationTest.php @@ -19,7 +19,7 @@ use AdvancedJsonRpc; use RecursiveDirectoryIterator; use RecursiveIteratorIterator; use Sabre\Event\Loop; -use Microsoft\PhpParser as Tolerant; +use Microsoft\PhpParser; $frameworksDir = realpath(__DIR__ . '/../../validation/frameworks'); @@ -94,7 +94,7 @@ class ValidationTest extends TestCase global $frameworksDir; $index = new Index(); - $parser = new Tolerant\Parser(); + $parser = new PhpParser\Parser(); $docBlockFactory = DocBlockFactory::createInstance(); $definitionResolver = new DefinitionResolver($index);