Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: DotNetAnalyzers/StyleCopAnalyzers
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 1.2.0-beta.553
Choose a base ref
...
head repository: DotNetAnalyzers/StyleCopAnalyzers
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 1.2.0-beta.556
Choose a head ref
  • 3 commits
  • 2 files changed
  • 2 contributors

Commits on Dec 20, 2023

  1. Copy the full SHA
    32646fb View commit details
  2. Fix review comments

    bjornhellander committed Dec 20, 2023
    Copy the full SHA
    e099358 View commit details
  3. Merge pull request #3760 from bjornhellander/feature/sa1131-left-expr…

    …essions
    
    Fix SA1131 to not treat "complex" expressions as a literal
    sharwell authored Dec 20, 2023
    Copy the full SHA
    73a46ae View commit details
Original file line number Diff line number Diff line change
@@ -521,7 +521,55 @@ public void Test()
[InlineData("Method1", "Const1", false)]
[InlineData("Method2", "Const1", false)]
[WorkItem(3677, "https://github.com/DotNetAnalyzers/StyleCopAnalyzers/issues/3677")]
public async Task TestMethodsAsync(string expr1, string expr2, bool shouldTrigger)
public async Task TestSimpleMethodsAsync(string expr1, string expr2, bool shouldTrigger)
{
await this.TestMethodAsync(expr1, expr2, shouldTrigger).ConfigureAwait(false);
}

[Theory]
[InlineData("TestClass.Method1", "arg", true)]
[InlineData("this.Method2", "arg", true)]
[InlineData("TestClass.Method1", "field1", true)]
[InlineData("this.Method2", "field1", true)]
[InlineData("TestClass.Method1", "field2", true)]
[InlineData("this.Method2", "field2", true)]
[InlineData("Const1", "TestClass.Method1", false)]
[InlineData("Const1", "this.Method2", false)]
[InlineData("TestClass.Method1", "Const1", false)]
[InlineData("this.Method2", "Const1", false)]
[InlineData("Method3<int>", "arg", true)]
[InlineData("TestClass.Method3<int>", "arg", true)]
[WorkItem(3759, "https://github.com/DotNetAnalyzers/StyleCopAnalyzers/issues/3759")]
public async Task TestComplexMethodsAsync(string expr1, string expr2, bool shouldTrigger)
{
await this.TestMethodAsync(expr1, expr2, shouldTrigger).ConfigureAwait(false);
}

[Theory]
[InlineData("==")]
[InlineData("!=")]
[InlineData(">=")]
[InlineData("<=")]
[InlineData(">")]
[InlineData("<")]
[WorkItem(3759, "https://github.com/DotNetAnalyzers/StyleCopAnalyzers/issues/3759")]
public async Task TestComplexLeftHandSideExpressionAsync(string @operator)
{
var testCode = $@"
using System;
public class TypeName
{{
public void Test(int x, int y, Func<int> a)
{{
var r1 = x + 1 {@operator} y;
var r2 = -x {@operator} y;
var r3 = a() {@operator} y;
}}
}}";
await VerifyCSharpDiagnosticAsync(testCode, DiagnosticResult.EmptyDiagnosticResults, CancellationToken.None).ConfigureAwait(false);
}

private async Task TestMethodAsync(string expr1, string expr2, bool shouldTrigger)
{
var testExpr = $"{expr1} == {expr2}";
var testCode = $@"
@@ -546,6 +594,10 @@ private static void Method1()
private void Method2()
{{
}}
private static void Method3<T>()
{{
}}
}}
";

@@ -572,6 +624,10 @@ private static void Method1()
private void Method2()
{{
}}
private static void Method3<T>()
{{
}}
}}
";

Original file line number Diff line number Diff line change
@@ -86,7 +86,11 @@ private static bool IsLiteral(ExpressionSyntax expression, SemanticModel semanti
switch (symbol)
{
case IFieldSymbol fieldSymbol when fieldSymbol.IsStatic && fieldSymbol.IsReadOnly:
case IMethodSymbol:
return true;

// NOTE: Without the when clause, this would also treat e.g unary or binary expressions as literals,
// since GetSymbolInfo returns the operator method in those cases.
case IMethodSymbol when expression is NameSyntax or MemberAccessExpressionSyntax:
return true;

default: