@@ -93,7 +93,7 @@ public async Task<CSharpSyntaxNode> ConvertClausesAsync(SyntaxList<VBSyntax.Quer
9393 new Queue < ( SyntaxList < CSSyntax . QueryClauseSyntax > , VBSyntax . QueryClauseSyntax ) > ( ) ;
9494 while ( vbBodyClauses . Any ( ) && ! RequiresMethodInvocation ( vbBodyClauses . Peek ( ) ) ) {
9595 var convertedClauses = new List < CSSyntax . QueryClauseSyntax > ( ) ;
96- while ( vbBodyClauses . Any ( ) && ! RequiredContinuation ( vbBodyClauses . Peek ( ) ) ) {
96+ while ( vbBodyClauses . Any ( ) && ! RequiredContinuation ( vbBodyClauses . Peek ( ) , vbBodyClauses . Count - 1 ) ) {
9797 convertedClauses . Add ( await ConvertQueryBodyClauseAsync ( vbBodyClauses . Dequeue ( ) ) ) ;
9898 }
9999
@@ -233,11 +233,11 @@ private static bool RequiresMethodInvocation(VBSyntax.QueryClauseSyntax queryCla
233233 || queryClauseSyntax is VBSyntax . DistinctClauseSyntax ;
234234 }
235235
236- private static bool RequiredContinuation ( VBSyntax . QueryClauseSyntax queryClauseSyntax )
237- {
238- return queryClauseSyntax is VBSyntax . GroupByClauseSyntax
239- || queryClauseSyntax is VBSyntax . SelectClauseSyntax ;
240- }
236+ /// <summary>
237+ /// In VB, multiple selects work like Let clauses, but the last one needs to become the actual select (its name is discarded)
238+ /// </summary>
239+ private static bool RequiredContinuation ( VBSyntax . QueryClauseSyntax queryClauseSyntax , int clausesAfter ) => queryClauseSyntax is VBSyntax . GroupByClauseSyntax
240+ || queryClauseSyntax is VBSyntax . SelectClauseSyntax sc && ( sc . Variables . Any ( v => v . NameEquals is null ) || clausesAfter == 0 ) ;
241241
242242 private async Task < CSSyntax . FromClauseSyntax > ConvertFromClauseSyntaxAsync ( VBSyntax . FromClauseSyntax vbFromClause )
243243 {
@@ -284,20 +284,19 @@ private static CSSyntax.SelectClauseSyntax CreateDefaultSelectClause(SyntaxToken
284284 return SyntaxFactory . SelectClause ( SyntaxFactory . IdentifierName ( reusableCsFromId ) ) ;
285285 }
286286
287- private async Task < CSSyntax . QueryClauseSyntax > ConvertQueryBodyClauseAsync ( VBSyntax . QueryClauseSyntax node )
287+ private Task < CSSyntax . QueryClauseSyntax > ConvertQueryBodyClauseAsync ( VBSyntax . QueryClauseSyntax node )
288288 {
289- return await node
290- . TypeSwitch < VBSyntax . QueryClauseSyntax , VBSyntax . FromClauseSyntax , VBSyntax . JoinClauseSyntax ,
291- VBSyntax . LetClauseSyntax , VBSyntax . OrderByClauseSyntax , VBSyntax . WhereClauseSyntax ,
292- Task < CSSyntax . QueryClauseSyntax > > (
293- //(VBSyntax.AggregateClauseSyntax ags) => null,
294- async syntax => ( CSSyntax . QueryClauseSyntax ) await ConvertFromClauseSyntaxAsync ( syntax ) ,
295- ConvertJoinClauseAsync ,
296- ConvertLetClauseAsync ,
297- ConvertOrderByClauseAsync ,
298- ConvertWhereClauseAsync ,
299- _ => throw new NotImplementedException (
300- $ "Conversion for query clause with kind '{ node . Kind ( ) } ' not implemented") ) ;
289+ return node switch {
290+ VBSyntax . FromClauseSyntax x => ConvertFromQueryClauseSyntaxAsync ( x ) ,
291+ VBSyntax . JoinClauseSyntax x => ConvertJoinClauseAsync ( x ) ,
292+ VBSyntax . SelectClauseSyntax x => ConvertSelectClauseAsync ( x ) ,
293+ VBSyntax . LetClauseSyntax x => ConvertLetClauseAsync ( x ) ,
294+ VBSyntax . OrderByClauseSyntax x => ConvertOrderByClauseAsync ( x ) ,
295+ VBSyntax . WhereClauseSyntax x => ConvertWhereClauseAsync ( x ) ,
296+ _ => throw new NotImplementedException ( $ "Conversion for query clause with kind '{ node . Kind ( ) } ' not implemented")
297+ } ;
298+
299+ async Task < CSSyntax . QueryClauseSyntax > ConvertFromQueryClauseSyntaxAsync ( VBSyntax . FromClauseSyntax x ) => await ConvertFromClauseSyntaxAsync ( x ) ;
301300 }
302301
303302 private async Task < CSSyntax . ExpressionSyntax > GetGroupExpressionAsync ( VBSyntax . GroupByClauseSyntax gs )
@@ -337,6 +336,13 @@ private IEnumerable<string> GetGroupKeyIdentifiers(VBSyntax.GroupByClauseSyntax
337336 return SyntaxFactory . WhereClause ( await ws . Condition . AcceptAsync < CSSyntax . ExpressionSyntax > ( _triviaConvertingVisitor ) ) ;
338337 }
339338
339+ private async Task < CSSyntax . QueryClauseSyntax > ConvertSelectClauseAsync ( VBSyntax . SelectClauseSyntax sc )
340+ {
341+ var singleVariable = sc . Variables . Single ( ) ;
342+ var identifier = CommonConversions . ConvertIdentifier ( singleVariable . NameEquals . Identifier . Identifier ) ;
343+ return SyntaxFactory . LetClause ( identifier , await singleVariable . Expression . AcceptAsync < CSSyntax . ExpressionSyntax > ( _triviaConvertingVisitor ) ) ;
344+ }
345+
340346 private async Task < CSSyntax . QueryClauseSyntax > ConvertLetClauseAsync ( VBSyntax . LetClauseSyntax ls )
341347 {
342348 var singleVariable = ls . Variables . Single ( ) ;
0 commit comments