예제 #1
0
        private AnalysisEntity(
            ISymbol?symbol,
            ImmutableArray <AbstractIndex> indices,
            SyntaxNode?instanceReferenceOperationSyntax,
            InterproceduralCaptureId?captureId,
            PointsToAbstractValue location,
            ITypeSymbol type,
            AnalysisEntity?parent,
            bool isThisOrMeInstance)
        {
            Debug.Assert(!indices.IsDefault);
            Debug.Assert(symbol != null || !indices.IsEmpty || instanceReferenceOperationSyntax != null || captureId.HasValue);
            Debug.Assert(parent == null || parent.Type.HasValueCopySemantics() || !indices.IsEmpty);

            Symbol  = symbol;
            Indices = indices;
            InstanceReferenceOperationSyntax = instanceReferenceOperationSyntax;
            CaptureId          = captureId;
            InstanceLocation   = location;
            Type               = type;
            Parent             = parent;
            IsThisOrMeInstance = isThisOrMeInstance;

            _ignoringLocationHashCodeParts   = ComputeIgnoringLocationHashCodeParts();
            EqualsIgnoringInstanceLocationId = HashUtilities.Combine(_ignoringLocationHashCodeParts);
        }
            protected override PropertySetAbstractValue VisitAssignmentOperation(IAssignmentOperation operation, object?argument)
            {
                PropertySetAbstractValue?baseValue = base.VisitAssignmentOperation(operation, argument);

                // If we need to evaluate hazardous usages on initializations, track assignments of properties and fields, so
                // at the end of the CFG we can figure out which assignment operations to flag.
                if (this.TrackedFieldPropertyAssignments != null &&
                    this.TrackedTypeSymbols.Any(s => operation.Target.Type.GetBaseTypesAndThis().Contains(s)) &&
                    (operation.Target.Kind == OperationKind.PropertyReference ||
                     operation.Target.Kind == OperationKind.FieldReference ||
                     operation.Target.Kind == OperationKind.FlowCaptureReference))
                {
                    AnalysisEntity?targetAnalysisEntity = null;
                    if (operation.Target.Kind == OperationKind.FlowCaptureReference)
                    {
                        if (this.TryUnwrapFlowCaptureReference(operation.Target, out IOperation? lValueOperation, OperationKind.PropertyReference, OperationKind.FieldReference))
                        {
                            this.AnalysisEntityFactory.TryCreate(lValueOperation, out targetAnalysisEntity);
                        }
                    }
                    else
                    {
                        this.AnalysisEntityFactory.TryCreate(operation.Target, out targetAnalysisEntity);
                    }

                    if (targetAnalysisEntity != null)
                    {
                        PointsToAbstractValue pointsToAbstractValue = this.GetPointsToAbstractValue(operation.Value);
                        if (!this.TrackedFieldPropertyAssignments.TryGetValue(
                                targetAnalysisEntity,
                                out TrackedAssignmentData trackedAssignmentData))
                        {
                            trackedAssignmentData = new TrackedAssignmentData();
                            this.TrackedFieldPropertyAssignments.Add(targetAnalysisEntity, trackedAssignmentData);
                        }

                        if (pointsToAbstractValue.Kind == PointsToAbstractValueKind.KnownLocations)
                        {
                            foreach (AbstractLocation abstractLocation in pointsToAbstractValue.Locations)
                            {
                                trackedAssignmentData.TrackAssignmentWithAbstractLocation(operation, abstractLocation);
                            }
                        }
                        else if (pointsToAbstractValue.Kind is PointsToAbstractValueKind.Unknown
                                 or PointsToAbstractValueKind.UnknownNotNull)
                        {
                            trackedAssignmentData.TrackAssignmentWithUnknownLocation(operation);
                        }
                        else if (pointsToAbstractValue.NullState == NullAbstractValue.Null)
                        {
                            // Do nothing.
                        }
                        else
                        {
                            Debug.Fail($"Unhandled PointsToAbstractValue: Kind = {pointsToAbstractValue.Kind}, NullState = {pointsToAbstractValue.NullState}");
                        }
                    }
                }
예제 #3
0
 public ArgumentInfo(
     IOperation operation,
     AnalysisEntity?analysisEntity,
     PointsToAbstractValue instanceLocation,
     TAbstractAnalysisValue value)
 {
     Operation        = operation;
     AnalysisEntity   = analysisEntity;
     InstanceLocation = instanceLocation;
     Value            = value;
 }
예제 #4
0
        protected virtual void SetAbstractValueForAssignment(AnalysisEntity targetAnalysisEntity, IOperation?assignedValueOperation, TAbstractAnalysisValue assignedValue)
        {
            AnalysisEntity?assignedValueEntity = null;

            if (assignedValueOperation != null)
            {
                var success = AnalysisEntityFactory.TryCreate(assignedValueOperation, out assignedValueEntity);
                Debug.Assert(success || assignedValueEntity == null);
            }

            SetAbstractValueForAssignment(targetAnalysisEntity, assignedValueEntity, assignedValueOperation, assignedValue);
        }
        public bool TryCreateForSymbolDeclaration(ISymbol symbol, [NotNullWhen(returnValue: true)] out AnalysisEntity?analysisEntity)
        {
            Debug.Assert(symbol.Kind is SymbolKind.Local or SymbolKind.Parameter or SymbolKind.Field or SymbolKind.Property);

            var        indices  = ImmutableArray <AbstractIndex> .Empty;
            IOperation?instance = null;
            var        type     = symbol.GetMemberOrLocalOrParameterType();

            RoslynDebug.Assert(type != null);

            return(TryCreate(symbol, indices, type, instance, out analysisEntity));
        }
예제 #6
0
        private AbstractLocation(IOperation?creation, ImmutableStack <IOperation>?creationCallStack, AnalysisEntity?analysisEntity, ISymbol?symbol, InterproceduralCaptureId?captureId, ITypeSymbol?locationType, bool isSpecialSingleton)
        {
            Debug.Assert(isSpecialSingleton ^ (locationType != null));

            CreationOpt         = creation;
            CreationCallStack   = creationCallStack ?? ImmutableStack <IOperation> .Empty;
            AnalysisEntityOpt   = analysisEntity;
            SymbolOpt           = symbol;
            CaptureIdOpt        = captureId;
            LocationTypeOpt     = locationType;
            _isSpecialSingleton = isSpecialSingleton;
        }
        internal AnalysisEntityFactory(
            ControlFlowGraph controlFlowGraph,
            WellKnownTypeProvider wellKnownTypeProvider,
            Func <IOperation, PointsToAbstractValue>?getPointsToAbstractValue,
            Func <bool> getIsInsideAnonymousObjectInitializer,
            Func <IFlowCaptureOperation, bool> getIsLValueFlowCapture,
            INamedTypeSymbol containingTypeSymbol,
            AnalysisEntity?interproceduralInvocationInstance,
            AnalysisEntity?interproceduralThisOrMeInstanceForCaller,
            ImmutableStack <IOperation>?interproceduralCallStack,
            ImmutableDictionary <ISymbol, PointsToAbstractValue>?interproceduralCapturedVariablesMap,
            Func <IOperation, AnalysisEntity?>?interproceduralGetAnalysisEntityForFlowCapture,
            Func <ISymbol, ImmutableStack <IOperation>?> getInterproceduralCallStackForOwningSymbol)
        {
            _controlFlowGraph         = controlFlowGraph;
            _wellKnownTypeProvider    = wellKnownTypeProvider;
            _getPointsToAbstractValue = getPointsToAbstractValue;
            _getIsInsideAnonymousObjectInitializer = getIsInsideAnonymousObjectInitializer;
            _getIsLValueFlowCapture = getIsLValueFlowCapture;
            _interproceduralThisOrMeInstanceForCaller = interproceduralThisOrMeInstanceForCaller;
            _interproceduralCallStack = interproceduralCallStack;
            _interproceduralGetAnalysisEntityForFlowCapture = interproceduralGetAnalysisEntityForFlowCapture;
            _getInterproceduralCallStackForOwningSymbol     = getInterproceduralCallStackForOwningSymbol;

            _analysisEntityMap       = new Dictionary <IOperation, AnalysisEntity?>();
            _tupleElementEntitiesMap = new Dictionary <ITupleOperation, ImmutableArray <AnalysisEntity> >();
            _captureIdEntityMap      = new Dictionary <CaptureId, AnalysisEntity>();
            _captureIdCopyValueMap   = new Dictionary <CaptureId, CopyAbstractValue>();

            _instanceLocationsForSymbols = new Dictionary <ISymbol, PointsToAbstractValue>();
            if (interproceduralCapturedVariablesMap != null)
            {
                _instanceLocationsForSymbols.AddRange(interproceduralCapturedVariablesMap);
            }

            if (interproceduralInvocationInstance != null)
            {
                ThisOrMeInstance = interproceduralInvocationInstance;
            }
            else
            {
                var thisOrMeInstanceLocation = AbstractLocation.CreateThisOrMeLocation(containingTypeSymbol, interproceduralCallStack);
                var instanceLocation         = PointsToAbstractValue.Create(thisOrMeInstanceLocation, mayBeNull: false);
                ThisOrMeInstance = AnalysisEntity.CreateThisOrMeInstance(containingTypeSymbol, instanceLocation);
            }
        }
        /// <summary>
        /// Updates the the copy values for all entities that are part of the given <paramref name="copyValue"/> set,
        /// i.e. <see cref="CopyAbstractValue.AnalysisEntities"/>.
        /// We do not support the <see cref="SetAbstractValue(AnalysisEntity, CopyAbstractValue)"/> overload
        /// that updates copy value for each individual entity.
        /// </summary>
        internal void SetAbstactValueForEntities(CopyAbstractValue copyValue, AnalysisEntity?entityBeingAssigned)
        {
            foreach (var entity in copyValue.AnalysisEntities)
            {
                // If we have any predicate data based on the previous value of this entity,
                // and we are changing the copy value for an assigment (i.e. entity == entityBeingAssigned),
                // we need to drop all the predicate data based on this entity.
                if (entity == entityBeingAssigned && HasPredicatedDataForEntity(entity))
                {
                    StopTrackingPredicatedData(entity);
                }

                // Remove all predicated values for this entity as we are going to set
                // a new value in CoreAnalysisData below, which is non-predicated.
                if (HasPredicatedData)
                {
                    RemoveEntriesInPredicatedData(entity);
                }

                // Finally, set the value in the core analysis data.
                CoreAnalysisData[entity] = copyValue;
            }
        }
예제 #9
0
        /// <summary>
        /// Transfers the analysis data rooted from <paramref name="valueAnalysisEntity"/> or <paramref name="assignedValueOperation"/> to <paramref name="targetAnalysisEntity"/>, for a value type assignment operation.
        /// This involves transfer of data for of all <see cref="AnalysisEntity"/> instances that share the same <see cref="AnalysisEntity.InstanceLocation"/> as <paramref name="valueAnalysisEntity"/> or allocation for the <paramref name="assignedValueOperation"/>
        /// to all <see cref="AnalysisEntity"/> instances that share the same <see cref="AnalysisEntity.InstanceLocation"/> as <paramref name="targetAnalysisEntity"/>.
        /// </summary>
        private void TransferValueTypeInstanceAnalysisDataForAssignment(AnalysisEntity targetAnalysisEntity, AnalysisEntity?valueAnalysisEntity, IOperation?assignedValueOperation)
        {
            Debug.Assert(HasPointsToAnalysisResult);
            Debug.Assert(targetAnalysisEntity.Type.HasValueCopySemantics());

            IEnumerable <AnalysisEntity> dependentAnalysisEntities;

            if (valueAnalysisEntity != null)
            {
                if (!valueAnalysisEntity.Type.HasValueCopySemantics())
                {
                    // Unboxing conversion from assigned value (reference type) to target (value copy semantics).
                    // We do not need to transfer any data for such a case as there is no entity for unboxed value.
                    return;
                }

                dependentAnalysisEntities = GetChildAnalysisEntities(valueAnalysisEntity);
            }
            else if (assignedValueOperation != null)
            {
                // For allocations.
                PointsToAbstractValue newValueLocation = GetPointsToAbstractValue(assignedValueOperation);
                dependentAnalysisEntities = GetChildAnalysisEntities(newValueLocation);
            }
            else
            {
                return;
            }

            foreach (AnalysisEntity dependentInstance in dependentAnalysisEntities)
            {
                // Clone the dependent instance but with with target as the root.
                AnalysisEntity newAnalysisEntity = AnalysisEntityFactory.CreateWithNewInstanceRoot(dependentInstance, targetAnalysisEntity);
                var            dependentValue    = GetAbstractValue(dependentInstance);
                SetAbstractValue(newAnalysisEntity, dependentValue);
            }
        }
예제 #10
0
        private void SetAbstractValueForAssignment(AnalysisEntity targetAnalysisEntity, AnalysisEntity?assignedValueEntity, IOperation?assignedValueOperation, TAbstractAnalysisValue assignedValue)
        {
            // Value type and string type assignment has copy semantics.
            if (HasPointsToAnalysisResult &&
                targetAnalysisEntity.Type.HasValueCopySemantics())
            {
                // Reset the analysis values for analysis entities within the target instance.
                ResetValueTypeInstanceAnalysisData(targetAnalysisEntity);

                // Transfer the values of symbols from the assigned instance to the analysis entities in the target instance.
                TransferValueTypeInstanceAnalysisDataForAssignment(targetAnalysisEntity, assignedValueEntity, assignedValueOperation);
            }

            var addressSharedCopyValue = TryGetAddressSharedCopyValue(targetAnalysisEntity);

            if (addressSharedCopyValue != null)
            {
                Debug.Assert(addressSharedCopyValue.AnalysisEntities.Contains(targetAnalysisEntity));
                foreach (var entity in addressSharedCopyValue.AnalysisEntities)
                {
                    SetAbstractValue(entity, assignedValue);
                }
            }
            else
            {
                SetAbstractValue(targetAnalysisEntity, assignedValue);
            }
        }
예제 #11
0
        public static AnalysisEntity Create(ISymbol?symbol, ImmutableArray <AbstractIndex> indices,
                                            ITypeSymbol type, PointsToAbstractValue instanceLocation, AnalysisEntity?parent)
        {
            Debug.Assert(symbol != null || !indices.IsEmpty);
            Debug.Assert(parent == null || parent.InstanceLocation == instanceLocation);

            return(new AnalysisEntity(symbol, indices, instanceLocation, type, parent));
        }
예제 #12
0
 private AnalysisEntity(ISymbol?symbol, ImmutableArray <AbstractIndex> indices, PointsToAbstractValue location, ITypeSymbol type, AnalysisEntity?parent)
     : this(symbol, indices, instanceReferenceOperationSyntax : null, captureId : null, location : location, type : type, parent : parent, isThisOrMeInstance : false)
 {
     Debug.Assert(symbol != null || !indices.IsEmpty);
 }
예제 #13
0
        public bool TryCreateForTupleElements(ITupleOperation tupleOperation, [NotNullWhen(returnValue: true)] out ImmutableArray <AnalysisEntity> elementEntities)
        {
            if (_tupleElementEntitiesMap.TryGetValue(tupleOperation, out elementEntities))
            {
                return(!elementEntities.IsDefault);
            }

            try
            {
                elementEntities = default;
                if (tupleOperation.Type?.IsTupleType != true ||
                    _getPointsToAbstractValue == null)
                {
                    return(false);
                }

                var tupleType = (INamedTypeSymbol)tupleOperation.Type;
                if (tupleType.TupleElements.IsDefault)
                {
                    return(false);
                }

                PointsToAbstractValue instanceLocation  = _getPointsToAbstractValue(tupleOperation);
                var            underlyingValueTupleType = tupleType.GetUnderlyingValueTupleTypeOrThis();
                AnalysisEntity?parentEntity             = null;
                if (tupleOperation.TryGetParentTupleOperation(out var parentTupleOperationOpt, out var elementOfParentTupleContainingTuple) &&
                    TryCreateForTupleElements(parentTupleOperationOpt, out var parentTupleElementEntities))
                {
                    Debug.Assert(parentTupleOperationOpt.Elements.Length == parentTupleElementEntities.Length);
                    for (int i = 0; i < parentTupleOperationOpt.Elements.Length; i++)
                    {
                        if (parentTupleOperationOpt.Elements[i] == elementOfParentTupleContainingTuple)
                        {
                            parentEntity     = parentTupleElementEntities[i];
                            instanceLocation = parentEntity.InstanceLocation;
                            break;
                        }
                    }

                    RoslynDebug.Assert(parentEntity != null);
                }
                else
                {
                    parentEntity = AnalysisEntity.Create(underlyingValueTupleType, ImmutableArray <AbstractIndex> .Empty,
                                                         underlyingValueTupleType, instanceLocation, parent: null);
                }

                Debug.Assert(parentEntity.InstanceLocation == instanceLocation);

                using var builder = ArrayBuilder <AnalysisEntity> .GetInstance(tupleType.TupleElements.Length);

                foreach (var field in tupleType.TupleElements)
                {
                    var tupleFieldName        = field.CorrespondingTupleField.Name;
                    var mappedValueTupleField = underlyingValueTupleType.GetMembers(tupleFieldName).OfType <IFieldSymbol>().FirstOrDefault();
                    if (mappedValueTupleField == null)
                    {
                        return(false);
                    }

                    builder.Add(AnalysisEntity.Create(mappedValueTupleField, indices: ImmutableArray <AbstractIndex> .Empty,
                                                      type: mappedValueTupleField.Type, instanceLocation, parentEntity));
                }

                elementEntities = builder.ToImmutable();
                return(true);
            }
예제 #14
0
        public bool TryCreate(IOperation operation, [NotNullWhen(returnValue: true)] out AnalysisEntity?analysisEntity)
        {
            if (_analysisEntityMap.TryGetValue(operation, out analysisEntity))
            {
                return(analysisEntity != null);
            }

            analysisEntity = null;
            ISymbol?symbol = null;
            ImmutableArray <AbstractIndex> indices = ImmutableArray <AbstractIndex> .Empty;
            IOperation? instance = null;
            ITypeSymbol?type     = operation.Type;

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

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

            case IMemberReferenceOperation memberReference:
                instance = memberReference.Instance;
                GetSymbolAndIndicesForMemberReference(memberReference, ref symbol, ref indices);

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

                break;

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

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

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

            case IInstanceReferenceOperation instanceReference:
                if (_getPointsToAbstractValue != null)
                {
                    instance = instanceReference.GetInstance(_getIsInsideAnonymousObjectInitializer());
                    if (instance == null)
                    {
                        // Reference to this or base instance.
                        analysisEntity = _interproceduralCallStack != null && _interproceduralCallStack.Peek().DescendantsAndSelf().Contains(instanceReference) ?
                                         _interproceduralThisOrMeInstanceForCaller :
                                         ThisOrMeInstance;
                    }
                    else
                    {
                        var instanceLocation = _getPointsToAbstractValue(instanceReference);
                        analysisEntity = AnalysisEntity.Create(instanceReference, instanceLocation);
                    }
                }
                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:
                var isLvalueFlowCapture = _getIsLValueFlowCapture(flowCapture);
                analysisEntity = GetOrCreateForFlowCapture(flowCapture.Id, flowCapture.Value.Type, flowCapture, isLvalueFlowCapture);

                // Store flow capture copy values for simple flow captures of non-flow captured entity.
                // This enables pseudo copy-analysis of values of these two entities in absence of true copy analysis, which is expensive.
                if (!isLvalueFlowCapture &&
                    TryCreate(flowCapture.Value, out var capturedEntity) &&
                    capturedEntity.CaptureId == null &&
                    !_captureIdCopyValueMap.ContainsKey(flowCapture.Id) &&
                    analysisEntity.Type.IsValueType == capturedEntity.Type.IsValueType)
                {
                    // Skip flow capture for conversions unless we know the points to value
                    // for conversion and operand is identical.
                    if (flowCapture.Value is IConversionOperation conversion)
                    {
                        if (_getPointsToAbstractValue == null ||
                            _getPointsToAbstractValue(conversion) != _getPointsToAbstractValue(conversion.Operand))
                        {
                            break;
                        }
                    }

                    var kind      = capturedEntity.Type.IsValueType ? CopyAbstractValueKind.KnownValueCopy : CopyAbstractValueKind.KnownReferenceCopy;
                    var copyValue = new CopyAbstractValue(ImmutableHashSet.Create(analysisEntity, capturedEntity), kind);
                    _captureIdCopyValueMap.Add(flowCapture.Id, copyValue);
                }

                break;

            case IFlowCaptureReferenceOperation flowCaptureReference:
                analysisEntity = GetOrCreateForFlowCapture(flowCaptureReference.Id, flowCaptureReference.Type, flowCaptureReference, flowCaptureReference.IsLValueFlowCaptureReference());
                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:
                symbol = variableDeclarator.Symbol;
                type   = variableDeclarator.Symbol.Type;
                break;

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

            default:
                break;
            }

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

            _analysisEntityMap[operation] = analysisEntity;
            return(analysisEntity != null);
        }
예제 #15
0
        public bool TryCreate(IOperation operation, [NotNullWhen(returnValue: true)] out AnalysisEntity?analysisEntity)
        {
            if (_analysisEntityMap.TryGetValue(operation, out analysisEntity))
            {
                return(analysisEntity != null);
            }

            analysisEntity = null;
            ISymbol?symbol = null;
            ImmutableArray <AbstractIndex> indices = ImmutableArray <AbstractIndex> .Empty;
            IOperation? instance = null;
            ITypeSymbol?type     = operation.Type;

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

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

            case IMemberReferenceOperation memberReference:
                instance = memberReference.Instance;
                GetSymbolAndIndicesForMemberReference(memberReference, ref symbol, ref indices);

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

                break;

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

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

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

            case IInstanceReferenceOperation instanceReference:
                if (_getPointsToAbstractValue != null)
                {
                    instance = instanceReference.GetInstance(_getIsInsideAnonymousObjectInitializer());
                    if (instance == null)
                    {
                        // Reference to this or base instance.
                        analysisEntity = _interproceduralCallStack != null && _interproceduralCallStack.Peek().DescendantsAndSelf().Contains(instanceReference) ?
                                         _interproceduralThisOrMeInstanceForCaller :
                                         ThisOrMeInstance;
                    }
                    else
                    {
                        var instanceLocation = _getPointsToAbstractValue(instanceReference);
                        analysisEntity = AnalysisEntity.Create(instanceReference, instanceLocation);
                    }
                }
                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, _getIsLValueFlowCapture(flowCapture));
                break;

            case IFlowCaptureReferenceOperation flowCaptureReference:
                analysisEntity = GetOrCreateForFlowCapture(flowCaptureReference.Id, flowCaptureReference.Type, flowCaptureReference, flowCaptureReference.IsLValueFlowCaptureReference());
                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:
                symbol = variableDeclarator.Symbol;
                type   = variableDeclarator.Symbol.Type;
                break;

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

            default:
                break;
            }

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

            _analysisEntityMap[operation] = analysisEntity;
            return(analysisEntity != null);
        }
예제 #16
0
        private static AbstractLocation Create(IOperation?creation, ImmutableStack <IOperation>?creationCallStack, AnalysisEntity?analysisEntity, ISymbol?symbol, InterproceduralCaptureId?captureId, ITypeSymbol?locationType)
        {
            Debug.Assert(creation != null ^ symbol != null ^ analysisEntity != null ^ captureId != null);
            Debug.Assert(locationType != null);

            return(new AbstractLocation(creation, creationCallStack, analysisEntity, symbol, captureId, locationType, isSpecialSingleton: false));
        }