fix(stub): 修复常量生成中的表达式类型检查问题

- 添加了对非标量字符串表达式的类型验证
- 修复了常量类型未实现时的错误消息显示
- 统一使用 String_ 类型检查替代完整命名空间
- 将 shell_exec 替换为 passthru 以获取编译返回状态
- 添加编译失败时的错误提示机制
pull/1/head
韩天峰 7 months ago
parent 57e1790639
commit c58a85baa2
  1. 16
      bin/gen_stub.php
  2. 6
      examples/const.php
  3. 5
      src/Php/Translator.php

@ -9,6 +9,7 @@ use PhpParser\Node;
use PhpParser\Node\AttributeGroup;
use PhpParser\Node\Expr;
use PhpParser\Node\Name;
use PhpParser\Node\Scalar\String_;
use PhpParser\Node\Stmt;
use PhpParser\Node\Stmt\Class_;
use PhpParser\Node\Stmt\Enum_;
@ -2410,7 +2411,12 @@ class EvaluatedValue
$expr = $prettyPrinter->prettyPrintExpr($this->expr);
// PHP single-quote to C double-quote string
if ($this->type->isString()) {
if (!($this->expr instanceof String_)) {
throw new Exception("Expression at line " . $this->expr->getStartLine() . " must be a scalar string");
}
$expr = preg_replace("/(^'|'$)/", '"', $expr);
} else {
$expr = $prettyPrinter->prettyPrintExpr($this->expr);
}
return $expr[0] == '"' ? $expr : preg_replace('(\bnull\b)', 'NULL', str_replace('\\', '', $expr));
}
@ -2784,7 +2790,7 @@ class ConstInfo extends VariableLike
return $code . "REGISTER_STRING_CONSTANT(\"$constName\", " . ($cExpr ?: '"' . addslashes($constValue) . '"') . ", $flags);\n";
}
throw new Exception("Unimplemented constant type");
throw new Exception("Unimplemented constant type: " . $value->type->name);
}
/** @param array<string, ConstInfo> $allConstInfos */
@ -2889,7 +2895,7 @@ class ConstInfo extends VariableLike
return "\tZEND_ASSERT(strcmp($cExpr, $cValue) == 0);\n";
}
throw new Exception("Unimplemented constant type");
throw new Exception("Unimplemented constant type: " . $value->type->name);
}
protected function getFlagsByPhpVersion(): VersionFlags
@ -3332,7 +3338,7 @@ class AttributeInfo {
foreach ($this->args as $i => $arg) {
$initValue = '';
if ($arg->value instanceof Node\Scalar\String_) {
if ($arg->value instanceof String_) {
$strVal = $arg->value->value;
[$strInit, $strUse, $strRelease] = StringBuilder::getString(
'unused',
@ -3353,7 +3359,7 @@ class AttributeInfo {
true,
"attribute_{$escapedAttributeName}_{$nameSuffix}_arg{$i}_str"
);
if ($arg->value instanceof Node\Scalar\String_) {
if ($arg->value instanceof String_) {
$declaredStrings[$arg->value->value] = "attribute_{$escapedAttributeName}_{$nameSuffix}_arg{$i}_str";
}
} else {
@ -4884,7 +4890,7 @@ function parseConstLike(
)
) {
$phpDocType = 'int';
} elseif ($const->value instanceof Node\Scalar\String_) {
} elseif ($const->value instanceof String_) {
$phpDocType = 'string';
} elseif ($const->value instanceof Expr\ConstFetch
&& $const->value->name instanceof Node\Name\FullyQualified

@ -5,12 +5,12 @@ const C_F = 1.1;
const C_S = "str";
const C_B = true;
const C_N = null;
const C_A = [1, 2, 3];
const C_O = new stdClass();
//const C_A = [1, 2, 3];
//const C_O = new stdClass();
const C_I2 = -C_I;
const C_F2 = C_F * 2;
const C_S2 = C_S . "hello";
const C_S2 = "hello";
function main()
{

@ -248,7 +248,10 @@ class Translator extends Preprocessor
$cmd = $this->cppCompiler . ' -c ' . $cppFile . ' -o ' . $objectFile;
$this->addCompilationOption($cmd, false);
$this->climate->comment($cmd);
shell_exec($cmd);
passthru($cmd, $ret);
if ($ret !== 0) {
$this->error('compile failed: ' . $cppFile);
}
}
public function build(array $objectFiles): void

Loading…
Cancel
Save