|
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
#nullable disable
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.CodeRefactorings;
using Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.CodeRefactorings;
using Microsoft.CodeAnalysis.Test.Utilities;
using Roslyn.Test.Utilities;
using Xunit;
namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.CodeActions.ConvertLinq;
[Trait(Traits.Feature, Traits.Features.CodeActionsConvertForEachToQuery)]
public class ConvertForEachToLinqQueryTests : AbstractCSharpCodeActionTest_NoEditor
{
protected override CodeRefactoringProvider CreateCodeRefactoringProvider(TestWorkspace workspace, TestParameters parameters)
=> new CodeAnalysis.CSharp.ConvertLinq.ConvertForEachToLinqQuery.CSharpConvertForEachToLinqQueryProvider();
#region Query Expressions
[Fact]
public async Task QueryForForWhere()
{
var source = """
using System.Collections.Generic;
using System.Linq;
class Query
{
public IEnumerable<int> void Main(string[] args)
{
List<int> c1 = new List<int>{1, 2, 3, 4, 5, 7};
List<int> c2 = new List<int>{10, 30, 40, 50, 60, 70};
[|foreach (var x1 in c1)
{
foreach (var x2 in c2)
{
if (object.Equals(x1, x2 / 10))
{
yield return x1 + x2;
}
}
}|]
}
}
""";
var queryOutput = """
using System.Collections.Generic;
using System.Linq;
class Query
{
public IEnumerable<int> void Main(string[] args)
{
List<int> c1 = new List<int>{1, 2, 3, 4, 5, 7};
List<int> c2 = new List<int>{10, 30, 40, 50, 60, 70};
return from x1 in c1
from x2 in c2
where object.Equals(x1, x2 / 10)
select x1 + x2;
}
}
""";
await TestInRegularAndScriptAsync(source, queryOutput, index: 0);
var linqInvocationOutput = """
using System.Collections.Generic;
using System.Linq;
class Query
{
public IEnumerable<int> void Main(string[] args)
{
List<int> c1 = new List<int>{1, 2, 3, 4, 5, 7};
List<int> c2 = new List<int>{10, 30, 40, 50, 60, 70};
return c1.SelectMany(x1 => c2.Where(x2 => object.Equals(x1, x2 / 10)).Select(x2 => x1 + x2));
}
}
""";
await TestInRegularAndScriptAsync(source, linqInvocationOutput, index: 1);
}
[Fact]
public async Task QueryWithEscapedSymbols()
{
var source = """
using System.Collections.Generic;
using System.Linq;
class Query
{
public IEnumerable<int> void Main(string[] args)
{
List<int> c1 = new List<int>{1, 2, 3, 4, 5, 7};
List<int> c2 = new List<int>{10, 30, 40, 50, 60, 70};
[|foreach (var @object in c1)
{
foreach (var x2 in c2)
{
yield return @object + x2;
}
}|]
}
}
""";
var queryOutput = """
using System.Collections.Generic;
using System.Linq;
class Query
{
public IEnumerable<int> void Main(string[] args)
{
List<int> c1 = new List<int>{1, 2, 3, 4, 5, 7};
List<int> c2 = new List<int>{10, 30, 40, 50, 60, 70};
return from @object in c1
from x2 in c2
select @object + x2;
}
}
""";
await TestInRegularAndScriptAsync(source, queryOutput, index: 0);
var linqInvocationOutput = """
using System.Collections.Generic;
using System.Linq;
class Query
{
public IEnumerable<int> void Main(string[] args)
{
List<int> c1 = new List<int>{1, 2, 3, 4, 5, 7};
List<int> c2 = new List<int>{10, 30, 40, 50, 60, 70};
return c1.SelectMany(@object => c2.Select(x2 => @object + x2));
}
}
""";
await TestInRegularAndScriptAsync(source, linqInvocationOutput, index: 1);
}
[Fact]
public async Task QueryForVarForWhere()
{
var source = """
using System.Linq;
class C
{
IEnumerable<int> M()
{
[|foreach (var num in new int[] { 1, 2 })
{
var n1 = num + 1;
foreach (var a in new int[] { 5, 6 })
{
foreach (var x1 in new int[] { 3, 4 })
{
if (object.Equals(num, x1))
{
foreach (var x2 in new int[] { 7, 8 })
{
if (object.Equals(num, x2))
{
var n2 = x2 - 1;
yield return n2 + n1;
}
}
}
}
}|]
}
}
}
""";
var queryOutput = """
using System.Linq;
class C
{
IEnumerable<int> M()
{
return from num in new int[] { 1, 2 }
let n1 = num + 1
from a in new int[] { 5, 6 }
from x1 in new int[] { 3, 4 }
where object.Equals(num, x1)
from x2 in new int[] { 7, 8 }
where object.Equals(num, x2)
let n2 = x2 - 1
select n2 + n1;
}
}
""";
await TestInRegularAndScriptAsync(source, queryOutput, index: 0);
// No linq refactoring offered due to variable declaration within the outermost foreach.
await TestActionCountAsync(source, count: 1);
}
[Fact]
public async Task QueryForVarForWhere_02()
{
var source = """
using System.Collections.Generic;
using System.Linq;
class C
{
IEnumerable<int> M()
{
[|foreach (var num in new int[] { 1, 2 })
{
foreach (var a in new int[] { 5, 6 })
{
foreach (var x1 in new int[] { 3, 4 })
{
if (object.Equals(num, x1))
{
foreach (var x2 in new int[] { 7, 8 })
{
if (object.Equals(num, x2))
{
var n1 = num + 1;
var n2 = x2 - 1;
yield return n2 + n1;
}
}
}
}
}|]
}
}
}
""";
var queryOutput = """
using System.Collections.Generic;
using System.Linq;
class C
{
IEnumerable<int> M()
{
return from num in new int[] { 1, 2 }
from a in new int[] { 5, 6 }
from x1 in new int[] { 3, 4 }
where object.Equals(num, x1)
from x2 in new int[] { 7, 8 }
where object.Equals(num, x2)
let n1 = num + 1
let n2 = x2 - 1
select n2 + n1;
}
}
""";
await TestInRegularAndScriptAsync(source, queryOutput, index: 0);
var linqInvocationOutput = """
using System.Collections.Generic;
using System.Linq;
class C
{
IEnumerable<int> M()
{
foreach (var (num, x2) in (new int[] { 1, 2 }).SelectMany(num => (new int[] { 5, 6 }).SelectMany(a => (new int[] { 3, 4 }).Where(x1 => object.Equals(num, x1)).SelectMany(x1 => (new int[] { 7, 8 }).Where(x2 => object.Equals(num, x2)).Select(x2 => (num, x2))))))
{
var n1 = num + 1;
var n2 = x2 - 1;
yield return n2 + n1;
}
}
}
""";
await TestInRegularAndScriptAsync(source, linqInvocationOutput, index: 1);
}
[Fact]
public async Task QueryForVarForWhere_03()
{
var source = """
using System.Collections.Generic;
using System.Linq;
class C
{
IEnumerable<int> M()
{
[|foreach (var num in new int[] { 1, 2 })
{
foreach (var a in new int[] { 5, 6 })
{
foreach (var x1 in new int[] { 3, 4 })
{
var n1 = num + 1;
if (object.Equals(num, x1))
{
foreach (var x2 in new int[] { 7, 8 })
{
if (object.Equals(num, x2))
{
var n2 = x2 - 1;
yield return n2 + n1;
}
}
}
}
}|]
}
}
}
""";
var queryOutput = """
using System.Collections.Generic;
using System.Linq;
class C
{
IEnumerable<int> M()
{
return from num in new int[] { 1, 2 }
from a in new int[] { 5, 6 }
from x1 in new int[] { 3, 4 }
let n1 = num + 1
where object.Equals(num, x1)
from x2 in new int[] { 7, 8 }
where object.Equals(num, x2)
let n2 = x2 - 1
select n2 + n1;
}
}
""";
await TestInRegularAndScriptAsync(source, queryOutput, index: 0);
var linqInvocationOutput = """
using System.Collections.Generic;
using System.Linq;
class C
{
IEnumerable<int> M()
{
foreach (var (num, x1) in (new int[] { 1, 2 }).SelectMany(num => (new int[] { 5, 6 }).SelectMany(a => (new int[] { 3, 4 }).Select(x1 => (num, x1)))))
{
var n1 = num + 1;
if (object.Equals(num, x1))
{
foreach (var x2 in new int[] { 7, 8 })
{
if (object.Equals(num, x2))
{
var n2 = x2 - 1;
yield return n2 + n1;
}
}
}
}
}
}
""";
await TestInRegularAndScriptAsync(source, linqInvocationOutput, index: 1);
}
[Fact]
public async Task QueryLet()
{
var source = """
using System;
using System.Collections.Generic;
using System.Linq;
class Query
{
void M()
{
List<int> c1 = new List<int>{ 1, 2, 3 };
List<int> r1 = new List<int>();
[|foreach (int x in c1)
{
var g = x * 10;
var z = g + x*100;
var a = 5 + z;
r1.Add(x + z - a);
}|]
}
}
""";
var queryOutput = """
using System;
using System.Collections.Generic;
using System.Linq;
class Query
{
void M()
{
List<int> c1 = new List<int>{ 1, 2, 3 };
List<int> r1 = (from int x in c1
let g = x * 10
let z = g + x * 100
let a = 5 + z
select x + z - a).ToList();
}
}
""";
await TestInRegularAndScriptAsync(source, queryOutput, index: 0);
// No linq invocation refactoring offered due to variable declaration(s) in topmost foreach.
await TestActionCountAsync(source, count: 1);
}
[Fact]
public async Task QueryEmptyDeclarations()
{
var source = """
using System;
using System.Collections.Generic;
using System.Linq;
class Query
{
void M()
{
[|foreach (int x in new[] {1,2})
{
int a = 3, b, c = 1;
if (x > c)
{
b = 0;
Console.Write(a + x + b);
}
}|]
}
}
""";
await TestMissingInRegularAndScriptAsync(source);
}
[Fact]
public async Task QueryWhereClause()
{
var source = """
using System;
using System.Linq;
class C
{
IEnumerable<int> M()
{
var nums = new int[] { 1, 2, 3, 4 };
[|foreach (var x in nums)
{
if (x > 2)
{
yield return x;
}
}|]
}
}
""";
var queryOutput = """
using System;
using System.Linq;
class C
{
IEnumerable<int> M()
{
var nums = new int[] { 1, 2, 3, 4 };
return from x in nums
where x > 2
select x;
}
}
""";
await TestInRegularAndScriptAsync(source, queryOutput, index: 0);
var linqInvocationOutput = """
using System;
using System.Linq;
class C
{
IEnumerable<int> M()
{
var nums = new int[] { 1, 2, 3, 4 };
return nums.Where(x => x > 2);
}
}
""";
await TestInRegularAndScriptAsync(source, linqInvocationOutput, index: 1);
}
[Fact]
public async Task QueryOverQueries()
{
var source = """
using System;
using System.Linq;
class C
{
IEnumerable<int> M()
{
var nums = new int[] { 1, 2, 3, 4 };
[|foreach (var y in from x in nums select x)
{
foreach (var z in from x in nums select x)
{
yield return y;
}
}|]
}
}
""";
var queryOutput = """
using System;
using System.Linq;
class C
{
IEnumerable<int> M()
{
var nums = new int[] { 1, 2, 3, 4 };
return from y in
from x in nums select x
from z in
from x in nums select x
select y;
}
}
""";
await TestInRegularAndScriptAsync(source, queryOutput, index: 0);
var linqInvocationOutput = """
using System;
using System.Linq;
class C
{
IEnumerable<int> M()
{
var nums = new int[] { 1, 2, 3, 4 };
return (from x in nums select x).SelectMany(y => (from x in nums select x).Select(z => y));
}
}
""";
await TestInRegularAndScriptAsync(source, linqInvocationOutput, index: 1);
}
[Fact]
public async Task QueryNoVariablesUsed()
{
var source = """
using System;
using System.Linq;
class C
{
void M()
{
[|foreach (var a in new[] { 1 })
{
foreach (var b in new[] { 2 })
{
System.Console.Write(0);
}
}|]
}
}
""";
var queryOutput = """
using System;
using System.Linq;
class C
{
void M()
{
foreach (var _ in from a in new[] { 1 }
from b in new[] { 2 }
select new { })
{
System.Console.Write(0);
}
}
}
""";
await TestInRegularAndScriptAsync(source, queryOutput, index: 0);
var linqInvocationOutput = """
using System;
using System.Linq;
class C
{
void M()
{
foreach (var _ in (new[] { 1 }).SelectMany(a => (new[] { 2 }).Select(b => new { })))
{
System.Console.Write(0);
}
}
}
""";
await TestInRegularAndScriptAsync(source, linqInvocationOutput, index: 1);
}
[Fact]
public async Task QueryNoBlock()
{
var source = """
using System;
using System.Linq;
class C
{
void M()
{
[|foreach (var a in new[] { 1 })
foreach (var b in new[] { 2 })
System.Console.Write(a);|]
}
}
""";
var queryOutput = """
using System;
using System.Linq;
class C
{
void M()
{
foreach (var a in from a in new[] { 1 }
from b in new[] { 2 }
select a)
{
System.Console.Write(a);
}
}
}
""";
await TestInRegularAndScriptAsync(source, queryOutput, index: 0);
var linqInvocationOutput = """
using System;
using System.Linq;
class C
{
void M()
{
foreach (var a in (new[] { 1 }).SelectMany(a => (new[] { 2 }).Select(b => a)))
{
System.Console.Write(a);
}
}
}
""";
await TestInRegularAndScriptAsync(source, linqInvocationOutput, index: 1);
}
[Fact]
public async Task QuerySelectExpression()
{
var source = """
using System;
using System.Linq;
class C
{
void M()
{
[|foreach (var a in new[] { 1 })
foreach (var b in new[] { 2 })
Console.Write(a + b);|]
}
}
""";
var queryOutput = """
using System;
using System.Linq;
class C
{
void M()
{
foreach (var (a, b) in from a in new[] { 1 }
from b in new[] { 2 }
select (a, b))
{
Console.Write(a + b);
}
}
}
""";
await TestInRegularAndScriptAsync(source, queryOutput, index: 0);
var linqInvocationOutput = """
using System;
using System.Linq;
class C
{
void M()
{
foreach (var (a, b) in (new[] { 1 }).SelectMany(a => (new[] { 2 }).Select(b => (a, b))))
{
Console.Write(a + b);
}
}
}
""";
await TestInRegularAndScriptAsync(source, linqInvocationOutput, index: 1);
}
[Fact]
public async Task QuerySelectMultipleExpressions()
{
var source = """
using System;
using System.Linq;
class C
{
void M()
{
[|foreach (var a in new[] { 1 })
foreach (var b in new[] { 2 })
{
Console.Write(a + b);
Console.Write(a * b);
}|]
}
}
""";
var queryOutput = """
using System;
using System.Linq;
class C
{
void M()
{
foreach (var (a, b) in from a in new[] { 1 }
from b in new[] { 2 }
select (a, b))
{
Console.Write(a + b);
Console.Write(a * b);
}
}
}
""";
await TestInRegularAndScriptAsync(source, queryOutput, index: 0);
var linqInvocationOutput = """
using System;
using System.Linq;
class C
{
void M()
{
foreach (var (a, b) in (new[] { 1 }).SelectMany(a => (new[] { 2 }).Select(b => (a, b))))
{
Console.Write(a + b);
Console.Write(a * b);
}
}
}
""";
await TestInRegularAndScriptAsync(source, linqInvocationOutput, index: 1);
}
[Fact]
public async Task EmptyBody()
{
var source = """
using System.Collections.Generic;
using System.Linq;
class C
{
void M(IEnumerable<int> nums)
{
[|foreach (int n1 in nums)
{
foreach (int n2 in nums)
{
}
}|]
}
}
""";
var queryOutput = """
using System.Collections.Generic;
using System.Linq;
class C
{
void M(IEnumerable<int> nums)
{
foreach (var _ in from int n1 in nums
from int n2 in nums
select new { })
{
}
}
}
""";
await TestInRegularAndScriptAsync(source, queryOutput, index: 0);
var linqInvocationOutput = """
using System.Collections.Generic;
using System.Linq;
class C
{
void M(IEnumerable<int> nums)
{
foreach (var _ in nums.SelectMany(n1 => nums.Select(n2 => new { })))
{
}
}
}
""";
await TestInRegularAndScriptAsync(source, linqInvocationOutput, index: 1);
}
[Fact]
public async Task EmptyBodyNoBlock()
{
var source = """
using System.Collections.Generic;
using System.Linq;
class C
{
void M(IEnumerable<int> nums)
{
[|foreach (int n1 in nums)
{
foreach (int n2 in nums);
}|]
}
}
""";
var queryOutput = """
using System.Collections.Generic;
using System.Linq;
class C
{
void M(IEnumerable<int> nums)
{
foreach (var _ in from int n1 in nums
from int n2 in nums
select new { })
{
}
}
}
""";
await TestInRegularAndScriptAsync(source, queryOutput, index: 0);
var linqInvocationOutput = """
using System.Collections.Generic;
using System.Linq;
class C
{
void M(IEnumerable<int> nums)
{
foreach (var _ in nums.SelectMany(n1 => nums.Select(n2 => new { })))
{
}
}
}
""";
await TestInRegularAndScriptAsync(source, linqInvocationOutput, index: 1);
}
[Fact]
public async Task AddUsingToExistingList()
{
var source = """
using System.Collections.Generic;
class C
{
void M(IEnumerable<int> nums)
{
[|foreach (int n1 in nums)
{
foreach (int n2 in nums);
}|]
}
}
""";
var queryOutput = """
using System.Collections.Generic;
using System.Linq;
class C
{
void M(IEnumerable<int> nums)
{
foreach (var _ in from int n1 in nums
from int n2 in nums
select new { })
{
}
}
}
""";
await TestInRegularAndScriptAsync(source, queryOutput, index: 0);
var linqInvocationOutput = """
using System.Collections.Generic;
using System.Linq;
class C
{
void M(IEnumerable<int> nums)
{
foreach (var _ in nums.SelectMany(n1 => nums.Select(n2 => new { })))
{
}
}
}
""";
await TestInRegularAndScriptAsync(source, linqInvocationOutput, index: 1);
}
[Fact]
public async Task AddFirstUsing()
{
var source = """
class C
{
void M(int[] nums)
{
[|foreach (int n1 in nums)
{
foreach (int n2 in nums);
}|]
}
}
""";
var queryOutput = """
using System.Linq;
class C
{
void M(int[] nums)
{
foreach (var _ in from int n1 in nums
from int n2 in nums
select new { })
{
}
}
}
""";
await TestInRegularAndScriptAsync(source, queryOutput, index: 0);
var linqInvocationOutput = """
using System.Linq;
class C
{
void M(int[] nums)
{
foreach (var _ in nums.SelectMany(n1 => nums.Select(n2 => new { })))
{
}
}
}
""";
await TestInRegularAndScriptAsync(source, linqInvocationOutput, index: 1);
}
[Fact]
public async Task EmptyBodyDeclarationAsLast()
{
var source = """
using System.Collections.Generic;
using System.Linq;
class C
{
void M(IEnumerable<int> nums)
{
[|foreach (int n1 in nums)
{
foreach (int n2 in nums)
{
var a = n1 + n2;
}
}|]
}
}
""";
var queryOutput = """
using System.Collections.Generic;
using System.Linq;
class C
{
void M(IEnumerable<int> nums)
{
foreach (var _ in from int n1 in nums
from int n2 in nums
let a = n1 + n2
select new { })
{
}
}
}
""";
await TestInRegularAndScriptAsync(source, queryOutput, index: 0);
var linqInvocationOutput = """
using System.Collections.Generic;
using System.Linq;
class C
{
void M(IEnumerable<int> nums)
{
foreach (var (n1, n2) in nums.SelectMany(n1 => nums.Select(n2 => (n1, n2))))
{
var a = n1 + n2;
}
}
}
""";
await TestInRegularAndScriptAsync(source, linqInvocationOutput, index: 1);
}
[Fact]
public async Task EmptyBodyMultipleDeclarationsAsLast()
{
var source = """
using System.Collections.Generic;
using System.Linq;
class C
{
void M(IEnumerable<int> nums)
{
[|foreach (int n1 in nums)
{
foreach (int n2 in nums)
{
int a = n1 + n2, b = n1 * n2;
}
}|]
}
}
""";
var queryOutput = """
using System.Collections.Generic;
using System.Linq;
class C
{
void M(IEnumerable<int> nums)
{
foreach (var _ in from int n1 in nums
from int n2 in nums
let a = n1 + n2
let b = n1 * n2
select new { })
{
}
}
}
""";
await TestInRegularAndScriptAsync(source, queryOutput, index: 0);
var linqInvocationOutput = """
using System.Collections.Generic;
using System.Linq;
class C
{
void M(IEnumerable<int> nums)
{
foreach (var (n1, n2) in nums.SelectMany(n1 => nums.Select(n2 => (n1, n2))))
{
int a = n1 + n2, b = n1 * n2;
}
}
}
""";
await TestInRegularAndScriptAsync(source, linqInvocationOutput, index: 1);
}
#endregion
#region Assignments, Declarations, Returns
[Fact]
public async Task ReturnInvocationAndYieldReturn()
{
var source = """
using System;
using System.Collections.Generic;
using System.Linq;
class C
{
IEnumerable<int> M(IEnumerable<int> nums)
{
[|foreach (int n1 in nums)
{
foreach (int n2 in nums)
{
yield return N(n1);
}
}|]
}
int N(int n) => n;
}
""";
var queryOutput = """
using System;
using System.Collections.Generic;
using System.Linq;
class C
{
IEnumerable<int> M(IEnumerable<int> nums)
{
return from int n1 in nums
from int n2 in nums
select N(n1);
}
int N(int n) => n;
}
""";
await TestInRegularAndScriptAsync(source, queryOutput, index: 0);
var linqInvocationOutput = """
using System;
using System.Collections.Generic;
using System.Linq;
class C
{
IEnumerable<int> M(IEnumerable<int> nums)
{
return nums.SelectMany(n1 => nums.Select(n2 => N(n1)));
}
int N(int n) => n;
}
""";
await TestInRegularAndScriptAsync(source, linqInvocationOutput, index: 1);
}
[Fact]
public async Task BlockBodiedProperty()
{
var source = """
using System.Collections.Generic;
using System.Linq;
public class Test
{
private readonly int[] _nums = new int[] { 1, 2, 3, 4 };
public IEnumerable<int> Query1 { get { [|foreach (var x in _nums) { yield return x + 1; }|] } }
}
""";
var queryOutput = """
using System.Collections.Generic;
using System.Linq;
public class Test
{
private readonly int[] _nums = new int[] { 1, 2, 3, 4 };
public IEnumerable<int> Query1 { get { return from x in _nums select x + 1; } }
}
""";
await TestInRegularAndScriptAsync(source, queryOutput, index: 0);
var linqInvocationOutput = """
using System.Collections.Generic;
using System.Linq;
public class Test
{
private readonly int[] _nums = new int[] { 1, 2, 3, 4 };
public IEnumerable<int> Query1 { get { return _nums.Select(x => x + 1); } }
}
""";
await TestInRegularAndScriptAsync(source, linqInvocationOutput, index: 1);
}
[Fact]
public async Task ReturnIEnumerable()
{
var source = """
using System.Collections.Generic;
using System.Linq;
class C
{
IEnumerable<int> M(IEnumerable<int> nums)
{
[|foreach (int n1 in nums)
{
foreach (int n2 in nums)
{
yield return n1;
}
}|]
}
}
""";
var queryOutput = """
using System.Collections.Generic;
using System.Linq;
class C
{
IEnumerable<int> M(IEnumerable<int> nums)
{
return from int n1 in nums
from int n2 in nums
select n1;
}
}
""";
await TestInRegularAndScriptAsync(source, queryOutput, index: 0);
var linqInvocationOutput = """
using System.Collections.Generic;
using System.Linq;
class C
{
IEnumerable<int> M(IEnumerable<int> nums)
{
return nums.SelectMany(n1 => nums.Select(n2 => n1));
}
}
""";
await TestInRegularAndScriptAsync(source, linqInvocationOutput, index: 1);
}
[Fact]
public async Task ReturnIEnumerableWithYieldReturnAndLocalFunction()
{
var source = """
using System.Collections.Generic;
using System.Linq;
class C
{
IEnumerable<IEnumerable<int>> M(IEnumerable<int> nums)
{
[|foreach (int n1 in nums)
{
foreach (int n2 in nums)
{
yield return f(n1);
}
}|]
yield break;
IEnumerable<int> f(int a)
{
yield return a;
}
}
}
""";
var queryOutput = """
using System.Collections.Generic;
using System.Linq;
class C
{
IEnumerable<IEnumerable<int>> M(IEnumerable<int> nums)
{
return from int n1 in nums
from int n2 in nums
select f(n1);
IEnumerable<int> f(int a)
{
yield return a;
}
}
}
""";
await TestInRegularAndScriptAsync(source, queryOutput, index: 0);
var linqInvocationOutput = """
using System.Collections.Generic;
using System.Linq;
class C
{
IEnumerable<IEnumerable<int>> M(IEnumerable<int> nums)
{
return nums.SelectMany(n1 => nums.Select(n2 => f(n1)));
IEnumerable<int> f(int a)
{
yield return a;
}
}
}
""";
await TestInRegularAndScriptAsync(source, linqInvocationOutput, index: 1);
}
[Fact]
public async Task ReturnIEnumerablePartialMethod()
{
var source = """
using System.Collections.Generic;
using System.Linq;
partial class C
{
partial IEnumerable<int> M(IEnumerable<int> nums);
}
partial class C
{
partial IEnumerable<int> M(IEnumerable<int> nums)
{
[|foreach (int n1 in nums)
{
foreach (int n2 in nums)
{
yield return n1;
}
}|]
yield break;
}
}
""";
var queryOutput = """
using System.Collections.Generic;
using System.Linq;
partial class C
{
partial IEnumerable<int> M(IEnumerable<int> nums);
}
partial class C
{
partial IEnumerable<int> M(IEnumerable<int> nums)
{
return from int n1 in nums
from int n2 in nums
select n1;
}
}
""";
await TestInRegularAndScriptAsync(source, queryOutput, index: 0);
var linqInvocationOutput = """
using System.Collections.Generic;
using System.Linq;
partial class C
{
partial IEnumerable<int> M(IEnumerable<int> nums);
}
partial class C
{
partial IEnumerable<int> M(IEnumerable<int> nums)
{
return nums.SelectMany(n1 => nums.Select(n2 => n1));
}
}
""";
await TestInRegularAndScriptAsync(source, linqInvocationOutput, index: 1);
}
[Fact]
public async Task ReturnIEnumerableExtendedPartialMethod()
{
var source = """
using System.Collections.Generic;
using System.Linq;
partial class C
{
public partial IEnumerable<int> M(IEnumerable<int> nums);
}
partial class C
{
public partial IEnumerable<int> M(IEnumerable<int> nums)
{
[|foreach (int n1 in nums)
{
foreach (int n2 in nums)
{
yield return n1;
}
}|]
yield break;
}
}
""";
var queryOutput = """
using System.Collections.Generic;
using System.Linq;
partial class C
{
public partial IEnumerable<int> M(IEnumerable<int> nums);
}
partial class C
{
public partial IEnumerable<int> M(IEnumerable<int> nums)
{
return from int n1 in nums
from int n2 in nums
select n1;
}
}
""";
await TestInRegularAndScriptAsync(source, queryOutput, index: 0);
var linqInvocationOutput = """
using System.Collections.Generic;
using System.Linq;
partial class C
{
public partial IEnumerable<int> M(IEnumerable<int> nums);
}
partial class C
{
public partial IEnumerable<int> M(IEnumerable<int> nums)
{
return nums.SelectMany(n1 => nums.Select(n2 => n1));
}
}
""";
await TestInRegularAndScriptAsync(source, linqInvocationOutput, index: 1);
}
[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/31784")]
public async Task QueryWhichRequiresSelectManyWithIdentityLambda()
{
var source = """
using System.Collections.Generic;
class C
{
IEnumerable<int> M()
{
[|foreach (var x in new[] { new[] { 1, 2, 3 }, new[] { 4, 5, 6 } })
{
foreach (var y in x)
{
yield return y;
}
}|]
}
}
""";
var linqInvocationOutput = """
using System.Collections.Generic;
using System.Linq;
class C
{
IEnumerable<int> M()
{
return (new[] { new[] { 1, 2, 3 }, new[] { 4, 5, 6 } }).SelectMany(x => x);
}
}
""";
await TestInRegularAndScriptAsync(source, linqInvocationOutput, index: 1);
}
#endregion
#region In foreach
[Fact]
public async Task QueryInForEachWithSameVariableNameAndDifferentType()
{
var source = """
using System;
using System.Collections.Generic;
using System.Linq;
class A
{
public static implicit operator int(A x)
{
throw null;
}
public static implicit operator A(int x)
{
throw null;
}
}
class B : A { }
class C
{
void M(IEnumerable<int> nums)
{
[|foreach (B a in nums)
{
foreach (A c in nums)
{
Console.Write(a.ToString());
}
}|]
}
}
""";
var queryOutput = """
using System;
using System.Collections.Generic;
using System.Linq;
class A
{
public static implicit operator int(A x)
{
throw null;
}
public static implicit operator A(int x)
{
throw null;
}
}
class B : A { }
class C
{
void M(IEnumerable<int> nums)
{
foreach (var a in from B a in nums
from A c in nums
select a)
{
Console.Write(a.ToString());
}
}
}
""";
await TestInRegularAndScriptAsync(source, queryOutput, index: 0);
var linqInvocationOutput = """
using System;
using System.Collections.Generic;
using System.Linq;
class A
{
public static implicit operator int(A x)
{
throw null;
}
public static implicit operator A(int x)
{
throw null;
}
}
class B : A { }
class C
{
void M(IEnumerable<int> nums)
{
foreach (var a in nums.SelectMany(a => nums.Select(c => a)))
{
Console.Write(a.ToString());
}
}
}
""";
await TestInRegularAndScriptAsync(source, linqInvocationOutput, index: 1);
}
[Fact]
public async Task QueryInForEachWithSameVariableNameAndSameType()
{
var source = """
using System;
using System.Collections.Generic;
using System.Linq;
class A
{
public static implicit operator int(A x)
{
throw null;
}
public static implicit operator A(int x)
{
throw null;
}
}
class C
{
void M(IEnumerable<int> nums)
{
[|foreach (A a in nums)
{
foreach (A c in nums)
{
Console.Write(a.ToString());
}
}|]
}
}
""";
var queryOutput = """
using System;
using System.Collections.Generic;
using System.Linq;
class A
{
public static implicit operator int(A x)
{
throw null;
}
public static implicit operator A(int x)
{
throw null;
}
}
class C
{
void M(IEnumerable<int> nums)
{
foreach (var a in from A a in nums
from A c in nums
select a)
{
Console.Write(a.ToString());
}
}
}
""";
await TestInRegularAndScriptAsync(source, queryOutput, index: 0);
var linqInvocationOutput = """
using System;
using System.Collections.Generic;
using System.Linq;
class A
{
public static implicit operator int(A x)
{
throw null;
}
public static implicit operator A(int x)
{
throw null;
}
}
class C
{
void M(IEnumerable<int> nums)
{
foreach (var a in nums.SelectMany(a => nums.Select(c => a)))
{
Console.Write(a.ToString());
}
}
}
""";
await TestInRegularAndScriptAsync(source, linqInvocationOutput, index: 1);
}
[Fact]
public async Task QueryInForEachWithConvertedType()
{
var source = """
using System;
using System.Collections.Generic;
static class Extensions
{
public static IEnumerable<C> Select(this int[] x, Func<int, C> predicate) => throw null;
}
class C
{
public static implicit operator int(C x)
{
throw null;
}
public static implicit operator C(int x)
{
throw null;
}
IEnumerable<C> Test()
{
[|foreach (var x in new[] { 1, 2, 3 })
{
yield return x;
}|]
}
}
""";
var queryOutput = """
using System;
using System.Collections.Generic;
using System.Linq;
static class Extensions
{
public static IEnumerable<C> Select(this int[] x, Func<int, C> predicate) => throw null;
}
class C
{
public static implicit operator int(C x)
{
throw null;
}
public static implicit operator C(int x)
{
throw null;
}
IEnumerable<C> Test()
{
return from x in new[] { 1, 2, 3 }
select x;
}
}
""";
await TestAsync(source, queryOutput, parseOptions: null);
var linqInvocationOutput = """
using System;
using System.Collections.Generic;
using System.Linq;
static class Extensions
{
public static IEnumerable<C> Select(this int[] x, Func<int, C> predicate) => throw null;
}
class C
{
public static implicit operator int(C x)
{
throw null;
}
public static implicit operator C(int x)
{
throw null;
}
IEnumerable<C> Test()
{
return new[] { 1, 2, 3 };
}
}
""";
await TestInRegularAndScriptAsync(source, linqInvocationOutput, index: 1);
}
[Fact]
public async Task IQueryableConvertedToIEnumerableInReturn()
{
var source = """
using System.Collections.Generic;
using System.Linq;
class C
{
IEnumerable<int> M(IEnumerable<int> nums)
{
[|foreach (int n1 in nums.AsQueryable())
{
yield return n1;
}|]
yield break;
}
}
""";
var queryOutput = """
using System.Collections.Generic;
using System.Linq;
class C
{
IEnumerable<int> M(IEnumerable<int> nums)
{
return from int n1 in nums.AsQueryable()
select n1;
}
}
""";
await TestInRegularAndScriptAsync(source, queryOutput, index: 0);
var linqInvocationOutput = """
using System.Collections.Generic;
using System.Linq;
class C
{
IEnumerable<int> M(IEnumerable<int> nums)
{
return nums.AsQueryable();
}
}
""";
await TestInRegularAndScriptAsync(source, linqInvocationOutput, index: 1);
}
[Fact]
public async Task ReturnIQueryableConvertedToIEnumerableInAssignment()
{
var source = """
using System.Collections.Generic;
using System.Linq;
class C
{
IEnumerable<int> M(IEnumerable<int> nums)
{
[|foreach (int n1 in nums.AsQueryable())
{
yield return n1;
}|]
}
}
""";
var queryOutput = """
using System.Collections.Generic;
using System.Linq;
class C
{
IEnumerable<int> M(IEnumerable<int> nums)
{
return from int n1 in nums.AsQueryable()
select n1;
}
}
""";
await TestInRegularAndScriptAsync(source, queryOutput, index: 0);
var linqInvocationOutput = """
using System.Collections.Generic;
using System.Linq;
class C
{
IEnumerable<int> M(IEnumerable<int> nums)
{
return nums.AsQueryable();
}
}
""";
await TestInRegularAndScriptAsync(source, linqInvocationOutput, index: 1);
}
#endregion
#region In ToList
[Fact]
public async Task ToListLastDeclarationMerge()
{
var source = """
using System.Collections.Generic;
using System.Linq;
class C
{
List<int> M(IEnumerable<int> nums)
{
List<int> list0 = new List<int>(), list = new List<int>();
[|foreach (int n1 in nums)
{
foreach (int n2 in nums)
{
list.Add(n1);
}
}|]
return list;
}
}
""";
var queryOutput = """
using System.Collections.Generic;
using System.Linq;
class C
{
List<int> M(IEnumerable<int> nums)
{
List<int> list0 = new List<int>();
return (from int n1 in nums
from int n2 in nums
select n1).ToList();
}
}
""";
await TestInRegularAndScriptAsync(source, queryOutput, index: 0);
var linqInvocationOutput = """
using System.Collections.Generic;
using System.Linq;
class C
{
List<int> M(IEnumerable<int> nums)
{
List<int> list0 = new List<int>();
return nums.SelectMany(n1 => nums.Select(n2 => n1)).ToList();
}
}
""";
await TestInRegularAndScriptAsync(source, linqInvocationOutput, index: 1);
}
[Fact]
public async Task ToListParameterizedConstructor()
{
var source = """
using System.Collections.Generic;
using System.Linq;
class C
{
List<int> M(IEnumerable<int> nums)
{
List<int> list = new List<int>(nums);
[|foreach (int n1 in nums)
{
foreach (int n2 in nums)
{
list.Add(n1);
}
}|]
return list;
}
}
""";
var queryOutput = """
using System.Collections.Generic;
using System.Linq;
class C
{
List<int> M(IEnumerable<int> nums)
{
List<int> list = new List<int>(nums);
list.AddRange(from int n1 in nums
from int n2 in nums
select n1);
return list;
}
}
""";
await TestInRegularAndScriptAsync(source, queryOutput, index: 0);
var linqInvocationOutput = """
using System.Collections.Generic;
using System.Linq;
class C
{
List<int> M(IEnumerable<int> nums)
{
List<int> list = new List<int>(nums);
list.AddRange(nums.SelectMany(n1 => nums.Select(n2 => n1)));
return list;
}
}
""";
await TestInRegularAndScriptAsync(source, linqInvocationOutput, index: 1);
}
[Fact]
public async Task ToListWithListInitializer()
{
var source = """
using System.Collections.Generic;
using System.Linq;
class C
{
List<int> M(IEnumerable<int> nums)
{
List<int> list = new List<int>() { 1, 2, 3 };
[|foreach (int n1 in nums)
{
foreach (int n2 in nums)
{
list.Add(n1);
}
}|]
return list;
}
}
""";
var queryOutput = """
using System.Collections.Generic;
using System.Linq;
class C
{
List<int> M(IEnumerable<int> nums)
{
List<int> list = new List<int>() { 1, 2, 3 };
list.AddRange(from int n1 in nums
from int n2 in nums
select n1);
return list;
}
}
""";
await TestInRegularAndScriptAsync(source, queryOutput, index: 0);
var linqInvocationOutput = """
using System.Collections.Generic;
using System.Linq;
class C
{
List<int> M(IEnumerable<int> nums)
{
List<int> list = new List<int>() { 1, 2, 3 };
list.AddRange(nums.SelectMany(n1 => nums.Select(n2 => n1)));
return list;
}
}
""";
await TestInRegularAndScriptAsync(source, linqInvocationOutput, index: 1);
}
[Fact]
public async Task ToListWithEmptyArgumentList()
{
var source = """
using System.Collections.Generic;
using System.Linq;
class C
{
List<int> M(IEnumerable<int> nums)
{
List<int> list = new List<int> { };
[|foreach (int n1 in nums)
{
foreach (int n2 in nums)
{
list.Add(n1);
}
}|]
return list;
}
}
""";
var queryOutput = """
using System.Collections.Generic;
using System.Linq;
class C
{
List<int> M(IEnumerable<int> nums)
{
return (from int n1 in nums
from int n2 in nums
select n1).ToList();
}
}
""";
await TestInRegularAndScriptAsync(source, queryOutput, index: 0);
var linqInvocationOutput = """
using System.Collections.Generic;
using System.Linq;
class C
{
List<int> M(IEnumerable<int> nums)
{
return nums.SelectMany(n1 => nums.Select(n2 => n1)).ToList();
}
}
""";
await TestInRegularAndScriptAsync(source, linqInvocationOutput, index: 1);
}
[Fact]
public async Task ToListNotLastDeclaration()
{
var source = """
using System.Collections.Generic;
using System.Linq;
class C
{
List<int> M(IEnumerable<int> nums)
{
List<int> list = new List<int>(), list1 = new List<int>();
[|foreach (int n1 in nums)
{
foreach (int n2 in nums)
{
list.Add(n1);
}
}|]
return list;
}
}
""";
var queryOutput = """
using System.Collections.Generic;
using System.Linq;
class C
{
List<int> M(IEnumerable<int> nums)
{
List<int> list = new List<int>(), list1 = new List<int>();
list.AddRange(from int n1 in nums
from int n2 in nums
select n1);
return list;
}
}
""";
await TestInRegularAndScriptAsync(source, queryOutput, index: 0);
var linqInvocationOutput = """
using System.Collections.Generic;
using System.Linq;
class C
{
List<int> M(IEnumerable<int> nums)
{
List<int> list = new List<int>(), list1 = new List<int>();
list.AddRange(nums.SelectMany(n1 => nums.Select(n2 => n1)));
return list;
}
}
""";
await TestInRegularAndScriptAsync(source, linqInvocationOutput, index: 1);
}
[Fact]
public async Task ToListAssignToParameter()
{
var source = """
using System.Collections.Generic;
using System.Linq;
class C
{
List<int> M(IEnumerable<int> nums, List<int> list)
{
list = new List<int>();
[|foreach (int n1 in nums)
{
foreach (int n2 in nums)
{
list.Add(n1);
}
}|]
return list;
}
}
""";
var queryOutput = """
using System.Collections.Generic;
using System.Linq;
class C
{
List<int> M(IEnumerable<int> nums, List<int> list)
{
list = (from int n1 in nums
from int n2 in nums
select n1).ToList();
return list;
}
}
""";
await TestInRegularAndScriptAsync(source, queryOutput, index: 0);
var linqInvocationOutput = """
using System.Collections.Generic;
using System.Linq;
class C
{
List<int> M(IEnumerable<int> nums, List<int> list)
{
list = nums.SelectMany(n1 => nums.Select(n2 => n1)).ToList();
return list;
}
}
""";
await TestInRegularAndScriptAsync(source, linqInvocationOutput, index: 1);
}
[Fact]
public async Task ToListToArrayElement()
{
var source = """
using System.Collections.Generic;
using System.Linq;
class C
{
void M(IEnumerable<int> nums, List<int>[] lists)
{
[|foreach (int n1 in nums)
{
foreach (int n2 in nums)
{
lists[0].Add(n1);
}
}|]
}
}
""";
var queryOutput = """
using System.Collections.Generic;
using System.Linq;
class C
{
void M(IEnumerable<int> nums, List<int>[] lists)
{
lists[0].AddRange(from int n1 in nums
from int n2 in nums
select n1);
}
}
""";
await TestInRegularAndScriptAsync(source, queryOutput, index: 0);
var linqInvocationOutput = """
using System.Collections.Generic;
using System.Linq;
class C
{
void M(IEnumerable<int> nums, List<int>[] lists)
{
lists[0].AddRange(nums.SelectMany(n1 => nums.Select(n2 => n1)));
}
}
""";
await TestInRegularAndScriptAsync(source, linqInvocationOutput, index: 1);
}
[Fact]
public async Task ToListToNewArrayElement()
{
var source = """
using System.Collections.Generic;
using System.Linq;
class C
{
void M(IEnumerable<int> nums, List<int>[] lists)
{
lists[0] = new List<int>();
[|foreach (int n1 in nums)
{
foreach (int n2 in nums)
{
lists[0].Add(n1);
}
}|]
}
}
""";
var queryOutput = """
using System.Collections.Generic;
using System.Linq;
class C
{
void M(IEnumerable<int> nums, List<int>[] lists)
{
lists[0] = (from int n1 in nums
from int n2 in nums
select n1).ToList();
}
}
""";
await TestInRegularAndScriptAsync(source, queryOutput, index: 0);
var linqInvocationOutput = """
using System.Collections.Generic;
using System.Linq;
class C
{
void M(IEnumerable<int> nums, List<int>[] lists)
{
lists[0] = nums.SelectMany(n1 => nums.Select(n2 => n1)).ToList();
}
}
""";
await TestInRegularAndScriptAsync(source, linqInvocationOutput, index: 1);
}
[Fact]
public async Task ToListHashSetNoConversion()
{
var source = """
using System.Collections.Generic;
class C
{
void M(IEnumerable<int> nums)
{
var hashSet = new HashSet<int>();
[|foreach (int n1 in nums)
{
hashSet.Add(n1);
}|]
}
}
""";
await TestMissingAsync(source);
}
[Fact]
public async Task ToListMergeWithReturn()
{
var source = """
using System.Collections.Generic;
using System.Linq;
class C
{
List<int> M(IEnumerable<int> nums)
{
var list = new List<int>();
[|foreach (int n1 in nums)
{
foreach (int n2 in nums)
{
list.Add(n1);
}
}|]
return list;
}
}
""";
var queryOutput = """
using System.Collections.Generic;
using System.Linq;
class C
{
List<int> M(IEnumerable<int> nums)
{
return (from int n1 in nums
from int n2 in nums
select n1).ToList();
}
}
""";
await TestInRegularAndScriptAsync(source, queryOutput, index: 0);
var linqInvocationOutput = """
using System.Collections.Generic;
using System.Linq;
class C
{
List<int> M(IEnumerable<int> nums)
{
return nums.SelectMany(n1 => nums.Select(n2 => n1)).ToList();
}
}
""";
await TestInRegularAndScriptAsync(source, linqInvocationOutput, index: 1);
}
[Fact]
public async Task ToListSeparateDeclarationAndAssignmentMergeWithReturn()
{
var source = """
using System.Collections.Generic;
using System.Linq;
class C
{
List<int> M(IEnumerable<int> nums)
{
List<int> list;
list = new List<int>();
[|foreach (int n1 in nums)
{
foreach (int n2 in nums)
{
list.Add(n1);
}
}|]
return list;
}
}
""";
var queryOutput = """
using System.Collections.Generic;
using System.Linq;
class C
{
List<int> M(IEnumerable<int> nums)
{
List<int> list;
return (from int n1 in nums
from int n2 in nums
select n1).ToList();
}
}
""";
await TestInRegularAndScriptAsync(source, queryOutput, index: 0);
var linqInvocationOutput = """
using System.Collections.Generic;
using System.Linq;
class C
{
List<int> M(IEnumerable<int> nums)
{
List<int> list;
return nums.SelectMany(n1 => nums.Select(n2 => n1)).ToList();
}
}
""";
await TestInRegularAndScriptAsync(source, linqInvocationOutput, index: 1);
}
[Fact]
public async Task ToListSeparateDeclarationAndAssignment()
{
var source = """
using System.Collections.Generic;
using System.Linq;
class C
{
int M(IEnumerable<int> nums)
{
List<int> list;
list = new List<int>();
[|foreach (int n1 in nums)
{
foreach (int n2 in nums)
{
list.Add(n1);
}
}|]
return list.Count;
}
}
""";
var queryOutput = """
using System.Collections.Generic;
using System.Linq;
class C
{
int M(IEnumerable<int> nums)
{
List<int> list;
list = (from int n1 in nums
from int n2 in nums
select n1).ToList();
return list.Count;
}
}
""";
await TestInRegularAndScriptAsync(source, queryOutput, index: 0);
var linqInvocationOutput = """
using System.Collections.Generic;
using System.Linq;
class C
{
int M(IEnumerable<int> nums)
{
List<int> list;
list = nums.SelectMany(n1 => nums.Select(n2 => n1)).ToList();
return list.Count;
}
}
""";
await TestInRegularAndScriptAsync(source, linqInvocationOutput, index: 1);
}
[Fact]
public async Task ToListTypeReplacement01()
{
var source = """
using System;
using System.Linq;
using C = System.Collections.Generic.List<int>;
class Query
{
public static void Main(string[] args)
{
C c1 = new C { 1, 2, 3 };
C c2 = new C { 10, 20, 30 };
C c3 = new C { 100, 200, 300 };
C r1 = new C();
[|foreach (int x in c1)
{
foreach (int y in c2)
{
foreach (int z in c3)
{
var g = x + y + z;
if (x + y / 10 + z / 100 < 6)
{
r1.Add(g);
}
}
}
}|]
Console.WriteLine(r1);
}
}
""";
var queryOutput = """
using System;
using System.Linq;
using C = System.Collections.Generic.List<int>;
class Query
{
public static void Main(string[] args)
{
C c1 = new C { 1, 2, 3 };
C c2 = new C { 10, 20, 30 };
C c3 = new C { 100, 200, 300 };
C r1 = (from int x in c1
from int y in c2
from int z in c3
let g = x + y + z
where x + y / 10 + z / 100 < 6
select g).ToList();
Console.WriteLine(r1);
}
}
""";
await TestInRegularAndScriptAsync(source, queryOutput, index: 0);
var linqInvocationOutput = """
using System;
using System.Linq;
using C = System.Collections.Generic.List<int>;
class Query
{
public static void Main(string[] args)
{
C c1 = new C { 1, 2, 3 };
C c2 = new C { 10, 20, 30 };
C c3 = new C { 100, 200, 300 };
C r1 = new C();
foreach (var (x, y, z) in c1.SelectMany(x => c2.SelectMany(y => c3.Select(z => (x, y, z)))))
{
var g = x + y + z;
if (x + y / 10 + z / 100 < 6)
{
r1.Add(g);
}
}
Console.WriteLine(r1);
}
}
""";
await TestInRegularAndScriptAsync(source, linqInvocationOutput, index: 1);
}
[Fact]
public async Task ToListTypeReplacement02()
{
var source = """
using System.Linq;
using System;
using C = System.Collections.Generic.List<int>;
class Query
{
public static void Main(string[] args)
{
C c1 = new C { 1, 2, 3 };
C c2 = new C { 10, 20, 30 };
C r1 = new C();
[|foreach (int x in c1)
{
foreach (var y in c2)
{
if (Equals(x, y / 10))
{
var z = x + y;
r1.Add(z);
}
}
}|]
Console.WriteLine(r1);
}
}
""";
var queryOutput = """
using System.Linq;
using System;
using C = System.Collections.Generic.List<int>;
class Query
{
public static void Main(string[] args)
{
C c1 = new C { 1, 2, 3 };
C c2 = new C { 10, 20, 30 };
C r1 = (from int x in c1
from y in c2
where Equals(x, y / 10)
let z = x + y
select z).ToList();
Console.WriteLine(r1);
}
}
""";
await TestInRegularAndScriptAsync(source, queryOutput, index: 0);
var linqInvocationOutput = """
using System.Linq;
using System;
using C = System.Collections.Generic.List<int>;
class Query
{
public static void Main(string[] args)
{
C c1 = new C { 1, 2, 3 };
C c2 = new C { 10, 20, 30 };
C r1 = new C();
foreach (var (x, y) in c1.SelectMany(x => c2.Where(y => Equals(x, y / 10)).Select(y => (x, y))))
{
var z = x + y;
r1.Add(z);
}
Console.WriteLine(r1);
}
}
""";
await TestInRegularAndScriptAsync(source, linqInvocationOutput, index: 1);
}
[Fact]
public async Task ToListPropertyAssignment()
{
var source = """
using System.Collections.Generic;
using System.Linq;
public class Test
{
public static void Main()
{
var nums = new int[] { 1, 2, 3, 4 };
var c = new C();
c.A = new List<int>();
[|foreach (var x in nums)
{
c.A.Add(x + 1);
}|]
}
class C
{
public List<int> A { get; set; }
}
}
""";
var queryOutput = """
using System.Collections.Generic;
using System.Linq;
public class Test
{
public static void Main()
{
var nums = new int[] { 1, 2, 3, 4 };
var c = new C();
c.A = (from x in nums
select x + 1).ToList();
}
class C
{
public List<int> A { get; set; }
}
}
""";
await TestInRegularAndScriptAsync(source, queryOutput, index: 0);
var linqInvocationOutput = """
using System.Collections.Generic;
using System.Linq;
public class Test
{
public static void Main()
{
var nums = new int[] { 1, 2, 3, 4 };
var c = new C();
c.A = nums.Select(x => x + 1).ToList();
}
class C
{
public List<int> A { get; set; }
}
}
""";
await TestInRegularAndScriptAsync(source, linqInvocationOutput, index: 1);
}
[Fact]
public async Task ToListPropertyAssignmentNoDeclaration()
{
var source = """
using System.Collections.Generic;
using System.Linq;
public class Test
{
void M()
{
var nums = new int[] { 1, 2, 3, 4 };
var c = new C();
[|foreach (var x in nums)
{
c.A.Add(x + 1);
}|]
}
class C
{
public List<int> A { get; set; }
}
}
""";
var queryOutput = """
using System.Collections.Generic;
using System.Linq;
public class Test
{
void M()
{
var nums = new int[] { 1, 2, 3, 4 };
var c = new C();
c.A.AddRange(from x in nums
select x + 1);
}
class C
{
public List<int> A { get; set; }
}
}
""";
await TestInRegularAndScriptAsync(source, queryOutput, index: 0);
var linqInvocationOutput = """
using System.Collections.Generic;
using System.Linq;
public class Test
{
void M()
{
var nums = new int[] { 1, 2, 3, 4 };
var c = new C();
c.A.AddRange(nums.Select(x => x + 1));
}
class C
{
public List<int> A { get; set; }
}
}
""";
await TestInRegularAndScriptAsync(source, linqInvocationOutput, index: 1);
}
[Fact]
public async Task ToListNoInitialization()
{
var source = """
using System.Collections.Generic;
using System.Linq;
public class Test
{
public List<int> A { get; set; }
void M()
{
[|foreach (var x in new int[] { 1, 2, 3, 4 })
{
A.Add(x + 1);
}|]
}
}
""";
var queryOutput = """
using System.Collections.Generic;
using System.Linq;
public class Test
{
public List<int> A { get; set; }
void M()
{
A.AddRange(from x in new int[] { 1, 2, 3, 4 }
select x + 1);
}
}
""";
await TestInRegularAndScriptAsync(source, queryOutput, index: 0);
var linqInvocationOutput = """
using System.Collections.Generic;
using System.Linq;
public class Test
{
public List<int> A { get; set; }
void M()
{
A.AddRange((new int[] { 1, 2, 3, 4 }).Select(x => x + 1));
}
}
""";
await TestInRegularAndScriptAsync(source, linqInvocationOutput, index: 1);
}
[Fact]
public async Task ToListOverride()
{
var source = """
using System.Collections.Generic;
using System.Linq;
public static class C
{
public static void Add<T>(this List<T> list, T value, T anotherValue) { }
}
public class Test
{
void M()
{
var list = new List<int>();
[|foreach (var x in new int[] { 1, 2, 3, 4 })
{
list.Add(x + 1, x);
}|]
}
}
""";
await TestMissingAsync(source);
}
#endregion
#region In Count
[Fact]
public async Task CountInMultipleDeclarationLast()
{
var source = """
using System.Collections.Generic;
using System.Linq;
class C
{
void M(IEnumerable<int> nums)
{
int i = 0, cnt = 0;
[|foreach (int n1 in nums)
{
foreach (int n2 in nums)
{
cnt++;
}
}|]
}
}
""";
var queryOutput = """
using System.Collections.Generic;
using System.Linq;
class C
{
void M(IEnumerable<int> nums)
{
int i = 0, cnt = (from int n1 in nums
from int n2 in nums
select n1).Count();
}
}
""";
await TestInRegularAndScriptAsync(source, queryOutput, index: 0);
var linqInvocationOutput = """
using System.Collections.Generic;
using System.Linq;
class C
{
void M(IEnumerable<int> nums)
{
int i = 0, cnt = nums.SelectMany(n1 => nums.Select(n2 => n1)).Count();
}
}
""";
await TestInRegularAndScriptAsync(source, linqInvocationOutput, index: 1);
}
[Fact]
public async Task CountInMultipleDeclarationNotLast()
{
var source = """
using System.Collections.Generic;
using System.Linq;
class C
{
void M(IEnumerable<int> nums)
{
int cnt = 0, i = 0;
[|foreach (int n1 in nums)
{
foreach (int n2 in nums)
{
cnt++;
}
}|]
}
}
""";
var queryOutput = """
using System.Collections.Generic;
using System.Linq;
class C
{
void M(IEnumerable<int> nums)
{
int cnt = 0, i = 0;
cnt += (from int n1 in nums
from int n2 in nums
select n1).Count();
}
}
""";
await TestInRegularAndScriptAsync(source, queryOutput, index: 0);
var linqInvocationOutput = """
using System.Collections.Generic;
using System.Linq;
class C
{
void M(IEnumerable<int> nums)
{
int cnt = 0, i = 0;
cnt += nums.SelectMany(n1 => nums.Select(n2 => n1)).Count();
}
}
""";
await TestInRegularAndScriptAsync(source, linqInvocationOutput, index: 1);
}
[Fact]
public async Task CountInParameter()
{
var source = """
using System.Collections.Generic;
using System.Linq;
class C
{
void M(IEnumerable<int> nums, int c)
{
[|foreach (int n1 in nums)
{
foreach (int n2 in nums)
{
c++;
}
}|]
}
}
""";
var queryOutput = """
using System.Collections.Generic;
using System.Linq;
class C
{
void M(IEnumerable<int> nums, int c)
{
c += (from int n1 in nums
from int n2 in nums
select n1).Count();
}
}
""";
await TestInRegularAndScriptAsync(source, queryOutput, index: 0);
var linqInvocationOutput = """
using System.Collections.Generic;
using System.Linq;
class C
{
void M(IEnumerable<int> nums, int c)
{
c += nums.SelectMany(n1 => nums.Select(n2 => n1)).Count();
}
}
""";
await TestInRegularAndScriptAsync(source, linqInvocationOutput, index: 1);
}
[Fact]
public async Task CountInParameterAssignedToZero()
{
var source = """
using System.Collections.Generic;
using System.Linq;
class C
{
void M(IEnumerable<int> nums, int c)
{
c = 0;
[|foreach (int n1 in nums)
{
foreach (int n2 in nums)
{
c++;
}
}|]
}
}
""";
var queryOutput = """
using System.Collections.Generic;
using System.Linq;
class C
{
void M(IEnumerable<int> nums, int c)
{
c = (from int n1 in nums
from int n2 in nums
select n1).Count();
}
}
""";
await TestInRegularAndScriptAsync(source, queryOutput, index: 0);
var linqInvocationOutput = """
using System.Collections.Generic;
using System.Linq;
class C
{
void M(IEnumerable<int> nums, int c)
{
c = nums.SelectMany(n1 => nums.Select(n2 => n1)).Count();
}
}
""";
await TestInRegularAndScriptAsync(source, linqInvocationOutput, index: 1);
}
[Fact]
public async Task CountInParameterAssignedToNonZero()
{
var source = """
using System.Collections.Generic;
using System.Linq;
class C
{
void M(IEnumerable<int> nums, int c)
{
c = 5;
[|foreach (int n1 in nums)
{
foreach (int n2 in nums)
{
c++;
}
}|]
}
}
""";
var queryOutput = """
using System.Collections.Generic;
using System.Linq;
class C
{
void M(IEnumerable<int> nums, int c)
{
c = 5;
c += (from int n1 in nums
from int n2 in nums
select n1).Count();
}
}
""";
await TestInRegularAndScriptAsync(source, queryOutput, index: 0);
var linqInvocationOutput = """
using System.Collections.Generic;
using System.Linq;
class C
{
void M(IEnumerable<int> nums, int c)
{
c = 5;
c += nums.SelectMany(n1 => nums.Select(n2 => n1)).Count();
}
}
""";
await TestInRegularAndScriptAsync(source, linqInvocationOutput, index: 1);
}
[Fact]
public async Task CountInDeclarationMergeToReturn()
{
var source = """
using System.Collections.Generic;
using System.Linq;
class C
{
int M(IEnumerable<int> nums)
{
var cnt = 0;
[|foreach (int n1 in nums)
{
foreach (int n2 in nums)
{
cnt++;
}
}|]
return cnt;
}
}
""";
var queryOutput = """
using System.Collections.Generic;
using System.Linq;
class C
{
int M(IEnumerable<int> nums)
{
return (from int n1 in nums
from int n2 in nums
select n1).Count();
}
}
""";
await TestInRegularAndScriptAsync(source, queryOutput, index: 0);
var linqInvocationOutput = """
using System.Collections.Generic;
using System.Linq;
class C
{
int M(IEnumerable<int> nums)
{
return nums.SelectMany(n1 => nums.Select(n2 => n1)).Count();
}
}
""";
await TestInRegularAndScriptAsync(source, linqInvocationOutput, index: 1);
}
[Fact]
public async Task CountInDeclarationConversion()
{
var source = """
using System.Collections.Generic;
using System.Linq;
class C
{
double M(IEnumerable<int> nums)
{
double c = 0;
[|foreach (int n1 in nums)
{
foreach (int n2 in nums)
{
c++;
}
}|]
return c;
}
}
""";
var queryOutput = """
using System.Collections.Generic;
using System.Linq;
class C
{
double M(IEnumerable<int> nums)
{
return (from int n1 in nums
from int n2 in nums
select n1).Count();
}
}
""";
await TestInRegularAndScriptAsync(source, queryOutput, index: 0);
var linqInvocationOutput = """
using System.Collections.Generic;
using System.Linq;
class C
{
double M(IEnumerable<int> nums)
{
return nums.SelectMany(n1 => nums.Select(n2 => n1)).Count();
}
}
""";
await TestInRegularAndScriptAsync(source, linqInvocationOutput, index: 1);
}
[Fact]
public async Task CountInMultipleDeclarationMergeToReturnLast()
{
var source = """
using System.Collections.Generic;
using System.Linq;
class C
{
int M(IEnumerable<int> nums)
{
int c = 0, cnt = 0;
[|foreach (int n1 in nums)
{
foreach (int n2 in nums)
{
cnt++;
}
}|]
return cnt;
}
}
""";
var queryOutput = """
using System.Collections.Generic;
using System.Linq;
class C
{
int M(IEnumerable<int> nums)
{
int c = 0;
return (from int n1 in nums
from int n2 in nums
select n1).Count();
}
}
""";
await TestInRegularAndScriptAsync(source, queryOutput, index: 0);
var linqInvocationOutput = """
using System.Collections.Generic;
using System.Linq;
class C
{
int M(IEnumerable<int> nums)
{
int c = 0;
return nums.SelectMany(n1 => nums.Select(n2 => n1)).Count();
}
}
""";
await TestInRegularAndScriptAsync(source, linqInvocationOutput, index: 1);
}
[Fact]
public async Task CountInMultipleDeclarationLastButNotZero()
{
var source = """
using System.Collections.Generic;
using System.Linq;
class C
{
int M(IEnumerable<int> nums)
{
int c = 0, cnt = 5;
[|foreach (int n1 in nums)
{
foreach (int n2 in nums)
{
cnt++;
}
}|]
return cnt;
}
}
""";
var queryOutput = """
using System.Collections.Generic;
using System.Linq;
class C
{
int M(IEnumerable<int> nums)
{
int c = 0, cnt = 5;
cnt += (from int n1 in nums
from int n2 in nums
select n1).Count();
return cnt;
}
}
""";
await TestInRegularAndScriptAsync(source, queryOutput, index: 0);
var linqInvocationOutput = """
using System.Collections.Generic;
using System.Linq;
class C
{
int M(IEnumerable<int> nums)
{
int c = 0, cnt = 5;
cnt += nums.SelectMany(n1 => nums.Select(n2 => n1)).Count();
return cnt;
}
}
""";
await TestInRegularAndScriptAsync(source, linqInvocationOutput, index: 1);
}
[Fact]
public async Task CountInMultipleDeclarationMergeToReturnNotLast()
{
var source = """
using System.Collections.Generic;
using System.Linq;
class C
{
int M(IEnumerable<int> nums)
{
int cnt = 0, c = 0;
[|foreach (int n1 in nums)
{
foreach (int n2 in nums)
{
cnt++;
}
}|]
return cnt;
}
}
""";
var queryOutput = """
using System.Collections.Generic;
using System.Linq;
class C
{
int M(IEnumerable<int> nums)
{
int cnt = 0, c = 0;
cnt += (from int n1 in nums
from int n2 in nums
select n1).Count();
return cnt;
}
}
""";
await TestInRegularAndScriptAsync(source, queryOutput, index: 0);
var linqInvocationOutput = """
using System.Collections.Generic;
using System.Linq;
class C
{
int M(IEnumerable<int> nums)
{
int cnt = 0, c = 0;
cnt += nums.SelectMany(n1 => nums.Select(n2 => n1)).Count();
return cnt;
}
}
""";
await TestInRegularAndScriptAsync(source, linqInvocationOutput, index: 1);
}
[Fact]
public async Task CountInMultipleDeclarationNonZeroToReturnNotLast()
{
var source = """
using System.Collections.Generic;
using System.Linq;
class C
{
int M(IEnumerable<int> nums)
{
int cnt = 5, c = 0;
[|foreach (int n1 in nums)
{
foreach (int n2 in nums)
{
cnt++;
}
}|]
return cnt;
}
}
""";
var queryOutput = """
using System.Collections.Generic;
using System.Linq;
class C
{
int M(IEnumerable<int> nums)
{
int cnt = 5, c = 0;
cnt += (from int n1 in nums
from int n2 in nums
select n1).Count();
return cnt;
}
}
""";
await TestInRegularAndScriptAsync(source, queryOutput, index: 0);
var linqInvocationOutput = """
using System.Collections.Generic;
using System.Linq;
class C
{
int M(IEnumerable<int> nums)
{
int cnt = 5, c = 0;
cnt += nums.SelectMany(n1 => nums.Select(n2 => n1)).Count();
return cnt;
}
}
""";
await TestInRegularAndScriptAsync(source, linqInvocationOutput, index: 1);
}
[Fact]
public async Task CountInAssignmentToZero()
{
var source = """
using System.Collections.Generic;
using System.Linq;
class C
{
int M(IEnumerable<int> nums)
{
int cnt;
cnt = 0;
[|foreach (int n1 in nums)
{
foreach (int n2 in nums)
{
cnt++;
}
}|]
return cnt;
}
}
""";
var queryOutput = """
using System.Collections.Generic;
using System.Linq;
class C
{
int M(IEnumerable<int> nums)
{
int cnt;
return (from int n1 in nums
from int n2 in nums
select n1).Count();
}
}
""";
await TestInRegularAndScriptAsync(source, queryOutput, index: 0);
var linqInvocationOutput = """
using System.Collections.Generic;
using System.Linq;
class C
{
int M(IEnumerable<int> nums)
{
int cnt;
return nums.SelectMany(n1 => nums.Select(n2 => n1)).Count();
}
}
""";
await TestInRegularAndScriptAsync(source, linqInvocationOutput, index: 1);
}
[Fact]
public async Task CountInAssignmentToNonZero()
{
var source = """
using System.Collections.Generic;
using System.Linq;
class C
{
int M(IEnumerable<int> nums)
{
int cnt;
cnt = 5;
[|foreach (int n1 in nums)
{
foreach (int n2 in nums)
{
cnt++;
}
}|]
return cnt;
}
}
""";
var queryOutput = """
using System.Collections.Generic;
using System.Linq;
class C
{
int M(IEnumerable<int> nums)
{
int cnt;
cnt = 5;
cnt += (from int n1 in nums
from int n2 in nums
select n1).Count();
return cnt;
}
}
""";
await TestInRegularAndScriptAsync(source, queryOutput, index: 0);
var linqInvocationOutput = """
using System.Collections.Generic;
using System.Linq;
class C
{
int M(IEnumerable<int> nums)
{
int cnt;
cnt = 5;
cnt += nums.SelectMany(n1 => nums.Select(n2 => n1)).Count();
return cnt;
}
}
""";
await TestInRegularAndScriptAsync(source, linqInvocationOutput, index: 1);
}
[Fact]
public async Task CountInParameterAssignedToZeroAndReturned()
{
var source = """
using System.Collections.Generic;
using System.Linq;
class C
{
int M(IEnumerable<int> nums, int c)
{
c = 0;
[|foreach (int n1 in nums)
{
foreach (int n2 in nums)
{
c++;
}
}|]
return c;
}
}
""";
var queryOutput = """
using System.Collections.Generic;
using System.Linq;
class C
{
int M(IEnumerable<int> nums, int c)
{
c = (from int n1 in nums
from int n2 in nums
select n1).Count();
return c;
}
}
""";
await TestInRegularAndScriptAsync(source, queryOutput, index: 0);
var linqInvocationOutput = """
using System.Collections.Generic;
using System.Linq;
class C
{
int M(IEnumerable<int> nums, int c)
{
c = nums.SelectMany(n1 => nums.Select(n2 => n1)).Count();
return c;
}
}
""";
await TestInRegularAndScriptAsync(source, linqInvocationOutput, index: 1);
}
[Fact]
public async Task CountDeclareWithNonZero()
{
var source = """
using System.Collections.Generic;
using System.Linq;
class C
{
void M(IEnumerable<int> nums)
{
var count = 5;
[|foreach (int n1 in nums)
{
foreach (int n2 in nums)
{
count++;
}
}|]
}
}
""";
var queryOutput = """
using System.Collections.Generic;
using System.Linq;
class C
{
void M(IEnumerable<int> nums)
{
var count = 5;
count += (from int n1 in nums
from int n2 in nums
select n1).Count();
}
}
""";
await TestInRegularAndScriptAsync(source, queryOutput, index: 0);
var linqInvocationOutput = """
using System.Collections.Generic;
using System.Linq;
class C
{
void M(IEnumerable<int> nums)
{
var count = 5;
count += nums.SelectMany(n1 => nums.Select(n2 => n1)).Count();
}
}
""";
await TestInRegularAndScriptAsync(source, linqInvocationOutput, index: 1);
}
[Fact]
public async Task CountAssignWithZero()
{
var source = """
using System.Collections.Generic;
using System.Linq;
class C
{
void M(IEnumerable<int> nums)
{
int count = 1;
count = 0;
[|foreach (int n1 in nums)
{
foreach (int n2 in nums)
{
count++;
}
}|]
}
}
""";
var queryOutput = """
using System.Collections.Generic;
using System.Linq;
class C
{
void M(IEnumerable<int> nums)
{
int count = 1;
count = (from int n1 in nums
from int n2 in nums
select n1).Count();
}
}
""";
await TestInRegularAndScriptAsync(source, queryOutput, index: 0);
var linqInvocationOutput = """
using System.Collections.Generic;
using System.Linq;
class C
{
void M(IEnumerable<int> nums)
{
int count = 1;
count = nums.SelectMany(n1 => nums.Select(n2 => n1)).Count();
}
}
""";
await TestInRegularAndScriptAsync(source, linqInvocationOutput, index: 1);
}
[Fact]
public async Task CountAssignWithNonZero()
{
var source = """
using System.Collections.Generic;
using System.Linq;
class C
{
void M(IEnumerable<int> nums)
{
var count = 0;
count = 4;
[|foreach (int n1 in nums)
{
foreach (int n2 in nums)
{
count++;
}
}|]
}
}
""";
var queryOutput = """
using System.Collections.Generic;
using System.Linq;
class C
{
void M(IEnumerable<int> nums)
{
var count = 0;
count = 4;
count += (from int n1 in nums
from int n2 in nums
select n1).Count();
}
}
""";
await TestInRegularAndScriptAsync(source, queryOutput, index: 0);
var linqInvocationOutput = """
using System.Collections.Generic;
using System.Linq;
class C
{
void M(IEnumerable<int> nums)
{
var count = 0;
count = 4;
count += nums.SelectMany(n1 => nums.Select(n2 => n1)).Count();
}
}
""";
await TestInRegularAndScriptAsync(source, linqInvocationOutput, index: 1);
}
[Fact]
public async Task CountAssignPropertyAssignedToZero()
{
var source = """
using System.Collections.Generic;
using System.Linq;
class A { public int B { get; set; }}
class C
{
void M(IEnumerable<int> nums, A a)
{
a.B = 0;
[|foreach (int n1 in nums)
{
foreach (int n2 in nums)
{
a.B++;
}
}|]
}
}
""";
var queryOutput = """
using System.Collections.Generic;
using System.Linq;
class A { public int B { get; set; }}
class C
{
void M(IEnumerable<int> nums, A a)
{
a.B = (from int n1 in nums
from int n2 in nums
select n1).Count();
}
}
""";
await TestInRegularAndScriptAsync(source, queryOutput, index: 0);
var linqInvocationOutput = """
using System.Collections.Generic;
using System.Linq;
class A { public int B { get; set; }}
class C
{
void M(IEnumerable<int> nums, A a)
{
a.B = nums.SelectMany(n1 => nums.Select(n2 => n1)).Count();
}
}
""";
await TestInRegularAndScriptAsync(source, linqInvocationOutput, index: 1);
}
[Fact]
public async Task CountAssignPropertyAssignedToNonZero()
{
var source = """
using System.Collections.Generic;
using System.Linq;
class A { public int B { get; set; }}
class C
{
void M(IEnumerable<int> nums, A a)
{
a.B = 5;
[|foreach (int n1 in nums)
{
foreach (int n2 in nums)
{
a.B++;
}
}|]
}
}
""";
var queryOutput = """
using System.Collections.Generic;
using System.Linq;
class A { public int B { get; set; }}
class C
{
void M(IEnumerable<int> nums, A a)
{
a.B = 5;
a.B += (from int n1 in nums
from int n2 in nums
select n1).Count();
}
}
""";
await TestInRegularAndScriptAsync(source, queryOutput, index: 0);
var linqInvocationOutput = """
using System.Collections.Generic;
using System.Linq;
class A { public int B { get; set; }}
class C
{
void M(IEnumerable<int> nums, A a)
{
a.B = 5;
a.B += nums.SelectMany(n1 => nums.Select(n2 => n1)).Count();
}
}
""";
await TestInRegularAndScriptAsync(source, linqInvocationOutput, index: 1);
}
[Fact]
public async Task CountAssignPropertyNotKnownAssigned()
{
var source = """
using System.Collections.Generic;
using System.Linq;
class A { public int B { get; set; }}
class C
{
void M(IEnumerable<int> nums, A a)
{
[|foreach (int n1 in nums)
{
foreach (int n2 in nums)
{
a.B++;
}
}|]
}
}
""";
var queryOutput = """
using System.Collections.Generic;
using System.Linq;
class A { public int B { get; set; }}
class C
{
void M(IEnumerable<int> nums, A a)
{
a.B += (from int n1 in nums
from int n2 in nums
select n1).Count();
}
}
""";
await TestInRegularAndScriptAsync(source, queryOutput, index: 0);
var linqInvocationOutput = """
using System.Collections.Generic;
using System.Linq;
class A { public int B { get; set; }}
class C
{
void M(IEnumerable<int> nums, A a)
{
a.B += nums.SelectMany(n1 => nums.Select(n2 => n1)).Count();
}
}
""";
await TestInRegularAndScriptAsync(source, linqInvocationOutput, index: 1);
}
[Fact]
public async Task CountIQueryableInInvocation()
{
var source = """
using System.Collections.Generic;
using System.Linq;
class C
{
void M(IEnumerable<int> nums)
{
int c = 0;
[|foreach (int n1 in nums.AsQueryable())
{
c++;
}|]
}
}
""";
var queryOutput = """
using System.Collections.Generic;
using System.Linq;
class C
{
void M(IEnumerable<int> nums)
{
int c = (from int n1 in nums.AsQueryable()
select n1).Count();
}
}
""";
await TestInRegularAndScriptAsync(source, queryOutput, index: 0);
var linqInvocationOutput = """
using System.Collections.Generic;
using System.Linq;
class C
{
void M(IEnumerable<int> nums)
{
int c = nums.AsQueryable().Count();
}
}
""";
await TestInRegularAndScriptAsync(source, linqInvocationOutput, index: 1);
}
#endregion
#region Comments
[Fact]
public async Task CommentsYieldReturn()
{
var source = """
using System.Collections.Generic;
using System.Linq;
class C
{
IEnumerable<int> M(IEnumerable<int> nums)
{
[|// 1
foreach /* 2 */( /* 3 */ var /* 4 */ x /* 5 */ in /* 6 */ nums /* 7 */)// 8
{
// 9
/* 10 */
foreach /* 11 */ (/* 12 */ int /* 13 */ y /* 14 */ in /* 15 */ nums /* 16 */)/* 17 */ // 18
{// 19
/*20 */
if /* 21 */(/* 22 */ x > 2 /* 23 */) // 24
{ // 25
/* 26 */
yield /* 27 */ return /* 28 */ x * y /* 29 */; // 30
/* 31 */
}// 32
/* 33 */
} // 34
/* 35 */
}|] /* 36 */
/* 37 */
yield /* 38 */ break/* 39*/; // 40
}
}
""";
var queryOutput = """
using System.Collections.Generic;
using System.Linq;
class C
{
IEnumerable<int> M(IEnumerable<int> nums)
{
return
// 25
// 1
from/* 3 *//* 2 *//* 4 */x /* 5 */ in/* 6 */nums/* 7 */// 8
// 9
/* 10 */
from/* 12 *//* 11 */int /* 13 */ y /* 14 */ in/* 15 */nums/* 16 *//* 17 */// 18
// 19
/*20 */
where/* 21 *//* 22 */x > 2/* 23 */// 24
/* 26 *//* 27 *//* 28 */
select x * y/* 29 *//* 31 */// 32
/* 33 */// 34
/* 35 *//* 36 */// 30
/* 37 *//* 38 *//* 39*/// 40
;
}
}
""";
await TestInRegularAndScriptAsync(source, queryOutput, index: 0);
var linqInvocationOutput = """
using System.Collections.Generic;
using System.Linq;
class C
{
IEnumerable<int> M(IEnumerable<int> nums)
{
return nums /* 7 */.SelectMany(
// 1
/* 2 */// 25
/* 4 */x /* 5 */ => nums /* 16 */.Where(
/*20 *//* 21 */// 19
y =>
/* 22 */x > 2/* 23 */// 24
).Select(
// 9
/* 10 *//* 11 *//* 13 */y /* 14 */ =>
/* 26 *//* 27 *//* 28 */x * y/* 29 *//* 31 */// 32
/* 33 */// 34
/* 35 *//* 36 */// 30
/* 37 *//* 38 *//* 39*/// 40
/* 12 *//* 15 *//* 17 */// 18
)/* 3 *//* 6 */// 8
);
}
}
""";
await TestInRegularAndScriptAsync(source, linqInvocationOutput, index: 1);
}
[Fact]
public async Task CommentsToList()
{
var source = """
using System.Collections.Generic;
using System.Linq;
class C
{
List<int> M(IEnumerable<int> nums)
{
/* 1 */ var /* 2 */ list /* 3 */ = /* 4 */ new List<int>(); // 5
/* 6 */ [|foreach /* 7 */ (/* 8 */ var /* 9 */ x /* 10 */ in /* 11 */ nums /* 12 */) // 13
/* 14 */{ // 15
/* 16 */var /* 17 */ y /* 18 */ = /* 19 */ x + 1 /* 20 */; //21
/* 22 */ list.Add(/* 23 */y /* 24 */) /* 25 */;//26
/*27*/} //28|]
/*29*/return /*30*/ list /*31*/; //32
}
}
""";
var queryOutput = """
using System.Collections.Generic;
using System.Linq;
class C
{
List<int> M(IEnumerable<int> nums)
{
/*29*/
return /*30*/ /* 1 *//* 2 *//* 3 *//* 4 */// 5
/*31*//* 6 */
(from/* 8 *//* 7 *//* 9 */x /* 10 */ in/* 11 */nums/* 12 */// 13
/* 14 */// 15
/* 16 *//* 17 */
let y /* 18 */ = /* 19 */ x + 1/* 20 *///21
select y)/* 24 *//*27*///28
.ToList()/* 22 *//* 23 *//* 25 *///26
; //32
}
}
""";
await TestInRegularAndScriptAsync(source, queryOutput, index: 0);
// No linq refactoring offered due to variable declaration in outermost foreach.
await TestActionCountAsync(source, count: 1);
}
[Fact]
public async Task CommentsToList_02()
{
var source = """
using System.Collections.Generic;
using System.Linq;
class C
{
List<int> M(IEnumerable<int> nums)
{
/* 1 */ var /* 2 */ list /* 3 */ = /* 4 */ new List<int>(); // 5
/* 6 */ [|foreach /* 7 */ (/* 8 */ var /* 9 */ x /* 10 */ in /* 11 */ nums /* 12 */) // 13
/* 14 */{ // 15
/* 16 */
list.Add(/* 17 */ x + 1 /* 18 */) /* 19 */;//20
/*21*/} //22|]
/*23*/return /*24*/ list /*25*/; //26
}
}
""";
var queryOutput = """
using System.Collections.Generic;
using System.Linq;
class C
{
List<int> M(IEnumerable<int> nums)
{
/*23*/
return /*24*/ /* 1 *//* 2 *//* 3 *//* 4 */// 5
/*25*//* 14 */// 15
/* 6 */
(from/* 8 *//* 7 *//* 9 */x /* 10 */ in/* 11 */nums/* 12 */// 13
select x + 1)/* 18 *//*21*///22
.ToList()/* 16 *//* 17 *//* 19 *///20
; //26
}
}
""";
await TestInRegularAndScriptAsync(source, queryOutput, index: 0);
var linqInvocationOutput = """
using System.Collections.Generic;
using System.Linq;
class C
{
List<int> M(IEnumerable<int> nums)
{
/*23*/
return /*24*/ /* 1 *//* 2 *//* 3 *//* 4 */// 5
/*25*/
nums /* 12 */.Select(
/* 6 *//* 7 *//* 14 */// 15
/* 9 */x /* 10 */ => x + 1/* 18 *//*21*///22
/* 8 *//* 11 */// 13
).ToList()/* 16 *//* 17 *//* 19 *///20
; //26
}
}
""";
await TestInRegularAndScriptAsync(source, linqInvocationOutput, index: 1);
}
[Fact]
public async Task CommentsCount()
{
var source = """
using System.Collections.Generic;
using System.Linq;
class C
{
int M(IEnumerable<int> nums)
{
/* 1 */ var /* 2 */ c /* 3 */ = /* 4 */ 0; // 5
/* 6 */ [| foreach /* 7 */ (/* 8 */ var /* 9 */ x /* 10 */ in /* 11 */ nums /* 12 */) // 13
/* 14 */{ // 15
/* 16 */ c++ /* 17 */;//18
/*19*/}|] //20
/*21*/return /*22*/ c /*23*/; //24
}
}
""";
var queryOutput = """
using System.Collections.Generic;
using System.Linq;
class C
{
int M(IEnumerable<int> nums)
{
/*21*/
return /*22*/ /* 1 *//* 2 *//* 3 *//* 4 */// 5
/*23*//* 14 */// 15
/* 6 */
(from/* 8 *//* 7 *//* 9 */x /* 10 */ in/* 11 */nums/* 12 */// 13
select x)/* 10 *//*19*///20
.Count()/* 16 *//* 17 *///18
; //24
}
}
""";
await TestInRegularAndScriptAsync(source, queryOutput, index: 0);
var linqInvocationOutput = """
using System.Collections.Generic;
using System.Linq;
class C
{
int M(IEnumerable<int> nums)
{
/*21*/
return /*22*/ /* 1 *//* 2 *//* 3 *//* 4 */// 5
/*23*/
nums /* 12 *//* 6 *//* 7 *//* 14 */// 15
/* 9 *//* 10 *//* 10 *//*19*///20
/* 8 *//* 11 */// 13
.Count()/* 16 *//* 17 *///18
; //24
}
}
""";
await TestInRegularAndScriptAsync(source, linqInvocationOutput, index: 1);
}
[Fact]
public async Task CommentsDefault()
{
var source = """
using System;
using System.Collections.Generic;
using System.Linq;
class C
{
void M(IEnumerable<int> nums)
{
[|/* 1 */ foreach /* 2 */(int /* 3 */ n1 /* 4 */in /* 5 */ nums /* 6 */)// 7
/* 8*/{// 9
/* 10 */int /* 11 */ a /* 12 */ = /* 13 */ n1 + n1 /* 14*/, /* 15 */ b /*16*/ = /*17*/ n1 * n1/*18*/;//19
/*20*/Console.WriteLine(a + b);//21
/*22*/}/*23*/|]
}
}
""";
var queryOutput = """
using System;
using System.Collections.Generic;
using System.Linq;
class C
{
void M(IEnumerable<int> nums)
{
foreach (var (a /* 12 */ , b /*16*/ ) in
/* 1 */from/* 2 */int /* 3 */ n1 /* 4 */in/* 5 */nums/* 6 */// 7
/* 8*/// 9
/* 10 *//* 11 */
let a /* 12 */ = /* 13 */ n1 + n1/* 14*//* 15 */
let b /*16*/ = /*17*/ n1 * n1/*18*///19
select (a /* 12 */ , b /*16*/ )/*22*//*23*/)
{
/*20*/
Console.WriteLine(a + b);//21
}
}
}
""";
await TestInRegularAndScriptAsync(source, queryOutput, index: 0);
// No linq refactoring offered due to variable declaration(s) in outermost foreach.
await TestActionCountAsync(source, count: 1);
}
[Fact]
public async Task CommentsDefault_02()
{
var source = """
using System;
using System.Collections.Generic;
using System.Linq;
class C
{
void M(IEnumerable<int> nums)
{
[|/* 1 */ foreach /* 2 */(int /* 3 */ n1 /* 4 */in /* 5 */ nums /* 6 */)// 7
/* 8*/{// 9
/* 10 */ if /* 11 */ (/* 12 */ n1 /* 13 */ > /* 14 */ 0/* 15 */ ) // 16
/* 17 */{ // 18
/*19*/Console.WriteLine(n1);//20
/* 21 */} // 22
/*23*/}/*24*/|]
}
}
""";
var queryOutput = """
using System;
using System.Collections.Generic;
using System.Linq;
class C
{
void M(IEnumerable<int> nums)
{
foreach (var n1 /* 4 */in
/* 17 */// 18
/* 1 */from/* 2 */int /* 3 */ n1 /* 4 */in/* 5 */nums/* 6 */// 7
/* 8*/// 9
/* 10 */
where/* 11 *//* 12 */n1 /* 13 */ > /* 14 */ 0/* 15 */// 16
select n1/* 4 *//* 21 */// 22
/*23*//*24*/
)
{
/*19*/
Console.WriteLine(n1);//20
}
}
}
""";
await TestInRegularAndScriptAsync(source, queryOutput, index: 0);
var linqInvocationOutput = """
using System;
using System.Collections.Generic;
using System.Linq;
class C
{
void M(IEnumerable<int> nums)
{
foreach (var n1 /* 4 */in nums /* 6 */.Where(
/* 10 *//* 11 *//* 8*/// 9
n1 =>
/* 12 */n1 /* 13 */ > /* 14 */ 0/* 15 */// 16
)
/* 1 *//* 2 *//* 17 */// 18
/* 3 *//* 4 *//* 4 *//* 21 */// 22
/*23*//*24*//* 5 */// 7
)
{
/*19*/
Console.WriteLine(n1);//20
}
}
}
""";
await TestInRegularAndScriptAsync(source, linqInvocationOutput, index: 1);
}
#endregion
#region Preprocessor directives
[Fact]
public async Task NoConversionPreprocessorDirectives()
{
var source = """
using System.Collections.Generic;
using System.Linq;
class C
{
IEnumerable<int> M(IEnumerable<int> nums)
{
[|foreach(var x in nums)
{
#if (true)
yield return x + 1;
#endif
}|]
}
}
""";
// Cannot convert expressions with preprocessor directives
await TestMissingAsync(source);
}
#endregion
}
|