Example #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 (syntaxRoot.TryFindNodeOrAncestor(diagnostic, out MemberDeclarationSyntax member) &&
                    diagnostic.AdditionalLocations.TrySingle(out var additionalLocation) &&
                    syntaxRoot.FindNode(additionalLocation.SourceSpan)?.FirstAncestorOrSelf <MemberDeclarationSyntax>() is MemberDeclarationSyntax other &&
                    member.SharesAncestor(other, out ClassDeclarationSyntax type))
                {
                    context.RegisterCodeFix(
                        $"Move",
                        (e, _) => e.ReplaceNode(
                            type,
                            x =>
                    {
                        if (x.Members.IndexOf(m => m.IsEquivalentTo(member)) is var fromIndex &&
                            fromIndex >= 0 &&
                            x.Members.IndexOf(m => m.IsEquivalentTo(other)) is var toIndex &&
                            toIndex < fromIndex)
                        {
                            return(x.WithMembers(x.Members.RemoveAt(fromIndex).Insert(toIndex, member.WithLeadingElasticLineFeed().WithTrailingLineFeed())));
                        }

                        return(x);
                    }),
Example #2
0
        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(nameof(TypeSyntax), out var typesText) &&
                    syntaxRoot.TryFindNodeOrAncestor(diagnostic, out InvocationExpressionSyntax invocation) &&
                    invocation.Expression is MemberAccessExpressionSyntax)
                {
                    context.RegisterCodeFix(
                        $"Call MakeGenericMethod({typesText}).",
                        (editor, _) => editor.ReplaceNode(
                            invocation,
                            x =>
                    {
                        var memberAccess = (MemberAccessExpressionSyntax)invocation.Expression;
                        return(x.WithExpression(memberAccess.WithExpression(SyntaxFactory.ParseExpression($"{memberAccess.Expression.ToFullString()}.MakeGenericMethod({typesText})"))));
                    }),
                        nameof(CallMakeGenericMethodFix),
                        diagnostic);
                }
            }
        }
Example #3
0
        protected override async Task RegisterCodeFixesAsync(DocumentEditorCodeFixContext context)
        {
            var document   = context.Document;
            var syntaxRoot = await document.GetSyntaxRootAsync(context.CancellationToken)
                             .ConfigureAwait(false);

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

            foreach (var diagnostic in context.Diagnostics)
            {
                if (syntaxRoot.TryFindNodeOrAncestor <ClassDeclarationSyntax>(diagnostic, out var classDeclaration))
                {
                    if (ValueConverter.TryGetConversionTypes(classDeclaration, semanticModel, context.CancellationToken, out var sourceType, out var targetType))
                    {
                        context.RegisterCodeFix(
                            $"Add [ValueConversion(typeof({sourceType}), typeof({targetType}))].",
                            (e, _) => AddAttribute(e, classDeclaration, sourceType, targetType),
                            $"Add [ValueConversion(typeof({sourceType}), typeof({targetType}))].",
                            diagnostic);
                    }
                    else
                    {
                        context.RegisterCodeFix(
                            $"Add [ValueConversion(typeof({sourceType?.ToString() ?? "TYPE"}), typeof({targetType?.ToString() ?? "TYPE"}))].",
                            (e, _) => AddAttribute(e, classDeclaration, sourceType, targetType),
                            $"Add [ValueConversion(typeof({sourceType?.ToString() ?? "TYPE"}), typeof({targetType?.ToString() ?? "TYPE"}))].",
                            diagnostic);
                    }
                }
            }
Example #4
0
        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.FindNode(diagnostic.Location.SourceSpan, findInsideTrivia: false, getInnermostNodeForTie: true) is LiteralExpressionSyntax literal &&
                    diagnostic.Properties.TryGetValue(nameof(SyntaxKind.StringLiteralExpression), out var text))
                {
                    context.RegisterCodeFix(
                        $"Use fully qualified name: {text}.",
                        (editor, _) => editor.ReplaceNode(
                            literal,
                            x => x.WithToken(SyntaxFactory.Literal(text))),
                        nameof(UseFullyQualifiedFix),
                        diagnostic);
                }

                if (syntaxRoot.FindNode(diagnostic.Location.SourceSpan, findInsideTrivia: false, getInnermostNodeForTie: true) is IdentifierNameSyntax identifierName &&
                    diagnostic.Properties.TryGetValue(nameof(SimpleNameSyntax), out var name))
                {
                    context.RegisterCodeFix(
                        $"Use fully qualified name: {name}.",
                        (editor, _) => editor.ReplaceNode(
                            identifierName,
                            x => x.WithIdentifier(SyntaxFactory.Identifier(name))),
                        nameof(UseFullyQualifiedFix),
                        diagnostic);
                }
            }
        }
        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>();
                switch (argument?.Expression)
                {
                case LiteralExpressionSyntax literal when literal.IsKind(SyntaxKind.StringLiteralExpression) &&
                    diagnostic.Properties.TryGetValue(nameof(MemberAccessExpressionSyntax), out var member):
                    context.RegisterCodeFix(
                        "Use nameof.",
                        (editor, _) => editor.ReplaceNode(
                            literal,
                            (x, g) => SyntaxFactory.ParseExpression($"nameof({member}.{literal.Token.ValueText})")),
                        "Use nameof.",
                        diagnostic);

                    break;

                case MemberAccessExpressionSyntax memberAccess:
                    context.RegisterCodeFix(
                        "Use nameof.",
                        (editor, _) => editor.ReplaceNode(
                            memberAccess,
                            (x, g) => SyntaxFactory.ParseExpression($"nameof({memberAccess})")),
                        "Use nameof.",
                        diagnostic);
                    break;
                }
            }
        }
