Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions src/Analyser/ClassNode.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

use function array_filter;
use function in_array;
use function ltrim;
use function preg_match;
use function strcasecmp;
use function strncasecmp;
Expand Down Expand Up @@ -92,6 +93,8 @@ public function __construct(
*/
public function usesClass(string $class): bool
{
$class = ltrim($class, '\\');

if (! $this->dependsOn($class, isCaseSensitive: false)) {
return false;
}
Expand All @@ -111,6 +114,7 @@ public function usesClass(string $class): bool
*/
public function usesConstant(string $constant): bool
{
$constant = ltrim($constant, '\\');
$separatorPosition = strrpos($constant, '\\');

// a constant name is case-sensitive
Expand Down Expand Up @@ -224,6 +228,8 @@ public function nameMatches(string $pattern, bool $isFullName = false): bool
*/
public function implementsInterface(string $interface): bool
{
$interface = ltrim($interface, '\\');

return $this->matchesAnyClassLike($interface, $this->implements)
|| $this->matchesAnyClassLike($interface, $this->interfaceExtends)
|| $this->matchesAnyClassLike($interface, $this->parentInterfaces);
Expand Down
9 changes: 7 additions & 2 deletions src/Analyser/NodeQueryTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,12 @@
namespace Boundwize\StructArmed\Analyser;

use function in_array;
use function rtrim;
use function ltrim;
use function strcasecmp;
use function strlen;
use function strncasecmp;
use function strtolower;
use function trim;

/**
* Query helpers shared by {@see ClassNode}, {@see AnonymousClassNode},
Expand All @@ -35,6 +36,8 @@ public function isInLayer(string $layer): bool

public function dependsOn(string $dependency, bool $isCaseSensitive = true): bool
{
$dependency = ltrim($dependency, '\\');

if ($isCaseSensitive) {
return in_array($dependency, $this->dependencies, true);
}
Expand All @@ -50,7 +53,7 @@ public function dependsOn(string $dependency, bool $isCaseSensitive = true): boo

public function dependsOnNamespace(string $namespace): bool
{
$prefix = rtrim($namespace, '\\') . '\\';
$prefix = trim($namespace, '\\') . '\\';
$prefixLength = strlen($prefix);

// namespace names are case-insensitive; only the prefix is compared,
Expand Down Expand Up @@ -78,6 +81,8 @@ public function setFunctionCalls(array $functionCalls): void

public function callsFunction(string $function): bool
{
$function = ltrim($function, '\\');

foreach ($this->functionCalls as $functionCall) {
if (strcasecmp($functionCall, $function) === 0) {
return true;
Expand Down
5 changes: 5 additions & 0 deletions src/Analyser/RecursiveParentsTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

namespace Boundwize\StructArmed\Analyser;

use function ltrim;
use function strcasecmp;

/**
Expand Down Expand Up @@ -36,12 +37,16 @@ public function setRecursiveParents(array $parentClasses, array $parentInterface
*/
public function implementsInterface(string $interface): bool
{
$interface = ltrim($interface, '\\');

return $this->matchesAnyClassLike($interface, $this->implements)
|| $this->matchesAnyClassLike($interface, $this->parentInterfaces);
}

public function extendsClass(string $class): bool
{
$class = ltrim($class, '\\');

if ($this->extends !== null && strcasecmp($this->extends, $class) === 0) {
return true;
}
Expand Down
2 changes: 2 additions & 0 deletions tests/Analyser/AnonymousClassNodeTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ public function testParentChainQueriesAreCaseInsensitive(): void

$this->assertSame(['App\\Support\\baseclass', 'App\\Support\\rootclass'], $anonymousClassNode->parentClasses);
$this->assertTrue($anonymousClassNode->extendsClass('App\\Support\\RootClass'));
$this->assertTrue($anonymousClassNode->extendsClass('\\App\\Support\\RootClass'));
$this->assertTrue($anonymousClassNode->implementsInterface('\\App\\Contracts\\RootInterface'));
$this->assertFalse($anonymousClassNode->extendsClass('App\\Support\\OtherClass'));
$this->assertTrue($anonymousClassNode->implementsInterface('App\\Contracts\\RootInterface'));
$this->assertFalse($anonymousClassNode->implementsInterface('App\\Contracts\\OtherInterface'));
Expand Down
12 changes: 12 additions & 0 deletions tests/Analyser/ClassNodeTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,7 @@ interfaceExtends: ['App\\Contracts\\BaseOrderService'],
$this->assertTrue($classNode->implementsInterface('App\\Contracts\\BaseOrderService'));
$this->assertTrue($classNode->callsFunction('var_dump'));
$this->assertTrue($classNode->callsFunction('VAR_DUMP'));
$this->assertTrue($classNode->callsFunction('\\var_dump'));
$this->assertFalse($classNode->callsFunction('array_map'));
$this->assertTrue($classNode->accessesSuperglobals());
$this->assertTrue($classNode->usesLanguageConstruct('exit'));
Expand Down Expand Up @@ -318,6 +319,7 @@ className: Foo::class,

$this->assertTrue($classNode->implementsInterface('App\\Contracts\\FooInterface'));
$this->assertTrue($classNode->implementsInterface('App\\Contracts\\RootInterface'));
$this->assertTrue($classNode->implementsInterface('\\App\\Contracts\\FooInterface'));
$this->assertFalse($classNode->implementsInterface('App\\Contracts\\OtherInterface'));
}

Expand All @@ -338,6 +340,8 @@ className: Foo::class,

$this->assertTrue($classNode->extendsClass('App\\Support\\BaseClass'));
$this->assertTrue($classNode->extendsClass('App\\Support\\RootClass'));
$this->assertTrue($classNode->extendsClass('\\App\\Support\\BaseClass'));
$this->assertTrue($classNode->extendsClass('\\App\\Support\\RootClass'));
$this->assertFalse($classNode->extendsClass('App\\Support\\OtherClass'));
}

Expand All @@ -358,6 +362,7 @@ interfaceExtends: ['App\\Contracts\\baseinterface'],
);

$this->assertTrue($classNode->implementsInterface('App\\Contracts\\BaseInterface'));
$this->assertTrue($classNode->implementsInterface('\\App\\Contracts\\BaseInterface'));
$this->assertTrue($classNode->implementsInterface('App\\Contracts\\RootInterface'));
$this->assertFalse($classNode->implementsInterface('App\\Contracts\\OtherInterface'));
}
Expand Down Expand Up @@ -514,6 +519,7 @@ className: 'App\\Domain\\OrderService',

$this->assertFalse($classNode->dependsOn('datetimeimmutable'));
$this->assertTrue($classNode->dependsOn('datetimeimmutable', isCaseSensitive: false));
$this->assertTrue($classNode->dependsOn('\\' . DateTimeImmutable::class));
$this->assertFalse($classNode->dependsOn('datetime', isCaseSensitive: false));
}

