提交 e24ef750 编写于 作者: A Alex Dima

Simplify tokenTree

上级 f94f0b71
...@@ -6,13 +6,12 @@ ...@@ -6,13 +6,12 @@
import {Position} from 'vs/editor/common/core/position'; import {Position} from 'vs/editor/common/core/position';
import {Range} from 'vs/editor/common/core/range'; import {Range} from 'vs/editor/common/core/range';
import {IModel, IPosition, IRichEditBracket} from 'vs/editor/common/editorCommon'; import {IModel, IPosition} from 'vs/editor/common/editorCommon';
import {LineTokens} from 'vs/editor/common/core/lineTokens'; import {LineToken} from 'vs/editor/common/core/lineTokens';
import {IRichEditBrackets} from 'vs/editor/common/modes'; import {IRichEditBrackets} from 'vs/editor/common/modes';
import {ignoreBracketsInToken} from 'vs/editor/common/modes/supports'; import {ignoreBracketsInToken} from 'vs/editor/common/modes/supports';
import {BracketsUtils} from 'vs/editor/common/modes/supports/richEditBrackets'; import {BracketsUtils} from 'vs/editor/common/modes/supports/richEditBrackets';
import {LanguageConfigurationRegistry} from 'vs/editor/common/modes/languageConfigurationRegistry'; import {LanguageConfigurationRegistry} from 'vs/editor/common/modes/languageConfigurationRegistry';
import {ModeTransition} from 'vs/editor/common/core/modeTransition';
export const enum TokenTreeBracket { export const enum TokenTreeBracket {
None = 0, None = 0,
...@@ -102,11 +101,18 @@ export class Block extends Node { ...@@ -102,11 +101,18 @@ export class Block extends Node {
} }
} }
interface Token { class Token {
_tokenBrand: void;
range: Range; range: Range;
bracket: TokenTreeBracket;
type: string; type: string;
__debugContent?: string; bracket: TokenTreeBracket;
constructor(range:Range, type: string, bracket: TokenTreeBracket) {
this.range = range;
this.type = type;
this.bracket = bracket;
}
} }
function newNode(token: Token): Node { function newNode(token: Token): Node {
...@@ -116,128 +122,154 @@ function newNode(token: Token): Node { ...@@ -116,128 +122,154 @@ function newNode(token: Token): Node {
return node; return node;
} }
class TokenScanner { class RawToken {
_basicTokenBrand: void;
public lineNumber: number;
public lineText: string;
public startOffset: number;
public endOffset: number;
public type: string;
public modeId: string;
constructor(source:LineToken, lineNumber:number, lineText:string) {
this.lineNumber = lineNumber;
this.lineText = lineText;
this.startOffset = source.startOffset;
this.endOffset = source.endOffset;
this.type = source.type;
this.modeId = source.modeId;
}
}
class ModelRawTokenScanner {
private _model: IModel; private _model: IModel;
private _lineCount: number;
private _versionId: number; private _versionId: number;
private _currentLineNumber: number; private _lineNumber: number;
private _currentTokenIndex: number; private _lineText: string;
private _currentTokenStart: number; private _next: LineToken;
private _currentLineTokens: LineTokens;
private _currentLineModeTransitions: ModeTransition[];
private _currentModeIndex: number;
private _nextModeStart: number;
private _currentModeBrackets: IRichEditBrackets;
private _currentLineText: string;
constructor(model: IModel) { constructor(model:IModel) {
this._model = model; this._model = model;
this._versionId = model.getVersionId(); this._lineCount = this._model.getLineCount();
this._currentLineNumber = 1; this._versionId = this._model.getVersionId();
this._lineNumber = 0;
this._lineText = null;
this._advance();
} }
next(): Token { private _advance(): void {
if (this._versionId !== this._model.getVersionId()) { this._next = (this._next ? this._next.next() : null);
// model has been modified while (!this._next && this._lineNumber < this._lineCount) {
return null; this._lineNumber++;
this._lineText = this._model.getLineContent(this._lineNumber);
let currentLineTokens = this._model.getLineTokens(this._lineNumber);
this._next = currentLineTokens.firstToken();
} }
if (this._currentLineNumber >= this._model.getLineCount() + 1) { }
// all line visisted
public next(): RawToken {
if (!this._next) {
return null; return null;
} }
if (!this._currentLineTokens) { if (this._model.getVersionId() !== this._versionId) {
// no tokens for this line return null;
this._currentLineTokens = this._model.getLineTokens(this._currentLineNumber);
this._currentLineText = this._model.getLineContent(this._currentLineNumber);
this._currentLineModeTransitions = this._model._getLineModeTransitions(this._currentLineNumber);
this._currentTokenIndex = 0;
this._currentTokenStart = 0;
this._currentModeIndex = -1;
this._nextModeStart = 0;
}
if (this._currentTokenIndex >= this._currentLineTokens.getTokenCount()) {
// last token of line visited
this._currentLineNumber += 1;
this._currentLineTokens = null;
return this.next();
} }
if (this._currentTokenStart >= this._nextModeStart) { let result = new RawToken(this._next, this._lineNumber, this._lineText);
this._currentModeIndex++; this._advance();
this._nextModeStart = (this._currentModeIndex + 1 < this._currentLineModeTransitions.length ? this._currentLineModeTransitions[this._currentModeIndex + 1].startIndex : this._currentLineText.length + 1); return result;
let mode = (this._currentModeIndex < this._currentLineModeTransitions.length ? this._currentLineModeTransitions[this._currentModeIndex] : null); }
this._currentModeBrackets = (mode ? LanguageConfigurationRegistry.getBracketsSupport(mode.modeId) : null); }
}
let tokenType = this._currentLineTokens.getTokenType(this._currentTokenIndex); class TokenScanner {
let tokenEndIndex = this._currentLineTokens.getTokenEndOffset(this._currentTokenIndex);
let tmpTokenEndIndex = tokenEndIndex;
let nextBracket: Range = null; private _rawTokenScanner: ModelRawTokenScanner;
if (this._currentModeBrackets && !ignoreBracketsInToken(tokenType)) { private _nextBuff: Token[];
nextBracket = BracketsUtils.findNextBracketInToken(this._currentModeBrackets.forwardRegex, this._currentLineNumber, this._currentLineText, this._currentTokenStart, tokenEndIndex);
}
if (nextBracket && this._currentTokenStart < nextBracket.startColumn - 1) { private _cachedModeBrackets: IRichEditBrackets;
// found a bracket, but it is not at the beginning of the token private _cachedModeId: string;
tmpTokenEndIndex = nextBracket.startColumn - 1;
nextBracket = null; constructor(model: IModel) {
} this._rawTokenScanner = new ModelRawTokenScanner(model);
this._nextBuff = [];
this._cachedModeBrackets = null;
this._cachedModeId = null;
}
let bracketData: IRichEditBracket = null; next(): Token {
let bracketIsOpen: boolean = false; if (this._nextBuff.length > 0) {
if (nextBracket) { return this._nextBuff.shift();
let bracketText = this._currentLineText.substring(nextBracket.startColumn - 1, nextBracket.endColumn - 1); }
bracketText = bracketText.toLowerCase();
bracketData = this._currentModeBrackets.textIsBracket[bracketText]; const token = this._rawTokenScanner.next();
bracketIsOpen = this._currentModeBrackets.textIsOpenBracket[bracketText]; if (!token) {
return null;
}
const lineNumber = token.lineNumber;
const lineText = token.lineText;
const tokenType = token.type;
let startOffset = token.startOffset;
const endOffset = token.endOffset;
if (this._cachedModeId !== token.modeId) {
this._cachedModeId = token.modeId;
this._cachedModeBrackets = LanguageConfigurationRegistry.getBracketsSupport(this._cachedModeId);
}
const modeBrackets = this._cachedModeBrackets;
if (!modeBrackets || ignoreBracketsInToken(tokenType)) {
return new Token(
new Range(lineNumber, startOffset + 1, lineNumber, endOffset + 1),
tokenType,
TokenTreeBracket.None
);
} }
if (!bracketData) { let foundBracket: Range;
let token: Token = { do {
type: tokenType, foundBracket = BracketsUtils.findNextBracketInToken(modeBrackets.forwardRegex, lineNumber, lineText, startOffset, endOffset);
bracket: TokenTreeBracket.None, if (foundBracket) {
range: new Range( const foundBracketStartOffset = foundBracket.startColumn - 1;
this._currentLineNumber, const foundBracketEndOffset = foundBracket.endColumn - 1;
1 + this._currentTokenStart,
this._currentLineNumber, if (startOffset < foundBracketStartOffset) {
1 + tmpTokenEndIndex // there is some text before this bracket in this token
) this._nextBuff.push(new Token(
}; new Range(lineNumber, startOffset + 1, lineNumber, foundBracketStartOffset + 1),
// console.log('TOKEN: <<' + this._currentLineText.substring(this._currentTokenStart, tmpTokenEndIndex) + '>>'); tokenType,
TokenTreeBracket.None
if (tmpTokenEndIndex < tokenEndIndex) { ));
// there is a bracket somewhere in this token... }
this._currentTokenStart = tmpTokenEndIndex;
} else { let bracketText = lineText.substring(foundBracketStartOffset, foundBracketEndOffset);
this._currentTokenIndex += 1; bracketText = bracketText.toLowerCase();
this._currentTokenStart = (this._currentTokenIndex < this._currentLineTokens.getTokenCount() ? this._currentLineTokens.getTokenStartOffset(this._currentTokenIndex) : 0);
const bracketData = modeBrackets.textIsBracket[bracketText];
const bracketIsOpen = modeBrackets.textIsOpenBracket[bracketText];
this._nextBuff.push(new Token(
new Range(lineNumber, foundBracketStartOffset + 1, lineNumber, foundBracketEndOffset + 1),
`${bracketData.modeId};${bracketData.open};${bracketData.close}`,
bracketIsOpen ? TokenTreeBracket.Open : TokenTreeBracket.Close
));
startOffset = foundBracketEndOffset;
} }
return token; } while(foundBracket);
if (startOffset < endOffset) {
// there is some remaining none-bracket text in this token
this._nextBuff.push(new Token(
new Range(lineNumber, startOffset + 1, lineNumber, endOffset + 1),
tokenType,
TokenTreeBracket.None
));
} }
let type = `${bracketData.modeId};${bracketData.open};${bracketData.close}`; return this._nextBuff.shift();
let token: Token = {
type: type,
bracket: bracketIsOpen ? TokenTreeBracket.Open : TokenTreeBracket.Close,
range: new Range(
this._currentLineNumber,
1 + this._currentTokenStart,
this._currentLineNumber,
nextBracket.endColumn
)
};
// console.log('BRACKET: <<' + this._currentLineText.substring(this._currentTokenStart, nextBracket.endColumn - 1) + '>>');
if (nextBracket.endColumn - 1 < tokenEndIndex) {
// found a bracket, but it is not at the end of the token
this._currentTokenStart = nextBracket.endColumn - 1;
} else {
this._currentTokenIndex += 1;
this._currentTokenStart = (this._currentTokenIndex < this._currentLineTokens.getTokenCount() ? this._currentLineTokens.getTokenStartOffset(this._currentTokenIndex) : 0);
}
return token;
} }
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册