From c58a85baa212df88ccf969a9bb7c4d4dc52edddd Mon Sep 17 00:00:00 2001 From: tianfenghan Date: Sat, 31 Jan 2026 12:05:44 +0800 Subject: [PATCH] =?UTF-8?q?fix(stub):=20=E4=BF=AE=E5=A4=8D=E5=B8=B8?= =?UTF-8?q?=E9=87=8F=E7=94=9F=E6=88=90=E4=B8=AD=E7=9A=84=E8=A1=A8=E8=BE=BE?= =?UTF-8?q?=E5=BC=8F=E7=B1=BB=E5=9E=8B=E6=A3=80=E6=9F=A5=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 添加了对非标量字符串表达式的类型验证 - 修复了常量类型未实现时的错误消息显示 - 统一使用 String_ 类型检查替代完整命名空间 - 将 shell_exec 替换为 passthru 以获取编译返回状态 - 添加编译失败时的错误提示机制 --- bin/gen_stub.php | 16 +++++++++++----- examples/const.php | 6 +++--- src/Php/Translator.php | 5 ++++- 3 files changed, 18 insertions(+), 9 deletions(-) diff --git a/bin/gen_stub.php b/bin/gen_stub.php index 312f7d27..7ddaeae7 100755 --- a/bin/gen_stub.php +++ b/bin/gen_stub.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 $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 diff --git a/examples/const.php b/examples/const.php index 948a41a8..0e3d4a1b 100644 --- a/examples/const.php +++ b/examples/const.php @@ -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() { diff --git a/src/Php/Translator.php b/src/Php/Translator.php index e2a64956..22ba5b75 100644 --- a/src/Php/Translator.php +++ b/src/Php/Translator.php @@ -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