fix(trait): preserve import context for property defaults (#69)

master
Echo 15 hours ago committed by GitHub
parent 26bfbdda4e
commit 3b66b488a3
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 22
      phpunit/code/trait-property-import-context/consumer.php
  2. 13
      phpunit/code/trait-property-import-context/levels.php
  3. 10
      phpunit/code/trait-property-import-context/trait.php
  4. 25
      phpunit/src/TraitPropertyImportContextTest.php
  5. 12
      src/Translator.php
  6. 61
      tests/compiler/trait/trait-property-import-context.phpt

@ -0,0 +1,22 @@
<?php
namespace TraitPropertyImports;
use TraitPropertyImports\Support\OtherLevel as ImportedLevel;
trait NestedLevels
{
use HasLevels;
}
class DirectConsumer
{
use HasLevels;
public array $ownLevels = ['debug' => ImportedLevel::Debug];
}
class NestedConsumer
{
use NestedLevels;
}

@ -0,0 +1,13 @@
<?php
namespace TraitPropertyImports\Support;
enum Level: int
{
case Debug = 100;
}
enum OtherLevel: int
{
case Debug = 200;
}

@ -0,0 +1,10 @@
<?php
namespace TraitPropertyImports;
use TraitPropertyImports\Support\Level as ImportedLevel;
trait HasLevels
{
public array $levels = ['debug' => ImportedLevel::Debug];
}

@ -0,0 +1,25 @@
<?php
use TypePhp\CompilerTest;
class TraitPropertyImportContextTest extends BaseTest
{
public function testPropertyDefaultsKeepTheirDeclaringFileImports(): void
{
global $translator;
$compiler = CompilerTest::create(TYPEPHP_ROOT_PATH);
$translator = $compiler;
$directory = TYPEPHP_ROOT_PATH . '/phpunit/code/trait-property-import-context/';
$files = [$directory . 'levels.php', $directory . 'trait.php', $directory . 'consumer.php'];
$compiler->addFiles($files);
foreach ($files as $file) {
$compiler->prepareFile($file);
}
foreach ($files as $file) {
$compiler->convertFile($file);
}
$this->addToAssertionCount(1);
}
}

@ -3301,6 +3301,9 @@ CODE;
}
}
if ($traitStmt instanceof Node\Stmt\Property) {
if ($traitStmt->getAttribute(self::TRAIT_ORIGIN_ATTRIBUTE) === null) {
$traitStmt->setAttribute(self::TRAIT_ORIGIN_ATTRIBUTE, $traitFullName);
}
foreach ($traitStmt->props as $k2 => $prop) {
$propName = strtolower($prop->name->toString());
if (isset($properties[$propName])) {
@ -6160,7 +6163,14 @@ CODE;
} elseif ($stmt instanceof Node\Stmt\Property) {
foreach ($stmt->props as $prop) {
if (!$this->classDef->hasProperty($prop->name->toString())) {
$this->parseClassPropertyDef($stmt);
$origin = $stmt->getAttribute(self::TRAIT_ORIGIN_ATTRIBUTE);
if (is_string($origin)) {
$this->withTraitNameContext($origin, function () use ($stmt): void {
$this->parseClassPropertyDef($stmt);
});
} else {
$this->parseClassPropertyDef($stmt);
}
break;
}
}

@ -0,0 +1,61 @@
--TEST--
Trait property defaults retain the original imports through nested composition
--FILE--
<?php
namespace TraitPropertyDefaults\Support {
enum Level: int {
case Debug = 100;
}
enum OtherLevel: int {
case Debug = 200;
}
}
namespace TraitPropertyDefaults\Template {
use TraitPropertyDefaults\Support\Level;
trait HasLevels {
public array $levels = ['debug' => Level::Debug];
}
}
namespace TraitPropertyDefaults\Wrapper {
use TraitPropertyDefaults\Support\OtherLevel as Level;
use TraitPropertyDefaults\Template\HasLevels;
trait NestedLevels {
use HasLevels;
}
}
namespace TraitPropertyDefaults\Consumer {
use TraitPropertyDefaults\Support\OtherLevel as Level;
use TraitPropertyDefaults\Template\HasLevels;
use TraitPropertyDefaults\Wrapper\NestedLevels;
class DirectConsumer {
use HasLevels;
public array $ownLevels = ['debug' => Level::Debug];
}
class NestedConsumer {
use NestedLevels;
}
}
namespace {
function main(): void {
$direct = new TraitPropertyDefaults\Consumer\DirectConsumer();
$nested = new TraitPropertyDefaults\Consumer\NestedConsumer();
var_dump($direct->levels['debug']->value);
var_dump($nested->levels['debug']->value);
var_dump($direct->ownLevels['debug']->value);
}
}
?>
--EXPECT--
int(100)
int(100)
int(200)
Loading…
Cancel
Save