提交 4418ff2e 编写于 作者: A Alex Dima

Optimize usage of modeTransitions

上级 df829157
......@@ -19,13 +19,16 @@ export namespace Arrays {
*/
export function findIndexInSegmentsArray(arr: { startIndex: number; }[], desiredIndex: number): number {
var low = 0,
high = arr.length - 1,
mid: number;
let low = 0;
let high = arr.length - 1;
if (high <= 0) {
return 0;
}
while (low < high) {
mid = low + Math.ceil((high - low) / 2);
let mid = low + Math.ceil((high - low) / 2);
if (arr[mid].startIndex > desiredIndex) {
high = mid - 1;
......@@ -37,4 +40,4 @@ export namespace Arrays {
return low;
}
}
\ No newline at end of file
}
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import {IMode, IModeTransition} from 'vs/editor/common/modes';
import {Arrays} from 'vs/editor/common/core/arrays';
export class ModeTransition {
_modeTransitionTrait: void;
public startIndex:number;
public mode:IMode;
constructor(startIndex:number, mode:IMode) {
this.startIndex = startIndex|0;
this.mode = mode;
}
public static findIndexInSegmentsArray(arr:ModeTransition[], desiredIndex: number): number {
return Arrays.findIndexInSegmentsArray(arr, desiredIndex);
}
public static create(modeTransitions:IModeTransition[]): ModeTransition[] {
let result:ModeTransition[] = [];
for (let i = 0, len = modeTransitions.length; i < len; i++) {
let modeTransition = modeTransitions[i];
result.push(new ModeTransition(modeTransition.startIndex, modeTransition.mode));
}
return result;
}
}
......@@ -8,6 +8,7 @@ import * as strings from 'vs/base/common/strings';
import {ILineTokens, IReadOnlyLineMarker, ITokensInflatorMap} from 'vs/editor/common/editorCommon';
import {IMode, IModeTransition, IState, IToken} from 'vs/editor/common/modes';
import * as TokensBinaryEncoding from 'vs/editor/common/model/tokensBinaryEncoding';
import {ModeTransition} from 'vs/editor/common/core/modeTransition';
export interface ILineEdit {
startColumn: number;
......@@ -31,10 +32,6 @@ export interface IChangedMarkers {
[markerId:string]: boolean;
}
export interface IModeTransitions {
toArray(topLevelMode: IMode): IModeTransition[];
}
export interface ITextWithMarkers {
text: string;
markers: ILineMarker[];
......@@ -73,7 +70,7 @@ export class ModelLine {
public isInvalid:boolean;
private _state:IState;
private _modeTransitions:IModeTransitions;
private _modeTransitions:ModeTransition[];
private _lineTokens:ILineTokens;
private _markers:ILineMarker[];
......@@ -108,11 +105,12 @@ export class ModelLine {
this._modeTransitions = desired;
}
public getModeTransitions(): IModeTransitions {
public getModeTransitions(topLevelMode:IMode): ModeTransition[] {
if (this._modeTransitions) {
return this._modeTransitions;
} else {
return [new ModeTransition(0, topLevelMode)];
}
return DefaultModeTransitions.INSTANCE;
}
// --- END MODE TRANSITIONS
......@@ -800,57 +798,13 @@ export class DefaultLineTokens implements ILineTokens {
}
function toModeTransitions(topLevelMode:IMode, modeTransitions:IModeTransition[]): IModeTransitions {
function toModeTransitions(topLevelMode:IMode, modeTransitions:IModeTransition[]): ModeTransition[] {
if (!modeTransitions || modeTransitions.length === 0) {
return null;
} else if (modeTransitions.length === 1 && modeTransitions[0].startIndex === 0) {
if (modeTransitions[0].mode === topLevelMode) {
return null;
} else {
return new SingleModeTransition(modeTransitions[0].mode);
}
}
return new ModeTransitions(modeTransitions);
}
class DefaultModeTransitions implements IModeTransitions {
public static INSTANCE = new DefaultModeTransitions();
public toArray(topLevelMode:IMode): IModeTransition[] {
return [{
startIndex: 0,
mode: topLevelMode
}];
}
}
class SingleModeTransition implements IModeTransitions {
private _mode: IMode;
constructor(mode:IMode) {
this._mode = mode;
} else if (modeTransitions.length === 1 && modeTransitions[0].startIndex === 0 && modeTransitions[0].mode === topLevelMode) {
return null;
}
public toArray(topLevelMode:IMode): IModeTransition[] {
return [{
startIndex: 0,
mode: this._mode
}];
}
return ModeTransition.create(modeTransitions);
}
class ModeTransitions implements IModeTransitions {
private _modeTransitions: IModeTransition[];
constructor(modeTransitions:IModeTransition[]) {
this._modeTransitions = modeTransitions;
}
public toArray(topLevelMode:IMode): IModeTransition[] {
return this._modeTransitions.slice(0);
}
}
\ No newline at end of file
......@@ -12,18 +12,18 @@ import {StopWatch} from 'vs/base/common/stopwatch';
import * as timer from 'vs/base/common/timer';
import {TPromise} from 'vs/base/common/winjs.base';
import {DefaultConfig} from 'vs/editor/common/config/defaultConfig';
import {Arrays} from 'vs/editor/common/core/arrays';
import {Range} from 'vs/editor/common/core/range';
import * as editorCommon from 'vs/editor/common/editorCommon';
import {ModelLine} from 'vs/editor/common/model/modelLine';
import {TextModel} from 'vs/editor/common/model/textModel';
import {WordHelper} from 'vs/editor/common/model/textModelWithTokensHelpers';
import {TokenIterator} from 'vs/editor/common/model/tokenIterator';
import {ILineContext, ILineTokens, IMode, IModeTransition, IState} from 'vs/editor/common/modes';
import {ILineContext, ILineTokens, IMode, IState} from 'vs/editor/common/modes';
import {NullMode, NullState, nullTokenize} from 'vs/editor/common/modes/nullMode';
import {ignoreBracketsInToken} from 'vs/editor/common/modes/supports';
import {BracketsUtils} from 'vs/editor/common/modes/supports/richEditBrackets';
import * as TokensBinaryEncoding from 'vs/editor/common/model/tokensBinaryEncoding';
import {ModeTransition} from 'vs/editor/common/core/modeTransition';
export class TokensInflatorMap implements editorCommon.ITokensInflatorMap {
......@@ -139,12 +139,12 @@ export class FullModelRetokenizer implements IRetokenizeRequest {
class LineContext implements ILineContext {
public modeTransitions:IModeTransition[];
public modeTransitions:ModeTransition[];
private _text:string;
private _lineTokens:editorCommon.ILineTokens;
constructor (topLevelMode:IMode, line:ModelLine) {
this.modeTransitions = line.getModeTransitions().toArray(topLevelMode);
this.modeTransitions = line.getModeTransitions(topLevelMode);
this._text = line.text;
this._lineTokens = line.getTokens();
}
......@@ -200,9 +200,6 @@ export class TextModelWithTokens extends TextModel implements editorCommon.IToke
private _scheduleRetokenizeNow: RunOnceScheduler;
private _retokenizers:IRetokenizeRequest[];
private _tokenizationElapsedTime: number;
private _tokenizationTotalCharacters: number;
private _shouldSimplifyMode: boolean;
private _shouldDenyMode: boolean;
......@@ -226,9 +223,6 @@ export class TextModelWithTokens extends TextModel implements editorCommon.IToke
this._scheduleRetokenizeNow = null;
this._retokenizers = null;
this._tokenizationElapsedTime = 0;
this._tokenizationTotalCharacters = 0;
this._shouldSimplifyMode = (rawText.length > TextModelWithTokens.MODEL_SYNC_LIMIT);
this._shouldDenyMode = (rawText.length > TextModelWithTokens.MODEL_TOKENIZATION_LIMIT);
......@@ -391,8 +385,6 @@ export class TextModelWithTokens extends TextModel implements editorCommon.IToke
this._lines[i].setState(null);
}
this._initializeTokenizationState();
this._tokenizationElapsedTime = 0;
this._tokenizationTotalCharacters = 1;
}
private _clearTimers(): void {
......@@ -527,7 +519,7 @@ export class TextModelWithTokens extends TextModel implements editorCommon.IToke
return this.getStateAfterLine(lineNumber).getMode();
} else {
var modeTransitions = this._getLineModeTransitions(lineNumber);
var modeTransitionIndex = Arrays.findIndexInSegmentsArray(modeTransitions, column - 1);
var modeTransitionIndex = ModeTransition.findIndexInSegmentsArray(modeTransitions, column - 1);
return modeTransitions[modeTransitionIndex].mode;
}
}
......@@ -618,11 +610,6 @@ export class TextModelWithTokens extends TextModel implements editorCommon.IToke
}
elapsedTime = sw.elapsed();
// console.log('TOKENIZED LOCAL (' + this._mode.getId() + ') ' + tokenizedChars + '\t in \t' + elapsedTime + '\t speed \t' + tokenizedChars/elapsedTime);
// console.log('TOKENIZED GLOBAL(' + this._mode.getId() + ') ' + this._tokenizationTotalCharacters + '\t in*\t' + this._tokenizationElapsedTime + '\t speed*\t' + this._tokenizationTotalCharacters/this._tokenizationElapsedTime);
var t2 = timer.start(timer.Topic.EDITOR, '**speed: ' + this._tokenizationTotalCharacters / this._tokenizationElapsedTime);
t2.stop();
if (fromLineNumber <= toLineNumber) {
this.emitModelTokensChangedEvent(fromLineNumber, toLineNumber);
......@@ -645,12 +632,12 @@ export class TextModelWithTokens extends TextModel implements editorCommon.IToke
return lineNumber < this._lines.length ? this._lines[lineNumber].getState() : this._lastState;
}
_getLineModeTransitions(lineNumber:number): IModeTransition[] {
_getLineModeTransitions(lineNumber:number): ModeTransition[] {
if (lineNumber < 1 || lineNumber > this.getLineCount()) {
throw new Error('Illegal value ' + lineNumber + ' for `lineNumber`');
}
this._updateTokensUntilLine(lineNumber, true);
return this._lines[lineNumber - 1].getModeTransitions().toArray(this._mode);
return this._lines[lineNumber - 1].getModeTransitions(this._mode);
}
private _updateTokensUntilLine(lineNumber:number, emitEvents:boolean): void {
......@@ -661,9 +648,6 @@ export class TextModelWithTokens extends TextModel implements editorCommon.IToke
stopLineTokenizationAfter = 1000000000; // 1 billion, if a line is so long, you have other trouble :).
}
var sw = StopWatch.create(false);
var tokenizedCharacters = 0;
var fromLineNumber = this._invalidLineStartIndex + 1, toLineNumber = lineNumber;
// Validate all states up to and including endLineIndex
......@@ -676,7 +660,6 @@ export class TextModelWithTokens extends TextModel implements editorCommon.IToke
try {
// Tokenize only the first X characters
r = this._mode.tokenizationSupport.tokenize(this._lines[lineIndex].text, this._lines[lineIndex].getState(), 0, stopLineTokenizationAfter);
tokenizedCharacters = r ? r.actualStopOffset : this._lines[lineIndex].text.length;
} catch (e) {
e.friendlyMessage = TextModelWithTokens.MODE_TOKENIZATION_FAILED_MSG;
onUnexpectedError(e);
......@@ -752,9 +735,6 @@ export class TextModelWithTokens extends TextModel implements editorCommon.IToke
}
this._invalidLineStartIndex = Math.max(this._invalidLineStartIndex, endLineIndex + 1);
this._tokenizationElapsedTime += sw.elapsed();
this._tokenizationTotalCharacters += tokenizedCharacters;
if (emitEvents && fromLineNumber <= toLineNumber) {
this.emitModelTokensChangedEvent(fromLineNumber, toLineNumber);
}
......@@ -829,8 +809,8 @@ export class TextModelWithTokens extends TextModel implements editorCommon.IToke
public findMatchingBracketUp(bracket:string, _position:editorCommon.IPosition): editorCommon.IEditorRange {
let position = this.validatePosition(_position);
let modeTransitions = this._lines[position.lineNumber - 1].getModeTransitions().toArray(this._mode);
let currentModeIndex = Arrays.findIndexInSegmentsArray(modeTransitions, position.column - 1);
let modeTransitions = this._lines[position.lineNumber - 1].getModeTransitions(this._mode);
let currentModeIndex = ModeTransition.findIndexInSegmentsArray(modeTransitions, position.column - 1);
let currentMode = modeTransitions[currentModeIndex];
let currentModeBrackets = currentMode.mode.richEditSupport ? currentMode.mode.richEditSupport.brackets : null;
......@@ -861,8 +841,8 @@ export class TextModelWithTokens extends TextModel implements editorCommon.IToke
let currentTokenIndex = lineTokens.findIndexOfOffset(position.column - 1);
let currentTokenStart = getStartIndex(tokens[currentTokenIndex]);
let modeTransitions = this._lines[lineNumber - 1].getModeTransitions().toArray(this._mode);
let currentModeIndex = Arrays.findIndexInSegmentsArray(modeTransitions, position.column - 1);
let modeTransitions = this._lines[lineNumber - 1].getModeTransitions(this._mode);
let currentModeIndex = ModeTransition.findIndexInSegmentsArray(modeTransitions, position.column - 1);
let currentMode = modeTransitions[currentModeIndex];
let currentModeBrackets = currentMode.mode.richEditSupport ? currentMode.mode.richEditSupport.brackets : null;
......@@ -978,7 +958,7 @@ export class TextModelWithTokens extends TextModel implements editorCommon.IToke
let lineTokens = this._lines[lineNumber - 1].getTokens();
let lineText = this._lines[lineNumber - 1].text;
let tokens = lineTokens.getBinaryEncodedTokens();
let modeTransitions = this._lines[lineNumber - 1].getModeTransitions().toArray(this._mode);
let modeTransitions = this._lines[lineNumber - 1].getModeTransitions(this._mode);
let currentModeIndex = modeTransitions.length - 1;
let currentModeStart = modeTransitions[currentModeIndex].startIndex;
let currentModeId = modeTransitions[currentModeIndex].mode.getId();
......@@ -989,7 +969,7 @@ export class TextModelWithTokens extends TextModel implements editorCommon.IToke
tokensLength = lineTokens.findIndexOfOffset(position.column - 1);
currentTokenEnd = position.column - 1;
currentModeIndex = Arrays.findIndexInSegmentsArray(modeTransitions, position.column - 1);
currentModeIndex = ModeTransition.findIndexInSegmentsArray(modeTransitions, position.column - 1);
currentModeStart = modeTransitions[currentModeIndex].startIndex;
currentModeId = modeTransitions[currentModeIndex].mode.getId();
}
......@@ -1048,7 +1028,7 @@ export class TextModelWithTokens extends TextModel implements editorCommon.IToke
let lineTokens = this._lines[lineNumber - 1].getTokens();
let lineText = this._lines[lineNumber - 1].text;
let tokens = lineTokens.getBinaryEncodedTokens();
let modeTransitions = this._lines[lineNumber - 1].getModeTransitions().toArray(this._mode);
let modeTransitions = this._lines[lineNumber - 1].getModeTransitions(this._mode);
let currentModeIndex = 0;
let nextModeStart = (currentModeIndex + 1 < modeTransitions.length ? modeTransitions[currentModeIndex + 1].startIndex : lineText.length + 1);
let currentModeId = modeTransitions[currentModeIndex].mode.getId();
......@@ -1059,7 +1039,7 @@ export class TextModelWithTokens extends TextModel implements editorCommon.IToke
startTokenIndex = lineTokens.findIndexOfOffset(position.column - 1);
currentTokenStart = Math.max(currentTokenStart, position.column - 1);
currentModeIndex = Arrays.findIndexInSegmentsArray(modeTransitions, position.column - 1);
currentModeIndex = ModeTransition.findIndexInSegmentsArray(modeTransitions, position.column - 1);
nextModeStart = (currentModeIndex + 1 < modeTransitions.length ? modeTransitions[currentModeIndex + 1].startIndex : lineText.length + 1);
currentModeId = modeTransitions[currentModeIndex].mode.getId();
}
......
......@@ -4,10 +4,10 @@
*--------------------------------------------------------------------------------------------*/
'use strict';
import {Arrays} from 'vs/editor/common/core/arrays';
import {ILineTokens, IPosition, IWordAtPosition, IWordRange} from 'vs/editor/common/editorCommon';
import {IMode, IModeTransition} from 'vs/editor/common/modes';
import {NullMode} from 'vs/editor/common/modes/nullMode';
import {ModeTransition} from 'vs/editor/common/core/modeTransition';
export interface ITextSource {
......@@ -21,7 +21,7 @@ export interface ITextSource {
getModeAtPosition(lineNumber:number, column:number): IMode;
_getLineModeTransitions(lineNumber:number): IModeTransition[];
_getLineModeTransitions(lineNumber:number): ModeTransition[];
getLineTokens(lineNumber:number, inaccurateTokensAcceptable:boolean): ILineTokens;
}
......@@ -168,7 +168,7 @@ export class WordHelper {
var txt = textSource.getLineContent(position.lineNumber),
modeTransitions = textSource._getLineModeTransitions(position.lineNumber),
columnIndex = position.column - 1,
modeIndex = Arrays.findIndexInSegmentsArray(modeTransitions, columnIndex);
modeIndex = ModeTransition.findIndexInSegmentsArray(modeTransitions, columnIndex);
result = WordHelper._getWordAtColumn(txt, position.column, modeIndex, modeTransitions);
......
......@@ -12,6 +12,7 @@ import {TPromise} from 'vs/base/common/winjs.base';
import {AsyncDescriptor0} from 'vs/platform/instantiation/common/descriptors';
import {IMarker} from 'vs/platform/markers/common/markers';
import * as editorCommon from 'vs/editor/common/editorCommon';
import {ModeTransition} from 'vs/editor/common/core/modeTransition';
export interface IWorkerParticipantDescriptor {
modeId: string;
......@@ -165,7 +166,7 @@ export interface IModeDescriptor {
export interface ILineContext {
getLineContent(): string;
modeTransitions: IModeTransition[];
modeTransitions: ModeTransition[];
getTokenCount(): number;
getTokenStartIndex(tokenIndex:number): number;
......
......@@ -5,9 +5,9 @@
'use strict';
import * as strings from 'vs/base/common/strings';
import {Arrays} from 'vs/editor/common/core/arrays';
import {IModel, IPosition} from 'vs/editor/common/editorCommon';
import * as modes from 'vs/editor/common/modes';
import {ModeTransition} from 'vs/editor/common/core/modeTransition';
export class Token implements modes.IToken {
public startIndex:number;
......@@ -29,7 +29,7 @@ export function handleEvent<T>(context:modes.ILineContext, offset:number, runner
return runner(modeTransitions[0].mode, context, offset);
}
var modeIndex = Arrays.findIndexInSegmentsArray(modeTransitions, offset);
var modeIndex = ModeTransition.findIndexInSegmentsArray(modeTransitions, offset);
var nestedMode = modeTransitions[modeIndex].mode;
var modeStartIndex = modeTransitions[modeIndex].startIndex;
......@@ -87,7 +87,7 @@ export function isLineToken(context:modes.ILineContext, offset:number, types:str
export class FilteredLineContext implements modes.ILineContext {
public modeTransitions: modes.IModeTransition[];
public modeTransitions: ModeTransition[];
private _actual:modes.ILineContext;
private _firstTokenInModeIndex:number;
......@@ -99,10 +99,7 @@ export class FilteredLineContext implements modes.ILineContext {
firstTokenInModeIndex:number, nextTokenAfterMode:number,
firstTokenCharacterOffset:number, nextCharacterAfterModeIndex:number) {
this.modeTransitions = [{
startIndex: 0,
mode: mode
}];
this.modeTransitions = [new ModeTransition(0, mode)];
this._actual = actual;
this._firstTokenInModeIndex = firstTokenInModeIndex;
this._nextTokenAfterMode = nextTokenAfterMode;
......
......@@ -8,6 +8,7 @@ import {Arrays} from 'vs/editor/common/core/arrays';
import * as modes from 'vs/editor/common/modes';
import {RichEditSupport} from 'vs/editor/common/modes/supports/richEditSupport';
import {MockMode} from 'vs/editor/test/common/mocks/mockMode';
import {ModeTransition} from 'vs/editor/common/core/modeTransition';
class ModeWithRichEditSupport extends MockMode {
......@@ -45,16 +46,16 @@ export function createLineContextFromTokenText(tokens: TokenText[]): modes.ILine
}
export function createMockLineContext(line:string, tokens:modes.ILineTokens): modes.ILineContext {
return new TestLineContext(line, tokens.tokens, tokens.modeTransitions);
return new TestLineContext(line, tokens.tokens, ModeTransition.create(tokens.modeTransitions));
}
class TestLineContext implements modes.ILineContext {
public modeTransitions: modes.IModeTransition[];
public modeTransitions: ModeTransition[];
private _line:string;
private _tokens: modes.IToken[];
constructor(line:string, tokens: modes.IToken[], modeTransitions:modes.IModeTransition[]) {
constructor(line:string, tokens: modes.IToken[], modeTransitions:ModeTransition[]) {
this.modeTransitions = modeTransitions;
this._line = line;
this._tokens = tokens;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册