Skip to content

Commit 0a367c4

Browse files
committed
Simplify: use existing expression visitor instead of VbNameExprToCsExpr
Replace the hand-rolled VbNameExprToCsExpr/BuildCharExpressionFromVbSyntax static helpers with a call to the existing expression visitor (_triviaConvertingExpressionVisitor) via AcceptAsync. This handles all VB expression types uniformly without a verbose manual switch. https://claude.ai/code/session_01AkwUvu3XuCdj3D4axoX4UX
1 parent 5c8966e commit 0a367c4

1 file changed

Lines changed: 6 additions & 42 deletions

File tree

CodeConverter/CSharp/DeclarationNodeVisitor.cs

Lines changed: 6 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)