From 76c110423445ca7bebf15b728c8e40fccfd41393 Mon Sep 17 00:00:00 2001 From: tianfenghan Date: Tue, 31 Mar 2026 19:08:16 +0800 Subject: [PATCH] =?UTF-8?q?feat(compiler):=20=E6=B7=BB=E5=8A=A0=E6=B5=8B?= =?UTF-8?q?=E8=AF=95=E6=A8=A1=E5=BC=8F=E5=92=8C=E9=9D=99=E6=80=81=E5=8F=98?= =?UTF-8?q?=E9=87=8F=E9=87=8D=E5=A4=8D=E6=A3=80=E6=B5=8B=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 引入 CompilerTest 类用于测试模式运行 - 在 CompilerBase 中添加 forTest 标志和 TestError 异常 - 实现静态变量重复定义的检测和报错功能 - 添加 phpunit 配置文件和引导文件 - 创建重复静态变量的测试用例 - 添加基本静态变量功能的测试文件 - 修改 Translator 的 addFiles 方法支持文件列表添加 - convert 方法中添加文件路径解析功能 --- phpunit.xml | 8 +++ phpunit/bootstrap.php | 9 +++ phpunit/code/duplicate.php | 6 ++ phpunit/src/ErrorTest.php | 23 +++++++ src/Php/CompilerBase.php | 15 ++++- src/Php/CompilerTest.php | 23 +++++++ src/Php/Exception/TestError.php | 8 +++ src/Php/Translator.php | 6 ++ tests/core/lang/static_basic_001.phpt | 87 +++++++++++++++++++++++++++ 9 files changed, 182 insertions(+), 3 deletions(-) create mode 100644 phpunit.xml create mode 100644 phpunit/bootstrap.php create mode 100644 phpunit/code/duplicate.php create mode 100644 phpunit/src/ErrorTest.php create mode 100644 src/Php/CompilerTest.php create mode 100644 src/Php/Exception/TestError.php create mode 100644 tests/core/lang/static_basic_001.phpt diff --git a/phpunit.xml b/phpunit.xml new file mode 100644 index 00000000..76b70f89 --- /dev/null +++ b/phpunit.xml @@ -0,0 +1,8 @@ + + + + + ./phpunit + + + diff --git a/phpunit/bootstrap.php b/phpunit/bootstrap.php new file mode 100644 index 00000000..9bbaf678 --- /dev/null +++ b/phpunit/bootstrap.php @@ -0,0 +1,9 @@ +addFiles([$file]); + $o->convert($file); + } catch (TestError $exception) { + $this->assertStringContainsString('Duplicate static variable', $exception->getMessage()); + return; + } + $this->fail(); + } +} diff --git a/src/Php/CompilerBase.php b/src/Php/CompilerBase.php index 0fbae6a9..ccf0396e 100644 --- a/src/Php/CompilerBase.php +++ b/src/Php/CompilerBase.php @@ -19,6 +19,7 @@ use PhpAot\Php\Exception\DynamicCall; use PhpAot\Php\Exception\PlaceHolder; use PhpAot\Php\Exception\Redo; use PhpAot\Php\Exception\Skip; +use PhpAot\Php\Exception\TestError; use PhpAot\Php\Generator\ClosureGenerator; use PhpAot\Php\Generator\PlaceHolderGenerator; use PhpAot\Php\Generator\PropertyPromotion; @@ -244,6 +245,7 @@ class CompilerBase extends \PhpAot\Core\Translator protected bool $defaultNativeType = false; protected bool $stubFile = false; protected bool $enableProfiler = false; + protected bool $forTest = false; protected Parser $parser; protected PrettyPrinter $printer; @@ -1567,6 +1569,9 @@ class CompilerBase extends \PhpAot\Core\Translator protected function addStaticVar(string $name, string $type): void { $this->context->staticVars[$name] = $type; + if ($this->hasStaticVar($name)) { + $this->error('Duplicate static variable `$' . $name . '`'); + } $this->addGlobalVar($this->getStaticVarName($name), $type); } @@ -2175,9 +2180,13 @@ class CompilerBase extends \PhpAot\Core\Translator protected function error(string $msg): never { - $this->climate->red("Fatal error: {$msg}"); - debug_print_backtrace(); - exit(255); + if ($this->forTest) { + throw new TestError($msg); + } else { + $this->climate->red("Fatal error: {$msg}"); + debug_print_backtrace(); + exit(255); + } } protected function fatalError(Node $node, string $msg): never diff --git a/src/Php/CompilerTest.php b/src/Php/CompilerTest.php new file mode 100644 index 00000000..488671ce --- /dev/null +++ b/src/Php/CompilerTest.php @@ -0,0 +1,23 @@ +forTest = true; + } + return self::$instance; + } +} diff --git a/src/Php/Exception/TestError.php b/src/Php/Exception/TestError.php new file mode 100644 index 00000000..a107cbc2 --- /dev/null +++ b/src/Php/Exception/TestError.php @@ -0,0 +1,8 @@ +hasCppFileCache($file)) { $this->climate->darkGray('skip: ' . $file . ', cache exists'); @@ -148,6 +149,11 @@ class Translator extends Preprocessor $this->targetName = $name; } + public function addFiles(array $files): void + { + $this->sourceDirs = array_merge($this->sourceDirs, $files); + } + public function getFiles(string $path): array { $realpath = realpath($path); diff --git a/tests/core/lang/static_basic_001.phpt b/tests/core/lang/static_basic_001.phpt new file mode 100644 index 00000000..80802f30 --- /dev/null +++ b/tests/core/lang/static_basic_001.phpt @@ -0,0 +1,87 @@ +--TEST-- +Static keyword - basic tests +--FILE-- + +--EXPECT-- +Same variable used as static and non static. +--------- +0 +10 +--------- +0 +11 +--------- +0 +12 + +Lots of initialisations in the same statement. +------------- Call 0 -------------- +Uninitialized : +Initialized to 10: 10 +Initialized to 20: 20 +Uninitialized : +Initialized to 30: 30 +------------- Call 1 -------------- +Uninitialized : 1 +Initialized to 10: 11 +Initialized to 20: 21 +Uninitialized : 1 +Initialized to 30: 31 +------------- Call 2 -------------- +Uninitialized : 2 +Initialized to 10: 12 +Initialized to 20: 22 +Uninitialized : 2 +Initialized to 30: 32 + +Using static keyword at global scope + 10 +1 11 +2 12