static void Analyze(SyntaxNodeAnalysisContext context) { var typeDecl = (TypeDeclarationSyntax)context.Node; var semanticModel = context.SemanticModel; var typeSymbol = semanticModel.GetDeclaredSymbol(typeDecl); if (typeSymbol == null || typeSymbol.IsAbstract || typeSymbol.IsStatic) { return; } var varMembers = new VariableMemberCollector(semanticModel).Collect(typeDecl); if (varMembers.All(v => v.HasInitializer)) { return; } var languageVersion = (typeDecl.SyntaxTree.Options as CSharpParseOptions)?.LanguageVersion ?? LanguageVersion.CSharp6; var factory = new MySyntaxFactory(languageVersion); factory.FixCompleteConstructor(semanticModel, typeDecl, varMembers, out var constructorDecl, out var fix); if (constructorDecl != null && fix != null && constructorDecl.Identifier != null && typeDecl.Identifier != null ) { context.ReportDiagnostic( Diagnostic.Create( DiagnosticProvider.CompleteConstructorFix, constructorDecl.Identifier.GetLocation(), typeDecl.Identifier.Text )); } }
public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context) { var document = context.Document; var ct = context.CancellationToken; var diagnostic = context.Diagnostics.FirstOrDefault(); if (diagnostic == null) { return; } var diagnosticSpan = diagnostic.Location.SourceSpan; var root = await document.GetSyntaxRootAsync(ct).ConfigureAwait(false); if (root == null) { return; } var semanticModel = await document.GetSemanticModelAsync(ct); if (semanticModel == null) { return; } var typeDecl = root .FindToken(diagnosticSpan.Start) .Parent .AncestorsAndSelf() .OfType <TypeDeclarationSyntax>() .FirstOrDefault(); if (typeDecl == null) { return; } var tree = typeDecl.SyntaxTree; var typeSymbol = semanticModel.GetDeclaredSymbol(typeDecl, ct); if (typeSymbol == null) { return; } var varMembers = new VariableMemberCollector(semanticModel).Collect(typeDecl); var languageVersion = (tree.Options as CSharpParseOptions)?.LanguageVersion ?? LanguageVersion.CSharp6; var factory = new MySyntaxFactory(languageVersion); factory.FixCompleteConstructor(semanticModel, typeDecl, varMembers, out var constructorDecl, out var fix); if (constructorDecl != null && fix != null) { context.RegisterCodeFix( CodeAction.Create( diagnostic.Descriptor.Title.ToString(), async _ => document.WithSyntaxRoot( root.ReplaceNode( constructorDecl, fix() )), equivalenceKey: diagnostic.Id ), diagnostic ); } }
public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context) { var diagnostic = context.Diagnostics.FirstOrDefault(); if (diagnostic == null) { return; } var document = context.Document; var ct = context.CancellationToken; var root = await document.GetSyntaxRootAsync(ct).ConfigureAwait(false); if (root == null) { return; } var typeDecl = root .FindToken(diagnostic.Location.SourceSpan.Start) .Parent .AncestorsAndSelf() .OfType <TypeDeclarationSyntax>() .FirstOrDefault(); if (typeDecl == null) { return; } var semanticModel = await document.GetSemanticModelAsync(ct); if (semanticModel == null) { return; } // Generate fixing method. var varMembers = new VariableMemberCollector(semanticModel).Collect(typeDecl); if (varMembers.All(m => m.HasInitializer)) { return; } var languageVersion = (typeDecl.SyntaxTree.Options as CSharpParseOptions)?.LanguageVersion ?? LanguageVersion.CSharp6; var factory = new MySyntaxFactory(languageVersion); async Task <Document> FixAsync() { var constructor = factory.CompleteConstructor(semanticModel, typeDecl, varMembers); return (document.WithSyntaxRoot( root.ReplaceNode( typeDecl, typeDecl.AddMembers(constructor) ))); } context.RegisterCodeFix( CodeAction.Create( diagnostic.Descriptor.Title.ToString(), _ => FixAsync(), equivalenceKey: diagnostic.Id ), diagnostic ); }