diff --git a/src/Php/Entity/ClassDef.php b/src/Php/Entity/ClassDef.php index 409f16ca..dddab867 100644 --- a/src/Php/Entity/ClassDef.php +++ b/src/Php/Entity/ClassDef.php @@ -34,7 +34,7 @@ class ClassDef extends ClassLikeDef public ?Trait_ $trait = null; /** * FullMethodName -> NewMethodName - * @var array + * @var array */ public array $traitAliases = []; /** diff --git a/src/Php/Preprocessor.php b/src/Php/Preprocessor.php index 08b74ae2..27bc10dd 100644 --- a/src/Php/Preprocessor.php +++ b/src/Php/Preprocessor.php @@ -616,15 +616,15 @@ class Preprocessor extends CompilerBase if ($adaptation instanceof Node\Stmt\TraitUseAdaptation\Alias) { $trait1 = $this->getNamespacedClassName($adaptation->trait); $methodName = $adaptation->method->toString(); - if ($adaptation->newModifier) { - $this->fatalError($traitUse, "Trait `{$trait1}` cannot use `newModifier`"); - } /** * 例如: * use TraitA { TraitA::method as newMethod} * 这表示 TraitA::method() 会被重命名为 TraitA::newMethod() */ - $aliases[$this->getFullMethodName($trait1, $methodName)] = $adaptation->newName->toString(); + $aliases[$this->getFullMethodName($trait1, $methodName)] = array( + 'newName' => $adaptation->newName->toString(), + 'newModifier' => $adaptation->newModifier ?: $adaptation->newModifier->toString(), + ); } if ($adaptation instanceof Node\Stmt\TraitUseAdaptation\Precedence) { $methodName = $adaptation->method->toString(); diff --git a/src/Php/Translator.php b/src/Php/Translator.php index 4f58b29f..6f7bac93 100644 --- a/src/Php/Translator.php +++ b/src/Php/Translator.php @@ -972,8 +972,11 @@ class Translator extends Preprocessor $fullMethodName = $this->getFullMethodName($traitFullName, $methodName); if (isset($classDef->traitAliases[$fullMethodName])) { $alias = $classDef->traitAliases[$fullMethodName]; - $traitStmt->name = new Node\Identifier($alias); - $methodName = $alias; + $methodName = $alias['newName']; + $traitStmt->name = new Node\Identifier($methodName); + if ($alias['newModifier']) { + $traitStmt->flags = $alias['newModifier']; + } } if (isset($classDef->traitIgnored[$fullMethodName])) { unset($traitStmts[$k1]); @@ -1296,9 +1299,12 @@ class Translator extends Preprocessor $fullMethodName = $this->getFullMethodName($traitFullName, $traitMethodName); // Trait 设置了别名 if (isset($classDef->traitAliases[$fullMethodName])) { - $classMethodName = $classDef->traitAliases[$fullMethodName]; + $alias = $classDef->traitAliases[$fullMethodName]; $methodDef = clone $methodDef; - $methodDef->name = $classMethodName; + $classMethodName = $methodDef->name = $alias['newName']; + if ($alias['newModifier']) { + $methodDef->flags = $this->parseModifiers($alias['newModifier']); + } } // 设置了 insteadof 选项,此 Trait 的方法将不会被使用 if (isset($classDef->traitIgnored[$fullMethodName])) { diff --git a/tests/aot/trait/005.phpt b/tests/aot/trait/005.phpt new file mode 100644 index 00000000..7ac4844a --- /dev/null +++ b/tests/aot/trait/005.phpt @@ -0,0 +1,35 @@ +--TEST-- +Method conflict in traits +--FILE-- +hello2(); + $o->hello(); +} + +?> +--EXPECT-- +Hello 2 +Hello 1 \ No newline at end of file