2

I'm trying to replace a statement in code with something else entirely. From:

var results = item.Axes.GetDescendants();

To (something like):

using (var context = ContentSearchManager.GetIndex("someindex").CreateSearchContext())
{
    IQueryable<SearchResultItem> searchQuery = Context.GetQueryable<SearchResultItem>().Where(item => item.Paths.Path.Contains("some arbitrary path"));
}
var results = searchQuery.GetResults();

To do so, I have this task:

context.RegisterCodeFix(
                CodeAction.Create(
                    title: title,
                    equivalenceKey: title,
                    createChangedDocument: c => RemoveDeclarationAsync(context.Document, nodeToRemove, c)
                    ),
                diagnostic);

RemoveDeclarationAsync looks like this:

private async Task<Document> RemoveDeclarationAsync(Document document, SyntaxNode declaration, CancellationToken cancellationToken)
{
    SyntaxNode node = SyntaxFactory.ParseExpression(snippet);

    var syntaxRoot = (await document.GetSyntaxRootAsync());
    var newSyntax = syntaxRoot.ReplaceNode(declaration, node);
    return document.WithSyntaxRoot(newSyntax);
}

snippet is effectively the using statement as a string. declaration is the node to replace. However, when I debug this I get an error message:

Unable to cast object of type 'Microsoft.CodeAnalysis.CSharp.Syntax.IdentifierNameSyntax' to type 'Microsoft.CodeAnalysis.CSharp.Syntax.VariableDeclarationSyntax'.

Even though declaration and node are both defined as SyntaxNode it's not having it, because declaration is a VariableDeclarationSyntax and node is an IdentifierNameSyntax.

If I call ReplaceNode like so:

var newSyntax = syntaxRoot.ReplaceNode((SyntaxNode)declaration, (SyntaxNode)node);

the error goes away, but nothing actually happens, newSyntax is exactly the same as the original syntaxRoot.

How do I get the correct CodeFix for the old statement?

edit

If I use the statement item.Axes.GetDescendants(); instead of the full var results = item.Axes.GetDescendants(); as declaration it starts working. Of course, that's not entirely what I want, because I need the declaration part (var results =) also to be removed...

I've tried inserting the new node before the old one instead using (await document.GetSyntaxRootAsync()).InsertNodesBefore(declaration, listOfOneNode), but that errors out.

Trayek
  • 4,410
  • 3
  • 24
  • 39
  • What does `SyntaxFactory.ParseExpression(snippet)` return to your as a node? And I'm little confused that you try to replace the one Syntax node by two others node using just one `ReplaceNode` method and nothing else... Isntead of try to replace `VariableDeclaratorSyntax` try to replace the corresponding `LocalVariableStatementSyntax` to `UsingStatementSyntax` and then add a other `LocalVariableStatementSyntax`. – George Alexandria Jun 10 '18 at 19:14
  • snippet is defined as that using () statement in the top of my post, as a string - I'm not sure whether that's the right way to do it either.. It's type after ParseExpression is IdentifierNameSyntax. In all honesty, I didn't realize it should've been done by a replace and an add rather than a replace, even if the thing I want to replace it with is 2 statements in one block if that makes sense. – Trayek Jun 11 '18 at 15:32
  • `SyntaxFactory.ParseExpression` can only parse expressions, not statements, and certainly not a sequence of two statements. You can use `SyntaxFactory.ParseStatement` to parse a single statement. – Kris Vandermotten Jun 14 '18 at 15:03

0 Answers0