Skip to content

Conversation

@martin-strecker-sonarsource
Copy link
Contributor

Fixes #9096


namespace Microsoft.CodeAnalysis.Shared.Extensions;

[GeneratedCode("Copied from Roslyn", "ca66296efa86bd8078508fe7b38b91b415364f78")]
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

#if NET

[TestMethod]
public void UseAwaitableMethod_CS_Test() =>
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This snippet is for testing only and will be removed before merging

Copy link
Contributor

@zsolt-kolbay-sonarsource zsolt-kolbay-sonarsource left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. Left a bunch of polishing comments, but nothing major.


ReturnMethod(); // Noncompliant
_ = ReturnMethod(); // Noncompliant
this.ReturnMethod().ReturnMethod().ReturnMethod();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add the following test case:

        await ReturnMethod().ReturnMethodAsync(); // Noncompliant
//            ^^^^^^^^^^^^^^

public static C operator -(C c) => default(C);
public static C operator -(C c1, C c2) => default(C);
public static C operator !(C c) => default(C);
public static C operator ~(C c) => default(C);
Copy link
Contributor

@zsolt-kolbay-sonarsource zsolt-kolbay-sonarsource Apr 17, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The ~ operator is not used.

using System;

var ms = new MemoryStream();
ms.Dispose(); // Noncompliant {{Await DisposeAsync instead.}}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The rule can be extended to also raise a warning a using statement without the await keyword in an async context (or maybe as a new rule?).

using var ms1 = new MemoryStream(); // Noncompliant
await using var ms2 = new MemoryStream(); // Compliant

WDYT?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 That requires a different implementation. Please create a Rule Idea issue.

return wellKnownExtensionMethodContainer;
}

private static IEnumerable<IMethodSymbol> GetMethodSymbolsInScope(string methodName, WellKnownExtensionMethodContainer wellKnownExtensionMethodContainer,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Move this and the following method below FindAwaitableAlternatives.

@martin-strecker-sonarsource
Copy link
Contributor Author

Comment on lines +93 to +100
if (awaitableRoot is { Parent: AwaitExpressionSyntax })
{
return ImmutableArray<ISymbol>.Empty; // Invocation result is already awaited.
}
if (invocationExpression.EnclosingScope() is { } scope && !IsAsyncCodeBlock(scope))
{
return ImmutableArray<ISymbol>.Empty; // Not in an async scope
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The two conditions can be merged into a single if statement.

Copy link
Contributor

@zsolt-kolbay-sonarsource zsolt-kolbay-sonarsource left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@sonarqubecloud
Copy link

@sonarqubecloud
Copy link

Quality Gate Passed Quality Gate passed

Issues
0 New issues
0 Accepted issues

Measures
0 Security Hotspots
No data about Coverage
No data about Duplication

See analysis details on SonarCloud

@martin-strecker-sonarsource
Copy link
Contributor Author

Peach validation:

  • There are AD0001 -> fix is needed
  • FP/TP rate -> still needs to be done

Performance

The rule is about 3 times as expensive as other rules, like ImplementIDisposableCorrectly or InsteadOfAny. In some projects, it is 15 to 20 times as expensive.
On average it is 2% as expensive as SymbolicExecutionRunner, but can be up to 20-30% as expensive in some projects.
It is 40% as expensive as CopyPasteTokenAnalyzer, but can be up to 5 times as expensive.
The data is shown here.

@martin-strecker-sonarsource
Copy link
Contributor Author

Peach validation:

430 issues found. All are TP with the following exceptions:

Most of the violations originate from (in that order)

  • Stream
  • Database / EF
  • CancelationTokenSource
  • Custom user methods or nuget package methods
  • Dispose
  • XmlWriter

We also have found issues in razor files (@renderSection and the like).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

New Rule S6966: Awaitable method should be used

2 participants