Expand All @@ -535,7 +541,9 @@ className: 'App\\Domain\\OrderService',

$this->assertTrue($classNode->usesClass('datetimeimmutable'));
$this->assertTrue($classNode->usesClass('DATETIMEIMMUTABLE'));
$this->assertTrue($classNode->usesClass('\\' . DateTimeImmutable::class));
$this->assertFalse($classNode->usesClass('VENDOR\\HELPER'));
$this->assertFalse($classNode->usesClass('\\Vendor\\helper'));
}

public function testUsesClassIgnoresDependencyOnlyUsedAsFunctionOrConstant(): void
Expand Down Expand Up @@ -577,6 +585,8 @@ className: 'App\\Domain\\OrderService',
);

$this->assertTrue($classNode->usesConstant('STDIN'));
$this->assertTrue($classNode->usesConstant('\\STDIN'));
$this->assertTrue($classNode->usesConstant('\\Vendor\\Config\\DEBUG'));
$this->assertFalse($classNode->usesConstant('stdin'));
$this->assertTrue($classNode->usesConstant('vendor\\config\\DEBUG'));
$this->assertFalse($classNode->usesConstant('Vendor\\Config\\debug'));
Expand Down Expand Up @@ -621,6 +631,8 @@ className: 'App\\Domain\\OrderService',
);

$this->assertTrue($classNode->dependsOnNamespace('App\\Bar'));
$this->assertTrue($classNode->dependsOnNamespace('\\App\\Bar'));
$this->assertTrue($classNode->dependsOnNamespace('\\App\\Bar\\'));
$this->assertFalse($classNode->dependsOnNamespace('App\\Baz'));
}

Expand Down
Loading