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
187 views
in Technique[技术] by (71.8m points)

c# - How do I create a new root by adding and removing nodes retrieved from the old root?

I am creating a Code Fix that changes this:

if(obj is MyClass)
{
    var castedObj = obj as MyClass;
}

into this:

var castedObj = obj as MyClass;
if(castedObj != null)
{
}

This means I have to do 3 things:

  • Change the condition in the if statement.
  • Move the casting right above the if statement.
  • Remove the statement in the body.

So far, all my attempts have stranded me at getting at most 2 of these things to work.

I believe this problem occurs because you basically have 2 syntax nodes on the same level. As such, making a change to one of them invalidates the location of the other one. Or something like that. Long story short: I either manage to copy the variable assignment outside the if statement, or I manage to change the condition + remove the variable assignment. Never all 3.

How would I solve this?

For good measure, here is my code which changes the condition and removes the assignment:

var newIfStatement = ifStatement.RemoveNode(
                                   variableDeclaration,
                                   SyntaxRemoveOptions.KeepExteriorTrivia);
newIfStatement = newIfStatement.ReplaceNode(newIfStatement.Condition, newCondition);

var ifParent = ifStatement.Parent;
var newParent = ifParent.ReplaceNode(ifStatement, newIfStatement);
newParent = newParent.InsertNodesBefore(
                           newIfStatement, 
                           new[] { variableDeclaration })
                           .WithAdditionalAnnotations(Formatter.Annotation);

var newRoot = root.ReplaceNode(ifParent, newParent);
See Question&Answers more detail:os

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

1 Reply

0 votes
by (71.8m points)

Have you looked at the DocumentEditor class ? It is very useful when dealing with modifying syntax, especially when the changes that are applied to the tree might cause invalidation problems. The operations are pretty much the same as the ones you already have defined, just use the DocumentEditor methods instead and see if that helps. I can't verify if that solves your problem ATM, but I think it solved the a similar problem for me once in the past. I'll test it out later if I can.

Something like this will do it:

var editor = await DocumentEditor.CreateAsync(document);
editor.RemoveNode(variableDeclaration);
editor.ReplaceNode(ifStatement.Condition, newCondition);
editor.InsertBefore(ifStatement, 
     new[] { variableDeclaration.WithAdditionalAnnotations(Formatter.Annotation) });

var newDocument = editor.GetChangedDocument();

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

...