예제 #1
0
        /// <inheritdoc/>
        protected override async Task RegisterCodeFixesAsync(DocumentEditorCodeFixContext context)
        {
            var syntaxRoot = await context.Document.GetSyntaxRootAsync(context.CancellationToken)
                             .ConfigureAwait(false);

            foreach (var diagnostic in context.Diagnostics)
            {
                if (diagnostic.Properties.TryGetValue("Name", out var name))
                {
                    if (syntaxRoot.FindNode(diagnostic.Location.SourceSpan, getInnermostNodeForTie: true) is MemberAccessExpressionSyntax memberAccess)
                    {
                        context.RegisterCodeFix(
                            "Prefer parameter.",
                            (editor, _) => editor.ReplaceNode(
                                memberAccess,
                                SyntaxFactory.IdentifierName(name)
                                .WithLeadingTriviaFrom(memberAccess)),
                            "Prefer parameter.",
                            diagnostic);
                    }
                    else if (syntaxRoot.FindNode(diagnostic.Location.SourceSpan, getInnermostNodeForTie: true) is IdentifierNameSyntax identifierName)
                    {
                        context.RegisterCodeFix(
                            "Prefer parameter.",
                            (editor, _) => editor.ReplaceNode(
                                identifierName,
                                identifierName.WithIdentifier(SyntaxFactory.Identifier(name))
                                .WithLeadingTriviaFrom(identifierName)),
                            "Prefer parameter.",
                            diagnostic);
                    }
                }
            }
        }
        /// <inheritdoc/>
        protected override async Task RegisterCodeFixesAsync(DocumentEditorCodeFixContext context)
        {
            var syntaxRoot = await context.Document.GetSyntaxRootAsync(context.CancellationToken)
                             .ConfigureAwait(false);

            foreach (var diagnostic in context.Diagnostics)
            {
                var node = syntaxRoot.FindNode(diagnostic.Location.SourceSpan);
                if (node is IdentifierNameSyntax identifierName)
                {
                    context.RegisterCodeFix(
                        "Throw if null.",
                        (editor, _) => editor.ReplaceNode(
                            node,
                            SyntaxFactory.ParseExpression($"{identifierName.Identifier.ValueText} ?? throw new System.ArgumentNullException(nameof({identifierName.Identifier.ValueText}))").WithSimplifiedNames()),
                        this.GetType(),
                        diagnostic);
                }
                else if (node is ParameterSyntax parameter)
                {
                    var semanticModel = await context.Document.GetSemanticModelAsync(context.CancellationToken)
                                        .ConfigureAwait(false);

                    var method = parameter.FirstAncestor <BaseMethodDeclarationSyntax>();
                    if (method != null)
                    {
                        using (var walker = AssignmentWalker.Create(method, Search.TopLevel, semanticModel, context.CancellationToken))
                        {
                            if (TryFirstAssignedWith(parameter, walker.Assignments, out var assignedValue))
                            {
                                context.RegisterCodeFix(
                                    "Throw if null on first assignment.",
                                    (editor, _) => editor.ReplaceNode(
                                        assignedValue,
                                        SyntaxFactory.ParseExpression($"{assignedValue.Identifier.ValueText} ?? throw new System.ArgumentNullException(nameof({assignedValue.Identifier.ValueText}))").WithSimplifiedNames()),
                                    this.GetType(),
                                    diagnostic);
                            }
                            else if (method.Body != null)
                            {
                                context.RegisterCodeFix(
                                    "Add null check.",
                                    (editor, _) => editor.ReplaceNode(
                                        method.Body,
                                        method.Body.InsertNodesBefore(
                                            method.Body.Statements[0],
                                            new[] { IfNullThrow(parameter.Identifier.ValueText) })),
                                    this.GetType(),
                                    diagnostic);
                            }
                        }
                    }
                }
            }
        }
