@codingame/monaco-vscode-treesitter-service-override 17.2.0 → 18.0.0
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/index.js +6 -12
- package/package.json +4 -5
- package/vscode/src/vs/amdX.d.ts +3 -0
- package/vscode/src/vs/amdX.js +188 -0
- package/vscode/src/vs/workbench/services/treeSitter/browser/treeSitterLibraryService.d.ts +28 -0
- package/vscode/src/vs/workbench/services/treeSitter/browser/treeSitterLibraryService.js +136 -0
- package/vscode/src/vs/workbench/services/treeSitter/browser/treeSitterThemeService.d.ts +11 -0
- package/vscode/src/vs/workbench/services/treeSitter/browser/treeSitterThemeService.js +26 -0
- package/vscode/src/vs/editor/common/model/tokenStore.d.ts +0 -65
- package/vscode/src/vs/editor/common/model/tokenStore.js +0 -412
- package/vscode/src/vs/editor/common/model/treeSitterTokenStoreService.d.ts +0 -32
- package/vscode/src/vs/editor/common/model/treeSitterTokenStoreService.js +0 -135
- package/vscode/src/vs/editor/common/services/treeSitter/cursorUtils.d.ts +0 -6
- package/vscode/src/vs/editor/common/services/treeSitter/cursorUtils.js +0 -76
- package/vscode/src/vs/editor/common/services/treeSitter/textModelTreeSitter.d.ts +0 -88
- package/vscode/src/vs/editor/common/services/treeSitter/textModelTreeSitter.js +0 -684
- package/vscode/src/vs/editor/common/services/treeSitter/treeSitterLanguages.d.ts +0 -31
- package/vscode/src/vs/editor/common/services/treeSitter/treeSitterLanguages.js +0 -120
- package/vscode/src/vs/editor/common/services/treeSitter/treeSitterParserService.d.ts +0 -48
- package/vscode/src/vs/editor/common/services/treeSitter/treeSitterParserService.js +0 -179
- package/vscode/src/vs/editor/common/services/treeSitterParserService.d.ts +0 -61
- package/vscode/src/vs/editor/common/services/treeSitterParserService.js +0 -36
- package/vscode/src/vs/workbench/services/treeSitter/browser/treeSitterCodeEditors.d.ts +0 -32
- package/vscode/src/vs/workbench/services/treeSitter/browser/treeSitterCodeEditors.js +0 -119
- package/vscode/src/vs/workbench/services/treeSitter/browser/treeSitterTokenizationFeature.contribution.d.ts +0 -1
- package/vscode/src/vs/workbench/services/treeSitter/browser/treeSitterTokenizationFeature.contribution.js +0 -54
- package/vscode/src/vs/workbench/services/treeSitter/browser/treeSitterTokenizationFeature.d.ts +0 -96
- package/vscode/src/vs/workbench/services/treeSitter/browser/treeSitterTokenizationFeature.js +0 -719
package/vscode/src/vs/workbench/services/treeSitter/browser/treeSitterTokenizationFeature.js
DELETED
|
@@ -1,719 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
import { __decorate, __param } from '@codingame/monaco-vscode-api/external/tslib/tslib.es6';
|
|
3
|
-
import { Emitter, Event } from '@codingame/monaco-vscode-api/vscode/vs/base/common/event';
|
|
4
|
-
import { Disposable, DisposableMap, DisposableStore } from '@codingame/monaco-vscode-api/vscode/vs/base/common/lifecycle';
|
|
5
|
-
import { FileAccess } from '@codingame/monaco-vscode-api/vscode/vs/base/common/network';
|
|
6
|
-
import { LazyTokenizationSupport, TreeSitterTokenizationRegistry } from '@codingame/monaco-vscode-api/vscode/vs/editor/common/languages';
|
|
7
|
-
import { EDITOR_EXPERIMENTAL_PREFER_TREESITTER, TREESITTER_ALLOWED_SUPPORT } from '../../../../editor/common/services/treeSitterParserService.js';
|
|
8
|
-
import { ITreeSitterImporter, ITreeSitterParserService } from '@codingame/monaco-vscode-api/vscode/vs/editor/common/services/treeSitterParserService.service';
|
|
9
|
-
import { IConfigurationService } from '@codingame/monaco-vscode-api/vscode/vs/platform/configuration/common/configuration.service';
|
|
10
|
-
import { IFileService } from '@codingame/monaco-vscode-api/vscode/vs/platform/files/common/files.service';
|
|
11
|
-
import '@codingame/monaco-vscode-api/vscode/vs/platform/instantiation/common/extensions';
|
|
12
|
-
import { IInstantiationService } from '@codingame/monaco-vscode-api/vscode/vs/platform/instantiation/common/instantiation';
|
|
13
|
-
import { findMetadata } from '@codingame/monaco-vscode-9d0168a3-519b-57f3-9bcc-89efc41f951a-common/vscode/vs/workbench/services/themes/common/colorThemeData';
|
|
14
|
-
import { ILanguageService } from '@codingame/monaco-vscode-api/vscode/vs/editor/common/languages/language.service';
|
|
15
|
-
import { StopWatch } from '@codingame/monaco-vscode-api/vscode/vs/base/common/stopwatch';
|
|
16
|
-
import { ITreeSitterTokenizationStoreService } from '@codingame/monaco-vscode-api/vscode/vs/editor/common/model/treeSitterTokenStoreService.service';
|
|
17
|
-
import { TokenQuality } from '../../../../editor/common/model/tokenStore.js';
|
|
18
|
-
import { Range } from '@codingame/monaco-vscode-api/vscode/vs/editor/common/core/range';
|
|
19
|
-
import { setTimeout0 } from '@codingame/monaco-vscode-api/vscode/vs/base/common/platform';
|
|
20
|
-
import { findLikelyRelevantLines } from '@codingame/monaco-vscode-api/vscode/vs/editor/common/model/textModelTokens';
|
|
21
|
-
import { TreeSitterCodeEditors } from './treeSitterCodeEditors.js';
|
|
22
|
-
import { IWorkbenchThemeService } from '@codingame/monaco-vscode-7443a901-21f6-577a-9674-42893b997ee0-common/vscode/vs/workbench/services/themes/common/workbenchThemeService.service';
|
|
23
|
-
import { Position } from '@codingame/monaco-vscode-api/vscode/vs/editor/common/core/position';
|
|
24
|
-
|
|
25
|
-
const TREESITTER_BASE_SCOPES = {
|
|
26
|
-
'css': 'source.css',
|
|
27
|
-
'typescript': 'source.ts',
|
|
28
|
-
'ini': 'source.ini',
|
|
29
|
-
'regex': 'source.regex',
|
|
30
|
-
};
|
|
31
|
-
const BRACKETS = /[\{\}\[\]\<\>\(\)]/g;
|
|
32
|
-
let TreeSitterTokenizationFeature = class TreeSitterTokenizationFeature extends Disposable {
|
|
33
|
-
constructor(_treeSitterImporter, _languageService, _configurationService, _instantiationService, _fileService) {
|
|
34
|
-
super();
|
|
35
|
-
this._treeSitterImporter = _treeSitterImporter;
|
|
36
|
-
this._languageService = _languageService;
|
|
37
|
-
this._configurationService = _configurationService;
|
|
38
|
-
this._instantiationService = _instantiationService;
|
|
39
|
-
this._fileService = _fileService;
|
|
40
|
-
this._tokenizersRegistrations = this._register(( new DisposableMap()));
|
|
41
|
-
this._handleGrammarsExtPoint();
|
|
42
|
-
this._register(this._configurationService.onDidChangeConfiguration(e => {
|
|
43
|
-
if (e.affectsConfiguration(EDITOR_EXPERIMENTAL_PREFER_TREESITTER)) {
|
|
44
|
-
this._handleGrammarsExtPoint();
|
|
45
|
-
}
|
|
46
|
-
}));
|
|
47
|
-
}
|
|
48
|
-
_getSetting(languageId) {
|
|
49
|
-
return this._configurationService.getValue(`${EDITOR_EXPERIMENTAL_PREFER_TREESITTER}.${languageId}`);
|
|
50
|
-
}
|
|
51
|
-
_handleGrammarsExtPoint() {
|
|
52
|
-
for (const languageId of TREESITTER_ALLOWED_SUPPORT) {
|
|
53
|
-
const setting = this._getSetting(languageId);
|
|
54
|
-
if (setting && !( this._tokenizersRegistrations.has(languageId))) {
|
|
55
|
-
const lazyTokenizationSupport = ( new LazyTokenizationSupport(() => this._createTokenizationSupport(languageId)));
|
|
56
|
-
const disposableStore = ( new DisposableStore());
|
|
57
|
-
disposableStore.add(lazyTokenizationSupport);
|
|
58
|
-
disposableStore.add(TreeSitterTokenizationRegistry.registerFactory(languageId, lazyTokenizationSupport));
|
|
59
|
-
this._tokenizersRegistrations.set(languageId, disposableStore);
|
|
60
|
-
TreeSitterTokenizationRegistry.getOrCreate(languageId);
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
const languagesToUnregister = [...( this._tokenizersRegistrations.keys())].filter(languageId => !this._getSetting(languageId));
|
|
64
|
-
for (const languageId of languagesToUnregister) {
|
|
65
|
-
this._tokenizersRegistrations.deleteAndDispose(languageId);
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
async _fetchQueries(newLanguage) {
|
|
69
|
-
const languageLocation = `vs/editor/common/languages/highlights/${newLanguage}.scm`;
|
|
70
|
-
const query = await this._fileService.readFile(( FileAccess.asFileUri(languageLocation)));
|
|
71
|
-
return ( query.value.toString());
|
|
72
|
-
}
|
|
73
|
-
async _createTokenizationSupport(languageId) {
|
|
74
|
-
const queries = await this._fetchQueries(languageId);
|
|
75
|
-
const Query = await this._treeSitterImporter.getQueryClass();
|
|
76
|
-
return this._instantiationService.createInstance(TreeSitterTokenizationSupport, queries, Query, languageId, this._languageService.languageIdCodec);
|
|
77
|
-
}
|
|
78
|
-
};
|
|
79
|
-
TreeSitterTokenizationFeature = ( __decorate([
|
|
80
|
-
( __param(0, ITreeSitterImporter)),
|
|
81
|
-
( __param(1, ILanguageService)),
|
|
82
|
-
( __param(2, IConfigurationService)),
|
|
83
|
-
( __param(3, IInstantiationService)),
|
|
84
|
-
( __param(4, IFileService))
|
|
85
|
-
], TreeSitterTokenizationFeature));
|
|
86
|
-
let TreeSitterTokenizationSupport = class TreeSitterTokenizationSupport extends Disposable {
|
|
87
|
-
constructor(_queries, Query, _languageId, _languageIdCodec, _treeSitterService, _themeService, _tokenizationStoreService, _instantiationService) {
|
|
88
|
-
super();
|
|
89
|
-
this._queries = _queries;
|
|
90
|
-
this.Query = Query;
|
|
91
|
-
this._languageId = _languageId;
|
|
92
|
-
this._languageIdCodec = _languageIdCodec;
|
|
93
|
-
this._treeSitterService = _treeSitterService;
|
|
94
|
-
this._themeService = _themeService;
|
|
95
|
-
this._tokenizationStoreService = _tokenizationStoreService;
|
|
96
|
-
this._instantiationService = _instantiationService;
|
|
97
|
-
this._onDidChangeTokens = this._register(( new Emitter()));
|
|
98
|
-
this.onDidChangeTokens = this._onDidChangeTokens.event;
|
|
99
|
-
this._onDidCompleteBackgroundTokenization = this._register(( new Emitter()));
|
|
100
|
-
this.onDidChangeBackgroundTokenization = this._onDidCompleteBackgroundTokenization.event;
|
|
101
|
-
this._codeEditors = this._instantiationService.createInstance(TreeSitterCodeEditors, this._languageId);
|
|
102
|
-
this._register(this._codeEditors.onDidChangeViewport(e => {
|
|
103
|
-
this._parseAndTokenizeViewPort(e.model, e.ranges);
|
|
104
|
-
}));
|
|
105
|
-
this._codeEditors.getInitialViewPorts().then(async (viewports) => {
|
|
106
|
-
for (const viewport of viewports) {
|
|
107
|
-
this._parseAndTokenizeViewPort(viewport.model, viewport.ranges);
|
|
108
|
-
}
|
|
109
|
-
});
|
|
110
|
-
this._register(Event.runAndSubscribe(this._themeService.onDidColorThemeChange, (e) => this._updateTheme(e)));
|
|
111
|
-
this._register(this._treeSitterService.onDidUpdateTree((e) => {
|
|
112
|
-
if (e.languageId !== this._languageId) {
|
|
113
|
-
return;
|
|
114
|
-
}
|
|
115
|
-
if (this._tokenizationStoreService.hasTokens(e.textModel)) {
|
|
116
|
-
for (const range of e.ranges) {
|
|
117
|
-
this._tokenizationStoreService.markForRefresh(e.textModel, range.newRange);
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
if (e.versionId !== e.textModel.getVersionId()) {
|
|
121
|
-
return;
|
|
122
|
-
}
|
|
123
|
-
if (!this._tokenizationStoreService.hasTokens(e.textModel)) {
|
|
124
|
-
this._firstTreeUpdate(e.textModel, e.versionId, e.tree);
|
|
125
|
-
}
|
|
126
|
-
else {
|
|
127
|
-
this._handleTreeUpdate(e.ranges, e.textModel, e.versionId, e.tree);
|
|
128
|
-
}
|
|
129
|
-
}));
|
|
130
|
-
}
|
|
131
|
-
get _encodedLanguageId() {
|
|
132
|
-
if (!this._encodedLanguage) {
|
|
133
|
-
this._encodedLanguage = this._languageIdCodec.encodeLanguageId(this._languageId);
|
|
134
|
-
}
|
|
135
|
-
return this._encodedLanguage;
|
|
136
|
-
}
|
|
137
|
-
_setInitialTokens(textModel) {
|
|
138
|
-
const tokens = this._createEmptyTokens(textModel);
|
|
139
|
-
this._tokenizationStoreService.setTokens(textModel, tokens, TokenQuality.None);
|
|
140
|
-
}
|
|
141
|
-
_forceParseAndTokenizeContent(model, range, startOffsetOfRangeInDocument, endOffsetOfRangeInDocument, content, asUpdate) {
|
|
142
|
-
const likelyRelevantLines = findLikelyRelevantLines(model, range.startLineNumber).likelyRelevantLines;
|
|
143
|
-
const likelyRelevantPrefix = likelyRelevantLines.join(model.getEOL());
|
|
144
|
-
const tree = this._treeSitterService.getTreeSync(`${likelyRelevantPrefix}${content}`, this._languageId);
|
|
145
|
-
if (!tree) {
|
|
146
|
-
return;
|
|
147
|
-
}
|
|
148
|
-
const treeRange = ( new Range(
|
|
149
|
-
1,
|
|
150
|
-
1,
|
|
151
|
-
range.endLineNumber - range.startLineNumber + 1 + likelyRelevantLines.length,
|
|
152
|
-
range.endColumn
|
|
153
|
-
));
|
|
154
|
-
const captures = this._captureAtRange(treeRange, tree);
|
|
155
|
-
const tokens = this._tokenizeCapturesWithMetadata(tree, captures, likelyRelevantPrefix.length, endOffsetOfRangeInDocument - startOffsetOfRangeInDocument + likelyRelevantPrefix.length);
|
|
156
|
-
if (!tokens) {
|
|
157
|
-
return;
|
|
158
|
-
}
|
|
159
|
-
if (asUpdate) {
|
|
160
|
-
return this._rangeTokensAsUpdates(startOffsetOfRangeInDocument, tokens.endOffsetsAndMetadata, likelyRelevantPrefix.length);
|
|
161
|
-
}
|
|
162
|
-
else {
|
|
163
|
-
return tokens.endOffsetsAndMetadata;
|
|
164
|
-
}
|
|
165
|
-
}
|
|
166
|
-
async _parseAndTokenizeViewPort(model, viewportRanges) {
|
|
167
|
-
if (!this._tokenizationStoreService.hasTokens(model)) {
|
|
168
|
-
this._setInitialTokens(model);
|
|
169
|
-
}
|
|
170
|
-
for (const range of viewportRanges) {
|
|
171
|
-
const startOffsetOfRangeInDocument = model.getOffsetAt(range.getStartPosition());
|
|
172
|
-
const endOffsetOfRangeInDocument = model.getOffsetAt(range.getEndPosition());
|
|
173
|
-
const version = model.getVersionId();
|
|
174
|
-
if (this._tokenizationStoreService.rangeHasTokens(model, range, TokenQuality.ViewportGuess)) {
|
|
175
|
-
continue;
|
|
176
|
-
}
|
|
177
|
-
const content = model.getValueInRange(range);
|
|
178
|
-
const tokenUpdates = await this._forceParseAndTokenizeContent(model, range, startOffsetOfRangeInDocument, endOffsetOfRangeInDocument, content, true);
|
|
179
|
-
if (!tokenUpdates || this._tokenizationStoreService.rangeHasTokens(model, range, TokenQuality.ViewportGuess)) {
|
|
180
|
-
continue;
|
|
181
|
-
}
|
|
182
|
-
if (tokenUpdates.length === 0) {
|
|
183
|
-
continue;
|
|
184
|
-
}
|
|
185
|
-
const lastToken = tokenUpdates[tokenUpdates.length - 1];
|
|
186
|
-
const oldRangeLength = lastToken.startOffsetInclusive + lastToken.length - tokenUpdates[0].startOffsetInclusive;
|
|
187
|
-
this._tokenizationStoreService.updateTokens(model, version, [{ newTokens: tokenUpdates, oldRangeLength }], TokenQuality.ViewportGuess);
|
|
188
|
-
this._onDidChangeTokens.fire({ textModel: model, changes: { semanticTokensApplied: false, ranges: [{ fromLineNumber: range.startLineNumber, toLineNumber: range.endLineNumber }] } });
|
|
189
|
-
}
|
|
190
|
-
}
|
|
191
|
-
guessTokensForLinesContent(lineNumber, textModel, lines) {
|
|
192
|
-
if (lines.length === 0) {
|
|
193
|
-
return undefined;
|
|
194
|
-
}
|
|
195
|
-
const lineContent = lines.join(textModel.getEOL());
|
|
196
|
-
const range = ( new Range(1, 1, lineNumber + lines.length, lines[lines.length - 1].length + 1));
|
|
197
|
-
const startOffset = textModel.getOffsetAt({ lineNumber, column: 1 });
|
|
198
|
-
const tokens = this._forceParseAndTokenizeContent(textModel, range, startOffset, startOffset + lineContent.length, lineContent, false);
|
|
199
|
-
if (!tokens) {
|
|
200
|
-
return undefined;
|
|
201
|
-
}
|
|
202
|
-
const tokensByLine = ( new Array(lines.length));
|
|
203
|
-
let tokensIndex = 0;
|
|
204
|
-
let tokenStartOffset = 0;
|
|
205
|
-
let lineStartOffset = 0;
|
|
206
|
-
for (let i = 0; i < lines.length; i++) {
|
|
207
|
-
const tokensForLine = [];
|
|
208
|
-
let moveToNextLine = false;
|
|
209
|
-
for (let j = tokensIndex; (!moveToNextLine && (j < tokens.length)); j++) {
|
|
210
|
-
const token = tokens[j];
|
|
211
|
-
const lineAdjustedEndOffset = token.endOffset - lineStartOffset;
|
|
212
|
-
const lineAdjustedStartOffset = tokenStartOffset - lineStartOffset;
|
|
213
|
-
if (lineAdjustedEndOffset <= lines[i].length) {
|
|
214
|
-
tokensForLine.push({ endOffset: lineAdjustedEndOffset, metadata: token.metadata });
|
|
215
|
-
tokensIndex++;
|
|
216
|
-
}
|
|
217
|
-
else if (lineAdjustedStartOffset < lines[i].length) {
|
|
218
|
-
const partialToken = { endOffset: lines[i].length, metadata: token.metadata };
|
|
219
|
-
tokensForLine.push(partialToken);
|
|
220
|
-
moveToNextLine = true;
|
|
221
|
-
}
|
|
222
|
-
else {
|
|
223
|
-
moveToNextLine = true;
|
|
224
|
-
}
|
|
225
|
-
tokenStartOffset = token.endOffset;
|
|
226
|
-
}
|
|
227
|
-
tokensByLine[i] = this._endOffsetTokensToUint32Array(tokensForLine);
|
|
228
|
-
lineStartOffset += lines[i].length + textModel.getEOL().length;
|
|
229
|
-
}
|
|
230
|
-
return tokensByLine;
|
|
231
|
-
}
|
|
232
|
-
_emptyTokensForOffsetAndLength(offset, length, emptyToken) {
|
|
233
|
-
return { token: emptyToken, length: offset + length, startOffsetInclusive: 0 };
|
|
234
|
-
}
|
|
235
|
-
_createEmptyTokens(textModel) {
|
|
236
|
-
const emptyToken = this._emptyToken();
|
|
237
|
-
const modelEndOffset = textModel.getValueLength();
|
|
238
|
-
const emptyTokens = [this._emptyTokensForOffsetAndLength(0, modelEndOffset, emptyToken)];
|
|
239
|
-
return emptyTokens;
|
|
240
|
-
}
|
|
241
|
-
_firstTreeUpdate(textModel, versionId, tree) {
|
|
242
|
-
this._setInitialTokens(textModel);
|
|
243
|
-
return this._setViewPortTokens(textModel, versionId, tree);
|
|
244
|
-
}
|
|
245
|
-
_setViewPortTokens(textModel, versionId, tree) {
|
|
246
|
-
const maxLine = textModel.getLineCount();
|
|
247
|
-
let rangeChanges;
|
|
248
|
-
const editor = this._codeEditors.getEditorForModel(textModel);
|
|
249
|
-
if (editor) {
|
|
250
|
-
const viewPort = editor.getVisibleRangesPlusViewportAboveBelow();
|
|
251
|
-
const ranges = ( new Array(viewPort.length));
|
|
252
|
-
rangeChanges = ( new Array(viewPort.length));
|
|
253
|
-
for (let i = 0; i < viewPort.length; i++) {
|
|
254
|
-
const range = viewPort[i];
|
|
255
|
-
ranges[i] = { fromLineNumber: range.startLineNumber, toLineNumber: range.endLineNumber < maxLine ? range.endLineNumber : maxLine };
|
|
256
|
-
const newRangeStartOffset = textModel.getOffsetAt(range.getStartPosition());
|
|
257
|
-
const newRangeEndOffset = textModel.getOffsetAt(range.getEndPosition());
|
|
258
|
-
rangeChanges[i] = {
|
|
259
|
-
newRange: range,
|
|
260
|
-
newRangeStartOffset,
|
|
261
|
-
newRangeEndOffset,
|
|
262
|
-
};
|
|
263
|
-
}
|
|
264
|
-
}
|
|
265
|
-
else {
|
|
266
|
-
const valueLength = textModel.getValueLength();
|
|
267
|
-
rangeChanges = [{ newRange: ( new Range(1, 1, maxLine, textModel.getLineMaxColumn(maxLine))), newRangeStartOffset: 0, newRangeEndOffset: valueLength }];
|
|
268
|
-
}
|
|
269
|
-
return this._handleTreeUpdate(rangeChanges, textModel, versionId, tree);
|
|
270
|
-
}
|
|
271
|
-
_handleTreeUpdate(ranges, textModel, versionId, textModelTreeSitter) {
|
|
272
|
-
const tree = textModelTreeSitter.parseResult?.tree;
|
|
273
|
-
if (!tree) {
|
|
274
|
-
return;
|
|
275
|
-
}
|
|
276
|
-
const rangeChanges = [];
|
|
277
|
-
const chunkSize = 1000;
|
|
278
|
-
for (let i = 0; i < ranges.length; i++) {
|
|
279
|
-
const rangeLinesLength = ranges[i].newRange.endLineNumber - ranges[i].newRange.startLineNumber;
|
|
280
|
-
if (rangeLinesLength > chunkSize) {
|
|
281
|
-
const fullRangeEndLineNumber = ranges[i].newRange.endLineNumber;
|
|
282
|
-
let chunkLineStart = ranges[i].newRange.startLineNumber;
|
|
283
|
-
let chunkColumnStart = ranges[i].newRange.startColumn;
|
|
284
|
-
let chunkLineEnd = chunkLineStart + chunkSize;
|
|
285
|
-
do {
|
|
286
|
-
const chunkStartingPosition = ( new Position(chunkLineStart, chunkColumnStart));
|
|
287
|
-
const chunkEndColumn = ((chunkLineEnd === ranges[i].newRange.endLineNumber) ? ranges[i].newRange.endColumn : textModel.getLineMaxColumn(chunkLineEnd));
|
|
288
|
-
const chunkEndPosition = ( new Position(chunkLineEnd, chunkEndColumn));
|
|
289
|
-
const chunkRange = Range.fromPositions(chunkStartingPosition, chunkEndPosition);
|
|
290
|
-
rangeChanges.push({
|
|
291
|
-
range: chunkRange,
|
|
292
|
-
startOffset: textModel.getOffsetAt(chunkRange.getStartPosition()),
|
|
293
|
-
endOffset: textModel.getOffsetAt(chunkRange.getEndPosition())
|
|
294
|
-
});
|
|
295
|
-
chunkLineStart = chunkLineEnd + 1;
|
|
296
|
-
chunkColumnStart = 1;
|
|
297
|
-
if (chunkLineEnd < fullRangeEndLineNumber && chunkLineEnd + chunkSize > fullRangeEndLineNumber) {
|
|
298
|
-
chunkLineEnd = fullRangeEndLineNumber;
|
|
299
|
-
}
|
|
300
|
-
else {
|
|
301
|
-
chunkLineEnd = chunkLineEnd + chunkSize;
|
|
302
|
-
}
|
|
303
|
-
} while (chunkLineEnd <= fullRangeEndLineNumber);
|
|
304
|
-
}
|
|
305
|
-
else {
|
|
306
|
-
if ((i === 0) || (rangeChanges[i - 1].endOffset < ranges[i].newRangeStartOffset)) {
|
|
307
|
-
rangeChanges.push({
|
|
308
|
-
range: ranges[i].newRange,
|
|
309
|
-
startOffset: ranges[i].newRangeStartOffset,
|
|
310
|
-
endOffset: ranges[i].newRangeEndOffset
|
|
311
|
-
});
|
|
312
|
-
}
|
|
313
|
-
else if (rangeChanges[i - 1].endOffset < ranges[i].newRangeEndOffset) {
|
|
314
|
-
const startPosition = textModel.getPositionAt(rangeChanges[i - 1].endOffset + 1);
|
|
315
|
-
const range = ( new Range(
|
|
316
|
-
startPosition.lineNumber,
|
|
317
|
-
startPosition.column,
|
|
318
|
-
ranges[i].newRange.endLineNumber,
|
|
319
|
-
ranges[i].newRange.endColumn
|
|
320
|
-
));
|
|
321
|
-
rangeChanges.push({
|
|
322
|
-
range,
|
|
323
|
-
startOffset: rangeChanges[i - 1].endOffset + 1,
|
|
324
|
-
endOffset: ranges[i].newRangeEndOffset
|
|
325
|
-
});
|
|
326
|
-
}
|
|
327
|
-
}
|
|
328
|
-
}
|
|
329
|
-
const captures = ( rangeChanges.map(range => this._getCaptures(range.range, textModelTreeSitter, tree)));
|
|
330
|
-
return this._updateTreeForRanges(textModel, rangeChanges, versionId, tree, captures).then(() => {
|
|
331
|
-
const tree = this._getTree(textModel);
|
|
332
|
-
if (!textModel.isDisposed() && (tree?.parseResult?.versionId === textModel.getVersionId())) {
|
|
333
|
-
this._refreshNeedsRefresh(textModel, versionId);
|
|
334
|
-
}
|
|
335
|
-
});
|
|
336
|
-
}
|
|
337
|
-
async _updateTreeForRanges(textModel, rangeChanges, versionId, tree, captures) {
|
|
338
|
-
let tokenUpdate;
|
|
339
|
-
for (let i = 0; i < rangeChanges.length; i++) {
|
|
340
|
-
if (!textModel.isDisposed() && versionId !== textModel.getVersionId()) {
|
|
341
|
-
break;
|
|
342
|
-
}
|
|
343
|
-
const capture = captures[i];
|
|
344
|
-
const range = rangeChanges[i];
|
|
345
|
-
const updates = this.getTokensInRange(textModel, range.range, range.startOffset, range.endOffset, tree, capture);
|
|
346
|
-
if (updates) {
|
|
347
|
-
tokenUpdate = { newTokens: updates };
|
|
348
|
-
}
|
|
349
|
-
else {
|
|
350
|
-
tokenUpdate = { newTokens: [] };
|
|
351
|
-
}
|
|
352
|
-
this._tokenizationStoreService.updateTokens(textModel, versionId, [tokenUpdate], TokenQuality.Accurate);
|
|
353
|
-
this._onDidChangeTokens.fire({
|
|
354
|
-
textModel: textModel,
|
|
355
|
-
changes: {
|
|
356
|
-
semanticTokensApplied: false,
|
|
357
|
-
ranges: [{ fromLineNumber: range.range.getStartPosition().lineNumber, toLineNumber: range.range.getEndPosition().lineNumber }]
|
|
358
|
-
}
|
|
359
|
-
});
|
|
360
|
-
await ( new Promise(resolve => setTimeout0(resolve)));
|
|
361
|
-
}
|
|
362
|
-
this._onDidCompleteBackgroundTokenization.fire({ textModel });
|
|
363
|
-
}
|
|
364
|
-
_refreshNeedsRefresh(textModel, versionId) {
|
|
365
|
-
const rangesToRefresh = this._tokenizationStoreService.getNeedsRefresh(textModel);
|
|
366
|
-
if (rangesToRefresh.length === 0) {
|
|
367
|
-
return;
|
|
368
|
-
}
|
|
369
|
-
const rangeChanges = ( new Array(rangesToRefresh.length));
|
|
370
|
-
for (let i = 0; i < rangesToRefresh.length; i++) {
|
|
371
|
-
const range = rangesToRefresh[i];
|
|
372
|
-
rangeChanges[i] = {
|
|
373
|
-
newRange: range.range,
|
|
374
|
-
newRangeStartOffset: range.startOffset,
|
|
375
|
-
newRangeEndOffset: range.endOffset
|
|
376
|
-
};
|
|
377
|
-
}
|
|
378
|
-
const tree = this._getTree(textModel);
|
|
379
|
-
if (tree?.parseResult?.tree && tree.parseResult.versionId === versionId) {
|
|
380
|
-
this._handleTreeUpdate(rangeChanges, textModel, versionId, tree);
|
|
381
|
-
}
|
|
382
|
-
}
|
|
383
|
-
_rangeTokensAsUpdates(rangeOffset, endOffsetToken, startingOffsetInArray) {
|
|
384
|
-
const updates = [];
|
|
385
|
-
let lastEnd = 0;
|
|
386
|
-
for (const token of endOffsetToken) {
|
|
387
|
-
if (token.endOffset <= lastEnd || (startingOffsetInArray && (token.endOffset < startingOffsetInArray))) {
|
|
388
|
-
continue;
|
|
389
|
-
}
|
|
390
|
-
let tokenUpdate;
|
|
391
|
-
if (startingOffsetInArray && (lastEnd < startingOffsetInArray)) {
|
|
392
|
-
tokenUpdate = { startOffsetInclusive: rangeOffset + startingOffsetInArray, length: token.endOffset - startingOffsetInArray, token: token.metadata };
|
|
393
|
-
}
|
|
394
|
-
else {
|
|
395
|
-
tokenUpdate = { startOffsetInclusive: rangeOffset + lastEnd, length: token.endOffset - lastEnd, token: token.metadata };
|
|
396
|
-
}
|
|
397
|
-
updates.push(tokenUpdate);
|
|
398
|
-
lastEnd = token.endOffset;
|
|
399
|
-
}
|
|
400
|
-
return updates;
|
|
401
|
-
}
|
|
402
|
-
getTokensInRange(textModel, range, rangeStartOffset, rangeEndOffset, tree, captures) {
|
|
403
|
-
const tokens = captures ? this._tokenizeCapturesWithMetadata(tree, captures, rangeStartOffset, rangeEndOffset) : this._tokenize(range, rangeStartOffset, rangeEndOffset, textModel);
|
|
404
|
-
if (tokens?.endOffsetsAndMetadata) {
|
|
405
|
-
return this._rangeTokensAsUpdates(rangeStartOffset, tokens.endOffsetsAndMetadata);
|
|
406
|
-
}
|
|
407
|
-
return undefined;
|
|
408
|
-
}
|
|
409
|
-
_getTree(textModel) {
|
|
410
|
-
return this._treeSitterService.getParseResult(textModel);
|
|
411
|
-
}
|
|
412
|
-
_ensureQuery() {
|
|
413
|
-
if (!this._query) {
|
|
414
|
-
const language = this._treeSitterService.getOrInitLanguage(this._languageId);
|
|
415
|
-
if (!language) {
|
|
416
|
-
if (!this._languageAddedListener) {
|
|
417
|
-
this._languageAddedListener = this._register(Event.onceIf(this._treeSitterService.onDidAddLanguage, e => e.id === this._languageId)((e) => {
|
|
418
|
-
this._query = new this.Query(e.language, this._queries);
|
|
419
|
-
}));
|
|
420
|
-
}
|
|
421
|
-
return;
|
|
422
|
-
}
|
|
423
|
-
this._query = new this.Query(language, this._queries);
|
|
424
|
-
}
|
|
425
|
-
return this._query;
|
|
426
|
-
}
|
|
427
|
-
_updateTheme(e) {
|
|
428
|
-
this._colorThemeData = this._themeService.getColorTheme();
|
|
429
|
-
for (const model of this._codeEditors.textModels) {
|
|
430
|
-
const modelRange = model.getFullModelRange();
|
|
431
|
-
this._tokenizationStoreService.markForRefresh(model, modelRange);
|
|
432
|
-
const editor = this._codeEditors.getEditorForModel(model);
|
|
433
|
-
if (editor) {
|
|
434
|
-
this._parseAndTokenizeViewPort(model, editor.getVisibleRangesPlusViewportAboveBelow());
|
|
435
|
-
}
|
|
436
|
-
}
|
|
437
|
-
}
|
|
438
|
-
captureAtPosition(lineNumber, column, textModel) {
|
|
439
|
-
const textModelTreeSitter = this._getTree(textModel);
|
|
440
|
-
if (!textModelTreeSitter?.parseResult?.tree) {
|
|
441
|
-
return [];
|
|
442
|
-
}
|
|
443
|
-
const captures = this._captureAtRangeWithInjections(( new Range(lineNumber, column, lineNumber, column + 1)), textModelTreeSitter, textModelTreeSitter.parseResult.tree);
|
|
444
|
-
return captures;
|
|
445
|
-
}
|
|
446
|
-
captureAtRangeTree(range, tree, textModelTreeSitter) {
|
|
447
|
-
const captures = textModelTreeSitter ? this._captureAtRangeWithInjections(range, textModelTreeSitter, tree) : this._captureAtRange(range, tree);
|
|
448
|
-
return captures;
|
|
449
|
-
}
|
|
450
|
-
_captureAtRange(range, tree) {
|
|
451
|
-
const query = this._ensureQuery();
|
|
452
|
-
if (!tree || !query) {
|
|
453
|
-
return [];
|
|
454
|
-
}
|
|
455
|
-
return ( query.captures(tree.rootNode, { startPosition: { row: range.startLineNumber - 1, column: range.startColumn - 1 }, endPosition: { row: range.endLineNumber - 1, column: range.endColumn - 1 } }).map(capture => ({
|
|
456
|
-
name: capture.name,
|
|
457
|
-
text: capture.node.text,
|
|
458
|
-
node: {
|
|
459
|
-
startIndex: capture.node.startIndex,
|
|
460
|
-
endIndex: capture.node.endIndex,
|
|
461
|
-
startPosition: {
|
|
462
|
-
lineNumber: capture.node.startPosition.row + 1,
|
|
463
|
-
column: capture.node.startPosition.column + 1
|
|
464
|
-
},
|
|
465
|
-
endPosition: {
|
|
466
|
-
lineNumber: capture.node.endPosition.row + 1,
|
|
467
|
-
column: capture.node.endPosition.column + 1
|
|
468
|
-
}
|
|
469
|
-
},
|
|
470
|
-
encodedLanguageId: this._encodedLanguageId
|
|
471
|
-
})));
|
|
472
|
-
}
|
|
473
|
-
_captureAtRangeWithInjections(range, textModelTreeSitter, tree) {
|
|
474
|
-
const query = this._ensureQuery();
|
|
475
|
-
if (!textModelTreeSitter?.parseResult || !query) {
|
|
476
|
-
return [];
|
|
477
|
-
}
|
|
478
|
-
const captures = this._captureAtRange(range, tree);
|
|
479
|
-
for (let i = 0; i < captures.length; i++) {
|
|
480
|
-
const capture = captures[i];
|
|
481
|
-
const capStartLine = capture.node.startPosition.lineNumber;
|
|
482
|
-
const capEndLine = capture.node.endPosition.lineNumber;
|
|
483
|
-
const capStartColumn = capture.node.startPosition.column;
|
|
484
|
-
const capEndColumn = capture.node.endPosition.column;
|
|
485
|
-
const startLine = ((capStartLine > range.startLineNumber) && (capStartLine < range.endLineNumber)) ? capStartLine : range.startLineNumber;
|
|
486
|
-
const endLine = ((capEndLine > range.startLineNumber) && (capEndLine < range.endLineNumber)) ? capEndLine : range.endLineNumber;
|
|
487
|
-
const startColumn = (capStartLine === range.startLineNumber) ? (capStartColumn < range.startColumn ? range.startColumn : capStartColumn) : (capStartLine < range.startLineNumber ? range.startColumn : capStartColumn);
|
|
488
|
-
const endColumn = (capEndLine === range.endLineNumber) ? (capEndColumn > range.endColumn ? range.endColumn : capEndColumn) : (capEndLine > range.endLineNumber ? range.endColumn : capEndColumn);
|
|
489
|
-
const injectionRange = ( new Range(startLine, startColumn, endLine, endColumn));
|
|
490
|
-
const injection = this._getInjectionCaptures(textModelTreeSitter, capture, injectionRange);
|
|
491
|
-
if (injection && injection.length > 0) {
|
|
492
|
-
captures.splice(i + 1, 0, ...injection);
|
|
493
|
-
i += injection.length;
|
|
494
|
-
}
|
|
495
|
-
}
|
|
496
|
-
return captures;
|
|
497
|
-
}
|
|
498
|
-
tokenizeEncoded(lineNumber, textModel) {
|
|
499
|
-
const tokens = this._tokenizeEncoded(lineNumber, textModel);
|
|
500
|
-
if (!tokens) {
|
|
501
|
-
return undefined;
|
|
502
|
-
}
|
|
503
|
-
const updates = this._rangeTokensAsUpdates(textModel.getOffsetAt({ lineNumber, column: 1 }), tokens.result);
|
|
504
|
-
if (tokens.versionId === textModel.getVersionId()) {
|
|
505
|
-
this._tokenizationStoreService.updateTokens(textModel, tokens.versionId, [{ newTokens: updates, oldRangeLength: textModel.getLineLength(lineNumber) }], TokenQuality.Accurate);
|
|
506
|
-
}
|
|
507
|
-
}
|
|
508
|
-
tokenizeEncodedInstrumented(lineNumber, textModel) {
|
|
509
|
-
const tokens = this._tokenizeEncoded(lineNumber, textModel);
|
|
510
|
-
if (!tokens) {
|
|
511
|
-
return undefined;
|
|
512
|
-
}
|
|
513
|
-
return { result: this._endOffsetTokensToUint32Array(tokens.result), captureTime: tokens.captureTime, metadataTime: tokens.metadataTime };
|
|
514
|
-
}
|
|
515
|
-
_getCaptures(range, textModelTreeSitter, tree) {
|
|
516
|
-
const captures = this._captureAtRangeWithInjections(range, textModelTreeSitter, tree);
|
|
517
|
-
return captures;
|
|
518
|
-
}
|
|
519
|
-
_tokenize(range, rangeStartOffset, rangeEndOffset, textModel) {
|
|
520
|
-
const tree = this._getTree(textModel);
|
|
521
|
-
if (!tree?.parseResult?.tree) {
|
|
522
|
-
return undefined;
|
|
523
|
-
}
|
|
524
|
-
const captures = this._getCaptures(range, tree, tree.parseResult.tree);
|
|
525
|
-
const result = this._tokenizeCapturesWithMetadata(tree.parseResult.tree, captures, rangeStartOffset, rangeEndOffset);
|
|
526
|
-
if (!result) {
|
|
527
|
-
return undefined;
|
|
528
|
-
}
|
|
529
|
-
return { ...result, versionId: tree.parseResult.versionId };
|
|
530
|
-
}
|
|
531
|
-
_createTokensFromCaptures(tree, captures, rangeStartOffset, rangeEndOffset) {
|
|
532
|
-
const stopwatch = StopWatch.create();
|
|
533
|
-
const rangeLength = rangeEndOffset - rangeStartOffset;
|
|
534
|
-
const encodedLanguageId = this._languageIdCodec.encodeLanguageId(this._languageId);
|
|
535
|
-
const baseScope = TREESITTER_BASE_SCOPES[this._languageId] || 'source';
|
|
536
|
-
if (captures.length === 0) {
|
|
537
|
-
if (tree) {
|
|
538
|
-
stopwatch.stop();
|
|
539
|
-
const endOffsetsAndMetadata = [{ endOffset: rangeLength, scopes: [], encodedLanguageId }];
|
|
540
|
-
return { endOffsets: endOffsetsAndMetadata, captureTime: stopwatch.elapsed() };
|
|
541
|
-
}
|
|
542
|
-
return undefined;
|
|
543
|
-
}
|
|
544
|
-
const endOffsetsAndScopes = Array(captures.length);
|
|
545
|
-
endOffsetsAndScopes.fill({ endOffset: 0, scopes: [baseScope], encodedLanguageId });
|
|
546
|
-
let tokenIndex = 0;
|
|
547
|
-
const increaseSizeOfTokensByOneToken = () => {
|
|
548
|
-
endOffsetsAndScopes.push({ endOffset: 0, scopes: [baseScope], encodedLanguageId });
|
|
549
|
-
};
|
|
550
|
-
const brackets = (capture, startOffset) => {
|
|
551
|
-
return (capture.name.includes('punctuation') && capture.text) ? ( Array.from(capture.text.matchAll(BRACKETS)).map(match => startOffset + match.index)) : undefined;
|
|
552
|
-
};
|
|
553
|
-
const addCurrentTokenToArray = (capture, startOffset, endOffset, position) => {
|
|
554
|
-
if (position !== undefined) {
|
|
555
|
-
const oldScopes = endOffsetsAndScopes[position].scopes;
|
|
556
|
-
let oldBracket = endOffsetsAndScopes[position].bracket;
|
|
557
|
-
const prevEndOffset = position > 0 ? endOffsetsAndScopes[position - 1].endOffset : 0;
|
|
558
|
-
if (prevEndOffset !== startOffset) {
|
|
559
|
-
let preInsertBracket = undefined;
|
|
560
|
-
if (oldBracket && oldBracket.length > 0) {
|
|
561
|
-
preInsertBracket = [];
|
|
562
|
-
const postInsertBracket = [];
|
|
563
|
-
for (let i = 0; i < oldBracket.length; i++) {
|
|
564
|
-
const bracket = oldBracket[i];
|
|
565
|
-
if (bracket < startOffset) {
|
|
566
|
-
preInsertBracket.push(bracket);
|
|
567
|
-
}
|
|
568
|
-
else if (bracket > endOffset) {
|
|
569
|
-
postInsertBracket.push(bracket);
|
|
570
|
-
}
|
|
571
|
-
}
|
|
572
|
-
if (preInsertBracket.length === 0) {
|
|
573
|
-
preInsertBracket = undefined;
|
|
574
|
-
}
|
|
575
|
-
if (postInsertBracket.length === 0) {
|
|
576
|
-
oldBracket = undefined;
|
|
577
|
-
}
|
|
578
|
-
else {
|
|
579
|
-
oldBracket = postInsertBracket;
|
|
580
|
-
}
|
|
581
|
-
}
|
|
582
|
-
endOffsetsAndScopes.splice(position, 0, { endOffset: startOffset, scopes: [...oldScopes], bracket: preInsertBracket, encodedLanguageId: capture.encodedLanguageId });
|
|
583
|
-
position++;
|
|
584
|
-
increaseSizeOfTokensByOneToken();
|
|
585
|
-
tokenIndex++;
|
|
586
|
-
}
|
|
587
|
-
endOffsetsAndScopes.splice(position, 0, { endOffset: endOffset, scopes: [...oldScopes, capture.name], bracket: brackets(capture, startOffset), encodedLanguageId: capture.encodedLanguageId });
|
|
588
|
-
endOffsetsAndScopes[tokenIndex].bracket = oldBracket;
|
|
589
|
-
}
|
|
590
|
-
else {
|
|
591
|
-
endOffsetsAndScopes[tokenIndex] = { endOffset: endOffset, scopes: [baseScope, capture.name], bracket: brackets(capture, startOffset), encodedLanguageId: capture.encodedLanguageId };
|
|
592
|
-
}
|
|
593
|
-
tokenIndex++;
|
|
594
|
-
};
|
|
595
|
-
for (let captureIndex = 0; captureIndex < captures.length; captureIndex++) {
|
|
596
|
-
const capture = captures[captureIndex];
|
|
597
|
-
const tokenEndIndex = capture.node.endIndex < rangeEndOffset ? ((capture.node.endIndex < rangeStartOffset) ? rangeStartOffset : capture.node.endIndex) : rangeEndOffset;
|
|
598
|
-
const tokenStartIndex = capture.node.startIndex < rangeStartOffset ? rangeStartOffset : capture.node.startIndex;
|
|
599
|
-
const endOffset = tokenEndIndex - rangeStartOffset;
|
|
600
|
-
let previousEndOffset;
|
|
601
|
-
const currentTokenLength = tokenEndIndex - tokenStartIndex;
|
|
602
|
-
if (captureIndex > 0) {
|
|
603
|
-
previousEndOffset = endOffsetsAndScopes[(tokenIndex - 1)].endOffset;
|
|
604
|
-
}
|
|
605
|
-
else {
|
|
606
|
-
previousEndOffset = tokenStartIndex - rangeStartOffset - 1;
|
|
607
|
-
}
|
|
608
|
-
const startOffset = endOffset - currentTokenLength;
|
|
609
|
-
if ((previousEndOffset >= 0) && (previousEndOffset < startOffset)) {
|
|
610
|
-
endOffsetsAndScopes[tokenIndex] = { endOffset: startOffset, scopes: [baseScope], encodedLanguageId: this._encodedLanguageId };
|
|
611
|
-
tokenIndex++;
|
|
612
|
-
increaseSizeOfTokensByOneToken();
|
|
613
|
-
}
|
|
614
|
-
if (currentTokenLength < 0) {
|
|
615
|
-
continue;
|
|
616
|
-
}
|
|
617
|
-
if (previousEndOffset >= endOffset) {
|
|
618
|
-
let withinTokenIndex = tokenIndex - 1;
|
|
619
|
-
let previousTokenEndOffset = endOffsetsAndScopes[withinTokenIndex].endOffset;
|
|
620
|
-
let previousTokenStartOffset = ((withinTokenIndex >= 2) ? endOffsetsAndScopes[withinTokenIndex - 1].endOffset : 0);
|
|
621
|
-
do {
|
|
622
|
-
if ((previousTokenStartOffset + currentTokenLength) === previousTokenEndOffset) {
|
|
623
|
-
if (previousTokenStartOffset === startOffset) {
|
|
624
|
-
endOffsetsAndScopes[withinTokenIndex].scopes.push(capture.name);
|
|
625
|
-
const oldBracket = endOffsetsAndScopes[withinTokenIndex].bracket;
|
|
626
|
-
endOffsetsAndScopes[withinTokenIndex].bracket = ((oldBracket && (oldBracket.length > 0)) ? oldBracket : brackets(capture, startOffset));
|
|
627
|
-
}
|
|
628
|
-
}
|
|
629
|
-
else if (previousTokenStartOffset <= startOffset) {
|
|
630
|
-
addCurrentTokenToArray(capture, startOffset, endOffset, withinTokenIndex);
|
|
631
|
-
break;
|
|
632
|
-
}
|
|
633
|
-
withinTokenIndex--;
|
|
634
|
-
previousTokenStartOffset = ((withinTokenIndex >= 1) ? endOffsetsAndScopes[withinTokenIndex - 1].endOffset : 0);
|
|
635
|
-
previousTokenEndOffset = ((withinTokenIndex >= 0) ? endOffsetsAndScopes[withinTokenIndex].endOffset : 0);
|
|
636
|
-
} while (previousTokenEndOffset > startOffset);
|
|
637
|
-
}
|
|
638
|
-
else {
|
|
639
|
-
addCurrentTokenToArray(capture, startOffset, endOffset);
|
|
640
|
-
}
|
|
641
|
-
}
|
|
642
|
-
if ((endOffsetsAndScopes[tokenIndex - 1].endOffset < rangeLength)) {
|
|
643
|
-
if (rangeLength - endOffsetsAndScopes[tokenIndex - 1].endOffset > 0) {
|
|
644
|
-
increaseSizeOfTokensByOneToken();
|
|
645
|
-
endOffsetsAndScopes[tokenIndex] = { endOffset: rangeLength, scopes: endOffsetsAndScopes[tokenIndex].scopes, encodedLanguageId: this._encodedLanguageId };
|
|
646
|
-
tokenIndex++;
|
|
647
|
-
}
|
|
648
|
-
}
|
|
649
|
-
for (let i = 0; i < endOffsetsAndScopes.length; i++) {
|
|
650
|
-
const token = endOffsetsAndScopes[i];
|
|
651
|
-
if (token.endOffset === 0 && i !== 0) {
|
|
652
|
-
endOffsetsAndScopes.splice(i, endOffsetsAndScopes.length - i);
|
|
653
|
-
break;
|
|
654
|
-
}
|
|
655
|
-
}
|
|
656
|
-
const captureTime = stopwatch.elapsed();
|
|
657
|
-
return { endOffsets: endOffsetsAndScopes, captureTime };
|
|
658
|
-
}
|
|
659
|
-
_getInjectionCaptures(textModelTreeSitter, parentCapture, range) {
|
|
660
|
-
const injection = textModelTreeSitter.getInjection(parentCapture.node.startIndex, this._languageId);
|
|
661
|
-
if (!injection?.tree || injection.versionId !== textModelTreeSitter.parseResult?.versionId) {
|
|
662
|
-
return undefined;
|
|
663
|
-
}
|
|
664
|
-
const feature = TreeSitterTokenizationRegistry.get(injection.languageId);
|
|
665
|
-
if (!feature) {
|
|
666
|
-
return undefined;
|
|
667
|
-
}
|
|
668
|
-
return feature.captureAtRangeTree(range, injection.tree, textModelTreeSitter);
|
|
669
|
-
}
|
|
670
|
-
_tokenizeCapturesWithMetadata(tree, captures, rangeStartOffset, rangeEndOffset) {
|
|
671
|
-
const stopwatch = StopWatch.create();
|
|
672
|
-
const emptyTokens = this._createTokensFromCaptures(tree, captures, rangeStartOffset, rangeEndOffset);
|
|
673
|
-
if (!emptyTokens) {
|
|
674
|
-
return undefined;
|
|
675
|
-
}
|
|
676
|
-
const endOffsetsAndScopes = emptyTokens.endOffsets;
|
|
677
|
-
for (let i = 0; i < endOffsetsAndScopes.length; i++) {
|
|
678
|
-
const token = endOffsetsAndScopes[i];
|
|
679
|
-
token.metadata = findMetadata(this._colorThemeData, token.scopes, token.encodedLanguageId, !!token.bracket && (token.bracket.length > 0));
|
|
680
|
-
}
|
|
681
|
-
const metadataTime = stopwatch.elapsed();
|
|
682
|
-
return { endOffsetsAndMetadata: endOffsetsAndScopes, captureTime: emptyTokens.captureTime, metadataTime };
|
|
683
|
-
}
|
|
684
|
-
_emptyToken() {
|
|
685
|
-
return findMetadata(this._colorThemeData, [], this._encodedLanguageId, false);
|
|
686
|
-
}
|
|
687
|
-
_tokenizeEncoded(lineNumber, textModel) {
|
|
688
|
-
const lineOffset = textModel.getOffsetAt({ lineNumber: lineNumber, column: 1 });
|
|
689
|
-
const maxLine = textModel.getLineCount();
|
|
690
|
-
const lineEndOffset = (lineNumber + 1 <= maxLine) ? textModel.getOffsetAt({ lineNumber: lineNumber + 1, column: 1 }) : textModel.getValueLength();
|
|
691
|
-
const lineLength = lineEndOffset - lineOffset;
|
|
692
|
-
const result = this._tokenize(( new Range(lineNumber, 1, lineNumber, lineLength + 1)), lineOffset, lineEndOffset, textModel);
|
|
693
|
-
if (!result) {
|
|
694
|
-
return undefined;
|
|
695
|
-
}
|
|
696
|
-
return { result: result.endOffsetsAndMetadata, captureTime: result.captureTime, metadataTime: result.metadataTime, versionId: result.versionId };
|
|
697
|
-
}
|
|
698
|
-
_endOffsetTokensToUint32Array(endOffsetsAndMetadata) {
|
|
699
|
-
const uint32Array = ( new Uint32Array(endOffsetsAndMetadata.length * 2));
|
|
700
|
-
for (let i = 0; i < endOffsetsAndMetadata.length; i++) {
|
|
701
|
-
uint32Array[i * 2] = endOffsetsAndMetadata[i].endOffset;
|
|
702
|
-
uint32Array[i * 2 + 1] = endOffsetsAndMetadata[i].metadata;
|
|
703
|
-
}
|
|
704
|
-
return uint32Array;
|
|
705
|
-
}
|
|
706
|
-
dispose() {
|
|
707
|
-
super.dispose();
|
|
708
|
-
this._query?.delete();
|
|
709
|
-
this._query = undefined;
|
|
710
|
-
}
|
|
711
|
-
};
|
|
712
|
-
TreeSitterTokenizationSupport = ( __decorate([
|
|
713
|
-
( __param(4, ITreeSitterParserService)),
|
|
714
|
-
( __param(5, IWorkbenchThemeService)),
|
|
715
|
-
( __param(6, ITreeSitterTokenizationStoreService)),
|
|
716
|
-
( __param(7, IInstantiationService))
|
|
717
|
-
], TreeSitterTokenizationSupport));
|
|
718
|
-
|
|
719
|
-
export { TREESITTER_BASE_SCOPES, TreeSitterTokenizationFeature, TreeSitterTokenizationSupport };
|