Merge from master

This commit is contained in:
Raj Musuku
2019-02-21 17:56:04 -08:00
parent 5a146e34fa
commit 666ae11639
11482 changed files with 119352 additions and 255574 deletions

View File

@@ -2,15 +2,14 @@
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import { Position } from 'vs/editor/common/core/position';
import { CharCode } from 'vs/base/common/charCode';
import { Position } from 'vs/editor/common/core/position';
import { Range } from 'vs/editor/common/core/range';
import { ITextSnapshot } from 'vs/platform/files/common/files';
import { leftest, righttest, updateTreeMetadata, rbDelete, fixInsert, NodeColor, SENTINEL, TreeNode } from 'vs/editor/common/model/pieceTreeTextBuffer/rbTreeBase';
import { SearchData, isValidMatch, Searcher, createFindMatch } from 'vs/editor/common/model/textModelSearch';
import { FindMatch } from 'vs/editor/common/model';
import { NodeColor, SENTINEL, TreeNode, fixInsert, leftest, rbDelete, righttest, updateTreeMetadata } from 'vs/editor/common/model/pieceTreeTextBuffer/rbTreeBase';
import { SearchData, Searcher, createFindMatch, isValidMatch } from 'vs/editor/common/model/textModelSearch';
import { ITextSnapshot } from 'vs/platform/files/common/files';
// const lfRegex = new RegExp(/\r\n|\r|\n/g);
export const AverageBufferSize = 65535;
@@ -178,7 +177,7 @@ class PieceTreeSnapshot implements ITextSnapshot {
}
}
read(): string {
read(): string | null {
if (this._pieces.length === 0) {
if (this._index === 0) {
this._index++;
@@ -199,16 +198,22 @@ class PieceTreeSnapshot implements ITextSnapshot {
}
}
interface CacheEntry {
node: TreeNode;
nodeStartOffset: number;
nodeStartLineNumber?: number;
}
class PieceTreeSearchCache {
private _limit: number;
private _cache: { node: TreeNode, nodeStartOffset: number, nodeStartLineNumber?: number }[];
private _cache: CacheEntry[];
constructor(limit: number) {
this._limit = limit;
this._cache = [];
}
public get(offset: number): { node: TreeNode, nodeStartOffset: number, nodeStartLineNumber?: number } {
public get(offset: number): CacheEntry | null {
for (let i = this._cache.length - 1; i >= 0; i--) {
let nodePos = this._cache[i];
if (nodePos.nodeStartOffset <= offset && nodePos.nodeStartOffset + nodePos.node.piece.length >= offset) {
@@ -218,17 +223,17 @@ class PieceTreeSearchCache {
return null;
}
public get2(lineNumber: number): { node: TreeNode, nodeStartOffset: number, nodeStartLineNumber?: number } {
public get2(lineNumber: number): { node: TreeNode, nodeStartOffset: number, nodeStartLineNumber: number } | null {
for (let i = this._cache.length - 1; i >= 0; i--) {
let nodePos = this._cache[i];
if (nodePos.nodeStartLineNumber && nodePos.nodeStartLineNumber < lineNumber && nodePos.nodeStartLineNumber + nodePos.node.piece.lineFeedCnt >= lineNumber) {
return nodePos;
return <{ node: TreeNode, nodeStartOffset: number, nodeStartLineNumber: number }>nodePos;
}
}
return null;
}
public set(nodePosition: { node: TreeNode, nodeStartOffset: number, nodeStartLineNumber?: number }) {
public set(nodePosition: CacheEntry) {
if (this._cache.length >= this._limit) {
this._cache.shift();
}
@@ -237,20 +242,22 @@ class PieceTreeSearchCache {
public valdiate(offset: number) {
let hasInvalidVal = false;
for (let i = 0; i < this._cache.length; i++) {
let nodePos = this._cache[i];
let tmp: (CacheEntry | null)[] = this._cache;
for (let i = 0; i < tmp.length; i++) {
let nodePos = tmp[i]!;
if (nodePos.node.parent === null || nodePos.nodeStartOffset >= offset) {
this._cache[i] = null;
tmp[i] = null;
hasInvalidVal = true;
continue;
}
}
if (hasInvalidVal) {
let newArr = [];
for (let i = 0; i < this._cache.length; i++) {
if (this._cache[i] !== null) {
newArr.push(this._cache[i]);
let newArr: CacheEntry[] = [];
for (let i = 0; i < tmp.length; i++) {
const entry = tmp[i];
if (entry !== null) {
newArr.push(entry);
}
}
@@ -269,7 +276,7 @@ export class PieceTreeBase {
protected _EOLNormalized: boolean;
private _lastChangeBufferPos: BufferCursor;
private _searchCache: PieceTreeSearchCache;
private _lastVisitedLine: { lineNumber: number, value: string };
private _lastVisitedLine: { lineNumber: number; value: string; };
constructor(chunks: StringBuffer[], eol: '\r\n' | '\n', eolNormalized: boolean) {
this.create(chunks, eol, eolNormalized);
@@ -287,7 +294,7 @@ export class PieceTreeBase {
this._EOLLength = eol.length;
this._EOLNormalized = eolNormalized;
let lastNode: TreeNode = null;
let lastNode: TreeNode | null = null;
for (let i = 0, len = chunks.length; i < len; i++) {
if (chunks[i].buffer.length > 0) {
if (!chunks[i].lineStarts) {
@@ -307,7 +314,7 @@ export class PieceTreeBase {
}
this._searchCache = new PieceTreeSearchCache(1);
this._lastVisitedLine = { lineNumber: 0, value: null };
this._lastVisitedLine = { lineNumber: 0, value: '' };
this.computeBufferMetadata();
}
@@ -570,7 +577,7 @@ export class PieceTreeBase {
let start = this.offsetInBuffer(node.piece.bufferIndex, startCursor);
let end = this.offsetInBuffer(node.piece.bufferIndex, endCursor);
let m: RegExpExecArray;
let m: RegExpExecArray | null;
// Reset regex to search from the beginning
searcher.reset(start);
let ret: BufferCursor = { line: 0, column: 0 };
@@ -694,7 +701,7 @@ export class PieceTreeBase {
return resultLen;
}
let m: RegExpExecArray;
let m: RegExpExecArray | null;
// Reset regex to search from the beginning
searcher.reset(0);
do {
@@ -715,7 +722,7 @@ export class PieceTreeBase {
insert(offset: number, value: string, eolNormalized: boolean = false): void {
this._EOLNormalized = this._EOLNormalized && eolNormalized;
this._lastVisitedLine.lineNumber = 0;
this._lastVisitedLine.value = null;
this._lastVisitedLine.value = '';
if (this.root !== SENTINEL) {
let { node, remainder, nodeStartOffset } = this.nodeAt(offset);
@@ -739,7 +746,7 @@ export class PieceTreeBase {
this._searchCache.valdiate(offset);
} else if (nodeStartOffset + node.piece.length > offset) {
// we are inserting into the middle of a node.
let nodesToDel = [];
let nodesToDel: TreeNode[] = [];
let newRightPiece = new Piece(
piece.bufferIndex,
insertPosInBuffer,
@@ -812,7 +819,7 @@ export class PieceTreeBase {
delete(offset: number, cnt: number): void {
this._lastVisitedLine.lineNumber = 0;
this._lastVisitedLine.value = null;
this._lastVisitedLine.value = '';
if (cnt <= 0 || this.root === SENTINEL) {
return;
@@ -855,7 +862,7 @@ export class PieceTreeBase {
return;
}
let nodesToDel = [];
let nodesToDel: TreeNode[] = [];
let startSplitPosInBuffer = this.positionInBuffer(startNode, startPosition.remainder);
this.deleteNodeTail(startNode, startSplitPosInBuffer);
@@ -885,7 +892,7 @@ export class PieceTreeBase {
insertContentToNodeLeft(value: string, node: TreeNode) {
// we are inserting content to the beginning of node
let nodesToDel = [];
let nodesToDel: TreeNode[] = [];
if (this.shouldCheckCRLF() && this.endWithCR(value) && this.startWithLF(node)) {
// move `\n` to new node.
@@ -936,7 +943,9 @@ export class PieceTreeBase {
this.validateCRLFWithPrevNode(newNode);
}
positionInBuffer(node: TreeNode, remainder: number, ret?: BufferCursor): BufferCursor {
positionInBuffer(node: TreeNode, remainder: number): BufferCursor;
positionInBuffer(node: TreeNode, remainder: number, ret: BufferCursor): null;
positionInBuffer(node: TreeNode, remainder: number, ret?: BufferCursor): BufferCursor | null {
let piece = node.piece;
let bufferIndex = node.piece.bufferIndex;
let lineStarts = this._buffers[bufferIndex].lineStarts;
@@ -949,9 +958,9 @@ export class PieceTreeBase {
let low = piece.start.line;
let high = piece.end.line;
let mid: number;
let midStop: number;
let midStart: number;
let mid: number = 0;
let midStop: number = 0;
let midStart: number = 0;
while (low <= high) {
mid = low + ((high - low) / 2) | 0;
@@ -1029,7 +1038,7 @@ export class PieceTreeBase {
if (text.length > AverageBufferSize) {
// the content is large, operations like substring, charCode becomes slow
// so here we split it into smaller chunks, just like what we did for CR/LF normalization
let newPieces = [];
let newPieces: Piece[] = [];
while (text.length > AverageBufferSize) {
const lastChar = text.charCodeAt(AverageBufferSize - 1);
let splitText;
@@ -1100,7 +1109,7 @@ export class PieceTreeBase {
let endColumn = endOffset - this._buffers[0].lineStarts[endIndex];
let endPos = { line: endIndex, column: endColumn };
let newPiece = new Piece(
0, /** todo */
0, /** todo@peng */
start,
endPos,
this.getLineFeedCnt(0, start, endPos),
@@ -1388,7 +1397,7 @@ export class PieceTreeBase {
}
}
return null;
return null!;
}
nodeAt2(lineNumber: number, column: number): NodePosition {
@@ -1455,7 +1464,7 @@ export class PieceTreeBase {
x = x.next();
}
return null;
return null!;
}
nodeCharCodeAt(node: TreeNode, offset: number): number {
@@ -1545,7 +1554,7 @@ export class PieceTreeBase {
}
fixCRLF(prev: TreeNode, next: TreeNode) {
let nodesToDel = [];
let nodesToDel: TreeNode[] = [];
// update node
let lineStarts = this._buffers[prev.piece.bufferIndex].lineStarts;
let newEnd: BufferCursor;
@@ -1677,7 +1686,7 @@ export class PieceTreeBase {
* /
* z
*/
rbInsertRight(node: TreeNode, p: Piece): TreeNode {
rbInsertRight(node: TreeNode | null, p: Piece): TreeNode {
let z = new TreeNode(p, NodeColor.Red);
z.left = SENTINEL;
z.right = SENTINEL;
@@ -1689,11 +1698,11 @@ export class PieceTreeBase {
if (x === SENTINEL) {
this.root = z;
z.color = NodeColor.Black;
} else if (node.right === SENTINEL) {
node.right = z;
z.parent = node;
} else if (node!.right === SENTINEL) {
node!.right = z;
z.parent = node!;
} else {
let nextNode = leftest(node.right);
let nextNode = leftest(node!.right);
nextNode.left = z;
z.parent = nextNode;
}
@@ -1709,7 +1718,7 @@ export class PieceTreeBase {
* \
* z
*/
rbInsertLeft(node: TreeNode, p: Piece): TreeNode {
rbInsertLeft(node: TreeNode | null, p: Piece): TreeNode {
let z = new TreeNode(p, NodeColor.Red);
z.left = SENTINEL;
z.right = SENTINEL;
@@ -1717,15 +1726,14 @@ export class PieceTreeBase {
z.size_left = 0;
z.lf_left = 0;
let x = this.root;
if (x === SENTINEL) {
if (this.root === SENTINEL) {
this.root = z;
z.color = NodeColor.Black;
} else if (node.left === SENTINEL) {
node.left = z;
z.parent = node;
} else if (node!.left === SENTINEL) {
node!.left = z;
z.parent = node!;
} else {
let prevNode = righttest(node.left); // a
let prevNode = righttest(node!.left); // a
prevNode.right = z;
z.parent = prevNode;
}

View File

@@ -2,23 +2,22 @@
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import { Range } from 'vs/editor/common/core/range';
import { Position } from 'vs/editor/common/core/position';
import * as strings from 'vs/base/common/strings';
import { Position } from 'vs/editor/common/core/position';
import { Range } from 'vs/editor/common/core/range';
import { ApplyEditsResult, EndOfLinePreference, FindMatch, IIdentifiedSingleEditOperation, IInternalModelContentChange, ISingleEditOperationIdentifier, ITextBuffer } from 'vs/editor/common/model';
import { PieceTreeBase, StringBuffer } from 'vs/editor/common/model/pieceTreeTextBuffer/pieceTreeBase';
import { IIdentifiedSingleEditOperation, EndOfLinePreference, ITextBuffer, ApplyEditsResult, IInternalModelContentChange, FindMatch, ISingleEditOperationIdentifier } from 'vs/editor/common/model';
import { ITextSnapshot } from 'vs/platform/files/common/files';
import { SearchData } from 'vs/editor/common/model/textModelSearch';
import { ITextSnapshot } from 'vs/platform/files/common/files';
export interface IValidatedEditOperation {
sortIndex: number;
identifier: ISingleEditOperationIdentifier;
identifier: ISingleEditOperationIdentifier | null;
range: Range;
rangeOffset: number;
rangeLength: number;
lines: string[];
lines: string[] | null;
forceMoveMarkers: boolean;
isAutoWhitespaceEdit: boolean;
}
@@ -193,12 +192,12 @@ export class PieceTreeTextBuffer implements ITextBuffer {
}
operations[i] = {
sortIndex: i,
identifier: op.identifier,
identifier: op.identifier || null,
range: validatedRange,
rangeOffset: this.getOffsetAt(validatedRange.startLineNumber, validatedRange.startColumn),
rangeLength: this.getValueLengthInRange(validatedRange),
lines: op.text ? op.text.split(/\r\n|\r|\n/) : null,
forceMoveMarkers: op.forceMoveMarkers,
forceMoveMarkers: Boolean(op.forceMoveMarkers),
isAutoWhitespaceEdit: op.isAutoWhitespaceEdit || false
};
}
@@ -271,7 +270,7 @@ export class PieceTreeTextBuffer implements ITextBuffer {
const contentChanges = this._doApplyEdits(operations);
let trimAutoWhitespaceLineNumbers: number[] = null;
let trimAutoWhitespaceLineNumbers: number[] | null = null;
if (recordTrimAutoWhitespace && newTrimAutoWhitespaceCandidates.length > 0) {
// sort line numbers auto whitespace removal candidates for next edit descending
newTrimAutoWhitespaceCandidates.sort((a, b) => b.lineNumber - a.lineNumber);
@@ -313,7 +312,7 @@ export class PieceTreeTextBuffer implements ITextBuffer {
}
// At one point, due to how events are emitted and how each operation is handled,
// some operations can trigger a high ammount of temporary string allocations,
// some operations can trigger a high amount of temporary string allocations,
// that will immediately get edited again.
// e.g. a formatter inserting ridiculous ammounts of \n on a model with a single line
// Therefore, the strategy is to collapse all the operations into a huge single edit operation
@@ -416,7 +415,7 @@ export class PieceTreeTextBuffer implements ITextBuffer {
if (editingLinesCnt < insertingLinesCnt) {
let newLinesContent: string[] = [];
for (let j = editingLinesCnt + 1; j <= insertingLinesCnt; j++) {
newLinesContent.push(op.lines[j]);
newLinesContent.push(op.lines![j]);
}
newLinesContent[newLinesContent.length - 1] = this.getLineContent(startLineNumber + insertingLinesCnt - 1);
@@ -451,9 +450,9 @@ export class PieceTreeTextBuffer implements ITextBuffer {
public static _getInverseEditRanges(operations: IValidatedEditOperation[]): Range[] {
let result: Range[] = [];
let prevOpEndLineNumber: number;
let prevOpEndColumn: number;
let prevOp: IValidatedEditOperation = null;
let prevOpEndLineNumber: number = 0;
let prevOpEndColumn: number = 0;
let prevOp: IValidatedEditOperation | null = null;
for (let i = 0, len = operations.length; i < len; i++) {
let op = operations[i];

View File

@@ -2,13 +2,12 @@
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import * as strings from 'vs/base/common/strings';
import { ITextBufferBuilder, DefaultEndOfLine, ITextBufferFactory, ITextBuffer } from 'vs/editor/common/model';
import { PieceTreeTextBuffer } from 'vs/editor/common/model/pieceTreeTextBuffer/pieceTreeTextBuffer';
import { StringBuffer, createLineStarts, createLineStartsFast } from 'vs/editor/common/model/pieceTreeTextBuffer/pieceTreeBase';
import { CharCode } from 'vs/base/common/charCode';
import * as strings from 'vs/base/common/strings';
import { DefaultEndOfLine, ITextBuffer, ITextBufferBuilder, ITextBufferFactory } from 'vs/editor/common/model';
import { StringBuffer, createLineStarts, createLineStartsFast } from 'vs/editor/common/model/pieceTreeTextBuffer/pieceTreeBase';
import { PieceTreeTextBuffer } from 'vs/editor/common/model/pieceTreeTextBuffer/pieceTreeTextBuffer';
export class PieceTreeTextBufferFactory implements ITextBufferFactory {

View File

@@ -2,7 +2,6 @@
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import { Piece, PieceTreeBase } from 'vs/editor/common/model/pieceTreeTextBuffer/pieceTreeBase';
@@ -22,9 +21,9 @@ export class TreeNode {
this.color = color;
this.size_left = 0;
this.lf_left = 0;
this.parent = null;
this.left = null;
this.right = null;
this.parent = this;
this.left = this;
this.right = this;
}
public next(): TreeNode {
@@ -72,9 +71,9 @@ export class TreeNode {
}
public detach(): void {
this.parent = null;
this.left = null;
this.right = null;
this.parent = null!;
this.left = null!;
this.right = null!;
}
}
@@ -83,7 +82,7 @@ export const enum NodeColor {
Red = 1,
}
export const SENTINEL: TreeNode = new TreeNode(null, NodeColor.Black);
export const SENTINEL: TreeNode = new TreeNode(null!, NodeColor.Black);
SENTINEL.parent = SENTINEL;
SENTINEL.left = SENTINEL;
SENTINEL.right = SENTINEL;