예제 #3
0
        /// <inheritdoc/>
        protected override async Task RegisterCodeFixesAsync(DocumentEditorCodeFixContext context)
        {
            var syntaxRoot = await context.Document.GetSyntaxRootAsync(context.CancellationToken)
                             .ConfigureAwait(false);

            foreach (var diagnostic in context.Diagnostics)
            {
                var node = syntaxRoot.FindNode(diagnostic.Location.SourceSpan);
                if (node is IdentifierNameSyntax identifierName)
                {
                    context.RegisterCodeFix(
                        "Throw if null.",
                        (editor, _) => editor.ReplaceNode(
                            node,
                            SyntaxFactory.ParseExpression($"{identifierName.Identifier.ValueText} ?? throw new System.ArgumentNullException(nameof({identifierName.Identifier.ValueText}))").WithSimplifiedNames()),
                        this.GetType(),
                        diagnostic);
                }
                else if (node is ParameterSyntax parameter)
                {
                    var semanticModel = await context.Document.GetSemanticModelAsync(context.CancellationToken)
                                        .ConfigureAwait(false);

                    if (parameter.Parent is ParameterListSyntax parameterList &&
                        parameterList.Parent is BaseMethodDeclarationSyntax methodDeclaration)
                    {
                        using (var walker = AssignmentExecutionWalker.Borrow(methodDeclaration, Scope.Member, semanticModel, context.CancellationToken))
                        {
                            if (TryFirstAssignedWith(parameter, walker.Assignments, out var assignedValue))
                            {
                                context.RegisterCodeFix(
                                    "Throw if null on first assignment.",
                                    (editor, _) => editor.ReplaceNode(
                                        assignedValue,
                                        SyntaxFactory.ParseExpression($"{assignedValue.Identifier.ValueText} ?? throw new System.ArgumentNullException(nameof({assignedValue.Identifier.ValueText}))").WithSimplifiedNames()),
                                    this.GetType(),
                                    diagnostic);
                            }
                            else if (methodDeclaration.Body is BlockSyntax block)
                            {
                                context.RegisterCodeFix(
                                    "Add null check.",
                                    (editor, _) => editor.ReplaceNode(
                                        block,
                                        x => WithNullCheck(x, parameter)),
                                    this.GetType(),
                                    diagnostic);
                            }
                        }
                    }
                }
            }
        }
