From 682cb2a072df07e692592f48ad43a76555771a20 Mon Sep 17 00:00:00 2001 From: Trevor Bortins Date: Mon, 6 Feb 2017 18:24:01 -0800 Subject: [PATCH] handle other vendor references --- src/Index/ProjectIndex.php | 5 ++-- src/Indexer.php | 10 ++------ src/LanguageServer.php | 5 ++-- src/PhpDocument.php | 11 --------- src/Server/TextDocument.php | 2 +- src/Server/Workspace.php | 5 ++-- src/utils.php | 46 ++++++++++++++++++++++++++++++++++++- tests/PhpDocumentTest.php | 10 ++++---- 8 files changed, 62 insertions(+), 32 deletions(-) diff --git a/src/Index/ProjectIndex.php b/src/Index/ProjectIndex.php index 8adc938..8bc2467 100644 --- a/src/Index/ProjectIndex.php +++ b/src/Index/ProjectIndex.php @@ -22,10 +22,11 @@ class ProjectIndex extends AbstractAggregateIndex */ private $sourceIndex; - public function __construct(Index $sourceIndex, DependenciesIndex $dependenciesIndex) + public function __construct(Index $sourceIndex, DependenciesIndex $dependenciesIndex, \stdClass $composerJson = null) { $this->sourceIndex = $sourceIndex; $this->dependenciesIndex = $dependenciesIndex; + $this->composerJson = $composerJson; parent::__construct(); } @@ -43,7 +44,7 @@ class ProjectIndex extends AbstractAggregateIndex */ public function getIndexForUri(string $uri): Index { - if (preg_match('/\/vendor\/([^\/]+\/[^\/]+)\//', $uri, $matches)) { + if (\LanguageServer\uriInVendorDir($this->composerJson, $uri, $matches)) { $packageName = $matches[1]; return $this->dependenciesIndex->getDependencyIndex($packageName); } diff --git a/src/Indexer.php b/src/Indexer.php index a8c2bb1..bf5ed90 100644 --- a/src/Indexer.php +++ b/src/Indexer.php @@ -117,14 +117,8 @@ class Indexer /** @var string[][] */ $deps = []; - $vendorDir = isset($this->composerJson->config->{'vendor-dir'}) ? - $this->composerJson->config->{'vendor-dir'} - : 'vendor'; - $vendorDir = str_replace('/', '\/', $vendorDir); - $this->client->window->logMessage(MessageType::INFO, "Vendor dir: $vendorDir"); - foreach ($uris as $uri) { - if ($this->composerLock !== null && preg_match("/\/$vendorDir\/([^\/]+\/[^\/]+)\//", $uri, $matches)) { + if ($this->composerLock !== null && uriInVendorDir($this->composerJson, $uri, $matches)) { // Dependency file $packageName = $matches[1]; if (!isset($deps[$packageName])) { @@ -221,7 +215,7 @@ class Indexer $this->client->window->logMessage(MessageType::LOG, "Parsing $uri"); try { $document = yield $this->documentLoader->load($uri); - if (!$document->isVendored()) { + if (!isVendored($document, $this->composerJson)) { $this->client->textDocument->publishDiagnostics($uri, $document->getDiagnostics()); } } catch (ContentTooLargeException $e) { diff --git a/src/LanguageServer.php b/src/LanguageServer.php index 7445e53..3c999f2 100644 --- a/src/LanguageServer.php +++ b/src/LanguageServer.php @@ -187,7 +187,7 @@ class LanguageServer extends AdvancedJsonRpc\Dispatcher $dependenciesIndex = new DependenciesIndex; $sourceIndex = new Index; - $this->projectIndex = new ProjectIndex($sourceIndex, $dependenciesIndex); + $this->projectIndex = new ProjectIndex($sourceIndex, $dependenciesIndex, $this->composerJson); $stubsIndex = StubsIndex::read(); $this->globalIndex = new GlobalIndex($stubsIndex, $this->projectIndex); @@ -257,7 +257,8 @@ class LanguageServer extends AdvancedJsonRpc\Dispatcher $dependenciesIndex, $sourceIndex, $this->composerLock, - $this->documentLoader + $this->documentLoader, + $this->composerJson ); } diff --git a/src/PhpDocument.php b/src/PhpDocument.php index b838cd3..3a25c23 100644 --- a/src/PhpDocument.php +++ b/src/PhpDocument.php @@ -220,17 +220,6 @@ class PhpDocument } } - /** - * Returns true if the document is a dependency - * - * @return bool - */ - public function isVendored(): bool - { - $path = Uri\parse($this->uri)['path']; - return strpos($path, '/vendor/') !== false; - } - /** * Returns array of TextEdit changes to format this document. * diff --git a/src/Server/TextDocument.php b/src/Server/TextDocument.php index 532d642..b087807 100644 --- a/src/Server/TextDocument.php +++ b/src/Server/TextDocument.php @@ -134,7 +134,7 @@ class TextDocument public function didOpen(TextDocumentItem $textDocument) { $document = $this->documentLoader->open($textDocument->uri, $textDocument->text); - if (!$document->isVendored()) { + if (!\LanguageServer\isVendored($document, $this->composerJson)) { $this->client->textDocument->publishDiagnostics($textDocument->uri, $document->getDiagnostics()); } } diff --git a/src/Server/Workspace.php b/src/Server/Workspace.php index 5aae7cf..46cab28 100644 --- a/src/Server/Workspace.php +++ b/src/Server/Workspace.php @@ -49,13 +49,14 @@ class Workspace * @param \stdClass $composerLock The parsed composer.lock of the project, if any * @param PhpDocumentLoader $documentLoader PhpDocumentLoader instance to load documents */ - public function __construct(ProjectIndex $index, DependenciesIndex $dependenciesIndex, Index $sourceIndex, \stdClass $composerLock = null, PhpDocumentLoader $documentLoader) + public function __construct(ProjectIndex $index, DependenciesIndex $dependenciesIndex, Index $sourceIndex, \stdClass $composerLock = null, PhpDocumentLoader $documentLoader, \stdClass $composerJson = null) { $this->sourceIndex = $sourceIndex; $this->index = $index; $this->dependenciesIndex = $dependenciesIndex; $this->composerLock = $composerLock; $this->documentLoader = $documentLoader; + $this->composerJson = $composerJson; } /** @@ -122,7 +123,7 @@ class Workspace $symbol->$prop = $val; } // Find out package name - preg_match('/\/vendor\/([^\/]+\/[^\/]+)\//', $def->symbolInformation->location->uri, $matches); + uriInVendorDir($this->composerJson, $def->symbolInformation->location->uri, $matches); $packageName = $matches[1]; foreach ($this->composerLock->packages as $package) { if ($package->name === $packageName) { diff --git a/src/utils.php b/src/utils.php index 6cbb317..3d844e4 100644 --- a/src/utils.php +++ b/src/utils.php @@ -137,7 +137,7 @@ function stripStringOverlap(string $a, string $b): string * Use for sorting an array of URIs by number of segments * in ascending order. * - * @param array + * @param array $uriList * @return void */ function sortUrisLevelOrder(&$uriList) @@ -146,3 +146,47 @@ function sortUrisLevelOrder(&$uriList) return substr_count(Uri\parse($a)['path'], '/') - substr_count(Uri\parse($b)['path'], '/'); }); } + +/** + * Checks a document against the composer.json to see if it + * is a vendored document + * + * @param PhpDocument $document + * @param \stdClass|null $composerJson + * @return bool + */ +function isVendored(PhpDocument $document, \stdClass $composerJson = null): bool +{ + $path = Uri\parse($document->getUri())['path']; + $vendorDir = getVendorDir($composerJson); + return strpos($path, "/$vendorDir/") !== false; +} + +/** + * Check a given URI against the composer.json to see if it + * is a vendored URI + * + * @param \stdClass|null $composerJson + * @param string $uri + * @param array $matches + * @return int + */ +function uriInVendorDir(\stdClass $composerJson = null, string $uri, &$matches): int +{ + $vendorDir = str_replace('/', '\/', getVendorDir($composerJson)); + return preg_match("/\/$vendorDir\/([^\/]+\/[^\/]+)\//", $uri, $matches); +} + +/** + * Helper function to get the vendor directory from composer.json + * or default to 'vendor' + * + * @param \stdClass|null $composerJson + * @return string + */ +function getVendorDir(\stdClass $composerJson = null): string +{ + return isset($composerJson->config->{'vendor-dir'}) ? + $composerJson->config->{'vendor-dir'} + : 'vendor'; +} diff --git a/tests/PhpDocumentTest.php b/tests/PhpDocumentTest.php index b9b3704..829a176 100644 --- a/tests/PhpDocumentTest.php +++ b/tests/PhpDocumentTest.php @@ -42,18 +42,18 @@ class PhpDocumentTest extends TestCase public function testIsVendored() { $document = $this->createDocument('file:///dir/vendor/x.php', "assertEquals(true, $document->isVendored()); + $this->assertEquals(true, \LanguageServer\isVendored($document)); $document = $this->createDocument('file:///c:/dir/vendor/x.php', "assertEquals(true, $document->isVendored()); + $this->assertEquals(true, \LanguageServer\isVendored($document)); $document = $this->createDocument('file:///vendor/x.php', "assertEquals(true, $document->isVendored()); + $this->assertEquals(true, \LanguageServer\isVendored($document)); $document = $this->createDocument('file:///dir/vendor.php', "assertEquals(false, $document->isVendored()); + $this->assertEquals(false, \LanguageServer\isVendored($document)); $document = $this->createDocument('file:///dir/x.php', "assertEquals(false, $document->isVendored()); + $this->assertEquals(false, \LanguageServer\isVendored($document)); } }