diff --git a/src/TokenParsers/FileTokenParser.php b/src/TokenParsers/FileTokenParser.php index 8a88399..2bcf1c2 100644 --- a/src/TokenParsers/FileTokenParser.php +++ b/src/TokenParsers/FileTokenParser.php @@ -5,7 +5,6 @@ use Spatie\StructureDiscoverer\Collections\TokenCollection; use Spatie\StructureDiscoverer\Collections\UsageCollection; use Spatie\StructureDiscoverer\Data\DiscoveredStructure; -use Spatie\StructureDiscoverer\Data\Token; use Spatie\StructureDiscoverer\Enums\DiscoveredStructureType; use Spatie\StructureDiscoverer\Exceptions\CouldNotParseFile; use Throwable; @@ -40,7 +39,6 @@ public function execute( $index = 0; - try { do { if ($tokens->get($index)->is(T_NAMESPACE)) { @@ -74,6 +72,15 @@ public function execute( continue; } + if ( + $type === DiscoveredStructureType::ClassDefinition + && $this->isAnonymousClass($tokens, $index) + ) { + $index++; + + continue; + } + $discoveredStructure = $this->discoveredDataResolver->execute( $index + 1, $tokens, @@ -97,4 +104,21 @@ public function execute( return $found; } + + private function isAnonymousClass(TokenCollection $tokens, int $index): bool + { + $prevIndex = $index - 1; + + // find the previous non-whitespace token + while ($prevIndex >= 0 && $tokens->get($prevIndex)->is(T_WHITESPACE)) { + $prevIndex--; + } + + // if the token before T_CLASS is T_NEW, it's an anonymous class + if ($prevIndex >= 0 && $tokens->get($prevIndex)->is(T_NEW)) { + return true; + } + + return false; + } } diff --git a/tests/Fakes/FakeWithAnonymousClass.php b/tests/Fakes/FakeWithAnonymousClass.php new file mode 100644 index 0000000..6b6bf43 --- /dev/null +++ b/tests/Fakes/FakeWithAnonymousClass.php @@ -0,0 +1,15 @@ + [ @@ -310,6 +319,9 @@ public function satisfies(DiscoveredStructure $discoveredData): bool FakeChildClass::class, FakeRootClass::class, FakeSubChildClass::class, + FakeWithAnonymousClass::class, + FakeWithMultipleClasses::class, + FakeWithMultipleClassesSub::class, FakeNestedClass::class, FakeOtherNestedClass::class, ], @@ -331,6 +343,9 @@ public function satisfies(DiscoveredStructure $discoveredData): bool [ FakeOtherNestedClass::class, FakeNestedClass::class, + FakeWithMultipleClasses::class, + FakeWithMultipleClassesSub::class, + FakeWithAnonymousClass::class, FakeSubChildClass::class, FakeRootClass::class, FakeChildClass::class, @@ -507,3 +522,15 @@ public function satisfies(DiscoveredStructure $discoveredData): bool FakeIntEnum::class, ]); }); + +it('can parse anonymous classes', function () { + $found = Discover::in(__DIR__.'/Fakes')->get(); + + expect($found)->not->toContain("Spatie\StructureDiscoverer\Tests\Fakes\("); +}); + +it('can parse multiple nested classes', function () { + $found = Discover::in(__DIR__.'/Fakes')->get(); + + expect($found)->toContain("Spatie\StructureDiscoverer\Tests\Fakes\FakeWithMultipleClassesSub"); +});