1

I'm playing with Roslyn analyzers and Codefixes. In my scenario I wan't to have every domain class should have an according builder in another project.

The diagnostic part was no problem but now I struggle with the codefix. That is what I have so far:

The registration of the codefix (works)

public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context) {
        var root = await context.Document.GetSyntaxRootAsync(context.CancellationToken).ConfigureAwait(false);

        var diagnostic = context.Diagnostics.First();
        var diagnosticSpan = diagnostic.Location.SourceSpan;

        // Find the type declaration identified by the diagnostic.
        var declaration = root.FindToken(diagnosticSpan.Start).Parent.AncestorsAndSelf().OfType<TypeDeclarationSyntax>().First();

        var equivalenceKey = "CreateTestDataBuilder";
        var codeAction = CodeAction.Create(equivalenceKey, c => CreateTestDataBuilderAsync(context.Document, declaration, c), equivalenceKey: equivalenceKey);
        context.RegisterCodeFix(codeAction, diagnostic);    
}

The codeaction to create the document (crashes)

private async Task<Solution> CreateTestDataBuilderAsync(Document contextDocument, TypeDeclarationSyntax declaration, CancellationToken cancellationToken) {
        Project contextDocumentProject = contextDocument.Project;
        Solution solution = contextDocumentProject.Solution;
        Project testProject = solution.Projects.FirstOrDefault(p => p.Name == contextDocument.Project.Name + ".Test");
        if (testProject == null) {
            return solution;
        }

        var semanticModel = await contextDocument.GetSemanticModelAsync(cancellationToken);
        var typeSymbol = semanticModel.GetDeclaredSymbol(declaration, cancellationToken);

        string[] folders = new[] { "src/Builders" };
        Document testDataBuilderDocument = testProject.AddDocument(typeSymbol + "Builder.cs", SourceText.From(string.Format(TestDataBuilderTemplate, typeSymbol.Name)), folders);

        bool result = solution.Workspace.TryApplyChanges(solution);

        return solution;
}

I think I dont got the idea of how to manipulate the solution with codefixes. Any help?

Tobias
  • 2,945
  • 5
  • 41
  • 59

0 Answers0