monaco-editor-core 0.55.0-dev-20251102 → 0.55.0-dev-20251103
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/esm/nls.messages.cs.js +1 -1
- package/esm/nls.messages.de.js +1 -1
- package/esm/nls.messages.es.js +1 -1
- package/esm/nls.messages.fr.js +1 -1
- package/esm/nls.messages.it.js +1 -1
- package/esm/nls.messages.ja.js +1 -1
- package/esm/nls.messages.ko.js +1 -1
- package/esm/nls.messages.pl.js +1 -1
- package/esm/nls.messages.pt-br.js +1 -1
- package/esm/nls.messages.ru.js +1 -1
- package/esm/nls.messages.tr.js +1 -1
- package/esm/nls.messages.zh-cn.js +1 -1
- package/esm/nls.messages.zh-tw.js +1 -1
- package/esm/vs/base/browser/dom.js.map +1 -1
- package/esm/vs/base/browser/markdownRenderer.js.map +1 -1
- package/esm/vs/base/browser/ui/list/listView.js.map +1 -1
- package/esm/vs/base/browser/ui/tree/abstractTree.js +2 -0
- package/esm/vs/base/browser/ui/tree/abstractTree.js.map +1 -1
- package/esm/vs/base/browser/ui/tree/asyncDataTree.js +2 -0
- package/esm/vs/base/browser/ui/tree/asyncDataTree.js.map +1 -1
- package/esm/vs/base/common/arrays.js.map +1 -1
- package/esm/vs/base/common/event.js.map +1 -1
- package/esm/vs/base/common/glob.js.map +1 -1
- package/esm/vs/base/common/lifecycle.js.map +1 -1
- package/esm/vs/base/common/network.js.map +1 -1
- package/esm/vs/base/common/ternarySearchTree.js.map +1 -1
- package/esm/vs/editor/browser/controller/mouseHandler.js.map +1 -1
- package/esm/vs/editor/browser/controller/mouseTarget.js.map +1 -1
- package/esm/vs/editor/browser/dataTransfer.js.map +1 -1
- package/esm/vs/editor/browser/viewParts/viewLines/viewLine.js.map +1 -1
- package/esm/vs/editor/browser/viewParts/viewLinesGpu/viewLinesGpu.js.map +1 -1
- package/esm/vs/editor/browser/widget/codeEditor/codeEditorWidget.js.map +1 -1
- package/esm/vs/editor/browser/widget/diffEditor/components/accessibleDiffViewer.js.map +1 -1
- package/esm/vs/editor/browser/widget/diffEditor/diffEditorViewModel.js.map +1 -1
- package/esm/vs/editor/browser/widget/diffEditor/diffEditorWidget.js.map +1 -1
- package/esm/vs/editor/browser/widget/diffEditor/features/gutterFeature.js.map +1 -1
- package/esm/vs/editor/common/config/editorOptions.js.map +1 -1
- package/esm/vs/editor/common/core/edits/edit.js.map +1 -1
- package/esm/vs/editor/common/languages/defaultDocumentColorsComputer.js.map +1 -1
- package/esm/vs/editor/common/model/bracketPairsTextModelPart/bracketPairsTree/ast.js.map +1 -1
- package/esm/vs/editor/common/model/bracketPairsTextModelPart/bracketPairsTree/concat23Trees.js.map +1 -1
- package/esm/vs/editor/common/model/tokens/treeSitter/tokenStore.js.map +1 -1
- package/esm/vs/editor/common/model/tokens/treeSitter/treeSitterTree.js.map +1 -1
- package/esm/vs/editor/common/viewModel/viewModelLines.js.map +1 -1
- package/esm/vs/editor/contrib/editorState/browser/editorState.js.map +1 -1
- package/esm/vs/editor/contrib/find/browser/findDecorations.js.map +1 -1
- package/esm/vs/editor/contrib/find/browser/findModel.js.map +1 -1
- package/esm/vs/editor/contrib/folding/browser/folding.js.map +1 -1
- package/esm/vs/editor/contrib/inlineCompletions/browser/controller/commands.js.map +1 -1
- package/esm/vs/editor/contrib/inlineCompletions/browser/model/suggestWidgetAdapter.js.map +1 -1
- package/esm/vs/editor/contrib/inlineCompletions/browser/view/inlineEdits/inlineEditsViews/originalEditorInlineDiffView.js.map +1 -1
- package/esm/vs/editor/contrib/links/browser/links.js.map +1 -1
- package/esm/vs/editor/contrib/rename/browser/renameWidget.js.map +1 -1
- package/esm/vs/editor/contrib/snippet/browser/snippetParser.js.map +1 -1
- package/esm/vs/editor/contrib/stickyScroll/browser/stickyScrollController.js.map +1 -1
- package/esm/vs/editor/contrib/stickyScroll/browser/stickyScrollModelProvider.js.map +1 -1
- package/esm/vs/editor/standalone/browser/standaloneEditor.js.map +1 -1
- package/esm/vs/editor/standalone/common/monarch/monarchCompile.js.map +1 -1
- package/esm/vs/platform/configuration/common/configurationRegistry.js.map +1 -1
- package/esm/vs/platform/contextkey/common/contextkey.js +0 -4
- package/esm/vs/platform/contextkey/common/contextkey.js.map +1 -1
- package/esm/vs/platform/hover/browser/hoverService.js.map +1 -1
- package/esm/vs/platform/observable/common/wrapInHotClass.js.map +1 -1
- package/esm/vs/platform/observable/common/wrapInReloadableClass.js +0 -1
- package/esm/vs/platform/observable/common/wrapInReloadableClass.js.map +1 -1
- package/esm/vs/platform/quickinput/browser/commandsQuickAccess.js.map +1 -1
- package/esm/vs/platform/quickinput/browser/quickInput.js.map +1 -1
- package/esm/vs/platform/quickinput/browser/quickInputController.js.map +1 -1
- package/esm/vs/platform/quickinput/browser/quickInputList.js.map +1 -1
- package/package.json +2 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["file:///mnt/vss/_work/1/s/dependencies/vscode/out-editor-src/vs/editor/common/model/tokens/treeSitter/tokenStore.ts","vs/editor/common/model/tokens/treeSitter/tokenStore.ts"],"names":[],"mappings":"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","file":"tokenStore.js","sourceRoot":"file:///mnt/vss/_work/1/s/dependencies/vscode/out-editor-src","sourcesContent":["/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n\nimport { IDisposable } from '../../../../../base/common/lifecycle.js';\nimport { ITextModel } from '../../../model.js';\n\n// Exported for tests\nexport class ListNode implements IDisposable {\n\tparent?: ListNode;\n\tprivate readonly _children: Node[] = [];\n\tget children(): ReadonlyArray<Node> { return this._children; }\n\n\tprivate _length: number = 0;\n\tget length(): number { return this._length; }\n\n\tconstructor(public readonly height: number) { }\n\n\tstatic create(node1: Node, node2: Node) {\n\t\tconst list = new ListNode(node1.height + 1);\n\t\tlist.appendChild(node1);\n\t\tlist.appendChild(node2);\n\t\treturn list;\n\t}\n\n\tcanAppendChild(): boolean {\n\t\treturn this._children.length < 3;\n\t}\n\n\tappendChild(node: Node) {\n\t\tif (!this.canAppendChild()) {\n\t\t\tthrow new Error('Cannot insert more than 3 children in a ListNode');\n\t\t}\n\t\tthis._children.push(node);\n\n\t\tthis._length += node.length;\n\t\tthis._updateParentLength(node.length);\n\t\tif (!isLeaf(node)) {\n\t\t\tnode.parent = this;\n\t\t}\n\t}\n\n\tprivate _updateParentLength(delta: number) {\n\t\tlet updateParent = this.parent;\n\t\twhile (updateParent) {\n\t\t\tupdateParent._length += delta;\n\t\t\tupdateParent = updateParent.parent;\n\t\t}\n\t}\n\n\tunappendChild(): Node {\n\t\tconst child = this._children.pop()!;\n\t\tthis._length -= child.length;\n\t\tthis._updateParentLength(-child.length);\n\t\treturn child;\n\t}\n\n\tprependChild(node: Node) {\n\t\tif (this._children.length >= 3) {\n\t\t\tthrow new Error('Cannot prepend more than 3 children in a ListNode');\n\t\t}\n\t\tthis._children.unshift(node);\n\n\t\tthis._length += node.length;\n\t\tthis._updateParentLength(node.length);\n\t\tif (!isLeaf(node)) {\n\t\t\tnode.parent = this;\n\t\t}\n\t}\n\n\tunprependChild(): Node {\n\t\tconst child = this._children.shift()!;\n\t\tthis._length -= child.length;\n\t\tthis._updateParentLength(-child.length);\n\t\treturn child;\n\t}\n\n\tlastChild(): Node {\n\t\treturn this._children[this._children.length - 1];\n\t}\n\n\tdispose() {\n\t\tthis._children.splice(0, this._children.length);\n\t}\n}\n\nexport enum TokenQuality {\n\tNone = 0,\n\tViewportGuess = 1,\n\tEditGuess = 2,\n\tAccurate = 3\n}\n\ntype Node = ListNode | LeafNode;\n\n// Exported for tests\nexport interface LeafNode {\n\treadonly length: number;\n\ttoken: number;\n\ttokenQuality: TokenQuality;\n\theight: 0;\n}\n\nexport interface TokenUpdate {\n\treadonly startOffsetInclusive: number;\n\treadonly length: number;\n\treadonly token: number;\n}\n\nfunction isLeaf(node: Node): node is LeafNode {\n\treturn (node as LeafNode).token !== undefined;\n}\n\n// Heavily inspired by https://github.com/microsoft/vscode/blob/4eb2658d592cb6114a7a393655574176cc790c5b/src/vs/editor/common/model/bracketPairsTextModelPart/bracketPairsTree/concat23Trees.ts#L108-L109\nfunction append(node: Node, nodeToAppend: Node): Node {\n\tlet curNode = node;\n\tconst parents: ListNode[] = [];\n\tlet nodeToAppendOfCorrectHeight: Node | undefined;\n\twhile (true) {\n\t\tif (nodeToAppend.height === curNode.height) {\n\t\t\tnodeToAppendOfCorrectHeight = nodeToAppend;\n\t\t\tbreak;\n\t\t}\n\n\t\tif (isLeaf(curNode)) {\n\t\t\tthrow new Error('unexpected');\n\t\t}\n\t\tparents.push(curNode);\n\t\tcurNode = curNode.lastChild();\n\t}\n\tfor (let i = parents.length - 1; i >= 0; i--) {\n\t\tconst parent = parents[i];\n\t\tif (nodeToAppendOfCorrectHeight) {\n\t\t\t// Can we take the element?\n\t\t\tif (parent.children.length >= 3) {\n\t\t\t\t// we need to split to maintain (2,3)-tree property.\n\t\t\t\t// Send the third element + the new element to the parent.\n\t\t\t\tconst newList = ListNode.create(parent.unappendChild()!, nodeToAppendOfCorrectHeight);\n\t\t\t\tnodeToAppendOfCorrectHeight = newList;\n\t\t\t} else {\n\t\t\t\tparent.appendChild(nodeToAppendOfCorrectHeight);\n\t\t\t\tnodeToAppendOfCorrectHeight = undefined;\n\t\t\t}\n\t\t}\n\t}\n\tif (nodeToAppendOfCorrectHeight) {\n\t\tconst newList = new ListNode(nodeToAppendOfCorrectHeight.height + 1);\n\t\tnewList.appendChild(node);\n\t\tnewList.appendChild(nodeToAppendOfCorrectHeight);\n\t\treturn newList;\n\t} else {\n\t\treturn node;\n\t}\n}\n\nfunction prepend(list: Node, nodeToAppend: Node): Node {\n\tlet curNode = list;\n\tconst parents: ListNode[] = [];\n\twhile (nodeToAppend.height !== curNode.height) {\n\t\tif (isLeaf(curNode)) {\n\t\t\tthrow new Error('unexpected');\n\t\t}\n\t\tparents.push(curNode);\n\t\t// assert 2 <= curNode.childrenFast.length <= 3\n\t\tcurNode = curNode.children[0] as ListNode;\n\t}\n\tlet nodeToPrependOfCorrectHeight: Node | undefined = nodeToAppend;\n\t// assert nodeToAppendOfCorrectHeight!.listHeight === curNode.listHeight\n\tfor (let i = parents.length - 1; i >= 0; i--) {\n\t\tconst parent = parents[i];\n\t\tif (nodeToPrependOfCorrectHeight) {\n\t\t\t// Can we take the element?\n\t\t\tif (parent.children.length >= 3) {\n\t\t\t\t// we need to split to maintain (2,3)-tree property.\n\t\t\t\t// Send the third element + the new element to the parent.\n\t\t\t\tnodeToPrependOfCorrectHeight = ListNode.create(nodeToPrependOfCorrectHeight, parent.unprependChild());\n\t\t\t} else {\n\t\t\t\tparent.prependChild(nodeToPrependOfCorrectHeight);\n\t\t\t\tnodeToPrependOfCorrectHeight = undefined;\n\t\t\t}\n\t\t}\n\t}\n\tif (nodeToPrependOfCorrectHeight) {\n\t\treturn ListNode.create(nodeToPrependOfCorrectHeight, list);\n\t} else {\n\t\treturn list;\n\t}\n}\n\nfunction concat(node1: Node, node2: Node): Node {\n\tif (node1.height === node2.height) {\n\t\treturn ListNode.create(node1, node2);\n\t}\n\telse if (node1.height > node2.height) {\n\t\t// node1 is the tree we want to insert into\n\t\treturn append(node1, node2);\n\t} else {\n\t\treturn prepend(node2, node1);\n\t}\n}\n\nexport class TokenStore implements IDisposable {\n\tprivate _root: Node;\n\n\tconstructor(private readonly _textModel: ITextModel) {\n\t\tthis._root = this.createEmptyRoot();\n\t}\n\n\tprivate createEmptyRoot(): Node {\n\t\treturn {\n\t\t\tlength: this._textModel.getValueLength(),\n\t\t\ttoken: 0,\n\t\t\theight: 0,\n\t\t\ttokenQuality: TokenQuality.None\n\t\t};\n\t}\n\n\t/**\n\t *\n\t * @param update all the tokens for the document in sequence\n\t */\n\tbuildStore(tokens: TokenUpdate[], tokenQuality: TokenQuality): void {\n\t\tthis._root = this.createFromUpdates(tokens, tokenQuality);\n\t}\n\n\tprivate createFromUpdates(tokens: TokenUpdate[], tokenQuality: TokenQuality): Node {\n\t\tif (tokens.length === 0) {\n\t\t\treturn this.createEmptyRoot();\n\t\t}\n\t\tlet newRoot: Node = {\n\t\t\tlength: tokens[0].length,\n\t\t\ttoken: tokens[0].token,\n\t\t\theight: 0,\n\t\t\ttokenQuality\n\t\t};\n\t\tfor (let j = 1; j < tokens.length; j++) {\n\t\t\tnewRoot = append(newRoot, { length: tokens[j].length, token: tokens[j].token, height: 0, tokenQuality });\n\t\t}\n\t\treturn newRoot;\n\t}\n\n\t/**\n\t *\n\t * @param tokens tokens are in sequence in the document.\n\t */\n\tupdate(length: number, tokens: TokenUpdate[], tokenQuality: TokenQuality) {\n\t\tif (tokens.length === 0) {\n\t\t\treturn;\n\t\t}\n\t\tthis.replace(length, tokens[0].startOffsetInclusive, tokens, tokenQuality);\n\t}\n\n\tdelete(length: number, startOffset: number) {\n\t\tthis.replace(length, startOffset, [], TokenQuality.EditGuess);\n\t}\n\n\t/**\n\t *\n\t * @param tokens tokens are in sequence in the document.\n\t */\n\tprivate replace(length: number, updateOffsetStart: number, tokens: TokenUpdate[], tokenQuality: TokenQuality) {\n\t\tconst firstUnchangedOffsetAfterUpdate = updateOffsetStart + length;\n\t\t// Find the last unchanged node preceding the update\n\t\tconst precedingNodes: Node[] = [];\n\t\t// Find the first unchanged node after the update\n\t\tconst postcedingNodes: Node[] = [];\n\t\tconst stack: { node: Node; offset: number }[] = [{ node: this._root, offset: 0 }];\n\n\t\twhile (stack.length > 0) {\n\t\t\tconst node = stack.pop()!;\n\t\t\tconst currentOffset = node.offset;\n\n\t\t\tif (currentOffset < updateOffsetStart && currentOffset + node.node.length <= updateOffsetStart) {\n\t\t\t\tif (!isLeaf(node.node)) {\n\t\t\t\t\tnode.node.parent = undefined;\n\t\t\t\t}\n\t\t\t\tprecedingNodes.push(node.node);\n\t\t\t\tcontinue;\n\t\t\t} else if (isLeaf(node.node) && (currentOffset < updateOffsetStart)) {\n\t\t\t\t// We have a partial preceding node\n\t\t\t\tprecedingNodes.push({ length: updateOffsetStart - currentOffset, token: node.node.token, height: 0, tokenQuality: node.node.tokenQuality });\n\t\t\t\t// Node could also be postceeding, so don't continue\n\t\t\t}\n\n\t\t\tif ((updateOffsetStart <= currentOffset) && (currentOffset + node.node.length <= firstUnchangedOffsetAfterUpdate)) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tif (currentOffset >= firstUnchangedOffsetAfterUpdate) {\n\t\t\t\tif (!isLeaf(node.node)) {\n\t\t\t\t\tnode.node.parent = undefined;\n\t\t\t\t}\n\t\t\t\tpostcedingNodes.push(node.node);\n\t\t\t\tcontinue;\n\t\t\t} else if (isLeaf(node.node) && (currentOffset + node.node.length > firstUnchangedOffsetAfterUpdate)) {\n\t\t\t\t// we have a partial postceeding node\n\t\t\t\tpostcedingNodes.push({ length: currentOffset + node.node.length - firstUnchangedOffsetAfterUpdate, token: node.node.token, height: 0, tokenQuality: node.node.tokenQuality });\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tif (!isLeaf(node.node)) {\n\t\t\t\t// Push children in reverse order to process them left-to-right when popping\n\t\t\t\tlet childOffset = currentOffset + node.node.length;\n\t\t\t\tfor (let i = node.node.children.length - 1; i >= 0; i--) {\n\t\t\t\t\tchildOffset -= node.node.children[i].length;\n\t\t\t\t\tstack.push({ node: node.node.children[i], offset: childOffset });\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tlet allNodes: Node[];\n\t\tif (tokens.length > 0) {\n\t\t\tallNodes = precedingNodes.concat(this.createFromUpdates(tokens, tokenQuality), postcedingNodes);\n\t\t} else {\n\t\t\tallNodes = precedingNodes.concat(postcedingNodes);\n\t\t}\n\t\tlet newRoot: Node = allNodes[0];\n\t\tfor (let i = 1; i < allNodes.length; i++) {\n\t\t\tnewRoot = concat(newRoot, allNodes[i]);\n\t\t}\n\n\t\tthis._root = newRoot ?? this.createEmptyRoot();\n\t}\n\n\t/**\n\t *\n\t * @param startOffsetInclusive\n\t * @param endOffsetExclusive\n\t * @param visitor Return true from visitor to exit early\n\t * @returns\n\t */\n\tprivate traverseInOrderInRange(startOffsetInclusive: number, endOffsetExclusive: number, visitor: (node: Node, offset: number) => boolean): void {\n\t\tconst stack: { node: Node; offset: number }[] = [{ node: this._root, offset: 0 }];\n\n\t\twhile (stack.length > 0) {\n\t\t\tconst { node, offset } = stack.pop()!;\n\t\t\tconst nodeEnd = offset + node.length;\n\n\t\t\t// Skip nodes that are completely before or after the range\n\t\t\tif (nodeEnd <= startOffsetInclusive || offset >= endOffsetExclusive) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tif (visitor(node, offset)) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (!isLeaf(node)) {\n\t\t\t\t// Push children in reverse order to process them left-to-right when popping\n\t\t\t\tlet childOffset = offset + node.length;\n\t\t\t\tfor (let i = node.children.length - 1; i >= 0; i--) {\n\t\t\t\t\tchildOffset -= node.children[i].length;\n\t\t\t\t\tstack.push({ node: node.children[i], offset: childOffset });\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tgetTokenAt(offset: number): TokenUpdate | undefined {\n\t\tlet result: TokenUpdate | undefined;\n\t\tthis.traverseInOrderInRange(offset, this._root.length, (node, offset) => {\n\t\t\tif (isLeaf(node)) {\n\t\t\t\tresult = { token: node.token, startOffsetInclusive: offset, length: node.length };\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\treturn false;\n\t\t});\n\t\treturn result;\n\t}\n\n\tgetTokensInRange(startOffsetInclusive: number, endOffsetExclusive: number): TokenUpdate[] {\n\t\tconst result: { token: number; startOffsetInclusive: number; length: number }[] = [];\n\t\tthis.traverseInOrderInRange(startOffsetInclusive, endOffsetExclusive, (node, offset) => {\n\t\t\tif (isLeaf(node)) {\n\t\t\t\tlet clippedLength = node.length;\n\t\t\t\tlet clippedOffset = offset;\n\t\t\t\tif ((offset < startOffsetInclusive) && (offset + node.length > endOffsetExclusive)) {\n\t\t\t\t\tclippedOffset = startOffsetInclusive;\n\t\t\t\t\tclippedLength = endOffsetExclusive - startOffsetInclusive;\n\t\t\t\t} else if (offset < startOffsetInclusive) {\n\t\t\t\t\tclippedLength -= (startOffsetInclusive - offset);\n\t\t\t\t\tclippedOffset = startOffsetInclusive;\n\t\t\t\t} else if (offset + node.length > endOffsetExclusive) {\n\t\t\t\t\tclippedLength -= (offset + node.length - endOffsetExclusive);\n\t\t\t\t}\n\t\t\t\tresult.push({ token: node.token, startOffsetInclusive: clippedOffset, length: clippedLength });\n\t\t\t}\n\t\t\treturn false;\n\t\t});\n\t\treturn result;\n\t}\n\n\tmarkForRefresh(startOffsetInclusive: number, endOffsetExclusive: number): void {\n\t\tthis.traverseInOrderInRange(startOffsetInclusive, endOffsetExclusive, (node) => {\n\t\t\tif (isLeaf(node)) {\n\t\t\t\tnode.tokenQuality = TokenQuality.None;\n\t\t\t}\n\t\t\treturn false;\n\t\t});\n\t}\n\n\trangeHasTokens(startOffsetInclusive: number, endOffsetExclusive: number, minimumTokenQuality: TokenQuality): boolean {\n\t\tlet hasAny = true;\n\t\tthis.traverseInOrderInRange(startOffsetInclusive, endOffsetExclusive, (node) => {\n\t\t\tif (isLeaf(node) && (node.tokenQuality < minimumTokenQuality)) {\n\t\t\t\thasAny = false;\n\t\t\t}\n\t\t\treturn false;\n\t\t});\n\t\treturn hasAny;\n\t}\n\n\trangeNeedsRefresh(startOffsetInclusive: number, endOffsetExclusive: number): boolean {\n\t\tlet needsRefresh = false;\n\t\tthis.traverseInOrderInRange(startOffsetInclusive, endOffsetExclusive, (node) => {\n\t\t\tif (isLeaf(node) && (node.tokenQuality !== TokenQuality.Accurate)) {\n\t\t\t\tneedsRefresh = true;\n\t\t\t}\n\t\t\treturn false;\n\t\t});\n\t\treturn needsRefresh;\n\t}\n\n\tgetNeedsRefresh(): { startOffset: number; endOffset: number }[] {\n\t\tconst result: { startOffset: number; endOffset: number }[] = [];\n\n\t\tthis.traverseInOrderInRange(0, this._textModel.getValueLength(), (node, offset) => {\n\t\t\tif (isLeaf(node) && (node.tokenQuality !== TokenQuality.Accurate)) {\n\t\t\t\tif ((result.length > 0) && (result[result.length - 1].endOffset === offset)) {\n\t\t\t\t\tresult[result.length - 1].endOffset += node.length;\n\t\t\t\t} else {\n\t\t\t\t\tresult.push({ startOffset: offset, endOffset: offset + node.length });\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn false;\n\t\t});\n\t\treturn result;\n\t}\n\n\tdispose(): void {\n\t\tconst stack: Array<[Node, boolean]> = [[this._root, false]];\n\t\twhile (stack.length > 0) {\n\t\t\tconst [node, visited] = stack.pop()!;\n\t\t\tif (isLeaf(node)) {\n\t\t\t\t// leaf node does not need to be disposed\n\t\t\t} else if (!visited) {\n\t\t\t\tstack.push([node, true]);\n\t\t\t\tfor (let i = node.children.length - 1; i >= 0; i--) {\n\t\t\t\t\tstack.push([node.children[i], false]);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tnode.dispose();\n\t\t\t\tnode.parent = undefined;\n\t\t\t}\n\t\t}\n\t\tthis._root = undefined!;\n\t}\n}\n","/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n\nimport { IDisposable } from '../../../../../base/common/lifecycle.js';\nimport { ITextModel } from '../../../model.js';\n\n// Exported for tests\nexport class ListNode implements IDisposable {\n\tparent?: ListNode;\n\tprivate readonly _children: Node[] = [];\n\tget children(): ReadonlyArray<Node> { return this._children; }\n\n\tprivate _length: number = 0;\n\tget length(): number { return this._length; }\n\n\tconstructor(public readonly height: number) { }\n\n\tstatic create(node1: Node, node2: Node) {\n\t\tconst list = new ListNode(node1.height + 1);\n\t\tlist.appendChild(node1);\n\t\tlist.appendChild(node2);\n\t\treturn list;\n\t}\n\n\tcanAppendChild(): boolean {\n\t\treturn this._children.length < 3;\n\t}\n\n\tappendChild(node: Node) {\n\t\tif (!this.canAppendChild()) {\n\t\t\tthrow new Error('Cannot insert more than 3 children in a ListNode');\n\t\t}\n\t\tthis._children.push(node);\n\n\t\tthis._length += node.length;\n\t\tthis._updateParentLength(node.length);\n\t\tif (!isLeaf(node)) {\n\t\t\tnode.parent = this;\n\t\t}\n\t}\n\n\tprivate _updateParentLength(delta: number) {\n\t\tlet updateParent = this.parent;\n\t\twhile (updateParent) {\n\t\t\tupdateParent._length += delta;\n\t\t\tupdateParent = updateParent.parent;\n\t\t}\n\t}\n\n\tunappendChild(): Node {\n\t\tconst child = this._children.pop()!;\n\t\tthis._length -= child.length;\n\t\tthis._updateParentLength(-child.length);\n\t\treturn child;\n\t}\n\n\tprependChild(node: Node) {\n\t\tif (this._children.length >= 3) {\n\t\t\tthrow new Error('Cannot prepend more than 3 children in a ListNode');\n\t\t}\n\t\tthis._children.unshift(node);\n\n\t\tthis._length += node.length;\n\t\tthis._updateParentLength(node.length);\n\t\tif (!isLeaf(node)) {\n\t\t\tnode.parent = this;\n\t\t}\n\t}\n\n\tunprependChild(): Node {\n\t\tconst child = this._children.shift()!;\n\t\tthis._length -= child.length;\n\t\tthis._updateParentLength(-child.length);\n\t\treturn child;\n\t}\n\n\tlastChild(): Node {\n\t\treturn this._children[this._children.length - 1];\n\t}\n\n\tdispose() {\n\t\tthis._children.splice(0, this._children.length);\n\t}\n}\n\nexport enum TokenQuality {\n\tNone = 0,\n\tViewportGuess = 1,\n\tEditGuess = 2,\n\tAccurate = 3\n}\n\ntype Node = ListNode | LeafNode;\n\n// Exported for tests\nexport interface LeafNode {\n\treadonly length: number;\n\ttoken: number;\n\ttokenQuality: TokenQuality;\n\theight: 0;\n}\n\nexport interface TokenUpdate {\n\treadonly startOffsetInclusive: number;\n\treadonly length: number;\n\treadonly token: number;\n}\n\nfunction isLeaf(node: Node): node is LeafNode {\n\treturn (node as LeafNode).token !== undefined;\n}\n\n// Heavily inspired by https://github.com/microsoft/vscode/blob/4eb2658d592cb6114a7a393655574176cc790c5b/src/vs/editor/common/model/bracketPairsTextModelPart/bracketPairsTree/concat23Trees.ts#L108-L109\nfunction append(node: Node, nodeToAppend: Node): Node {\n\tlet curNode = node;\n\tconst parents: ListNode[] = [];\n\tlet nodeToAppendOfCorrectHeight: Node | undefined;\n\twhile (true) {\n\t\tif (nodeToAppend.height === curNode.height) {\n\t\t\tnodeToAppendOfCorrectHeight = nodeToAppend;\n\t\t\tbreak;\n\t\t}\n\n\t\tif (isLeaf(curNode)) {\n\t\t\tthrow new Error('unexpected');\n\t\t}\n\t\tparents.push(curNode);\n\t\tcurNode = curNode.lastChild();\n\t}\n\tfor (let i = parents.length - 1; i >= 0; i--) {\n\t\tconst parent = parents[i];\n\t\tif (nodeToAppendOfCorrectHeight) {\n\t\t\t// Can we take the element?\n\t\t\tif (parent.children.length >= 3) {\n\t\t\t\t// we need to split to maintain (2,3)-tree property.\n\t\t\t\t// Send the third element + the new element to the parent.\n\t\t\t\tconst newList = ListNode.create(parent.unappendChild()!, nodeToAppendOfCorrectHeight);\n\t\t\t\tnodeToAppendOfCorrectHeight = newList;\n\t\t\t} else {\n\t\t\t\tparent.appendChild(nodeToAppendOfCorrectHeight);\n\t\t\t\tnodeToAppendOfCorrectHeight = undefined;\n\t\t\t}\n\t\t}\n\t}\n\tif (nodeToAppendOfCorrectHeight) {\n\t\tconst newList = new ListNode(nodeToAppendOfCorrectHeight.height + 1);\n\t\tnewList.appendChild(node);\n\t\tnewList.appendChild(nodeToAppendOfCorrectHeight);\n\t\treturn newList;\n\t} else {\n\t\treturn node;\n\t}\n}\n\nfunction prepend(list: Node, nodeToAppend: Node): Node {\n\tlet curNode = list;\n\tconst parents: ListNode[] = [];\n\twhile (nodeToAppend.height !== curNode.height) {\n\t\tif (isLeaf(curNode)) {\n\t\t\tthrow new Error('unexpected');\n\t\t}\n\t\tparents.push(curNode);\n\t\t// assert 2 <= curNode.childrenFast.length <= 3\n\t\tcurNode = curNode.children[0] as ListNode;\n\t}\n\tlet nodeToPrependOfCorrectHeight: Node | undefined = nodeToAppend;\n\t// assert nodeToAppendOfCorrectHeight!.listHeight === curNode.listHeight\n\tfor (let i = parents.length - 1; i >= 0; i--) {\n\t\tconst parent = parents[i];\n\t\tif (nodeToPrependOfCorrectHeight) {\n\t\t\t// Can we take the element?\n\t\t\tif (parent.children.length >= 3) {\n\t\t\t\t// we need to split to maintain (2,3)-tree property.\n\t\t\t\t// Send the third element + the new element to the parent.\n\t\t\t\tnodeToPrependOfCorrectHeight = ListNode.create(nodeToPrependOfCorrectHeight, parent.unprependChild());\n\t\t\t} else {\n\t\t\t\tparent.prependChild(nodeToPrependOfCorrectHeight);\n\t\t\t\tnodeToPrependOfCorrectHeight = undefined;\n\t\t\t}\n\t\t}\n\t}\n\tif (nodeToPrependOfCorrectHeight) {\n\t\treturn ListNode.create(nodeToPrependOfCorrectHeight, list);\n\t} else {\n\t\treturn list;\n\t}\n}\n\nfunction concat(node1: Node, node2: Node): Node {\n\tif (node1.height === node2.height) {\n\t\treturn ListNode.create(node1, node2);\n\t}\n\telse if (node1.height > node2.height) {\n\t\t// node1 is the tree we want to insert into\n\t\treturn append(node1, node2);\n\t} else {\n\t\treturn prepend(node2, node1);\n\t}\n}\n\nexport class TokenStore implements IDisposable {\n\tprivate _root: Node;\n\n\tconstructor(private readonly _textModel: ITextModel) {\n\t\tthis._root = this.createEmptyRoot();\n\t}\n\n\tprivate createEmptyRoot(): Node {\n\t\treturn {\n\t\t\tlength: this._textModel.getValueLength(),\n\t\t\ttoken: 0,\n\t\t\theight: 0,\n\t\t\ttokenQuality: TokenQuality.None\n\t\t};\n\t}\n\n\t/**\n\t *\n\t * @param update all the tokens for the document in sequence\n\t */\n\tbuildStore(tokens: TokenUpdate[], tokenQuality: TokenQuality): void {\n\t\tthis._root = this.createFromUpdates(tokens, tokenQuality);\n\t}\n\n\tprivate createFromUpdates(tokens: TokenUpdate[], tokenQuality: TokenQuality): Node {\n\t\tif (tokens.length === 0) {\n\t\t\treturn this.createEmptyRoot();\n\t\t}\n\t\tlet newRoot: Node = {\n\t\t\tlength: tokens[0].length,\n\t\t\ttoken: tokens[0].token,\n\t\t\theight: 0,\n\t\t\ttokenQuality\n\t\t};\n\t\tfor (let j = 1; j < tokens.length; j++) {\n\t\t\tnewRoot = append(newRoot, { length: tokens[j].length, token: tokens[j].token, height: 0, tokenQuality });\n\t\t}\n\t\treturn newRoot;\n\t}\n\n\t/**\n\t *\n\t * @param tokens tokens are in sequence in the document.\n\t */\n\tupdate(length: number, tokens: TokenUpdate[], tokenQuality: TokenQuality) {\n\t\tif (tokens.length === 0) {\n\t\t\treturn;\n\t\t}\n\t\tthis.replace(length, tokens[0].startOffsetInclusive, tokens, tokenQuality);\n\t}\n\n\tdelete(length: number, startOffset: number) {\n\t\tthis.replace(length, startOffset, [], TokenQuality.EditGuess);\n\t}\n\n\t/**\n\t *\n\t * @param tokens tokens are in sequence in the document.\n\t */\n\tprivate replace(length: number, updateOffsetStart: number, tokens: TokenUpdate[], tokenQuality: TokenQuality) {\n\t\tconst firstUnchangedOffsetAfterUpdate = updateOffsetStart + length;\n\t\t// Find the last unchanged node preceding the update\n\t\tconst precedingNodes: Node[] = [];\n\t\t// Find the first unchanged node after the update\n\t\tconst postcedingNodes: Node[] = [];\n\t\tconst stack: { node: Node; offset: number }[] = [{ node: this._root, offset: 0 }];\n\n\t\twhile (stack.length > 0) {\n\t\t\tconst node = stack.pop()!;\n\t\t\tconst currentOffset = node.offset;\n\n\t\t\tif (currentOffset < updateOffsetStart && currentOffset + node.node.length <= updateOffsetStart) {\n\t\t\t\tif (!isLeaf(node.node)) {\n\t\t\t\t\tnode.node.parent = undefined;\n\t\t\t\t}\n\t\t\t\tprecedingNodes.push(node.node);\n\t\t\t\tcontinue;\n\t\t\t} else if (isLeaf(node.node) && (currentOffset < updateOffsetStart)) {\n\t\t\t\t// We have a partial preceding node\n\t\t\t\tprecedingNodes.push({ length: updateOffsetStart - currentOffset, token: node.node.token, height: 0, tokenQuality: node.node.tokenQuality });\n\t\t\t\t// Node could also be postceeding, so don't continue\n\t\t\t}\n\n\t\t\tif ((updateOffsetStart <= currentOffset) && (currentOffset + node.node.length <= firstUnchangedOffsetAfterUpdate)) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tif (currentOffset >= firstUnchangedOffsetAfterUpdate) {\n\t\t\t\tif (!isLeaf(node.node)) {\n\t\t\t\t\tnode.node.parent = undefined;\n\t\t\t\t}\n\t\t\t\tpostcedingNodes.push(node.node);\n\t\t\t\tcontinue;\n\t\t\t} else if (isLeaf(node.node) && (currentOffset + node.node.length > firstUnchangedOffsetAfterUpdate)) {\n\t\t\t\t// we have a partial postceeding node\n\t\t\t\tpostcedingNodes.push({ length: currentOffset + node.node.length - firstUnchangedOffsetAfterUpdate, token: node.node.token, height: 0, tokenQuality: node.node.tokenQuality });\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tif (!isLeaf(node.node)) {\n\t\t\t\t// Push children in reverse order to process them left-to-right when popping\n\t\t\t\tlet childOffset = currentOffset + node.node.length;\n\t\t\t\tfor (let i = node.node.children.length - 1; i >= 0; i--) {\n\t\t\t\t\tchildOffset -= node.node.children[i].length;\n\t\t\t\t\tstack.push({ node: node.node.children[i], offset: childOffset });\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tlet allNodes: Node[];\n\t\tif (tokens.length > 0) {\n\t\t\tallNodes = precedingNodes.concat(this.createFromUpdates(tokens, tokenQuality), postcedingNodes);\n\t\t} else {\n\t\t\tallNodes = precedingNodes.concat(postcedingNodes);\n\t\t}\n\t\tlet newRoot: Node = allNodes[0];\n\t\tfor (let i = 1; i < allNodes.length; i++) {\n\t\t\tnewRoot = concat(newRoot, allNodes[i]);\n\t\t}\n\n\t\tthis._root = newRoot ?? this.createEmptyRoot();\n\t}\n\n\t/**\n\t *\n\t * @param startOffsetInclusive\n\t * @param endOffsetExclusive\n\t * @param visitor Return true from visitor to exit early\n\t * @returns\n\t */\n\tprivate traverseInOrderInRange(startOffsetInclusive: number, endOffsetExclusive: number, visitor: (node: Node, offset: number) => boolean): void {\n\t\tconst stack: { node: Node; offset: number }[] = [{ node: this._root, offset: 0 }];\n\n\t\twhile (stack.length > 0) {\n\t\t\tconst { node, offset } = stack.pop()!;\n\t\t\tconst nodeEnd = offset + node.length;\n\n\t\t\t// Skip nodes that are completely before or after the range\n\t\t\tif (nodeEnd <= startOffsetInclusive || offset >= endOffsetExclusive) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tif (visitor(node, offset)) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (!isLeaf(node)) {\n\t\t\t\t// Push children in reverse order to process them left-to-right when popping\n\t\t\t\tlet childOffset = offset + node.length;\n\t\t\t\tfor (let i = node.children.length - 1; i >= 0; i--) {\n\t\t\t\t\tchildOffset -= node.children[i].length;\n\t\t\t\t\tstack.push({ node: node.children[i], offset: childOffset });\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tgetTokenAt(offset: number): TokenUpdate | undefined {\n\t\tlet result: TokenUpdate | undefined;\n\t\tthis.traverseInOrderInRange(offset, this._root.length, (node, offset) => {\n\t\t\tif (isLeaf(node)) {\n\t\t\t\tresult = { token: node.token, startOffsetInclusive: offset, length: node.length };\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\treturn false;\n\t\t});\n\t\treturn result;\n\t}\n\n\tgetTokensInRange(startOffsetInclusive: number, endOffsetExclusive: number): TokenUpdate[] {\n\t\tconst result: { token: number; startOffsetInclusive: number; length: number }[] = [];\n\t\tthis.traverseInOrderInRange(startOffsetInclusive, endOffsetExclusive, (node, offset) => {\n\t\t\tif (isLeaf(node)) {\n\t\t\t\tlet clippedLength = node.length;\n\t\t\t\tlet clippedOffset = offset;\n\t\t\t\tif ((offset < startOffsetInclusive) && (offset + node.length > endOffsetExclusive)) {\n\t\t\t\t\tclippedOffset = startOffsetInclusive;\n\t\t\t\t\tclippedLength = endOffsetExclusive - startOffsetInclusive;\n\t\t\t\t} else if (offset < startOffsetInclusive) {\n\t\t\t\t\tclippedLength -= (startOffsetInclusive - offset);\n\t\t\t\t\tclippedOffset = startOffsetInclusive;\n\t\t\t\t} else if (offset + node.length > endOffsetExclusive) {\n\t\t\t\t\tclippedLength -= (offset + node.length - endOffsetExclusive);\n\t\t\t\t}\n\t\t\t\tresult.push({ token: node.token, startOffsetInclusive: clippedOffset, length: clippedLength });\n\t\t\t}\n\t\t\treturn false;\n\t\t});\n\t\treturn result;\n\t}\n\n\tmarkForRefresh(startOffsetInclusive: number, endOffsetExclusive: number): void {\n\t\tthis.traverseInOrderInRange(startOffsetInclusive, endOffsetExclusive, (node) => {\n\t\t\tif (isLeaf(node)) {\n\t\t\t\tnode.tokenQuality = TokenQuality.None;\n\t\t\t}\n\t\t\treturn false;\n\t\t});\n\t}\n\n\trangeHasTokens(startOffsetInclusive: number, endOffsetExclusive: number, minimumTokenQuality: TokenQuality): boolean {\n\t\tlet hasAny = true;\n\t\tthis.traverseInOrderInRange(startOffsetInclusive, endOffsetExclusive, (node) => {\n\t\t\tif (isLeaf(node) && (node.tokenQuality < minimumTokenQuality)) {\n\t\t\t\thasAny = false;\n\t\t\t}\n\t\t\treturn false;\n\t\t});\n\t\treturn hasAny;\n\t}\n\n\trangeNeedsRefresh(startOffsetInclusive: number, endOffsetExclusive: number): boolean {\n\t\tlet needsRefresh = false;\n\t\tthis.traverseInOrderInRange(startOffsetInclusive, endOffsetExclusive, (node) => {\n\t\t\tif (isLeaf(node) && (node.tokenQuality !== TokenQuality.Accurate)) {\n\t\t\t\tneedsRefresh = true;\n\t\t\t}\n\t\t\treturn false;\n\t\t});\n\t\treturn needsRefresh;\n\t}\n\n\tgetNeedsRefresh(): { startOffset: number; endOffset: number }[] {\n\t\tconst result: { startOffset: number; endOffset: number }[] = [];\n\n\t\tthis.traverseInOrderInRange(0, this._textModel.getValueLength(), (node, offset) => {\n\t\t\tif (isLeaf(node) && (node.tokenQuality !== TokenQuality.Accurate)) {\n\t\t\t\tif ((result.length > 0) && (result[result.length - 1].endOffset === offset)) {\n\t\t\t\t\tresult[result.length - 1].endOffset += node.length;\n\t\t\t\t} else {\n\t\t\t\t\tresult.push({ startOffset: offset, endOffset: offset + node.length });\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn false;\n\t\t});\n\t\treturn result;\n\t}\n\n\tdispose(): void {\n\t\tconst stack: Array<[Node, boolean]> = [[this._root, false]];\n\t\twhile (stack.length > 0) {\n\t\t\tconst [node, visited] = stack.pop()!;\n\t\t\tif (isLeaf(node)) {\n\t\t\t\t// leaf node does not need to be disposed\n\t\t\t} else if (!visited) {\n\t\t\t\tstack.push([node, true]);\n\t\t\t\tfor (let i = node.children.length - 1; i >= 0; i--) {\n\t\t\t\t\tstack.push([node.children[i], false]);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tnode.dispose();\n\t\t\t\tnode.parent = undefined;\n\t\t\t}\n\t\t}\n\t\tthis._root = undefined!;\n\t}\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["file:///mnt/vss/_work/1/s/dependencies/vscode/out-editor-src/vs/editor/common/model/tokens/treeSitter/tokenStore.ts","vs/editor/common/model/tokens/treeSitter/tokenStore.ts"],"names":[],"mappings":"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","file":"tokenStore.js","sourceRoot":"file:///mnt/vss/_work/1/s/dependencies/vscode/out-editor-src","sourcesContent":["/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n\nimport { IDisposable } from '../../../../../base/common/lifecycle.js';\nimport { ITextModel } from '../../../model.js';\n\n// Exported for tests\nexport class ListNode implements IDisposable {\n\tparent?: ListNode;\n\tprivate readonly _children: Node[] = [];\n\tget children(): ReadonlyArray<Node> { return this._children; }\n\n\tprivate _length: number = 0;\n\tget length(): number { return this._length; }\n\n\tconstructor(public readonly height: number) { }\n\n\tstatic create(node1: Node, node2: Node) {\n\t\tconst list = new ListNode(node1.height + 1);\n\t\tlist.appendChild(node1);\n\t\tlist.appendChild(node2);\n\t\treturn list;\n\t}\n\n\tcanAppendChild(): boolean {\n\t\treturn this._children.length < 3;\n\t}\n\n\tappendChild(node: Node) {\n\t\tif (!this.canAppendChild()) {\n\t\t\tthrow new Error('Cannot insert more than 3 children in a ListNode');\n\t\t}\n\t\tthis._children.push(node);\n\n\t\tthis._length += node.length;\n\t\tthis._updateParentLength(node.length);\n\t\tif (!isLeaf(node)) {\n\t\t\tnode.parent = this;\n\t\t}\n\t}\n\n\tprivate _updateParentLength(delta: number) {\n\t\tlet updateParent = this.parent;\n\t\twhile (updateParent) {\n\t\t\tupdateParent._length += delta;\n\t\t\tupdateParent = updateParent.parent;\n\t\t}\n\t}\n\n\tunappendChild(): Node {\n\t\tconst child = this._children.pop()!;\n\t\tthis._length -= child.length;\n\t\tthis._updateParentLength(-child.length);\n\t\treturn child;\n\t}\n\n\tprependChild(node: Node) {\n\t\tif (this._children.length >= 3) {\n\t\t\tthrow new Error('Cannot prepend more than 3 children in a ListNode');\n\t\t}\n\t\tthis._children.unshift(node);\n\n\t\tthis._length += node.length;\n\t\tthis._updateParentLength(node.length);\n\t\tif (!isLeaf(node)) {\n\t\t\tnode.parent = this;\n\t\t}\n\t}\n\n\tunprependChild(): Node {\n\t\tconst child = this._children.shift()!;\n\t\tthis._length -= child.length;\n\t\tthis._updateParentLength(-child.length);\n\t\treturn child;\n\t}\n\n\tlastChild(): Node {\n\t\treturn this._children[this._children.length - 1];\n\t}\n\n\tdispose() {\n\t\tthis._children.splice(0, this._children.length);\n\t}\n}\n\nexport enum TokenQuality {\n\tNone = 0,\n\tViewportGuess = 1,\n\tEditGuess = 2,\n\tAccurate = 3\n}\n\ntype Node = ListNode | LeafNode;\n\n// Exported for tests\nexport interface LeafNode {\n\treadonly length: number;\n\ttoken: number;\n\ttokenQuality: TokenQuality;\n\theight: 0;\n}\n\nexport interface TokenUpdate {\n\treadonly startOffsetInclusive: number;\n\treadonly length: number;\n\treadonly token: number;\n}\n\nfunction isLeaf(node: Node): node is LeafNode {\n\treturn (node as LeafNode).token !== undefined;\n}\n\n// Heavily inspired by https://github.com/microsoft/vscode/blob/4eb2658d592cb6114a7a393655574176cc790c5b/src/vs/editor/common/model/bracketPairsTextModelPart/bracketPairsTree/concat23Trees.ts#L108-L109\nfunction append(node: Node, nodeToAppend: Node): Node {\n\tlet curNode = node;\n\tconst parents: ListNode[] = [];\n\tlet nodeToAppendOfCorrectHeight: Node | undefined;\n\twhile (true) {\n\t\tif (nodeToAppend.height === curNode.height) {\n\t\t\tnodeToAppendOfCorrectHeight = nodeToAppend;\n\t\t\tbreak;\n\t\t}\n\n\t\tif (isLeaf(curNode)) {\n\t\t\tthrow new Error('unexpected');\n\t\t}\n\t\tparents.push(curNode);\n\t\tcurNode = curNode.lastChild();\n\t}\n\tfor (let i = parents.length - 1; i >= 0; i--) {\n\t\tconst parent = parents[i];\n\t\tif (nodeToAppendOfCorrectHeight) {\n\t\t\t// Can we take the element?\n\t\t\tif (parent.children.length >= 3) {\n\t\t\t\t// we need to split to maintain (2,3)-tree property.\n\t\t\t\t// Send the third element + the new element to the parent.\n\t\t\t\tconst newList = ListNode.create(parent.unappendChild(), nodeToAppendOfCorrectHeight);\n\t\t\t\tnodeToAppendOfCorrectHeight = newList;\n\t\t\t} else {\n\t\t\t\tparent.appendChild(nodeToAppendOfCorrectHeight);\n\t\t\t\tnodeToAppendOfCorrectHeight = undefined;\n\t\t\t}\n\t\t}\n\t}\n\tif (nodeToAppendOfCorrectHeight) {\n\t\tconst newList = new ListNode(nodeToAppendOfCorrectHeight.height + 1);\n\t\tnewList.appendChild(node);\n\t\tnewList.appendChild(nodeToAppendOfCorrectHeight);\n\t\treturn newList;\n\t} else {\n\t\treturn node;\n\t}\n}\n\nfunction prepend(list: Node, nodeToAppend: Node): Node {\n\tlet curNode = list;\n\tconst parents: ListNode[] = [];\n\twhile (nodeToAppend.height !== curNode.height) {\n\t\tif (isLeaf(curNode)) {\n\t\t\tthrow new Error('unexpected');\n\t\t}\n\t\tparents.push(curNode);\n\t\t// assert 2 <= curNode.childrenFast.length <= 3\n\t\tcurNode = curNode.children[0] as ListNode;\n\t}\n\tlet nodeToPrependOfCorrectHeight: Node | undefined = nodeToAppend;\n\t// assert nodeToAppendOfCorrectHeight!.listHeight === curNode.listHeight\n\tfor (let i = parents.length - 1; i >= 0; i--) {\n\t\tconst parent = parents[i];\n\t\tif (nodeToPrependOfCorrectHeight) {\n\t\t\t// Can we take the element?\n\t\t\tif (parent.children.length >= 3) {\n\t\t\t\t// we need to split to maintain (2,3)-tree property.\n\t\t\t\t// Send the third element + the new element to the parent.\n\t\t\t\tnodeToPrependOfCorrectHeight = ListNode.create(nodeToPrependOfCorrectHeight, parent.unprependChild());\n\t\t\t} else {\n\t\t\t\tparent.prependChild(nodeToPrependOfCorrectHeight);\n\t\t\t\tnodeToPrependOfCorrectHeight = undefined;\n\t\t\t}\n\t\t}\n\t}\n\tif (nodeToPrependOfCorrectHeight) {\n\t\treturn ListNode.create(nodeToPrependOfCorrectHeight, list);\n\t} else {\n\t\treturn list;\n\t}\n}\n\nfunction concat(node1: Node, node2: Node): Node {\n\tif (node1.height === node2.height) {\n\t\treturn ListNode.create(node1, node2);\n\t}\n\telse if (node1.height > node2.height) {\n\t\t// node1 is the tree we want to insert into\n\t\treturn append(node1, node2);\n\t} else {\n\t\treturn prepend(node2, node1);\n\t}\n}\n\nexport class TokenStore implements IDisposable {\n\tprivate _root: Node;\n\n\tconstructor(private readonly _textModel: ITextModel) {\n\t\tthis._root = this.createEmptyRoot();\n\t}\n\n\tprivate createEmptyRoot(): Node {\n\t\treturn {\n\t\t\tlength: this._textModel.getValueLength(),\n\t\t\ttoken: 0,\n\t\t\theight: 0,\n\t\t\ttokenQuality: TokenQuality.None\n\t\t};\n\t}\n\n\t/**\n\t *\n\t * @param update all the tokens for the document in sequence\n\t */\n\tbuildStore(tokens: TokenUpdate[], tokenQuality: TokenQuality): void {\n\t\tthis._root = this.createFromUpdates(tokens, tokenQuality);\n\t}\n\n\tprivate createFromUpdates(tokens: TokenUpdate[], tokenQuality: TokenQuality): Node {\n\t\tif (tokens.length === 0) {\n\t\t\treturn this.createEmptyRoot();\n\t\t}\n\t\tlet newRoot: Node = {\n\t\t\tlength: tokens[0].length,\n\t\t\ttoken: tokens[0].token,\n\t\t\theight: 0,\n\t\t\ttokenQuality\n\t\t};\n\t\tfor (let j = 1; j < tokens.length; j++) {\n\t\t\tnewRoot = append(newRoot, { length: tokens[j].length, token: tokens[j].token, height: 0, tokenQuality });\n\t\t}\n\t\treturn newRoot;\n\t}\n\n\t/**\n\t *\n\t * @param tokens tokens are in sequence in the document.\n\t */\n\tupdate(length: number, tokens: TokenUpdate[], tokenQuality: TokenQuality) {\n\t\tif (tokens.length === 0) {\n\t\t\treturn;\n\t\t}\n\t\tthis.replace(length, tokens[0].startOffsetInclusive, tokens, tokenQuality);\n\t}\n\n\tdelete(length: number, startOffset: number) {\n\t\tthis.replace(length, startOffset, [], TokenQuality.EditGuess);\n\t}\n\n\t/**\n\t *\n\t * @param tokens tokens are in sequence in the document.\n\t */\n\tprivate replace(length: number, updateOffsetStart: number, tokens: TokenUpdate[], tokenQuality: TokenQuality) {\n\t\tconst firstUnchangedOffsetAfterUpdate = updateOffsetStart + length;\n\t\t// Find the last unchanged node preceding the update\n\t\tconst precedingNodes: Node[] = [];\n\t\t// Find the first unchanged node after the update\n\t\tconst postcedingNodes: Node[] = [];\n\t\tconst stack: { node: Node; offset: number }[] = [{ node: this._root, offset: 0 }];\n\n\t\twhile (stack.length > 0) {\n\t\t\tconst node = stack.pop()!;\n\t\t\tconst currentOffset = node.offset;\n\n\t\t\tif (currentOffset < updateOffsetStart && currentOffset + node.node.length <= updateOffsetStart) {\n\t\t\t\tif (!isLeaf(node.node)) {\n\t\t\t\t\tnode.node.parent = undefined;\n\t\t\t\t}\n\t\t\t\tprecedingNodes.push(node.node);\n\t\t\t\tcontinue;\n\t\t\t} else if (isLeaf(node.node) && (currentOffset < updateOffsetStart)) {\n\t\t\t\t// We have a partial preceding node\n\t\t\t\tprecedingNodes.push({ length: updateOffsetStart - currentOffset, token: node.node.token, height: 0, tokenQuality: node.node.tokenQuality });\n\t\t\t\t// Node could also be postceeding, so don't continue\n\t\t\t}\n\n\t\t\tif ((updateOffsetStart <= currentOffset) && (currentOffset + node.node.length <= firstUnchangedOffsetAfterUpdate)) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tif (currentOffset >= firstUnchangedOffsetAfterUpdate) {\n\t\t\t\tif (!isLeaf(node.node)) {\n\t\t\t\t\tnode.node.parent = undefined;\n\t\t\t\t}\n\t\t\t\tpostcedingNodes.push(node.node);\n\t\t\t\tcontinue;\n\t\t\t} else if (isLeaf(node.node) && (currentOffset + node.node.length > firstUnchangedOffsetAfterUpdate)) {\n\t\t\t\t// we have a partial postceeding node\n\t\t\t\tpostcedingNodes.push({ length: currentOffset + node.node.length - firstUnchangedOffsetAfterUpdate, token: node.node.token, height: 0, tokenQuality: node.node.tokenQuality });\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tif (!isLeaf(node.node)) {\n\t\t\t\t// Push children in reverse order to process them left-to-right when popping\n\t\t\t\tlet childOffset = currentOffset + node.node.length;\n\t\t\t\tfor (let i = node.node.children.length - 1; i >= 0; i--) {\n\t\t\t\t\tchildOffset -= node.node.children[i].length;\n\t\t\t\t\tstack.push({ node: node.node.children[i], offset: childOffset });\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tlet allNodes: Node[];\n\t\tif (tokens.length > 0) {\n\t\t\tallNodes = precedingNodes.concat(this.createFromUpdates(tokens, tokenQuality), postcedingNodes);\n\t\t} else {\n\t\t\tallNodes = precedingNodes.concat(postcedingNodes);\n\t\t}\n\t\tlet newRoot: Node = allNodes[0];\n\t\tfor (let i = 1; i < allNodes.length; i++) {\n\t\t\tnewRoot = concat(newRoot, allNodes[i]);\n\t\t}\n\n\t\tthis._root = newRoot ?? this.createEmptyRoot();\n\t}\n\n\t/**\n\t *\n\t * @param startOffsetInclusive\n\t * @param endOffsetExclusive\n\t * @param visitor Return true from visitor to exit early\n\t * @returns\n\t */\n\tprivate traverseInOrderInRange(startOffsetInclusive: number, endOffsetExclusive: number, visitor: (node: Node, offset: number) => boolean): void {\n\t\tconst stack: { node: Node; offset: number }[] = [{ node: this._root, offset: 0 }];\n\n\t\twhile (stack.length > 0) {\n\t\t\tconst { node, offset } = stack.pop()!;\n\t\t\tconst nodeEnd = offset + node.length;\n\n\t\t\t// Skip nodes that are completely before or after the range\n\t\t\tif (nodeEnd <= startOffsetInclusive || offset >= endOffsetExclusive) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tif (visitor(node, offset)) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (!isLeaf(node)) {\n\t\t\t\t// Push children in reverse order to process them left-to-right when popping\n\t\t\t\tlet childOffset = offset + node.length;\n\t\t\t\tfor (let i = node.children.length - 1; i >= 0; i--) {\n\t\t\t\t\tchildOffset -= node.children[i].length;\n\t\t\t\t\tstack.push({ node: node.children[i], offset: childOffset });\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tgetTokenAt(offset: number): TokenUpdate | undefined {\n\t\tlet result: TokenUpdate | undefined;\n\t\tthis.traverseInOrderInRange(offset, this._root.length, (node, offset) => {\n\t\t\tif (isLeaf(node)) {\n\t\t\t\tresult = { token: node.token, startOffsetInclusive: offset, length: node.length };\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\treturn false;\n\t\t});\n\t\treturn result;\n\t}\n\n\tgetTokensInRange(startOffsetInclusive: number, endOffsetExclusive: number): TokenUpdate[] {\n\t\tconst result: { token: number; startOffsetInclusive: number; length: number }[] = [];\n\t\tthis.traverseInOrderInRange(startOffsetInclusive, endOffsetExclusive, (node, offset) => {\n\t\t\tif (isLeaf(node)) {\n\t\t\t\tlet clippedLength = node.length;\n\t\t\t\tlet clippedOffset = offset;\n\t\t\t\tif ((offset < startOffsetInclusive) && (offset + node.length > endOffsetExclusive)) {\n\t\t\t\t\tclippedOffset = startOffsetInclusive;\n\t\t\t\t\tclippedLength = endOffsetExclusive - startOffsetInclusive;\n\t\t\t\t} else if (offset < startOffsetInclusive) {\n\t\t\t\t\tclippedLength -= (startOffsetInclusive - offset);\n\t\t\t\t\tclippedOffset = startOffsetInclusive;\n\t\t\t\t} else if (offset + node.length > endOffsetExclusive) {\n\t\t\t\t\tclippedLength -= (offset + node.length - endOffsetExclusive);\n\t\t\t\t}\n\t\t\t\tresult.push({ token: node.token, startOffsetInclusive: clippedOffset, length: clippedLength });\n\t\t\t}\n\t\t\treturn false;\n\t\t});\n\t\treturn result;\n\t}\n\n\tmarkForRefresh(startOffsetInclusive: number, endOffsetExclusive: number): void {\n\t\tthis.traverseInOrderInRange(startOffsetInclusive, endOffsetExclusive, (node) => {\n\t\t\tif (isLeaf(node)) {\n\t\t\t\tnode.tokenQuality = TokenQuality.None;\n\t\t\t}\n\t\t\treturn false;\n\t\t});\n\t}\n\n\trangeHasTokens(startOffsetInclusive: number, endOffsetExclusive: number, minimumTokenQuality: TokenQuality): boolean {\n\t\tlet hasAny = true;\n\t\tthis.traverseInOrderInRange(startOffsetInclusive, endOffsetExclusive, (node) => {\n\t\t\tif (isLeaf(node) && (node.tokenQuality < minimumTokenQuality)) {\n\t\t\t\thasAny = false;\n\t\t\t}\n\t\t\treturn false;\n\t\t});\n\t\treturn hasAny;\n\t}\n\n\trangeNeedsRefresh(startOffsetInclusive: number, endOffsetExclusive: number): boolean {\n\t\tlet needsRefresh = false;\n\t\tthis.traverseInOrderInRange(startOffsetInclusive, endOffsetExclusive, (node) => {\n\t\t\tif (isLeaf(node) && (node.tokenQuality !== TokenQuality.Accurate)) {\n\t\t\t\tneedsRefresh = true;\n\t\t\t}\n\t\t\treturn false;\n\t\t});\n\t\treturn needsRefresh;\n\t}\n\n\tgetNeedsRefresh(): { startOffset: number; endOffset: number }[] {\n\t\tconst result: { startOffset: number; endOffset: number }[] = [];\n\n\t\tthis.traverseInOrderInRange(0, this._textModel.getValueLength(), (node, offset) => {\n\t\t\tif (isLeaf(node) && (node.tokenQuality !== TokenQuality.Accurate)) {\n\t\t\t\tif ((result.length > 0) && (result[result.length - 1].endOffset === offset)) {\n\t\t\t\t\tresult[result.length - 1].endOffset += node.length;\n\t\t\t\t} else {\n\t\t\t\t\tresult.push({ startOffset: offset, endOffset: offset + node.length });\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn false;\n\t\t});\n\t\treturn result;\n\t}\n\n\tdispose(): void {\n\t\tconst stack: Array<[Node, boolean]> = [[this._root, false]];\n\t\twhile (stack.length > 0) {\n\t\t\tconst [node, visited] = stack.pop()!;\n\t\t\tif (isLeaf(node)) {\n\t\t\t\t// leaf node does not need to be disposed\n\t\t\t} else if (!visited) {\n\t\t\t\tstack.push([node, true]);\n\t\t\t\tfor (let i = node.children.length - 1; i >= 0; i--) {\n\t\t\t\t\tstack.push([node.children[i], false]);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tnode.dispose();\n\t\t\t\tnode.parent = undefined;\n\t\t\t}\n\t\t}\n\t\tthis._root = undefined!;\n\t}\n}\n","/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n\nimport { IDisposable } from '../../../../../base/common/lifecycle.js';\nimport { ITextModel } from '../../../model.js';\n\n// Exported for tests\nexport class ListNode implements IDisposable {\n\tparent?: ListNode;\n\tprivate readonly _children: Node[] = [];\n\tget children(): ReadonlyArray<Node> { return this._children; }\n\n\tprivate _length: number = 0;\n\tget length(): number { return this._length; }\n\n\tconstructor(public readonly height: number) { }\n\n\tstatic create(node1: Node, node2: Node) {\n\t\tconst list = new ListNode(node1.height + 1);\n\t\tlist.appendChild(node1);\n\t\tlist.appendChild(node2);\n\t\treturn list;\n\t}\n\n\tcanAppendChild(): boolean {\n\t\treturn this._children.length < 3;\n\t}\n\n\tappendChild(node: Node) {\n\t\tif (!this.canAppendChild()) {\n\t\t\tthrow new Error('Cannot insert more than 3 children in a ListNode');\n\t\t}\n\t\tthis._children.push(node);\n\n\t\tthis._length += node.length;\n\t\tthis._updateParentLength(node.length);\n\t\tif (!isLeaf(node)) {\n\t\t\tnode.parent = this;\n\t\t}\n\t}\n\n\tprivate _updateParentLength(delta: number) {\n\t\tlet updateParent = this.parent;\n\t\twhile (updateParent) {\n\t\t\tupdateParent._length += delta;\n\t\t\tupdateParent = updateParent.parent;\n\t\t}\n\t}\n\n\tunappendChild(): Node {\n\t\tconst child = this._children.pop()!;\n\t\tthis._length -= child.length;\n\t\tthis._updateParentLength(-child.length);\n\t\treturn child;\n\t}\n\n\tprependChild(node: Node) {\n\t\tif (this._children.length >= 3) {\n\t\t\tthrow new Error('Cannot prepend more than 3 children in a ListNode');\n\t\t}\n\t\tthis._children.unshift(node);\n\n\t\tthis._length += node.length;\n\t\tthis._updateParentLength(node.length);\n\t\tif (!isLeaf(node)) {\n\t\t\tnode.parent = this;\n\t\t}\n\t}\n\n\tunprependChild(): Node {\n\t\tconst child = this._children.shift()!;\n\t\tthis._length -= child.length;\n\t\tthis._updateParentLength(-child.length);\n\t\treturn child;\n\t}\n\n\tlastChild(): Node {\n\t\treturn this._children[this._children.length - 1];\n\t}\n\n\tdispose() {\n\t\tthis._children.splice(0, this._children.length);\n\t}\n}\n\nexport enum TokenQuality {\n\tNone = 0,\n\tViewportGuess = 1,\n\tEditGuess = 2,\n\tAccurate = 3\n}\n\ntype Node = ListNode | LeafNode;\n\n// Exported for tests\nexport interface LeafNode {\n\treadonly length: number;\n\ttoken: number;\n\ttokenQuality: TokenQuality;\n\theight: 0;\n}\n\nexport interface TokenUpdate {\n\treadonly startOffsetInclusive: number;\n\treadonly length: number;\n\treadonly token: number;\n}\n\nfunction isLeaf(node: Node): node is LeafNode {\n\treturn (node as LeafNode).token !== undefined;\n}\n\n// Heavily inspired by https://github.com/microsoft/vscode/blob/4eb2658d592cb6114a7a393655574176cc790c5b/src/vs/editor/common/model/bracketPairsTextModelPart/bracketPairsTree/concat23Trees.ts#L108-L109\nfunction append(node: Node, nodeToAppend: Node): Node {\n\tlet curNode = node;\n\tconst parents: ListNode[] = [];\n\tlet nodeToAppendOfCorrectHeight: Node | undefined;\n\twhile (true) {\n\t\tif (nodeToAppend.height === curNode.height) {\n\t\t\tnodeToAppendOfCorrectHeight = nodeToAppend;\n\t\t\tbreak;\n\t\t}\n\n\t\tif (isLeaf(curNode)) {\n\t\t\tthrow new Error('unexpected');\n\t\t}\n\t\tparents.push(curNode);\n\t\tcurNode = curNode.lastChild();\n\t}\n\tfor (let i = parents.length - 1; i >= 0; i--) {\n\t\tconst parent = parents[i];\n\t\tif (nodeToAppendOfCorrectHeight) {\n\t\t\t// Can we take the element?\n\t\t\tif (parent.children.length >= 3) {\n\t\t\t\t// we need to split to maintain (2,3)-tree property.\n\t\t\t\t// Send the third element + the new element to the parent.\n\t\t\t\tconst newList = ListNode.create(parent.unappendChild(), nodeToAppendOfCorrectHeight);\n\t\t\t\tnodeToAppendOfCorrectHeight = newList;\n\t\t\t} else {\n\t\t\t\tparent.appendChild(nodeToAppendOfCorrectHeight);\n\t\t\t\tnodeToAppendOfCorrectHeight = undefined;\n\t\t\t}\n\t\t}\n\t}\n\tif (nodeToAppendOfCorrectHeight) {\n\t\tconst newList = new ListNode(nodeToAppendOfCorrectHeight.height + 1);\n\t\tnewList.appendChild(node);\n\t\tnewList.appendChild(nodeToAppendOfCorrectHeight);\n\t\treturn newList;\n\t} else {\n\t\treturn node;\n\t}\n}\n\nfunction prepend(list: Node, nodeToAppend: Node): Node {\n\tlet curNode = list;\n\tconst parents: ListNode[] = [];\n\twhile (nodeToAppend.height !== curNode.height) {\n\t\tif (isLeaf(curNode)) {\n\t\t\tthrow new Error('unexpected');\n\t\t}\n\t\tparents.push(curNode);\n\t\t// assert 2 <= curNode.childrenFast.length <= 3\n\t\tcurNode = curNode.children[0] as ListNode;\n\t}\n\tlet nodeToPrependOfCorrectHeight: Node | undefined = nodeToAppend;\n\t// assert nodeToAppendOfCorrectHeight!.listHeight === curNode.listHeight\n\tfor (let i = parents.length - 1; i >= 0; i--) {\n\t\tconst parent = parents[i];\n\t\tif (nodeToPrependOfCorrectHeight) {\n\t\t\t// Can we take the element?\n\t\t\tif (parent.children.length >= 3) {\n\t\t\t\t// we need to split to maintain (2,3)-tree property.\n\t\t\t\t// Send the third element + the new element to the parent.\n\t\t\t\tnodeToPrependOfCorrectHeight = ListNode.create(nodeToPrependOfCorrectHeight, parent.unprependChild());\n\t\t\t} else {\n\t\t\t\tparent.prependChild(nodeToPrependOfCorrectHeight);\n\t\t\t\tnodeToPrependOfCorrectHeight = undefined;\n\t\t\t}\n\t\t}\n\t}\n\tif (nodeToPrependOfCorrectHeight) {\n\t\treturn ListNode.create(nodeToPrependOfCorrectHeight, list);\n\t} else {\n\t\treturn list;\n\t}\n}\n\nfunction concat(node1: Node, node2: Node): Node {\n\tif (node1.height === node2.height) {\n\t\treturn ListNode.create(node1, node2);\n\t}\n\telse if (node1.height > node2.height) {\n\t\t// node1 is the tree we want to insert into\n\t\treturn append(node1, node2);\n\t} else {\n\t\treturn prepend(node2, node1);\n\t}\n}\n\nexport class TokenStore implements IDisposable {\n\tprivate _root: Node;\n\n\tconstructor(private readonly _textModel: ITextModel) {\n\t\tthis._root = this.createEmptyRoot();\n\t}\n\n\tprivate createEmptyRoot(): Node {\n\t\treturn {\n\t\t\tlength: this._textModel.getValueLength(),\n\t\t\ttoken: 0,\n\t\t\theight: 0,\n\t\t\ttokenQuality: TokenQuality.None\n\t\t};\n\t}\n\n\t/**\n\t *\n\t * @param update all the tokens for the document in sequence\n\t */\n\tbuildStore(tokens: TokenUpdate[], tokenQuality: TokenQuality): void {\n\t\tthis._root = this.createFromUpdates(tokens, tokenQuality);\n\t}\n\n\tprivate createFromUpdates(tokens: TokenUpdate[], tokenQuality: TokenQuality): Node {\n\t\tif (tokens.length === 0) {\n\t\t\treturn this.createEmptyRoot();\n\t\t}\n\t\tlet newRoot: Node = {\n\t\t\tlength: tokens[0].length,\n\t\t\ttoken: tokens[0].token,\n\t\t\theight: 0,\n\t\t\ttokenQuality\n\t\t};\n\t\tfor (let j = 1; j < tokens.length; j++) {\n\t\t\tnewRoot = append(newRoot, { length: tokens[j].length, token: tokens[j].token, height: 0, tokenQuality });\n\t\t}\n\t\treturn newRoot;\n\t}\n\n\t/**\n\t *\n\t * @param tokens tokens are in sequence in the document.\n\t */\n\tupdate(length: number, tokens: TokenUpdate[], tokenQuality: TokenQuality) {\n\t\tif (tokens.length === 0) {\n\t\t\treturn;\n\t\t}\n\t\tthis.replace(length, tokens[0].startOffsetInclusive, tokens, tokenQuality);\n\t}\n\n\tdelete(length: number, startOffset: number) {\n\t\tthis.replace(length, startOffset, [], TokenQuality.EditGuess);\n\t}\n\n\t/**\n\t *\n\t * @param tokens tokens are in sequence in the document.\n\t */\n\tprivate replace(length: number, updateOffsetStart: number, tokens: TokenUpdate[], tokenQuality: TokenQuality) {\n\t\tconst firstUnchangedOffsetAfterUpdate = updateOffsetStart + length;\n\t\t// Find the last unchanged node preceding the update\n\t\tconst precedingNodes: Node[] = [];\n\t\t// Find the first unchanged node after the update\n\t\tconst postcedingNodes: Node[] = [];\n\t\tconst stack: { node: Node; offset: number }[] = [{ node: this._root, offset: 0 }];\n\n\t\twhile (stack.length > 0) {\n\t\t\tconst node = stack.pop()!;\n\t\t\tconst currentOffset = node.offset;\n\n\t\t\tif (currentOffset < updateOffsetStart && currentOffset + node.node.length <= updateOffsetStart) {\n\t\t\t\tif (!isLeaf(node.node)) {\n\t\t\t\t\tnode.node.parent = undefined;\n\t\t\t\t}\n\t\t\t\tprecedingNodes.push(node.node);\n\t\t\t\tcontinue;\n\t\t\t} else if (isLeaf(node.node) && (currentOffset < updateOffsetStart)) {\n\t\t\t\t// We have a partial preceding node\n\t\t\t\tprecedingNodes.push({ length: updateOffsetStart - currentOffset, token: node.node.token, height: 0, tokenQuality: node.node.tokenQuality });\n\t\t\t\t// Node could also be postceeding, so don't continue\n\t\t\t}\n\n\t\t\tif ((updateOffsetStart <= currentOffset) && (currentOffset + node.node.length <= firstUnchangedOffsetAfterUpdate)) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tif (currentOffset >= firstUnchangedOffsetAfterUpdate) {\n\t\t\t\tif (!isLeaf(node.node)) {\n\t\t\t\t\tnode.node.parent = undefined;\n\t\t\t\t}\n\t\t\t\tpostcedingNodes.push(node.node);\n\t\t\t\tcontinue;\n\t\t\t} else if (isLeaf(node.node) && (currentOffset + node.node.length > firstUnchangedOffsetAfterUpdate)) {\n\t\t\t\t// we have a partial postceeding node\n\t\t\t\tpostcedingNodes.push({ length: currentOffset + node.node.length - firstUnchangedOffsetAfterUpdate, token: node.node.token, height: 0, tokenQuality: node.node.tokenQuality });\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tif (!isLeaf(node.node)) {\n\t\t\t\t// Push children in reverse order to process them left-to-right when popping\n\t\t\t\tlet childOffset = currentOffset + node.node.length;\n\t\t\t\tfor (let i = node.node.children.length - 1; i >= 0; i--) {\n\t\t\t\t\tchildOffset -= node.node.children[i].length;\n\t\t\t\t\tstack.push({ node: node.node.children[i], offset: childOffset });\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tlet allNodes: Node[];\n\t\tif (tokens.length > 0) {\n\t\t\tallNodes = precedingNodes.concat(this.createFromUpdates(tokens, tokenQuality), postcedingNodes);\n\t\t} else {\n\t\t\tallNodes = precedingNodes.concat(postcedingNodes);\n\t\t}\n\t\tlet newRoot: Node = allNodes[0];\n\t\tfor (let i = 1; i < allNodes.length; i++) {\n\t\t\tnewRoot = concat(newRoot, allNodes[i]);\n\t\t}\n\n\t\tthis._root = newRoot ?? this.createEmptyRoot();\n\t}\n\n\t/**\n\t *\n\t * @param startOffsetInclusive\n\t * @param endOffsetExclusive\n\t * @param visitor Return true from visitor to exit early\n\t * @returns\n\t */\n\tprivate traverseInOrderInRange(startOffsetInclusive: number, endOffsetExclusive: number, visitor: (node: Node, offset: number) => boolean): void {\n\t\tconst stack: { node: Node; offset: number }[] = [{ node: this._root, offset: 0 }];\n\n\t\twhile (stack.length > 0) {\n\t\t\tconst { node, offset } = stack.pop()!;\n\t\t\tconst nodeEnd = offset + node.length;\n\n\t\t\t// Skip nodes that are completely before or after the range\n\t\t\tif (nodeEnd <= startOffsetInclusive || offset >= endOffsetExclusive) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tif (visitor(node, offset)) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (!isLeaf(node)) {\n\t\t\t\t// Push children in reverse order to process them left-to-right when popping\n\t\t\t\tlet childOffset = offset + node.length;\n\t\t\t\tfor (let i = node.children.length - 1; i >= 0; i--) {\n\t\t\t\t\tchildOffset -= node.children[i].length;\n\t\t\t\t\tstack.push({ node: node.children[i], offset: childOffset });\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tgetTokenAt(offset: number): TokenUpdate | undefined {\n\t\tlet result: TokenUpdate | undefined;\n\t\tthis.traverseInOrderInRange(offset, this._root.length, (node, offset) => {\n\t\t\tif (isLeaf(node)) {\n\t\t\t\tresult = { token: node.token, startOffsetInclusive: offset, length: node.length };\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\treturn false;\n\t\t});\n\t\treturn result;\n\t}\n\n\tgetTokensInRange(startOffsetInclusive: number, endOffsetExclusive: number): TokenUpdate[] {\n\t\tconst result: { token: number; startOffsetInclusive: number; length: number }[] = [];\n\t\tthis.traverseInOrderInRange(startOffsetInclusive, endOffsetExclusive, (node, offset) => {\n\t\t\tif (isLeaf(node)) {\n\t\t\t\tlet clippedLength = node.length;\n\t\t\t\tlet clippedOffset = offset;\n\t\t\t\tif ((offset < startOffsetInclusive) && (offset + node.length > endOffsetExclusive)) {\n\t\t\t\t\tclippedOffset = startOffsetInclusive;\n\t\t\t\t\tclippedLength = endOffsetExclusive - startOffsetInclusive;\n\t\t\t\t} else if (offset < startOffsetInclusive) {\n\t\t\t\t\tclippedLength -= (startOffsetInclusive - offset);\n\t\t\t\t\tclippedOffset = startOffsetInclusive;\n\t\t\t\t} else if (offset + node.length > endOffsetExclusive) {\n\t\t\t\t\tclippedLength -= (offset + node.length - endOffsetExclusive);\n\t\t\t\t}\n\t\t\t\tresult.push({ token: node.token, startOffsetInclusive: clippedOffset, length: clippedLength });\n\t\t\t}\n\t\t\treturn false;\n\t\t});\n\t\treturn result;\n\t}\n\n\tmarkForRefresh(startOffsetInclusive: number, endOffsetExclusive: number): void {\n\t\tthis.traverseInOrderInRange(startOffsetInclusive, endOffsetExclusive, (node) => {\n\t\t\tif (isLeaf(node)) {\n\t\t\t\tnode.tokenQuality = TokenQuality.None;\n\t\t\t}\n\t\t\treturn false;\n\t\t});\n\t}\n\n\trangeHasTokens(startOffsetInclusive: number, endOffsetExclusive: number, minimumTokenQuality: TokenQuality): boolean {\n\t\tlet hasAny = true;\n\t\tthis.traverseInOrderInRange(startOffsetInclusive, endOffsetExclusive, (node) => {\n\t\t\tif (isLeaf(node) && (node.tokenQuality < minimumTokenQuality)) {\n\t\t\t\thasAny = false;\n\t\t\t}\n\t\t\treturn false;\n\t\t});\n\t\treturn hasAny;\n\t}\n\n\trangeNeedsRefresh(startOffsetInclusive: number, endOffsetExclusive: number): boolean {\n\t\tlet needsRefresh = false;\n\t\tthis.traverseInOrderInRange(startOffsetInclusive, endOffsetExclusive, (node) => {\n\t\t\tif (isLeaf(node) && (node.tokenQuality !== TokenQuality.Accurate)) {\n\t\t\t\tneedsRefresh = true;\n\t\t\t}\n\t\t\treturn false;\n\t\t});\n\t\treturn needsRefresh;\n\t}\n\n\tgetNeedsRefresh(): { startOffset: number; endOffset: number }[] {\n\t\tconst result: { startOffset: number; endOffset: number }[] = [];\n\n\t\tthis.traverseInOrderInRange(0, this._textModel.getValueLength(), (node, offset) => {\n\t\t\tif (isLeaf(node) && (node.tokenQuality !== TokenQuality.Accurate)) {\n\t\t\t\tif ((result.length > 0) && (result[result.length - 1].endOffset === offset)) {\n\t\t\t\t\tresult[result.length - 1].endOffset += node.length;\n\t\t\t\t} else {\n\t\t\t\t\tresult.push({ startOffset: offset, endOffset: offset + node.length });\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn false;\n\t\t});\n\t\treturn result;\n\t}\n\n\tdispose(): void {\n\t\tconst stack: Array<[Node, boolean]> = [[this._root, false]];\n\t\twhile (stack.length > 0) {\n\t\t\tconst [node, visited] = stack.pop()!;\n\t\t\tif (isLeaf(node)) {\n\t\t\t\t// leaf node does not need to be disposed\n\t\t\t} else if (!visited) {\n\t\t\t\tstack.push([node, true]);\n\t\t\t\tfor (let i = node.children.length - 1; i >= 0; i--) {\n\t\t\t\t\tstack.push([node.children[i], false]);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tnode.dispose();\n\t\t\t\tnode.parent = undefined;\n\t\t\t}\n\t\t}\n\t\tthis._root = undefined!;\n\t}\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["file:///mnt/vss/_work/1/s/dependencies/vscode/out-editor-src/vs/editor/common/model/tokens/treeSitter/treeSitterTree.ts","vs/editor/common/model/tokens/treeSitter/treeSitterTree.ts"],"names":[],"mappings":"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","file":"treeSitterTree.js","sourceRoot":"file:///mnt/vss/_work/1/s/dependencies/vscode/out-editor-src","sourcesContent":["/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\nimport type * as TreeSitter from '@vscode/tree-sitter-wasm';\nimport { TaskQueue } from '../../../../../base/common/async.js';\nimport { Disposable, toDisposable } from '../../../../../base/common/lifecycle.js';\nimport { IObservable, observableValue, transaction, IObservableWithChange } from '../../../../../base/common/observable.js';\nimport { setTimeout0 } from '../../../../../base/common/platform.js';\nimport { ILogService } from '../../../../../platform/log/common/log.js';\nimport { ITelemetryService } from '../../../../../platform/telemetry/common/telemetry.js';\nimport { TextLength } from '../../../core/text/textLength.js';\nimport { IModelContentChangedEvent } from '../../../textModelEvents.js';\nimport { IModelContentChange } from '../../mirrorTextModel.js';\nimport { TextModel } from '../../textModel.js';\nimport { gotoParent, getClosestPreviousNodes, nextSiblingOrParentSibling, gotoNthChild } from './cursorUtils.js';\nimport { Range } from '../../../core/range.js';\n\nexport class TreeSitterTree extends Disposable {\n\n\tprivate readonly _tree = observableValue<TreeSitter.Tree | undefined, TreeParseUpdateEvent>(this, undefined);\n\tpublic readonly tree: IObservableWithChange<TreeSitter.Tree | undefined, TreeParseUpdateEvent> = this._tree;\n\n\tprivate readonly _treeLastParsedVersion = observableValue(this, -1);\n\tpublic readonly treeLastParsedVersion: IObservable<number> = this._treeLastParsedVersion;\n\n\tprivate _lastFullyParsed: TreeSitter.Tree | undefined;\n\tprivate _lastFullyParsedWithEdits: TreeSitter.Tree | undefined;\n\n\tprivate _onDidChangeContentQueue: TaskQueue = new TaskQueue();\n\n\tconstructor(\n\t\tpublic readonly languageId: string,\n\t\tprivate _ranges: TreeSitter.Range[] | undefined,\n\t\t// readonly treeSitterLanguage: Language,\n\t\t/** Must have the language set! */\n\t\tprivate readonly _parser: TreeSitter.Parser,\n\t\tprivate readonly _parserClass: typeof TreeSitter.Parser,\n\t\t// private readonly _injectionQuery: TreeSitter.Query,\n\t\tpublic readonly textModel: TextModel,\n\t\t@ILogService private readonly _logService: ILogService,\n\t\t@ITelemetryService private readonly _telemetryService: ITelemetryService\n\t) {\n\t\tsuper();\n\n\t\tthis._tree = observableValue(this, undefined);\n\t\tthis.tree = this._tree;\n\n\t\tthis._register(toDisposable(() => {\n\t\t\tthis._tree.get()?.delete();\n\t\t\tthis._lastFullyParsed?.delete();\n\t\t\tthis._lastFullyParsedWithEdits?.delete();\n\t\t\tthis._parser.delete();\n\t\t}));\n\t\tthis.handleContentChange(undefined, this._ranges);\n\t}\n\n\tpublic handleContentChange(e: IModelContentChangedEvent | undefined, ranges?: TreeSitter.Range[]): void {\n\t\tconst version = this.textModel.getVersionId();\n\t\tlet newRanges: TreeSitter.Range[] = [];\n\t\tif (ranges) {\n\t\t\tnewRanges = this._setRanges(ranges);\n\t\t}\n\t\tif (e) {\n\t\t\tthis._applyEdits(e.changes);\n\t\t}\n\n\t\tthis._onDidChangeContentQueue.clearPending();\n\t\tthis._onDidChangeContentQueue.schedule(async () => {\n\t\t\tif (this._store.isDisposed) {\n\t\t\t\t// No need to continue the queue if we are disposed\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst oldTree = this._lastFullyParsed;\n\t\t\tlet changedNodes: TreeSitter.Range[] | undefined;\n\t\t\tif (this._lastFullyParsedWithEdits && this._lastFullyParsed) {\n\t\t\t\tchangedNodes = this._findChangedNodes(this._lastFullyParsedWithEdits, this._lastFullyParsed);\n\t\t\t}\n\n\t\t\tconst completed = await this._parseAndUpdateTree(version);\n\t\t\tif (completed) {\n\t\t\t\tlet ranges: RangeChange[] | undefined;\n\t\t\t\tif (!changedNodes) {\n\t\t\t\t\tif (this._ranges) {\n\t\t\t\t\t\tranges = this._ranges.map(r => ({ newRange: new Range(r.startPosition.row + 1, r.startPosition.column + 1, r.endPosition.row + 1, r.endPosition.column + 1), oldRangeLength: r.endIndex - r.startIndex, newRangeStartOffset: r.startIndex, newRangeEndOffset: r.endIndex }));\n\t\t\t\t\t}\n\t\t\t\t} else if (oldTree && changedNodes) {\n\t\t\t\t\tranges = this._findTreeChanges(completed, changedNodes, newRanges);\n\t\t\t\t}\n\t\t\t\tif (!ranges) {\n\t\t\t\t\tranges = [{ newRange: this.textModel.getFullModelRange(), newRangeStartOffset: 0, newRangeEndOffset: this.textModel.getValueLength() }];\n\t\t\t\t}\n\n\t\t\t\tconst previousTree = this._tree.get();\n\t\t\t\ttransaction(tx => {\n\t\t\t\t\tthis._tree.set(completed, tx, { ranges, versionId: version });\n\t\t\t\t\tthis._treeLastParsedVersion.set(version, tx);\n\t\t\t\t});\n\t\t\t\tpreviousTree?.delete();\n\t\t\t}\n\t\t});\n\t}\n\n\tprivate _applyEdits(changes: IModelContentChange[]) {\n\t\tfor (const change of changes) {\n\t\t\tconst originalTextLength = TextLength.ofRange(Range.lift(change.range));\n\t\t\tconst newTextLength = TextLength.ofText(change.text);\n\t\t\tconst summedTextLengths = change.text.length === 0 ? newTextLength : originalTextLength.add(newTextLength);\n\t\t\tconst edit = {\n\t\t\t\tstartIndex: change.rangeOffset,\n\t\t\t\toldEndIndex: change.rangeOffset + change.rangeLength,\n\t\t\t\tnewEndIndex: change.rangeOffset + change.text.length,\n\t\t\t\tstartPosition: { row: change.range.startLineNumber - 1, column: change.range.startColumn - 1 },\n\t\t\t\toldEndPosition: { row: change.range.endLineNumber - 1, column: change.range.endColumn - 1 },\n\t\t\t\tnewEndPosition: { row: change.range.startLineNumber + summedTextLengths.lineCount - 1, column: summedTextLengths.lineCount ? summedTextLengths.columnCount : (change.range.endColumn + summedTextLengths.columnCount) }\n\t\t\t};\n\t\t\tthis._tree.get()?.edit(edit);\n\t\t\tthis._lastFullyParsedWithEdits?.edit(edit);\n\t\t}\n\t}\n\n\tprivate _findChangedNodes(newTree: TreeSitter.Tree, oldTree: TreeSitter.Tree): TreeSitter.Range[] | undefined {\n\t\tif ((this._ranges && this._ranges.every(range => range.startPosition.row !== newTree.rootNode.startPosition.row)) || newTree.rootNode.startPosition.row !== 0) {\n\t\t\treturn [];\n\t\t}\n\t\tconst newCursor = newTree.walk();\n\t\tconst oldCursor = oldTree.walk();\n\n\t\tconst nodes: TreeSitter.Range[] = [];\n\t\tlet next = true;\n\n\t\tdo {\n\t\t\tif (newCursor.currentNode.hasChanges) {\n\t\t\t\t// Check if only one of the children has changes.\n\t\t\t\t// If it's only one, then we go to that child.\n\t\t\t\t// If it's more then, we need to go to each child\n\t\t\t\t// If it's none, then we've found one of our ranges\n\t\t\t\tconst newChildren = newCursor.currentNode.children;\n\t\t\t\tconst indexChangedChildren: number[] = [];\n\t\t\t\tconst changedChildren = newChildren.filter((c, index) => {\n\t\t\t\t\tif (c?.hasChanges || (oldCursor.currentNode.children.length <= index)) {\n\t\t\t\t\t\tindexChangedChildren.push(index);\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t\treturn false;\n\t\t\t\t});\n\t\t\t\t// If we have changes and we *had* an error, the whole node should be refreshed.\n\t\t\t\tif ((changedChildren.length === 0) || (newCursor.currentNode.hasError !== oldCursor.currentNode.hasError)) {\n\t\t\t\t\t// walk up again until we get to the first one that's named as unnamed nodes can be too granular\n\t\t\t\t\twhile (newCursor.currentNode.parent && next && !newCursor.currentNode.isNamed) {\n\t\t\t\t\t\tnext = gotoParent(newCursor, oldCursor);\n\t\t\t\t\t}\n\t\t\t\t\t// Use the end position of the previous node and the start position of the current node\n\t\t\t\t\tconst newNode = newCursor.currentNode;\n\t\t\t\t\tconst closestPreviousNode = getClosestPreviousNodes(newCursor, newTree) ?? newNode;\n\t\t\t\t\tnodes.push({\n\t\t\t\t\t\tstartIndex: closestPreviousNode.startIndex,\n\t\t\t\t\t\tendIndex: newNode.endIndex,\n\t\t\t\t\t\tstartPosition: closestPreviousNode.startPosition,\n\t\t\t\t\t\tendPosition: newNode.endPosition\n\t\t\t\t\t});\n\t\t\t\t\tnext = nextSiblingOrParentSibling(newCursor, oldCursor);\n\t\t\t\t} else if (changedChildren.length >= 1) {\n\t\t\t\t\tnext = gotoNthChild(newCursor, oldCursor, indexChangedChildren[0]);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tnext = nextSiblingOrParentSibling(newCursor, oldCursor);\n\t\t\t}\n\t\t} while (next);\n\n\t\tnewCursor.delete();\n\t\toldCursor.delete();\n\t\treturn nodes;\n\t}\n\n\tprivate _findTreeChanges(newTree: TreeSitter.Tree, changedNodes: TreeSitter.Range[], newRanges: TreeSitter.Range[]): RangeChange[] {\n\t\tlet newRangeIndex = 0;\n\t\tconst mergedChanges: RangeChange[] = [];\n\n\t\t// Find the parent in the new tree of the changed node\n\t\tfor (let nodeIndex = 0; nodeIndex < changedNodes.length; nodeIndex++) {\n\t\t\tconst node = changedNodes[nodeIndex];\n\n\t\t\tif (mergedChanges.length > 0) {\n\t\t\t\tif ((node.startIndex >= mergedChanges[mergedChanges.length - 1].newRangeStartOffset) && (node.endIndex <= mergedChanges[mergedChanges.length - 1].newRangeEndOffset)) {\n\t\t\t\t\t// This node is within the previous range, skip it\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst cursor = newTree.walk();\n\t\t\tconst cursorContainersNode = () => cursor.startIndex < node.startIndex && cursor.endIndex > node.endIndex;\n\n\t\t\twhile (cursorContainersNode()) {\n\t\t\t\t// See if we can go to a child\n\t\t\t\tlet child = cursor.gotoFirstChild();\n\t\t\t\tlet foundChild = false;\n\t\t\t\twhile (child) {\n\t\t\t\t\tif (cursorContainersNode() && cursor.currentNode.isNamed) {\n\t\t\t\t\t\tfoundChild = true;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tchild = cursor.gotoNextSibling();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (!foundChild) {\n\t\t\t\t\tcursor.gotoParent();\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tif (cursor.currentNode.childCount === 0) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst startPosition = cursor.currentNode.startPosition;\n\t\t\tconst endPosition = cursor.currentNode.endPosition;\n\t\t\tconst startIndex = cursor.currentNode.startIndex;\n\t\t\tconst endIndex = cursor.currentNode.endIndex;\n\n\t\t\tconst newChange = { newRange: new Range(startPosition.row + 1, startPosition.column + 1, endPosition.row + 1, endPosition.column + 1), newRangeStartOffset: startIndex, newRangeEndOffset: endIndex };\n\t\t\tif ((newRangeIndex < newRanges.length) && rangesIntersect(newRanges[newRangeIndex], { startIndex, endIndex, startPosition, endPosition })) {\n\t\t\t\t// combine the new change with the range\n\t\t\t\tif (newRanges[newRangeIndex].startIndex < newChange.newRangeStartOffset) {\n\t\t\t\t\tnewChange.newRange = newChange.newRange.setStartPosition(newRanges[newRangeIndex].startPosition.row + 1, newRanges[newRangeIndex].startPosition.column + 1);\n\t\t\t\t\tnewChange.newRangeStartOffset = newRanges[newRangeIndex].startIndex;\n\t\t\t\t}\n\t\t\t\tif (newRanges[newRangeIndex].endIndex > newChange.newRangeEndOffset) {\n\t\t\t\t\tnewChange.newRange = newChange.newRange.setEndPosition(newRanges[newRangeIndex].endPosition.row + 1, newRanges[newRangeIndex].endPosition.column + 1);\n\t\t\t\t\tnewChange.newRangeEndOffset = newRanges[newRangeIndex].endIndex;\n\t\t\t\t}\n\t\t\t\tnewRangeIndex++;\n\t\t\t} else if (newRangeIndex < newRanges.length && newRanges[newRangeIndex].endIndex < newChange.newRangeStartOffset) {\n\t\t\t\t// add the full range to the merged changes\n\t\t\t\tmergedChanges.push({\n\t\t\t\t\tnewRange: new Range(newRanges[newRangeIndex].startPosition.row + 1, newRanges[newRangeIndex].startPosition.column + 1, newRanges[newRangeIndex].endPosition.row + 1, newRanges[newRangeIndex].endPosition.column + 1),\n\t\t\t\t\tnewRangeStartOffset: newRanges[newRangeIndex].startIndex,\n\t\t\t\t\tnewRangeEndOffset: newRanges[newRangeIndex].endIndex\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tif ((mergedChanges.length > 0) && (mergedChanges[mergedChanges.length - 1].newRangeEndOffset >= newChange.newRangeStartOffset)) {\n\t\t\t\t// Merge the changes\n\t\t\t\tmergedChanges[mergedChanges.length - 1].newRange = Range.fromPositions(mergedChanges[mergedChanges.length - 1].newRange.getStartPosition(), newChange.newRange.getEndPosition());\n\t\t\t\tmergedChanges[mergedChanges.length - 1].newRangeEndOffset = newChange.newRangeEndOffset;\n\t\t\t} else {\n\t\t\t\tmergedChanges.push(newChange);\n\t\t\t}\n\t\t}\n\t\treturn this._constrainRanges(mergedChanges);\n\t}\n\n\tprivate _constrainRanges(changes: RangeChange[]): RangeChange[] {\n\t\tif (!this._ranges) {\n\t\t\treturn changes;\n\t\t}\n\n\t\tconst constrainedChanges: RangeChange[] = [];\n\t\tlet changesIndex = 0;\n\t\tlet rangesIndex = 0;\n\t\twhile (changesIndex < changes.length && rangesIndex < this._ranges.length) {\n\t\t\tconst change = changes[changesIndex];\n\t\t\tconst range = this._ranges[rangesIndex];\n\t\t\tif (change.newRangeEndOffset < range.startIndex) {\n\t\t\t\t// Change is before the range, move to the next change\n\t\t\t\tchangesIndex++;\n\t\t\t} else if (change.newRangeStartOffset > range.endIndex) {\n\t\t\t\t// Change is after the range, move to the next range\n\t\t\t\trangesIndex++;\n\t\t\t} else {\n\t\t\t\t// Change is within the range, constrain it\n\t\t\t\tconst newRangeStartOffset = Math.max(change.newRangeStartOffset, range.startIndex);\n\t\t\t\tconst newRangeEndOffset = Math.min(change.newRangeEndOffset, range.endIndex);\n\t\t\t\tconst newRange = change.newRange.intersectRanges(new Range(range.startPosition.row + 1, range.startPosition.column + 1, range.endPosition.row + 1, range.endPosition.column + 1))!;\n\t\t\t\tconstrainedChanges.push({\n\t\t\t\t\tnewRange,\n\t\t\t\t\tnewRangeEndOffset,\n\t\t\t\t\tnewRangeStartOffset\n\t\t\t\t});\n\t\t\t\t// Remove the intersected range from the current change\n\t\t\t\tif (newRangeEndOffset < change.newRangeEndOffset) {\n\t\t\t\t\tchange.newRange = Range.fromPositions(newRange.getEndPosition(), change.newRange.getEndPosition());\n\t\t\t\t\tchange.newRangeStartOffset = newRangeEndOffset + 1;\n\t\t\t\t} else {\n\t\t\t\t\t// Move to the next change\n\t\t\t\t\tchangesIndex++;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn constrainedChanges;\n\t}\n\n\tprivate async _parseAndUpdateTree(version: number): Promise<TreeSitter.Tree | undefined> {\n\t\tconst tree = await this._parse();\n\t\tif (tree) {\n\t\t\tthis._lastFullyParsed?.delete();\n\t\t\tthis._lastFullyParsed = tree.copy();\n\t\t\tthis._lastFullyParsedWithEdits?.delete();\n\t\t\tthis._lastFullyParsedWithEdits = tree.copy();\n\n\t\t\treturn tree;\n\t\t} else if (!this._tree.get()) {\n\t\t\t// No tree means this is the initial parse and there were edits\n\t\t\t// parse function doesn't handle this well and we can end up with an incorrect tree, so we reset\n\t\t\tthis._parser.reset();\n\t\t}\n\t\treturn undefined;\n\t}\n\n\tprivate _parse(): Promise<TreeSitter.Tree | undefined> {\n\t\tlet parseType: TelemetryParseType = TelemetryParseType.Full;\n\t\tif (this._tree.get()) {\n\t\t\tparseType = TelemetryParseType.Incremental;\n\t\t}\n\t\treturn this._parseAndYield(parseType);\n\t}\n\n\tprivate async _parseAndYield(parseType: TelemetryParseType): Promise<TreeSitter.Tree | undefined> {\n\t\tlet time: number = 0;\n\t\tlet passes: number = 0;\n\t\tconst inProgressVersion = this.textModel.getVersionId();\n\t\tlet newTree: TreeSitter.Tree | null | undefined;\n\n\t\tconst progressCallback = newTimeOutProgressCallback();\n\n\t\tdo {\n\t\t\tconst timer = performance.now();\n\n\t\t\tnewTree = this._parser.parse((index: number, position?: TreeSitter.Point) => this._parseCallback(index), this._tree.get(), { progressCallback, includedRanges: this._ranges });\n\n\t\t\ttime += performance.now() - timer;\n\t\t\tpasses++;\n\n\t\t\t// So long as this isn't the initial parse, even if the model changes and edits are applied, the tree parsing will continue correctly after the await.\n\t\t\tawait new Promise<void>(resolve => setTimeout0(resolve));\n\n\t\t} while (!this._store.isDisposed && !newTree && inProgressVersion === this.textModel.getVersionId());\n\t\tthis._sendParseTimeTelemetry(parseType, time, passes);\n\t\treturn (newTree && (inProgressVersion === this.textModel.getVersionId())) ? newTree : undefined;\n\t}\n\n\tprivate _parseCallback(index: number): string | undefined {\n\t\ttry {\n\t\t\treturn this.textModel.getTextBuffer().getNearestChunk(index);\n\t\t} catch (e) {\n\t\t\tthis._logService.debug('Error getting chunk for tree-sitter parsing', e);\n\t\t}\n\t\treturn undefined;\n\t}\n\n\tprivate _setRanges(newRanges: TreeSitter.Range[]): TreeSitter.Range[] {\n\t\tconst unKnownRanges: TreeSitter.Range[] = [];\n\t\t// If we have existing ranges, find the parts of the new ranges that are not included in the existing ones\n\t\tif (this._ranges) {\n\t\t\tfor (const newRange of newRanges) {\n\t\t\t\tlet isFullyIncluded = false;\n\n\t\t\t\tfor (let i = 0; i < this._ranges.length; i++) {\n\t\t\t\t\tconst existingRange = this._ranges[i];\n\n\t\t\t\t\tif (rangesEqual(existingRange, newRange) || rangesIntersect(existingRange, newRange)) {\n\t\t\t\t\t\tisFullyIncluded = true;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (!isFullyIncluded) {\n\t\t\t\t\tunKnownRanges.push(newRange);\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\t// No existing ranges, all new ranges are unknown\n\t\t\tunKnownRanges.push(...newRanges);\n\t\t}\n\n\t\tthis._ranges = newRanges;\n\t\treturn unKnownRanges;\n\t}\n\n\tprivate _sendParseTimeTelemetry(parseType: TelemetryParseType, time: number, passes: number): void {\n\t\tthis._logService.debug(`Tree parsing (${parseType}) took ${time} ms and ${passes} passes.`);\n\t\ttype ParseTimeClassification = {\n\t\t\towner: 'alexr00';\n\t\t\tcomment: 'Used to understand how long it takes to parse a tree-sitter tree';\n\t\t\tlanguageId: { classification: 'SystemMetaData'; purpose: 'FeatureInsight'; comment: 'The programming language ID.' };\n\t\t\ttime: { classification: 'SystemMetaData'; purpose: 'FeatureInsight'; isMeasurement: true; comment: 'The ms it took to parse' };\n\t\t\tpasses: { classification: 'SystemMetaData'; purpose: 'FeatureInsight'; isMeasurement: true; comment: 'The number of passes it took to parse' };\n\t\t};\n\t\tif (parseType === TelemetryParseType.Full) {\n\t\t\tthis._telemetryService.publicLog2<{ languageId: string; time: number; passes: number }, ParseTimeClassification>(`treeSitter.fullParse`, { languageId: this.languageId, time, passes });\n\t\t} else {\n\t\t\tthis._telemetryService.publicLog2<{ languageId: string; time: number; passes: number }, ParseTimeClassification>(`treeSitter.incrementalParse`, { languageId: this.languageId, time, passes });\n\t\t}\n\t}\n\n\tpublic createParsedTreeSync(src: string): TreeSitter.Tree | undefined {\n\t\tconst parser = new this._parserClass();\n\t\tparser.setLanguage(this._parser.language!);\n\t\tconst tree = parser.parse(src);\n\t\tparser.delete();\n\t\treturn tree ?? undefined;\n\t}\n}\n\nconst enum TelemetryParseType {\n\tFull = 'fullParse',\n\tIncremental = 'incrementalParse'\n}\n\nexport interface TreeParseUpdateEvent {\n\tranges: RangeChange[];\n\tversionId: number;\n}\n\nexport interface RangeWithOffsets {\n\trange: Range;\n\tstartOffset: number;\n\tendOffset: number;\n}\n\nexport interface RangeChange {\n\tnewRange: Range;\n\tnewRangeStartOffset: number;\n\tnewRangeEndOffset: number;\n}\n\nfunction newTimeOutProgressCallback(): (state: TreeSitter.ParseState) => void {\n\tlet lastYieldTime: number = performance.now();\n\treturn function parseProgressCallback(_state: TreeSitter.ParseState) {\n\t\tconst now = performance.now();\n\t\tif (now - lastYieldTime > 50) {\n\t\t\tlastYieldTime = now;\n\t\t\treturn true;\n\t\t}\n\t\treturn false;\n\t};\n}\nexport function rangesEqual(a: TreeSitter.Range, b: TreeSitter.Range) {\n\treturn (a.startPosition.row === b.startPosition.row)\n\t\t&& (a.startPosition.column === b.startPosition.column)\n\t\t&& (a.endPosition.row === b.endPosition.row)\n\t\t&& (a.endPosition.column === b.endPosition.column)\n\t\t&& (a.startIndex === b.startIndex)\n\t\t&& (a.endIndex === b.endIndex);\n}\n\nexport function rangesIntersect(a: TreeSitter.Range, b: TreeSitter.Range) {\n\treturn (a.startIndex <= b.startIndex && a.endIndex >= b.startIndex) ||\n\t\t(b.startIndex <= a.startIndex && b.endIndex >= a.startIndex);\n}\n","/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\nimport type * as TreeSitter from '@vscode/tree-sitter-wasm';\nimport { TaskQueue } from '../../../../../base/common/async.js';\nimport { Disposable, toDisposable } from '../../../../../base/common/lifecycle.js';\nimport { IObservable, observableValue, transaction, IObservableWithChange } from '../../../../../base/common/observable.js';\nimport { setTimeout0 } from '../../../../../base/common/platform.js';\nimport { ILogService } from '../../../../../platform/log/common/log.js';\nimport { ITelemetryService } from '../../../../../platform/telemetry/common/telemetry.js';\nimport { TextLength } from '../../../core/text/textLength.js';\nimport { IModelContentChangedEvent } from '../../../textModelEvents.js';\nimport { IModelContentChange } from '../../mirrorTextModel.js';\nimport { TextModel } from '../../textModel.js';\nimport { gotoParent, getClosestPreviousNodes, nextSiblingOrParentSibling, gotoNthChild } from './cursorUtils.js';\nimport { Range } from '../../../core/range.js';\n\nexport class TreeSitterTree extends Disposable {\n\n\tprivate readonly _tree = observableValue<TreeSitter.Tree | undefined, TreeParseUpdateEvent>(this, undefined);\n\tpublic readonly tree: IObservableWithChange<TreeSitter.Tree | undefined, TreeParseUpdateEvent> = this._tree;\n\n\tprivate readonly _treeLastParsedVersion = observableValue(this, -1);\n\tpublic readonly treeLastParsedVersion: IObservable<number> = this._treeLastParsedVersion;\n\n\tprivate _lastFullyParsed: TreeSitter.Tree | undefined;\n\tprivate _lastFullyParsedWithEdits: TreeSitter.Tree | undefined;\n\n\tprivate _onDidChangeContentQueue: TaskQueue = new TaskQueue();\n\n\tconstructor(\n\t\tpublic readonly languageId: string,\n\t\tprivate _ranges: TreeSitter.Range[] | undefined,\n\t\t// readonly treeSitterLanguage: Language,\n\t\t/** Must have the language set! */\n\t\tprivate readonly _parser: TreeSitter.Parser,\n\t\tprivate readonly _parserClass: typeof TreeSitter.Parser,\n\t\t// private readonly _injectionQuery: TreeSitter.Query,\n\t\tpublic readonly textModel: TextModel,\n\t\t@ILogService private readonly _logService: ILogService,\n\t\t@ITelemetryService private readonly _telemetryService: ITelemetryService\n\t) {\n\t\tsuper();\n\n\t\tthis._tree = observableValue(this, undefined);\n\t\tthis.tree = this._tree;\n\n\t\tthis._register(toDisposable(() => {\n\t\t\tthis._tree.get()?.delete();\n\t\t\tthis._lastFullyParsed?.delete();\n\t\t\tthis._lastFullyParsedWithEdits?.delete();\n\t\t\tthis._parser.delete();\n\t\t}));\n\t\tthis.handleContentChange(undefined, this._ranges);\n\t}\n\n\tpublic handleContentChange(e: IModelContentChangedEvent | undefined, ranges?: TreeSitter.Range[]): void {\n\t\tconst version = this.textModel.getVersionId();\n\t\tlet newRanges: TreeSitter.Range[] = [];\n\t\tif (ranges) {\n\t\t\tnewRanges = this._setRanges(ranges);\n\t\t}\n\t\tif (e) {\n\t\t\tthis._applyEdits(e.changes);\n\t\t}\n\n\t\tthis._onDidChangeContentQueue.clearPending();\n\t\tthis._onDidChangeContentQueue.schedule(async () => {\n\t\t\tif (this._store.isDisposed) {\n\t\t\t\t// No need to continue the queue if we are disposed\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst oldTree = this._lastFullyParsed;\n\t\t\tlet changedNodes: TreeSitter.Range[] | undefined;\n\t\t\tif (this._lastFullyParsedWithEdits && this._lastFullyParsed) {\n\t\t\t\tchangedNodes = this._findChangedNodes(this._lastFullyParsedWithEdits, this._lastFullyParsed);\n\t\t\t}\n\n\t\t\tconst completed = await this._parseAndUpdateTree(version);\n\t\t\tif (completed) {\n\t\t\t\tlet ranges: RangeChange[] | undefined;\n\t\t\t\tif (!changedNodes) {\n\t\t\t\t\tif (this._ranges) {\n\t\t\t\t\t\tranges = this._ranges.map(r => ({ newRange: new Range(r.startPosition.row + 1, r.startPosition.column + 1, r.endPosition.row + 1, r.endPosition.column + 1), oldRangeLength: r.endIndex - r.startIndex, newRangeStartOffset: r.startIndex, newRangeEndOffset: r.endIndex }));\n\t\t\t\t\t}\n\t\t\t\t} else if (oldTree && changedNodes) {\n\t\t\t\t\tranges = this._findTreeChanges(completed, changedNodes, newRanges);\n\t\t\t\t}\n\t\t\t\tif (!ranges) {\n\t\t\t\t\tranges = [{ newRange: this.textModel.getFullModelRange(), newRangeStartOffset: 0, newRangeEndOffset: this.textModel.getValueLength() }];\n\t\t\t\t}\n\n\t\t\t\tconst previousTree = this._tree.get();\n\t\t\t\ttransaction(tx => {\n\t\t\t\t\tthis._tree.set(completed, tx, { ranges, versionId: version });\n\t\t\t\t\tthis._treeLastParsedVersion.set(version, tx);\n\t\t\t\t});\n\t\t\t\tpreviousTree?.delete();\n\t\t\t}\n\t\t});\n\t}\n\n\tprivate _applyEdits(changes: IModelContentChange[]) {\n\t\tfor (const change of changes) {\n\t\t\tconst originalTextLength = TextLength.ofRange(Range.lift(change.range));\n\t\t\tconst newTextLength = TextLength.ofText(change.text);\n\t\t\tconst summedTextLengths = change.text.length === 0 ? newTextLength : originalTextLength.add(newTextLength);\n\t\t\tconst edit = {\n\t\t\t\tstartIndex: change.rangeOffset,\n\t\t\t\toldEndIndex: change.rangeOffset + change.rangeLength,\n\t\t\t\tnewEndIndex: change.rangeOffset + change.text.length,\n\t\t\t\tstartPosition: { row: change.range.startLineNumber - 1, column: change.range.startColumn - 1 },\n\t\t\t\toldEndPosition: { row: change.range.endLineNumber - 1, column: change.range.endColumn - 1 },\n\t\t\t\tnewEndPosition: { row: change.range.startLineNumber + summedTextLengths.lineCount - 1, column: summedTextLengths.lineCount ? summedTextLengths.columnCount : (change.range.endColumn + summedTextLengths.columnCount) }\n\t\t\t};\n\t\t\tthis._tree.get()?.edit(edit);\n\t\t\tthis._lastFullyParsedWithEdits?.edit(edit);\n\t\t}\n\t}\n\n\tprivate _findChangedNodes(newTree: TreeSitter.Tree, oldTree: TreeSitter.Tree): TreeSitter.Range[] | undefined {\n\t\tif ((this._ranges && this._ranges.every(range => range.startPosition.row !== newTree.rootNode.startPosition.row)) || newTree.rootNode.startPosition.row !== 0) {\n\t\t\treturn [];\n\t\t}\n\t\tconst newCursor = newTree.walk();\n\t\tconst oldCursor = oldTree.walk();\n\n\t\tconst nodes: TreeSitter.Range[] = [];\n\t\tlet next = true;\n\n\t\tdo {\n\t\t\tif (newCursor.currentNode.hasChanges) {\n\t\t\t\t// Check if only one of the children has changes.\n\t\t\t\t// If it's only one, then we go to that child.\n\t\t\t\t// If it's more then, we need to go to each child\n\t\t\t\t// If it's none, then we've found one of our ranges\n\t\t\t\tconst newChildren = newCursor.currentNode.children;\n\t\t\t\tconst indexChangedChildren: number[] = [];\n\t\t\t\tconst changedChildren = newChildren.filter((c, index) => {\n\t\t\t\t\tif (c?.hasChanges || (oldCursor.currentNode.children.length <= index)) {\n\t\t\t\t\t\tindexChangedChildren.push(index);\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t\treturn false;\n\t\t\t\t});\n\t\t\t\t// If we have changes and we *had* an error, the whole node should be refreshed.\n\t\t\t\tif ((changedChildren.length === 0) || (newCursor.currentNode.hasError !== oldCursor.currentNode.hasError)) {\n\t\t\t\t\t// walk up again until we get to the first one that's named as unnamed nodes can be too granular\n\t\t\t\t\twhile (newCursor.currentNode.parent && next && !newCursor.currentNode.isNamed) {\n\t\t\t\t\t\tnext = gotoParent(newCursor, oldCursor);\n\t\t\t\t\t}\n\t\t\t\t\t// Use the end position of the previous node and the start position of the current node\n\t\t\t\t\tconst newNode = newCursor.currentNode;\n\t\t\t\t\tconst closestPreviousNode = getClosestPreviousNodes(newCursor, newTree) ?? newNode;\n\t\t\t\t\tnodes.push({\n\t\t\t\t\t\tstartIndex: closestPreviousNode.startIndex,\n\t\t\t\t\t\tendIndex: newNode.endIndex,\n\t\t\t\t\t\tstartPosition: closestPreviousNode.startPosition,\n\t\t\t\t\t\tendPosition: newNode.endPosition\n\t\t\t\t\t});\n\t\t\t\t\tnext = nextSiblingOrParentSibling(newCursor, oldCursor);\n\t\t\t\t} else if (changedChildren.length >= 1) {\n\t\t\t\t\tnext = gotoNthChild(newCursor, oldCursor, indexChangedChildren[0]);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tnext = nextSiblingOrParentSibling(newCursor, oldCursor);\n\t\t\t}\n\t\t} while (next);\n\n\t\tnewCursor.delete();\n\t\toldCursor.delete();\n\t\treturn nodes;\n\t}\n\n\tprivate _findTreeChanges(newTree: TreeSitter.Tree, changedNodes: TreeSitter.Range[], newRanges: TreeSitter.Range[]): RangeChange[] {\n\t\tlet newRangeIndex = 0;\n\t\tconst mergedChanges: RangeChange[] = [];\n\n\t\t// Find the parent in the new tree of the changed node\n\t\tfor (let nodeIndex = 0; nodeIndex < changedNodes.length; nodeIndex++) {\n\t\t\tconst node = changedNodes[nodeIndex];\n\n\t\t\tif (mergedChanges.length > 0) {\n\t\t\t\tif ((node.startIndex >= mergedChanges[mergedChanges.length - 1].newRangeStartOffset) && (node.endIndex <= mergedChanges[mergedChanges.length - 1].newRangeEndOffset)) {\n\t\t\t\t\t// This node is within the previous range, skip it\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst cursor = newTree.walk();\n\t\t\tconst cursorContainersNode = () => cursor.startIndex < node.startIndex && cursor.endIndex > node.endIndex;\n\n\t\t\twhile (cursorContainersNode()) {\n\t\t\t\t// See if we can go to a child\n\t\t\t\tlet child = cursor.gotoFirstChild();\n\t\t\t\tlet foundChild = false;\n\t\t\t\twhile (child) {\n\t\t\t\t\tif (cursorContainersNode() && cursor.currentNode.isNamed) {\n\t\t\t\t\t\tfoundChild = true;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tchild = cursor.gotoNextSibling();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (!foundChild) {\n\t\t\t\t\tcursor.gotoParent();\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tif (cursor.currentNode.childCount === 0) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst startPosition = cursor.currentNode.startPosition;\n\t\t\tconst endPosition = cursor.currentNode.endPosition;\n\t\t\tconst startIndex = cursor.currentNode.startIndex;\n\t\t\tconst endIndex = cursor.currentNode.endIndex;\n\n\t\t\tconst newChange = { newRange: new Range(startPosition.row + 1, startPosition.column + 1, endPosition.row + 1, endPosition.column + 1), newRangeStartOffset: startIndex, newRangeEndOffset: endIndex };\n\t\t\tif ((newRangeIndex < newRanges.length) && rangesIntersect(newRanges[newRangeIndex], { startIndex, endIndex, startPosition, endPosition })) {\n\t\t\t\t// combine the new change with the range\n\t\t\t\tif (newRanges[newRangeIndex].startIndex < newChange.newRangeStartOffset) {\n\t\t\t\t\tnewChange.newRange = newChange.newRange.setStartPosition(newRanges[newRangeIndex].startPosition.row + 1, newRanges[newRangeIndex].startPosition.column + 1);\n\t\t\t\t\tnewChange.newRangeStartOffset = newRanges[newRangeIndex].startIndex;\n\t\t\t\t}\n\t\t\t\tif (newRanges[newRangeIndex].endIndex > newChange.newRangeEndOffset) {\n\t\t\t\t\tnewChange.newRange = newChange.newRange.setEndPosition(newRanges[newRangeIndex].endPosition.row + 1, newRanges[newRangeIndex].endPosition.column + 1);\n\t\t\t\t\tnewChange.newRangeEndOffset = newRanges[newRangeIndex].endIndex;\n\t\t\t\t}\n\t\t\t\tnewRangeIndex++;\n\t\t\t} else if (newRangeIndex < newRanges.length && newRanges[newRangeIndex].endIndex < newChange.newRangeStartOffset) {\n\t\t\t\t// add the full range to the merged changes\n\t\t\t\tmergedChanges.push({\n\t\t\t\t\tnewRange: new Range(newRanges[newRangeIndex].startPosition.row + 1, newRanges[newRangeIndex].startPosition.column + 1, newRanges[newRangeIndex].endPosition.row + 1, newRanges[newRangeIndex].endPosition.column + 1),\n\t\t\t\t\tnewRangeStartOffset: newRanges[newRangeIndex].startIndex,\n\t\t\t\t\tnewRangeEndOffset: newRanges[newRangeIndex].endIndex\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tif ((mergedChanges.length > 0) && (mergedChanges[mergedChanges.length - 1].newRangeEndOffset >= newChange.newRangeStartOffset)) {\n\t\t\t\t// Merge the changes\n\t\t\t\tmergedChanges[mergedChanges.length - 1].newRange = Range.fromPositions(mergedChanges[mergedChanges.length - 1].newRange.getStartPosition(), newChange.newRange.getEndPosition());\n\t\t\t\tmergedChanges[mergedChanges.length - 1].newRangeEndOffset = newChange.newRangeEndOffset;\n\t\t\t} else {\n\t\t\t\tmergedChanges.push(newChange);\n\t\t\t}\n\t\t}\n\t\treturn this._constrainRanges(mergedChanges);\n\t}\n\n\tprivate _constrainRanges(changes: RangeChange[]): RangeChange[] {\n\t\tif (!this._ranges) {\n\t\t\treturn changes;\n\t\t}\n\n\t\tconst constrainedChanges: RangeChange[] = [];\n\t\tlet changesIndex = 0;\n\t\tlet rangesIndex = 0;\n\t\twhile (changesIndex < changes.length && rangesIndex < this._ranges.length) {\n\t\t\tconst change = changes[changesIndex];\n\t\t\tconst range = this._ranges[rangesIndex];\n\t\t\tif (change.newRangeEndOffset < range.startIndex) {\n\t\t\t\t// Change is before the range, move to the next change\n\t\t\t\tchangesIndex++;\n\t\t\t} else if (change.newRangeStartOffset > range.endIndex) {\n\t\t\t\t// Change is after the range, move to the next range\n\t\t\t\trangesIndex++;\n\t\t\t} else {\n\t\t\t\t// Change is within the range, constrain it\n\t\t\t\tconst newRangeStartOffset = Math.max(change.newRangeStartOffset, range.startIndex);\n\t\t\t\tconst newRangeEndOffset = Math.min(change.newRangeEndOffset, range.endIndex);\n\t\t\t\tconst newRange = change.newRange.intersectRanges(new Range(range.startPosition.row + 1, range.startPosition.column + 1, range.endPosition.row + 1, range.endPosition.column + 1))!;\n\t\t\t\tconstrainedChanges.push({\n\t\t\t\t\tnewRange,\n\t\t\t\t\tnewRangeEndOffset,\n\t\t\t\t\tnewRangeStartOffset\n\t\t\t\t});\n\t\t\t\t// Remove the intersected range from the current change\n\t\t\t\tif (newRangeEndOffset < change.newRangeEndOffset) {\n\t\t\t\t\tchange.newRange = Range.fromPositions(newRange.getEndPosition(), change.newRange.getEndPosition());\n\t\t\t\t\tchange.newRangeStartOffset = newRangeEndOffset + 1;\n\t\t\t\t} else {\n\t\t\t\t\t// Move to the next change\n\t\t\t\t\tchangesIndex++;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn constrainedChanges;\n\t}\n\n\tprivate async _parseAndUpdateTree(version: number): Promise<TreeSitter.Tree | undefined> {\n\t\tconst tree = await this._parse();\n\t\tif (tree) {\n\t\t\tthis._lastFullyParsed?.delete();\n\t\t\tthis._lastFullyParsed = tree.copy();\n\t\t\tthis._lastFullyParsedWithEdits?.delete();\n\t\t\tthis._lastFullyParsedWithEdits = tree.copy();\n\n\t\t\treturn tree;\n\t\t} else if (!this._tree.get()) {\n\t\t\t// No tree means this is the initial parse and there were edits\n\t\t\t// parse function doesn't handle this well and we can end up with an incorrect tree, so we reset\n\t\t\tthis._parser.reset();\n\t\t}\n\t\treturn undefined;\n\t}\n\n\tprivate _parse(): Promise<TreeSitter.Tree | undefined> {\n\t\tlet parseType: TelemetryParseType = TelemetryParseType.Full;\n\t\tif (this._tree.get()) {\n\t\t\tparseType = TelemetryParseType.Incremental;\n\t\t}\n\t\treturn this._parseAndYield(parseType);\n\t}\n\n\tprivate async _parseAndYield(parseType: TelemetryParseType): Promise<TreeSitter.Tree | undefined> {\n\t\tlet time: number = 0;\n\t\tlet passes: number = 0;\n\t\tconst inProgressVersion = this.textModel.getVersionId();\n\t\tlet newTree: TreeSitter.Tree | null | undefined;\n\n\t\tconst progressCallback = newTimeOutProgressCallback();\n\n\t\tdo {\n\t\t\tconst timer = performance.now();\n\n\t\t\tnewTree = this._parser.parse((index: number, position?: TreeSitter.Point) => this._parseCallback(index), this._tree.get(), { progressCallback, includedRanges: this._ranges });\n\n\t\t\ttime += performance.now() - timer;\n\t\t\tpasses++;\n\n\t\t\t// So long as this isn't the initial parse, even if the model changes and edits are applied, the tree parsing will continue correctly after the await.\n\t\t\tawait new Promise<void>(resolve => setTimeout0(resolve));\n\n\t\t} while (!this._store.isDisposed && !newTree && inProgressVersion === this.textModel.getVersionId());\n\t\tthis._sendParseTimeTelemetry(parseType, time, passes);\n\t\treturn (newTree && (inProgressVersion === this.textModel.getVersionId())) ? newTree : undefined;\n\t}\n\n\tprivate _parseCallback(index: number): string | undefined {\n\t\ttry {\n\t\t\treturn this.textModel.getTextBuffer().getNearestChunk(index);\n\t\t} catch (e) {\n\t\t\tthis._logService.debug('Error getting chunk for tree-sitter parsing', e);\n\t\t}\n\t\treturn undefined;\n\t}\n\n\tprivate _setRanges(newRanges: TreeSitter.Range[]): TreeSitter.Range[] {\n\t\tconst unKnownRanges: TreeSitter.Range[] = [];\n\t\t// If we have existing ranges, find the parts of the new ranges that are not included in the existing ones\n\t\tif (this._ranges) {\n\t\t\tfor (const newRange of newRanges) {\n\t\t\t\tlet isFullyIncluded = false;\n\n\t\t\t\tfor (let i = 0; i < this._ranges.length; i++) {\n\t\t\t\t\tconst existingRange = this._ranges[i];\n\n\t\t\t\t\tif (rangesEqual(existingRange, newRange) || rangesIntersect(existingRange, newRange)) {\n\t\t\t\t\t\tisFullyIncluded = true;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (!isFullyIncluded) {\n\t\t\t\t\tunKnownRanges.push(newRange);\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\t// No existing ranges, all new ranges are unknown\n\t\t\tunKnownRanges.push(...newRanges);\n\t\t}\n\n\t\tthis._ranges = newRanges;\n\t\treturn unKnownRanges;\n\t}\n\n\tprivate _sendParseTimeTelemetry(parseType: TelemetryParseType, time: number, passes: number): void {\n\t\tthis._logService.debug(`Tree parsing (${parseType}) took ${time} ms and ${passes} passes.`);\n\t\ttype ParseTimeClassification = {\n\t\t\towner: 'alexr00';\n\t\t\tcomment: 'Used to understand how long it takes to parse a tree-sitter tree';\n\t\t\tlanguageId: { classification: 'SystemMetaData'; purpose: 'FeatureInsight'; comment: 'The programming language ID.' };\n\t\t\ttime: { classification: 'SystemMetaData'; purpose: 'FeatureInsight'; isMeasurement: true; comment: 'The ms it took to parse' };\n\t\t\tpasses: { classification: 'SystemMetaData'; purpose: 'FeatureInsight'; isMeasurement: true; comment: 'The number of passes it took to parse' };\n\t\t};\n\t\tif (parseType === TelemetryParseType.Full) {\n\t\t\tthis._telemetryService.publicLog2<{ languageId: string; time: number; passes: number }, ParseTimeClassification>(`treeSitter.fullParse`, { languageId: this.languageId, time, passes });\n\t\t} else {\n\t\t\tthis._telemetryService.publicLog2<{ languageId: string; time: number; passes: number }, ParseTimeClassification>(`treeSitter.incrementalParse`, { languageId: this.languageId, time, passes });\n\t\t}\n\t}\n\n\tpublic createParsedTreeSync(src: string): TreeSitter.Tree | undefined {\n\t\tconst parser = new this._parserClass();\n\t\tparser.setLanguage(this._parser.language!);\n\t\tconst tree = parser.parse(src);\n\t\tparser.delete();\n\t\treturn tree ?? undefined;\n\t}\n}\n\nconst enum TelemetryParseType {\n\tFull = 'fullParse',\n\tIncremental = 'incrementalParse'\n}\n\nexport interface TreeParseUpdateEvent {\n\tranges: RangeChange[];\n\tversionId: number;\n}\n\nexport interface RangeWithOffsets {\n\trange: Range;\n\tstartOffset: number;\n\tendOffset: number;\n}\n\nexport interface RangeChange {\n\tnewRange: Range;\n\tnewRangeStartOffset: number;\n\tnewRangeEndOffset: number;\n}\n\nfunction newTimeOutProgressCallback(): (state: TreeSitter.ParseState) => void {\n\tlet lastYieldTime: number = performance.now();\n\treturn function parseProgressCallback(_state: TreeSitter.ParseState) {\n\t\tconst now = performance.now();\n\t\tif (now - lastYieldTime > 50) {\n\t\t\tlastYieldTime = now;\n\t\t\treturn true;\n\t\t}\n\t\treturn false;\n\t};\n}\nexport function rangesEqual(a: TreeSitter.Range, b: TreeSitter.Range) {\n\treturn (a.startPosition.row === b.startPosition.row)\n\t\t&& (a.startPosition.column === b.startPosition.column)\n\t\t&& (a.endPosition.row === b.endPosition.row)\n\t\t&& (a.endPosition.column === b.endPosition.column)\n\t\t&& (a.startIndex === b.startIndex)\n\t\t&& (a.endIndex === b.endIndex);\n}\n\nexport function rangesIntersect(a: TreeSitter.Range, b: TreeSitter.Range) {\n\treturn (a.startIndex <= b.startIndex && a.endIndex >= b.startIndex) ||\n\t\t(b.startIndex <= a.startIndex && b.endIndex >= a.startIndex);\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["file:///mnt/vss/_work/1/s/dependencies/vscode/out-editor-src/vs/editor/common/model/tokens/treeSitter/treeSitterTree.ts","vs/editor/common/model/tokens/treeSitter/treeSitterTree.ts"],"names":[],"mappings":"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","file":"treeSitterTree.js","sourceRoot":"file:///mnt/vss/_work/1/s/dependencies/vscode/out-editor-src","sourcesContent":["/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\nimport type * as TreeSitter from '@vscode/tree-sitter-wasm';\nimport { TaskQueue } from '../../../../../base/common/async.js';\nimport { Disposable, toDisposable } from '../../../../../base/common/lifecycle.js';\nimport { IObservable, observableValue, transaction, IObservableWithChange } from '../../../../../base/common/observable.js';\nimport { setTimeout0 } from '../../../../../base/common/platform.js';\nimport { ILogService } from '../../../../../platform/log/common/log.js';\nimport { ITelemetryService } from '../../../../../platform/telemetry/common/telemetry.js';\nimport { TextLength } from '../../../core/text/textLength.js';\nimport { IModelContentChangedEvent } from '../../../textModelEvents.js';\nimport { IModelContentChange } from '../../mirrorTextModel.js';\nimport { TextModel } from '../../textModel.js';\nimport { gotoParent, getClosestPreviousNodes, nextSiblingOrParentSibling, gotoNthChild } from './cursorUtils.js';\nimport { Range } from '../../../core/range.js';\n\nexport class TreeSitterTree extends Disposable {\n\n\tprivate readonly _tree = observableValue<TreeSitter.Tree | undefined, TreeParseUpdateEvent>(this, undefined);\n\tpublic readonly tree: IObservableWithChange<TreeSitter.Tree | undefined, TreeParseUpdateEvent> = this._tree;\n\n\tprivate readonly _treeLastParsedVersion = observableValue(this, -1);\n\tpublic readonly treeLastParsedVersion: IObservable<number> = this._treeLastParsedVersion;\n\n\tprivate _lastFullyParsed: TreeSitter.Tree | undefined;\n\tprivate _lastFullyParsedWithEdits: TreeSitter.Tree | undefined;\n\n\tprivate _onDidChangeContentQueue: TaskQueue = new TaskQueue();\n\n\tconstructor(\n\t\tpublic readonly languageId: string,\n\t\tprivate _ranges: TreeSitter.Range[] | undefined,\n\t\t// readonly treeSitterLanguage: Language,\n\t\t/** Must have the language set! */\n\t\tprivate readonly _parser: TreeSitter.Parser,\n\t\tprivate readonly _parserClass: typeof TreeSitter.Parser,\n\t\t// private readonly _injectionQuery: TreeSitter.Query,\n\t\tpublic readonly textModel: TextModel,\n\t\t@ILogService private readonly _logService: ILogService,\n\t\t@ITelemetryService private readonly _telemetryService: ITelemetryService\n\t) {\n\t\tsuper();\n\n\t\tthis._tree = observableValue(this, undefined);\n\t\tthis.tree = this._tree;\n\n\t\tthis._register(toDisposable(() => {\n\t\t\tthis._tree.get()?.delete();\n\t\t\tthis._lastFullyParsed?.delete();\n\t\t\tthis._lastFullyParsedWithEdits?.delete();\n\t\t\tthis._parser.delete();\n\t\t}));\n\t\tthis.handleContentChange(undefined, this._ranges);\n\t}\n\n\tpublic handleContentChange(e: IModelContentChangedEvent | undefined, ranges?: TreeSitter.Range[]): void {\n\t\tconst version = this.textModel.getVersionId();\n\t\tlet newRanges: TreeSitter.Range[] = [];\n\t\tif (ranges) {\n\t\t\tnewRanges = this._setRanges(ranges);\n\t\t}\n\t\tif (e) {\n\t\t\tthis._applyEdits(e.changes);\n\t\t}\n\n\t\tthis._onDidChangeContentQueue.clearPending();\n\t\tthis._onDidChangeContentQueue.schedule(async () => {\n\t\t\tif (this._store.isDisposed) {\n\t\t\t\t// No need to continue the queue if we are disposed\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst oldTree = this._lastFullyParsed;\n\t\t\tlet changedNodes: TreeSitter.Range[] | undefined;\n\t\t\tif (this._lastFullyParsedWithEdits && this._lastFullyParsed) {\n\t\t\t\tchangedNodes = this._findChangedNodes(this._lastFullyParsedWithEdits, this._lastFullyParsed);\n\t\t\t}\n\n\t\t\tconst completed = await this._parseAndUpdateTree(version);\n\t\t\tif (completed) {\n\t\t\t\tlet ranges: RangeChange[] | undefined;\n\t\t\t\tif (!changedNodes) {\n\t\t\t\t\tif (this._ranges) {\n\t\t\t\t\t\tranges = this._ranges.map(r => ({ newRange: new Range(r.startPosition.row + 1, r.startPosition.column + 1, r.endPosition.row + 1, r.endPosition.column + 1), oldRangeLength: r.endIndex - r.startIndex, newRangeStartOffset: r.startIndex, newRangeEndOffset: r.endIndex }));\n\t\t\t\t\t}\n\t\t\t\t} else if (oldTree && changedNodes) {\n\t\t\t\t\tranges = this._findTreeChanges(completed, changedNodes, newRanges);\n\t\t\t\t}\n\t\t\t\tif (!ranges) {\n\t\t\t\t\tranges = [{ newRange: this.textModel.getFullModelRange(), newRangeStartOffset: 0, newRangeEndOffset: this.textModel.getValueLength() }];\n\t\t\t\t}\n\n\t\t\t\tconst previousTree = this._tree.get();\n\t\t\t\ttransaction(tx => {\n\t\t\t\t\tthis._tree.set(completed, tx, { ranges, versionId: version });\n\t\t\t\t\tthis._treeLastParsedVersion.set(version, tx);\n\t\t\t\t});\n\t\t\t\tpreviousTree?.delete();\n\t\t\t}\n\t\t});\n\t}\n\n\tprivate _applyEdits(changes: IModelContentChange[]) {\n\t\tfor (const change of changes) {\n\t\t\tconst originalTextLength = TextLength.ofRange(Range.lift(change.range));\n\t\t\tconst newTextLength = TextLength.ofText(change.text);\n\t\t\tconst summedTextLengths = change.text.length === 0 ? newTextLength : originalTextLength.add(newTextLength);\n\t\t\tconst edit = {\n\t\t\t\tstartIndex: change.rangeOffset,\n\t\t\t\toldEndIndex: change.rangeOffset + change.rangeLength,\n\t\t\t\tnewEndIndex: change.rangeOffset + change.text.length,\n\t\t\t\tstartPosition: { row: change.range.startLineNumber - 1, column: change.range.startColumn - 1 },\n\t\t\t\toldEndPosition: { row: change.range.endLineNumber - 1, column: change.range.endColumn - 1 },\n\t\t\t\tnewEndPosition: { row: change.range.startLineNumber + summedTextLengths.lineCount - 1, column: summedTextLengths.lineCount ? summedTextLengths.columnCount : (change.range.endColumn + summedTextLengths.columnCount) }\n\t\t\t};\n\t\t\tthis._tree.get()?.edit(edit);\n\t\t\tthis._lastFullyParsedWithEdits?.edit(edit);\n\t\t}\n\t}\n\n\tprivate _findChangedNodes(newTree: TreeSitter.Tree, oldTree: TreeSitter.Tree): TreeSitter.Range[] | undefined {\n\t\tif ((this._ranges && this._ranges.every(range => range.startPosition.row !== newTree.rootNode.startPosition.row)) || newTree.rootNode.startPosition.row !== 0) {\n\t\t\treturn [];\n\t\t}\n\t\tconst newCursor = newTree.walk();\n\t\tconst oldCursor = oldTree.walk();\n\n\t\tconst nodes: TreeSitter.Range[] = [];\n\t\tlet next = true;\n\n\t\tdo {\n\t\t\tif (newCursor.currentNode.hasChanges) {\n\t\t\t\t// Check if only one of the children has changes.\n\t\t\t\t// If it's only one, then we go to that child.\n\t\t\t\t// If it's more then, we need to go to each child\n\t\t\t\t// If it's none, then we've found one of our ranges\n\t\t\t\tconst newChildren = newCursor.currentNode.children;\n\t\t\t\tconst indexChangedChildren: number[] = [];\n\t\t\t\tconst changedChildren = newChildren.filter((c, index) => {\n\t\t\t\t\tif (c?.hasChanges || (oldCursor.currentNode.children.length <= index)) {\n\t\t\t\t\t\tindexChangedChildren.push(index);\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t\treturn false;\n\t\t\t\t});\n\t\t\t\t// If we have changes and we *had* an error, the whole node should be refreshed.\n\t\t\t\tif ((changedChildren.length === 0) || (newCursor.currentNode.hasError !== oldCursor.currentNode.hasError)) {\n\t\t\t\t\t// walk up again until we get to the first one that's named as unnamed nodes can be too granular\n\t\t\t\t\twhile (newCursor.currentNode.parent && next && !newCursor.currentNode.isNamed) {\n\t\t\t\t\t\tnext = gotoParent(newCursor, oldCursor);\n\t\t\t\t\t}\n\t\t\t\t\t// Use the end position of the previous node and the start position of the current node\n\t\t\t\t\tconst newNode = newCursor.currentNode;\n\t\t\t\t\tconst closestPreviousNode = getClosestPreviousNodes(newCursor, newTree) ?? newNode;\n\t\t\t\t\tnodes.push({\n\t\t\t\t\t\tstartIndex: closestPreviousNode.startIndex,\n\t\t\t\t\t\tendIndex: newNode.endIndex,\n\t\t\t\t\t\tstartPosition: closestPreviousNode.startPosition,\n\t\t\t\t\t\tendPosition: newNode.endPosition\n\t\t\t\t\t});\n\t\t\t\t\tnext = nextSiblingOrParentSibling(newCursor, oldCursor);\n\t\t\t\t} else if (changedChildren.length >= 1) {\n\t\t\t\t\tnext = gotoNthChild(newCursor, oldCursor, indexChangedChildren[0]);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tnext = nextSiblingOrParentSibling(newCursor, oldCursor);\n\t\t\t}\n\t\t} while (next);\n\n\t\tnewCursor.delete();\n\t\toldCursor.delete();\n\t\treturn nodes;\n\t}\n\n\tprivate _findTreeChanges(newTree: TreeSitter.Tree, changedNodes: TreeSitter.Range[], newRanges: TreeSitter.Range[]): RangeChange[] {\n\t\tlet newRangeIndex = 0;\n\t\tconst mergedChanges: RangeChange[] = [];\n\n\t\t// Find the parent in the new tree of the changed node\n\t\tfor (let nodeIndex = 0; nodeIndex < changedNodes.length; nodeIndex++) {\n\t\t\tconst node = changedNodes[nodeIndex];\n\n\t\t\tif (mergedChanges.length > 0) {\n\t\t\t\tif ((node.startIndex >= mergedChanges[mergedChanges.length - 1].newRangeStartOffset) && (node.endIndex <= mergedChanges[mergedChanges.length - 1].newRangeEndOffset)) {\n\t\t\t\t\t// This node is within the previous range, skip it\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst cursor = newTree.walk();\n\t\t\tconst cursorContainersNode = () => cursor.startIndex < node.startIndex && cursor.endIndex > node.endIndex;\n\n\t\t\twhile (cursorContainersNode()) {\n\t\t\t\t// See if we can go to a child\n\t\t\t\tlet child = cursor.gotoFirstChild();\n\t\t\t\tlet foundChild = false;\n\t\t\t\twhile (child) {\n\t\t\t\t\tif (cursorContainersNode() && cursor.currentNode.isNamed) {\n\t\t\t\t\t\tfoundChild = true;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tchild = cursor.gotoNextSibling();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (!foundChild) {\n\t\t\t\t\tcursor.gotoParent();\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tif (cursor.currentNode.childCount === 0) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst startPosition = cursor.currentNode.startPosition;\n\t\t\tconst endPosition = cursor.currentNode.endPosition;\n\t\t\tconst startIndex = cursor.currentNode.startIndex;\n\t\t\tconst endIndex = cursor.currentNode.endIndex;\n\n\t\t\tconst newChange = { newRange: new Range(startPosition.row + 1, startPosition.column + 1, endPosition.row + 1, endPosition.column + 1), newRangeStartOffset: startIndex, newRangeEndOffset: endIndex };\n\t\t\tif ((newRangeIndex < newRanges.length) && rangesIntersect(newRanges[newRangeIndex], { startIndex, endIndex, startPosition, endPosition })) {\n\t\t\t\t// combine the new change with the range\n\t\t\t\tif (newRanges[newRangeIndex].startIndex < newChange.newRangeStartOffset) {\n\t\t\t\t\tnewChange.newRange = newChange.newRange.setStartPosition(newRanges[newRangeIndex].startPosition.row + 1, newRanges[newRangeIndex].startPosition.column + 1);\n\t\t\t\t\tnewChange.newRangeStartOffset = newRanges[newRangeIndex].startIndex;\n\t\t\t\t}\n\t\t\t\tif (newRanges[newRangeIndex].endIndex > newChange.newRangeEndOffset) {\n\t\t\t\t\tnewChange.newRange = newChange.newRange.setEndPosition(newRanges[newRangeIndex].endPosition.row + 1, newRanges[newRangeIndex].endPosition.column + 1);\n\t\t\t\t\tnewChange.newRangeEndOffset = newRanges[newRangeIndex].endIndex;\n\t\t\t\t}\n\t\t\t\tnewRangeIndex++;\n\t\t\t} else if (newRangeIndex < newRanges.length && newRanges[newRangeIndex].endIndex < newChange.newRangeStartOffset) {\n\t\t\t\t// add the full range to the merged changes\n\t\t\t\tmergedChanges.push({\n\t\t\t\t\tnewRange: new Range(newRanges[newRangeIndex].startPosition.row + 1, newRanges[newRangeIndex].startPosition.column + 1, newRanges[newRangeIndex].endPosition.row + 1, newRanges[newRangeIndex].endPosition.column + 1),\n\t\t\t\t\tnewRangeStartOffset: newRanges[newRangeIndex].startIndex,\n\t\t\t\t\tnewRangeEndOffset: newRanges[newRangeIndex].endIndex\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tif ((mergedChanges.length > 0) && (mergedChanges[mergedChanges.length - 1].newRangeEndOffset >= newChange.newRangeStartOffset)) {\n\t\t\t\t// Merge the changes\n\t\t\t\tmergedChanges[mergedChanges.length - 1].newRange = Range.fromPositions(mergedChanges[mergedChanges.length - 1].newRange.getStartPosition(), newChange.newRange.getEndPosition());\n\t\t\t\tmergedChanges[mergedChanges.length - 1].newRangeEndOffset = newChange.newRangeEndOffset;\n\t\t\t} else {\n\t\t\t\tmergedChanges.push(newChange);\n\t\t\t}\n\t\t}\n\t\treturn this._constrainRanges(mergedChanges);\n\t}\n\n\tprivate _constrainRanges(changes: RangeChange[]): RangeChange[] {\n\t\tif (!this._ranges) {\n\t\t\treturn changes;\n\t\t}\n\n\t\tconst constrainedChanges: RangeChange[] = [];\n\t\tlet changesIndex = 0;\n\t\tlet rangesIndex = 0;\n\t\twhile (changesIndex < changes.length && rangesIndex < this._ranges.length) {\n\t\t\tconst change = changes[changesIndex];\n\t\t\tconst range = this._ranges[rangesIndex];\n\t\t\tif (change.newRangeEndOffset < range.startIndex) {\n\t\t\t\t// Change is before the range, move to the next change\n\t\t\t\tchangesIndex++;\n\t\t\t} else if (change.newRangeStartOffset > range.endIndex) {\n\t\t\t\t// Change is after the range, move to the next range\n\t\t\t\trangesIndex++;\n\t\t\t} else {\n\t\t\t\t// Change is within the range, constrain it\n\t\t\t\tconst newRangeStartOffset = Math.max(change.newRangeStartOffset, range.startIndex);\n\t\t\t\tconst newRangeEndOffset = Math.min(change.newRangeEndOffset, range.endIndex);\n\t\t\t\tconst newRange = change.newRange.intersectRanges(new Range(range.startPosition.row + 1, range.startPosition.column + 1, range.endPosition.row + 1, range.endPosition.column + 1))!;\n\t\t\t\tconstrainedChanges.push({\n\t\t\t\t\tnewRange,\n\t\t\t\t\tnewRangeEndOffset,\n\t\t\t\t\tnewRangeStartOffset\n\t\t\t\t});\n\t\t\t\t// Remove the intersected range from the current change\n\t\t\t\tif (newRangeEndOffset < change.newRangeEndOffset) {\n\t\t\t\t\tchange.newRange = Range.fromPositions(newRange.getEndPosition(), change.newRange.getEndPosition());\n\t\t\t\t\tchange.newRangeStartOffset = newRangeEndOffset + 1;\n\t\t\t\t} else {\n\t\t\t\t\t// Move to the next change\n\t\t\t\t\tchangesIndex++;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn constrainedChanges;\n\t}\n\n\tprivate async _parseAndUpdateTree(version: number): Promise<TreeSitter.Tree | undefined> {\n\t\tconst tree = await this._parse();\n\t\tif (tree) {\n\t\t\tthis._lastFullyParsed?.delete();\n\t\t\tthis._lastFullyParsed = tree.copy();\n\t\t\tthis._lastFullyParsedWithEdits?.delete();\n\t\t\tthis._lastFullyParsedWithEdits = tree.copy();\n\n\t\t\treturn tree;\n\t\t} else if (!this._tree.get()) {\n\t\t\t// No tree means this is the initial parse and there were edits\n\t\t\t// parse function doesn't handle this well and we can end up with an incorrect tree, so we reset\n\t\t\tthis._parser.reset();\n\t\t}\n\t\treturn undefined;\n\t}\n\n\tprivate _parse(): Promise<TreeSitter.Tree | undefined> {\n\t\tlet parseType: TelemetryParseType = TelemetryParseType.Full;\n\t\tif (this._tree.get()) {\n\t\t\tparseType = TelemetryParseType.Incremental;\n\t\t}\n\t\treturn this._parseAndYield(parseType);\n\t}\n\n\tprivate async _parseAndYield(parseType: TelemetryParseType): Promise<TreeSitter.Tree | undefined> {\n\t\tlet time: number = 0;\n\t\tlet passes: number = 0;\n\t\tconst inProgressVersion = this.textModel.getVersionId();\n\t\tlet newTree: TreeSitter.Tree | null | undefined;\n\n\t\tconst progressCallback = newTimeOutProgressCallback();\n\n\t\tdo {\n\t\t\tconst timer = performance.now();\n\n\t\t\tnewTree = this._parser.parse((index: number, position?: TreeSitter.Point) => this._parseCallback(index), this._tree.get(), { progressCallback, includedRanges: this._ranges });\n\n\t\t\ttime += performance.now() - timer;\n\t\t\tpasses++;\n\n\t\t\t// So long as this isn't the initial parse, even if the model changes and edits are applied, the tree parsing will continue correctly after the await.\n\t\t\tawait new Promise<void>(resolve => setTimeout0(resolve));\n\n\t\t} while (!this._store.isDisposed && !newTree && inProgressVersion === this.textModel.getVersionId());\n\t\tthis._sendParseTimeTelemetry(parseType, time, passes);\n\t\treturn (newTree && (inProgressVersion === this.textModel.getVersionId())) ? newTree : undefined;\n\t}\n\n\tprivate _parseCallback(index: number): string | undefined {\n\t\ttry {\n\t\t\treturn this.textModel.getTextBuffer().getNearestChunk(index);\n\t\t} catch (e) {\n\t\t\tthis._logService.debug('Error getting chunk for tree-sitter parsing', e);\n\t\t}\n\t\treturn undefined;\n\t}\n\n\tprivate _setRanges(newRanges: TreeSitter.Range[]): TreeSitter.Range[] {\n\t\tconst unKnownRanges: TreeSitter.Range[] = [];\n\t\t// If we have existing ranges, find the parts of the new ranges that are not included in the existing ones\n\t\tif (this._ranges) {\n\t\t\tfor (const newRange of newRanges) {\n\t\t\t\tlet isFullyIncluded = false;\n\n\t\t\t\tfor (let i = 0; i < this._ranges.length; i++) {\n\t\t\t\t\tconst existingRange = this._ranges[i];\n\n\t\t\t\t\tif (rangesEqual(existingRange, newRange) || rangesIntersect(existingRange, newRange)) {\n\t\t\t\t\t\tisFullyIncluded = true;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (!isFullyIncluded) {\n\t\t\t\t\tunKnownRanges.push(newRange);\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\t// No existing ranges, all new ranges are unknown\n\t\t\tunKnownRanges.push(...newRanges);\n\t\t}\n\n\t\tthis._ranges = newRanges;\n\t\treturn unKnownRanges;\n\t}\n\n\tprivate _sendParseTimeTelemetry(parseType: TelemetryParseType, time: number, passes: number): void {\n\t\tthis._logService.debug(`Tree parsing (${parseType}) took ${time} ms and ${passes} passes.`);\n\t\ttype ParseTimeClassification = {\n\t\t\towner: 'alexr00';\n\t\t\tcomment: 'Used to understand how long it takes to parse a tree-sitter tree';\n\t\t\tlanguageId: { classification: 'SystemMetaData'; purpose: 'FeatureInsight'; comment: 'The programming language ID.' };\n\t\t\ttime: { classification: 'SystemMetaData'; purpose: 'FeatureInsight'; isMeasurement: true; comment: 'The ms it took to parse' };\n\t\t\tpasses: { classification: 'SystemMetaData'; purpose: 'FeatureInsight'; isMeasurement: true; comment: 'The number of passes it took to parse' };\n\t\t};\n\t\tif (parseType === TelemetryParseType.Full) {\n\t\t\tthis._telemetryService.publicLog2<{ languageId: string; time: number; passes: number }, ParseTimeClassification>(`treeSitter.fullParse`, { languageId: this.languageId, time, passes });\n\t\t} else {\n\t\t\tthis._telemetryService.publicLog2<{ languageId: string; time: number; passes: number }, ParseTimeClassification>(`treeSitter.incrementalParse`, { languageId: this.languageId, time, passes });\n\t\t}\n\t}\n\n\tpublic createParsedTreeSync(src: string): TreeSitter.Tree | undefined {\n\t\tconst parser = new this._parserClass();\n\t\tparser.setLanguage(this._parser.language);\n\t\tconst tree = parser.parse(src);\n\t\tparser.delete();\n\t\treturn tree ?? undefined;\n\t}\n}\n\nconst enum TelemetryParseType {\n\tFull = 'fullParse',\n\tIncremental = 'incrementalParse'\n}\n\nexport interface TreeParseUpdateEvent {\n\tranges: RangeChange[];\n\tversionId: number;\n}\n\nexport interface RangeWithOffsets {\n\trange: Range;\n\tstartOffset: number;\n\tendOffset: number;\n}\n\nexport interface RangeChange {\n\tnewRange: Range;\n\tnewRangeStartOffset: number;\n\tnewRangeEndOffset: number;\n}\n\nfunction newTimeOutProgressCallback(): (state: TreeSitter.ParseState) => void {\n\tlet lastYieldTime: number = performance.now();\n\treturn function parseProgressCallback(_state: TreeSitter.ParseState) {\n\t\tconst now = performance.now();\n\t\tif (now - lastYieldTime > 50) {\n\t\t\tlastYieldTime = now;\n\t\t\treturn true;\n\t\t}\n\t\treturn false;\n\t};\n}\nexport function rangesEqual(a: TreeSitter.Range, b: TreeSitter.Range) {\n\treturn (a.startPosition.row === b.startPosition.row)\n\t\t&& (a.startPosition.column === b.startPosition.column)\n\t\t&& (a.endPosition.row === b.endPosition.row)\n\t\t&& (a.endPosition.column === b.endPosition.column)\n\t\t&& (a.startIndex === b.startIndex)\n\t\t&& (a.endIndex === b.endIndex);\n}\n\nexport function rangesIntersect(a: TreeSitter.Range, b: TreeSitter.Range) {\n\treturn (a.startIndex <= b.startIndex && a.endIndex >= b.startIndex) ||\n\t\t(b.startIndex <= a.startIndex && b.endIndex >= a.startIndex);\n}\n","/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\nimport type * as TreeSitter from '@vscode/tree-sitter-wasm';\nimport { TaskQueue } from '../../../../../base/common/async.js';\nimport { Disposable, toDisposable } from '../../../../../base/common/lifecycle.js';\nimport { IObservable, observableValue, transaction, IObservableWithChange } from '../../../../../base/common/observable.js';\nimport { setTimeout0 } from '../../../../../base/common/platform.js';\nimport { ILogService } from '../../../../../platform/log/common/log.js';\nimport { ITelemetryService } from '../../../../../platform/telemetry/common/telemetry.js';\nimport { TextLength } from '../../../core/text/textLength.js';\nimport { IModelContentChangedEvent } from '../../../textModelEvents.js';\nimport { IModelContentChange } from '../../mirrorTextModel.js';\nimport { TextModel } from '../../textModel.js';\nimport { gotoParent, getClosestPreviousNodes, nextSiblingOrParentSibling, gotoNthChild } from './cursorUtils.js';\nimport { Range } from '../../../core/range.js';\n\nexport class TreeSitterTree extends Disposable {\n\n\tprivate readonly _tree = observableValue<TreeSitter.Tree | undefined, TreeParseUpdateEvent>(this, undefined);\n\tpublic readonly tree: IObservableWithChange<TreeSitter.Tree | undefined, TreeParseUpdateEvent> = this._tree;\n\n\tprivate readonly _treeLastParsedVersion = observableValue(this, -1);\n\tpublic readonly treeLastParsedVersion: IObservable<number> = this._treeLastParsedVersion;\n\n\tprivate _lastFullyParsed: TreeSitter.Tree | undefined;\n\tprivate _lastFullyParsedWithEdits: TreeSitter.Tree | undefined;\n\n\tprivate _onDidChangeContentQueue: TaskQueue = new TaskQueue();\n\n\tconstructor(\n\t\tpublic readonly languageId: string,\n\t\tprivate _ranges: TreeSitter.Range[] | undefined,\n\t\t// readonly treeSitterLanguage: Language,\n\t\t/** Must have the language set! */\n\t\tprivate readonly _parser: TreeSitter.Parser,\n\t\tprivate readonly _parserClass: typeof TreeSitter.Parser,\n\t\t// private readonly _injectionQuery: TreeSitter.Query,\n\t\tpublic readonly textModel: TextModel,\n\t\t@ILogService private readonly _logService: ILogService,\n\t\t@ITelemetryService private readonly _telemetryService: ITelemetryService\n\t) {\n\t\tsuper();\n\n\t\tthis._tree = observableValue(this, undefined);\n\t\tthis.tree = this._tree;\n\n\t\tthis._register(toDisposable(() => {\n\t\t\tthis._tree.get()?.delete();\n\t\t\tthis._lastFullyParsed?.delete();\n\t\t\tthis._lastFullyParsedWithEdits?.delete();\n\t\t\tthis._parser.delete();\n\t\t}));\n\t\tthis.handleContentChange(undefined, this._ranges);\n\t}\n\n\tpublic handleContentChange(e: IModelContentChangedEvent | undefined, ranges?: TreeSitter.Range[]): void {\n\t\tconst version = this.textModel.getVersionId();\n\t\tlet newRanges: TreeSitter.Range[] = [];\n\t\tif (ranges) {\n\t\t\tnewRanges = this._setRanges(ranges);\n\t\t}\n\t\tif (e) {\n\t\t\tthis._applyEdits(e.changes);\n\t\t}\n\n\t\tthis._onDidChangeContentQueue.clearPending();\n\t\tthis._onDidChangeContentQueue.schedule(async () => {\n\t\t\tif (this._store.isDisposed) {\n\t\t\t\t// No need to continue the queue if we are disposed\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst oldTree = this._lastFullyParsed;\n\t\t\tlet changedNodes: TreeSitter.Range[] | undefined;\n\t\t\tif (this._lastFullyParsedWithEdits && this._lastFullyParsed) {\n\t\t\t\tchangedNodes = this._findChangedNodes(this._lastFullyParsedWithEdits, this._lastFullyParsed);\n\t\t\t}\n\n\t\t\tconst completed = await this._parseAndUpdateTree(version);\n\t\t\tif (completed) {\n\t\t\t\tlet ranges: RangeChange[] | undefined;\n\t\t\t\tif (!changedNodes) {\n\t\t\t\t\tif (this._ranges) {\n\t\t\t\t\t\tranges = this._ranges.map(r => ({ newRange: new Range(r.startPosition.row + 1, r.startPosition.column + 1, r.endPosition.row + 1, r.endPosition.column + 1), oldRangeLength: r.endIndex - r.startIndex, newRangeStartOffset: r.startIndex, newRangeEndOffset: r.endIndex }));\n\t\t\t\t\t}\n\t\t\t\t} else if (oldTree && changedNodes) {\n\t\t\t\t\tranges = this._findTreeChanges(completed, changedNodes, newRanges);\n\t\t\t\t}\n\t\t\t\tif (!ranges) {\n\t\t\t\t\tranges = [{ newRange: this.textModel.getFullModelRange(), newRangeStartOffset: 0, newRangeEndOffset: this.textModel.getValueLength() }];\n\t\t\t\t}\n\n\t\t\t\tconst previousTree = this._tree.get();\n\t\t\t\ttransaction(tx => {\n\t\t\t\t\tthis._tree.set(completed, tx, { ranges, versionId: version });\n\t\t\t\t\tthis._treeLastParsedVersion.set(version, tx);\n\t\t\t\t});\n\t\t\t\tpreviousTree?.delete();\n\t\t\t}\n\t\t});\n\t}\n\n\tprivate _applyEdits(changes: IModelContentChange[]) {\n\t\tfor (const change of changes) {\n\t\t\tconst originalTextLength = TextLength.ofRange(Range.lift(change.range));\n\t\t\tconst newTextLength = TextLength.ofText(change.text);\n\t\t\tconst summedTextLengths = change.text.length === 0 ? newTextLength : originalTextLength.add(newTextLength);\n\t\t\tconst edit = {\n\t\t\t\tstartIndex: change.rangeOffset,\n\t\t\t\toldEndIndex: change.rangeOffset + change.rangeLength,\n\t\t\t\tnewEndIndex: change.rangeOffset + change.text.length,\n\t\t\t\tstartPosition: { row: change.range.startLineNumber - 1, column: change.range.startColumn - 1 },\n\t\t\t\toldEndPosition: { row: change.range.endLineNumber - 1, column: change.range.endColumn - 1 },\n\t\t\t\tnewEndPosition: { row: change.range.startLineNumber + summedTextLengths.lineCount - 1, column: summedTextLengths.lineCount ? summedTextLengths.columnCount : (change.range.endColumn + summedTextLengths.columnCount) }\n\t\t\t};\n\t\t\tthis._tree.get()?.edit(edit);\n\t\t\tthis._lastFullyParsedWithEdits?.edit(edit);\n\t\t}\n\t}\n\n\tprivate _findChangedNodes(newTree: TreeSitter.Tree, oldTree: TreeSitter.Tree): TreeSitter.Range[] | undefined {\n\t\tif ((this._ranges && this._ranges.every(range => range.startPosition.row !== newTree.rootNode.startPosition.row)) || newTree.rootNode.startPosition.row !== 0) {\n\t\t\treturn [];\n\t\t}\n\t\tconst newCursor = newTree.walk();\n\t\tconst oldCursor = oldTree.walk();\n\n\t\tconst nodes: TreeSitter.Range[] = [];\n\t\tlet next = true;\n\n\t\tdo {\n\t\t\tif (newCursor.currentNode.hasChanges) {\n\t\t\t\t// Check if only one of the children has changes.\n\t\t\t\t// If it's only one, then we go to that child.\n\t\t\t\t// If it's more then, we need to go to each child\n\t\t\t\t// If it's none, then we've found one of our ranges\n\t\t\t\tconst newChildren = newCursor.currentNode.children;\n\t\t\t\tconst indexChangedChildren: number[] = [];\n\t\t\t\tconst changedChildren = newChildren.filter((c, index) => {\n\t\t\t\t\tif (c?.hasChanges || (oldCursor.currentNode.children.length <= index)) {\n\t\t\t\t\t\tindexChangedChildren.push(index);\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t\treturn false;\n\t\t\t\t});\n\t\t\t\t// If we have changes and we *had* an error, the whole node should be refreshed.\n\t\t\t\tif ((changedChildren.length === 0) || (newCursor.currentNode.hasError !== oldCursor.currentNode.hasError)) {\n\t\t\t\t\t// walk up again until we get to the first one that's named as unnamed nodes can be too granular\n\t\t\t\t\twhile (newCursor.currentNode.parent && next && !newCursor.currentNode.isNamed) {\n\t\t\t\t\t\tnext = gotoParent(newCursor, oldCursor);\n\t\t\t\t\t}\n\t\t\t\t\t// Use the end position of the previous node and the start position of the current node\n\t\t\t\t\tconst newNode = newCursor.currentNode;\n\t\t\t\t\tconst closestPreviousNode = getClosestPreviousNodes(newCursor, newTree) ?? newNode;\n\t\t\t\t\tnodes.push({\n\t\t\t\t\t\tstartIndex: closestPreviousNode.startIndex,\n\t\t\t\t\t\tendIndex: newNode.endIndex,\n\t\t\t\t\t\tstartPosition: closestPreviousNode.startPosition,\n\t\t\t\t\t\tendPosition: newNode.endPosition\n\t\t\t\t\t});\n\t\t\t\t\tnext = nextSiblingOrParentSibling(newCursor, oldCursor);\n\t\t\t\t} else if (changedChildren.length >= 1) {\n\t\t\t\t\tnext = gotoNthChild(newCursor, oldCursor, indexChangedChildren[0]);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tnext = nextSiblingOrParentSibling(newCursor, oldCursor);\n\t\t\t}\n\t\t} while (next);\n\n\t\tnewCursor.delete();\n\t\toldCursor.delete();\n\t\treturn nodes;\n\t}\n\n\tprivate _findTreeChanges(newTree: TreeSitter.Tree, changedNodes: TreeSitter.Range[], newRanges: TreeSitter.Range[]): RangeChange[] {\n\t\tlet newRangeIndex = 0;\n\t\tconst mergedChanges: RangeChange[] = [];\n\n\t\t// Find the parent in the new tree of the changed node\n\t\tfor (let nodeIndex = 0; nodeIndex < changedNodes.length; nodeIndex++) {\n\t\t\tconst node = changedNodes[nodeIndex];\n\n\t\t\tif (mergedChanges.length > 0) {\n\t\t\t\tif ((node.startIndex >= mergedChanges[mergedChanges.length - 1].newRangeStartOffset) && (node.endIndex <= mergedChanges[mergedChanges.length - 1].newRangeEndOffset)) {\n\t\t\t\t\t// This node is within the previous range, skip it\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst cursor = newTree.walk();\n\t\t\tconst cursorContainersNode = () => cursor.startIndex < node.startIndex && cursor.endIndex > node.endIndex;\n\n\t\t\twhile (cursorContainersNode()) {\n\t\t\t\t// See if we can go to a child\n\t\t\t\tlet child = cursor.gotoFirstChild();\n\t\t\t\tlet foundChild = false;\n\t\t\t\twhile (child) {\n\t\t\t\t\tif (cursorContainersNode() && cursor.currentNode.isNamed) {\n\t\t\t\t\t\tfoundChild = true;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tchild = cursor.gotoNextSibling();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (!foundChild) {\n\t\t\t\t\tcursor.gotoParent();\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tif (cursor.currentNode.childCount === 0) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst startPosition = cursor.currentNode.startPosition;\n\t\t\tconst endPosition = cursor.currentNode.endPosition;\n\t\t\tconst startIndex = cursor.currentNode.startIndex;\n\t\t\tconst endIndex = cursor.currentNode.endIndex;\n\n\t\t\tconst newChange = { newRange: new Range(startPosition.row + 1, startPosition.column + 1, endPosition.row + 1, endPosition.column + 1), newRangeStartOffset: startIndex, newRangeEndOffset: endIndex };\n\t\t\tif ((newRangeIndex < newRanges.length) && rangesIntersect(newRanges[newRangeIndex], { startIndex, endIndex, startPosition, endPosition })) {\n\t\t\t\t// combine the new change with the range\n\t\t\t\tif (newRanges[newRangeIndex].startIndex < newChange.newRangeStartOffset) {\n\t\t\t\t\tnewChange.newRange = newChange.newRange.setStartPosition(newRanges[newRangeIndex].startPosition.row + 1, newRanges[newRangeIndex].startPosition.column + 1);\n\t\t\t\t\tnewChange.newRangeStartOffset = newRanges[newRangeIndex].startIndex;\n\t\t\t\t}\n\t\t\t\tif (newRanges[newRangeIndex].endIndex > newChange.newRangeEndOffset) {\n\t\t\t\t\tnewChange.newRange = newChange.newRange.setEndPosition(newRanges[newRangeIndex].endPosition.row + 1, newRanges[newRangeIndex].endPosition.column + 1);\n\t\t\t\t\tnewChange.newRangeEndOffset = newRanges[newRangeIndex].endIndex;\n\t\t\t\t}\n\t\t\t\tnewRangeIndex++;\n\t\t\t} else if (newRangeIndex < newRanges.length && newRanges[newRangeIndex].endIndex < newChange.newRangeStartOffset) {\n\t\t\t\t// add the full range to the merged changes\n\t\t\t\tmergedChanges.push({\n\t\t\t\t\tnewRange: new Range(newRanges[newRangeIndex].startPosition.row + 1, newRanges[newRangeIndex].startPosition.column + 1, newRanges[newRangeIndex].endPosition.row + 1, newRanges[newRangeIndex].endPosition.column + 1),\n\t\t\t\t\tnewRangeStartOffset: newRanges[newRangeIndex].startIndex,\n\t\t\t\t\tnewRangeEndOffset: newRanges[newRangeIndex].endIndex\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tif ((mergedChanges.length > 0) && (mergedChanges[mergedChanges.length - 1].newRangeEndOffset >= newChange.newRangeStartOffset)) {\n\t\t\t\t// Merge the changes\n\t\t\t\tmergedChanges[mergedChanges.length - 1].newRange = Range.fromPositions(mergedChanges[mergedChanges.length - 1].newRange.getStartPosition(), newChange.newRange.getEndPosition());\n\t\t\t\tmergedChanges[mergedChanges.length - 1].newRangeEndOffset = newChange.newRangeEndOffset;\n\t\t\t} else {\n\t\t\t\tmergedChanges.push(newChange);\n\t\t\t}\n\t\t}\n\t\treturn this._constrainRanges(mergedChanges);\n\t}\n\n\tprivate _constrainRanges(changes: RangeChange[]): RangeChange[] {\n\t\tif (!this._ranges) {\n\t\t\treturn changes;\n\t\t}\n\n\t\tconst constrainedChanges: RangeChange[] = [];\n\t\tlet changesIndex = 0;\n\t\tlet rangesIndex = 0;\n\t\twhile (changesIndex < changes.length && rangesIndex < this._ranges.length) {\n\t\t\tconst change = changes[changesIndex];\n\t\t\tconst range = this._ranges[rangesIndex];\n\t\t\tif (change.newRangeEndOffset < range.startIndex) {\n\t\t\t\t// Change is before the range, move to the next change\n\t\t\t\tchangesIndex++;\n\t\t\t} else if (change.newRangeStartOffset > range.endIndex) {\n\t\t\t\t// Change is after the range, move to the next range\n\t\t\t\trangesIndex++;\n\t\t\t} else {\n\t\t\t\t// Change is within the range, constrain it\n\t\t\t\tconst newRangeStartOffset = Math.max(change.newRangeStartOffset, range.startIndex);\n\t\t\t\tconst newRangeEndOffset = Math.min(change.newRangeEndOffset, range.endIndex);\n\t\t\t\tconst newRange = change.newRange.intersectRanges(new Range(range.startPosition.row + 1, range.startPosition.column + 1, range.endPosition.row + 1, range.endPosition.column + 1))!;\n\t\t\t\tconstrainedChanges.push({\n\t\t\t\t\tnewRange,\n\t\t\t\t\tnewRangeEndOffset,\n\t\t\t\t\tnewRangeStartOffset\n\t\t\t\t});\n\t\t\t\t// Remove the intersected range from the current change\n\t\t\t\tif (newRangeEndOffset < change.newRangeEndOffset) {\n\t\t\t\t\tchange.newRange = Range.fromPositions(newRange.getEndPosition(), change.newRange.getEndPosition());\n\t\t\t\t\tchange.newRangeStartOffset = newRangeEndOffset + 1;\n\t\t\t\t} else {\n\t\t\t\t\t// Move to the next change\n\t\t\t\t\tchangesIndex++;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn constrainedChanges;\n\t}\n\n\tprivate async _parseAndUpdateTree(version: number): Promise<TreeSitter.Tree | undefined> {\n\t\tconst tree = await this._parse();\n\t\tif (tree) {\n\t\t\tthis._lastFullyParsed?.delete();\n\t\t\tthis._lastFullyParsed = tree.copy();\n\t\t\tthis._lastFullyParsedWithEdits?.delete();\n\t\t\tthis._lastFullyParsedWithEdits = tree.copy();\n\n\t\t\treturn tree;\n\t\t} else if (!this._tree.get()) {\n\t\t\t// No tree means this is the initial parse and there were edits\n\t\t\t// parse function doesn't handle this well and we can end up with an incorrect tree, so we reset\n\t\t\tthis._parser.reset();\n\t\t}\n\t\treturn undefined;\n\t}\n\n\tprivate _parse(): Promise<TreeSitter.Tree | undefined> {\n\t\tlet parseType: TelemetryParseType = TelemetryParseType.Full;\n\t\tif (this._tree.get()) {\n\t\t\tparseType = TelemetryParseType.Incremental;\n\t\t}\n\t\treturn this._parseAndYield(parseType);\n\t}\n\n\tprivate async _parseAndYield(parseType: TelemetryParseType): Promise<TreeSitter.Tree | undefined> {\n\t\tlet time: number = 0;\n\t\tlet passes: number = 0;\n\t\tconst inProgressVersion = this.textModel.getVersionId();\n\t\tlet newTree: TreeSitter.Tree | null | undefined;\n\n\t\tconst progressCallback = newTimeOutProgressCallback();\n\n\t\tdo {\n\t\t\tconst timer = performance.now();\n\n\t\t\tnewTree = this._parser.parse((index: number, position?: TreeSitter.Point) => this._parseCallback(index), this._tree.get(), { progressCallback, includedRanges: this._ranges });\n\n\t\t\ttime += performance.now() - timer;\n\t\t\tpasses++;\n\n\t\t\t// So long as this isn't the initial parse, even if the model changes and edits are applied, the tree parsing will continue correctly after the await.\n\t\t\tawait new Promise<void>(resolve => setTimeout0(resolve));\n\n\t\t} while (!this._store.isDisposed && !newTree && inProgressVersion === this.textModel.getVersionId());\n\t\tthis._sendParseTimeTelemetry(parseType, time, passes);\n\t\treturn (newTree && (inProgressVersion === this.textModel.getVersionId())) ? newTree : undefined;\n\t}\n\n\tprivate _parseCallback(index: number): string | undefined {\n\t\ttry {\n\t\t\treturn this.textModel.getTextBuffer().getNearestChunk(index);\n\t\t} catch (e) {\n\t\t\tthis._logService.debug('Error getting chunk for tree-sitter parsing', e);\n\t\t}\n\t\treturn undefined;\n\t}\n\n\tprivate _setRanges(newRanges: TreeSitter.Range[]): TreeSitter.Range[] {\n\t\tconst unKnownRanges: TreeSitter.Range[] = [];\n\t\t// If we have existing ranges, find the parts of the new ranges that are not included in the existing ones\n\t\tif (this._ranges) {\n\t\t\tfor (const newRange of newRanges) {\n\t\t\t\tlet isFullyIncluded = false;\n\n\t\t\t\tfor (let i = 0; i < this._ranges.length; i++) {\n\t\t\t\t\tconst existingRange = this._ranges[i];\n\n\t\t\t\t\tif (rangesEqual(existingRange, newRange) || rangesIntersect(existingRange, newRange)) {\n\t\t\t\t\t\tisFullyIncluded = true;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (!isFullyIncluded) {\n\t\t\t\t\tunKnownRanges.push(newRange);\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\t// No existing ranges, all new ranges are unknown\n\t\t\tunKnownRanges.push(...newRanges);\n\t\t}\n\n\t\tthis._ranges = newRanges;\n\t\treturn unKnownRanges;\n\t}\n\n\tprivate _sendParseTimeTelemetry(parseType: TelemetryParseType, time: number, passes: number): void {\n\t\tthis._logService.debug(`Tree parsing (${parseType}) took ${time} ms and ${passes} passes.`);\n\t\ttype ParseTimeClassification = {\n\t\t\towner: 'alexr00';\n\t\t\tcomment: 'Used to understand how long it takes to parse a tree-sitter tree';\n\t\t\tlanguageId: { classification: 'SystemMetaData'; purpose: 'FeatureInsight'; comment: 'The programming language ID.' };\n\t\t\ttime: { classification: 'SystemMetaData'; purpose: 'FeatureInsight'; isMeasurement: true; comment: 'The ms it took to parse' };\n\t\t\tpasses: { classification: 'SystemMetaData'; purpose: 'FeatureInsight'; isMeasurement: true; comment: 'The number of passes it took to parse' };\n\t\t};\n\t\tif (parseType === TelemetryParseType.Full) {\n\t\t\tthis._telemetryService.publicLog2<{ languageId: string; time: number; passes: number }, ParseTimeClassification>(`treeSitter.fullParse`, { languageId: this.languageId, time, passes });\n\t\t} else {\n\t\t\tthis._telemetryService.publicLog2<{ languageId: string; time: number; passes: number }, ParseTimeClassification>(`treeSitter.incrementalParse`, { languageId: this.languageId, time, passes });\n\t\t}\n\t}\n\n\tpublic createParsedTreeSync(src: string): TreeSitter.Tree | undefined {\n\t\tconst parser = new this._parserClass();\n\t\tparser.setLanguage(this._parser.language);\n\t\tconst tree = parser.parse(src);\n\t\tparser.delete();\n\t\treturn tree ?? undefined;\n\t}\n}\n\nconst enum TelemetryParseType {\n\tFull = 'fullParse',\n\tIncremental = 'incrementalParse'\n}\n\nexport interface TreeParseUpdateEvent {\n\tranges: RangeChange[];\n\tversionId: number;\n}\n\nexport interface RangeWithOffsets {\n\trange: Range;\n\tstartOffset: number;\n\tendOffset: number;\n}\n\nexport interface RangeChange {\n\tnewRange: Range;\n\tnewRangeStartOffset: number;\n\tnewRangeEndOffset: number;\n}\n\nfunction newTimeOutProgressCallback(): (state: TreeSitter.ParseState) => void {\n\tlet lastYieldTime: number = performance.now();\n\treturn function parseProgressCallback(_state: TreeSitter.ParseState) {\n\t\tconst now = performance.now();\n\t\tif (now - lastYieldTime > 50) {\n\t\t\tlastYieldTime = now;\n\t\t\treturn true;\n\t\t}\n\t\treturn false;\n\t};\n}\nexport function rangesEqual(a: TreeSitter.Range, b: TreeSitter.Range) {\n\treturn (a.startPosition.row === b.startPosition.row)\n\t\t&& (a.startPosition.column === b.startPosition.column)\n\t\t&& (a.endPosition.row === b.endPosition.row)\n\t\t&& (a.endPosition.column === b.endPosition.column)\n\t\t&& (a.startIndex === b.startIndex)\n\t\t&& (a.endIndex === b.endIndex);\n}\n\nexport function rangesIntersect(a: TreeSitter.Range, b: TreeSitter.Range) {\n\treturn (a.startIndex <= b.startIndex && a.endIndex >= b.startIndex) ||\n\t\t(b.startIndex <= a.startIndex && b.endIndex >= a.startIndex);\n}\n"]}
|