Skip to content

Commit

Permalink
S3655: Fields with methods, local functions, yield and async (#6981)
Browse files Browse the repository at this point in the history
  • Loading branch information
antonioaversa authored and pavel-mikula-sonarsource committed Apr 4, 2023
1 parent 6385ce6 commit e34f83d
Showing 1 changed file with 114 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

class Basics
{
Expand Down Expand Up @@ -736,6 +737,119 @@ void RefParams(int? iParam)
}
}

class MutableField
{
int? theField;

void Basics()
{
_ = theField.Value; // Compliant, unknown

theField = null;
_ = theField.Value; // Noncompliant, empty
_ = theField.Value; // Compliant, when reached the ".Value" above implies theField is not null
}

void LocalFunctions()
{
theField = 42;
LocalFunctionChangingTheField();
_ = theField.Value; // Compliant, unknown

theField = null;
LocalFunctionChangingTheField();
_ = theField.Value; // Noncompliant, FP, local functions don't reset the state

theField = 42;
LocalFunctionNotChangingTheField();
_ = theField.Value; // Compliant, unknown

void LocalFunctionChangingTheField() => theField = null;
void LocalFunctionNotChangingTheField() { }
}

void Methods()
{
theField = 42;
MethodChangingTheField();
_ = theField.Value; // Compliant, unknown

theField = null;
MethodChangingTheField();
_ = theField.Value; // Compliant, instance methods reset the state

theField = 42;
MethodNotChangingTheField();
_ = theField.Value; // Compliant, unknown

void LocalFunctionChangingTheField() => theField = null;
void LocalFunctionNotChangingTheField() { }
}

void MethodChangingTheField() => theField = null;

void MethodNotChangingTheField() { }

IEnumerable<int> WithYield()
{
_ = theField.Value; // Compliant, unknown
yield return 42;

theField = null;
yield return 42;
_ = theField.Value; // Noncompliant, FP, should be unknown

theField = 42;
yield return 42;
_ = theField.Value; // Compliant, unknown

theField = null;
yield return theField.Value; // Noncompliant, empty
_ = theField.Value; // Compliant, unknown

theField = null;
yield break;
_ = theField.Value; // Compliant, unreachable
}

async Task WithAsyncAwait()
{
_ = theField.Value; // Compliant, unknown
await AnAsyncOperation();

theField = null;
await AnAsyncOperation();
_ = theField.Value; // Compliant, unknown

theField = 42;
await AnAsyncOperation();
_ = theField.Value; // Compliant, unknown

theField = null;
await AnotherAsyncOperation(theField.Value); // Noncompliant, empty
_ = theField.Value; // Compliant, unknown

theField = null;
await AnAsyncOperation();
_ = theField.Value; // Compliant, unknown

var task = AnAsyncOperation();
theField = null;
await task;
_ = theField.Value; // Compliant, unknown

theField = await AnAsyncOperation();
_ = theField.Value; // Compliant, unknown

theField = null;
theField = await AnotherAsyncOperation(theField.Value); // Noncompliant, empty
_ = theField.Value; // Compliant, unknown

async Task<int?> AnAsyncOperation() => await Task.FromResult(42);
async Task<int?> AnotherAsyncOperation(int i) => await Task.FromResult(42);
}
}

namespace WithAliases
{
using MaybeInt = Nullable<System.Int32>;
Expand Down

0 comments on commit e34f83d

Please sign in to comment.