Example #6
0
        /// <inheritdoc/>
        protected override async Task RegisterCodeFixesAsync(DocumentEditorCodeFixContext context)
        {
            var document   = context.Document;
            var syntaxRoot = await document.GetSyntaxRootAsync(context.CancellationToken)
                             .ConfigureAwait(false);

            var semanticModel = await 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))
                {
                    continue;
                }

                if (syntaxRoot.FindNode(diagnostic.Location.SourceSpan).TryFirstAncestorOrSelf <MethodDeclarationSyntax>(out var methodDeclaration) &&
                    semanticModel.TryGetSymbol(methodDeclaration, context.CancellationToken, out var method) &&
                    method.Parameters.TrySingle(out var parameter))
                {
                    context.RegisterCodeFix(
                        $"Add [AttachedPropertyBrowsableForTypeAttribute(typeof({parameter.Type})))].",
                        (e, _) => AddAttribute(e, methodDeclaration, parameter.Type),
                        this.GetType().FullName,
                        diagnostic);
                }
            }
        }
        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.FindToken(diagnostic.Location.SourceSpan.Start) is SyntaxToken token)
                {
                    if (token.IsKind(SyntaxKind.PrivateKeyword))
                    {
                        context.RegisterCodeFix(
                            $"Change to: protected.",
                            (editor, _) => editor.ReplaceToken(
                                token,
                                SyntaxFactory.Token(SyntaxKind.ProtectedKeyword)),
                            nameof(MakeProtectedFix),
                            diagnostic);
                    }
                    else if (token.IsKind(SyntaxKind.IdentifierToken) &&
                             token.Parent is MethodDeclarationSyntax methodDeclaration)
                    {
                        context.RegisterCodeFix(
                            $"Make protected.",
                            (editor, _) => editor.ReplaceNode(
                                methodDeclaration,
                                methodDeclaration.WithModifiers(methodDeclaration.Modifiers.Insert(0, SyntaxFactory.Token(SyntaxKind.ProtectedKeyword)))),
                            nameof(MakeProtectedFix),
                            diagnostic);
                    }
                }
            }
        }
