Example #1
0
        public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context)
        {
            SyntaxNode root = await context.Document.GetSyntaxRootAsync(context.CancellationToken).ConfigureAwait(false);

            SyntaxNode node = root.FindNode(context.Span);

            SyntaxNode binaryExpressionSyntax = GetBinaryExpression(node);

            if (!IsEqualsOperator(binaryExpressionSyntax) && !IsNotEqualsOperator(binaryExpressionSyntax))
            {
                return;
            }

            SemanticModel model = await context.Document.GetSemanticModelAsync(context.CancellationToken).ConfigureAwait(false);

            INamedTypeSymbol systemSingleType = model.Compilation.GetTypeByMetadataName("System.Single");
            INamedTypeSymbol systemDoubleType = model.Compilation.GetTypeByMetadataName("System.Double");

            if (systemSingleType == null || systemDoubleType == null)
            {
                return;
            }

            FixResolution resolution = TryGetFixResolution(binaryExpressionSyntax, model, systemSingleType, systemDoubleType);

            if (resolution != null)
            {
                var action = CodeAction.Create(MicrosoftNetCoreAnalyzersResources.TestForNaNCorrectlyMessage,
                                               async ct => await ConvertToMethodInvocation(context, resolution).ConfigureAwait(false),
                                               equivalenceKey: MicrosoftNetCoreAnalyzersResources.TestForNaNCorrectlyMessage);

                context.RegisterCodeFix(action, context.Diagnostics);
            }
        }
