コード例 #1
0
        public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context)
        {
            Document document = context.Document;

            CodeAnalysis.Text.TextSpan span = context.Span;
            CancellationToken          cancellationToken = context.CancellationToken;

            cancellationToken.ThrowIfCancellationRequested();
            SyntaxNode root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false);

            ClassDeclarationSyntax classDeclaration = root.FindToken(span.Start).Parent?.FirstAncestorOrSelf <ClassDeclarationSyntax>();

            if (classDeclaration != null)
            {
                var codeAction = new MyCodeAction(MicrosoftApiDesignGuidelinesAnalyzersResources.MakeClassStatic,
                                                  async ct => await MakeClassStatic(document, classDeclaration, ct).ConfigureAwait(false));
                context.RegisterCodeFix(codeAction, context.Diagnostics);
            }
        }
        public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context)
        {
            Document document = context.Document;

            CodeAnalysis.Text.TextSpan span = context.Span;
            CancellationToken          cancellationToken = context.CancellationToken;

            cancellationToken.ThrowIfCancellationRequested();
            SyntaxNode root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false);

            ClassDeclarationSyntax?classDeclaration = root.FindToken(span.Start).Parent?.FirstAncestorOrSelf <ClassDeclarationSyntax>();

            if (classDeclaration != null)
            {
                string title      = MicrosoftCodeQualityAnalyzersResources.MakeClassStatic;
                var    codeAction = CodeAction.Create(title,
                                                      async ct => await MakeClassStaticAsync(document, classDeclaration, ct).ConfigureAwait(false),
                                                      equivalenceKey: title);
                context.RegisterCodeFix(codeAction, context.Diagnostics);
            }
        }
        private static async Task <Document> AddConstructorsAsync(Document document, IEnumerable <Diagnostic> diagnostics, SyntaxNode root, CancellationToken cancellationToken)
        {
            DocumentEditor editor = await DocumentEditor.CreateAsync(document, cancellationToken).ConfigureAwait(false);

            SyntaxGenerator generator = editor.Generator;
            SemanticModel   model     = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);

            CodeAnalysis.Text.TextSpan diagnosticSpan = diagnostics.First().Location.SourceSpan; // All the diagnostics are reported at the same location -- the name of the declared class -- so it doesn't matter which one we pick
            SyntaxNode node       = root.FindNode(diagnosticSpan);
            SyntaxNode targetNode = editor.Generator.GetDeclaration(node, DeclarationKind.Class);

            if (model.GetDeclaredSymbol(targetNode, cancellationToken) is not INamedTypeSymbol typeSymbol)
            {
                return(document);
            }

            foreach (Diagnostic diagnostic in diagnostics)
            {
                var missingCtorSignature = (ImplementStandardExceptionConstructorsAnalyzer.MissingCtorSignature)Enum.Parse(typeof(ImplementStandardExceptionConstructorsAnalyzer.MissingCtorSignature), diagnostic.Properties["Signature"]);

                switch (missingCtorSignature)
                {
                case ImplementStandardExceptionConstructorsAnalyzer.MissingCtorSignature.CtorWithNoParameter:
                    // Add missing CtorWithNoParameter
                    SyntaxNode newConstructorNode1 = generator.ConstructorDeclaration(typeSymbol.Name, accessibility: Accessibility.Public);
                    editor.AddMember(targetNode, newConstructorNode1);
                    break;

                case ImplementStandardExceptionConstructorsAnalyzer.MissingCtorSignature.CtorWithStringParameter:
                    // Add missing CtorWithStringParameter
                    SyntaxNode newConstructorNode2 = generator.ConstructorDeclaration(
                        containingTypeName: typeSymbol.Name,
                        parameters: new[]
                    {
                        generator.ParameterDeclaration("message", generator.TypeExpression(editor.SemanticModel.Compilation.GetSpecialType(SpecialType.System_String)))
                    },
                        accessibility: Accessibility.Public,
                        baseConstructorArguments: new[]
                    {
                        generator.Argument(generator.IdentifierName("message"))
                    });
                    editor.AddMember(targetNode, newConstructorNode2);
                    break;

                case ImplementStandardExceptionConstructorsAnalyzer.MissingCtorSignature.CtorWithStringAndExceptionParameters:
                    // Add missing CtorWithStringAndExceptionParameters
                    SyntaxNode newConstructorNode3 = generator.ConstructorDeclaration(
                        containingTypeName: typeSymbol.Name,
                        parameters: new[]
                    {
                        generator.ParameterDeclaration("message", generator.TypeExpression(editor.SemanticModel.Compilation.GetSpecialType(SpecialType.System_String))),
                        generator.ParameterDeclaration("innerException", generator.TypeExpression(editor.SemanticModel.Compilation.GetOrCreateTypeByMetadataName(WellKnownTypeNames.SystemException)))
                    },
                        accessibility: Accessibility.Public,
                        baseConstructorArguments: new[]
                    {
                        generator.Argument(generator.IdentifierName("message")),
                        generator.Argument(generator.IdentifierName("innerException"))
                    });
                    editor.AddMember(targetNode, newConstructorNode3);
                    break;
                }
            }

            return(editor.GetChangedDocument());
        }