using System; using System.Collections.Immutable; namespace Microsoft.CodeAnalysis.Syntax; internal abstract class AbstractWarningStateMap where TWarningState : struct { protected readonly struct WarningStateMapEntry : IComparable { public readonly int Position; public readonly TWarningState GeneralWarningOption; public readonly ImmutableDictionary SpecificWarningOption; public WarningStateMapEntry(int position) { Position = position; GeneralWarningOption = default(TWarningState); SpecificWarningOption = ImmutableDictionary.Create(); } public WarningStateMapEntry(int position, TWarningState general, ImmutableDictionary specific) { Position = position; GeneralWarningOption = general; SpecificWarningOption = specific ?? ImmutableDictionary.Create(); } public int CompareTo(WarningStateMapEntry other) { return Position - other.Position; } } private readonly WarningStateMapEntry[] _warningStateMapEntries; protected AbstractWarningStateMap(SyntaxTree syntaxTree) { _warningStateMapEntries = CreateWarningStateMapEntries(syntaxTree); } protected abstract WarningStateMapEntry[] CreateWarningStateMapEntries(SyntaxTree syntaxTree); public TWarningState GetWarningState(string id, int position) { WarningStateMapEntry entryAtOrBeforePosition = GetEntryAtOrBeforePosition(position); if (entryAtOrBeforePosition.SpecificWarningOption.TryGetValue(id, out var value)) { return value; } return entryAtOrBeforePosition.GeneralWarningOption; } private WarningStateMapEntry GetEntryAtOrBeforePosition(int position) { int num = Array.BinarySearch(_warningStateMapEntries, new WarningStateMapEntry(position)); return _warningStateMapEntries[(num >= 0) ? num : (~num - 1)]; } }