예제 #4
0
        /// <inheritdoc/>
        protected override async Task RegisterCodeFixesAsync(DocumentEditorCodeFixContext context)
        {
            var syntaxRoot = await context.Document.GetSyntaxRootAsync(context.CancellationToken)
                             .ConfigureAwait(false);

            var semanticModel = await context.Document.GetSemanticModelAsync(context.CancellationToken)
                                .ConfigureAwait(false);

            foreach (var diagnostic in context.Diagnostics)
            {
                var token = syntaxRoot.FindToken(diagnostic.Location.SourceSpan.Start);
                if (string.IsNullOrEmpty(token.ValueText) || token.IsMissing)
                {
                    continue;
                }

                var syntaxNode = syntaxRoot.FindNode(diagnostic.Location.SourceSpan);
                if (diagnostic.Id == Descriptors.GU0021CalculatedPropertyAllocates.Id)
                {
                    if (syntaxNode is ObjectCreationExpressionSyntax objectCreation)
                    {
                        var arguments  = objectCreation.ArgumentList.Arguments;
                        var hasMutable = IsAnyArgumentMutable(semanticModel, context.CancellationToken, arguments) ||
                                         IsAnyInitializerMutable(semanticModel, context.CancellationToken, objectCreation.Initializer);

                        var property = syntaxNode.FirstAncestorOrSelf <PropertyDeclarationSyntax>();
                        if (TryGetConstructor(property, out var ctor))
                        {
                            context.RegisterCodeFix(
                                "Use get-only" + (hasMutable ? " UNSAFE" : string.Empty),
                                (editor, cancellationToken) =>
                                ApplyInitializeInCtorFix(editor, ctor, property, objectCreation),
                                this.GetType().FullName + "UNSAFE",
                                diagnostic);
                        }
                    }
                }
                else if (diagnostic.Id == Descriptors.GU0022UseGetOnly.Id)
                {
                    var setter = syntaxNode.FirstAncestorOrSelf <AccessorDeclarationSyntax>();
                    if (setter != null)
                    {
                        context.RegisterCodeFix(
                            "Use get-only",
                            (editor, _) => ApplyRemoveSetterFix(editor, setter),
                            this.GetType(),
                            diagnostic);
                    }
                }
            }
        }
        /// <inheritdoc/>
        protected override async Task RegisterCodeFixesAsync(DocumentEditorCodeFixContext context)
        {
            var syntaxRoot = await context.Document.GetSyntaxRootAsync(context.CancellationToken)
                             .ConfigureAwait(false);

            var semanticModel = await context.Document.GetSemanticModelAsync(context.CancellationToken)
                                .ConfigureAwait(false);

            foreach (var diagnostic in context.Diagnostics)
            {
                var token = syntaxRoot.FindToken(diagnostic.Location.SourceSpan.Start);
                if (string.IsNullOrEmpty(token.ValueText) || token.IsMissing)
                {
                    continue;
                }

                var arguments = (ArgumentListSyntax)syntaxRoot.FindNode(diagnostic.Location.SourceSpan);
                if (HasAnyNamedArgument(arguments))
                {
                    continue;
                }

                var method = semanticModel.GetSymbolSafe(arguments.Parent, context.CancellationToken) as IMethodSymbol;
                if (method == null)
                {
                    continue;
                }

                context.RegisterCodeFix(
                    "Name arguments",
                    (editor, _) => ApplyFix(editor, method, arguments),
                    this.GetType(),
                    diagnostic);
            }
        }
        /// <inheritdoc/>
        protected override async Task RegisterCodeFixesAsync(DocumentEditorCodeFixContext context)
        {
            var syntaxRoot = await context.Document.GetSyntaxRootAsync(context.CancellationToken)
                             .ConfigureAwait(false);

            var semanticModel = await context.Document.GetSemanticModelAsync(context.CancellationToken)
                                .ConfigureAwait(false);

            foreach (var diagnostic in context.Diagnostics)
            {
                var token = syntaxRoot.FindToken(diagnostic.Location.SourceSpan.Start);
                if (string.IsNullOrEmpty(token.ValueText) || token.IsMissing)
                {
                    continue;
                }

                if (diagnostic.Id == Descriptors.GU0001NameArguments.Id &&
                    syntaxRoot.TryFindNode <ArgumentListSyntax>(diagnostic, out var arguments) &&
                    !HasAnyNamedArgument(arguments) &&
                    semanticModel.TryGetSymbol(arguments.Parent, context.CancellationToken, out IMethodSymbol method))
                {
                    context.RegisterCodeFix(
                        "Name arguments",
                        (editor, _) => ApplyFix(editor, method, arguments, 0),
                        this.GetType(),
                        diagnostic);
                }
                else if (diagnostic.Id == Descriptors.GU0009UseNamedParametersForBooleans.Id &&
                         syntaxRoot.TryFindNode <ArgumentSyntax>(diagnostic, out var boolArgument) &&
                         boolArgument.Parent is ArgumentListSyntax argumentList &&
                         !HasAnyNamedArgument(argumentList) &&
                         semanticModel.TryGetSymbol(argumentList.Parent, context.CancellationToken, out method))
                {
                    context.RegisterCodeFix(
                        "Name arguments",
                        (editor, _) => ApplyFix(editor, method, argumentList, argumentList.Arguments.IndexOf(boolArgument)),
                        this.GetType(),
                        diagnostic);
                }
            }
        }
