feat(php): 支持trait方法别名和访问修饰符转换

- 修改traitAliases数据结构以存储方法别名和新修饰符信息
- 实现trait方法别名时保留原始访问修饰符功能
- 添加对trait方法别名中newModifier属性的支持
- 更新翻译器中trait方法别名处理逻辑
- 扩展测试用例验证trait方法冲突解决机制
pull/1/head
韩天峰 4 months ago
parent 57220d63b9
commit aea979fae1
  1. 2
      src/Php/Entity/ClassDef.php
  2. 8
      src/Php/Preprocessor.php
  3. 14
      src/Php/Translator.php
  4. 35
      tests/aot/trait/005.phpt

@ -34,7 +34,7 @@ class ClassDef extends ClassLikeDef
public ?Trait_ $trait = null;
/**
* FullMethodName -> NewMethodName
* @var array<string, string>
* @var array<string, array>
*/
public array $traitAliases = [];
/**

@ -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();

@ -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])) {

@ -0,0 +1,35 @@
--TEST--
Method conflict in traits
--FILE--
<?php
trait THello1
{
private function hello()
{
echo 'Hello 2', PHP_EOL;
}
}
class TraitsTest
{
use THello1 {
THello1::hello as public hello2;
}
public function hello()
{
echo 'Hello 1' , PHP_EOL;
}
}
function main()
{
$o = new TraitsTest;
$o->hello2();
$o->hello();
}
?>
--EXPECT--
Hello 2
Hello 1
Loading…
Cancel
Save