Remove "Tolerant" alias
- Now unnecessary - Makes type annotations more readablepull/357/head
parent
836cdb77c0
commit
3dfe505727
|
@ -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);
|
||||
|
|
|
@ -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('<?php', CompletionItemKind::KEYWORD);
|
||||
$item->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 <Tolerant\Node\Expr\Variable|Tolerant\Node\Param|Tolerant\Node\Expr\ClosureUse>
|
||||
* @return array <Node\Expr\Variable|Node\Param|Node\Expr\ClosureUse>
|
||||
*/
|
||||
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
|
||||
);
|
||||
};
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)) {
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
namespace LanguageServer;
|
||||
|
||||
use phpDocumentor\Reflection\{Type, Types};
|
||||
use Microsoft\PhpParser as Tolerant;
|
||||
use Microsoft\PhpParser;
|
||||
|
||||
class FqnUtilities
|
||||
{
|
||||
|
|
|
@ -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]);
|
||||
}
|
||||
}
|
|
@ -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()
|
||||
{
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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()), "$");
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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] = [];
|
||||
|
|
|
@ -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("<?php\ndefine('TEST_DEFINE', true);", $doc->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("<?php\ndefine('TEST_DEFINE', true);", $doc->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("<?php\ndefine('TEST_DEFINE');", $doc->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("<?php\ndefine('TEST_DEFINE', true);", $doc->getUri());
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
Loading…
Reference in New Issue