feat: 实现 Java → C# 转换器 (Task 2.5)

新增组件:
- JavaToCSharpStrategy: Java 到 C# 转换策略
- JavaToCSharpConverter: Java 到 C# 转换器
- JavaParser: Java 简化解析器(基于文本处理)
- CSharpCodeGenerator: C# 代码生成器

功能实现:
- 18 种类型映射(Java → C#)
- package → namespace 转换
- import → using 转换
- JavaDoc → XML Doc 转换
- Stream API 检测并添加 TODO
- CompletableFuture 检测并添加 TODO

测试覆盖:
- 添加 4 个 JavaToCSharpConverterTests 测试用例
- 总测试数 17 个,全部通过
Co-authored-by: monkeycode-ai <monkeycode-ai@chaitin.com>
This commit is contained in:
monkeycode-ai
2026-06-03 05:45:23 +00:00
parent 80b4718568
commit dd02c3a053
6 changed files with 858 additions and 0 deletions
+167
View File
@@ -0,0 +1,167 @@
using System.Text;
using CodePlay.Core.Interfaces;
using CodePlay.Core.Models;
using CodePlay.Core.Common;
namespace CodePlay.Core.Parsers;
/// <summary>
/// Java 语法解析器(简化版本,基于文本处理)
/// </summary>
public class JavaParser : BaseParser
{
/// <summary>
/// 支持的语言类型
/// </summary>
public override LanguageType SupportedLanguage => LanguageType.Java;
/// <summary>
/// 解析 Java 源代码
/// </summary>
public override Task<Interfaces.SyntaxTree> ParseAsync(string sourceCode, CancellationToken cancellationToken = default)
{
var tree = CreateSyntaxTree();
tree.SourceCode = sourceCode;
// 简单提取类和方**
var root = new Interfaces.SyntaxNode
{
Type = SyntaxNodeType.CompilationUnit,
Text = sourceCode
};
ExtractImports(tree, sourceCode);
ExtractPackages(tree, sourceCode);
ExtractClasses(tree, sourceCode, root);
ExtractComments(tree, sourceCode);
tree.Root = root;
return Task.FromResult(tree);
}
private void ExtractPackages(Interfaces.SyntaxTree tree, string sourceCode)
{
var packageMatch = System.Text.RegularExpressions.Regex.Match(sourceCode, @"package\s+([\w.]+);");
if (packageMatch.Success)
{
tree.Documentation.Add(new SyntaxDocumentation
{
ElementName = "package",
Content = packageMatch.Groups[1].Value,
Format = DocFormat.JavaDoc
});
}
}
private void ExtractImports(Interfaces.SyntaxTree tree, string sourceCode)
{
var importMatches = System.Text.RegularExpressions.Regex.Matches(sourceCode, @"import\s+([\w.]+);");
foreach (System.Text.RegularExpressions.Match match in importMatches)
{
tree.Comments.Add(new SyntaxComment
{
Text = $"import {match.Groups[1].Value};",
Type = CommentType.SingleLine,
LineNumber = 0
});
}
}
private void ExtractClasses(Interfaces.SyntaxTree tree, string sourceCode, Interfaces.SyntaxNode root)
{
var classPattern = @"(public|private|protected)?\s*(abstract|final|static)?\s*class\s+(\w+)(\s+extends\s+\w+)?(\s+implements\s+[\w,]+)?";
var classMatches = System.Text.RegularExpressions.Regex.Matches(sourceCode, classPattern);
foreach (System.Text.RegularExpressions.Match match in classMatches)
{
var classNode = new Interfaces.SyntaxNode
{
Type = SyntaxNodeType.Class,
Text = match.Value
};
root.Children.Add(classNode);
// 提取方法
ExtractMethods(match.Value, classNode);
// 提取字段
ExtractFields(match.Value, classNode);
}
}
private void ExtractMethods(string classCode, Interfaces.SyntaxNode classNode)
{
var methodPattern = @"(public|private|protected)?\s*(static)?\s*(\w+(?:<[^>]+>)?)\s+(\w+)\s*\([^)]*\)\s*(\{[^}]*\})?";
var methodMatches = System.Text.RegularExpressions.Regex.Matches(classCode, methodPattern);
foreach (System.Text.RegularExpressions.Match match in methodMatches)
{
if (!match.Value.Contains(" class ") && !match.Value.Contains(" new "))
{
var methodNode = new Interfaces.SyntaxNode
{
Type = SyntaxNodeType.Method,
Text = match.Value
};
classNode.Children.Add(methodNode);
}
}
}
private void ExtractFields(string classCode, Interfaces.SyntaxNode classNode)
{
var fieldPattern = @"(public|private|protected)?\s*(static)?\s*(final)?\s*(\w+)\\s+(\w+)\\s*;";
var fieldMatches = System.Text.RegularExpressions.Regex.Matches(classCode, fieldPattern);
foreach (System.Text.RegularExpressions.Match match in fieldMatches)
{
var fieldNode = new Interfaces.SyntaxNode
{
Type = SyntaxNodeType.Field,
Text = match.Value
};
classNode.Children.Add(fieldNode);
}
}
private void ExtractComments(Interfaces.SyntaxTree tree, string sourceCode)
{
var lines = sourceCode.Split('\n');
for (int i = 0; i < lines.Length; i++)
{
var line = lines[i].Trim();
if (line.StartsWith("//"))
{
tree.Comments.Add(new SyntaxComment
{
Text = line,
Type = CommentType.SingleLine,
LineNumber = i + 1
});
}
else if (line.StartsWith("/**"))
{
var javaDocContent = new StringBuilder();
for (int j = i; j < lines.Length; j++)
{
javaDocContent.AppendLine(lines[j]);
if (lines[j].Contains("*/"))
{
tree.Comments.Add(new SyntaxComment
{
Text = javaDocContent.ToString(),
Type = CommentType.JavaDoc,
LineNumber = i + 1
});
break;
}
}
}
}
}
}