fix(aot): 修复属性数组参数支持并调整编译器方法可见性

- 将 CompilerBase.php 中的 parseAssignOpBitwiseOr 方法从 private 改为 protected
- 将 CompilerBase.php 中的 error 方法从 protected 改为 public
- 在 gen_stub.php 中添加对属性数组参数的错误检查和提示
- 修复 Translator.php 中构建目录文件名使用 targetName 而非 getModuleName()
pull/1/head
韩天峰 4 months ago
parent 588cd85ca4
commit aa51b09fa9
  1. 4
      src/Php/CompilerBase.php
  2. 2
      src/Php/Translator.php
  3. 3
      src/gen_stub.php
  4. 72
      tests/aot/attribute/001.phpt
  5. 29
      tests/aot/attribute/002.phpt
  6. 34
      tests/aot/attribute/003.phpt

@ -2672,7 +2672,7 @@ class CompilerBase extends \PhpAot\Core\Translator
return $this->parseAssignOp($expr, '&=');
}
private function parseAssignOpBitwiseOr(Expr\AssignOp\BitwiseOr $expr): string
protected function parseAssignOpBitwiseOr(Expr\AssignOp\BitwiseOr $expr): string
{
return $this->parseAssignOp($expr, '|=');
}
@ -2682,7 +2682,7 @@ class CompilerBase extends \PhpAot\Core\Translator
return $this->parseAssignOp($expr, '**=');
}
protected function error(string $msg): never
public function error(string $msg): never
{
if ($this->forTest) {
throw new TestError($msg);

@ -426,7 +426,7 @@ class Translator extends Preprocessor
exit(1);
}
}
$file = $this->getBuildDir() . '/extension-' . $this->getModuleName() . '.cc';
$file = $this->getBuildDir() . '/extension-' . $this->targetName . '.cc';
$this->localHeaders = $this->argInfoHeaderFiles;
$this->genClassCeList();
$this->indentLevel++;

@ -3397,6 +3397,9 @@ class AttributeInfo {
}
}
if ($initValue === '') {
if ($arg->value instanceof Expr\Array_ && count($arg->value->items) > 0) {
getTranslator()->error("Array arguments to attributes are not supported");
}
$value = EvaluatedValue::createFromExpression($arg->value, null, null, $allConstInfos);
$code .= $value->initializeZval(
"attribute_{$escapedAttributeName}_{$nameSuffix}->args[$i].value",

@ -0,0 +1,72 @@
--TEST--
Attribute: 001
--FILE--
<?php
#[Attribute]
class MyAttribute
{
const VALUE = 'value';
private $value;
public function __construct($value = null)
{
$this->value = $value;
}
}
#[MyAttribute]
#[MyAttribute(1234)]
#[MyAttribute(value: 1234)]
#[MyAttribute(MyAttribute::VALUE)]
#[MyAttribute([])]
#[MyAttribute(100 + 200)]
class Thing
{
}
#[MyAttribute(1234), MyAttribute(5678)]
class AnotherThing
{
}
function main() {
$reflection = (new ReflectionClass(Thing::class));
$attributes = $reflection->getAttributes();
foreach ($attributes as $attribute) {
var_dump($attribute->getName());
var_dump($attribute->getArguments());
}
}
?>
--EXPECT--
string(11) "MyAttribute"
array(0) {
}
string(11) "MyAttribute"
array(1) {
[0]=>
int(1234)
}
string(11) "MyAttribute"
array(1) {
["value"]=>
int(1234)
}
string(11) "MyAttribute"
array(1) {
[0]=>
string(5) "value"
}
string(11) "MyAttribute"
array(1) {
[0]=>
array(0) {
}
}
string(11) "MyAttribute"
array(1) {
[0]=>
int(300)
}

@ -0,0 +1,29 @@
--TEST--
Attribute: 002
--FILE--
<?php
#[MyAttribute]
class Thing
{
}
function main() {
$o = new Thing;
var_dump($o);
$reflection = new ReflectionClass(Thing::class);
$attributes = $reflection->getAttributes(MyAttribute::class);
var_dump($attributes);
}
?>
--EXPECT--
object(Thing)#1 (0) {
}
array(1) {
[0]=>
object(ReflectionAttribute)#3 (1) {
["name"]=>
string(11) "MyAttribute"
}
}

@ -0,0 +1,34 @@
--TEST--
Attribute: 003
--SKIPIF--
<?php die("skip"); ?>
--FILE--
<?php
#[MyAttribute([1, 2, 3])]
class Thing
{
}
function main() {
$o = new Thing;
var_dump($o);
$reflection = new ReflectionClass(Thing::class);
$attributes = $reflection->getAttributes(MyAttribute::class);
foreach ($attributes as $attribute) {
var_dump($attribute->getName());
var_dump($attribute->getArguments());
}
}
?>
--EXPECT--
object(Thing)#1 (0) {
}
array(1) {
[0]=>
object(ReflectionAttribute)#3 (1) {
["name"]=>
string(11) "MyAttribute"
}
}
Loading…
Cancel
Save