@@ -684,16 +684,17 @@ public override async Task<CSharpSyntaxNode> VisitMethodBlock(VBSyntax.MethodBlo
684684
685685 /// <summary>
686686 /// In VB, a Char constant can be the default value of a String parameter. In C#, this is invalid.
687- /// Fix: replace the default with null and prepend a null-coalescing assignment in the method body.
687+ /// VisitParameter in ExpressionNodeVisitor sets the default to null for these cases; this method
688+ /// prepends a null-coalescing assignment to restore the char default at runtime.
688689 /// </summary>
689690 private static ( BaseMethodDeclarationSyntax MethodBlock , BlockSyntax ConvertedStatements ) FixCharDefaultsForStringParams (
690691 IMethodSymbol declaredSymbol , BaseMethodDeclarationSyntax methodBlock , BlockSyntax convertedStatements , SemanticModel semanticModel )
691692 {
692693 var prependedStatements = new List < StatementSyntax > ( ) ;
693- var updatedParams = methodBlock . ParameterList . Parameters . ToList ( ) ;
694694 var vbParams = declaredSymbol ? . Parameters ?? ImmutableArray < IParameterSymbol > . Empty ;
695+ var csParams = methodBlock . ParameterList . Parameters ;
695696
696- for ( int i = 0 ; i < updatedParams . Count && i < vbParams . Length ; i ++ ) {
697+ for ( int i = 0 ; i < csParams . Count && i < vbParams . Length ; i ++ ) {
697698 var vbParam = vbParams [ i ] ;
698699 if ( vbParam . Type . SpecialType != SpecialType . System_String
699700 || ! vbParam . HasExplicitDefaultValue ) continue ;
@@ -704,20 +705,17 @@ private static (BaseMethodDeclarationSyntax MethodBlock, BlockSyntax ConvertedSt
704705 if ( defaultValueNode == null ) continue ;
705706 if ( semanticModel . GetTypeInfo ( defaultValueNode ) . Type ? . SpecialType != SpecialType . System_Char ) continue ;
706707
707- var csParam = updatedParams [ i ] ;
708- var defaultExpr = csParam . Default ? . Value ;
709- if ( defaultExpr is null ) continue ;
708+ 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 ) ;
710712
711- // Replace the default value with null
712- updatedParams [ i ] = csParam . WithDefault (
713- CS . SyntaxFactory . EqualsValueClause ( ValidSyntaxFactory . NullExpression ) ) ;
714-
715- // Build: paramName = paramName ?? existingDefaultExpr.ToString();
713+ // Build: paramName = paramName ?? charExpr.ToString();
716714 var paramId = ValidSyntaxFactory . IdentifierName ( csParam . Identifier . ValueText ) ;
717715 var toStringCall = CS . SyntaxFactory . InvocationExpression (
718716 CS . SyntaxFactory . MemberAccessExpression (
719717 CS . SyntaxKind . SimpleMemberAccessExpression ,
720- defaultExpr . WithoutTrivia ( ) ,
718+ charExpr ,
721719 CS . SyntaxFactory . IdentifierName ( "ToString" ) ) ) ;
722720 var coalesce = CS . SyntaxFactory . BinaryExpression ( CS . SyntaxKind . CoalesceExpression , paramId , toStringCall ) ;
723721 var assignment = CS . SyntaxFactory . AssignmentExpression ( CS . SyntaxKind . SimpleAssignmentExpression , paramId , coalesce ) ;
@@ -726,11 +724,18 @@ private static (BaseMethodDeclarationSyntax MethodBlock, BlockSyntax ConvertedSt
726724
727725 if ( prependedStatements . Count == 0 ) return ( methodBlock , convertedStatements ) ;
728726
729- var newParamList = methodBlock . ParameterList . WithParameters ( CS . SyntaxFactory . SeparatedList ( updatedParams , methodBlock . ParameterList . Parameters . GetSeparators ( ) ) ) ;
730- methodBlock = methodBlock . WithParameterList ( newParamList ) ;
731- convertedStatements = convertedStatements . WithStatements ( CS . SyntaxFactory . List ( prependedStatements . Concat ( convertedStatements . Statements ) ) ) ;
727+ return ( methodBlock , convertedStatements . WithStatements ( CS . SyntaxFactory . List ( prependedStatements . Concat ( convertedStatements . Statements ) ) ) ) ;
728+ }
732729
733- return ( methodBlock , convertedStatements ) ;
730+ private static ExpressionSyntax BuildCharExpressionFromVbSyntax ( VBSyntax . ExpressionSyntax defaultValueNode , SemanticModel semanticModel )
731+ {
732+ // For constant char literals (e.g. "^"c), reconstruct directly from the constant value
733+ var constant = semanticModel . GetConstantValue ( defaultValueNode ) ;
734+ if ( constant . HasValue && constant . Value is char c ) {
735+ return CS . SyntaxFactory . LiteralExpression ( CS . SyntaxKind . CharacterLiteralExpression , CS . SyntaxFactory . Literal ( c ) ) ;
736+ }
737+ // For named constant references (e.g. DlM), use the VB expression text as-is
738+ return ValidSyntaxFactory . IdentifierName ( defaultValueNode . ToString ( ) ) ;
734739 }
735740
736741 private static bool IsThisResumeLayoutInvocation ( StatementSyntax s )
0 commit comments