@@ -675,7 +675,7 @@ public override async Task<CSharpSyntaxNode> VisitMethodBlock(VBSyntax.MethodBlo
675675 convertedStatements = convertedStatements . InsertNodesBefore ( firstResumeLayout , _typeContext . HandledEventsAnalysis . GetInitializeComponentClassEventHandlers ( ) ) ;
676676 }
677677
678- ( methodBlock , convertedStatements ) = FixCharDefaultsForStringParams ( declaredSymbol , methodBlock , convertedStatements , _semanticModel ) ;
678+ ( methodBlock , convertedStatements ) = await FixCharDefaultsForStringParamsAsync ( declaredSymbol , methodBlock , convertedStatements , _semanticModel , _triviaConvertingExpressionVisitor ) ;
679679
680680 var body = _accessorDeclarationNodeConverter . WithImplicitReturnStatements ( node , convertedStatements , csReturnVariableOrNull ) ;
681681
@@ -687,8 +687,9 @@ public override async Task<CSharpSyntaxNode> VisitMethodBlock(VBSyntax.MethodBlo
687687 /// VisitParameter in ExpressionNodeVisitor sets the default to null for these cases; this method
688688 /// prepends a null-coalescing assignment to restore the char default at runtime.
689689 /// </summary>
690- private static ( BaseMethodDeclarationSyntax MethodBlock , BlockSyntax ConvertedStatements ) FixCharDefaultsForStringParams (
691- IMethodSymbol declaredSymbol , BaseMethodDeclarationSyntax methodBlock , BlockSyntax convertedStatements , SemanticModel semanticModel )
690+ private static async Task < ( BaseMethodDeclarationSyntax MethodBlock , BlockSyntax ConvertedStatements ) > FixCharDefaultsForStringParamsAsync (
691+ IMethodSymbol declaredSymbol , BaseMethodDeclarationSyntax methodBlock , BlockSyntax convertedStatements , SemanticModel semanticModel ,
692+ CommentConvertingVisitorWrapper expressionVisitor )
692693 {
693694 var prependedStatements = new List < StatementSyntax > ( ) ;
694695 var vbParams = declaredSymbol ? . Parameters ?? ImmutableArray < IParameterSymbol > . Empty ;
@@ -700,15 +701,13 @@ private static (BaseMethodDeclarationSyntax MethodBlock, BlockSyntax ConvertedSt
700701 || ! vbParam . HasExplicitDefaultValue ) continue ;
701702 // ExplicitDefaultValue is normalized to the parameter's declared type (String), so we
702703 // must inspect the VB syntax to detect when the original expression is Char-typed.
703- var vbSyntaxParam = vbParam . DeclaringSyntaxReferences . FirstOrDefault ( ) ? . GetSyntax ( ) as VBSyntax . ParameterSyntax ;
704+ var vbSyntaxParam = await vbParam . DeclaringSyntaxReferences . FirstOrDefault ( ) ? . GetSyntaxAsync ( ) as VBSyntax . ParameterSyntax ;
704705 var defaultValueNode = vbSyntaxParam ? . Default ? . Value ;
705706 if ( defaultValueNode == null ) continue ;
706707 if ( semanticModel . GetTypeInfo ( defaultValueNode ) . Type ? . SpecialType != SpecialType . System_Char ) continue ;
707708
708709 var csParam = csParams [ i ] ;
709- // The default was set to null at point of creation in VisitParameter (ExpressionNodeVisitor).
710- // Reconstruct the char expression from VB syntax to avoid depending on the already-converted value.
711- var charExpr = BuildCharExpressionFromVbSyntax ( defaultValueNode , semanticModel ) ;
710+ var charExpr = await defaultValueNode . AcceptAsync < ExpressionSyntax > ( expressionVisitor ) ;
712711
713712 // Build: paramName = paramName ?? charExpr.ToString();
714713 var paramId = ValidSyntaxFactory . IdentifierName ( csParam . Identifier . ValueText ) ;
@@ -727,41 +726,6 @@ private static (BaseMethodDeclarationSyntax MethodBlock, BlockSyntax ConvertedSt
727726 return ( methodBlock , convertedStatements . WithStatements ( CS . SyntaxFactory . List ( prependedStatements . Concat ( convertedStatements . Statements ) ) ) ) ;
728727 }
729728
730- private static ExpressionSyntax BuildCharExpressionFromVbSyntax ( VBSyntax . ExpressionSyntax defaultValueNode , SemanticModel semanticModel )
731- {
732- // For char literal expressions (e.g. "^"c), use the constant value directly
733- if ( defaultValueNode . IsKind ( VBasic . SyntaxKind . CharacterLiteralExpression ) ) {
734- var constant = semanticModel . GetConstantValue ( defaultValueNode ) ;
735- if ( constant . HasValue && constant . Value is char c )
736- return CS . SyntaxFactory . LiteralExpression ( CS . SyntaxKind . CharacterLiteralExpression , CS . SyntaxFactory . Literal ( c ) ) ;
737- }
738- return VbNameExprToCsExpr ( defaultValueNode ) ;
739- }
740-
741- private static ExpressionSyntax VbNameExprToCsExpr ( VBSyntax . ExpressionSyntax vbExpr )
742- {
743- switch ( vbExpr ) {
744- case VBSyntax . IdentifierNameSyntax identifier :
745- return CS . SyntaxFactory . IdentifierName ( identifier . Identifier . Text ) ;
746- case VBSyntax . MemberAccessExpressionSyntax memberAccess :
747- // Skip VB's "Global." qualifier — it's VB's global namespace prefix, has no direct C# identifier equivalent
748- if ( memberAccess . Expression . IsKind ( VBasic . SyntaxKind . GlobalName ) )
749- return CS . SyntaxFactory . IdentifierName ( memberAccess . Name . Identifier . Text ) ;
750- return CS . SyntaxFactory . MemberAccessExpression ( CS . SyntaxKind . SimpleMemberAccessExpression ,
751- VbNameExprToCsExpr ( memberAccess . Expression ) ,
752- CS . SyntaxFactory . IdentifierName ( memberAccess . Name . Identifier . Text ) ) ;
753- case VBSyntax . QualifiedNameSyntax qualifiedName :
754- // Qualified names (e.g. Global.TestModule) appear in name/type context within default values
755- if ( qualifiedName . Left . IsKind ( VBasic . SyntaxKind . GlobalName ) )
756- return CS . SyntaxFactory . IdentifierName ( qualifiedName . Right . Identifier . Text ) ;
757- return CS . SyntaxFactory . MemberAccessExpression ( CS . SyntaxKind . SimpleMemberAccessExpression ,
758- VbNameExprToCsExpr ( qualifiedName . Left ) ,
759- CS . SyntaxFactory . IdentifierName ( qualifiedName . Right . Identifier . Text ) ) ;
760- default :
761- throw new NotSupportedException ( $ "Unexpected VB expression in char default value: { vbExpr } ") ;
762- }
763- }
764-
765729 private static bool IsThisResumeLayoutInvocation ( StatementSyntax s )
766730 {
767731 return s is ExpressionStatementSyntax ess && ess . Expression is InvocationExpressionSyntax ies && ies . Expression . ToString ( ) . Equals ( "this.ResumeLayout" , StringComparison . Ordinal ) ;
0 commit comments