public override NullAbstractValue VisitConditionalAccess(IConditionalAccessOperation operation, object argument)
            {
                var leftValue  = Visit(operation.Operation, argument);
                var rightValue = Visit(operation.WhenNotNull, argument);

                switch (leftValue)
                {
                case NullAbstractValue.Null:
                    return(GetAbstractDefaultValue(operation.WhenNotNull.Type));

                case NullAbstractValue.NotNull:
                    return(rightValue);

                default:
                    return(NullAbstractValue.MaybeNull);
                }
            }
        public override TAbstractAnalysisValue VisitConditionalAccess(IConditionalAccessOperation operation, object argument)
        {
            var leftValue     = Visit(operation.Operation, argument);
            var whenNullValue = Visit(operation.WhenNotNull, argument);
            var leftNullValue = GetNullAbstractValue(operation.Operation);

            switch (leftNullValue)
            {
            case NullAbstractValue.Null:
                return(GetAbstractDefaultValue(operation.WhenNotNull.Type));

            case NullAbstractValue.NotNull:
                return(whenNullValue);

            default:
                var value1 = GetAbstractDefaultValue(operation.WhenNotNull.Type);
                return(ValueDomain.Merge(value1, whenNullValue));
            }
        }
        public bool TryCreate(IOperation operation, out AnalysisEntity analysisEntity)
        {
            if (_analysisEntityMap.TryGetValue(operation, out analysisEntity))
            {
                return(analysisEntity != null);
            }

            analysisEntity = null;
            ISymbol symbolOpt = null;
            ImmutableArray <AbstractIndex> indices = ImmutableArray <AbstractIndex> .Empty;
            IOperation instanceOpt = null;

            switch (operation)
            {
            case ILocalReferenceOperation localReference:
                symbolOpt = localReference.Local;
                break;

            case IParameterReferenceOperation parameterReference:
                symbolOpt = parameterReference.Parameter;
                break;

            case IMemberReferenceOperation memberReference:
                instanceOpt = memberReference.Instance;
                GetSymbolAndIndicesForMemberReference(memberReference, ref symbolOpt, ref indices);

                // Workaround for https://github.com/dotnet/roslyn/issues/22736 (IPropertyReferenceExpressions in IAnonymousObjectCreationExpression are missing a receiver).
                if (instanceOpt == null &&
                    symbolOpt != null &&
                    memberReference is IPropertyReferenceOperation propertyReference)
                {
                    instanceOpt = propertyReference.GetAnonymousObjectCreation();
                }

                break;

            case IArrayElementReferenceOperation arrayElementReference:
                instanceOpt = arrayElementReference.ArrayReference;
                indices     = CreateAbstractIndices(arrayElementReference.Indices);
                break;

            case IDynamicIndexerAccessOperation dynamicIndexerAccess:
                instanceOpt = dynamicIndexerAccess.Operation;
                indices     = CreateAbstractIndices(dynamicIndexerAccess.Arguments);
                break;

            case IConditionalAccessInstanceOperation conditionalAccessInstance:
                IConditionalAccessOperation conditionalAccess = conditionalAccessInstance.GetConditionalAccess();
                instanceOpt = conditionalAccess.Operation;
                if (conditionalAccessInstance.Parent is IMemberReferenceOperation memberReferenceParent)
                {
                    GetSymbolAndIndicesForMemberReference(memberReferenceParent, ref symbolOpt, ref indices);
                }
                break;

            case IInstanceReferenceOperation instanceReference:
                instanceOpt = instanceReference.GetInstance();
                if (instanceOpt == null)
                {
                    // Reference to this or base instance.
                    analysisEntity = ThisOrMeInstance;
                }
                else
                {
                    var instanceLocation = _getPointsToAbstractValueOpt(instanceReference);
                    analysisEntity = AnalysisEntity.Create(instanceReference, instanceLocation);
                }
                break;

            case IInvocationOperation invocation:
                symbolOpt   = invocation.TargetMethod;
                instanceOpt = invocation.Instance;
                break;

            case IConversionOperation conversion:
                return(TryCreate(conversion.Operand, out analysisEntity));

            case IParenthesizedOperation parenthesized:
                return(TryCreate(parenthesized.Operand, out analysisEntity));

            case IArgumentOperation argument:
                return(TryCreate(argument.Value, out analysisEntity));

            case IDeclarationExpressionOperation declarationExpression:
                switch (declarationExpression.Expression)
                {
                case ILocalReferenceOperation localReference:
                    return(TryCreateForSymbolDeclaration(localReference.Local, out analysisEntity));

                case ITupleOperation tupleOperation:
                    // TODO handle tuple operations
                    // https://github.com/dotnet/roslyn-analyzers/issues/1571
                    break;
                }

                break;

            default:
                break;
            }

            if (symbolOpt != null || !indices.IsEmpty)
            {
                TryCreate(symbolOpt, indices, operation.Type, instanceOpt, out analysisEntity);
            }

            _analysisEntityMap[operation] = analysisEntity;
            return(analysisEntity != null);
        }