Example #8
0
        /// <inheritdoc/>
        protected override async Task RegisterCodeFixesAsync(DocumentEditorCodeFixContext context)
        {
            var document   = context.Document;
            var syntaxRoot = await document.GetSyntaxRootAsync(context.CancellationToken)
                             .ConfigureAwait(false);

            var semanticModel = await 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))
                {
                    continue;
                }

                if (syntaxRoot.TryFindNodeOrAncestor(diagnostic, out MemberDeclarationSyntax member) &&
                    semanticModel.TryGetSymbol(member, context.CancellationToken, out ISymbol symbol) &&
                    BackingFieldOrProperty.TryCreateForDependencyProperty(symbol, out var fieldOrProperty) &&
                    DependencyProperty.TryGetRegisteredName(fieldOrProperty, semanticModel, context.CancellationToken, out var name))
                {
                    context.RegisterCodeFix(
                        "Add standard documentation.",
                        (editor, _) => editor.ReplaceNode(member, x => x.WithDocumentationText($"/// <summary>Identifies the <see cref=\"{name}\"/> dependency property.</summary>")),
                        this.GetType(),
                        diagnostic);
                }
            }
        }
Example #9
0
        /// <inheritdoc/>
        protected override async Task RegisterCodeFixesAsync(DocumentEditorCodeFixContext context)
        {
            var document   = context.Document;
            var syntaxRoot = await document.GetSyntaxRootAsync(context.CancellationToken)
                             .ConfigureAwait(false);

            var semanticModel = await 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))
                {
                    continue;
                }

                var argument = syntaxRoot.FindNode(diagnostic.Location.SourceSpan)
                               .FirstAncestorOrSelf <AttributeArgumentSyntax>();
                var attribute = argument.FirstAncestor <AttributeSyntax>();
                if (MarkupExtension.TryGetReturnType(attribute.FirstAncestor <ClassDeclarationSyntax>(), semanticModel, context.CancellationToken, out var returnType))
                {
                    context.RegisterCodeFix(
                        $"Change type to {returnType}.",
                        (e, _) => FixType(e, argument, returnType),
                        this.GetType(),
                        diagnostic);
                }
            }
        }
