File: src\RoslynAnalyzers\Utilities\FlowAnalysis\FlowAnalysis\Analysis\PointsToAnalysis\PointsToAnalysisResult.cs
Web Access
Project: src\src\RoslynAnalyzers\Microsoft.CodeAnalysis.AnalyzerUtilities\Microsoft.CodeAnalysis.AnalyzerUtilities.csproj (Microsoft.CodeAnalysis.AnalyzerUtilities)
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
 
using System.Collections.Immutable;
 
namespace Microsoft.CodeAnalysis.FlowAnalysis.DataFlow.PointsToAnalysis
{
    /// <summary>
    /// Analysis result from execution of <see cref="PointsToAnalysis"/> on a control flow graph.
    /// </summary>
    public sealed class PointsToAnalysisResult : DataFlowAnalysisResult<PointsToBlockAnalysisResult, PointsToAbstractValue>
    {
        private readonly ImmutableDictionary<IOperation, ImmutableHashSet<AbstractLocation>> _escapedLocationsThroughOperationsMap;
        private readonly ImmutableDictionary<IOperation, ImmutableHashSet<AbstractLocation>> _escapedLocationsThroughReturnValuesMap;
        private readonly ImmutableDictionary<AnalysisEntity, ImmutableHashSet<AbstractLocation>> _escapedLocationsThroughEntitiesMap;
        private readonly ImmutableHashSet<AnalysisEntity> _trackedEntities;
        private readonly ImmutableHashSet<PointsToAbstractValue> _trackedPointsToValues;
 
        internal PointsToAnalysisResult(
            DataFlowAnalysisResult<PointsToBlockAnalysisResult, PointsToAbstractValue> corePointsToAnalysisResult,
            ImmutableDictionary<IOperation, ImmutableHashSet<AbstractLocation>> escapedLocationsThroughOperationsMap,
            ImmutableDictionary<IOperation, ImmutableHashSet<AbstractLocation>> escapedLocationsThroughReturnValuesMap,
            ImmutableDictionary<AnalysisEntity, ImmutableHashSet<AbstractLocation>> escapedLocationsThroughEntitiesMap,
            TrackedEntitiesBuilder trackedEntitiesBuilder)
            : base(corePointsToAnalysisResult)
        {
            _escapedLocationsThroughOperationsMap = escapedLocationsThroughOperationsMap;
            _escapedLocationsThroughReturnValuesMap = escapedLocationsThroughReturnValuesMap;
            _escapedLocationsThroughEntitiesMap = escapedLocationsThroughEntitiesMap;
            (_trackedEntities, _trackedPointsToValues) = trackedEntitiesBuilder.ToImmutable();
            PointsToAnalysisKind = trackedEntitiesBuilder.PointsToAnalysisKind;
        }
 
        public PointsToAnalysisKind PointsToAnalysisKind { get; }
 
        public ImmutableHashSet<AbstractLocation> GetEscapedAbstractLocations(IOperation operation)
            => ImmutableHashSetExtensions.AddRange(
                GetEscapedAbstractLocations(operation, _escapedLocationsThroughOperationsMap),
                GetEscapedAbstractLocations(operation, _escapedLocationsThroughReturnValuesMap));
 
        public ImmutableHashSet<AbstractLocation> GetEscapedAbstractLocations(AnalysisEntity analysisEntity)
            => GetEscapedAbstractLocations(analysisEntity, _escapedLocationsThroughEntitiesMap);
 
        private static ImmutableHashSet<AbstractLocation> GetEscapedAbstractLocations<TKey>(
            TKey key,
            ImmutableDictionary<TKey, ImmutableHashSet<AbstractLocation>> map)
            where TKey : class
        {
            if (map.TryGetValue(key, out var escapedLocations))
            {
                return escapedLocations;
            }
 
            return ImmutableHashSet<AbstractLocation>.Empty;
        }
 
        internal bool IsTrackedEntity(AnalysisEntity analysisEntity)
            => _trackedEntities.Contains(analysisEntity);
 
        internal bool IsTrackedPointsToValue(PointsToAbstractValue value)
            => _trackedPointsToValues.Contains(value);
    }
}