protected abstract void SetValueForParameterPointsToLocationOnExit(IParameterSymbol parameter, AnalysisEntity analysisEntity, PointsToAbstractValue pointsToAbstractValue);
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); }
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)); }