1
0
Fork 0
pull/357/head
Sara Itani 2017-03-04 18:36:17 -08:00
parent 2280e7889b
commit 722898f74d
20 changed files with 189 additions and 72 deletions

View File

@ -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();

View File

@ -1,19 +0,0 @@
<?php
namespace LanguageServer;
use LanguageServer\Index\ReadableIndex;
class DefinitionResolverFactory
{
public static function create(ReadableIndex $index, int $parserKind = ParserKind::PHP_PARSER) : DefinitionResolverInterface
{
if ($parserKind === ParserKind::PHP_PARSER) {
return new DefinitionResolver($index);
} elseif ($parserKind === ParserKind::TOLERANT_PHP_PARSER) {
return new TolerantDefinitionResolver($index);
}
throw new \Exception("Unhandled parser kind");
}
}

View File

@ -192,7 +192,7 @@ class LanguageServer extends AdvancedJsonRpc\Dispatcher
$this->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,

View File

@ -0,0 +1,26 @@
<?php
namespace LanguageServer;
use Microsoft\PhpParser as Tolerant;
use LanguageServer\Index\ReadableIndex;
class ParserResourceFactory {
const PARSER_KIND = ParserKind::PHP_PARSER;
public function getParser() {
if (self::PARSER_KIND === ParserKind::PHP_PARSER) {
return new Parser;
} else {
return new Tolerant\Parser;
}
}
public function getDefinitionResolver(ReadableIndex $index) {
if (self::PARSER_KIND === ParserKind::PHP_PARSER) {
return new DefinitionResolver($index);
} else {
return new TolerantDefinitionResolver($index);
}
}
}

View File

@ -96,19 +96,11 @@ class PhpDocument
*/
private $diagnostics;
/**
* Microsoft\PhpParser\Parser instance
*
* @var Tolerant\Parser
*/
private $tolerantParser;
/**
* @param string $uri The URI of the document
* @param string $content The content of the document
* @param Index $index The Index to register definitions and references to
* @param Parser $parser The PHPParser instance
* @param Parser $tolerantParser The tolerant PHP Parser instance
* @param DocBlockFactory $docBlockFactory The DocBlockFactory instance to parse docblocks
* @param DefinitionResolverInterface $definitionResolver The DefinitionResolver to resolve definitions to symbols in the workspace
*/
@ -116,15 +108,13 @@ class PhpDocument
string $uri,
string $content,
Index $index,
Parser $parser,
Tolerant\Parser $tolerantParser,
$parser,
DocBlockFactory $docBlockFactory,
DefinitionResolverInterface $definitionResolver
) {
$this->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();

View File

@ -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
);

View File

@ -0,0 +1,88 @@
<?php
declare(strict_types = 1);
namespace LanguageServer;
use LanguageServer\Protocol\{Diagnostic, DiagnosticSeverity, Range, Position, TextEdit};
use LanguageServer\NodeVisitor\{
NodeAtPositionFinder,
ReferencesAdder,
DocBlockParser,
DefinitionCollector,
ColumnCalculator,
ReferencesCollector
};
use LanguageServer\Index\Index;
use PhpParser\{Error, ErrorHandler, Node, NodeTraverser, Parser};
use PhpParser\NodeVisitor\NameResolver;
use phpDocumentor\Reflection\DocBlockFactory;
use Sabre\Uri;
use Microsoft\PhpParser as Tolerant;
class TolerantTreeAnalyzer implements TreeAnalyzerInterface {
private $parser;
private $stmts;
public function __construct(Parser $parser, $content, $docBlockFactory, $definitionResolver, $uri) {
$this->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;
}
}

View File

@ -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;

View File

@ -0,0 +1,34 @@
<?php
declare(strict_types = 1);
namespace LanguageServer;
use LanguageServer\Protocol\{Diagnostic, DiagnosticSeverity, Range, Position, TextEdit};
use LanguageServer\NodeVisitor\{
NodeAtPositionFinder,
ReferencesAdder,
DocBlockParser,
DefinitionCollector,
ColumnCalculator,
ReferencesCollector
};
use LanguageServer\Index\Index;
use PhpParser\{Error, ErrorHandler, Node, NodeTraverser, Parser};
use PhpParser\NodeVisitor\NameResolver;
use phpDocumentor\Reflection\DocBlockFactory;
use Sabre\Uri;
use Microsoft\PhpParser as Tolerant;
interface TreeAnalyzerInterface {
public function __construct(Parser $parser, $content, $docBlockFactory, $definitionResolver, $uri);
public function getDiagnostics();
public function getDefinitions();
public function getDefinitionNodes();
public function getReferenceNodes();
public function getStmts();
}

View File

@ -8,7 +8,7 @@ use PhpParser\{NodeTraverser, Node};
use PhpParser\NodeVisitor\NameResolver;
use phpDocumentor\Reflection\DocBlockFactory;
use LanguageServer\{
DefinitionResolverFactory, LanguageClient, PhpDocument, PhpDocumentLoader, Parser, DefinitionResolver
ParserResourceFactory, LanguageClient, PhpDocument, PhpDocumentLoader, Parser, DefinitionResolver
};
use LanguageServer\ContentRetriever\FileSystemContentRetriever;
use LanguageServer\Protocol\ClientCapabilities;
@ -24,13 +24,12 @@ class DefinitionCollectorTest extends TestCase
{
$path = realpath(__DIR__ . '/../../fixtures/symbols.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;
@ -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;

View File

@ -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)
);
}

View File

@ -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()

View File

@ -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);

View File

@ -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();

View File

@ -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);

View File

@ -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', "<?php\necho 'Hello, World'\n");

View File

@ -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};
@ -19,7 +19,7 @@ class DidCloseTest 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', "<?php\necho 'Hello, World'\n");

View File

@ -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\Index\{Index, ProjectIndex, DependenciesIndex};
use LanguageServer\ContentRetriever\FileSystemContentRetriever;
@ -27,7 +27,7 @@ class FormattingTest 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);

View File

@ -6,7 +6,7 @@ namespace LanguageServer\Tests\Server\TextDocument;
use PHPUnit\Framework\TestCase;
use LanguageServer\Tests\MockProtocolStream;
use LanguageServer\{
DefinitionResolverFactory, Server, Client, LanguageClient, ClientHandler, PhpDocumentLoader, DefinitionResolver
ParserResourceFactory, Server, Client, LanguageClient, ClientHandler, PhpDocumentLoader, DefinitionResolver
};
use LanguageServer\Index\{Index, ProjectIndex, DependenciesIndex};
use LanguageServer\ContentRetriever\FileSystemContentRetriever;
@ -40,7 +40,7 @@ class ParseErrorsTest extends TestCase
}
};
$projectIndex = new ProjectIndex(new Index, new DependenciesIndex);
$definitionResolver = DefinitionResolverFactory::create($projectIndex);
$definitionResolver = ParserResourceFactory::getDefinitionResolver($projectIndex);
$loader = new PhpDocumentLoader(new FileSystemContentRetriever, $projectIndex, $definitionResolver);
$this->textDocument = new Server\TextDocument($loader, $definitionResolver, $client, $projectIndex);
}

View File

@ -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);