Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 10 additions & 3 deletions CodeConverter/CSharp/VbNameExpander.cs
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ public SyntaxNode ExpandNode(SyntaxNode node, SemanticModel semanticModel,
semanticModel.GetOperation(node) is IMemberReferenceOperation { Instance: { Syntax: ExpressionSyntax promotedInstance }, Member: {} member }) {
return MemberAccess(promotedInstance, SyntaxFactory.IdentifierName(member.Name));
}
return IsOriginalSymbolGenericMethod(semanticModel, node) ? node : Simplifier.Expand(node, semanticModel, workspace);
return IsOriginalSymbolGenericOrExtensionMethod(semanticModel, node) ? node : Simplifier.Expand(node, semanticModel, workspace);
}

private static bool IsReducedExtensionInExtendedTypeOrDerivedType(SyntaxNode node, ISymbol symbol, SemanticModel semanticModel)
Expand Down Expand Up @@ -136,8 +136,15 @@ public static bool IsRoslynInstanceExpressionBug(MemberAccessExpressionSyntax no
/// Roslyn bug - accidentally expands anonymous types to just "Global."
/// Since the C# reducer also doesn't seem to reduce generic extension methods, it's best to avoid those too, so let's just avoid all generic methods
/// </summary>
private static bool IsOriginalSymbolGenericMethod(SemanticModel semanticModel, SyntaxNode node) =>
semanticModel.GetSymbolInfo(node).Symbol.IsGenericMethod();
private static bool IsOriginalSymbolGenericOrExtensionMethod(SemanticModel semanticModel, SyntaxNode node)
{
var symbolInfo = semanticModel.GetSymbolInfo(node);
var symbol = symbolInfo.Symbol ?? symbolInfo.CandidateSymbols.FirstOrDefault();
if (symbol?.IsGenericMethod() == true) return true;
if (symbol is IMethodSymbol ms && (ms.MethodKind == MethodKind.ReducedExtension || ms.IsExtensionMethod)) return true;
return false;
}


private static bool IsQualifiableInstanceReference(ISymbol symbol) =>
symbol?.IsStatic == false && (symbol.IsKind(SymbolKind.Method) || symbol.IsKind(SymbolKind.Field) ||
Expand Down
53 changes: 53 additions & 0 deletions Tests/CSharp/ExpressionTests/LinqExtensionMethodReproTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
using System.Threading.Tasks;
using Xunit;
using ICSharpCode.CodeConverter.Tests.TestRunners;

namespace ICSharpCode.CodeConverter.Tests.CSharp.ExpressionTests;

public class LinqExtensionMethodReproTests : ConverterTestBase
{
[Fact]
public async Task TestLinqExtensionMethods()
{
await TestConversionVisualBasicToCSharpAsync(@"Imports System.Linq

Public Class TestClass
Public Shared Sub Test()
Dim intCol = New Integer() {1, 2, 3}
Dim intCol2 = New Integer() {1, 2, 3}

Dim intColQuery = intCol.Select(Function(x) x)
Dim intColCopy = intCol.Select(Function(x) x).ToArray()
Dim intSum = intCol.Select(Function(x) x).Sum(Function(x) x)
Dim intMax = intCol.Select(Function(x) x).Max(Function(x) x)
Dim intCnt = intCol.Select(Function(x) x).Count(Function(x) x > 1)

Dim intSum2 = intCol.Select(Function(x) x).Sum()
Dim intMax2 = intCol.OrderBy(Function(x) x).Max()
Dim intCnt2 = intCol.Select(Function(x) x).Count()
Dim intSum3 = intCol.Zip(intCol2, Function(x, y) x + y).Sum()
End Sub
End Class", @"using System;
using System.Linq;

public partial class TestClass
{
public static void Test()
{
int[] intCol = new int[] { 1, 2, 3 };
int[] intCol2 = new int[] { 1, 2, 3 };

var intColQuery = intCol.Select(x => x);
int[] intColCopy = intCol.Select(x => x).ToArray();
int intSum = intCol.Select(x => x).Sum(x => x);
int intMax = intCol.Select(x => x).Max(x => x);
int intCnt = intCol.Select(x => x).Count(x => x > 1);

int intSum2 = intCol.Select(x => x).Sum();
int intMax2 = intCol.OrderBy(x => x).Max();
int intCnt2 = intCol.Select(x => x).Count();
int intSum3 = intCol.Zip(intCol2, (x, y) => x + y).Sum();
}
}");
}
}
Loading