Example #10
0
        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 InvocationExpressionSyntax? setValue) &&
                    TryGetName(setValue, out var identifierName))
                {
                    context.RegisterCodeFix(
                        setValue.ToString().Replace("SetValue", "SetCurrentValue"),
                        (editor, _) => editor.ReplaceNode(
                            identifierName,
                            x => x.WithIdentifier(SyntaxFactory.Identifier("SetCurrentValue")).WithTriviaFrom(x)),
                        nameof(UseSetCurrentValueFix),
                        diagnostic);
                }
                else if (syntaxRoot.TryFindNodeOrAncestor(diagnostic, out AssignmentExpressionSyntax? assignment) &&
                         TryCreatePath(assignment, out var path) &&
                         diagnostic.Properties.TryGetValue(nameof(BackingFieldOrProperty), out var backingFieldOrProperty))
                {
                    var expressionString = $"{path}SetCurrentValue({backingFieldOrProperty}, {Cast(assignment)}{assignment.Right})";
                    context.RegisterCodeFix(
                        expressionString,
                        (editor, _) => editor.ReplaceNode(
                            assignment,
                            x => SyntaxFactory.ParseExpression(expressionString).WithTriviaFrom(x)),
                        nameof(UseSetCurrentValueFix),
                        diagnostic);
                }
        protected override async Task RegisterCodeFixesAsync(DocumentEditorCodeFixContext context)
        {
            var document   = context.Document;
            var syntaxRoot = await document.GetSyntaxRootAsync(context.CancellationToken)
                             .ConfigureAwait(false);

            foreach (var diagnostic in context.Diagnostics)
            {
                if (syntaxRoot.TryFindNodeOrAncestor(diagnostic, out InvocationExpressionSyntax? invocation) &&
                    diagnostic.Properties.TryGetValue(nameof(DependencyPropertyKeyType), out var keyName))
                {
                    context.RegisterCodeFix(
                        invocation.ToString(),
                        (e, _) => e.ReplaceNode(invocation.Expression, x => SetValue(x))
                        .ReplaceNode(invocation.ArgumentList.Arguments[0].Expression, x => PropertyKey(x)),
                        this.GetType().FullName,
                        diagnostic);

                    ExpressionSyntax PropertyKey(ExpressionSyntax old)
                    {
                        return(old switch
                        {
                            IdentifierNameSyntax id => id.WithIdentifier(SyntaxFactory.Identifier(keyName)),
                            MemberAccessExpressionSyntax {
                                Name : IdentifierNameSyntax id
                            } ma => ma.WithName(id.WithIdentifier(SyntaxFactory.Identifier(keyName))),
                            _ => old,
                        });
                    }
Example #12
0
        /// <inheritdoc/>
        protected override async Task RegisterCodeFixesAsync(DocumentEditorCodeFixContext context)
        {
            var document   = context.Document;
            var syntaxRoot = await document.GetSyntaxRootAsync(context.CancellationToken)
                             .ConfigureAwait(false);

            foreach (var diagnostic in context.Diagnostics)
            {
                if (syntaxRoot.TryFindNodeOrAncestor <ClassDeclarationSyntax>(diagnostic, out var classDeclaration))
                {
                    if (diagnostic.Properties.TryGetValue(nameof(AttributeListSyntax), out var attribute))
                    {
                        context.RegisterCodeFix(
                            $"Add {attribute}.",
                            (e, _) =>
                        {
                            e.ReplaceNode(
                                classDeclaration,
                                classDeclaration.WithAttributeLists(
                                    classDeclaration.AttributeLists.Add(
                                        ParseAttributeList(attribute))));
                        },
                            "[TemplatePart]",
                            diagnostic);
                    }
                }
            }
        }
Example #13
0
        protected override async Task RegisterCodeFixesAsync(DocumentEditorCodeFixContext context)
        {
            var document   = context.Document;
            var syntaxRoot = await document.GetSyntaxRootAsync(context.CancellationToken)
                             .ConfigureAwait(false);

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

            foreach (var diagnostic in context.Diagnostics)
            {
                if (syntaxRoot.TryFindNodeOrAncestor(diagnostic, out ClassDeclarationSyntax? classDeclaration) &&
                    MarkupExtension.TryGetReturnType(classDeclaration, semanticModel, context.CancellationToken, out var returnType))
                {
                    context.RegisterCodeFix(
                        "Add MarkupExtensionReturnTypeAttribute.",
                        (e, _) => AddAttribute(e),
                        "Add MarkupExtensionReturnTypeAttribute.",
                        diagnostic);

                    void AddAttribute(DocumentEditor editor)
                    {
                        editor.AddAttribute(
                            classDeclaration,
                            editor.Generator.AddAttributeArguments(
                                Attribute,
                                new[] { editor.Generator.AttributeArgument(editor.Generator.TypeOfExpression(editor.Generator.TypeExpression(returnType))) }));
                    }
                }
            }
        }
Example #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.TryFindNode(diagnostic, out AssignmentExpressionSyntax? assignment) &&
                    diagnostic.AdditionalLocations.TrySingle(out var additionalLocation) &&
                    syntaxRoot.FindNode(additionalLocation.SourceSpan) is ExpressionSyntax fieldAccess)
                {
                    context.RegisterCodeFix(
                        "Set backing field.",
                        (e, cancellationToken) => e.ReplaceNode(
                            assignment.Left,
                            (x, _) => Qualify(fieldAccess).WithTriviaFrom(x)),
                        nameof(SetBackingFieldFix),
                        diagnostic);

                    ExpressionSyntax Qualify(ExpressionSyntax expression)
                    {
                        if (expression is IdentifierNameSyntax identifierName &&
                            (Scope.HasParameter(assignment, identifierName.Identifier.ValueText) ||
                             Scope.HasLocal(assignment, identifierName.Identifier.ValueText)))
                        {
                            return(InpcFactory.SymbolAccess(identifierName.Identifier.ValueText, CodeStyleResult.Yes));
                        }

                        return(expression);
                    }
                }
            }
        }
