From 31441f4b7ed96d5c648a55eaa75cf69244e82883 Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Tue, 2 May 2017 11:04:44 -0700 Subject: [PATCH] Remove ParserResourceFactory and DefinitionResolverInterface (leave original DefinitionResolver for now, for more testing) --- Performance.php | 14 +-- src/CompletionProvider.php | 8 +- src/ComposerScripts.php | 4 +- src/DefinitionResolver.php | 2 +- src/DefinitionResolverInterface.php | 86 ------------------- src/LanguageServer.php | 11 +-- src/NodeVisitor/DefinitionCollector.php | 5 +- src/NodeVisitor/ReferencesCollector.php | 11 +-- src/ParserResourceFactory.php | 45 ---------- src/PhpDocument.php | 35 ++++---- src/PhpDocumentLoader.php | 11 +-- src/Server/TextDocument.php | 39 +++------ src/TolerantDefinitionResolver.php | 56 ++++++------ tests/NodeVisitor/DefinitionCollectorTest.php | 8 +- tests/PhpDocumentLoaderTest.php | 18 ++-- tests/PhpDocumentTest.php | 25 +++--- tests/Server/ServerTestCase.php | 9 +- tests/Server/TextDocument/CompletionTest.php | 7 +- .../Definition/GlobalFallbackTest.php | 7 +- tests/Server/TextDocument/DidChangeTest.php | 9 +- tests/Server/TextDocument/DidCloseTest.php | 7 +- tests/Server/TextDocument/FormattingTest.php | 5 +- tests/Server/TextDocument/ParseErrorsTest.php | 6 +- .../References/GlobalFallbackTest.php | 15 ++-- tests/Validation/ValidationTest.php | 63 +++----------- 25 files changed, 147 insertions(+), 359 deletions(-) delete mode 100644 src/DefinitionResolverInterface.php delete mode 100644 src/ParserResourceFactory.php diff --git a/Performance.php b/Performance.php index c110300..8ed002f 100644 --- a/Performance.php +++ b/Performance.php @@ -6,16 +6,12 @@ require __DIR__ . '/vendor/autoload.php'; use Exception; use LanguageServer\Index\Index; use LanguageServer\ParserKind; -use LanguageServer\ParserResourceFactory; use LanguageServer\PhpDocument; +use LanguageServer\TolerantDefinitionResolver; +use Microsoft\PhpParser as Tolerant; use phpDocumentor\Reflection\DocBlockFactory; -use PHPUnit\Framework\TestCase; -use LanguageServer\ClientHandler; -use LanguageServer\Protocol\Message; -use AdvancedJsonRpc; use RecursiveDirectoryIterator; use RecursiveIteratorIterator; -use Sabre\Event\Loop; $totalSize = 0; @@ -60,11 +56,9 @@ foreach($frameworks as $framework) { $index = new Index; $maxRecursion = []; $definitions = []; - global $parserKind; - $parserKind = $kind; - $definitionResolver = ParserResourceFactory::getDefinitionResolver($index); - $parser = ParserResourceFactory::getParser(); + $definitionResolver = new TolerantDefinitionResolver($index); + $parser = new Tolerant\Parser(); try { $document = new PhpDocument($testCaseFile, $fileContents, $index, $parser, $docBlockFactory, $definitionResolver); diff --git a/src/CompletionProvider.php b/src/CompletionProvider.php index 58531e2..d19c6bf 100644 --- a/src/CompletionProvider.php +++ b/src/CompletionProvider.php @@ -89,7 +89,7 @@ class CompletionProvider ]; /** - * @var DefinitionResolverInterface + * @var TolerantDefinitionResolver */ private $definitionResolver; @@ -104,10 +104,10 @@ class CompletionProvider private $index; /** - * @param DefinitionResolverInterface $definitionResolver + * @param TolerantDefinitionResolver $definitionResolver * @param ReadableIndex $index */ - public function __construct(DefinitionResolverInterface $definitionResolver, ReadableIndex $index) + public function __construct(TolerantDefinitionResolver $definitionResolver, ReadableIndex $index) { $this->definitionResolver = $definitionResolver; $this->index = $index; @@ -124,7 +124,7 @@ class CompletionProvider { // This can be made much more performant if the tree follows specific invariants. $node = $doc->getNodeAtPosition($pos); - + if($node !== null && ($offset = $pos->toOffset($node->getFileContents())) > $node->getEndPosition() && $node->parent->getLastChild() instanceof Tolerant\MissingToken) { diff --git a/src/ComposerScripts.php b/src/ComposerScripts.php index 6109fb2..086a010 100644 --- a/src/ComposerScripts.php +++ b/src/ComposerScripts.php @@ -30,8 +30,8 @@ class ComposerScripts $finder = new FileSystemFilesFinder; $contentRetriever = new FileSystemContentRetriever; $docBlockFactory = DocBlockFactory::createInstance(); - $parser = ParserResourceFactory::getParser(); - $definitionResolver = ParserResourceFactory::getDefinitionResolver($index); + $parser = Tolerant\Parser(); + $definitionResolver = new TolerantDefinitionResolver($index); $stubsLocation = null; foreach ([__DIR__ . '/../../../jetbrains/phpstorm-stubs', __DIR__ . '/../vendor/jetbrains/phpstorm-stubs'] as $dir) { diff --git a/src/DefinitionResolver.php b/src/DefinitionResolver.php index 3d3a360..3bc7b0c 100644 --- a/src/DefinitionResolver.php +++ b/src/DefinitionResolver.php @@ -9,7 +9,7 @@ use phpDocumentor\Reflection\{Types, Type, Fqsen, TypeResolver}; use LanguageServer\Protocol\SymbolInformation; use LanguageServer\Index\ReadableIndex; -class DefinitionResolver implements DefinitionResolverInterface +class DefinitionResolver { /** * @var \LanguageServer\Index\ReadableIndex diff --git a/src/DefinitionResolverInterface.php b/src/DefinitionResolverInterface.php deleted file mode 100644 index 767f4e0..0000000 --- a/src/DefinitionResolverInterface.php +++ /dev/null @@ -1,86 +0,0 @@ -globalIndex = new GlobalIndex($stubsIndex, $this->projectIndex); // The DefinitionResolver should look in stubs, the project source and dependencies - $this->definitionResolver = ParserResourceFactory::getDefinitionResolver($this->globalIndex); + $this->definitionResolver = new TolerantDefinitionResolver($this->globalIndex); $this->documentLoader = new PhpDocumentLoader( $this->contentRetriever, diff --git a/src/NodeVisitor/DefinitionCollector.php b/src/NodeVisitor/DefinitionCollector.php index 7579ce9..37eeebe 100644 --- a/src/NodeVisitor/DefinitionCollector.php +++ b/src/NodeVisitor/DefinitionCollector.php @@ -5,9 +5,8 @@ namespace LanguageServer\NodeVisitor; use PhpParser\{NodeVisitorAbstract, Node}; use LanguageServer\{ - Definition, DefinitionResolver, DefinitionResolverInterface, FqnUtilities + Definition, FqnUtilities, TolerantDefinitionResolver }; -use LanguageServer\Protocol\SymbolInformation; /** * Collects definitions of classes, interfaces, traits, methods, properties and constants @@ -31,7 +30,7 @@ class DefinitionCollector extends NodeVisitorAbstract private $definitionResolver; - public function __construct(DefinitionResolverInterface $definitionResolver) + public function __construct(TolerantDefinitionResolver $definitionResolver) { $this->definitionResolver = $definitionResolver; } diff --git a/src/NodeVisitor/ReferencesCollector.php b/src/NodeVisitor/ReferencesCollector.php index d586b5b..a64e633 100644 --- a/src/NodeVisitor/ReferencesCollector.php +++ b/src/NodeVisitor/ReferencesCollector.php @@ -4,8 +4,9 @@ declare(strict_types = 1); namespace LanguageServer\NodeVisitor; use LanguageServer\DefinitionResolverInterface; -use PhpParser\{NodeVisitorAbstract, Node}; -use LanguageServer\DefinitionResolver; +use PhpParser\{ + Node, NodeVisitorAbstract +}; /** * Collects references to classes, interfaces, traits, methods, properties and constants @@ -21,14 +22,14 @@ class ReferencesCollector extends NodeVisitorAbstract public $nodes = []; /** - * @var DefinitionResolverInterface + * @var TolerantDefinitionResolver */ private $definitionResolver; /** - * @param DefinitionResolverInterface $definitionResolver The DefinitionResolver to resolve reference nodes to definitions + * @param TolerantDefinitionResolver $definitionResolver The definition resolver to resolve reference nodes to definitions */ - public function __construct(DefinitionResolverInterface $definitionResolver) + public function __construct(TolerantDefinitionResolver $definitionResolver) { $this->definitionResolver = $definitionResolver; } diff --git a/src/ParserResourceFactory.php b/src/ParserResourceFactory.php deleted file mode 100644 index bd957d0..0000000 --- a/src/ParserResourceFactory.php +++ /dev/null @@ -1,45 +0,0 @@ -uri = $uri; $this->index = $index; @@ -161,7 +158,7 @@ class PhpDocument $this->definitions = null; $this->definitionNodes = null; - $treeAnalyzer = ParserResourceFactory::getTreeAnalyzer($this->parser, $content, $this->docBlockFactory, $this->definitionResolver, $this->uri); + $treeAnalyzer = new TolerantTreeAnalyzer($this->parser, $content, $this->docBlockFactory, $this->definitionResolver, $this->uri); $this->diagnostics = $treeAnalyzer->getDiagnostics(); @@ -170,7 +167,7 @@ class PhpDocument $this->definitionNodes = $treeAnalyzer->getDefinitionNodes(); $this->referenceNodes = $treeAnalyzer->getReferenceNodes(); - + foreach ($this->definitions as $fqn => $definition) { $this->index->setDefinition($fqn, $definition); } @@ -179,7 +176,7 @@ class PhpDocument foreach ($this->referenceNodes as $fqn => $nodes) { $this->index->addReferenceUri($fqn, $this->uri); } - + $this->stmts = $treeAnalyzer->getStmts(); } diff --git a/src/PhpDocumentLoader.php b/src/PhpDocumentLoader.php index 88ed525..8f94943 100644 --- a/src/PhpDocumentLoader.php +++ b/src/PhpDocumentLoader.php @@ -48,24 +48,25 @@ class PhpDocumentLoader private $docBlockFactory; /** - * @var DefinitionResolverInterface + * @var TolerantDefinitionResolver */ private $definitionResolver; /** * @param ContentRetriever $contentRetriever - * @param ProjectIndex $project - * @param DefinitionResolverInterface $definitionResolver + * @param ProjectIndex $projectIndex + * @param TolerantDefinitionResolver $definitionResolver + * @internal param ProjectIndex $project */ public function __construct( ContentRetriever $contentRetriever, ProjectIndex $projectIndex, - DefinitionResolverInterface $definitionResolver + TolerantDefinitionResolver $definitionResolver ) { $this->contentRetriever = $contentRetriever; $this->projectIndex = $projectIndex; $this->definitionResolver = $definitionResolver; - $this->parser = ParserResourceFactory::getParser(); + $this->parser = new Tolerant\Parser(); $this->docBlockFactory = DocBlockFactory::createInstance(); } diff --git a/src/Server/TextDocument.php b/src/Server/TextDocument.php index b479317..3679950 100644 --- a/src/Server/TextDocument.php +++ b/src/Server/TextDocument.php @@ -3,37 +3,20 @@ declare(strict_types = 1); namespace LanguageServer\Server; -use Microsoft\PhpParser as Tolerant; -use phpDocumentor\Reflection\DocBlock\Tags\Param; -use PhpParser\{Node, NodeTraverser}; use LanguageServer\{ - DefinitionResolverInterface, FqnUtilities, LanguageClient, PhpDocumentLoader, PhpDocument, DefinitionResolver, CompletionProvider, TolerantDefinitionResolver, TolerantTreeAnalyzer -}; -use LanguageServer\NodeVisitor\VariableReferencesCollector; -use LanguageServer\Protocol\{ - SymbolLocationInformation, - SymbolDescriptor, - TextDocumentItem, - TextDocumentIdentifier, - VersionedTextDocumentIdentifier, - Position, - Range, - FormattingOptions, - TextEdit, - Location, - SymbolInformation, - ReferenceContext, - Hover, - MarkedString, - SymbolKind, - CompletionItem, - CompletionItemKind + CompletionProvider, FqnUtilities, LanguageClient, PhpDocument, PhpDocumentLoader, TolerantDefinitionResolver }; 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 Sabre\Event\Promise; use Sabre\Uri; +use function LanguageServer\{ + isVendored, waitForEvent +}; use function Sabre\Event\coroutine; -use function LanguageServer\{waitForEvent, isVendored}; /** * Provides method handlers for all textDocument/* methods @@ -53,7 +36,7 @@ class TextDocument protected $project; /** - * @var DefinitionResolverInterface + * @var TolerantDefinitionResolver */ protected $definitionResolver; @@ -79,7 +62,7 @@ class TextDocument /** * @param PhpDocumentLoader $documentLoader - * @param DefinitionResolverInterface $definitionResolver + * @param TolerantDefinitionResolver $definitionResolver * @param LanguageClient $client * @param ReadableIndex $index * @param \stdClass $composerJson @@ -87,7 +70,7 @@ class TextDocument */ public function __construct( PhpDocumentLoader $documentLoader, - DefinitionResolverInterface $definitionResolver, + TolerantDefinitionResolver $definitionResolver, LanguageClient $client, ReadableIndex $index, \stdClass $composerJson = null, diff --git a/src/TolerantDefinitionResolver.php b/src/TolerantDefinitionResolver.php index 0459a43..38d2ce7 100644 --- a/src/TolerantDefinitionResolver.php +++ b/src/TolerantDefinitionResolver.php @@ -3,16 +3,15 @@ declare(strict_types = 1); namespace LanguageServer; -use LanguageServer\Protocol\TolerantSymbolInformation; -use PhpParser\Node; -use phpDocumentor\Reflection\{ - DocBlock, DocBlockFactory, Types, Type, Fqsen, TypeResolver -}; -use LanguageServer\Protocol\SymbolInformation; use LanguageServer\Index\ReadableIndex; +use LanguageServer\Protocol\TolerantSymbolInformation; use Microsoft\PhpParser as Tolerant; +use phpDocumentor\Reflection\{ + DocBlock, DocBlockFactory, Fqsen, Type, TypeResolver, Types +}; +use PhpParser\Node; -class TolerantDefinitionResolver implements DefinitionResolverInterface +class TolerantDefinitionResolver { /** * The current project index (for retrieving existing definitions) @@ -77,7 +76,7 @@ class TolerantDefinitionResolver implements DefinitionResolverInterface $defLine = \rtrim(\strtok($defLine, "\n"), "\r"); // TODO - pretty print rather than getting text - + return $defLine; } @@ -93,7 +92,7 @@ class TolerantDefinitionResolver implements DefinitionResolverInterface if ($node instanceof Tolerant\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 = TolerantParserHelpers::tryGetPropertyDeclaration($node) ?? TolerantParserHelpers::tryGetConstOrClassConstDeclaration($node); @@ -196,8 +195,8 @@ class TolerantDefinitionResolver implements DefinitionResolverInterface // TODO - why is this represented as an array? // TODO interface implementations. } elseif ( - $node instanceof Tolerant\Node\Statement\InterfaceDeclaration && - // TODO - this hould be better represented in the parser API + $node instanceof Tolerant\Node\Statement\InterfaceDeclaration && + // TODO - this should be better represented in the parser API $node->interfaceBaseClause !== null && $node->interfaceBaseClause->interfaceNameList !== null ) { $def->extends = []; @@ -229,7 +228,7 @@ class TolerantDefinitionResolver implements DefinitionResolverInterface // 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 && + if ($node instanceof Tolerant\Node\Expression\Variable && !($parent instanceof Tolerant\Node\Expression\ScopedPropertyAccessExpression)) { // Resolve $this to the containing class definition. @@ -252,6 +251,7 @@ class TolerantDefinitionResolver implements DefinitionResolverInterface } // 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 = TolerantParserHelpers::isConstantFetch($node) || $parent instanceof Tolerant\Node\Expression\CallExpression; // Return the Definition object from the index index return $this->index->getDefinition($fqn, $globalFallback); @@ -264,7 +264,7 @@ class TolerantDefinitionResolver implements DefinitionResolverInterface * @param Node $node * @return string|null */ - public function resolveReferenceNodeToFqn($node) { + public function resolveReferenceNodeToFqn($node) { // TODO all name tokens should be a part of a node if ($node instanceof Tolerant\Node\QualifiedName) { return $this->resolveQualifiedNameNodeToFqn($node); @@ -278,7 +278,7 @@ class TolerantDefinitionResolver implements DefinitionResolverInterface } else if ( // A\B::C - constant access expression - $node instanceof Tolerant\Node\Expression\ScopedPropertyAccessExpression + $node instanceof Tolerant\Node\Expression\ScopedPropertyAccessExpression && !($node->memberName instanceof Tolerant\Node\Expression\Variable) ) { return $this->resolveScopedPropertyAccessExpressionNodeToFqn($node); @@ -299,10 +299,10 @@ class TolerantDefinitionResolver implements DefinitionResolverInterface return null; } // Add use clause references - if (($useClause = $parent) instanceof Tolerant\Node\NamespaceUseGroupClause + if (($useClause = $parent) instanceof Tolerant\Node\NamespaceUseGroupClause || $useClause instanceof Tolerant\Node\NamespaceUseClause ) { - $contents = $node->getFileContents(); + $contents = $node->getFileContents(); if ($useClause instanceof Tolerant\Node\NamespaceUseGroupClause) { $prefix = $useClause->parent->parent->namespaceName; if ($prefix === null) { @@ -331,7 +331,7 @@ class TolerantDefinitionResolver implements DefinitionResolverInterface // 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) { $name .= '()'; } @@ -555,7 +555,7 @@ class TolerantDefinitionResolver implements DefinitionResolverInterface // VARIABLE // $this -> Type\this - // $myVariable -> type of corresponding assignment expression + // $myVariable -> type of corresponding assignment expression if ($expr instanceof Tolerant\Node\Expression\Variable || $expr instanceof Tolerant\Node\UseVariableName) { if ($expr->getName() === 'this') { return new Types\This; @@ -577,7 +577,7 @@ class TolerantDefinitionResolver implements DefinitionResolverInterface $expr->callableExpression instanceof Tolerant\Node\Expression\ScopedPropertyAccessExpression || $expr->callableExpression instanceof Tolerant\Node\Expression\MemberAccessExpression) ) { - + // Find the function definition if ($expr->callableExpression instanceof Tolerant\Node\Expression) { // Cannot get type for dynamic function call @@ -664,7 +664,7 @@ class TolerantDefinitionResolver implements DefinitionResolverInterface if ($expr->parent instanceof Tolerant\Node\Expression\CallExpression) { $fqn .= '()'; } - + $def = $this->index->getDefinition($fqn); if ($def === null) { return new Types\Mixed; @@ -686,14 +686,14 @@ class TolerantDefinitionResolver implements DefinitionResolverInterface } // ASSIGNMENT EXPRESSION - // $a = $myExpression => resolves to the type of the right-hand operand + // $a = $myExpression => resolves to the type of the right-hand operand if ($expr instanceof Tolerant\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 + // $condition ?: $elseExpression => resolves to type of $condition or $elseExpression if ($expr instanceof Tolerant\Node\Expression\TernaryExpression) { // ?: if ($expr->ifExpression === null) { @@ -751,7 +751,7 @@ class TolerantDefinitionResolver implements DefinitionResolverInterface return new Types\String_; } - // BINARY EXPRESSIONS: + // BINARY EXPRESSIONS: // Resolve to Types\Integer if both left and right operands are integer types, otherwise Types\Float // [operator] +, -, *, ** // [assignment] *=, **=, -=, += @@ -1005,8 +1005,8 @@ class TolerantDefinitionResolver implements DefinitionResolverInterface // PROPERTIES, CONSTS, CLASS CONSTS, ASSIGNMENT EXPRESSIONS // Get the documented type the assignment resolves to. if ( - ($declarationNode = - TolerantParserHelpers::tryGetPropertyDeclaration($node) ?? + ($declarationNode = + TolerantParserHelpers::tryGetPropertyDeclaration($node) ?? TolerantParserHelpers::tryGetConstOrClassConstDeclaration($node) ) !== null || ($node = $node->parent) instanceof Tolerant\Node\Expression\AssignmentExpression) @@ -1085,8 +1085,8 @@ class TolerantDefinitionResolver implements DefinitionResolverInterface // INPUT OUTPUT // namespace A\B; // class C { - // function a () {} A\B\C::a() - // static function b() {} A\B\C->b() + // function a () {} A\B\C->a() + // static function b() {} A\B\C::b() // } else if ($node instanceof Tolerant\Node\MethodDeclaration) { // Class method: use ClassName->methodName() as name @@ -1111,7 +1111,7 @@ class TolerantDefinitionResolver implements DefinitionResolverInterface // namespace A\B; // class C { // 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 + // $a = 4, $b = 4 A\B\C->$a, A\B\C->$b // TODO verify variable name // } else if ( ($propertyDeclaration = TolerantParserHelpers::tryGetPropertyDeclaration($node)) !== null && diff --git a/tests/NodeVisitor/DefinitionCollectorTest.php b/tests/NodeVisitor/DefinitionCollectorTest.php index d53f43b..5d6e7e8 100644 --- a/tests/NodeVisitor/DefinitionCollectorTest.php +++ b/tests/NodeVisitor/DefinitionCollectorTest.php @@ -7,7 +7,7 @@ use PHPUnit\Framework\TestCase; use PhpParser\{Node}; use phpDocumentor\Reflection\DocBlockFactory; use LanguageServer\{ - ParserResourceFactory + TolerantDefinitionResolver, TolerantTreeAnalyzer }; use LanguageServer\Index\{Index}; use function LanguageServer\pathToUri; @@ -67,14 +67,14 @@ class DefinitionCollectorTest extends TestCase private function collectDefinitions($path):array { $uri = pathToUri($path); - $parser = ParserResourceFactory::getParser(); + $parser = new Tolerant\Parser(); $docBlockFactory = DocBlockFactory::createInstance(); $index = new Index; - $definitionResolver = ParserResourceFactory::getDefinitionResolver($index); + $definitionResolver = new TolerantDefinitionResolver($index); $content = file_get_contents($path); - $treeAnalyzer = ParserResourceFactory::getTreeAnalyzer($parser, $content, $docBlockFactory, $definitionResolver, $uri); + $treeAnalyzer = new TolerantTreeAnalyzer($parser, $content, $docBlockFactory, $definitionResolver, $uri); return $treeAnalyzer->getDefinitionNodes(); } } diff --git a/tests/PhpDocumentLoaderTest.php b/tests/PhpDocumentLoaderTest.php index 8ae56d8..18e8373 100644 --- a/tests/PhpDocumentLoaderTest.php +++ b/tests/PhpDocumentLoaderTest.php @@ -3,22 +3,14 @@ declare(strict_types = 1); namespace LanguageServer\Tests\Server; -use PHPUnit\Framework\TestCase; -use LanguageServer\Tests\MockProtocolStream; use LanguageServer\{ - ParserResourceFactory, Server, Client, LanguageClient, Project, PhpDocument, PhpDocumentLoader, DefinitionResolver + PhpDocument, PhpDocumentLoader, Project, TolerantDefinitionResolver }; use LanguageServer\ContentRetriever\FileSystemContentRetriever; -use LanguageServer\Index\{Index, ProjectIndex, DependenciesIndex}; -use LanguageServer\Protocol\{ - TextDocumentItem, - TextDocumentIdentifier, - SymbolKind, - DiagnosticSeverity, - FormattingOptions, - ClientCapabilities +use LanguageServer\Index\{ + DependenciesIndex, Index, ProjectIndex }; -use AdvancedJsonRpc\{Request as RequestBody, Response as ResponseBody}; +use PHPUnit\Framework\TestCase; use function LanguageServer\pathToUri; class PhpDocumentLoaderTest extends TestCase @@ -34,7 +26,7 @@ class PhpDocumentLoaderTest extends TestCase $this->loader = new PhpDocumentLoader( new FileSystemContentRetriever, $projectIndex, - ParserResourceFactory::getDefinitionResolver($projectIndex) + new TolerantDefinitionResolver($projectIndex) ); } diff --git a/tests/PhpDocumentTest.php b/tests/PhpDocumentTest.php index 0dc9a6d..19081af 100644 --- a/tests/PhpDocumentTest.php +++ b/tests/PhpDocumentTest.php @@ -3,28 +3,29 @@ declare(strict_types = 1); namespace LanguageServer\Tests\Server; -use PHPUnit\Framework\TestCase; -use phpDocumentor\Reflection\DocBlockFactory; -use LanguageServer\Tests\MockProtocolStream; use LanguageServer\{ - ParserResourceFactory, LanguageClient, PhpDocument, DefinitionResolver, Parser + PhpDocument, TolerantDefinitionResolver +}; +use LanguageServer\Index\{ + Index +}; +use LanguageServer\Protocol\{ + Position }; -use LanguageServer\NodeVisitor\NodeAtPositionFinder; -use LanguageServer\ContentRetriever\FileSystemContentRetriever; -use LanguageServer\Protocol\{SymbolKind, Position, ClientCapabilities}; -use LanguageServer\Index\{Index, ProjectIndex, DependenciesIndex}; -use PhpParser\Node; -use function LanguageServer\isVendored; use Microsoft\PhpParser as Tolerant; +use phpDocumentor\Reflection\DocBlockFactory; +use PhpParser\Node; +use PHPUnit\Framework\TestCase; +use function LanguageServer\isVendored; class PhpDocumentTest extends TestCase { public function createDocument(string $uri, string $content) { - $parser = ParserResourceFactory::getParser(); + $parser = new Tolerant\Parser(); $docBlockFactory = DocBlockFactory::createInstance(); $index = new Index; - $definitionResolver = ParserResourceFactory::getDefinitionResolver($index); + $definitionResolver = new TolerantDefinitionResolver($index); return new PhpDocument($uri, $content, $index, $parser, $docBlockFactory, $definitionResolver); } diff --git a/tests/Server/ServerTestCase.php b/tests/Server/ServerTestCase.php index 583b40a..a93e4c1 100644 --- a/tests/Server/ServerTestCase.php +++ b/tests/Server/ServerTestCase.php @@ -6,13 +6,12 @@ namespace LanguageServer\Tests\Server; use PHPUnit\Framework\TestCase; use LanguageServer\Tests\MockProtocolStream; use LanguageServer\{ - ParserResourceFactory, Server, LanguageClient, PhpDocumentLoader, DefinitionResolver + Server, LanguageClient, PhpDocumentLoader, TolerantDefinitionResolver }; -use LanguageServer\Index\{ProjectIndex, StubsIndex, GlobalIndex, DependenciesIndex, Index}; +use LanguageServer\Index\{ProjectIndex, DependenciesIndex, Index}; use LanguageServer\ContentRetriever\FileSystemContentRetriever; -use LanguageServer\Protocol\{Position, Location, Range, ClientCapabilities}; +use LanguageServer\Protocol\{Position, Location, Range}; use function LanguageServer\pathToUri; -use Sabre\Event\Promise; abstract class ServerTestCase extends TestCase { @@ -52,7 +51,7 @@ abstract class ServerTestCase extends TestCase $projectIndex = new ProjectIndex($sourceIndex, $dependenciesIndex); $projectIndex->setComplete(); - $definitionResolver = ParserResourceFactory::getDefinitionResolver($projectIndex); + $definitionResolver = new TolerantDefinitionResolver($projectIndex); $client = new LanguageClient(new MockProtocolStream, new MockProtocolStream); $this->documentLoader = new PhpDocumentLoader(new FileSystemContentRetriever, $projectIndex, $definitionResolver); $this->textDocument = new Server\TextDocument($this->documentLoader, $definitionResolver, $client, $projectIndex); diff --git a/tests/Server/TextDocument/CompletionTest.php b/tests/Server/TextDocument/CompletionTest.php index a48ab95..600755d 100644 --- a/tests/Server/TextDocument/CompletionTest.php +++ b/tests/Server/TextDocument/CompletionTest.php @@ -6,16 +6,15 @@ namespace LanguageServer\Tests\Server\TextDocument; use PHPUnit\Framework\TestCase; use LanguageServer\Tests\MockProtocolStream; use LanguageServer\{ - ParserResourceFactory, Server, LanguageClient, PhpDocumentLoader, CompletionProvider, DefinitionResolver + Server, LanguageClient, PhpDocumentLoader, TolerantDefinitionResolver }; -use LanguageServer\Index\{Index, ProjectIndex, DependenciesIndex, GlobalIndex, StubsIndex}; +use LanguageServer\Index\{Index, ProjectIndex, DependenciesIndex}; use LanguageServer\ContentRetriever\FileSystemContentRetriever; use LanguageServer\Protocol\{ TextDocumentIdentifier, TextEdit, Range, Position, - ClientCapabilities, CompletionList, CompletionItem, CompletionItemKind @@ -38,7 +37,7 @@ class CompletionTest extends TestCase { $client = new LanguageClient(new MockProtocolStream, new MockProtocolStream); $projectIndex = new ProjectIndex(new Index, new DependenciesIndex); - $definitionResolver = ParserResourceFactory::getDefinitionResolver($projectIndex); + $definitionResolver = new TolerantDefinitionResolver($projectIndex); $contentRetriever = new FileSystemContentRetriever; $this->loader = new PhpDocumentLoader($contentRetriever, $projectIndex, $definitionResolver); $this->loader->load(pathToUri(__DIR__ . '/../../../fixtures/global_symbols.php'))->wait(); diff --git a/tests/Server/TextDocument/Definition/GlobalFallbackTest.php b/tests/Server/TextDocument/Definition/GlobalFallbackTest.php index b0510f6..aa9d7b9 100644 --- a/tests/Server/TextDocument/Definition/GlobalFallbackTest.php +++ b/tests/Server/TextDocument/Definition/GlobalFallbackTest.php @@ -6,12 +6,11 @@ namespace LanguageServer\Tests\Server\TextDocument\Definition; use LanguageServer\Tests\MockProtocolStream; use LanguageServer\Tests\Server\ServerTestCase; use LanguageServer\{ - ParserResourceFactory, Server, LanguageClient, PhpDocumentLoader, DefinitionResolver + Server, LanguageClient, PhpDocumentLoader, TolerantDefinitionResolver }; use LanguageServer\Index\{Index, ProjectIndex, DependenciesIndex}; use LanguageServer\ContentRetriever\FileSystemContentRetriever; -use LanguageServer\Protocol\{TextDocumentIdentifier, Position, Range, Location, ClientCapabilities}; -use Sabre\Event\Promise; +use LanguageServer\Protocol\{TextDocumentIdentifier, Position, Range, Location}; class GlobalFallbackTest extends ServerTestCase { @@ -20,7 +19,7 @@ class GlobalFallbackTest extends ServerTestCase $projectIndex = new ProjectIndex(new Index, new DependenciesIndex); $projectIndex->setComplete(); $client = new LanguageClient(new MockProtocolStream, new MockProtocolStream); - $definitionResolver = ParserResourceFactory::getDefinitionResolver($projectIndex); + $definitionResolver = new TolerantDefinitionResolver($projectIndex); $contentRetriever = new FileSystemContentRetriever; $loader = new PhpDocumentLoader($contentRetriever, $projectIndex, $definitionResolver); $this->textDocument = new Server\TextDocument($loader, $definitionResolver, $client, $projectIndex); diff --git a/tests/Server/TextDocument/DidChangeTest.php b/tests/Server/TextDocument/DidChangeTest.php index 3e66e94..d46067b 100644 --- a/tests/Server/TextDocument/DidChangeTest.php +++ b/tests/Server/TextDocument/DidChangeTest.php @@ -6,18 +6,15 @@ namespace LanguageServer\Tests\Server\TextDocument; use PHPUnit\Framework\TestCase; use LanguageServer\Tests\MockProtocolStream; use LanguageServer\{ - ParserResourceFactory, Server, Client, LanguageClient, PhpDocumentLoader, DefinitionResolver + Server, LanguageClient, PhpDocumentLoader, TolerantDefinitionResolver }; use LanguageServer\ContentRetriever\FileSystemContentRetriever; use LanguageServer\Index\{Index, ProjectIndex, DependenciesIndex}; use LanguageServer\Protocol\{ - TextDocumentIdentifier, - TextDocumentItem, VersionedTextDocumentIdentifier, TextDocumentContentChangeEvent, Range, - Position, - ClientCapabilities + Position }; class DidChangeTest extends TestCase @@ -26,7 +23,7 @@ class DidChangeTest extends TestCase { $projectIndex = new ProjectIndex(new Index, new DependenciesIndex); $client = new LanguageClient(new MockProtocolStream, new MockProtocolStream); - $definitionResolver = ParserResourceFactory::getDefinitionResolver($projectIndex); + $definitionResolver = new TolerantDefinitionResolver($projectIndex); $loader = new PhpDocumentLoader(new FileSystemContentRetriever, $projectIndex, $definitionResolver); $textDocument = new Server\TextDocument($loader, $definitionResolver, $client, $projectIndex); $phpDocument = $loader->open('whatever', "open('whatever', "textDocument = new Server\TextDocument($loader, $definitionResolver, $client, $projectIndex); } diff --git a/tests/Server/TextDocument/References/GlobalFallbackTest.php b/tests/Server/TextDocument/References/GlobalFallbackTest.php index 1fc9daa..684be18 100644 --- a/tests/Server/TextDocument/References/GlobalFallbackTest.php +++ b/tests/Server/TextDocument/References/GlobalFallbackTest.php @@ -3,14 +3,17 @@ declare(strict_types = 1); namespace LanguageServer\Tests\Server\TextDocument\References; -use PHPUnit\Framework\TestCase; -use LanguageServer\Tests\MockProtocolStream; use LanguageServer\{ - ParserResourceFactory, Server, LanguageClient, PhpDocumentLoader, DefinitionResolver + LanguageClient, PhpDocumentLoader, Server, TolerantDefinitionResolver }; -use LanguageServer\Index\{Index, ProjectIndex, DependenciesIndex}; use LanguageServer\ContentRetriever\FileSystemContentRetriever; -use LanguageServer\Protocol\{TextDocumentIdentifier, Position, ReferenceContext, Location, Range, ClientCapabilities}; +use LanguageServer\Index\{ + DependenciesIndex, Index, ProjectIndex +}; +use LanguageServer\Protocol\{ + Location, Position, Range, ReferenceContext, TextDocumentIdentifier +}; +use LanguageServer\Tests\MockProtocolStream; use LanguageServer\Tests\Server\ServerTestCase; class GlobalFallbackTest extends ServerTestCase @@ -19,7 +22,7 @@ class GlobalFallbackTest extends ServerTestCase { $projectIndex = new ProjectIndex(new Index, new DependenciesIndex); $projectIndex->setComplete(); - $definitionResolver = ParserResourceFactory::getDefinitionResolver($projectIndex); + $definitionResolver = new TolerantDefinitionResolver($projectIndex); $client = new LanguageClient(new MockProtocolStream, new MockProtocolStream); $this->documentLoader = new PhpDocumentLoader(new FileSystemContentRetriever, $projectIndex, $definitionResolver); $this->textDocument = new Server\TextDocument($this->documentLoader, $definitionResolver, $client, $projectIndex); diff --git a/tests/Validation/ValidationTest.php b/tests/Validation/ValidationTest.php index 1b47695..d830f19 100644 --- a/tests/Validation/ValidationTest.php +++ b/tests/Validation/ValidationTest.php @@ -8,8 +8,8 @@ use Exception; use LanguageServer\Definition; use LanguageServer\Index\Index; use LanguageServer\ParserKind; -use LanguageServer\ParserResourceFactory; use LanguageServer\PhpDocument; +use LanguageServer\TolerantDefinitionResolver; use phpDocumentor\Reflection\DocBlock; use phpDocumentor\Reflection\DocBlockFactory; use PHPUnit\Framework\TestCase; @@ -60,8 +60,14 @@ class ValidationTest extends TestCase echo "Test file: " . realpath($testCaseFile) . PHP_EOL; $fileContents = file_get_contents($testCaseFile); - $expectedValues = $this->getExpectedTestValues($testCaseFile, $frameworkName, $fileContents); - $actualValues = $this->getActualTestValues($testCaseFile, $frameworkName, $fileContents); + $actualValues = $this->getActualTestValues($testCaseFile, $fileContents); + + $outputFile = getExpectedValuesFile($testCaseFile); + if (!file_exists($outputFile)) { + file_put_contents(json_encode($actualValues, JSON_PRETTY_PRINT)); + } + + $expectedValues = (array)json_decode(file_get_contents($outputFile)); try { $this->assertEquals($expectedValues['definitions'], $actualValues['definitions']); @@ -81,56 +87,11 @@ class ValidationTest extends TestCase } } - /** - * @param $filename - * @param $frameworkName - * @param $fileContents - * @return array - */ - private function getExpectedTestValues($filename, $frameworkName, $fileContents) { - global $parserKind; - $parserKind = ParserKind::PHP_PARSER; - - $outputFile = getExpectedValuesFile($filename); - if (file_exists($outputFile)) { - return (array)json_decode(file_get_contents($outputFile)); - } - + private function getActualTestValues($filename, $fileContents): array { $index = new Index(); - $parser = ParserResourceFactory::getParser(); + $parser = new Tolerant\Parser(); $docBlockFactory = DocBlockFactory::createInstance(); - $definitionResolver = ParserResourceFactory::getDefinitionResolver($index); - - try { - $document = new PhpDocument($filename, $fileContents, $index, $parser, $docBlockFactory, $definitionResolver); - } catch (\Throwable $e) { - $this->markTestSkipped('Baseline parser failed: '. $e->getTraceAsString()); - } - - if ($document->getStmts() === null) { - $this->markTestSkipped('Baseline parser failed: null AST'); - } - - $expectedRefs = $index->references; - $this->filterSkippedReferences($expectedRefs); - $expectedDefs = $this->getTestValuesFromDefs($document->getDefinitions()); - - $refsAndDefs = array( - 'references' => json_decode(json_encode($expectedRefs)), - 'definitions' => json_decode(json_encode($expectedDefs)) - ); - - return $refsAndDefs; - } - - private function getActualTestValues($filename, $frameworkName, $fileContents): array { - global $parserKind; - $parserKind = ParserKind::TOLERANT_PHP_PARSER; - - $index = new Index(); - $parser = ParserResourceFactory::getParser(); - $docBlockFactory = DocBlockFactory::createInstance(); - $definitionResolver = ParserResourceFactory::getDefinitionResolver($index); + $definitionResolver = new TolerantDefinitionResolver($index); $document = new PhpDocument($filename, $fileContents, $index, $parser, $docBlockFactory, $definitionResolver);