提交 64668f86 编写于 作者: S Sam Harwell

Remove dotnet_style_prefer_is_object_for_negated_null_checks

The code is updated to always assume this is true.
上级 6e7a18d9
......@@ -72,7 +72,7 @@ void M(string s)
}
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsUseIsNullCheck)]
public async Task TestNotEquality1()
public async Task TestNotEquality()
{
await TestInRegularAndScriptAsync(
@"using System;
......@@ -98,35 +98,7 @@ void M(string s)
}
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsUseIsNullCheck)]
public async Task TestNotEquality2()
{
await TestInRegularAndScriptAsync(
@"using System;
class C
{
void M(string s)
{
if ([||](object)s != null)
return;
}
}",
@"using System;
class C
{
void M(string s)
{
if (!(s is null))
return;
}
}",
options: ImmutableDictionary<OptionKey, object>.Empty
.SetItem(new OptionKey(CodeStyleOptions.PreferIsObjectForNegatedNullChecksChecks, LanguageNames.CSharp), false));
}
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsUseIsNullCheck)]
public async Task TestNotEqualitySwapped1()
public async Task TestNotEqualitySwapped()
{
await TestInRegularAndScriptAsync(
@"using System;
......@@ -151,34 +123,6 @@ void M(string s)
}");
}
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsUseIsNullCheck)]
public async Task TestNotEqualitySwapped2()
{
await TestInRegularAndScriptAsync(
@"using System;
class C
{
void M(string s)
{
if ([||]null != (object)s)
return;
}
}",
@"using System;
class C
{
void M(string s)
{
if (!(s is null))
return;
}
}",
options: ImmutableDictionary<OptionKey, object>.Empty
.SetItem(new OptionKey(CodeStyleOptions.PreferIsObjectForNegatedNullChecksChecks, LanguageNames.CSharp), false));
}
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsUseIsNullCheck)]
public async Task TestMissingPreCSharp7()
{
......
......@@ -125,7 +125,7 @@ void M(string s)
}
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsUseIsNullCheck)]
public async Task TestNegated1()
public async Task TestNegated()
{
await TestInRegularAndScriptAsync(
@"using System;
......@@ -150,34 +150,6 @@ void M(string s)
}");
}
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsUseIsNullCheck)]
public async Task TestNegated2()
{
await TestInRegularAndScriptAsync(
@"using System;
class C
{
void M(string s)
{
if (![||]ReferenceEquals(null, s))
return;
}
}",
@"using System;
class C
{
void M(string s)
{
if (!(s is null))
return;
}
}",
options: ImmutableDictionary<OptionKey, object>.Empty
.SetItem(new OptionKey(CodeStyleOptions.PreferIsObjectForNegatedNullChecksChecks, LanguageNames.CSharp), false));
}
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsUseIsNullCheck)]
public async Task TestNotInCSharp6()
{
......
......@@ -8,7 +8,6 @@
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.CodeActions;
using Microsoft.CodeAnalysis.CodeFixes;
using Microsoft.CodeAnalysis.CodeStyle;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.Diagnostics;
using Microsoft.CodeAnalysis.Editing;
......@@ -41,13 +40,10 @@ public override Task RegisterCodeFixesAsync(CodeFixContext context)
return Task.CompletedTask;
}
protected override async Task FixAllAsync(
protected override Task FixAllAsync(
Document document, ImmutableArray<Diagnostic> diagnostics,
SyntaxEditor editor, CancellationToken cancellationToken)
{
var options = await document.GetOptionsAsync(cancellationToken).ConfigureAwait(false);
var preferIsObject = options.GetOption(CodeStyleOptions.PreferIsObjectForNegatedNullChecksChecks);
foreach (var diagnostic in diagnostics)
{
if (!IsSupportedDiagnostic(diagnostic))
......@@ -59,11 +55,13 @@ public override Task RegisterCodeFixesAsync(CodeFixContext context)
editor.ReplaceNode(
binary,
(current, g) => Rewrite((BinaryExpressionSyntax)current, preferIsObject));
(current, g) => Rewrite((BinaryExpressionSyntax)current));
}
return Task.CompletedTask;
}
private static ExpressionSyntax Rewrite(BinaryExpressionSyntax binary, bool preferIsObject)
private static ExpressionSyntax Rewrite(BinaryExpressionSyntax binary)
{
var isPattern = RewriteWorker(binary);
if (binary.IsKind(SyntaxKind.EqualsExpression))
......@@ -71,23 +69,13 @@ private static ExpressionSyntax Rewrite(BinaryExpressionSyntax binary, bool pref
return isPattern;
}
if (preferIsObject)
{
// convert: (object)expr != null to expr is object
return SyntaxFactory
.BinaryExpression(
SyntaxKind.IsExpression,
isPattern.Expression,
SyntaxFactory.PredefinedType(SyntaxFactory.Token(SyntaxKind.ObjectKeyword)))
.WithTriviaFrom(isPattern);
}
else
{
// convert: (object)expr != null to !(expr is null)
return SyntaxFactory.PrefixUnaryExpression(
SyntaxKind.LogicalNotExpression,
SyntaxFactory.ParenthesizedExpression(isPattern.WithoutTrivia())).WithTriviaFrom(isPattern);
}
// convert: (object)expr != null to expr is object
return SyntaxFactory
.BinaryExpression(
SyntaxKind.IsExpression,
isPattern.Expression,
SyntaxFactory.PredefinedType(SyntaxFactory.Token(SyntaxKind.ObjectKeyword)))
.WithTriviaFrom(isPattern);
}
private static IsPatternExpressionSyntax RewriteWorker(BinaryExpressionSyntax binary)
......
......@@ -17,9 +17,9 @@ protected override string GetIsNullTitle()
protected override string GetIsNotNullTitle()
=> GetIsNullTitle();
private static SyntaxNode CreateEqualsNullCheck(SyntaxNode argument, SyntaxKind comparisonOperator)
private static SyntaxNode CreateEqualsNullCheck(SyntaxNode argument)
=> SyntaxFactory.BinaryExpression(
comparisonOperator,
SyntaxKind.EqualsExpression,
(ExpressionSyntax)argument,
SyntaxFactory.LiteralExpression(SyntaxKind.NullLiteralExpression)).Parenthesize();
......@@ -28,29 +28,22 @@ private static SyntaxNode CreateIsNullCheck(SyntaxNode argument)
(ExpressionSyntax)argument,
SyntaxFactory.ConstantPattern(SyntaxFactory.LiteralExpression(SyntaxKind.NullLiteralExpression))).Parenthesize();
private static SyntaxNode CreateIsNotNullCheck(SyntaxNode notExpression, SyntaxNode argument, bool preferIsObject)
private static SyntaxNode CreateIsNotNullCheck(SyntaxNode argument)
{
if (preferIsObject)
{
return SyntaxFactory
.BinaryExpression(
SyntaxKind.IsExpression,
(ExpressionSyntax)argument,
SyntaxFactory.PredefinedType(SyntaxFactory.Token(SyntaxKind.ObjectKeyword)))
.Parenthesize();
}
return ((PrefixUnaryExpressionSyntax)notExpression).WithOperand((ExpressionSyntax)CreateIsNullCheck(argument));
return SyntaxFactory
.BinaryExpression(
SyntaxKind.IsExpression,
(ExpressionSyntax)argument,
SyntaxFactory.PredefinedType(SyntaxFactory.Token(SyntaxKind.ObjectKeyword)))
.Parenthesize();
}
protected override SyntaxNode CreateNullCheck(SyntaxNode argument, bool isUnconstrainedGeneric)
=> isUnconstrainedGeneric
? CreateEqualsNullCheck(argument, SyntaxKind.EqualsExpression)
? CreateEqualsNullCheck(argument)
: CreateIsNullCheck(argument);
protected override SyntaxNode CreateNotNullCheck(SyntaxNode notExpression, SyntaxNode argument, bool preferIsObject, bool isUnconstrainedGeneric)
=> isUnconstrainedGeneric && !preferIsObject
? CreateEqualsNullCheck(argument, SyntaxKind.NotEqualsExpression)
: CreateIsNotNullCheck(notExpression, argument, preferIsObject);
protected override SyntaxNode CreateNotNullCheck(SyntaxNode argument)
=> CreateIsNotNullCheck(argument);
}
}
......@@ -7,7 +7,6 @@
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.CodeActions;
using Microsoft.CodeAnalysis.CodeFixes;
using Microsoft.CodeAnalysis.CodeStyle;
using Microsoft.CodeAnalysis.Diagnostics;
using Microsoft.CodeAnalysis.Editing;
using Microsoft.CodeAnalysis.LanguageServices;
......@@ -27,7 +26,7 @@ public override ImmutableArray<string> FixableDiagnosticIds
protected abstract string GetIsNullTitle();
protected abstract string GetIsNotNullTitle();
protected abstract SyntaxNode CreateNullCheck(SyntaxNode argument, bool isUnconstrainedGeneric);
protected abstract SyntaxNode CreateNotNullCheck(SyntaxNode notExpression, SyntaxNode argument, bool preferIsObject, bool isUnconstrainedGeneric);
protected abstract SyntaxNode CreateNotNullCheck(SyntaxNode argument);
private static bool IsSupportedDiagnostic(Diagnostic diagnostic)
=> diagnostic.Properties[UseIsNullConstants.Kind] == UseIsNullConstants.ReferenceEqualsKey;
......@@ -48,13 +47,11 @@ public override Task RegisterCodeFixesAsync(CodeFixContext context)
return Task.CompletedTask;
}
protected override async Task FixAllAsync(
protected override Task FixAllAsync(
Document document, ImmutableArray<Diagnostic> diagnostics,
SyntaxEditor editor, CancellationToken cancellationToken)
{
var syntaxFacts = document.GetLanguageService<ISyntaxFactsService>();
var options = await document.GetOptionsAsync(cancellationToken).ConfigureAwait(false);
var preferIsObject = options.GetOption(CodeStyleOptions.PreferIsObjectForNegatedNullChecksChecks);
// Order in reverse so we process inner diagnostics before outer diagnostics.
// Otherwise, we won't be able to find the nodes we want to replace if they're
......@@ -77,13 +74,15 @@ public override Task RegisterCodeFixesAsync(CodeFixContext context)
var toReplace = negate ? invocation.Parent : invocation;
var replacement = negate
? CreateNotNullCheck(invocation.Parent, argument, preferIsObject, isUnconstrainedGeneric)
? CreateNotNullCheck(argument)
: CreateNullCheck(argument, isUnconstrainedGeneric);
editor.ReplaceNode(
toReplace,
replacement.WithTriviaFrom(toReplace));
}
return Task.CompletedTask;
}
private class MyCodeAction : CodeAction.DocumentChangeAction
......
......@@ -24,7 +24,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.UseIsNullCheck
SyntaxFactory.NothingLiteralExpression(SyntaxFactory.Token(SyntaxKind.NothingKeyword))).Parenthesize()
End Function
Protected Overrides Function CreateNotNullCheck(notExpression As SyntaxNode, argument As SyntaxNode, preferIsObject As Boolean, isUnconstrainedGeneric As Boolean) As SyntaxNode
Protected Overrides Function CreateNotNullCheck(argument As SyntaxNode) As SyntaxNode
Return SyntaxFactory.IsNotExpression(
DirectCast(argument, ExpressionSyntax).Parenthesize(),
SyntaxFactory.NothingLiteralExpression(SyntaxFactory.Token(SyntaxKind.NothingKeyword))).Parenthesize()
......
......@@ -74,7 +74,6 @@ dotnet_style_prefer_conditional_expression_over_return = true:silent
dotnet_style_prefer_inferred_anonymous_type_member_names = true:suggestion
dotnet_style_prefer_inferred_tuple_names = true:suggestion
dotnet_style_prefer_is_null_check_over_reference_equality_method = true:suggestion
dotnet_style_prefer_is_object_for_negated_null_checks = true
# Field preferences
dotnet_style_readonly_field = true:suggestion
......@@ -202,7 +201,6 @@ dotnet_style_prefer_conditional_expression_over_return = true:silent
dotnet_style_prefer_inferred_anonymous_type_member_names = true:suggestion
dotnet_style_prefer_inferred_tuple_names = true:suggestion
dotnet_style_prefer_is_null_check_over_reference_equality_method = true:suggestion
dotnet_style_prefer_is_object_for_negated_null_checks = true
# Field preferences
dotnet_style_readonly_field = true:suggestion
......
......@@ -73,7 +73,6 @@ dotnet_style_prefer_conditional_expression_over_return = true:silent
dotnet_style_prefer_inferred_anonymous_type_member_names = true:suggestion
dotnet_style_prefer_inferred_tuple_names = true:suggestion
dotnet_style_prefer_is_null_check_over_reference_equality_method = true:suggestion
dotnet_style_prefer_is_object_for_negated_null_checks = true
# Field preferences
dotnet_style_readonly_field = true:suggestion
......@@ -282,7 +281,6 @@ dotnet_style_prefer_conditional_expression_over_return = true:silent
dotnet_style_prefer_inferred_anonymous_type_member_names = true:suggestion
dotnet_style_prefer_inferred_tuple_names = true:suggestion
dotnet_style_prefer_is_null_check_over_reference_equality_method = true:suggestion
dotnet_style_prefer_is_object_for_negated_null_checks = true
# Field preferences
dotnet_style_readonly_field = true:suggestion
......
......@@ -196,14 +196,6 @@ private static PerLanguageOption<T> CreateOption<T>(OptionGroup group, string na
EditorConfigStorageLocation.ForBoolCodeStyleOption("dotnet_style_prefer_is_null_check_over_reference_equality_method"),
new RoamingProfileStorageLocation($"TextEditor.%LANGUAGE%.Specific.{nameof(PreferIsNullCheckOverReferenceEqualityMethod)}") });
internal static readonly PerLanguageOption<bool> PreferIsObjectForNegatedNullChecksChecks = CreateOption(
CodeStyleOptionGroups.ExpressionLevelPreferences,
nameof(PreferIsObjectForNegatedNullChecksChecks),
defaultValue: true,
storageLocations: new OptionStorageLocation[] {
EditorConfigStorageLocation.ForBoolOption("dotnet_style_prefer_is_object_for_negated_null_checks"),
new RoamingProfileStorageLocation($"TextEditor.%LANGUAGE%.Specific.{nameof(PreferIsObjectForNegatedNullChecksChecks)}") });
internal static readonly PerLanguageOption<CodeStyleOption<bool>> PreferConditionalExpressionOverAssignment = CreateOption(
CodeStyleOptionGroups.ExpressionLevelPreferences, nameof(PreferConditionalExpressionOverAssignment),
defaultValue: TrueWithSilentEnforcement,
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册