- 将preset.ts移动到config目录,符合架构规范 - 迁移php-tools到java-tools,参考Java架构而非PHP - 清理AI层文档,整合为单一README - 删除core层,专注boot和ai层 - 集成AI层与Boot层,实现100%组件集成 - 清理废弃js文件和临时报告文件 - 更新导入路径,保持代码一致性
456 lines
12 KiB
JavaScript
456 lines
12 KiB
JavaScript
/**
|
|
* 多阶段转换管道
|
|
* 为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('BadRequestException')) {
|
|
imports.push("import { BadRequestException } from '@nestjs/common';");
|
|
}
|
|
|
|
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;
|