File: src\11b41c7305441175\PropertySetAnalysis.PropertySetDataFlowOperationVisitor.TrackedAssignmentData.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 Analyzer.Utilities.PooledObjects;
using Microsoft.CodeAnalysis.FlowAnalysis.DataFlow;
using Microsoft.CodeAnalysis.Operations;

namespace Analyzer.Utilities.FlowAnalysis.Analysis.PropertySetAnalysis
{
    internal partial class PropertySetAnalysis
    {
        private sealed partial class PropertySetDataFlowOperationVisitor
        {
            /// <summary>
            /// For a given analysis entity, keep track of property / field assignment operations and abstract locations, for
            /// evaluating hazardous usages on initializations.
            /// </summary>
            private class TrackedAssignmentData
            {
                public PooledHashSet<IAssignmentOperation>? AssignmentsWithUnknownLocation
                {
                    get;
                    private set;
                }

                public PooledDictionary<AbstractLocation, PooledHashSet<IAssignmentOperation>>? AbstractLocationsToAssignments
                {
                    get;
                    private set;
                }

                public void Free()
                {
                    this.AssignmentsWithUnknownLocation?.Dispose();
                    this.AssignmentsWithUnknownLocation = null;

                    if (this.AbstractLocationsToAssignments != null)
                    {
                        foreach (PooledHashSet<IAssignmentOperation> hashSet in this.AbstractLocationsToAssignments.Values)
                        {
                            hashSet?.Dispose();
                        }

                        this.AbstractLocationsToAssignments.Dispose();
                        this.AbstractLocationsToAssignments = null;
                    }
                }

                public void TrackAssignmentWithUnknownLocation(IAssignmentOperation assignmentOperation)
                {
                    this.AssignmentsWithUnknownLocation ??= PooledHashSet<IAssignmentOperation>.GetInstance();

                    this.AssignmentsWithUnknownLocation.Add(assignmentOperation);
                }

                public void TrackAssignmentWithAbstractLocation(
                    IAssignmentOperation assignmentOperation,
                    AbstractLocation abstractLocation)
                {
                    this.AbstractLocationsToAssignments ??=
                            PooledDictionary<AbstractLocation, PooledHashSet<IAssignmentOperation>>.GetInstance();

                    if (!this.AbstractLocationsToAssignments.TryGetValue(
                            abstractLocation,
                            out PooledHashSet<IAssignmentOperation> assignments))
                    {
                        assignments = PooledHashSet<IAssignmentOperation>.GetInstance();
                        this.AbstractLocationsToAssignments.Add(abstractLocation, assignments);
                    }

                    assignments.Add(assignmentOperation);
                }
            }
        }
    }
}