diff --git a/src/ComposerScripts.php b/src/ComposerScripts.php index 717af19..6109fb2 100644 --- a/src/ComposerScripts.php +++ b/src/ComposerScripts.php @@ -30,9 +30,8 @@ class ComposerScripts $finder = new FileSystemFilesFinder; $contentRetriever = new FileSystemContentRetriever; $docBlockFactory = DocBlockFactory::createInstance(); - $parser = new Parser; - $tolerantParser = new Tolerant\Parser(); - $definitionResolver = DefinitionResolverFactory::create($index); + $parser = ParserResourceFactory::getParser(); + $definitionResolver = ParserResourceFactory::getDefinitionResolver($index); $stubsLocation = null; foreach ([__DIR__ . '/../../../jetbrains/phpstorm-stubs', __DIR__ . '/../vendor/jetbrains/phpstorm-stubs'] as $dir) { @@ -57,7 +56,7 @@ class ComposerScripts $parts['scheme'] = 'phpstubs'; $uri = Uri\build($parts); - $document = new PhpDocument($uri, $content, $index, $parser, $tolerantParser, $docBlockFactory, $definitionResolver); + $document = new PhpDocument($uri, $content, $index, $parser, $docBlockFactory, $definitionResolver); } $index->setComplete(); diff --git a/src/DefinitionResolverFactory.php b/src/DefinitionResolverFactory.php deleted file mode 100644 index ee64b4f..0000000 --- a/src/DefinitionResolverFactory.php +++ /dev/null @@ -1,19 +0,0 @@ -globalIndex = new GlobalIndex($stubsIndex, $this->projectIndex); // The DefinitionResolver should look in stubs, the project source and dependencies - $this->definitionResolver = DefinitionResolverFactory::create($this->globalIndex); + $this->definitionResolver = ParserResourceFactory::getDefinitionResolver($this->globalIndex); $this->documentLoader = new PhpDocumentLoader( $this->contentRetriever, diff --git a/src/ParserResourceFactory.php b/src/ParserResourceFactory.php new file mode 100644 index 0000000..6077848 --- /dev/null +++ b/src/ParserResourceFactory.php @@ -0,0 +1,26 @@ +uri = $uri; $this->index = $index; $this->parser = $parser; - $this->tolerantParser = $tolerantParser; $this->docBlockFactory = $docBlockFactory; $this->definitionResolver = $definitionResolver; $this->updateContent($content); @@ -171,7 +161,11 @@ class PhpDocument $this->definitions = null; $this->definitionNodes = null; - $treeAnalyzer = new TreeAnalyzer($this->parser, $content, $this->docBlockFactory, $this->definitionResolver, $this->uri); + $treeAnalyzerClass = $this->parser instanceof Parser + ? TreeAnalyzer::class + : TolerantTreeAnalyzer::class; + + $treeAnalyzer = new $treeAnalyzerClass($this->parser, $content, $this->docBlockFactory, $this->definitionResolver, $this->uri); $this->diagnostics = $treeAnalyzer->getDiagnostics(); diff --git a/src/PhpDocumentLoader.php b/src/PhpDocumentLoader.php index b49e63d..88ed525 100644 --- a/src/PhpDocumentLoader.php +++ b/src/PhpDocumentLoader.php @@ -65,8 +65,7 @@ class PhpDocumentLoader $this->contentRetriever = $contentRetriever; $this->projectIndex = $projectIndex; $this->definitionResolver = $definitionResolver; - $this->parser = new Parser; - $this->tolerantParser = new Tolerant\Parser(); + $this->parser = ParserResourceFactory::getParser(); $this->docBlockFactory = DocBlockFactory::createInstance(); } @@ -137,7 +136,6 @@ class PhpDocumentLoader $content, $this->projectIndex->getIndexForUri($uri), $this->parser, - $this->tolerantParser, $this->docBlockFactory, $this->definitionResolver ); diff --git a/src/TolerantTreeAnalyzer.php b/src/TolerantTreeAnalyzer.php new file mode 100644 index 0000000..095281d --- /dev/null +++ b/src/TolerantTreeAnalyzer.php @@ -0,0 +1,88 @@ +uri = $uri; + $this->parser = $parser; + $this->docBlockFactory = $docBlockFactory; + $this->definitionResolver = $definitionResolver; + $this->content = $content; + $this->$stmts = $this->parser->parse($content); + + // TODO - docblock errors + + foreach ($this->stmts->getDescendantNodes() as $node) { + $fqn = DefinitionResolver::getDefinedFqn($node); + // Only index definitions with an FQN (no variables) + if ($fqn === null) { + continue; + } + $this->definitionNodes[$fqn] = $node; + $this->definitions[$fqn] = $this->definitionResolver->createDefinitionFromNode($node, $fqn); + } + } + + public function getDiagnostics() { + $diagnostics = []; + foreach (Tolerant\DiagnosticsProvider::getDiagnostics($tolerantStmts) as $_error) { + $range = Tolerant\PositionUtilities::getRangeFromPosition($_error->start, $_error->length, $content); + + $diagnostics[] = new Diagnostic( + $_error->message, + new Range( + new Position($range->start->line, $range->start->character), + new Position($range->end->line, $range->start->character) + ) + ); + } + return $diagnostics; + } + + public function getDefinitions() { + return $this->definitions ?? []; + } + + public function getDefinitionNodes() { + return $this->definitionNodes ?? []; + } + + public function getReferenceNodes() { + return $this->referenceNodes ?? []; + } + + public function getStmts() { + return $this->stmts; + } + /** + * Returns the URI of the document + * + * @return string + */ + public function getUri(): string + { + return $this->uri; + } +} diff --git a/src/TreeAnalyzer.php b/src/TreeAnalyzer.php index def47c6..d4f4d5e 100644 --- a/src/TreeAnalyzer.php +++ b/src/TreeAnalyzer.php @@ -19,7 +19,7 @@ use phpDocumentor\Reflection\DocBlockFactory; use Sabre\Uri; use Microsoft\PhpParser as Tolerant; -class TreeAnalyzer { +class TreeAnalyzer implements TreeAnalyzerInterface { private $parser; private $stmts; diff --git a/src/TreeAnalyzerInterface.php b/src/TreeAnalyzerInterface.php new file mode 100644 index 0000000..695ac41 --- /dev/null +++ b/src/TreeAnalyzerInterface.php @@ -0,0 +1,34 @@ +parse($content); $traverser = new NodeTraverser; @@ -73,13 +72,12 @@ class DefinitionCollectorTest extends TestCase { $path = realpath(__DIR__ . '/../../fixtures/references.php'); $uri = pathToUri($path); - $parser = new Parser; - $tolerantParser = new Tolerant\Parser(); + $parser = ParserResourceFactory::getParser(); $docBlockFactory = DocBlockFactory::createInstance(); $index = new Index; - $definitionResolver = DefinitionResolverFactory::create($index); + $definitionResolver = ParserResourceFactory::getDefinitionResolver($index); $content = file_get_contents($path); - $document = new PhpDocument($uri, $content, $index, $parser, $tolerantParser, $docBlockFactory, $definitionResolver); + $document = new PhpDocument($uri, $content, $index, $parser, $docBlockFactory, $definitionResolver); $stmts = $parser->parse($content); $traverser = new NodeTraverser; diff --git a/tests/PhpDocumentLoaderTest.php b/tests/PhpDocumentLoaderTest.php index 7697417..8ae56d8 100644 --- a/tests/PhpDocumentLoaderTest.php +++ b/tests/PhpDocumentLoaderTest.php @@ -6,7 +6,7 @@ namespace LanguageServer\Tests\Server; use PHPUnit\Framework\TestCase; use LanguageServer\Tests\MockProtocolStream; use LanguageServer\{ - DefinitionResolverFactory, Server, Client, LanguageClient, Project, PhpDocument, PhpDocumentLoader, DefinitionResolver + ParserResourceFactory, Server, Client, LanguageClient, Project, PhpDocument, PhpDocumentLoader, DefinitionResolver }; use LanguageServer\ContentRetriever\FileSystemContentRetriever; use LanguageServer\Index\{Index, ProjectIndex, DependenciesIndex}; @@ -34,7 +34,7 @@ class PhpDocumentLoaderTest extends TestCase $this->loader = new PhpDocumentLoader( new FileSystemContentRetriever, $projectIndex, - DefinitionResolverFactory::create($projectIndex) + ParserResourceFactory::getDefinitionResolver($projectIndex) ); } diff --git a/tests/PhpDocumentTest.php b/tests/PhpDocumentTest.php index 341e01b..94399f0 100644 --- a/tests/PhpDocumentTest.php +++ b/tests/PhpDocumentTest.php @@ -7,7 +7,7 @@ use PHPUnit\Framework\TestCase; use phpDocumentor\Reflection\DocBlockFactory; use LanguageServer\Tests\MockProtocolStream; use LanguageServer\{ - DefinitionResolverFactory, LanguageClient, PhpDocument, DefinitionResolver, Parser + ParserResourceFactory, LanguageClient, PhpDocument, DefinitionResolver, Parser }; use LanguageServer\NodeVisitor\NodeAtPositionFinder; use LanguageServer\ContentRetriever\FileSystemContentRetriever; @@ -21,12 +21,11 @@ class PhpDocumentTest extends TestCase { public function createDocument(string $uri, string $content) { - $parser = new Parser; - $tolerantParser = new Tolerant\Parser(); + $parser = ParserResourceFactory::getParser(); $docBlockFactory = DocBlockFactory::createInstance(); $index = new Index; - $definitionResolver = DefinitionResolverFactory::create($index); - return new PhpDocument($uri, $content, $index, $parser, $tolerantParser, $docBlockFactory, $definitionResolver); + $definitionResolver = ParserResourceFactory::getDefinitionResolver($index); + return new PhpDocument($uri, $content, $index, $parser, $docBlockFactory, $definitionResolver); } public function testParsesVariableVariables() diff --git a/tests/Server/ServerTestCase.php b/tests/Server/ServerTestCase.php index 75d59d1..0dcac39 100644 --- a/tests/Server/ServerTestCase.php +++ b/tests/Server/ServerTestCase.php @@ -6,7 +6,7 @@ namespace LanguageServer\Tests\Server; use PHPUnit\Framework\TestCase; use LanguageServer\Tests\MockProtocolStream; use LanguageServer\{ - DefinitionResolverFactory, Server, LanguageClient, PhpDocumentLoader, DefinitionResolver + ParserResourceFactory, Server, LanguageClient, PhpDocumentLoader, DefinitionResolver }; use LanguageServer\Index\{ProjectIndex, StubsIndex, GlobalIndex, DependenciesIndex, Index}; use LanguageServer\ContentRetriever\FileSystemContentRetriever; @@ -52,7 +52,7 @@ abstract class ServerTestCase extends TestCase $projectIndex = new ProjectIndex($sourceIndex, $dependenciesIndex); $projectIndex->setComplete(); - $definitionResolver = DefinitionResolverFactory::create($projectIndex); + $definitionResolver = ParserResourceFactory::getDefinitionResolver($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 d08ee63..a48ab95 100644 --- a/tests/Server/TextDocument/CompletionTest.php +++ b/tests/Server/TextDocument/CompletionTest.php @@ -6,7 +6,7 @@ namespace LanguageServer\Tests\Server\TextDocument; use PHPUnit\Framework\TestCase; use LanguageServer\Tests\MockProtocolStream; use LanguageServer\{ - DefinitionResolverFactory, Server, LanguageClient, PhpDocumentLoader, CompletionProvider, DefinitionResolver + ParserResourceFactory, Server, LanguageClient, PhpDocumentLoader, CompletionProvider, DefinitionResolver }; use LanguageServer\Index\{Index, ProjectIndex, DependenciesIndex, GlobalIndex, StubsIndex}; use LanguageServer\ContentRetriever\FileSystemContentRetriever; @@ -38,7 +38,7 @@ class CompletionTest extends TestCase { $client = new LanguageClient(new MockProtocolStream, new MockProtocolStream); $projectIndex = new ProjectIndex(new Index, new DependenciesIndex); - $definitionResolver = DefinitionResolverFactory::create($projectIndex); + $definitionResolver = ParserResourceFactory::getDefinitionResolver($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 661b222..b0510f6 100644 --- a/tests/Server/TextDocument/Definition/GlobalFallbackTest.php +++ b/tests/Server/TextDocument/Definition/GlobalFallbackTest.php @@ -6,7 +6,7 @@ namespace LanguageServer\Tests\Server\TextDocument\Definition; use LanguageServer\Tests\MockProtocolStream; use LanguageServer\Tests\Server\ServerTestCase; use LanguageServer\{ - DefinitionResolverFactory, Server, LanguageClient, PhpDocumentLoader, DefinitionResolver + ParserResourceFactory, Server, LanguageClient, PhpDocumentLoader, DefinitionResolver }; use LanguageServer\Index\{Index, ProjectIndex, DependenciesIndex}; use LanguageServer\ContentRetriever\FileSystemContentRetriever; @@ -20,7 +20,7 @@ class GlobalFallbackTest extends ServerTestCase $projectIndex = new ProjectIndex(new Index, new DependenciesIndex); $projectIndex->setComplete(); $client = new LanguageClient(new MockProtocolStream, new MockProtocolStream); - $definitionResolver = DefinitionResolverFactory::create($projectIndex); + $definitionResolver = ParserResourceFactory::getDefinitionResolver($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 4b42ae2..3e66e94 100644 --- a/tests/Server/TextDocument/DidChangeTest.php +++ b/tests/Server/TextDocument/DidChangeTest.php @@ -6,7 +6,7 @@ namespace LanguageServer\Tests\Server\TextDocument; use PHPUnit\Framework\TestCase; use LanguageServer\Tests\MockProtocolStream; use LanguageServer\{ - DefinitionResolverFactory, Server, Client, LanguageClient, PhpDocumentLoader, DefinitionResolver + ParserResourceFactory, Server, Client, LanguageClient, PhpDocumentLoader, DefinitionResolver }; use LanguageServer\ContentRetriever\FileSystemContentRetriever; use LanguageServer\Index\{Index, ProjectIndex, DependenciesIndex}; @@ -26,7 +26,7 @@ class DidChangeTest extends TestCase { $projectIndex = new ProjectIndex(new Index, new DependenciesIndex); $client = new LanguageClient(new MockProtocolStream, new MockProtocolStream); - $definitionResolver = DefinitionResolverFactory::create($projectIndex); + $definitionResolver = ParserResourceFactory::getDefinitionResolver($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 d6a22c2..1fc9daa 100644 --- a/tests/Server/TextDocument/References/GlobalFallbackTest.php +++ b/tests/Server/TextDocument/References/GlobalFallbackTest.php @@ -6,7 +6,7 @@ namespace LanguageServer\Tests\Server\TextDocument\References; use PHPUnit\Framework\TestCase; use LanguageServer\Tests\MockProtocolStream; use LanguageServer\{ - DefinitionResolverFactory, Server, LanguageClient, PhpDocumentLoader, DefinitionResolver + ParserResourceFactory, Server, LanguageClient, PhpDocumentLoader, DefinitionResolver }; use LanguageServer\Index\{Index, ProjectIndex, DependenciesIndex}; use LanguageServer\ContentRetriever\FileSystemContentRetriever; @@ -19,7 +19,7 @@ class GlobalFallbackTest extends ServerTestCase { $projectIndex = new ProjectIndex(new Index, new DependenciesIndex); $projectIndex->setComplete(); - $definitionResolver = DefinitionResolverFactory::create($projectIndex); + $definitionResolver = ParserResourceFactory::getDefinitionResolver($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);