Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

VB -> C#: Query syntax -Linq with multiple groups #298

Open
mrmonday opened this issue Apr 22, 2019 · 3 comments
Open

VB -> C#: Query syntax -Linq with multiple groups #298

mrmonday opened this issue Apr 22, 2019 · 3 comments
Labels
compilation error A bug where the converted output won't compile VB -> C# Specific to VB -> C# conversion

Comments

@mrmonday
Copy link
Contributor

Input code

Public Class Class1
    Sub Foo()
        Dim xs As New List(Of String)
        Dim y = From x In xs Group By x.Length, x.Count() Into Group
    End Sub
End Class

Erroneous output

    public class Class1
    {
        public void Foo()
        {
            List<string> xs = new List<string>();
            ;/* Cannot convert LocalDeclarationStatementSyntax, System.InvalidOperationException: Sequence contains no elements
   at System.Linq.Enumerable.Single[TSource](IEnumerable`1 source)
   at ICSharpCode.CodeConverter.CSharp.QueryConverter.ConvertSubQuery(FromClauseSyntax fromClauseSyntax, QueryClauseSyntax clauseEnd, QueryBodySyntax nestedClause, SyntaxList`1 convertedClauses)
   at ICSharpCode.CodeConverter.CSharp.QueryConverter.ConvertQuerySegments(IEnumerable`1 querySegments, FromClauseSyntax fromClauseSyntax)
   at ICSharpCode.CodeConverter.CSharp.QueryConverter.ConvertClauses(SyntaxList`1 clauses)
   at ICSharpCode.CodeConverter.CSharp.VisualBasicConverter.NodesVisitor.VisitQueryExpression(QueryExpressionSyntax node)
   at Microsoft.CodeAnalysis.VisualBasic.Syntax.QueryExpressionSyntax.Accept[TResult](VisualBasicSyntaxVisitor`1 visitor)
   at Microsoft.CodeAnalysis.VisualBasic.VisualBasicSyntaxVisitor`1.Visit(SyntaxNode node)
   at ICSharpCode.CodeConverter.CSharp.CommentConvertingNodesVisitor.DefaultVisit(SyntaxNode node)
   at Microsoft.CodeAnalysis.VisualBasic.VisualBasicSyntaxVisitor`1.VisitQueryExpression(QueryExpressionSyntax node)
   at Microsoft.CodeAnalysis.VisualBasic.Syntax.QueryExpressionSyntax.Accept[TResult](VisualBasicSyntaxVisitor`1 visitor)
   at ICSharpCode.CodeConverter.CSharp.CommonConversions.ConvertInitializer(VariableDeclaratorSyntax declarator)
   at ICSharpCode.CodeConverter.CSharp.CommonConversions.SplitVariableDeclarations(VariableDeclaratorSyntax declarator, Boolean preferExplicitType)
   at ICSharpCode.CodeConverter.CSharp.VisualBasicConverter.MethodBodyVisitor.VisitLocalDeclarationStatement(LocalDeclarationStatementSyntax node)
   at Microsoft.CodeAnalysis.VisualBasic.Syntax.LocalDeclarationStatementSyntax.Accept[TResult](VisualBasicSyntaxVisitor`1 visitor)
   at Microsoft.CodeAnalysis.VisualBasic.VisualBasicSyntaxVisitor`1.Visit(SyntaxNode node)
   at ICSharpCode.CodeConverter.CSharp.CommentConvertingMethodBodyVisitor.ConvertWithTrivia(SyntaxNode node)
   at ICSharpCode.CodeConverter.CSharp.CommentConvertingMethodBodyVisitor.DefaultVisit(SyntaxNode node)

Input: 
        Dim y = From x In xs Group By x.Length, x.Count() Into Group

 */
        }
    }

Expected output

    public class Class1
    {
        public void Foo()
        {
            List<string> xs = new List<string>();
            // Not 100% that this does the same thing.
            var y = from x in xs group x by new { x.Length, Count = x.Count(), Group = xs.AsEnumerable() };
        }
    }
@GrahamTheCoder GrahamTheCoder added exception caught An exception is caught (and stacktrace provided) VB -> C# Specific to VB -> C# conversion labels Apr 24, 2019
@GrahamTheCoder
Copy link
Member

