diff --git a/analyzers/src/SonarAnalyzer.Common/SymbolicExecution/Roslyn/Extensions/IInvocationOperationExtensions.cs b/analyzers/src/SonarAnalyzer.Common/SymbolicExecution/Roslyn/Extensions/IInvocationOperationExtensions.cs index ff2b29ef8c5..a5cc6a13b66 100644 --- a/analyzers/src/SonarAnalyzer.Common/SymbolicExecution/Roslyn/Extensions/IInvocationOperationExtensions.cs +++ b/analyzers/src/SonarAnalyzer.Common/SymbolicExecution/Roslyn/Extensions/IInvocationOperationExtensions.cs @@ -43,7 +43,7 @@ public static bool HasThisReceiver(this IInvocationOperationWrapper invocation, && !invocation.Arguments.IsEmpty && state.ResolveCaptureAndUnwrapConversion(invocation.Arguments[0].ToArgument().Value).Kind == OperationKindEx.InstanceReference); - public static IOperation EffectiveInstance(this IInvocationOperationWrapper invocation, ProgramState state) => + public static IOperation Target(this IInvocationOperationWrapper invocation, ProgramState state) => invocation.Instance ?? (invocation.TargetMethod.IsExtensionMethod ? state.ResolveCaptureAndUnwrapConversion(invocation.Arguments[0].ToArgument().Value) diff --git a/analyzers/src/SonarAnalyzer.Common/SymbolicExecution/Roslyn/OperationProcessors/CollectionTracker.cs b/analyzers/src/SonarAnalyzer.Common/SymbolicExecution/Roslyn/OperationProcessors/CollectionTracker.cs index 8b66d5b988b..d2a4c2bfaee 100644 --- a/analyzers/src/SonarAnalyzer.Common/SymbolicExecution/Roslyn/OperationProcessors/CollectionTracker.cs +++ b/analyzers/src/SonarAnalyzer.Common/SymbolicExecution/Roslyn/OperationProcessors/CollectionTracker.cs @@ -149,7 +149,7 @@ public static ProgramState LearnFrom(ProgramState state, IInvocationOperationWra { return state.SetOperationConstraint(invocation, constraint); } - if (invocation.EffectiveInstance(state) is { } instance && instance.Type.DerivesOrImplementsAny(CollectionTypes)) + if (invocation.Target(state) is { } instance && instance.Type.DerivesOrImplementsAny(CollectionTypes)) { var targetMethod = invocation.TargetMethod; var symbolValue = state[instance] ?? SymbolicValue.Empty; @@ -182,7 +182,7 @@ private static NumberConstraint EnumerableCountConstraint(ProgramState state, II { if (invocation.TargetMethod.Is(KnownType.System_Linq_Enumerable, nameof(Enumerable.Count))) { - if (invocation.EffectiveInstance(state).TrackedSymbol(state) is { } symbol + if (invocation.Target(state).TrackedSymbol(state) is { } symbol && state[symbol]?.Constraint() is { } collection) { if (collection == CollectionConstraint.Empty) diff --git a/analyzers/src/SonarAnalyzer.Common/SymbolicExecution/Roslyn/OperationProcessors/Invocation.Enumerable.cs b/analyzers/src/SonarAnalyzer.Common/SymbolicExecution/Roslyn/OperationProcessors/Invocation.Enumerable.cs index 0377a0d8cf0..95704728886 100644 --- a/analyzers/src/SonarAnalyzer.Common/SymbolicExecution/Roslyn/OperationProcessors/Invocation.Enumerable.cs +++ b/analyzers/src/SonarAnalyzer.Common/SymbolicExecution/Roslyn/OperationProcessors/Invocation.Enumerable.cs @@ -98,7 +98,7 @@ private static ProgramState[] ProcessLinqEnumerableAndQueryable(ProgramState sta static IEnumerable ProcessElementOrDefaultMethods(ProgramState state, IInvocationOperationWrapper invocation) { - var constraint = invocation.EffectiveInstance(state).TrackedSymbol(state) is { } instanceSymbol + var constraint = invocation.Target(state).TrackedSymbol(state) is { } instanceSymbol && GetElementType(instanceSymbol) is { } elementType && (elementType.IsReferenceType || elementType.IsNullableValueType()) ? state[instanceSymbol]?.Constraint() @@ -119,7 +119,7 @@ static IEnumerable ProcessElementOrDefaultMethods(ProgramState sta private static ProgramState[] ProcessElementExistsCheckMethods(ProgramState state, IInvocationOperationWrapper invocation) { - if (ElementExistsCheckMethods.Contains(invocation.TargetMethod.Name) && invocation.EffectiveInstance(state).TrackedSymbol(state) is { } instanceSymbol) + if (ElementExistsCheckMethods.Contains(invocation.TargetMethod.Name) && invocation.Target(state).TrackedSymbol(state) is { } instanceSymbol) { return state[instanceSymbol]?.Constraint() switch { diff --git a/analyzers/src/SonarAnalyzer.Common/SymbolicExecution/Roslyn/RuleChecks/EmptyCollectionsShouldNotBeEnumeratedBase.cs b/analyzers/src/SonarAnalyzer.Common/SymbolicExecution/Roslyn/RuleChecks/EmptyCollectionsShouldNotBeEnumeratedBase.cs index 9be80460501..499d8a3fcf8 100644 --- a/analyzers/src/SonarAnalyzer.Common/SymbolicExecution/Roslyn/RuleChecks/EmptyCollectionsShouldNotBeEnumeratedBase.cs +++ b/analyzers/src/SonarAnalyzer.Common/SymbolicExecution/Roslyn/RuleChecks/EmptyCollectionsShouldNotBeEnumeratedBase.cs @@ -97,7 +97,7 @@ public override void ExecutionCompleted() protected override ProgramState PreProcessSimple(SymbolicContext context) { if (context.Operation.Instance.AsInvocation() is { } invocation - && invocation.EffectiveInstance(context.State) is { } instance + && invocation.Target(context.State) is { } instance && RaisingMethods.Contains(invocation.TargetMethod.Name)) { if (context.State[instance]?.HasConstraint(CollectionConstraint.Empty) is true) diff --git a/analyzers/tests/SonarAnalyzer.Test/SymbolicExecution/Roslyn/IInvocationOperationExtensionsTest.cs b/analyzers/tests/SonarAnalyzer.Test/SymbolicExecution/Roslyn/IInvocationOperationExtensionsTest.cs index 25b61f7ff28..7578cea74d7 100644 --- a/analyzers/tests/SonarAnalyzer.Test/SymbolicExecution/Roslyn/IInvocationOperationExtensionsTest.cs +++ b/analyzers/tests/SonarAnalyzer.Test/SymbolicExecution/Roslyn/IInvocationOperationExtensionsTest.cs @@ -57,7 +57,7 @@ public static void ExtensionMethod(this Sample sample) {} var (tree, model) = TestHelper.CompileCS(code); var invocationSyntax = tree.GetRoot().DescendantNodesAndSelf().OfType().First(); var operation = IInvocationOperationWrapper.FromOperation(model.GetOperation(invocationSyntax)); - operation.EffectiveInstance(ProgramState.Empty).Should().NotBeNull().And.BeAssignableTo().Which.Kind.Should().Be(kind); + operation.Target(ProgramState.Empty).Should().NotBeNull().And.BeAssignableTo().Which.Kind.Should().Be(kind); } [DataTestMethod] @@ -96,6 +96,6 @@ End Module var (tree, model) = TestHelper.CompileVB(code); var invocationSyntax = tree.GetRoot().DescendantNodesAndSelf().OfType().First(); var operation = IInvocationOperationWrapper.FromOperation(model.GetOperation(invocationSyntax)); - operation.EffectiveInstance(ProgramState.Empty).Should().NotBeNull().And.BeAssignableTo().Which.Kind.Should().Be(kind); + operation.Target(ProgramState.Empty).Should().NotBeNull().And.BeAssignableTo().Which.Kind.Should().Be(kind); } }