Converts a Node to a SymbolInformation

@param Node $node
@param string $fqn If given, $containerName will be extracted from it
@return SymbolInformation|null
495522
public static function fromNode($node, string $fqn = null)
    {
        $symbol = new SymbolInformation();
        if ($node instanceof Node\Statement\ClassDeclaration) {
            $symbol->kind = SymbolKind::CLASS_;
        } else if ($node instanceof Node\Statement\TraitDeclaration) {
            $symbol->kind = SymbolKind::CLASS_;
        } else if (\LanguageServer\ParserHelpers\isConstDefineExpression($node)) {
            // constants with define() like
            // define('TEST_DEFINE_CONSTANT', false);
            $symbol->kind = SymbolKind::CONSTANT;
            $symbol->name = $node->argumentExpressionList->children[0]->expression->getStringContentsText();
        } else if ($node instanceof Node\Statement\InterfaceDeclaration) {
            $symbol->kind = SymbolKind::INTERFACE;
        } else if ($node instanceof Node\Statement\NamespaceDefinition) {
            $symbol->kind = SymbolKind::NAMESPACE;
        } else if ($node instanceof Node\Statement\FunctionDeclaration) {
            $symbol->kind = SymbolKind::FUNCTION;
        } 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 Node\Expression\Variable && $node->getFirstAncestor(Node\PropertyDeclaration::class) !== null) {
            $symbol->kind = SymbolKind::PROPERTY;
        } else if ($node instanceof Node\ConstElement) {
            $symbol->kind = SymbolKind::CONSTANT;
        } else if (
            (
                ($node instanceof Node\Expression\AssignmentExpression)
                && $node->leftOperand instanceof Node\Expression\Variable
            )
            || $node instanceof Node\UseVariableName
            || $node instanceof Node\Parameter
        ) {
            $symbol->kind = SymbolKind::VARIABLE;
        } else {
            return null;
        }

        if ($node instanceof Node\Expression\AssignmentExpression) {
            if ($node->leftOperand instanceof Node\Expression\Variable) {
                $symbol->name = $node->leftOperand->getName();
            } elseif ($node->leftOperand instanceof PhpParser\Token) {
                $symbol->name = trim($node->leftOperand->getText($node->getFileContents()), "$");
            }
        } else if ($node instanceof Node\UseVariableName) {
            $symbol->name = $node->getName();
        } else if (isset($node->name)) {
            if ($node->name instanceof Node\QualifiedName) {
                $symbol->name = (string)ResolvedName::buildName($node->name->nameParts, $node->getFileContents());
            } else {
                $symbol->name = ltrim((string)$node->name->getText($node->getFileContents()), "$");
            }
        } else if (isset($node->variableName)) {
            $symbol->name = $node->variableName->getText($node);
        } else if (!isset($symbol->name)) {
            return null;
        }

        $symbol->location = LocationFactory::fromNode($node);
        if ($fqn !== null) {
            $parts = preg_split('/(::|->|\\\\)/', $fqn);
            array_pop($parts);
            $symbol->containerName = implode('\\', $parts);
        }
        return $symbol;
    }
408568
public function getInterfacesNamespaceForEntity(
        string $entityFqn
    ): string {
        $interfacesNamespace = $this->getProjectNamespaceRootFromEntityFqn($entityFqn)
                               . AbstractGenerator::ENTITY_RELATIONS_NAMESPACE
                               . '\\' . $this->getEntitySubNamespace($entityFqn)
                               . '\\Interfaces';

        return $this->tidy($interfacesNamespace);
    }
508976
public function enterNode(Node $node): void
    {
        $name = null;

        if ($node instanceof Name) {
            $name = $node->toString();
        }

        if ($name === null
            || (array_key_exists($name, $this->symbols)
                && $this->symbols[$name] === false
            )
        ) {
            return;
        }

        if (!$this->filter->__invoke($name)) {
            $this->symbols[$name] = false;
            return;
        }

        if (!array_key_exists($name, $this->symbols)) {
            $this->symbols[$name] = [];
        }

        $this->symbols[$name][] = $node;
    }
1344824
public function getDocumentationFromNode($node)
    {
        // Any NamespaceDefinition comments likely apply to the file, not the declaration itself.
        if ($node instanceof Node\Statement\NamespaceDefinition) {
            return null;
        }

        // For properties and constants, set the node to the declaration node, rather than the individual property.
        // This is because they get defined as part of a list.
        $constOrPropertyDeclaration = ParserHelpers\tryGetPropertyDeclaration($node) ?? ParserHelpers\tryGetConstOrClassConstDeclaration($node);
        if ($constOrPropertyDeclaration !== null) {
            $node = $constOrPropertyDeclaration;
        }

        // For parameters, parse the function-like declaration to get documentation for a parameter
        if ($node instanceof Node\Parameter) {
            $variableName = $node->getName();

            $functionLikeDeclaration = ParserHelpers\getFunctionLikeDeclarationFromParameter($node);
            $docBlock = $this->getDocBlock($functionLikeDeclaration);

            $parameterDocBlockTag = $this->tryGetDocBlockTagForParameter($docBlock, $variableName);
            return $parameterDocBlockTag !== null ? $parameterDocBlockTag->getDescription()->render() : null;
        }

        // For everything else, get the doc block summary corresponding to the current node.
        $docBlock = $this->getDocBlock($node);
        if ($docBlock !== null) {
            // check whether we have a description, when true, add a new paragraph
            // with the description
            $description = $docBlock->getDescription()->render();

            if (empty($description)) {
                return $docBlock->getSummary();
            }

            return $docBlock->getSummary() . "\n\n" . $description;
        }
        return null;
    }
274659
public function visitFunctionNode(FunctionNode $node)
    {
        $functionName = $node->getName();
        $operand = $node->getOperand()->accept($this);

        return "$functionName($operand)";
    }
494330
public static function fromXPathNavigator( $node )
	{
		return QNameValue::fromQName( new \lyquidity\xml\qname( $node->getPrefix(), $node->getNamespaceURI(), $node->getLocalName() ) );
	}
1002382
public function pExpr_FuncCall(\PHPParser_Node_Expr_FuncCall $node) {
        $functionName = $this->p($node->name);
        if (count($node->args)) {
            return '$this->callFunction("'.$functionName.'", '.$this->pCommaSeparated($node->args). ')';
        }
        return '$this->callFunction("'.$functionName.'")';
    }
294086
public function getValueForNode(Node $node)
    {
        if ($node->isNamed()) {
            return $node->getUri();
        } elseif ($node->isLiteral()) {
            return $node->getValue();
        } elseif ($node->isBlank()) {
            return $node->getBlankId();
        } else {
            return null;
        }
    }
4494
protected function pExpr_FuncCall(Expr\FuncCall $node)
    {
        $functionName = $this->pCallLhs($node->name);

        $this->securityManager->checkFunctionCall($functionName, $node->args);

        return $functionName
            . '(' . $this->pMaybeMultiline($node->args) . ')';
    }
696251
public static function checkDiagnostics($node) {
        if ($node instanceof Token) {
            if (\get_class($node) === Token::class) {
                return null;
            }
            return self::checkDiagnosticForUnexpectedToken($node);
        }

        if ($node instanceof Node) {
            return $node->getDiagnosticForNode();
        }
        return null;
    }
363446
public static function fromQName( $qn )
	{
		$qname = new QNameValue();
		$qname->LocalName = $qn->localName;
		$qname->Prefix = $qn->prefix;
		$qname->NamespaceUri = $qn->namespaceURI;

		if ( strlen( $qn->localName ) == 0 ||
			 ! preg_match( "/^" . NameValue::$ncName . "$/u", $qn->localName ) ||
			 ( strlen( $qn->prefix ) != 0 && ! preg_match( "/^" . NameValue::$ncName . "$/u", $qn->prefix ) )
		)
		{
			throw XPath2Exception::withErrorCodeAndParam( "FOCA0002", Resources::FOCA0002, $qn->__toString() );
		}

		return $qname;
	}
1165823
public function getEntitySubPath(
        string $entityFqn
    ): string {
        $entityPath = str_replace(
            '\\',
            '/',
            $this->getEntitySubNamespace($entityFqn)
        );

        return '/' . $entityPath;
    }
586002
protected function splitFullQualifyClassName($fqcn)
    {
        $parts = explode('\\', $fqcn);
        $classname = array_pop($parts);
        return [implode('\\', $parts), $classname];
    }
1194836
public function getEntitySubNamespace(
        string $entityFqn
    ): string {
        return $this->tidy(
            \substr(
                $entityFqn,
                \strrpos(
                    $entityFqn,
                    '\\' . AbstractGenerator::ENTITIES_FOLDER_NAME . '\\'
                )
                + \strlen('\\' . AbstractGenerator::ENTITIES_FOLDER_NAME . '\\')
            )
        );
    }