Example #15
0
        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(nameof(ITypeSymbol.ContainingType), out var typeName))
                {
                    if (syntaxRoot.TryFindNode(diagnostic, out TypeSyntax type))
                    {
                        context.RegisterCodeFix(
                            $"Use containing type: {typeName}.",
                            (editor, _) => editor.ReplaceNode(
                                type,
                                x => SyntaxFactory.ParseTypeName(typeName)
                                .WithTriviaFrom(x)),
                            nameof(UseContainingTypeFix),
                            diagnostic);
                    }
                    else if (syntaxRoot.TryFindNode(diagnostic, out MemberAccessExpressionSyntax memberAccess) &&
                             memberAccess.Expression is ExpressionSyntax expression)
                    {
                        context.RegisterCodeFix(
                            $"Use containing type: {typeName}.",
                            (editor, _) => editor.ReplaceNode(
                                expression,
                                x => SyntaxFactory.ParseExpression($"typeof({typeName})").WithTriviaFrom(x)),
                            nameof(UseContainingTypeFix),
                            diagnostic);
                    }
                }
            }
        }
Example #16
0
        /// <inheritdoc/>
        protected override async Task RegisterCodeFixesAsync(DocumentEditorCodeFixContext context)
        {
            var document   = context.Document;
            var syntaxRoot = await document.GetSyntaxRootAsync(context.CancellationToken)
                             .ConfigureAwait(false);

            var semanticModel = await 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))
                {
                    continue;
                }

                var classDeclaration = syntaxRoot.FindNode(diagnostic.Location.SourceSpan)
                                       .FirstAncestorOrSelf <ClassDeclarationSyntax>();
                if (classDeclaration != null &&
                    MarkupExtension.TryGetReturnType(classDeclaration, semanticModel, context.CancellationToken, out var returnType))
                {
                    context.RegisterCodeFix(
                        "Add MarkupExtensionReturnTypeAttribute.",
                        (e, _) => AddAttribute(e, classDeclaration, returnType),
                        "Add MarkupExtensionReturnTypeAttribute.",
                        diagnostic);
                }
            }
        }
Example #17
0
        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(nameof(TypeSyntax), out var typeText) &&
                    syntaxRoot.TryFindNode(diagnostic, out TypeSyntax typeSyntax) &&
                    typeSyntax.Parent is PropertyDeclarationSyntax property &&
                    property.TryGetGetter(out var getter))
                {
                    context.RegisterCodeFix(
                        $"Change to: {typeText}.",
                        (editor, _) => editor.ReplaceNode(
                            typeSyntax,
                            x => SyntaxFactory.ParseTypeName(typeText).WithTriviaFrom(x))
                        .ReplaceNode(
                            getter,
                            x => WithCast(x, typeText)),
                        nameof(UseRegisteredTypeFix),
                        diagnostic);
                }
            }
        }
Example #18
0
        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);
                switch (node)
                {
                case AssignmentExpressionSyntax {
                        Left: { } left
                } assignment:
                    context.RegisterCodeFix(
                        "Dispose before re-assigning.",
                        (editor, cancellationToken) => DisposeBefore(editor, left, assignment, cancellationToken),
                        "Dispose before re-assigning.",
                        diagnostic);
                    break;

                case ArgumentSyntax {
                        Expression: { } expression
                } argument:
                    context.RegisterCodeFix(
                        "Dispose before re-assigning.",
                        (editor, cancellationToken) => DisposeBefore(editor, expression, argument, cancellationToken),
                        "Dispose before re-assigning.",
                        diagnostic);
                    break;
                }
            }
        }
Example #19
0
        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.FindNode(diagnostic.Location.SourceSpan, getInnermostNodeForTie: true) is LiteralExpressionSyntax literal &&
                    literal.IsKind(SyntaxKind.StringLiteralExpression) &&
                    TryGetNameAndArity(literal, out var typeName, out var arity))
                {
                    foreach (var assembly in new[] { semanticModel.Compilation.Assembly }.Concat(semanticModel.Compilation.Assembly.Modules.SelectMany(x => x.ReferencedAssemblySymbols)))
                    {
                        foreach (var type in GetTypes(assembly.GlobalNamespace, typeName, arity))
                        {
                            context.RegisterCodeFix(
                                $"Use: {type}.",
                                (editor, _) => editor.ReplaceNode(
                                    literal,
                                    x => x.WithToken(SyntaxFactory.Literal(type.QualifiedMetadataName()))),
                                nameof(SuggestTypeFix),
                                diagnostic);
                        }
                    }
                }
            }
        }
        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(
                        "Add OnPropertyChanged()",
                        (editor, cancellationToken) => editor.AddOnPropertyChangedMethodAsync(
                            classDeclaration,
                            editor.SemanticModel.GetNullableContext(classDeclaration.SpanStart).AnnotationsEnabled(),
                            cancellationToken),
                        "Add OnPropertyChanged()",
                        diagnostic);

                    if (!classDeclaration.Modifiers.Any(SyntaxKind.AbstractKeyword) &&
                        !classDeclaration.Modifiers.Any(SyntaxKind.StaticKeyword))
                    {
                        var semanticModel = await context.Document.GetSemanticModelAsync(context.CancellationToken).ConfigureAwait(false);

                        if (ShouldSeal(classDeclaration, semanticModel, context.CancellationToken))
                        {
                            context.RegisterCodeFix(
                                "Seal class.",
                                (editor, _) => editor.Seal(classDeclaration),
                                "Seal class.",
                                diagnostic);
                        }
                    }
                }
            }
        }
