use a single array to store definitions
parent
188a5df382
commit
cacde1ea72
|
@ -16,12 +16,13 @@ class Index implements ReadableIndex, \Serializable
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An associative array that maps splitted fully qualified symbol names
|
* An associative array that maps splitted fully qualified symbol names
|
||||||
* to member definitions, eg :
|
* to definitions, eg :
|
||||||
* [
|
* [
|
||||||
* 'Psr' => [
|
* 'Psr' => [
|
||||||
* '\Log' => [
|
* '\Log' => [
|
||||||
* '\LoggerInterface' => [
|
* '\LoggerInterface' => [
|
||||||
* '->log()' => $definition,
|
* '' => $def1, // definition for 'Psr\Log\LoggerInterface' which is non-member
|
||||||
|
* '->log()' => $def2, // definition for 'Psr\Log\LoggerInterface->log()' which is a member definition
|
||||||
* ],
|
* ],
|
||||||
* ],
|
* ],
|
||||||
* ],
|
* ],
|
||||||
|
@ -29,23 +30,7 @@ class Index implements ReadableIndex, \Serializable
|
||||||
*
|
*
|
||||||
* @var array
|
* @var array
|
||||||
*/
|
*/
|
||||||
private $memberDefinitions = [];
|
private $definitions = [];
|
||||||
|
|
||||||
/**
|
|
||||||
* An associative array that maps splitted fully qualified symbol names
|
|
||||||
* to non member definitions, eg :
|
|
||||||
* [
|
|
||||||
* 'Psr' => [
|
|
||||||
* '\Log' => [
|
|
||||||
* '\LoggerInterface' => $definition,
|
|
||||||
* ],
|
|
||||||
* ],
|
|
||||||
* ]
|
|
||||||
*
|
|
||||||
* @var array
|
|
||||||
*/
|
|
||||||
private $nonMemberDefinitions = [];
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An associative array that maps fully qualified symbol names
|
* An associative array that maps fully qualified symbol names
|
||||||
|
@ -124,8 +109,7 @@ class Index implements ReadableIndex, \Serializable
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
|
|
||||||
yield from $this->yieldDefinitionsRecursively($this->memberDefinitions);
|
yield from $this->yieldDefinitionsRecursively($this->definitions);
|
||||||
yield from $this->yieldDefinitionsRecursively($this->nonMemberDefinitions);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -141,20 +125,18 @@ class Index implements ReadableIndex, \Serializable
|
||||||
// }
|
// }
|
||||||
|
|
||||||
$parts = $this->splitFqn($fqn);
|
$parts = $this->splitFqn($fqn);
|
||||||
$result = $this->getIndexValue($parts, $this->memberDefinitions);
|
if ('' === end($parts)) {
|
||||||
|
// we want to return all the definitions in the given FQN, not only
|
||||||
if ($result instanceof Definition) {
|
// the one matching exactly the FQN.
|
||||||
yield $fqn => $result;
|
array_pop($parts);
|
||||||
} elseif (is_array($result)) {
|
|
||||||
yield from $this->yieldDefinitionsRecursively($result, $fqn);
|
|
||||||
} else {
|
|
||||||
$result = $this->getIndexValue($parts, $this->nonMemberDefinitions);
|
|
||||||
|
|
||||||
if ($result instanceof Definition) {
|
|
||||||
yield $fqn => $result;
|
|
||||||
} elseif (is_array($result)) {
|
|
||||||
yield from $this->yieldDefinitionsRecursively($result, $fqn);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$result = $this->getIndexValue($parts, $this->definitions);
|
||||||
|
|
||||||
|
if ($result instanceof Definition) {
|
||||||
|
yield $fqn => $result;
|
||||||
|
} elseif (is_array($result)) {
|
||||||
|
yield from $this->yieldDefinitionsRecursively($result, $fqn);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -181,18 +163,23 @@ class Index implements ReadableIndex, \Serializable
|
||||||
// }
|
// }
|
||||||
|
|
||||||
$parts = $this->splitFqn($fqn);
|
$parts = $this->splitFqn($fqn);
|
||||||
$result = $this->getIndexValue($parts, $this->memberDefinitions);
|
$result = $this->getIndexValue($parts, $this->definitions);
|
||||||
|
|
||||||
if ($result instanceof Definition) {
|
if ($result instanceof Definition) {
|
||||||
return $result;
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
$result = $this->getIndexValue($parts, $this->nonMemberDefinitions);
|
if ($globalFallback) {
|
||||||
|
$parts = explode('\\', $fqn);
|
||||||
|
$fqn = end($parts);
|
||||||
|
|
||||||
return $result instanceof Definition
|
return $this->getDefinition($fqn);
|
||||||
? $result
|
}
|
||||||
: null
|
|
||||||
;
|
// return $result instanceof Definition
|
||||||
|
// ? $result
|
||||||
|
// : null
|
||||||
|
// ;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -212,12 +199,7 @@ class Index implements ReadableIndex, \Serializable
|
||||||
// $this->fqnDefinitions[$namespacedFqn][$fqn] = $definition;
|
// $this->fqnDefinitions[$namespacedFqn][$fqn] = $definition;
|
||||||
|
|
||||||
$parts = $this->splitFqn($fqn);
|
$parts = $this->splitFqn($fqn);
|
||||||
|
$this->indexDefinition(0, $parts, $this->definitions, $definition);
|
||||||
if ($definition->isMember) {
|
|
||||||
$this->indexDefinition(0, $parts, $this->memberDefinitions, $definition);
|
|
||||||
} else {
|
|
||||||
$this->indexDefinition(0, $parts, $this->nonMemberDefinitions, $definition);
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->emit('definition-added');
|
$this->emit('definition-added');
|
||||||
}
|
}
|
||||||
|
@ -242,9 +224,7 @@ class Index implements ReadableIndex, \Serializable
|
||||||
|
|
||||||
$parts = $this->splitFqn($fqn);
|
$parts = $this->splitFqn($fqn);
|
||||||
|
|
||||||
if (true !== $this->removeIndexedDefinition(0, $parts, $this->memberDefinitions)) {
|
$this->removeIndexedDefinition(0, $parts, $this->definitions);
|
||||||
$this->removeIndexedDefinition(0, $parts, $this->nonMemberDefinitions);
|
|
||||||
}
|
|
||||||
|
|
||||||
unset($this->references[$fqn]);
|
unset($this->references[$fqn]);
|
||||||
}
|
}
|
||||||
|
@ -317,6 +297,14 @@ class Index implements ReadableIndex, \Serializable
|
||||||
{
|
{
|
||||||
$data = unserialize($serialized);
|
$data = unserialize($serialized);
|
||||||
|
|
||||||
|
if (isset($data['definitions'])) {
|
||||||
|
foreach ($data['definitions'] as $fqn => $definition) {
|
||||||
|
$this->setDefinition($fqn, $definition);
|
||||||
|
}
|
||||||
|
|
||||||
|
unset($data['definitions']);
|
||||||
|
}
|
||||||
|
|
||||||
foreach ($data as $prop => $val) {
|
foreach ($data as $prop => $val) {
|
||||||
$this->$prop = $val;
|
$this->$prop = $val;
|
||||||
}
|
}
|
||||||
|
@ -329,8 +317,7 @@ class Index implements ReadableIndex, \Serializable
|
||||||
public function serialize()
|
public function serialize()
|
||||||
{
|
{
|
||||||
return serialize([
|
return serialize([
|
||||||
'memberDefinitions' => $this->memberDefinitions,
|
'definitions' => iterator_to_array($this->getDefinitions(), true),
|
||||||
'nonMemberDefinitions' => $this->nonMemberDefinitions,
|
|
||||||
'references' => $this->references,
|
'references' => $this->references,
|
||||||
'complete' => $this->complete,
|
'complete' => $this->complete,
|
||||||
'staticComplete' => $this->staticComplete
|
'staticComplete' => $this->staticComplete
|
||||||
|
@ -401,10 +388,12 @@ class Index implements ReadableIndex, \Serializable
|
||||||
}
|
}
|
||||||
|
|
||||||
// split the last part in 2 parts at the operator
|
// split the last part in 2 parts at the operator
|
||||||
|
$hasOperator = false;
|
||||||
$lastPart = end($parts);
|
$lastPart = end($parts);
|
||||||
foreach (['::', '->'] as $operator) {
|
foreach (['::', '->'] as $operator) {
|
||||||
$endParts = explode($operator, $lastPart);
|
$endParts = explode($operator, $lastPart);
|
||||||
if (count($endParts) > 1) {
|
if (count($endParts) > 1) {
|
||||||
|
$hasOperator = true;
|
||||||
// replace the last part by its pieces
|
// replace the last part by its pieces
|
||||||
array_pop($parts);
|
array_pop($parts);
|
||||||
$parts[] = $endParts[0];
|
$parts[] = $endParts[0];
|
||||||
|
@ -413,6 +402,16 @@ class Index implements ReadableIndex, \Serializable
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!$hasOperator) {
|
||||||
|
// add an empty part to store the non-member definition to avoid
|
||||||
|
// definition collisions in the index array, eg
|
||||||
|
// 'Psr\Log\LoggerInterface' will be stored at
|
||||||
|
// ['Psr']['\Log']['\LoggerInterface'][''] to be able to also store
|
||||||
|
// member definitions, ie 'Psr\Log\LoggerInterface->log()' will be
|
||||||
|
// stored at ['Psr']['\Log']['\LoggerInterface']['->log()']
|
||||||
|
$parts[] = '';
|
||||||
|
}
|
||||||
|
|
||||||
return $parts;
|
return $parts;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -439,12 +438,6 @@ class Index implements ReadableIndex, \Serializable
|
||||||
return $storage[$part];
|
return $storage[$part];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!is_array($storage[$part]) && count($parts) > 0) {
|
|
||||||
// we're looking for a member definition in the non member index,
|
|
||||||
// no matches can be found.
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this->getIndexValue($parts, $storage[$part]);
|
return $this->getIndexValue($parts, $storage[$part]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -471,12 +464,6 @@ class Index implements ReadableIndex, \Serializable
|
||||||
$storage[$part] = [];
|
$storage[$part] = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!is_array($storage[$part])) {
|
|
||||||
// it's a non member definition, we can't add it to the member
|
|
||||||
// definitions index
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->indexDefinition($level + 1, $parts, $storage[$part], $definition);
|
$this->indexDefinition($level + 1, $parts, $storage[$part], $definition);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -491,7 +478,6 @@ class Index implements ReadableIndex, \Serializable
|
||||||
* @param array $parts The splitted FQN
|
* @param array $parts The splitted FQN
|
||||||
* @param array &$storage The current array in which to remove data
|
* @param array &$storage The current array in which to remove data
|
||||||
* @param array &$rootStorage The root storage array
|
* @param array &$rootStorage The root storage array
|
||||||
* @return boolean|null True when the definition has been found and removed, null otherwise.
|
|
||||||
*/
|
*/
|
||||||
private function removeIndexedDefinition(int $level, array $parts, array &$storage, &$rootStorage)
|
private function removeIndexedDefinition(int $level, array $parts, array &$storage, &$rootStorage)
|
||||||
{
|
{
|
||||||
|
@ -504,16 +490,16 @@ class Index implements ReadableIndex, \Serializable
|
||||||
if (0 === $level) {
|
if (0 === $level) {
|
||||||
// we're at root level, no need to check for parents
|
// we're at root level, no need to check for parents
|
||||||
// w/o children
|
// w/o children
|
||||||
return true;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
array_pop($parts);
|
array_pop($parts);
|
||||||
// parse again the definition tree to see if the parent
|
// parse again the definition tree to see if the parent
|
||||||
// can be removed too if it has no more children
|
// can be removed too if it has no more children
|
||||||
return $this->removeIndexedDefinition(0, $parts, $rootStorage, $rootStorage);
|
$this->removeIndexedDefinition(0, $parts, $rootStorage, $rootStorage);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return $this->removeIndexedDefinition($level + 1, $parts, $storage[$part], $rootStorage);
|
$this->removeIndexedDefinition($level + 1, $parts, $storage[$part], $rootStorage);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,7 +18,7 @@ class Indexer
|
||||||
/**
|
/**
|
||||||
* @var int The prefix for every cache item
|
* @var int The prefix for every cache item
|
||||||
*/
|
*/
|
||||||
const CACHE_VERSION = 2;
|
const CACHE_VERSION = 1;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var FilesFinder
|
* @var FilesFinder
|
||||||
|
|
Loading…
Reference in New Issue