From a6826d5fd03855adb04cab9cd6beac6a8b0bad05 Mon Sep 17 00:00:00 2001 From: tianfenghan Date: Fri, 16 Jan 2026 16:54:20 +0800 Subject: [PATCH] =?UTF-8?q?feat(compiler):=20=E6=B7=BB=E5=8A=A0PHP?= =?UTF-8?q?=E8=AF=AD=E6=B3=95=E9=94=99=E8=AF=AF=E5=A4=84=E7=90=86=E5=92=8C?= =?UTF-8?q?=E7=B1=BB=E5=B8=B8=E9=87=8F=E9=87=8D=E5=A4=8D=E5=AE=9A=E4=B9=89?= =?UTF-8?q?=E6=A3=80=E6=9F=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 在编译器中引入SyntaxError异常类用于处理PHP语法错误 - 修改预处理器捕获PHP解析错误并转换为SyntaxError异常 - 实现类常量重复定义的检测逻辑并抛出致命错误 - 添加多个测试用例验证类常量相关错误场景 - 更新编译器跳过包含语法错误的文件处理流程 --- bin/compiler.php | 3 +++ src/Php/Preprocessor.php | 7 ++++++- src/Php/SyntaxError.php | 8 ++++++++ src/Php/Translator.php | 6 +++++- tests/core/classes/constants_error_001.phpt | 18 ++++++++++++++++++ tests/core/classes/constants_error_002.phpt | 13 +++++++++++++ tests/core/classes/constants_error_005.phpt | 16 ++++++++++++++++ 7 files changed, 69 insertions(+), 2 deletions(-) create mode 100644 src/Php/SyntaxError.php create mode 100644 tests/core/classes/constants_error_001.phpt create mode 100644 tests/core/classes/constants_error_002.phpt create mode 100644 tests/core/classes/constants_error_005.phpt diff --git a/bin/compiler.php b/bin/compiler.php index 365062ae..d3248409 100755 --- a/bin/compiler.php +++ b/bin/compiler.php @@ -3,6 +3,7 @@ require __DIR__ . '/bootstrap.php'; use PhpAot\Php\FileScanner; +use PhpAot\Php\SyntaxError; use PhpAot\Php\Translator; use PhpAot\Php\Unsupported; @@ -41,6 +42,8 @@ foreach ($list as $k => $file) { echo " unsupported syntax: " . $e->getMessage() . "\n"; echo " skip: " . $file . "\n"; unset($list[$k]); + } catch (SyntaxError $e) { + unset($list[$k]); } } } diff --git a/src/Php/Preprocessor.php b/src/Php/Preprocessor.php index d5a31070..92ea303c 100644 --- a/src/Php/Preprocessor.php +++ b/src/Php/Preprocessor.php @@ -85,7 +85,12 @@ class Preprocessor extends CompilerBase $phpCode = $this->loadFile($file); $this->climate->info('prepare: ' . $this->file); - $ast = $this->parser->parse($phpCode); + try { + $ast = $this->parser->parse($phpCode); + } catch (\PhpParser\Error $e) { + $this->climate->red("Fatal error: {$e->getMessage()} in {$this->file}"); + throw new SyntaxError($e->getMessage(), $e->getCode()); + } $traverser = new NodeTraverser(); $traverser->addVisitor(new Visitor()); diff --git a/src/Php/SyntaxError.php b/src/Php/SyntaxError.php new file mode 100644 index 00000000..689a8cb6 --- /dev/null +++ b/src/Php/SyntaxError.php @@ -0,0 +1,8 @@ +flags; $type = $v->type ? $this->getTypeFromZendType($this->parseIdentifier($v->type)) : self::TYPE_VAR; foreach ($v->consts as $const) { - $constInfo = new ConstantDef($this->parseIdentifier($const->name), $flags, $type, $this->parseIdentifier($const->value)); + $constName = $this->parseIdentifier($const->name); + if (isset($this->classDef->constants[$constName])) { + $this->fatalError($const, 'Cannot redefine class constant ' . $this->class . '::' . $constName); + } + $constInfo = new ConstantDef($constName, $flags, $type, $this->parseIdentifier($const->value)); $this->classDef->constants[$constInfo->name] = $constInfo; } } diff --git a/tests/core/classes/constants_error_001.phpt b/tests/core/classes/constants_error_001.phpt new file mode 100644 index 00000000..13428675 --- /dev/null +++ b/tests/core/classes/constants_error_001.phpt @@ -0,0 +1,18 @@ +--TEST-- +Error case: duplicate class constant definition +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +Fatal error: Cannot redefine class constant myclass::myConst in %s on line 5 diff --git a/tests/core/classes/constants_error_002.phpt b/tests/core/classes/constants_error_002.phpt new file mode 100644 index 00000000..32aba740 --- /dev/null +++ b/tests/core/classes/constants_error_002.phpt @@ -0,0 +1,13 @@ +--TEST-- +Error case: class constant as an array +--FILE-- + +--EXPECT-- diff --git a/tests/core/classes/constants_error_005.phpt b/tests/core/classes/constants_error_005.phpt new file mode 100644 index 00000000..9c31e147 --- /dev/null +++ b/tests/core/classes/constants_error_005.phpt @@ -0,0 +1,16 @@ +--TEST-- +Error case: class constant as an encapsed containing a variable +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +Fatal error: Constant expression contains invalid operations in %s on line %d