From 7ad7657e286f4791852d171b9f50505c1fb07aa0 Mon Sep 17 00:00:00 2001 From: tianfenghan Date: Thu, 7 May 2026 15:28:05 +0800 Subject: [PATCH] cs-fix --- src/Php/AstNodeType.php | 4 +- src/Php/CompilerBase.php | 207 ++++++++++++++-------------- src/Php/Constants.php | 2 +- src/Php/Context/FunctionContext.php | 1 + src/Php/Parser/StdArrayParser.php | 15 +- src/Php/Preprocessor.php | 6 +- src/Php/Symbol.php | 2 +- src/Php/Translator.php | 94 ++++++------- 8 files changed, 169 insertions(+), 162 deletions(-) diff --git a/src/Php/AstNodeType.php b/src/Php/AstNodeType.php index 75d7b1eb..8c651d11 100644 --- a/src/Php/AstNodeType.php +++ b/src/Php/AstNodeType.php @@ -102,10 +102,10 @@ trait AstNodeType protected function isScalarBool(NodeAbstract $expr): bool { - return $expr instanceof Node\Expr\ConstFetch and in_array($expr->name->toString(), ['true', 'false']); + return $expr instanceof Expr\ConstFetch and in_array($expr->name->toString(), ['true', 'false']); } - protected function getBoolValue(Node\Expr\ConstFetch $expr): string + protected function getBoolValue(Expr\ConstFetch $expr): string { return $expr->name->toString() === 'true' ? self::VALUE_TRUE : self::VALUE_FALSE; } diff --git a/src/Php/CompilerBase.php b/src/Php/CompilerBase.php index 1137eaaa..c36560d7 100644 --- a/src/Php/CompilerBase.php +++ b/src/Php/CompilerBase.php @@ -293,10 +293,10 @@ class CompilerBase extends \PhpAot\Core\Translator $climate = new CLImate(); $this->climate = $climate; // $this->noLiteralStrings = $climate->arguments->get('no-literal-strings'); - + // 检测操作系统并设置编译器 $this->detectPlatform(); - + // 检测 PHP 是否为线程安全版本(ZTS) $this->isPhpZts = defined('PHP_ZTS'); } @@ -305,12 +305,12 @@ class CompilerBase extends \PhpAot\Core\Translator { // 检测是否为 Windows 系统 $this->isWindows = strtoupper(substr(PHP_OS, 0, 3)) === 'WIN'; - + if ($this->isWindows) { // Windows 下检测使用哪个编译器 // 优先级:环境变量 PHPX_CC > clang > cl (MSVC) $compilerEnv = getenv('PHPX_CC'); - + if ($compilerEnv) { // 用户通过环境变量指定编译器 $this->cppCompiler = $compilerEnv; @@ -338,37 +338,37 @@ class CompilerBase extends \PhpAot\Core\Translator if (!$this->isWindows) { return false; } - + // 首先尝试 PATH 中的 clang++ $output = []; $returnCode = 0; exec('clang++ --version 2>&1', $output, $returnCode); - + if ($returnCode === 0) { // 检查是否有 lld-link $this->checkLldLinker(); return true; } - + // 如果 PATH 中没有,尝试从 LLVM_HOME 环境变量获取 $llvmHome = getenv('LLVM_HOME'); if ($llvmHome && is_dir($llvmHome)) { - $clangPath = rtrim($llvmHome, '\\/') . '\x64\bin\clang++.exe'; + $clangPath = rtrim($llvmHome, '\/') . '\x64\bin\clang++.exe'; if (file_exists($clangPath)) { // 验证是否可以执行 exec('"' . $clangPath . '" --version 2>&1', $output, $returnCode); if ($returnCode === 0) { // 将 Clang 路径添加到环境变量 $clangDir = dirname($clangPath); - putenv("PATH=$clangDir;" . getenv('PATH')); - + putenv("PATH={$clangDir};" . getenv('PATH')); + // 检查是否有 lld-link $this->checkLldLinker(); return true; } } } - + return false; } @@ -381,30 +381,30 @@ class CompilerBase extends \PhpAot\Core\Translator $output = []; $returnCode = 0; exec('lld-link --version 2>&1', $output, $returnCode); - + if ($returnCode === 0) { $this->linker = 'lld-link'; $this->climate->info('Using lld-link linker (faster than link.exe)'); return; } - + // 如果 PATH 中没有,尝试从 LLVM_HOME 获取 $llvmHome = getenv('LLVM_HOME'); if ($llvmHome && is_dir($llvmHome)) { - $lldLinkPath = rtrim($llvmHome, '\\/') . '\x64\bin\lld-link.exe'; + $lldLinkPath = rtrim($llvmHome, '\/') . '\x64\bin\lld-link.exe'; if (file_exists($lldLinkPath)) { exec('"' . $lldLinkPath . '" --version 2>&1', $output, $returnCode); if ($returnCode === 0) { // 将 lld-link 路径添加到环境变量 $lldDir = dirname($lldLinkPath); - putenv("PATH=$lldDir;" . getenv('PATH')); + putenv("PATH={$lldDir};" . getenv('PATH')); $this->linker = 'lld-link'; $this->climate->info('Using lld-link linker from LLVM_HOME (faster than link.exe)'); return; } } } - + // Fallback 到 MSVC link.exe $this->linker = 'link'; $this->climate->info('Using MSVC link.exe linker'); @@ -415,9 +415,9 @@ class CompilerBase extends \PhpAot\Core\Translator // 优先使用环境变量 PHPX_HOME $phpxDir = getenv('PHPX_HOME'); if ($phpxDir && is_dir($phpxDir)) { - return rtrim($phpxDir, '\\/'); + return rtrim($phpxDir, '\/'); } - + // 默认路径 return $this->rootPath . '/vendor/swoole/phpx'; } @@ -438,20 +438,20 @@ class CompilerBase extends \PhpAot\Core\Translator // Windows 下尝试从环境变量获取 PHP 路径 $phpDir = getenv('PHP_HOME'); if ($phpDir && is_dir($phpDir)) { - return rtrim($phpDir, '\\/'); + return rtrim($phpDir, '\/'); } - + // 尝试从 php.exe 路径推断(使用 where 命令) $phpExe = exec('where php 2>nul'); if ($phpExe) { $phpDir = dirname($phpExe); if (is_dir($phpDir)) { - return rtrim($phpDir, '\\/'); + return rtrim($phpDir, '\/'); } } - + // 默认路径 - return 'C:\\php'; + return 'C:\php'; } else { // Unix/Linux/macOS 下使用 php-config 获取 PHP 路径 $phpDir = shell_exec('php-config --prefix 2>/dev/null'); @@ -766,7 +766,7 @@ class CompilerBase extends \PhpAot\Core\Translator $short = str_replace('/', '\\', $short); $long = str_replace('/', '\\', $long); } - + $len = min(strlen($short), strlen($long)); $prefixLen = 0; @@ -779,14 +779,14 @@ class CompilerBase extends \PhpAot\Core\Translator } $result = substr($long, $prefixLen); - + // 移除开头的路径分隔符 if ($this->isWindows()) { $result = ltrim($result, '\\'); } else { $result = ltrim($result, '/'); } - + return $result; } @@ -2261,13 +2261,13 @@ class CompilerBase extends \PhpAot\Core\Translator if ($this->isWindows()) { return $this->parseWindowsIncludes(); } - + $list = [ $this->getPhpxDir() . '/include', $this->getBuildDir() . '/include', $this->getPhpxDir() . '/src/misc', ]; - + // 尝试使用 php-config 获取包含路径,如果失败则手动构建 $phpIncludes = shell_exec('php-config --includes 2>/dev/null'); if ($phpIncludes) { @@ -2281,7 +2281,7 @@ class CompilerBase extends \PhpAot\Core\Translator $out = ''; } } - + foreach ($list as $li) { $out .= '-I ' . $li . ' '; } @@ -2292,23 +2292,20 @@ class CompilerBase extends \PhpAot\Core\Translator protected function parseWindowsIncludes(): string { $list = [ - $this->getPhpxDir() . '\\include', - $this->getBuildDir() . '\\include', - $this->getPhpxDir() . '\\src\\misc', + $this->getPhpxDir() . '\include', + $this->getBuildDir() . '\include', + $this->getPhpxDir() . '\src\misc', ]; - + // Windows 下 PHP 头文件必须从 SDK/include 读取 - $phpSdkInclude = $this->getPhpDir() . '\\SDK\\include'; + $phpSdkInclude = $this->getPhpDir() . '\SDK\include'; if (!is_dir($phpSdkInclude)) { - throw new \RuntimeException( - "PHP SDK include directory not found: {$phpSdkInclude}\n" . - "Please ensure PHP is installed with SDK headers at the expected location." - ); + throw new \RuntimeException("PHP SDK include directory not found: {$phpSdkInclude}\n" . 'Please ensure PHP is installed with SDK headers at the expected location.'); } - + // 添加主包含目录 $list[] = $phpSdkInclude; - + // 添加子目录:main, Zend, TSRM, ext $subDirs = ['main', 'Zend', 'TSRM', 'ext']; foreach ($subDirs as $subDir) { @@ -2317,7 +2314,7 @@ class CompilerBase extends \PhpAot\Core\Translator $list[] = $subPath; } } - + $out = ''; // 根据编译器类型选择不同的包含路径格式 if ($this->cppCompiler === 'clang++' || $this->cppCompiler === 'clang') { @@ -2342,11 +2339,11 @@ class CompilerBase extends \PhpAot\Core\Translator if ($this->isWindows()) { return $this->parseWindowsLdflags(); } - + $list = [ $this->getPhpxDir() . '/lib', ]; - + // 尝试使用 php-config 获取库路径,如果失败则手动构建 $phpLibDir = shell_exec('php-config --prefix 2>/dev/null'); if ($phpLibDir) { @@ -2361,7 +2358,7 @@ class CompilerBase extends \PhpAot\Core\Translator array_unshift($list, $phpLibPath); } } - + $out = ''; foreach ($list as $li) { $out .= '-L ' . $li . ' '; @@ -2373,25 +2370,25 @@ class CompilerBase extends \PhpAot\Core\Translator protected function parseWindowsLdflags(): string { $list = []; - + // Windows 下 PHP 库文件固定从 SDK/lib 读取 - $phpLib = $this->getPhpDir() . '\\SDK\\lib'; + $phpLib = $this->getPhpDir() . '\SDK\lib'; if (is_dir($phpLib)) { $list[] = $phpLib; } else { // 备选:尝试直接从 lib 目录 - $phpLibAlt = $this->getPhpDir() . '\\lib'; + $phpLibAlt = $this->getPhpDir() . '\lib'; if (is_dir($phpLibAlt)) { $list[] = $phpLibAlt; } } - + // phpx 库文件 - $phpxLib = $this->getPhpxDir() . '\\lib'; + $phpxLib = $this->getPhpxDir() . '\lib'; if (is_dir($phpxLib)) { $list[] = $phpxLib; } - + $out = ''; foreach ($list as $li) { if (is_dir($li)) { @@ -2407,7 +2404,7 @@ class CompilerBase extends \PhpAot\Core\Translator if ($this->isWindows()) { return $this->parseWindowsLibs(); } - + $list = ['phpx']; if ($this->buildMode === 'bin') { $list[] = 'php'; @@ -2423,21 +2420,21 @@ class CompilerBase extends \PhpAot\Core\Translator protected function parseWindowsLibs(): string { $list = []; - + // 优先使用 .lib 导入库 - $phpxLib = $this->getPhpxDir() . '\\lib\\phpx.lib'; + $phpxLib = $this->getPhpxDir() . '\lib\phpx.lib'; if (file_exists($phpxLib)) { $list[] = '"' . $phpxLib . '"'; } else { // 如果没有 .lib,尝试直接使用 DLL(需要生成导入库) - $phpxDll = $this->getPhpxDir() . '\\lib\\phpx.dll'; + $phpxDll = $this->getPhpxDir() . '\lib\phpx.dll'; if (file_exists($phpxDll)) { $this->climate->magenta('phpx.lib not found, using phpx.dll directly'); $this->climate->info('Note: You may need to generate phpx.lib from phpx.dll using lib /def:phpx.def'); $list[] = '"' . $phpxDll . '"'; } } - + if ($this->buildMode === 'bin') { // Windows 下 PHP 库文件和 DLL 的查找顺序: // 1. SDK/lib/php8embed.lib (嵌入模式首选) @@ -2446,51 +2443,53 @@ class CompilerBase extends \PhpAot\Core\Translator // 4. lib/php8embed.lib // 5. lib/php8ts.lib // 6. lib/php8.lib - + $phpDirs = [ - $this->getPhpDir() . '\\SDK\\lib', // 优先从 SDK/lib 查找 - $this->getPhpDir() . '\\lib', // 备选从 lib 查找 + $this->getPhpDir() . '\SDK\lib', // 优先从 SDK/lib 查找 + $this->getPhpDir() . '\lib', // 备选从 lib 查找 ]; - + $found = false; foreach ($phpDirs as $phpDir) { - if (!is_dir($phpDir)) continue; - + if (!is_dir($phpDir)) { + continue; + } + // 尝试 php8embed.lib (嵌入模式) - $phpEmbedLib = $phpDir . '\\php8embed.lib'; + $phpEmbedLib = $phpDir . '\php8embed.lib'; if (file_exists($phpEmbedLib)) { $list[] = '"' . $phpEmbedLib . '"'; $found = true; break; } - + // 尝试 php8ts.lib - $phpTsLib = $phpDir . '\\php8ts.lib'; + $phpTsLib = $phpDir . '\php8ts.lib'; if (file_exists($phpTsLib)) { $list[] = '"' . $phpTsLib . '"'; $found = true; break; } - + // 尝试 php8.lib - $phpLib = $phpDir . '\\php8.lib'; + $phpLib = $phpDir . '\php8.lib'; if (file_exists($phpLib)) { $list[] = '"' . $phpLib . '"'; $found = true; break; } } - + // 如果都没找到 .lib,尝试直接使用根目录的 DLL if (!$found) { - $phpDll = $this->getPhpDir() . '\\php8.dll'; + $phpDll = $this->getPhpDir() . '\php8.dll'; if (file_exists($phpDll)) { $this->climate->magenta('php8embed.lib not found, using php8.dll directly'); $this->climate->info('Note: This may require additional setup'); $list[] = '"' . $phpDll . '"'; } else { // 尝试 php8ts.dll - $phpTsDll = $this->getPhpDir() . '\\php8ts.dll'; + $phpTsDll = $this->getPhpDir() . '\php8ts.dll'; if (file_exists($phpTsDll)) { $this->climate->magenta('php8embed.lib not found, using php8ts.dll directly'); $this->climate->info('Note: This may require additional setup'); @@ -2499,7 +2498,7 @@ class CompilerBase extends \PhpAot\Core\Translator } } } - + $out = ''; foreach ($list as $li) { $out .= $li . ' '; @@ -2531,18 +2530,18 @@ class CompilerBase extends \PhpAot\Core\Translator if (!$link) { $cmd .= ' ' . $this->parseWindowsIncludes(); } - + // Windows 平台必需的宏定义(参考 CMakeLists.txt)- 仅在编译时 if (!$link) { $cmd .= ' /DZEND_WIN32'; // 标识 Windows 平台 $cmd .= ' /DPHP_WIN32'; // 标识 Windows 平台 $cmd .= ' /DZEND_DEBUG=0'; // 禁用调试模式 - + // 根据 PHP 是否为线程安全版本决定是否添加 ZTS 宏 if ($this->isPhpZts) { $cmd .= ' /DZTS'; // 启用线程安全 } - + // Sanitizer 支持(MSVC 使用 /fsanitize) if ($this->sanitize) { // MSVC 支持的 sanitizer: address @@ -2553,7 +2552,7 @@ class CompilerBase extends \PhpAot\Core\Translator $this->climate->warning("Unsupported sanitizer type: {$this->sanitize} (MSVC only supports 'address')"); } } - + // 调试模式:当启用 --debug-info 时,自动禁用优化并添加调试信息 if ($this->debugInfo) { $cmd .= ' /Od'; // 禁用优化(类似 gcc -O0) @@ -2577,27 +2576,27 @@ class CompilerBase extends \PhpAot\Core\Translator // 警告级别 $cmd .= ' /W3'; - + // 禁用 PHP SDK 和 Windows SDK 头文件中的常见警告 // 这些警告都是编译器噪音,不影响功能(从 Constants 配置中读取) foreach (Constants::MSVC_SUPPRESSED_WARNINGS as $code => $description) { $cmd .= " /wd{$code}"; // C{$code}: {$description} } - + // 启用 C++ 异常处理(消除 C4530 警告) $cmd .= ' /EHsc'; - + // C++ 标准(从 cxxStd 属性读取,如果 cxxflags 中没有指定) if (!str_contains($this->cxxflags, '/std:')) { $cmd .= ' /std:' . $this->cxxStd; } - + // 编译时的额外选项 if ($this->cxxflags) { $cmd .= ' ' . $this->cxxflags; } } - + // 禁用编译器版权信息输出 $cmd .= ' /nologo'; @@ -2613,12 +2612,12 @@ class CompilerBase extends \PhpAot\Core\Translator // 链接选项 if ($link) { $cmd .= ' ' . $this->parseWindowsLdflags(); - + // 调试模式:链接时生成 PDB 文件 if ($this->debugInfo) { $cmd .= ' /DEBUG'; // 生成 PDB 调试信息文件 } - + // 对于 bin 模式且指定了 --no-console,使用 Windows 子系统(不显示控制台窗口) if ($this->buildMode === 'bin' && $this->noConsole) { $cmd .= ' /SUBSYSTEM:WINDOWS'; @@ -2627,7 +2626,7 @@ class CompilerBase extends \PhpAot\Core\Translator // 注意:使用 WINDOWS 子系统后,程序将没有控制台窗口 // 所有输出需要通过 GUI 元素(如消息框)显示 } - + // 排除静态 CRT 库,只使用动态 CRT(/MD) $cmd .= ' /NODEFAULTLIB:LIBCMT'; @@ -2639,7 +2638,7 @@ class CompilerBase extends \PhpAot\Core\Translator // 编译时使用动态多线程 CRT(与 PHP SDK 一致) $cmd .= ' /MD'; } - + // 定义宏(仅在编译时) if (!$link && $this->enableProfiler) { $cmd .= ' /DPPROF_ON=1'; @@ -2655,33 +2654,33 @@ class CompilerBase extends \PhpAot\Core\Translator if (!$link) { $cmd .= ' ' . $this->parseWindowsIncludes(); } - + // Windows 平台必需的宏定义 - 仅在编译时 if (!$link) { $cmd .= ' -DZEND_WIN32'; // 标识 Windows 平台 $cmd .= ' -DPHP_WIN32'; // 标识 Windows 平台 $cmd .= ' -DZEND_DEBUG=0'; // 禁用调试模式 - + // 根据 PHP 是否为线程安全版本决定是否添加 ZTS 宏 if ($this->isPhpZts) { $cmd .= ' -DZTS'; // 启用线程安全 } - + // Sanitizer 支持(Clang 使用 -fsanitize) if ($this->sanitize && !$link) { $sanitizers = explode(',', $this->sanitize); $validSanitizers = ['address', 'undefined', 'thread', 'memory', 'leak']; $enabledSanitizers = []; - + foreach ($sanitizers as $san) { $san = trim($san); if (in_array($san, $validSanitizers)) { $enabledSanitizers[] = $san; } else { - $this->climate->warning("Unsupported sanitizer: $san"); + $this->climate->warning("Unsupported sanitizer: {$san}"); } } - + if (!empty($enabledSanitizers)) { $sanitizerFlag = '-fsanitize=' . implode(',', $enabledSanitizers); $cmd .= ' ' . $sanitizerFlag; @@ -2692,7 +2691,7 @@ class CompilerBase extends \PhpAot\Core\Translator $this->climate->info('Sanitizers enabled (Clang): ' . implode(', ', $enabledSanitizers)); } } - + // 调试模式:当启用 --debug-info 时,自动禁用优化并添加调试信息 if ($this->debugInfo) { $cmd .= ' -O0'; // 禁用优化 @@ -2705,12 +2704,12 @@ class CompilerBase extends \PhpAot\Core\Translator // 警告级别 $cmd .= ' -Wall'; - + // C++ 标准 if (!str_contains($this->cxxflags, ' -std=')) { $cmd .= ' -std=' . $this->cxxStd; } - + // 编译时的额外选项 if ($this->cxxflags) { $cmd .= ' ' . $this->cxxflags; @@ -2729,18 +2728,18 @@ class CompilerBase extends \PhpAot\Core\Translator // 链接选项(Clang on Windows 仍然使用 MSVC 的链接器) if ($link) { $cmd .= ' ' . $this->parseWindowsLdflags(); - + // 调试模式:链接时生成 PDB 文件(Clang + lld-link/link.exe) if ($this->debugInfo) { $cmd .= ' /DEBUG'; // 生成 PDB 调试信息文件 } - + // 对于 bin 模式且指定了 --no-console,使用 Windows 子系统 if ($this->buildMode === 'bin' && $this->noConsole) { $cmd .= ' /SUBSYSTEM:WINDOWS'; $cmd .= ' /ENTRY:mainCRTStartup'; } - + // CRT 库配置 $cmd .= ' /NODEFAULTLIB:LIBCMT'; @@ -2752,7 +2751,7 @@ class CompilerBase extends \PhpAot\Core\Translator // 编译时使用动态多线程 CRT $cmd .= ' -MD'; } - + // 定义宏(仅在编译时) if (!$link && $this->enableProfiler) { $cmd .= ' -DPPROF_ON=1'; @@ -2762,7 +2761,7 @@ class CompilerBase extends \PhpAot\Core\Translator protected function addUnixCompilationOption(string &$cmd, bool $link): void { $cmd .= ' ' . $this->parseIncludes(); - + // 调试模式:当启用 --debug-info 时,自动禁用优化并添加调试信息 if ($this->debugInfo) { $cmd .= ' -O0'; // 禁用优化(类似 MSVC /Od) @@ -2772,24 +2771,24 @@ class CompilerBase extends \PhpAot\Core\Translator // 非调试模式:使用用户指定的优化级别 $cmd .= ' -O' . $this->optimizeLevel; } - + $cmd .= ' -Wall'; - + // Sanitizer 支持(GCC/Clang 使用 -fsanitize) if ($this->sanitize && !$link) { $sanitizers = explode(',', $this->sanitize); $validSanitizers = ['address', 'undefined', 'thread', 'memory', 'leak']; $enabledSanitizers = []; - + foreach ($sanitizers as $san) { $san = trim($san); if (in_array($san, $validSanitizers)) { $enabledSanitizers[] = $san; } else { - $this->climate->warning("Unsupported sanitizer: $san"); + $this->climate->warning("Unsupported sanitizer: {$san}"); } } - + if (!empty($enabledSanitizers)) { $sanitizerFlag = '-fsanitize=' . implode(',', $enabledSanitizers); $cmd .= ' ' . $sanitizerFlag; @@ -4409,12 +4408,12 @@ class CompilerBase extends \PhpAot\Core\Translator if (!$this->formatCode) { return; } - + // Windows 下可能没有 clang-format,跳过格式化 if ($this->isWindows()) { return; } - + $cmd = 'cd ' . $this->rootPath . ' && clang-format -i ' . $file; $this->climate->info('format: ' . $this->getRelativePath($file)); $this->climate->comment($cmd); diff --git a/src/Php/Constants.php b/src/Php/Constants.php index 816f3bdf..8752049a 100644 --- a/src/Php/Constants.php +++ b/src/Php/Constants.php @@ -160,7 +160,7 @@ class Constants /** * MSVC 编译器警告屏蔽列表 * 这些警告来自 Windows SDK 和 PHP SDK 头文件,都是编译器噪音,不影响功能 - * + * * @var array 键为警告编号,值为说明 */ public const array MSVC_SUPPRESSED_WARNINGS = [ diff --git a/src/Php/Context/FunctionContext.php b/src/Php/Context/FunctionContext.php index d89227c6..b8bf5fd0 100644 --- a/src/Php/Context/FunctionContext.php +++ b/src/Php/Context/FunctionContext.php @@ -14,6 +14,7 @@ class FunctionContext * @var array */ public array $objects = []; + /** * @var array */ diff --git a/src/Php/Parser/StdArrayParser.php b/src/Php/Parser/StdArrayParser.php index 8379570f..a41988ae 100644 --- a/src/Php/Parser/StdArrayParser.php +++ b/src/Php/Parser/StdArrayParser.php @@ -1,4 +1,10 @@ parseExpr($expr->args[1]->value); $type = $this->context->stdArrays[$array]['type']; $value = $this->convertExprFromType($type, $valueExpr); - return "{$array}.fill({$value})"; + return "{$array}.fill({$value})"; } protected function getStdArrayInfo(Expr\ArrayDimFetch $expr): ?array @@ -103,7 +109,7 @@ trait StdArrayParser $tmp = $expr; $nesting = []; - while(true) { + while (true) { if (count($tmp->args) !== 2) { $this->fatalError($tmp, 'std::array() expects two arguments'); } @@ -132,7 +138,8 @@ trait StdArrayParser break; } break; - } elseif ($this->isStaticCall($typeExpr)) { + } + if ($this->isStaticCall($typeExpr)) { $tmp = $typeExpr; if (!$this->isNameExpr($tmp->class) || !$this->isIdExpr($tmp->name) || $tmp->class->toString() !== 'std' || $tmp->name->toString() !== 'array') { $this->fatalError($tmp, 'An incorrect `std::array` definition'); @@ -154,4 +161,4 @@ trait StdArrayParser ]; return '// ' . $decl; } -} \ No newline at end of file +} diff --git a/src/Php/Preprocessor.php b/src/Php/Preprocessor.php index ce720228..d23c7258 100644 --- a/src/Php/Preprocessor.php +++ b/src/Php/Preprocessor.php @@ -71,11 +71,11 @@ class Preprocessor extends CompilerBase public function getCppFile(string $file): string { $info = pathinfo($file); - + // Windows 下使用反斜杠,其他平台使用正斜杠 $separator = $this->isWindows() ? '\\' : '/'; $relativePath = $this->removeCommonPrefix($this->buildDir, $info['dirname']); - + return $this->buildDir . $separator . $relativePath . $separator . $info['filename'] . '.cc'; } @@ -83,7 +83,7 @@ class Preprocessor extends CompilerBase { $info = pathinfo($cppFile); $ext = $this->isWindows() ? '.obj' : '.o'; - + // 保持与 cppFile 相同的路径分隔符 return $info['dirname'] . ($this->isWindows() ? '\\' : '/') . $info['filename'] . $ext; } diff --git a/src/Php/Symbol.php b/src/Php/Symbol.php index 5617e6f6..dd3b57e1 100644 --- a/src/Php/Symbol.php +++ b/src/Php/Symbol.php @@ -57,6 +57,6 @@ class Symbol public static function safeIndex(string $index, string $size): string { - return "php::safeIndex($index, $size)"; + return "php::safeIndex({$index}, {$size})"; } } diff --git a/src/Php/Translator.php b/src/Php/Translator.php index 904f93f3..86e9f922 100644 --- a/src/Php/Translator.php +++ b/src/Php/Translator.php @@ -125,47 +125,47 @@ class Translator extends Preprocessor if ($this->climate->arguments->defined('optimize')) { $this->optimizeLevel = $this->climate->arguments->get('optimize'); } - + // 构建模式 if ($this->climate->arguments->defined('mode')) { $this->buildMode = $this->climate->arguments->get('mode'); } - + // 调试行号 if ($this->climate->arguments->defined('debug-line')) { $this->debugLine = intval($this->climate->arguments->get('debug-line')); } - + // 最大并行任务数 if ($this->climate->arguments->defined('job')) { $this->maxJob = intval($this->climate->arguments->get('job')); } - + // 调试信息 if ($this->climate->arguments->defined('debug-info')) { $this->debugInfo = true; } - + // 禁用字面量字符串优化 if ($this->climate->arguments->defined('no-literal-strings')) { $this->noLiteralStrings = true; } - + // 启用性能分析 if ($this->climate->arguments->defined('profile')) { $this->enableProfiler = true; } - + // 隐藏控制台窗口 if ($this->climate->arguments->defined('no-console')) { $this->noConsole = true; } - + // Sanitizer if ($this->climate->arguments->defined('sanitize')) { $this->sanitize = $this->climate->arguments->get('sanitize'); } - + // C++ 标准版本 if ($this->climate->arguments->defined('cxx-std')) { $this->cxxStd = $this->climate->arguments->get('cxx-std'); @@ -283,48 +283,48 @@ class Translator extends Preprocessor // Windows 平台检查 dll 和 lib 文件 // 按照新的路径规则检查:SDK/lib, lib, 根目录 $phpDirs = [ - $this->getPhpDir() . '\\SDK\\lib', - $this->getPhpDir() . '\\lib', + $this->getPhpDir() . '\SDK\lib', + $this->getPhpDir() . '\lib', ]; - + $foundLib = false; foreach ($phpDirs as $phpDir) { if (is_dir($phpDir)) { - if (is_file($phpDir . '\\php8.lib') || is_file($phpDir . '\\php8ts.lib')) { + if (is_file($phpDir . '\php8.lib') || is_file($phpDir . '\php8ts.lib')) { $foundLib = true; break; } } } - + // 如果没找到 lib,检查根目录的 DLL if (!$foundLib) { - $phpDll = $this->getPhpDir() . '\\php8.dll'; - $phpTsDll = $this->getPhpDir() . '\\php8ts.dll'; + $phpDll = $this->getPhpDir() . '\php8.dll'; + $phpTsDll = $this->getPhpDir() . '\php8ts.dll'; if (!is_file($phpDll) && !is_file($phpTsDll)) { - $this->climate->warning("The `php8.lib` or `php8.dll` is not found in PHP directory, please check your PHP installation"); + $this->climate->warning('The `php8.lib` or `php8.dll` is not found in PHP directory, please check your PHP installation'); } } - - $phpxLib = $this->getPhpxDir() . '\\lib\\phpx.lib'; - $phpxDll = $this->getPhpxDir() . '\\lib\\phpx.dll'; + + $phpxLib = $this->getPhpxDir() . '\lib\phpx.lib'; + $phpxDll = $this->getPhpxDir() . '\lib\phpx.dll'; if (!is_file($phpxLib) && !is_file($phpxDll)) { - $this->climate->warning("The `phpx.lib` or `phpx.dll` is not found in PHX directory"); - $this->climate->info("Note: If you are building an extension (-m ext), this is OK. For binary mode, please run `make` to build it"); + $this->climate->warning('The `phpx.lib` or `phpx.dll` is not found in PHX directory'); + $this->climate->info('Note: If you are building an extension (-m ext), this is OK. For binary mode, please run `make` to build it'); } } else { // Unix/Linux/macOS 平台检查 .so 或 .dylib 文件 $ext = $this->isMacos() ? 'dylib' : 'so'; $phpLib = $this->getPhpDir() . '/lib/libphp.' . $ext; $phpxLib = $this->getPhpxDir() . '/lib/libphpx.' . $ext; - + if (!is_file($phpLib)) { $this->climate->warning("The `libphp.{$ext}` is not found"); - $this->climate->info("Note: If you are building an extension (-m ext), this is OK. For binary mode, please run `make` to build it"); + $this->climate->info('Note: If you are building an extension (-m ext), this is OK. For binary mode, please run `make` to build it'); } if (!is_file($phpxLib)) { $this->climate->warning("The `libphpx.{$ext}` is not found"); - $this->climate->info("Note: If you are building an extension (-m ext), this is OK. For binary mode, please run `make` to build it"); + $this->climate->info('Note: If you are building an extension (-m ext), this is OK. For binary mode, please run `make` to build it'); } } } @@ -723,14 +723,14 @@ CODE; return; } - + // 根据平台和编译器类型构建编译命令 if ($this->isWindows()) { // C 文件和 C++ 文件使用不同的选项 - $isCppFile = (pathinfo($cppFile, PATHINFO_EXTENSION) === 'cc' || - pathinfo($cppFile, PATHINFO_EXTENSION) === 'cpp' || - pathinfo($cppFile, PATHINFO_EXTENSION) === 'cxx'); - + $isCppFile = (pathinfo($cppFile, PATHINFO_EXTENSION) === 'cc' + || pathinfo($cppFile, PATHINFO_EXTENSION) === 'cpp' + || pathinfo($cppFile, PATHINFO_EXTENSION) === 'cxx'); + // Windows 下根据编译器类型选择参数格式 if ($this->cppCompiler === 'clang++' || $this->cppCompiler === 'clang') { // Clang on Windows 使用 GCC 风格的参数 @@ -744,7 +744,7 @@ CODE; // MSVC 使用 /c 和 /Fo 参数 $cmd = $this->cppCompiler . ' /c ' . $cppFile . ' /Fo' . $objectFile; } - + // 添加编译选项(C 文件不需要 /EHsc 和 /std:c++17) if ($isCppFile) { $this->addCompilationOption($cmd, false); @@ -773,7 +773,7 @@ CODE; $cmd = $this->cppCompiler . ' -c ' . $cppFile . ' -o ' . $objectFile; $this->addCompilationOption($cmd, false); } - + if (!$parallel) { $this->climate->comment($cmd); } @@ -830,7 +830,7 @@ CODE; foreach ($sourceFiles as $cppFile) { $objectFile = $this->getObjectFile($cppFile); - + try { $this->compileFile($cppFile, $objectFile, false); if (is_file($objectFile)) { @@ -954,7 +954,7 @@ CODE; public function build(array $objectFiles): void { $targetFile = $this->targetName; - + // 根据平台设置目标文件扩展名 if ($this->isWindows()) { if ($this->buildMode == 'ext') { @@ -971,12 +971,12 @@ CODE; $targetFile .= '.so'; } } - + // 根据平台构建链接命令 if ($this->isWindows()) { // Windows 使用 link.exe 或 lld-link 进行链接 $objectList = implode(' ', $objectFiles); - + // 使用检测到的链接器(lld-link 或 link) $linkerCmd = $this->linker; $linkCmd = "{$linkerCmd} /nologo {$objectList} /OUT:{$targetFile}"; @@ -985,30 +985,30 @@ CODE; $objectList = implode(' ', $objectFiles); $linkCmd = $this->cppCompiler . ' ' . $objectList . ' -o ' . $targetFile; } - + $this->addCompilationOption($linkCmd, true); $this->climate->comment($linkCmd); - + // 执行链接并捕获输出 exec($linkCmd . ' 2>&1', $output, $ret); - + // 显示输出(如果有) if (!empty($output)) { foreach ($output as $line) { $this->climate->out($line); } } - + // 检查链接是否成功 if ($ret !== 0) { $this->error('link failed: ' . $targetFile); } - + // 验证目标文件是否生成 if (!file_exists($targetFile)) { $this->error('target file not generated: ' . $targetFile); } - + $this->climate->green('Build successful: ' . $targetFile); } @@ -1260,7 +1260,7 @@ CODE; } else { $list = $this->getFilesFromDir($projectDir); } - + // 读取 cxxflags(支持中横线和下划线) $cxxflags = $cfg['cxx-flags'] ?? $cfg['cxxflags'] ?? null; if (!empty($cxxflags)) { @@ -1270,13 +1270,13 @@ CODE; $this->cxxflags = str_replace("\n", ' ', $cxxflags); } } - + // 读取 C++ 标准版本(支持中横线和下划线) $cxxStd = $cfg['cxx-std'] ?? $cfg['cxx_std'] ?? null; if (!empty($cxxStd)) { $this->cxxStd = $cxxStd; } - + // 读取 ldflags(支持中横线和下划线) $ldflags = $cfg['ld-flags'] ?? $cfg['ldflags'] ?? null; if (!empty($ldflags)) { @@ -1286,12 +1286,12 @@ CODE; $this->ldflags = str_replace("\n", ' ', $ldflags); } } - + // 读取 name if (!empty($cfg['name'])) { $this->setTargetName($cfg['name']); } - + // 读取 type/build-mode(支持中横线和下划线) $buildMode = $cfg['build-mode'] ?? $cfg['type'] ?? null; if (!empty($buildMode)) {