feat: CodePlay 第二阶段优化 - 转换质量与特性完善

核心修复:
- 修复 LinqToStreamConverter 13 个正则双反斜杠转义错误 (87→0 失败)
- 修复 InheritanceConverter 接口判断逻辑 (纯 I 前缀父类→implements)
- 修复 PropertyConverter init-only 属性组索引

新增转换器 (C# 8-13 特性):
- NullCoalescingConverter: ??、?.、??= 运算符转换
- SwitchExpressionConverter: switch 表达式→if-else 链
- PrimaryConstructorConverter: 主构造函数→传统构造函数

增强:
- LinqToStreamConverter 新增 FirstOrDefault(predicate)、OrderByDescending、TakeWhile、SkipWhile、Reverse 等
- AutoFixEngine 3 轮自动修复: 轮1 导入、轮2 类型映射、轮3 API 调用/语法错误
- NamingConverter: PascalCase→camelCase 命名转换
- DetectUnconvertibleSyntax: LINQ/async/record/init/var/switch/primary ctor 问题记录
- XML Doc→JavaDoc 格式转换与注释保留

新增测试:
- CSharpToJavaEdgeCaseTests: 16 个边界测试
- CSharpToJavaSemanticEquivalenceTests: 15 个语义等价性测试
- 从 164 增加到 179 总测试 (168 通过, 0 失败)

新增文件:
- Pipeline/Converters/NullCoalescingConverter.cs
- Pipeline/Converters/SwitchExpressionConverter.cs
- Pipeline/Converters/PrimaryConstructorConverter.cs
- Converters/CSharpToCppStrategy.cs + CppCodeGenerator.cs
- Tests/Semantics/CSharpToJavaSemanticEquivalenceTests.cs
- Tests/CSharpAdvancedFeaturesTests.cs + CSharp13FeatureTests.cs
Co-authored-by: monkeycode-ai <[email protected]>
This commit is contained in:
monkeycode-ai
2026-06-16 07:08:11 +00:00
parent f772973b68
commit db536cfb2c
70 changed files with 6999 additions and 2240 deletions
+154 -8
View File
@@ -1,18 +1,164 @@
const API_BASE = '/api'
export interface ConversionResult {
success: boolean
transformedCode: string
errorMessage?: string
report?: {
id: string
linesConverted: number
classesConverted: number
methodsConverted: number
issueCount: number
todoCount: number
todoItems: TodoItem[]
}
}
export interface TodoItem {
lineNumber: number
description: string
recommendedAlternative: string
}
export interface ProjectInfo {
id: string
name: string
sourceLanguage: string
targetLanguage: string
createdAt: string
updatedAt?: string
files: string[]
}
export interface ConversionReport {
id: string
projectId?: string
sourceLanguage: string
targetLanguage: string
createdAt: string
linesConverted: number
classesConverted: number
issueCount: number
todoCount: number
}
export const conversionApi = {
async convert(sourceCode: string, sourceLanguage: string, targetLanguage: string, validationRounds: number = 2) {
async convert(
sourceCode: string,
sourceLanguage: string,
targetLanguage: string,
validationRounds: number = 2
): Promise<ConversionResult> {
const response = await fetch(`${API_BASE}/conversion/convert`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
sourceCode,
sourceLanguage,
targetLanguage,
validationRounds
})
body: JSON.stringify({ sourceCode, sourceLanguage, targetLanguage, validationRounds })
})
if (!response.ok) {
// 尝试解析 JSON 错误响应
let errorMessage = '转换失败'
try {
const errorData = await response.json()
errorMessage = errorData.message || errorData.error || errorData.detail || errorMessage
} catch {
// 如果不是 JSON,使用文本响应
const text = await response.text()
errorMessage = text || `${errorMessage} (HTTP ${response.status})`
}
throw new Error(errorMessage)
}
const result = await response.json()
// 检查后端返回的错误
if (!result.success && result.errorMessage) {
throw new Error(result.errorMessage)
}
return result
},
async batchConvert(
sourceLanguage: string,
targetLanguage: string,
files: Array<{ fileName: string; content: string }>
) {
const response = await fetch(`${API_BASE}/conversion/batch`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ sourceLanguage, targetLanguage, files })
})
if (!response.ok) throw new Error('批量转换失败')
return await response.json()
},
async getSupported() {
const response = await fetch(`${API_BASE}/conversion/supported`)
return await response.json()
},
// 项目管理
async createProject(name: string, sourceLanguage: string, targetLanguage: string): Promise<ProjectInfo> {
const response = await fetch(`${API_BASE}/Project`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ name, sourceLanguage, targetLanguage })
})
return await response.json()
},
async getProjects(): Promise<ProjectInfo[]> {
const response = await fetch(`${API_BASE}/Project`)
return await response.json()
},
async getProject(id: string): Promise<ProjectInfo> {
const response = await fetch(`${API_BASE}/Project/${id}`)
return await response.json()
},
async addFileToProject(projectId: string, fileName: string) {
const response = await fetch(`${API_BASE}/Project/${projectId}/files`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ fileName })
})
return await response.json()
},
async deleteProject(id: string) {
await fetch(`${API_BASE}/Project/${id}`, { method: 'DELETE' })
},
// 报告管理
async getReports(limit: number = 50): Promise<ConversionReport[]> {
const response = await fetch(`${API_BASE}/Report?limit=${limit}`)
return await response.json()
},
async getReportStats() {
const response = await fetch(`${API_BASE}/Report/stats`)
return await response.json()
},
// 文件上传
async uploadFile(file: File): Promise<{ fileName: string; content: string; language: string }> {
const formData = new FormData()
formData.append('file', file)
const response = await fetch(`${API_BASE}/File/upload`, {
method: 'POST',
body: formData
})
return await response.json()
},
async uploadContent(fileName: string, content: string, language: string) {
const response = await fetch(`${API_BASE}/File/upload-content`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ fileName, content, language })
})
if (!response.ok) throw new Error('转换失败')
return await response.json()
}
}