db536cfb2c
核心修复: - 修复 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 <monkeycode-ai@chaitin.com>
72 lines
3.1 KiB
C#
72 lines
3.1 KiB
C#
using CodePlay.Core.Interfaces;
|
|
using CodePlay.Core.Models;
|
|
using CodePlay.Core.Common;
|
|
|
|
namespace CodePlay.Core.Converters;
|
|
|
|
public class CSharpToCppStrategy : IConversionStrategy
|
|
{
|
|
public LanguageType SourceLanguage => LanguageType.CSharp;
|
|
public LanguageType TargetLanguage => LanguageType.CPlusPlus;
|
|
|
|
private readonly List<(string Src, string Tgt)> _mappings = new();
|
|
|
|
public CSharpToCppStrategy() => InitMappings();
|
|
|
|
void InitMappings()
|
|
{
|
|
_mappings.AddRange(new[] {
|
|
("string", "std::string"), ("String", "std::string"),
|
|
("int", "int"), ("long", "long"), ("bool", "bool"),
|
|
("double", "double"), ("float", "float"),
|
|
("List<", "std::vector<"), ("Dictionary<", "std::map<"),
|
|
("Console.WriteLine", "std::cout <<"),
|
|
("DateTime", "std::chrono::system_clock::time_point"),
|
|
("Exception", "std::exception"),
|
|
("Task<", "std::future<"), ("async Task", "std::future"),
|
|
("var ", "auto "),
|
|
});
|
|
}
|
|
|
|
public SyntaxNode ConvertNode(SyntaxNode node, ConversionContext context)
|
|
{
|
|
var nn = new SyntaxNode {
|
|
Type = node.Type, Text = Convert(node.Text),
|
|
Metadata = new Dictionary<string, object?>(node.Metadata),
|
|
Parent = node.Parent, Children = new List<SyntaxNode>(),
|
|
IsUnconvertible = node.IsUnconvertible, TodoDescription = node.TodoDescription
|
|
};
|
|
foreach (var c in node.Children) { var cc = ConvertNode(c, context); cc.Parent = nn; nn.Children.Add(cc); }
|
|
return nn;
|
|
}
|
|
|
|
string Convert(string t)
|
|
{
|
|
if (string.IsNullOrWhiteSpace(t)) return t;
|
|
var r = t;
|
|
|
|
if (r.Trim().StartsWith("namespace ")) r = r.Replace("namespace ", "namespace ") + " {";
|
|
if (r.Trim().StartsWith("using ")) r = "#include <" + System.Text.RegularExpressions.Regex.Match(r, @"using\s+([\w.]+);").Groups[1].Value.Replace(".", "/") + ">";
|
|
|
|
foreach (var (s, tgt) in _mappings) r = r.Replace(s, tgt);
|
|
|
|
r = System.Text.RegularExpressions.Regex.Replace(r, @"(public|private|protected)\s+(\w+)\s+(\w+)\s*\{\s*get;\s*set;\s*\}", m =>
|
|
{
|
|
var mod = m.Groups[1].Value == "public" ? "" : m.Groups[1].Value + ":";
|
|
var type = m.Groups[2].Value; var name = m.Groups[3].Value;
|
|
return $"{mod}\n {type} {name};\n";
|
|
});
|
|
|
|
r = r.Replace("async ", "").Replace("await ", "");
|
|
r = System.Text.RegularExpressions.Regex.Replace(r, @"return\s+await\s+Task\.FromResult\(", "return std::async([]{ return ");
|
|
r = r.Replace(".Where(", ".| std::views::filter(").Replace(".Select(", ".| std::views::transform(");
|
|
r = r.Replace(".ToList()", ".to_vector()");
|
|
r = System.Text.RegularExpressions.Regex.Replace(r, @"(\w+)\s*=>", m => $"{m.Groups[1].Value}");
|
|
|
|
r = r.Replace("null", "nullptr").Replace("true", "true").Replace("false", "false");
|
|
return r;
|
|
}
|
|
|
|
public string MapType(string s) { var r = s; foreach (var (src, tgt) in _mappings) r = r.Replace(src, tgt); return r; }
|
|
}
|