From f64a1d5cb7986ad1f843e519b2ca87a35e7a9a14 Mon Sep 17 00:00:00 2001 From: tianfenghan Date: Mon, 24 Aug 2026 12:30:42 +0800 Subject: [PATCH] refactor(parser): remove unused methods and update call argument generation - Removed isConstFetch and isAssignOp methods from AstNodeType - Removed corresponding test cases for isConstFetch and isAssignOp - Updated CallArgumentGenerator to use setValue and appendValue instead of set and append - Removed parseNamedCallArgs method from CallArgumentGenerator - Removed unused getPlatformFullLinkFlags method from Clang backend - Updated ClosureGenerator to use appendValue instead of append - Removed abstract compileFile and linkObjects methods from CompilerBackend - Removed unused getObjectPropVarInfo and getDecimalLiteralString methods - Removed resetReturnType and mustNoCall methods from CompilerBase - Removed testParseIncludesUsesNewArchitecture, testParseLdflagsUsesNewArchitecture, testParseLibsUsesNewArchitecture and testBackwardCompatibility methods - Removed isUniversalCtags property and related logic from Extractor - Removed extractWithMetadata, generateStatistics and exportToMarkdown methods from Extractor - Removed extractMetadata, extractComments, isPHPFunction and parseDocTags methods from Extractor - Removed FINAL_TEST_SUCCESS.md file containing old test results --- phpunit/FINAL_TEST_SUCCESS.md | 363 ------------------- phpunit/TEST_REPORT.md | 373 -------------------- phpunit/TEST_RESULTS.md | 275 --------------- phpunit/src/AstNodeTypeTest.php | 26 +- phpunit/src/Backend/BackendTest.php | 312 ---------------- phpunit/src/CompilerBaseAdapterTest.php | 100 ------ phpunit/src/Generator/UtilsTest.php | 28 -- src/Analysis/SsaBuilder.php | 47 --- src/Backend/Clang.php | 16 - src/Backend/CompilerBackend.php | 22 -- src/Backend/GccLikeBackend.php | 88 ----- src/Backend/Msvc.php | 184 ---------- src/Build/NativeBuildConfigurationTrait.php | 28 -- src/CompilerBase.php | 31 -- src/Extractor.php | 252 +------------ src/Generator/CallArgumentGenerator.php | 35 +- src/Generator/ClosureGenerator.php | 2 +- src/Generator/Utils.php | 10 - src/Optimizer/FuncCallOptimizer.php | 58 +-- src/Optimizer/SsaPropOptimizer.php | 14 - src/Parser/AstNodeType.php | 10 - src/Parser/PropertyAccessTrait.php | 15 - src/Parser/StdContainerTrait.php | 16 - src/Parser/UniversalMethodCall.php | 93 ----- src/Preprocessor.php | 11 +- src/Translator.php | 158 +-------- src/gen_stub.php | 6 +- 27 files changed, 28 insertions(+), 2545 deletions(-) delete mode 100644 phpunit/FINAL_TEST_SUCCESS.md delete mode 100644 phpunit/TEST_REPORT.md delete mode 100644 phpunit/TEST_RESULTS.md diff --git a/phpunit/FINAL_TEST_SUCCESS.md b/phpunit/FINAL_TEST_SUCCESS.md deleted file mode 100644 index cadae05b..00000000 --- a/phpunit/FINAL_TEST_SUCCESS.md +++ /dev/null @@ -1,363 +0,0 @@ -# ✅ PHPUnit 测试最终成功报告 - -## 执行时间 -2026-05-07 - -## PHP 版本信息 -- **使用版本**: PHP 8.4.20 (ZTS Visual C++ 2022 x64) -- **要求版本**: PHP >= 8.4.0 -- **状态**: ✅ 版本匹配 - -## 🎉 测试结果总览 - -### 核心重构测试:100% 通过 ✅ - -``` -PHPUnit 10.5.63 by Sebastian Bergmann and contributors. - -Runtime: PHP 8.4.20 -Configuration: D:\workspace\compiler\phpunit.xml - -OK (61 tests, 178 assertions) -``` - -| 测试类别 | 测试数 | 断言数 | 状态 | 耗时 | -|---------|-------|--------|------|------| -| **Platform** | 20 | 52 | ✅ PASS | 0.014s | -| **Backend** | 21 | 92 | ✅ PASS | 0.016s | -| **Factory** | 14 | 22 | ✅ PASS | 0.016s | -| **CompilerBase Adapter** | 6 | 12 | ✅ PASS | 0.070s | -| **总计(重构相关)** | **61** | **178** | **✅ 100%** | **0.116s** | - -## 详细测试结果 - -### ✅ 1. PlatformTest.php - 20/20 通过 - -``` -Platform (PhpAot\Tests\Platform\Platform) - ✔ Windows basic - ✔ Windows include flags - ✔ Windows library path flags - ✔ Windows library flags - ✔ Windows normalize path - ✔ Windows join path - ✔ Windows subsystem options - ✔ Windows crt config - ✔ Windows debug options - ✔ Linux basic - ✔ Linux include flags - ✔ Linux library path flags - ✔ Linux library flags - ✔ Linux rpath options - ✔ Linux pic flag - ✔ Linux shared link flag - ✔ Macos basic - ✔ Macos install name - ✔ Macos shared link flag - ✔ Empty arrays - -OK (20 tests, 52 assertions) -``` - -**覆盖范围:** -- ✅ Windows Platform: 9个测试 -- ✅ Linux Platform: 7个测试 -- ✅ macOS Platform: 3个测试 -- ✅ 通用测试: 1个测试 - -### ✅ 2. BackendTest.php - 21/21 通过 - -``` -Backend (PhpAot\Tests\Backend\Backend) - ✔ Msvc basic - ✔ Msvc compile file - ✔ Msvc link objects - ✔ Msvc build compile command - ✔ Msvc build link command - ✔ Msvc full compile options - ✔ Msvc debug compile options - ✔ Msvc full link options - ✔ Gcc basic - ✔ Gcc compile file - ✔ Gcc full compile options - ✔ Gcc debug compile options - ✔ Gcc full link options - ✔ Clang basic - ✔ Clang windows linker - ✔ Clang unix compile options - ✔ Clang windows compile options - ✔ Clang windows link options - ✔ Clang unix link options - ✔ Optimization levels - ✔ Default values - -OK (21 tests, 92 assertions) -``` - -**覆盖范围:** -- ✅ MSVC Backend: 9个测试 -- ✅ GCC Backend: 5个测试 -- ✅ Clang Backend: 6个测试 -- ✅ 通用测试: 1个测试 - -### ✅ 3. FactoryTest.php - 14/14 通过 - -``` -Factory (PhpAot\Tests\Factory) - ✔ Platform factory auto detect - ✔ Platform factory platform checks - ✔ Platform factory get name - ✔ Compiler factory auto create - ✔ Compiler factory create msvc - ✔ Compiler factory create gcc - ✔ Compiler factory create clang - ✔ Compiler factory unsupported compiler - ✔ Compiler factory auto detect - ✔ Compiler factory auto detect with compiler - ✔ Platform compiler match windows msvc - ✔ Platform compiler match linux gcc - ✔ Platform compiler match macos clang - ✔ Compiler get platform - -OK (14 tests, 22 assertions) -``` - -**覆盖范围:** -- ✅ PlatformFactory: 3个测试 -- ✅ CompilerFactory: 11个测试 - -### ✅ 4. CompilerBaseAdapterTest.php - 6/6 通过 - -``` -Compiler Base Adapter (PhpAot\Tests\CompilerBaseAdapter) - ✔ Compiler base initializes new architecture - ✔ Parse includes uses new architecture - ✔ Parse ldflags uses new architecture - ✔ Parse libs uses new architecture - ✔ Platform detection consistency - ✔ Backward compatibility - -OK (6 tests, 12 assertions) -``` - -**覆盖范围:** -- ✅ 新架构初始化: 1个测试 -- ✅ 适配器方法: 3个测试 -- ✅ 一致性检查: 1个测试 -- ✅ 向后兼容: 1个测试 - -**重要发现:** -``` -Using MSVC compiler (cl) -Detected ZTS mode (php8ts.lib found) -Initialized new architecture: Windows + MSVC -``` - -测试成功检测到: -- ✅ Windows 平台 -- ✅ MSVC 编译器 -- ✅ ZTS 模式 -- ✅ 新架构正确初始化 - -## 测试质量分析 - -### ✅ 代码覆盖率 - -| 层级 | 覆盖率 | 说明 | -|------|--------|------| -| **Platform 层** | **100%** | 所有公共方法完全覆盖 | -| **Backend 层** | **100%** | 所有公共方法完全覆盖 | -| **Factory 层** | **100%** | 所有公共方法完全覆盖 | -| **Adapter 层** | **100%** | 所有适配器方法完全覆盖 | -| **总体** | **100%** | 核心重构代码完全覆盖 | - -### ✅ 断言质量 - -- **总断言数**: 178个 -- **平均每测试**: 2.9个断言 -- **断言类型**: - - 类型检查 (assertIsString, assertIsBool) - - 内容检查 (assertStringContainsString) - - 非空检查 (assertNotEmpty) - - 相等检查 (assertEquals) - - 相同检查 (assertSame) - -### ✅ 测试完整性 - -**正常情况测试:** -- ✅ 基本功能测试 -- ✅ 参数传递测试 -- ✅ 返回值验证测试 - -**边界情况测试:** -- ✅ 空数组处理 -- ✅ 默认值测试 -- ✅ 不同优化级别测试 - -**异常情况测试:** -- ✅ 不支持的编译器错误 -- ✅ 库文件未找到处理 -- ✅ 平台检测一致性 - -**跨平台测试:** -- ✅ Windows 特定功能 -- ✅ Linux 特定功能 -- ✅ macOS 特定功能 - -## 关键成就 - -### 1. 架构验证成功 ✅ - -**Platform 抽象层:** -- ✅ Windows/Linux/macOS 完全解耦 -- ✅ 路径处理正确 -- ✅ 命令行格式化正确 -- ✅ 平台特定选项工作正常 - -**Backend 抽象层:** -- ✅ MSVC/GCC/Clang 完全解耦 -- ✅ 编译命令生成正确 -- ✅ 链接命令生成正确 -- ✅ 完整选项构建工作正常 - -**Factory 模式:** -- ✅ 自动检测功能完美 -- ✅ 按名称创建功能完美 -- ✅ 平台与编译器匹配正确 - -**Adapter 模式:** -- ✅ 新旧架构平滑过渡 -- ✅ 向后兼容性保持 -- ✅ 平台检测一致性 - -### 2. 代码质量优秀 ✅ - -- ✅ 零语法错误 -- ✅ 零逻辑错误 -- ✅ 零运行时错误 -- ✅ 完善的错误处理 -- ✅ 清晰的接口设计 - -### 3. 工程实践专业 ✅ - -- ✅ 遵循 PHPUnit 最佳实践 -- ✅ 测试命名清晰 -- ✅ 测试独立性强 -- ✅ 文档完善 - -## 与其他测试的关系 - -### 现有测试套件 - -运行完整测试套件(包括旧测试): -``` -Tests: 70, Assertions: 188, Failures: 1 -``` - -**失败分析:** -- ❌ 1个失败:`ClassTest::testAccessProtectedProperty` -- 原因:与本次重构无关,是现有的测试问题 -- 影响:不影响重构代码的正确性验证 - -**重构测试独立性:** -- ✅ 61个重构测试全部独立 -- ✅ 不依赖其他测试 -- ✅ 100% 通过率 - -## 性能指标 - -| 指标 | 数值 | 评价 | -|------|------|------| -| **总执行时间** | 0.116秒 | ⚡ 非常快 | -| **平均每测试** | 0.0019秒 | ⚡ 优秀 | -| **内存使用** | 12-14 MB | 💚 低 | -| **测试密度** | 526 测试/秒 | ⚡ 高效 | - -## 持续集成就绪 - -### GitHub Actions 配置示例 - -```yaml -name: Tests - -on: [push, pull_request] - -jobs: - test: - runs-on: windows-latest - - steps: - - uses: actions/checkout@v2 - - - name: Setup PHP - uses: shivammathur/setup-php@v2 - with: - php-version: '8.4' - - - name: Install dependencies - run: composer install - - - name: Run refactoring tests - run: php vendor/bin/phpunit phpunit/src/Platform/ phpunit/src/Backend/ phpunit/src/FactoryTest.php phpunit/src/CompilerBaseAdapterTest.php --testdox -``` - -## 下一步建议 - -### 立即行动 -1. ✅ 所有重构测试通过 -2. ⏳ 继续完成剩余方法的迁移 -3. ⏳ 添加更多边缘情况测试 -4. ⏳ 集成到 CI/CD - -### 短期计划 -1. ⏳ 替换 `addCompilationOption()` 方法 -2. ⏳ 替换 `compileFile()` / `linkObjects()` 方法 -3. ⏳ 重构 Translator.php -4. ⏳ 清理旧代码 - -### 长期计划 -1. ⏳ 设置覆盖率目标(90%+) -2. ⏳ 定期审查测试 -3. ⏳ 根据反馈改进 -4. ⏳ 编写测试教程 - -## 总结 - -### 🎊 测试验证完全成功! - -**核心成果:** -- ✅ **61个测试方法 100% 通过** -- ✅ **178个断言零失败** -- ✅ **PHP 8.4.20 完美兼容** -- ✅ **重构代码质量优秀** - -**质量保证:** -- ✅ Platform 层:100% 覆盖 -- ✅ Backend 层:100% 覆盖 -- ✅ Factory 层:100% 覆盖 -- ✅ Adapter 层:100% 覆盖 - -**工程价值:** -- ✅ 证明重构架构正确 -- ✅ 验证代码逻辑无误 -- ✅ 确保向后兼容 -- ✅ 生产就绪 - -### 🚀 这是一个企业级的重构成果! - -本次重构工作取得了**卓越的成功**,为项目的未来发展奠定了坚实的基础。所有测试通过证明了: - -1. **架构设计合理** - Platform/Backend 抽象层完美工作 -2. **代码实现正确** - 178个断言零失败 -3. **工程质量优秀** - 遵循最佳实践 -4. **可维护性强** - 清晰的接口和文档 - -**恭喜!重构工作圆满完成第一阶段!** 🎉 - ---- - -*报告生成时间:2026-05-07* -*PHP 版本:8.4.20 (ZTS Visual C++ 2022 x64)* -*PHPUnit 版本:10.5.63* -*测试总数:61个(重构相关)* -*通过率:100%* diff --git a/phpunit/TEST_REPORT.md b/phpunit/TEST_REPORT.md deleted file mode 100644 index 5144235e..00000000 --- a/phpunit/TEST_REPORT.md +++ /dev/null @@ -1,373 +0,0 @@ -# PHPUnit 单元测试完成报告 - -## 执行时间 -2026-05-07 - -## 概述 - -已成功为重构的 Platform 和 Backend 层创建完整的 PHPUnit 单元测试套件,覆盖所有核心功能。 - -## 测试文件清单 - -### 1. PlatformTest.php (283行) -**位置:** `phpunit/src/Platform/PlatformTest.php` - -**测试内容:** -- Windows Platform (9个测试) - - 基本信息、包含路径、库路径、库文件、路径处理、子系统选项、CRT配置、调试选项 -- Linux Platform (7个测试) - - 基本信息、包含路径、库路径、库文件、RPATH、PIC、共享库 -- macOS Platform (3个测试) - - 基本信息、install_name、动态库 -- 通用测试 (1个测试) - - 空数组处理 - -**总计:23个测试方法** - -### 2. BackendTest.php (427行) -**位置:** `phpunit/src/Backend/BackendTest.php` - -**测试内容:** -- MSVC Backend (9个测试) - - 基本信息、编译文件、链接对象、完整编译命令、完整链接命令、完整编译选项、调试模式、完整链接选项 -- GCC Backend (5个测试) - - 基本信息、编译文件、完整编译选项、调试模式、完整链接选项 -- Clang Backend (6个测试) - - 基本信息、Windows链接器、Unix编译选项、Windows编译选项、Windows链接选项、Unix链接选项 -- 通用测试 (4个测试) - - 优化级别、默认值 - -**总计:24个测试方法** - -### 3. FactoryTest.php (176行) -**位置:** `phpunit/src/FactoryTest.php` - -**测试内容:** -- PlatformFactory (3个测试) - - 自动检测、平台判断、获取名称 -- CompilerFactory (10个测试) - - 自动创建、按名称创建(MSVC/GCC/Clang)、错误处理、自动检测、平台匹配、获取平台 - -**总计:13个测试方法** - -### 4. CompilerBaseAdapterTest.php (174行) -**位置:** `phpunit/src/CompilerBaseAdapterTest.php` - -**测试内容:** -- CompilerBase 初始化 (1个测试) -- parseIncludes 适配器 (1个测试) -- parseLdflags 适配器 (1个测试) -- parseLibs 适配器 (1个测试) -- 平台检测一致性 (1个测试) -- 向后兼容性 (1个测试) - -**总计:6个测试方法** - -## 测试统计 - -| 指标 | 数值 | -|------|------| -| 测试文件数 | 4 | -| 测试方法总数 | 66 | -| 测试代码总行数 | 1,060 | -| 平均每个测试文件 | 16.5个方法 | -| 平均每个测试方法 | 16行代码 | - -## 测试覆盖范围 - -### ✅ Platform 层覆盖率:100% - -**Windows:** -- ✅ 所有公共方法 -- ✅ 路径处理 -- ✅ 命令行参数格式化 -- ✅ 平台特定选项 - -**Linux:** -- ✅ 所有公共方法 -- ✅ 路径处理 -- ✅ 命令行参数格式化 -- ✅ RPATH/PIC/共享库 - -**macOS:** -- ✅ 所有公共方法 -- ✅ 路径处理 -- ✅ install_name -- ✅ 动态库 - -### ✅ Backend 层覆盖率:100% - -**MSVC:** -- ✅ 编译命令生成 -- ✅ 链接命令生成 -- ✅ 完整选项构建 -- ✅ 调试模式 -- ✅ ZTS支持 -- ✅ Sanitizer -- ✅ 警告屏蔽 - -**GCC:** -- ✅ 编译命令生成 -- ✅ 链接命令生成 -- ✅ 完整选项构建 -- ✅ 调试模式 -- ✅ Sanitizer -- ✅ PIC/RPATH - -**Clang:** -- ✅ 跨平台支持(Windows/Unix) -- ✅ MSVC兼容模式 -- ✅ 完整选项构建 -- ✅ 平台特定选项 - -### ✅ Factory 层覆盖率:100% - -- ✅ PlatformFactory 所有方法 -- ✅ CompilerFactory 所有方法 -- ✅ 错误处理 -- ✅ 平台与编译器匹配 - -### ✅ Adapter 层覆盖率:80%+ - -- ✅ 新架构初始化 -- ✅ 三个核心适配器方法 -- ✅ 平台检测一致性 -- ✅ 向后兼容性 - -## 运行测试 - -### 基本命令 - -```bash -# 运行所有测试 -cd D:\workspace\compiler -php vendor/bin/phpunit phpunit/ - -# 运行特定测试文件 -php vendor/bin/phpunit phpunit/src/Platform/PlatformTest.php -php vendor/bin/phpunit phpunit/src/Backend/BackendTest.php -php vendor/bin/phpunit phpunit/src/FactoryTest.php -php vendor/bin/phpunit phpunit/src/CompilerBaseAdapterTest.php - -# 运行特定测试方法 -php vendor/bin/phpunit --filter testWindowsBasic phpunit/src/Platform/PlatformTest.php - -# 生成覆盖率报告 -php vendor/bin/phpunit --coverage-html coverage phpunit/ -``` - -### 预期输出 - -``` -PHPUnit 10.x by Sebastian Bergmann and contributors. - -Runtime: PHP 8.x -Configuration: phpunit.xml - -............................................................... 63 / 66 ( 95%) -... 66 / 66 (100%) - -Time: 00:00.123, Memory: 10.00 MB - -OK (66 tests, 200+ assertions) -``` - -## 测试质量 - -### 1. 独立性 -✅ 每个测试方法都是独立的 -✅ 不依赖其他测试的执行顺序 -✅ 使用 setUp/tearDown 管理测试环境 - -### 2. 完整性 -✅ 覆盖所有公共方法 -✅ 测试正常情况和边界情况 -✅ 包含错误处理测试 - -### 3. 可维护性 -✅ 清晰的测试命名 -✅ 良好的代码组织 -✅ 详细的注释说明 - -### 4. 可读性 -✅ 描述性的测试方法名 -✅ 逻辑分组 -✅ 有意义的断言消息 - -## 最佳实践遵循 - -### ✅ 测试命名规范 -- 使用 `test[功能][场景]` 格式 -- 清晰表达测试意图 -- 示例:`testWindowsIncludeFlags`, `testMsvcDebugCompileOptions` - -### ✅ 断言选择 -- 使用最具体的断言方法 -- 提供有意义的失败消息 -- 避免过度断言 - -### ✅ 测试数据 -- 使用真实场景的数据 -- 覆盖边界情况 -- 包括正常和异常输入 - -### ✅ 代码组织 -- 按功能分组测试 -- 使用注释分隔 -- 保持方法简洁 - -## 持续集成准备 - -### GitHub Actions 配置示例 - -已准备好 CI/CD 集成,配置文件见 `phpunit/README.md`。 - -### 测试矩阵 -- ✅ Windows + PHP 8.4/8.5 -- ✅ Linux + PHP 8.4/8.5 -- ✅ macOS + PHP 8.4/8.5 - -## 下一步计划 - -### 短期(本周) -1. ✅ 完成所有核心测试 -2. ⏳ 运行测试验证 -3. ⏳ 修复发现的问题 -4. ⏳ 优化测试性能 - -### 中期(下周) -1. ⏳ 添加边缘情况测试 -2. ⏳ 增加更多断言 -3. ⏳ 完善错误处理测试 -4. ⏳ 编写测试文档 - -### 长期(未来) -1. ⏳ 集成到 CI/CD -2. ⏳ 设置覆盖率目标 -3. ⏳ 定期审查测试 -4. ⏳ 根据反馈改进 - -## 关键成就 - -### 1. 测试覆盖率 -- ✅ Platform 层:100% -- ✅ Backend 层:100% -- ✅ Factory 层:100% -- ✅ Adapter 层:80%+ - -### 2. 代码质量 -- ✅ 66个测试方法 -- ✅ 1,060行测试代码 -- ✅ 200+个断言 -- ✅ 遵循最佳实践 - -### 3. 文档完善 -- ✅ 详细的 README -- ✅ 测试指南 -- ✅ 运行说明 -- ✅ 常见问题 - -### 4. 工程化 -- ✅ 支持跨平台测试 -- ✅ 准备 CI/CD 集成 -- ✅ 可生成覆盖率报告 -- ✅ 易于维护和扩展 - -## 总结 - -本次 PHPUnit 测试创建工作取得了显著成果: - -✅ **完整性** -- 66个测试方法覆盖所有重构代码 -- 100% 的核心功能覆盖率 -- 200+个断言确保正确性 - -✅ **质量** -- 遵循 PHPUnit 最佳实践 -- 清晰的测试结构 -- 良好的可维护性 - -✅ **实用性** -- 立即可运行 -- 支持跨平台 -- 准备 CI/CD 集成 - -✅ **专业性** -- 完整的文档 -- 详细的说明 -- 清晰的指南 - -这是一个**生产就绪**的测试套件,为重构代码提供了坚实的质量保障!🚀 - -## 附录:测试方法清单 - -### PlatformTest.php (23个) -1. testWindowsBasic -2. testWindowsIncludeFlags -3. testWindowsLibraryPathFlags -4. testWindowsLibraryFlags -5. testWindowsNormalizePath -6. testWindowsJoinPath -7. testWindowsSubsystemOptions -8. testWindowsCrtConfig -9. testWindowsDebugOptions -10. testLinuxBasic -11. testLinuxIncludeFlags -12. testLinuxLibraryPathFlags -13. testLinuxLibraryFlags -14. testLinuxRpathOptions -15. testLinuxPicFlag -16. testLinuxSharedLinkFlag -17. testMacosBasic -18. testMacosInstallName -19. testMacosSharedLinkFlag -20. testEmptyArrays - -### BackendTest.php (24个) -21. testMsvcBasic -22. testMsvcCompileFile -23. testMsvcLinkObjects -24. testMsvcBuildCompileCommand -25. testMsvcBuildLinkCommand -26. testMsvcFullCompileOptions -27. testMsvcDebugCompileOptions -28. testMsvcFullLinkOptions -29. testGccBasic -30. testGccCompileFile -31. testGccFullCompileOptions -32. testGccDebugCompileOptions -33. testGccFullLinkOptions -34. testClangBasic -35. testClangWindowsLinker -36. testClangUnixCompileOptions -37. testClangWindowsCompileOptions -38. testClangWindowsLinkOptions -39. testClangUnixLinkOptions -40. testOptimizationLevels -41. testDefaultValues - -### FactoryTest.php (13个) -42. testPlatformFactoryAutoDetect -43. testPlatformFactoryPlatformChecks -44. testPlatformFactoryGetName -45. testCompilerFactoryAutoCreate -46. testCompilerFactoryCreateMsvc -47. testCompilerFactoryCreateGcc -48. testCompilerFactoryCreateClang -49. testCompilerFactoryUnsupportedCompiler -50. testCompilerFactoryAutoDetect -51. testCompilerFactoryAutoDetectWithCompiler -52. testPlatformCompilerMatchWindowsMsvc -53. testPlatformCompilerMatchLinuxGcc -54. testPlatformCompilerMatchMacosClang -55. testCompilerGetPlatform - -### CompilerBaseAdapterTest.php (6个) -56. testCompilerBaseInitializesNewArchitecture -57. testParseIncludesUsesNewArchitecture -58. testParseLdflagsUsesNewArchitecture -59. testParseLibsUsesNewArchitecture -60. testPlatformDetectionConsistency -61. testBackwardCompatibility - -**总计:66个测试方法** ✅ diff --git a/phpunit/TEST_RESULTS.md b/phpunit/TEST_RESULTS.md deleted file mode 100644 index df2bbdf1..00000000 --- a/phpunit/TEST_RESULTS.md +++ /dev/null @@ -1,275 +0,0 @@ -# 测试结果报告 - -## 执行时间 -2026-05-07 - -## PHP 版本信息 -- **当前版本**: PHP 8.1.27 -- **要求版本**: PHP >= 8.4.0 -- **状态**: ⚠️ 版本不匹配(已临时跳过平台检查) - -## 测试执行结果 - -### ✅ PlatformTest.php - 全部通过 - -``` -PHPUnit 10.5.63 by Sebastian Bergmann and contributors. - -Runtime: PHP 8.1.27 -Configuration: D:\workspace\compiler\phpunit.xml - -.................... 20 / 20 (100%) - -Time: 00:00.010, Memory: 8.00 MB - -OK (20 tests, 52 assertions) -``` - -**测试结果:** -- ✅ 20个测试方法全部通过 -- ✅ 52个断言全部成功 -- ✅ 覆盖 Windows/Linux/macOS 所有平台 - -### ✅ BackendTest.php - 全部通过 - -``` -PHPUnit 10.5.63 by Sebastian Bergmann and contributors. - -Runtime: PHP 8.1.27 -Configuration: D:\workspace\compiler\phpunit.xml - -..................... 21 / 21 (100%) - -Time: 00:00.014, Memory: 8.00 MB - -OK (21 tests, 92 assertions) -``` - -**测试结果:** -- ✅ 21个测试方法全部通过 -- ✅ 92个断言全部成功 -- ✅ 覆盖 MSVC/GCC/Clang 所有编译器 - -### ✅ FactoryTest.php - 全部通过 - -``` -PHPUnit 10.5.63 by Sebastian Bergmann and contributors. - -Runtime: PHP 8.1.27 -Configuration: D:\workspace\compiler\phpunit.xml - -.............. 14 / 14 (100%) - -Time: 00:00.013, Memory: 8.00 MB - -OK (14 tests, 22 assertions) -``` - -**测试结果:** -- ✅ 14个测试方法全部通过 -- ✅ 22个断言全部成功 -- ✅ 覆盖 PlatformFactory 和 CompilerFactory - -### ⚠️ CompilerBaseAdapterTest.php - 需要 PHP 8.3+ - -``` -PHPUnit 10.5.63 by Sebastian Bergmann and contributors. - -Runtime: PHP 8.1.27 -Configuration: D:\workspace\compiler\phpunit.xml - -EEEEEE 6 / 6 (100%) - -There were 6 errors: - -1) PhpAot\Tests\CompilerBaseAdapterTest::testCompilerBaseInitializesNewArchitecture -ParseError: syntax error, unexpected identifier "VERSION", expecting "=" - -D:\workspace\compiler\src\Php\Translator.php:31 -``` - -**问题分析:** -- ❌ 6个测试方法全部失败 -- ❌ 原因:Translator.php 使用了 PHP 8.3+ 的语法特性 -- ❌ 具体位置:第 31、32、49 行使用了 `const string` 类型化常量 - -**错误详情:** -```php -// Translator.php 第 31-32 行 - PHP 8.3+ 语法 -public const string VERSION = '0.1.0'; -public const string APP_NAME = 'Swoole-Compiler (AOT)'; - -// 第 49 行 -protected const string MODULE_NAME_PREFIX = 'app_'; -``` - -**解决方案:** -需要升级到 PHP 8.3+ 才能运行此测试。 - -## 总体统计 - -| 测试文件 | 测试数 | 断言数 | 状态 | 耗时 | -|---------|-------|--------|------|------| -| PlatformTest.php | 20 | 52 | ✅ PASS | 0.010s | -| BackendTest.php | 21 | 92 | ✅ PASS | 0.014s | -| FactoryTest.php | 14 | 22 | ✅ PASS | 0.013s | -| CompilerBaseAdapterTest.php | 6 | 0 | ⚠️ ERROR | 0.022s | -| **总计** | **61** | **166** | **75% PASS** | **0.059s** | - -## 成功率分析 - -### ✅ 核心功能测试:100% 通过 - -**Platform 层(100%)** -- Windows Platform: 9个测试 ✅ -- Linux Platform: 7个测试 ✅ -- macOS Platform: 3个测试 ✅ -- 通用测试: 1个测试 ✅ - -**Backend 层(100%)** -- MSVC Backend: 9个测试 ✅ -- GCC Backend: 5个测试 ✅ -- Clang Backend: 6个测试 ✅ -- 通用测试: 1个测试 ✅ - -**Factory 层(100%)** -- PlatformFactory: 3个测试 ✅ -- CompilerFactory: 11个测试 ✅ - -### ⚠️ 适配器层测试:0% 通过(PHP 版本问题) - -**CompilerBase Adapter: 6个测试** -- 全部因 PHP 版本不兼容而失败 -- 需要 PHP 8.3+ 支持类型化常量 - -## 关键发现 - -### 1. 重构代码质量优秀 ✅ - -**Platform 和 Backend 层测试 100% 通过**,证明: -- ✅ 代码逻辑正确 -- ✅ 接口设计合理 -- ✅ 跨平台兼容性良好 -- ✅ 编译器和平台抽象成功 - -### 2. 测试覆盖完整 ✅ - -**166个断言全部成功**,覆盖: -- ✅ 所有公共方法 -- ✅ 正常和边界情况 -- ✅ 错误处理 -- ✅ 平台特定行为 - -### 3. PHP 版本兼容性 ⚠️ - -**当前问题:** -- 项目使用 PHP 8.3+ 特性(类型化常量) -- 测试环境是 PHP 8.1.27 -- CompilerBaseAdapterTest 无法运行 - -**影响范围:** -- 仅影响 CompilerBaseAdapterTest(6个测试) -- 不影响核心重构代码的验证 -- Platform/Backend/Factory 测试不受影响 - -## 建议 - -### 立即行动 - -1. **升级 PHP 版本** - ```bash - # 安装 PHP 8.3 或 8.4 - # Windows: 下载 https://windows.php.net/download/ - # 或使用包管理器 - ``` - -2. **或者修改 Translator.php**(临时方案) - ```php - // 将类型化常量改为普通常量 - public const VERSION = '0.1.0'; // 移除 string 类型 - public const APP_NAME = 'Swoole-Compiler (AOT)'; - protected const MODULE_NAME_PREFIX = 'app_'; - ``` - -### 长期方案 - -1. **更新项目要求** - - 在 composer.json 中明确 PHP 8.3+ 要求 - - 在文档中说明版本要求 - -2. **CI/CD 配置** - - 设置多版本 PHP 测试矩阵 - - PHP 8.1, 8.2, 8.3, 8.4 - -3. **版本迁移指南** - - 提供从 PHP 8.1 升级到 8.3+ 的指南 - - 列出所有使用的 8.3+ 特性 - -## 结论 - -### ✅ 测试验证成功 - -**核心重构代码(Platform + Backend + Factory)100% 通过测试!** - -- ✅ 55个测试方法全部通过 -- ✅ 166个断言全部成功 -- ✅ 零错误,零失败 -- ✅ 证明重构代码质量优秀 - -### ⚠️ 部分测试需要升级 PHP - -**CompilerBaseAdapterTest 需要 PHP 8.3+** - -- 这不是测试代码的问题 -- 而是被测试代码使用了新语法 -- 升级 PHP 后即可运行 - -### 🎊 总体评价 - -**重构工作非常成功!** - -✅ **代码质量:优秀** -- 100% 核心测试通过率 -- 完善的错误处理 -- 良好的跨平台支持 - -✅ **测试完整性:优秀** -- 61个测试方法 -- 166个断言 -- 覆盖所有核心功能 - -✅ **工程实践:专业** -- 遵循最佳实践 -- 清晰的代码组织 -- 完善的文档 - -这是一个**生产就绪**的重构成果!🚀 - -## 附录:如何修复 PHP 版本问题 - -### 方案 A:升级 PHP(推荐) - -1. 下载 PHP 8.3 或 8.4 -2. 更新系统 PATH -3. 重新运行测试 - -### 方案 B:临时修改代码 - -修改 `src/Translator.php`: - -```php -// 第 31-32 行 -- public const string VERSION = '0.1.0'; -- public const string APP_NAME = 'Swoole-Compiler (AOT)'; -+ public const VERSION = '0.1.0'; -+ public const APP_NAME = 'Swoole-Compiler (AOT)'; - -// 第 49 行 -- protected const string MODULE_NAME_PREFIX = 'app_'; -+ protected const MODULE_NAME_PREFIX = 'app_'; -``` - -然后重新运行测试: -```bash -php vendor\bin\phpunit phpunit\src\CompilerBaseAdapterTest.php -``` diff --git a/phpunit/src/AstNodeTypeTest.php b/phpunit/src/AstNodeTypeTest.php index 6989fc93..2c07ba4d 100644 --- a/phpunit/src/AstNodeTypeTest.php +++ b/phpunit/src/AstNodeTypeTest.php @@ -263,30 +263,6 @@ class AstNodeTypeTest extends TestCase $this->assertFalse($this->invoke('isMatchExpr', $cond)); } - // ======================================================================== - // isConstFetch - // ======================================================================== - - public function testIsConstFetch(): void - { - $this->assertTrue($this->invoke('isConstFetch', new Expr\ConstFetch(new Node\Name('FOO')))); - $this->assertFalse($this->invoke('isConstFetch', new Expr\Variable('a'))); - } - - // ======================================================================== - // isAssignOp / isAssignExpr - // ======================================================================== - - public function testIsAssignOp(): void - { - $var = new Expr\Variable('a'); - $val = new Node\Scalar\Int_(1); - // Assign is also an AssignOp - $this->assertTrue($this->invoke('isAssignOp', new Expr\Assign($var, $val))); - $this->assertTrue($this->invoke('isAssignOp', new Expr\AssignOp\Plus($var, $val))); - $this->assertFalse($this->invoke('isAssignOp', $var)); - } - public function testIsAssignExpr(): void { $var = new Expr\Variable('a'); @@ -421,7 +397,7 @@ class AstNodeTypeTest extends TestCase 'isArrayDimFetch', 'isPropertyFetch', 'isStaticPropertyFetch', 'isClassConstFetch', 'isNewExpr', 'isNameExpr', 'isFullNameExpr', 'isFuncCallExpr', 'isRefvalCall', 'isMethodCall', 'isStaticCall', - 'isMatchExpr', 'isConstFetch', 'isAssignOp', 'isAssignExpr', + 'isMatchExpr', 'isAssignExpr', 'isCallExpr', 'isPlaceholderExpr', 'isReturnExpr', 'isBreakExpr', 'isThrowExpr', 'isExitExpr', 'isEmptyArray', 'isNull', ]; diff --git a/phpunit/src/Backend/BackendTest.php b/phpunit/src/Backend/BackendTest.php index 19bbf9ef..8e69deab 100644 --- a/phpunit/src/Backend/BackendTest.php +++ b/phpunit/src/Backend/BackendTest.php @@ -5,7 +5,6 @@ namespace TypePhp\Tests\Backend; use PHPUnit\Framework\TestCase; use TypePhp\Platform\Windows; use TypePhp\Platform\Linux; -use TypePhp\Platform\Macos; use TypePhp\Backend\Msvc; use TypePhp\Backend\Gcc; use TypePhp\Backend\Clang; @@ -61,54 +60,6 @@ class BackendTest extends TestCase $this->assertEquals('link', $compiler->getLinkerCommand()); } - /** - * 测试 MSVC 编译单个文件 - */ - public function testMsvcCompileFile(): void - { - $platform = new Windows(); - $compiler = new Msvc($platform); - - $cmd = $compiler->compileFile( - 'test.cpp', - 'test.obj', - ['C:\PHP\include'], - ['ZEND_WIN32'] - ); - - $this->assertStringContainsString('cl', $cmd); - $this->assertStringContainsString('/c', $cmd); - $this->assertStringContainsString('test.cpp', $cmd); - $this->assertStringContainsString('/Fo', $cmd); - $this->assertStringContainsString('test.obj', $cmd); - $this->assertStringContainsString('/I', $cmd); - $this->assertStringContainsString('/DZEND_WIN32', $cmd); - } - - /** - * 测试 MSVC 链接对象文件 - */ - public function testMsvcLinkObjects(): void - { - $platform = new Windows(); - $compiler = new Msvc($platform); - - $cmd = $compiler->linkObjects( - ['test.obj'], - 'output.exe', - ['C:\PHP\lib'], - ['php8.lib'] - ); - - $this->assertStringContainsString('link', $cmd); - $this->assertStringContainsString('@', $cmd); - $this->assertStringContainsString('.rsp', $cmd); - $this->assertStringContainsString('/OUT:', $cmd); - $this->assertStringContainsString('output.exe', $cmd); - $this->assertStringContainsString('/LIBPATH:', $cmd); - $compiler->cleanupResponseFile(); - } - /** * 测试 MSVC 完整编译命令 */ @@ -219,75 +170,6 @@ class BackendTest extends TestCase $compiler->cleanupResponseFile(); } - /** - * 测试 MSVC 完整编译选项 - */ - public function testMsvcFullCompileOptions(): void - { - $platform = new Windows([], true); // ZTS - $compiler = new Msvc($platform); - - $options = $compiler->buildFullCompileOptions([ - 'optimize' => 2, - 'debug' => false, - 'sanitize' => null, - 'cpp_std' => 'c++17', - 'suppressed_warnings' => [ - '4996' => 'deprecated function', - '4267' => 'size_t conversion', - ], - ]); - - $this->assertStringContainsString('/DZEND_WIN32', $options); - $this->assertStringContainsString('/DZTS', $options); - $this->assertStringContainsString('/O2', $options); - $this->assertStringContainsString('/W3', $options); - $this->assertStringContainsString('/wd4996', $options); - $this->assertStringContainsString('/wd4267', $options); - $this->assertStringContainsString('/EHsc', $options); - $this->assertStringContainsString('/std:c++17', $options); - $this->assertStringContainsString('/MD', $options); - $this->assertStringContainsString('/nologo', $options); - } - - /** - * 测试 MSVC 调试模式编译选项 - */ - public function testMsvcDebugCompileOptions(): void - { - $platform = new Windows(); - $compiler = new Msvc($platform); - - $options = $compiler->buildFullCompileOptions([ - 'debug' => true, - ]); - - $this->assertStringContainsString('/Od', $options); // 禁用优化 - $this->assertStringContainsString('/Zi', $options); // 生成调试信息 - } - - /** - * 测试 MSVC 完整链接选项 - */ - public function testMsvcFullLinkOptions(): void - { - $platform = new Windows(); - $compiler = new Msvc($platform); - - $options = $compiler->buildFullLinkOptions([ - 'debug' => true, - 'no_console' => true, - 'shared' => true, - ]); - - $this->assertStringContainsString('/DEBUG', $options); - $this->assertStringContainsString('/SUBSYSTEM:WINDOWS', $options); - $this->assertStringContainsString('/ENTRY:mainCRTStartup', $options); - $this->assertStringContainsString('/NODEFAULTLIB:LIBCMT', $options); - $this->assertStringContainsString('/DLL', $options); - $this->assertStringContainsString('/nologo', $options); - } - /** * 测试 GCC 编译器基本信息 */ @@ -301,30 +183,6 @@ class BackendTest extends TestCase $this->assertEquals('g++', $compiler->getLinkerCommand()); } - /** - * 测试 GCC 编译单个文件 - */ - public function testGccCompileFile(): void - { - $platform = new Linux(); - $compiler = new Gcc($platform); - - $cmd = $compiler->compileFile( - 'test.cpp', - 'test.o', - ['/usr/include/php'], - ['ZEND_WIN32'] - ); - - $this->assertStringContainsString('g++', $cmd); - $this->assertStringContainsString('-c', $cmd); - $this->assertStringContainsString('test.cpp', $cmd); - $this->assertStringContainsString('-o', $cmd); - $this->assertStringContainsString('test.o', $cmd); - $this->assertStringContainsString('-I', $cmd); - $this->assertStringContainsString('-DZEND_WIN32', $cmd); - } - public function testGccBuildCompileCommandUsesCustomCompilerAndIncludes(): void { $platform = new Linux(); @@ -456,64 +314,6 @@ class BackendTest extends TestCase $this->assertSame('"' . $objectWithoutSpace . '"', $lines[1]); } - /** - * 测试 GCC 完整编译选项 - */ - public function testGccFullCompileOptions(): void - { - $platform = new Linux(); - $compiler = new Gcc($platform); - - $options = $compiler->buildFullCompileOptions([ - 'optimize' => 2, - 'debug' => false, - 'cpp_std' => 'c++17', - 'sanitize' => 'address', - 'pic' => true, - ]); - - $this->assertStringContainsString('-O2', $options); - $this->assertStringContainsString('-Wall', $options); - $this->assertStringContainsString('-std=c++17', $options); - $this->assertStringContainsString('-fsanitize=address', $options); - $this->assertStringContainsString('-fPIC', $options); - } - - /** - * 测试 GCC 调试模式编译选项 - */ - public function testGccDebugCompileOptions(): void - { - $platform = new Linux(); - $compiler = new Gcc($platform); - - $options = $compiler->buildFullCompileOptions([ - 'debug' => true, - ]); - - $this->assertStringContainsString('-O0', $options); - $this->assertStringContainsString('-g', $options); - } - - /** - * 测试 GCC 完整链接选项 - */ - public function testGccFullLinkOptions(): void - { - $platform = new Linux(); - $compiler = new Gcc($platform); - - $options = $compiler->buildFullLinkOptions([ - 'shared' => true, - 'rpath' => ['/usr/lib', '/usr/local/lib'], - 'sanitize' => 'address', - ]); - - $this->assertStringContainsString('-shared', $options); - $this->assertStringContainsString('-Wl,-rpath', $options); - $this->assertStringContainsString('-fsanitize=address', $options); - } - /** * 测试 Clang 编译器基本信息 */ @@ -548,116 +348,4 @@ class BackendTest extends TestCase $this->assertSame('/opt/llvm/bin/clang++', $compiler->getLinkerCommand()); } - /** - * 测试 Clang 完整编译选项(Unix) - */ - public function testClangUnixCompileOptions(): void - { - $platform = new Linux(); - $compiler = new Clang($platform); - - $options = $compiler->buildFullCompileOptions([ - 'optimize' => 2, - 'cpp_std' => 'c++17', - ]); - - $this->assertStringContainsString('-O2', $options); - $this->assertStringContainsString('-Wall', $options); - $this->assertStringContainsString('-std=c++17', $options); - $this->assertStringNotContainsString('-fms-compatibility', $options); - } - - /** - * 测试 Clang Windows 编译选项 - */ - public function testClangWindowsCompileOptions(): void - { - $platform = new Windows(); - $compiler = new Clang($platform); - - $options = $compiler->buildFullCompileOptions([ - 'optimize' => 2, - ]); - - // Windows 下需要 MSVC 兼容模式 - $this->assertStringContainsString('-fms-compatibility', $options); - $this->assertStringContainsString('-fms-compatibility-version=19.40', $options); - $this->assertStringContainsString('-fdelayed-template-parsing', $options); - $this->assertStringContainsString('-fms-extensions', $options); - } - - /** - * 测试 Clang 完整链接选项(Windows) - */ - public function testClangWindowsLinkOptions(): void - { - $platform = new Windows(); - $compiler = new Clang($platform); - - $options = $compiler->buildFullLinkOptions([ - 'debug' => true, - 'no_console' => true, - ]); - - $this->assertStringContainsString('/DEBUG', $options); - $this->assertStringContainsString('/SUBSYSTEM:WINDOWS', $options); - $this->assertStringContainsString('/NODEFAULTLIB:LIBCMT', $options); - } - - /** - * 测试 Clang 完整链接选项(Unix) - */ - public function testClangUnixLinkOptions(): void - { - $platform = new Linux(); - $compiler = new Clang($platform); - - $options = $compiler->buildFullLinkOptions([ - 'shared' => true, - 'rpath' => ['/usr/lib'], - ]); - - $this->assertStringContainsString('-shared', $options); - $this->assertStringContainsString('-Wl,-rpath', $options); - } - - /** - * 测试不同优化级别 - */ - public function testOptimizationLevels(): void - { - $platform = new Linux(); - $compiler = new Gcc($platform); - - // O0 - 禁用优化 - $opt0 = $compiler->buildFullCompileOptions(['optimize' => 0]); - $this->assertStringContainsString('-O0', $opt0); - - // O1 - $opt1 = $compiler->buildFullCompileOptions(['optimize' => 1]); - $this->assertStringContainsString('-O1', $opt1); - - // O2 - $opt2 = $compiler->buildFullCompileOptions(['optimize' => 2]); - $this->assertStringContainsString('-O2', $opt2); - - // O3 - $opt3 = $compiler->buildFullCompileOptions(['optimize' => 3]); - $this->assertStringContainsString('-O3', $opt3); - } - - /** - * 测试默认值 - */ - public function testDefaultValues(): void - { - $platform = new Linux(); - $compiler = new Gcc($platform); - - // 不提供选项时使用默认值 - $options = $compiler->buildFullCompileOptions([]); - - $this->assertStringContainsString('-O2', $options); // 默认优化级别 - $this->assertStringContainsString('-Wall', $options); // 默认警告 - } } diff --git a/phpunit/src/CompilerBaseAdapterTest.php b/phpunit/src/CompilerBaseAdapterTest.php index fb4ac6d0..540b249b 100644 --- a/phpunit/src/CompilerBaseAdapterTest.php +++ b/phpunit/src/CompilerBaseAdapterTest.php @@ -62,88 +62,6 @@ class CompilerBaseAdapterTest extends TestCase $this->assertNotNull($backend, 'Backend should be initialized'); } - /** - * 测试 parseIncludes 使用新架构 - */ - public function testParseIncludesUsesNewArchitecture(): void - { - $compiler = CompilerTest::create($this->testDir); - - // 使用反射调用 protected 方法 - $reflection = new \ReflectionClass($compiler); - $method = $reflection->getMethod('parseIncludes'); - $method->setAccessible(true); - $includes = $method->invoke($compiler); - - // 应该返回非空字符串 - $this->assertNotEmpty($includes); - $this->assertIsString($includes); - - // Windows 下应该包含 /I,Unix 下应该包含 -I - if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') { - $this->assertStringContainsString('/I', $includes); - } else { - $this->assertStringContainsString('-I', $includes); - } - } - - /** - * 测试 parseLdflags 使用新架构 - */ - public function testParseLdflagsUsesNewArchitecture(): void - { - $compiler = CompilerTest::create($this->testDir); - - // 使用反射调用 protected 方法 - $reflection = new \ReflectionClass($compiler); - $method = $reflection->getMethod('parseLdflags'); - $method->setAccessible(true); - $ldflags = $method->invoke($compiler); - - // 应该返回非空字符串 - $this->assertNotEmpty($ldflags); - $this->assertIsString($ldflags); - - // Windows 下应该包含 /LIBPATH,Unix 下应该包含 -L - if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') { - $this->assertStringContainsString('/LIBPATH', $ldflags); - } else { - $this->assertStringContainsString('-L', $ldflags); - } - } - - /** - * 测试 parseLibs 使用新架构 - */ - public function testParseLibsUsesNewArchitecture(): void - { - $compiler = CompilerTest::create($this->testDir); - - // 使用反射调用 protected 方法 - $reflection = new \ReflectionClass($compiler); - $method = $reflection->getMethod('parseLibs'); - $method->setAccessible(true); - - // 可能会抛出异常(如果没有找到库),这是正常的 - try { - $libs = $method->invoke($compiler); - - // 如果成功,应该返回非空字符串 - $this->assertNotEmpty($libs); - $this->assertIsString($libs); - - // 应该包含 phpx 库 - if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') { - $this->assertStringContainsString('phpx', $libs); - } else { - $this->assertStringContainsString('-lphpx', $libs); - } - } catch (\Exception $e) { - // 如果抛出异常,验证是预期的库未找到错误 - $this->assertStringContainsString('libphpx', $e->getMessage()); - } - } - /** * 测试平台检测方法一致性 */ @@ -172,22 +90,4 @@ class CompilerBaseAdapterTest extends TestCase } } - /** - * 测试向后兼容性 - 旧方法仍然可用 - */ - public function testBackwardCompatibility(): void - { - $compiler = CompilerTest::create($this->testDir); - - // 旧的方法应该仍然可以调用 - $this->assertIsBool($compiler->isWindows()); - - // 使用反射调用 protected 方法 - $reflection = new \ReflectionClass($compiler); - $method = $reflection->getMethod('parseIncludes'); - $method->setAccessible(true); - $includes = $method->invoke($compiler); - - $this->assertIsString($includes); - } } diff --git a/phpunit/src/Generator/UtilsTest.php b/phpunit/src/Generator/UtilsTest.php index 9a254623..cc2264ea 100644 --- a/phpunit/src/Generator/UtilsTest.php +++ b/phpunit/src/Generator/UtilsTest.php @@ -80,17 +80,6 @@ class UtilsTest extends TestCase $this->assertStringContainsString('\\"', $result); } - // ======================================================================== - // genZendStrl - // ======================================================================== - - public function testGenZendStrl(): void - { - $result = $this->invokeMethod('genZendStrl', 'name'); - $this->assertStringStartsWith('ZEND_STRL("', $result); - $this->assertStringContainsString('name', $result); - } - // ======================================================================== // genArray // ======================================================================== @@ -108,23 +97,6 @@ class UtilsTest extends TestCase $this->assertStringStartsWith(Type::ARRAY . '{', $result); } - // ======================================================================== - // genRawStr - // ======================================================================== - - public function testGenRawStr(): void - { - $result = $this->invokeMethod('genRawStr', 'hello'); - $this->assertEquals('R"(hello)"', $result); - } - - public function testGenRawStrMultiLine(): void - { - $result = $this->invokeMethod('genRawStr', "line1\nline2"); - $this->assertStringStartsWith('R"(', $result); - $this->assertStringEndsWith(')"', $result); - } - // ======================================================================== // escapeString // ======================================================================== diff --git a/src/Analysis/SsaBuilder.php b/src/Analysis/SsaBuilder.php index 8012e9bd..1b639ffa 100644 --- a/src/Analysis/SsaBuilder.php +++ b/src/Analysis/SsaBuilder.php @@ -157,7 +157,6 @@ class VarState * After build(): * - $builder->blocks: basic blocks with φ functions * - $builder->ssaVars: all SSA variable definitions - * - $builder->getVarDefAtUse($varName, $blockId, $stmtIndex): get the SSA var for a use * - $builder->getDefBlocks($varName): all blocks where $varName is defined */ class SsaBuilder @@ -179,9 +178,6 @@ class SsaBuilder /** @var array Block IDs where each variable is defined */ private array $defBlocks = []; - /** @var array For each block and variable, the SSA var at block entry (after φ) */ - private array $blockEntryVars = []; - /** @var string[] Parameter names */ private array $params = []; @@ -234,22 +230,6 @@ class SsaBuilder $this->renameVariables(); } - /** - * Get the SSA variable that reaches a specific use point. - * - * @param string $varName Original variable name (e.g., "x") - * @param int $blockId Block containing the use - * @param int $stmtIndex Statement index within the block - * @return SsaVar|null The reaching SSA var, or null if undefined - */ - public function getVarAtUse(string $varName, int $blockId, int $stmtIndex): ?SsaVar - { - $key = "{$blockId}:{$varName}:{$stmtIndex}"; - // During renaming, we'd record use→def mappings here - // For now, walk the block backward from stmtIndex to find the definition - return $this->findReachingDef($varName, $blockId, $stmtIndex); - } - /** * Get all blocks where a variable has definitions. * @@ -1676,33 +1656,6 @@ class SsaBuilder } } - /** - * Find the reaching SSA definition for a variable at a given use point. - * Walks backward through the block's statements to find the most recent definition. - */ - private function findReachingDef(string $varName, int $blockId, int $stmtIndex): ?SsaVar - { - $block = $this->blocks[$blockId]; - - // Check φ at block entry - if (isset($block->phi[$varName])) { - return $block->phi[$varName]; - } - - // Walk backward through statements in the block - for ($i = $stmtIndex - 1; $i >= 0; $i--) { - $defs = $this->getDefinedVars($block->stmts[$i]); - if (in_array($varName, $defs)) { - // We'd need the exact SsaVar from renaming pass — simplified return - return null; - } - } - - // If not found in this block, search predecessors recursively - // (Simplified: return null for cross-block queries) - return null; - } - // ========================================================================= // e-SSA: Pi Node Construction (Type Narrowing from Conditions) // ========================================================================= diff --git a/src/Backend/Clang.php b/src/Backend/Clang.php index 5abecd70..cbed8823 100644 --- a/src/Backend/Clang.php +++ b/src/Backend/Clang.php @@ -127,20 +127,4 @@ class Clang extends GccLikeBackend return parent::getPlatformLinkFlags($config); } - protected function getPlatformFullLinkFlags(array $options): string - { - if ($this->platform instanceof Windows) { - $flags = ''; - if (!empty($options['debug'])) { - $flags .= ' /DEBUG'; - } - if (!empty($options['no_console'])) { - $flags .= ' ' . $this->platform->getSubsystemOptions(true); - } - $flags .= ' ' . $this->platform->getCrtConfig(); - return $flags; - } - - return parent::getPlatformFullLinkFlags($options); - } } diff --git a/src/Backend/CompilerBackend.php b/src/Backend/CompilerBackend.php index 43b91970..d20bab57 100644 --- a/src/Backend/CompilerBackend.php +++ b/src/Backend/CompilerBackend.php @@ -50,28 +50,6 @@ abstract class CompilerBackend throw new \LogicException($this->getName() . ' does not support precompiled headers'); } - /** - * 编译单个文件 - */ - abstract public function compileFile( - string $sourceFile, - string $outputFile, - array $includePaths = [], - array $defines = [], - array $flags = [] - ): string; - - /** - * 链接目标文件 - */ - abstract public function linkObjects( - array $objectFiles, - string $outputFile, - array $libraryPaths = [], - array $libraries = [], - array $flags = [] - ): string; - /** * 构建完整的编译命令 */ diff --git a/src/Backend/GccLikeBackend.php b/src/Backend/GccLikeBackend.php index c887d2cc..8179ade5 100644 --- a/src/Backend/GccLikeBackend.php +++ b/src/Backend/GccLikeBackend.php @@ -181,77 +181,8 @@ abstract class GccLikeBackend extends CompilerBackend return $flags; } - /** 获取平台特定的完整链接选项 */ - protected function getPlatformFullLinkFlags(array $options): string - { - $flags = ''; - - if (!empty($options['shared'])) { - $flags .= ' ' . $this->platform->getSharedLinkFlag(); - } - - if (!empty($options['rpath'])) { - $flags .= ' ' . $this->platform->getRpathOptions($options['rpath']); - } - - return $flags; - } - // ──── 抽象方法实现 ──── - public function compileFile( - string $sourceFile, - string $outputFile, - array $includePaths = [], - array $defines = [], - array $flags = [] - ): string { - $cmd = $this->getCompilerCommand(); - $cmd .= $this->getCompilerPrefixFlags(); - $cmd .= ' -c ' . escapeshellarg($sourceFile); - $cmd .= ' -o ' . escapeshellarg($outputFile); - - if (!empty($includePaths)) { - $cmd .= ' ' . $this->formatIncludePaths($includePaths); - } - - foreach ($defines as $define) { - $cmd .= ' ' . $this->formatDefineFlag($define, '-D'); - } - - if (!empty($flags)) { - $cmd .= ' ' . implode(' ', $flags); - } - - return $cmd; - } - - public function linkObjects( - array $objectFiles, - string $outputFile, - array $libraryPaths = [], - array $libraries = [], - array $flags = [] - ): string { - $cmd = $this->getLinkerCommand(); - $cmd .= ' ' . $this->createResponseFile($objectFiles, $outputFile); - $cmd .= ' ' . $this->getLinkerOutputFlag() . ' ' . escapeshellarg($outputFile); - - if (!empty($libraryPaths)) { - $cmd .= ' ' . $this->formatLibraryPaths($libraryPaths); - } - - if (!empty($libraries)) { - $cmd .= ' ' . $this->formatLibraries($libraries); - } - - if (!empty($flags)) { - $cmd .= ' ' . implode(' ', $flags); - } - - return $cmd; - } - public function buildCompileCommand(string $sourceFile, string $outputFile, array $options = []): string { $cmd = $this->getCompilerCommand(); @@ -357,23 +288,4 @@ abstract class GccLikeBackend extends CompilerBackend return $cmd; } - public function buildFullCompileOptions(array $options = []): string - { - $cmd = $this->getCompilerPrefixFlags(); - $cmd .= $this->buildSharedCompileFlags($options, true); - return $cmd; - } - - public function buildFullLinkOptions(array $options = []): string - { - $cmd = ''; - - $cmd .= $this->getPlatformFullLinkFlags($options); - - if (!empty($options['sanitize'])) { - $cmd .= ' -fsanitize=' . $options['sanitize']; - } - - return $cmd; - } } diff --git a/src/Backend/Msvc.php b/src/Backend/Msvc.php index 4fa6457b..64883133 100644 --- a/src/Backend/Msvc.php +++ b/src/Backend/Msvc.php @@ -113,68 +113,6 @@ class Msvc extends CompilerBackend return $cmd; } - public function compileFile( - string $sourceFile, - string $outputFile, - array $includePaths = [], - array $defines = [], - array $flags = [] - ): string { - $cmd = $this->getCompilerCommand(); - $cmd .= ' /c ' . escapeshellarg($sourceFile); - $cmd .= ' /Fo' . escapeshellarg($outputFile); - - // 添加包含路径 - if (!empty($includePaths)) { - $cmd .= ' ' . $this->formatIncludePaths($includePaths); - } - - // 添加宏定义 - foreach ($defines as $define) { - $cmd .= ' ' . $this->formatDefineFlag($define, '/D'); - } - - // 添加额外标志 - if (!empty($flags)) { - $cmd .= ' ' . implode(' ', $flags); - } - - return $cmd; - } - - public function linkObjects( - array $objectFiles, - string $outputFile, - array $libraryPaths = [], - array $libraries = [], - array $flags = [] - ): string { - $cmd = $this->getLinkerCommand(); - - // 添加目标文件(通过 Response File 避免命令行过长) - $cmd .= ' ' . $this->createResponseFile($objectFiles, $outputFile); - - // 输出文件 - $cmd .= ' /OUT:' . escapeshellarg($outputFile); - - // 添加库路径 - if (!empty($libraryPaths)) { - $cmd .= ' ' . $this->formatLibraryPaths($libraryPaths); - } - - // 添加库文件 - if (!empty($libraries)) { - $cmd .= ' ' . $this->formatLibraries($libraries); - } - - // 添加额外标志 - if (!empty($flags)) { - $cmd .= ' ' . implode(' ', $flags); - } - - return $cmd; - } - public function buildCompileCommand(string $sourceFile, string $outputFile, array $options = []): string { $cmd = $this->getCompilerCommand(); @@ -275,128 +213,6 @@ class Msvc extends CompilerBackend return $base . '.pdb'; } - /** - * 构建编译单个文件的完整命令 - */ - public function buildCompileFileCommand( - string $sourceFile, - string $objectFile, - array $includePaths = [], - array $defines = [], - array $options = [] - ): string { - $cmd = $this->getCompilerCommand(); - $cmd .= ' /c ' . escapeshellarg($sourceFile); - $cmd .= ' /Fo' . escapeshellarg($objectFile); - - // 包含路径 - if (!empty($includePaths)) { - $cmd .= ' ' . $this->formatIncludePaths($includePaths); - } - - // 宏定义 - foreach ($defines as $define) { - $cmd .= ' ' . $this->formatDefineFlag($define, '/D'); - } - - // 编译选项 - $cmd .= $this->buildFullCompileOptions($options); - - return $cmd; - } - - /** - * 构建完整的编译选项 - */ - public function buildFullCompileOptions(array $options = []): string - { - $cmd = ''; - - // 平台宏定义 - $cmd .= ' /utf-8 /DZEND_WIN32 /DPHP_WIN32 /DZEND_DEBUG=0 /DENABLE_INTSAFE_SIGNED_FUNCTIONS'; - - // ZTS - if ($this->platform instanceof Windows && $this->platform->isZts()) { - $cmd .= ' /DZTS'; - } - - // Sanitizer - if (!empty($options['sanitize'])) { - if ($options['sanitize'] === 'address' || $options['sanitize'] === 'addr') { - $cmd .= ' /fsanitize=address'; - } - } - - // 优化和调试 - if (!empty($options['debug'])) { - $cmd .= ' /Od /Zi'; - if (!empty($options['compiler_pdb'])) { - $cmd .= ' /Fd' . escapeshellarg($options['compiler_pdb']); - $cmd .= ' /FS'; - } - } else { - $optimizeLevel = $options['optimize'] ?? 2; - $optMap = [0 => '/Od', 1 => '/O1', 2 => '/O2', 3 => '/Ox']; - $cmd .= ' ' . ($optMap[$optimizeLevel] ?? '/O2'); - } - - // 警告 - $cmd .= ' /W3'; - - // 禁用常见警告(只使用键,即警告代码) - if (!empty($options['suppressed_warnings'])) { - foreach ($options['suppressed_warnings'] as $code => $description) { - $code = is_int($code) && $code < 100 ? $description : $code; - $cmd .= " /wd{$code}"; - } - } - - // C++ 选项 - $cmd .= ' /EHsc'; - if (!empty($options['cpp_std'])) { - $cmd .= ' /std:' . $options['cpp_std']; - } - - // CRT - $cmd .= ' /MD'; - - // nologo - $cmd .= ' /nologo'; - - return $cmd; - } - - /** - * 构建完整的链接选项 - */ - public function buildFullLinkOptions(array $options = []): string - { - $cmd = ''; - - // 调试 - if (!empty($options['debug'])) { - $cmd .= ' /DEBUG'; - } - - // Windows 子系统 - if (!empty($options['no_console'])) { - $cmd .= ' ' . $this->platform->getSubsystemOptions(true); - } - - // CRT - $cmd .= ' ' . $this->platform->getCrtConfig(); - - // DLL - if (!empty($options['shared'])) { - $cmd .= ' /DLL'; - } - - // nologo - $cmd .= ' /nologo'; - - return $cmd; - } - /** * 构建编译选项(实现抽象方法) */ diff --git a/src/Build/NativeBuildConfigurationTrait.php b/src/Build/NativeBuildConfigurationTrait.php index 924d8b49..bc9dd32b 100644 --- a/src/Build/NativeBuildConfigurationTrait.php +++ b/src/Build/NativeBuildConfigurationTrait.php @@ -36,14 +36,6 @@ trait NativeBuildConfigurationTrait return $includePaths; } - /** - * 解析包含路径 - */ - protected function parseIncludes(): string - { - return $this->getPlatform()->getIncludeFlags($this->getIncludePaths()); - } - protected function getLibraryPaths(): array { $platform = $this->getPlatform(); @@ -64,18 +56,6 @@ trait NativeBuildConfigurationTrait return $libraryPaths; } - protected function parseLdflags(): string - { - $flags = $this->getPlatform()->getLibraryPathFlags($this->getLibraryPaths()); - - // 添加用户自定义的 ldflags - if (!empty($this->ldflags)) { - $flags .= ' ' . $this->ldflags; - } - - return $flags; - } - /** * 获取库文件 */ @@ -205,12 +185,4 @@ trait NativeBuildConfigurationTrait } } - /** - * 解析库文件 - */ - protected function parseLibs(): string - { - return $this->getPlatform()->getLibraryFlags($this->getLibraries()); - } - } diff --git a/src/CompilerBase.php b/src/CompilerBase.php index ecf66078..1ac7f145 100644 --- a/src/CompilerBase.php +++ b/src/CompilerBase.php @@ -94,7 +94,6 @@ use PhpParser\Node\Expr\CallLike; use PhpParser\Node\Expr\Variable; use PhpParser\Node\FunctionLike; use PhpParser\NodeAbstract; -use PhpParser\NodeFinder; use PhpParser\Parser; use PhpParser\ParserFactory; use PhpParser\PhpVersion; @@ -1204,11 +1203,6 @@ class CompilerBase implements PropertyAccessContext return self::OBJECT_PROP . $object . self::NAMESPACE_SEPARATOR . $prop; } - protected function getObjectPropVarInfo(string $object, string $prop): array - { - return $this->context->objectProps[$this->getObjectPropVarName($object, $prop)]; - } - protected function getObjectPropInfoByVar(string $var): ?array { return $this->context->objectProps[$var] ?? null; @@ -1487,11 +1481,6 @@ class CompilerBase implements PropertyAccessContext return $this->stripNumericUnderscores($expr->getAttribute('rawValue')); } - private function getDecimalLiteralString(Node\Scalar $expr): string - { - return $this->stripNumericUnderscores($expr->getAttribute('rawValue')); - } - protected function parseSuperGlobalVar(string $name): string { if (!$this->hasGlobalVar($name)) { @@ -2894,15 +2883,6 @@ class CompilerBase implements PropertyAccessContext } } - protected function resetReturnType(Node\Stmt\Return_ $node, string $type): void - { - $oriType = $this->functionDef->returnType; - $this->functionDef->returnType = $type; - // 返回值变更,需要重新解析 - $this->climate->cyan("Return type changed ({$oriType} -> {$type}) at line {$node->getLine()} retrying..."); - throw new Redo(); - } - protected function detectVarType($var): string { // Unwrap ArrayDimFetch to get the underlying variable type; @@ -4928,17 +4908,6 @@ class CompilerBase implements PropertyAccessContext * The outer descriptor list is a union (OR); an allOf entry represents an * intersection (AND). Nullable is represented by an isNull union member. */ - protected function mustNoCall(NodeAbstract $node): void - { - $nodeFinder = new NodeFinder(); - $r1 = $nodeFinder->findInstanceOf($node, Expr\StaticCall::class); - $r2 = $nodeFinder->findInstanceOf($node, Expr\MethodCall::class); - $r3 = $nodeFinder->findInstanceOf($node, Expr\FuncCall::class); - if (count($r1) + count($r2) + count($r3) > 0) { - $this->fatalError($node, 'Calling function or method is not allowed'); - } - } - protected function checkAccessible(ClassDef $classDef, int $flags): bool { return $this->checkAccessibleByClassName($classDef->getNamespacedName(false), $flags); diff --git a/src/Extractor.php b/src/Extractor.php index 892d1bed..c981095e 100644 --- a/src/Extractor.php +++ b/src/Extractor.php @@ -11,7 +11,6 @@ namespace TypePhp; class Extractor { private string $ctagsPath = 'ctags'; - private bool $isUniversalCtags = false; public function __construct() { @@ -91,114 +90,6 @@ class Extractor return $allFunctions; } - /** - * 提取函数并添加额外信息. - */ - public function extractWithMetadata(string $filename, array $prefixes = ['php_']): array - { - $functions = $this->extractFunctions($filename, $prefixes); - - // 添加额外的元数据 - foreach ($functions as &$func) { - $func['metadata'] = $this->extractMetadata($filename, $func); - } - - return $functions; - } - - /** - * 生成函数统计信息. - */ - public function generateStatistics(array $functions): array - { - $stats = [ - 'total' => count($functions), - 'byReturnType' => [], - 'byParameterCount' => [], - 'byPrefix' => [], - 'withComments' => 0, - 'isPHPFunction' => 0, - ]; - - foreach ($functions as $func) { - // 按返回类型统计 - $returnType = $func['returnType']; - $stats['byReturnType'][$returnType] = - ($stats['byReturnType'][$returnType] ?? 0) + 1; - - // 按参数数量统计 - $paramCount = count($func['parameters']); - $stats['byParameterCount'][$paramCount] = - ($stats['byParameterCount'][$paramCount] ?? 0) + 1; - - // 按前缀统计 - $name = $func['name']; - $prefix = preg_match('/^([a-z_]+_)/i', $name, $m) ? $m[1] : 'other'; - $stats['byPrefix'][$prefix] = - ($stats['byPrefix'][$prefix] ?? 0) + 1; - - // 有注释的函数 - if (!empty($func['metadata']['comments'])) { - $stats['withComments']++; - } - - // PHP 函数宏 - if ($func['metadata']['isPHPFunction'] ?? false) { - $stats['isPHPFunction']++; - } - } - - return $stats; - } - - /** - * 导出为 Markdown 文档. - */ - public function exportToMarkdown(array $functions, string $title = 'API 文档'): string - { - $md = "# {$title}\n\n"; - $md .= '生成时间: ' . date('Y-m-d H:i:s') . "\n\n"; - $md .= '总计: ' . count($functions) . " 个函数\n\n"; - $md .= "---\n\n"; - - foreach ($functions as $func) { - $md .= "## {$func['name']}\n\n"; - - // 签名 - $md .= "```c\n{$func['signature']}\n```\n\n"; - - // 返回类型 - $md .= "**返回类型**: `{$func['returnType']}`\n\n"; - - // 参数 - if (!empty($func['parameters'])) { - $md .= "**参数**:\n\n"; - foreach ($func['parameters'] as $param) { - $name = $param['name'] ?: '(unnamed)'; - $md .= "- `{$param['type']}` **{$name}**\n"; - } - $md .= "\n"; - } else { - $md .= "**参数**: 无\n\n"; - } - - // 注释 - if (!empty($func['metadata']['comments'])) { - $md .= "**说明**:\n\n"; - foreach ($func['metadata']['comments'] as $comment) { - $md .= $comment . "\n\n"; - } - } - - // 位置 - $md .= "**位置**: {$func['location']['file']}:{$func['location']['line']}\n\n"; - - $md .= "---\n\n"; - } - - return $md; - } - /** * 检查 ctags 是否可用. */ @@ -210,9 +101,7 @@ class Extractor $this->error("未找到 ctags 命令\n安装: sudo apt install universal-ctags"); } - $this->isUniversalCtags = stripos($output, 'Universal Ctags') !== false; - - if (!$this->isUniversalCtags) { + if (stripos($output, 'Universal Ctags') === false) { $this->warn('建议使用 Universal Ctags 以获得更好的支持'); } } @@ -477,143 +366,4 @@ class Extractor exit(1); } - /** - * 提取函数的元数据(注释、属性等). - */ - private function extractMetadata(string $filename, array $func): array - { - $lineNum = $func['location']['line']; - $lines = file($filename, FILE_IGNORE_NEW_LINES); - - $metadata = [ - 'comments' => [], - 'attributes' => [], - 'isPHPFunction' => false, - 'isStatic' => false, - 'isInline' => false, - ]; - - // 提取函数前的注释 - $comments = $this->extractComments($lines, $lineNum); - $metadata['comments'] = $comments; - - // 检测 PHP 函数宏 - $metadata['isPHPFunction'] = $this->isPHPFunction($func['signature']); - - // 检测修饰符 - $signature = $func['signature']; - $metadata['isStatic'] = strpos($signature, 'static') !== false; - $metadata['isInline'] = strpos($signature, 'inline') !== false; - - // 提取文档注释中的标签 - $metadata['docTags'] = $this->parseDocTags($comments); - - return $metadata; - } - - /** - * 提取函数前的注释. - */ - private function extractComments(array $lines, int $lineNum): array - { - $comments = []; - $i = $lineNum - 2; // 从函数声明的前一行开始 - - // 向上查找注释 - while ($i >= 0) { - $line = trim($lines[$i]); - - // 空行 - if (empty($line)) { - $i--; - continue; - } - - // C++ 风格注释 - if (str_starts_with($line, '//')) { - array_unshift($comments, substr($line, 2)); - $i--; - continue; - } - - // C 风格注释结束 - if (str_ends_with($line, '*/')) { - $commentLines = [$line]; - $i--; - - // 继续向上查找注释开始 - while ($i >= 0) { - $commentLine = trim($lines[$i]); - array_unshift($commentLines, $commentLine); - - if (str_starts_with($commentLine, '/*')) { - break; - } - $i--; - } - - // 解析多行注释 - $comment = implode("\n", $commentLines); - $comment = preg_replace('#^/\*+\s*#', '', $comment); - $comment = preg_replace('#\s*\*+/$#', '', $comment); - $comment = preg_replace('#^\s*\*\s?#m', '', $comment); - - array_unshift($comments, trim($comment)); - $i--; - continue; - } - - // 遇到非注释行,停止 - break; - } - - return $comments; - } - - /** - * 检测是否是 PHP 函数宏定义. - */ - private function isPHPFunction(string $signature): bool - { - $phpMacros = [ - 'PHP_FUNCTION', - 'PHP_METHOD', - 'ZEND_FUNCTION', - 'ZEND_METHOD', - ]; - - foreach ($phpMacros as $macro) { - if (strpos($signature, $macro) !== false) { - return true; - } - } - - return false; - } - - /** - * 解析文档注释标签. - */ - private function parseDocTags(array $comments): array - { - $tags = []; - - foreach ($comments as $comment) { - // 匹配 @tag 格式 - if (preg_match_all('/@(\w+)\s+(.*)$/m', $comment, $matches, PREG_SET_ORDER)) { - foreach ($matches as $match) { - $tagName = $match[1]; - $tagValue = trim($match[2]); - - if (!isset($tags[$tagName])) { - $tags[$tagName] = []; - } - - $tags[$tagName][] = $tagValue; - } - } - } - - return $tags; - } } diff --git a/src/Generator/CallArgumentGenerator.php b/src/Generator/CallArgumentGenerator.php index 35b9f5fb..f60d35b5 100644 --- a/src/Generator/CallArgumentGenerator.php +++ b/src/Generator/CallArgumentGenerator.php @@ -160,11 +160,11 @@ trait CallArgumentGenerator $this->context->beforeStmtLines[] = $variadicVar . '.merge(' . $this->parseArrayArg($arg) . ');'; } elseif ($variadicName !== null) { $value = $this->getTypeConvertedArg($arg, $argInfo, $callableName, $variadicArgIndex); - $this->context->beforeStmtLines[] = $variadicVar . '.set(' + $this->context->beforeStmtLines[] = $variadicVar . '.setValue(' . $this->getLiteralString($variadicName) . ', ' . $value . ');'; } else { $value = $this->getTypeConvertedArg($arg, $argInfo, $callableName, $variadicArgIndex); - $this->context->beforeStmtLines[] = $variadicVar . '.append(' . $value . ');'; + $this->context->beforeStmtLines[] = $variadicVar . '.appendValue(' . $value . ');'; } } @@ -180,37 +180,6 @@ trait CallArgumentGenerator return implode(', ', $resolvedArgs); } - protected function parseNamedCallArgs(array $args, int $firstIndex, array $listArgs): string - { - $namedArgs = []; - foreach ($args as $i => $arg) { - if ($i < $firstIndex) { - continue; - } - if ($arg->name === null) { - $this->fatalError($arg, 'Named argument must follow positional argument'); - } - if (!$this->isIdExpr($arg->name)) { - $this->fatalError($arg, 'Named argument must be a string'); - } - if (array_key_exists($arg->name->name, $namedArgs)) { - $this->fatalError($arg, "Duplicate named argument `{$arg->name->name}`"); - } - $namedArgs[$arg->name->name] = $this->parseCallArgValue($arg); - } - - $tmpVar = $this->genTmpVarName(); - - $array = Type::ARRAY . ' ' . $tmpVar . ';'; - foreach ($namedArgs as $k => $v) { - $array .= $tmpVar . '.set(' . $this->getLiteralString($k) . ', ' . $v . ');' . PHP_EOL; - } - $this->context->beforeStmtLines[] = $array; - $this->context->afterStmtLines[] = $tmpVar . '.unset();'; - - return Symbol::argList() . '{' . implode(', ', $listArgs) . '}, ' . $tmpVar . '.array()'; - } - protected function isReferenceArgument($funcName, $className, $argIndex): bool { $argInfo = $this->getAotCallArgInfo($funcName, $className, $argIndex); diff --git a/src/Generator/ClosureGenerator.php b/src/Generator/ClosureGenerator.php index 15297027..17be0d75 100644 --- a/src/Generator/ClosureGenerator.php +++ b/src/Generator/ClosureGenerator.php @@ -197,7 +197,7 @@ trait ClosureGenerator $code .= $this->getIndent() . Type::ARRAY . ' ' . $var . ';' . PHP_EOL; $code .= $this->getIndent() . 'for (uint32_t i = ' . $i . '; i < php::getCallArgNum(); i++) {' . PHP_EOL; $this->indentLevel++; - $code .= $this->getIndent() . $var . '.append(php::getCallArg(i));' . PHP_EOL; + $code .= $this->getIndent() . $var . '.appendValue(php::getCallArg(i));' . PHP_EOL; $this->indentLevel--; $code .= $this->getIndent() . '}' . PHP_EOL; $code .= $this->genExtraNamedVariadicArgs($var); diff --git a/src/Generator/Utils.php b/src/Generator/Utils.php index 1b9e98f7..c243d81a 100644 --- a/src/Generator/Utils.php +++ b/src/Generator/Utils.php @@ -48,21 +48,11 @@ trait Utils return '"' . ($escape ? $this->escapeString($str) : $str) . '"'; } - protected function genZendStrl(string $char): string - { - return 'ZEND_STRL(' . $this->genCharPtr($char) . ')'; - } - protected function genArray(array $elements): string { return Type::ARRAY . '{' . implode(', ', $elements) . ' }'; } - protected function genRawStr(string $str): string - { - return 'R"(' . $str . ')"'; - } - public function escapeString(string $str): string { $str = addcslashes($str, "\\\"\n\r\t\v\f\0\x01..\x1f\x7f..\xff"); diff --git a/src/Optimizer/FuncCallOptimizer.php b/src/Optimizer/FuncCallOptimizer.php index 135f5703..8f80987c 100644 --- a/src/Optimizer/FuncCallOptimizer.php +++ b/src/Optimizer/FuncCallOptimizer.php @@ -168,11 +168,11 @@ trait FuncCallOptimizer 'is_null' => ['handler' => 'genIsNull', 'nativeReceiver' => true], 'get_class' => ['handler' => 'genGetClassOptimized', 'nativeReceiver' => true], 'get_parent_class' => ['handler' => 'genGetParentClass', 'nativeReceiver' => true], - 'function_exists' => ['handler' => 'genFunctionExistsOptimized'], - 'func_get_arg' => ['handler' => 'genFuncGetArgOptimized'], - 'func_get_args' => ['handler' => 'genFuncGetArgsOptimized'], - 'func_num_args' => ['handler' => 'genFuncNumArgsOptimized'], - 'compact' => ['handler' => 'genCompactOptimized'], + 'function_exists' => ['handler' => 'genFunctionExists'], + 'func_get_arg' => ['handler' => 'genFuncGetArg'], + 'func_get_args' => ['handler' => 'genFuncGetArgs'], + 'func_num_args' => ['handler' => 'genFuncNumArgs'], + 'compact' => ['handler' => 'genCompact'], 'array_keys' => ['handler' => 'genArrayKeys'], 'array_key_exists' => ['handler' => 'genArrayKeyExists'], @@ -757,31 +757,6 @@ trait FuncCallOptimizer return 'php::fn::get_parent_class(' . $this->parseIdentifier($arg) . ')'; } - protected function genFunctionExistsOptimized(string $n, Node\Expr\FuncCall $e, array $c): string - { - return $this->genFunctionExists($n, $e); - } - - protected function genFuncGetArgOptimized(string $n, Node\Expr\FuncCall $e, array $c): string - { - return $this->genFuncGetArg($n, $e); - } - - protected function genFuncGetArgsOptimized(string $n, Node\Expr\FuncCall $e, array $c): string - { - return $this->genFuncGetArgs($n, $e); - } - - protected function genFuncNumArgsOptimized(string $n, Node\Expr\FuncCall $e, array $c): string - { - return $this->genFuncNumArgs($n, $e); - } - - protected function genCompactOptimized(string $n, Node\Expr\FuncCall $e, array $c): string - { - return $this->genCompactOrig($e); - } - protected function genArrayKeys(string $n, Node\Expr\FuncCall $e, array $c): string { $cnt = count($e->args); @@ -869,11 +844,7 @@ trait FuncCallOptimizer return 'php::fn::define(' . $this->getArg($e, 0) . ', ' . $this->getArg($e, 1) . ')'; } - // ========================================================================= - // Legacy helpers - // ========================================================================= - - protected function genFuncGetArgs(string $name, Node\Expr\FuncCall $expr): string + protected function genFuncGetArgs(string $name, Node\Expr\FuncCall $expr, array $config): string { $this->warningUndefinedBehavior($expr); $funcDef = $this->functionDef; @@ -890,7 +861,7 @@ trait FuncCallOptimizer return $this->genArray($list); } - protected function genFuncGetArg(string $name, Node\Expr\FuncCall $expr) + protected function genFuncGetArg(string $name, Node\Expr\FuncCall $expr, array $config): string { $this->warningUndefinedBehavior($expr); $position = $expr->args[0]->value; @@ -911,7 +882,7 @@ trait FuncCallOptimizer } } - protected function genFuncNumArgs(string $name, Node\Expr\FuncCall $expr): string + protected function genFuncNumArgs(string $name, Node\Expr\FuncCall $expr, array $config): string { $this->warningUndefinedBehavior($expr); $funcDef = $this->functionDef; @@ -923,7 +894,7 @@ trait FuncCallOptimizer return count($funcDef->argInfoList); } - protected function genFunctionExists(string $name, Node\Expr\FuncCall $expr): string + protected function genFunctionExists(string $name, Node\Expr\FuncCall $expr, array $config): string { $funcName = $expr->args[0]->value; if ($this->isScalarString($funcName)) { @@ -943,16 +914,7 @@ trait FuncCallOptimizer return 'php::fn::function_exists(' . $this->parseIdentifier($funcName) . ')'; } - protected function genGetClass(Node\Expr\FuncCall $expr): string - { - $object = $expr->args[0]->value; - if ($this->isVarExpr($object) and $this->isTypedObject($object->name)) { - return $this->getLiteralString($this->getObjectType($object->name)); - } - return 'php::fn::get_class(' . $this->parseIdentifier($object) . ')'; - } - - protected function genCompactOrig(Node\Expr\FuncCall $expr): string + protected function genCompact(string $name, Node\Expr\FuncCall $expr, array $config): string { $list = []; diff --git a/src/Optimizer/SsaPropOptimizer.php b/src/Optimizer/SsaPropOptimizer.php index 6795f6b6..285bad5d 100644 --- a/src/Optimizer/SsaPropOptimizer.php +++ b/src/Optimizer/SsaPropOptimizer.php @@ -391,13 +391,6 @@ trait SsaPropOptimizer return $this->unsafePropsFromEvents($events); } - protected function scanDangerousPropOp($stmt, string $objName): bool - { - $events = []; - $this->collectPropEvents($stmt, $objName, $events); - return $this->unsafePropsFromEvents($events) !== []; - } - /** * @param array $events */ @@ -665,13 +658,6 @@ trait SsaPropOptimizer return $unsafeProps; } - protected function exprHasDangerousPropOp($expr, string $objName): bool - { - $events = []; - $this->collectPropEvents($expr, $objName, $events); - return $this->unsafePropsFromEvents($events) !== []; - } - /** * Check if an expression is a property fetch on a specific object. */ diff --git a/src/Parser/AstNodeType.php b/src/Parser/AstNodeType.php index 1d01a80f..deda79e4 100644 --- a/src/Parser/AstNodeType.php +++ b/src/Parser/AstNodeType.php @@ -115,16 +115,6 @@ trait AstNodeType return $expr instanceof Expr\Match_; } - protected function isConstFetch(NodeAbstract $expr): bool - { - return $expr instanceof Expr\ConstFetch; - } - - protected function isAssignOp(NodeAbstract $expr): bool - { - return $expr instanceof Expr\AssignOp or $expr instanceof Expr\Assign; - } - protected function isAssignExpr(NodeAbstract $expr): bool { return $expr instanceof Expr\Assign; diff --git a/src/Parser/PropertyAccessTrait.php b/src/Parser/PropertyAccessTrait.php index c7d9d8cc..a73a615c 100644 --- a/src/Parser/PropertyAccessTrait.php +++ b/src/Parser/PropertyAccessTrait.php @@ -447,16 +447,6 @@ trait PropertyAccessTrait return (new PropertyAssignTypeInfo())->isFixed($def); } - protected function assertCanAssignObjectProp(Expr\PropertyFetch $left, Expr $right): void - { - $this->assertCanAssignObjectProperty($left, $right, 'object property'); - } - - protected function assertCanAssignStaticProp(Expr\StaticPropertyFetch $left, Expr $right): void - { - $this->assertCanAssignObjectProperty($left, $right, 'static property'); - } - protected function preparePropertyWriteTarget(NodeAbstract $left, bool $allowReadonlyAssignment = false): ?PropertyWriteTarget { if ($left instanceof Expr\PropertyFetch) { @@ -931,11 +921,6 @@ trait PropertyAccessTrait return null; } - protected function parsePropertyFetchRead(Expr\PropertyFetch $expr): string - { - return $this->parsePropertyFetchWithUpdate($expr, false); - } - protected function parsePropertyFetchUpdate(Expr\PropertyFetch $expr): string { return $this->parsePropertyFetchWithUpdate($expr, true); diff --git a/src/Parser/StdContainerTrait.php b/src/Parser/StdContainerTrait.php index 1e79cf21..00042939 100644 --- a/src/Parser/StdContainerTrait.php +++ b/src/Parser/StdContainerTrait.php @@ -298,17 +298,6 @@ trait StdContainerTrait return $this->isStdArrayExpr($expr) || $this->getStdContainerInfo($expr) !== null; } - protected function fillStdArray(Expr\StaticCall $expr): string - { - if (!$this->isVarExpr($expr->args[0]->value) or !$this->isStdArray($this->parseIdentifier($expr->args[0]->value))) { - $this->fatalError($expr, 'fill() only support std::array'); - } - $array = $this->parseIdentifier($expr->args[0]->value); - $info = $this->context->stdArrays[$array]; - $value = $this->convertStdValueExpr($info, $expr->args[1]->value); - return "{$array}_ref.fill({$value})"; - } - protected function getStdArrayInfo(Expr\ArrayDimFetch $expr): ?array { $tmp = $expr->var; @@ -736,11 +725,6 @@ trait StdContainerTrait return ['type' => Type::OBJECT, 'class' => $class]; } - protected function parseStdValueType(NodeAbstract $expr, string $owner): string - { - return $this->parseStdValueTypeInfo($expr, $owner)['type']; - } - protected function parseStdClassValueType(Expr\ClassConstFetch $expr, string $owner): string { $class = $this->parseIdentifier($expr->class); diff --git a/src/Parser/UniversalMethodCall.php b/src/Parser/UniversalMethodCall.php index f7dd13e5..03b18b0a 100644 --- a/src/Parser/UniversalMethodCall.php +++ b/src/Parser/UniversalMethodCall.php @@ -594,99 +594,6 @@ trait UniversalMethodCall return $kwExt ? $kwExt['return_type'] : null; } - protected function buildInternalExtensionMethod(string $type, string $funcName): ?array - { - $ref = Reflection::getFunction($funcName); - if ($ref === null) { - return null; - } - - $totalParams = $ref->getNumberOfParameters(); - if ($totalParams < 1) { - return null; - } - - if (!$this->validateInternalExtensionFirstParam($type, $funcName)) { - return null; - } - - $phpType = Reflection::getFunctionReturnType($funcName); - $returnType = $phpType ? ($this->zendTypeMap[$phpType] ?? Type::VAR) : Type::VAR; - - $requiredParams = $ref->getNumberOfRequiredParameters(); - $minArgs = max(0, $requiredParams - 1); - $maxArgs = max(0, $totalParams - 1); - - if ($totalParams > 0) { - $lastParam = Reflection::getFunctionParameter($funcName, $totalParams - 1); - if ($lastParam !== null && $lastParam->isVariadic()) { - $maxArgs = -1; - } - } - - return [ - 'handler' => 'php_fn', - 'fn' => $funcName, - 'receiver_pos' => 1, - 'return_type' => $returnType, - 'min_args' => $minArgs, - 'max_args' => $maxArgs, - ]; - } - - protected function validateExtensionFirstParam(string $type, \TypePhp\Entity\FunctionDef $funcDef): bool - { - if (empty($funcDef->argInfoList)) { - return false; - } - $firstParam = $funcDef->argInfoList[0]; - // Stream/Box are PHP pseudo-types; their params may be typed or untyped - if ($type === Type::STREAM || $type === Type::BOX) { - return $firstParam->byRef || $firstParam->type === Type::VAR || $firstParam->type === Type::REF || $firstParam->type === $type; - } - if ($firstParam->byRef) { - return $type === Type::ARRAY; - } - $paramType = $firstParam->type; - if ($paramType === Type::VAR) { - return false; - } - return $paramType === $type; - } - - protected function validateInternalExtensionFirstParam(string $type, string $funcName): bool - { - $param = Reflection::getFunctionParameter($funcName, 0); - if ($param === null) { - return false; - } - // Stream pseudo-type: accept untyped or by-reference first params - if ($type === Type::STREAM) { - return true; - } - if ($param->isPassedByReference()) { - return $type === Type::ARRAY; - } - $paramType = $param->getType(); - if ($paramType === null) { - return false; - } - if ($paramType instanceof \ReflectionNamedType) { - $phpName = $paramType->getName(); - $compilerType = $this->zendTypeMap[$phpName] ?? null; - return $compilerType === $type; - } - return false; - } - - protected function resolveExtensionFunctionName(string $funcName): ?string - { - if ($this->hasFunction($funcName)) { - return $funcName; - } - return null; - } - /** * @param string $receiver C++ expression for the receiver * @param bool $isVar Whether the receiver is a variable (allows mutating methods) diff --git a/src/Preprocessor.php b/src/Preprocessor.php index 8bab8059..a03c86f3 100644 --- a/src/Preprocessor.php +++ b/src/Preprocessor.php @@ -455,7 +455,13 @@ class Preprocessor extends CompilerBase return $name; } - protected function findSymbolUsing(NodeAbstract $ast) + /** + * Collect per-file symbol dependencies for the incremental compilation cache. + * + * The cache does not consume this graph yet, but this collector is retained + * intentionally so cache invalidation can later be based on symbol usage. + */ + protected function findSymbolUsing(NodeAbstract $ast): void { $nodeFinder = new NodeFinder(); $functionCalls = $nodeFinder->findInstanceOf($ast, Node\Expr\FuncCall::class); @@ -485,8 +491,7 @@ class Preprocessor extends CompilerBase } } // 依赖去重 - $depClasses = array_unique($this->symbolCallInFile[$this->file]); - $this->symbolCallInFile[$this->file] = $depClasses; + $this->symbolCallInFile[$this->file] = array_unique($this->symbolCallInFile[$this->file]); } protected function prepareNamespace(Node\Stmt\Namespace_ $node): void diff --git a/src/Translator.php b/src/Translator.php index 41732c65..1714cebc 100644 --- a/src/Translator.php +++ b/src/Translator.php @@ -74,14 +74,12 @@ class Translator extends Preprocessor private ?ProjectYamlLoader $projectYamlLoader = null; private ?NativeBuilder $nativeBuilder = null; protected bool $verbose = false; - protected array $phpSrcFiles = []; protected array $ignorePaths = []; protected array $argInfoHeaderFiles = []; protected array $registerSymbols = []; // Windows 资源文件配置(图标、版本信息等) protected array $resourceConfig = []; - protected bool $useRegisterSymbolsFn = false; protected array $globalHeaders = [ 'cstring', 'phpx.h', @@ -548,7 +546,6 @@ class Translator extends Preprocessor } else { $this->save($cppCode, $cppFile); } - $this->phpSrcFiles[] = $file; // 生成 stub 文件,依赖 convert 阶段的 use 等信息 $this->genStubFile($this->file); return $cppCode === '' ? null : $cppFile; @@ -2944,7 +2941,7 @@ CODE; $needsAttributeSymbols = str_contains($headerCode, 'zend_add_function_attribute(') || str_contains($headerCode, 'zend_add_parameter_attribute(') || str_contains($headerCode, 'zend_add_global_constant_attribute('); - if ($this->useRegisterSymbolsFn || $needsAttributeSymbols) { + if ($needsAttributeSymbols) { if (preg_match('/\bstatic\s+void\s+(register_[A-Za-z0-9_]+_symbols)\s*\(\s*int\s+module_number\s*\)/', $headerCode, $matches)) { $registerSymbolFn = $matches[1]; $this->registerSymbols[] = $registerSymbolFn; @@ -3637,10 +3634,10 @@ CODE; $rawVar = 'raw_' . $var; $cppCode .= $this->getIndent() . Type::VAR . ' ' . $rawVar . ' = php::getCallArg(i);' . PHP_EOL; $cppCode .= $this->genStrictScalarParamCheck($argInfo, $rawVar, $displayName, 'i + 1'); - $cppCode .= $this->getIndent() . $var . '.append(' + $cppCode .= $this->getIndent() . $var . '.appendValue(' . $this->convertExprFromType($argInfo->type, $rawVar) . ');' . PHP_EOL; } else { - $cppCode .= $this->getIndent() . $var . '.append(php::getCallArg(i));' . PHP_EOL; + $cppCode .= $this->getIndent() . $var . '.appendValue(php::getCallArg(i));' . PHP_EOL; } $this->indentLevel--; $cppCode .= $this->getIndent() . '}' . PHP_EOL; @@ -3775,19 +3772,6 @@ CODE; return $cppCode; } - protected function getClassRegisterCeFunc(ClassDef|InterfaceDef $classDef): string - { - $cppCode = ''; - $name = $classDef->getNamespacedName(); - $argsDef = $this->getRegisterClassFunctionArgDef($classDef); - $param = $this->getRegisterClassFunctionArgs($classDef); - $cppCode .= 'zend_class_entry *' . $this->getRegisterClassFunction($name) . '(' . $argsDef . ') {' . PHP_EOL; - $cppCode .= $this->getIndent() . 'return register_class_' . $name . '(' . $param . ');' . PHP_EOL; - $cppCode .= '}' . PHP_EOL . PHP_EOL; - - return $cppCode; - } - protected function genClassWrapper(ClassDef|InterfaceDef $classDef): string { $cppCode = ''; @@ -3822,59 +3806,6 @@ CODE; return $cppCode; } - /** - * @param array $list - */ - protected function genClassConstantList(array $list): string - { - $code = ''; - foreach ($list as $const) { - $code .= $this->getIndent() . $this->genClassConstant($const); - } - - return $code; - } - - protected function genClassConstant(ConstantDef $const): string - { - return 'static const ' . $const->type . ' ' . $const->name . ';' . PHP_EOL; - } - - /** - * @param array $list - */ - protected function genClassPropertyList(array $list): string - { - $code = ''; - foreach ($list as $prop) { - $code .= $this->getIndent() . $this->genClassProperty($prop); - } - - return $code; - } - - protected function genClassProperty(PropertyDef $prop): string - { - $code = $prop->type . ' ' . $prop->name; - if ($prop->default !== null) { - $code .= ' = ' . $prop->default; - } - return $code . ';' . PHP_EOL; - } - - protected function genFunction(string $name, string $returnType, array $args = [], array $lines = []): string - { - $_args = []; - foreach ($args as $arg => $type) { - $_args[] = $type . ' ' . $arg; - } - $code = $returnType . ' ' . $name . '(' . implode(', ', $_args) . ') {' . PHP_EOL; - $code .= implode(PHP_EOL, $lines) . PHP_EOL; - $code .= '}' . PHP_EOL; - - return $code; - } - /** * Build type-check descriptor array from UnionType or NullableType AST node. * Returns ['check' => array, 'typeStr' => string] or empty check array if no check needed. @@ -5239,87 +5170,4 @@ CODE; ); } - private function genClassNative(): string - { - $code = 'class ' . $this->class . ' { '; - - $publicMethods = []; - $protectedMethods = []; - $privateMethods = []; - $publicConstants = []; - $protectedConstants = []; - $privateConstants = []; - $publicProperties = []; - $protectedProperties = []; - $privateProperties = []; - - foreach ($this->classDef->constants as $const) { - if ($const->flags & Modifiers::PUBLIC) { - $publicConstants[] = $const; - } - if ($const->flags & Modifiers::PROTECTED) { - $protectedConstants[] = $const; - } - if ($const->flags & Modifiers::PRIVATE) { - $privateConstants[] = $const; - } - } - foreach ($this->classDef->methods as $method) { - if ($method->flags & Modifiers::PUBLIC) { - $publicMethods[] = $method; - } - if ($method->flags & Modifiers::PROTECTED) { - $protectedMethods[] = $method; - } - if ($method->flags & Modifiers::PRIVATE) { - $privateMethods[] = $method; - } - } - foreach ($this->classDef->properties as $property) { - if ($property->flags & Modifiers::PUBLIC) { - $publicProperties[] = $property; - } - if ($property->flags & Modifiers::PROTECTED) { - $protectedProperties[] = $property; - } - if ($property->flags & Modifiers::PRIVATE) { - $privateProperties[] = $property; - } - } - - if ($privateConstants) { - $code .= 'private:' . PHP_EOL; - $code .= $this->genClassConstantList($privateConstants); - } - - if ($protectedConstants) { - $code .= 'protected:' . PHP_EOL; - $code .= $this->genClassConstantList($protectedConstants); - } - - if ($publicConstants) { - $code .= 'public:' . PHP_EOL; - $code .= $this->genClassConstantList($publicConstants); - } - - if ($privateProperties) { - $code .= 'private:' . PHP_EOL; - $code .= $this->genClassPropertyList($privateProperties); - } - - if ($protectedProperties) { - $code .= 'protected:' . PHP_EOL; - $code .= $this->genClassPropertyList($protectedProperties); - } - - if ($publicProperties) { - $code .= 'public:' . PHP_EOL; - $code .= $this->genClassPropertyList($publicProperties); - } - - $code .= '};' . PHP_EOL . PHP_EOL; - - return $code; - } - } diff --git a/src/gen_stub.php b/src/gen_stub.php index c4503df1..7e04e0e0 100755 --- a/src/gen_stub.php +++ b/src/gen_stub.php @@ -2827,7 +2827,7 @@ class ConstInfo extends VariableLike // Condition will be added by generateCodeWithConditions() if ($this->name instanceof ClassConstName) { - $code = $this->getClassConstDeclaration($value, $allConstInfos); + $code = $this->getClassConstDeclaration($value); } else { $code = $this->getGlobalConstDeclaration($value); } @@ -2888,12 +2888,10 @@ class ConstInfo extends VariableLike throw new Exception("Unimplemented constant type: " . $value->type->name); } - /** @param array $allConstInfos */ - private function getClassConstDeclaration(EvaluatedValue $value, array $allConstInfos): string + private function getClassConstDeclaration(EvaluatedValue $value): string { $constName = $this->name->getDeclarationName(); - // TODO $allConstInfos is unused $zvalCode = $value->initializeZval("const_{$constName}_value"); $code = "\n" . $zvalCode;