GrahamTheCoder commented Apr 24, 2019

I'll leave this open for now since its much more specific and achievable than #29
I'd slightly caution against working on this issue in isolation though. There's a collection of very custom code for the query syntax, but really, more careful investigation into how the vb and c# parser deal with it might yield a more general solution.
The main problem I've had, is that I don't understand VB's query syntax. It's a whole language of its own that appears more expressive than C#s version. If we can find a way to turn it into linq method chaining in vb, then convert that, it'd be easier. Either the compiler, or some other library may assist.
Checking what sort of il gets generated would be good start

GrahamTheCoder added a commit that referenced this issue Jan 19, 2020
@GrahamTheCoder
Copy link
Member

GrahamTheCoder commented Jan 19, 2020

I've stopped this throwing an error, but not gone as far as completely fixing it (it'll still be a compile error from the consuming code). The output of the LinqGroupByTwoThingsAnonymously test is now:

using System.Collections.Generic;
using System.Linq;

public partial class Class1
{
    public void Foo()
    {
        var xs = new List<string>();
        var y = from x in xs
                group x by new { x.Length, Count = x.Count() };
    }
}

but I think should be

using System.Collections.Generic;
using System.Linq;

public partial class Class1
{
    public void Foo()
    {
        var xs = new List<string>();
        var y = from x in xs
                group x by new { x.Length, Count = x.Count() } into g
                select new { Length = g.Key.Length, Count = g.Key.Count, Group = g.AsEnumerable() };
    }
}

@GrahamTheCoder GrahamTheCoder added compilation error A bug where the converted output won't compile and removed exception caught An exception is caught (and stacktrace provided) labels Mar 20, 2020
@GrahamTheCoder GrahamTheCoder modified the milestone: When more users request Mar 20, 2020
@jrmoreno1
Copy link
Contributor

Exact opposite error message (no elements versus more than one), but it might be related.

Cannot convert QueryExpressionSyntax, System.InvalidOperationException: Sequence contains more than one element
at System.Linq.Enumerable.Single[TSource](IEnumerable1 source) at ICSharpCode.CodeConverter.CSharp.QueryConverter.<ConvertSubQueryAsync>d__15.MoveNext() --- End of stack trace from previous location where exception was thrown --- at ICSharpCode.CodeConverter.CSharp.QueryConverter.<ConvertQueryWithContinuationAsync>d__14.MoveNext() --- End of stack trace from previous location where exception was thrown --- at ICSharpCode.CodeConverter.CSharp.QueryConverter.<ConvertQueryWithContinuationsAsync>d__13.MoveNext() --- End of stack trace from previous location where exception was thrown --- at ICSharpCode.CodeConverter.CSharp.QueryConverter.<ConvertQuerySegmentsAsync>d__11.MoveNext() --- End of stack trace from previous location where exception was thrown --- at ICSharpCode.CodeConverter.CSharp.QueryConverter.<ConvertClausesAsync>d__6.MoveNext() --- End of stack trace from previous location where exception was thrown --- at ICSharpCode.CodeConverter.CSharp.ExpressionNodeVisitor.<VisitQueryExpression>d__70.MoveNext() --- End of stack trace from previous location where exception was thrown --- at ICSharpCode.CodeConverter.CSharp.CommentConvertingVisitorWrapper.<ConvertHandledAsync>d__81.MoveNext()

Dim gridDataSource = (From p In _Parent
Join pt In _ParentType On pt.parentId Equals p.parentId
Group p By key = p.parentId, desc = p.ParentTypeDesc, sequence = pt.Sequence Into Group
Select New With {.parentId = key,
.ParentTypeDesc = desc,
.Sequence = sequence}).OrderBy(Function(c) c.Sequence)

@GrahamTheCoder GrahamTheCoder changed the title VB -> C#: Linq with multiple groups VB -> C#: Query syntax -Linq with multiple groups Aug 4, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
compilation error A bug where the converted output won't compile VB -> C# Specific to VB -> C# conversion
Projects
None yet
Development

No branches or pull requests

3 participants