From 601b985600271a70ceb66560a79be760b5256ee2 Mon Sep 17 00:00:00 2001 From: tianfenghan Date: Tue, 23 Jun 2026 19:08:20 +0800 Subject: [PATCH] =?UTF-8?q?feat(compiler):=20=E6=B7=BB=E5=8A=A0=E8=BF=9B?= =?UTF-8?q?=E5=BA=A6=E6=9D=A1=E6=98=BE=E7=A4=BA=E5=B9=B6=E6=9B=B4=E6=96=B0?= =?UTF-8?q?=E4=BE=9D=E8=B5=96=E5=BA=93?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 集成 ajaxray/ansikit 库用于终端UI显示 - 升级 swoole/phpx 从 v2.1.4 到 v2.3.9 版本 - 在并行编译过程中添加进度条实时显示编译进度 - 移除函数返回类型的推断逻辑和相关字段 - 设置PHP平台版本要求为 >=8.2 <8.6 - 优化编译失败时的错误输出格式 --- composer.json | 3 +- composer.lock | 64 ++++++++++++++++++++++++++++++++++++------ src/Php/Translator.php | 15 +++++++++- src/gen_stub.php | 17 ++--------- 4 files changed, 74 insertions(+), 25 deletions(-) diff --git a/composer.json b/composer.json index 1fe4f5ca..f7588431 100644 --- a/composer.json +++ b/composer.json @@ -6,7 +6,8 @@ "marcj/topsort": "^2.0", "symfony/var-dumper": "^8.0", "symfony/yaml": "^8.0", - "swoole/phpx": "~2.3.9" + "swoole/phpx": "~2.3.9", + "ajaxray/ansikit": "^0.3.1" }, "require-dev": { "phpunit/phpunit": "^10.4", diff --git a/composer.lock b/composer.lock index 27b186a0..eed915fd 100644 --- a/composer.lock +++ b/composer.lock @@ -4,8 +4,51 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "b85ec97da999339a1cebcf7664e5465b", + "content-hash": "41bca06c5ece84cfb4ed396385b10988", "packages": [ + { + "name": "ajaxray/ansikit", + "version": "v0.3.1", + "source": { + "type": "git", + "url": "https://github.com/ajaxray/AnsiKit.git", + "reference": "b318313e879a248bf0fe77c792a3a03f232484f0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/ajaxray/AnsiKit/zipball/b318313e879a248bf0fe77c792a3a03f232484f0", + "reference": "b318313e879a248bf0fe77c792a3a03f232484f0", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "require-dev": { + "phpunit/phpunit": "^11.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Ajaxray\\AnsiKit\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Anis Uddin Ahmad", + "email": "anis.programmer@gmail.com" + } + ], + "description": "Tiny ANSI escape helper for terminal UIs (text styles, foreground & background colors, cursor positions, clearing) with table, progressbar, and more helpers.", + "support": { + "issues": "https://github.com/ajaxray/AnsiKit/issues", + "source": "https://github.com/ajaxray/AnsiKit/tree/v0.3.1" + }, + "time": "2025-09-22T13:57:26+00:00" + }, { "name": "league/climate", "version": "3.10.1", @@ -299,20 +342,21 @@ }, { "name": "swoole/phpx", - "version": "v2.1.4", + "version": "v2.3.9", "source": { "type": "git", "url": "https://github.com/swoole/phpx.git", - "reference": "2f6d8de5333085c0d8f7975ca9b6b6cdb74057b6" + "reference": "98f96dead31b36510a4d3323a2d1a1bcfcd07a5e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/swoole/phpx/zipball/2f6d8de5333085c0d8f7975ca9b6b6cdb74057b6", - "reference": "2f6d8de5333085c0d8f7975ca9b6b6cdb74057b6", + "url": "https://api.github.com/repos/swoole/phpx/zipball/98f96dead31b36510a4d3323a2d1a1bcfcd07a5e", + "reference": "98f96dead31b36510a4d3323a2d1a1bcfcd07a5e", "shasum": "" }, "require": { - "league/climate": "^3.10" + "league/climate": "^3.10", + "marcj/topsort": "^2.0" }, "require-dev": { "friendsofphp/php-cs-fixer": "^3.75", @@ -337,9 +381,9 @@ ], "support": { "issues": "https://github.com/swoole/phpx/issues", - "source": "https://github.com/swoole/phpx/tree/v2.1.4" + "source": "https://github.com/swoole/phpx/tree/v2.3.9" }, - "time": "2026-04-23T06:18:21+00:00" + "time": "2026-06-23T05:59:31+00:00" }, { "name": "symfony/polyfill-ctype", @@ -4733,7 +4777,9 @@ "stability-flags": {}, "prefer-stable": false, "prefer-lowest": false, - "platform": {}, + "platform": { + "php": ">=8.2 <8.6" + }, "platform-dev": {}, "plugin-api-version": "2.9.0" } diff --git a/src/Php/Translator.php b/src/Php/Translator.php index 1cafc04b..94441541 100644 --- a/src/Php/Translator.php +++ b/src/Php/Translator.php @@ -33,6 +33,8 @@ use PhpParser\Node\Expr\List_; use PhpParser\Node\Stmt\Foreach_; use PhpParser\NodeAbstract; use PhpParser\NodeTraverser; +use Ajaxray\AnsiKit\AnsiTerminal; +use Ajaxray\AnsiKit\Components\Progressbar; use Symfony\Component\Yaml\Yaml; class Translator extends Preprocessor @@ -1227,6 +1229,12 @@ CODE; $this->climate->lightBlue("Starting parallel compilation with {$job} jobs for {$totalFiles} files"); + $progress = new Progressbar(); + $progress->barStyle([AnsiTerminal::FG_GREEN]) + ->percentageStyle([AnsiTerminal::TEXT_BOLD]) + ->labelStyle([AnsiTerminal::FG_CYAN]); + $progress->renderInPlace(0, $totalFiles, 'Compiling'); + while ($compiledCount < $totalFiles) { // 启动新进程,直到达到最大并发数 while ($runningProcesses < $job && !empty($fileQueue)) { @@ -1268,14 +1276,17 @@ CODE; $exitCode = pcntl_wexitstatus($status); if ($exitCode !== 0) { $failedFile = $processInfo['file'] ?? 'unknown'; - $this->climate->red("Compilation failed: {$failedFile}"); $failedFiles[] = $failedFile; + echo PHP_EOL; + $this->climate->red("Compilation failed: {$failedFile}"); + echo PHP_EOL; } else { if ($processInfo) { $objectFiles[] = $processInfo['object']; } } $compiledCount++; + $progress->renderInPlace($compiledCount, $totalFiles, 'Compiling'); } } } @@ -1291,6 +1302,8 @@ CODE; } } + echo PHP_EOL; + if (!empty($failedFiles)) { throw new \Exception('Compilation failed for: ' . implode(', ', $failedFiles)); } diff --git a/src/gen_stub.php b/src/gen_stub.php index 241d4d6e..0ba7faf2 100755 --- a/src/gen_stub.php +++ b/src/gen_stub.php @@ -1110,21 +1110,18 @@ class ReturnInfo { public /* readonly */ ?Type $phpDocType; public /* readonly */ bool $tentativeReturnType; public /* readonly */ string $refcount; - private bool $isInferredPhpDocType; public function __construct( bool $byRef, ?Type $type, ?Type $phpDocType, bool $tentativeReturnType, - ?string $refcount, - bool $isInferredPhpDocType = false + ?string $refcount ) { $this->byRef = $byRef; $this->type = $type; $this->phpDocType = $phpDocType; $this->tentativeReturnType = $tentativeReturnType; - $this->isInferredPhpDocType = $isInferredPhpDocType; $this->setRefcount($refcount); } @@ -5041,15 +5038,8 @@ function parseFunctionLike( } $returnType = $func->getReturnType(); - $isInferredReturnType = false; if ($returnType === null && $docReturnType === null && !$name->isConstructor() && !$name->isDestructor()) { - $defaultReturnType = getMagicMethodDefaultReturnType($name); - if ($defaultReturnType !== null) { - $docReturnType = $defaultReturnType; - } else { - $docReturnType = 'mixed'; - $isInferredReturnType = true; - } + $docReturnType = getMagicMethodDefaultReturnType($name); } $return = new ReturnInfo( @@ -5057,8 +5047,7 @@ function parseFunctionLike( $returnType ? Type::fromNode($returnType) : null, $docReturnType ? Type::fromString($docReturnType) : null, $tentativeReturnType, - $refcount, - $isInferredReturnType + $refcount ); return new FuncInfo(