monaco-editor-core 0.53.0-dev-20250829 → 0.53.0-dev-20250830

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.
@@ -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, IModelContentChange } from '../../../textModelEvents.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, IModelContentChange } from '../../../textModelEvents.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"]}