From ec98d1045dc0fe99941350f261ee48c99da39113 Mon Sep 17 00:00:00 2001 From: tianfenghan Date: Fri, 17 Apr 2026 14:45:50 +0800 Subject: [PATCH] =?UTF-8?q?fix(php):=20=E4=BF=AE=E5=A4=8D=E5=BC=82?= =?UTF-8?q?=E5=B8=B8=E5=A4=84=E7=90=86=E5=92=8C=E7=BC=96=E8=AF=91=E5=99=A8?= =?UTF-8?q?=E9=80=BB=E8=BE=91=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 添加了 try-catch 异常处理的测试用例 - 实现了 isFullNameExpr 方法用于检查完全限定名称表达式 - 修复了编译器中的 break 语句缺失问题 - 重命名了 parseGlobal 方法参数以避免变量冲突 - 优化了 catch 类型检查逻辑,支持类名实例化检查 - 添加了 C++ 关键字到保留字常量列表 - 完善了项目配置文件 project.yml - 添加了 instanceOf 符号方法 - 修复了多个 switch 语句中的 break 缺失问题 --- project.yml | 12 +++++++++++ src/Php/AstNodeType.php | 5 +++++ src/Php/CompilerBase.php | 21 ++++++++++++++----- src/Php/Constants.php | 5 +++++ src/Php/Preprocessor.php | 6 ++++-- src/Php/Symbol.php | 5 +++++ src/Php/Translator.php | 3 +++ .../{try-catch.phpt => exception/001.phpt} | 0 .../{try-catch-2.phpt => exception/002.phpt} | 0 tests/aot/exception/003.phpt | 21 +++++++++++++++++++ 10 files changed, 71 insertions(+), 7 deletions(-) create mode 100644 project.yml rename tests/aot/{try-catch.phpt => exception/001.phpt} (100%) rename tests/aot/{try-catch-2.phpt => exception/002.phpt} (100%) create mode 100644 tests/aot/exception/003.phpt diff --git a/project.yml b/project.yml new file mode 100644 index 00000000..aba23544 --- /dev/null +++ b/project.yml @@ -0,0 +1,12 @@ +name: swoole-compiler +type: ext +version: 0.0.1 +cxxflags: | + -std=c++14 + -Wall +sources: + - ./src/Php + - ./src/Core + - ./src/functions.php + - ./src/gen_stub.php + - ./vendor/nikic/php-parser/lib/PhpParser/NodeVisitorAbstract.php diff --git a/src/Php/AstNodeType.php b/src/Php/AstNodeType.php index e77de8ed..38d966e7 100644 --- a/src/Php/AstNodeType.php +++ b/src/Php/AstNodeType.php @@ -55,6 +55,11 @@ trait AstNodeType return $expr instanceof Node\Name; } + protected function isFullNameExpr(NodeAbstract $expr): bool + { + return $expr instanceof Node\Name\FullyQualified; + } + protected function isNamedMethod(NodeAbstract $expr): bool { return $this->isIdExpr($expr); diff --git a/src/Php/CompilerBase.php b/src/Php/CompilerBase.php index 0a2aa8f2..706a496f 100644 --- a/src/Php/CompilerBase.php +++ b/src/Php/CompilerBase.php @@ -515,9 +515,10 @@ class CompilerBase extends \PhpAot\Core\Translator case 'Expr_Yield': case 'Expr_YieldFrom': $this->fatalError($expr, 'The `' . $type . '` is not supported'); - // no break + break; default: abort($expr); + break; } } @@ -926,6 +927,7 @@ class CompilerBase extends \PhpAot\Core\Translator return $expr->hasAttribute('noLiteralString') ? $this->genCharPtr($expr->value) : $this->getLiteralString($expr->value); default: abort($expr); + break; } } @@ -1135,9 +1137,10 @@ class CompilerBase extends \PhpAot\Core\Translator break; case 'Stmt_Class': $this->fatalError($v, 'Cannot declare class in function'); - // no break + break; default: abort($v); + break; } $lines = array_merge($lines, $this->context->beforeStmtLines); $this->context->beforeStmtLines = []; @@ -3224,9 +3227,9 @@ class CompilerBase extends \PhpAot\Core\Translator return '"' . $this->escapeString($expr->value) . '"'; } - protected function parseGlobal(Node\Stmt\Global_ $v): string + protected function parseGlobal(Node\Stmt\Global_ $expr): string { - foreach ($v->vars as $v) { + foreach ($expr->vars as $v) { $name = $this->parseVariable($v); if (!$this->hasGlobalVar($name)) { $this->addGlobalVar($name, self::TYPE_VAR); @@ -3433,6 +3436,7 @@ class CompilerBase extends \PhpAot\Core\Translator return '"' . $this->escapeString($class) . '::' . $this->escapeString($this->method) . '"'; default: abort($expr); + break; } } @@ -3700,6 +3704,7 @@ class CompilerBase extends \PhpAot\Core\Translator break; default: $this->fatalError($expr, 'Invalid include type'); + break; } return 'php::include(' . $this->parseIdentifier($expr->expr) . ', ' . $type . ')'; @@ -4356,7 +4361,13 @@ class CompilerBase extends \PhpAot\Core\Translator $code .= $this->getIndent() . 'if (' . $var . ' && '; foreach ($types as $type) { - $code .= 'php::instanceOf(' . $var . ', "' . $this->parseIdentifier($type) . '")'; + if ($this->isNameExpr($type) or $this->isFullNameExpr($type)) { + $class = $this->getNamespacedClassName($this->parseIdentifier($type)); + $ce = $this->getClassEntryPtr($class); + $code .= Symbol::instanceOf() . '(' . $var . ', ' . $ce . ')'; + } else { + $this->fatalError($type, 'Unsupported catch type'); + } } $code .= ') {' . PHP_EOL; diff --git a/src/Php/Constants.php b/src/Php/Constants.php index b028dcb5..4a83d0ab 100644 --- a/src/Php/Constants.php +++ b/src/Php/Constants.php @@ -33,6 +33,11 @@ class Constants 'if', 'bool', 'int', + 'short', + 'long', + 'unsigned', + 'void', + 'signed', 'double', 'float', 'false', diff --git a/src/Php/Preprocessor.php b/src/Php/Preprocessor.php index 90f7a111..eb3672e3 100644 --- a/src/Php/Preprocessor.php +++ b/src/Php/Preprocessor.php @@ -143,9 +143,10 @@ class Preprocessor extends CompilerBase break; case 'Stmt_Expression': $this->foundStrayCode($v); - // no break + break; default: $this->fatalError($v, 'Unsupported statement: ' . $type); + break; } } } @@ -451,9 +452,10 @@ class Preprocessor extends CompilerBase break; case 'Stmt_Expression': $this->foundStrayCode($v); - // no break + break; default: abort($v); + break; } } diff --git a/src/Php/Symbol.php b/src/Php/Symbol.php index d23c03d7..d2ddb2e9 100644 --- a/src/Php/Symbol.php +++ b/src/Php/Symbol.php @@ -20,6 +20,11 @@ class Symbol return 'php::setStaticProperty'; } + public static function instanceOf(): string + { + return 'php::instanceOf'; + } + public static function getCalledCe(): string { return CompilerBase::PREFIX . 'get_called_ce(this_)'; diff --git a/src/Php/Translator.php b/src/Php/Translator.php index c015f5c7..349bea83 100644 --- a/src/Php/Translator.php +++ b/src/Php/Translator.php @@ -857,6 +857,7 @@ class Translator extends Preprocessor break; default: abort($v); + break; } } @@ -988,6 +989,7 @@ class Translator extends Preprocessor break; default: abort($v2); + break; } } $code .= $ns_end; @@ -1162,6 +1164,7 @@ class Translator extends Preprocessor break; default: abort($v); + break; } } $code = $this->genNativeMethod($methodCodes); diff --git a/tests/aot/try-catch.phpt b/tests/aot/exception/001.phpt similarity index 100% rename from tests/aot/try-catch.phpt rename to tests/aot/exception/001.phpt diff --git a/tests/aot/try-catch-2.phpt b/tests/aot/exception/002.phpt similarity index 100% rename from tests/aot/try-catch-2.phpt rename to tests/aot/exception/002.phpt diff --git a/tests/aot/exception/003.phpt b/tests/aot/exception/003.phpt new file mode 100644 index 00000000..dc8d72c5 --- /dev/null +++ b/tests/aot/exception/003.phpt @@ -0,0 +1,21 @@ +--TEST-- +try catch 2 +--FILE-- +getMessage()); + } +} +} +?> +--EXPECT-- +string(10) "test error"