@@ -15,7 +15,7 @@ namespace ICSharpCode.CodeConverter.CSharp;
1515internal partial class ExpressionNodeVisitor : VBasic . VisualBasicSyntaxVisitor < Task < CSharpSyntaxNode > >
1616{
1717 private static readonly Type ConvertType = typeof ( Conversions ) ;
18- private CommentConvertingVisitorWrapper TriviaConvertingExpressionVisitor => CommonConversions . TriviaConvertingExpressionVisitor ;
18+ public CommentConvertingVisitorWrapper TriviaConvertingExpressionVisitor => CommonConversions . TriviaConvertingExpressionVisitor ;
1919 private readonly SemanticModel _semanticModel ;
2020 private readonly HashSet < string > _extraUsingDirectives ;
2121 private readonly IOperatorConverter _operatorConverter ;
@@ -38,7 +38,7 @@ public ExpressionNodeVisitor(SemanticModel semanticModel,
3838 _semanticModel = semanticModel ;
3939 CommonConversions = commonConversions ;
4040 commonConversions . TriviaConvertingExpressionVisitor = new CommentConvertingVisitorWrapper ( this , _semanticModel . SyntaxTree ) ;
41- _lambdaConverter = new LambdaConverter ( commonConversions , semanticModel ) ;
41+ _lambdaConverter = new LambdaConverter ( commonConversions , semanticModel , _withBlockLhs , extraUsingDirectives , typeContext ) ;
4242 _visualBasicEqualityComparison = visualBasicEqualityComparison ;
4343 _queryConverter = new QueryConverter ( commonConversions , _semanticModel , TriviaConvertingExpressionVisitor ) ;
4444 _typeContext = typeContext ;
@@ -80,8 +80,8 @@ public override async Task<CSharpSyntaxNode> DefaultVisit(SyntaxNode node)
8080 public override Task < CSharpSyntaxNode > VisitXmlName ( VBSyntax . XmlNameSyntax node ) => _xmlExpressionConverter . ConvertXmlNameAsync ( node ) ;
8181 public override async Task < CSharpSyntaxNode > VisitSimpleArgument ( VBasic . Syntax . SimpleArgumentSyntax node ) => await _argumentConverter . ConvertSimpleArgumentAsync ( node ) ;
8282 public override async Task < CSharpSyntaxNode > VisitBinaryExpression ( VBasic . Syntax . BinaryExpressionSyntax entryNode ) => await _binaryExpressionConverter . ConvertBinaryExpressionAsync ( entryNode ) ;
83- public override Task < CSharpSyntaxNode > VisitSingleLineLambdaExpression ( VBasic . Syntax . SingleLineLambdaExpressionSyntax node ) => ConvertSingleLineLambdaAsync ( node ) ;
84- public override Task < CSharpSyntaxNode > VisitMultiLineLambdaExpression ( VBasic . Syntax . MultiLineLambdaExpressionSyntax node ) => ConvertMultiLineLambdaAsync ( node ) ;
83+ public override Task < CSharpSyntaxNode > VisitSingleLineLambdaExpression ( VBasic . Syntax . SingleLineLambdaExpressionSyntax node ) => _lambdaConverter . ConvertSingleLineLambdaAsync ( node ) ;
84+ public override Task < CSharpSyntaxNode > VisitMultiLineLambdaExpression ( VBasic . Syntax . MultiLineLambdaExpressionSyntax node ) => _lambdaConverter . ConvertMultiLineLambdaAsync ( node ) ;
8585
8686 public override async Task < CSharpSyntaxNode > VisitGetTypeExpression ( VBasic . Syntax . GetTypeExpressionSyntax node )
8787 {
@@ -513,101 +513,6 @@ private CSharpSyntaxNode ConvertAddressOf(VBSyntax.UnaryExpressionSyntax node, E
513513 }
514514
515515
516-
517- private async Task < CSharpSyntaxNode > ConvertSingleLineLambdaAsync ( VBSyntax . SingleLineLambdaExpressionSyntax node )
518- {
519- var originalIsWithinQuery = TriviaConvertingExpressionVisitor . IsWithinQuery ;
520- TriviaConvertingExpressionVisitor . IsWithinQuery = CommonConversions . IsLinqDelegateExpression ( node ) ;
521- try {
522- return await ConvertInnerAsync ( ) ;
523- } finally {
524- TriviaConvertingExpressionVisitor . IsWithinQuery = originalIsWithinQuery ;
525- }
526-
527- async Task < CSharpSyntaxNode > ConvertInnerAsync ( )
528- {
529- IReadOnlyCollection < StatementSyntax > convertedStatements ;
530- if ( node . Body is VBasic . Syntax . StatementSyntax statement )
531- {
532- convertedStatements = await ConvertMethodBodyStatementsAsync ( statement , statement . Yield ( ) . ToArray ( ) ) ;
533- }
534- else
535- {
536- var csNode = await node . Body . AcceptAsync < ExpressionSyntax > ( TriviaConvertingExpressionVisitor ) ;
537- convertedStatements = new [ ] { SyntaxFactory . ExpressionStatement ( csNode ) } ;
538- }
539-
540- var param = await node . SubOrFunctionHeader . ParameterList . AcceptAsync < ParameterListSyntax > ( TriviaConvertingExpressionVisitor ) ;
541- return await _lambdaConverter . ConvertAsync ( node , param , convertedStatements ) ;
542- }
543- }
544-
545-
546- private async Task < CSharpSyntaxNode > ConvertMultiLineLambdaAsync ( VBSyntax . MultiLineLambdaExpressionSyntax node )
547- {
548- var originalIsWithinQuery = TriviaConvertingExpressionVisitor . IsWithinQuery ;
549- TriviaConvertingExpressionVisitor . IsWithinQuery = CommonConversions . IsLinqDelegateExpression ( node ) ;
550- try {
551- return await ConvertInnerAsync ( ) ;
552- } finally {
553- TriviaConvertingExpressionVisitor . IsWithinQuery = originalIsWithinQuery ;
554- }
555-
556- async Task < CSharpSyntaxNode > ConvertInnerAsync ( )
557- {
558- var body = await ConvertMethodBodyStatementsAsync ( node , node . Statements ) ;
559- var param = await node . SubOrFunctionHeader . ParameterList . AcceptAsync < ParameterListSyntax > ( TriviaConvertingExpressionVisitor ) ;
560- return await _lambdaConverter . ConvertAsync ( node , param , body . ToList ( ) ) ;
561- }
562- }
563-
564- public async Task < IReadOnlyCollection < StatementSyntax > > ConvertMethodBodyStatementsAsync ( VBasic . VisualBasicSyntaxNode node , IReadOnlyCollection < VBSyntax . StatementSyntax > statements , bool isIterator = false , IdentifierNameSyntax csReturnVariable = null )
565- {
566-
567- var innerMethodBodyVisitor = await MethodBodyExecutableStatementVisitor . CreateAsync ( node , _semanticModel , TriviaConvertingExpressionVisitor , CommonConversions , _visualBasicEqualityComparison , _withBlockLhs , _extraUsingDirectives , _typeContext , isIterator , csReturnVariable ) ;
568- return await GetWithConvertedGotosOrNull ( statements ) ?? await ConvertStatements ( statements ) ;
569-
570- async Task < List < StatementSyntax > > ConvertStatements ( IEnumerable < VBSyntax . StatementSyntax > readOnlyCollection )
571- {
572- return ( await readOnlyCollection . SelectManyAsync ( async s => ( IEnumerable < StatementSyntax > ) await s . Accept ( innerMethodBodyVisitor . CommentConvertingVisitor ) ) ) . ToList ( ) ;
573- }
574-
575- async Task < IReadOnlyCollection < StatementSyntax > > GetWithConvertedGotosOrNull ( IReadOnlyCollection < Microsoft . CodeAnalysis . VisualBasic . Syntax . StatementSyntax > statements )
576- {
577- var onlyIdentifierLabel = statements . OnlyOrDefault ( s => s . IsKind ( VBasic . SyntaxKind . LabelStatement ) ) ;
578- var onlyOnErrorGotoStatement = statements . OnlyOrDefault ( s => s . IsKind ( VBasic . SyntaxKind . OnErrorGoToLabelStatement ) ) ;
579-
580- // See https://learn.microsoft.com/en-us/dotnet/visual-basic/language-reference/statements/on-error-statement
581- if ( onlyIdentifierLabel != null && onlyOnErrorGotoStatement != null ) {
582- var statementsList = statements . ToList ( ) ;
583- var onlyIdentifierLabelIndex = statementsList . IndexOf ( onlyIdentifierLabel ) ;
584- var onlyOnErrorGotoStatementIndex = statementsList . IndexOf ( onlyOnErrorGotoStatement ) ;
585-
586- // Even this very simple case can generate compile errors if the error handling uses statements declared in the scope of the try block
587- // For now, the user will have to fix these manually, in future it'd be possible to hoist any used declarations out of the try block
588- if ( onlyOnErrorGotoStatementIndex < onlyIdentifierLabelIndex ) {
589- var beforeStatements = await ConvertStatements ( statements . Take ( onlyOnErrorGotoStatementIndex ) ) ;
590- var tryBlockStatements = await ConvertStatements ( statements . Take ( onlyIdentifierLabelIndex ) . Skip ( onlyOnErrorGotoStatementIndex + 1 ) ) ;
591- var tryBlock = SyntaxFactory . Block ( tryBlockStatements ) ;
592- var afterStatements = await ConvertStatements ( statements . Skip ( onlyIdentifierLabelIndex + 1 ) ) ;
593-
594- var catchClauseSyntax = SyntaxFactory . CatchClause ( ) ;
595-
596- // Default to putting the statements after the catch block in case logic falls through, but if the last statement is a return, put them inside the catch block for neatness.
597- if ( tryBlockStatements . LastOrDefault ( ) . IsKind ( SyntaxKind . ReturnStatement ) ) {
598- catchClauseSyntax = catchClauseSyntax . WithBlock ( SyntaxFactory . Block ( afterStatements ) ) ;
599- afterStatements = new List < StatementSyntax > ( ) ;
600- }
601-
602- var tryStatement = SyntaxFactory . TryStatement ( SyntaxFactory . SingletonList ( catchClauseSyntax ) ) . WithBlock ( tryBlock ) ;
603- return beforeStatements . Append ( tryStatement ) . Concat ( afterStatements ) . ToList ( ) ;
604- }
605- }
606-
607- return null ;
608- }
609- }
610-
611516 public override async Task < CSharpSyntaxNode > VisitParameterList ( VBSyntax . ParameterListSyntax node )
612517 {
613518 var parameters = await node . Parameters . SelectAsync ( async p => await p . AcceptAsync < ParameterSyntax > ( TriviaConvertingExpressionVisitor ) ) ;
@@ -817,8 +722,9 @@ private static InvocationExpressionSyntax Invoke(ExpressionSyntax toInvoke, Expr
817722 ) ;
818723 }
819724
820- private SyntaxToken ConvertIdentifier ( SyntaxToken identifierIdentifier , bool isAttribute = false )
821- {
822- return CommonConversions . ConvertIdentifier ( identifierIdentifier , isAttribute ) ;
823- }
725+ private SyntaxToken ConvertIdentifier ( SyntaxToken identifierIdentifier , bool isAttribute = false ) =>
726+ CommonConversions . ConvertIdentifier ( identifierIdentifier , isAttribute ) ;
727+
728+ public Task < IReadOnlyCollection < StatementSyntax > > ConvertMethodBodyStatementsAsync ( VBasic . VisualBasicSyntaxNode node , IReadOnlyCollection < VBSyntax . StatementSyntax > statements , bool isIterator = false , IdentifierNameSyntax csReturnVariable = null ) =>
729+ _lambdaConverter . ConvertMethodBodyStatementsAsync ( node , statements , isIterator , csReturnVariable ) ;
824730}
0 commit comments