From e7f2760d936b283d8e0612e09522753cbb74d0e5 Mon Sep 17 00:00:00 2001 From: tianfenghan Date: Mon, 23 Mar 2026 14:30:43 +0800 Subject: [PATCH] =?UTF-8?q?feat(compiler):=20=E6=94=AF=E6=8C=81=E7=B1=BB?= =?UTF-8?q?=E5=B8=B8=E9=87=8F=E7=BB=A7=E6=89=BF=E5=92=8C=E8=AE=BF=E9=97=AE?= =?UTF-8?q?=E6=8E=A7=E5=88=B6=E6=A3=80=E6=9F=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 添加 ConstantDef 实体类用于表示类常量定义 - 实现 getNativeClassConst 方法支持类常量子类继承查找 - 重构 checkAccessible 方法支持常量访问控制检查 - 集成类常量访问到编译器表达式处理流程 - 添加类常量测试用例验证继承功能 --- src/Php/CompilerBase.php | 50 +++++++++++++++++++++++++++------- tests/aot/class-const-002.phpt | 36 ++++++++++++++++++++++++ 2 files changed, 76 insertions(+), 10 deletions(-) create mode 100644 tests/aot/class-const-002.phpt diff --git a/src/Php/CompilerBase.php b/src/Php/CompilerBase.php index 32ade24b..cd77c8b8 100644 --- a/src/Php/CompilerBase.php +++ b/src/Php/CompilerBase.php @@ -11,6 +11,7 @@ namespace PhpAot\Php; use League\CLImate\CLImate; use PhpAot\Php\Context\FunctionContext; use PhpAot\Php\Entity\ClassDef; +use PhpAot\Php\Entity\ConstantDef; use PhpAot\Php\Entity\FunctionDef; use PhpAot\Php\Entity\InterfaceDef; use PhpAot\Php\Entity\MethodDef; @@ -1662,6 +1663,39 @@ class CompilerBase extends \PhpAot\Core\Translator return $this->getNativeName($method, $classDef->namespace, $classDef->name); } + protected function getNativeClassConst(NodeAbstract $expr, string $class, string $const): string|false + { + if (!$this->hasNativeClass($class)) { + return false; + } + + $classDef = $this->getClassDef($class); + $constDef = null; + // 递归查找,若子类中未定义方法,则尝试查找父类是否存在此方法 + while ($classDef) { + if (!$classDef->hasConstant($const)) { + if (!$classDef->extends) { + return false; + } + if (!$this->hasNativeClass($classDef->extends)) { + return false; + } + $classDef = $this->getClassDef($classDef->extends); + } else { + $constDef = $classDef->getConstant($const); + break; + } + } + if (!$this->checkAccessible($classDef, $constDef)) { + $this->fatalError($expr, 'Constant `' . $classDef->getNamespacedName() . '::' . $const . '` is not accessible'); + } + if ($constDef->type === self::TYPE_ARRAY) { + return self::PREFIX . $this->getNativeName($constDef->name, $classDef->namespace, $classDef->name); + } else { + return $constDef->value; + } + } + protected function getClassDef(string $name): ClassDef { return $this->classes[$this->escapeClass($name)]; @@ -3882,18 +3916,14 @@ class CompilerBase extends \PhpAot\Core\Translator if (($self or $this->isNameExpr($expr->class)) and $this->isIdExpr($expr->name)) { if ($this->hasNativeClass($class)) { $classDef = $this->getClassDef($class); - if ($classDef->hasConstant($const)) { - $constInfo = $classDef->getConstant($const); - if ($constInfo->type === self::TYPE_ARRAY) { - return self::PREFIX . $this->getNativeName($constInfo->name, $classDef->namespace, $classDef->name); - } else { - return $constInfo->value; - } - } if ($classDef->enum) { $ce = $this->getClassEntryPtr($class); return 'php::getEnumCase(' . $ce . ', ' . $this->getLiteralString($const) . ')'; } + $nativeConst = $this->getNativeClassConst($expr, $class, $const); + if ($nativeConst) { + return $nativeConst; + } } $ce = $this->getClassEntryPtr($class); return 'php::constant(' . $ce . ', ' . $this->getLiteralString($const) . ')'; @@ -4141,7 +4171,7 @@ class CompilerBase extends \PhpAot\Core\Translator } } - protected function checkAccessible(ClassDef $classDef, MethodDef $methodDef): bool + protected function checkAccessible(ClassDef $classDef, MethodDef|ConstantDef $def): bool { // 在当前类中,允许调用所有方法 if ($classDef->namespace === $this->namespace and $classDef->name == $this->class) { @@ -4149,7 +4179,7 @@ class CompilerBase extends \PhpAot\Core\Translator } // 类外部调用,只允许调用 public 方法 - return $methodDef->flags & Modifiers::PUBLIC; + return $def->flags & Modifiers::PUBLIC; } protected function findNativeMethod(CallLike $expr, string $object, string $method): string|false diff --git a/tests/aot/class-const-002.phpt b/tests/aot/class-const-002.phpt new file mode 100644 index 00000000..802f8db5 --- /dev/null +++ b/tests/aot/class-const-002.phpt @@ -0,0 +1,36 @@ +--TEST-- +class const 002 +--FILE-- + +--EXPECT-- +array(4) { + [0]=> + string(3) "php" + [1]=> + string(4) "java" + [2]=> + string(3) "c++" + [3]=> + string(6) "golang" +} +string(3) "c++" \ No newline at end of file