mirror of
https://github.com/danog/class-finder.git
synced 2024-11-27 04:24:41 +01:00
Select the best possible namespace instead of the last one to match any of the elements.
This commit is contained in:
parent
88b389e489
commit
b74b0b02c1
@ -20,16 +20,7 @@ class PSR4Finder implements FinderInterface
|
||||
*/
|
||||
public function findClasses($namespace)
|
||||
{
|
||||
$composerNamespaces = $this->factory->getPSR4Namespaces();
|
||||
|
||||
/** @var PSR4Namespace $bestNamespace */
|
||||
$bestNamespace = array_reduce($composerNamespaces, function($carry, PSR4Namespace $potentialNamespace) use ($namespace) {
|
||||
if ($potentialNamespace->matches($namespace)) {
|
||||
return $potentialNamespace;
|
||||
} else {
|
||||
return $carry;
|
||||
}
|
||||
}, null);
|
||||
$bestNamespace = $this->findBestPSR4Namespace($namespace);
|
||||
|
||||
if ($bestNamespace instanceof PSR4Namespace) {
|
||||
return $bestNamespace->findClasses($namespace);
|
||||
@ -40,4 +31,31 @@ class PSR4Finder implements FinderInterface
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $namespace
|
||||
* @return PSR4Namespace
|
||||
*/
|
||||
private function findBestPSR4Namespace($namespace)
|
||||
{
|
||||
$composerNamespaces = $this->factory->getPSR4Namespaces();
|
||||
|
||||
$carry = new \stdClass();
|
||||
$carry->highestMatchingSegments = 0;
|
||||
$carry->bestNamespace = null;
|
||||
|
||||
/** @var PSR4Namespace $bestNamespace */
|
||||
$bestNamespace = array_reduce($composerNamespaces, function ($carry, PSR4Namespace $potentialNamespace) use ($namespace) {
|
||||
$matchingSegments = $potentialNamespace->countMatchingNamespaceSegments($namespace);
|
||||
|
||||
if ($matchingSegments > $carry->highestMatchingSegments) {
|
||||
$carry->highestMatchingSegments = $matchingSegments;
|
||||
$carry->bestNamespace = $potentialNamespace;
|
||||
}
|
||||
|
||||
return $carry;
|
||||
}, $carry);
|
||||
|
||||
return $bestNamespace->bestNamespace;
|
||||
}
|
||||
}
|
||||
|
@ -14,7 +14,28 @@ class PSR4Namespace
|
||||
$this->directories = $directories;
|
||||
}
|
||||
|
||||
public function matches($namespace)
|
||||
/**
|
||||
* Determines how many namespace segments match the internal namespace. This is useful because multiple namespaces
|
||||
* may technically match a registered namespace root, but one of the matches may be a better match. Namespaces that
|
||||
* match, but are not _the best_ match are incorrect matches. TestApp1\\ is **not** the best match when searching for
|
||||
* namespace TestApp1\\Multi\\Foo if TestApp1\\Multi was explicitly registered.
|
||||
*
|
||||
* PSR4Namespace $a;
|
||||
* $a->namespace = "TestApp1\\";
|
||||
* $a->countMatchingNamespaceSegments("TestApp1\\Multi") -> 1, TestApp1 matches.
|
||||
*
|
||||
* PSR4Namespace $b;
|
||||
* $b->namespace = "TestApp1\\Multi";
|
||||
* $b->countMatchingNamespaceSegments("TestApp1\\Multi") -> 2, TestApp1\\Multi matches
|
||||
*
|
||||
* PSR4Namespace $c;
|
||||
* $c->namespace = "HaydenPierce\\Foo\\Bar";
|
||||
* $c->countMatchingNamespaceSegments("TestApp1\\Multi") -> 0, No matches.
|
||||
*
|
||||
* @param $namespace
|
||||
* @return int
|
||||
*/
|
||||
public function countMatchingNamespaceSegments($namespace)
|
||||
{
|
||||
$namespaceFragments = explode('\\', $namespace);
|
||||
$undefinedNamespaceFragments = [];
|
||||
@ -23,13 +44,13 @@ class PSR4Namespace
|
||||
$possibleNamespace = implode('\\', $namespaceFragments) . '\\';
|
||||
|
||||
if($this->namespace === $possibleNamespace){
|
||||
return true;
|
||||
return count(explode('\\', $possibleNamespace));
|
||||
}
|
||||
|
||||
array_unshift($undefinedNamespaceFragments, array_pop($namespaceFragments));
|
||||
}
|
||||
|
||||
return false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
public function findClasses($namespace)
|
||||
|
Loading…
Reference in New Issue
Block a user