private void LocateToken()

in ReSharper.FSharp/src/FSharp/FSharp.Psi/src/Parsing/FSharpPreprocessedLexer.cs [226:315]


    private void LocateToken() =>
      myCurrTokenType ??= LocateTokenImpl();

    private class PreprocessorState
    {
      private enum PreprocessorElseState
      {
        BeforeElse,
        AfterElse,
        InactiveBeforeElse,
        InactiveAfterElse,
        Error
      }

      private struct PreprocessorBlockState
      {
        private PreprocessorElseState myElseState;
        private readonly bool myCondition;

        public PreprocessorBlockState(bool condition, bool hasActiveBranch)
        {
          myCondition = condition;
          myElseState = hasActiveBranch ? PreprocessorElseState.BeforeElse : PreprocessorElseState.InactiveBeforeElse;
        }

        public bool Condition
        {
          get
          {
            switch (myElseState)
            {
              case PreprocessorElseState.BeforeElse: return myCondition;
              case PreprocessorElseState.AfterElse: return !myCondition;
              case PreprocessorElseState.Error: return true;
              default: return false;
            }
          }
        }

        public PreprocessorElseState SwitchBranch()
        {
          switch (myElseState)
          {
            case PreprocessorElseState.BeforeElse:
              myElseState = PreprocessorElseState.AfterElse;
              break;
            case PreprocessorElseState.InactiveBeforeElse:
              myElseState = PreprocessorElseState.InactiveAfterElse;
              break;
            default:
              myElseState = PreprocessorElseState.Error;
              break;
          }
          return myElseState;
        }
      }

      private readonly Stack<PreprocessorBlockState> myStack = new();
      private readonly Queue<LexerState> myQueue = new();

      public IEnumerable<LexerState> LexerStates() => myQueue;

      public void EnqueueLexerState(LexerState state) =>
        myQueue.Enqueue(state);

      public LexerState DequeueLexerState() =>
        myQueue.Dequeue();

      public void InIfBlock(bool condition, bool hasActiveBranch) =>
        myStack.Push(new PreprocessorBlockState(condition, hasActiveBranch));

      public void FromIfBlock()
      {
        if (!myStack.IsEmpty())
          myStack.Pop();
      }

      public void SwitchBranch()
      {
        if (myStack.IsEmpty())
          return;
        var state = myStack.Pop();
        if (state.SwitchBranch() == PreprocessorElseState.Error)
          myStack.Clear();
        else
          myStack.Push(state);
      }

      public bool Condition => myStack.IsEmpty() || myStack.Peek().Condition;
    }