예제 #7
0
        /// <inheritdoc/>
        protected override async Task RegisterCodeFixesAsync(DocumentEditorCodeFixContext context)
        {
            var syntaxRoot = await context.Document.GetSyntaxRootAsync(context.CancellationToken)
                             .ConfigureAwait(false);

            foreach (var diagnostic in context.Diagnostics)
            {
                var token = syntaxRoot.FindToken(diagnostic.Location.SourceSpan.Start);
                if (string.IsNullOrEmpty(token.ValueText) ||
                    token.IsMissing)
                {
                    continue;
                }

                if (syntaxRoot.TryFindNodeOrAncestor <EventFieldDeclarationSyntax>(diagnostic, out var eventField))
                {
                    context.RegisterCodeFix(
                        "Add [field:NonSerialized].",
                        (editor, _) => editor.ReplaceNode(
                            eventField,
                            x => x.AddAttributeLists(NonSerializedWithTargetSpecifier)
                            .WithLeadingTriviaFrom(x)),
                        nameof(NonSerializedFix),
                        diagnostic);
                    continue;
                }

                if (syntaxRoot.TryFindNodeOrAncestor <FieldDeclarationSyntax>(diagnostic, out var field))
                {
                    context.RegisterCodeFix(
                        "Add [NonSerialized].",
                        (editor, _) => editor.ReplaceNode(
                            field,
                            x => x.AddAttributeLists(NonSerialized)
                            .WithLeadingTriviaFrom(x)),
                        nameof(NonSerializedFix),
                        diagnostic);
                }
            }
        }
예제 #8
0
        /// <inheritdoc/>
        protected override async Task RegisterCodeFixesAsync(DocumentEditorCodeFixContext context)
        {
            var syntaxRoot = await context.Document.GetSyntaxRootAsync(context.CancellationToken)
                             .ConfigureAwait(false);

            foreach (var diagnostic in context.Diagnostics)
            {
                var token = syntaxRoot.FindToken(diagnostic.Location.SourceSpan.Start);
                if (string.IsNullOrEmpty(token.ValueText) || token.IsMissing)
                {
                    continue;
                }

                if (diagnostic.Id == Descriptors.GU0002NamedArgumentPositionMatches.Id)
                {
                    var arguments = (ArgumentListSyntax)syntaxRoot.FindNode(diagnostic.Location.SourceSpan);
                    if (!HasWhitespaceTriviaOnly(arguments))
                    {
                        continue;
                    }

                    context.RegisterCodeFix(
                        "Move arguments to match parameter positions.",
                        (editor, cancellationToken) => ApplyFixGU0002(editor, arguments, cancellationToken),
                        this.GetType(),
                        diagnostic);
                }

                if (diagnostic.Id == Descriptors.GU0005ExceptionArgumentsPositions.Id)
                {
                    var argument = (ArgumentSyntax)syntaxRoot.FindNode(diagnostic.Location.SourceSpan);
                    context.RegisterCodeFix(
                        "Move name argument to match parameter positions.",
                        (editor, cancellationToken) => ApplyFixGU0005(editor, argument, cancellationToken),
                        this.GetType(),
                        diagnostic);
                }
            }
        }
        /// <inheritdoc/>
        protected override async Task RegisterCodeFixesAsync(DocumentEditorCodeFixContext context)
        {
            var syntaxRoot = await context.Document.GetSyntaxRootAsync(context.CancellationToken)
                             .ConfigureAwait(false);

            var semanticModel = await context.Document.GetSemanticModelAsync(context.CancellationToken)
                                .ConfigureAwait(false);

            foreach (var diagnostic in context.Diagnostics)
            {
                if (syntaxRoot.TryFindNode(diagnostic, out ParameterListSyntax parameterList) &&
                    TryFindTestAttribute(parameterList.Parent as MethodDeclarationSyntax, semanticModel, context.CancellationToken, out var attribute) &&
                    TryGetParameters(attribute, semanticModel, context.CancellationToken, out var parameters))
                {
                    context.RegisterCodeFix(
                        "Update parameters",
                        (editor, c) =>
                        editor.ReplaceNode(
                            parameterList,
                            x => x.WithParameters(parameters)),
                        nameof(TestMethodParametersFix),
                        diagnostic);
                }
                else if (syntaxRoot.TryFindNodeOrAncestor(diagnostic, out attribute) &&
                         attribute.TryFirstAncestor(out MethodDeclarationSyntax method) &&
                         TryGetParameters(attribute, semanticModel, context.CancellationToken, out parameters))
                {
                    context.RegisterCodeFix(
                        "Update parameters",
                        (editor, c) =>
                        editor.ReplaceNode(
                            method.ParameterList,
                            x => x.WithParameters(parameters)),
                        nameof(TestMethodParametersFix),
                        diagnostic);
                }
            }
        }
        /// <inheritdoc/>
        protected override async Task RegisterCodeFixesAsync(DocumentEditorCodeFixContext context)
        {
            var syntaxRoot = await context.Document.GetSyntaxRootAsync(context.CancellationToken)
                             .ConfigureAwait(false);

            foreach (var diagnostic in context.Diagnostics)
            {
                if (syntaxRoot.TryFindNodeOrAncestor <BasePropertyDeclarationSyntax>(diagnostic, out var property))
                {
                    context.RegisterCodeFix(
                        "Sort property.",
                        (editor, _) => Move(editor, property),
                        "Sort property.",
                        diagnostic);
                }
            }
        }
