Skip to content

Commit fd31255

Browse files
Copilotruudk
andauthored
Add Importable interface to enable direct passing of importable objects (#6)
* Initial plan * Add Importable interface and update all classes to implement it Co-authored-by: ruudk <104180+ruudk@users.noreply.github.com> * Fix code style whitespace issue Co-authored-by: ruudk <104180+ruudk@users.noreply.github.com> * Tweak --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: ruudk <104180+ruudk@users.noreply.github.com> Co-authored-by: Ruud Kamphuis <ruudk@users.noreply.github.com>
1 parent bf7191a commit fd31255

File tree

8 files changed

+216
-30
lines changed

8 files changed

+216
-30
lines changed

src/Alias.php

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,16 +6,15 @@
66

77
use InvalidArgumentException;
88
use Override;
9-
use Stringable;
109

11-
final readonly class Alias implements Stringable
10+
final readonly class Alias implements Importable
1211
{
1312
public string $alias;
14-
public FullyQualified | FunctionName | NamespaceName $target;
13+
public Importable $target;
1514

1615
public function __construct(
1716
string $alias,
18-
FullyQualified | FunctionName | NamespaceName $target,
17+
Importable $target,
1918
) {
2019
$alias = trim($alias);
2120

@@ -37,13 +36,15 @@ public function __toString() : string
3736
return sprintf('%s as %s', $this->target, $this->alias);
3837
}
3938

39+
#[Override]
4040
public function equals(object $other) : bool
4141
{
4242
return $other instanceof self
4343
&& $this->alias === $other->alias
4444
&& $this->target->equals($other->target);
4545
}
4646

47+
#[Override]
4748
public function compare(object $other) : int
4849
{
4950
// Aliases should sort by their target, not their alias name

src/ClassName.php

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,8 @@
66

77
use InvalidArgumentException;
88
use Override;
9-
use Stringable;
109

11-
final readonly class ClassName implements Stringable
10+
final readonly class ClassName implements Importable
1211
{
1312
/**
1413
* @var non-empty-string
@@ -34,7 +33,7 @@ public function __construct(
3433
/**
3534
* @phpstan-return ($input is null ? null : self)
3635
*/
37-
public static function maybeFromString(null | self | string $input) : ?self
36+
public static function maybeFromString(null | Importable | self | string $input) : ?self
3837
{
3938
if ($input === null) {
4039
return null;
@@ -44,7 +43,7 @@ public static function maybeFromString(null | self | string $input) : ?self
4443
return $input;
4544
}
4645

47-
return new self($input);
46+
return new self((string) $input);
4847
}
4948

5049
#[Override]
@@ -53,11 +52,13 @@ public function __toString() : string
5352
return $this->name;
5453
}
5554

55+
#[Override]
5656
public function equals(object $other) : bool
5757
{
5858
return $other instanceof self && $this->name === $other->name;
5959
}
6060

61+
#[Override]
6162
public function compare(object $other) : int
6263
{
6364
if ($other instanceof self) {

src/CodeGenerator.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,7 @@ public function maybeDump(
159159
/**
160160
* Finds an available alias for a type, appending numbers if the alias is already taken
161161
*/
162-
private function findAvailableAlias(Alias | FullyQualified | FunctionName | NamespaceName $type, string $alias, int $i = 1) : string
162+
private function findAvailableAlias(Importable $type, string $alias, int $i = 1) : string
163163
{
164164
$aliasToCheck = $i === 1 ? $alias : sprintf('%s%d', $alias, $i);
165165

@@ -188,7 +188,7 @@ public function importEnum(UnitEnum $enum) : string
188188
/**
189189
* Imports a class, namespace, or function and returns the alias to use in the generated code
190190
*/
191-
public function import(FullyQualified | FunctionName | NamespaceName | string $fqcnOrEnum) : string
191+
public function import(Importable | string $fqcnOrEnum) : string
192192
{
193193
if ($fqcnOrEnum instanceof FunctionName) {
194194
$alias = $this->findAvailableAlias($fqcnOrEnum, $fqcnOrEnum->shortName);
@@ -214,7 +214,7 @@ public function import(FullyQualified | FunctionName | NamespaceName | string $f
214214
/**
215215
* Imports a class by importing its parent namespace and returning the relative path
216216
*/
217-
public function importByParent(FullyQualified | string $name) : string
217+
public function importByParent(Importable | string $name) : string
218218
{
219219
$fqcn = FullyQualified::maybeFromString($name);
220220

@@ -231,7 +231,7 @@ public function importByParent(FullyQualified | string $name) : string
231231
// Import the namespace and return the alias with class name
232232
return (string) new FullyQualified(
233233
$this->import($fqcn->namespace),
234-
(string) $fqcn->className,
234+
$fqcn->className,
235235
);
236236
}
237237

src/FullyQualified.php

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,19 +6,24 @@
66

77
use InvalidArgumentException;
88
use Override;
9-
use Stringable;
109

11-
final readonly class FullyQualified implements Stringable
10+
final readonly class FullyQualified implements Importable
1211
{
1312
public ClassName $className;
1413
public ?NamespaceName $namespace;
1514

1615
public function __construct(
17-
string $part,
18-
string ...$parts,
16+
Importable | string $part,
17+
Importable | string ...$parts,
1918
) {
2019
$flattened = array_filter(
21-
explode('\\', implode('\\', [$part, ...$parts])),
20+
explode(
21+
'\\',
22+
implode(
23+
'\\',
24+
array_map(strval(...), [$part, ...$parts]),
25+
),
26+
),
2227
fn($p) => $p !== '',
2328
);
2429

@@ -29,15 +34,13 @@ public function __construct(
2934
$classNamePart = array_pop($flattened);
3035
$this->className = new ClassName($classNamePart);
3136

32-
$this->namespace = $flattened !== []
33-
? new NamespaceName(implode('\\', $flattened))
34-
: null;
37+
$this->namespace = $flattened !== [] ? new NamespaceName(implode('\\', $flattened)) : null;
3538
}
3639

3740
/**
3841
* @phpstan-return ($input is null ? null : self)
3942
*/
40-
public static function maybeFromString(null | self | string $input) : ?self
43+
public static function maybeFromString(null | Importable | self | string $input) : ?self
4144
{
4245
if ($input === null) {
4346
return null;
@@ -47,7 +50,7 @@ public static function maybeFromString(null | self | string $input) : ?self
4750
return $input;
4851
}
4952

50-
return new self($input);
53+
return new self((string) $input);
5154
}
5255

5356
#[Override]
@@ -60,11 +63,13 @@ public function __toString() : string
6063
return $this->namespace . '\\' . $this->className;
6164
}
6265

66+
#[Override]
6367
public function equals(object $other) : bool
6468
{
6569
return $other instanceof self && (string) $this === (string) $other;
6670
}
6771

72+
#[Override]
6873
public function compare(object $other) : int
6974
{
7075
$thisStr = str_replace('\\', ' ', (string) $this);

src/FunctionName.php

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,8 @@
66

77
use InvalidArgumentException;
88
use Override;
9-
use Stringable;
109

11-
final class FunctionName implements Stringable
10+
final class FunctionName implements Importable
1211
{
1312
public readonly string $name;
1413

@@ -38,7 +37,7 @@ public function __construct(
3837
/**
3938
* @phpstan-return ($input is null ? null : self)
4039
*/
41-
public static function maybeFromString(null | self | string $input) : ?self
40+
public static function maybeFromString(null | Importable | self | string $input) : ?self
4241
{
4342
if ($input === null) {
4443
return null;
@@ -48,7 +47,7 @@ public static function maybeFromString(null | self | string $input) : ?self
4847
return $input;
4948
}
5049

51-
return new self($input);
50+
return new self((string) $input);
5251
}
5352

5453
#[Override]
@@ -57,11 +56,13 @@ public function __toString() : string
5756
return 'function ' . $this->name;
5857
}
5958

59+
#[Override]
6060
public function equals(object $other) : bool
6161
{
6262
return $other instanceof self && (string) $this === (string) $other;
6363
}
6464

65+
#[Override]
6566
public function compare(object $other) : int
6667
{
6768
$thisStr = str_replace('\\', ' ', $this->name);

src/Importable.php

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Ruudk\CodeGenerator;
6+
7+
use Stringable;
8+
9+
/**
10+
* Interface for classes that can be imported in code generation
11+
*/
12+
interface Importable extends Stringable
13+
{
14+
/**
15+
* Check if this importable is equal to another object
16+
*/
17+
public function equals(object $other) : bool;
18+
19+
/**
20+
* Compare this importable with another object for sorting
21+
*/
22+
public function compare(object $other) : int;
23+
}

src/NamespaceName.php

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,8 @@
66

77
use InvalidArgumentException;
88
use Override;
9-
use Stringable;
109

11-
final class NamespaceName implements Stringable
10+
final class NamespaceName implements Importable
1211
{
1312
/**
1413
* @var non-empty-string
@@ -45,7 +44,7 @@ public function __construct(
4544
/**
4645
* @phpstan-return ($input is null ? null : self)
4746
*/
48-
public static function maybeFromString(null | self | string $input) : ?self
47+
public static function maybeFromString(null | Importable | self | string $input) : ?self
4948
{
5049
if ($input === null) {
5150
return null;
@@ -55,7 +54,7 @@ public static function maybeFromString(null | self | string $input) : ?self
5554
return $input;
5655
}
5756

58-
return new self($input);
57+
return new self((string) $input);
5958
}
6059

6160
#[Override]
@@ -72,11 +71,13 @@ public function with(string $part, string ...$parts) : self
7271
return new self($this->namespace, $part, ...$parts);
7372
}
7473

74+
#[Override]
7575
public function equals(object $other) : bool
7676
{
7777
return $other instanceof self && $this->namespace === $other->namespace;
7878
}
7979

80+
#[Override]
8081
public function compare(object $other) : int
8182
{
8283
$thisStr = str_replace('\\', ' ', $this->namespace);

0 commit comments

Comments
 (0)