mirror of
https://github.com/microsoft/vscode.git
synced 2026-04-23 18:19:12 +01:00
Fixes #3662: validate positions when converting them
This commit is contained in:
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user