예제 #11
0
        /// <inheritdoc/>
        protected override async Task RegisterCodeFixesAsync(DocumentEditorCodeFixContext context)
        {
            var syntaxRoot = await context.Document.GetSyntaxRootAsync(context.CancellationToken)
                             .ConfigureAwait(false);

            foreach (var diagnostic in context.Diagnostics)
            {
                if (syntaxRoot.TryFindNodeOrAncestor <IdentifierNameSyntax>(diagnostic, out var identifierName))
                {
                    context.RegisterCodeFix(
                        "Use lambda.",
                        (editor, cancellationToken) => UseLambda(editor, identifierName, cancellationToken),
                        "Use lambda.",
                        diagnostic);
                }
            }
        }
예제 #12
0
        /// <inheritdoc/>
        protected override async Task RegisterCodeFixesAsync(DocumentEditorCodeFixContext context)
        {
            var syntaxRoot = await context.Document.GetSyntaxRootAsync(context.CancellationToken)
                             .ConfigureAwait(false);

            foreach (var diagnostic in context.Diagnostics)
            {
                if (syntaxRoot.TryFindNodeOrAncestor(diagnostic, out ClassDeclarationSyntax classDeclaration))
                {
                    context.RegisterCodeFix(
                        "Make sealed.",
                        (editor, _) => editor.MakeSealed(classDeclaration),
                        "Make sealed.",
                        diagnostic);
                }
            }
        }
예제 #13
0
        /// <inheritdoc/>
        protected override async Task RegisterCodeFixesAsync(DocumentEditorCodeFixContext context)
        {
            var syntaxRoot = await context.Document.GetSyntaxRootAsync(context.CancellationToken)
                             .ConfigureAwait(false);

            foreach (var diagnostic in context.Diagnostics)
            {
                if (syntaxRoot.TryFindNode(diagnostic, out ExpressionSyntax node) &&
                    diagnostic.Properties.TryGetValue(nameof(INamedTypeSymbol), out var typeName) &&
                    diagnostic.Properties.TryGetValue(nameof(Inject.Injectable), out var injectable))
                {
                    context.RegisterCodeFix(
                        $"Inject {(injectable == nameof(Inject.Injectable.Safe) ? injectable.ToLower() : injectable.ToUpper())}.",
                        (editor, cancellationToken) => Fix(editor, cancellationToken, node, typeName),
                        nameof(InjectFix),
                        diagnostic);
                }
            }
        }
예제 #14
0
        /// <inheritdoc/>
        protected override async Task RegisterCodeFixesAsync(DocumentEditorCodeFixContext context)
        {
            var syntaxRoot = await context.Document.GetSyntaxRootAsync(context.CancellationToken)
                             .ConfigureAwait(false);

            foreach (var diagnostic in context.Diagnostics)
            {
                if (syntaxRoot.TryFindNodeOrAncestor(diagnostic, out MethodDeclarationSyntax methodDeclaration))
                {
                    context.RegisterCodeFix(
                        "Make Static.",
                        (editor, _) => editor.ReplaceNode(
                            methodDeclaration,
                            x => x.WithModifiers(methodDeclaration.Modifiers.Add(SyntaxFactory.Token(SyntaxKind.StaticKeyword)))),
                        "Make Static.",
                        diagnostic);
                }
            }
        }
