提交 2a34051d 编写于 作者: A Alex Dima

Remove unused code

上级 d98f5893
/*---------------------------------------------------------------------------------------------
* 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 * as editorCommon from 'vs/editor/common/editorCommon';
import { LineToken } from 'vs/editor/common/core/lineTokens';
import { Position } from 'vs/editor/common/core/position';
import { StandardTokenType } from 'vs/editor/common/modes';
export interface ITokenInfo {
readonly type: StandardTokenType;
readonly lineNumber: number;
readonly startColumn: number;
readonly endColumn: number;
}
export interface ITokenIterator {
hasNext(): boolean;
next(): ITokenInfo;
hasPrev(): boolean;
prev(): ITokenInfo;
}
class TokenInfo implements ITokenInfo {
_tokenInfoBrand: void;
readonly _actual: LineToken;
public readonly lineNumber: number;
public readonly startColumn: number;
public readonly endColumn: number;
public readonly type: StandardTokenType;
constructor(actual: LineToken, lineNumber: number) {
this._actual = actual;
this.lineNumber = lineNumber;
this.startColumn = this._actual.startOffset + 1;
this.endColumn = this._actual.endOffset + 1;
this.type = this._actual.tokenType;
}
}
function findClosestNonEmptyLine(model: editorCommon.ITokenizedModel, position: Position): Position {
const lineNumber = position.lineNumber;
if (model.getLineMaxColumn(lineNumber) !== 1) {
return position;
}
const lineCount = model.getLineCount();
// we need to go up or down
let distance = 1;
while (true) {
let aboveLineNumber = lineNumber - distance;
let belowLineNumber = lineNumber + distance;
if (aboveLineNumber < 1 && belowLineNumber > lineCount) {
// No more lines above or below
break;
}
if (aboveLineNumber >= 1) {
let aboveMaxColumn = model.getLineMaxColumn(aboveLineNumber);
if (aboveMaxColumn !== 1) {
// bingo!
return new Position(aboveLineNumber, aboveMaxColumn);
}
}
if (belowLineNumber <= lineCount) {
let belowMaxColumn = model.getLineMaxColumn(belowLineNumber);
if (belowMaxColumn !== 1) {
// bingo!
return new Position(belowLineNumber, 1);
}
}
distance++;
}
return null;
}
export class TokenIterator implements ITokenIterator {
private _model: editorCommon.ITokenizedModel;
private _lineCount: number;
private _prev: TokenInfo;
private _next: TokenInfo;
constructor(model: editorCommon.ITokenizedModel, position: Position) {
this._model = model;
this._lineCount = this._model.getLineCount();
this._prev = null;
this._next = null;
position = findClosestNonEmptyLine(model, position);
if (position) {
this._model.forceTokenization(position.lineNumber);
let lineTokens = this._model.getLineTokens(position.lineNumber);
let currentToken = lineTokens.findTokenAtOffset(position.column - 1);
if (currentToken) {
this._prev = this._next = new TokenInfo(currentToken, position.lineNumber);
}
}
}
private _advanceNext(): void {
if (!this._next) {
return;
}
let lineNumber = this._next.lineNumber;
let next = this._next._actual.next();
while (!next && lineNumber < this._lineCount) {
lineNumber++;
this._model.forceTokenization(lineNumber);
let currentLineTokens = this._model.getLineTokens(lineNumber);
next = currentLineTokens.firstToken();
}
this._prev = this._next;
if (next) {
this._next = new TokenInfo(next, lineNumber);
} else {
this._next = null;
}
}
private _advancePrev(): void {
if (!this._prev) {
return;
}
let lineNumber = this._prev.lineNumber;
let prev = this._prev._actual.prev();
while (!prev && lineNumber > 1) {
lineNumber--;
this._model.forceTokenization(lineNumber);
let currentLineTokens = this._model.getLineTokens(lineNumber);
prev = currentLineTokens.lastToken();
}
this._next = this._prev;
if (prev) {
this._prev = new TokenInfo(prev, lineNumber);
} else {
this._prev = null;
}
}
public hasNext(): boolean {
return this._next !== null;
}
public next(): ITokenInfo {
const result = this._next;
this._advanceNext();
return result;
}
public hasPrev(): boolean {
return this._prev !== null;
}
public prev(): ITokenInfo {
const result = this._prev;
this._advancePrev();
return result;
}
public _invalidate() {
// replace all public functions with errors
var errorFn = function (): any {
throw new Error('iteration isn\'t valid anymore');
};
this.hasNext = errorFn;
this.next = errorFn;
this.hasPrev = errorFn;
this.prev = errorFn;
}
}
......@@ -13,7 +13,6 @@ import { Model } from 'vs/editor/common/model/model';
import * as modes from 'vs/editor/common/modes';
import { NULL_STATE } from 'vs/editor/common/modes/nullMode';
import { TokenizationResult2 } from 'vs/editor/common/core/token';
import { TokenIterator, ITokenInfo } from 'vs/editor/common/model/tokenIterator';
// --------- utils
......@@ -289,242 +288,3 @@ suite('Editor Model - Model Modes 2', () => {
statesEqual(thisModel, ['', 'ne3', 'Line4', 'Line5']);
});
});
suite('Editor Model - Token Iterator', () => {
const tokenizationSupport: modes.ITokenizationSupport = {
getInitialState: (): modes.IState => NULL_STATE,
tokenize: undefined,
tokenize2: (line: string, state: modes.IState): TokenizationResult2 => {
if (line.length % 3 !== 0) {
throw new Error('Unexpected line length in ' + line);
}
let tokensCount = line.length / 3;
let tokens = new Uint32Array(tokensCount << 1);
for (let i = 0; i < tokensCount; i++) {
tokens[(i << 1)] = 3 * i;
tokens[(i << 1) + 1] = (
i << modes.MetadataConsts.FOREGROUND_OFFSET
) >>> 0;
}
return new TokenizationResult2(tokens, state);
}
};
let thisModel: Model = null;
let languageRegistration: IDisposable = null;
setup(() => {
const TEXT =
'foobarfoobar' + '\r\n' +
'foobarfoobar' + '\r\n' +
'foobarfoobar' + '\r\n';
const LANGUAGE_ID = 'modelModeTestTokenIterator';
languageRegistration = modes.TokenizationRegistry.register(LANGUAGE_ID, tokenizationSupport);
thisModel = Model.createFromString(TEXT, undefined, new modes.LanguageIdentifier(LANGUAGE_ID, 0));
});
teardown(() => {
thisModel.dispose();
thisModel = null;
languageRegistration.dispose();
languageRegistration = null;
});
function tokenIterator(model: Model, position: Position, callback: (it: TokenIterator) => any): any {
let iter = new TokenIterator(model, model.validatePosition(position));
let result = callback(iter);
iter._invalidate();
return result;
}
test('all tokens with ranges', () => {
var calls = 0;
var ranges = [
[1, 4, 4, 7, 7, 10, 10, 13],
[1, 4, 4, 7, 7, 10, 10, 13],
[1, 4, 4, 7, 7, 10, 10, 13],
];
tokenIterator(thisModel, new Position(1, 1), (iter) => {
var a: number[] = [], line = 0;
while (iter.hasNext()) {
calls++;
if (a.length === 0) {
a = ranges.shift();
line += 1;
}
var next = iter.next();
assert.equal(next.lineNumber, line);
assert.equal(next.startColumn, a.shift());
assert.equal(next.endColumn, a.shift());
}
});
assert.equal(calls, 12, 'calls');
});
test('all tokens from beginning with next', () => {
var n = 0;
tokenIterator(thisModel, new Position(1, 1), (iter) => {
while (iter.hasNext()) {
iter.next();
n++;
}
});
assert.equal(n, 12);
});
test('all tokens from beginning with prev', () => {
var n = 0;
tokenIterator(thisModel, new Position(1, 1), (iter) => {
while (iter.hasPrev()) {
iter.prev();
n++;
}
});
assert.equal(n, 1);
});
test('all tokens from end with prev', () => {
var n = 0;
tokenIterator(thisModel, new Position(3, 12), (iter) => {
while (iter.hasPrev()) {
iter.prev();
n++;
}
});
assert.equal(n, 12);
});
test('all tokens from end with next', () => {
var n = 0;
tokenIterator(thisModel, new Position(3, 12), (iter) => {
while (iter.hasNext()) {
iter.next();
n++;
}
});
assert.equal(n, 1);
});
test('prev and next are assert.equal at start', () => {
var calls = 0;
tokenIterator(thisModel, new Position(1, 2), (iter) => {
calls++;
var next = iter.next();
var prev = iter.prev();
assert.deepEqual(next, prev);
});
assert.equal(calls, 1, 'calls');
});
test('position variance within token', () => {
var calls = 0;
tokenIterator(thisModel, new Position(1, 4), (iter) => {
calls++;
var next = iter.next();
assert.equal(next.lineNumber, 1);
assert.equal(next.startColumn, 4);
assert.equal(next.endColumn, 7);
});
tokenIterator(thisModel, new Position(1, 5), (iter) => {
calls++;
var next = iter.next();
assert.equal(next.lineNumber, 1);
assert.equal(next.startColumn, 4);
assert.equal(next.endColumn, 7);
});
tokenIterator(thisModel, new Position(1, 6), (iter) => {
calls++;
var next = iter.next();
assert.equal(next.lineNumber, 1);
assert.equal(next.startColumn, 4);
assert.equal(next.endColumn, 7);
});
assert.equal(calls, 3, 'calls');
});
test('iterator allows next/prev', () => {
var n = 0;
var up: ITokenInfo[] = [], down: ITokenInfo[] = [];
tokenIterator(thisModel, new Position(1, 1), (iter) => {
while (iter.hasNext()) {
var next = iter.next();
up.push(next);
n++;
}
while (iter.hasPrev()) {
var prev = iter.prev();
down.push(prev);
n++;
}
});
assert.equal(n, 24);
assert.equal(up.length, 12);
assert.equal(down.length, 12);
while (up.length) {
assert.deepEqual(up.pop(), down.shift());
}
});
test('iterator allows prev/next', () => {
var n = 0;
var up: ITokenInfo[] = [], down: ITokenInfo[] = [];
tokenIterator(thisModel, new Position(3, 12), (iter) => {
while (iter.hasPrev()) {
var prev = iter.prev();
down.push(prev);
n++;
}
while (iter.hasNext()) {
var next = iter.next();
up.push(next);
n++;
}
});
assert.equal(n, 24);
assert.equal(up.length, 12);
assert.equal(down.length, 12);
while (up.length) {
assert.deepEqual(up.pop(), down.shift());
}
});
test('iterator can not be used outside of callback', () => {
var illegalIterReference: TokenIterator;
tokenIterator(thisModel, new Position(3, 12), (iter) => {
illegalIterReference = iter;
});
try {
illegalIterReference.hasNext();
assert.ok(false);
} catch (e) {
assert.ok(true);
}
try {
illegalIterReference.next();
assert.ok(false);
} catch (e) {
assert.ok(true);
}
try {
illegalIterReference.hasPrev();
assert.ok(false);
} catch (e) {
assert.ok(true);
}
try {
illegalIterReference.prev();
assert.ok(false);
} catch (e) {
assert.ok(true);
}
});
});
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册