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>
880 lines
26 KiB
C#
880 lines
26 KiB
C#
using CodePlay.Core.Parsers;
|
|
using CodePlay.Core.Converters;
|
|
using CodePlay.Core.Common;
|
|
using Xunit;
|
|
|
|
namespace CodePlay.Tests.Converters;
|
|
|
|
public class CSharp13FeatureTests
|
|
{
|
|
private readonly CSharpParser _parser;
|
|
private readonly CSharpToJavaConverter _converter;
|
|
|
|
public CSharp13FeatureTests()
|
|
{
|
|
_parser = new CSharpParser();
|
|
_converter = new CSharpToJavaConverter();
|
|
}
|
|
|
|
#region 1. 参数数组展开运算符 (Spread Operator) - 4 个测试
|
|
|
|
[Fact]
|
|
public async Task ConvertAsync_SpreadOperator_IntArraySpread_ShouldConvert()
|
|
{
|
|
var sourceCode = @"
|
|
int[] a = { 1, 2, 3 };
|
|
int[] b = { 0, ..a, 4 };";
|
|
|
|
var syntaxTree = await _parser.ParseAsync(sourceCode);
|
|
var result = await _converter.ConvertAsync(syntaxTree, LanguageType.Java);
|
|
|
|
Assert.NotNull(result);
|
|
Assert.True(result.Success);
|
|
Assert.NotNull(result.TransformedCode);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task ConvertAsync_SpreadOperator_StringArraySpread_ShouldConvert()
|
|
{
|
|
var sourceCode = @"
|
|
string[] names = { ""Alice"", ""Bob"" };
|
|
string[] all = { ..names, ""Charlie"" };";
|
|
|
|
var syntaxTree = await _parser.ParseAsync(sourceCode);
|
|
var result = await _converter.ConvertAsync(syntaxTree, LanguageType.Java);
|
|
|
|
Assert.NotNull(result);
|
|
Assert.True(result.Success);
|
|
Assert.NotNull(result.TransformedCode);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task ConvertAsync_SpreadOperator_MultipleSpreads_ShouldConvert()
|
|
{
|
|
var sourceCode = @"
|
|
int[] a = { 1, 2 };
|
|
int[] b = { 3, 4 };
|
|
int[] combined = { ..a, 0, ..b };";
|
|
|
|
var syntaxTree = await _parser.ParseAsync(sourceCode);
|
|
var result = await _converter.ConvertAsync(syntaxTree, LanguageType.Java);
|
|
|
|
Assert.NotNull(result);
|
|
Assert.True(result.Success);
|
|
Assert.NotNull(result.TransformedCode);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task ConvertAsync_SpreadOperator_CollectionExpression_ShouldConvert()
|
|
{
|
|
var sourceCode = @"
|
|
List<int> list = [1, ..existingList, 5];";
|
|
|
|
var syntaxTree = await _parser.ParseAsync(sourceCode);
|
|
var result = await _converter.ConvertAsync(syntaxTree, LanguageType.Java);
|
|
|
|
Assert.NotNull(result);
|
|
Assert.True(result.Success);
|
|
Assert.NotNull(result.TransformedCode);
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region 2. 隐式 Lambda 参数类型 - 4 个测试
|
|
|
|
[Fact]
|
|
public async Task ConvertAsync_ImplicitLambda_SingleParameter_ShouldConvert()
|
|
{
|
|
var sourceCode = @"
|
|
var square = x => x * x;";
|
|
|
|
var syntaxTree = await _parser.ParseAsync(sourceCode);
|
|
var result = await _converter.ConvertAsync(syntaxTree, LanguageType.Java);
|
|
|
|
Assert.NotNull(result);
|
|
Assert.True(result.Success);
|
|
Assert.NotNull(result.TransformedCode);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task ConvertAsync_ImplicitLambda_TwoParameters_ShouldConvert()
|
|
{
|
|
var sourceCode = @"
|
|
var add = (x, y) => x + y;";
|
|
|
|
var syntaxTree = await _parser.ParseAsync(sourceCode);
|
|
var result = await _converter.ConvertAsync(syntaxTree, LanguageType.Java);
|
|
|
|
Assert.NotNull(result);
|
|
Assert.True(result.Success);
|
|
Assert.NotNull(result.TransformedCode);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task ConvertAsync_ImplicitLambda_MultiParameters_ShouldConvert()
|
|
{
|
|
var sourceCode = @"
|
|
Func<int, int, int> add = (x, y) => x + y;";
|
|
|
|
var syntaxTree = await _parser.ParseAsync(sourceCode);
|
|
var result = await _converter.ConvertAsync(syntaxTree, LanguageType.Java);
|
|
|
|
Assert.NotNull(result);
|
|
Assert.True(result.Success);
|
|
Assert.NotNull(result.TransformedCode);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task ConvertAsync_ImplicitLambda_WithBlockBody_ShouldConvert()
|
|
{
|
|
var sourceCode = @"
|
|
var process = (a, b) => {
|
|
var sum = a + b;
|
|
return sum * 2;
|
|
};";
|
|
|
|
var syntaxTree = await _parser.ParseAsync(sourceCode);
|
|
var result = await _converter.ConvertAsync(syntaxTree, LanguageType.Java);
|
|
|
|
Assert.NotNull(result);
|
|
Assert.True(result.Success);
|
|
Assert.NotNull(result.TransformedCode);
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region 3. 列表模式匹配 - 4 个测试
|
|
|
|
[Fact]
|
|
public async Task ConvertAsync_ListPattern_EmptyListMatch_ShouldConvert()
|
|
{
|
|
var sourceCode = @"
|
|
if (values is []) { return true; }";
|
|
|
|
var syntaxTree = await _parser.ParseAsync(sourceCode);
|
|
var result = await _converter.ConvertAsync(syntaxTree, LanguageType.Java);
|
|
|
|
Assert.NotNull(result);
|
|
Assert.True(result.Success);
|
|
Assert.NotNull(result.TransformedCode);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task ConvertAsync_ListPattern_SingleElementMatch_ShouldConvert()
|
|
{
|
|
var sourceCode = @"
|
|
if (values is [1]) { return true; }";
|
|
|
|
var syntaxTree = await _parser.ParseAsync(sourceCode);
|
|
var result = await _converter.ConvertAsync(syntaxTree, LanguageType.Java);
|
|
|
|
Assert.NotNull(result);
|
|
Assert.True(result.Success);
|
|
Assert.NotNull(result.TransformedCode);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task ConvertAsync_ListPattern_MultipleElementsMatch_ShouldConvert()
|
|
{
|
|
var sourceCode = @"
|
|
if (values is [1, 2, 3]) { }";
|
|
|
|
var syntaxTree = await _parser.ParseAsync(sourceCode);
|
|
var result = await _converter.ConvertAsync(syntaxTree, LanguageType.Java);
|
|
|
|
Assert.NotNull(result);
|
|
Assert.True(result.Success);
|
|
Assert.NotNull(result.TransformedCode);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task ConvertAsync_ListPattern_WithDiscard_ShouldConvert()
|
|
{
|
|
var sourceCode = @"
|
|
if (values is [_, _, _]) { }";
|
|
|
|
var syntaxTree = await _parser.ParseAsync(sourceCode);
|
|
var result = await _converter.ConvertAsync(syntaxTree, LanguageType.Java);
|
|
|
|
Assert.NotNull(result);
|
|
Assert.True(result.Success);
|
|
Assert.NotNull(result.TransformedCode);
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region 4. 切片模式匹配 - 4 个测试
|
|
|
|
[Fact]
|
|
public async Task ConvertAsync_SlicePattern_EndSliceOnly_ShouldConvert()
|
|
{
|
|
var sourceCode = @"
|
|
if (values is [1, 2, ..]) { }";
|
|
|
|
var syntaxTree = await _parser.ParseAsync(sourceCode);
|
|
var result = await _converter.ConvertAsync(syntaxTree, LanguageType.Java);
|
|
|
|
Assert.NotNull(result);
|
|
Assert.True(result.Success);
|
|
Assert.NotNull(result.TransformedCode);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task ConvertAsync_SlicePattern_StartSliceOnly_ShouldConvert()
|
|
{
|
|
var sourceCode = @"
|
|
if (values is [.., 3, 4]) { }";
|
|
|
|
var syntaxTree = await _parser.ParseAsync(sourceCode);
|
|
var result = await _converter.ConvertAsync(syntaxTree, LanguageType.Java);
|
|
|
|
Assert.NotNull(result);
|
|
Assert.True(result.Success);
|
|
Assert.NotNull(result.TransformedCode);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task ConvertAsync_SlicePattern_MiddleSlice_ShouldConvert()
|
|
{
|
|
var sourceCode = @"
|
|
if (values is [1, .., 4]) { }";
|
|
|
|
var syntaxTree = await _parser.ParseAsync(sourceCode);
|
|
var result = await _converter.ConvertAsync(syntaxTree, LanguageType.Java);
|
|
|
|
Assert.NotNull(result);
|
|
Assert.True(result.Success);
|
|
Assert.NotNull(result.TransformedCode);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task ConvertAsync_SlicePattern_OmegaOnly_ShouldConvert()
|
|
{
|
|
var sourceCode = @"
|
|
if (values is [..]) { }";
|
|
|
|
var syntaxTree = await _parser.ParseAsync(sourceCode);
|
|
var result = await _converter.ConvertAsync(syntaxTree, LanguageType.Java);
|
|
|
|
Assert.NotNull(result);
|
|
Assert.True(result.Success);
|
|
Assert.NotNull(result.TransformedCode);
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region 5. 关系模式匹配 - 4 个测试
|
|
|
|
[Fact]
|
|
public async Task ConvertAsync_RelationalPattern_GreaterThan_ShouldConvert()
|
|
{
|
|
var sourceCode = @"
|
|
if (x is > 0) { }";
|
|
|
|
var syntaxTree = await _parser.ParseAsync(sourceCode);
|
|
var result = await _converter.ConvertAsync(syntaxTree, LanguageType.Java);
|
|
|
|
Assert.NotNull(result);
|
|
Assert.True(result.Success);
|
|
Assert.NotNull(result.TransformedCode);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task ConvertAsync_RelationalPattern_LessThan_ShouldConvert()
|
|
{
|
|
var sourceCode = @"
|
|
if (x is < 10) { }";
|
|
|
|
var syntaxTree = await _parser.ParseAsync(sourceCode);
|
|
var result = await _converter.ConvertAsync(syntaxTree, LanguageType.Java);
|
|
|
|
Assert.NotNull(result);
|
|
Assert.True(result.Success);
|
|
Assert.NotNull(result.TransformedCode);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task ConvertAsync_RelationalPattern_AndPattern_ShouldConvert()
|
|
{
|
|
var sourceCode = @"
|
|
if (x is (> 0 and < 10)) { }";
|
|
|
|
var syntaxTree = await _parser.ParseAsync(sourceCode);
|
|
var result = await _converter.ConvertAsync(syntaxTree, LanguageType.Java);
|
|
|
|
Assert.NotNull(result);
|
|
Assert.True(result.Success);
|
|
Assert.NotNull(result.TransformedCode);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task ConvertAsync_RelationalPattern_OrPattern_ShouldConvert()
|
|
{
|
|
var sourceCode = @"
|
|
if (x is (< 0 or > 100)) { }";
|
|
|
|
var syntaxTree = await _parser.ParseAsync(sourceCode);
|
|
var result = await _converter.ConvertAsync(syntaxTree, LanguageType.Java);
|
|
|
|
Assert.NotNull(result);
|
|
Assert.True(result.Success);
|
|
Assert.NotNull(result.TransformedCode);
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region 6. 主构造函数参数 - 4 个测试
|
|
|
|
[Fact]
|
|
public async Task ConvertAsync_PrimaryConstructor_SingleParameter_ShouldConvert()
|
|
{
|
|
var sourceCode = @"
|
|
public class Point(int x)
|
|
{
|
|
public int X => x;
|
|
}";
|
|
|
|
var syntaxTree = await _parser.ParseAsync(sourceCode);
|
|
var result = await _converter.ConvertAsync(syntaxTree, LanguageType.Java);
|
|
|
|
Assert.NotNull(result);
|
|
Assert.True(result.Success);
|
|
Assert.NotNull(result.TransformedCode);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task ConvertAsync_PrimaryConstructor_MultipleParameters_ShouldConvert()
|
|
{
|
|
var sourceCode = @"
|
|
public class Point(int x, int y)
|
|
{
|
|
public int X => x;
|
|
public int Y => y;
|
|
}";
|
|
|
|
var syntaxTree = await _parser.ParseAsync(sourceCode);
|
|
var result = await _converter.ConvertAsync(syntaxTree, LanguageType.Java);
|
|
|
|
Assert.NotNull(result);
|
|
Assert.True(result.Success);
|
|
Assert.NotNull(result.TransformedCode);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task ConvertAsync_PrimaryConstructor_ParamsArray_ShouldConvert()
|
|
{
|
|
var sourceCode = @"
|
|
public class Collection(params int[] items)
|
|
{
|
|
public int[] Items => items;
|
|
}";
|
|
|
|
var syntaxTree = await _parser.ParseAsync(sourceCode);
|
|
var result = await _converter.ConvertAsync(syntaxTree, LanguageType.Java);
|
|
|
|
Assert.NotNull(result);
|
|
Assert.True(result.Success);
|
|
Assert.NotNull(result.TransformedCode);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task ConvertAsync_PrimaryConstructor_WithGenerics_ShouldConvert()
|
|
{
|
|
var sourceCode = @"
|
|
public class Box<T>(T value)
|
|
{
|
|
public T Value => value;
|
|
}";
|
|
|
|
var syntaxTree = await _parser.ParseAsync(sourceCode);
|
|
var result = await _converter.ConvertAsync(syntaxTree, LanguageType.Java);
|
|
|
|
Assert.NotNull(result);
|
|
Assert.True(result.Success);
|
|
Assert.NotNull(result.TransformedCode);
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region 7. Lock 语句 - 4 个测试
|
|
|
|
[Fact]
|
|
public async Task ConvertAsync_LockStatement_SimpleLock_ShouldConvert()
|
|
{
|
|
var sourceCode = @"
|
|
lock (syncObj)
|
|
{
|
|
count++;
|
|
}";
|
|
|
|
var syntaxTree = await _parser.ParseAsync(sourceCode);
|
|
var result = await _converter.ConvertAsync(syntaxTree, LanguageType.Java);
|
|
|
|
Assert.NotNull(result);
|
|
Assert.True(result.Success);
|
|
Assert.NotNull(result.TransformedCode);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task ConvertAsync_LockStatement_WithMultipleStatements_ShouldConvert()
|
|
{
|
|
var sourceCode = @"
|
|
lock (this)
|
|
{
|
|
balance += amount;
|
|
NotifyChanged();
|
|
}";
|
|
|
|
var syntaxTree = await _parser.ParseAsync(sourceCode);
|
|
var result = await _converter.ConvertAsync(syntaxTree, LanguageType.Java);
|
|
|
|
Assert.NotNull(result);
|
|
Assert.True(result.Success);
|
|
Assert.NotNull(result.TransformedCode);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task ConvertAsync_LockStatement_NestedLock_ShouldConvert()
|
|
{
|
|
var sourceCode = @"
|
|
lock (outer)
|
|
{
|
|
lock (inner)
|
|
{
|
|
DoWork();
|
|
}
|
|
}";
|
|
|
|
var syntaxTree = await _parser.ParseAsync(sourceCode);
|
|
var result = await _converter.ConvertAsync(syntaxTree, LanguageType.Java);
|
|
|
|
Assert.NotNull(result);
|
|
Assert.True(result.Success);
|
|
Assert.NotNull(result.TransformedCode);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task ConvertAsync_LockStatement_WithReturn_ShouldConvert()
|
|
{
|
|
var sourceCode = @"
|
|
lock (sync)
|
|
{
|
|
if (condition) return value;
|
|
return null;
|
|
}";
|
|
|
|
var syntaxTree = await _parser.ParseAsync(sourceCode);
|
|
var result = await _converter.ConvertAsync(syntaxTree, LanguageType.Java);
|
|
|
|
Assert.NotNull(result);
|
|
Assert.True(result.Success);
|
|
Assert.NotNull(result.TransformedCode);
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region 8. Params IEnumerable 增强 - 4 个测试
|
|
|
|
[Fact]
|
|
public async Task ConvertAsync_Params_EnumerableInt_ShouldConvert()
|
|
{
|
|
var sourceCode = @"
|
|
public void Process(params IEnumerable<int> items)
|
|
{
|
|
foreach (var item in items) { }
|
|
}";
|
|
|
|
var syntaxTree = await _parser.ParseAsync(sourceCode);
|
|
var result = await _converter.ConvertAsync(syntaxTree, LanguageType.Java);
|
|
|
|
Assert.NotNull(result);
|
|
Assert.True(result.Success);
|
|
Assert.NotNull(result.TransformedCode);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task ConvertAsync_Params_EnumerableString_ShouldConvert()
|
|
{
|
|
var sourceCode = @"
|
|
public void PrintAll(params IEnumerable<string> values)
|
|
{
|
|
foreach (var v in values) Console.WriteLine(v);
|
|
}";
|
|
|
|
var syntaxTree = await _parser.ParseAsync(sourceCode);
|
|
var result = await _converter.ConvertAsync(syntaxTree, LanguageType.Java);
|
|
|
|
Assert.NotNull(result);
|
|
Assert.True(result.Success);
|
|
Assert.NotNull(result.TransformedCode);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task ConvertAsync_Params_ICollection_ShouldConvert()
|
|
{
|
|
var sourceCode = @"
|
|
public void SumAll(params ICollection<int> numbers) { }";
|
|
|
|
var syntaxTree = await _parser.ParseAsync(sourceCode);
|
|
var result = await _converter.ConvertAsync(syntaxTree, LanguageType.Java);
|
|
|
|
Assert.NotNull(result);
|
|
Assert.True(result.Success);
|
|
Assert.NotNull(result.TransformedCode);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task ConvertAsync_Params_IList_ShouldConvert()
|
|
{
|
|
var sourceCode = @"
|
|
public void ProcessList(params IList<string> items) { }";
|
|
|
|
var syntaxTree = await _parser.ParseAsync(sourceCode);
|
|
var result = await _converter.ConvertAsync(syntaxTree, LanguageType.Java);
|
|
|
|
Assert.NotNull(result);
|
|
Assert.True(result.Success);
|
|
Assert.NotNull(result.TransformedCode);
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region 9. C# 12 集合表达式 - 4 个测试
|
|
|
|
[Fact]
|
|
public async Task ConvertAsync_CSharp12Collection_IntListLiteral_ShouldConvert()
|
|
{
|
|
var sourceCode = @"
|
|
List<int> numbers = [1, 2, 3];";
|
|
|
|
var syntaxTree = await _parser.ParseAsync(sourceCode);
|
|
var result = await _converter.ConvertAsync(syntaxTree, LanguageType.Java);
|
|
|
|
Assert.NotNull(result);
|
|
Assert.True(result.Success);
|
|
Assert.NotNull(result.TransformedCode);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task ConvertAsync_CSharp12Collection_StringListLiteral_ShouldConvert()
|
|
{
|
|
var sourceCode = @"
|
|
List<string> names = [""Alice"", ""Bob"", ""Charlie""];";
|
|
|
|
var syntaxTree = await _parser.ParseAsync(sourceCode);
|
|
var result = await _converter.ConvertAsync(syntaxTree, LanguageType.Java);
|
|
|
|
Assert.NotNull(result);
|
|
Assert.True(result.Success);
|
|
Assert.NotNull(result.TransformedCode);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task ConvertAsync_CSharp12Collection_NestedCollectionLiteral_ShouldConvert()
|
|
{
|
|
var sourceCode = @"
|
|
List<List<int>> matrix = [[1, 2], [3, 4]];";
|
|
|
|
var syntaxTree = await _parser.ParseAsync(sourceCode);
|
|
var result = await _converter.ConvertAsync(syntaxTree, LanguageType.Java);
|
|
|
|
Assert.NotNull(result);
|
|
Assert.True(result.Success);
|
|
Assert.NotNull(result.TransformedCode);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task ConvertAsync_CSharp12Collection_ArrayLiteral_ShouldConvert()
|
|
{
|
|
var sourceCode = @"
|
|
int[] array = [10, 20, 30, 40];";
|
|
|
|
var syntaxTree = await _parser.ParseAsync(sourceCode);
|
|
var result = await _converter.ConvertAsync(syntaxTree, LanguageType.Java);
|
|
|
|
Assert.NotNull(result);
|
|
Assert.True(result.Success);
|
|
Assert.NotNull(result.TransformedCode);
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region 10. 类型别名 (C# 12) - 3 个测试
|
|
|
|
[Fact]
|
|
public async Task ConvertAsync_TypeAlias_SimpleAlias_ShouldRemove()
|
|
{
|
|
var sourceCode = @"
|
|
using IntList = System.Collections.Generic.List<int>;";
|
|
|
|
var syntaxTree = await _parser.ParseAsync(sourceCode);
|
|
var result = await _converter.ConvertAsync(syntaxTree, LanguageType.Java);
|
|
|
|
Assert.NotNull(result);
|
|
Assert.True(result.Success);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task ConvertAsync_TypeAlias_NestedTypeAlias_ShouldRemove()
|
|
{
|
|
var sourceCode = @"
|
|
using StringDict = System.Collections.Generic.Dictionary<string, string>;";
|
|
|
|
var syntaxTree = await _parser.ParseAsync(sourceCode);
|
|
var result = await _converter.ConvertAsync(syntaxTree, LanguageType.Java);
|
|
|
|
Assert.NotNull(result);
|
|
Assert.True(result.Success);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task ConvertAsync_TypeAlias_MultipleAliases_ShouldRemove()
|
|
{
|
|
var sourceCode = @"
|
|
using IntList = System.Collections.Generic.List<int>;
|
|
using StringList = System.Collections.Generic.List<string>;";
|
|
|
|
var syntaxTree = await _parser.ParseAsync(sourceCode);
|
|
var result = await _converter.ConvertAsync(syntaxTree, LanguageType.Java);
|
|
|
|
Assert.NotNull(result);
|
|
Assert.True(result.Success);
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region 11. 默认 Lambda 参数 (C# 13) - 3 个测试
|
|
|
|
[Fact]
|
|
public async Task ConvertAsync_DefaultLambdaParameters_SingleDefault_ShouldConvert()
|
|
{
|
|
var sourceCode = @"
|
|
var method = (int x = 10) => x * 2;";
|
|
|
|
var syntaxTree = await _parser.ParseAsync(sourceCode);
|
|
var result = await _converter.ConvertAsync(syntaxTree, LanguageType.Java);
|
|
|
|
Assert.NotNull(result);
|
|
Assert.True(result.Success);
|
|
Assert.NotNull(result.TransformedCode);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task ConvertAsync_DefaultLambdaParameters_MultipleDefaults_ShouldConvert()
|
|
{
|
|
var sourceCode = @"
|
|
var method = (int x = 10, int y = 20) => x + y;";
|
|
|
|
var syntaxTree = await _parser.ParseAsync(sourceCode);
|
|
var result = await _converter.ConvertAsync(syntaxTree, LanguageType.Java);
|
|
|
|
Assert.NotNull(result);
|
|
Assert.True(result.Success);
|
|
Assert.NotNull(result.TransformedCode);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task ConvertAsync_DefaultLambdaParameters_MixedDefaults_ShouldConvert()
|
|
{
|
|
var sourceCode = @"
|
|
var method = (int x, int y = 5) => x + y;";
|
|
|
|
var syntaxTree = await _parser.ParseAsync(sourceCode);
|
|
var result = await _converter.ConvertAsync(syntaxTree, LanguageType.Java);
|
|
|
|
Assert.NotNull(result);
|
|
Assert.True(result.Success);
|
|
Assert.NotNull(result.TransformedCode);
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region 12. Switch Type Pattern - 3 个测试
|
|
|
|
[Fact]
|
|
public async Task ConvertAsync_TypeSwitchPattern_SingleType_ShouldConvert()
|
|
{
|
|
var sourceCode = @"
|
|
string result = value switch {
|
|
string s => ""String"",
|
|
_ => ""Other""
|
|
};";
|
|
|
|
var syntaxTree = await _parser.ParseAsync(sourceCode);
|
|
var result = await _converter.ConvertAsync(syntaxTree, LanguageType.Java);
|
|
|
|
Assert.NotNull(result);
|
|
Assert.True(result.Success);
|
|
Assert.NotNull(result.TransformedCode);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task ConvertAsync_TypeSwitchPattern_GenericTypes_ShouldConvert()
|
|
{
|
|
var sourceCode = @"
|
|
string result = value switch
|
|
{
|
|
IEnumerable<int> seq => ""Int Seq"",
|
|
IEnumerable<string> seq => ""String Seq"",
|
|
_ => ""Other""
|
|
};";
|
|
|
|
var syntaxTree = await _parser.ParseAsync(sourceCode);
|
|
var result = await _converter.ConvertAsync(syntaxTree, LanguageType.Java);
|
|
|
|
Assert.NotNull(result);
|
|
Assert.True(result.Success);
|
|
Assert.NotNull(result.TransformedCode);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task ConvertAsync_TypeSwitchPattern_MultipleConditions_ShouldConvert()
|
|
{
|
|
var sourceCode = @"
|
|
string GetType(object o) => o switch {
|
|
int i => ""Integer"",
|
|
string s when s.Length > 0 => ""Non-empty String"",
|
|
null => ""Null"",
|
|
_ => ""Unknown""
|
|
};";
|
|
|
|
var syntaxTree = await _parser.ParseAsync(sourceCode);
|
|
var result = await _converter.ConvertAsync(syntaxTree, LanguageType.Java);
|
|
|
|
Assert.NotNull(result);
|
|
Assert.True(result.Success);
|
|
Assert.NotNull(result.TransformedCode);
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region 13. 原始字符串字面量 - 3 个测试
|
|
|
|
[Fact]
|
|
public async Task ConvertAsync_RawStringLiteral_SingleLine_ShouldConvert()
|
|
{
|
|
var sourceCode = @"
|
|
string xml = $""""""<root><item>Value</item></root>"""""";";
|
|
|
|
var syntaxTree = await _parser.ParseAsync(sourceCode);
|
|
var result = await _converter.ConvertAsync(syntaxTree, LanguageType.Java);
|
|
|
|
Assert.NotNull(result);
|
|
Assert.True(result.Success);
|
|
Assert.NotNull(result.TransformedCode);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task ConvertAsync_RawStringLiteral_MultiLine_ShouldConvert()
|
|
{
|
|
var sourceCode = @"
|
|
string xml = $""""""
|
|
<root>
|
|
<item>Value</item>
|
|
</root>
|
|
"""""";";
|
|
|
|
var syntaxTree = await _parser.ParseAsync(sourceCode);
|
|
var result = await _converter.ConvertAsync(syntaxTree, LanguageType.Java);
|
|
|
|
Assert.NotNull(result);
|
|
Assert.True(result.Success);
|
|
Assert.NotNull(result.TransformedCode);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task ConvertAsync_RawStringLiteral_WithInterpolation_ShouldConvert()
|
|
{
|
|
var sourceCode = @"
|
|
string html = $""""""
|
|
<div>
|
|
<p>{name}</p>
|
|
</div>
|
|
"""""";";
|
|
|
|
var syntaxTree = await _parser.ParseAsync(sourceCode);
|
|
var result = await _converter.ConvertAsync(syntaxTree, LanguageType.Java);
|
|
|
|
Assert.NotNull(result);
|
|
Assert.True(result.Success);
|
|
Assert.NotNull(result.TransformedCode);
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region 14. 综合测试 - 4 个测试
|
|
|
|
[Fact]
|
|
public async Task ConvertAsync_CSharp13_CombinedSpreadAndLambda_ShouldConvert()
|
|
{
|
|
var sourceCode = @"
|
|
int[] a = [1, 2];
|
|
int[] b = [0, ..a, 3];
|
|
var sum = b.Sum(x => x * 2);";
|
|
|
|
var syntaxTree = await _parser.ParseAsync(sourceCode);
|
|
var result = await _converter.ConvertAsync(syntaxTree, LanguageType.Java);
|
|
|
|
Assert.NotNull(result);
|
|
Assert.True(result.Success);
|
|
Assert.NotNull(result.TransformedCode);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task ConvertAsync_CSharp13_CombinedPatternAndSwitch_ShouldConvert()
|
|
{
|
|
var sourceCode = @"
|
|
string Describe(object o) => o switch {
|
|
(> 0 and < 10) => ""Small positive"",
|
|
(>= 10 and <= 100) => ""Medium"",
|
|
_ => ""Other""
|
|
};";
|
|
|
|
var syntaxTree = await _parser.ParseAsync(sourceCode);
|
|
var result = await _converter.ConvertAsync(syntaxTree, LanguageType.Java);
|
|
|
|
Assert.NotNull(result);
|
|
Assert.True(result.Success);
|
|
Assert.NotNull(result.TransformedCode);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task ConvertAsync_CSharp13_CombinedLockAndParams_ShouldConvert()
|
|
{
|
|
var sourceCode = @"
|
|
public void UpdateAll(params IEnumerable<int> values)
|
|
{
|
|
lock (sync)
|
|
{
|
|
foreach (var v in values) data.Add(v);
|
|
}
|
|
}";
|
|
|
|
var syntaxTree = await _parser.ParseAsync(sourceCode);
|
|
var result = await _converter.ConvertAsync(syntaxTree, LanguageType.Java);
|
|
|
|
Assert.NotNull(result);
|
|
Assert.True(result.Success);
|
|
Assert.NotNull(result.TransformedCode);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task ConvertAsync_CSharp13_RecordWithCollectionAndSpread_ShouldConvert()
|
|
{
|
|
var sourceCode = @"
|
|
public record Data(int[] Values);
|
|
var d1 = new Data([1, 2, 3]);
|
|
int[] base = [0];
|
|
var d2 = new Data([..base, 4, 5]);";
|
|
|
|
var syntaxTree = await _parser.ParseAsync(sourceCode);
|
|
var result = await _converter.ConvertAsync(syntaxTree, LanguageType.Java);
|
|
|
|
Assert.NotNull(result);
|
|
Assert.True(result.Success);
|
|
Assert.NotNull(result.TransformedCode);
|
|
}
|
|
|
|
#endregion
|
|
}
|