f772973b68
增强内容: C# 解析器增强 (CSharpParser.cs): ✅ 泛型支持:TypeParameter, TypeArgument 提取 ✅ 特性支持:Attribute 检测 ✅ async/await 检测 ✅ LINQ 使用统计 ✅ 访问修饰符提取 (public/private/protected/internal) ✅ 类修饰符 (abstract/static/sealed) ✅ 方法修饰符 (virtual/override/async) ✅ 属性 getter/setter 检测 ✅ 字段修饰符 (static/const/readonly) Java 解析器增强 (JavaParser.cs): ✅ 注解检测 (@Override, @Deprecated 等) ✅ 泛型支持 (TypeParameters) ✅ record 类支持 (Java 16+) ✅ sealed/non-sealed 接口 ✅ Lambda 表达式计数 ✅ Stream API 使用统计 ✅ Optional 使用统计 ✅ 注解提取 ✅ 方法修饰符 (static/final/synchronized) ✅ 字段修饰符 (final/transient/volatile) ✅ throws 子句提取 不可转换检测优化 (TodoGenerator.cs): ✅ 13 种 C# 特有模式检测 (LINQ/async/event/dynamic 等) ✅ 7 种 Java 特有模式检测 (Stream/Lambda/Optional 等) ✅ 替代方案建议 ✅ 置信度评分 ✅ 去重和排序 测试结果: 40 个测试通过 (2 个 Java 解析器测试需更新) 新增 PatternInfo 和 ConversionSuggestion 类用于模式匹配 Co-authored-by: monkeycode-ai <monkeycode-ai@chaitin.com>
109 lines
5.0 KiB
C#
109 lines
5.0 KiB
C#
using CodePlay.Core.Models;
|
|
using CodePlay.Core.Common;
|
|
|
|
namespace CodePlay.Core.Services;
|
|
|
|
public class TodoGenerator
|
|
{
|
|
private static readonly List<PatternInfo> CSharpPatterns = new()
|
|
{
|
|
new PatternInfo("linq", @"\.(Where|Select|OrderBy|FirstOrDefault|Any|All|Count|ToList)\s*\(", "LINQ 查询", "Java 没有 LINQ", "Stream API"),
|
|
new PatternInfo("async_await", @"async\s+[\w<>]+\s+\w+\s*\([^)]*\)", "async/await 异步方法", "Java 使用 CompletableFuture", "CompletableFuture"),
|
|
new PatternInfo("attributes", @"\[(?:Obsolete|Serializable|DataContract|DllImport)\b", "C# 特性", "Java 使用注解", "@Annotation"),
|
|
new PatternInfo("delegate", @"\b(?:Action|Func|EventHandler)\b", "委托类型", "Java 使用函数式接口", "Function/Consumer"),
|
|
new PatternInfo("event", @"\bevent\s+", "C# 事件", "Java 使用观察者模式", "PropertyChangeListener"),
|
|
new PatternInfo("dynamic", @"\bdynamic\b", "dynamic 类型", "Java 使用 Object", "Object/反射"),
|
|
new PatternInfo("pattern_match", @"\bis\s+(?:not\s+)?null", "模式匹配", "Java 16+ 支持", "instanceof"),
|
|
new PatternInfo("nullable", @"\?\s+", "可空引用", "Java 使用 Optional", "Optional"),
|
|
new PatternInfo("using_stmt", @"using\s*\([^)]+\)\s*\{", "using 语句", "Java try-with-resources", "try-with-resources"),
|
|
new PatternInfo("yield", @"\byield\s+return", "yield return", "Java 使用 Iterator", "Iterator"),
|
|
new PatternInfo("record", @"\brecord\s+\w+", "C# record", "Java 16+ record", "Java record"),
|
|
new PatternInfo("init_only", @"\binit\s*;", "init-only", "Java 使用 final", "final 字段"),
|
|
new PatternInfo("var", @"\bvar\s+\w+\s*=", "var 推断", "Java 10+ var", "var (Java 10+)")
|
|
};
|
|
|
|
private static readonly List<PatternInfo> JavaPatterns = new()
|
|
{
|
|
new PatternInfo("stream", @"\.(stream|filter|map|collect|reduce)\s*\(", "Stream API", "C# 使用 LINQ", "LINQ"),
|
|
new PatternInfo("lambda", @"->\s*\{", "Lambda 表达式", "C# 使用 =>", "=> lambda"),
|
|
new PatternInfo("optional", @"Optional<", "Optional 类型", "C# 使用可空", "Nullable"),
|
|
new PatternInfo("annotation", @"@(?:Override|Deprecated|FunctionalInterface)\b", "Java 注解", "C# 使用特性", "[Attribute]"),
|
|
new PatternInfo("wildcard", @"\?\s+(?:extends|super)", "泛型通配符", "C# in/out", "in/out"),
|
|
new PatternInfo("diamond", @"<>\s*;", "菱形操作符", "C# var 推断", "var"),
|
|
new PatternInfo("method_ref", @"::\s*\w+", "方法引用", "C# 组方法", "组方法")
|
|
};
|
|
|
|
public List<TodoItem> GenerateTodos(string sourceCode, LanguageType sourceLanguage, LanguageType targetLanguage)
|
|
{
|
|
var todos = new List<TodoItem>();
|
|
var patterns = sourceLanguage == LanguageType.CSharp ? CSharpPatterns : JavaPatterns;
|
|
|
|
foreach (var pattern in patterns)
|
|
{
|
|
var matches = System.Text.RegularExpressions.Regex.Matches(sourceCode, pattern.Pattern);
|
|
foreach (System.Text.RegularExpressions.Match match in matches)
|
|
{
|
|
todos.Add(new TodoItem
|
|
{
|
|
Description = pattern.Name,
|
|
LineNumber = GetLineNumber(sourceCode, match.Index),
|
|
OriginalSyntax = match.Value.Trim(),
|
|
WhyNotDirect = pattern.Reason,
|
|
RecommendedAlternative = pattern.Alternative
|
|
});
|
|
}
|
|
}
|
|
|
|
return todos.GroupBy(t => new { t.Description, t.LineNumber })
|
|
.Select(g => g.First())
|
|
.OrderBy(t => t.LineNumber)
|
|
.ToList();
|
|
}
|
|
|
|
public string GenerateTodoComment(TodoItem todo)
|
|
{
|
|
return $"// TODO: {todo.Description} - {todo.WhyNotDirect}";
|
|
}
|
|
|
|
public ConversionSuggestion Analyze(string sourceCode, LanguageType sourceLanguage, LanguageType targetLanguage)
|
|
{
|
|
var todos = GenerateTodos(sourceCode, sourceLanguage, targetLanguage);
|
|
return new ConversionSuggestion
|
|
{
|
|
TotalIssues = todos.Count,
|
|
ConfidenceScore = Math.Max(0, 100 - todos.Count * 5),
|
|
TodoItems = todos
|
|
};
|
|
}
|
|
|
|
private int GetLineNumber(string sourceCode, int index)
|
|
{
|
|
return sourceCode.Substring(0, index).Count(c => c == '\n') + 1;
|
|
}
|
|
}
|
|
|
|
public class PatternInfo
|
|
{
|
|
public string Key { get; set; } = "";
|
|
public string Pattern { get; set; } = "";
|
|
public string Name { get; set; } = "";
|
|
public string Reason { get; set; } = "";
|
|
public string Alternative { get; set; } = "";
|
|
|
|
public PatternInfo(string key, string pattern, string name, string reason, string alternative)
|
|
{
|
|
Key = key;
|
|
Pattern = pattern;
|
|
Name = name;
|
|
Reason = reason;
|
|
Alternative = alternative;
|
|
}
|
|
}
|
|
|
|
public class ConversionSuggestion
|
|
{
|
|
public int TotalIssues { get; set; }
|
|
public int ConfidenceScore { get; set; }
|
|
public List<TodoItem> TodoItems { get; set; } = new();
|
|
}
|