Skip to content

Commit

Permalink
S3655: Static properties and fields called Value (#7000)
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 263a4f8 commit 0612ef5
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 17 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,11 @@ protected override ProgramState PreProcessSimple(SymbolicContext context)
if (operationInstance.Kind == OperationKindEx.PropertyReference
&& operationInstance.ToPropertyReference() is var reference
&& reference.Property.Name == nameof(Nullable<int>.Value)
&& reference.Instance.Type.IsNullableValueType()
&& context.HasConstraint(reference.Instance, ObjectConstraint.Null))
&& reference.Instance is { } instance
&& instance.Type.IsNullableValueType()
&& context.HasConstraint(instance, ObjectConstraint.Null))
{
ReportIssue(reference.Instance, reference.Instance.Syntax.ToString());
ReportIssue(instance, instance.Syntax.ToString());
}
else if (operationInstance.Kind == OperationKindEx.Conversion
&& operationInstance.ToConversion() is var conversion
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -949,46 +949,99 @@ void Basics(MaybeInt i)
}
}

namespace TypeWithValueProperty
namespace TypeWithInstancePropertyCalledValue
{
class Test
{
void Basics1()
{
ClassWithValueProperty i = null;
_ = i.Value; // Compliant, ClassWithValueProperty not a nullable type
ClassWithPropertyCalledValue i = null;
_ = i.Value; // Compliant, not a nullable type
}

void Basics2()
{
ClassWithValueProperty i = null;
_ = i.APropertyNotCalledValue; // Compliant, ClassWithValuePropertyAndImplicitCast not a nullable type
ClassWithPropertyCalledValue i = null;
_ = i.APropertyNotCalledValue; // Compliant, not a nullable type
}

void ImplicitCast()
{
StructWithValuePropertyAndCastOperators i = null as int?; // Noncompliant, FP
_ = i.Value; // Compliant, ClassWithValuePropertyAndImplicitCast not a nullable type
StructWithPropertyCalledValueAndCastOperators i = null as int?; // Noncompliant, FP
_ = i.Value; // Compliant, not a nullable type
}

int ExplicitCast1 => ((StructWithValuePropertyAndCastOperators)(null as long?)).Value; // Noncompliant, FP, just gives 42
StructWithValuePropertyAndCastOperators ExplicitCast2 => (null as StructWithValuePropertyAndCastOperators?).Value; // Noncompliant, FP, just gives a struct
int ExplicitCast3 => (null as StructWithValuePropertyAndCastOperators?).Value.Value; // Noncompliant, FP, just gives 42
int ExplicitCast1 => ((StructWithPropertyCalledValueAndCastOperators)(null as long?)).Value; // Noncompliant, FP, just gives 42
StructWithPropertyCalledValueAndCastOperators ExplicitCast2 => (null as StructWithPropertyCalledValueAndCastOperators?).Value; // Noncompliant, FP, just gives a struct
int ExplicitCast3 => (null as StructWithPropertyCalledValueAndCastOperators?).Value.Value; // Noncompliant, FP, just gives 42
}

class ClassWithValueProperty
class ClassWithPropertyCalledValue
{
public int Value => 42;
public int APropertyNotCalledValue => 42;
}

struct StructWithValuePropertyAndCastOperators
struct StructWithPropertyCalledValueAndCastOperators
{
public int Value => 42;
public int APropertyNotCalledValue => 42;

public static implicit operator StructWithValuePropertyAndCastOperators(int? value) => new StructWithValuePropertyAndCastOperators();
public static explicit operator StructWithValuePropertyAndCastOperators(long? value) => new StructWithValuePropertyAndCastOperators();
public static implicit operator StructWithPropertyCalledValueAndCastOperators(int? value) => new StructWithPropertyCalledValueAndCastOperators();
public static explicit operator StructWithPropertyCalledValueAndCastOperators(long? value) => new StructWithPropertyCalledValueAndCastOperators();
}
}

namespace TypeWithStaticPropertyCalledValue
{
class Test
{
void Basics()
{
_ = ClassWithStaticPropertyCalledValue.Value; // Compliant, not on nullable value type
_ = ClassWithStaticPropertyCalledValue.Value.Value; // Compliant
_ = ClassWithStaticPropertyCalledValue.Value.Value.InstanceProperty; // Compliant
_ = ClassWithStaticPropertyCalledValue.Value.Value.InstanceProperty.Value; // Compliant
_ = new ClassWithInstancePropertyCalledValue().Value; // Compliant
}
}

class ClassWithStaticPropertyCalledValue
{
public ClassWithInstancePropertyCalledValue InstanceProperty => null;

public static ClassWithInstancePropertyCalledValue Value => null;
}

class ClassWithInstancePropertyCalledValue
{
public ClassWithStaticPropertyCalledValue Value => null;
}
}

namespace TypeWithStaticFieldCalledValue
{
class Test
{
void Basics()
{
_ = ClassWithStaticFieldCalledValue.Value; // Compliant, not on nullable value type
_ = ClassWithStaticFieldCalledValue.Value.Value; // Compliant
_ = ClassWithStaticFieldCalledValue.Value.Value.InstanceField; // Compliant
_ = ClassWithStaticFieldCalledValue.Value.Value.InstanceField.Value; // Compliant
_ = new ClassWithInstanceFieldCalledValue().Value; // Compliant
}
}

class ClassWithStaticFieldCalledValue
{
public ClassWithInstanceFieldCalledValue InstanceField = null;

public static ClassWithInstanceFieldCalledValue Value = null;
}

class ClassWithInstanceFieldCalledValue
{
public ClassWithStaticFieldCalledValue Value = null;
}
}

0 comments on commit 0612ef5

Please sign in to comment.