Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
79 views
in Technique[技术] by (71.8m points)

c# - Get symbol info from new node

I have a CSharpSyntaxRewriter that overrides VisitMemberAccessExpression, inside that method, I am calling MemberAccessExpressionSyntax.WithName(), but the node it returns has a different SyntaxTree compared to the original node, this is a problem since it means an error is thrown when calling SemanticModel.GetSymbolInfo(node).

Is there a way to change the Name of a MemberAccessExpressionSyntax but still have a SyntaxTree that works with SemanticModel.GetSymbolInfo(node)?

My code is:

public sealed override SyntaxNode VisitNode(SyntaxNode node)
{
    var nodeSyntax = (MemberAccessExpressionSyntax) node;
    if (nodeSyntax.Name.ToString() == OldModifier && !HasSymbol(nodeSyntax, out _))
    {
        if (ModifierType == ModifierType.Damage)
            nodeSyntax = nodeSyntax.WithName(IdentifierName($"GetDamage({NewModifier})"));
        else
            nodeSyntax = nodeSyntax.WithName(IdentifierName($"GetCritChance({NewModifier})"));

        nodeSyntax = nodeSyntax.WithLeadingTrivia(node.GetLeadingTrivia()).WithTrailingTrivia(node.GetTrailingTrivia());
    }

    return nodeSyntax;
}

(VisitNode is called from VisitMemberAccessExpression)

And here are images showing the difference in the SyntaxTree: original: original node After calling WithName: modified node

question from:https://stackoverflow.com/questions/65929197/get-symbol-info-from-new-node

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

There's a few ways to approach something like this:

Change Your Visit Method

Can you restructure your code to call VisitNode before you've done any changes to VisitMemberAccessExpression? For example can you go from:

var memberAccess = memberAccess.With...();
memberAccess = VisitNode(memberAccess);
return memberAccess;

to

var memberAccess = VisitNode(memberAccess);
memberAccess = memberAccess.With...();
return memberAccess;

Then it might mean that you are then visiting with the original node before you've done rewriting. Note this can still be tricky though if you are doing recursive stuff.

Use ReplaceNodes

There's a helper method you can use instead of a rewriter. This will call the function you pass to do rewriting at each step, but that function is handed both the original node in the original tree and the node after child nodes have been rewritten; you can use the original one to ask binding questions (since that's from the original tree) and consume the one that's been rewritten for recursive rewriting.

Break Your Problem into Two Steps

Do two walks: first get a list of all the places will need to update, add those SyntaxNodes to a HashSet or like, and then do the rewrite second where you are updating those places.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...