Skip to content
Merged
35 changes: 33 additions & 2 deletions src/CodeGenerator.php
Original file line number Diff line number Diff line change
Expand Up @@ -186,9 +186,9 @@ public function importEnum(UnitEnum $enum) : string
}

/**
* Imports a class or function and returns the alias to use in the generated code
* Imports a class, namespace, or function and returns the alias to use in the generated code
*/
public function import(FullyQualified | FunctionName | string $fqcnOrEnum) : string
public function import(FullyQualified | FunctionName | NamespaceName | string $fqcnOrEnum) : string
{
if ($fqcnOrEnum instanceof FunctionName) {
$alias = $this->findAvailableAlias($fqcnOrEnum, $fqcnOrEnum->shortName);
Expand All @@ -197,13 +197,44 @@ public function import(FullyQualified | FunctionName | string $fqcnOrEnum) : str
return $alias;
}

if ($fqcnOrEnum instanceof NamespaceName) {
$alias = $this->findAvailableAlias($fqcnOrEnum, $fqcnOrEnum->lastPart);
$this->imports[$alias] = $fqcnOrEnum;

return $alias;
}

$fqcn = FullyQualified::maybeFromString($fqcnOrEnum);
$alias = $this->findAvailableAlias($fqcn, $fqcn->className->name);
$this->imports[$alias] = $fqcn;

return $alias;
}

/**
* Imports a class by importing its parent namespace and returning the relative path
*/
public function importByParent(FullyQualified | string $name) : string
{
$fqcn = FullyQualified::maybeFromString($name);

// If there's no namespace, just return the class name
if ($fqcn->namespace === null) {
return (string) $fqcn->className;
}

// Check if the full target namespace is the same as the current namespace
if ($this->namespace?->equals($fqcn->namespace) === true) {
return (string) $fqcn->className;
}

// Import the namespace and return the alias with class name
return (string) new FullyQualified(
$this->import($fqcn->namespace),
(string) $fqcn->className,
);
}

/**
* Generates a PHP attribute string for the given fully qualified class name
*/
Expand Down
101 changes: 101 additions & 0 deletions tests/CodeGeneratorTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,107 @@ public function testImportSameNamespace() : void
);
}

public function testImportByParentWithString() : void
{
$alias = $this->generator->importByParent('App\\Models\\User');

self::assertSame('Models\\User', $alias);

$this->assertDumpFile(
<<<'PHP'
<?php

declare(strict_types=1);

use App\Models;

PHP,
[],
);
}

public function testImportByParentWithNamespaceName() : void
{
$fqcn = new FullyQualified('App\\Services\\UserService');
$alias = $this->generator->importByParent($fqcn);

self::assertSame('Services\\UserService', $alias);

$this->assertDumpFile(
<<<'PHP'
<?php

declare(strict_types=1);

use App\Services;

PHP,
[],
);
}

public function testImportByParentWithConflict() : void
{
$alias1 = $this->generator->importByParent('App\\Models\\User');
$alias2 = $this->generator->importByParent('App\\Entities\\User');

self::assertSame('Models\\User', $alias1);
self::assertSame('Entities\\User', $alias2);

$this->assertDumpFile(
<<<'PHP'
<?php

declare(strict_types=1);

use App\Entities;
use App\Models;

PHP,
[],
);
}

public function testImportByParentSameNamespace() : void
{
$this->generator = new CodeGenerator('App\\Models');

$alias = $this->generator->importByParent('App\\Models\\User');

self::assertSame('User', $alias);

$this->assertDumpFile(
<<<'PHP'
<?php

declare(strict_types=1);

namespace App\Models;

PHP,
[],
);
}

public function testImportByParentWithThreePartNamespace() : void
{
$alias = $this->generator->importByParent('App\\Services\\Database\\Connection');

self::assertSame('Database\\Connection', $alias);

$this->assertDumpFile(
<<<'PHP'
<?php

declare(strict_types=1);

use App\Services\Database;

PHP,
[],
);
}

public function testDumpAttribute() : void
{
self::assertSame(
Expand Down