mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-11 02:32:35 -05:00
Merge from master
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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];
|
||||
|
||||
|
||||
@@ -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 {
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user