Exemple #4
0
        public bool TryCreate(IOperation operation, out AnalysisEntity analysisEntity)
        {
            if (_analysisEntityMap.TryGetValue(operation, out analysisEntity))
            {
                return(analysisEntity != null);
            }

            analysisEntity = null;
            ISymbol symbolOpt = null;
            ImmutableArray <AbstractIndex> indices = ImmutableArray <AbstractIndex> .Empty;
            IOperation  instanceOpt = null;
            ITypeSymbol type        = operation.Type;

            switch (operation)
            {
            case ILocalReferenceOperation localReference:
                symbolOpt = localReference.Local;
                break;

            case IParameterReferenceOperation parameterReference:
                symbolOpt = parameterReference.Parameter;
                break;

            case IMemberReferenceOperation memberReference:
                instanceOpt = memberReference.Instance;
                GetSymbolAndIndicesForMemberReference(memberReference, ref symbolOpt, ref indices);

                // Workaround for https://github.com/dotnet/roslyn/issues/22736 (IPropertyReferenceExpressions in IAnonymousObjectCreationExpression are missing a receiver).
                if (instanceOpt == null &&
                    symbolOpt != null &&
                    memberReference is IPropertyReferenceOperation propertyReference)
                {
                    instanceOpt = propertyReference.GetAnonymousObjectCreation();
                }

                break;

            case IArrayElementReferenceOperation arrayElementReference:
                instanceOpt = arrayElementReference.ArrayReference;
                indices     = CreateAbstractIndices(arrayElementReference.Indices);
                break;

            case IDynamicIndexerAccessOperation dynamicIndexerAccess:
                instanceOpt = dynamicIndexerAccess.Operation;
                indices     = CreateAbstractIndices(dynamicIndexerAccess.Arguments);
                break;

            case IConditionalAccessInstanceOperation conditionalAccessInstance:
                IConditionalAccessOperation conditionalAccess = conditionalAccessInstance.GetConditionalAccess();
                instanceOpt = conditionalAccess.Operation;
                if (conditionalAccessInstance.Parent is IMemberReferenceOperation memberReferenceParent)
                {
                    GetSymbolAndIndicesForMemberReference(memberReferenceParent, ref symbolOpt, ref indices);
                }
                break;

            case IInstanceReferenceOperation instanceReference:
                if (_getPointsToAbstractValueOpt != null)
                {
                    instanceOpt = instanceReference.GetInstance(_getIsInsideAnonymousObjectInitializer());
                    if (instanceOpt == null)
                    {
                        // Reference to this or base instance.
                        analysisEntity = _interproceduralCallStackOpt != null && _interproceduralCallStackOpt.Peek().DescendantsAndSelf().Contains(instanceReference) ?
                                         _interproceduralThisOrMeInstanceForCallerOpt :
                                         ThisOrMeInstance;
                    }
                    else
                    {
                        var instanceLocation = _getPointsToAbstractValueOpt(instanceReference);
                        analysisEntity = AnalysisEntity.Create(instanceReference, instanceLocation);
                    }
                }
                break;

            case IInvocationOperation invocation:
                symbolOpt   = invocation.TargetMethod;
                instanceOpt = invocation.Instance;
                break;

            case IConversionOperation conversion:
                return(TryCreate(conversion.Operand, out analysisEntity));

            case IParenthesizedOperation parenthesized:
                return(TryCreate(parenthesized.Operand, out analysisEntity));

            case IArgumentOperation argument:
                return(TryCreate(argument.Value, out analysisEntity));

            case IFlowCaptureOperation flowCapture:
                analysisEntity = GetOrCreateForFlowCapture(flowCapture.Id, flowCapture.Value.Type, flowCapture);
                break;

            case IFlowCaptureReferenceOperation flowCaptureReference:
                analysisEntity = GetOrCreateForFlowCapture(flowCaptureReference.Id, flowCaptureReference.Type, flowCaptureReference);
                break;

            case IDeclarationExpressionOperation declarationExpression:
                switch (declarationExpression.Expression)
                {
                case ILocalReferenceOperation localReference:
                    return(TryCreateForSymbolDeclaration(localReference.Local, out analysisEntity));

                case ITupleOperation tupleOperation:
                    return(TryCreate(tupleOperation, out analysisEntity));
                }

                break;

            case IVariableDeclaratorOperation variableDeclarator:
                symbolOpt = variableDeclarator.Symbol;
                type      = variableDeclarator.Symbol.Type;
                break;

            case IDeclarationPatternOperation declarationPattern:
                var declaredLocal = declarationPattern.DeclaredSymbol as ILocalSymbol;
                symbolOpt = declaredLocal;
                type      = declaredLocal?.Type;
                break;

            default:
                break;
            }

            if (symbolOpt != null || !indices.IsEmpty)
            {
                TryCreate(symbolOpt, indices, type, instanceOpt, out analysisEntity);
            }

            _analysisEntityMap[operation] = analysisEntity;
            return(analysisEntity != null);
        }
Exemple #5
0
 public override IOperation VisitConditionalAccess(IConditionalAccessOperation operation, object argument)
 {
     return(new ConditionalAccessExpression(Visit(operation.WhenNotNull), Visit(operation.Operation), ((Operation)operation).SemanticModel, operation.Syntax, operation.Type, operation.ConstantValue, operation.IsImplicit));
 }
 public override void VisitConditionalAccess(IConditionalAccessOperation operation)
 {
     Assert.Equal(OperationKind.ConditionalAccess, operation.Kind);
     AssertEx.Equal(new[] { operation.Operation, operation.WhenNotNull }, operation.Children);
 }
Exemple #7
0
 public virtual void VisitConditionalAccess(IConditionalAccessOperation operation)
 {
     DefaultVisit(operation);
 }
Exemple #8
0
 public override void VisitConditionalAccess([NotNull] IConditionalAccessOperation operation)
 {
     base.VisitConditionalAccess(operation);
 }
        public override TAbstractAnalysisValue VisitConditionalAccessInstance(IConditionalAccessInstanceOperation operation, object argument)
        {
            IConditionalAccessOperation conditionalAccess = operation.GetConditionalAccess();

            return(GetCachedAbstractValue(conditionalAccess.Operation));
        }
Exemple #10
0
 public override bool VisitConditionalAccess([NotNull] IConditionalAccessOperation operation1,
                                             [CanBeNull] IOperation argument)
 {
     return(argument is IConditionalAccessOperation operation2 && AreBaseOperationsEqual(operation1, operation2));
 }