using System.Collections.Generic; using System.Collections.Immutable; using System.Threading; using Microsoft.CodeAnalysis.PooledObjects; using Microsoft.CodeAnalysis.Text; using Roslyn.Utilities; namespace Microsoft.CodeAnalysis.CSharp.Syntax; internal readonly struct NullableContextStateMap { private sealed class PositionComparer : IComparer { internal static readonly PositionComparer Instance = new PositionComparer(); public int Compare(NullableContextState x, NullableContextState y) { return x.Position.CompareTo(y.Position); } } private readonly ImmutableArray _contexts; internal static NullableContextStateMap Create(SyntaxTree tree) { return new NullableContextStateMap(GetContexts(tree)); } private NullableContextStateMap(ImmutableArray contexts) { _contexts = contexts; } private static NullableContextState GetContextForFileStart() { return new NullableContextState(0, NullableContextState.State.Unknown, NullableContextState.State.Unknown); } private int GetContextStateIndex(int position) { int num = ImmutableArray.BinarySearch(value: new NullableContextState(position, NullableContextState.State.Unknown, NullableContextState.State.Unknown), array: _contexts, comparer: PositionComparer.Instance); if (num < 0) { num = ~num - 1; } return num; } internal NullableContextState GetContextState(int position) { int contextStateIndex = GetContextStateIndex(position); if (contextStateIndex >= 0) { return _contexts[contextStateIndex]; } return GetContextForFileStart(); } internal bool? IsNullableAnalysisEnabled(TextSpan span) { bool flag = false; int num = GetContextStateIndex(((TextSpan)(ref span)).Start); NullableContextState nullableContextState = ((num < 0) ? GetContextForFileStart() : _contexts[num]); do { switch (nullableContextState.WarningsState) { case NullableContextState.State.Enabled: return true; case NullableContextState.State.Unknown: case NullableContextState.State.ExplicitlyRestored: flag = true; break; } num++; if (num >= _contexts.Length) { break; } nullableContextState = _contexts[num]; } while (nullableContextState.Position < ((TextSpan)(ref span)).End); if (!flag) { return false; } return null; } private static ImmutableArray GetContexts(SyntaxTree tree) { //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Unknown result type (might be due to invalid IL or missing references) NullableContextState nullableContextState = GetContextForFileStart(); ArrayBuilder instance = ArrayBuilder.GetInstance(); foreach (DirectiveTriviaSyntax directive in tree.GetRoot(default(CancellationToken)).GetDirectives()) { if (directive.Kind() == SyntaxKind.NullableDirectiveTrivia) { NullableDirectiveTriviaSyntax nullableDirectiveTriviaSyntax = (NullableDirectiveTriviaSyntax)directive; SyntaxToken settingToken = nullableDirectiveTriviaSyntax.SettingToken; if (!((SyntaxToken)(ref settingToken)).IsMissing && nullableDirectiveTriviaSyntax.IsActive) { int endPosition = ((SyntaxNode)nullableDirectiveTriviaSyntax).EndPosition; SyntaxKind syntaxKind = nullableDirectiveTriviaSyntax.SettingToken.Kind(); NullableContextState.State state = syntaxKind switch { SyntaxKind.EnableKeyword => NullableContextState.State.Enabled, SyntaxKind.DisableKeyword => NullableContextState.State.Disabled, SyntaxKind.RestoreKeyword => NullableContextState.State.ExplicitlyRestored, _ => throw ExceptionUtilities.UnexpectedValue((object)syntaxKind), }; SyntaxKind syntaxKind2 = nullableDirectiveTriviaSyntax.TargetToken.Kind(); NullableContextState nullableContextState2 = syntaxKind2 switch { SyntaxKind.None => new NullableContextState(endPosition, state, state), SyntaxKind.WarningsKeyword => new NullableContextState(endPosition, state, nullableContextState.AnnotationsState), SyntaxKind.AnnotationsKeyword => new NullableContextState(endPosition, nullableContextState.WarningsState, state), _ => throw ExceptionUtilities.UnexpectedValue((object)syntaxKind2), }; instance.Add(nullableContextState2); nullableContextState = nullableContextState2; } } } return instance.ToImmutableAndFree(); } }