diff --git a/src/Php/Entity/ClassDef.php b/src/Php/Entity/ClassDef.php index dddab867..0203bc42 100644 --- a/src/Php/Entity/ClassDef.php +++ b/src/Php/Entity/ClassDef.php @@ -32,11 +32,13 @@ class ClassDef extends ClassLikeDef public bool $requireCtor = false; public bool $enum = false; public ?Trait_ $trait = null; + /** * FullMethodName -> NewMethodName * @var array */ public array $traitAliases = []; + /** * FullMethodName -> true * @var array diff --git a/src/Php/Preprocessor.php b/src/Php/Preprocessor.php index 27bc10dd..2b865e0a 100644 --- a/src/Php/Preprocessor.php +++ b/src/Php/Preprocessor.php @@ -611,29 +611,29 @@ class Preprocessor extends CompilerBase { foreach ($traitUse->adaptations as $adaptation) { if (!$adaptation->trait) { - $this->fatalError($traitUse, "Trait `use` cannot use `use` without `as`"); + $this->fatalError($traitUse, 'Trait `use` cannot use `use` without `as`'); } if ($adaptation instanceof Node\Stmt\TraitUseAdaptation\Alias) { $trait1 = $this->getNamespacedClassName($adaptation->trait); $methodName = $adaptation->method->toString(); - /** + /* * 例如: * use TraitA { TraitA::method as newMethod} * 这表示 TraitA::method() 会被重命名为 TraitA::newMethod() */ - $aliases[$this->getFullMethodName($trait1, $methodName)] = array( + $aliases[$this->getFullMethodName($trait1, $methodName)] = [ 'newName' => $adaptation->newName->toString(), 'newModifier' => $adaptation->newModifier ?: $adaptation->newModifier->toString(), - ); + ]; } if ($adaptation instanceof Node\Stmt\TraitUseAdaptation\Precedence) { $methodName = $adaptation->method->toString(); - /** + /* * 例如: * use TraitA { TraitA::method insteadof TraitB} * 这表示 TraitB::method() 将会被忽略,真正执行的是 TraitA::method() */ - foreach($adaptation->insteadof as $trait2) { + foreach ($adaptation->insteadof as $trait2) { $ignored[$this->getFullMethodName($trait2, $methodName)] = true; } } diff --git a/src/Php/Translator.php b/src/Php/Translator.php index 6f7bac93..9c1f9944 100644 --- a/src/Php/Translator.php +++ b/src/Php/Translator.php @@ -1316,15 +1316,15 @@ class Translator extends Preprocessor } $classDef->addMethod($methodDef); - $traitMethodNativeName = self::PREFIX . $this->getNativeName($traitMethodName, $traitDef->namespace, $traitDef->name); - $classMethodNativeName = self::PREFIX . $this->getNativeName($classMethodName, $classDef->namespace, $classDef->name); + $traitMethodNativeName = $this->getNativeName($traitMethodName, $traitDef->namespace, $traitDef->name); + $classMethodNativeName = $this->getNativeName($classMethodName, $classDef->namespace, $classDef->name); $argList = ['this_']; foreach ($methodDef->functionDef->argInfoList as $argInfo) { $argList[] = $argInfo->name; } $argv = implode(', ', $argList); - $code = $methodDef->getReturnType() . ' ' . $classMethodNativeName . '('; + $code = $methodDef->getReturnType() . ' ' . self::PREFIX . $classMethodNativeName . '('; if ($this->class) { $code .= self::TYPE_OBJECT . ' &this_'; if ($methodDef->functionDef->params) { @@ -1332,10 +1332,12 @@ class Translator extends Preprocessor } } + $this->addFunction($classMethodNativeName, $methodDef->functionDef); + $code .= $methodDef->functionDef->params . ')'; $code .= '{' . PHP_EOL; $this->indentLevel++; - $methodCall = $traitMethodNativeName . '(' . $argv . ')'; + $methodCall = self::PREFIX . $traitMethodNativeName . '(' . $argv . ')'; if ($methodDef->getReturnType() !== self::TYPE_VOID) { $methodCall = 'return ' . $methodCall; } diff --git a/tests/aot/trait/006.phpt b/tests/aot/trait/006.phpt new file mode 100644 index 00000000..d2fa923b --- /dev/null +++ b/tests/aot/trait/006.phpt @@ -0,0 +1,24 @@ +--TEST-- +Method conflict in traits +--FILE-- + +--EXPECT-- +Hello 2 \ No newline at end of file