Fix autofixable formatting errors
parent
05aa935908
commit
2568a42e12
|
@ -150,8 +150,9 @@ class CompletionProvider
|
||||||
stripStringOverlap($doc->getRange(new Range(new Position(0, 0), $pos)), '<?php')
|
stripStringOverlap($doc->getRange(new Range(new Position(0, 0), $pos)), '<?php')
|
||||||
);
|
);
|
||||||
$list->items[] = $item;
|
$list->items[] = $item;
|
||||||
}
|
} /*
|
||||||
// VARIABLES
|
|
||||||
|
VARIABLES */
|
||||||
elseif (
|
elseif (
|
||||||
$node instanceof Node\Expression\Variable &&
|
$node instanceof Node\Expression\Variable &&
|
||||||
!(
|
!(
|
||||||
|
@ -172,11 +173,11 @@ class CompletionProvider
|
||||||
);
|
);
|
||||||
$list->items[] = $item;
|
$list->items[] = $item;
|
||||||
}
|
}
|
||||||
}
|
} /*
|
||||||
|
|
||||||
// MEMBER ACCESS EXPRESSIONS
|
MEMBER ACCESS EXPRESSIONS
|
||||||
// $a->c#
|
$a->c#
|
||||||
// $a->#
|
$a-># */
|
||||||
elseif ($node instanceof Node\Expression\MemberAccessExpression) {
|
elseif ($node instanceof Node\Expression\MemberAccessExpression) {
|
||||||
$prefixes = FqnUtilities::getFqnsFromType(
|
$prefixes = FqnUtilities::getFqnsFromType(
|
||||||
$this->definitionResolver->resolveExpressionNodeToType($node->dereferencableExpression)
|
$this->definitionResolver->resolveExpressionNodeToType($node->dereferencableExpression)
|
||||||
|
@ -196,14 +197,14 @@ class CompletionProvider
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
} /*
|
||||||
|
|
||||||
// SCOPED PROPERTY ACCESS EXPRESSIONS
|
SCOPED PROPERTY ACCESS EXPRESSIONS
|
||||||
// A\B\C::$a#
|
A\B\C::$a#
|
||||||
// A\B\C::#
|
A\B\C::#
|
||||||
// A\B\C::$#
|
A\B\C::$#
|
||||||
// A\B\C::foo#
|
A\B\C::foo#
|
||||||
// TODO: $a::#
|
TODO: $a::# */
|
||||||
elseif (
|
elseif (
|
||||||
($scoped = $node->parent) instanceof Node\Expression\ScopedPropertyAccessExpression ||
|
($scoped = $node->parent) instanceof Node\Expression\ScopedPropertyAccessExpression ||
|
||||||
($scoped = $node) instanceof Node\Expression\ScopedPropertyAccessExpression
|
($scoped = $node) instanceof Node\Expression\ScopedPropertyAccessExpression
|
||||||
|
@ -230,7 +231,6 @@ class CompletionProvider
|
||||||
} elseif (ParserHelpers::isConstantFetch($node) ||
|
} elseif (ParserHelpers::isConstantFetch($node) ||
|
||||||
($creation = $node->parent) instanceof Node\Expression\ObjectCreationExpression ||
|
($creation = $node->parent) instanceof Node\Expression\ObjectCreationExpression ||
|
||||||
(($creation = $node) instanceof Node\Expression\ObjectCreationExpression)) {
|
(($creation = $node) instanceof Node\Expression\ObjectCreationExpression)) {
|
||||||
|
|
||||||
$class = isset($creation) ? $creation->classTypeDesignator : $node;
|
$class = isset($creation) ? $creation->classTypeDesignator : $node;
|
||||||
|
|
||||||
$prefix = $class instanceof Node\QualifiedName
|
$prefix = $class instanceof Node\QualifiedName
|
||||||
|
@ -240,7 +240,7 @@ class CompletionProvider
|
||||||
$namespaceDefinition = $node->getNamespaceDefinition();
|
$namespaceDefinition = $node->getNamespaceDefinition();
|
||||||
|
|
||||||
list($namespaceImportTable,,) = $node->getImportTablesForCurrentScope();
|
list($namespaceImportTable,,) = $node->getImportTablesForCurrentScope();
|
||||||
foreach ($namespaceImportTable as $alias=>$name) {
|
foreach ($namespaceImportTable as $alias => $name) {
|
||||||
$namespaceImportTable[$alias] = (string)$name;
|
$namespaceImportTable[$alias] = (string)$name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -267,8 +267,7 @@ class CompletionProvider
|
||||||
|
|
||||||
if (!$isNotFullyQualified && ($fqnStartsWithPrefix || strStartsWith($fqn, $namespacePrefix . "\\" . $prefix))) {
|
if (!$isNotFullyQualified && ($fqnStartsWithPrefix || strStartsWith($fqn, $namespacePrefix . "\\" . $prefix))) {
|
||||||
// $fqn = $fqn;
|
// $fqn = $fqn;
|
||||||
}
|
} elseif (!$isAliased && !array_search($fqn, array_values($namespaceImportTable))) {
|
||||||
elseif (!$isAliased && !array_search($fqn, array_values($namespaceImportTable))) {
|
|
||||||
if (empty($prefix)) {
|
if (empty($prefix)) {
|
||||||
$fqn = '\\' . $fqn;
|
$fqn = '\\' . $fqn;
|
||||||
} elseif (strStartsWith($fqn, $namespacePrefix . "\\" . $prefix)) {
|
} elseif (strStartsWith($fqn, $namespacePrefix . "\\" . $prefix)) {
|
||||||
|
@ -406,7 +405,7 @@ class CompletionProvider
|
||||||
&& $node->leftOperand instanceof Node\Expression\Variable
|
&& $node->leftOperand instanceof Node\Expression\Variable
|
||||||
&& (empty($namePrefix) || strpos($node->leftOperand->getName(), $namePrefix) !== false);
|
&& (empty($namePrefix) || strpos($node->leftOperand->getName(), $namePrefix) !== false);
|
||||||
};
|
};
|
||||||
$isNotFunctionLike = function($node) {
|
$isNotFunctionLike = function ($node) {
|
||||||
return !(
|
return !(
|
||||||
ParserHelpers::isFunctionLike($node) ||
|
ParserHelpers::isFunctionLike($node) ||
|
||||||
$node instanceof Node\Statement\ClassDeclaration ||
|
$node instanceof Node\Statement\ClassDeclaration ||
|
||||||
|
|
|
@ -139,7 +139,7 @@ class DefinitionResolver
|
||||||
$docCommentText = $node->getDocCommentText();
|
$docCommentText = $node->getDocCommentText();
|
||||||
if ($docCommentText !== null) {
|
if ($docCommentText !== null) {
|
||||||
list($namespaceImportTable,,) = $node->getImportTablesForCurrentScope();
|
list($namespaceImportTable,,) = $node->getImportTablesForCurrentScope();
|
||||||
foreach ($namespaceImportTable as $alias=>$name) {
|
foreach ($namespaceImportTable as $alias => $name) {
|
||||||
$namespaceImportTable[$alias] = (string)$name;
|
$namespaceImportTable[$alias] = (string)$name;
|
||||||
}
|
}
|
||||||
$namespaceDefinition = $node->getNamespaceDefinition();
|
$namespaceDefinition = $node->getNamespaceDefinition();
|
||||||
|
@ -197,8 +197,7 @@ class DefinitionResolver
|
||||||
|
|
||||||
if ($node instanceof Node\Statement\ClassDeclaration &&
|
if ($node instanceof Node\Statement\ClassDeclaration &&
|
||||||
// TODO - this should be bette rrpreented in the parser API
|
// TODO - this should be bette rrpreented in the parser API
|
||||||
$node->classBaseClause !== null && $node->classBaseClause->baseClass !== null)
|
$node->classBaseClause !== null && $node->classBaseClause->baseClass !== null) {
|
||||||
{
|
|
||||||
$def->extends = [(string)$node->classBaseClause->baseClass->getResolvedName()];
|
$def->extends = [(string)$node->classBaseClause->baseClass->getResolvedName()];
|
||||||
// TODO - why is this represented as an array?
|
// TODO - why is this represented as an array?
|
||||||
// TODO interface implementations.
|
// TODO interface implementations.
|
||||||
|
@ -237,8 +236,7 @@ class DefinitionResolver
|
||||||
// Ignore variable nodes that are part of ScopedPropertyAccessExpression,
|
// Ignore variable nodes that are part of ScopedPropertyAccessExpression,
|
||||||
// as the scoped property access expression node is handled separately.
|
// as the scoped property access expression node is handled separately.
|
||||||
if ($node instanceof Node\Expression\Variable &&
|
if ($node instanceof Node\Expression\Variable &&
|
||||||
!($parent instanceof Node\Expression\ScopedPropertyAccessExpression))
|
!($parent instanceof Node\Expression\ScopedPropertyAccessExpression)) {
|
||||||
{
|
|
||||||
// Resolve $this to the containing class definition.
|
// Resolve $this to the containing class definition.
|
||||||
if ($node->getName() === 'this' && $fqn = $this->getContainingClassFqn($node)) {
|
if ($node->getName() === 'this' && $fqn = $this->getContainingClassFqn($node)) {
|
||||||
return $this->index->getDefinition($fqn, false);
|
return $this->index->getDefinition($fqn, false);
|
||||||
|
@ -272,19 +270,16 @@ class DefinitionResolver
|
||||||
* @param Node $node
|
* @param Node $node
|
||||||
* @return string|null
|
* @return string|null
|
||||||
*/
|
*/
|
||||||
public function resolveReferenceNodeToFqn($node) {
|
public function resolveReferenceNodeToFqn($node)
|
||||||
|
{
|
||||||
// TODO all name tokens should be a part of a node
|
// TODO all name tokens should be a part of a node
|
||||||
if ($node instanceof Node\QualifiedName) {
|
if ($node instanceof Node\QualifiedName) {
|
||||||
return $this->resolveQualifiedNameNodeToFqn($node);
|
return $this->resolveQualifiedNameNodeToFqn($node);
|
||||||
}
|
} else if ($node instanceof Node\Expression\MemberAccessExpression) {
|
||||||
|
|
||||||
else if ($node instanceof Node\Expression\MemberAccessExpression) {
|
|
||||||
return $this->resolveMemberAccessExpressionNodeToFqn($node);
|
return $this->resolveMemberAccessExpressionNodeToFqn($node);
|
||||||
}
|
} else if (ParserHelpers::isConstantFetch($node)) {
|
||||||
else if (ParserHelpers::isConstantFetch($node)) {
|
|
||||||
return (string)($node->getNamespacedName());
|
return (string)($node->getNamespacedName());
|
||||||
}
|
} else if (
|
||||||
else if (
|
|
||||||
// A\B::C - constant access expression
|
// A\B::C - constant access expression
|
||||||
$node instanceof Node\Expression\ScopedPropertyAccessExpression
|
$node instanceof Node\Expression\ScopedPropertyAccessExpression
|
||||||
&& !($node->memberName instanceof Node\Expression\Variable)
|
&& !($node->memberName instanceof Node\Expression\Variable)
|
||||||
|
@ -300,7 +295,8 @@ class DefinitionResolver
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private function resolveQualifiedNameNodeToFqn(Node\QualifiedName $node) {
|
private function resolveQualifiedNameNodeToFqn(Node\QualifiedName $node)
|
||||||
|
{
|
||||||
$parent = $node->parent;
|
$parent = $node->parent;
|
||||||
|
|
||||||
if ($parent instanceof Node\TraitSelectOrAliasClause) {
|
if ($parent instanceof Node\TraitSelectOrAliasClause) {
|
||||||
|
@ -346,7 +342,8 @@ class DefinitionResolver
|
||||||
return $name;
|
return $name;
|
||||||
}
|
}
|
||||||
|
|
||||||
private function resolveMemberAccessExpressionNodeToFqn(Node\Expression\MemberAccessExpression $access) {
|
private function resolveMemberAccessExpressionNodeToFqn(Node\Expression\MemberAccessExpression $access)
|
||||||
|
{
|
||||||
if ($access->memberName instanceof Node\Expression) {
|
if ($access->memberName instanceof Node\Expression) {
|
||||||
// Cannot get definition if right-hand side is expression
|
// Cannot get definition if right-hand side is expression
|
||||||
return null;
|
return null;
|
||||||
|
@ -393,7 +390,6 @@ class DefinitionResolver
|
||||||
while ($implementorFqn = array_shift($implementorFqns)) {
|
while ($implementorFqn = array_shift($implementorFqns)) {
|
||||||
// If the member FQN exists, return it
|
// If the member FQN exists, return it
|
||||||
if ($this->index->getDefinition($implementorFqn . $memberSuffix)) {
|
if ($this->index->getDefinition($implementorFqn . $memberSuffix)) {
|
||||||
|
|
||||||
return $implementorFqn . $memberSuffix;
|
return $implementorFqn . $memberSuffix;
|
||||||
}
|
}
|
||||||
// Get Definition of implementor class
|
// Get Definition of implementor class
|
||||||
|
@ -413,7 +409,8 @@ class DefinitionResolver
|
||||||
return $classFqn . $memberSuffix;
|
return $classFqn . $memberSuffix;
|
||||||
}
|
}
|
||||||
|
|
||||||
private function resolveScopedPropertyAccessExpressionNodeToFqn(Node\Expression\ScopedPropertyAccessExpression $scoped) {
|
private function resolveScopedPropertyAccessExpressionNodeToFqn(Node\Expression\ScopedPropertyAccessExpression $scoped)
|
||||||
|
{
|
||||||
if ($scoped->scopeResolutionQualifier instanceof Node\Expression\Variable) {
|
if ($scoped->scopeResolutionQualifier instanceof Node\Expression\Variable) {
|
||||||
$varType = $this->getTypeFromNode($scoped->scopeResolutionQualifier);
|
$varType = $this->getTypeFromNode($scoped->scopeResolutionQualifier);
|
||||||
if ($varType === null) {
|
if ($varType === null) {
|
||||||
|
@ -502,7 +499,6 @@ class DefinitionResolver
|
||||||
// If a function is met, check the parameters and use statements
|
// If a function is met, check the parameters and use statements
|
||||||
if (ParserHelpers::isFunctionLike($n)) {
|
if (ParserHelpers::isFunctionLike($n)) {
|
||||||
if ($n->parameters !== null) {
|
if ($n->parameters !== null) {
|
||||||
|
|
||||||
foreach ($n->parameters->getElements() as $param) {
|
foreach ($n->parameters->getElements() as $param) {
|
||||||
if ($param->getName() === $name) {
|
if ($param->getName() === $name) {
|
||||||
return $param;
|
return $param;
|
||||||
|
@ -513,8 +509,7 @@ class DefinitionResolver
|
||||||
if ($n instanceof Node\Expression\AnonymousFunctionCreationExpression &&
|
if ($n instanceof Node\Expression\AnonymousFunctionCreationExpression &&
|
||||||
$n->anonymousFunctionUseClause !== null &&
|
$n->anonymousFunctionUseClause !== null &&
|
||||||
$n->anonymousFunctionUseClause->useVariableNameList !== null) {
|
$n->anonymousFunctionUseClause->useVariableNameList !== null) {
|
||||||
foreach ($n->anonymousFunctionUseClause->useVariableNameList->getElements() as $use
|
foreach ($n->anonymousFunctionUseClause->useVariableNameList->getElements() as $use) {
|
||||||
) {
|
|
||||||
if ($use->getName() === $name) {
|
if ($use->getName() === $name) {
|
||||||
return $use;
|
return $use;
|
||||||
}
|
}
|
||||||
|
@ -585,7 +580,6 @@ class DefinitionResolver
|
||||||
$expr->callableExpression instanceof Node\Expression\ScopedPropertyAccessExpression ||
|
$expr->callableExpression instanceof Node\Expression\ScopedPropertyAccessExpression ||
|
||||||
$expr->callableExpression instanceof Node\Expression\MemberAccessExpression)
|
$expr->callableExpression instanceof Node\Expression\MemberAccessExpression)
|
||||||
) {
|
) {
|
||||||
|
|
||||||
// Find the function definition
|
// Find the function definition
|
||||||
if ($expr->callableExpression instanceof Node\Expression) {
|
if ($expr->callableExpression instanceof Node\Expression) {
|
||||||
// Cannot get type for dynamic function call
|
// Cannot get type for dynamic function call
|
||||||
|
@ -627,36 +621,36 @@ class DefinitionResolver
|
||||||
|
|
||||||
// MEMBER ACCESS EXPRESSION
|
// MEMBER ACCESS EXPRESSION
|
||||||
if ($expr instanceof Node\Expression\MemberAccessExpression) {
|
if ($expr instanceof Node\Expression\MemberAccessExpression) {
|
||||||
if ($expr->memberName instanceof Node\Expression) {
|
if ($expr->memberName instanceof Node\Expression) {
|
||||||
return new Types\Mixed;
|
return new Types\Mixed;
|
||||||
}
|
}
|
||||||
$var = $expr->dereferencableExpression;
|
$var = $expr->dereferencableExpression;
|
||||||
|
|
||||||
// Resolve object
|
// Resolve object
|
||||||
$objType = $this->resolveExpressionNodeToType($var);
|
$objType = $this->resolveExpressionNodeToType($var);
|
||||||
if (!($objType instanceof Types\Compound)) {
|
if (!($objType instanceof Types\Compound)) {
|
||||||
$objType = new Types\Compound([$objType]);
|
$objType = new Types\Compound([$objType]);
|
||||||
}
|
}
|
||||||
for ($i = 0; $t = $objType->get($i); $i++) {
|
for ($i = 0; $t = $objType->get($i); $i++) {
|
||||||
if ($t instanceof Types\This) {
|
if ($t instanceof Types\This) {
|
||||||
$classFqn = self::getContainingClassFqn($expr);
|
$classFqn = self::getContainingClassFqn($expr);
|
||||||
if ($classFqn === null) {
|
if ($classFqn === null) {
|
||||||
return new Types\Mixed;
|
return new Types\Mixed;
|
||||||
}
|
}
|
||||||
} else if (!($t instanceof Types\Object_) || $t->getFqsen() === null) {
|
} else if (!($t instanceof Types\Object_) || $t->getFqsen() === null) {
|
||||||
return new Types\Mixed;
|
return new Types\Mixed;
|
||||||
} else {
|
} else {
|
||||||
$classFqn = substr((string)$t->getFqsen(), 1);
|
$classFqn = substr((string)$t->getFqsen(), 1);
|
||||||
}
|
}
|
||||||
$fqn = $classFqn . '->' . $expr->memberName->getText($expr->getFileContents());
|
$fqn = $classFqn . '->' . $expr->memberName->getText($expr->getFileContents());
|
||||||
if ($expr->parent instanceof Node\Expression\CallExpression) {
|
if ($expr->parent instanceof Node\Expression\CallExpression) {
|
||||||
$fqn .= '()';
|
$fqn .= '()';
|
||||||
}
|
}
|
||||||
$def = $this->index->getDefinition($fqn);
|
$def = $this->index->getDefinition($fqn);
|
||||||
if ($def !== null) {
|
if ($def !== null) {
|
||||||
return $def->type;
|
return $def->type;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// SCOPED PROPERTY ACCESS EXPRESSION
|
// SCOPED PROPERTY ACCESS EXPRESSION
|
||||||
|
@ -1023,8 +1017,7 @@ class DefinitionResolver
|
||||||
ParserHelpers::tryGetPropertyDeclaration($node) ??
|
ParserHelpers::tryGetPropertyDeclaration($node) ??
|
||||||
ParserHelpers::tryGetConstOrClassConstDeclaration($node)
|
ParserHelpers::tryGetConstOrClassConstDeclaration($node)
|
||||||
) !== null ||
|
) !== null ||
|
||||||
($node = $node->parent) instanceof Node\Expression\AssignmentExpression)
|
($node = $node->parent) instanceof Node\Expression\AssignmentExpression) {
|
||||||
{
|
|
||||||
$declarationNode = $declarationNode ?? $node;
|
$declarationNode = $declarationNode ?? $node;
|
||||||
|
|
||||||
// Property, constant or variable
|
// Property, constant or variable
|
||||||
|
@ -1084,25 +1077,27 @@ class DefinitionResolver
|
||||||
|
|
||||||
// INPUT OUTPUT:
|
// INPUT OUTPUT:
|
||||||
// namespace A\B; A\B
|
// namespace A\B; A\B
|
||||||
else if ($node instanceof Node\Statement\NamespaceDefinition && $node->name instanceof Node\QualifiedName) {
|
if ($node instanceof Node\Statement\NamespaceDefinition && $node->name instanceof Node\QualifiedName) {
|
||||||
$name = (string) PhpParser\ResolvedName::buildName($node->name->nameParts, $node->getFileContents());
|
$name = (string) PhpParser\ResolvedName::buildName($node->name->nameParts, $node->getFileContents());
|
||||||
return \count($name) > 0 ? $name : null;
|
return \count($name) > 0 ? $name : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// INPUT OUTPUT:
|
// INPUT OUTPUT:
|
||||||
// namespace A\B;
|
// namespace A\B;
|
||||||
// function a(); A\B\a();
|
// function a(); A\B\a();
|
||||||
else if ($node instanceof Node\Statement\FunctionDeclaration) {
|
if ($node instanceof Node\Statement\FunctionDeclaration) {
|
||||||
// Function: use functionName() as the name
|
// Function: use functionName() as the name
|
||||||
$name = (string)$node->getNamespacedName();
|
$name = (string)$node->getNamespacedName();
|
||||||
return \count($name) > 0 ? $name . '()' : null;
|
return \count($name) > 0 ? $name . '()' : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// INPUT OUTPUT
|
// INPUT OUTPUT
|
||||||
// namespace A\B;
|
// namespace A\B;
|
||||||
// class C {
|
// class C {
|
||||||
// function a () {} A\B\C->a()
|
// function a () {} A\B\C->a()
|
||||||
// static function b() {} A\B\C::b()
|
// static function b() {} A\B\C::b()
|
||||||
// }
|
// }
|
||||||
else if ($node instanceof Node\MethodDeclaration) {
|
if ($node instanceof Node\MethodDeclaration) {
|
||||||
// Class method: use ClassName->methodName() as name
|
// Class method: use ClassName->methodName() as name
|
||||||
$class = $node->getFirstAncestor(
|
$class = $node->getFirstAncestor(
|
||||||
Node\Expression\ObjectCreationExpression::class,
|
Node\Expression\ObjectCreationExpression::class,
|
||||||
|
@ -1127,7 +1122,7 @@ class DefinitionResolver
|
||||||
// static $a = 4, $b = 4 A\B\C::$a, A\B\C::$b
|
// static $a = 4, $b = 4 A\B\C::$a, A\B\C::$b
|
||||||
// $a = 4, $b = 4 A\B\C->$a, A\B\C->$b // TODO verify variable name
|
// $a = 4, $b = 4 A\B\C->$a, A\B\C->$b // TODO verify variable name
|
||||||
// }
|
// }
|
||||||
else if (
|
if (
|
||||||
($propertyDeclaration = ParserHelpers::tryGetPropertyDeclaration($node)) !== null &&
|
($propertyDeclaration = ParserHelpers::tryGetPropertyDeclaration($node)) !== null &&
|
||||||
($classDeclaration =
|
($classDeclaration =
|
||||||
$node->getFirstAncestor(
|
$node->getFirstAncestor(
|
||||||
|
@ -1136,8 +1131,7 @@ class DefinitionResolver
|
||||||
Node\Statement\InterfaceDeclaration::class,
|
Node\Statement\InterfaceDeclaration::class,
|
||||||
Node\Statement\TraitDeclaration::class
|
Node\Statement\TraitDeclaration::class
|
||||||
)
|
)
|
||||||
) !== null && isset($classDeclaration->name))
|
) !== null && isset($classDeclaration->name)) {
|
||||||
{
|
|
||||||
$name = $node->getName();
|
$name = $node->getName();
|
||||||
if ($propertyDeclaration->isStatic()) {
|
if ($propertyDeclaration->isStatic()) {
|
||||||
// Static Property: use ClassName::$propertyName as name
|
// Static Property: use ClassName::$propertyName as name
|
||||||
|
@ -1154,7 +1148,7 @@ class DefinitionResolver
|
||||||
// class C {
|
// class C {
|
||||||
// const $a, $b = 4 A\B\C::$a(), A\B\C::$b
|
// const $a, $b = 4 A\B\C::$a(), A\B\C::$b
|
||||||
// }
|
// }
|
||||||
else if (($constDeclaration = ParserHelpers::tryGetConstOrClassConstDeclaration($node)) !== null) {
|
if (($constDeclaration = ParserHelpers::tryGetConstOrClassConstDeclaration($node)) !== null) {
|
||||||
if ($constDeclaration instanceof Node\Statement\ConstDeclaration) {
|
if ($constDeclaration instanceof Node\Statement\ConstDeclaration) {
|
||||||
// Basic constant: use CONSTANT_NAME as name
|
// Basic constant: use CONSTANT_NAME as name
|
||||||
return (string)$node->getNamespacedName();
|
return (string)$node->getNamespacedName();
|
||||||
|
@ -1174,7 +1168,7 @@ class DefinitionResolver
|
||||||
return (string)$classDeclaration->getNamespacedName() . '::' . $node->getName();
|
return (string)$classDeclaration->getNamespacedName() . '::' . $node->getName();
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (ParserHelpers::isConstDefineExpression($node)) {
|
if (ParserHelpers::isConstDefineExpression($node)) {
|
||||||
return $node->argumentExpressionList->children[0]->expression->getStringContentsText();
|
return $node->argumentExpressionList->children[0]->expression->getStringContentsText();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1186,7 +1180,8 @@ class DefinitionResolver
|
||||||
* @param $variableName
|
* @param $variableName
|
||||||
* @return DocBlock\Tags\Param | null
|
* @return DocBlock\Tags\Param | null
|
||||||
*/
|
*/
|
||||||
private function tryGetDocBlockTagForParameter($docBlock, $variableName) {
|
private function tryGetDocBlockTagForParameter($docBlock, $variableName)
|
||||||
|
{
|
||||||
if ($docBlock === null) {
|
if ($docBlock === null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,8 +6,10 @@ namespace LanguageServer;
|
||||||
use Microsoft\PhpParser;
|
use Microsoft\PhpParser;
|
||||||
use Microsoft\PhpParser\Node;
|
use Microsoft\PhpParser\Node;
|
||||||
|
|
||||||
class ParserHelpers {
|
class ParserHelpers
|
||||||
public static function isConstantFetch(Node $node) : bool {
|
{
|
||||||
|
public static function isConstantFetch(Node $node) : bool
|
||||||
|
{
|
||||||
$parent = $node->parent;
|
$parent = $node->parent;
|
||||||
return
|
return
|
||||||
(
|
(
|
||||||
|
@ -34,18 +36,21 @@ class ParserHelpers {
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function getFunctionLikeDeclarationFromParameter(Node\Parameter $node) {
|
public static function getFunctionLikeDeclarationFromParameter(Node\Parameter $node)
|
||||||
|
{
|
||||||
return $node->parent->parent;
|
return $node->parent->parent;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function isFunctionLike(Node $node) {
|
public static function isFunctionLike(Node $node)
|
||||||
|
{
|
||||||
return
|
return
|
||||||
$node instanceof Node\Statement\FunctionDeclaration ||
|
$node instanceof Node\Statement\FunctionDeclaration ||
|
||||||
$node instanceof Node\MethodDeclaration ||
|
$node instanceof Node\MethodDeclaration ||
|
||||||
$node instanceof Node\Expression\AnonymousFunctionCreationExpression;
|
$node instanceof Node\Expression\AnonymousFunctionCreationExpression;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function isBooleanExpression($expression) : bool {
|
public static function isBooleanExpression($expression) : bool
|
||||||
|
{
|
||||||
if (!($expression instanceof Node\Expression\BinaryExpression)) {
|
if (!($expression instanceof Node\Expression\BinaryExpression)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -77,7 +82,8 @@ class ParserHelpers {
|
||||||
* @param Node $node
|
* @param Node $node
|
||||||
* @return Node\PropertyDeclaration | null $node
|
* @return Node\PropertyDeclaration | null $node
|
||||||
*/
|
*/
|
||||||
public static function tryGetPropertyDeclaration(Node $node) {
|
public static function tryGetPropertyDeclaration(Node $node)
|
||||||
|
{
|
||||||
if ($node instanceof Node\Expression\Variable &&
|
if ($node instanceof Node\Expression\Variable &&
|
||||||
(($propertyDeclaration = $node->parent->parent) instanceof Node\PropertyDeclaration ||
|
(($propertyDeclaration = $node->parent->parent) instanceof Node\PropertyDeclaration ||
|
||||||
($propertyDeclaration = $propertyDeclaration->parent) instanceof Node\PropertyDeclaration)
|
($propertyDeclaration = $propertyDeclaration->parent) instanceof Node\PropertyDeclaration)
|
||||||
|
@ -92,7 +98,8 @@ class ParserHelpers {
|
||||||
* @param Node $node
|
* @param Node $node
|
||||||
* @return Node\Statement\ConstDeclaration | Node\ClassConstDeclaration | null $node
|
* @return Node\Statement\ConstDeclaration | Node\ClassConstDeclaration | null $node
|
||||||
*/
|
*/
|
||||||
public static function tryGetConstOrClassConstDeclaration(Node $node) {
|
public static function tryGetConstOrClassConstDeclaration(Node $node)
|
||||||
|
{
|
||||||
if (
|
if (
|
||||||
$node instanceof Node\ConstElement && (
|
$node instanceof Node\ConstElement && (
|
||||||
($constDeclaration = $node->parent->parent) instanceof Node\ClassConstDeclaration ||
|
($constDeclaration = $node->parent->parent) instanceof Node\ClassConstDeclaration ||
|
||||||
|
@ -109,7 +116,8 @@ class ParserHelpers {
|
||||||
* @param Node $node
|
* @param Node $node
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
public static function isConstDefineExpression(Node $node): bool {
|
public static function isConstDefineExpression(Node $node): bool
|
||||||
|
{
|
||||||
return $node instanceof Node\Expression\CallExpression
|
return $node instanceof Node\Expression\CallExpression
|
||||||
&& $node->callableExpression instanceof Node\QualifiedName
|
&& $node->callableExpression instanceof Node\QualifiedName
|
||||||
&& strtolower($node->callableExpression->getText()) === 'define'
|
&& strtolower($node->callableExpression->getText()) === 'define'
|
||||||
|
|
|
@ -2,7 +2,6 @@
|
||||||
|
|
||||||
namespace LanguageServer;
|
namespace LanguageServer;
|
||||||
|
|
||||||
|
|
||||||
class ParserKind
|
class ParserKind
|
||||||
{
|
{
|
||||||
const PHP_PARSER = 1;
|
const PHP_PARSER = 1;
|
||||||
|
|
|
@ -54,8 +54,7 @@ class SymbolInformation
|
||||||
$symbol->kind = SymbolKind::CLASS_;
|
$symbol->kind = SymbolKind::CLASS_;
|
||||||
} else if ($node instanceof Node\Statement\TraitDeclaration) {
|
} else if ($node instanceof Node\Statement\TraitDeclaration) {
|
||||||
$symbol->kind = SymbolKind::CLASS_;
|
$symbol->kind = SymbolKind::CLASS_;
|
||||||
}
|
} else if (\LanguageServer\ParserHelpers::isConstDefineExpression($node)) {
|
||||||
else if (\LanguageServer\ParserHelpers::isConstDefineExpression($node)) {
|
|
||||||
// constants with define() like
|
// constants with define() like
|
||||||
// define('TEST_DEFINE_CONSTANT', false);
|
// define('TEST_DEFINE_CONSTANT', false);
|
||||||
$symbol->kind = SymbolKind::CONSTANT;
|
$symbol->kind = SymbolKind::CONSTANT;
|
||||||
|
@ -77,9 +76,7 @@ class SymbolInformation
|
||||||
$symbol->kind = SymbolKind::PROPERTY;
|
$symbol->kind = SymbolKind::PROPERTY;
|
||||||
} else if ($node instanceof Node\ConstElement) {
|
} else if ($node instanceof Node\ConstElement) {
|
||||||
$symbol->kind = SymbolKind::CONSTANT;
|
$symbol->kind = SymbolKind::CONSTANT;
|
||||||
}
|
} else if (
|
||||||
|
|
||||||
else if (
|
|
||||||
(
|
(
|
||||||
($node instanceof Node\Expression\AssignmentExpression)
|
($node instanceof Node\Expression\AssignmentExpression)
|
||||||
&& $node->leftOperand instanceof Node\Expression\Variable
|
&& $node->leftOperand instanceof Node\Expression\Variable
|
||||||
|
|
|
@ -10,7 +10,8 @@ use Sabre\Uri;
|
||||||
use Microsoft\PhpParser;
|
use Microsoft\PhpParser;
|
||||||
use Microsoft\PhpParser\Node;
|
use Microsoft\PhpParser\Node;
|
||||||
|
|
||||||
class TreeAnalyzer {
|
class TreeAnalyzer
|
||||||
|
{
|
||||||
private $parser;
|
private $parser;
|
||||||
|
|
||||||
/** @var Node */
|
/** @var Node */
|
||||||
|
@ -28,7 +29,8 @@ class TreeAnalyzer {
|
||||||
* @param DefinitionResolver $definitionResolver
|
* @param DefinitionResolver $definitionResolver
|
||||||
* @param $uri
|
* @param $uri
|
||||||
*/
|
*/
|
||||||
public function __construct($parser, $content, $docBlockFactory, $definitionResolver, $uri) {
|
public function __construct($parser, $content, $docBlockFactory, $definitionResolver, $uri)
|
||||||
|
{
|
||||||
$this->uri = $uri;
|
$this->uri = $uri;
|
||||||
$this->parser = $parser;
|
$this->parser = $parser;
|
||||||
$this->docBlockFactory = $docBlockFactory;
|
$this->docBlockFactory = $docBlockFactory;
|
||||||
|
@ -41,7 +43,8 @@ class TreeAnalyzer {
|
||||||
$this->collectDefinitionsAndReferences($this->stmts);
|
$this->collectDefinitionsAndReferences($this->stmts);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function collectDefinitionsAndReferences(Node $stmts) {
|
public function collectDefinitionsAndReferences(Node $stmts)
|
||||||
|
{
|
||||||
foreach ($stmts::CHILD_NAMES as $name) {
|
foreach ($stmts::CHILD_NAMES as $name) {
|
||||||
$node = $stmts->$name;
|
$node = $stmts->$name;
|
||||||
|
|
||||||
|
@ -79,7 +82,8 @@ class TreeAnalyzer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function update($node) {
|
public function update($node)
|
||||||
|
{
|
||||||
$fqn = ($this->definitionResolver)::getDefinedFqn($node);
|
$fqn = ($this->definitionResolver)::getDefinedFqn($node);
|
||||||
// Only index definitions with an FQN (no variables)
|
// Only index definitions with an FQN (no variables)
|
||||||
if ($fqn !== null) {
|
if ($fqn !== null) {
|
||||||
|
@ -98,7 +102,6 @@ class TreeAnalyzer {
|
||||||
))
|
))
|
||||||
|| ($parent instanceof 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);
|
$fqn = $this->definitionResolver->resolveReferenceNodeToFqn($node);
|
||||||
if ($fqn !== null) {
|
if ($fqn !== null) {
|
||||||
$this->addReference($fqn, $node);
|
$this->addReference($fqn, $node);
|
||||||
|
@ -138,7 +141,8 @@ class TreeAnalyzer {
|
||||||
$this->collectDefinitionsAndReferences($node);
|
$this->collectDefinitionsAndReferences($node);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getDiagnostics() {
|
public function getDiagnostics()
|
||||||
|
{
|
||||||
return $this->diagnostics ?? [];
|
return $this->diagnostics ?? [];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -150,19 +154,23 @@ class TreeAnalyzer {
|
||||||
$this->referenceNodes[$fqn][] = $node;
|
$this->referenceNodes[$fqn][] = $node;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getDefinitions() {
|
public function getDefinitions()
|
||||||
|
{
|
||||||
return $this->definitions ?? [];
|
return $this->definitions ?? [];
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getDefinitionNodes() {
|
public function getDefinitionNodes()
|
||||||
|
{
|
||||||
return $this->definitionNodes ?? [];
|
return $this->definitionNodes ?? [];
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getReferenceNodes() {
|
public function getReferenceNodes()
|
||||||
|
{
|
||||||
return $this->referenceNodes ?? [];
|
return $this->referenceNodes ?? [];
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getStmts() {
|
public function getStmts()
|
||||||
|
{
|
||||||
return $this->stmts;
|
return $this->stmts;
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -172,6 +172,7 @@ function getVendorDir(\stdClass $composerJson = null): string
|
||||||
return $composerJson->config->{'vendor-dir'} ?? 'vendor';
|
return $composerJson->config->{'vendor-dir'} ?? 'vendor';
|
||||||
}
|
}
|
||||||
|
|
||||||
function strStartsWith(string $haystack, string $prefix): bool {
|
function strStartsWith(string $haystack, string $prefix): bool
|
||||||
|
{
|
||||||
return empty($prefix) || strpos($haystack, $prefix) === 0;
|
return empty($prefix) || strpos($haystack, $prefix) === 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,7 +44,8 @@ class PhpDocumentTest extends TestCase
|
||||||
$this->assertEquals('SomeClass', (string)$node);
|
$this->assertEquals('SomeClass', (string)$node);
|
||||||
}
|
}
|
||||||
|
|
||||||
private function assertQualifiedName($node) {
|
private function assertQualifiedName($node)
|
||||||
|
{
|
||||||
$this->assertInstanceOf(Node\QualifiedName::class, $node);
|
$this->assertInstanceOf(Node\QualifiedName::class, $node);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -499,7 +499,8 @@ class CompletionTest extends TestCase
|
||||||
], true), $items);
|
], true), $items);
|
||||||
}
|
}
|
||||||
|
|
||||||
private function assertCompletionsListSubset(CompletionList $subsetList, CompletionList $list) {
|
private function assertCompletionsListSubset(CompletionList $subsetList, CompletionList $list)
|
||||||
|
{
|
||||||
foreach ($subsetList->items as $expectedItem) {
|
foreach ($subsetList->items as $expectedItem) {
|
||||||
$this->assertContains($expectedItem, $list->items, null, null, false);
|
$this->assertContains($expectedItem, $list->items, null, null, false);
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,8 @@ use function LanguageServer\{strStartsWith};
|
||||||
|
|
||||||
class UtilsTest extends TestCase
|
class UtilsTest extends TestCase
|
||||||
{
|
{
|
||||||
public function testStrStartsWithDataProvider(): array {
|
public function testStrStartsWithDataProvider(): array
|
||||||
|
{
|
||||||
return [
|
return [
|
||||||
['a', 'b', false],
|
['a', 'b', false],
|
||||||
['', 'a', false],
|
['', 'a', false],
|
||||||
|
|
|
@ -25,7 +25,8 @@ $frameworksDir = realpath(__DIR__ . '/../../validation/frameworks');
|
||||||
|
|
||||||
class ValidationTest extends TestCase
|
class ValidationTest extends TestCase
|
||||||
{
|
{
|
||||||
public function frameworkErrorProvider() {
|
public function frameworkErrorProvider()
|
||||||
|
{
|
||||||
global $frameworksDir;
|
global $frameworksDir;
|
||||||
$frameworks = glob($frameworksDir . '/*', GLOB_ONLYDIR);
|
$frameworks = glob($frameworksDir . '/*', GLOB_ONLYDIR);
|
||||||
|
|
||||||
|
@ -61,7 +62,8 @@ class ValidationTest extends TestCase
|
||||||
* @param $testCaseFile
|
* @param $testCaseFile
|
||||||
* @param $frameworkName
|
* @param $frameworkName
|
||||||
*/
|
*/
|
||||||
public function testDefinitionErrors($testCaseFile, $frameworkName) {
|
public function testDefinitionErrors($testCaseFile, $frameworkName)
|
||||||
|
{
|
||||||
$fileContents = file_get_contents($testCaseFile);
|
$fileContents = file_get_contents($testCaseFile);
|
||||||
$actualValues = $this->getActualTestValues($testCaseFile, $fileContents);
|
$actualValues = $this->getActualTestValues($testCaseFile, $fileContents);
|
||||||
|
|
||||||
|
@ -90,7 +92,8 @@ class ValidationTest extends TestCase
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private function getActualTestValues($filename, $fileContents): array {
|
private function getActualTestValues($filename, $fileContents): array
|
||||||
|
{
|
||||||
global $frameworksDir;
|
global $frameworksDir;
|
||||||
|
|
||||||
$index = new Index();
|
$index = new Index();
|
||||||
|
@ -113,7 +116,7 @@ class ValidationTest extends TestCase
|
||||||
|
|
||||||
// Turn references into relative paths
|
// Turn references into relative paths
|
||||||
foreach ($refsAndDefs['references'] as $key => $list) {
|
foreach ($refsAndDefs['references'] as $key => $list) {
|
||||||
$fixedPathRefs = array_map(function($ref) {
|
$fixedPathRefs = array_map(function ($ref) {
|
||||||
global $frameworksDir;
|
global $frameworksDir;
|
||||||
return str_replace($frameworksDir, '.', $ref);
|
return str_replace($frameworksDir, '.', $ref);
|
||||||
}, $list);
|
}, $list);
|
||||||
|
@ -184,6 +187,7 @@ class ValidationTest extends TestCase
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function getExpectedValuesFile($testCaseFile): string {
|
function getExpectedValuesFile($testCaseFile): string
|
||||||
|
{
|
||||||
return $testCaseFile . '.expected.json';
|
return $testCaseFile . '.expected.json';
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue