2016-11-18 14:22:24 +00:00
|
|
|
<?php
|
|
|
|
declare(strict_types = 1);
|
|
|
|
|
|
|
|
namespace LanguageServer;
|
|
|
|
|
2017-07-07 11:18:19 +00:00
|
|
|
use LanguageServer\Index\ReadableIndex;
|
2016-11-18 14:22:24 +00:00
|
|
|
use phpDocumentor\Reflection\{Types, Type, Fqsen, TypeResolver};
|
2018-09-09 12:37:35 +00:00
|
|
|
use LanguageServerProtocol\SymbolInformation;
|
2017-07-07 11:18:19 +00:00
|
|
|
use Generator;
|
2016-11-18 14:22:24 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Class used to represent symbols
|
|
|
|
*/
|
|
|
|
class Definition
|
|
|
|
{
|
|
|
|
/**
|
|
|
|
* The fully qualified name of the symbol, if it has one
|
|
|
|
*
|
|
|
|
* Examples of FQNs:
|
|
|
|
* - testFunction()
|
2016-11-30 21:23:51 +00:00
|
|
|
* - TestNamespace
|
2016-11-18 14:22:24 +00:00
|
|
|
* - TestNamespace\TestClass
|
|
|
|
* - TestNamespace\TestClass::TEST_CONSTANT
|
2016-11-30 21:23:51 +00:00
|
|
|
* - TestNamespace\TestClass::$staticTestProperty
|
|
|
|
* - TestNamespace\TestClass->testProperty
|
2016-11-18 14:22:24 +00:00
|
|
|
* - TestNamespace\TestClass::staticTestMethod()
|
2016-11-30 21:23:51 +00:00
|
|
|
* - TestNamespace\TestClass->testMethod()
|
2016-11-18 14:22:24 +00:00
|
|
|
*
|
|
|
|
* @var string|null
|
|
|
|
*/
|
|
|
|
public $fqn;
|
|
|
|
|
2016-12-16 00:40:17 +00:00
|
|
|
/**
|
|
|
|
* For class or interfaces, the FQNs of extended classes and implemented interfaces
|
|
|
|
*
|
|
|
|
* @var string[]
|
|
|
|
*/
|
|
|
|
public $extends;
|
|
|
|
|
2016-11-30 21:23:51 +00:00
|
|
|
/**
|
2017-10-30 00:45:06 +00:00
|
|
|
* False for classes, interfaces, traits, functions and non-class constants
|
|
|
|
* True for methods, properties and class constants
|
2016-11-30 21:23:51 +00:00
|
|
|
* This is so methods and properties are not suggested in the global scope
|
|
|
|
*
|
|
|
|
* @var bool
|
|
|
|
*/
|
2017-10-30 00:45:06 +00:00
|
|
|
public $isMember;
|
2016-11-30 21:23:51 +00:00
|
|
|
|
2017-06-16 18:31:13 +00:00
|
|
|
/**
|
|
|
|
* True if this definition is affected by global namespace fallback (global function or global constant)
|
|
|
|
*
|
|
|
|
* @var bool
|
|
|
|
*/
|
|
|
|
public $roamed;
|
|
|
|
|
2016-11-30 21:23:51 +00:00
|
|
|
/**
|
|
|
|
* False for instance methods and properties
|
|
|
|
*
|
|
|
|
* @var bool
|
|
|
|
*/
|
|
|
|
public $isStatic;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* True if the Definition is a class
|
|
|
|
*
|
|
|
|
* @var bool
|
|
|
|
*/
|
|
|
|
public $canBeInstantiated;
|
|
|
|
|
2016-11-18 14:22:24 +00:00
|
|
|
/**
|
2018-02-28 18:05:22 +00:00
|
|
|
* @var SymbolInformation
|
2016-11-18 14:22:24 +00:00
|
|
|
*/
|
|
|
|
public $symbolInformation;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* The type a reference to this symbol will resolve to.
|
|
|
|
* For properties and constants, this is the type of the property/constant.
|
|
|
|
* For functions and methods, this is the return type.
|
|
|
|
* For any other declaration it will be null.
|
|
|
|
* Can also be a compound type.
|
2017-10-23 00:34:08 +00:00
|
|
|
* If it is unknown, will be Types\Mixed_.
|
2016-11-18 14:22:24 +00:00
|
|
|
*
|
|
|
|
* @var \phpDocumentor\Type|null
|
|
|
|
*/
|
|
|
|
public $type;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* The first line of the declaration, for use in textDocument/hover
|
|
|
|
*
|
|
|
|
* @var string
|
|
|
|
*/
|
|
|
|
public $declarationLine;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* A documentation string, for use in textDocument/hover
|
|
|
|
*
|
|
|
|
* @var string
|
|
|
|
*/
|
|
|
|
public $documentation;
|
2017-07-07 11:18:19 +00:00
|
|
|
|
2017-12-10 05:10:43 +00:00
|
|
|
/**
|
|
|
|
* Signature information if this definition is for a FunctionLike, for use in textDocument/signatureHelp
|
|
|
|
*
|
|
|
|
* @var SignatureInformation
|
|
|
|
*/
|
|
|
|
public $signatureInformation;
|
|
|
|
|
2017-07-07 11:18:19 +00:00
|
|
|
/**
|
|
|
|
* Yields the definitons of all ancestor classes (the Definition fqn is yielded as key)
|
|
|
|
*
|
|
|
|
* @param ReadableIndex $index the index to search for needed definitions
|
|
|
|
* @param bool $includeSelf should the first yielded value be the current definition itself
|
|
|
|
* @return Generator
|
|
|
|
*/
|
|
|
|
public function getAncestorDefinitions(ReadableIndex $index, bool $includeSelf = false): Generator
|
|
|
|
{
|
|
|
|
if ($includeSelf) {
|
|
|
|
yield $this->fqn => $this;
|
|
|
|
}
|
|
|
|
if ($this->extends !== null) {
|
|
|
|
// iterating once, storing the references and iterating again
|
|
|
|
// guarantees that closest definitions are yielded first
|
|
|
|
$definitions = [];
|
|
|
|
foreach ($this->extends as $fqn) {
|
|
|
|
$def = $index->getDefinition($fqn);
|
|
|
|
if ($def !== null) {
|
|
|
|
yield $def->fqn => $def;
|
|
|
|
$definitions[] = $def;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
foreach ($definitions as $def) {
|
|
|
|
yield from $def->getAncestorDefinitions($index);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2018-11-09 20:35:05 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Checks the definition's visibility.
|
2018-11-10 12:40:55 +00:00
|
|
|
* @param string $match Owner of the FQNS
|
|
|
|
* @param string $caller Descendant of the FQNS owner
|
|
|
|
* @param bool $isInMethodDeclaration checking if the call is from inside a
|
|
|
|
* method
|
2018-11-09 20:35:05 +00:00
|
|
|
* @return bool
|
|
|
|
*/
|
2018-11-10 12:40:55 +00:00
|
|
|
public function isVisible(string $match, string $caller, bool $isInMethodDeclaration): bool
|
|
|
|
{
|
|
|
|
if ($isInMethodDeclaration) {
|
2018-11-09 20:35:05 +00:00
|
|
|
if ($match !== $caller && $this->isPrivate()) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
} else if ($this->isProtected() || $this->isPrivate()) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
private function isPrivate(): bool
|
|
|
|
{
|
|
|
|
return 'private' === substr($this->declarationLine, 0, 7);
|
|
|
|
}
|
|
|
|
|
|
|
|
private function isProtected(): bool
|
|
|
|
{
|
|
|
|
return 'protected' === substr($this->declarationLine, 0, 9);
|
|
|
|
}
|
2016-11-18 14:22:24 +00:00
|
|
|
}
|