diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md index 5d576fae..eab0308e 100644 --- a/.github/copilot-instructions.md +++ b/.github/copilot-instructions.md @@ -2,7 +2,7 @@ ## Project overview -TypePHP is an ahead-of-time compiler that translates PHP source into C++, then compiles and links it into a native binary or a PHP extension. The primary entrypoint is `tpc`, which boots `src/compiler.php`; that drives `PhpAot\Php\Translator` through a fixed pipeline: +TypePHP is an ahead-of-time compiler that translates PHP source into C++, then compiles and links it into a native binary or a PHP extension. The primary entrypoint is `tpc`, which boots `src/compiler.php`; that drives `TypePhp\Translator` through a fixed pipeline: 1. `prepare()` scans files, parses ASTs, collects symbols, and topologically sorts PHP files by cross-file symbol usage. 2. `convert()` turns PHP ASTs into generated `.cc` files while passing through native source files (`.cpp`, `.c`, `.s`, `.m`, `.mm`). @@ -86,5 +86,5 @@ Generated C++ is auto-formatted by the compiler itself when `clang-format` is av ## Test-specific conventions - PHPUnit tests for compiler internals should use `CompilerTest::create(ROOT_PATH)`, which enables test mode instead of normal fatal exits. -- `phpunit/bootstrap.php` exposes a `BaseTest::exec()` helper that expects compilation failures to surface as `PhpAot\Php\Exception\TestError`. +- `phpunit/bootstrap.php` exposes a `BaseTest::exec()` helper that expects compilation failures to surface as `TypePhp\Exception\TestError`. - PHPT end-to-end tests live in `tests/aot/`; existing guidance and examples generally put executable test logic inside a `main()` function. diff --git a/CLAUDE.md b/CLAUDE.md index 98316c92..27501c8e 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -60,13 +60,12 @@ The compiler follows a 4-stage pipeline, orchestrated by `src/Php/Translator.php ### Class Hierarchy ``` -src/Core/Translator (abstract base — indent/output/mode helpers) - └─ src/Php/CompilerBase (core PHP→C++ translation logic) - ├─ uses traits: AstNodeType, FuncCallOptimizer, ClosureGenerator, - │ PlaceHolderGenerator, PropertyPromotion, MagicMethodDetector - └─ src/Php/Preprocessor (scanning, symbol tables, dependency sort, YAML config) - └─ src/Php/Translator (full pipeline: prepare→convert→compile→build) - └─ src/Php/CompilerTest (test-only subclass, used by PHPUnit tests) +src/Php/CompilerBase (core PHP→C++ translation logic, indent/output/mode helpers) + ├─ uses traits: AstNodeType, FuncCallOptimizer, ClosureGenerator, + │ PlaceHolderGenerator, PropertyPromotion, MagicMethodDetector + └─ src/Php/Preprocessor (scanning, symbol tables, dependency sort, YAML config) + └─ src/Php/Translator (full pipeline: prepare→convert→compile→build) + └─ src/Php/CompilerTest (test-only subclass, used by PHPUnit tests) ``` ### Key Components diff --git a/bin/arg_info.php b/bin/arg_info.php index a61a5d07..c7ea4482 100644 --- a/bin/arg_info.php +++ b/bin/arg_info.php @@ -1,4 +1,4 @@ isPassedByReference()); \ No newline at end of file diff --git a/bin/extractor.php b/bin/extractor.php index abb35a65..dc9645a2 100644 --- a/bin/extractor.php +++ b/bin/extractor.php @@ -80,7 +80,7 @@ function main(array $argv): void } // 创建提取器 - $extractor = new PhpAot\Php\Extractor(); + $extractor = new TypePhp\Extractor(); // 批量模式 if ($options['batch']) { diff --git a/composer.json b/composer.json index c4f54128..bf050b2a 100644 --- a/composer.json +++ b/composer.json @@ -15,7 +15,10 @@ }, "autoload": { "psr-4": { - "PhpAot\\": "src" + "TypePhp\\": [ + "src/Php", + "src" + ] } }, "scripts": { diff --git a/phpunit/bootstrap.php b/phpunit/bootstrap.php index a5719565..a487b22d 100644 --- a/phpunit/bootstrap.php +++ b/phpunit/bootstrap.php @@ -1,8 +1,8 @@ addFiles([$testFile]); @@ -42,7 +42,7 @@ class ClassTest extends \BaseTest public function testParentCanBePartOfUnionType() { global $translator; - $compiler = \PhpAot\Php\CompilerTest::create(ROOT_PATH); + $compiler = \TypePhp\CompilerTest::create(ROOT_PATH); $translator = $compiler; $testFile = __DIR__ . '/../code/union_type_parent_allowed.php'; $compiler->addFiles([$testFile]); diff --git a/phpunit/src/ClosureTest.php b/phpunit/src/ClosureTest.php index e32ce9de..afb60044 100644 --- a/phpunit/src/ClosureTest.php +++ b/phpunit/src/ClosureTest.php @@ -1,6 +1,6 @@ getValue($compiler); if ($platform !== null) { - $isWindowsNew = $platform instanceof \PhpAot\Php\Platform\Windows; + $isWindowsNew = $platform instanceof \TypePhp\Platform\Windows; // 新旧方法应该一致 $this->assertEquals($isWindowsOld, $isWindowsNew, diff --git a/phpunit/src/CompilerBaseApiTest.php b/phpunit/src/CompilerBaseApiTest.php index 5793705a..2b4ba653 100644 --- a/phpunit/src/CompilerBaseApiTest.php +++ b/phpunit/src/CompilerBaseApiTest.php @@ -1,11 +1,11 @@ = "Linux" YAML); - $this->expectException(\PhpAot\Php\Exception\TestError::class); + $this->expectException(\TypePhp\Exception\TestError::class); $this->expectExceptionMessage('Unsupported source condition'); $this->invokeMethod('parseProjectYaml', $projectFile); @@ -640,7 +640,7 @@ sources: if: PHP_VERSION YAML); - $this->expectException(\PhpAot\Php\Exception\TestError::class); + $this->expectException(\TypePhp\Exception\TestError::class); $this->expectExceptionMessage('Unsupported source condition'); $this->invokeMethod('parseProjectYaml', $projectFile); @@ -654,7 +654,7 @@ sources: if: PHP_VERSION_ID >= getenv("MIN_PHP") YAML); - $this->expectException(\PhpAot\Php\Exception\TestError::class); + $this->expectException(\TypePhp\Exception\TestError::class); $this->expectExceptionMessage('Unsupported source condition'); $this->invokeMethod('parseProjectYaml', $projectFile); diff --git a/phpunit/src/CompilerPhaseTest.php b/phpunit/src/CompilerPhaseTest.php index 5aac906c..e75a338c 100644 --- a/phpunit/src/CompilerPhaseTest.php +++ b/phpunit/src/CompilerPhaseTest.php @@ -1,7 +1,7 @@ invoke($this); return $resolver->canAccessProtectedProperty('ProbeClass', 'ProbeClass'); } diff --git a/phpunit/src/Context/FunctionContextExtendedTest.php b/phpunit/src/Context/FunctionContextExtendedTest.php index 47892de6..a02b3d38 100644 --- a/phpunit/src/Context/FunctionContextExtendedTest.php +++ b/phpunit/src/Context/FunctionContextExtendedTest.php @@ -1,10 +1,10 @@ assertNotNull($class->propertyContext); - $this->assertInstanceOf(\PhpAot\Php\Context\FunctionContext::class, $class->propertyContext); + $this->assertInstanceOf(\TypePhp\Context\FunctionContext::class, $class->propertyContext); } public function testGetNamespacedNameInheritedFromClassLikeDef(): void diff --git a/phpunit/src/Entity/ClassLikeDefTest.php b/phpunit/src/Entity/ClassLikeDefTest.php index 10c511f2..e5e66f86 100644 --- a/phpunit/src/Entity/ClassLikeDefTest.php +++ b/phpunit/src/Entity/ClassLikeDefTest.php @@ -1,11 +1,11 @@ assertSame(42, $this->invokeMethod('genCValue', 42)); - $this->assertSame(-1, $this->invokeMethod('genCValue', -1)); - $this->assertSame(0, $this->invokeMethod('genCValue', 0)); + $this->assertSame($this->invokeMethod('genIntegerLiteral', 42), $this->invokeMethod('genCValue', 42)); + $this->assertSame($this->invokeMethod('genIntegerLiteral', -1), $this->invokeMethod('genCValue', -1)); + $this->assertSame($this->invokeMethod('genIntegerLiteral', 0), $this->invokeMethod('genCValue', 0)); } public function testGenCValueFloat(): void diff --git a/phpunit/src/InheritanceErrorTest.php b/phpunit/src/InheritanceErrorTest.php index 46977a4e..77d37ea3 100644 --- a/phpunit/src/InheritanceErrorTest.php +++ b/phpunit/src/InheritanceErrorTest.php @@ -1,7 +1,7 @@ osType = PHP_OS_FAMILY; - } - - public function isMacos(): bool - { - return $this->osType === 'Darwin'; - } - - public function isLinux(): bool - { - return $this->osType === 'Linux'; - } - - public function isWindows(): bool - { - return $this->osType === 'Windows'; - } - - public function setMode($mode): void - { - $this->mode = $mode; - } - - public function setIndent(string $indent): void - { - $this->indentStr = $indent; - } - - public function setIndentLevel(int $level): void - { - $this->indentLevel = $level; - } - - public function getLang(): string - { - return $this->lang; - } - - abstract public function getLine($node): int; - - abstract public function getType($node): string; - - protected function getIndent(): string - { - return str_repeat($this->indentStr, $this->indentLevel); - } -} diff --git a/src/Php/Analysis/SsaBuilder.php b/src/Php/Analysis/SsaBuilder.php index 3aa567e8..bc912fd9 100644 --- a/src/Php/Analysis/SsaBuilder.php +++ b/src/Php/Analysis/SsaBuilder.php @@ -23,9 +23,9 @@ * unknown value after the call. Tracked via IS_REFERENCE flag. */ -namespace PhpAot\Php\Analysis; +namespace TypePhp\Analysis; -use PhpAot\Php\AstNodeType; +use TypePhp\AstNodeType; use PhpParser\Node; use PhpParser\Node\Expr; use PhpParser\Node\Stmt; diff --git a/src/Php/ArgInfo.php b/src/Php/ArgInfo.php index af14b5fb..87596cc0 100644 --- a/src/Php/ArgInfo.php +++ b/src/Php/ArgInfo.php @@ -6,9 +6,9 @@ * @contact service@swoole.com */ -namespace PhpAot\Php; +namespace TypePhp; -use PhpAot\Php\Entity\ArrayInitPlan; +use TypePhp\Entity\ArrayInitPlan; use PhpParser\Node\Expr; use PhpParser\NodeAbstract; diff --git a/src/Php/AstNodeType.php b/src/Php/AstNodeType.php index b3e3c8fb..c138ef51 100644 --- a/src/Php/AstNodeType.php +++ b/src/Php/AstNodeType.php @@ -6,7 +6,7 @@ * @contact service@swoole.com */ -namespace PhpAot\Php; +namespace TypePhp; use PhpParser\Node; use PhpParser\Node\Expr; diff --git a/src/Php/Backend/Clang.php b/src/Php/Backend/Clang.php index b3cb8fb2..ec96b6d2 100644 --- a/src/Php/Backend/Clang.php +++ b/src/Php/Backend/Clang.php @@ -1,10 +1,10 @@ platform->getSharedLinkFlag(); - if ($this->platform instanceof \PhpAot\Php\Platform\Macos && !empty($config['install_name'])) { + if ($this->platform instanceof \TypePhp\Platform\Macos && !empty($config['install_name'])) { $flags .= ' ' . $this->platform->getCurrentInstallNameOption($config['install_name']); } } diff --git a/src/Php/Backend/Msvc.php b/src/Php/Backend/Msvc.php index 9256d68e..baf1f6b6 100644 --- a/src/Php/Backend/Msvc.php +++ b/src/Php/Backend/Msvc.php @@ -1,8 +1,8 @@ osType = PHP_OS_FAMILY; if (version_compare(PHP_VERSION, '8.2.0', '<')) { $this->error('PHP 8.2.0 or later is required'); } @@ -421,6 +425,31 @@ class CompilerBase extends \PhpAot\Core\Translator implements PropertyAccessCont $this->climate = $climate; } + public function setMode($mode): void + { + $this->mode = $mode; + } + + public function setIndent(string $indent): void + { + $this->indentStr = $indent; + } + + public function setIndentLevel(int $level): void + { + $this->indentLevel = $level; + } + + public function getLang(): string + { + return $this->lang; + } + + protected function getIndent(): string + { + return str_repeat($this->indentStr, $this->indentLevel); + } + protected function getPhpxDir(): string { // 优先使用环境变量 PHPX_HOME diff --git a/src/Php/CompilerTest.php b/src/Php/CompilerTest.php index 9adca885..7754c6fe 100644 --- a/src/Php/CompilerTest.php +++ b/src/Php/CompilerTest.php @@ -6,7 +6,7 @@ * @contact service@swoole.com */ -namespace PhpAot\Php; +namespace TypePhp; /** * @internal diff --git a/src/Php/Constants.php b/src/Php/Constants.php index 91033f70..60836af3 100644 --- a/src/Php/Constants.php +++ b/src/Php/Constants.php @@ -6,7 +6,7 @@ * @contact service@swoole.com */ -namespace PhpAot\Php; +namespace TypePhp; class Constants { diff --git a/src/Php/Context/FunctionContext.php b/src/Php/Context/FunctionContext.php index 70718d01..f966c933 100644 --- a/src/Php/Context/FunctionContext.php +++ b/src/Php/Context/FunctionContext.php @@ -6,9 +6,9 @@ * @contact service@swoole.com */ -namespace PhpAot\Php\Context; +namespace TypePhp\Context; -use PhpAot\Php\Analysis\SsaBuilder; +use TypePhp\Analysis\SsaBuilder; class FunctionContext { diff --git a/src/Php/Context/ScopeContext.php b/src/Php/Context/ScopeContext.php index 39c3cb6a..8c7ee0dd 100644 --- a/src/Php/Context/ScopeContext.php +++ b/src/Php/Context/ScopeContext.php @@ -1,6 +1,6 @@ .res $backend = $this->getCompilerBackend(); - if ($backend instanceof \PhpAot\Php\Backend\Msvc) { + if ($backend instanceof \TypePhp\Backend\Msvc) { $resFile = $this->getResourceResFile(); $cmd = $backend->compileResourceFile($rcFile, $resFile); $this->climate->comment($cmd); diff --git a/src/Php/UniversalMethodCall.php b/src/Php/UniversalMethodCall.php index fad51823..098dab00 100644 --- a/src/Php/UniversalMethodCall.php +++ b/src/Php/UniversalMethodCall.php @@ -1,6 +1,6 @@ argInfoList)) { return false; diff --git a/src/Php/Visitor.php b/src/Php/Visitor.php index 9fa1938c..5bc28d15 100644 --- a/src/Php/Visitor.php +++ b/src/Php/Visitor.php @@ -6,7 +6,7 @@ * @contact service@swoole.com */ -namespace PhpAot\Php; +namespace TypePhp; use PhpParser\NodeVisitorAbstract; diff --git a/src/compiler.php b/src/compiler.php index 111aba10..ce7977ae 100644 --- a/src/compiler.php +++ b/src/compiler.php @@ -1,5 +1,5 @@