Example #21
0
        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(nameof(TypeSyntax), out var typeString))
                {
                    if (syntaxRoot.TryFindNode(diagnostic, out TypeSyntax typeSyntax))
                    {
                        context.RegisterCodeFix(
                            $"Cast to {typeString}.",
                            (editor, _) => editor.ReplaceNode(
                                typeSyntax,
                                x => SyntaxFactory.ParseTypeName(typeString)),
                            nameof(CastReturnValueFix),
                            diagnostic);
                    }
                    else if (syntaxRoot.TryFindNode(diagnostic, out InvocationExpressionSyntax invocation))
                    {
                        context.RegisterCodeFix(
                            $"Cast to {typeString}.",
                            (editor, _) => editor.ReplaceNode(
                                invocation,
                                x => SyntaxFactory.CastExpression(SyntaxFactory.ParseTypeName(typeString), x)),
                            nameof(CastReturnValueFix),
                            diagnostic);
                    }
                }
            }
        }
Example #22
0
        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 InvocationExpressionSyntax? invocation) &&
                    IdentifierName() is { } identifier)
                {
                    context.RegisterCodeFix(
                        "Use SetValue",
                        e => e.ReplaceNode(
                            identifier,
                            x => x.WithIdentifier(SyntaxFactory.Identifier("SetValue"))),
                        "Use SetValue",
                        diagnostic);
                }

                IdentifierNameSyntax?IdentifierName()
                {
                    return(invocation !.Expression switch
                    {
                        IdentifierNameSyntax identifierName => identifierName,
                        MemberAccessExpressionSyntax {
                            Name : IdentifierNameSyntax identifierName
                        } => identifierName,
Example #23
0
        protected override async Task RegisterCodeFixesAsync(DocumentEditorCodeFixContext context)
        {
            var document   = context.Document;
            var syntaxRoot = await document.GetSyntaxRootAsync(context.CancellationToken)
                             .ConfigureAwait(false);

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

            foreach (var diagnostic in context.Diagnostics)
            {
                if (syntaxRoot.TryFindNodeOrAncestor(diagnostic, out TypeOfExpressionSyntax? typeofExpression) &&
                    typeofExpression.TryFirstAncestor(out TypeDeclarationSyntax? typeDeclaration) &&
                    semanticModel.TryGetSymbol(typeDeclaration, context.CancellationToken, out var containingType))
                {
                    var containingTypeName = containingType.ToMinimalDisplayString(semanticModel, typeofExpression.SpanStart, SymbolDisplayFormat.MinimallyQualifiedFormat);

                    context.RegisterCodeFix(
                        $"Use containing type: {containingTypeName}.",
                        (editor, _) => editor.ReplaceNode(
                            typeofExpression,
                            x => x.WithType(SyntaxFactory.ParseTypeName(containingTypeName))),
                        "Use containing type.",
                        diagnostic);
                }
            }
        }
Example #24
0
        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 InvocationExpressionSyntax invocation) &&
                    invocation.ArgumentList is ArgumentListSyntax argumentList &&
                    argumentList.Arguments.TrySingle(out var arg) &&
                    IsAssignableFromAnalyzer.IsInstanceGetType(arg.Expression, semanticModel, context.CancellationToken, out var instance))
                {
                    context.RegisterCodeFix(
                        $"Change to: IsInstanceOfType().",
                        (editor, _) => editor.ReplaceNode(
                            invocation.Expression,
                            x =>
                    {
                        var memberAccess = (MemberAccessExpressionSyntax)x;
                        return(memberAccess.WithName(memberAccess.Name.WithIdentifier(SyntaxFactory.Identifier("IsInstanceOfType"))));
                    })
                        .ReplaceNode(
                            arg.Expression,
                            x => instance.WithTriviaFrom(x)),
                        nameof(UseIsInstanceOfTypeFix),
                        diagnostic);
                }
            }
        }
