Example #1
0
 protected abstract void SetValueForParameterPointsToLocationOnExit(IParameterSymbol parameter, AnalysisEntity analysisEntity, PointsToAbstractValue pointsToAbstractValue);
Example #2
0
 protected override void SetValueForParameterOnEntry(IParameterSymbol parameter, AnalysisEntity analysisEntity)
 {
     Debug.Assert(analysisEntity.SymbolOpt == parameter);
     if (TryGetPointsToAbstractValueAtCurrentBlockExit(analysisEntity, out PointsToAbstractValue pointsToAbstractValue))
     {
         SetValueForParameterPointsToLocationOnEntry(parameter, pointsToAbstractValue);
     }
 }
        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);
                    AddToMap(instanceLocation, analysisEntity);
                }
                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));

            default:
                break;
            }

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

            _analysisEntityMap[operation] = analysisEntity;
            return(analysisEntity != null);
        }
Example #4
0
 protected override void ResetValueTypeInstanceAnalysisData(AnalysisEntity analysisEntity)
 {
 }
        private AnalysisEntity Create(ISymbol symbolOpt, ImmutableArray <AbstractIndex> indices, ITypeSymbol type, PointsToAbstractValue instanceLocationOpt, AnalysisEntity parentOpt)
        {
            instanceLocationOpt = EnsureLocation(instanceLocationOpt, symbolOpt, parentOpt);
            Debug.Assert(instanceLocationOpt != null);
            var analysisEntity = AnalysisEntity.Create(symbolOpt, indices, type, instanceLocationOpt, parentOpt);

            AddToMap(instanceLocationOpt, analysisEntity);
            return(analysisEntity);
        }
        public AnalysisEntity CreateWithNewInstanceRoot(AnalysisEntity analysisEntity, AnalysisEntity newRootInstance)
        {
            if (analysisEntity.InstanceLocation == newRootInstance.InstanceLocation)
            {
                return(analysisEntity);
            }

            if (analysisEntity.ParentOpt == null)
            {
                return(newRootInstance);
            }

            AnalysisEntity parentOpt = CreateWithNewInstanceRoot(analysisEntity.ParentOpt, newRootInstance);

            return(Create(analysisEntity.SymbolOpt, analysisEntity.Indices, analysisEntity.Type, newRootInstance.InstanceLocation, parentOpt));
        }
        public bool TryCreateForElementInitializer(IOperation instance, ImmutableArray <AbstractIndex> indices, ITypeSymbol elementType, out AnalysisEntity analysisEntity)
        {
            Debug.Assert(instance != null);
            Debug.Assert(!indices.IsEmpty);
            Debug.Assert(elementType != null);

            ISymbol symbol = null;

            return(TryCreate(symbol, indices, elementType, instance, out analysisEntity));
        }
 protected override void SetValueForParameterOnExit(IParameterSymbol parameter, AnalysisEntity analysisEntity)
 {
     Debug.Assert(analysisEntity.SymbolOpt == parameter);
     if (parameter.RefKind != RefKind.None)
     {
         SetAbstractValue(analysisEntity, GetDefaultValueForParameterOnExit(analysisEntity.Type));
     }
 }
 protected virtual TAbstractAnalysisValue ComputeAnalysisValueForOutArgument(AnalysisEntity analysisEntity, IArgumentOperation operation, TAbstractAnalysisValue defaultValue)
 {
     return(defaultValue);
 }
 public AnalysisEntityBasedIndex(AnalysisEntity analysisEntity)
 {
     AnalysisEntity = analysisEntity;
 }
 protected abstract bool HasAbstractValue(AnalysisEntity analysisEntity);
 protected abstract TAbstractAnalysisValue GetAbstractValue(AnalysisEntity analysisEntity);
 protected abstract void SetAbstractValue(AnalysisEntity analysisEntity, TAbstractAnalysisValue value);
 protected virtual TValue GetDefaultValue(AnalysisEntity analysisEntity) => ValueDomain.UnknownOrMayBeValue;
        private PointsToAbstractValue EnsureLocation(PointsToAbstractValue instanceLocationOpt, ISymbol symbolOpt, AnalysisEntity parentOpt)
        {
            if (instanceLocationOpt == null && symbolOpt != null)
            {
                Debug.Assert(symbolOpt.Kind == SymbolKind.Local || symbolOpt.Kind == SymbolKind.Parameter || symbolOpt.IsStatic);

                if (!_instanceLocationsForSymbols.TryGetValue(symbolOpt, out instanceLocationOpt))
                {
                    if (parentOpt != null)
                    {
                        instanceLocationOpt = parentOpt.InstanceLocation;
                    }
                    else
                    {
                        var location = AbstractLocation.CreateSymbolLocation(symbolOpt);
                        instanceLocationOpt = new PointsToAbstractValue(location);
                    }

                    _instanceLocationsForSymbols.Add(symbolOpt, instanceLocationOpt);
                }
            }

            return(instanceLocationOpt);
        }
        protected override IDictionary <AnalysisEntity, TValue> MergeCore(IDictionary <AnalysisEntity, TValue> map1, IDictionary <AnalysisEntity, TValue> map2)
        {
            Debug.Assert(map1 != null);
            Debug.Assert(map2 != null);

            TValue GetMergedValueForEntityPresentInOneMap(AnalysisEntity key, TValue value)
            {
                var defaultValue = GetDefaultValue(key);

                return(key.SymbolOpt != null?ValueDomain.Merge(value, defaultValue) : defaultValue);
            }

            var resultMap = new Dictionary <AnalysisEntity, TValue>();
            var map2LookupIgnoringInstanceLocation = map2.Keys.ToLookup(entity => entity.EqualsIgnoringInstanceLocationId);

            foreach (var entry1 in map1)
            {
                AnalysisEntity key1   = entry1.Key;
                TValue         value1 = entry1.Value;

                var equivalentKeys2 = map2LookupIgnoringInstanceLocation[key1.EqualsIgnoringInstanceLocationId];
                if (!equivalentKeys2.Any())
                {
                    TValue mergedValue = GetMergedValueForEntityPresentInOneMap(key1, value1);
                    resultMap.Add(key1, mergedValue);
                    continue;
                }

                foreach (AnalysisEntity key2 in equivalentKeys2)
                {
                    TValue value2      = map2[key2];
                    TValue mergedValue = ValueDomain.Merge(value1, value2);
                    if (key1.InstanceLocation.Equals(key2.InstanceLocation))
                    {
                        resultMap[key1] = mergedValue;
                    }
                    else
                    {
                        AnalysisEntity mergedKey = key1.WithMergedInstanceLocation(key2);
                        if (resultMap.TryGetValue(mergedKey, out var existingValue))
                        {
                            mergedValue = ValueDomain.Merge(mergedValue, existingValue);
                        }
                        else if (ReferenceEquals(mergedValue, ValueDomain.UnknownOrMayBeValue))
                        {
                            // PERF: Do not add a new key-value pair to the resultMap if the value is UnknownOrMayBeValue.
                            continue;
                        }
                        else if (key1.SymbolOpt == null || key1.SymbolOpt != key2.SymbolOpt)
                        {
                            // PERF: Do not add a add a new key-value pair to the resultMap for unrelated entities or non-symbol based entities.
                            continue;
                        }

                        resultMap[mergedKey] = mergedValue;
                    }
                }
            }

            foreach (var kvp in map2)
            {
                var key2   = kvp.Key;
                var value2 = kvp.Value;
                if (!resultMap.ContainsKey(key2))
                {
                    TValue mergedValue = GetMergedValueForEntityPresentInOneMap(key2, value2);
                    resultMap.Add(key2, mergedValue);
                }
            }

            return(resultMap);
        }
 protected override void SetValueForParameterOnEntry(IParameterSymbol parameter, AnalysisEntity analysisEntity)
 {
     Debug.Assert(analysisEntity.SymbolOpt == parameter);
     SetAbstractValue(analysisEntity, GetDefaultValueForParameterOnEntry(analysisEntity.Type));
 }