private void LexBlock(SnapshotSpan span, TrackedBlock block, bool cache) { this.InvalidateBlockEdge(span, block); block.ClearCache(); block.Version = span.Snapshot.Version; Span textSpan = block.Block.GetSpan(span.Snapshot); string text = span.Snapshot.GetText(textSpan); this.lexer.Reset(); this.lexer.SetInputStream(new AntlrInputStream(text)); if (block.StartState == null) { block.StartState = this.SaveLexerState(); } else { block.StartState.Restore(this.lexer); } IToken token = null; int tokenType = -1; int startPosition = textSpan.Start; int endPosition = startPosition; int blockEnd = startPosition + BlockSize; do { LexerState state = this.SaveLexerState(); token = lexer.NextToken(); if (lexer._hitEOF) { tokenType = -1; endPosition = textSpan.End; } else if (token != null) { tokenType = token.Type; endPosition += token.StopIndex - token.StartIndex + 1; } if (token == null || tokenType < 0) { int textLength = endPosition - startPosition; int delta = 0; tokenType = -1; while (tokenType < 0 && startPosition + textLength < span.Snapshot.Length) { delta += 1024; textLength += Math.Min(span.Snapshot.Length - startPosition - textLength, delta); string currentText = span.Snapshot.GetText(startPosition, textLength); textLength = currentText.Length; this.lexer.Reset(); this.lexer.SetInputStream(new AntlrInputStream(currentText)); state.Restore(this.lexer); token = lexer.NextToken(); if (lexer._hitEOF) { endPosition = startPosition + textLength; } else if (token != null) { tokenType = token.Type; endPosition = startPosition + token.StopIndex - token.StartIndex + 1; } else { endPosition = startPosition + textLength; } } } if (cache) { var classification = this.GetClassificationType(tokenType, this.lexer._mode); var tokenSpan = this.CreateSnapshotSpan(span, startPosition, endPosition); var classificationSpan = new ClassificationSpan(tokenSpan, classification); block.CacheClassification(classificationSpan); } startPosition = endPosition; }while (token != null && startPosition < textSpan.End && startPosition < blockEnd); Span blockSpan = Span.FromBounds(textSpan.Start, endPosition); block.Block = span.Snapshot.CreateTrackingSpan(blockSpan, textSpan.Start == 0 ? SpanTrackingMode.EdgeInclusive : SpanTrackingMode.EdgePositive); block.EndState = this.SaveLexerState(); this.InvalidateBlockEdge(span, block); }
protected virtual LexerState SaveLexerState() { LexerState state = new LexerState(this.lexer); return(state); }