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); } }
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(); }