/** * 多阶段转换管道 * 为AI自动生成打下基石 */ const ConversionRulesDatabase = require('./conversion-rules-database'); class ConversionPipeline { constructor() { this.rulesDB = new ConversionRulesDatabase(); this.stages = [ 'preprocessing', // 预处理 'syntax', // 语法转换 'semantic', // 语义转换 'context', // 上下文转换 'validation', // 验证 'postprocessing' // 后处理 ]; this.stageHandlers = { preprocessing: this.preprocess.bind(this), syntax: this.convertSyntax.bind(this), semantic: this.convertSemantic.bind(this), context: this.convertContext.bind(this), validation: this.validate.bind(this), postprocessing: this.postprocess.bind(this) }; } /** * 执行完整转换管道 */ async convert(phpCode, context = {}) { let convertedCode = phpCode; const results = { original: phpCode, stages: {}, errors: [], warnings: [], metrics: {} }; console.log('🚀 开始多阶段转换管道...'); for (const stage of this.stages) { try { console.log(`📋 执行阶段: ${stage}`); const startTime = Date.now(); convertedCode = await this.stageHandlers[stage](convertedCode, context, results); const endTime = Date.now(); results.stages[stage] = { input: results.stages[stage - 1]?.output || phpCode, output: convertedCode, duration: endTime - startTime, success: true }; console.log(`✅ 阶段 ${stage} 完成 (${endTime - startTime}ms)`); } catch (error) { console.error(`❌ 阶段 ${stage} 失败:`, error.message); results.errors.push({ stage, error: error.message, stack: error.stack }); results.stages[stage] = { success: false, error: error.message }; } } results.final = convertedCode; results.metrics = this.calculateMetrics(results); console.log('🎉 转换管道完成!'); return results; } /** * 预处理阶段 */ async preprocess(code, context, results) { console.log(' 🔧 预处理: 清理和标准化代码...'); // 清理代码 let processed = code // 移除多余的空白 .replace(/\s+/g, ' ') .replace(/\n\s*\n/g, '\n') // 标准化换行 .replace(/\r\n/g, '\n') .replace(/\r/g, '\n') // 移除注释中的特殊字符 .replace(/\/\*[\s\S]*?\*\//g, (match) => { return match.replace(/[^\x20-\x7E\n]/g, ''); }); // 检测代码特征 const features = this.detectFeatures(processed); context.features = features; console.log(` 📊 检测到特征: ${Object.keys(features).join(', ')}`); return processed; } /** * 语法转换阶段 */ async convertSyntax(code, context, results) { console.log(' 🔄 语法转换: 基础PHP到TypeScript转换...'); // 应用基础语法转换规则 let converted = this.rulesDB.applyRules(code, 'syntax'); // 应用类型转换规则 converted = this.rulesDB.applyRules(converted, 'types'); // 应用方法转换规则 converted = this.rulesDB.applyRules(converted, 'methods'); // 应用数组和对象转换规则 converted = this.rulesDB.applyRules(converted, 'collections'); // 应用异常处理转换规则 converted = this.rulesDB.applyRules(converted, 'exceptions'); // 应用字符串处理规则 converted = this.rulesDB.applyRules(converted, 'strings'); console.log(` 📈 语法转换完成,代码长度: ${converted.length}`); return converted; } /** * 语义转换阶段 */ async convertSemantic(code, context, results) { console.log(' 🧠 语义转换: 业务逻辑语义转换...'); // 应用服务调用转换规则 let converted = this.rulesDB.applyRules(code, 'services'); // 智能识别和转换业务逻辑模式 converted = this.convertBusinessPatterns(converted, context); // 转换控制流 converted = this.convertControlFlow(converted, context); console.log(` 🎯 语义转换完成,业务模式识别: ${context.features?.businessPatterns?.length || 0}个`); return converted; } /** * 上下文转换阶段 */ async convertContext(code, context, results) { console.log(' 🎭 上下文转换: 根据代码上下文优化转换...'); let converted = code; // 根据文件类型应用不同的转换策略 if (context.fileType === 'service') { converted = this.convertServiceContext(converted, context); } else if (context.fileType === 'controller') { converted = this.convertControllerContext(converted, context); } else if (context.fileType === 'entity') { converted = this.convertEntityContext(converted, context); } // 根据业务领域应用特定转换 if (context.businessDomain) { converted = this.convertBusinessDomain(converted, context); } console.log(` 🏗️ 上下文转换完成,文件类型: ${context.fileType || 'unknown'}`); return converted; } /** * 验证阶段 */ async validate(code, context, results) { console.log(' ✅ 验证: 检查转换质量和语法正确性...'); const validation = { syntax: this.validateSyntax(code), types: this.validateTypes(code), imports: this.validateImports(code), business: this.validateBusinessLogic(code, context) }; // 收集验证结果 const errors = []; const warnings = []; Object.entries(validation).forEach(([type, result]) => { if (result.errors) { errors.push(...result.errors.map(e => ({ type, ...e }))); } if (result.warnings) { warnings.push(...result.warnings.map(w => ({ type, ...w }))); } }); results.errors.push(...errors); results.warnings.push(...warnings); console.log(` 📊 验证完成: ${errors.length}个错误, ${warnings.length}个警告`); return code; } /** * 后处理阶段 */ async postprocess(code, context, results) { console.log(' 🎨 后处理: 最终优化和格式化...'); // 应用语法错误修复规则 let processed = this.rulesDB.applyRules(code, 'syntaxFixes'); // 格式化代码 processed = this.formatCode(processed); // 添加必要的导入语句 processed = this.addImports(processed, context); console.log(` 🎉 后处理完成,最终代码长度: ${processed.length}`); return processed; } /** * 检测代码特征 */ detectFeatures(code) { const features = { hasClasses: /class\s+\w+/.test(code), hasFunctions: /function\s+\w+/.test(code), hasArrays: /array\s*\(/.test(code), hasObjects: /->\s*\w+/.test(code), hasExceptions: /throw\s+new/.test(code), hasServices: /new\s+[A-Z]\w+Service/.test(code), hasControllers: /class\s+\w+Controller/.test(code), hasEntities: /@Entity|@Table/.test(code), businessPatterns: [] }; // 检测业务模式 const businessPatterns = [ { pattern: /success\s*\(/, name: 'success_response' }, { pattern: /error\s*\(/, name: 'error_response' }, { pattern: /validate\s*\(/, name: 'validation' }, { pattern: /cache\s*\(/, name: 'caching' }, { pattern: /log\s*\(/, name: 'logging' } ]; businessPatterns.forEach(({ pattern, name }) => { if (pattern.test(code)) { features.businessPatterns.push(name); } }); return features; } /** * 转换业务模式 */ convertBusinessPatterns(code, context) { let converted = code; // 转换success响应 converted = converted.replace(/return\s+success\s*\(([^)]+)\)/g, (match, data) => { return `return { success: true, data: ${data} };`; }); // 转换error响应 converted = converted.replace(/return\s+error\s*\(([^)]+)\)/g, (match, message) => { return `throw new BusinessException(${message});`; }); return converted; } /** * 转换控制流 */ convertControlFlow(code, context) { let converted = code; // 转换PHP控制流到TypeScript converted = converted.replace(/foreach\s*\(\s*([^)]+)\s+as\s+([^)]+)\s*\)/g, 'for (const $2 of $1)'); converted = converted.replace(/foreach\s*\(\s*([^)]+)\s+as\s+([^)]+)\s*=>\s*([^)]+)\s*\)/g, 'for (const [$3, $2] of Object.entries($1))'); return converted; } /** * 服务上下文转换 */ convertServiceContext(code, context) { // 服务特定的转换逻辑 return code; } /** * 控制器上下文转换 */ convertControllerContext(code, context) { // 控制器特定的转换逻辑 return code; } /** * 实体上下文转换 */ convertEntityContext(code, context) { // 实体特定的转换逻辑 return code; } /** * 业务领域转换 */ convertBusinessDomain(code, context) { // 根据业务领域应用特定转换 return code; } /** * 验证语法 */ validateSyntax(code) { const errors = []; const warnings = []; // 检查基本语法错误 if (code.includes(']]')) { errors.push({ message: '发现方括号错误', line: this.findLineNumber(code, ']]') }); } if (code.includes('BusinessBusinessException')) { errors.push({ message: '发现重复的Business前缀', line: this.findLineNumber(code, 'BusinessBusinessException') }); } return { errors, warnings }; } /** * 验证类型 */ validateTypes(code) { const errors = []; const warnings = []; // 类型验证逻辑 return { errors, warnings }; } /** * 验证导入 */ validateImports(code) { const errors = []; const warnings = []; // 导入验证逻辑 return { errors, warnings }; } /** * 验证业务逻辑 */ validateBusinessLogic(code, context) { const errors = []; const warnings = []; // 业务逻辑验证 return { errors, warnings }; } /** * 格式化代码 */ formatCode(code) { // 简单的代码格式化 return code .replace(/\s+/g, ' ') .replace(/\n\s*\n/g, '\n') .trim(); } /** * 添加导入语句 */ addImports(code, context) { // 根据代码内容添加必要的导入 let imports = []; if (code.includes('BusinessException')) { imports.push("import { BusinessException } from '@wwjCommon/exceptions/business.exception';"); } if (code.includes('@Injectable')) { imports.push("import { Injectable } from '@nestjs/common';"); } if (imports.length > 0) { return imports.join('\n') + '\n\n' + code; } return code; } /** * 计算指标 */ calculateMetrics(results) { const originalLength = results.original.length; const finalLength = results.final.length; return { originalLength, finalLength, compressionRatio: (originalLength - finalLength) / originalLength, errorCount: results.errors.length, warningCount: results.warnings.length, stageCount: Object.keys(results.stages).length, totalDuration: Object.values(results.stages).reduce((sum, stage) => sum + (stage.duration || 0), 0) }; } /** * 查找行号 */ findLineNumber(code, searchText) { const lines = code.split('\n'); for (let i = 0; i < lines.length; i++) { if (lines[i].includes(searchText)) { return i + 1; } } return -1; } } module.exports = ConversionPipeline;