예제 #15
0
        /// <inheritdoc/>
        protected override async Task RegisterCodeFixesAsync(DocumentEditorCodeFixContext context)
        {
            var syntaxRoot = await context.Document.GetSyntaxRootAsync(context.CancellationToken)
                             .ConfigureAwait(false);

            foreach (var diagnostic in context.Diagnostics)
            {
                var argument = syntaxRoot.FindNode(diagnostic.Location.SourceSpan)
                               .FirstAncestorOrSelf <ArgumentSyntax>();
                if (argument != null &&
                    diagnostic.Properties.TryGetValue("Name", out var name))
                {
                    context.RegisterCodeFix(
                        "Use correct parameter name.",
                        (editor, _) => editor.ReplaceNode(
                            argument.Expression,
                            SyntaxFactory.ParseExpression($"nameof({name})")),
                        this.GetType(),
                        diagnostic);
                }
            }
        }
        /// <inheritdoc/>
        protected override async Task RegisterCodeFixesAsync(DocumentEditorCodeFixContext context)
        {
            var syntaxRoot = await context.Document.GetSyntaxRootAsync(context.CancellationToken)
                             .ConfigureAwait(false);

            foreach (var diagnostic in context.Diagnostics)
            {
                if (syntaxRoot.TryFindNode(diagnostic, out ArgumentSyntax argument) &&
                    diagnostic.Properties.TryGetValue(nameof(IdentifierNameSyntax), out var name))
                {
                    context.RegisterCodeFix(
                        $"Use nameof({name}).",
                        (editor, _) => editor.ReplaceNode(
                            argument.Expression,
                            x => CreateNode(x).WithTriviaFrom(x)),
                        this.GetType(),
                        diagnostic);

                    ExpressionSyntax CreateNode(ExpressionSyntax old)
                    {
                        switch (old)
                        {
                        case LiteralExpressionSyntax literal when literal.IsKind(SyntaxKind.StringLiteralExpression):
                            return(SyntaxFactory.ParseExpression($"nameof({name})"));

                        case IdentifierNameSyntax identifierName when identifierName.Parent is ArgumentSyntax candidate &&
                            candidate.Parent is ArgumentListSyntax argumentList &&
                            argumentList.Parent is InvocationExpressionSyntax invocation &&
                            invocation.IsNameOf():
                            return(identifierName.WithIdentifier(SyntaxFactory.Identifier(name)));

                        default:
                            throw new InvalidOperationException("Failed updating parameter name.");
                        }
                    }
                }
            }
        }
예제 #17
0
        /// <inheritdoc/>
        protected override async Task RegisterCodeFixesAsync(DocumentEditorCodeFixContext context)
        {
            var syntaxRoot = await context.Document.GetSyntaxRootAsync(context.CancellationToken)
                             .ConfigureAwait(false);

            foreach (var diagnostic in context.Diagnostics)
            {
                var token = syntaxRoot.FindToken(diagnostic.Location.SourceSpan.Start);
                if (string.IsNullOrEmpty(token.ValueText) || token.IsMissing)
                {
                    continue;
                }

                if (syntaxRoot.FindNode(diagnostic.Location.SourceSpan) is ArgumentSyntax argument &&
                    argument.Expression is LiteralExpressionSyntax literal)
                {
                    context.RegisterCodeFix(
                        "Use nameof",
                        (editor, cancellationToken) => ApplyFix(editor, argument, literal.Token.ValueText, cancellationToken),
                        this.GetType(),
                        diagnostic);
                }
            }
        }
