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

Fixes #3662: validate positions when converting them

上级 2e264669
......@@ -622,8 +622,20 @@ export class SplitLinesCollection implements ILinesCollection {
return this.prefixSumComputer.getTotalValue();
}
private _toValidOutputLineNumber(outputLineNumber: number): number {
if (outputLineNumber < 1) {
return 1;
}
let outputLineCount = this.getOutputLineCount();
if (outputLineNumber > outputLineCount) {
return outputLineCount;
}
return outputLineNumber;
}
public getOutputLineContent(outputLineNumber: number): string {
this._ensureValidState();
outputLineNumber = this._toValidOutputLineNumber(outputLineNumber);
this.prefixSumComputer.getIndexOf(outputLineNumber - 1, this.tmpIndexOfResult);
var lineIndex = this.tmpIndexOfResult.index;
var remainder = this.tmpIndexOfResult.remainder;
......@@ -633,6 +645,7 @@ export class SplitLinesCollection implements ILinesCollection {
public getOutputLineMinColumn(outputLineNumber:number): number {
this._ensureValidState();
outputLineNumber = this._toValidOutputLineNumber(outputLineNumber);
this.prefixSumComputer.getIndexOf(outputLineNumber - 1, this.tmpIndexOfResult);
var lineIndex = this.tmpIndexOfResult.index;
var remainder = this.tmpIndexOfResult.remainder;
......@@ -642,6 +655,7 @@ export class SplitLinesCollection implements ILinesCollection {
public getOutputLineMaxColumn(outputLineNumber: number): number {
this._ensureValidState();
outputLineNumber = this._toValidOutputLineNumber(outputLineNumber);
this.prefixSumComputer.getIndexOf(outputLineNumber - 1, this.tmpIndexOfResult);
var lineIndex = this.tmpIndexOfResult.index;
var remainder = this.tmpIndexOfResult.remainder;
......@@ -651,6 +665,7 @@ export class SplitLinesCollection implements ILinesCollection {
public getOutputLineTokens(outputLineNumber: number, inaccurateTokensAcceptable: boolean): editorCommon.IViewLineTokens {
this._ensureValidState();
outputLineNumber = this._toValidOutputLineNumber(outputLineNumber);
this.prefixSumComputer.getIndexOf(outputLineNumber - 1, this.tmpIndexOfResult);
var lineIndex = this.tmpIndexOfResult.index;
var remainder = this.tmpIndexOfResult.remainder;
......@@ -660,20 +675,23 @@ export class SplitLinesCollection implements ILinesCollection {
public convertOutputPositionToInputPosition(viewLineNumber: number, viewColumn: number): editorCommon.IEditorPosition {
this._ensureValidState();
viewLineNumber = this._toValidOutputLineNumber(viewLineNumber);
this.prefixSumComputer.getIndexOf(viewLineNumber - 1, this.tmpIndexOfResult);
var lineIndex = this.tmpIndexOfResult.index;
var remainder = this.tmpIndexOfResult.remainder;
var inputColumn = this.lines[lineIndex].getInputColumnOfOutputPosition(remainder, viewColumn);
// console.log('out -> in ' + viewLineNumber + ',' + viewColumn + ' ===> ' + (lineIndex+1) + ',' + inputColumn);
return new Position(lineIndex+1, inputColumn);
// console.log('out -> in ' + viewLineNumber + ',' + viewColumn + ' ===> ' + (lineIndex+1) + ',' + inputColumn);
return this.model.validatePosition(new Position(lineIndex+1, inputColumn));
}
public convertInputPositionToOutputPosition(inputLineNumber: number, inputColumn: number): editorCommon.IEditorPosition {
public convertInputPositionToOutputPosition(_inputLineNumber: number, _inputColumn: number): editorCommon.IEditorPosition {
this._ensureValidState();
if (inputLineNumber > this.lines.length) {
inputLineNumber = this.lines.length;
}
let validPosition = this.model.validatePosition(new Position(_inputLineNumber, _inputColumn));
let inputLineNumber = validPosition.lineNumber;
let inputColumn = validPosition.column;
let lineIndex = inputLineNumber - 1, lineIndexChanged = false;
while (lineIndex > 0 && !this.lines[lineIndex].isVisible()) {
......@@ -682,6 +700,7 @@ export class SplitLinesCollection implements ILinesCollection {
}
if (lineIndex === 0 && !this.lines[lineIndex].isVisible()) {
// Could not reach a real line
// console.log('in -> out ' + inputLineNumber + ',' + inputColumn + ' ===> ' + 1 + ',' + 1);
return new Position(1, 1);
}
var deltaLineNumber = 1 + (lineIndex === 0 ? 0 : this.prefixSumComputer.getAccumulatedValue(lineIndex - 1));
......@@ -693,7 +712,7 @@ export class SplitLinesCollection implements ILinesCollection {
r = this.lines[inputLineNumber - 1].getOutputPositionOfInputPosition(deltaLineNumber, inputColumn);
}
// console.log('in -> out ' + inputLineNumber + ',' + inputColumn + ' ===> ' + r.lineNumber + ',' + r.column);
// console.log('in -> out ' + inputLineNumber + ',' + inputColumn + ' ===> ' + r.lineNumber + ',' + r);
return r;
}
}
\ No newline at end of file
......@@ -6,9 +6,12 @@
import * as assert from 'assert';
import {Position} from 'vs/editor/common/core/position';
import {CharacterHardWrappingLineMapping} from 'vs/editor/common/viewModel/characterHardWrappingLineMapper';
import {CharacterHardWrappingLineMapping, CharacterHardWrappingLineMapperFactory} from 'vs/editor/common/viewModel/characterHardWrappingLineMapper';
import {PrefixSumComputer} from 'vs/editor/common/viewModel/prefixSumComputer';
import {ILineMapping, IModel, SplitLine} from 'vs/editor/common/viewModel/splitLinesCollection';
import {ILineMapping, IModel, SplitLine, SplitLinesCollection} from 'vs/editor/common/viewModel/splitLinesCollection';
import {MockConfiguration} from 'vs/editor/test/common/mocks/mockConfiguration';
import {Model} from 'vs/editor/common/model/model';
import * as editorCommon from 'vs/editor/common/editorCommon';
suite('Editor ViewModel - SplitLinesCollection', () => {
test('SplitLine', () => {
......@@ -76,6 +79,93 @@ suite('Editor ViewModel - SplitLinesCollection', () => {
assert.deepEqual(line1.getOutputPositionOfInputPosition(0, col), pos(2, 1 + col - 13 - 14), 'getOutputPositionOfInputPosition(' + col + ')');
}
});
test('issue #3662', () => {
let config = new MockConfiguration({});
let hardWrappingLineMapperFactory = new CharacterHardWrappingLineMapperFactory(
config.editor.wordWrapBreakBeforeCharacters,
config.editor.wordWrapBreakAfterCharacters,
config.editor.wordWrapBreakObtrusiveCharacters
);
let model = new Model([
'int main() {',
'\tprintf("Hello world!");',
'}',
'int main() {',
'\tprintf("Hello world!");',
'}',
].join('\n'), editorCommon.DefaultEndOfLine.LF, null);
let linesCollection = new SplitLinesCollection(
model,
hardWrappingLineMapperFactory,
config.getIndentationOptions().tabSize,
config.editor.wrappingInfo.wrappingColumn,
config.editor.typicalFullwidthCharacterWidth / config.editor.typicalHalfwidthCharacterWidth,
editorCommon.wrappingIndentFromString(config.editor.wrappingIndent)
);
linesCollection.setHiddenAreas([{
startLineNumber: 1,
startColumn: 1,
endLineNumber: 3,
endColumn: 1
}, {
startLineNumber: 5,
startColumn: 1,
endLineNumber: 6,
endColumn: 1
}], (eventType, payload) => {/*no-op*/});
let viewLineCount = linesCollection.getOutputLineCount();
assert.equal(viewLineCount, 1, 'getOutputLineCount()');
let modelLineCount = model.getLineCount();
for (let lineNumber = 0; lineNumber <= modelLineCount + 1; lineNumber++) {
let lineMinColumn = (lineNumber >= 1 && lineNumber <= modelLineCount) ? model.getLineMinColumn(lineNumber) : 1;
let lineMaxColumn = (lineNumber >= 1 && lineNumber <= modelLineCount) ? model.getLineMaxColumn(lineNumber) : 1;
for (let column = lineMinColumn - 1; column <= lineMaxColumn + 1; column++) {
let viewPosition = linesCollection.convertInputPositionToOutputPosition(lineNumber, column);
// validate view position
let viewLineNumber = viewPosition.lineNumber;
let viewColumn = viewPosition.column;
if (viewLineNumber < 1) {
viewLineNumber = 1;
}
var lineCount = linesCollection.getOutputLineCount();
if (viewLineNumber > lineCount) {
viewLineNumber = lineCount;
}
var viewMinColumn = linesCollection.getOutputLineMinColumn(viewLineNumber);
var viewMaxColumn = linesCollection.getOutputLineMaxColumn(viewLineNumber);
if (viewColumn < viewMinColumn) {
viewColumn = viewMinColumn;
}
if (viewColumn > viewMaxColumn) {
viewColumn = viewMaxColumn;
}
let validViewPosition = new Position(viewLineNumber, viewColumn);
assert.equal(viewPosition.toString(), validViewPosition.toString(), 'model->view for ' + lineNumber + ', ' + column);
}
}
for (let lineNumber = 0; lineNumber <= viewLineCount + 1; lineNumber++) {
let lineMinColumn = linesCollection.getOutputLineMinColumn(lineNumber);
let lineMaxColumn = linesCollection.getOutputLineMaxColumn(lineNumber);
for (let column = lineMinColumn - 1; column <= lineMaxColumn + 1; column++) {
let modelPosition = linesCollection.convertOutputPositionToInputPosition(lineNumber, column);
let validModelPosition = model.validatePosition(modelPosition);
assert.equal(modelPosition.toString(), validModelPosition.toString(), 'view->model for ' + lineNumber + ', ' + column);
}
}
linesCollection.dispose();
model.dispose();
config.dispose();
});
});
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册