Skip to content

Commit 820d297

Browse files
committed
Refactor GenerateInterfaceUnionsCommand to improve type safety and extend functionality, update parsing logic in BaseCommand, and add tests for new attribute handling.
1 parent 346adf8 commit 820d297

4 files changed

Lines changed: 47 additions & 2 deletions

File tree

src/Commands/BaseCommand.php

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,23 @@ protected function findClassTokenIndex(array $tokens): ?int
179179
continue;
180180
}
181181

182-
return $index;
182+
for ($lookahead = $index + 1; isset($tokens[$lookahead]); $lookahead++) {
183+
$nextToken = $tokens[$lookahead];
184+
185+
if (!is_array($nextToken)) {
186+
continue;
187+
}
188+
189+
if (in_array($nextToken[0], [T_WHITESPACE, T_COMMENT, T_DOC_COMMENT], true)) {
190+
continue;
191+
}
192+
193+
if ($nextToken[0] === T_STRING) {
194+
return $index;
195+
}
196+
197+
break;
198+
}
183199
}
184200

185201
return null;

src/Commands/GenerateInterfaceUnionsCommand.php

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
namespace SynergiTech\ExportTypes\Commands;
44

55
use Illuminate\Filesystem\Filesystem;
6+
use Illuminate\Support\Collection;
67
use Illuminate\Support\Str;
78
use RecursiveDirectoryIterator;
89
use RecursiveIteratorIterator;
@@ -55,6 +56,7 @@ protected function readInterfaces(string $path, array $interfaces)
5556

5657
$rootNamespace = $this->determineRootNamespace($interfaces);
5758

59+
/** @var Collection<string, array{namespace:string,class:string,fqcn:string,extends:string,implements:array<int,string>}> $classes */
5860
$classes = collect($paths)
5961
->map(function ($item) {
6062
if (!$item->isFile()) {
@@ -83,7 +85,14 @@ protected function readInterfaces(string $path, array $interfaces)
8385
->toArray();
8486
}
8587

86-
protected function classImplementsInterface(array $info, string $interface, $classes): bool
88+
/**
89+
* @param array{namespace:string,class:string,fqcn:string,extends:string,implements:array<int,string>} $info
90+
* @param Collection<
91+
* string,
92+
* array{namespace:string,class:string,fqcn:string,extends:string,implements:array<int,string>}
93+
* > $classes
94+
*/
95+
protected function classImplementsInterface(array $info, string $interface, Collection $classes): bool
8796
{
8897
if (in_array($interface, $info['implements'], true)) {
8998
return true;

tests/Commands/GenerateInterfaceUnionsCommandTest.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ public function testCommandExports(): void
2222

2323
$this->assertIsString($output);
2424
$this->assertStringContainsString('"App\\\\Models\\\\AliasAnimal"', $output);
25+
$this->assertStringContainsString('"App\\\\Models\\\\AttributeClassReferenceAnimal"', $output);
2526
$this->assertStringContainsString('"App\\\\Models\\\\FullyQualifiedAnimal"', $output);
2627
$this->assertStringContainsString('"App\\\\Models\\\\GroupedUseAnimal"', $output);
2728
$this->assertStringContainsString('"App\\\\Models\\\\InheritedAnimal"', $output);
@@ -111,6 +112,15 @@ public function testParserResolvesSingleSegmentImports(): void
111112
$this->assertSame(['ArrayAccess'], $info['implements']);
112113
}
113114

115+
public function testParserIgnoresClassConstantReferencesBeforeClassDeclaration(): void
116+
{
117+
$info = $this->makeParserCommand()->classInfo('./workbench/app/Models/AttributeClassReferenceAnimal.php');
118+
119+
$this->assertSame('AttributeClassReferenceAnimal', $info['class']);
120+
$this->assertSame('App\\Models\\AttributeClassReferenceAnimal', $info['fqcn']);
121+
$this->assertSame(['App\\Interfaces\\AnimalInterface'], $info['implements']);
122+
}
123+
114124
public function testCommandFailsForInvalidInputPath(): void
115125
{
116126
$this->expectException(\RuntimeException::class);
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<?php
2+
3+
namespace App\Models;
4+
5+
use App\Interfaces\AnimalInterface;
6+
7+
#[\AllowDynamicProperties(ParentAnimal::class)]
8+
class AttributeClassReferenceAnimal implements AnimalInterface
9+
{
10+
}

0 commit comments

Comments
 (0)