예제 #18
0
        /// <inheritdoc/>
        protected override async Task RegisterCodeFixesAsync(DocumentEditorCodeFixContext context)
        {
            var syntaxRoot = await context.Document.GetSyntaxRootAsync(context.CancellationToken)
                             .ConfigureAwait(false);

            var semanticModel = await context.Document.GetSemanticModelAsync(context.CancellationToken)
                                .ConfigureAwait(false);

            foreach (var diagnostic in context.Diagnostics)
            {
                if (syntaxRoot.TryFindNodeOrAncestor(diagnostic, out BaseMethodDeclarationSyntax methodDeclaration))
                {
                    if (syntaxRoot.TryFindNodeOrAncestor(diagnostic, out ParameterSyntax parameter) &&
                        methodDeclaration.TryGetDocumentationComment(out var docs))
                    {
                        if (StandardDocs.TryGet(parameter, out var text))
                        {
                            context.RegisterCodeFix(
                                "Generate standard xml documentation for parameter.",
                                (editor, _) => editor.ReplaceNode(
                                    docs,
                                    x => x.WithParamText(parameter.Identifier.ValueText, text)),
                                text,
                                diagnostic);
                        }
                        else if (parameter.Type is PredefinedTypeSyntax)
                        {
                            context.RegisterCodeFix(
                                "Generate useless xml documentation for parameter.",
                                (editor, _) => editor.ReplaceNode(
                                    docs,
                                    x => x.WithParamText(parameter.Identifier.ValueText, string.Empty)),
                                nameof(UselessDocsFix),
                                diagnostic);
                        }
                        else
                        {
                            context.RegisterCodeFix(
                                "Generate useless xml documentation for parameter.",
                                (editor, _) => editor.ReplaceNode(
                                    docs,
                                    x => x.WithParamText(parameter.Identifier.ValueText, $"The <see cref=\"{parameter.Type.ToString().Replace("<", "{").Replace(">", "}")}\"/>.")),
                                nameof(UselessDocsFix),
                                diagnostic);
                        }
                    }
                    else if (syntaxRoot.TryFindNodeOrAncestor(diagnostic, out TypeParameterSyntax typeParameter) &&
                             methodDeclaration.TryGetDocumentationComment(out docs))
                    {
                        if (TryGetTypeParameterText(methodDeclaration, typeParameter, semanticModel, context.CancellationToken, out var text))
                        {
                            context.RegisterCodeFix(
                                "Generate useless xml documentation for type parameter.",
                                (editor, _) => editor.ReplaceNode(
                                    docs,
                                    x => x.WithTypeParamText(typeParameter.Identifier.ValueText, text)),
                                nameof(UselessDocsFix),
                                diagnostic);
                        }
                        else
                        {
                            context.RegisterCodeFix(
                                "Generate empty xml documentation for type parameter.",
                                (editor, _) => editor.ReplaceNode(
                                    docs,
                                    x => x.WithTypeParamText(typeParameter.Identifier.ValueText, string.Empty)),
                                nameof(UselessDocsFix),
                                diagnostic);
                        }
                    }
                    else if (syntaxRoot.FindNode(diagnostic.Location.SourceSpan, findInsideTrivia: true, getInnermostNodeForTie: true) is XmlElementSyntax element &&
                             element.TryGetNameAttribute(out var name) &&
                             methodDeclaration.TryFindParameter(name.Identifier?.Identifier.ValueText, out parameter))
                    {
                        if (StandardDocs.TryGet(parameter, out var text))
                        {
                            context.RegisterCodeFix(
                                "Generate standard xml documentation for parameter.",
                                (editor, _) => editor.ReplaceNode(
                                    element,
                                    x => WithText(x, text)),
                                text,
                                diagnostic);
                        }
                        else
                        {
                            context.RegisterCodeFix(
                                "Generate useless xml documentation for parameter.",
                                (editor, _) => editor.ReplaceNode(
                                    element,
                                    x => WithText(x, $"The <see cref=\"{parameter.Type.ToString().Replace("<", "{").Replace(">", "}")}\"/>.")),
                                nameof(UselessDocsFix),
                                diagnostic);
                        }
                    }
                }
            }
        }