fix(stub): 修复 self/parent/static 类常量引用解析失败的问题

pull/37/head
Yurun 1 month ago
parent 2287695b44
commit edcbcf7cff
  1. 29
      src/gen_stub.php
  2. 41
      tests/compiler/self-class/003.phpt

@ -2368,20 +2368,23 @@ class EvaluatedValue
return ltrim($className, '\\');
}
$class = getClassConstFetchClassName($expr);
if ($class === 'self') {
$constName = ClassInfo::$currentClass . "::" . $constName;
if (isset($allConstInfos[$constName])) {
return $allConstInfos[$constName]->getValue($allConstInfos)->value;
} else {
return normalizeConstExprValue(
getTranslator()->getClassConstValue($expr, ClassInfo::$currentClass, $constName)
);
}
} else {
return normalizeConstExprValue(
getTranslator()->getClassConstValue($expr, $class, $constName, ClassInfo::$currentClass)
);
// Resolve the special class-name keywords to concrete classes.
// Previously `self` was passed as both the class and a
// `ClassName::` name prefix (yielding `B::B::A`), and `parent` /
// `static` were passed verbatim (yielding `parent::A`), so the
// constant lookup always failed.
if (strcasecmp($class, 'self') === 0 || strcasecmp($class, 'static') === 0) {
$class = ClassInfo::$currentClass;
} elseif (strcasecmp($class, 'parent') === 0) {
$class = getTranslator()->getParentClass(ClassInfo::$currentClass);
}
$fqcnName = ltrim($class, '\\') . "::" . $constName;
if (isset($allConstInfos[$fqcnName])) {
return $allConstInfos[$fqcnName]->getValue($allConstInfos)->value;
}
return normalizeConstExprValue(
getTranslator()->getClassConstValue($expr, $class, $constName, ClassInfo::$currentClass)
);
} else {
$constName = $expr->name->__toString();
if (strtolower($constName) === "unknown") {

@ -0,0 +1,41 @@
--TEST--
Class constant referenced via self:: / parent:: / ClassName:: as a property default value
--FILE--
<?php
declare(strict_types=1);
class A
{
const A = 1;
const B = 2;
}
class B extends A
{
// self:: referencing an inherited constant.
// Bug: self::A was incorrectly resolved as B::B::A and the lookup failed.
public $a = self::A;
// self:: referencing a constant declared in the same class.
const LOCAL = 10;
public $local = self::LOCAL;
// parent:: referencing a parent constant.
public $b = parent::A;
// explicit class name.
public $c = A::B;
}
function main()
{
$test = new B;
var_dump($test->a);
var_dump($test->local);
var_dump($test->b);
var_dump($test->c);
}
?>
--EXPECT--
int(1)
int(10)
int(1)
int(2)
Loading…
Cancel
Save