| File: Syntax\AbstractWarningStateMap.cs | Web Access |
| Project: src\roslyn\src\Compilers\Core\Portable\Microsoft.CodeAnalysis.csproj (Microsoft.CodeAnalysis) |
// 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; using System.Collections.Immutable; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; namespace Microsoft.CodeAnalysis.Syntax { internal abstract class AbstractWarningStateMap<TWarningState> where TWarningState : struct { /// <summary> /// List of entries sorted in source order, each of which captures a /// position in the supplied syntax tree and the set of diagnostics (warnings) /// whose reporting should either be suppressed or enabled at this position. /// </summary> private readonly WarningStateMapEntry[] _warningStateMapEntries; protected AbstractWarningStateMap(SyntaxTree syntaxTree) { _warningStateMapEntries = CreateWarningStateMapEntries(syntaxTree); } /// <summary> /// Returns list of entries sorted in source order, each of which captures a /// position in the supplied syntax tree and the set of diagnostics (warnings) /// whose reporting should either be suppressed or enabled at this position. /// </summary> protected abstract WarningStateMapEntry[] CreateWarningStateMapEntries(SyntaxTree syntaxTree); /// <summary> /// Returns the reporting state for the supplied diagnostic id at the supplied position /// in the associated syntax tree. /// </summary> public TWarningState GetWarningState(string id, int position) { var entry = GetEntryAtOrBeforePosition(position); TWarningState state; if (entry.SpecificWarningOption.TryGetValue(id, out state)) { return state; } return entry.GeneralWarningOption; } /// <summary> /// Gets the entry with the largest position less than or equal to supplied position. /// </summary> private WarningStateMapEntry GetEntryAtOrBeforePosition(int position) { Debug.Assert(_warningStateMapEntries != null && _warningStateMapEntries.Length > 0); int r = Array.BinarySearch(_warningStateMapEntries, new WarningStateMapEntry(position)); return _warningStateMapEntries[r >= 0 ? r : ((~r) - 1)]; } /// <summary> /// Struct that represents an entry in the warning state map. Sorts by position in the associated syntax tree. /// </summary> protected readonly struct WarningStateMapEntry : IComparable<WarningStateMapEntry> { // 0-based position in the associated syntax tree public readonly int Position; // the general option applicable to all warnings, accumulated of all #pragma up to the current Line. public readonly TWarningState GeneralWarningOption; // the mapping of the specific warning to the option, accumulated of all #pragma up to the current Line. public readonly ImmutableDictionary<string, TWarningState> SpecificWarningOption; public WarningStateMapEntry(int position) { this.Position = position; this.GeneralWarningOption = default; this.SpecificWarningOption = ImmutableDictionary.Create<string, TWarningState>(); } public WarningStateMapEntry(int position, TWarningState general, ImmutableDictionary<string, TWarningState> specific) { this.Position = position; this.GeneralWarningOption = general; this.SpecificWarningOption = specific ?? ImmutableDictionary.Create<string, TWarningState>(); } public int CompareTo(WarningStateMapEntry other) { return this.Position - other.Position; } } } }