| File: src\ffd9070534249528\DefaultPointsToValueGenerator.cs | Web Access |
| Project: src\sdk\src\Microsoft.CodeAnalysis.NetAnalyzers\src\Microsoft.CodeAnalysis.NetAnalyzers\Microsoft.CodeAnalysis.NetAnalyzers.csproj (Microsoft.CodeAnalysis.NetAnalyzers) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System.Collections.Immutable; using Analyzer.Utilities.Extensions; namespace Microsoft.CodeAnalysis.FlowAnalysis.DataFlow.PointsToAnalysis { /// <summary> /// Generates and stores the default <see cref="PointsToAbstractValue"/> for <see cref="AnalysisEntity"/> instances generated for member and element reference operations. /// </summary> internal sealed class DefaultPointsToValueGenerator { private readonly TrackedEntitiesBuilder _trackedEntitiesBuilder; private readonly ImmutableDictionary<AnalysisEntity, PointsToAbstractValue>.Builder _defaultPointsToValueMapBuilder; public DefaultPointsToValueGenerator(TrackedEntitiesBuilder trackedEntitiesBuilder) { _trackedEntitiesBuilder = trackedEntitiesBuilder; _defaultPointsToValueMapBuilder = ImmutableDictionary.CreateBuilder<AnalysisEntity, PointsToAbstractValue>(); } public PointsToAnalysisKind PointsToAnalysisKind => _trackedEntitiesBuilder.PointsToAnalysisKind; public PointsToAbstractValue GetOrCreateDefaultValue(AnalysisEntity analysisEntity) { if (!_defaultPointsToValueMapBuilder.TryGetValue(analysisEntity, out var value)) { if (analysisEntity.Symbol?.Kind == SymbolKind.Local || analysisEntity.Symbol is IParameterSymbol parameter && parameter.RefKind == RefKind.Out || analysisEntity.CaptureId != null) { return PointsToAbstractValue.Undefined; } else if (analysisEntity.Type.IsNonNullableValueType()) { return PointsToAbstractValue.NoLocation; } else if (analysisEntity.HasUnknownInstanceLocation) { return PointsToAbstractValue.Unknown; } value = PointsToAbstractValue.Create(AbstractLocation.CreateAnalysisEntityDefaultLocation(analysisEntity), mayBeNull: true); // PERF: Do not track entity and its points to value for partial analysis for entities requiring complete analysis. if (analysisEntity.ShouldBeTrackedForPointsToAnalysis(PointsToAnalysisKind)) { _trackedEntitiesBuilder.AddEntityAndPointsToValue(analysisEntity, value); _defaultPointsToValueMapBuilder.Add(analysisEntity, value); } } return value; } public bool IsTrackedEntity(AnalysisEntity analysisEntity) => _defaultPointsToValueMapBuilder.ContainsKey(analysisEntity); public bool IsTrackedPointsToValue(PointsToAbstractValue value) => _trackedEntitiesBuilder.IsTrackedPointsToValue(value); public void AddTrackedPointsToValue(PointsToAbstractValue value) => _trackedEntitiesBuilder.AddTrackedPointsToValue(value); public bool HasAnyTrackedEntity => _defaultPointsToValueMapBuilder.Count > 0; } }