1322435
private function collectDefinitionsAndReferences(Node $node)
    {
        $fqn = ($this->definitionResolver)::getDefinedFqn($node);
        // Only index definitions with an FQN (no variables)
        if ($fqn !== null) {
            $this->definitionNodes[$fqn] = $node;
            $this->definitions[$fqn] = $this->definitionResolver->createDefinitionFromNode($node, $fqn);
        } else {

            $parent = $node->parent;
            if (
                (
                    // $node->parent instanceof Node\Expression\ScopedPropertyAccessExpression ||
                    ($node instanceof Node\Expression\ScopedPropertyAccessExpression ||
                    $node instanceof Node\Expression\MemberAccessExpression)
                    && !(
                        $node->parent instanceof Node\Expression\CallExpression ||
                        $node->memberName instanceof PhpParser\Token
                    ))
                || ($parent instanceof Node\Statement\NamespaceDefinition && $parent->name !== null && $parent->name->getStart() === $node->getStart())
            ) {
                return;
            }

            $fqn = $this->definitionResolver->resolveReferenceNodeToFqn($node);
            if (!$fqn) {
                return;
            }

            if ($fqn === 'self' || $fqn === 'static') {
                // Resolve self and static keywords to the containing class
                // (This is not 100% correct for static but better than nothing)
                $classNode = $node->getFirstAncestor(Node\Statement\ClassDeclaration::class);
                if (!$classNode) {
                    return;
                }
                $fqn = (string)$classNode->getNamespacedName();
                if (!$fqn) {
                    return;
                }
            } else if ($fqn === 'parent') {
                // Resolve parent keyword to the base class FQN
                $classNode = $node->getFirstAncestor(Node\Statement\ClassDeclaration::class);
                if (!$classNode || !$classNode->classBaseClause || !$classNode->classBaseClause->baseClass) {
                    return;
                }
                $fqn = (string)$classNode->classBaseClause->baseClass->getResolvedName();
                if (!$fqn) {
                    return;
                }
            }

            $this->addReference($fqn, $node);

            if (
                $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
                $ns = $fqn;
                while (($pos = strrpos($ns, '\\')) !== false) {
                    $ns = substr($ns, 0, $pos);
                    $this->addReference($ns, $node);
                }
            }

            // Namespaced constant access and function calls also need to register a reference
            // 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 Node\Expression\CallExpression
                    && !(
                        $node instanceof Node\Expression\ScopedPropertyAccessExpression ||
                        $node instanceof Node\Expression\MemberAccessExpression
                    ))) {
                $parts = explode('\\', $fqn);
                if (count($parts) > 1) {
                    $globalFqn = end($parts);
                    $this->addReference($globalFqn, $node);
                }
            }
        }
    }
718666
public function leaveNode(Node $node)
    {
        // Collect arguments as variables
        if ($node instanceof Expr\FuncCall
            || $node instanceof Expr\MethodCall
            || $node instanceof Expr\StaticCall
        ) {
            $variables = $this->getSplatCallVars($node->args);
            if (is_null($variables)) {
                return;
            }
        }

        // Call to call_user_func_array
        if ($node instanceof Expr\FuncCall) {
            $callee = new Scalar\String_($node->name);
            return $this->splatToCallUserFuncArray($callee, $variables);
        } elseif ($node instanceof Expr\MethodCall) {
            if ($node->var instanceof Expr\New_) {
                $var = $node->var;
            } elseif ($node->var instanceof Expr\Variable) {
                $var = new Expr\Variable($node->var->name);
            } else {
                return;
            }
            $callee = new Expr\Array_([$var,new Scalar\String_($node->name)]);
            return $this->splatToCallUserFuncArray($callee, $variables);
        } elseif ($node instanceof Expr\StaticCall) {
            $var = new Expr\ClassConstFetch($node->class, 'class');
            if ($this->useStringifiedStaticCalls) {
                $var = $this->classConstToStrVisitor->leaveNode($var);
            }
            $callee = new Expr\Array_([$var, new Scalar\String_($node->name)]);
            return $this->splatToCallUserFuncArray($callee, $variables);
        }
    }
301014
private function getPrimitiveValue(Node $node) {
		if ($this->isBool($node)) {
			return (bool) $this->getExpression($node);
		}
	
		if ($this->isNull($node)) {
			return null;
		}
	
		return $node->value;
	}