Example #2
0
        public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context)
        {
            SyntaxNode root = await context.Document.GetSyntaxRootAsync(context.CancellationToken).ConfigureAwait(false);

            SyntaxNode node = root.FindNode(context.Span);

            SyntaxNode binaryExpressionSyntax = GetBinaryExpression(node);

            if (!IsEqualsOperator(binaryExpressionSyntax) && !IsNotEqualsOperator(binaryExpressionSyntax))
            {
                return;
            }

            SemanticModel model = await context.Document.GetSemanticModelAsync(context.CancellationToken).ConfigureAwait(false);

            FixResolution resolution = TryGetFixResolution(binaryExpressionSyntax, model);

            if (resolution != null)
            {
                var methodInvocationAction = CodeAction.Create(MicrosoftNetCoreAnalyzersResources.TestForEmptyStringsUsingStringLengthMessage,
                                                               async ct => await ConvertToMethodInvocation(context, resolution).ConfigureAwait(false),
                                                               equivalenceKey: "TestForEmptyStringCorrectlyUsingIsNullOrEmpty");

                context.RegisterCodeFix(methodInvocationAction, context.Diagnostics);

                var stringLengthAction = CodeAction.Create(MicrosoftNetCoreAnalyzersResources.TestForEmptyStringsUsingStringLengthMessage,
                                                           async ct => await ConvertToStringLengthComparison(context, resolution).ConfigureAwait(false),
                                                           equivalenceKey: "TestForEmptyStringCorrectlyUsingStringLength");

                context.RegisterCodeFix(stringLengthAction, context.Diagnostics);
            }
        }
        private static async Task <Document> ConvertToMethodInvocation(CodeFixContext context, FixResolution fixResolution)
        {
            DocumentEditor editor = await DocumentEditor.CreateAsync(context.Document, context.CancellationToken).ConfigureAwait(false);

            SyntaxNode typeNameSyntax              = editor.Generator.TypeExpression(SpecialType.System_String);
            SyntaxNode nullOrEmptyMemberSyntax     = editor.Generator.MemberAccessExpression(typeNameSyntax, "IsNullOrEmpty");
            SyntaxNode nullOrEmptyInvocationSyntax = editor.Generator.InvocationExpression(nullOrEmptyMemberSyntax, fixResolution.ComparisonOperand.WithoutTrailingTrivia());

            SyntaxNode replacementSyntax          = fixResolution.UsesEqualsOperator ? nullOrEmptyInvocationSyntax : editor.Generator.LogicalNotExpression(nullOrEmptyInvocationSyntax);
            SyntaxNode replacementAnnotatedSyntax = replacementSyntax.WithAdditionalAnnotations(Formatter.Annotation).WithTriviaFrom(fixResolution.BinaryExpressionSyntax);

            editor.ReplaceNode(fixResolution.BinaryExpressionSyntax, replacementAnnotatedSyntax);

            return(editor.GetChangedDocument());
        }
        private async Task <Document> ConvertToStringLengthComparison(CodeFixContext context, FixResolution fixResolution)
        {
            DocumentEditor editor = await DocumentEditor.CreateAsync(context.Document, context.CancellationToken).ConfigureAwait(false);

            SyntaxNode leftOperand  = GetLeftOperand(fixResolution.BinaryExpressionSyntax);
            SyntaxNode rightOperand = GetRightOperand(fixResolution.BinaryExpressionSyntax);

            // Take the below example:
            //   if (f == String.Empty) ...
            // The comparison operand, f, will now become 'f.Length' and a the other operand will become '0'
            SyntaxNode zeroLengthSyntax = editor.Generator.LiteralExpression(0);

            if (leftOperand == fixResolution.ComparisonOperand)
            {
                leftOperand  = editor.Generator.MemberAccessExpression(leftOperand, "Length");
                rightOperand = zeroLengthSyntax.WithTriviaFrom(rightOperand);
            }
            else
            {
                leftOperand  = zeroLengthSyntax;
                rightOperand = editor.Generator.MemberAccessExpression(rightOperand.WithoutTrivia(), "Length");
            }

            SyntaxNode replacementSyntax = fixResolution.UsesEqualsOperator ?
                                           editor.Generator.ValueEqualsExpression(leftOperand, rightOperand) :
                                           editor.Generator.ValueNotEqualsExpression(leftOperand, rightOperand);

            SyntaxNode replacementAnnotatedSyntax = replacementSyntax.WithAdditionalAnnotations(Formatter.Annotation);

            editor.ReplaceNode(fixResolution.BinaryExpressionSyntax, replacementAnnotatedSyntax);

            return(editor.GetChangedDocument());
        }
        private async Task <Document> ConvertToMethodInvocation(CodeFixContext context, FixResolution fixResolution)
        {
            DocumentEditor editor = await DocumentEditor.CreateAsync(context.Document, context.CancellationToken).ConfigureAwait(false);

            SyntaxNode typeNameSyntax            = editor.Generator.TypeExpression(fixResolution.FloatingSystemType);
            SyntaxNode nanMemberSyntax           = editor.Generator.MemberAccessExpression(typeNameSyntax, "IsNaN");
            SyntaxNode nanMemberInvocationSyntax = editor.Generator.InvocationExpression(nanMemberSyntax, fixResolution.ComparisonOperand);

            SyntaxNode replacementSyntax          = fixResolution.UsesEqualsOperator ? nanMemberInvocationSyntax : editor.Generator.LogicalNotExpression(nanMemberInvocationSyntax);
            SyntaxNode replacementAnnotatedSyntax = replacementSyntax.WithAdditionalAnnotations(Formatter.Annotation);

            editor.ReplaceNode(fixResolution.BinaryExpressionSyntax, replacementAnnotatedSyntax);

            return(editor.GetChangedDocument());
        }
        private async Task<Document> ConvertToMethodInvocation(CodeFixContext context, FixResolution fixResolution)
        {
            DocumentEditor editor = await DocumentEditor.CreateAsync(context.Document, context.CancellationToken).ConfigureAwait(false);

            SyntaxNode typeNameSyntax = editor.Generator.TypeExpression(fixResolution.FloatingSystemType);
            SyntaxNode nanMemberSyntax = editor.Generator.MemberAccessExpression(typeNameSyntax, "IsNaN");
            SyntaxNode nanMemberInvocationSyntax = editor.Generator.InvocationExpression(nanMemberSyntax, fixResolution.ComparisonOperand);

            SyntaxNode replacementSyntax = fixResolution.UsesEqualsOperator ? nanMemberInvocationSyntax : editor.Generator.LogicalNotExpression(nanMemberInvocationSyntax);
            SyntaxNode replacementAnnotatedSyntax = replacementSyntax.WithAdditionalAnnotations(Formatter.Annotation);

            editor.ReplaceNode(fixResolution.BinaryExpressionSyntax, replacementAnnotatedSyntax);

            return editor.GetChangedDocument();
        }