Example #25
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.TryFindNode(diagnostic, out ArgumentSyntax? argument) &&
                    argument.Expression is LiteralExpressionSyntax literal &&
                    semanticModel.LookupSymbols(argument.SpanStart, name: literal.Token.ValueText).TryFirst(out var member))
                {
                    context.RegisterCodeFix(
                        "Use nameof",
                        async(editor, cancellationToken) =>
                    {
                        var replacement = await editor.SymbolAccessAsync(member, literal, cancellationToken)
                                          .ConfigureAwait(false);
                        _ = editor.ReplaceNode(
                            literal,
                            x => InpcFactory.Nameof(replacement).WithTriviaFrom(x));
                    },
                        nameof(UseNameofFix),
                        diagnostic);
                }
            }
        }
Example #26
0
        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 (IsSupportedDiagnostic(diagnostic) &&
                    syntaxRoot.TryFindNodeOrAncestor(diagnostic, out TypeDeclarationSyntax? typeDeclaration))
                {
                    if (diagnostic.Id == Descriptors.IDISP009IsIDisposable.Id)
                    {
                        context.RegisterCodeFix(
                            "Add IDisposable interface",
                            (editor, cancellationToken) => editor.AddInterfaceType(typeDeclaration, IDisposableFactory.SystemIDisposable),
                            "add interface",
                            diagnostic);
                    }
                    else if (typeDeclaration is StructDeclarationSyntax structDeclaration)
                    {
                        context.RegisterCodeFix(
                            "Implement IDisposable.",
                            (editor, _) => editor.AddMethod(structDeclaration, MethodFactory.Dispose()),
                            "Struct",
                            diagnostic);
                    }
                    else if (typeDeclaration is ClassDeclarationSyntax classDeclaration &&
                             semanticModel.TryGetNamedType(classDeclaration, context.CancellationToken, out var type))
                    {
                        if (Disposable.IsAssignableFrom(type, semanticModel.Compilation) &&
                            type.TryFindFirstMethodRecursive("Dispose", x => x.IsVirtual, out var baseDispose))
                        {
                            context.RegisterCodeFix(
                                $"override {baseDispose}",
                                (editor, cancellationToken) => OverrideDisposeAsync(editor, cancellationToken),
                                "override",
                                diagnostic);

                            async Task OverrideDisposeAsync(DocumentEditor editor, CancellationToken cancellationToken)
                            {
                                var disposed = await editor.AddFieldAsync(
                                    classDeclaration,
                                    "disposed",
                                    Accessibility.Private,
                                    DeclarationModifiers.None,
                                    SyntaxFactory.ParseTypeName("bool"),
                                    cancellationToken).ConfigureAwait(false);

                                _ = editor.AddMethod(classDeclaration, MethodFactory.OverrideDispose(disposed, baseDispose !))
                                    .AddThrowIfDisposed(classDeclaration, disposed, cancellationToken);
                            }
                        }
                        else if (CanImplement())
                        {
                            switch (type)
                            {
                            case { IsSealed: true } :
Example #27
0
        /// <inheritdoc/>
        protected override async Task RegisterCodeFixesAsync(DocumentEditorCodeFixContext context)
        {
            var document   = context.Document;
            var syntaxRoot = await document.GetSyntaxRootAsync(context.CancellationToken)
                             .ConfigureAwait(false);

            var semanticModel = await 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))
                {
                    continue;
                }

                var argument = syntaxRoot.FindNode(diagnostic.Location.SourceSpan)
                               .FirstAncestorOrSelf <AttributeArgumentSyntax>();
                var attribute = argument.FirstAncestor <AttributeSyntax>();
                if (ValueConverter.TryGetConversionTypes(
                        attribute.FirstAncestor <ClassDeclarationSyntax>(),
                        semanticModel,
                        context.CancellationToken,
                        out var sourceType,
                        out var targetType))
                {
                    context.RegisterCodeFix(
                        $"Change to [ValueConversion(typeof({sourceType}), typeof({targetType}))].",
                        (e, _) => FixArgument(e, attribute, sourceType, targetType),
                        $"Change to [ValueConversion(typeof({sourceType}), typeof({targetType}))].",
                        diagnostic);
                }
            }
        }
Example #28
0
        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 InvocationExpressionSyntax invocation) &&
                    invocation.ArgumentList is ArgumentListSyntax argumentList)
                {
                    if (argumentList.Arguments.Count == 1)
                    {
                        context.RegisterCodeFix(
                            "Throw on error.",
                            (e, cancellationToken) => e.ReplaceNode(
                                argumentList,
                                x => x.AddArguments(SyntaxFactory.Argument(SyntaxFactory.NameColon("throwOnError"), SyntaxFactory.Token(SyntaxKind.None), SyntaxFactory.LiteralExpression(SyntaxKind.TrueLiteralExpression)))),
                            "Throw on error.",
                            diagnostic);
                    }
                    else if (argumentList.Arguments.Count == 2 &&
                             argumentList.Arguments.TrySingle(x => x.Expression.IsKind(SyntaxKind.FalseLiteralExpression), out var argument))
                    {
                        context.RegisterCodeFix(
                            "Throw on error.",
                            (e, cancellationToken) => e.ReplaceNode(
                                argument.Expression,
                                x => SyntaxFactory.LiteralExpression(SyntaxKind.TrueLiteralExpression).WithTriviaFrom(x)),
                            "Throw on error.",
                            diagnostic);
                    }
                }
            }
        }
        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(nameof(TypeSyntax), out var typeText))
                {
                    if (syntaxRoot.TryFindNode(diagnostic, out TypeSyntax typeSyntax) &&
                        typeSyntax.Parent is TypeOfExpressionSyntax)
                    {
                        context.RegisterCodeFix(
                            $"Change to: {typeText}.",
                            (editor, _) => editor.ReplaceNode(
                                typeSyntax,
                                x => SyntaxFactory.ParseTypeName(typeText)
                                .WithTriviaFrom(x)),
                            nameof(UseParameterTypeFix),
                            diagnostic);
                    }
                    else if (syntaxRoot.TryFindNode(diagnostic, out ExpressionSyntax expression))
                    {
                        context.RegisterCodeFix(
                            $"Change to: typeof({typeText}).",
                            (editor, _) => editor.ReplaceNode(
                                expression,
                                x => SyntaxFactory.ParseExpression($"typeof({typeText})")
                                .WithTriviaFrom(x)),
                            nameof(UseParameterTypeFix),
                            diagnostic);
                    }
                }
            }
        }
Example #30
0
        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 ExpressionSyntax? expression) &&
                    semanticModel.TryGetSymbol(expression, context.CancellationToken, out var symbol) &&
                    diagnostic.AdditionalLocations.TrySingle(out var valueLocation) &&
                    syntaxRoot.FindNode(valueLocation.SourceSpan) is ExpressionSyntax value &&
                    expression.TryFirstAncestor(out BlockSyntax? block))
                {
                    context.RegisterCodeFix(
                        $"Copy to local.",
                        (editor, _) =>
                    {
                        var identifierName = SyntaxFactory.IdentifierName(symbol.Name.ToFirstCharLower());
                        editor.ReplaceNode(
                            expression,
                            identifierName);
                        editor.InsertBefore(
                            block.Statements[0],
                            editor.Generator.LocalDeclarationStatement(identifierName.Identifier.ValueText, value));
                    },
                        nameof(CopyToLocalFix),
                        diagnostic);
                }
            }
        }