using System.Text; using System.Text.RegularExpressions; using CodePlay.Core.Interfaces; using CodePlay.Core.Models; using CodePlay.Core.Common; namespace CodePlay.Core.Converters; public class JavaToCSharpStrategy : IConversionStrategy { public LanguageType SourceLanguage => LanguageType.Java; public LanguageType TargetLanguage => LanguageType.CSharp; private readonly List _typeMappings; public JavaToCSharpStrategy() { _typeMappings = InitializeTypeMappings(); } private List InitializeTypeMappings() { return new List { // 基本类型 new("String", "string"), new("java.lang.String", "string"), new("Integer", "int"), new("Long", "long"), new("Float", "float"), new("Double", "double"), new("Boolean", "bool"), new("Byte", "byte"), new("Character", "char"), new("Short", "short"), new("Void", "void"), // 集合类型 new("ArrayList<", "List<"), new("LinkedList<", "LinkedList<"), new("HashSet<", "HashSet<"), new("TreeSet<", "SortedSet<"), new("HashMap<", "Dictionary<"), new("TreeMap<", "SortedDictionary<"), new("ConcurrentHashMap<", "ConcurrentDictionary<"), new("List<", "IList<"), new("Map<", "IDictionary<"), new("Set<", "ISet<"), // 任务/异步 new("CompletableFuture<", "Task<"), new("CompletableFuture", "Task"), new("CompletableFuture", "Task"), // 时间类型 new("LocalDateTime", "DateTime"), new("LocalDate", "DateOnly"), new("LocalTime", "TimeOnly"), new("Duration", "TimeSpan"), new("Period", "TimeSpan"), new("Instant", "DateTime"), new("ZoneId", "TimeZoneInfo"), // 异常类型 new("IllegalArgumentException", "ArgumentException"), new("IllegalStateException", "InvalidOperationException"), new("NullPointerException", "ArgumentNullException"), new("IOException", "IOException"), new("RuntimeException", "Exception"), new("Exception", "Exception"), new("Throwable", "Exception"), // 其他 new("StringBuilder", "StringBuilder"), new("Object", "object"), new("Class<", "Type"), }; } public SyntaxNode ConvertNode(SyntaxNode node, ConversionContext context) { var newNode = new SyntaxNode { Type = node.Type, Text = ConvertText(node.Text ?? "", context), Metadata = new Dictionary(node.Metadata ?? new Dictionary()), Parent = node.Parent, Children = new List(), IsUnconvertible = node.IsUnconvertible, TodoDescription = node.TodoDescription }; foreach (var child in node.Children) { var convertedChild = ConvertNode(child, context); convertedChild.Parent = newNode; newNode.Children.Add(convertedChild); } return newNode; } public string MapType(string sourceType) { var result = sourceType; foreach (var mapping in _typeMappings) { if (result.Contains(mapping.SourceType)) { result = result.Replace(mapping.SourceType, mapping.TargetType); } } return result; } private string ConvertText(string text, ConversionContext context) { if (string.IsNullOrWhiteSpace(text)) return text; var result = text; // 1. package -> namespace result = Regex.Replace(result, @"^package\s+([\w.]+)\s*;", m => $"namespace {m.Groups[1].Value.Replace('_', '.')}"); // 2. import -> using result = Regex.Replace(result, @"^import\s+([\w.]+)\s*;", m => $"using {m.Groups[1].Value};"); // 移除 Java 特有的静态导入 result = Regex.Replace(result, @"^import\s+static\s+[\w.]+\s*;[\r\n]*", ""); // 3. 添加常用的 using 语句 if (result.Contains("List<") || result.Contains("ArrayList")) { if (!result.Contains("using System.Collections.Generic;")) { var insertIdx = result.IndexOf("using "); if (insertIdx >= 0) { var endOfLine = result.IndexOf('\n', insertIdx); result = result.Insert(endOfLine + 1, "using System.Collections.Generic;\n"); } } } // 4. 类型映射 foreach (var mapping in _typeMappings) { result = Regex.Replace(result, $@"\b{Regex.Escape(mapping.SourceType)}(?=<|\b)", mapping.TargetType); } // 5. extends -> : (类继承) result = Regex.Replace(result, @"(class\s+\w+)\s+extends\s+(\w+)", "$1 : $2"); // 6. implements -> : (接口实现) result = Regex.Replace(result, @"(class\s+\w+\s*(?::\s*\w+)?)\s+implements\s+", "$1, "); // 7. 移除 Java 注解 result = Regex.Replace(result, @"@\w+(?:\([^)]*\))?\s*", ""); // 8. static import 处理 result = Regex.Replace(result, @"import\s+static\s+([\w.]+)\s*;", "// TODO: Convert static import: using static $1;"); // 9. System.out.println -> Console.WriteLine result = Regex.Replace(result, @"System\.out\.println\s*\(", "Console.WriteLine("); // 10. System.out.print -> Console.Write result = Regex.Replace(result, @"System\.out\.print\s*\(", "Console.Write("); // 11. super -> base result = Regex.Replace(result, @"\bsuper\b", "base"); // 12. this -> this (保持不变) // result = Regex.Replace(result, @"\bthis\b", "this"); // 13. null, true, false (Java 和 C# 相同,但确保小写) result = result.Replace("null", "null") .Replace("true", "true") .Replace("false", "false"); // 14. getter/setter -> C# 属性 result = ConvertGettersSetters(result); // 15. Lambda 表达式:(a, b) -> expr => (a, b) => expr result = Regex.Replace(result, @"(\w+)\s*->\s*", "$1 => "); result = Regex.Replace(result, @"\(([\w,\s]+)\)\s*->\s*", "($1) => "); // 16. Stream API -> LINQ result = ConvertStreamToLinq(result); // 17. CompletableFuture -> Task result = Regex.Replace(result, @"CompletableFuture\.completedFuture\(", "Task.FromResult("); result = Regex.Replace(result, @"CompletableFuture\.supplyAsync\(", "Task.Run("); result = Regex.Replace(result, @"\.thenApply\(", ".ContinueWith(t => "); result = Regex.Replace(result, @"\.thenCompose\(", ".ContinueWith("); result = Regex.Replace(result, @"\.whenComplete\(", ".ContinueWith("); // 18. throws -> 移除 (C# 不强制声明异常) result = Regex.Replace(result, @"\s*throws\s+\w+(?:\s*,\s*\w+)*", ""); // 19. @Override -> [Obsolete] 或移除 result = Regex.Replace(result, @"@Override\s*", "// [Obsolete]\n"); // 20. final -> 不移除 (C# 没有等价物,但可作为注释保留) result = Regex.Replace(result, @"\bfinal\s+", "// final\n"); // 21. 泛型通配符处理 result = Regex.Replace(result, @"List<\? extends (\w+)>", "IEnumerable<$1>"); result = Regex.Replace(result, @"List<\? super (\w+)>", "IList<$1>"); result = Regex.Replace(result, @"List<\?>", "IEnumerable"); // 22. 方法引用 -> Lambda result = Regex.Replace(result, @"(\w+)::(\w+)", "x => x.$2"); return result; } private string ConvertGettersSetters(string code) { // 处理 getter: public Type getName() { return name; } code = Regex.Replace(code, @"(public|private|protected)\s+(\w+)\s+get(\w+)\s*\(\s*\)\s*\{\s*return\s+(\w+)\s*;\s*\}", m => { var access = m.Groups[1].Value; var type = m.Groups[2].Value; var propName = Capitalize(m.Groups[4].Value); var fieldName = m.Groups[4].Value; return $"{access} {type} {propName} {{ get => {fieldName}; }}"; }); // 处理 setter: public void setName(Type name) { this.name = name; } var setterPattern = @"(public|private|protected)\s+void\s+set(\w+)\s*\(\s*(\w+)\s+(\w+)\s*\)\s*\{\s*this\.(\w+)\s*=\s*(\w+)\s*;\s*\}"; var setters = Regex.Matches(code, setterPattern); foreach (Match setter in setters) { var access = setter.Groups[1].Value; var propName = Capitalize(setter.Groups[2].Value); var type = setter.Groups[3].Value; var paramName = setter.Groups[4].Value; var fieldName = setter.Groups[5].Value; // 查找对应的 getter 并组合成完整属性 var getterPattern = $@"({access})\s+{type}\s+{propName}\s*\{{\s*get\s*=>\s*{fieldName}\s*;\s*\}}"; var getterMatch = Regex.Match(code, getterPattern); if (getterMatch.Success) { // 替换为完整属性 code = Regex.Replace(code, getterPattern, $"{access} {type} {propName} {{ get; set; }}"); // 移除 setter code = Regex.Replace(code, setterPattern, ""); } } return code; } private string ConvertStreamToLinq(string code) { // Stream 方法映射 var mappings = new (string Java, string CSharp)[] { (".stream()", ""), // C# 直接使用 IEnumerable (".filter(", ".Where("), (".map(", ".Select("), (".flatMap(", ".SelectMany("), (".anyMatch(", ".Any("), (".allMatch(", ".All("), (".noneMatch(", "!.Any("), (".count()", ".Count()"), (".sum()", ".Sum()"), (".average()", ".Average()"), (".max(", ".Max("), (".min(", ".Min("), (".findFirst().orElse(null)", ".FirstOrDefault()"), (".findFirst().orElseThrow()", ".First()"), (".findAny()", ".FirstOrDefault()"), (".collect(Collectors.toList())", ".ToList()"), (".collect(Collectors.toSet())", ".ToHashSet()"), (".collect(Collectors.toMap(", ".ToDictionary("), (".collect(Collectors.joining(", ".Aggregate("), (".collect(Collectors.groupingBy(", ".GroupBy("), (".collect(Collectors.partitioningBy(", ".GroupBy("), (".skip(", ".Skip("), (".limit(", ".Take("), (".takeWhile(", ".TakeWhile("), (".dropWhile(", ".SkipWhile("), (".sorted(", ".OrderBy(x => x)"), (".sorted(Comparator.", ".OrderBy("), (".distinct(", ".Distinct("), (".peek(", ".Select("), // C# 没有直接的 Peek (".reduce(", ".Aggregate("), (".forEach(", ".ToList().ForEach("), (".toArray(", ".ToArray()"), (".parallel()", ".AsParallel()"), (".parallelStream()", ".AsParallel()"), }; var result = code; foreach (var (java, csharp) in mappings) { result = Regex.Replace(result, Regex.Escape(java), csharp); } // 添加 LINQ using if (result.Contains(".Where(") || result.Contains(".Select(") || result.Contains(".Any(")) { if (!result.Contains("using System.Linq;")) { var insertIdx = result.IndexOf("using "); if (insertIdx >= 0) { var endOfLine = result.IndexOf('\n', insertIdx); result = result.Insert(endOfLine + 1, "using System.Linq;\n"); } } } return result; } private string Capitalize(string s) { if (string.IsNullOrEmpty(s)) return s; return char.ToUpperInvariant(s[0]) + s.Substring(1); } } public class TypeMapping { public string SourceType { get; set; } public string TargetType { get; set; } public TypeMapping(string source, string target) { SourceType = source; TargetType = target; } }