1
0
Fork 0
php-language-server/src/Index/Index.php

215 lines
5.1 KiB
PHP
Raw Normal View History

2016-12-13 00:51:02 +00:00
<?php
declare(strict_types = 1);
namespace LanguageServer\Index;
use LanguageServer\Definition;
2017-01-25 00:38:11 +00:00
use Sabre\Event\EmitterTrait;
2016-12-13 00:51:02 +00:00
/**
* Represents the index of a project or dependency
* Serializable for caching
*/
2017-02-03 23:20:38 +00:00
class Index implements ReadableIndex, \Serializable
2016-12-13 00:51:02 +00:00
{
2017-01-25 00:38:11 +00:00
use EmitterTrait;
2016-12-13 00:51:02 +00:00
/**
* An associative array that maps fully qualified symbol names to Definitions
*
* @var Definition[]
*/
private $definitions = [];
/**
* An associative array that maps fully qualified symbol names to arrays of document URIs that reference the symbol
*
* @var string[][]
*/
private $references = [];
2017-01-25 00:38:11 +00:00
/**
* @var bool
*/
private $complete = false;
/**
* @var bool
*/
private $staticComplete = false;
/**
* Marks this index as complete
*
* @return void
*/
public function setComplete()
{
if (!$this->isStaticComplete()) {
$this->setStaticComplete();
}
$this->complete = true;
$this->emit('complete');
}
/**
* Marks this index as complete for static definitions and references
*
* @return void
*/
public function setStaticComplete()
{
$this->staticComplete = true;
$this->emit('static-complete');
}
/**
* Returns true if this index is complete
*
* @return bool
*/
public function isComplete(): bool
{
return $this->complete;
}
/**
* Returns true if this index is complete
*
* @return bool
*/
public function isStaticComplete(): bool
{
return $this->staticComplete;
}
2016-12-13 00:51:02 +00:00
/**
* Returns an associative array [string => Definition] that maps fully qualified symbol names
* to Definitions
*
* @return Definition[]
*/
public function getDefinitions(): array
{
return $this->definitions;
}
/**
* Returns the Definition object by a specific FQN
*
* @param string $fqn
* @param bool $globalFallback Whether to fallback to global if the namespaced FQN was not found
* @return Definition|null
*/
public function getDefinition(string $fqn, bool $globalFallback = false)
{
if (isset($this->definitions[$fqn])) {
return $this->definitions[$fqn];
}
if ($globalFallback) {
$parts = explode('\\', $fqn);
$fqn = end($parts);
return $this->getDefinition($fqn);
}
}
/**
* Registers a definition
*
* @param string $fqn The fully qualified name of the symbol
* @param string $definition The Definition object
* @return void
*/
public function setDefinition(string $fqn, Definition $definition)
{
$this->definitions[$fqn] = $definition;
2017-01-25 00:38:11 +00:00
$this->emit('definition-added');
2016-12-13 00:51:02 +00:00
}
/**
* Unsets the Definition for a specific symbol
* and removes all references pointing to that symbol
*
* @param string $fqn The fully qualified name of the symbol
* @return void
*/
public function removeDefinition(string $fqn)
{
unset($this->definitions[$fqn]);
unset($this->references[$fqn]);
}
/**
* Returns all URIs in this index that reference a symbol
*
* @param string $fqn The fully qualified name of the symbol
* @return string[]
*/
public function getReferenceUris(string $fqn): array
{
return $this->references[$fqn] ?? [];
}
/**
* Adds a document URI as a referencee of a specific symbol
*
* @param string $fqn The fully qualified name of the symbol
* @return void
*/
public function addReferenceUri(string $fqn, string $uri)
{
if (!isset($this->references[$fqn])) {
$this->references[$fqn] = [];
}
// TODO: use DS\Set instead of searching array
if (array_search($uri, $this->references[$fqn], true) === false) {
$this->references[$fqn][] = $uri;
}
}
/**
* Removes a document URI as the container for a specific symbol
*
* @param string $fqn The fully qualified name of the symbol
* @param string $uri The URI
* @return void
*/
public function removeReferenceUri(string $fqn, string $uri)
{
if (!isset($this->references[$fqn])) {
return;
}
$index = array_search($fqn, $this->references[$fqn], true);
if ($index === false) {
return;
}
array_splice($this->references[$fqn], $index, 1);
}
2017-02-03 23:20:38 +00:00
/**
* @param string $serialized
* @return void
*/
public function unserialize($serialized)
{
$data = unserialize($serialized);
foreach ($data as $prop => $val) {
$this->$prop = $val;
}
}
/**
* @param string $serialized
* @return string
*/
public function serialize()
{
return serialize([
'definitions' => $this->definitions,
'references' => $this->references,
'complete' => $this->complete,
'staticComplete' => $this->staticComplete
]);
}
2016-12-13 00:51:02 +00:00
}