From e1ea829d23495c395f02afed1bdce298f6384aad Mon Sep 17 00:00:00 2001 From: Alex Ross Date: Tue, 7 May 2024 17:31:37 +0200 Subject: [PATCH 01/37] Make space for tree sitter --- src/vs/editor/common/languages.ts | 30 ++++++--- src/vs/editor/common/model/textModel.ts | 3 + .../common/model/tokenizationTextModelPart.ts | 67 ++++++++++++++----- .../editor/common/model/treeSitterTokens.ts | 26 +++++++ src/vs/editor/common/services/modelService.ts | 1 + src/vs/editor/common/tokenizationRegistry.ts | 22 +++--- .../browser/peek/referencesWidget.ts | 4 +- .../bulkEdit/browser/preview/bulkEditTree.ts | 4 +- 8 files changed, 120 insertions(+), 37 deletions(-) create mode 100644 src/vs/editor/common/model/treeSitterTokens.ts diff --git a/src/vs/editor/common/languages.ts b/src/vs/editor/common/languages.ts index 68fbf632fb4cf..bf4b0d8614400 100644 --- a/src/vs/editor/common/languages.ts +++ b/src/vs/editor/common/languages.ts @@ -82,6 +82,14 @@ export class EncodedTokenizationResult { } } +/** + * An intermediate interface for scaffolding the new tree sitter tokenization support. Not final. + * @internal + */ +export interface IMockTreeSitterTokenizationSupport { + +} + /** * @internal */ @@ -2090,14 +2098,14 @@ export interface ITokenizationSupportChangedEvent { /** * @internal */ -export interface ILazyTokenizationSupport { - get tokenizationSupport(): Promise; +export interface ILazyTokenizationSupport { + get tokenizationSupport(): Promise; } /** * @internal */ -export class LazyTokenizationSupport implements IDisposable, ILazyTokenizationSupport { +export class LazyTokenizationSupport implements IDisposable, ILazyTokenizationSupport { private _tokenizationSupport: Promise | null = null; constructor(private readonly createSupport: () => Promise) { @@ -2124,7 +2132,7 @@ export class LazyTokenizationSupport implements IDisposable, ILazyTokenizationSu /** * @internal */ -export interface ITokenizationRegistry { +export interface ITokenizationRegistry { /** * An event triggered when: @@ -2142,24 +2150,24 @@ export interface ITokenizationRegistry { /** * Register a tokenization support. */ - register(languageId: string, support: ITokenizationSupport): IDisposable; + register(languageId: string, support: TSupport): IDisposable; /** * Register a tokenization support factory. */ - registerFactory(languageId: string, factory: ILazyTokenizationSupport): IDisposable; + registerFactory(languageId: string, factory: ILazyTokenizationSupport): IDisposable; /** * Get or create the tokenization support for a language. * Returns `null` if not found. */ - getOrCreate(languageId: string): Promise; + getOrCreate(languageId: string): Promise; /** * Get the tokenization support for a language. * Returns `null` if not found. */ - get(languageId: string): ITokenizationSupport | null; + get(languageId: string): TSupport | null; /** * Returns false if a factory is still pending. @@ -2179,8 +2187,12 @@ export interface ITokenizationRegistry { /** * @internal */ -export const TokenizationRegistry: ITokenizationRegistry = new TokenizationRegistryImpl(); +export const TokenizationRegistry: ITokenizationRegistry = new TokenizationRegistryImpl(); +/** + * @internal + */ +export const TreeSitterTokenizationRegistry: ITokenizationRegistry = new TokenizationRegistryImpl(); /** * @internal diff --git a/src/vs/editor/common/model/textModel.ts b/src/vs/editor/common/model/textModel.ts index 626217e8bffd9..11e61c391ac08 100644 --- a/src/vs/editor/common/model/textModel.ts +++ b/src/vs/editor/common/model/textModel.ts @@ -43,6 +43,7 @@ import { IBracketPairsTextModelPart } from 'vs/editor/common/textModelBracketPai import { IModelContentChangedEvent, IModelDecorationsChangedEvent, IModelOptionsChangedEvent, InternalModelContentChangeEvent, LineInjectedText, ModelInjectedTextChangedEvent, ModelRawChange, ModelRawContentChangedEvent, ModelRawEOLChanged, ModelRawFlush, ModelRawLineChanged, ModelRawLinesDeleted, ModelRawLinesInserted } from 'vs/editor/common/textModelEvents'; import { IGuidesTextModelPart } from 'vs/editor/common/textModelGuides'; import { ITokenizationTextModelPart } from 'vs/editor/common/tokenizationTextModelPart'; +import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { IColorTheme } from 'vs/platform/theme/common/themeService'; import { IUndoRedoService, ResourceEditStackSnapshot, UndoRedoGroup } from 'vs/platform/undoRedo/common/undoRedo'; @@ -299,6 +300,7 @@ export class TextModel extends Disposable implements model.ITextModel, IDecorati @IUndoRedoService private readonly _undoRedoService: IUndoRedoService, @ILanguageService private readonly _languageService: ILanguageService, @ILanguageConfigurationService private readonly _languageConfigurationService: ILanguageConfigurationService, + @IConfigurationService configurationService: IConfigurationService ) { super(); @@ -334,6 +336,7 @@ export class TextModel extends Disposable implements model.ITextModel, IDecorati this._bracketPairs, languageId, this._attachedViews, + configurationService ); const bufferLineCount = this._buffer.getLineCount(); diff --git a/src/vs/editor/common/model/tokenizationTextModelPart.ts b/src/vs/editor/common/model/tokenizationTextModelPart.ts index 804f63c6a2800..ff79dd9eb8e65 100644 --- a/src/vs/editor/common/model/tokenizationTextModelPart.ts +++ b/src/vs/editor/common/model/tokenizationTextModelPart.ts @@ -15,7 +15,7 @@ import { IPosition, Position } from 'vs/editor/common/core/position'; import { Range } from 'vs/editor/common/core/range'; import { IWordAtPosition, getWordAtText } from 'vs/editor/common/core/wordHelper'; import { StandardTokenType } from 'vs/editor/common/encodedTokenAttributes'; -import { IBackgroundTokenizationStore, IBackgroundTokenizer, ILanguageIdCodec, IState, ITokenizationSupport, TokenizationRegistry } from 'vs/editor/common/languages'; +import { IBackgroundTokenizationStore, IBackgroundTokenizer, ILanguageIdCodec, IState, ITokenizationSupport, TokenizationRegistry, TreeSitterTokenizationRegistry } from 'vs/editor/common/languages'; import { ILanguageService } from 'vs/editor/common/languages/language'; import { ILanguageConfigurationService, ResolvedLanguageConfiguration } from 'vs/editor/common/languages/languageConfigurationRegistry'; import { IAttachedView } from 'vs/editor/common/model'; @@ -23,6 +23,7 @@ import { BracketPairsTextModelPart } from 'vs/editor/common/model/bracketPairsTe import { AttachedViews, IAttachedViewState, TextModel } from 'vs/editor/common/model/textModel'; import { TextModelPart } from 'vs/editor/common/model/textModelPart'; import { DefaultBackgroundTokenizer, TokenizerWithStateStoreAndTextModel, TrackingTokenizationStateStore } from 'vs/editor/common/model/textModelTokens'; +import { TreeSitterTokens } from 'vs/editor/common/model/treeSitterTokens'; import { IModelContentChangedEvent, IModelLanguageChangedEvent, IModelLanguageConfigurationChangedEvent, IModelTokensChangedEvent } from 'vs/editor/common/textModelEvents'; import { BackgroundTokenizationState, ITokenizationTextModelPart } from 'vs/editor/common/tokenizationTextModelPart'; import { ContiguousMultilineTokens } from 'vs/editor/common/tokens/contiguousMultilineTokens'; @@ -31,6 +32,10 @@ import { ContiguousTokensStore } from 'vs/editor/common/tokens/contiguousTokensS import { LineTokens } from 'vs/editor/common/tokens/lineTokens'; import { SparseMultilineTokens } from 'vs/editor/common/tokens/sparseMultilineTokens'; import { SparseTokensStore } from 'vs/editor/common/tokens/sparseTokensStore'; +import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; + +// Setting value will be an array of language IDs that will prefer tree sitter tokenization over textmate when they both exist. +const TOKENIZATION_PROVIDER_SETTING = 'editor.experimental.preferTreeSitter'; export class TokenizationTextModelPart extends TextModelPart implements ITokenizationTextModelPart { private readonly _semanticTokens: SparseTokensStore = new SparseTokensStore(this._languageService.languageIdCodec); @@ -44,7 +49,8 @@ export class TokenizationTextModelPart extends TextModelPart implements ITokeniz private readonly _onDidChangeTokens: Emitter = this._register(new Emitter()); public readonly onDidChangeTokens: Event = this._onDidChangeTokens.event; - private readonly grammarTokens = this._register(new GrammarTokens(this._languageService.languageIdCodec, this._textModel, () => this._languageId, this._attachedViews)); + private grammarTokens: GrammarTokens | undefined; + private treeSitterTokens: TreeSitterTokens | undefined; constructor( private readonly _languageService: ILanguageService, @@ -53,6 +59,7 @@ export class TokenizationTextModelPart extends TextModelPart implements ITokeniz private readonly _bracketPairsTextModelPart: BracketPairsTextModelPart, private _languageId: string, private readonly _attachedViews: AttachedViews, + private readonly _configurationService: IConfigurationService, ) { super(); @@ -62,6 +69,11 @@ export class TokenizationTextModelPart extends TextModelPart implements ITokeniz } })); + this.createPreferredTokenProvider(); + } + + private createGrammarTokens() { + this.grammarTokens = this._register(new GrammarTokens(this._languageService.languageIdCodec, this._textModel, () => this._languageId, this._attachedViews)); this._register(this.grammarTokens.onDidChangeTokens(e => { this._emitModelTokensChangedEvent(e); })); @@ -71,6 +83,31 @@ export class TokenizationTextModelPart extends TextModelPart implements ITokeniz })); } + private createTreeSitterTokens() { + this.treeSitterTokens = this._register(new TreeSitterTokens(this._languageService.languageIdCodec)); + } + + private createPreferredTokenProvider() { + const preferTreeSitter: string[] = this._configurationService.getValue(TOKENIZATION_PROVIDER_SETTING) ?? []; + if (preferTreeSitter.includes(this._languageId) && TreeSitterTokenizationRegistry.get(this._languageId)) { + if (this.treeSitterTokens) { + this.treeSitterTokens.resetTokenization(true); + } else { + this.grammarTokens?.dispose(); + this.grammarTokens = undefined; + this.createTreeSitterTokens(); + } + } else { + if (this.grammarTokens) { + this.grammarTokens.resetTokenization(true); + } else { + this.treeSitterTokens?.dispose(); + this.treeSitterTokens = undefined; + this.createGrammarTokens(); + } + } + } + _hasListeners(): boolean { return (this._onDidChangeLanguage.hasListeners() || this._onDidChangeLanguageConfiguration.hasListeners() @@ -94,11 +131,11 @@ export class TokenizationTextModelPart extends TextModelPart implements ITokeniz } } - this.grammarTokens.handleDidChangeContent(e); + this.grammarTokens?.handleDidChangeContent(e); } public handleDidChangeAttached(): void { - this.grammarTokens.handleDidChangeAttached(); + this.grammarTokens?.handleDidChangeAttached(); } /** @@ -106,7 +143,7 @@ export class TokenizationTextModelPart extends TextModelPart implements ITokeniz */ public getLineTokens(lineNumber: number): LineTokens { this.validateLineNumber(lineNumber); - const syntacticTokens = this.grammarTokens.getLineTokens(lineNumber); + const syntacticTokens = (this.treeSitterTokens?.getLineTokens(lineNumber) ?? this.grammarTokens?.getLineTokens(lineNumber))!; return this._semanticTokens.addSparseTokens(lineNumber, syntacticTokens); } @@ -126,43 +163,43 @@ export class TokenizationTextModelPart extends TextModelPart implements ITokeniz } public get hasTokens(): boolean { - return this.grammarTokens.hasTokens; + return !!this.grammarTokens?.hasTokens; } public resetTokenization() { - this.grammarTokens.resetTokenization(); + this.grammarTokens?.resetTokenization(); } public get backgroundTokenizationState() { - return this.grammarTokens.backgroundTokenizationState; + return this.grammarTokens?.backgroundTokenizationState ?? BackgroundTokenizationState.InProgress; } public forceTokenization(lineNumber: number): void { this.validateLineNumber(lineNumber); - this.grammarTokens.forceTokenization(lineNumber); + this.grammarTokens?.forceTokenization(lineNumber); } public hasAccurateTokensForLine(lineNumber: number): boolean { this.validateLineNumber(lineNumber); - return this.grammarTokens.hasAccurateTokensForLine(lineNumber); + return !!this.grammarTokens?.hasAccurateTokensForLine(lineNumber); } public isCheapToTokenize(lineNumber: number): boolean { this.validateLineNumber(lineNumber); - return this.grammarTokens.isCheapToTokenize(lineNumber); + return !!this.grammarTokens?.isCheapToTokenize(lineNumber); } public tokenizeIfCheap(lineNumber: number): void { this.validateLineNumber(lineNumber); - this.grammarTokens.tokenizeIfCheap(lineNumber); + this.grammarTokens?.tokenizeIfCheap(lineNumber); } public getTokenTypeIfInsertingCharacter(lineNumber: number, column: number, character: string): StandardTokenType { - return this.grammarTokens.getTokenTypeIfInsertingCharacter(lineNumber, column, character); + return this.grammarTokens?.getTokenTypeIfInsertingCharacter(lineNumber, column, character) ?? StandardTokenType.Other; } public tokenizeLineWithEdit(position: IPosition, length: number, newText: string): LineTokens | null { - return this.grammarTokens.tokenizeLineWithEdit(position, length, newText); + return this.grammarTokens?.tokenizeLineWithEdit(position, length, newText) ?? null; } // #endregion @@ -327,7 +364,7 @@ export class TokenizationTextModelPart extends TextModelPart implements ITokeniz this._languageId = languageId; this._bracketPairsTextModelPart.handleDidChangeLanguage(e); - this.grammarTokens.resetTokenization(); + this.createPreferredTokenProvider(); this._onDidChangeLanguage.fire(e); this._onDidChangeLanguageConfiguration.fire({}); } diff --git a/src/vs/editor/common/model/treeSitterTokens.ts b/src/vs/editor/common/model/treeSitterTokens.ts new file mode 100644 index 0000000000000..ceda0410c47e4 --- /dev/null +++ b/src/vs/editor/common/model/treeSitterTokens.ts @@ -0,0 +1,26 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { Disposable } from 'vs/base/common/lifecycle'; +import { ILanguageIdCodec } from 'vs/editor/common/languages'; +import { LineTokens } from 'vs/editor/common/tokens/lineTokens'; + +/** + * Placeholder class, will be replaced with some real implementation. + */ +export class TreeSitterTokens extends Disposable { + constructor(private readonly languageIdCoded: ILanguageIdCodec) { + super(); + } + public getLineTokens(lineNumber: number): LineTokens { + // placeholder for now + return LineTokens.createEmpty('', this.languageIdCoded); + } + + public resetTokenization(fireTokenChangeEvent: boolean = true): void { + // placeholder for now + } + +} diff --git a/src/vs/editor/common/services/modelService.ts b/src/vs/editor/common/services/modelService.ts index 2bbda14a026a3..9a6cb92ed2cf5 100644 --- a/src/vs/editor/common/services/modelService.ts +++ b/src/vs/editor/common/services/modelService.ts @@ -322,6 +322,7 @@ export class ModelService extends Disposable implements IModelService { this._undoRedoService, this._languageService, this._languageConfigurationService, + this._configurationService ); if (resource && this._disposedModels.has(MODEL_ID(resource))) { const disposedModelData = this._removeDisposedModel(resource)!; diff --git a/src/vs/editor/common/tokenizationRegistry.ts b/src/vs/editor/common/tokenizationRegistry.ts index d9fb1bba82f2b..15ad1b8515974 100644 --- a/src/vs/editor/common/tokenizationRegistry.ts +++ b/src/vs/editor/common/tokenizationRegistry.ts @@ -6,13 +6,13 @@ import { Color } from 'vs/base/common/color'; import { Emitter, Event } from 'vs/base/common/event'; import { Disposable, IDisposable, toDisposable } from 'vs/base/common/lifecycle'; -import { ITokenizationRegistry, ITokenizationSupport, ITokenizationSupportChangedEvent, ILazyTokenizationSupport } from 'vs/editor/common/languages'; +import { ITokenizationRegistry, ITokenizationSupportChangedEvent, ILazyTokenizationSupport } from 'vs/editor/common/languages'; import { ColorId } from 'vs/editor/common/encodedTokenAttributes'; -export class TokenizationRegistry implements ITokenizationRegistry { +export class TokenizationRegistry implements ITokenizationRegistry { - private readonly _tokenizationSupports = new Map(); - private readonly _factories = new Map(); + private readonly _tokenizationSupports = new Map(); + private readonly _factories = new Map>(); private readonly _onDidChange = new Emitter(); public readonly onDidChange: Event = this._onDidChange.event; @@ -30,7 +30,7 @@ export class TokenizationRegistry implements ITokenizationRegistry { }); } - public register(languageId: string, support: ITokenizationSupport): IDisposable { + public register(languageId: string, support: TSupport): IDisposable { this._tokenizationSupports.set(languageId, support); this.handleChange([languageId]); return toDisposable(() => { @@ -42,11 +42,11 @@ export class TokenizationRegistry implements ITokenizationRegistry { }); } - public get(languageId: string): ITokenizationSupport | null { + public get(languageId: string): TSupport | null { return this._tokenizationSupports.get(languageId) || null; } - public registerFactory(languageId: string, factory: ILazyTokenizationSupport): IDisposable { + public registerFactory(languageId: string, factory: ILazyTokenizationSupport): IDisposable { this._factories.get(languageId)?.dispose(); const myData = new TokenizationSupportFactoryData(this, languageId, factory); this._factories.set(languageId, myData); @@ -60,7 +60,7 @@ export class TokenizationRegistry implements ITokenizationRegistry { }); } - public async getOrCreate(languageId: string): Promise { + public async getOrCreate(languageId: string): Promise { // check first if the support is already set const tokenizationSupport = this.get(languageId); if (tokenizationSupport) { @@ -112,7 +112,7 @@ export class TokenizationRegistry implements ITokenizationRegistry { } } -class TokenizationSupportFactoryData extends Disposable { +class TokenizationSupportFactoryData extends Disposable { private _isDisposed: boolean = false; private _resolvePromise: Promise | null = null; @@ -123,9 +123,9 @@ class TokenizationSupportFactoryData extends Disposable { } constructor( - private readonly _registry: TokenizationRegistry, + private readonly _registry: TokenizationRegistry, private readonly _languageId: string, - private readonly _factory: ILazyTokenizationSupport, + private readonly _factory: ILazyTokenizationSupport, ) { super(); } diff --git a/src/vs/editor/contrib/gotoSymbol/browser/peek/referencesWidget.ts b/src/vs/editor/contrib/gotoSymbol/browser/peek/referencesWidget.ts index b80e75d47eca3..9f1dc67d6d118 100644 --- a/src/vs/editor/contrib/gotoSymbol/browser/peek/referencesWidget.ts +++ b/src/vs/editor/contrib/gotoSymbol/browser/peek/referencesWidget.ts @@ -37,6 +37,7 @@ import { IWorkbenchAsyncDataTreeOptions, WorkbenchAsyncDataTree } from 'vs/platf import { IColorTheme, IThemeService } from 'vs/platform/theme/common/themeService'; import { IUndoRedoService } from 'vs/platform/undoRedo/common/undoRedo'; import { FileReferences, OneReference, ReferencesModel } from '../referencesModel'; +import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; class DecorationsManager implements IDisposable { @@ -228,6 +229,7 @@ export class ReferenceWidget extends peekView.PeekViewWidget { @IKeybindingService private readonly _keybindingService: IKeybindingService, @ILanguageService private readonly _languageService: ILanguageService, @ILanguageConfigurationService private readonly _languageConfigurationService: ILanguageConfigurationService, + @IConfigurationService private readonly _configurationService: IConfigurationService ) { super(editor, { showFrame: false, showArrow: true, isResizeable: true, isAccessible: true, supportOnTitleClick: true }, _instantiationService); @@ -315,7 +317,7 @@ export class ReferenceWidget extends peekView.PeekViewWidget { }; this._preview = this._instantiationService.createInstance(EmbeddedCodeEditorWidget, this._previewContainer, options, {}, this.editor); dom.hide(this._previewContainer); - this._previewNotAvailableMessage = new TextModel(nls.localize('missingPreviewMessage', "no preview available"), PLAINTEXT_LANGUAGE_ID, TextModel.DEFAULT_CREATION_OPTIONS, null, this._undoRedoService, this._languageService, this._languageConfigurationService); + this._previewNotAvailableMessage = new TextModel(nls.localize('missingPreviewMessage', "no preview available"), PLAINTEXT_LANGUAGE_ID, TextModel.DEFAULT_CREATION_OPTIONS, null, this._undoRedoService, this._languageService, this._languageConfigurationService, this._configurationService); // tree this._treeContainer = dom.append(containerElement, dom.$('div.ref-tree.inline')); diff --git a/src/vs/workbench/contrib/bulkEdit/browser/preview/bulkEditTree.ts b/src/vs/workbench/contrib/bulkEdit/browser/preview/bulkEditTree.ts index e45a95008c3ff..1716dd06a07b8 100644 --- a/src/vs/workbench/contrib/bulkEdit/browser/preview/bulkEditTree.ts +++ b/src/vs/workbench/contrib/bulkEdit/browser/preview/bulkEditTree.ts @@ -32,6 +32,7 @@ import { ILanguageService } from 'vs/editor/common/languages/language'; import { PLAINTEXT_LANGUAGE_ID } from 'vs/editor/common/languages/modesRegistry'; import { SnippetParser } from 'vs/editor/contrib/snippet/browser/snippetParser'; import { AriaRole } from 'vs/base/browser/ui/aria/aria'; +import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; // --- VIEW MODEL @@ -205,6 +206,7 @@ export class BulkEditDataSource implements IAsyncDataSource Date: Mon, 13 May 2024 12:09:58 +0200 Subject: [PATCH 02/37] Add the tree sitter wasm file --- build/filters.js | 2 + .../common/web-tree-sitter/cgmanifest.json | 17 + .../web-tree-sitter/tree-sitter-web.d.ts | 242 + .../common/web-tree-sitter/tree-sitter.js | 4031 +++++++++++++++++ .../common/web-tree-sitter/tree-sitter.wasm | Bin 0 -> 192649 bytes src/vs/editor/common/languages.ts | 4 +- .../common/model/tokenizationTextModelPart.ts | 2 +- ...eSitterTokenizationFeature.contribution.ts | 25 + .../browser/treeSitterTokenizationFeature.ts | 12 + .../treeSitterTokenizationFeatureImpl.ts | 20 + src/vs/workbench/workbench.common.main.ts | 1 + 11 files changed, 4353 insertions(+), 3 deletions(-) create mode 100644 src/vs/base/common/web-tree-sitter/cgmanifest.json create mode 100644 src/vs/base/common/web-tree-sitter/tree-sitter-web.d.ts create mode 100644 src/vs/base/common/web-tree-sitter/tree-sitter.js create mode 100644 src/vs/base/common/web-tree-sitter/tree-sitter.wasm create mode 100644 src/vs/workbench/services/treeSitter/browser/treeSitterTokenizationFeature.contribution.ts create mode 100644 src/vs/workbench/services/treeSitter/browser/treeSitterTokenizationFeature.ts create mode 100644 src/vs/workbench/services/treeSitter/browser/treeSitterTokenizationFeatureImpl.ts diff --git a/build/filters.js b/build/filters.js index c7be2d818d9bf..27cc35196e446 100644 --- a/build/filters.js +++ b/build/filters.js @@ -75,6 +75,7 @@ module.exports.indentationFilter = [ '!src/vs/base/browser/dompurify/*', '!src/vs/base/common/marked/marked.js', '!src/vs/base/common/semver/semver.js', + '!src/vs/base/common/web-tree-sitter/tree-sitter.js', '!src/vs/base/node/terminateProcess.sh', '!src/vs/base/node/cpuUsage.sh', '!test/unit/assert.js', @@ -172,6 +173,7 @@ module.exports.copyrightFilter = [ '!extensions/typescript-language-features/node-maintainer/**', '!extensions/html-language-features/server/src/modes/typescript/*', '!extensions/*/server/bin/*', + '!src/vs/base/common/web-tree-sitter/tree-sitter.js', '!src/vs/editor/test/node/classification/typescript-test.ts', ]; diff --git a/src/vs/base/common/web-tree-sitter/cgmanifest.json b/src/vs/base/common/web-tree-sitter/cgmanifest.json new file mode 100644 index 0000000000000..48bb91c66763e --- /dev/null +++ b/src/vs/base/common/web-tree-sitter/cgmanifest.json @@ -0,0 +1,17 @@ +{ + "registrations": [ + { + "component": { + "type": "git", + "git": { + "name": "web-tree-sitter", + "repositoryUrl": "https://github.com/tree-sitter/tree-sitter", + "commitHash": "fc15f621334a262039ffaded5937e2844f88da61" + } + }, + "license": "MIT", + "version": "0.22.2" + } + ], + "version": 1 +} diff --git a/src/vs/base/common/web-tree-sitter/tree-sitter-web.d.ts b/src/vs/base/common/web-tree-sitter/tree-sitter-web.d.ts new file mode 100644 index 0000000000000..dc984bf1da6c9 --- /dev/null +++ b/src/vs/base/common/web-tree-sitter/tree-sitter-web.d.ts @@ -0,0 +1,242 @@ +declare module 'web-tree-sitter' { + class Parser { + /** + * + * @param moduleOptions Optional emscripten module-object, see https://emscripten.org/docs/api_reference/module.html + */ + static init(moduleOptions?: object): Promise; + delete(): void; + parse(input: string | Parser.Input, oldTree?: Parser.Tree, options?: Parser.Options): Parser.Tree; + getIncludedRanges(): Parser.Range[]; + getTimeoutMicros(): number; + setTimeoutMicros(timeout: number): void; + reset(): void; + getLanguage(): Parser.Language; + setLanguage(language?: Parser.Language | null): void; + getLogger(): Parser.Logger; + setLogger(logFunc?: Parser.Logger | false | null): void; + } + + namespace Parser { + export type Options = { + includedRanges?: Range[]; + }; + + export type Point = { + row: number; + column: number; + }; + + export type Range = { + startIndex: number, + endIndex: number, + startPosition: Point, + endPosition: Point + }; + + export type Edit = { + startIndex: number; + oldEndIndex: number; + newEndIndex: number; + startPosition: Point; + oldEndPosition: Point; + newEndPosition: Point; + }; + + export type Logger = ( + message: string, + params: { [param: string]: string }, + type: "parse" | "lex" + ) => void; + + export interface Input { + (index: number, position?: Point): string | null; + } + + export interface SyntaxNode { + tree: Tree; + id: number; + typeId: number; + grammarId: number; + type: string; + grammarType: string; + isNamed: boolean; + isMissing: boolean; + isExtra: boolean; + hasChanges: boolean; + hasError: boolean; + isError: boolean; + text: string; + parseState: number; + nextParseState: number; + startPosition: Point; + endPosition: Point; + startIndex: number; + endIndex: number; + parent: SyntaxNode | null; + children: Array; + namedChildren: Array; + childCount: number; + namedChildCount: number; + firstChild: SyntaxNode | null; + firstNamedChild: SyntaxNode | null; + lastChild: SyntaxNode | null; + lastNamedChild: SyntaxNode | null; + nextSibling: SyntaxNode | null; + nextNamedSibling: SyntaxNode | null; + previousSibling: SyntaxNode | null; + previousNamedSibling: SyntaxNode | null; + descendantCount: number; + + equals(other: SyntaxNode): boolean; + toString(): string; + child(index: number): SyntaxNode | null; + namedChild(index: number): SyntaxNode | null; + childForFieldName(fieldName: string): SyntaxNode | null; + childForFieldId(fieldId: number): SyntaxNode | null; + fieldNameForChild(childIndex: number): string | null; + childrenForFieldName(fieldName: string, cursor: TreeCursor): Array; + childrenForFieldId(fieldId: number, cursor: TreeCursor): Array; + firstChildForIndex(index: number): SyntaxNode | null; + firstNamedChildForIndex(index: number): SyntaxNode | null; + + descendantForIndex(index: number): SyntaxNode; + descendantForIndex(startIndex: number, endIndex: number): SyntaxNode; + namedDescendantForIndex(index: number): SyntaxNode; + namedDescendantForIndex(startIndex: number, endIndex: number): SyntaxNode; + descendantForPosition(position: Point): SyntaxNode; + descendantForPosition(startPosition: Point, endPosition: Point): SyntaxNode; + namedDescendantForPosition(position: Point): SyntaxNode; + namedDescendantForPosition(startPosition: Point, endPosition: Point): SyntaxNode; + descendantsOfType(types: String | Array, startPosition?: Point, endPosition?: Point): Array; + + walk(): TreeCursor; + } + + export interface TreeCursor { + nodeType: string; + nodeTypeId: number; + nodeStateId: number; + nodeText: string; + nodeId: number; + nodeIsNamed: boolean; + nodeIsMissing: boolean; + startPosition: Point; + endPosition: Point; + startIndex: number; + endIndex: number; + readonly currentNode: SyntaxNode; + readonly currentFieldName: string; + readonly currentFieldId: number; + readonly currentDepth: number; + readonly currentDescendantIndex: number; + + reset(node: SyntaxNode): void; + resetTo(cursor: TreeCursor): void; + delete(): void; + gotoParent(): boolean; + gotoFirstChild(): boolean; + gotoLastChild(): boolean; + gotoFirstChildForIndex(goalIndex: number): boolean; + gotoFirstChildForPosition(goalPosition: Point): boolean; + gotoNextSibling(): boolean; + gotoPreviousSibling(): boolean; + gotoDescendant(goalDescendantIndex: number): void; + } + + export interface Tree { + readonly rootNode: SyntaxNode; + + rootNodeWithOffset(offsetBytes: number, offsetExtent: Point): SyntaxNode; + copy(): Tree; + delete(): void; + edit(edit: Edit): Tree; + walk(): TreeCursor; + getChangedRanges(other: Tree): Range[]; + getIncludedRanges(): Range[]; + getEditedRange(other: Tree): Range; + getLanguage(): Language; + } + + export interface QueryCapture { + name: string; + text?: string; + node: SyntaxNode; + setProperties?: { [prop: string]: string | null }; + assertedProperties?: { [prop: string]: string | null }; + refutedProperties?: { [prop: string]: string | null }; + } + + export interface QueryMatch { + pattern: number; + captures: QueryCapture[]; + } + + export type QueryOptions = { + startPosition?: Point; + endPosition?: Point; + startIndex?: number; + endIndex?: number; + matchLimit?: number; + maxStartDepth?: number; + }; + + export interface PredicateResult { + operator: string; + operands: { name: string; type: string }[]; + } + + export class Query { + captureNames: string[]; + readonly predicates: { [name: string]: Function }[]; + readonly setProperties: any[]; + readonly assertedProperties: any[]; + readonly refutedProperties: any[]; + readonly matchLimit: number; + + delete(): void; + captures(node: SyntaxNode, options?: QueryOptions): QueryCapture[]; + matches(node: SyntaxNode, options?: QueryOptions): QueryMatch[]; + predicatesForPattern(patternIndex: number): PredicateResult[]; + disableCapture(captureName: string): void; + disablePattern(patternIndex: number): void; + isPatternGuaranteedAtStep(byteOffset: number): boolean; + isPatternRooted(patternIndex: number): boolean; + isPatternNonLocal(patternIndex: number): boolean; + startIndexForPattern(patternIndex: number): number; + didExceedMatchLimit(): boolean; + } + + class Language { + static load(input: string | Uint8Array): Promise; + + readonly version: number; + readonly fieldCount: number; + readonly stateCount: number; + readonly nodeTypeCount: number; + + fieldNameForId(fieldId: number): string | null; + fieldIdForName(fieldName: string): number | null; + idForNodeType(type: string, named: boolean): number; + nodeTypeForId(typeId: number): string | null; + nodeTypeIsNamed(typeId: number): boolean; + nodeTypeIsVisible(typeId: number): boolean; + nextState(stateId: number, typeId: number): number; + query(source: string): Query; + lookaheadIterator(stateId: number): LookaheadIterable | null; + } + + export class LookaheadIterable { + readonly language: Language; + readonly currentTypeId: number; + readonly currentType: string; + + delete(): void; + reset(language: Language, stateId: number): boolean; + resetState(stateId: number): boolean; + [Symbol.iterator](): Iterator; + } + } + + export = Parser +} diff --git a/src/vs/base/common/web-tree-sitter/tree-sitter.js b/src/vs/base/common/web-tree-sitter/tree-sitter.js new file mode 100644 index 0000000000000..d4672b2f6a8cc --- /dev/null +++ b/src/vs/base/common/web-tree-sitter/tree-sitter.js @@ -0,0 +1,4031 @@ +/* eslint-disable no-eval */ +/* eslint-disable no-case-declarations */ +/* eslint-disable no-throw-literal */ +/* eslint-disable eqeqeq */ +/* eslint-disable curly */ +/* eslint-disable local/code-no-unused-expressions */ +/* eslint-disable local/code-no-unexternalized-strings */ +/* eslint-disable no-var */ +/* eslint-disable header/header */ + +(function (global, factory) { + typeof define === "function" && define.amd + ? define(["exports"], factory) + : typeof exports === "object" && typeof module !== "undefined" + ? factory(exports) + : ((global = + typeof globalThis !== "undefined" ? globalThis : global || self), + factory((global.Parser = {}))); +})(this, function () { + var Module = void 0 !== Module ? Module : {}, + TreeSitter = (function () { + var initPromise, + document = + "object" == typeof window + ? { currentScript: window.document.currentScript } + : null; + class Parser { + constructor() { + this.initialize(); + } + initialize() { + throw new Error("cannot construct a Parser before calling `init()`"); + } + static init(moduleOptions) { + return ( + initPromise || + ((Module = Object.assign({}, Module, moduleOptions)), + (initPromise = new Promise((resolveInitPromise) => { + var moduleOverrides = Object.assign({}, Module), + arguments_ = [], + thisProgram = "./this.program", + quit_ = (e, t) => { + throw t; + }, + ENVIRONMENT_IS_WEB = "object" == typeof window, + ENVIRONMENT_IS_WORKER = "function" == typeof importScripts, + ENVIRONMENT_IS_NODE = + "object" == typeof process && + "object" == typeof process.versions && + "string" == typeof process.versions.node, + scriptDirectory = "", + read_, + readAsync, + readBinary, + setWindowTitle; + function locateFile(e) { + return Module.locateFile + ? Module.locateFile(e, scriptDirectory) + : scriptDirectory + e; + } + if (ENVIRONMENT_IS_NODE) { + var fs = require("fs"), + nodePath = require("path"); + (scriptDirectory = ENVIRONMENT_IS_WORKER + ? nodePath.dirname(scriptDirectory) + "/" + : __dirname + "/"), + (read_ = (e, t) => ( + (e = isFileURI(e) ? new URL(e) : nodePath.normalize(e)), + fs.readFileSync(e, t ? void 0 : "utf8") + )), + (readBinary = (e) => { + var t = read_(e, !0); + return t.buffer || (t = new Uint8Array(t)), t; + }), + (readAsync = (e, t, r, _ = !0) => { + (e = isFileURI(e) ? new URL(e) : nodePath.normalize(e)), + fs.readFile(e, _ ? void 0 : "utf8", (e, s) => { + e ? r(e) : t(_ ? s.buffer : s); + }); + }), + !Module.thisProgram && + process.argv.length > 1 && + (thisProgram = process.argv[1].replace(/\\/g, "/")), + (arguments_ = process.argv.slice(2)), + "undefined" != typeof module && (module.exports = Module), + (quit_ = (e, t) => { + throw ((process.exitCode = e), t); + }), + (Module.inspect = () => "[Emscripten Module object]"); + } else + (ENVIRONMENT_IS_WEB || ENVIRONMENT_IS_WORKER) && + (ENVIRONMENT_IS_WORKER + ? (scriptDirectory = self.location.href) + : void 0 !== document && + document.currentScript && + (scriptDirectory = document.currentScript.src), + (scriptDirectory = + 0 !== scriptDirectory.indexOf("blob:") + ? scriptDirectory.substr( + 0, + scriptDirectory + .replace(/[?#].*/, "") + .lastIndexOf("/") + 1 + ) + : ""), + (read_ = (e) => { + var t = new XMLHttpRequest(); + return t.open("GET", e, !1), t.send(null), t.responseText; + }), + ENVIRONMENT_IS_WORKER && + (readBinary = (e) => { + var t = new XMLHttpRequest(); + return ( + t.open("GET", e, !1), + (t.responseType = "arraybuffer"), + t.send(null), + new Uint8Array(t.response) + ); + }), + (readAsync = (e, t, r) => { + var _ = new XMLHttpRequest(); + _.open("GET", e, !0), + (_.responseType = "arraybuffer"), + (_.onload = () => { + 200 == _.status || (0 == _.status && _.response) + ? t(_.response) + : r(); + }), + (_.onerror = r), + _.send(null); + }), + (setWindowTitle = (e) => (document.title = e))); + var out = Module.print || console.log.bind(console), + err = Module.printErr || console.warn.bind(console); + Object.assign(Module, moduleOverrides), + (moduleOverrides = null), + Module.arguments && (arguments_ = Module.arguments), + Module.thisProgram && (thisProgram = Module.thisProgram), + Module.quit && (quit_ = Module.quit); + var dynamicLibraries = Module.dynamicLibraries || [], + wasmBinary; + Module.wasmBinary && (wasmBinary = Module.wasmBinary); + var noExitRuntime = Module.noExitRuntime || !0, + wasmMemory; + "object" != typeof WebAssembly && + abort("no native wasm support detected"); + var ABORT = !1, + EXITSTATUS, + HEAP8, + HEAPU8, + HEAP16, + HEAPU16, + HEAP32, + HEAPU32, + HEAPF32, + HEAPF64; + function assert(e, t) { + e || abort(t); + } + function updateMemoryViews() { + var e = wasmMemory.buffer; + (Module.HEAP8 = HEAP8 = new Int8Array(e)), + (Module.HEAP16 = HEAP16 = new Int16Array(e)), + (Module.HEAP32 = HEAP32 = new Int32Array(e)), + (Module.HEAPU8 = HEAPU8 = new Uint8Array(e)), + (Module.HEAPU16 = HEAPU16 = new Uint16Array(e)), + (Module.HEAPU32 = HEAPU32 = new Uint32Array(e)), + (Module.HEAPF32 = HEAPF32 = new Float32Array(e)), + (Module.HEAPF64 = HEAPF64 = new Float64Array(e)); + } + var INITIAL_MEMORY = Module.INITIAL_MEMORY || 33554432; + assert( + INITIAL_MEMORY >= 65536, + "INITIAL_MEMORY should be larger than STACK_SIZE, was " + + INITIAL_MEMORY + + "! (STACK_SIZE=65536)" + ), + (wasmMemory = Module.wasmMemory + ? Module.wasmMemory + : new WebAssembly.Memory({ + initial: INITIAL_MEMORY / 65536, + maximum: 32768, + })), + updateMemoryViews(), + (INITIAL_MEMORY = wasmMemory.buffer.byteLength); + var wasmTable = new WebAssembly.Table({ + initial: 25, + element: "anyfunc", + }), + __ATPRERUN__ = [], + __ATINIT__ = [], + __ATMAIN__ = [], + __ATPOSTRUN__ = [], + __RELOC_FUNCS__ = [], + runtimeInitialized = !1, + runtimeKeepaliveCounter = 0; + function keepRuntimeAlive() { + return noExitRuntime || runtimeKeepaliveCounter > 0; + } + function preRun() { + if (Module.preRun) + for ( + "function" == typeof Module.preRun && + (Module.preRun = [Module.preRun]); + Module.preRun.length; + + ) + addOnPreRun(Module.preRun.shift()); + callRuntimeCallbacks(__ATPRERUN__); + } + function initRuntime() { + (runtimeInitialized = !0), + callRuntimeCallbacks(__RELOC_FUNCS__), + callRuntimeCallbacks(__ATINIT__); + } + function preMain() { + callRuntimeCallbacks(__ATMAIN__); + } + function postRun() { + if (Module.postRun) + for ( + "function" == typeof Module.postRun && + (Module.postRun = [Module.postRun]); + Module.postRun.length; + + ) + addOnPostRun(Module.postRun.shift()); + callRuntimeCallbacks(__ATPOSTRUN__); + } + function addOnPreRun(e) { + __ATPRERUN__.unshift(e); + } + function addOnInit(e) { + __ATINIT__.unshift(e); + } + function addOnPostRun(e) { + __ATPOSTRUN__.unshift(e); + } + var runDependencies = 0, + runDependencyWatcher = null, + dependenciesFulfilled = null; + function getUniqueRunDependency(e) { + return e; + } + function addRunDependency(e) { + runDependencies++, + Module.monitorRunDependencies && + Module.monitorRunDependencies(runDependencies); + } + function removeRunDependency(e) { + if ( + (runDependencies--, + Module.monitorRunDependencies && + Module.monitorRunDependencies(runDependencies), + 0 == runDependencies && + (null !== runDependencyWatcher && + (clearInterval(runDependencyWatcher), + (runDependencyWatcher = null)), + dependenciesFulfilled)) + ) { + var t = dependenciesFulfilled; + (dependenciesFulfilled = null), t(); + } + } + function abort(e) { + throw ( + (Module.onAbort && Module.onAbort(e), + err((e = "Aborted(" + e + ")")), + (ABORT = !0), + (EXITSTATUS = 1), + (e += ". Build with -sASSERTIONS for more info."), + new WebAssembly.RuntimeError(e)) + ); + } + var dataURIPrefix = "data:application/octet-stream;base64,", + wasmBinaryFile, + tempDouble, + tempI64; + function isDataURI(e) { + return e.startsWith(dataURIPrefix); + } + function isFileURI(e) { + return e.startsWith("file://"); + } + function getBinary(e) { + try { + if (e == wasmBinaryFile && wasmBinary) + return new Uint8Array(wasmBinary); + if (readBinary) return readBinary(e); + throw "both async and sync fetching of the wasm failed"; + } catch (e) { + abort(e); + } + } + function getBinaryPromise(e) { + if ( + !wasmBinary && + (ENVIRONMENT_IS_WEB || ENVIRONMENT_IS_WORKER) + ) { + if ("function" == typeof fetch && !isFileURI(e)) + return fetch(e, { credentials: "same-origin" }) + .then((t) => { + if (!t.ok) + throw ( + "failed to load wasm binary file at '" + e + "'" + ); + return t.arrayBuffer(); + }) + .catch(() => getBinary(e)); + if (readAsync) + return new Promise((t, r) => { + readAsync(e, (e) => t(new Uint8Array(e)), r); + }); + } + return Promise.resolve().then(() => getBinary(e)); + } + function instantiateArrayBuffer(e, t, r) { + return getBinaryPromise(e) + .then((e) => WebAssembly.instantiate(e, t)) + .then((e) => e) + .then(r, (e) => { + err("failed to asynchronously prepare wasm: " + e), + abort(e); + }); + } + function instantiateAsync(e, t, r, _) { + return e || + "function" != typeof WebAssembly.instantiateStreaming || + isDataURI(t) || + isFileURI(t) || + ENVIRONMENT_IS_NODE || + "function" != typeof fetch + ? instantiateArrayBuffer(t, r, _) + : fetch(t, { credentials: "same-origin" }).then((e) => + WebAssembly.instantiateStreaming(e, r).then( + _, + function (e) { + return ( + err("wasm streaming compile failed: " + e), + err("falling back to ArrayBuffer instantiation"), + instantiateArrayBuffer(t, r, _) + ); + } + ) + ); + } + function createWasm() { + var e = { + env: wasmImports, + wasi_snapshot_preview1: wasmImports, + "GOT.mem": new Proxy(wasmImports, GOTHandler), + "GOT.func": new Proxy(wasmImports, GOTHandler), + }; + function t(e, t) { + var r = e.exports; + r = relocateExports(r, 1024); + var _ = getDylinkMetadata(t); + return ( + _.neededDynlibs && + (dynamicLibraries = + _.neededDynlibs.concat(dynamicLibraries)), + mergeLibSymbols(r, "main"), + (Module.asm = r), + addOnInit(Module.asm.__wasm_call_ctors), + __RELOC_FUNCS__.push(Module.asm.__wasm_apply_data_relocs), + removeRunDependency("wasm-instantiate"), + r + ); + } + if ( + (addRunDependency("wasm-instantiate"), Module.instantiateWasm) + ) + try { + return Module.instantiateWasm(e, t); + } catch (e) { + return ( + err( + "Module.instantiateWasm callback failed with error: " + + e + ), + !1 + ); + } + return ( + instantiateAsync(wasmBinary, wasmBinaryFile, e, function (e) { + t(e.instance, e.module); + }), + {} + ); + } + (wasmBinaryFile = "tree-sitter.wasm"), + isDataURI(wasmBinaryFile) || + (wasmBinaryFile = locateFile(wasmBinaryFile)); + var ASM_CONSTS = {}; + function ExitStatus(e) { + (this.name = "ExitStatus"), + (this.message = "Program terminated with exit(" + e + ")"), + (this.status = e); + } + var GOT = {}, + currentModuleWeakSymbols = new Set([]), + GOTHandler = { + get: function (e, t) { + var r = GOT[t]; + return ( + r || + (r = GOT[t] = + new WebAssembly.Global({ + value: "i32", + mutable: !0, + })), + currentModuleWeakSymbols.has(t) || (r.required = !0), + r + ); + }, + }; + function callRuntimeCallbacks(e) { + for (; e.length > 0; ) e.shift()(Module); + } + var UTF8Decoder = + "undefined" != typeof TextDecoder + ? new TextDecoder("utf8") + : void 0; + function UTF8ArrayToString(e, t, r) { + for (var _ = t + r, s = t; e[s] && !(s >= _); ) ++s; + if (s - t > 16 && e.buffer && UTF8Decoder) + return UTF8Decoder.decode(e.subarray(t, s)); + for (var n = ""; t < s; ) { + var a = e[t++]; + if (128 & a) { + var o = 63 & e[t++]; + if (192 != (224 & a)) { + var l = 63 & e[t++]; + if ( + (a = + 224 == (240 & a) + ? ((15 & a) << 12) | (o << 6) | l + : ((7 & a) << 18) | + (o << 12) | + (l << 6) | + (63 & e[t++])) < 65536 + ) + n += String.fromCharCode(a); + else { + var i = a - 65536; + n += String.fromCharCode( + 55296 | (i >> 10), + 56320 | (1023 & i) + ); + } + } else n += String.fromCharCode(((31 & a) << 6) | o); + } else n += String.fromCharCode(a); + } + return n; + } + function getDylinkMetadata(e) { + var t = 0, + r = 0; + function _() { + for (var r = 0, _ = 1; ; ) { + var s = e[t++]; + if (((r += (127 & s) * _), (_ *= 128), !(128 & s))) break; + } + return r; + } + function s() { + var r = _(); + return UTF8ArrayToString(e, (t += r) - r, r); + } + function n(e, t) { + if (e) throw new Error(t); + } + var a = "dylink.0"; + if (e instanceof WebAssembly.Module) { + var o = WebAssembly.Module.customSections(e, a); + 0 === o.length && + ((a = "dylink"), + (o = WebAssembly.Module.customSections(e, a))), + n(0 === o.length, "need dylink section"), + (r = (e = new Uint8Array(o[0])).length); + } else { + n( + !( + 1836278016 == + new Uint32Array( + new Uint8Array(e.subarray(0, 24)).buffer + )[0] + ), + "need to see wasm magic number" + ), + n(0 !== e[8], "need the dylink section to be first"), + (t = 9); + var l = _(); + (r = t + l), (a = s()); + } + var i = { + neededDynlibs: [], + tlsExports: new Set(), + weakImports: new Set(), + }; + if ("dylink" == a) { + (i.memorySize = _()), + (i.memoryAlign = _()), + (i.tableSize = _()), + (i.tableAlign = _()); + for (var u = _(), d = 0; d < u; ++d) { + var m = s(); + i.neededDynlibs.push(m); + } + } else { + n("dylink.0" !== a); + for (; t < r; ) { + var c = e[t++], + p = _(); + if (1 === c) + (i.memorySize = _()), + (i.memoryAlign = _()), + (i.tableSize = _()), + (i.tableAlign = _()); + else if (2 === c) + for (u = _(), d = 0; d < u; ++d) + (m = s()), i.neededDynlibs.push(m); + else if (3 === c) + for (var h = _(); h--; ) { + var f = s(); + 256 & _() && i.tlsExports.add(f); + } + else if (4 === c) + for (h = _(); h--; ) { + s(), (f = s()); + 1 == (3 & _()) && i.weakImports.add(f); + } + else t += p; + } + } + return i; + } + function getValue(e, t = "i8") { + switch ((t.endsWith("*") && (t = "*"), t)) { + case "i1": + case "i8": + return HEAP8[e | 0]; + case "i16": + return HEAP16[e >> 1]; + case "i32": + case "i64": + return HEAP32[e >> 2]; + case "float": + return HEAPF32[e >> 2]; + case "double": + return HEAPF64[e >> 3]; + case "*": + return HEAPU32[e >> 2]; + default: + abort("invalid type for getValue: " + t); + } + } + function newDSO(e, t, r) { + var _ = { refcount: 1 / 0, name: e, exports: r, global: !0 }; + return ( + (LDSO.loadedLibsByName[e] = _), + null != t && (LDSO.loadedLibsByHandle[t] = _), + _ + ); + } + var LDSO = { + loadedLibsByName: {}, + loadedLibsByHandle: {}, + init: () => newDSO("__main__", 0, wasmImports), + }, + ___heap_base = 78144; + function zeroMemory(e, t) { + return HEAPU8.fill(0, e, e + t), e; + } + function getMemory(e) { + if (runtimeInitialized) return zeroMemory(_malloc(e), e); + var t = ___heap_base, + r = (t + e + 15) & -16; + return (___heap_base = r), (GOT.__heap_base.value = r), t; + } + function isInternalSym(e) { + return [ + "__cpp_exception", + "__c_longjmp", + "__wasm_apply_data_relocs", + "__dso_handle", + "__tls_size", + "__tls_align", + "__set_stack_limits", + "_emscripten_tls_init", + "__wasm_init_tls", + "__wasm_call_ctors", + "__start_em_asm", + "__stop_em_asm", + ].includes(e); + } + function uleb128Encode(e, t) { + e < 128 ? t.push(e) : t.push(e % 128 | 128, e >> 7); + } + function sigToWasmTypes(e) { + for ( + var t = { i: "i32", j: "i32", f: "f32", d: "f64", p: "i32" }, + r = { + parameters: [], + results: "v" == e[0] ? [] : [t[e[0]]], + }, + _ = 1; + _ < e.length; + ++_ + ) + r.parameters.push(t[e[_]]), + "j" === e[_] && r.parameters.push("i32"); + return r; + } + function generateFuncType(e, t) { + var r = e.slice(0, 1), + _ = e.slice(1), + s = { i: 127, p: 127, j: 126, f: 125, d: 124 }; + t.push(96), uleb128Encode(_.length, t); + for (var n = 0; n < _.length; ++n) t.push(s[_[n]]); + "v" == r ? t.push(0) : t.push(1, s[r]); + } + function convertJsFunctionToWasm(e, t) { + if ("function" == typeof WebAssembly.Function) + return new WebAssembly.Function(sigToWasmTypes(t), e); + var r = [1]; + generateFuncType(t, r); + var _ = [0, 97, 115, 109, 1, 0, 0, 0, 1]; + uleb128Encode(r.length, _), + _.push.apply(_, r), + _.push(2, 7, 1, 1, 101, 1, 102, 0, 0, 7, 5, 1, 1, 102, 0, 0); + var s = new WebAssembly.Module(new Uint8Array(_)); + return new WebAssembly.Instance(s, { e: { f: e } }).exports.f; + } + var wasmTableMirror = []; + function getWasmTableEntry(e) { + var t = wasmTableMirror[e]; + return ( + t || + (e >= wasmTableMirror.length && + (wasmTableMirror.length = e + 1), + (wasmTableMirror[e] = t = wasmTable.get(e))), + t + ); + } + function updateTableMap(e, t) { + if (functionsInTableMap) + for (var r = e; r < e + t; r++) { + var _ = getWasmTableEntry(r); + _ && functionsInTableMap.set(_, r); + } + } + var functionsInTableMap = void 0; + function getFunctionAddress(e) { + return ( + functionsInTableMap || + ((functionsInTableMap = new WeakMap()), + updateTableMap(0, wasmTable.length)), + functionsInTableMap.get(e) || 0 + ); + } + var freeTableIndexes = []; + function getEmptyTableSlot() { + if (freeTableIndexes.length) return freeTableIndexes.pop(); + try { + wasmTable.grow(1); + } catch (e) { + if (!(e instanceof RangeError)) throw e; + throw "Unable to grow wasm table. Set ALLOW_TABLE_GROWTH."; + } + return wasmTable.length - 1; + } + function setWasmTableEntry(e, t) { + wasmTable.set(e, t), (wasmTableMirror[e] = wasmTable.get(e)); + } + function addFunction(e, t) { + var r = getFunctionAddress(e); + if (r) return r; + var _ = getEmptyTableSlot(); + try { + setWasmTableEntry(_, e); + } catch (r) { + if (!(r instanceof TypeError)) throw r; + setWasmTableEntry(_, convertJsFunctionToWasm(e, t)); + } + return functionsInTableMap.set(e, _), _; + } + function updateGOT(e, t) { + for (var r in e) + if (!isInternalSym(r)) { + var _ = e[r]; + r.startsWith("orig$") && ((r = r.split("$")[1]), (t = !0)), + GOT[r] || + (GOT[r] = new WebAssembly.Global({ + value: "i32", + mutable: !0, + })), + (t || 0 == GOT[r].value) && + ("function" == typeof _ + ? (GOT[r].value = addFunction(_)) + : "number" == typeof _ + ? (GOT[r].value = _) + : err( + "unhandled export type for `" + + r + + "`: " + + typeof _ + )); + } + } + function relocateExports(e, t, r) { + var _ = {}; + for (var s in e) { + var n = e[s]; + "object" == typeof n && (n = n.value), + "number" == typeof n && (n += t), + (_[s] = n); + } + return updateGOT(_, r), _; + } + function isSymbolDefined(e) { + var t = wasmImports[e]; + return !(!t || t.stub); + } + function resolveGlobalSymbol(e, t = !1) { + var r; + return ( + t && "orig$" + e in wasmImports && (e = "orig$" + e), + isSymbolDefined(e) + ? (r = wasmImports[e]) + : e.startsWith("invoke_") && + (r = wasmImports[e] = + createInvokeFunction(e.split("_")[1])), + { sym: r, name: e } + ); + } + function alignMemory(e, t) { + return Math.ceil(e / t) * t; + } + function dynCallLegacy(e, t, r) { + var _ = Module["dynCall_" + e]; + return r && r.length + ? _.apply(null, [t].concat(r)) + : _.call(null, t); + } + function dynCall(e, t, r) { + return e.includes("j") + ? dynCallLegacy(e, t, r) + : getWasmTableEntry(t).apply(null, r); + } + function createInvokeFunction(e) { + return function () { + var t = stackSave(); + try { + return dynCall( + e, + arguments[0], + Array.prototype.slice.call(arguments, 1) + ); + } catch (e) { + if ((stackRestore(t), e !== e + 0)) throw e; + _setThrew(1, 0); + } + }; + } + function UTF8ToString(e, t) { + return e ? UTF8ArrayToString(HEAPU8, e, t) : ""; + } + function loadWebAssemblyModule( + binary, + flags, + localScope, + handle + ) { + var metadata = getDylinkMetadata(binary); + function loadModule() { + var firstLoad = !handle || !HEAP8[(handle + 8) | 0]; + if (firstLoad) { + var memAlign = Math.pow(2, metadata.memoryAlign); + memAlign = Math.max(memAlign, 16); + var memoryBase = metadata.memorySize + ? alignMemory( + getMemory(metadata.memorySize + memAlign), + memAlign + ) + : 0, + tableBase = metadata.tableSize ? wasmTable.length : 0; + handle && + ((HEAP8[(handle + 8) | 0] = 1), + (HEAPU32[(handle + 12) >> 2] = memoryBase), + (HEAP32[(handle + 16) >> 2] = metadata.memorySize), + (HEAPU32[(handle + 20) >> 2] = tableBase), + (HEAP32[(handle + 24) >> 2] = metadata.tableSize)); + } else + (memoryBase = HEAPU32[(handle + 12) >> 2]), + (tableBase = HEAPU32[(handle + 20) >> 2]); + var tableGrowthNeeded = + tableBase + metadata.tableSize - wasmTable.length, + moduleExports; + function resolveSymbol(e) { + var t = resolveGlobalSymbol(e).sym; + return ( + !t && localScope && (t = localScope[e]), + t || (t = moduleExports[e]), + t + ); + } + tableGrowthNeeded > 0 && wasmTable.grow(tableGrowthNeeded); + var proxyHandler = { + get: function (e, t) { + switch (t) { + case "__memory_base": + return memoryBase; + case "__table_base": + return tableBase; + } + if (t in wasmImports && !wasmImports[t].stub) + return wasmImports[t]; + var r; + t in e || + (e[t] = function () { + return ( + r || (r = resolveSymbol(t)), + r.apply(null, arguments) + ); + }); + return e[t]; + }, + }, + proxy = new Proxy({}, proxyHandler), + info = { + "GOT.mem": new Proxy({}, GOTHandler), + "GOT.func": new Proxy({}, GOTHandler), + env: proxy, + wasi_snapshot_preview1: proxy, + }; + function postInstantiation(instance) { + function addEmAsm(addr, body) { + for ( + var args = [], arity = 0; + arity < 16 && -1 != body.indexOf("$" + arity); + arity++ + ) + args.push("$" + arity); + args = args.join(","); + var func = "(" + args + " ) => { " + body + "};"; + ASM_CONSTS[start] = eval(func); + } + if ( + (updateTableMap(tableBase, metadata.tableSize), + (moduleExports = relocateExports( + instance.exports, + memoryBase + )), + flags.allowUndefined || reportUndefinedSymbols(), + "__start_em_asm" in moduleExports) + ) + for ( + var start = moduleExports.__start_em_asm, + stop = moduleExports.__stop_em_asm; + start < stop; + + ) { + var jsString = UTF8ToString(start); + addEmAsm(start, jsString), + (start = HEAPU8.indexOf(0, start) + 1); + } + var applyRelocs = moduleExports.__wasm_apply_data_relocs; + applyRelocs && + (runtimeInitialized + ? applyRelocs() + : __RELOC_FUNCS__.push(applyRelocs)); + var init = moduleExports.__wasm_call_ctors; + return ( + init && + (runtimeInitialized ? init() : __ATINIT__.push(init)), + moduleExports + ); + } + if (flags.loadAsync) { + if (binary instanceof WebAssembly.Module) { + var instance = new WebAssembly.Instance(binary, info); + return Promise.resolve(postInstantiation(instance)); + } + return WebAssembly.instantiate(binary, info).then((e) => + postInstantiation(e.instance) + ); + } + var module = + binary instanceof WebAssembly.Module + ? binary + : new WebAssembly.Module(binary), + instance = new WebAssembly.Instance(module, info); + return postInstantiation(instance); + } + return ( + (currentModuleWeakSymbols = metadata.weakImports), + flags.loadAsync + ? metadata.neededDynlibs + .reduce( + (e, t) => e.then(() => loadDynamicLibrary(t, flags)), + Promise.resolve() + ) + .then(loadModule) + : (metadata.neededDynlibs.forEach((e) => + loadDynamicLibrary(e, flags, localScope) + ), + loadModule()) + ); + } + function mergeLibSymbols(e, t) { + for (var r in e) { + if (!e.hasOwnProperty(r)) continue; + const t = (t) => { + isSymbolDefined(t) || (wasmImports[t] = e[r]); + }; + t(r); + const _ = "__main_argc_argv"; + "main" == r && t(_), + r == _ && t("main"), + r.startsWith("dynCall_") && + !Module.hasOwnProperty(r) && + (Module[r] = e[r]); + } + } + function asyncLoad(e, t, r, _) { + var s = _ ? "" : getUniqueRunDependency("al " + e); + readAsync( + e, + (r) => { + assert( + r, + 'Loading data file "' + e + '" failed (no arrayBuffer).' + ), + t(new Uint8Array(r)), + s && removeRunDependency(s); + }, + (t) => { + if (!r) throw 'Loading data file "' + e + '" failed.'; + r(); + } + ), + s && addRunDependency(s); + } + function loadDynamicLibrary( + e, + t = { global: !0, nodelete: !0 }, + r, + _ + ) { + var s = LDSO.loadedLibsByName[e]; + if (s) + return ( + t.global && + !s.global && + ((s.global = !0), + "loading" !== s.exports && mergeLibSymbols(s.exports, e)), + t.nodelete && s.refcount !== 1 / 0 && (s.refcount = 1 / 0), + s.refcount++, + _ && (LDSO.loadedLibsByHandle[_] = s), + !t.loadAsync || Promise.resolve(!0) + ); + function n() { + if (t.fs && t.fs.findObject(e)) { + var r = t.fs.readFile(e, { encoding: "binary" }); + return ( + r instanceof Uint8Array || (r = new Uint8Array(r)), + t.loadAsync ? Promise.resolve(r) : r + ); + } + var _ = locateFile(e); + if (t.loadAsync) + return new Promise(function (e, t) { + asyncLoad(_, (t) => e(t), t); + }); + if (!readBinary) + throw new Error( + _ + + ": file not found, and synchronous loading of external files is not available" + ); + return readBinary(_); + } + function a() { + if ("undefined" != typeof preloadedWasm && preloadedWasm[e]) { + var s = preloadedWasm[e]; + return t.loadAsync ? Promise.resolve(s) : s; + } + return t.loadAsync + ? n().then((e) => loadWebAssemblyModule(e, t, r, _)) + : loadWebAssemblyModule(n(), t, r, _); + } + function o(t) { + s.global ? mergeLibSymbols(t, e) : r && Object.assign(r, t), + (s.exports = t); + } + return ( + ((s = newDSO(e, _, "loading")).refcount = t.nodelete + ? 1 / 0 + : 1), + (s.global = t.global), + t.loadAsync ? a().then((e) => (o(e), !0)) : (o(a()), !0) + ); + } + function reportUndefinedSymbols() { + for (var e in GOT) + if (0 == GOT[e].value) { + var t = resolveGlobalSymbol(e, !0).sym; + if (!t && !GOT[e].required) continue; + if ("function" == typeof t) + GOT[e].value = addFunction(t, t.sig); + else { + if ("number" != typeof t) + throw new Error( + "bad export type for `" + e + "`: " + typeof t + ); + GOT[e].value = t; + } + } + } + function loadDylibs() { + dynamicLibraries.length + ? (addRunDependency("loadDylibs"), + dynamicLibraries + .reduce( + (e, t) => + e.then(() => + loadDynamicLibrary(t, { + loadAsync: !0, + global: !0, + nodelete: !0, + allowUndefined: !0, + }) + ), + Promise.resolve() + ) + .then(() => { + reportUndefinedSymbols(), + removeRunDependency("loadDylibs"); + })) + : reportUndefinedSymbols(); + } + function setValue(e, t, r = "i8") { + switch ((r.endsWith("*") && (r = "*"), r)) { + case "i1": + case "i8": + HEAP8[e | 0] = t; + break; + case "i16": + HEAP16[e >> 1] = t; + break; + case "i32": + HEAP32[e >> 2] = t; + break; + case "i64": + (tempI64 = [ + t >>> 0, + ((tempDouble = t), + +Math.abs(tempDouble) >= 1 + ? tempDouble > 0 + ? +Math.floor(tempDouble / 4294967296) >>> 0 + : ~~+Math.ceil( + (tempDouble - +(~~tempDouble >>> 0)) / 4294967296 + ) >>> 0 + : 0), + ]), + (HEAP32[e >> 2] = tempI64[0]), + (HEAP32[(e + 4) >> 2] = tempI64[1]); + break; + case "float": + HEAPF32[e >> 2] = t; + break; + case "double": + HEAPF64[e >> 3] = t; + break; + case "*": + HEAPU32[e >> 2] = t; + break; + default: + abort("invalid type for setValue: " + r); + } + } + var ___memory_base = new WebAssembly.Global( + { value: "i32", mutable: !1 }, + 1024 + ), + ___stack_pointer = new WebAssembly.Global( + { value: "i32", mutable: !0 }, + 78144 + ), + ___table_base = new WebAssembly.Global( + { value: "i32", mutable: !1 }, + 1 + ), + nowIsMonotonic = !0, + _emscripten_get_now; + function __emscripten_get_now_is_monotonic() { + return nowIsMonotonic; + } + function _abort() { + abort(""); + } + function _emscripten_date_now() { + return Date.now(); + } + function _emscripten_memcpy_big(e, t, r) { + HEAPU8.copyWithin(e, t, t + r); + } + function getHeapMax() { + return 2147483648; + } + function emscripten_realloc_buffer(e) { + var t = wasmMemory.buffer; + try { + return ( + wasmMemory.grow((e - t.byteLength + 65535) >>> 16), + updateMemoryViews(), + 1 + ); + } catch (e) {} + } + function _emscripten_resize_heap(e) { + var t = HEAPU8.length; + e >>>= 0; + var r = getHeapMax(); + if (e > r) return !1; + for (var _ = 1; _ <= 4; _ *= 2) { + var s = t * (1 + 0.2 / _); + if ( + ((s = Math.min(s, e + 100663296)), + emscripten_realloc_buffer( + Math.min( + r, + (n = Math.max(e, s)) + (((a = 65536) - (n % a)) % a) + ) + )) + ) + return !0; + } + var n, a; + return !1; + } + (__emscripten_get_now_is_monotonic.sig = "i"), + (_abort.sig = "v"), + (_emscripten_date_now.sig = "d"), + (_emscripten_get_now = ENVIRONMENT_IS_NODE + ? () => { + var e = process.hrtime(); + return 1e3 * e[0] + e[1] / 1e6; + } + : () => performance.now()), + (_emscripten_get_now.sig = "d"), + (_emscripten_memcpy_big.sig = "vppp"), + (_emscripten_resize_heap.sig = "ip"); + var SYSCALLS = { + DEFAULT_POLLMASK: 5, + calculateAt: function (e, t, r) { + if (PATH.isAbs(t)) return t; + var _; + -100 === e + ? (_ = FS.cwd()) + : (_ = SYSCALLS.getStreamFromFD(e).path); + if (0 == t.length) { + if (!r) throw new FS.ErrnoError(44); + return _; + } + return PATH.join2(_, t); + }, + doStat: function (e, t, r) { + try { + var _ = e(t); + } catch (e) { + if ( + e && + e.node && + PATH.normalize(t) !== PATH.normalize(FS.getPath(e.node)) + ) + return -54; + throw e; + } + (HEAP32[r >> 2] = _.dev), + (HEAP32[(r + 8) >> 2] = _.ino), + (HEAP32[(r + 12) >> 2] = _.mode), + (HEAPU32[(r + 16) >> 2] = _.nlink), + (HEAP32[(r + 20) >> 2] = _.uid), + (HEAP32[(r + 24) >> 2] = _.gid), + (HEAP32[(r + 28) >> 2] = _.rdev), + (tempI64 = [ + _.size >>> 0, + ((tempDouble = _.size), + +Math.abs(tempDouble) >= 1 + ? tempDouble > 0 + ? +Math.floor(tempDouble / 4294967296) >>> 0 + : ~~+Math.ceil( + (tempDouble - +(~~tempDouble >>> 0)) / 4294967296 + ) >>> 0 + : 0), + ]), + (HEAP32[(r + 40) >> 2] = tempI64[0]), + (HEAP32[(r + 44) >> 2] = tempI64[1]), + (HEAP32[(r + 48) >> 2] = 4096), + (HEAP32[(r + 52) >> 2] = _.blocks); + var s = _.atime.getTime(), + n = _.mtime.getTime(), + a = _.ctime.getTime(); + return ( + (tempI64 = [ + Math.floor(s / 1e3) >>> 0, + ((tempDouble = Math.floor(s / 1e3)), + +Math.abs(tempDouble) >= 1 + ? tempDouble > 0 + ? +Math.floor(tempDouble / 4294967296) >>> 0 + : ~~+Math.ceil( + (tempDouble - +(~~tempDouble >>> 0)) / 4294967296 + ) >>> 0 + : 0), + ]), + (HEAP32[(r + 56) >> 2] = tempI64[0]), + (HEAP32[(r + 60) >> 2] = tempI64[1]), + (HEAPU32[(r + 64) >> 2] = (s % 1e3) * 1e3), + (tempI64 = [ + Math.floor(n / 1e3) >>> 0, + ((tempDouble = Math.floor(n / 1e3)), + +Math.abs(tempDouble) >= 1 + ? tempDouble > 0 + ? +Math.floor(tempDouble / 4294967296) >>> 0 + : ~~+Math.ceil( + (tempDouble - +(~~tempDouble >>> 0)) / 4294967296 + ) >>> 0 + : 0), + ]), + (HEAP32[(r + 72) >> 2] = tempI64[0]), + (HEAP32[(r + 76) >> 2] = tempI64[1]), + (HEAPU32[(r + 80) >> 2] = (n % 1e3) * 1e3), + (tempI64 = [ + Math.floor(a / 1e3) >>> 0, + ((tempDouble = Math.floor(a / 1e3)), + +Math.abs(tempDouble) >= 1 + ? tempDouble > 0 + ? +Math.floor(tempDouble / 4294967296) >>> 0 + : ~~+Math.ceil( + (tempDouble - +(~~tempDouble >>> 0)) / 4294967296 + ) >>> 0 + : 0), + ]), + (HEAP32[(r + 88) >> 2] = tempI64[0]), + (HEAP32[(r + 92) >> 2] = tempI64[1]), + (HEAPU32[(r + 96) >> 2] = (a % 1e3) * 1e3), + (tempI64 = [ + _.ino >>> 0, + ((tempDouble = _.ino), + +Math.abs(tempDouble) >= 1 + ? tempDouble > 0 + ? +Math.floor(tempDouble / 4294967296) >>> 0 + : ~~+Math.ceil( + (tempDouble - +(~~tempDouble >>> 0)) / 4294967296 + ) >>> 0 + : 0), + ]), + (HEAP32[(r + 104) >> 2] = tempI64[0]), + (HEAP32[(r + 108) >> 2] = tempI64[1]), + 0 + ); + }, + doMsync: function (e, t, r, _, s) { + if (!FS.isFile(t.node.mode)) throw new FS.ErrnoError(43); + if (2 & _) return 0; + var n = HEAPU8.slice(e, e + r); + FS.msync(t, n, s, r, _); + }, + varargs: void 0, + get: function () { + return ( + (SYSCALLS.varargs += 4), HEAP32[(SYSCALLS.varargs - 4) >> 2] + ); + }, + getStr: function (e) { + return UTF8ToString(e); + }, + getStreamFromFD: function (e) { + var t = FS.getStream(e); + if (!t) throw new FS.ErrnoError(8); + return t; + }, + }; + function _fd_close(e) { + try { + var t = SYSCALLS.getStreamFromFD(e); + return FS.close(t), 0; + } catch (e) { + if ("undefined" == typeof FS || "ErrnoError" !== e.name) + throw e; + return e.errno; + } + } + function convertI32PairToI53Checked(e, t) { + return (t + 2097152) >>> 0 < 4194305 - !!e + ? (e >>> 0) + 4294967296 * t + : NaN; + } + function _fd_seek(e, t, r, _, s) { + try { + var n = convertI32PairToI53Checked(t, r); + if (isNaN(n)) return 61; + var a = SYSCALLS.getStreamFromFD(e); + return ( + FS.llseek(a, n, _), + (tempI64 = [ + a.position >>> 0, + ((tempDouble = a.position), + +Math.abs(tempDouble) >= 1 + ? tempDouble > 0 + ? +Math.floor(tempDouble / 4294967296) >>> 0 + : ~~+Math.ceil( + (tempDouble - +(~~tempDouble >>> 0)) / 4294967296 + ) >>> 0 + : 0), + ]), + (HEAP32[s >> 2] = tempI64[0]), + (HEAP32[(s + 4) >> 2] = tempI64[1]), + a.getdents && 0 === n && 0 === _ && (a.getdents = null), + 0 + ); + } catch (e) { + if ("undefined" == typeof FS || "ErrnoError" !== e.name) + throw e; + return e.errno; + } + } + function doWritev(e, t, r, _) { + for (var s = 0, n = 0; n < r; n++) { + var a = HEAPU32[t >> 2], + o = HEAPU32[(t + 4) >> 2]; + t += 8; + var l = FS.write(e, HEAP8, a, o, _); + if (l < 0) return -1; + (s += l), void 0 !== _ && (_ += l); + } + return s; + } + function _fd_write(e, t, r, _) { + try { + var s = doWritev(SYSCALLS.getStreamFromFD(e), t, r); + return (HEAPU32[_ >> 2] = s), 0; + } catch (e) { + if ("undefined" == typeof FS || "ErrnoError" !== e.name) + throw e; + return e.errno; + } + } + function _tree_sitter_log_callback(e, t) { + if (currentLogCallback) { + const r = UTF8ToString(t); + currentLogCallback(r, 0 !== e); + } + } + function _tree_sitter_parse_callback(e, t, r, _, s) { + const n = currentParseCallback(t, { row: r, column: _ }); + "string" == typeof n + ? (setValue(s, n.length, "i32"), stringToUTF16(n, e, 10240)) + : setValue(s, 0, "i32"); + } + function _proc_exit(e) { + (EXITSTATUS = e), + keepRuntimeAlive() || + (Module.onExit && Module.onExit(e), (ABORT = !0)), + quit_(e, new ExitStatus(e)); + } + function exitJS(e, t) { + (EXITSTATUS = e), _proc_exit(e); + } + function handleException(e) { + if (e instanceof ExitStatus || "unwind" == e) return EXITSTATUS; + quit_(1, e); + } + function lengthBytesUTF8(e) { + for (var t = 0, r = 0; r < e.length; ++r) { + var _ = e.charCodeAt(r); + _ <= 127 + ? t++ + : _ <= 2047 + ? (t += 2) + : _ >= 55296 && _ <= 57343 + ? ((t += 4), ++r) + : (t += 3); + } + return t; + } + function stringToUTF8Array(e, t, r, _) { + if (!(_ > 0)) return 0; + for (var s = r, n = r + _ - 1, a = 0; a < e.length; ++a) { + var o = e.charCodeAt(a); + if (o >= 55296 && o <= 57343) + o = + (65536 + ((1023 & o) << 10)) | (1023 & e.charCodeAt(++a)); + if (o <= 127) { + if (r >= n) break; + t[r++] = o; + } else if (o <= 2047) { + if (r + 1 >= n) break; + (t[r++] = 192 | (o >> 6)), (t[r++] = 128 | (63 & o)); + } else if (o <= 65535) { + if (r + 2 >= n) break; + (t[r++] = 224 | (o >> 12)), + (t[r++] = 128 | ((o >> 6) & 63)), + (t[r++] = 128 | (63 & o)); + } else { + if (r + 3 >= n) break; + (t[r++] = 240 | (o >> 18)), + (t[r++] = 128 | ((o >> 12) & 63)), + (t[r++] = 128 | ((o >> 6) & 63)), + (t[r++] = 128 | (63 & o)); + } + } + return (t[r] = 0), r - s; + } + function stringToUTF8(e, t, r) { + return stringToUTF8Array(e, HEAPU8, t, r); + } + function stringToUTF8OnStack(e) { + var t = lengthBytesUTF8(e) + 1, + r = stackAlloc(t); + return stringToUTF8(e, r, t), r; + } + function stringToUTF16(e, t, r) { + if ((void 0 === r && (r = 2147483647), r < 2)) return 0; + for ( + var _ = t, + s = (r -= 2) < 2 * e.length ? r / 2 : e.length, + n = 0; + n < s; + ++n + ) { + var a = e.charCodeAt(n); + (HEAP16[t >> 1] = a), (t += 2); + } + return (HEAP16[t >> 1] = 0), t - _; + } + function AsciiToString(e) { + for (var t = ""; ; ) { + var r = HEAPU8[e++ | 0]; + if (!r) return t; + t += String.fromCharCode(r); + } + } + (_fd_close.sig = "ii"), + (_fd_seek.sig = "iijip"), + (_fd_write.sig = "iippp"), + (_proc_exit.sig = "vi"); + var wasmImports = { + __heap_base: ___heap_base, + __indirect_function_table: wasmTable, + __memory_base: ___memory_base, + __stack_pointer: ___stack_pointer, + __table_base: ___table_base, + _emscripten_get_now_is_monotonic: + __emscripten_get_now_is_monotonic, + abort: _abort, + emscripten_get_now: _emscripten_get_now, + emscripten_memcpy_big: _emscripten_memcpy_big, + emscripten_resize_heap: _emscripten_resize_heap, + fd_close: _fd_close, + fd_seek: _fd_seek, + fd_write: _fd_write, + memory: wasmMemory, + tree_sitter_log_callback: _tree_sitter_log_callback, + tree_sitter_parse_callback: _tree_sitter_parse_callback, + }, + asm = createWasm(), + ___wasm_call_ctors = function () { + return (___wasm_call_ctors = + Module.asm.__wasm_call_ctors).apply(null, arguments); + }, + ___wasm_apply_data_relocs = (Module.___wasm_apply_data_relocs = + function () { + return (___wasm_apply_data_relocs = + Module.___wasm_apply_data_relocs = + Module.asm.__wasm_apply_data_relocs).apply( + null, + arguments + ); + }), + _malloc = (Module._malloc = function () { + return (_malloc = Module._malloc = Module.asm.malloc).apply( + null, + arguments + ); + }), + _calloc = (Module._calloc = function () { + return (_calloc = Module._calloc = Module.asm.calloc).apply( + null, + arguments + ); + }), + _realloc = (Module._realloc = function () { + return (_realloc = Module._realloc = + Module.asm.realloc).apply(null, arguments); + }), + _free = (Module._free = function () { + return (_free = Module._free = Module.asm.free).apply( + null, + arguments + ); + }), + _ts_language_symbol_count = (Module._ts_language_symbol_count = + function () { + return (_ts_language_symbol_count = + Module._ts_language_symbol_count = + Module.asm.ts_language_symbol_count).apply( + null, + arguments + ); + }), + _ts_language_state_count = (Module._ts_language_state_count = + function () { + return (_ts_language_state_count = + Module._ts_language_state_count = + Module.asm.ts_language_state_count).apply( + null, + arguments + ); + }), + _ts_language_version = (Module._ts_language_version = + function () { + return (_ts_language_version = Module._ts_language_version = + Module.asm.ts_language_version).apply(null, arguments); + }), + _ts_language_field_count = (Module._ts_language_field_count = + function () { + return (_ts_language_field_count = + Module._ts_language_field_count = + Module.asm.ts_language_field_count).apply( + null, + arguments + ); + }), + _ts_language_next_state = (Module._ts_language_next_state = + function () { + return (_ts_language_next_state = + Module._ts_language_next_state = + Module.asm.ts_language_next_state).apply( + null, + arguments + ); + }), + _ts_language_symbol_name = (Module._ts_language_symbol_name = + function () { + return (_ts_language_symbol_name = + Module._ts_language_symbol_name = + Module.asm.ts_language_symbol_name).apply( + null, + arguments + ); + }), + _ts_language_symbol_for_name = + (Module._ts_language_symbol_for_name = function () { + return (_ts_language_symbol_for_name = + Module._ts_language_symbol_for_name = + Module.asm.ts_language_symbol_for_name).apply( + null, + arguments + ); + }), + _ts_language_symbol_type = (Module._ts_language_symbol_type = + function () { + return (_ts_language_symbol_type = + Module._ts_language_symbol_type = + Module.asm.ts_language_symbol_type).apply( + null, + arguments + ); + }), + _ts_language_field_name_for_id = + (Module._ts_language_field_name_for_id = function () { + return (_ts_language_field_name_for_id = + Module._ts_language_field_name_for_id = + Module.asm.ts_language_field_name_for_id).apply( + null, + arguments + ); + }), + _ts_lookahead_iterator_new = + (Module._ts_lookahead_iterator_new = function () { + return (_ts_lookahead_iterator_new = + Module._ts_lookahead_iterator_new = + Module.asm.ts_lookahead_iterator_new).apply( + null, + arguments + ); + }), + _ts_lookahead_iterator_delete = + (Module._ts_lookahead_iterator_delete = function () { + return (_ts_lookahead_iterator_delete = + Module._ts_lookahead_iterator_delete = + Module.asm.ts_lookahead_iterator_delete).apply( + null, + arguments + ); + }), + _ts_lookahead_iterator_reset_state = + (Module._ts_lookahead_iterator_reset_state = function () { + return (_ts_lookahead_iterator_reset_state = + Module._ts_lookahead_iterator_reset_state = + Module.asm.ts_lookahead_iterator_reset_state).apply( + null, + arguments + ); + }), + _ts_lookahead_iterator_reset = + (Module._ts_lookahead_iterator_reset = function () { + return (_ts_lookahead_iterator_reset = + Module._ts_lookahead_iterator_reset = + Module.asm.ts_lookahead_iterator_reset).apply( + null, + arguments + ); + }), + _ts_lookahead_iterator_next = + (Module._ts_lookahead_iterator_next = function () { + return (_ts_lookahead_iterator_next = + Module._ts_lookahead_iterator_next = + Module.asm.ts_lookahead_iterator_next).apply( + null, + arguments + ); + }), + _ts_lookahead_iterator_current_symbol = + (Module._ts_lookahead_iterator_current_symbol = function () { + return (_ts_lookahead_iterator_current_symbol = + Module._ts_lookahead_iterator_current_symbol = + Module.asm.ts_lookahead_iterator_current_symbol).apply( + null, + arguments + ); + }), + _memset = (Module._memset = function () { + return (_memset = Module._memset = Module.asm.memset).apply( + null, + arguments + ); + }), + _memcpy = (Module._memcpy = function () { + return (_memcpy = Module._memcpy = Module.asm.memcpy).apply( + null, + arguments + ); + }), + _ts_parser_delete = (Module._ts_parser_delete = function () { + return (_ts_parser_delete = Module._ts_parser_delete = + Module.asm.ts_parser_delete).apply(null, arguments); + }), + _ts_parser_reset = (Module._ts_parser_reset = function () { + return (_ts_parser_reset = Module._ts_parser_reset = + Module.asm.ts_parser_reset).apply(null, arguments); + }), + _ts_parser_set_language = (Module._ts_parser_set_language = + function () { + return (_ts_parser_set_language = + Module._ts_parser_set_language = + Module.asm.ts_parser_set_language).apply( + null, + arguments + ); + }), + _ts_parser_timeout_micros = (Module._ts_parser_timeout_micros = + function () { + return (_ts_parser_timeout_micros = + Module._ts_parser_timeout_micros = + Module.asm.ts_parser_timeout_micros).apply( + null, + arguments + ); + }), + _ts_parser_set_timeout_micros = + (Module._ts_parser_set_timeout_micros = function () { + return (_ts_parser_set_timeout_micros = + Module._ts_parser_set_timeout_micros = + Module.asm.ts_parser_set_timeout_micros).apply( + null, + arguments + ); + }), + _ts_parser_set_included_ranges = + (Module._ts_parser_set_included_ranges = function () { + return (_ts_parser_set_included_ranges = + Module._ts_parser_set_included_ranges = + Module.asm.ts_parser_set_included_ranges).apply( + null, + arguments + ); + }), + _memmove = (Module._memmove = function () { + return (_memmove = Module._memmove = + Module.asm.memmove).apply(null, arguments); + }), + _memcmp = (Module._memcmp = function () { + return (_memcmp = Module._memcmp = Module.asm.memcmp).apply( + null, + arguments + ); + }), + _ts_query_new = (Module._ts_query_new = function () { + return (_ts_query_new = Module._ts_query_new = + Module.asm.ts_query_new).apply(null, arguments); + }), + _ts_query_delete = (Module._ts_query_delete = function () { + return (_ts_query_delete = Module._ts_query_delete = + Module.asm.ts_query_delete).apply(null, arguments); + }), + _iswspace = (Module._iswspace = function () { + return (_iswspace = Module._iswspace = + Module.asm.iswspace).apply(null, arguments); + }), + _iswalnum = (Module._iswalnum = function () { + return (_iswalnum = Module._iswalnum = + Module.asm.iswalnum).apply(null, arguments); + }), + _ts_query_pattern_count = (Module._ts_query_pattern_count = + function () { + return (_ts_query_pattern_count = + Module._ts_query_pattern_count = + Module.asm.ts_query_pattern_count).apply( + null, + arguments + ); + }), + _ts_query_capture_count = (Module._ts_query_capture_count = + function () { + return (_ts_query_capture_count = + Module._ts_query_capture_count = + Module.asm.ts_query_capture_count).apply( + null, + arguments + ); + }), + _ts_query_string_count = (Module._ts_query_string_count = + function () { + return (_ts_query_string_count = + Module._ts_query_string_count = + Module.asm.ts_query_string_count).apply( + null, + arguments + ); + }), + _ts_query_capture_name_for_id = + (Module._ts_query_capture_name_for_id = function () { + return (_ts_query_capture_name_for_id = + Module._ts_query_capture_name_for_id = + Module.asm.ts_query_capture_name_for_id).apply( + null, + arguments + ); + }), + _ts_query_string_value_for_id = + (Module._ts_query_string_value_for_id = function () { + return (_ts_query_string_value_for_id = + Module._ts_query_string_value_for_id = + Module.asm.ts_query_string_value_for_id).apply( + null, + arguments + ); + }), + _ts_query_predicates_for_pattern = + (Module._ts_query_predicates_for_pattern = function () { + return (_ts_query_predicates_for_pattern = + Module._ts_query_predicates_for_pattern = + Module.asm.ts_query_predicates_for_pattern).apply( + null, + arguments + ); + }), + _ts_query_disable_capture = (Module._ts_query_disable_capture = + function () { + return (_ts_query_disable_capture = + Module._ts_query_disable_capture = + Module.asm.ts_query_disable_capture).apply( + null, + arguments + ); + }), + _ts_tree_copy = (Module._ts_tree_copy = function () { + return (_ts_tree_copy = Module._ts_tree_copy = + Module.asm.ts_tree_copy).apply(null, arguments); + }), + _ts_tree_delete = (Module._ts_tree_delete = function () { + return (_ts_tree_delete = Module._ts_tree_delete = + Module.asm.ts_tree_delete).apply(null, arguments); + }), + _ts_init = (Module._ts_init = function () { + return (_ts_init = Module._ts_init = + Module.asm.ts_init).apply(null, arguments); + }), + _ts_parser_new_wasm = (Module._ts_parser_new_wasm = + function () { + return (_ts_parser_new_wasm = Module._ts_parser_new_wasm = + Module.asm.ts_parser_new_wasm).apply(null, arguments); + }), + _ts_parser_enable_logger_wasm = + (Module._ts_parser_enable_logger_wasm = function () { + return (_ts_parser_enable_logger_wasm = + Module._ts_parser_enable_logger_wasm = + Module.asm.ts_parser_enable_logger_wasm).apply( + null, + arguments + ); + }), + _ts_parser_parse_wasm = (Module._ts_parser_parse_wasm = + function () { + return (_ts_parser_parse_wasm = + Module._ts_parser_parse_wasm = + Module.asm.ts_parser_parse_wasm).apply(null, arguments); + }), + _ts_parser_included_ranges_wasm = + (Module._ts_parser_included_ranges_wasm = function () { + return (_ts_parser_included_ranges_wasm = + Module._ts_parser_included_ranges_wasm = + Module.asm.ts_parser_included_ranges_wasm).apply( + null, + arguments + ); + }), + _ts_language_type_is_named_wasm = + (Module._ts_language_type_is_named_wasm = function () { + return (_ts_language_type_is_named_wasm = + Module._ts_language_type_is_named_wasm = + Module.asm.ts_language_type_is_named_wasm).apply( + null, + arguments + ); + }), + _ts_language_type_is_visible_wasm = + (Module._ts_language_type_is_visible_wasm = function () { + return (_ts_language_type_is_visible_wasm = + Module._ts_language_type_is_visible_wasm = + Module.asm.ts_language_type_is_visible_wasm).apply( + null, + arguments + ); + }), + _ts_tree_root_node_wasm = (Module._ts_tree_root_node_wasm = + function () { + return (_ts_tree_root_node_wasm = + Module._ts_tree_root_node_wasm = + Module.asm.ts_tree_root_node_wasm).apply( + null, + arguments + ); + }), + _ts_tree_root_node_with_offset_wasm = + (Module._ts_tree_root_node_with_offset_wasm = function () { + return (_ts_tree_root_node_with_offset_wasm = + Module._ts_tree_root_node_with_offset_wasm = + Module.asm.ts_tree_root_node_with_offset_wasm).apply( + null, + arguments + ); + }), + _ts_tree_edit_wasm = (Module._ts_tree_edit_wasm = function () { + return (_ts_tree_edit_wasm = Module._ts_tree_edit_wasm = + Module.asm.ts_tree_edit_wasm).apply(null, arguments); + }), + _ts_tree_included_ranges_wasm = + (Module._ts_tree_included_ranges_wasm = function () { + return (_ts_tree_included_ranges_wasm = + Module._ts_tree_included_ranges_wasm = + Module.asm.ts_tree_included_ranges_wasm).apply( + null, + arguments + ); + }), + _ts_tree_get_changed_ranges_wasm = + (Module._ts_tree_get_changed_ranges_wasm = function () { + return (_ts_tree_get_changed_ranges_wasm = + Module._ts_tree_get_changed_ranges_wasm = + Module.asm.ts_tree_get_changed_ranges_wasm).apply( + null, + arguments + ); + }), + _ts_tree_cursor_new_wasm = (Module._ts_tree_cursor_new_wasm = + function () { + return (_ts_tree_cursor_new_wasm = + Module._ts_tree_cursor_new_wasm = + Module.asm.ts_tree_cursor_new_wasm).apply( + null, + arguments + ); + }), + _ts_tree_cursor_delete_wasm = + (Module._ts_tree_cursor_delete_wasm = function () { + return (_ts_tree_cursor_delete_wasm = + Module._ts_tree_cursor_delete_wasm = + Module.asm.ts_tree_cursor_delete_wasm).apply( + null, + arguments + ); + }), + _ts_tree_cursor_reset_wasm = + (Module._ts_tree_cursor_reset_wasm = function () { + return (_ts_tree_cursor_reset_wasm = + Module._ts_tree_cursor_reset_wasm = + Module.asm.ts_tree_cursor_reset_wasm).apply( + null, + arguments + ); + }), + _ts_tree_cursor_reset_to_wasm = + (Module._ts_tree_cursor_reset_to_wasm = function () { + return (_ts_tree_cursor_reset_to_wasm = + Module._ts_tree_cursor_reset_to_wasm = + Module.asm.ts_tree_cursor_reset_to_wasm).apply( + null, + arguments + ); + }), + _ts_tree_cursor_goto_first_child_wasm = + (Module._ts_tree_cursor_goto_first_child_wasm = function () { + return (_ts_tree_cursor_goto_first_child_wasm = + Module._ts_tree_cursor_goto_first_child_wasm = + Module.asm.ts_tree_cursor_goto_first_child_wasm).apply( + null, + arguments + ); + }), + _ts_tree_cursor_goto_last_child_wasm = + (Module._ts_tree_cursor_goto_last_child_wasm = function () { + return (_ts_tree_cursor_goto_last_child_wasm = + Module._ts_tree_cursor_goto_last_child_wasm = + Module.asm.ts_tree_cursor_goto_last_child_wasm).apply( + null, + arguments + ); + }), + _ts_tree_cursor_goto_first_child_for_index_wasm = + (Module._ts_tree_cursor_goto_first_child_for_index_wasm = + function () { + return (_ts_tree_cursor_goto_first_child_for_index_wasm = + Module._ts_tree_cursor_goto_first_child_for_index_wasm = + Module.asm.ts_tree_cursor_goto_first_child_for_index_wasm).apply( + null, + arguments + ); + }), + _ts_tree_cursor_goto_first_child_for_position_wasm = + (Module._ts_tree_cursor_goto_first_child_for_position_wasm = + function () { + return (_ts_tree_cursor_goto_first_child_for_position_wasm = + Module._ts_tree_cursor_goto_first_child_for_position_wasm = + Module.asm.ts_tree_cursor_goto_first_child_for_position_wasm).apply( + null, + arguments + ); + }), + _ts_tree_cursor_goto_next_sibling_wasm = + (Module._ts_tree_cursor_goto_next_sibling_wasm = function () { + return (_ts_tree_cursor_goto_next_sibling_wasm = + Module._ts_tree_cursor_goto_next_sibling_wasm = + Module.asm.ts_tree_cursor_goto_next_sibling_wasm).apply( + null, + arguments + ); + }), + _ts_tree_cursor_goto_previous_sibling_wasm = + (Module._ts_tree_cursor_goto_previous_sibling_wasm = + function () { + return (_ts_tree_cursor_goto_previous_sibling_wasm = + Module._ts_tree_cursor_goto_previous_sibling_wasm = + Module.asm.ts_tree_cursor_goto_previous_sibling_wasm).apply( + null, + arguments + ); + }), + _ts_tree_cursor_goto_descendant_wasm = + (Module._ts_tree_cursor_goto_descendant_wasm = function () { + return (_ts_tree_cursor_goto_descendant_wasm = + Module._ts_tree_cursor_goto_descendant_wasm = + Module.asm.ts_tree_cursor_goto_descendant_wasm).apply( + null, + arguments + ); + }), + _ts_tree_cursor_goto_parent_wasm = + (Module._ts_tree_cursor_goto_parent_wasm = function () { + return (_ts_tree_cursor_goto_parent_wasm = + Module._ts_tree_cursor_goto_parent_wasm = + Module.asm.ts_tree_cursor_goto_parent_wasm).apply( + null, + arguments + ); + }), + _ts_tree_cursor_current_node_type_id_wasm = + (Module._ts_tree_cursor_current_node_type_id_wasm = + function () { + return (_ts_tree_cursor_current_node_type_id_wasm = + Module._ts_tree_cursor_current_node_type_id_wasm = + Module.asm.ts_tree_cursor_current_node_type_id_wasm).apply( + null, + arguments + ); + }), + _ts_tree_cursor_current_node_state_id_wasm = + (Module._ts_tree_cursor_current_node_state_id_wasm = + function () { + return (_ts_tree_cursor_current_node_state_id_wasm = + Module._ts_tree_cursor_current_node_state_id_wasm = + Module.asm.ts_tree_cursor_current_node_state_id_wasm).apply( + null, + arguments + ); + }), + _ts_tree_cursor_current_node_is_named_wasm = + (Module._ts_tree_cursor_current_node_is_named_wasm = + function () { + return (_ts_tree_cursor_current_node_is_named_wasm = + Module._ts_tree_cursor_current_node_is_named_wasm = + Module.asm.ts_tree_cursor_current_node_is_named_wasm).apply( + null, + arguments + ); + }), + _ts_tree_cursor_current_node_is_missing_wasm = + (Module._ts_tree_cursor_current_node_is_missing_wasm = + function () { + return (_ts_tree_cursor_current_node_is_missing_wasm = + Module._ts_tree_cursor_current_node_is_missing_wasm = + Module.asm.ts_tree_cursor_current_node_is_missing_wasm).apply( + null, + arguments + ); + }), + _ts_tree_cursor_current_node_id_wasm = + (Module._ts_tree_cursor_current_node_id_wasm = function () { + return (_ts_tree_cursor_current_node_id_wasm = + Module._ts_tree_cursor_current_node_id_wasm = + Module.asm.ts_tree_cursor_current_node_id_wasm).apply( + null, + arguments + ); + }), + _ts_tree_cursor_start_position_wasm = + (Module._ts_tree_cursor_start_position_wasm = function () { + return (_ts_tree_cursor_start_position_wasm = + Module._ts_tree_cursor_start_position_wasm = + Module.asm.ts_tree_cursor_start_position_wasm).apply( + null, + arguments + ); + }), + _ts_tree_cursor_end_position_wasm = + (Module._ts_tree_cursor_end_position_wasm = function () { + return (_ts_tree_cursor_end_position_wasm = + Module._ts_tree_cursor_end_position_wasm = + Module.asm.ts_tree_cursor_end_position_wasm).apply( + null, + arguments + ); + }), + _ts_tree_cursor_start_index_wasm = + (Module._ts_tree_cursor_start_index_wasm = function () { + return (_ts_tree_cursor_start_index_wasm = + Module._ts_tree_cursor_start_index_wasm = + Module.asm.ts_tree_cursor_start_index_wasm).apply( + null, + arguments + ); + }), + _ts_tree_cursor_end_index_wasm = + (Module._ts_tree_cursor_end_index_wasm = function () { + return (_ts_tree_cursor_end_index_wasm = + Module._ts_tree_cursor_end_index_wasm = + Module.asm.ts_tree_cursor_end_index_wasm).apply( + null, + arguments + ); + }), + _ts_tree_cursor_current_field_id_wasm = + (Module._ts_tree_cursor_current_field_id_wasm = function () { + return (_ts_tree_cursor_current_field_id_wasm = + Module._ts_tree_cursor_current_field_id_wasm = + Module.asm.ts_tree_cursor_current_field_id_wasm).apply( + null, + arguments + ); + }), + _ts_tree_cursor_current_depth_wasm = + (Module._ts_tree_cursor_current_depth_wasm = function () { + return (_ts_tree_cursor_current_depth_wasm = + Module._ts_tree_cursor_current_depth_wasm = + Module.asm.ts_tree_cursor_current_depth_wasm).apply( + null, + arguments + ); + }), + _ts_tree_cursor_current_descendant_index_wasm = + (Module._ts_tree_cursor_current_descendant_index_wasm = + function () { + return (_ts_tree_cursor_current_descendant_index_wasm = + Module._ts_tree_cursor_current_descendant_index_wasm = + Module.asm.ts_tree_cursor_current_descendant_index_wasm).apply( + null, + arguments + ); + }), + _ts_tree_cursor_current_node_wasm = + (Module._ts_tree_cursor_current_node_wasm = function () { + return (_ts_tree_cursor_current_node_wasm = + Module._ts_tree_cursor_current_node_wasm = + Module.asm.ts_tree_cursor_current_node_wasm).apply( + null, + arguments + ); + }), + _ts_node_symbol_wasm = (Module._ts_node_symbol_wasm = + function () { + return (_ts_node_symbol_wasm = Module._ts_node_symbol_wasm = + Module.asm.ts_node_symbol_wasm).apply(null, arguments); + }), + _ts_node_field_name_for_child_wasm = + (Module._ts_node_field_name_for_child_wasm = function () { + return (_ts_node_field_name_for_child_wasm = + Module._ts_node_field_name_for_child_wasm = + Module.asm.ts_node_field_name_for_child_wasm).apply( + null, + arguments + ); + }), + _ts_node_children_by_field_id_wasm = + (Module._ts_node_children_by_field_id_wasm = function () { + return (_ts_node_children_by_field_id_wasm = + Module._ts_node_children_by_field_id_wasm = + Module.asm.ts_node_children_by_field_id_wasm).apply( + null, + arguments + ); + }), + _ts_node_first_child_for_byte_wasm = + (Module._ts_node_first_child_for_byte_wasm = function () { + return (_ts_node_first_child_for_byte_wasm = + Module._ts_node_first_child_for_byte_wasm = + Module.asm.ts_node_first_child_for_byte_wasm).apply( + null, + arguments + ); + }), + _ts_node_first_named_child_for_byte_wasm = + (Module._ts_node_first_named_child_for_byte_wasm = + function () { + return (_ts_node_first_named_child_for_byte_wasm = + Module._ts_node_first_named_child_for_byte_wasm = + Module.asm.ts_node_first_named_child_for_byte_wasm).apply( + null, + arguments + ); + }), + _ts_node_grammar_symbol_wasm = + (Module._ts_node_grammar_symbol_wasm = function () { + return (_ts_node_grammar_symbol_wasm = + Module._ts_node_grammar_symbol_wasm = + Module.asm.ts_node_grammar_symbol_wasm).apply( + null, + arguments + ); + }), + _ts_node_child_count_wasm = (Module._ts_node_child_count_wasm = + function () { + return (_ts_node_child_count_wasm = + Module._ts_node_child_count_wasm = + Module.asm.ts_node_child_count_wasm).apply( + null, + arguments + ); + }), + _ts_node_named_child_count_wasm = + (Module._ts_node_named_child_count_wasm = function () { + return (_ts_node_named_child_count_wasm = + Module._ts_node_named_child_count_wasm = + Module.asm.ts_node_named_child_count_wasm).apply( + null, + arguments + ); + }), + _ts_node_child_wasm = (Module._ts_node_child_wasm = + function () { + return (_ts_node_child_wasm = Module._ts_node_child_wasm = + Module.asm.ts_node_child_wasm).apply(null, arguments); + }), + _ts_node_named_child_wasm = (Module._ts_node_named_child_wasm = + function () { + return (_ts_node_named_child_wasm = + Module._ts_node_named_child_wasm = + Module.asm.ts_node_named_child_wasm).apply( + null, + arguments + ); + }), + _ts_node_child_by_field_id_wasm = + (Module._ts_node_child_by_field_id_wasm = function () { + return (_ts_node_child_by_field_id_wasm = + Module._ts_node_child_by_field_id_wasm = + Module.asm.ts_node_child_by_field_id_wasm).apply( + null, + arguments + ); + }), + _ts_node_next_sibling_wasm = + (Module._ts_node_next_sibling_wasm = function () { + return (_ts_node_next_sibling_wasm = + Module._ts_node_next_sibling_wasm = + Module.asm.ts_node_next_sibling_wasm).apply( + null, + arguments + ); + }), + _ts_node_prev_sibling_wasm = + (Module._ts_node_prev_sibling_wasm = function () { + return (_ts_node_prev_sibling_wasm = + Module._ts_node_prev_sibling_wasm = + Module.asm.ts_node_prev_sibling_wasm).apply( + null, + arguments + ); + }), + _ts_node_next_named_sibling_wasm = + (Module._ts_node_next_named_sibling_wasm = function () { + return (_ts_node_next_named_sibling_wasm = + Module._ts_node_next_named_sibling_wasm = + Module.asm.ts_node_next_named_sibling_wasm).apply( + null, + arguments + ); + }), + _ts_node_prev_named_sibling_wasm = + (Module._ts_node_prev_named_sibling_wasm = function () { + return (_ts_node_prev_named_sibling_wasm = + Module._ts_node_prev_named_sibling_wasm = + Module.asm.ts_node_prev_named_sibling_wasm).apply( + null, + arguments + ); + }), + _ts_node_descendant_count_wasm = + (Module._ts_node_descendant_count_wasm = function () { + return (_ts_node_descendant_count_wasm = + Module._ts_node_descendant_count_wasm = + Module.asm.ts_node_descendant_count_wasm).apply( + null, + arguments + ); + }), + _ts_node_parent_wasm = (Module._ts_node_parent_wasm = + function () { + return (_ts_node_parent_wasm = Module._ts_node_parent_wasm = + Module.asm.ts_node_parent_wasm).apply(null, arguments); + }), + _ts_node_descendant_for_index_wasm = + (Module._ts_node_descendant_for_index_wasm = function () { + return (_ts_node_descendant_for_index_wasm = + Module._ts_node_descendant_for_index_wasm = + Module.asm.ts_node_descendant_for_index_wasm).apply( + null, + arguments + ); + }), + _ts_node_named_descendant_for_index_wasm = + (Module._ts_node_named_descendant_for_index_wasm = + function () { + return (_ts_node_named_descendant_for_index_wasm = + Module._ts_node_named_descendant_for_index_wasm = + Module.asm.ts_node_named_descendant_for_index_wasm).apply( + null, + arguments + ); + }), + _ts_node_descendant_for_position_wasm = + (Module._ts_node_descendant_for_position_wasm = function () { + return (_ts_node_descendant_for_position_wasm = + Module._ts_node_descendant_for_position_wasm = + Module.asm.ts_node_descendant_for_position_wasm).apply( + null, + arguments + ); + }), + _ts_node_named_descendant_for_position_wasm = + (Module._ts_node_named_descendant_for_position_wasm = + function () { + return (_ts_node_named_descendant_for_position_wasm = + Module._ts_node_named_descendant_for_position_wasm = + Module.asm.ts_node_named_descendant_for_position_wasm).apply( + null, + arguments + ); + }), + _ts_node_start_point_wasm = (Module._ts_node_start_point_wasm = + function () { + return (_ts_node_start_point_wasm = + Module._ts_node_start_point_wasm = + Module.asm.ts_node_start_point_wasm).apply( + null, + arguments + ); + }), + _ts_node_end_point_wasm = (Module._ts_node_end_point_wasm = + function () { + return (_ts_node_end_point_wasm = + Module._ts_node_end_point_wasm = + Module.asm.ts_node_end_point_wasm).apply( + null, + arguments + ); + }), + _ts_node_start_index_wasm = (Module._ts_node_start_index_wasm = + function () { + return (_ts_node_start_index_wasm = + Module._ts_node_start_index_wasm = + Module.asm.ts_node_start_index_wasm).apply( + null, + arguments + ); + }), + _ts_node_end_index_wasm = (Module._ts_node_end_index_wasm = + function () { + return (_ts_node_end_index_wasm = + Module._ts_node_end_index_wasm = + Module.asm.ts_node_end_index_wasm).apply( + null, + arguments + ); + }), + _ts_node_to_string_wasm = (Module._ts_node_to_string_wasm = + function () { + return (_ts_node_to_string_wasm = + Module._ts_node_to_string_wasm = + Module.asm.ts_node_to_string_wasm).apply( + null, + arguments + ); + }), + _ts_node_children_wasm = (Module._ts_node_children_wasm = + function () { + return (_ts_node_children_wasm = + Module._ts_node_children_wasm = + Module.asm.ts_node_children_wasm).apply( + null, + arguments + ); + }), + _ts_node_named_children_wasm = + (Module._ts_node_named_children_wasm = function () { + return (_ts_node_named_children_wasm = + Module._ts_node_named_children_wasm = + Module.asm.ts_node_named_children_wasm).apply( + null, + arguments + ); + }), + _ts_node_descendants_of_type_wasm = + (Module._ts_node_descendants_of_type_wasm = function () { + return (_ts_node_descendants_of_type_wasm = + Module._ts_node_descendants_of_type_wasm = + Module.asm.ts_node_descendants_of_type_wasm).apply( + null, + arguments + ); + }), + _ts_node_is_named_wasm = (Module._ts_node_is_named_wasm = + function () { + return (_ts_node_is_named_wasm = + Module._ts_node_is_named_wasm = + Module.asm.ts_node_is_named_wasm).apply( + null, + arguments + ); + }), + _ts_node_has_changes_wasm = (Module._ts_node_has_changes_wasm = + function () { + return (_ts_node_has_changes_wasm = + Module._ts_node_has_changes_wasm = + Module.asm.ts_node_has_changes_wasm).apply( + null, + arguments + ); + }), + _ts_node_has_error_wasm = (Module._ts_node_has_error_wasm = + function () { + return (_ts_node_has_error_wasm = + Module._ts_node_has_error_wasm = + Module.asm.ts_node_has_error_wasm).apply( + null, + arguments + ); + }), + _ts_node_is_error_wasm = (Module._ts_node_is_error_wasm = + function () { + return (_ts_node_is_error_wasm = + Module._ts_node_is_error_wasm = + Module.asm.ts_node_is_error_wasm).apply( + null, + arguments + ); + }), + _ts_node_is_missing_wasm = (Module._ts_node_is_missing_wasm = + function () { + return (_ts_node_is_missing_wasm = + Module._ts_node_is_missing_wasm = + Module.asm.ts_node_is_missing_wasm).apply( + null, + arguments + ); + }), + _ts_node_is_extra_wasm = (Module._ts_node_is_extra_wasm = + function () { + return (_ts_node_is_extra_wasm = + Module._ts_node_is_extra_wasm = + Module.asm.ts_node_is_extra_wasm).apply( + null, + arguments + ); + }), + _ts_node_parse_state_wasm = (Module._ts_node_parse_state_wasm = + function () { + return (_ts_node_parse_state_wasm = + Module._ts_node_parse_state_wasm = + Module.asm.ts_node_parse_state_wasm).apply( + null, + arguments + ); + }), + _ts_node_next_parse_state_wasm = + (Module._ts_node_next_parse_state_wasm = function () { + return (_ts_node_next_parse_state_wasm = + Module._ts_node_next_parse_state_wasm = + Module.asm.ts_node_next_parse_state_wasm).apply( + null, + arguments + ); + }), + _ts_query_matches_wasm = (Module._ts_query_matches_wasm = + function () { + return (_ts_query_matches_wasm = + Module._ts_query_matches_wasm = + Module.asm.ts_query_matches_wasm).apply( + null, + arguments + ); + }), + _ts_query_captures_wasm = (Module._ts_query_captures_wasm = + function () { + return (_ts_query_captures_wasm = + Module._ts_query_captures_wasm = + Module.asm.ts_query_captures_wasm).apply( + null, + arguments + ); + }), + ___errno_location = function () { + return (___errno_location = + Module.asm.__errno_location).apply(null, arguments); + }, + _iswdigit = (Module._iswdigit = function () { + return (_iswdigit = Module._iswdigit = + Module.asm.iswdigit).apply(null, arguments); + }), + _iswalpha = (Module._iswalpha = function () { + return (_iswalpha = Module._iswalpha = + Module.asm.iswalpha).apply(null, arguments); + }), + _iswblank = (Module._iswblank = function () { + return (_iswblank = Module._iswblank = + Module.asm.iswblank).apply(null, arguments); + }), + _iswlower = (Module._iswlower = function () { + return (_iswlower = Module._iswlower = + Module.asm.iswlower).apply(null, arguments); + }), + _iswupper = (Module._iswupper = function () { + return (_iswupper = Module._iswupper = + Module.asm.iswupper).apply(null, arguments); + }), + _iswxdigit = (Module._iswxdigit = function () { + return (_iswxdigit = Module._iswxdigit = + Module.asm.iswxdigit).apply(null, arguments); + }), + _memchr = (Module._memchr = function () { + return (_memchr = Module._memchr = Module.asm.memchr).apply( + null, + arguments + ); + }), + _strlen = (Module._strlen = function () { + return (_strlen = Module._strlen = Module.asm.strlen).apply( + null, + arguments + ); + }), + _strcmp = (Module._strcmp = function () { + return (_strcmp = Module._strcmp = Module.asm.strcmp).apply( + null, + arguments + ); + }), + _strncpy = (Module._strncpy = function () { + return (_strncpy = Module._strncpy = + Module.asm.strncpy).apply(null, arguments); + }), + _towlower = (Module._towlower = function () { + return (_towlower = Module._towlower = + Module.asm.towlower).apply(null, arguments); + }), + _towupper = (Module._towupper = function () { + return (_towupper = Module._towupper = + Module.asm.towupper).apply(null, arguments); + }), + _setThrew = function () { + return (_setThrew = Module.asm.setThrew).apply( + null, + arguments + ); + }, + stackSave = function () { + return (stackSave = Module.asm.stackSave).apply( + null, + arguments + ); + }, + stackRestore = function () { + return (stackRestore = Module.asm.stackRestore).apply( + null, + arguments + ); + }, + stackAlloc = function () { + return (stackAlloc = Module.asm.stackAlloc).apply( + null, + arguments + ); + }, + dynCall_jiji = (Module.dynCall_jiji = function () { + return (dynCall_jiji = Module.dynCall_jiji = + Module.asm.dynCall_jiji).apply(null, arguments); + }), + _orig$ts_parser_timeout_micros = + (Module._orig$ts_parser_timeout_micros = function () { + return (_orig$ts_parser_timeout_micros = + Module._orig$ts_parser_timeout_micros = + Module.asm.orig$ts_parser_timeout_micros).apply( + null, + arguments + ); + }), + _orig$ts_parser_set_timeout_micros = + (Module._orig$ts_parser_set_timeout_micros = function () { + return (_orig$ts_parser_set_timeout_micros = + Module._orig$ts_parser_set_timeout_micros = + Module.asm.orig$ts_parser_set_timeout_micros).apply( + null, + arguments + ); + }), + calledRun; + function callMain(e = []) { + var t = resolveGlobalSymbol("main").sym; + if (t) { + e.unshift(thisProgram); + var r = e.length, + _ = stackAlloc(4 * (r + 1)), + s = _ >> 2; + e.forEach((e) => { + HEAP32[s++] = stringToUTF8OnStack(e); + }), + (HEAP32[s] = 0); + try { + var n = t(r, _); + return exitJS(n, !0), n; + } catch (e) { + return handleException(e); + } + } + } + (Module.AsciiToString = AsciiToString), + (Module.stringToUTF16 = stringToUTF16), + (dependenciesFulfilled = function e() { + calledRun || run(), calledRun || (dependenciesFulfilled = e); + }); + var dylibsLoaded = !1; + function run(e = arguments_) { + function t() { + calledRun || + ((calledRun = !0), + (Module.calledRun = !0), + ABORT || + (initRuntime(), + preMain(), + Module.onRuntimeInitialized && + Module.onRuntimeInitialized(), + shouldRunNow && callMain(e), + postRun())); + } + runDependencies > 0 || + (!dylibsLoaded && + (loadDylibs(), (dylibsLoaded = !0), runDependencies > 0)) || + (preRun(), + runDependencies > 0 || + (Module.setStatus + ? (Module.setStatus("Running..."), + setTimeout(function () { + setTimeout(function () { + Module.setStatus(""); + }, 1), + t(); + }, 1)) + : t())); + } + if ((LDSO.init(), Module.preInit)) + for ( + "function" == typeof Module.preInit && + (Module.preInit = [Module.preInit]); + Module.preInit.length > 0; + + ) + Module.preInit.pop()(); + var shouldRunNow = !0; + Module.noInitialRun && (shouldRunNow = !1), run(); + const C = Module, + INTERNAL = {}, + SIZE_OF_INT = 4, + SIZE_OF_CURSOR = 3 * SIZE_OF_INT, + SIZE_OF_NODE = 5 * SIZE_OF_INT, + SIZE_OF_POINT = 2 * SIZE_OF_INT, + SIZE_OF_RANGE = 2 * SIZE_OF_INT + 2 * SIZE_OF_POINT, + ZERO_POINT = { row: 0, column: 0 }, + QUERY_WORD_REGEX = /[\w-.]*/g, + PREDICATE_STEP_TYPE_CAPTURE = 1, + PREDICATE_STEP_TYPE_STRING = 2, + LANGUAGE_FUNCTION_REGEX = /^_?tree_sitter_\w+/; + let VERSION, + MIN_COMPATIBLE_VERSION, + TRANSFER_BUFFER, + currentParseCallback, + currentLogCallback; + class ParserImpl { + static init() { + (TRANSFER_BUFFER = C._ts_init()), + (VERSION = getValue(TRANSFER_BUFFER, "i32")), + (MIN_COMPATIBLE_VERSION = getValue( + TRANSFER_BUFFER + SIZE_OF_INT, + "i32" + )); + } + initialize() { + C._ts_parser_new_wasm(), + (this[0] = getValue(TRANSFER_BUFFER, "i32")), + (this[1] = getValue(TRANSFER_BUFFER + SIZE_OF_INT, "i32")); + } + delete() { + C._ts_parser_delete(this[0]), + C._free(this[1]), + (this[0] = 0), + (this[1] = 0); + } + setLanguage(e) { + let t; + if (e) { + if (e.constructor !== Language) + throw new Error("Argument must be a Language"); + { + t = e[0]; + const r = C._ts_language_version(t); + if (r < MIN_COMPATIBLE_VERSION || VERSION < r) + throw new Error( + `Incompatible language version ${r}. Compatibility range ${MIN_COMPATIBLE_VERSION} through ${VERSION}.` + ); + } + } else (t = 0), (e = null); + return ( + (this.language = e), + C._ts_parser_set_language(this[0], t), + this + ); + } + getLanguage() { + return this.language; + } + parse(e, t, r) { + if ("string" == typeof e) + currentParseCallback = (t, r) => e.slice(t); + else { + if ("function" != typeof e) + throw new Error( + "Argument must be a string or a function" + ); + currentParseCallback = e; + } + this.logCallback + ? ((currentLogCallback = this.logCallback), + C._ts_parser_enable_logger_wasm(this[0], 1)) + : ((currentLogCallback = null), + C._ts_parser_enable_logger_wasm(this[0], 0)); + let _ = 0, + s = 0; + if (r && r.includedRanges) { + (_ = r.includedRanges.length), + (s = C._calloc(_, SIZE_OF_RANGE)); + let e = s; + for (let t = 0; t < _; t++) + marshalRange(e, r.includedRanges[t]), + (e += SIZE_OF_RANGE); + } + const n = C._ts_parser_parse_wasm( + this[0], + this[1], + t ? t[0] : 0, + s, + _ + ); + if (!n) + throw ( + ((currentParseCallback = null), + (currentLogCallback = null), + new Error("Parsing failed")) + ); + const a = new Tree( + INTERNAL, + n, + this.language, + currentParseCallback + ); + return ( + (currentParseCallback = null), + (currentLogCallback = null), + a + ); + } + reset() { + C._ts_parser_reset(this[0]); + } + getIncludedRanges() { + C._ts_parser_included_ranges_wasm(this[0]); + const e = getValue(TRANSFER_BUFFER, "i32"), + t = getValue(TRANSFER_BUFFER + SIZE_OF_INT, "i32"), + r = new Array(e); + if (e > 0) { + let _ = t; + for (let t = 0; t < e; t++) + (r[t] = unmarshalRange(_)), (_ += SIZE_OF_RANGE); + C._free(t); + } + return r; + } + getTimeoutMicros() { + return C._ts_parser_timeout_micros(this[0]); + } + setTimeoutMicros(e) { + C._ts_parser_set_timeout_micros(this[0], e); + } + setLogger(e) { + if (e) { + if ("function" != typeof e) + throw new Error("Logger callback must be a function"); + } else e = null; + return (this.logCallback = e), this; + } + getLogger() { + return this.logCallback; + } + } + class Tree { + constructor(e, t, r, _) { + assertInternal(e), + (this[0] = t), + (this.language = r), + (this.textCallback = _); + } + copy() { + const e = C._ts_tree_copy(this[0]); + return new Tree( + INTERNAL, + e, + this.language, + this.textCallback + ); + } + delete() { + C._ts_tree_delete(this[0]), (this[0] = 0); + } + edit(e) { + marshalEdit(e), C._ts_tree_edit_wasm(this[0]); + } + get rootNode() { + return ( + C._ts_tree_root_node_wasm(this[0]), unmarshalNode(this) + ); + } + rootNodeWithOffset(e, t) { + const r = TRANSFER_BUFFER + SIZE_OF_NODE; + return ( + setValue(r, e, "i32"), + marshalPoint(r + SIZE_OF_INT, t), + C._ts_tree_root_node_with_offset_wasm(this[0]), + unmarshalNode(this) + ); + } + getLanguage() { + return this.language; + } + walk() { + return this.rootNode.walk(); + } + getChangedRanges(e) { + if (e.constructor !== Tree) + throw new TypeError("Argument must be a Tree"); + C._ts_tree_get_changed_ranges_wasm(this[0], e[0]); + const t = getValue(TRANSFER_BUFFER, "i32"), + r = getValue(TRANSFER_BUFFER + SIZE_OF_INT, "i32"), + _ = new Array(t); + if (t > 0) { + let e = r; + for (let r = 0; r < t; r++) + (_[r] = unmarshalRange(e)), (e += SIZE_OF_RANGE); + C._free(r); + } + return _; + } + getIncludedRanges() { + C._ts_tree_included_ranges_wasm(this[0]); + const e = getValue(TRANSFER_BUFFER, "i32"), + t = getValue(TRANSFER_BUFFER + SIZE_OF_INT, "i32"), + r = new Array(e); + if (e > 0) { + let _ = t; + for (let t = 0; t < e; t++) + (r[t] = unmarshalRange(_)), (_ += SIZE_OF_RANGE); + C._free(t); + } + return r; + } + } + class Node { + constructor(e, t) { + assertInternal(e), (this.tree = t); + } + get typeId() { + return ( + marshalNode(this), C._ts_node_symbol_wasm(this.tree[0]) + ); + } + get grammarId() { + return ( + marshalNode(this), + C._ts_node_grammar_symbol_wasm(this.tree[0]) + ); + } + get type() { + return this.tree.language.types[this.typeId] || "ERROR"; + } + get grammarType() { + return this.tree.language.types[this.grammarId] || "ERROR"; + } + get endPosition() { + return ( + marshalNode(this), + C._ts_node_end_point_wasm(this.tree[0]), + unmarshalPoint(TRANSFER_BUFFER) + ); + } + get endIndex() { + return ( + marshalNode(this), C._ts_node_end_index_wasm(this.tree[0]) + ); + } + get text() { + return getText(this.tree, this.startIndex, this.endIndex); + } + get parseState() { + return ( + marshalNode(this), C._ts_node_parse_state_wasm(this.tree[0]) + ); + } + get nextParseState() { + return ( + marshalNode(this), + C._ts_node_next_parse_state_wasm(this.tree[0]) + ); + } + get isNamed() { + return ( + marshalNode(this), + 1 === C._ts_node_is_named_wasm(this.tree[0]) + ); + } + get hasError() { + return ( + marshalNode(this), + 1 === C._ts_node_has_error_wasm(this.tree[0]) + ); + } + get hasChanges() { + return ( + marshalNode(this), + 1 === C._ts_node_has_changes_wasm(this.tree[0]) + ); + } + get isError() { + return ( + marshalNode(this), + 1 === C._ts_node_is_error_wasm(this.tree[0]) + ); + } + get isMissing() { + return ( + marshalNode(this), + 1 === C._ts_node_is_missing_wasm(this.tree[0]) + ); + } + get isExtra() { + return ( + marshalNode(this), + 1 === C._ts_node_is_extra_wasm(this.tree[0]) + ); + } + equals(e) { + return this.id === e.id; + } + child(e) { + return ( + marshalNode(this), + C._ts_node_child_wasm(this.tree[0], e), + unmarshalNode(this.tree) + ); + } + namedChild(e) { + return ( + marshalNode(this), + C._ts_node_named_child_wasm(this.tree[0], e), + unmarshalNode(this.tree) + ); + } + childForFieldId(e) { + return ( + marshalNode(this), + C._ts_node_child_by_field_id_wasm(this.tree[0], e), + unmarshalNode(this.tree) + ); + } + childForFieldName(e) { + const t = this.tree.language.fields.indexOf(e); + if (-1 !== t) return this.childForFieldId(t); + } + fieldNameForChild(e) { + marshalNode(this); + const t = C._ts_node_field_name_for_child_wasm( + this.tree[0], + e + ); + if (!t) return null; + return AsciiToString(t); + } + childrenForFieldName(e) { + const t = this.tree.language.fields.indexOf(e); + if (-1 !== t && 0 !== t) return this.childrenForFieldId(t); + } + childrenForFieldId(e) { + marshalNode(this), + C._ts_node_children_by_field_id_wasm(this.tree[0], e); + const t = getValue(TRANSFER_BUFFER, "i32"), + r = getValue(TRANSFER_BUFFER + SIZE_OF_INT, "i32"), + _ = new Array(t); + if (t > 0) { + let e = r; + for (let r = 0; r < t; r++) + (_[r] = unmarshalNode(this.tree, e)), (e += SIZE_OF_NODE); + C._free(r); + } + return _; + } + firstChildForIndex(e) { + marshalNode(this); + return ( + setValue(TRANSFER_BUFFER + SIZE_OF_NODE, e, "i32"), + C._ts_node_first_child_for_byte_wasm(this.tree[0]), + unmarshalNode(this.tree) + ); + } + firstNamedChildForIndex(e) { + marshalNode(this); + return ( + setValue(TRANSFER_BUFFER + SIZE_OF_NODE, e, "i32"), + C._ts_node_first_named_child_for_byte_wasm(this.tree[0]), + unmarshalNode(this.tree) + ); + } + get childCount() { + return ( + marshalNode(this), C._ts_node_child_count_wasm(this.tree[0]) + ); + } + get namedChildCount() { + return ( + marshalNode(this), + C._ts_node_named_child_count_wasm(this.tree[0]) + ); + } + get firstChild() { + return this.child(0); + } + get firstNamedChild() { + return this.namedChild(0); + } + get lastChild() { + return this.child(this.childCount - 1); + } + get lastNamedChild() { + return this.namedChild(this.namedChildCount - 1); + } + get children() { + if (!this._children) { + marshalNode(this), C._ts_node_children_wasm(this.tree[0]); + const e = getValue(TRANSFER_BUFFER, "i32"), + t = getValue(TRANSFER_BUFFER + SIZE_OF_INT, "i32"); + if (((this._children = new Array(e)), e > 0)) { + let r = t; + for (let t = 0; t < e; t++) + (this._children[t] = unmarshalNode(this.tree, r)), + (r += SIZE_OF_NODE); + C._free(t); + } + } + return this._children; + } + get namedChildren() { + if (!this._namedChildren) { + marshalNode(this), + C._ts_node_named_children_wasm(this.tree[0]); + const e = getValue(TRANSFER_BUFFER, "i32"), + t = getValue(TRANSFER_BUFFER + SIZE_OF_INT, "i32"); + if (((this._namedChildren = new Array(e)), e > 0)) { + let r = t; + for (let t = 0; t < e; t++) + (this._namedChildren[t] = unmarshalNode(this.tree, r)), + (r += SIZE_OF_NODE); + C._free(t); + } + } + return this._namedChildren; + } + descendantsOfType(e, t, r) { + Array.isArray(e) || (e = [e]), + t || (t = ZERO_POINT), + r || (r = ZERO_POINT); + const _ = [], + s = this.tree.language.types; + for (let t = 0, r = s.length; t < r; t++) + e.includes(s[t]) && _.push(t); + const n = C._malloc(SIZE_OF_INT * _.length); + for (let e = 0, t = _.length; e < t; e++) + setValue(n + e * SIZE_OF_INT, _[e], "i32"); + marshalNode(this), + C._ts_node_descendants_of_type_wasm( + this.tree[0], + n, + _.length, + t.row, + t.column, + r.row, + r.column + ); + const a = getValue(TRANSFER_BUFFER, "i32"), + o = getValue(TRANSFER_BUFFER + SIZE_OF_INT, "i32"), + l = new Array(a); + if (a > 0) { + let e = o; + for (let t = 0; t < a; t++) + (l[t] = unmarshalNode(this.tree, e)), (e += SIZE_OF_NODE); + } + return C._free(o), C._free(n), l; + } + get nextSibling() { + return ( + marshalNode(this), + C._ts_node_next_sibling_wasm(this.tree[0]), + unmarshalNode(this.tree) + ); + } + get previousSibling() { + return ( + marshalNode(this), + C._ts_node_prev_sibling_wasm(this.tree[0]), + unmarshalNode(this.tree) + ); + } + get nextNamedSibling() { + return ( + marshalNode(this), + C._ts_node_next_named_sibling_wasm(this.tree[0]), + unmarshalNode(this.tree) + ); + } + get previousNamedSibling() { + return ( + marshalNode(this), + C._ts_node_prev_named_sibling_wasm(this.tree[0]), + unmarshalNode(this.tree) + ); + } + get descendantCount() { + return ( + marshalNode(this), + C._ts_node_descendant_count_wasm(this.tree[0]) + ); + } + get parent() { + return ( + marshalNode(this), + C._ts_node_parent_wasm(this.tree[0]), + unmarshalNode(this.tree) + ); + } + descendantForIndex(e, t = e) { + if ("number" != typeof e || "number" != typeof t) + throw new Error("Arguments must be numbers"); + marshalNode(this); + const r = TRANSFER_BUFFER + SIZE_OF_NODE; + return ( + setValue(r, e, "i32"), + setValue(r + SIZE_OF_INT, t, "i32"), + C._ts_node_descendant_for_index_wasm(this.tree[0]), + unmarshalNode(this.tree) + ); + } + namedDescendantForIndex(e, t = e) { + if ("number" != typeof e || "number" != typeof t) + throw new Error("Arguments must be numbers"); + marshalNode(this); + const r = TRANSFER_BUFFER + SIZE_OF_NODE; + return ( + setValue(r, e, "i32"), + setValue(r + SIZE_OF_INT, t, "i32"), + C._ts_node_named_descendant_for_index_wasm(this.tree[0]), + unmarshalNode(this.tree) + ); + } + descendantForPosition(e, t = e) { + if (!isPoint(e) || !isPoint(t)) + throw new Error("Arguments must be {row, column} objects"); + marshalNode(this); + const r = TRANSFER_BUFFER + SIZE_OF_NODE; + return ( + marshalPoint(r, e), + marshalPoint(r + SIZE_OF_POINT, t), + C._ts_node_descendant_for_position_wasm(this.tree[0]), + unmarshalNode(this.tree) + ); + } + namedDescendantForPosition(e, t = e) { + if (!isPoint(e) || !isPoint(t)) + throw new Error("Arguments must be {row, column} objects"); + marshalNode(this); + const r = TRANSFER_BUFFER + SIZE_OF_NODE; + return ( + marshalPoint(r, e), + marshalPoint(r + SIZE_OF_POINT, t), + C._ts_node_named_descendant_for_position_wasm(this.tree[0]), + unmarshalNode(this.tree) + ); + } + walk() { + return ( + marshalNode(this), + C._ts_tree_cursor_new_wasm(this.tree[0]), + new TreeCursor(INTERNAL, this.tree) + ); + } + toString() { + marshalNode(this); + const e = C._ts_node_to_string_wasm(this.tree[0]), + t = AsciiToString(e); + return C._free(e), t; + } + } + class TreeCursor { + constructor(e, t) { + assertInternal(e), (this.tree = t), unmarshalTreeCursor(this); + } + delete() { + marshalTreeCursor(this), + C._ts_tree_cursor_delete_wasm(this.tree[0]), + (this[0] = this[1] = this[2] = 0); + } + reset(e) { + marshalNode(e), + marshalTreeCursor(this, TRANSFER_BUFFER + SIZE_OF_NODE), + C._ts_tree_cursor_reset_wasm(this.tree[0]), + unmarshalTreeCursor(this); + } + resetTo(e) { + marshalTreeCursor(this, TRANSFER_BUFFER), + marshalTreeCursor(e, TRANSFER_BUFFER + SIZE_OF_CURSOR), + C._ts_tree_cursor_reset_to_wasm(this.tree[0], e.tree[0]), + unmarshalTreeCursor(this); + } + get nodeType() { + return this.tree.language.types[this.nodeTypeId] || "ERROR"; + } + get nodeTypeId() { + return ( + marshalTreeCursor(this), + C._ts_tree_cursor_current_node_type_id_wasm(this.tree[0]) + ); + } + get nodeStateId() { + return ( + marshalTreeCursor(this), + C._ts_tree_cursor_current_node_state_id_wasm(this.tree[0]) + ); + } + get nodeId() { + return ( + marshalTreeCursor(this), + C._ts_tree_cursor_current_node_id_wasm(this.tree[0]) + ); + } + get nodeIsNamed() { + return ( + marshalTreeCursor(this), + 1 === + C._ts_tree_cursor_current_node_is_named_wasm(this.tree[0]) + ); + } + get nodeIsMissing() { + return ( + marshalTreeCursor(this), + 1 === + C._ts_tree_cursor_current_node_is_missing_wasm( + this.tree[0] + ) + ); + } + get nodeText() { + marshalTreeCursor(this); + const e = C._ts_tree_cursor_start_index_wasm(this.tree[0]), + t = C._ts_tree_cursor_end_index_wasm(this.tree[0]); + return getText(this.tree, e, t); + } + get startPosition() { + return ( + marshalTreeCursor(this), + C._ts_tree_cursor_start_position_wasm(this.tree[0]), + unmarshalPoint(TRANSFER_BUFFER) + ); + } + get endPosition() { + return ( + marshalTreeCursor(this), + C._ts_tree_cursor_end_position_wasm(this.tree[0]), + unmarshalPoint(TRANSFER_BUFFER) + ); + } + get startIndex() { + return ( + marshalTreeCursor(this), + C._ts_tree_cursor_start_index_wasm(this.tree[0]) + ); + } + get endIndex() { + return ( + marshalTreeCursor(this), + C._ts_tree_cursor_end_index_wasm(this.tree[0]) + ); + } + get currentNode() { + return ( + marshalTreeCursor(this), + C._ts_tree_cursor_current_node_wasm(this.tree[0]), + unmarshalNode(this.tree) + ); + } + get currentFieldId() { + return ( + marshalTreeCursor(this), + C._ts_tree_cursor_current_field_id_wasm(this.tree[0]) + ); + } + get currentFieldName() { + return this.tree.language.fields[this.currentFieldId]; + } + get currentDepth() { + return ( + marshalTreeCursor(this), + C._ts_tree_cursor_current_depth_wasm(this.tree[0]) + ); + } + get currentDescendantIndex() { + return ( + marshalTreeCursor(this), + C._ts_tree_cursor_current_descendant_index_wasm( + this.tree[0] + ) + ); + } + gotoFirstChild() { + marshalTreeCursor(this); + const e = C._ts_tree_cursor_goto_first_child_wasm( + this.tree[0] + ); + return unmarshalTreeCursor(this), 1 === e; + } + gotoLastChild() { + marshalTreeCursor(this); + const e = C._ts_tree_cursor_goto_last_child_wasm( + this.tree[0] + ); + return unmarshalTreeCursor(this), 1 === e; + } + gotoFirstChildForIndex(e) { + marshalTreeCursor(this), + setValue(TRANSFER_BUFFER + SIZE_OF_CURSOR, e, "i32"); + const t = C._ts_tree_cursor_goto_first_child_for_index_wasm( + this.tree[0] + ); + return unmarshalTreeCursor(this), 1 === t; + } + gotoFirstChildForPosition(e) { + marshalTreeCursor(this), + marshalPoint(TRANSFER_BUFFER + SIZE_OF_CURSOR, e); + const t = + C._ts_tree_cursor_goto_first_child_for_position_wasm( + this.tree[0] + ); + return unmarshalTreeCursor(this), 1 === t; + } + gotoNextSibling() { + marshalTreeCursor(this); + const e = C._ts_tree_cursor_goto_next_sibling_wasm( + this.tree[0] + ); + return unmarshalTreeCursor(this), 1 === e; + } + gotoPreviousSibling() { + marshalTreeCursor(this); + const e = C._ts_tree_cursor_goto_previous_sibling_wasm( + this.tree[0] + ); + return unmarshalTreeCursor(this), 1 === e; + } + gotoDescendant(e) { + marshalTreeCursor(this), + C._ts_tree_cursor_goto_descendant_wasm(this.tree[0], e), + unmarshalTreeCursor(this); + } + gotoParent() { + marshalTreeCursor(this); + const e = C._ts_tree_cursor_goto_parent_wasm(this.tree[0]); + return unmarshalTreeCursor(this), 1 === e; + } + } + class Language { + constructor(e, t) { + assertInternal(e), + (this[0] = t), + (this.types = new Array( + C._ts_language_symbol_count(this[0]) + )); + for (let e = 0, t = this.types.length; e < t; e++) + C._ts_language_symbol_type(this[0], e) < 2 && + (this.types[e] = UTF8ToString( + C._ts_language_symbol_name(this[0], e) + )); + this.fields = new Array( + C._ts_language_field_count(this[0]) + 1 + ); + for (let e = 0, t = this.fields.length; e < t; e++) { + const t = C._ts_language_field_name_for_id(this[0], e); + this.fields[e] = 0 !== t ? UTF8ToString(t) : null; + } + } + get version() { + return C._ts_language_version(this[0]); + } + get fieldCount() { + return this.fields.length - 1; + } + get stateCount() { + return C._ts_language_state_count(this[0]); + } + fieldIdForName(e) { + const t = this.fields.indexOf(e); + return -1 !== t ? t : null; + } + fieldNameForId(e) { + return this.fields[e] || null; + } + idForNodeType(e, t) { + const r = lengthBytesUTF8(e), + _ = C._malloc(r + 1); + stringToUTF8(e, _, r + 1); + const s = C._ts_language_symbol_for_name(this[0], _, r, t); + return C._free(_), s || null; + } + get nodeTypeCount() { + return C._ts_language_symbol_count(this[0]); + } + nodeTypeForId(e) { + const t = C._ts_language_symbol_name(this[0], e); + return t ? UTF8ToString(t) : null; + } + nodeTypeIsNamed(e) { + return !!C._ts_language_type_is_named_wasm(this[0], e); + } + nodeTypeIsVisible(e) { + return !!C._ts_language_type_is_visible_wasm(this[0], e); + } + nextState(e, t) { + return C._ts_language_next_state(this[0], e, t); + } + lookaheadIterator(e) { + const t = C._ts_lookahead_iterator_new(this[0], e); + if (t) return new LookaheadIterable(INTERNAL, t, this); + } + query(e) { + const t = lengthBytesUTF8(e), + r = C._malloc(t + 1); + stringToUTF8(e, r, t + 1); + const _ = C._ts_query_new( + this[0], + r, + t, + TRANSFER_BUFFER, + TRANSFER_BUFFER + SIZE_OF_INT + ); + if (!_) { + const t = getValue(TRANSFER_BUFFER + SIZE_OF_INT, "i32"), + _ = UTF8ToString( + r, + getValue(TRANSFER_BUFFER, "i32") + ).length, + s = e.substr(_, 100).split("\n")[0]; + let n, + a = s.match(QUERY_WORD_REGEX)[0]; + switch (t) { + case 2: + n = new RangeError(`Bad node name '${a}'`); + break; + case 3: + n = new RangeError(`Bad field name '${a}'`); + break; + case 4: + n = new RangeError(`Bad capture name @${a}`); + break; + case 5: + (n = new TypeError( + `Bad pattern structure at offset ${_}: '${s}'...` + )), + (a = ""); + break; + default: + (n = new SyntaxError( + `Bad syntax at offset ${_}: '${s}'...` + )), + (a = ""); + } + throw ((n.index = _), (n.length = a.length), C._free(r), n); + } + const s = C._ts_query_string_count(_), + n = C._ts_query_capture_count(_), + a = C._ts_query_pattern_count(_), + o = new Array(n), + l = new Array(s); + for (let e = 0; e < n; e++) { + const t = C._ts_query_capture_name_for_id( + _, + e, + TRANSFER_BUFFER + ), + r = getValue(TRANSFER_BUFFER, "i32"); + o[e] = UTF8ToString(t, r); + } + for (let e = 0; e < s; e++) { + const t = C._ts_query_string_value_for_id( + _, + e, + TRANSFER_BUFFER + ), + r = getValue(TRANSFER_BUFFER, "i32"); + l[e] = UTF8ToString(t, r); + } + const i = new Array(a), + u = new Array(a), + d = new Array(a), + m = new Array(a), + c = new Array(a); + for (let e = 0; e < a; e++) { + const t = C._ts_query_predicates_for_pattern( + _, + e, + TRANSFER_BUFFER + ), + r = getValue(TRANSFER_BUFFER, "i32"); + (m[e] = []), (c[e] = []); + const s = []; + let n = t; + for (let t = 0; t < r; t++) { + const t = getValue(n, "i32"); + n += SIZE_OF_INT; + const r = getValue(n, "i32"); + if ( + ((n += SIZE_OF_INT), t === PREDICATE_STEP_TYPE_CAPTURE) + ) + s.push({ type: "capture", name: o[r] }); + else if (t === PREDICATE_STEP_TYPE_STRING) + s.push({ type: "string", value: l[r] }); + else if (s.length > 0) { + if ("string" !== s[0].type) + throw new Error( + "Predicates must begin with a literal value" + ); + const t = s[0].value; + let r, + _ = !0, + n = !0; + switch (t) { + case "any-not-eq?": + case "not-eq?": + _ = !1; + case "any-eq?": + case "eq?": + if (3 !== s.length) + throw new Error( + `Wrong number of arguments to \`#${t}\` predicate. Expected 2, got ${ + s.length - 1 + }` + ); + if ("capture" !== s[1].type) + throw new Error( + `First argument of \`#${t}\` predicate must be a capture. Got "${s[1].value}"` + ); + if ( + ((n = !t.startsWith("any-")), + "capture" === s[2].type) + ) { + const t = s[1].name, + r = s[2].name; + c[e].push(function (e) { + const s = [], + a = []; + for (const _ of e) + _.name === t && s.push(_.node), + _.name === r && a.push(_.node); + const o = (e, t, r) => + r ? e.text === t.text : e.text !== t.text; + return n + ? s.every((e) => a.some((t) => o(e, t, _))) + : s.some((e) => a.some((t) => o(e, t, _))); + }); + } else { + r = s[1].name; + const t = s[2].value, + a = (e) => e.text === t, + o = (e) => e.text !== t; + c[e].push(function (e) { + const t = []; + for (const _ of e) + _.name === r && t.push(_.node); + const s = _ ? a : o; + return n ? t.every(s) : t.some(s); + }); + } + break; + case "any-not-match?": + case "not-match?": + _ = !1; + case "any-match?": + case "match?": + if (3 !== s.length) + throw new Error( + `Wrong number of arguments to \`#${t}\` predicate. Expected 2, got ${ + s.length - 1 + }.` + ); + if ("capture" !== s[1].type) + throw new Error( + `First argument of \`#${t}\` predicate must be a capture. Got "${s[1].value}".` + ); + if ("string" !== s[2].type) + throw new Error( + `Second argument of \`#${t}\` predicate must be a string. Got @${s[2].value}.` + ); + r = s[1].name; + const a = new RegExp(s[2].value); + (n = !t.startsWith("any-")), + c[e].push(function (e) { + const t = []; + for (const _ of e) + _.name === r && t.push(_.node.text); + const s = (e, t) => + t ? a.test(e) : !a.test(e); + return 0 === t.length + ? !_ + : n + ? t.every((e) => s(e, _)) + : t.some((e) => s(e, _)); + }); + break; + case "set!": + if (s.length < 2 || s.length > 3) + throw new Error( + `Wrong number of arguments to \`#set!\` predicate. Expected 1 or 2. Got ${ + s.length - 1 + }.` + ); + if (s.some((e) => "string" !== e.type)) + throw new Error( + 'Arguments to `#set!` predicate must be a strings.".' + ); + i[e] || (i[e] = {}), + (i[e][s[1].value] = s[2] ? s[2].value : null); + break; + case "is?": + case "is-not?": + if (s.length < 2 || s.length > 3) + throw new Error( + `Wrong number of arguments to \`#${t}\` predicate. Expected 1 or 2. Got ${ + s.length - 1 + }.` + ); + if (s.some((e) => "string" !== e.type)) + throw new Error( + `Arguments to \`#${t}\` predicate must be a strings.".` + ); + const o = "is?" === t ? u : d; + o[e] || (o[e] = {}), + (o[e][s[1].value] = s[2] ? s[2].value : null); + break; + case "not-any-of?": + _ = !1; + case "any-of?": + if (s.length < 2) + throw new Error( + `Wrong number of arguments to \`#${t}\` predicate. Expected at least 1. Got ${ + s.length - 1 + }.` + ); + if ("capture" !== s[1].type) + throw new Error( + `First argument of \`#${t}\` predicate must be a capture. Got "${s[1].value}".` + ); + for (let e = 2; e < s.length; e++) + if ("string" !== s[e].type) + throw new Error( + `Arguments to \`#${t}\` predicate must be a strings.".` + ); + r = s[1].name; + const l = s.slice(2).map((e) => e.value); + c[e].push(function (e) { + const t = []; + for (const _ of e) + _.name === r && t.push(_.node.text); + return 0 === t.length + ? !_ + : t.every((e) => l.includes(e)) === _; + }); + break; + default: + m[e].push({ operator: t, operands: s.slice(1) }); + } + s.length = 0; + } + } + Object.freeze(i[e]), + Object.freeze(u[e]), + Object.freeze(d[e]); + } + return ( + C._free(r), + new Query( + INTERNAL, + _, + o, + c, + m, + Object.freeze(i), + Object.freeze(u), + Object.freeze(d) + ) + ); + } + static load(e) { + let t; + if (e instanceof Uint8Array) t = Promise.resolve(e); + else { + const r = e; + if ( + "undefined" != typeof process && + process.versions && + process.versions.node + ) { + const e = require("fs"); + t = Promise.resolve(e.readFileSync(r)); + } else + t = fetch(r).then((e) => + e.arrayBuffer().then((t) => { + if (e.ok) return new Uint8Array(t); + { + const r = new TextDecoder("utf-8").decode(t); + throw new Error( + `Language.load failed with status ${e.status}.\n\n${r}` + ); + } + }) + ); + } + return t + .then((e) => loadWebAssemblyModule(e, { loadAsync: !0 })) + .then((e) => { + const t = Object.keys(e), + r = t.find( + (e) => + LANGUAGE_FUNCTION_REGEX.test(e) && + !e.includes("external_scanner_") + ); + r || + console.log( + `Couldn't find language function in WASM file. Symbols:\n${JSON.stringify( + t, + null, + 2 + )}` + ); + const _ = e[r](); + return new Language(INTERNAL, _); + }); + } + } + class LookaheadIterable { + constructor(e, t, r) { + assertInternal(e), (this[0] = t), (this.language = r); + } + get currentTypeId() { + return C._ts_lookahead_iterator_current_symbol(this[0]); + } + get currentType() { + return this.language.types[this.currentTypeId] || "ERROR"; + } + delete() { + C._ts_lookahead_iterator_delete(this[0]), (this[0] = 0); + } + resetState(e) { + return C._ts_lookahead_iterator_reset_state(this[0], e); + } + reset(e, t) { + return ( + !!C._ts_lookahead_iterator_reset(this[0], e[0], t) && + ((this.language = e), !0) + ); + } + [Symbol.iterator]() { + const e = this; + return { + next: () => + C._ts_lookahead_iterator_next(e[0]) + ? { done: !1, value: e.currentType } + : { done: !0, value: "" }, + }; + } + } + class Query { + constructor(e, t, r, _, s, n, a, o) { + assertInternal(e), + (this[0] = t), + (this.captureNames = r), + (this.textPredicates = _), + (this.predicates = s), + (this.setProperties = n), + (this.assertedProperties = a), + (this.refutedProperties = o), + (this.exceededMatchLimit = !1); + } + delete() { + C._ts_query_delete(this[0]), (this[0] = 0); + } + matches( + e, + { + startPosition: t = ZERO_POINT, + endPosition: r = ZERO_POINT, + startIndex: _ = 0, + endIndex: s = 0, + matchLimit: n = 4294967295, + maxStartDepth: a = 4294967295, + } = {} + ) { + if ("number" != typeof n) + throw new Error("Arguments must be numbers"); + marshalNode(e), + C._ts_query_matches_wasm( + this[0], + e.tree[0], + t.row, + t.column, + r.row, + r.column, + _, + s, + n, + a + ); + const o = getValue(TRANSFER_BUFFER, "i32"), + l = getValue(TRANSFER_BUFFER + SIZE_OF_INT, "i32"), + i = getValue(TRANSFER_BUFFER + 2 * SIZE_OF_INT, "i32"), + u = new Array(o); + this.exceededMatchLimit = !!i; + let d = 0, + m = l; + for (let t = 0; t < o; t++) { + const t = getValue(m, "i32"); + m += SIZE_OF_INT; + const r = getValue(m, "i32"); + m += SIZE_OF_INT; + const _ = new Array(r); + if ( + ((m = unmarshalCaptures(this, e.tree, m, _)), + this.textPredicates[t].every((e) => e(_))) + ) { + u[d] = { pattern: t, captures: _ }; + const e = this.setProperties[t]; + e && (u[d].setProperties = e); + const r = this.assertedProperties[t]; + r && (u[d].assertedProperties = r); + const s = this.refutedProperties[t]; + s && (u[d].refutedProperties = s), d++; + } + } + return (u.length = d), C._free(l), u; + } + captures( + e, + { + startPosition: t = ZERO_POINT, + endPosition: r = ZERO_POINT, + startIndex: _ = 0, + endIndex: s = 0, + matchLimit: n = 4294967295, + maxStartDepth: a = 4294967295, + } = {} + ) { + if ("number" != typeof n) + throw new Error("Arguments must be numbers"); + marshalNode(e), + C._ts_query_captures_wasm( + this[0], + e.tree[0], + t.row, + t.column, + r.row, + r.column, + _, + s, + n, + a + ); + const o = getValue(TRANSFER_BUFFER, "i32"), + l = getValue(TRANSFER_BUFFER + SIZE_OF_INT, "i32"), + i = getValue(TRANSFER_BUFFER + 2 * SIZE_OF_INT, "i32"), + u = []; + this.exceededMatchLimit = !!i; + const d = []; + let m = l; + for (let t = 0; t < o; t++) { + const t = getValue(m, "i32"); + m += SIZE_OF_INT; + const r = getValue(m, "i32"); + m += SIZE_OF_INT; + const _ = getValue(m, "i32"); + if ( + ((m += SIZE_OF_INT), + (d.length = r), + (m = unmarshalCaptures(this, e.tree, m, d)), + this.textPredicates[t].every((e) => e(d))) + ) { + const e = d[_], + r = this.setProperties[t]; + r && (e.setProperties = r); + const s = this.assertedProperties[t]; + s && (e.assertedProperties = s); + const n = this.refutedProperties[t]; + n && (e.refutedProperties = n), u.push(e); + } + } + return C._free(l), u; + } + predicatesForPattern(e) { + return this.predicates[e]; + } + disableCapture(e) { + const t = lengthBytesUTF8(e), + r = C._malloc(t + 1); + stringToUTF8(e, r, t + 1), + C._ts_query_disable_capture(this[0], r, t), + C._free(r); + } + didExceedMatchLimit() { + return this.exceededMatchLimit; + } + } + function getText(e, t, r) { + const _ = r - t; + let s = e.textCallback(t, null, r); + for (t += s.length; t < r; ) { + const _ = e.textCallback(t, null, r); + if (!(_ && _.length > 0)) break; + (t += _.length), (s += _); + } + return t > r && (s = s.slice(0, _)), s; + } + function unmarshalCaptures(e, t, r, _) { + for (let s = 0, n = _.length; s < n; s++) { + const n = getValue(r, "i32"), + a = unmarshalNode(t, (r += SIZE_OF_INT)); + (r += SIZE_OF_NODE), + (_[s] = { name: e.captureNames[n], node: a }); + } + return r; + } + function assertInternal(e) { + if (e !== INTERNAL) throw new Error("Illegal constructor"); + } + function isPoint(e) { + return ( + e && "number" == typeof e.row && "number" == typeof e.column + ); + } + function marshalNode(e) { + let t = TRANSFER_BUFFER; + setValue(t, e.id, "i32"), + (t += SIZE_OF_INT), + setValue(t, e.startIndex, "i32"), + (t += SIZE_OF_INT), + setValue(t, e.startPosition.row, "i32"), + (t += SIZE_OF_INT), + setValue(t, e.startPosition.column, "i32"), + (t += SIZE_OF_INT), + setValue(t, e[0], "i32"); + } + function unmarshalNode(e, t = TRANSFER_BUFFER) { + const r = getValue(t, "i32"); + if (0 === r) return null; + const _ = getValue((t += SIZE_OF_INT), "i32"), + s = getValue((t += SIZE_OF_INT), "i32"), + n = getValue((t += SIZE_OF_INT), "i32"), + a = getValue((t += SIZE_OF_INT), "i32"), + o = new Node(INTERNAL, e); + return ( + (o.id = r), + (o.startIndex = _), + (o.startPosition = { row: s, column: n }), + (o[0] = a), + o + ); + } + function marshalTreeCursor(e, t = TRANSFER_BUFFER) { + setValue(t + 0 * SIZE_OF_INT, e[0], "i32"), + setValue(t + 1 * SIZE_OF_INT, e[1], "i32"), + setValue(t + 2 * SIZE_OF_INT, e[2], "i32"); + } + function unmarshalTreeCursor(e) { + (e[0] = getValue(TRANSFER_BUFFER + 0 * SIZE_OF_INT, "i32")), + (e[1] = getValue(TRANSFER_BUFFER + 1 * SIZE_OF_INT, "i32")), + (e[2] = getValue(TRANSFER_BUFFER + 2 * SIZE_OF_INT, "i32")); + } + function marshalPoint(e, t) { + setValue(e, t.row, "i32"), + setValue(e + SIZE_OF_INT, t.column, "i32"); + } + function unmarshalPoint(e) { + return { + row: getValue(e, "i32") >>> 0, + column: getValue(e + SIZE_OF_INT, "i32") >>> 0, + }; + } + function marshalRange(e, t) { + marshalPoint(e, t.startPosition), + marshalPoint((e += SIZE_OF_POINT), t.endPosition), + setValue((e += SIZE_OF_POINT), t.startIndex, "i32"), + setValue((e += SIZE_OF_INT), t.endIndex, "i32"), + (e += SIZE_OF_INT); + } + function unmarshalRange(e) { + const t = {}; + return ( + (t.startPosition = unmarshalPoint(e)), + (e += SIZE_OF_POINT), + (t.endPosition = unmarshalPoint(e)), + (e += SIZE_OF_POINT), + (t.startIndex = getValue(e, "i32") >>> 0), + (e += SIZE_OF_INT), + (t.endIndex = getValue(e, "i32") >>> 0), + t + ); + } + function marshalEdit(e) { + let t = TRANSFER_BUFFER; + marshalPoint(t, e.startPosition), + (t += SIZE_OF_POINT), + marshalPoint(t, e.oldEndPosition), + (t += SIZE_OF_POINT), + marshalPoint(t, e.newEndPosition), + (t += SIZE_OF_POINT), + setValue(t, e.startIndex, "i32"), + (t += SIZE_OF_INT), + setValue(t, e.oldEndIndex, "i32"), + (t += SIZE_OF_INT), + setValue(t, e.newEndIndex, "i32"), + (t += SIZE_OF_INT); + } + for (const e of Object.getOwnPropertyNames(ParserImpl.prototype)) + Object.defineProperty(Parser.prototype, e, { + value: ParserImpl.prototype[e], + enumerable: !1, + writable: !1, + }); + (Parser.Language = Language), + (Module.onRuntimeInitialized = () => { + ParserImpl.init(), resolveInitPromise(); + }); + }))) + ); + } + } + return Parser; + })(); + "object" == typeof exports && (module.exports = TreeSitter); + + return { Parser: TreeSitter }; +}); diff --git a/src/vs/base/common/web-tree-sitter/tree-sitter.wasm b/src/vs/base/common/web-tree-sitter/tree-sitter.wasm new file mode 100644 index 0000000000000000000000000000000000000000..700cbe18713c97b1814eceee176e92f96eecb3b3 GIT binary patch literal 192649 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�wN$k zbsO01t}c(EP?}BMXMC&*RLKPBgKu%W1KC5ow#ikKKE9|o)G2<4>!6lK0hG4=_1^{! z^f77JXYf~P+TY-ihQg1O=z@GEUtrVp)hw;B2VRgWJa{=HAUKxB2gB+1>=U_#arb0+ z>2-v(tE8giJjhe;yh8|F@3iPIz~2gJi{I+`=P z_45~P7lo*W*9pdA8kdG2_jRUCv|Nadk`@hToF`e(ZbjS(<-*COS6tTjwL4zwy9G^W z^7=={^EmA#8+l+Rb>Rt~6#)pnwB3+4FvppfmoKn6x$>3bBKuL!GkDV8(Z2;BEG1U* z3_?(drY6a(s!1dl;@uV4&t3@Rm*NmE^t30LcDDp=alHzd()@n*5JIL=v}3jtzJe%9 zB1p2;6laQ_SpE$R3Sek+DaIbX{}#hR9ET^5s{q zUIVO|uRCa`-{~Xa=YPx4jkXC!PZ#D*wdzU_Rq4D85bFS*_pyvv=hO znFS$@_ok){73V4WsBce!BG)F0&9#8Cp$xR-_;$+#0>Cde@M4olQEDg=B5o9lyCX7( zmJ&~1ycSfNqzhDMIR3)0M5bF5yY1Cy$3}YkG%Qpub)) z0*qxNs~l_~(rUsp9-dSK8q-DGgM-qbn(1Bs*4?Y}La(vA0&I6@uIx*rdX?4Kw+xq+ z!~ZikOV>8fVR^fe2hOE_ZX;I zSX+r}X5pRmd^Prb_3e5FIy~z)LrRMlFa!PZ2{p}mh^xu-6he#q0+(3J#K6gH`Dht| zern@=**D~63C*fJp@dsl{|3e(M67>`gaET=Le{If1_qxGzsbZ^oe$bf=NK{lQU05D z!355oh#XPPOtw)?a#$k3kIx1bvJ2tZL%#XO555C4tB>cV1(dulMQqCArZ8x`gWxkx zF0m9-EJzsk&WIpnoj4)JVLxlmWdIhz%^mQCZOZW`5_$kl=2AAwwv7BYcR&p72J z40Nh5l4>!rKC69CJnt1{MbkV0FtcZ)pUF<9j{2j z;oDbqBy9c~yr<_Z`D||f>*=?6QrEvM-b8zx2;ZeQ_^`=Wb%iH?g`=3_SA{OhAIw!> zbMArD!$5G4B5R#q{XY0!M#M7^G zif+}jujI$Wx9aq8aV5Ve9FM2p2=|0G;^h?*t&j01M0eq?-yF=F#7rBU+x6&x@1|2e(<3gXG!$?)A1vUp7eIg&O~xCb?4 zEK6X7MaTjtnXaD;%>L8xn_X)?&VERrZHl}#x+7^a2{hkBk|w*AQx~XlZF$^+X)Hn% z`e_?cE*^rpqpbm$ZQF`uMOk+gn-s7v2X9%66GbvzCfi zS~J^+NQ2lz{LCYHdkm=Qm|` zGy8`2=5ol}COTzuCnf2*fN(wUm4=cZ&lI zaRG1d*U)7}b)`e9@b4pRjmi^Lu1Wf^$_4cPxPR-9&9W( zu+462K1L_)H@hr~&iz8$8?6~6ZMMccs>*C%i%{wkLvg6?_~Gjgab9I}lwqm&0rFMm zljHlhixzzPcx}wLdEpj+a|%>5@5TeT+=v}JY?OU$XaRtd)_(LnRVaavIiwg|C`>OX z1I2Gei1AgE#FFMYczKy|KhAd5PQGLoeR}&YAeDM0Gzn09x?hV5ht7NHRj^|_7DGj4 zR)_#){SBEzgYC^cJ!$5vOd86C0T%5p>hhYMp03?T2$Lv}s*A*fS`_nTpzix+01ju_ zJsBx`2}tL7_KC;>aai?3e7Zh8#MkTNLy-w0yTJCaLZkw&4O2K#8)=M1^W zsIj?TP4l*pC?T5CT)r{@WZLdxud6u_iIV!v7*)d(DkoyRO>IWZsv9b*5DO0NHSMq` z1Y)_YJx~pv(osOsTw7D5>~JCC!lB4+6kDF4dO1-HrQ(&RjxpHy9<(MvNZt{-JC%!3 zTE-vHr=N+X{1DamZ25v?LXVsu(H|zL@wKjtHMD~*{OY}O?GMS5k;6V4a?CsAK*9+* zWS^!X$Mw-h+?uo>qYbr;GJu^IqJJfK2Vj=<$D0SJNfkigfQuqru9L48=Hw2Od`*G3 zSe2}+9aeL?Ebuo1n7Ly*Tby*4>cTSD)ke&YP?D%zOsKu5NfjdLl5~Atz9`}vHM4B3 zQ=-Hj8VOjDwoM)(QtEO(*i+JLJt|R)`}XRYWA?}heeRErm!hEi z?!o6ld^x?_P6f|B3>Cd8?*!He+%YxsFmAJaXf*yY4#`ovJD$pY;_Gv|DyQmx9+Uyc z-OweRpyCOF&qk%97@W>KoS?e!(&!E_DQ_9hAwjd5%0EP(%%khj!alo;Q;OsB-h0a^*jl(19h|`r@0wn0*^3r%*imRa$V7b_RNP6 zl*}S$PDNlQRanCBdub&)H`3lFGUYqm*u;Qs$Wjt zW9^&cX}hs+OuWkYoLpOB^+foZ&Y~Aj8_Tqy3=gN#9X}LL#W@G#srX5=%!$heI;D_} z*N*7)E?PVhj>Xeo<@EQ&Q#t8($7kh^Kd95_j(=-Bl{#2tSOBIXz` z_Lc%zy><<*eHggEz)EU4@Md`c}&?qw7c1rxAb<_{Gz$^Hp4V6?) z)PbJ0J!eh|FFL*vGn|ufz;{Tt$?e7#i?3=(CuUKT+!}srqZPYc_uv>slhKi2t#UF5v!RvJ29MLu-AQNaI>lnPvIrQ*QfN`=7R z34o|v90*IfAQ+bKisJ>`k~Yw>*| zImNcPFtWvr2UIgh5HU`9LELjd@;4?auIyew4zVI4H%&emS>9eKT4~ejX_n5ovpc zdB-th8B{FW-~b8LvT=kZrXL2tHAObw-ukPBHpYnDW8M_Du@uZ_YZbfQ$;l^0#OVI! z2cJK7z&I|hclDHg5TnZ}#4$04`7>sm-dhr>xPHW;gP6m6J4Cik%v)Te*|*(#T`^+4 z^?E}LqpjCDfwdTpwq9?{ZoRG_K#wZZ*6T1_kS8E<BNWaeK@~L>44DG!`Q(b$HTi zO4v@FakcD4$P)%h3_vLI*F)fZ@hCE{IAuMi&+!6;-Ie8jex)zv;rD>R5Ilv7#E`Un@`mG8*9AKiSX&0-*CJ#ax$Yd>nh9ZFOcM3!6On6mZqPu+>Bzc?J zxC8{%B}sic9`3JP>AP)|2K)&Rj^x13WhOYCv+n}}>$wG$=B2o&wJh+P$}OxCK$~9x zWqM=-0SEA+{~KCCikZQR6mk0ZSXzh&K4v}>!ni0FWiS~#z<7b27!c@`P==K<-IC*B zL6jTfKxUx)5-e{$fqMgv>s#KJhFkJWxE@>AoVqKUCev~FHr8kX7laP=B+N3iFO51! zzcz>dkU)dd9BCk?yUX-B6_2|Cb%G#Na?A>cjx-+jN1d%1&@X9vLb1MH(6&I}I#xgm z32L98^dObTm1B|Wx+Yw>H&FnnwNW&OL0sS@eg*Z2ABGJZ|Dz#qOtwSGBl2Y`lb9<) zmf;qigcfW$Yk(_CBv8eCmYRS_hx&iMn=i(3d?hm% zA?LIu9Ru7$Q8dmWBIlk(TvWQAvtu0fEKl>`qNW=u`Jiq}uX5yZEiC9shwEE+`M96% z+^F#&prr?-%S&q1^d-?ftRjhv6Gt7_!>M7n)MjUC(A11ObIHsjFeP>KFD{k2}Zs-i&>462clEzyukeDTJ=txdWKbY`}xnd6GzN1;Lp{}#? zNtT(N6h6WM>+oR?OfX;#<;Rc=k_Yw}2dY^fW-Ae4E!}*8q zDav^E;d=^29b9`D*+VS&(v}uOviSQx(Qm~jLHCbIiAe>l$bZwu8~iw&-z$df$}5QD zVW~Txh_dHePxO=n_84Gve*WRq%;EgQlQur2Hk4A7ANfv(hVP;dK@-?@fWQ%5u}aYTl{&-?t}OvFgo?kalt`@3G3s#Av^p3go!W>*|UD1w11zV-E5 zp#UgsuvR3f$`M_wu1k`9j zmq-n1H#!#3bd<<>TorDIC<~s*z6(+gjrS#$h6uni*3IgYEn6g{lbTibmG3^__2HCH z;@&JkX-G?9mb|ptd!byQNhZpa_vU?-RuNm+wuoD0o8VU27MI{<3IoJcA$rU`%ukfI z8UWY1vU!Y3PuYlm4|3O)izpN^>mC)=;+RlEa?92DHAI+^Byu0|jw-wUi#fueqBW9h zUNn#{f9?+d4l|OLb9%3Pp$}!Ix(*QjF#Knu;JEv-&6i9pLA! zvbB&FDk<6-Qw~NyxD~Ui)ZVWsWQxEKtmm3lrEDxERXUW~R6SXcvV^}-mS_+TniCSP zF(1ksa?o~$9Qa&JRGaMsqJh*VDiC#x+Dz)wu*nlo1f;q4_?8(0+95XqIa_4M027e& zrO_?$BYQSQ0`}0Cs@@_eifDNJ)@(vyJJNwEV$cp^>fAadjObOnB#f&)OH?fJk+cri z9l~W}RI)jxk~l#>SzgRN$0%@OKB?kRvQdEb>llVK^Sj|J$F6wD-&H6T9t4 zXAWh3VNhkjchi{+P!J>jMvt~W1xp|+d9Wp#M9K!+B4wjwZH|{0i6`qm+K0vjoG6O5 z#>Aqqph_AOCAv*x&iUc7oI&v*9GXYRiI`8#9vJVf(P2j&9~9PqfI>m(>;`Nw7dgux zQAKOc+zTb8kqn%LsXUC}&wJUm_W|XLqmmo~(gB2WLIkL>bh^OV;+RTmS$xiyum==I zTXK4e2a0l!HveMlB)qV4Q0`ONE9nnZCA|bNKqVKYp_VGXh-wGTF}a46w2GYSdNG0r z!vt5YRpw-6R3qUf2zJo4(HB}pLm+mhzb@q0GDKx?lcpgw_k1(1ix`Hq5bPt;GYA!A za%gas!@wiL!g(_hZ<5J47LX@zP-4C1R@!4U(2Y>EFoPl{B4of&E}%&62PmQiSdBy1 zxB(GP5eQ+j+D4Bs!f0}-oIu5l)kOLtZoQ$>gcnoZ8XGr&`>y9jDN*8Y2287#xc(ZG z@~|i~g#$4V^ij|ch3X_yAw?v?hUlP4mI;E{GF90_@rJ#IEJB*a42o`uU^(B0VCf)T z_Ak(tbZY8>2IKiSb@L~Yk@pzfqZ6FfjQ!J)*rC5*6V!vN6{#9r@0M?NJ9s>)aZX_gAI>j?%7EJ zm6TqPCO8q)i&pa7!_+)yh`T10Rg3W{eWS}h?cLk~3TSm-?$JM?2S1`@EL(t(n2_%0 z3ZHk=C7tpSisSi{I(saJ(+{Jq$eSF_OF7i|I0%+KYUFZHi=g`cNehTj5OBVxs~;g5 zBjd&ChB}~m{dtm|e9B<`r-!+rS-%b8#1Gxif*5+C5S}#7olfO^=m9cndm22wp%&y3Pz|8_wb_IzaD(W2oZc69D`3J9l_V*3_!0wjX6iIQ$8qN)ChtB2l z`!(=p-h*+FEKvNddh4O-KKIU7Uo zmY%>;lKoRIFzN=I!;(cISVE~ScI*_Lv=)ZVUvwF6m)$3RdqRk6QBega$ng3mxZlpC z;s_@0_)9B0a&uygxQfP>?MXfI*vKe(7=DB}W<=RPhFanju0>X6Q=A!Q%suA<=j>!g zwO8{X95z8uR`VcWb58CMIOu|G4xLYVu$bimv=~fa9%L2N&3F*kGC@w`;D|+a32e!b zzD1V!4M~Iv^WB*cNT{Kj5dvu-bwF3HlorB~|^9M?Jp*JDqGWrTEddKKe zEsJZ&z(RXZzx?|lkm(jK9+rQ<&dz{}!uhTEsUwRa*(Nd- zDBf zMJ(C^O1zcS5j%Z3zlKl7=2KebkZZ{qZd5t14_ztSMqW&-A9h|>EP-bORCk4R4t%QM z?)ej0+rVVmohFeMnA5C+^DwRW=|!R)5qKa>v?8cLm#{%XOxS1|8|?Z`U?aRxK`PPY z8*~$F)RpmUH3tZ^c9ImJu~Fc6fPXJwpjm#2CiF3BT+54dd_OfmCbdVlQ61pG$erOP zs~=r{w)1)#H6)l|z@V8XxbBHmA`}@H4GR1yss#rGcXsQ+sEQ$-UkybE502U{( zAXoLH*(5cM#QbPBoFhOr*CA4BL0*=O7q(X#63=RDq{_rtf-#vP5rfWbes6h<&V4i! z@+NqMM>;AH^wJEeejf?SCH=bL#aW`&trXvOR{o1erv zWAIL039M-F^=E+BPjIU*?RbI9VBC$>ujmS4PH41Cp^c=;5K)gn#zW(E8;cq*KEn1H z)rlU!dmN~jp-S#F?K%>JcB1nRxnq(W&Sa})mo9@Ku>s`JdSnL2nYz!2=1B`?wC46a zTJH@^>za>?lK_xzfJTrLgs;wFI7$vlDyK2fogMpZ=T6cF>smrh!brI^Z03MNPp$Y7nFdcyU?33y)bw=f zCx=$D@(N{j*fy;zii6ADh$H1~)g!z^)(NS06cOQd@^8VYCB~W_FEr}HRDyYVogD`a z*Nr$hFm71a8o#Erdz_%e$>fe8g`Okx!hjK}F3TaU=vnVv3sy9n>N%P})5_bCi@(I& z29q?_;($a@TjgjGgzRoj(dX5o^EK8ff?oSjt58lD;-@w=Wg|l7M~EtA&~h@sV&tJ1 z86omQw|nCm%zexqwd2Nv+H@T$EgX_Fl*_u}lF00!^Y!b9-iOALa9@YXkrncI zT(@n&%##s<^AwUZy+Ym0B#9Z{C&1VIPnVo8eP~8#MR{&#_dOZLncaMW4W~S;MI-e7 zzO2mw$0%3!JLjV(I7bbZK@i<)?T3&C6G;2z2t&St64>Q=B@N>n6=hX^E9x~H*uj`G zPNudh?LHl_3F61H3G*-&ZsyU-T29$}QkqZLcfJe`uO(=Q`jhJr^@HTXy>#3oxq+Mj zQI=cdJSG|-XA%NXNSedPW1dIlhw_WN!z(R*GkEEL8@z9?t`oeF8o8S7)k~Q*4)X)UuPdHS0(ZAC2YJ6hE z9ddyYiVY-X9(Nm#4D2!z>FHe<82uwZ4p&eI;)BG_`js{Z3W?IM}`vV(GdG z3z{SbA0J*OoClq&8)K6NrOTGCy7OZ7%B5lf^&yp{5X}@-$EV%8aRuN zbWo6hbR=GN-9-@AF`|+V1cCpNj$KtNnqV8Z$?c%t;Rez{yV5AqkG3pk4)sWK-O>@j zYb_nMiAd5x+V7Y&unImT9lOITD%=cSDbsf@%{$=T-s{91BS4>bk0_s^k;@e)EQ+M?ulAszsLwRwL(@|5 zQx+w#hDJ#KO+<>+Iy^W-BlS38PaK9D(ufVt&9hKhO58NUA&gpFG}2TBFy0mBwb_X_ z0qOrl9(uNgkD1Qe+k^Z1oQik%7>s-CF_Ne^M}`}g;wZe+1@0XTiE}R3*})MGgrYn4 z7*s9;l{y&XN;+st7ub@Jk5wz$>wiEC4%_2~?1_{Z@bM%G>?xWL%72&lP6oA(S7ys{ z*w+IkAFFaOvO=7~{OI&4Pfs`{cWx9wywgKL@rn`;NDG%{{CcjF1H1ZSb){q`GCX+T zL^cn`+9&Yp;r0`mEJy2vTz&7p{MK9VR|LSnbOf0|JX>0QYko&`46lI~;+q`tKALSh z->VI1v^fQZ1KJLp9VxW*kFrW@i!7$4k7mwg9L+97-M(LwmDxyN$I#YQc@;a_!FFXAW!;aBRB?k1c80!qC9><7{IrHVLp+yJFS%+`ca2PPN<3s>C z5$%b<4_u8mb%Yc@q$9;HKcM4YHs;om@10yFKvUIJ%4h-p!$uMF(4J${^pW|MJA^)I z>59~kHil;i+WC|JoNLlh1-QcsDwN6QuAc{V&;%ZI)5jLNY_?m5qS zUjEPj{rNxtC#7cUUe(RGOU`tT+xhHF)-%n{S>?+VO$#b$c)NGLcsLku zh#$WDk|-Rg^a>e|xTmx3b>h{lUpxet(B>H@S)I_9HWKFeo9AEXK=s9Mdn!Ov%26%jYmFZvT*q2+!$M9Aj8XoJ3 z4$m413bbDmFPd*S*El4{uVciU-o4U}9It7|#V|*S6!9QO^RSfpH%+dnL z!8T9CX+o50(yg0C{(DrBeb~MXkJ;z%VG`mlM2d^@jr=^VoDIfL(#WziKOO~UdstU} zuvQhZ637`(l4*Q;3kS?}B`_WSbhIlGOPyYzk9UiKBVjv48(^jE--FK7>EF)R2V9LN zeUr-rxZ4Ga#(`09j+@yRnmv}loc=XG;QFii`d3T3e=696vN)Dr_}Lrp_!M{&y;L(m zR?avh0Z{-&z#vrW%rfw-^xB^0j}(jY>IS5jbQxo9O??2OsyxAXjG{f;(P?YgF3FR- zc=DjsX*@ZIS~MGeLMTQoTtm7r+Vs(E)_8=M*jbB4P?GWlR3#ohx^s&sfE|6*ai*YD znkrx%G6%zWK%K_uo(oN6Hfq?~gZkwU_6`F(8TLYaPVQ{lF?8bBO8V!>5k_N=Nr`by z(P}!Xn8`FM(3s&E&Vy&+oK)-R=wA615>C~^NGMq;9#?2A1>#294WG%}+A|*kXh$KI zzBmbD%~oR633809gI#H8&J1>ui_-aEFcKrST0*5uAkr#27tZW6nctq_9`+Zm46YIS zceH%$J-K4o;cUirVjnHV?8Jj#jfCqNO<)Rw3j9kjjD-q&e+>GG&Dr5jKr);N0_J+t zv0V>9gSUFabTG$XQZ5vpM`}r$Iny>9&_i6HH&fhF;UJ$-Yp#{U5aLT^m(g8 z^L0@QoQZX;_sWnyDP$ztp*Odgw=|5FbEH^?t793CZtCeY^~suSzXMtl~1m?1^d-3xD$)yt@3DAsK z5;*hoX->PYX@*aTh9R}sIdYIdn&*jQUuj0KkGGIlrkD#&bIa90H0X8>VE$zFM$DXm z2Y2n<8c6=(Z@MdTE$f$J3Q*_W3K+3byg0Fy13VX!jP3EuTU{#Km}YYTpcj1~`5D%gR*%UHQVXQ?+Z%%~|P!StVXlGK?Yz`N$+Qwaq){yEzn5N9X`3V zaYh3IKm=TIUAPd&yAa-wSA8B!zCl)c(BWh6I0XNohr`s6jN8m(E z_u9O_XKm)Mz~S2M>`dE#tO(P^Dqw}GXzO@zu&=BMG8NgzGs;TD%@3u^x&E2u08h1<26#BuKh3r|$?1d0t z%=64xRJ-`)z9aWZy8rB}E4j(pb*W`m)yLNvPVXTBAs|ga2zt^nIjN8EcA$y1``y-O=7X&mU z(}hrvuyL7=VYYE0Jt#Zbxb!ZWxVaw~vQHPi@i-Z>ct%87BMBH7UX?F%hv(}{T(I}! ztVOr2^qcWB3hIy#4d)~!@1JwZ(I1dpDLckKsA{+q@Y$kux$BNRlcm=K_zSFo+cj?! zk!JQ1J6wXh#IBdPi@h%3o~+K3zdjeNErQD-Jo=M46pODNhjR5kb13N&XA=oJ_%1|7 zZI{C-me@-cFew=}WHJ#v?af|?dIvSj$(UdGRDt<6$FA(qWiVMC&DHbt&!@N2!IPd|<m6v0Qo;?SNIg+R|vc3lcxY?}gV8xAq3}Do&)^MdY42BM7?;rK>Zwc4-5=x5; z@k^>WOH|%@|1M_9)|+Q_b7xDU+PDqH08sGsVmBCDr62N=%h7jwVviw9{orPos6Yk> zt;Viu>|_Fj zMFh{(Bc3{uwP|}&*%Q}$kyPF}0Om6-)Tg-!KwhMmly^8`jP9b%p;O^loEIol$7D(; zj(LOvkF{UHXy_Nhgl|}vzSC}a7s6yiHgDcka!4_ykII|sBy9+^IQJ{5&6xTkR+KR%?5#_=XH)b0(3pt zUBPIPt%X4VJJT4XPL$9HUUKOL{0OW->jw)YN32t~*}$LW25T~l1{Mt;)Y%N8G_i7` zC1>}B+I6A_q7AjjWd(;ISD9uz46>wcu*MhV0p-DA6lzicZ~z?@tt1$(S{tuMZc``{ z9|D9U`q-Yf$QEiwUQ>aMRpyC>C5^gb!kD8Br1(7-Z9C`eXOvW zWIM{JbSCuL9bLuoldTqzLa5rjVd_E1;8UaaY?lPdCnQ81wdY*6fQRjvA92UNiyDYM zntX;j~rkjbq;nN(qj(bxNIkT&WHE@p-m} zQ78VTWP@5sYM!AEqeEyR+y^e;W=}9_2A?Tz0UDSS!U}SqeIqGF)_Vlskw=fm}Y8?3nY?!|lCpV(2T`}+7Yqo+)&Y-}qX6-d*?f6HBGH9Kw4Ozz%7(K!t+x978lp(~FdKTQ^hAnsx@-E=S=BSFSN_6GoG(z}0$ zPmat`%ZAS#nE=_QAh>O(D}TMp<2fFbAUc@;fZf~z0%jxI0i&``aXwS}ZJT}(H(2KI zh9B9P(RLl@WoGhK9Ci5W;=-Bu2=R6sO6%C2;vR;9%pwWqf9-xfIg zz3AuV&rsGdT~k6ch&ZdB%5trGirmyqnY+#hIJt~cZ0j6^jdUyrHBv;sl6z2D zDe}=6K#X)uFJm3A*&aV3xBDQ@6MTXR9{i7GS#u_=<@P|v2|YxuyR8d`Zb3XoOES@D zwO#-3>OBRbca_AkxqxoDxdm|nFJOaGg-#KY&Kj`o8H6Yte1NlgV&qf#=hj3H=0InP z)#FgpRQ~vc$)Ft;k!j#+Y1{`23|a`tlZbXtRyvxo(mf!>rj`jwGX8GGo*4&YVzRif zB7=}i+M=lv)Y}XjRWHPV65jOC4~7Cg8}LgV8l?ln0ad73lkd*QmiP-TxY#K0by*1- z_$XD9NNXS>GnQdsz5=(hA-bgEZLC_v6QWBe#WJ>d0u#Y14EbCYI6?Aa7}FKFAuB*b zNRV?@60hxw2eY9!kOY`%gLl1LHJ`7)ZhJw^r>8`7(2_Rot-)`U?xp)ZLfu!xVfsINiErt@h zKUqu)1mkSnB}fp;gCoG@*A%$9g8fuM1C9=UXN9B9CX%}Wev?*2wci*7<%qNY;vRBw z#BVdQ`g#=wSf9?0QCXcjUiS~E{Z4qyJ4{VMc4fO8qQl^+;{EIAe=suc;C8<8Z zw6NX8&n}2Mk=EDBY_&Z~l*y`q{Vy^+G4E?!r|n6;@$~I@$~)o~R!~qPeac+HH2MF6 zJGN@a!a+3~!5@i^E!(kB3@>A-26OvbMjEmVfD*aCCJ7j|MlSi}7fnFb5qBI z=6CG%TkXNPt4aI(>S848n+~kiW+P56k8N&HpsQ|d7|+y^FarwJOEoPXpOe4-=LZS; z%TbWJq*zhs-J41+(XZV-eKd@tC~ z!wG0>z63pCdt8ID&`eGAOWqjgf!3#9s0!JKUu8S&B;L1mkQ66vle$* zb3tTR*AaaXi(3TL5EZ9v2iO`fB?j)^fN=dH5fzzLcKxabW!EpdS2-bA%svyF(LWjp zhQlJp$`X&emDmu-ER<$0L<9pb`%bfbh3OT&zeK8pHG58~7~*|$ngKKk79~}sa9!#*VI(xE~jDOu1UJi5`OgGK!?DYQn0`{%!gm#6QKZBIN^VI3F~{j zbv@lIXO4ul1t{ZMhGr-=ylzt8XYYrgO_3WBcAyp*P$afhiYF#Pm&`r73W%EOVT?h& zV=6jkWH78qG30_yghCh?5P*iVgf$otQx5_s-571j9ab1>8J$6L4MZwxMutvPM^>B( zCiGi(13?)mei?Hl6JZZ#343rP77f50q{2lWI`gsZ2q`S))JHKV=AULpR?EHxF{i$Z zl{1GqO!D$v8!XyK9xp!V4McU-wVn0YsEE!o`qa6|d?J++ZTz?q1d-3xd}8mJmAq~0 z5&aLmesuq1(KYqUO}m*0n2@c(-#}S{;1juCORC&7S2mx-UT1a2Yka8BIF!AkC0;~v zqy#!YC0;tIgbF7mUWyVgpH$-2RO00*ardMW_fmCG3PU@8&Y^qS5!zL5Vt89Z=2i-IcMecvzYH^ zQ@B zLIn{!XcKV?6m^jO(W-_7Jw!`vr1bYbTf=3`*s*fAHKL(D(sC}o>*cpg?WzpQnY`KaVXXbilYJ9L=l! zV_nu)n5IKS0D7ndSkL=DB=k9t3^_TO-@9G&i@n>kDNSAB8;<*RGFUvcF1I(@g@?8` zYW6YTx$R-QNZaVjo$yjBPfr1H%{!Z)>Iag-h8>Ef zDOU&w>a{)K$?_75#JZifnu8`C?$Ki>61P@b2< zGeP~Q++Zmz$8aeEi6mw+9meceOs&iR`0WTe@^q?@zf{yL;IQLWv*zaU?6AwP+p|%C zIYxOvClqE8i_Fnstm^Nyd-{jCyXc?GyxSA;MMq^Ox)VV&YsScijTSnbli#OM9?v_w1M zutq{zm<{`{I!3dQm+2C$xJTq1E=mZXAnwa!R4i}>Y}5k;4gh=h_>Mo`)Rzi|!f*gR zAX+f>Q+SkFul2L@BFx7{7?-jND2|KF-Su3TO*hA9#2=cf#+)$5(~kwgTP6RW_h+-n ztJHR=y)5SzhvRcZkU}aXv`Q!h5_R~)3-(ni~{stt!!b8J_1(G`HX2NY8Tmo zd9J-L!m)$ej{#u}$oOLFFh6#aS`P6x>`%p*Kp(+#xEZl^D@V~cLNz}_^Ih=wo1OPlyI&u{ZQ z86_#n{JsIE0Dr}gB7m1GGcHNl!^+J}sMJRF+Trv(*cqGWogX`1Qv_CVsi>q|%W;yO zV=}}RZkRYW2@*)5f{7q6J%^knc<>eznotyP$0tlddoGSCWI7jiDSXCXUp5cyIm<>V!ih8W|u zs}DBVe}T0fDy4Zoj~oZXreVoqHo8wSvcfp1g>(vBrGkIU#Z=FTG&IGn4(!?w$g$u^ zMVMwO)z`2&eUFm>`=1GZQ2Vr9c$eVC+h(pvm{FMFp8R#fR!YLRr76u}# zf=$s2EK;zE`bXj&h<^>~L%%;4j5Y=5AT)xv8S4YGkzv5!cCzne4WU#jz){4ZLmi-v zN!)CnHjbR0@YN=@M8Hqr;pYOdpJR+9g;0`-O#}<&K12_QT2ITD(Fo0Dc_8K?kHHG| zrIesOKRC*9QplIVj+;zR_b3tKv4>4RA_M@VY;K791xVSlmuVGXJ7AY5;9#0|?WKuQY(TO9s%Oc}f&} zYVtt-&!h#%(gzgDCkFq`6V*=IdHaB1PR_=$zZ{?$At~p<98_A4BwCt$jZiUC>aes5 zV3sDoV>~zKU$c?o?UKXMuTMOvwTkl)cQN(S$z6osOuk9tOFY>V&zL_$iTdvNNywZJ zvDR0b&9tDex(0huVO@r1xf!;nn(c#jXEMmEj+_X(Gdd#|Y&a3YDg?2NDcgjn>6fQ& z@=$I_EPrsTWoTh}YO}_%p%|g2X~%=NF09#I-SvW;n#cnxkFLPEX^q!x`CzeD-J05> zX*xS?8r7m%nzftG?68x~aMo_upvZmdNR!B?2>1oqF{KZHw|h?Cbc9CjE=_))RD(}BOW}5h|<#7!hv?J_h<@hnhVY%36`V#4y^{r9?H%0hJsfBa+@Uh7$2FagDfT6sb zD!&z9J0yO5uuP;B%zO@>dlCKb>GhRHmOJYuNv z0cY4PH-#wtO|H{swbkP3x8f=9JR05J;BQ2hCbMmsS#j92E@K=(v^-PwM-~vxreJg5 zg{U!oJ~Jz3@qf(UC$Ux-;RlgH*Q?Ip8zv zT79(cI@KLys)R8;EskUbaGM__uurDg1T`CI;^U;Q`n8X$NYM zCgNp0}T-)pSf8x8LFRlj-TVxxJXmeo&?( z;i=)9aqwhR#&(<1BjNe%Z&UV$w@=q>w?VOqp5ku}PV_E2aK6Mqe+S05&N*@M@Esn$ zID3DqVooT7RO2s4RgUf@HhL?827Vr?8mcnG9yYuU?j@@sIWP}w6H_H@FnBa&uR)yuT-YX(W^DWI8McXd z8QVm>kBV(#=Hsz#9~|08CG3z*41A3l2;Luf0T=I-5b_-W@}z`Z57d}Hd^9T|VKR-5 zX#+q+^+_d!+lR!qdO@%kPC?%xX(3_0pl2Lptxru;8qIL@6Jxnm>}0^V1-G}V*C1{b zQzk3??%{7ny!7oX*!$^Pp@{V35Si z+(Qx#knwmELh;zL1m78ODC3Os65WjgOhqwnQbn;u(VT^~CbbV)p)+2=j?$%e0Rrv& zkb{BrZcxlg`1QFUqT1tVQ3IMm_$Cl}lVbAkmblK-G6y`QmXrRnSLpe@GSL`tP%mVV zx@;+OwFK#@EwR1jr_Cw`t7DBqr5bHa9?9LiWy=q%_1AkGPidv;7k*Hx`#K6Gc6_6I zbY*hx-sHm1PX1|+^EVJxExSw4@yiY1mypOV<*wk}fwr;0-Zd}PF5PNw?2|*B6VHd- za_j*6L!0S&QwW&mhAA=d9>^8=ev9P`F0p9L6^cV4^DqmpJLJ1SxymiEXpEQxriF)L zgt`;ng#98dA-i{x;=CVDSCM63yQ>vbtcIf~pxV9G839)Jt;-5*S9Dx!F7W$3MvP!` zK5`)LjAc`@Mz`LEaKeki9B`YF4bQ9eQpdSsWRN${_p;bWfV}sSR9+WvJ2Ym#FmEr1 z6aqS6834^cn0to(E_+c6GJk*5(+UitABF-v;wBxe)kO-Z`=%Y7U1=sQ-NLioPYN*E zHISbLF}slgXIz9DtRAaCEj(ASY6YATLIt{2ob4@8n<|O%PG^{}Hd|~1@|_^(O;Y1g z6L=0VdB*C)HVrc1cUblnigkF+K6_ZVqMV=>-Z*zp@?BSwpIln-W zu)I3>y%UGV%|MHTBpoxZl`#^sUsodH7T2`Prdje%Mm=m?kOhWyvx!B}F+_P_Z>+q3 z-~q2}NHYxa{1)P0~zKb!X4woMGukQCxd+F^G{)EcWc!;Hl$2pKv;? ztC%>#jBAWbxB-i%!~ov2HVld9bu^}UjHmp!h%w=HWwyeJ&f!D zLuk|!QQGa;26tz_AgMSkL(*c1)JM0OU)+K+ux)M0N0%YMgfRjtY{sFSLAs;KuoAhB{oc2;8YV;+9 zy?+{xPg%VP4O>5PB>323gH)QuYw4JUah=n7<10N3WJpc(A~n45P{Tou(V`7YG@DR) zI82`pLJl$pb2-mX@_>iC;bzBO`V9(e9~EqQ_{nmdx1sX*G5{#~RBQKAawdp0zxY|yY3V~wm0F2591c&SyHn1>GV~om0LRtj zv`evkvA_>lX=i_m`*X_|@H`#yAnXfK&ePfW() z9rYYlKt5bdFpOJZqn;z;Hp397vTTUU6X+{bqR(gzB_dhl^t^+Hd+}6)wWj0xH}mzq ze0{)Gq5Za3nA^AV^RQ*`_Wb4i`;GMZtDxe_RkF5Vkz^}|{>)rJOH&sRfpDy=hA~9g zg1i}^e2W%j5cSh^NdHgVk^m(lFnOv+MuyETb}$?@KKo@p+w)ePK>ttN{$*}InQniP z+l#5}+u{F-8Xn;E`AMHXUB99GC%(F`Js!_q)%imlGOJNsD0E$SORbi>h%ufXNoFsm zdy*#XM+Cw?-WVD3vZo-y#>Qu`oK@}K#gu?$zq=As%Y$D}cArk!XX++ZLly=CGHIu| z!yl3_+zSJ)Nrh63gDVTx$qAaj9!ESzXZUgy9T>%HQm))#-2$+_Jg2M%hk?tZ;?jXI z;L&N(Cnp3+<8VV)MT;H$lg(}|<}#))is%YqbLk6E{m+BkC{g?EX|TVTaQG1Z{KU`B zz>ave$10LcjHM$F!{sv6YY>jhd9MKs4!sLb(YkQdo@4NU``r5oA!!^u&!@?mw}`6y zSXESymg-k~VDtf6lOFSEX((g^x>2V}L%R+;q8_v;KPa9@sbeSOKFg7@Oa|{v3^2ev z?qe5HnliEMtKeOjrYDT7S_y~4RT0DqT?5H?mR+afL`}Mn|C8~;P*P8t2o2%UMW3_! z*Yppv3jqa$o@?lxO}(sQH8W%$y%;cJ_TkHC*zZ`iY!>5d)s{PO3C6^Gzjkjy4=IhP zq;lt-M4#`yT_v8DC@m0J-Zw;ubuxPie~Ivh zU@F8O#}j=Ec7f?2Fa>b$0>M%z5FK%`><0|nH6B}<4!h>pBEvE!gg!&k9M=-Vruz)r zp*(KbI-M9p4BNUm57c49*B>`*eE|*|QLygJVjj&&uOJi=tZ24kPXJaa6u<+vA2UXk z9VO2+J}@HgD6Z6;^ALfweO*IN)YLUp!G87OfbhW$E7|RPWkO@%nD?thG+%ZN5$ySy z;yleR{6;hUjT_Bh{94L7PoCZI6dBtpork9g7>1{a-r0)3-YeTk6PteFDZ&K9If8mm z0S2}(=P5#~2`3Rm(m9C$4dUI<&u|i9rzzd<>my>JbF#x~6qnI`okHqvvCUnv$A@wJ zY>X0> z!(!&WL%avX%?RM=9a>CVSWVA@t(RN~2>ex4yb>*?hI_^mcZXY0i+-c+#M6Q!zE854 zf1$W`?uSM$7CYa|s0MQ39|O7KOdyeKaSplE?OG>XHzf8=hheBS^BCsp^|{Us$wEfB zAqQN$WAB;jbMtOUzTawNzX=*PimZsnpFlLO>G02yh{i7v4Q_EVqAh`FswW+yEzKd? zFc2-{hZXH%CdN*iglIK-LWgMF%p)3Kk3|u4$)wx3DFisG#rFeM5FjoM1xVo zcGyjm5Dn+Ms#8X^I4~El2X3(%2ib^ao)z3;EWK=ZZhtrnsP`qA5)QL+xooZ%rRor5L>cV{JKWw82dQcvqS^^}kQksr(ZlsXteVIUE>N5pI4?`Pre z$%T%bQU2TY&2)O)qk}A zu;$I<{*Z#i&^P!$Tu%E)B-B7u4|l<>pg^KeRfB)FQl56h0yghD52Cw7yWlP9wPsgg zC^UMSa9aFl`oY4HGDgLL?QCk}=9sA6-6Z;v5z-<$c8JK$ws@)WMb zi4CMABDbe*WYRH>&L~D|nLq1P>L0AFq&cIn>KgX}Oyf&+f!orb$%*M%A;ZTEQZ*9OVCJjG|2bdDCRakR|< z$iiJIt75>5?9NmBq%-^eA-w-C0zGOqGmKyXYP`8Zoob#z-kc__Q3O9X>`K4W89EoQ zKUMa|Xq+)}%dYi`691pe&_9Qts9Ak|yeiM)T^S*{_PWnjATAZoPq@I>mqU@`?%idz zkXUsX%7Fth@SXMC{}0WBwd_Ng&T86a0?1?B!DrsX5|Gj1X9{3JbeLzH?YPSw+ZA#5 zuIOPj30~-t(Q3306g$g2Iy`f`Q?pCh?=5phD!j`z^%|%Ou6PO>MO}18+lwX8t0f%4 z7$S70#vB@4*!RfPghOdgNfVGd`nVXvRU_L{nn%>>}CgF)~d<7aKEr)iKcRWb&>f_28{oOoxMCTdIbf>%+J8>(opa zpU1IZd+CEt1N?q&wSo%i|6#jk>v3YFNJnBnLVleTnIG`D@fKOK-m;siP?Q)ENQ;va zz0LIOfW)6GRxImFl{<8U6cOKS^}@gFA#;nlav5W)d?Qt!3PlMkho4zF(`DtH1R5Uh zwPqbC(t=Lr#G>VicJ)A)zkGl-O+W(6WG#W?u9{62UmOlm(;zF~1_H2v!yLA;MS*ZP z{hs$)Lv}e22K;5MJ@7ZD4~%hzhrEb0E*Zx>`Yz7Umjnf&HOrC}_Nk-Jo1wyKD{k(x z{RP_g5~EGCXE8d<43afr|( zA+nJnLaPZPK_VFWs=I#;DXvVLP-(M`sAFw}KH*~FtOpccZ>fo@@l-+e z;g2VIFd7j)3^@~Rxp#j4UD>RMrcaXFboj_9CEd23mFBcb0bocQ4PIzTi;fV$;REiB z>_D>*aFFAXeyv45C$GP_2@GzfoVUZtjbLa@RLCHLDb`l}T zsxiRpG>lw%j-HtZw;4(atEG7nESysO>=rC=)&R)$<|J)Uyuqk?f+z()0eOM2*)c+0!OfrOH-D}z-)f>-WMh#I4^ z#dh( zkdJjU&;t}fF%?C#-Bzm+#4!ez43z30PE>UCe+C-W>=9(HRA|Lq*Bw|0F&QuG$Qpa8 zSb5kil5>ooMZ?+`{@!#nEy73#3ho_s5tJiWKtrWbP3$NIJ`ElIr~Pt$Mu*Hsro(<9 zVZuc;K7UD^kjG=`5aIVII_!f!#D}mvEFGeH?lt{mbhtTBhnqo%@&@Vf)D%@swG(u> zkmwNRe4GyF-W{Psm*X-WS`UIwI)v14J%l^ep&|!;z?~`jiS!9@B%j%8(BTU4RF!(g z!VBQR!WX1H!c`3NC-fSurJ1!%Y^R#FAhtNtDmV#C5$L@vWX%&BKOakMv4)6QCm~qhLAgH-4zx%b5H=e*R&|qAb)FzHYl~VI z2{nHtU~~$0fLW!&^p;TvRlK>w8_&|%1lE=iO#k^u1(O&c?k zaJ$eng-g5E5k!CjvDEu4f%3(ewPmmnG@TbqbMIhS!8F+MMq%(Yl7IjJ;b1Uc0)Qh2 z90eCbC_?Ziiv^oz7-$k5!0L!V{ANu$0+oQP-Z;RNn6x#r&K?))T+n)^u-L6I(x&8WLWC+ zu+(Jbn*MTPR%}_U5EnC8qRlKdHmgiOg>7TF0V4S?eCi@~HvQL?29{xp;b2T+TrXpv z0>aqHrDcv}fnqY@BkqFm`_2@${GlmoW+H8Y2c!OyQ(Pp1gT?~;|J#u8^e9hkSDaB?oXmEt1QG``ea z%t0z|HJ9G!S?AaXPo!A>^pFJmyeWU-eX#Ko1n3(nHMkmCo01Y<@25N5cP!TXEG@0a zq3o=wkA8}2#8L5L?~Kp-`xat@%S|fe@)Alom+Nqa%M(^WcgIg>`mwd7dM`5p z{E7*fYV~a8nb#)fwE8d~_S%mFF7XUxEt`*rHlcFaZg-s1U42tk!pss(E4-6abLM#` zszmpW-Rs~gYMH!K!aogBGRPz`x1}J29Y7>41I2{D41oYaS>Uo1c*gq_oSh_Q-_Y#s z<`X(+l8+zpF>220bzXvFvK-+iUDyu~^^ENweE}}wtI3m$qpe}C@%kG@!Fdw~xf60_ zy4BIuV;^38pRhSV#26SwoasRTQnMbLG4q0hL1>=uS1o|yajuY(T1E!wk_27|w?4l+ zVuTf*v&T-6yp{;RDX-;muE3@UKvYdmZH00RRC%2FZhHPYFsFa)eC@Q$4jY&=3O7${ zJg(wqilzD<*FOL248?TfJc)=ia25a9E1pGOgjktk+`-Lh>*FeOEb^$#p~xZBE?}rN z%m^nz4f8rf7DSf9$@E10QlYl+PSEV~QBjuN6S%NP>w=llm9?w5-l?&r3g z*o`cQDpLEzOh+Si7;oz3$FScK*!9**KzejkI9esB0%U?t5DH2`Drh$nZhv-FWagX! zyK7fDB&XR_JVkQFZUAg$HFeVUA%Tp!sC;W0BLR`M83Qg~gbHCKO2ZNHj-fDDF1(X(XyzC1DYrKCNPA{wjK4 ze<3LrYhZTl^%Qa+>#94K)Y9El-T74A6REl0`~4%;ysT={&XW zQtLTH%&D>T|0MrE!T;vm+2wyThMe+S*3n<$LR^R;W{C0ITU&Hw6+p_w7eb(-eeSm|)7Q=T4qS-e4J6LxJUGMUBBSL(d{ie;_p(4mIm!an;7S@+ zpaKCQg4;=(WI)9sSRwgrlMKQp8E?!4gV!Y3Td{v29hfcgqD}ik#Hf_blemI{wf+Av zX=7yx5cis~yRYk}G1o>9ZnnZ|{lGKM@f9yZ=Ii4NAf9lexT{$rk#+@ZrSe*sO|~nJ z`x7i0UnHwB>+MHSQEx=%^tJM?yDml8h$Oq zKbtu8&QT7{8Vc1#WBAgVvs8J`3~x-|`QXq%WkF7Skqaz%p9_x7JubK)8ZNje&KtD` zL{8?!3lZ@#_*7ZuaF5bu&G64eR2exkiN1ZkDJGx1!yg=rX!3&}uS(dqB@3j5AIP+; zd=gG2zh=h-ev;~aiMqTqSV9I&%F(~>Aq9PzfCs(lRDP;#tH}qS##J%-27fI^XdY1% z^`C{W)prkKi++j;pv*g;aRna{L%F5rdX9z3Hxz%CPl_E_zbf6^EW zfqnG3x&B)&zeP(=t#Xzaqe;zmjam24rWPk26JPG;)|oK8i!Zbbo&^%4JTO&Qo#rpW zumFbt`v4dMDmdyw&@VHX2Mc&s-s#CAIP;3I5otv2|>7) zYZq8Y)^mrv0=~o+&3;Xah{>v9T&Qa`LzypHQ4|S6A4pOUEE*IOx}gipV|Shk3_On! z0n8`gBl|(xFkPr^6SYRshIDyH2Ge6OJqOcM6Y5V!6INM8)#ABbP%%D%GZ@Df^v#%P zTZkFqfQ@LGlz4W_6Fz~EFU$nti{J%mPE>DMTFR}fFR8Fp>`_Uyj$C}*J5(21g=84$ z3~~e<8S18bLKQvhCsi@3xrqk$6B*)KoDvtPwV^lS~Q0#_BE&wU^E?c z!bFw9xTLp%VUTJ<#lUfz1MSualMA6BnjJ_yDJLK2|E2qXrmYT)Uk2gJdk2%Bf(bZI zI10O%!J4si?ev z0H^LvExqz~TZ?NYH-b4T#bp~R)Zq=JSfrRh_i-9gIXB#vV3-fIicw-alDj=oY zq8q)iU<#;ism&mP`%XzP_Sj^S<>6rP&82bx!SOMH_7=Zcg3%4Ddp-5#4t-XID-a}@M4fg&M58V}f2Nqi*%bp-Lzio5#o z3LMbFyZ=yLV`zmri6@1;4f%_n4v;Bhu%ktxA(EH^?uN35&BE)b4Kg-Z8*~SBI;aCs zU>5IqJbES2%?Vd`dg&&{s{rRhLSTB!T0-zy%F1B5EVcDX3>IJi{Upg_F0;JJjMMLS z#w*kpyG%LKSRNad1%AHS{}}tOs!<)FX#ahvCadr&EkR5nc4#CNj`E z?s}bQfp?=<_zp}U06Y3s;mMQOM`OApE${<=HF#+>wSLL z4e`b3$EoMnfK$q!D|=v43!DJ(_JYidLV5BZ{|}P)%fL3c%jCgZhm!}tNjOEyg+2K& zh76~k{4_7h*FRH~jlcT$Cm;B$n8YF>TJm+?e^5Wqy9eK>zZjaz{AV&+tcm-R@5X0c zCDU3bDV~Fjxa_$8@WY=L((~WLAo+gt{^WZnem|{#R-w9`R24iD3yb_0sOJ%uM^$#6 z9IL-o6^e_K|Iy&`!P;iAG8mHIuI?=i2Se@_m&p5*lwy`!+-wAp!!O0%x@jtpzx;`k zwVpJAsyXxD{jo>Cx?DW+s~^v=rmaobWBdl&^+B54p&zS@e>vI=ZDE7;h(Mr++rQ#6 z)X81@myW(V-h{`h*TvvUC z)eX5cc}5rf5}8ZJr@DEiBc{i5X*f3_BaK5^yCTh6X_= ziNVmQka!V)gQr8@Lbisf!qa$8jxxT+S}b9G%ae~iN1u6bw)j~W+MUm>qCW?o)3p(C zfQzf_;7Y?loue|~Hmc}*H+VxCS;D9$d-yLv&)Np_TY~J$F=-XpR0JGgzabO=bGvHF zmU42zC9=ijZR0X2n-bk^^6&ijJuJq85%DFhnw;r2voUymOpj=}`@S*%mV3bGK6GGo zaCP!YBu#Lb<@vs{QlI-8kE?r#J{SiW;=C@~|J5d5)%TETlLz&I_=3YFeRu@RF zzHI8R+hjDPW}&`3F;rX?OfG}Ki$D-cTJ z7xP2yhPev1*a!o4?^hnza^@~>?l539&J*M7)pTSjv%rKluBY)J1~9 z^>ml*X>nn3@_!WvljmMoC8Sc&g3V8rxPd=|4`uR8KbBk@h9VQt2ce}Fr4evrS6Hyk zhV|Bz-@C^R0$PNV{@7foS2~zNtiUoD0PFfTniBh6{)}Yex2uHO187If(u=E>f1cfT zjkin?J9S~)IcW4$m+!Az5Ti3lviW~a9@(EJ!jEpQyQH+s?dC4S{T^t$S*4Su}Jh# z8!!iX9JMbVPA=z~7ylGpI(wtGW-_eF3V9HQ6h`LtDZY6&NDVe&JTO1-DufUjY z7=IGr6o-sPyx@LD%F>*ignAwc6E2a8tqw5rG3gY zX{@{ez~a{K>N@YmK5%avv}4k`*8T)U?Ya-}WX4y9tM>8ii_uNg+^&;DV~m;X7CLH2 zlYgJA;fuR1!epY46LA)E6?b3UZI?|W!$~)&?E|pW<#N-wK@seKV>VWqAK<~trJ+mK z3&|u>nKUvp)WlO#Q6xZRhNHVbg+nGbK+rE2_26I4B8Pn^Ol9h0CCiPJj!!dhdGv3! zL=WF;nGgCx@q^EEHurke@n+X5ZPEvQ)m`;6gRjtrZ7nt%;Kbq(-D@^` z%h4;U`Y{Gc9zSN04H_G3@;P9-Bp?%rt`*M&OL5iv4A?hB2(YNiGL$k}tfTHi<*h&} z6Sh)=UW?RfkQO}7!4ymh=9xT>?gvAo(0Y7LgDdC;H0V0H&)7+|bmV&mZ9AzX@zF~I z8MD2hGmwOn&RjqQ<^tOMoSU*%r}|12Lv@VgN+uta-~fS8B2bM17>Y;ChmiuSBXeF{ zPR~@S1)>j3Bwlz=u=r*a${%J(Gl|aPIs|ERo%-xTLNNfXP#`0DEb7+!;H!BV;J;|= z8&^!UxPFMi_Tl>Ty*DE^1|6cfS>*rzH8bYnj>r$b_s9PlhRvOE5qk6F`W@DB5Pq6F z4S8J`5ByojiMo)^UwZJ?FGONCj@|va*wyItCA4Amn&D8iu z7uI3y1S~EUh38u!Rb@}<6ACjI=?mHn#PcvatFe51j^f5Q9!QjaPk!#_zqWKYw&1DQ zHuYCplSwtbcyWLUM1eP4K*K=6sngY4aJTOfe!_Rb(OEnZFT*o!dp!5tb0$%^kb6MpSZ424^oWk}1(n-&gP4Ew z@DA-fKe)jX5IsmfIGXv!5bc!*_5H~Oyh+?G-B(<&tM_%UJXk!`Jr^DSgAWHU3_d8+ z>6t(?xi8W3@pX@GuBIn+O4EAbKs}U>P%97iHhK)c;t7#&uos6Ko&!4G14el9V)#6R z?J+2)uoqo{;24NC;gd);VFcHDMR*j*)zk+-#dggn1m1vkSjVAX5%z}W#9zzeTkH)U zh*D|aa|Mc5nu+Vx_3FA%(;*upDi~3~kpNAep9dPhpm38%|t7}Zb@8jHy9j1(*pZ_O6M+?eoK){6xtFKmX<~K}9 z@A}Avc^-tx%St1FZOcS)*MI5yUvH~l$>jIlKmKnx2j8H0M^_IXyftXawZ=${255RW zes}S!fA>F_e*M>GcWpVXXJS3&-=ZGa%!3DSxEwq9vqWkOvrm^zI(&x#Un9Jt95d#$ z9h}#uYb>U$6+GDk|MQVtfW;XGJT-X;n0JN@EI?0kmE+9+LXcD1c|7>vYL3HBv$nWb z#B^Z@^zxZ1X=*M*r+%#4(yr}Sx8gv!wCOv)Tk!eC2t0Rtt;Yl6K!U(!9jOQDlo-*K zqBonKZVKr6L)=R#u1p%Pc^&I$S6a1bSf;`mV+*G{|4vA9IfSPGb({YPyKM;*y3zm| zSAO}#vDs=+hi7*O8b?v>iVaEM~B~ zMXh;a?Hqlw_tC{ehv2yMszZLeO57>e!hLRLk{NSE^$t!s4Jr#`Fk<%-a->W0_-xgkc zmW-l95v-0^*Detq>xw~7_{3pi8zK303KukuTVFN{J3Ih6{CRM9^1+bt$C9VrZq{!L z4e|oms|_>EMG6f_WMj|-wrTd9wE=ejdodh$ z|CzQ5S6F#SjL0lkN_jk2iZFydK;=+^f3O`qAl}<&A)KTc$I4vfS}Suyu)t_&NJDF> zA&|67%F@M&7G&<{1Cz4oZw@{**N|*JHRR!ws^B6!eg^pmsIQKQyLpK!euaK5os^rU z%(+J%er+B&6ZsdI`J))qAM=Q6KY%GT=-5`;%9G!54+!)Rb?Lf@i9 z9(Y6}XFNdl{ii)39V{r0J>+&TqHRHl29;Iu;zWv^M^oP%o5IIK_Jk=s39=_lp$#3G z!pGxEx0z^e3Qxk7{&Wia-4w#&WA1d(F_SJ?&ZZDX|AS|7x-a)fF?CK0r-kNu10NDW zIzjm3pgSzd&!w$UaTgDzECPV|QWnZb&f24hucL{D4mD0BzWLKEGEK;E=mN1J5}!H^ zj9h?n%Yj`TK*J+d(Fxd(qls-FF{)TqoTvMf$?=37Nz=KUYdUfyMbmZHwBkA;4gJI^ zX0VxHi7p5p0LwJvl(?8CeV+@9YI|JJVw!I5{~n&2CAYu~BY@~gcBTJ!C^#lF$oDuH zk-undpTog@Y@(T+FiV2VK0MJUL;FWC(Z`@Xo#>7`oXp@)AlfN+n49Pz+L-7m(ayL- zp6Fw^)=l&^rWUe(Hcj-EG|`ujPW0u+O>|&XLyQzWx}MY9k&V5ps@U{CU73k(0F@9XtuPdmvd z^h=vwXVDcLJxCEp!zV1TBlNLf=hKr^vt%49-H?w~Ds(fnmDJ)GSrN}*pb;ApZmFfG zt2a`PhiSn-LS1`}t|2F*Yx-!;Vc#+BtRf)oH{&g#i?Kkjsp0Yh3fRVt zrMC$T-XsHIv++Kj-3@|I+YR^Mox%~NUNchN$O?}WhU+aBrOkJTW}i$x)ZvuOX0c18 zI`@hNV;FFCosT!(Z&y^#SmEGvl`~>w_d>%2UFmUd7X3_)y~-z>hQo>s1|xF}2os;0 z;v5fl68U{wf6XkXGKgF{gZ_Xmz2z>wX98hn7M?4u3Z z48Up(c5}WeI+DlVRib;i6Gg`pvOUeCqkGGN^kdMGwY#I}80P0g=-6|r%mq{YQS28f zhOj)s4F)|)N;=%|w*kAg8l9#(L8!~?5e2X&GGSN9XeDbYelWz7dHo5J)ddSs1hk)N z)FD|zqn=9EFjLK5+@(BxJZJyIYt%2v^xV$VPwLpW)u=rv44Dk0WQa#~9L>m+L2Si4t*|LgiT`pkmi8;Z@VURr<9q;@8L1gy<&nQ>6h11x?}gyph7k`~i*Y z_JO!`oMCJ4km`O_F?WNITFrvd-RtT8!Kdfn9mZ;#W>xgr{-O{s~SrrY$4 z0GPKoBky)RkL^5U;j9F>)kX@(=n6k@>CtON5Alc`be7io7+F?oVe3FJoFfZ^zqedH zfm@nt=n$ulcv))CTVz@I*&*y`zH!gZ`SB_OOqY*Niadld{xgANY8!HOyws4@V{bmI z%@cTOqO!;i=@Csd7kFbrf|m7b>s||RBhi?~1*dTei?rGpRinslrTW*V;Eu(YEjYYU zGWLzk<`EjwYdGPO999?9+6X>q)B}6$mf~V67%szDOvQB>NVMf1Uxu?yNXcUCE+xAS zeQlbR_MC#R-4Pf@!nPh%#*IrQu8z)72zT2>Plxp}2^Rx}o}lm(4N@q!ID1ZD@w}(Z zDVK1vL?gR;F<6l1|8P{I{M>P87Xt#YT=G$4Y+h!hfq0w{OELl0>W%GW^H*#f$Afsr z0vpYad+~-=($`*FODmB)7_wpx$HNVdFA;~=1v;8Fu(9e5y&d1kXRNWoY}_SBKtCDh zq{v9SX8eB3ey|}Wxb%4G?l9KlCq;v=akn{bOPkHMJy26jTy za>juXKd(~F9a{w{CDk4l7LIWV%f_bh?rs?o-E~@?F?6*s*N%JP*gs}``9^Z6vwy7M z7n{F^T=1qZHK%@q^|_QLiYjIUSWz(~goOXYPKi`3$L$mbVD8s6fZqH7dNUKn0bruo z<_{b|FAabUw+?{Z*baa*_8dU3i2<;;+{*BSI)Hg@!vKzR8&>L7MVOp&F#XK@)$J;pL4+qOB}9I+m6;*k-1d*clLp;h2_diBN)I zXcctFLeWbeWF&u=eA$0)mU#2526x;Uht@L3&O&;KC6Ydp6?V3Cl%2U;oGPAHLrC*c z84^sb7F%>lX$W8=X5UIP^uUg?>x7HNY!hTrMw^y&{CnIn57)Sa#a^;XR9}W_>So9> z7s?Yp34(}MSeljq>%Bl$?y_bt!U2E&G1}1|;|soK?SlZJ@LFAu?Muj-KdtpdLVTR* za6HEw6+=GS-%wkOqtxtv$*tURcRSkh*-e|P;9v_5^H{qo^5%%M>r8(YLTag%YjzYH zzGM#0V3)&*6x)|#odgrDCakOMGKn!=Q{d1s@oFwhrYl%rs8}D%U|>aRagJ=oD|mOJ zTu4OfEDew2aomxa(F%A*wnn5i|-eR#F}RQknsIX{rC)>q5Z^5(1MWiD*LoE->MP7effe=XaMuOKn)xPcMi#FvFV zcTd+Zrt^TfyOoXus$!0V5TCA}O@{&T#g%jx5J|Ewr=x(l`&2p!$i!LcARx-^dk%Ee z+@xcGsCg$H14Oyg=@=lMfju|H13LmjK>U&kD_xucw2&}q@Qb~w54%ff&|@}&*Gb#; z_4KQN1;JOtw-P&r!ja3gCT)&cio?0o4x3)mOoLeY4z5id;$=F;E>IN~s&HY!i~pfD z6lDI@2p1N=LptL2!1@M~of8apN;AZYbn_n=(cyHsN90f-b71PM#c}6#2(n=8F+I3T zlqZPfAP>984p7$kqNnT?Lj?eRdGEGf5Z$=e0{kZWhDAAHS#IZv*ZFB>1*ee1bhX4kKee9MAwe2Zrvot++4 zO8kY8VDvQ~EN8czGZC?uDh_UPq*LJ&>iU6)C@LNd9;{XyN%#>F-iOfyci=FqF>U2C00JW{;Geb_DQj#(PjftNRaO_fJ`#!P1vy1a2Ka}#$9kQh90ZB43Q?9 zhvH4pPxyDt;g=GBceJLYc1M&zM>u4lr;6#gMC56nRbz6>R;CAf2Br4URHWd!13lS3*q!ajv3>+E#%U8e7t{G+ zy*PDGE6T|tY=SuiB+Pc$<2`i3e7N7qWuPkH2U~~K$cB@R;ZqBgP9dRO4$~fBlQJ17^vN~sM-m8#RIxT@-_~C#05LDC{65y8A5KrfSpK1A(#?d+W?wtfp>u4CTQ5Lw-qDXfF{( zi@&=g8rbYWe>R97XCy?zax_qLbc4$IU{9^<7EL2DWsphz#;Ds94)$CI0a&+ZJcm;b~_4e*vA&*42VE&k%ARJkphoI zLJE2qNRgV(2YZ_K{Ak0n`a~X9CH)w8gfP4_dOoX5CbWh~uAp9_)-jrZORm??YnUp# zB?N5nS`aRFV*p869E(fhN%(u}?$Dg{N_0&nybzfl6bTPe^s1~wn=rlEQKDrc*L0L9 zvwXl>ie?r&VUoSbN=2HO)hO9=G!cTdP$}mq(NJhZ4NaDsBTM!XYQ~V5zK>JXb*qS3 zF~ITfEOz_0fV&c?aHG~*^_FlDkBmg?%O3iMqX{_v)OSW#&IRkGUXB3`RX-wShVab5 z7_I%4`nrX>f=!DB2&)xOP7#O(6!`qI(Nn}+bLs@>mopkpgF+nUZ>Rw z;rX%8D2mq)6~AVgI?6O_DLfSflqeY$T5-_KEpN#ch7ZRkore(tcJ#|h=y`f)D!vEQ zjo#lAOQ2wt84U;YLGvqd(FWkM6dCEh>TTp**?u48I{4otU?09la#Y-5ap@e}1F9`* z>|T-j(DW?49VIUtqHkWmX$&6YJ^qm)k9-o|7<|t>^sxG9T#dDKM`& zZA!n%LV!BJ`X!Y*Hfrrxue3{eTlkD+r{^fkqgTIp_`2b)3~htJBaYJr=-fQ`Zhc6w zV89C?(a~JtayLmHH4}kXh;sMdai}nGalK;WuNje21N_q3i>`Mu3 z5yiLNV13rRK%6*;#E)d>@SnFL4BJw7`6au%D`|%$i6vNYUUNT=D&abhO?;Gb$IT@i zyF`^qUFEKKwM2{bQv#tbuqj-2bGp263m8%{(VbpyG8KHsU8E|Z z^`t}Ck!2(Oq7TdBZ^l8*pIZzMmH@`_nq-#`BOOO)9U$@{XtML%P7Urs;W{rQ!w9>C zXsdD|JJv~wf$d;*%!}m4(3IzDqtIcTMZ-%z<_`?VxL#mB<7IA=a8C(+iLhzxHzyzt z!r(*WgjLN`NN5)VPw@Sryrz{{6f~Z=ERPSnNm1F8mF}nc zjOj;2>xyzHviHcm!z?U;PZ~RM=q4Poi7CqkQEo+^uAW&jYPecrk9HMe!!n<^0F%N# z_=(bpddViAH!taG48epEf&s&q+GGgbnecPhm(3{n3=FN;qKK}6D(d%jmrQ4g*_dkRRx${3C2DSH+P3Rg(C;I zvr9B&J1D8v#lwV5;KBe}1{}V|{c!_5q=Ed^sfR#vA|MH|A{}H=#pthN^nHNLU%0qMXM@Uxbil5&FrxFl-2~HE5W1NsQ1}6V(%)D0C%aF5r34MLKYLeCk&g>&%go|hKrtV%N#AC<|wXikw)iYr@)na|n zkTI4C$!CO>G>mDtU_Wt3Svr{*m8**BC~7W9c33vWIPY*AqaP@EtIuMt4jJQhhzh}B z$4Ygf6@JO0k+_?aQFwVN-&88l@MuJ1B+*}%o1}k^?l$maE$qFr#qU_HRYfT&pg%!~ z7!UalYD#ys3Ha}~tb*KOUCZGR$v)}dm5JNDynmV8Hw>b|1f?+ANa(DVL}ENt5(;#- z0RRY2?bA|m`th_zm5(@0IOS}2ym{;do`Y6>=S=nm&!ML;#wI5k!-0zH12n|vJ@jgzUl`8$>Mv=krf0UJp}g-cFFtfJ=J96#eArm#vFk1w_yF&_A(aoPOfDz(qtM zbg(&2E2yc_Aw=o~=H28Z z@#iP~d#|?~MxV-w|FXtq^9)6*$N&eqbp()&kcon?z-La-QFPHg>MG)_HgX%oyAXO^ z<!F2)#rZWW!5+4r}Fk`$cj`wJdnL5+K zeyn*zM)U~K#j+3tlh6v4+Z9~VssgRL72GufD4;!0kv~22OGmn1er8RF#N)gj7;BNd z@L)>QXU|dT^xBtz%l4Dh-Axl5qwhz#+Xe&IE`JCwm)QMM8Bxu zYRRewLcV6@!b=kQD42o2A_-&dXMPHazBa~tVr)$@4xz{I)L8cm7FNiIogftJlqrJn;xlKuj3@d2mee)Wdjuyl3J-CE21U>A5t ztK!MrfqW#i5|{u?r`2n+LD$i#II}@_rccgmL9hoJq;@O-r==oU!Ix%X1(M>~$K9tuZ zvow4Ck!Hz+&^TGBbud3mgAVaM?r}Ox*vKc$5+_Kq@_DC`v=LU*S>pL0YL=vlua{c+ zncX-!!McV1*5v0{f3G^fG6^T5cuTJNEhoxItDpsfLCjLXI7utNL+H;?<)8bD{<(}R z@WPR^Xd%H!)c_%guaw#M501rH?w?c#5s?Fl4I*2*iH0}=l!?>Jx7p!LOgP6FH5U}= zRuHp^UqdV$1wzRJ@nCoYEQd796IY2eAd>jqOTTyjkHCS`#)02%wT4fbfInLJ+Q#fAk-?O zMF@>ECOW=QJ@pu)8VyiTRCcQAQ%i+h=BdrW7pX)HMx;H=7f;P7uDae8NWKVFV28IA z1_|alzB?*F1Df;?XidF}Z$e~+O~2Ega&3*(i|A+T=&EKL0kuu~3-ulW!z~(O0TNqb zN*ebV3zV}OV|_o+a#biybZH?ArR=>u$@__I+ z1zc}K+tQM*2H>zN9tT6GkJNAsfrS#* z6aNU-uTHTZ_1!`l^MeUgkHCDkbUy;~Nm2m z*8}s{!Tfd1JTZS=%*Tm*ufu$n_n8BLF)yo*_+GFObqRn_x(R?f-I-y29H=SgFR_jk zeapz^T){gB;h->=_N-+=YOCLI!clkeK^nK;co%+@6{YCS zAnUaDZ;ZfAeuBAQv_AW#IV(9iL7}X|!wDh?Q<| zEa)=5W02Z@iW}fMvxM3|bv5vA>S~DR&|Y#iplZv2`fA)@C^gYF#7D(6OCvZ)lZnNG zB8dhmN&|D2d!Q=0=K>99mbWx;n6R7FCm5LmTLwDHBK#>Kixk}1geR$aczV>7 z)a-SltO_g_bg*dpL8=%}jsDQ@6r*+3K%K=;0_V^R&6!1-t(m9dn)aXemx!YKlZw2} zhBE&9a2NE$R{%7QDGZn%!UDK=3d3qPq*i8ZvwPjHQ8&wGB9$|2gp|1JKULY++H&S0 zyDRo*A6eXkA$&)%{0mY7G^h9H*8my<&S zD~RPbV09CG;nE;IxZFku;Iapo=5nhg6L2Xip+4PGwT)ilD-j;?f*tg#s8#BDC1 z=S`T@iV6`YLd)u@LQh{L8)Ust%Y?tpIy}jG(6YHVi%!_pd-mX2zK9;_6Ls?K3~TuJ zi1lV!COR{kXMLliox!N-I%7vnOB`l63ZozeAL#RXR6|3#BLy8Gr`st$OkM_5GE;Si%B`- z7vJdUx?xRMOVGfQpr98N0xv0xdbyW=T}+oNe1QM`8bhY#y;hP=GrRv#w3p!J=)2=` z84%~uH0?P?bMBFrzBVLs8OMcS!crtKDb6netC}sxEHVTJOZ-ByBVd+3TuND(e2+y& z>3PH<$(M>(Gn7GfsNi~wTee|3LQ8RP(NcIfqYT5KaFChmXA{D_C$4`01Si zpvDkC0N-$*B|bseoAV~1c%@5l_lxY5;S&5A0+6Ht)hnn3{8|yOi?qY0_Q7I${W3s_ zpfmL~7Fi;sirAh`L8gY6&>`qd%X%ol(#qnFcnK;2sBH=VWLl^Wwpo=0$_pJ0j)>@z zBSOx3qMG37hk49wI;NPQhfht*fQ6}4>*gt|($_U+pdn%4@<|qlOPUcu)#h=81I@FV zsc<8wYk)`xw)?~>$|?$pg3ycfka21Yoy%T+5=*XzbIV|oaIN*5wJ?K7$%+_KpUgmF zKUc)q(kUGJ0aBnbE`dWJXmTxMk@cryYzCOD=FbM*bn=O;G{iiI{8qWhI#aj6T}nOJ5IcS~?0F%q$W5)NDgwPQNlx}iJC zH=MoXe8oCv;&|wqEK9_u3wpMOhRRT$Zwl7z*iPqqXazF~HpTl*dd|{a^tP*v0(>u$ zN$VMKOgK)U)FZ1gwvZx>1tBbV-U-@Xr6*?~nk?t?DqftwH&q~Fk^VM`L1AutjE2iC z!m8&K2-nb*jObVMgfzE?c3gp29#jA!NJFs?I70q=!kp%!F*$XX+qm1ge^`Ntj$DJL zf`vtp4UkIGEp_HmE^Ir4IXP7zm|oOtxf*shW3U!9GN70A2vb1N17iM?LIX8%Z+{{~ zY(MEWsuR>2Isq|l0p1WruZ`CejWZ`@1^UvEd2O{c!|l@Ty$&BW9N_C%z_*%uf}grA z_4Uw|O9dZm#FViGf^ND`gYH^seLc2cINe!aiJW8j8LdB}yJOM>%MY);u(Gcqk+m0o zslBZI2(*`7rB6)b!`jOl(5`V>k*OEsLa%~Sh1+@UWtq`Dew~7yYHBZ-QlY&NvmVN4 z)9gC4N3<8AnY5Qo>%$O+$CMZ}i#V>5X?j^8R}twD0q#8d8ZvlEU&bYPFArDUvq z|1$U*YdgOjt57c+$q=R~@e64#U`%>=cG6q`($|v4AavRG5i}Oq59&)!Y8M_=3?K49 zl8vgMXDBbbxetHgfL92anV%cVO=$bJ)EJE3J%*UHQRA4#Bn=p zN3uD!T5B?D!l;^rlX^0=t0t_=SpEI}=X`hX;zd#q`jLpj-t)cAHopPkJ+jUFBQG!(VV~Ve_qm@LQTP3nWH!tcIzk;KH=4lLk|B6DVM; zf;7UD&0Fo*P>dN{*^VtSGHHc{mW?4E(t-DABaAs&k%-nlWvd;Sy+ zF~;`c&0g8KcmIX=!hO}^cRJW#~YAK17IV_@U*nzl%0_lV%GyA4}#3b_KD?{pc; z9xmFJ*YxBypN1{UN=`>8L2vkHp`5*R4kgXKqk9Kms7Q$0pdjk$9zw!$tq-LAq(s^( zv0?5IZk%W~?#c2xYZY82v?aL%cAKG75zS?E50TI?%$gtLpb$&LSbjudR?8y(Tq_R~ z;7$Y9o`l!TVX>M_JR#RgTcIy%cGq$^KsPXehYuCOlKC; z=9#|SFPeXq)Uy^5>4c8Zd3uHt5Slh zru)_Q$$I_vo4rv2}9%vkyutiD~K*qCRLJ$G2(-bGdgTmcKy(w>^+N92185>o5u`=>lZ>xRT=2 zDXq2xSwXrcuUuO%H>iUTdCO`f;RtMpnr9|2MYRVKz*Yia#ic+B_@ejI!n2LXN2}_m z$kIuzMRT@~Pdn(t@1DjsV}d_Ff6;qin4f;{^Ee=Q?->~rj>P7f`Ph-lZo|R^cM$3_ zvykxSne^`3Mx(3Miz;+}_+meO=(2YDkW8LTU(tM(wFE%oY~%2Z{Y`|s=9glQ0k1GCwN^U#`qX z082YiAT!LbH+IuOL-Gb*hT854ZUorzf5e>!P*S7tAH+6)I>6x&enSecr|@J&0)Lmm z*jwAoJZ5&ByB6I7cLyojn<~;cC^$Io4SpwDcbZ4vx7gwHuaFQrf5>4p^r-Hp&*8#R z0bdzk89j_V6b)_}j9py-2aAd`?mlX6`0^3A<3jqbLvl6s84SG~vyH=@DpYwqt;lgE z=w#e{Mwd=tG+SLjq-gFiTC$@kVskishV03{;wWYxtqabibQGM1eP0}05$mJoJw$mo zPoZ{!?xRj~>Qy3dI7JU7Ixhp}ThGTWM>$W09GCU{w{{uB-jEl9NgnKu9V5fhrRMOz zDLI`X$q&yqfFkaMBKf%w!_2u-U?A3%*W6`4jQx!~UQAJ>{rcj3^9N?Otk+5R@g7e~ zHa8q375l3;K9dKKx~~1~x96Kr_cwi(vit(VaApH-yJ4;{fLacJQ1}JD{=`K3J}@qQ z>3#v!iaQoCRs(GMh~Y4iwVb^+7^$vm(jVCko0X4ILUlOoQ57|5680R8{P}#nLiUrv zujjlM?#CB04aWAv*1gh7@fE*wD>?!SwTKPT6;je$A5oi$+CSpu`$zCXd@F8owxwEG zhREY(G68_M&C9G;bhpjIm$2mM@*$CcM4m3TmnisA!toe0V|4N`UcCVxJ{5M#Sq z=J@Vxc*u!}I_|__MT07E@PPR0!*{WboFgaP)W-MlTiU>)b9tEzn1N_fyZJ-%NaDlk zkx)4!L9@!ks2GOt=dRO1RZQJKo5#~IuT;jcr#paP%MC~GmAPeSEe(-K{Fv@Lu^z2% z_=6G$%icbIz(4nEU`m^@L#-U#BuV)&LFxYY&=oE-ii8gZ1i2g6uz0a+lr(<&hEw)6v$@>+Z}6pj(2<^bi%9rs!%H&v#b^`md_48V7uWvtAHr% z1^y^sWxnYl;|cc~qYqB!aN2=5o_LQLb|hfdpii^IAFVl#WmxQ^yxu&_aTns`V3t2{ z@GkcU;!F#NyVFNM?ni%E2E9nlbf&E7%SW-=?T&fG5|7z9A&1_<=j?LVQ$^U<=SDud zMPHKo??=&L+{@`$`6@cgtKb)3x@!iH1lo>64X#0i3bgJyIn&4CgbFWj!?Qr6{xAd0 zMTg^D+$Sj~`ji2ex@I@Pm|)Kg4__%T+6(*JH;6NFj5Pu3u&{j#YTCShHBd_@Nb*~s zZ2mFeoqf;AfM!$Q&CUMZCu0NLE#;oU-z*h*fcf5JB!Sj2mB6VnOXgTJ9I${jBhzHu zsIFa{w*WM*(xISn!JBNMLz85Vr98f)XSlriTEhnb*E3U}a$ItfcfQWcZfsJ3<5On< zcHn?S2WC4i4&xa7M>EyzCq=`Ufyp7ALt-&_A5+hiLrx@_8%8rp1b|D`8gb*EOBVkt zJ~i&-qhQXTy8RRN8Pl^@#?q05-Lff{34_IbBj3Q;@+XBo&~Z0(|=inY0Iq^9(T0$oi9$0JH{Y^ zvOn`L*`L&FIOKvpu!Vv{tIj<+nzgR5*Cl&)a-18_Jqc!?$G})W2e4dcn0r!81y4tTeP;)fPDPiSLP63kKl z{J8wPqibUB(=mQLUCd9p8}Fj8vG2)6PbdNHbGVzp$l+aV>!I3f+HNq{?Zlm;{AZXa zdP_$+mQqiqJA8lokvRU0uRZ>3UrEiUBgMe~iRXAG&ehmWL;rQ$`={LN?3S>8jHT^- zUYg06yUnR|G99L?^XqAaj$i?KWIR!X1Q`l?;DmuNb$NE2&tWQx;>YM$#7iA;yDRj4 zz=ltfiQpe|{z`0mn_PS94v|#{2rg&&8&=4fh0zdw+`B#|Tmn<_PAcVp&o#d^B95zl z&Gd5%9Gudets2(3IS+3)YvXqilC*`8}OCopqU(p1TGL+MB1CNOLt~<~F zVzl%VU;c9QOVi_l88Z#E@P0m?A7NO7^;=S2FMhn$S!?#{lW+EZaQCRk+c=krU1Xyk z*ws5X+6B&E1M{C{HYL@qpQ>j$eYoEBUtjB-0)3+J$xr-%EH_ty3P!l$ zvq|vwy~*iKvV7`e`DPp|2Jy0PG#%0rQE8}u4~iCqMnp`%crR2hBXNa42J}j3n4~@6k1n!r-W8 zz$xJJ?%nJB{?p=aKvul_5n;ph=L(ztI>2nY%`+x+1AEEd0O(G=fPJvo^#6TY zq0`Na*SUYfrWXb5LsZhtflf@JjdEWtfSbKg{OJ0;U1U3UJ@=Eus?PDnj=N~V&j zqV(|2_T*K~^s)AXBQ`Ik$v$|ywVn4y#ruy ztbD%DCFfuoX6L!H6aiOK)`i6&JemwzVxZ1GfhMrU9zneFrye*D?hl%>=A2XT?!Dal>GyJK5!}`I z_a~Z9%35bmjL4wFXXCA`H2+kH+Bslh6Hc&kcc4WF>S2F!GyiaCnzP2zyO0maM9I#> zyk-mzgl5R+1p81`W}3hF2tjk0OVr^(T?`7k7QqB_!7-cAay@`NT#cK&qyV_wdme?! zHZc+ek})pjjichNC&xQ>zZb;fU|a}+T?-_%1v>VC4o4rL{Hu^ceD+Zf?t~ouCus^b z&fwzmx{sl^*PZoq^|s+Yl+C70gpk6$n?ovs+t}pZR6)w{L5$MvbsP=oJI%r7CTqQC zcY1TXjCP|{WH^_SiTe^#Ps%JPxu@s0J1rxdLr6Hy{!?*|D8h~ZfOQ&=5|8A6oIxz8 z`zN7Pc@f8$s^5QUxX0#n!*%7xFf{*^GqMy19kkO(`u1@_Af69LLQG)xS}kmU|h5CO9fG9-1qLkwyA ziKaa@b~}i-9oVbX4`MoaW46Kdh*%twa5w2&fh|cvGJPlL(<(?L?Z}6w^&epy3Zv{a z1E#xK0O3conV}w98!a*lnRU zG1;@y)9gnXbf%{Xptl0=tszVaEIx^VQ~iUkL*D|&Br6vNww{oVY(6N9O&y7{g4?Cp zbv8l1v$wcMa1QA9)vzvqN+x+17(+cD2V}FJ_A5!VDvCpE=x{(KmLu3x1m-~h5CQi* zs<{KR;HOpIisDCIU!Q4izO}%NBp_l$aNx$%9|K(Ss>G?F;%)8=#UVetUU$UQG+*e9 zdl}gMTj_!CQpGCRki@)8MWV zM!IpNY@k+-aleEYMqqYy+jKU&ZG;prR(u6dNe&-Bt^v*Z;JK2VP(VvxYpB>@d|Z*^ z(+CyrW16@eh{2DniWM3IifD^D!qvo(f@s}J%Zq@1vXvGzcZ+erq$Y4iBlDGS-ElO) zLY$Zg$mlU_Re=_O6&@C0o@WGbFtN7$p~y@KroCq{&#mMD8vJr}J|mJVjN=)CZ^MVe z6^BYjjEy7Uk_Ane)AR@`M?in`2zY1J7ctN$Bd8p~>}5v4#+8dlfY-+n1QLQgbtiQl zvVPCtwW^%U&U;$f;tDZGV*pN=V19;oN`i9+N&GhM2U3$_ ztya0|@5aK46l-DUkjJJW7bS*h=?7X;&J_@`?$?P(T_i`6)y`I~BgnUg_u6287 zDiQhT2>AZPdbOf-pHmj4dvtik7s!j@2hrCdHD}98=5e_2XZ6JJ@ku~gm&foi2FErg z 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 = /** * @internal */ -export const TreeSitterTokenizationRegistry: ITokenizationRegistry = new TokenizationRegistryImpl(); +export const TreeSitterTokenizationRegistry: ITokenizationRegistry = new TokenizationRegistryImpl(); /** * @internal diff --git a/src/vs/editor/common/model/tokenizationTextModelPart.ts b/src/vs/editor/common/model/tokenizationTextModelPart.ts index ff79dd9eb8e65..0a99c9dd5af48 100644 --- a/src/vs/editor/common/model/tokenizationTextModelPart.ts +++ b/src/vs/editor/common/model/tokenizationTextModelPart.ts @@ -89,7 +89,7 @@ export class TokenizationTextModelPart extends TextModelPart implements ITokeniz private createPreferredTokenProvider() { const preferTreeSitter: string[] = this._configurationService.getValue(TOKENIZATION_PROVIDER_SETTING) ?? []; - if (preferTreeSitter.includes(this._languageId) && TreeSitterTokenizationRegistry.get(this._languageId)) { + if ((preferTreeSitter.includes(this._languageId) && TreeSitterTokenizationRegistry.get(this._languageId))) { if (this.treeSitterTokens) { this.treeSitterTokens.resetTokenization(true); } else { diff --git a/src/vs/workbench/services/treeSitter/browser/treeSitterTokenizationFeature.contribution.ts b/src/vs/workbench/services/treeSitter/browser/treeSitterTokenizationFeature.contribution.ts new file mode 100644 index 0000000000000..9d4ae5fdf8f24 --- /dev/null +++ b/src/vs/workbench/services/treeSitter/browser/treeSitterTokenizationFeature.contribution.ts @@ -0,0 +1,25 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { registerSingleton, InstantiationType } from 'vs/platform/instantiation/common/extensions'; +import { IWorkbenchContribution, WorkbenchPhase, registerWorkbenchContribution2 } from 'vs/workbench/common/contributions'; +import { ITreeSitterTokenizationService } from 'vs/workbench/services/treeSitter/browser/treeSitterTokenizationFeature'; +import { TreeSitterTokenizationService } from 'vs/workbench/services/treeSitter/browser/treeSitterTokenizationFeatureImpl'; + +/** + * Makes sure the ITreeSitterTokenizationService is instantiated + */ +class TreeSitterTokenizationInstantiator implements IWorkbenchContribution { + + static readonly ID = 'workbench.contrib.treeSitterTokenizationInstantiator'; + + constructor( + @ITreeSitterTokenizationService _treeSitterTokenizationService: ITreeSitterTokenizationService + ) { } +} + +registerSingleton(ITreeSitterTokenizationService, TreeSitterTokenizationService, InstantiationType.Eager); + +registerWorkbenchContribution2(TreeSitterTokenizationInstantiator.ID, TreeSitterTokenizationInstantiator, WorkbenchPhase.BlockRestore); diff --git a/src/vs/workbench/services/treeSitter/browser/treeSitterTokenizationFeature.ts b/src/vs/workbench/services/treeSitter/browser/treeSitterTokenizationFeature.ts new file mode 100644 index 0000000000000..31fb1c5df2f66 --- /dev/null +++ b/src/vs/workbench/services/treeSitter/browser/treeSitterTokenizationFeature.ts @@ -0,0 +1,12 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; + +export const ITreeSitterTokenizationService = createDecorator('treeSitterTokenizationService'); + +export interface ITreeSitterTokenizationService { + readonly _serviceBrand: undefined; +} diff --git a/src/vs/workbench/services/treeSitter/browser/treeSitterTokenizationFeatureImpl.ts b/src/vs/workbench/services/treeSitter/browser/treeSitterTokenizationFeatureImpl.ts new file mode 100644 index 0000000000000..a7ec715f089e1 --- /dev/null +++ b/src/vs/workbench/services/treeSitter/browser/treeSitterTokenizationFeatureImpl.ts @@ -0,0 +1,20 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { TreeSitterTokenizationRegistry } from 'vs/editor/common/languages'; +import { ITreeSitterTokenizationService } from 'vs/workbench/services/treeSitter/browser/treeSitterTokenizationFeature'; + +export class TreeSitterTokenizationService implements ITreeSitterTokenizationService { + readonly _serviceBrand: undefined; + + constructor() { + // Eventually, this should actually use an extension point to add tree sitter grammars, but for now they are hard coded in core + this._addGrammar('placeholder-language'); + } + + private _addGrammar(languageId: string) { + TreeSitterTokenizationRegistry.register(languageId, {}); + } +} diff --git a/src/vs/workbench/workbench.common.main.ts b/src/vs/workbench/workbench.common.main.ts index a4e3fa69d6ec5..52ad0ead54781 100644 --- a/src/vs/workbench/workbench.common.main.ts +++ b/src/vs/workbench/workbench.common.main.ts @@ -115,6 +115,7 @@ import 'vs/editor/common/services/languageFeaturesService'; import 'vs/editor/common/services/semanticTokensStylingService'; import 'vs/editor/common/services/treeViewsDndService'; import 'vs/workbench/services/textMate/browser/textMateTokenizationFeature.contribution'; +import 'vs/workbench/services/treeSitter/browser/treeSitterTokenizationFeature.contribution'; import 'vs/workbench/services/userActivity/common/userActivityService'; import 'vs/workbench/services/userActivity/browser/userActivityBrowser'; import 'vs/workbench/services/editor/browser/editorPaneService'; From 1ee4fe2747ac6c78581ee6a0ae7ba58c34d0d828 Mon Sep 17 00:00:00 2001 From: Alex Ross Date: Tue, 21 May 2024 18:06:59 +0200 Subject: [PATCH 03/37] Very naive tree-sitter syntax highlighting for html, with a layer breaker --- build/filters.js | 5 +- package.json | 2 + .../tree-sitter-html/highlights.scm | 15 ++ .../tree-sitter-html/tree-sitter-html.wasm | Bin 0 -> 17906 bytes .../web-tree-sitter/tree-sitter-web.d.ts | 7 +- .../{tree-sitter.js => tree-sitter-web.js} | 18 +- .../treeSitterTokenizationFeatureImpl.ts | 33 +++ src/vs/editor/common/languages.ts | 6 +- src/vs/editor/common/model/textModel.ts | 14 +- .../common/model/tokenizationTextModelPart.ts | 8 +- .../editor/common/model/treeSitterTokens.ts | 216 +++++++++++++++++- src/vs/editor/common/services/modelService.ts | 11 +- .../treeSitterTokenizationFeature.ts | 1 + .../browser/peek/referencesWidget.ts | 9 +- .../browser/documentSemanticTokens.test.ts | 5 + .../browser/services/testTreeSitterService.ts | 15 ++ .../test/browser/workbenchTestServices.ts | 190 +++++++++++++++ src/vs/platform/theme/common/themeService.ts | 14 ++ .../theme/test/common/testThemeService.ts | 7 +- .../mainThreadDocumentsAndEditors.test.ts | 5 + .../test/browser/mainThreadEditors.test.ts | 7 +- .../bulkEdit/browser/preview/bulkEditTree.ts | 10 +- .../debug/test/browser/mockDebugModel.ts | 2 +- .../files/test/browser/editorAutoSave.test.ts | 3 +- .../files/test/browser/explorerModel.test.ts | 3 +- .../files/test/browser/explorerView.test.ts | 2 +- .../browser/textFileEditorTracker.test.ts | 3 +- .../gettingStartedMarkdownRenderer.test.ts | 2 +- .../test/browser/extensionService.test.ts | 3 +- .../services/model/common/modelService.ts | 8 +- .../textMateTokenizationFeatureImpl.ts | 3 +- .../services/themes/common/colorThemeData.ts | 6 +- .../themes/common/themeCompatibility.ts | 3 +- .../themes/common/workbenchThemeService.ts | 14 +- ...eSitterTokenizationFeature.contribution.ts | 4 +- .../treeSitterTokenizationFeatureImpl.ts | 20 -- .../workingCopyBackupTracker.test.ts | 3 +- .../workingCopyHistoryTracker.test.ts | 3 +- .../test/browser/workbenchTestServices.ts | 173 +------------- .../electron-sandbox/workbenchTestServices.ts | 3 +- yarn.lock | 23 ++ 41 files changed, 622 insertions(+), 257 deletions(-) create mode 100644 src/vs/base/common/treeSitterLanguages/tree-sitter-html/highlights.scm create mode 100644 src/vs/base/common/treeSitterLanguages/tree-sitter-html/tree-sitter-html.wasm rename src/vs/base/common/web-tree-sitter/{tree-sitter.js => tree-sitter-web.js} (99%) create mode 100644 src/vs/editor/browser/services/treeSitter/treeSitterTokenizationFeatureImpl.ts rename src/vs/{workbench/services/treeSitter/browser => editor/common/services}/treeSitterTokenizationFeature.ts (95%) create mode 100644 src/vs/editor/test/browser/services/testTreeSitterService.ts create mode 100644 src/vs/platform/files/test/browser/workbenchTestServices.ts delete mode 100644 src/vs/workbench/services/treeSitter/browser/treeSitterTokenizationFeatureImpl.ts diff --git a/build/filters.js b/build/filters.js index 27cc35196e446..af870dd183c48 100644 --- a/build/filters.js +++ b/build/filters.js @@ -75,7 +75,8 @@ module.exports.indentationFilter = [ '!src/vs/base/browser/dompurify/*', '!src/vs/base/common/marked/marked.js', '!src/vs/base/common/semver/semver.js', - '!src/vs/base/common/web-tree-sitter/tree-sitter.js', + '!src/vs/base/common/web-tree-sitter/tree-sitter-web.js', + '!src/vs/base/common/treeSitterLanguages/*/highlights.scm', '!src/vs/base/node/terminateProcess.sh', '!src/vs/base/node/cpuUsage.sh', '!test/unit/assert.js', @@ -173,7 +174,7 @@ module.exports.copyrightFilter = [ '!extensions/typescript-language-features/node-maintainer/**', '!extensions/html-language-features/server/src/modes/typescript/*', '!extensions/*/server/bin/*', - '!src/vs/base/common/web-tree-sitter/tree-sitter.js', + '!src/vs/base/common/web-tree-sitter/tree-sitter-web.js', '!src/vs/editor/test/node/classification/typescript-test.ts', ]; diff --git a/package.json b/package.json index 36a60bee91ebd..6b46533ca76a2 100644 --- a/package.json +++ b/package.json @@ -205,6 +205,8 @@ "source-map": "0.6.1", "source-map-support": "^0.3.2", "style-loader": "^3.3.2", + "tree-sitter-cli": "^0.22.6", + "tree-sitter-html": "^0.20.3", "ts-loader": "^9.4.2", "ts-node": "^10.9.1", "tsec": "0.2.7", diff --git a/src/vs/base/common/treeSitterLanguages/tree-sitter-html/highlights.scm b/src/vs/base/common/treeSitterLanguages/tree-sitter-html/highlights.scm new file mode 100644 index 0000000000000..2107ae1cbc1ee --- /dev/null +++ b/src/vs/base/common/treeSitterLanguages/tree-sitter-html/highlights.scm @@ -0,0 +1,15 @@ +(tag_name) @entity.name.tag +(attribute_name) @entity.other.attribute-name +(attribute_value) @string +"\"" @string +(comment) @comment + +"=" @punctuation.separator.key-value + +[ + "<" + ">" + "" +] @meta.tag diff --git a/src/vs/base/common/treeSitterLanguages/tree-sitter-html/tree-sitter-html.wasm b/src/vs/base/common/treeSitterLanguages/tree-sitter-html/tree-sitter-html.wasm new file mode 100644 index 0000000000000000000000000000000000000000..8c024d45b6874494ef32a381e5f571d910d7088d GIT binary patch literal 17906 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 literal 0 HcmV?d00001 diff --git a/src/vs/base/common/web-tree-sitter/tree-sitter-web.d.ts b/src/vs/base/common/web-tree-sitter/tree-sitter-web.d.ts index dc984bf1da6c9..45967662482f0 100644 --- a/src/vs/base/common/web-tree-sitter/tree-sitter-web.d.ts +++ b/src/vs/base/common/web-tree-sitter/tree-sitter-web.d.ts @@ -1,5 +1,4 @@ -declare module 'web-tree-sitter' { - class Parser { +export class Parser { /** * * @param moduleOptions Optional emscripten module-object, see https://emscripten.org/docs/api_reference/module.html @@ -17,7 +16,7 @@ declare module 'web-tree-sitter' { setLogger(logFunc?: Parser.Logger | false | null): void; } - namespace Parser { +export namespace Parser { export type Options = { includedRanges?: Range[]; }; @@ -238,5 +237,3 @@ declare module 'web-tree-sitter' { } } - export = Parser -} diff --git a/src/vs/base/common/web-tree-sitter/tree-sitter.js b/src/vs/base/common/web-tree-sitter/tree-sitter-web.js similarity index 99% rename from src/vs/base/common/web-tree-sitter/tree-sitter.js rename to src/vs/base/common/web-tree-sitter/tree-sitter-web.js index d4672b2f6a8cc..643a79a701c91 100644 --- a/src/vs/base/common/web-tree-sitter/tree-sitter.js +++ b/src/vs/base/common/web-tree-sitter/tree-sitter-web.js @@ -9,15 +9,13 @@ /* eslint-disable header/header */ (function (global, factory) { - typeof define === "function" && define.amd - ? define(["exports"], factory) - : typeof exports === "object" && typeof module !== "undefined" - ? factory(exports) - : ((global = - typeof globalThis !== "undefined" ? globalThis : global || self), - factory((global.Parser = {}))); -})(this, function () { - var Module = void 0 !== Module ? Module : {}, + typeof define === 'function' && define.amd ? define(['exports'], factory) : + typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : + (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.Parser = {})); +})(this, (function () { + + var Module = void 0 !== Module ? Module : {}; + TreeSitter = (function () { var initPromise, document = @@ -4028,4 +4026,4 @@ "object" == typeof exports && (module.exports = TreeSitter); return { Parser: TreeSitter }; -}); +})); diff --git a/src/vs/editor/browser/services/treeSitter/treeSitterTokenizationFeatureImpl.ts b/src/vs/editor/browser/services/treeSitter/treeSitterTokenizationFeatureImpl.ts new file mode 100644 index 0000000000000..9b24f062344a5 --- /dev/null +++ b/src/vs/editor/browser/services/treeSitter/treeSitterTokenizationFeatureImpl.ts @@ -0,0 +1,33 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { TreeSitterTokenizationRegistry } from 'vs/editor/common/languages'; +import { Parser } from 'vs/base/common/web-tree-sitter/tree-sitter-web'; +import { AppResourcePath, FileAccess } from 'vs/base/common/network'; +import { ITreeSitterTokenizationService } from 'vs/editor/common/services/treeSitterTokenizationFeature'; + +export class TreeSitterTokenizationService implements ITreeSitterTokenizationService { + readonly _serviceBrand: undefined; + private _init: Promise; + + constructor() { + this._init = Parser.init({ + locateFile(_file: string, _folder: string) { + const wasmPath: AppResourcePath = `vs/base/common/web-tree-sitter/tree-sitter.wasm`; + return FileAccess.asBrowserUri(wasmPath).toString(true); + } + }); + // Eventually, this should actually use an extension point to add tree sitter grammars, but for now they are hard coded in core + this._addGrammar('html', 'tree-sitter-html'); + } + + public initTreeSitter(): Promise { + return this._init; + } + + private _addGrammar(languageId: string, grammarName: string) { + TreeSitterTokenizationRegistry.register(languageId, { name: grammarName }); + } +} diff --git a/src/vs/editor/common/languages.ts b/src/vs/editor/common/languages.ts index ea7c90780a496..0061e9c869c2b 100644 --- a/src/vs/editor/common/languages.ts +++ b/src/vs/editor/common/languages.ts @@ -86,8 +86,8 @@ export class EncodedTokenizationResult { * An intermediate interface for scaffolding the new tree sitter tokenization support. Not final. * @internal */ -export interface IPlaceholderTreeSitterTokenizationSupport { - +export interface ITreeSitterTokenizationSupport { + name: string; } /** @@ -2192,7 +2192,7 @@ export const TokenizationRegistry: ITokenizationRegistry = /** * @internal */ -export const TreeSitterTokenizationRegistry: ITokenizationRegistry = new TokenizationRegistryImpl(); +export const TreeSitterTokenizationRegistry: ITokenizationRegistry = new TokenizationRegistryImpl(); /** * @internal diff --git a/src/vs/editor/common/model/textModel.ts b/src/vs/editor/common/model/textModel.ts index 11e61c391ac08..40d474eeb6338 100644 --- a/src/vs/editor/common/model/textModel.ts +++ b/src/vs/editor/common/model/textModel.ts @@ -39,12 +39,14 @@ import { PieceTreeTextBuffer } from 'vs/editor/common/model/pieceTreeTextBuffer/ import { PieceTreeTextBufferBuilder } from 'vs/editor/common/model/pieceTreeTextBuffer/pieceTreeTextBufferBuilder'; import { SearchParams, TextModelSearch } from 'vs/editor/common/model/textModelSearch'; import { TokenizationTextModelPart } from 'vs/editor/common/model/tokenizationTextModelPart'; +import { ITreeSitterTokenizationService } from 'vs/editor/common/services/treeSitterTokenizationFeature'; import { IBracketPairsTextModelPart } from 'vs/editor/common/textModelBracketPairs'; import { IModelContentChangedEvent, IModelDecorationsChangedEvent, IModelOptionsChangedEvent, InternalModelContentChangeEvent, LineInjectedText, ModelInjectedTextChangedEvent, ModelRawChange, ModelRawContentChangedEvent, ModelRawEOLChanged, ModelRawFlush, ModelRawLineChanged, ModelRawLinesDeleted, ModelRawLinesInserted } from 'vs/editor/common/textModelEvents'; import { IGuidesTextModelPart } from 'vs/editor/common/textModelGuides'; import { ITokenizationTextModelPart } from 'vs/editor/common/tokenizationTextModelPart'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; -import { IColorTheme } from 'vs/platform/theme/common/themeService'; +import { IFileService } from 'vs/platform/files/common/files'; +import { IColorTheme, IThemeService } from 'vs/platform/theme/common/themeService'; import { IUndoRedoService, ResourceEditStackSnapshot, UndoRedoGroup } from 'vs/platform/undoRedo/common/undoRedo'; export function createTextBufferFactory(text: string): model.ITextBufferFactory { @@ -300,7 +302,10 @@ export class TextModel extends Disposable implements model.ITextModel, IDecorati @IUndoRedoService private readonly _undoRedoService: IUndoRedoService, @ILanguageService private readonly _languageService: ILanguageService, @ILanguageConfigurationService private readonly _languageConfigurationService: ILanguageConfigurationService, - @IConfigurationService configurationService: IConfigurationService + @IConfigurationService configurationService: IConfigurationService, + @IFileService fileService: IFileService, + @IThemeService themeService: IThemeService, + @ITreeSitterTokenizationService treeSitterService: ITreeSitterTokenizationService, ) { super(); @@ -336,7 +341,10 @@ export class TextModel extends Disposable implements model.ITextModel, IDecorati this._bracketPairs, languageId, this._attachedViews, - configurationService + configurationService, + fileService, + themeService, + treeSitterService ); const bufferLineCount = this._buffer.getLineCount(); diff --git a/src/vs/editor/common/model/tokenizationTextModelPart.ts b/src/vs/editor/common/model/tokenizationTextModelPart.ts index 0a99c9dd5af48..eda1fbb2ffbf5 100644 --- a/src/vs/editor/common/model/tokenizationTextModelPart.ts +++ b/src/vs/editor/common/model/tokenizationTextModelPart.ts @@ -24,6 +24,7 @@ import { AttachedViews, IAttachedViewState, TextModel } from 'vs/editor/common/m import { TextModelPart } from 'vs/editor/common/model/textModelPart'; import { DefaultBackgroundTokenizer, TokenizerWithStateStoreAndTextModel, TrackingTokenizationStateStore } from 'vs/editor/common/model/textModelTokens'; import { TreeSitterTokens } from 'vs/editor/common/model/treeSitterTokens'; +import { ITreeSitterTokenizationService } from 'vs/editor/common/services/treeSitterTokenizationFeature'; import { IModelContentChangedEvent, IModelLanguageChangedEvent, IModelLanguageConfigurationChangedEvent, IModelTokensChangedEvent } from 'vs/editor/common/textModelEvents'; import { BackgroundTokenizationState, ITokenizationTextModelPart } from 'vs/editor/common/tokenizationTextModelPart'; import { ContiguousMultilineTokens } from 'vs/editor/common/tokens/contiguousMultilineTokens'; @@ -33,6 +34,8 @@ import { LineTokens } from 'vs/editor/common/tokens/lineTokens'; import { SparseMultilineTokens } from 'vs/editor/common/tokens/sparseMultilineTokens'; import { SparseTokensStore } from 'vs/editor/common/tokens/sparseTokensStore'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; +import { IFileService } from 'vs/platform/files/common/files'; +import { IThemeService } from 'vs/platform/theme/common/themeService'; // Setting value will be an array of language IDs that will prefer tree sitter tokenization over textmate when they both exist. const TOKENIZATION_PROVIDER_SETTING = 'editor.experimental.preferTreeSitter'; @@ -60,6 +63,9 @@ export class TokenizationTextModelPart extends TextModelPart implements ITokeniz private _languageId: string, private readonly _attachedViews: AttachedViews, private readonly _configurationService: IConfigurationService, + private readonly _fileService: IFileService, + private readonly _themeService: IThemeService, + private readonly _treeSitterService: ITreeSitterTokenizationService, ) { super(); @@ -84,7 +90,7 @@ export class TokenizationTextModelPart extends TextModelPart implements ITokeniz } private createTreeSitterTokens() { - this.treeSitterTokens = this._register(new TreeSitterTokens(this._languageService.languageIdCodec)); + this.treeSitterTokens = this._register(new TreeSitterTokens(this._fileService, this._themeService, this._treeSitterService, this._languageService.languageIdCodec, this._textModel, () => this._languageId)); } private createPreferredTokenProvider() { diff --git a/src/vs/editor/common/model/treeSitterTokens.ts b/src/vs/editor/common/model/treeSitterTokens.ts index ceda0410c47e4..c76997614215b 100644 --- a/src/vs/editor/common/model/treeSitterTokens.ts +++ b/src/vs/editor/common/model/treeSitterTokens.ts @@ -4,23 +4,223 @@ *--------------------------------------------------------------------------------------------*/ import { Disposable } from 'vs/base/common/lifecycle'; -import { ILanguageIdCodec } from 'vs/editor/common/languages'; +import { AppResourcePath, FileAccess } from 'vs/base/common/network'; +import { ILanguageIdCodec, TreeSitterTokenizationRegistry } from 'vs/editor/common/languages'; import { LineTokens } from 'vs/editor/common/tokens/lineTokens'; +import { IFileService } from 'vs/platform/files/common/files'; +import { Parser } from 'vs/base/common/web-tree-sitter/tree-sitter-web'; +import { IThemeService } from 'vs/platform/theme/common/themeService'; +import { FontStyle, MetadataConsts } from 'vs/editor/common/encodedTokenAttributes'; +import { TokenStyle } from 'vs/platform/theme/common/tokenClassificationRegistry'; +import { ColorThemeData } from 'vs/workbench/services/themes/common/colorThemeData'; +import { TextModel } from 'vs/editor/common/model/textModel'; +import { ITreeSitterTokenizationService } from 'vs/editor/common/services/treeSitterTokenizationFeature'; -/** - * Placeholder class, will be replaced with some real implementation. - */ export class TreeSitterTokens extends Disposable { - constructor(private readonly languageIdCoded: ILanguageIdCodec) { + private _colorThemeData: ColorThemeData; + private _parser: Parser | undefined; + private _language: Parser.Language | undefined; + private _queries: string | undefined; + private _tokens: TextModelTokens | undefined; + private _lastLanguageId: string | undefined; + + constructor(private readonly _fileService: IFileService, + private readonly _themeService: IThemeService, + private readonly _treeSitterService: ITreeSitterTokenizationService, + private readonly _languageIdCoded: ILanguageIdCodec, + private readonly _textModel: TextModel, + private readonly _languageId: () => string) { super(); + // TODO @alexr00 respond to language changes + this._initialize(); + + // TODO @alexr00 remove the cast + this._colorThemeData = this._themeService.getColorTheme() as ColorThemeData; + // TODO @alexr00 respond to theme changes + } + + private async _initialize() { + const parser = await this._getParser(); + const newLanguage = this._languageId(); + const [language, queries] = await Promise.all([this._getLanguage(newLanguage), this._getQueries(newLanguage)]); + parser.setLanguage(language); + if (!this._tokens || this._lastLanguageId !== newLanguage) { + this._tokens?.dispose(); + this._tokens = new TextModelTokens(this._textModel, parser, queries, language, this._colorThemeData); + } + + } + + private async _getParser(): Promise { + if (!this._parser) { + await this._treeSitterService.initTreeSitter(); + this._parser = new Parser(); + } + return this._parser; + } + + private async _getLanguage(newLanguage: string): Promise { + if (!this._language || this._lastLanguageId !== newLanguage) { + this._language = await this._fetchLanguage(); + } + return this._language; } + + private async _fetchLanguage() { + const grammarName = TreeSitterTokenizationRegistry.get(this._languageId()); + const wasmPath: AppResourcePath = `vs/base/common/treeSitterLanguages/${grammarName?.name}/${grammarName?.name}.wasm`; + const languageFile = await (this._fileService.readFile(FileAccess.asFileUri(wasmPath))); + return Parser.Language.load(languageFile.value.buffer); + } + + private async _getQueries(newLanguage: string): Promise { + if (!this._queries || this._lastLanguageId !== newLanguage) { + this._queries = await this._fetchQueries(newLanguage); + } + return this._queries; + } + + private async _fetchQueries(newLanguage: string): Promise { + const grammarName = TreeSitterTokenizationRegistry.get(newLanguage); + const scmPath: AppResourcePath = `vs/base/common/treeSitterLanguages/${grammarName?.name}/highlights.scm`; + const query = await this._fileService.readFile(FileAccess.asFileUri(scmPath)); + return query.value.toString(); + } + + public getLineTokens(lineNumber: number): LineTokens { - // placeholder for now - return LineTokens.createEmpty('', this.languageIdCoded); + if (this._tokens) { + return new LineTokens(this._tokens.lineTokens(lineNumber), this._textModel.getLineContent(lineNumber), this._languageIdCoded); + } + return LineTokens.createEmpty('', this._languageIdCoded); } public resetTokenization(fireTokenChangeEvent: boolean = true): void { - // placeholder for now + // TODO @alexr00 determine if needed + } + +} + + +/** + * For handling the text model changes. + */ +class TextModelTokens extends Disposable { + private _tree: Parser.Tree | undefined; + private _query: Parser.Query | undefined; + + constructor(private readonly _textModel: TextModel, + private readonly _parser: Parser, + private readonly _queries: string, + private readonly _language: Parser.Language, + private readonly _colorThemeData: ColorThemeData) { + super(); + this._register(this._textModel.onDidChangeContent(() => this._onDidChangeContent())); + } + + private _onDidChangeContent() { + // TODO @alexr00 this is an extremely naive implementation and should absolutely not be pushed to main, it's just a placeholder. + this._tree?.delete(); + this._tree = undefined; + } + + private _ensureTree() { + if (!this._tree) { + this._tree = this._parser.parse(this._textModel.getValue()); + } + return this._tree; } + private _ensureQuery() { + if (!this._query) { + this._query = this._language.query(this._queries); + } + return this._query; + } + + /** + * Gets the tokens for a given line. + * Each token takes 2 elements in the array. The first element is the offset of the end of the token *in the line, not in the document*, and the second element is the metadata. + * + * @param lineNumber + * @returns + */ + public lineTokens(lineNumber: number): Uint32Array { + const tree = this._ensureTree(); + const query = this._ensureQuery(); + const lineLength = this._textModel.getLineMaxColumn(lineNumber); + const captures = query.captures(tree.rootNode, { startPosition: { row: lineNumber - 1, column: 0 }, endPosition: { row: lineNumber - 1, column: lineLength - 1 } }); + if (captures.length === 0 && lineLength > 0) { + // No captures, but we always want to return at least one token for each line + return new Uint32Array([lineLength, 0]); + } + + let tokens: Uint32Array = new Uint32Array(captures.length * 2); + let tokenIndex = 0; + for (let captureIndex = 0; captureIndex < captures.length; captureIndex++) { + const capture = captures[captureIndex]; + const metadata = this.findMetadata(capture.name); + const lineStartOffset = this._textModel.getOffsetAt({ lineNumber: lineNumber, column: 0 }); + const offset = this._textModel.getOffsetAt({ lineNumber: capture.node.endPosition.row + 1, column: capture.node.endPosition.column + 1 }) - lineStartOffset; + // Not every character will get captured, so we need to make sure that our current capture doesn't bleed toward the start of the line and cover characters that it doesn't apply to. + // We do this by creating a new token in the array if the previous token ends before the current token starts. + if (captureIndex > 0) { + const previousTokenEnd = tokens[(tokenIndex - 1) * 2]; + const currentTokenLength = capture.node.text.length; + const intermediateTokenOffset = offset - currentTokenLength; + if (previousTokenEnd < intermediateTokenOffset) { + tokens[tokenIndex * 2] = intermediateTokenOffset; + tokens[tokenIndex * 2 + 1] = 0; + tokenIndex++; + const newTokens = new Uint32Array(tokens.length + 2); + newTokens.set(tokens); + tokens = newTokens; + } + } + tokens[tokenIndex * 2] = offset; + tokens[tokenIndex * 2 + 1] = metadata; + tokenIndex++; + } + return tokens; + } + + private findMetadata(captureName: string): number { + const tokenStyle: TokenStyle | undefined = this._colorThemeData.resolveScopes([[captureName]]); + if (!tokenStyle) { + return 0; + } + + let metadata = 0; + if (typeof tokenStyle.italic !== 'undefined') { + const italicBit = (tokenStyle.italic ? FontStyle.Italic : 0); + metadata |= italicBit | MetadataConsts.ITALIC_MASK; + } + if (typeof tokenStyle.bold !== 'undefined') { + const boldBit = (tokenStyle.bold ? FontStyle.Bold : 0); + metadata |= boldBit | MetadataConsts.BOLD_MASK; + } + if (typeof tokenStyle.underline !== 'undefined') { + const underlineBit = (tokenStyle.underline ? FontStyle.Underline : 0); + metadata |= underlineBit | MetadataConsts.UNDERLINE_MASK; + } + if (typeof tokenStyle.strikethrough !== 'undefined') { + const strikethroughBit = (tokenStyle.strikethrough ? FontStyle.Strikethrough : 0); + metadata |= strikethroughBit | MetadataConsts.STRIKETHROUGH_MASK; + } + if (tokenStyle.foreground) { + const tokenStyleForeground = this._colorThemeData.getTokenColorIndex().get(tokenStyle?.foreground); + const foregroundBits = tokenStyleForeground << MetadataConsts.FOREGROUND_OFFSET; + metadata |= foregroundBits; + } + + return metadata; + } + + override dispose() { + super.dispose(); + this._tree?.delete(); + this._query?.delete(); + this._tree = undefined; + this._query = undefined; + } } diff --git a/src/vs/editor/common/services/modelService.ts b/src/vs/editor/common/services/modelService.ts index 9a6cb92ed2cf5..c7834669c8f67 100644 --- a/src/vs/editor/common/services/modelService.ts +++ b/src/vs/editor/common/services/modelService.ts @@ -24,6 +24,9 @@ import { isEditStackElement } from 'vs/editor/common/model/editStack'; import { Schemas } from 'vs/base/common/network'; import { equals } from 'vs/base/common/objects'; import { ILanguageConfigurationService } from 'vs/editor/common/languages/languageConfigurationRegistry'; +import { IFileService } from 'vs/platform/files/common/files'; +import { IThemeService } from 'vs/platform/theme/common/themeService'; +import { ITreeSitterTokenizationService } from 'vs/editor/common/services/treeSitterTokenizationFeature'; function MODEL_ID(resource: URI): string { return resource.toString(); @@ -109,6 +112,9 @@ export class ModelService extends Disposable implements IModelService { @IUndoRedoService private readonly _undoRedoService: IUndoRedoService, @ILanguageService private readonly _languageService: ILanguageService, @ILanguageConfigurationService private readonly _languageConfigurationService: ILanguageConfigurationService, + @IFileService private readonly _fileService: IFileService, + @IThemeService private readonly _themeService: IThemeService, + @ITreeSitterTokenizationService private readonly _treeSitterService: ITreeSitterTokenizationService ) { super(); this._modelCreationOptionsByLanguageAndResource = Object.create(null); @@ -322,7 +328,10 @@ export class ModelService extends Disposable implements IModelService { this._undoRedoService, this._languageService, this._languageConfigurationService, - this._configurationService + this._configurationService, + this._fileService, + this._themeService, + this._treeSitterService ); if (resource && this._disposedModels.has(MODEL_ID(resource))) { const disposedModelData = this._removeDisposedModel(resource)!; diff --git a/src/vs/workbench/services/treeSitter/browser/treeSitterTokenizationFeature.ts b/src/vs/editor/common/services/treeSitterTokenizationFeature.ts similarity index 95% rename from src/vs/workbench/services/treeSitter/browser/treeSitterTokenizationFeature.ts rename to src/vs/editor/common/services/treeSitterTokenizationFeature.ts index 31fb1c5df2f66..d7b612ded72b4 100644 --- a/src/vs/workbench/services/treeSitter/browser/treeSitterTokenizationFeature.ts +++ b/src/vs/editor/common/services/treeSitterTokenizationFeature.ts @@ -9,4 +9,5 @@ export const ITreeSitterTokenizationService = createDecorator; } diff --git a/src/vs/editor/contrib/gotoSymbol/browser/peek/referencesWidget.ts b/src/vs/editor/contrib/gotoSymbol/browser/peek/referencesWidget.ts index 9f1dc67d6d118..a0f7b1b74df42 100644 --- a/src/vs/editor/contrib/gotoSymbol/browser/peek/referencesWidget.ts +++ b/src/vs/editor/contrib/gotoSymbol/browser/peek/referencesWidget.ts @@ -38,6 +38,8 @@ import { IColorTheme, IThemeService } from 'vs/platform/theme/common/themeServic import { IUndoRedoService } from 'vs/platform/undoRedo/common/undoRedo'; import { FileReferences, OneReference, ReferencesModel } from '../referencesModel'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; +import { IFileService } from 'vs/platform/files/common/files'; +import { ITreeSitterTokenizationService } from 'vs/editor/common/services/treeSitterTokenizationFeature'; class DecorationsManager implements IDisposable { @@ -229,7 +231,10 @@ export class ReferenceWidget extends peekView.PeekViewWidget { @IKeybindingService private readonly _keybindingService: IKeybindingService, @ILanguageService private readonly _languageService: ILanguageService, @ILanguageConfigurationService private readonly _languageConfigurationService: ILanguageConfigurationService, - @IConfigurationService private readonly _configurationService: IConfigurationService + @IConfigurationService private readonly _configurationService: IConfigurationService, + @IFileService private readonly _fileService: IFileService, + @IThemeService private readonly _themeService: IThemeService, + @ITreeSitterTokenizationService private readonly _treeSitterService: ITreeSitterTokenizationService, ) { super(editor, { showFrame: false, showArrow: true, isResizeable: true, isAccessible: true, supportOnTitleClick: true }, _instantiationService); @@ -317,7 +322,7 @@ export class ReferenceWidget extends peekView.PeekViewWidget { }; this._preview = this._instantiationService.createInstance(EmbeddedCodeEditorWidget, this._previewContainer, options, {}, this.editor); dom.hide(this._previewContainer); - this._previewNotAvailableMessage = new TextModel(nls.localize('missingPreviewMessage', "no preview available"), PLAINTEXT_LANGUAGE_ID, TextModel.DEFAULT_CREATION_OPTIONS, null, this._undoRedoService, this._languageService, this._languageConfigurationService, this._configurationService); + this._previewNotAvailableMessage = new TextModel(nls.localize('missingPreviewMessage', "no preview available"), PLAINTEXT_LANGUAGE_ID, TextModel.DEFAULT_CREATION_OPTIONS, null, this._undoRedoService, this._languageService, this._languageConfigurationService, this._configurationService, this._fileService, this._themeService, this._treeSitterService); // tree this._treeContainer = dom.append(containerElement, dom.$('div.ref-tree.inline')); diff --git a/src/vs/editor/contrib/semanticTokens/test/browser/documentSemanticTokens.test.ts b/src/vs/editor/contrib/semanticTokens/test/browser/documentSemanticTokens.test.ts index c2d9a57c2026f..bbc71c813062d 100644 --- a/src/vs/editor/contrib/semanticTokens/test/browser/documentSemanticTokens.test.ts +++ b/src/vs/editor/contrib/semanticTokens/test/browser/documentSemanticTokens.test.ts @@ -24,11 +24,13 @@ import { ModelService } from 'vs/editor/common/services/modelService'; import { SemanticTokensStylingService } from 'vs/editor/common/services/semanticTokensStylingService'; import { DocumentSemanticTokensFeature } from 'vs/editor/contrib/semanticTokens/browser/documentSemanticTokens'; import { getDocumentSemanticTokens, isSemanticTokens } from 'vs/editor/contrib/semanticTokens/common/getSemanticTokens'; +import { TestTreeSitterTokenizationService } from 'vs/editor/test/browser/services/testTreeSitterService'; import { TestLanguageConfigurationService } from 'vs/editor/test/common/modes/testLanguageConfigurationService'; import { TestTextResourcePropertiesService } from 'vs/editor/test/common/services/testTextResourcePropertiesService'; import { TestConfigurationService } from 'vs/platform/configuration/test/common/testConfigurationService'; import { TestDialogService } from 'vs/platform/dialogs/test/common/testDialogService'; import { IEnvironmentService } from 'vs/platform/environment/common/environment'; +import { TestFileService } from 'vs/platform/files/test/browser/workbenchTestServices'; import { NullLogService } from 'vs/platform/log/common/log'; import { TestNotificationService } from 'vs/platform/notification/test/common/testNotificationService'; import { ColorScheme } from 'vs/platform/theme/common/theme'; @@ -56,6 +58,9 @@ suite('ModelSemanticColoring', () => { new UndoRedoService(new TestDialogService(), new TestNotificationService()), languageService, new TestLanguageConfigurationService(), + new TestFileService(), + new TestThemeService(), + new TestTreeSitterTokenizationService() )); const envService = new class extends mock() { override isBuilt: boolean = true; diff --git a/src/vs/editor/test/browser/services/testTreeSitterService.ts b/src/vs/editor/test/browser/services/testTreeSitterService.ts new file mode 100644 index 0000000000000..395b68f898a21 --- /dev/null +++ b/src/vs/editor/test/browser/services/testTreeSitterService.ts @@ -0,0 +1,15 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { ITreeSitterTokenizationService } from 'vs/editor/common/services/treeSitterTokenizationFeature'; + + +export class TestTreeSitterTokenizationService implements ITreeSitterTokenizationService { + readonly _serviceBrand: undefined; + + public initTreeSitter(): Promise { + return Promise.resolve(); + } +} diff --git a/src/vs/platform/files/test/browser/workbenchTestServices.ts b/src/vs/platform/files/test/browser/workbenchTestServices.ts new file mode 100644 index 0000000000000..85d60d6076a57 --- /dev/null +++ b/src/vs/platform/files/test/browser/workbenchTestServices.ts @@ -0,0 +1,190 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { timeout } from 'vs/base/common/async'; +import { VSBuffer, bufferToStream, VSBufferReadable } from 'vs/base/common/buffer'; +import { Emitter, Event } from 'vs/base/common/event'; +import { Iterable } from 'vs/base/common/iterator'; +import { toDisposable, IDisposable } from 'vs/base/common/lifecycle'; +import { ResourceMap } from 'vs/base/common/map'; +import { Schemas } from 'vs/base/common/network'; +import { isLinux } from 'vs/base/common/platform'; +import { basename } from 'vs/base/common/resources'; +import { URI } from 'vs/base/common/uri'; +import { IFileService, FileChangesEvent, FileOperationEvent, IFileSystemProviderCapabilitiesChangeEvent, IFileSystemProviderActivationEvent, IResolveMetadataFileOptions, IFileStatWithMetadata, IResolveFileOptions, IFileStat, IFileStatWithPartialMetadata, IFileStatResult, IReadFileOptions, IFileContent, IReadFileStreamOptions, IFileStreamContent, IWriteFileOptions, ICreateFileOptions, IFileSystemProvider, FileSystemProviderCapabilities, IWatchOptions, IFileSystemWatcher, IWatchOptionsWithCorrelation } from 'vs/platform/files/common/files'; + +export function createFileStat(resource: URI, readonly = false): IFileStatWithMetadata { + return { + resource, + etag: Date.now().toString(), + mtime: Date.now(), + ctime: Date.now(), + size: 42, + isFile: true, + isDirectory: false, + isSymbolicLink: false, + readonly, + locked: false, + name: basename(resource), + children: undefined + }; +} + +export class TestFileService implements IFileService { + + declare readonly _serviceBrand: undefined; + + private readonly _onDidFilesChange = new Emitter(); + get onDidFilesChange(): Event { return this._onDidFilesChange.event; } + fireFileChanges(event: FileChangesEvent): void { this._onDidFilesChange.fire(event); } + + private readonly _onDidRunOperation = new Emitter(); + get onDidRunOperation(): Event { return this._onDidRunOperation.event; } + fireAfterOperation(event: FileOperationEvent): void { this._onDidRunOperation.fire(event); } + + private readonly _onDidChangeFileSystemProviderCapabilities = new Emitter(); + get onDidChangeFileSystemProviderCapabilities(): Event { return this._onDidChangeFileSystemProviderCapabilities.event; } + fireFileSystemProviderCapabilitiesChangeEvent(event: IFileSystemProviderCapabilitiesChangeEvent): void { this._onDidChangeFileSystemProviderCapabilities.fire(event); } + + private _onWillActivateFileSystemProvider = new Emitter(); + readonly onWillActivateFileSystemProvider = this._onWillActivateFileSystemProvider.event; + readonly onDidWatchError = Event.None; + + private content = 'Hello Html'; + private lastReadFileUri!: URI; + + readonly = false; + + setContent(content: string): void { this.content = content; } + getContent(): string { return this.content; } + getLastReadFileUri(): URI { return this.lastReadFileUri; } + + resolve(resource: URI, _options: IResolveMetadataFileOptions): Promise; + resolve(resource: URI, _options?: IResolveFileOptions): Promise; + async resolve(resource: URI, _options?: IResolveFileOptions): Promise { + return createFileStat(resource, this.readonly); + } + + stat(resource: URI): Promise { + return this.resolve(resource, { resolveMetadata: true }); + } + + async resolveAll(toResolve: { resource: URI; options?: IResolveFileOptions }[]): Promise { + const stats = await Promise.all(toResolve.map(resourceAndOption => this.resolve(resourceAndOption.resource, resourceAndOption.options))); + + return stats.map(stat => ({ stat, success: true })); + } + + readonly notExistsSet = new ResourceMap(); + + async exists(_resource: URI): Promise { return !this.notExistsSet.has(_resource); } + + readShouldThrowError: Error | undefined = undefined; + + async readFile(resource: URI, options?: IReadFileOptions | undefined): Promise { + if (this.readShouldThrowError) { + throw this.readShouldThrowError; + } + + this.lastReadFileUri = resource; + + return { + ...createFileStat(resource, this.readonly), + value: VSBuffer.fromString(this.content) + }; + } + + async readFileStream(resource: URI, options?: IReadFileStreamOptions | undefined): Promise { + if (this.readShouldThrowError) { + throw this.readShouldThrowError; + } + + this.lastReadFileUri = resource; + + return { + ...createFileStat(resource, this.readonly), + value: bufferToStream(VSBuffer.fromString(this.content)) + }; + } + + writeShouldThrowError: Error | undefined = undefined; + + async writeFile(resource: URI, bufferOrReadable: VSBuffer | VSBufferReadable, options?: IWriteFileOptions): Promise { + await timeout(0); + + if (this.writeShouldThrowError) { + throw this.writeShouldThrowError; + } + + return createFileStat(resource, this.readonly); + } + + move(_source: URI, _target: URI, _overwrite?: boolean): Promise { return Promise.resolve(null!); } + copy(_source: URI, _target: URI, _overwrite?: boolean): Promise { return Promise.resolve(null!); } + async cloneFile(_source: URI, _target: URI): Promise { } + createFile(_resource: URI, _content?: VSBuffer | VSBufferReadable, _options?: ICreateFileOptions): Promise { return Promise.resolve(null!); } + createFolder(_resource: URI): Promise { return Promise.resolve(null!); } + + onDidChangeFileSystemProviderRegistrations = Event.None; + + private providers = new Map(); + + registerProvider(scheme: string, provider: IFileSystemProvider) { + this.providers.set(scheme, provider); + + return toDisposable(() => this.providers.delete(scheme)); + } + + getProvider(scheme: string) { + return this.providers.get(scheme); + } + + async activateProvider(_scheme: string): Promise { + this._onWillActivateFileSystemProvider.fire({ scheme: _scheme, join: () => { } }); + } + async canHandleResource(resource: URI): Promise { return this.hasProvider(resource); } + hasProvider(resource: URI): boolean { return resource.scheme === Schemas.file || this.providers.has(resource.scheme); } + listCapabilities() { + return [ + { scheme: Schemas.file, capabilities: FileSystemProviderCapabilities.FileOpenReadWriteClose }, + ...Iterable.map(this.providers, ([scheme, p]) => { return { scheme, capabilities: p.capabilities }; }) + ]; + } + hasCapability(resource: URI, capability: FileSystemProviderCapabilities): boolean { + if (capability === FileSystemProviderCapabilities.PathCaseSensitive && isLinux) { + return true; + } + + const provider = this.getProvider(resource.scheme); + + return !!(provider && (provider.capabilities & capability)); + } + + async del(_resource: URI, _options?: { useTrash?: boolean; recursive?: boolean }): Promise { } + + createWatcher(resource: URI, options: IWatchOptions): IFileSystemWatcher { + return { + onDidChange: Event.None, + dispose: () => { } + }; + } + + + readonly watches: URI[] = []; + watch(_resource: URI, options: IWatchOptionsWithCorrelation): IFileSystemWatcher; + watch(_resource: URI): IDisposable; + watch(_resource: URI): IDisposable { + this.watches.push(_resource); + + return toDisposable(() => this.watches.splice(this.watches.indexOf(_resource), 1)); + } + + dispose(): void { } + + async canCreateFile(source: URI, options?: ICreateFileOptions): Promise { return true; } + async canMove(source: URI, target: URI, overwrite?: boolean | undefined): Promise { return true; } + async canCopy(source: URI, target: URI, overwrite?: boolean | undefined): Promise { return true; } + async canDelete(resource: URI, options?: { useTrash?: boolean | undefined; recursive?: boolean | undefined } | undefined): Promise { return true; } +} diff --git a/src/vs/platform/theme/common/themeService.ts b/src/vs/platform/theme/common/themeService.ts index f89940c9f1e15..fee5d879f40c6 100644 --- a/src/vs/platform/theme/common/themeService.ts +++ b/src/vs/platform/theme/common/themeService.ts @@ -40,6 +40,20 @@ export interface ITokenStyle { readonly italic: boolean | undefined; } +export interface ITextMateThemingRule { + name?: string; + scope?: string | string[]; + settings: ITokenColorizationSetting; +} + +export interface ITokenColorizationSetting { + foreground?: string; + background?: string; + fontStyle?: string; /* [italic|bold|underline|strikethrough] */ +} + +export type ProbeScope = string[]; + export interface IColorTheme { readonly type: ColorScheme; diff --git a/src/vs/platform/theme/test/common/testThemeService.ts b/src/vs/platform/theme/test/common/testThemeService.ts index 5109b055e4c4e..1ca1abacdbd84 100644 --- a/src/vs/platform/theme/test/common/testThemeService.ts +++ b/src/vs/platform/theme/test/common/testThemeService.ts @@ -7,7 +7,8 @@ import { Color } from 'vs/base/common/color'; import { Emitter, Event } from 'vs/base/common/event'; import { IconContribution } from 'vs/platform/theme/common/iconRegistry'; import { ColorScheme } from 'vs/platform/theme/common/theme'; -import { IColorTheme, IFileIconTheme, IProductIconTheme, IThemeService, ITokenStyle } from 'vs/platform/theme/common/themeService'; +import { IColorTheme, IFileIconTheme, IProductIconTheme, ITextMateThemingRule, IThemeService, ITokenStyle, ProbeScope } from 'vs/platform/theme/common/themeService'; +import { TokenStyle } from 'vs/platform/theme/common/tokenClassificationRegistry'; export class TestColorTheme implements IColorTheme { @@ -19,6 +20,10 @@ export class TestColorTheme implements IColorTheme { public readonly semanticHighlighting = false ) { } + resolveScopes(scopes: ProbeScope[], definitions?: ITextMateThemingRule): TokenStyle | undefined { + throw new Error('Method not implemented.'); + } + getColor(color: string, useDefault?: boolean): Color | undefined { const value = this.colors[color]; if (value) { diff --git a/src/vs/workbench/api/test/browser/mainThreadDocumentsAndEditors.test.ts b/src/vs/workbench/api/test/browser/mainThreadDocumentsAndEditors.test.ts index d7190f1fe5c50..acf8a8afa5d48 100644 --- a/src/vs/workbench/api/test/browser/mainThreadDocumentsAndEditors.test.ts +++ b/src/vs/workbench/api/test/browser/mainThreadDocumentsAndEditors.test.ts @@ -14,6 +14,7 @@ import { ExtHostDocumentsAndEditorsShape, IDocumentsAndEditorsDelta } from 'vs/w import { createTestCodeEditor, ITestCodeEditor } from 'vs/editor/test/browser/testCodeEditor'; import { mock } from 'vs/base/test/common/mock'; import { TestEditorService, TestEditorGroupsService, TestEnvironmentService, TestPathService } from 'vs/workbench/test/browser/workbenchTestServices'; +import { TestFileService } from 'vs/platform/files/test/browser/workbenchTestServices'; import { Event } from 'vs/base/common/event'; import { ITextModel } from 'vs/editor/common/model'; import { ServiceCollection } from 'vs/platform/instantiation/common/serviceCollection'; @@ -32,6 +33,7 @@ import { TextModel } from 'vs/editor/common/model/textModel'; import { LanguageService } from 'vs/editor/common/services/languageService'; import { DisposableStore } from 'vs/base/common/lifecycle'; import { ensureNoDisposablesAreLeakedInTestSuite } from 'vs/base/test/common/utils'; +import { TestTreeSitterTokenizationService } from 'vs/editor/test/browser/services/testTreeSitterService'; suite('MainThreadDocumentsAndEditors', () => { @@ -67,6 +69,9 @@ suite('MainThreadDocumentsAndEditors', () => { undoRedoService, disposables.add(new LanguageService()), new TestLanguageConfigurationService(), + new TestFileService(), + new TestThemeService(), + new TestTreeSitterTokenizationService() ); codeEditorService = new TestCodeEditorService(themeService); textFileService = new class extends mock() { diff --git a/src/vs/workbench/api/test/browser/mainThreadEditors.test.ts b/src/vs/workbench/api/test/browser/mainThreadEditors.test.ts index 9809814a6c032..2885144cfe4a7 100644 --- a/src/vs/workbench/api/test/browser/mainThreadEditors.test.ts +++ b/src/vs/workbench/api/test/browser/mainThreadEditors.test.ts @@ -55,8 +55,10 @@ import { IPaneCompositePartService } from 'vs/workbench/services/panecomposite/b import { ITextFileService } from 'vs/workbench/services/textfile/common/textfiles'; import { ICopyOperation, ICreateFileOperation, ICreateOperation, IDeleteOperation, IMoveOperation, IWorkingCopyFileService } from 'vs/workbench/services/workingCopy/common/workingCopyFileService'; import { IWorkingCopyService } from 'vs/workbench/services/workingCopy/common/workingCopyService'; -import { TestEditorGroupsService, TestEditorService, TestEnvironmentService, TestFileService, TestLifecycleService, TestWorkingCopyService } from 'vs/workbench/test/browser/workbenchTestServices'; +import { TestEditorGroupsService, TestEditorService, TestEnvironmentService, TestLifecycleService, TestWorkingCopyService } from 'vs/workbench/test/browser/workbenchTestServices'; import { TestContextService, TestTextResourcePropertiesService } from 'vs/workbench/test/common/workbenchTestServices'; +import { TestFileService } from 'vs/platform/files/test/browser/workbenchTestServices'; +import { TestTreeSitterTokenizationService } from 'vs/editor/test/browser/services/testTreeSitterService'; suite('MainThreadEditors', () => { @@ -92,6 +94,9 @@ suite('MainThreadEditors', () => { undoRedoService, disposables.add(new LanguageService()), new TestLanguageConfigurationService(), + new TestFileService(), + new TestThemeService(), + new TestTreeSitterTokenizationService() ); const services = new ServiceCollection(); diff --git a/src/vs/workbench/contrib/bulkEdit/browser/preview/bulkEditTree.ts b/src/vs/workbench/contrib/bulkEdit/browser/preview/bulkEditTree.ts index 1716dd06a07b8..3f44bb729d4fc 100644 --- a/src/vs/workbench/contrib/bulkEdit/browser/preview/bulkEditTree.ts +++ b/src/vs/workbench/contrib/bulkEdit/browser/preview/bulkEditTree.ts @@ -15,7 +15,7 @@ import { ITextModel } from 'vs/editor/common/model'; import { IDisposable, DisposableStore } from 'vs/base/common/lifecycle'; import { TextModel } from 'vs/editor/common/model/textModel'; import { BulkFileOperations, BulkFileOperation, BulkFileOperationType, BulkTextEdit, BulkCategory } from 'vs/workbench/contrib/bulkEdit/browser/preview/bulkEditPreview'; -import { FileKind } from 'vs/platform/files/common/files'; +import { FileKind, IFileService } from 'vs/platform/files/common/files'; import { localize } from 'vs/nls'; import { ILabelService } from 'vs/platform/label/common/label'; import type { IListAccessibilityProvider } from 'vs/base/browser/ui/list/listWidget'; @@ -33,6 +33,7 @@ import { PLAINTEXT_LANGUAGE_ID } from 'vs/editor/common/languages/modesRegistry' import { SnippetParser } from 'vs/editor/contrib/snippet/browser/snippetParser'; import { AriaRole } from 'vs/base/browser/ui/aria/aria'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; +import { ITreeSitterTokenizationService } from 'vs/editor/common/services/treeSitterTokenizationFeature'; // --- VIEW MODEL @@ -206,7 +207,10 @@ export class BulkEditDataSource implements IAsyncDataSource { diff --git a/src/vs/workbench/services/model/common/modelService.ts b/src/vs/workbench/services/model/common/modelService.ts index 570f72df42df4..763d63b77d098 100644 --- a/src/vs/workbench/services/model/common/modelService.ts +++ b/src/vs/workbench/services/model/common/modelService.ts @@ -13,6 +13,9 @@ import { IConfigurationService } from 'vs/platform/configuration/common/configur import { InstantiationType, registerSingleton } from 'vs/platform/instantiation/common/extensions'; import { IUndoRedoService } from 'vs/platform/undoRedo/common/undoRedo'; import { IPathService } from 'vs/workbench/services/path/common/pathService'; +import { IFileService } from 'vs/platform/files/common/files'; +import { IThemeService } from 'vs/platform/theme/common/themeService'; +import { ITreeSitterTokenizationService } from 'vs/editor/common/services/treeSitterTokenizationFeature'; export class WorkbenchModelService extends ModelService { constructor( @@ -22,8 +25,11 @@ export class WorkbenchModelService extends ModelService { @ILanguageConfigurationService languageConfigurationService: ILanguageConfigurationService, @ILanguageService languageService: ILanguageService, @IPathService private readonly _pathService: IPathService, + @IFileService fileService: IFileService, + @IThemeService themeService: IThemeService, + @ITreeSitterTokenizationService treeSitterService: ITreeSitterTokenizationService ) { - super(configurationService, resourcePropertiesService, undoRedoService, languageService, languageConfigurationService); + super(configurationService, resourcePropertiesService, undoRedoService, languageService, languageConfigurationService, fileService, themeService, treeSitterService); } protected override _schemaShouldMaintainUndoRedoElements(resource: URI) { diff --git a/src/vs/workbench/services/textMate/browser/textMateTokenizationFeatureImpl.ts b/src/vs/workbench/services/textMate/browser/textMateTokenizationFeatureImpl.ts index 74a52fae9ff3f..3ba242b633f06 100644 --- a/src/vs/workbench/services/textMate/browser/textMateTokenizationFeatureImpl.ts +++ b/src/vs/workbench/services/textMate/browser/textMateTokenizationFeatureImpl.ts @@ -36,8 +36,9 @@ import { ThreadedBackgroundTokenizerFactory } from 'vs/workbench/services/textMa import { TMGrammarFactory, missingTMGrammarErrorMessage } from 'vs/workbench/services/textMate/common/TMGrammarFactory'; import { ITMSyntaxExtensionPoint, grammarsExtPoint } from 'vs/workbench/services/textMate/common/TMGrammars'; import { IValidEmbeddedLanguagesMap, IValidGrammarDefinition, IValidTokenTypeMap } from 'vs/workbench/services/textMate/common/TMScopeRegistry'; -import { ITextMateThemingRule, IWorkbenchColorTheme, IWorkbenchThemeService } from 'vs/workbench/services/themes/common/workbenchThemeService'; +import { IWorkbenchColorTheme, IWorkbenchThemeService } from 'vs/workbench/services/themes/common/workbenchThemeService'; import type { IGrammar, IOnigLib, IRawTheme } from 'vscode-textmate'; +import { ITextMateThemingRule } from 'vs/platform/theme/common/themeService'; export class TextMateTokenizationFeature extends Disposable implements ITextMateTokenizationService { private static reportTokenizationTimeCounter = { sync: 0, async: 0 }; diff --git a/src/vs/workbench/services/themes/common/colorThemeData.ts b/src/vs/workbench/services/themes/common/colorThemeData.ts index dd7a8f0d03f11..b37cfe30cd70e 100644 --- a/src/vs/workbench/services/themes/common/colorThemeData.ts +++ b/src/vs/workbench/services/themes/common/colorThemeData.ts @@ -6,13 +6,13 @@ import { basename } from 'vs/base/common/path'; import * as Json from 'vs/base/common/json'; import { Color } from 'vs/base/common/color'; -import { ExtensionData, ITokenColorCustomizations, ITextMateThemingRule, IWorkbenchColorTheme, IColorMap, IThemeExtensionPoint, VS_LIGHT_THEME, VS_HC_THEME, IColorCustomizations, ISemanticTokenRules, ISemanticTokenColorizationSetting, ISemanticTokenColorCustomizations, IThemeScopableCustomizations, IThemeScopedCustomizations, THEME_SCOPE_CLOSE_PAREN, THEME_SCOPE_OPEN_PAREN, themeScopeRegex, THEME_SCOPE_WILDCARD, VS_HC_LIGHT_THEME } from 'vs/workbench/services/themes/common/workbenchThemeService'; +import { ExtensionData, ITokenColorCustomizations, IWorkbenchColorTheme, IColorMap, IThemeExtensionPoint, VS_LIGHT_THEME, VS_HC_THEME, IColorCustomizations, ISemanticTokenRules, ISemanticTokenColorizationSetting, ISemanticTokenColorCustomizations, IThemeScopableCustomizations, IThemeScopedCustomizations, THEME_SCOPE_CLOSE_PAREN, THEME_SCOPE_OPEN_PAREN, themeScopeRegex, THEME_SCOPE_WILDCARD, VS_HC_LIGHT_THEME } from 'vs/workbench/services/themes/common/workbenchThemeService'; import { convertSettings } from 'vs/workbench/services/themes/common/themeCompatibility'; import * as nls from 'vs/nls'; import * as types from 'vs/base/common/types'; import * as resources from 'vs/base/common/resources'; import { Extensions as ColorRegistryExtensions, IColorRegistry, ColorIdentifier, editorBackground, editorForeground } from 'vs/platform/theme/common/colorRegistry'; -import { ITokenStyle, getThemeTypeSelector } from 'vs/platform/theme/common/themeService'; +import { ITextMateThemingRule, ITokenStyle, getThemeTypeSelector } from 'vs/platform/theme/common/themeService'; import { Registry } from 'vs/platform/registry/common/platform'; import { getParseErrorMessage } from 'vs/base/common/jsonErrorMessages'; import { URI } from 'vs/base/common/uri'; @@ -236,7 +236,7 @@ export class ColorThemeData implements IWorkbenchColorTheme { return undefined; } - private getTokenColorIndex(): TokenColorIndex { + public getTokenColorIndex(): TokenColorIndex { // collect all colors that tokens can have if (!this.tokenColorIndex) { const index = new TokenColorIndex(); diff --git a/src/vs/workbench/services/themes/common/themeCompatibility.ts b/src/vs/workbench/services/themes/common/themeCompatibility.ts index 21c643584f06d..8b698db8a7214 100644 --- a/src/vs/workbench/services/themes/common/themeCompatibility.ts +++ b/src/vs/workbench/services/themes/common/themeCompatibility.ts @@ -3,11 +3,12 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { ITextMateThemingRule, IColorMap } from 'vs/workbench/services/themes/common/workbenchThemeService'; +import { IColorMap } from 'vs/workbench/services/themes/common/workbenchThemeService'; import { Color } from 'vs/base/common/color'; import * as colorRegistry from 'vs/platform/theme/common/colorRegistry'; import * as editorColorRegistry from 'vs/editor/common/core/editorColorRegistry'; +import { ITextMateThemingRule } from 'vs/platform/theme/common/themeService'; const settingToColorIdMapping: { [settingId: string]: string[] } = {}; function addSettingMapping(settingId: string, colorId: string) { diff --git a/src/vs/workbench/services/themes/common/workbenchThemeService.ts b/src/vs/workbench/services/themes/common/workbenchThemeService.ts index aac853941a768..c60a281d054fe 100644 --- a/src/vs/workbench/services/themes/common/workbenchThemeService.ts +++ b/src/vs/workbench/services/themes/common/workbenchThemeService.ts @@ -6,7 +6,7 @@ import { refineServiceDecorator } from 'vs/platform/instantiation/common/instantiation'; import { Event } from 'vs/base/common/event'; import { Color } from 'vs/base/common/color'; -import { IColorTheme, IThemeService, IFileIconTheme, IProductIconTheme } from 'vs/platform/theme/common/themeService'; +import { IColorTheme, IThemeService, IFileIconTheme, IProductIconTheme, ITextMateThemingRule, ITokenColorizationSetting } from 'vs/platform/theme/common/themeService'; import { ConfigurationTarget } from 'vs/platform/configuration/common/configuration'; import { isBoolean, isString } from 'vs/base/common/types'; import { IconContribution, IconDefinition } from 'vs/platform/theme/common/iconRegistry'; @@ -233,18 +233,6 @@ export interface ISemanticTokenRules { [selector: string]: string | ISemanticTokenColorizationSetting | undefined; } -export interface ITextMateThemingRule { - name?: string; - scope?: string | string[]; - settings: ITokenColorizationSetting; -} - -export interface ITokenColorizationSetting { - foreground?: string; - background?: string; - fontStyle?: string; /* [italic|bold|underline|strikethrough] */ -} - export interface ISemanticTokenColorizationSetting { foreground?: string; fontStyle?: string; /* [italic|bold|underline|strikethrough] */ diff --git a/src/vs/workbench/services/treeSitter/browser/treeSitterTokenizationFeature.contribution.ts b/src/vs/workbench/services/treeSitter/browser/treeSitterTokenizationFeature.contribution.ts index 9d4ae5fdf8f24..f70fc12cf28bb 100644 --- a/src/vs/workbench/services/treeSitter/browser/treeSitterTokenizationFeature.contribution.ts +++ b/src/vs/workbench/services/treeSitter/browser/treeSitterTokenizationFeature.contribution.ts @@ -5,8 +5,8 @@ import { registerSingleton, InstantiationType } from 'vs/platform/instantiation/common/extensions'; import { IWorkbenchContribution, WorkbenchPhase, registerWorkbenchContribution2 } from 'vs/workbench/common/contributions'; -import { ITreeSitterTokenizationService } from 'vs/workbench/services/treeSitter/browser/treeSitterTokenizationFeature'; -import { TreeSitterTokenizationService } from 'vs/workbench/services/treeSitter/browser/treeSitterTokenizationFeatureImpl'; +import { TreeSitterTokenizationService } from 'vs/editor/browser/services/treeSitter/treeSitterTokenizationFeatureImpl'; +import { ITreeSitterTokenizationService } from 'vs/editor/common/services/treeSitterTokenizationFeature'; /** * Makes sure the ITreeSitterTokenizationService is instantiated diff --git a/src/vs/workbench/services/treeSitter/browser/treeSitterTokenizationFeatureImpl.ts b/src/vs/workbench/services/treeSitter/browser/treeSitterTokenizationFeatureImpl.ts deleted file mode 100644 index a7ec715f089e1..0000000000000 --- a/src/vs/workbench/services/treeSitter/browser/treeSitterTokenizationFeatureImpl.ts +++ /dev/null @@ -1,20 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import { TreeSitterTokenizationRegistry } from 'vs/editor/common/languages'; -import { ITreeSitterTokenizationService } from 'vs/workbench/services/treeSitter/browser/treeSitterTokenizationFeature'; - -export class TreeSitterTokenizationService implements ITreeSitterTokenizationService { - readonly _serviceBrand: undefined; - - constructor() { - // Eventually, this should actually use an extension point to add tree sitter grammars, but for now they are hard coded in core - this._addGrammar('placeholder-language'); - } - - private _addGrammar(languageId: string) { - TreeSitterTokenizationRegistry.register(languageId, {}); - } -} diff --git a/src/vs/workbench/services/workingCopy/test/electron-sandbox/workingCopyBackupTracker.test.ts b/src/vs/workbench/services/workingCopy/test/electron-sandbox/workingCopyBackupTracker.test.ts index fa293b361cf92..628af00c751c0 100644 --- a/src/vs/workbench/services/workingCopy/test/electron-sandbox/workingCopyBackupTracker.test.ts +++ b/src/vs/workbench/services/workingCopy/test/electron-sandbox/workingCopyBackupTracker.test.ts @@ -28,7 +28,8 @@ import { INativeHostService } from 'vs/platform/native/common/native'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { TestConfigurationService } from 'vs/platform/configuration/test/common/testConfigurationService'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; -import { createEditorPart, registerTestFileEditor, TestBeforeShutdownEvent, TestEnvironmentService, TestFilesConfigurationService, TestFileService, TestTextResourceConfigurationService, workbenchTeardown } from 'vs/workbench/test/browser/workbenchTestServices'; +import { createEditorPart, registerTestFileEditor, TestBeforeShutdownEvent, TestEnvironmentService, TestFilesConfigurationService, TestTextResourceConfigurationService, workbenchTeardown } from 'vs/workbench/test/browser/workbenchTestServices'; +import { TestFileService } from 'vs/platform/files/test/browser/workbenchTestServices'; import { MockContextKeyService } from 'vs/platform/keybinding/test/common/mockKeybindingService'; import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; import { IEnvironmentService } from 'vs/platform/environment/common/environment'; diff --git a/src/vs/workbench/services/workingCopy/test/electron-sandbox/workingCopyHistoryTracker.test.ts b/src/vs/workbench/services/workingCopy/test/electron-sandbox/workingCopyHistoryTracker.test.ts index ef04d7041db52..257e265bfd5d1 100644 --- a/src/vs/workbench/services/workingCopy/test/electron-sandbox/workingCopyHistoryTracker.test.ts +++ b/src/vs/workbench/services/workingCopy/test/electron-sandbox/workingCopyHistoryTracker.test.ts @@ -12,7 +12,8 @@ import { URI } from 'vs/base/common/uri'; import { WorkingCopyHistoryTracker } from 'vs/workbench/services/workingCopy/common/workingCopyHistoryTracker'; import { WorkingCopyService } from 'vs/workbench/services/workingCopy/common/workingCopyService'; import { UriIdentityService } from 'vs/platform/uriIdentity/common/uriIdentityService'; -import { TestFileService, TestPathService } from 'vs/workbench/test/browser/workbenchTestServices'; +import { TestPathService } from 'vs/workbench/test/browser/workbenchTestServices'; +import { TestFileService } from 'vs/platform/files/test/browser/workbenchTestServices'; import { DeferredPromise } from 'vs/base/common/async'; import { IFileService } from 'vs/platform/files/common/files'; import { Schemas } from 'vs/base/common/network'; diff --git a/src/vs/workbench/test/browser/workbenchTestServices.ts b/src/vs/workbench/test/browser/workbenchTestServices.ts index e7c8dbf262aff..b191e1c1519db 100644 --- a/src/vs/workbench/test/browser/workbenchTestServices.ts +++ b/src/vs/workbench/test/browser/workbenchTestServices.ts @@ -23,11 +23,11 @@ import { IUntitledTextEditorService, UntitledTextEditorService } from 'vs/workbe import { IWorkspaceContextService, IWorkspaceIdentifier } from 'vs/platform/workspace/common/workspace'; import { ILifecycleService, ShutdownReason, StartupKind, LifecyclePhase, WillShutdownEvent, BeforeShutdownErrorEvent, InternalBeforeShutdownEvent, IWillShutdownEventJoiner } from 'vs/workbench/services/lifecycle/common/lifecycle'; import { ServiceCollection } from 'vs/platform/instantiation/common/serviceCollection'; -import { FileOperationEvent, IFileService, IFileStat, IFileStatResult, FileChangesEvent, IResolveFileOptions, ICreateFileOptions, IFileSystemProvider, FileSystemProviderCapabilities, IFileChange, IWatchOptions, IStat, FileType, IFileDeleteOptions, IFileOverwriteOptions, IFileWriteOptions, IFileOpenOptions, IFileStatWithMetadata, IResolveMetadataFileOptions, IWriteFileOptions, IReadFileOptions, IFileContent, IFileStreamContent, FileOperationError, IFileSystemProviderWithFileReadStreamCapability, IFileReadStreamOptions, IReadFileStreamOptions, IFileSystemProviderCapabilitiesChangeEvent, IFileStatWithPartialMetadata, IFileSystemWatcher, IWatchOptionsWithCorrelation, IFileSystemProviderActivationEvent } from 'vs/platform/files/common/files'; +import { IFileService, IFileSystemProvider, FileSystemProviderCapabilities, IFileChange, IWatchOptions, IStat, FileType, IFileDeleteOptions, IFileOverwriteOptions, IFileWriteOptions, IFileOpenOptions, IFileStatWithMetadata, FileOperationError, IFileSystemProviderWithFileReadStreamCapability, IFileReadStreamOptions } from 'vs/platform/files/common/files'; import { IModelService } from 'vs/editor/common/services/model'; import { LanguageService } from 'vs/editor/common/services/languageService'; import { ModelService } from 'vs/editor/common/services/modelService'; -import { IResourceEncoding, ITextFileService, IReadTextFileOptions, ITextFileStreamContent, IWriteTextFileOptions, ITextFileEditorModel, ITextFileEditorModelManager } from 'vs/workbench/services/textfile/common/textfiles'; +import { ITextFileService, IReadTextFileOptions, ITextFileStreamContent, IWriteTextFileOptions, ITextFileEditorModel, ITextFileEditorModelManager } from 'vs/workbench/services/textfile/common/textfiles'; import { ILanguageService } from 'vs/editor/common/languages/language'; import { IHistoryService } from 'vs/workbench/services/history/common/history'; import { IInstantiationService, ServiceIdentifier } from 'vs/platform/instantiation/common/instantiation'; @@ -51,7 +51,7 @@ import { TestNotificationService } from 'vs/platform/notification/test/common/te import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions'; import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; import { IDecorationsService, IResourceDecorationChangeEvent, IDecoration, IDecorationData, IDecorationsProvider } from 'vs/workbench/services/decorations/common/decorations'; -import { IDisposable, toDisposable, Disposable, DisposableStore } from 'vs/base/common/lifecycle'; +import { IDisposable, Disposable, DisposableStore } from 'vs/base/common/lifecycle'; import { IEditorGroupsService, IEditorGroup, GroupsOrder, GroupsArrangement, GroupDirection, IMergeGroupOptions, IEditorReplacement, IFindGroupScope, EditorGroupLayout, ICloseEditorOptions, GroupOrientation, ICloseAllEditorsOptions, ICloseEditorsFilter, IEditorDropTargetDelegate, IEditorPart, IAuxiliaryEditorPart, IEditorGroupsContainer, IAuxiliaryEditorPartCreateEvent, IEditorWorkingSet, IEditorGroupContextKeyProvider, IEditorWorkingSetOptions } from 'vs/workbench/services/editor/common/editorGroupsService'; import { IEditorService, ISaveEditorsOptions, IRevertAllEditorsOptions, PreferredGroup, IEditorsChangeEvent, ISaveEditorsResult } from 'vs/workbench/services/editor/common/editorService'; import { ICodeEditorService } from 'vs/editor/browser/services/codeEditorService'; @@ -62,10 +62,10 @@ import { ILabelService } from 'vs/platform/label/common/label'; import { DeferredPromise, timeout } from 'vs/base/common/async'; import { PaneComposite, PaneCompositeDescriptor } from 'vs/workbench/browser/panecomposite'; import { IStorageService, StorageScope, StorageTarget } from 'vs/platform/storage/common/storage'; -import { IProcessEnvironment, isLinux, isWindows, OperatingSystem } from 'vs/base/common/platform'; +import { IProcessEnvironment, isWindows, OperatingSystem } from 'vs/base/common/platform'; import { LabelService } from 'vs/workbench/services/label/common/labelService'; import { Part } from 'vs/workbench/browser/part'; -import { bufferToStream, VSBuffer, VSBufferReadable, VSBufferReadableStream } from 'vs/base/common/buffer'; +import { VSBuffer, VSBufferReadable, VSBufferReadableStream } from 'vs/base/common/buffer'; import { Schemas } from 'vs/base/common/network'; import { IProductService } from 'vs/platform/product/common/productService'; import product from 'vs/platform/product/common/product'; @@ -98,7 +98,7 @@ import { IInputBox, IInputOptions, IPickOptions, IQuickInputButton, IQuickInputS import { QuickInputService } from 'vs/workbench/services/quickinput/browser/quickInputService'; import { IListService } from 'vs/platform/list/browser/listService'; import { win32, posix } from 'vs/base/common/path'; -import { TestContextService, TestStorageService, TestTextResourcePropertiesService, TestExtensionService, TestProductService, createFileStat, TestLoggerService, TestWorkspaceTrustManagementService, TestWorkspaceTrustRequestService, TestMarkerService, TestHistoryService } from 'vs/workbench/test/common/workbenchTestServices'; +import { TestContextService, TestStorageService, TestTextResourcePropertiesService, TestExtensionService, TestProductService, TestLoggerService, TestWorkspaceTrustManagementService, TestWorkspaceTrustRequestService, TestMarkerService, TestHistoryService } from 'vs/workbench/test/common/workbenchTestServices'; import { IView, ViewContainer, ViewContainerLocation } from 'vs/workbench/common/views'; import { IViewsService } from 'vs/workbench/services/views/common/viewsService'; import { IPaneComposite } from 'vs/workbench/common/panecomposite'; @@ -109,7 +109,6 @@ import { newWriteableStream, ReadableStreamEvents } from 'vs/base/common/stream' import { EncodingOracle, IEncodingOverride } from 'vs/workbench/services/textfile/browser/textFileService'; import { UTF16le, UTF16be, UTF8_with_bom } from 'vs/workbench/services/textfile/common/encoding'; import { ColorScheme } from 'vs/platform/theme/common/theme'; -import { Iterable } from 'vs/base/common/iterator'; import { InMemoryWorkingCopyBackupService } from 'vs/workbench/services/workingCopy/common/workingCopyBackupService'; import { BrowserWorkingCopyBackupService } from 'vs/workbench/services/workingCopy/browser/workingCopyBackupService'; import { FileService } from 'vs/platform/files/common/fileService'; @@ -132,7 +131,6 @@ import { IWorkingCopyEditorService, WorkingCopyEditorService } from 'vs/workbenc import { IElevatedFileService } from 'vs/workbench/services/files/common/elevatedFileService'; import { BrowserElevatedFileService } from 'vs/workbench/services/files/browser/elevatedFileService'; import { IEditorWorkerService } from 'vs/editor/common/services/editorWorker'; -import { ResourceMap } from 'vs/base/common/map'; import { SideBySideEditorInput } from 'vs/workbench/common/editor/sideBySideEditorInput'; import { ITextEditorService, TextEditorService } from 'vs/workbench/services/textfile/common/textEditorService'; import { IPaneCompositePartService } from 'vs/workbench/services/panecomposite/browser/panecomposite'; @@ -179,6 +177,7 @@ import { TerminalLogService } from 'vs/platform/terminal/common/terminalLogServi import { IEnvironmentVariableService } from 'vs/workbench/contrib/terminal/common/environmentVariable'; import { EnvironmentVariableService } from 'vs/workbench/contrib/terminal/common/environmentVariableService'; import { ContextMenuService } from 'vs/platform/contextview/browser/contextMenuService'; +import { TestFileService } from 'vs/platform/files/test/browser/workbenchTestServices'; export function createFileEditorInput(instantiationService: IInstantiationService, resource: URI): FileEditorInput { return instantiationService.createInstance(FileEditorInput, resource, undefined, undefined, undefined, undefined, undefined, undefined); @@ -1049,164 +1048,6 @@ export class TestEditorService extends Disposable implements EditorServiceImpl { revertAll(options?: IRevertAllEditorsOptions): Promise { throw new Error('Method not implemented.'); } } -export class TestFileService implements IFileService { - - declare readonly _serviceBrand: undefined; - - private readonly _onDidFilesChange = new Emitter(); - get onDidFilesChange(): Event { return this._onDidFilesChange.event; } - fireFileChanges(event: FileChangesEvent): void { this._onDidFilesChange.fire(event); } - - private readonly _onDidRunOperation = new Emitter(); - get onDidRunOperation(): Event { return this._onDidRunOperation.event; } - fireAfterOperation(event: FileOperationEvent): void { this._onDidRunOperation.fire(event); } - - private readonly _onDidChangeFileSystemProviderCapabilities = new Emitter(); - get onDidChangeFileSystemProviderCapabilities(): Event { return this._onDidChangeFileSystemProviderCapabilities.event; } - fireFileSystemProviderCapabilitiesChangeEvent(event: IFileSystemProviderCapabilitiesChangeEvent): void { this._onDidChangeFileSystemProviderCapabilities.fire(event); } - - private _onWillActivateFileSystemProvider = new Emitter(); - readonly onWillActivateFileSystemProvider = this._onWillActivateFileSystemProvider.event; - readonly onDidWatchError = Event.None; - - private content = 'Hello Html'; - private lastReadFileUri!: URI; - - readonly = false; - - setContent(content: string): void { this.content = content; } - getContent(): string { return this.content; } - getLastReadFileUri(): URI { return this.lastReadFileUri; } - - resolve(resource: URI, _options: IResolveMetadataFileOptions): Promise; - resolve(resource: URI, _options?: IResolveFileOptions): Promise; - async resolve(resource: URI, _options?: IResolveFileOptions): Promise { - return createFileStat(resource, this.readonly); - } - - stat(resource: URI): Promise { - return this.resolve(resource, { resolveMetadata: true }); - } - - async resolveAll(toResolve: { resource: URI; options?: IResolveFileOptions }[]): Promise { - const stats = await Promise.all(toResolve.map(resourceAndOption => this.resolve(resourceAndOption.resource, resourceAndOption.options))); - - return stats.map(stat => ({ stat, success: true })); - } - - readonly notExistsSet = new ResourceMap(); - - async exists(_resource: URI): Promise { return !this.notExistsSet.has(_resource); } - - readShouldThrowError: Error | undefined = undefined; - - async readFile(resource: URI, options?: IReadFileOptions | undefined): Promise { - if (this.readShouldThrowError) { - throw this.readShouldThrowError; - } - - this.lastReadFileUri = resource; - - return { - ...createFileStat(resource, this.readonly), - value: VSBuffer.fromString(this.content) - }; - } - - async readFileStream(resource: URI, options?: IReadFileStreamOptions | undefined): Promise { - if (this.readShouldThrowError) { - throw this.readShouldThrowError; - } - - this.lastReadFileUri = resource; - - return { - ...createFileStat(resource, this.readonly), - value: bufferToStream(VSBuffer.fromString(this.content)) - }; - } - - writeShouldThrowError: Error | undefined = undefined; - - async writeFile(resource: URI, bufferOrReadable: VSBuffer | VSBufferReadable, options?: IWriteFileOptions): Promise { - await timeout(0); - - if (this.writeShouldThrowError) { - throw this.writeShouldThrowError; - } - - return createFileStat(resource, this.readonly); - } - - move(_source: URI, _target: URI, _overwrite?: boolean): Promise { return Promise.resolve(null!); } - copy(_source: URI, _target: URI, _overwrite?: boolean): Promise { return Promise.resolve(null!); } - async cloneFile(_source: URI, _target: URI): Promise { } - createFile(_resource: URI, _content?: VSBuffer | VSBufferReadable, _options?: ICreateFileOptions): Promise { return Promise.resolve(null!); } - createFolder(_resource: URI): Promise { return Promise.resolve(null!); } - - onDidChangeFileSystemProviderRegistrations = Event.None; - - private providers = new Map(); - - registerProvider(scheme: string, provider: IFileSystemProvider) { - this.providers.set(scheme, provider); - - return toDisposable(() => this.providers.delete(scheme)); - } - - getProvider(scheme: string) { - return this.providers.get(scheme); - } - - async activateProvider(_scheme: string): Promise { - this._onWillActivateFileSystemProvider.fire({ scheme: _scheme, join: () => { } }); - } - async canHandleResource(resource: URI): Promise { return this.hasProvider(resource); } - hasProvider(resource: URI): boolean { return resource.scheme === Schemas.file || this.providers.has(resource.scheme); } - listCapabilities() { - return [ - { scheme: Schemas.file, capabilities: FileSystemProviderCapabilities.FileOpenReadWriteClose }, - ...Iterable.map(this.providers, ([scheme, p]) => { return { scheme, capabilities: p.capabilities }; }) - ]; - } - hasCapability(resource: URI, capability: FileSystemProviderCapabilities): boolean { - if (capability === FileSystemProviderCapabilities.PathCaseSensitive && isLinux) { - return true; - } - - const provider = this.getProvider(resource.scheme); - - return !!(provider && (provider.capabilities & capability)); - } - - async del(_resource: URI, _options?: { useTrash?: boolean; recursive?: boolean }): Promise { } - - createWatcher(resource: URI, options: IWatchOptions): IFileSystemWatcher { - return { - onDidChange: Event.None, - dispose: () => { } - }; - } - - - readonly watches: URI[] = []; - watch(_resource: URI, options: IWatchOptionsWithCorrelation): IFileSystemWatcher; - watch(_resource: URI): IDisposable; - watch(_resource: URI): IDisposable { - this.watches.push(_resource); - - return toDisposable(() => this.watches.splice(this.watches.indexOf(_resource), 1)); - } - - getWriteEncoding(_resource: URI): IResourceEncoding { return { encoding: 'utf8', hasBOM: false }; } - dispose(): void { } - - async canCreateFile(source: URI, options?: ICreateFileOptions): Promise { return true; } - async canMove(source: URI, target: URI, overwrite?: boolean | undefined): Promise { return true; } - async canCopy(source: URI, target: URI, overwrite?: boolean | undefined): Promise { return true; } - async canDelete(resource: URI, options?: { useTrash?: boolean | undefined; recursive?: boolean | undefined } | undefined): Promise { return true; } -} - export class TestWorkingCopyBackupService extends InMemoryWorkingCopyBackupService { readonly resolved: Set = new Set(); diff --git a/src/vs/workbench/test/electron-sandbox/workbenchTestServices.ts b/src/vs/workbench/test/electron-sandbox/workbenchTestServices.ts index 45f6d6d98f43f..62860d15462e8 100644 --- a/src/vs/workbench/test/electron-sandbox/workbenchTestServices.ts +++ b/src/vs/workbench/test/electron-sandbox/workbenchTestServices.ts @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import { Event } from 'vs/base/common/event'; -import { workbenchInstantiationService as browserWorkbenchInstantiationService, ITestInstantiationService, TestEncodingOracle, TestEnvironmentService, TestFileDialogService, TestFilesConfigurationService, TestFileService, TestLifecycleService, TestTextFileService } from 'vs/workbench/test/browser/workbenchTestServices'; +import { workbenchInstantiationService as browserWorkbenchInstantiationService, ITestInstantiationService, TestEncodingOracle, TestEnvironmentService, TestFileDialogService, TestFilesConfigurationService, TestLifecycleService, TestTextFileService } from 'vs/workbench/test/browser/workbenchTestServices'; import { ISharedProcessService } from 'vs/platform/ipc/electron-sandbox/services'; import { INativeHostService, INativeHostOptions, IOSProperties, IOSStatistics } from 'vs/platform/native/common/native'; import { VSBuffer, VSBufferReadable, VSBufferReadableStream } from 'vs/base/common/buffer'; @@ -48,6 +48,7 @@ import { NativeWorkingCopyBackupService } from 'vs/workbench/services/workingCop import { CancellationToken } from 'vs/base/common/cancellation'; import { UriIdentityService } from 'vs/platform/uriIdentity/common/uriIdentityService'; import { UserDataProfilesService } from 'vs/platform/userDataProfile/common/userDataProfile'; +import { TestFileService } from 'vs/platform/files/test/browser/workbenchTestServices'; export class TestSharedProcessService implements ISharedProcessService { diff --git a/yarn.lock b/yarn.lock index c09fbd906aef2..d0eb11f846e45 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7278,6 +7278,11 @@ node-addon-api@^6.0.0: resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-6.0.0.tgz#cfb3574e6df708ff71a30db6c4762d9e06e11c27" integrity sha512-GyHvgPvUXBvAkXa0YvYnhilSB1A+FRYMpIVggKzPZqdaZfevZOuzfWzyvgzOwRLHBeo/MMswmJFsrNF4Nw1pmA== +node-addon-api@^8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-8.0.0.tgz#5453b7ad59dd040d12e0f1a97a6fa1c765c5c9d2" + integrity sha512-ipO7rsHEBqa9STO5C5T10fj732ml+5kLN1cAG8/jdHd56ldQeGj3Q7+scUS+VHK/qy1zLEwC4wMK5+yM0btPvw== + node-fetch@2.6.8: version "2.6.8" resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.8.tgz#a68d30b162bc1d8fd71a367e81b997e1f4d4937e" @@ -7297,6 +7302,11 @@ node-gyp-build@4.8.1, node-gyp-build@^4.3.0: resolved "https://registry.yarnpkg.com/node-gyp-build/-/node-gyp-build-4.8.1.tgz#976d3ad905e71b76086f4f0b0d3637fe79b6cda5" integrity sha512-OSs33Z9yWr148JZcbZd5WiAXhh/n9z8TxQcdMhIOlpN9AhWpLfvVFO73+m77bBABQMaY9XSvIa+qk0jlI7Gcaw== +node-gyp-build@^4.8.1: + version "4.8.1" + resolved "https://registry.yarnpkg.com/node-gyp-build/-/node-gyp-build-4.8.1.tgz#976d3ad905e71b76086f4f0b0d3637fe79b6cda5" + integrity sha512-OSs33Z9yWr148JZcbZd5WiAXhh/n9z8TxQcdMhIOlpN9AhWpLfvVFO73+m77bBABQMaY9XSvIa+qk0jlI7Gcaw== + node-html-markdown@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/node-html-markdown/-/node-html-markdown-1.3.0.tgz#ef0b19a3bbfc0f1a880abb9ff2a0c9aa6bbff2a9" @@ -9889,6 +9899,19 @@ tree-kill@^1.2.2: resolved "https://registry.yarnpkg.com/tree-kill/-/tree-kill-1.2.2.tgz#4ca09a9092c88b73a7cdc5e8a01b507b0790a0cc" integrity sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A== +tree-sitter-cli@^0.22.6: + version "0.22.6" + resolved "https://registry.yarnpkg.com/tree-sitter-cli/-/tree-sitter-cli-0.22.6.tgz#f0542bce4095952c292d3f0300d72aeab442b765" + integrity sha512-s7mYOJXi8sIFkt/nLJSqlYZP96VmKTc3BAwIX0rrrlRxWjWuCwixFqwzxWZBQz4R8Hx01iP7z3cT3ih58BUmZQ== + +tree-sitter-html@^0.20.3: + version "0.20.3" + resolved "https://registry.yarnpkg.com/tree-sitter-html/-/tree-sitter-html-0.20.3.tgz#b7043448d7df482083e32f9ba9a8f366629e7704" + integrity sha512-D+hfQyGUnptdL909C5/hJRCuj1C6TtQ6/meHPtBNvCR4jp04Ir+BFhzhwKf8lwe5OcsCTYymU5ljMAd9yNXzfQ== + dependencies: + node-addon-api "^8.0.0" + node-gyp-build "^4.8.1" + ts-api-utils@^1.0.1: version "1.3.0" resolved "https://registry.yarnpkg.com/ts-api-utils/-/ts-api-utils-1.3.0.tgz#4b490e27129f1e8e686b45cc4ab63714dc60eea1" From 3614235d3302aafabae3a470b836da7de78a02ec Mon Sep 17 00:00:00 2001 From: Alex Ross Date: Wed, 22 May 2024 10:30:58 +0200 Subject: [PATCH 04/37] Update tree when content changes --- .../editor/common/model/treeSitterTokens.ts | 24 +++++++++++++++---- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/src/vs/editor/common/model/treeSitterTokens.ts b/src/vs/editor/common/model/treeSitterTokens.ts index c76997614215b..ae189a1b7d5a2 100644 --- a/src/vs/editor/common/model/treeSitterTokens.ts +++ b/src/vs/editor/common/model/treeSitterTokens.ts @@ -15,6 +15,7 @@ import { TokenStyle } from 'vs/platform/theme/common/tokenClassificationRegistry import { ColorThemeData } from 'vs/workbench/services/themes/common/colorThemeData'; import { TextModel } from 'vs/editor/common/model/textModel'; import { ITreeSitterTokenizationService } from 'vs/editor/common/services/treeSitterTokenizationFeature'; +import { IModelContentChangedEvent } from 'vs/editor/common/textModelEvents'; export class TreeSitterTokens extends Disposable { private _colorThemeData: ColorThemeData; @@ -115,13 +116,26 @@ class TextModelTokens extends Disposable { private readonly _language: Parser.Language, private readonly _colorThemeData: ColorThemeData) { super(); - this._register(this._textModel.onDidChangeContent(() => this._onDidChangeContent())); + this._register(this._textModel.onDidChangeContent((e) => this._onDidChangeContent(e))); } - private _onDidChangeContent() { - // TODO @alexr00 this is an extremely naive implementation and should absolutely not be pushed to main, it's just a placeholder. - this._tree?.delete(); - this._tree = undefined; + private _onDidChangeContent(e: IModelContentChangedEvent) { + if (!this._tree) { + return; + } + for (const change of e.changes) { + const newEndOffset = change.rangeOffset + change.text.length; + const newEndPosition = this._textModel.getPositionAt(newEndOffset); + this._tree.edit({ + startIndex: change.rangeOffset, + oldEndIndex: change.rangeOffset + change.rangeLength, + newEndIndex: change.rangeOffset + change.text.length, + startPosition: { row: change.range.startLineNumber - 1, column: change.range.startColumn - 1 }, + oldEndPosition: { row: change.range.endLineNumber - 1, column: change.range.endColumn - 1 }, + newEndPosition: { row: newEndPosition.lineNumber - 1, column: newEndPosition.column - 1 } + }); + } + this._tree = this._parser.parse(this._textModel.getValue(), this._tree); } private _ensureTree() { From 2703b6bda7618d9a5975190030e113da712ce023 Mon Sep 17 00:00:00 2001 From: Alex Ross Date: Wed, 22 May 2024 11:35:42 +0200 Subject: [PATCH 05/37] WIP for making abstract tokens class --- src/vs/editor/common/model/textModel.ts | 40 +---- .../common/model/tokenizationTextModelPart.ts | 156 +++++----------- src/vs/editor/common/model/tokens.ts | 166 ++++++++++++++++++ .../editor/common/model/treeSitterTokens.ts | 89 ++++++++-- 4 files changed, 282 insertions(+), 169 deletions(-) create mode 100644 src/vs/editor/common/model/tokens.ts diff --git a/src/vs/editor/common/model/textModel.ts b/src/vs/editor/common/model/textModel.ts index 40d474eeb6338..8dbfa3018a831 100644 --- a/src/vs/editor/common/model/textModel.ts +++ b/src/vs/editor/common/model/textModel.ts @@ -18,7 +18,6 @@ import { URI } from 'vs/base/common/uri'; import { ISingleEditOperation } from 'vs/editor/common/core/editOperation'; import { countEOL } from 'vs/editor/common/core/eolCounter'; import { normalizeIndentation } from 'vs/editor/common/core/indentation'; -import { LineRange } from 'vs/editor/common/core/lineRange'; import { IPosition, Position } from 'vs/editor/common/core/position'; import { IRange, Range } from 'vs/editor/common/core/range'; import { Selection } from 'vs/editor/common/core/selection'; @@ -39,6 +38,7 @@ import { PieceTreeTextBuffer } from 'vs/editor/common/model/pieceTreeTextBuffer/ import { PieceTreeTextBufferBuilder } from 'vs/editor/common/model/pieceTreeTextBuffer/pieceTreeTextBufferBuilder'; import { SearchParams, TextModelSearch } from 'vs/editor/common/model/textModelSearch'; import { TokenizationTextModelPart } from 'vs/editor/common/model/tokenizationTextModelPart'; +import { AttachedViews } from 'vs/editor/common/model/tokens'; import { ITreeSitterTokenizationService } from 'vs/editor/common/services/treeSitterTokenizationFeature'; import { IBracketPairsTextModelPart } from 'vs/editor/common/textModelBracketPairs'; import { IModelContentChangedEvent, IModelDecorationsChangedEvent, IModelOptionsChangedEvent, InternalModelContentChangeEvent, LineInjectedText, ModelInjectedTextChangedEvent, ModelRawChange, ModelRawContentChangedEvent, ModelRawEOLChanged, ModelRawFlush, ModelRawLineChanged, ModelRawLinesDeleted, ModelRawLinesInserted } from 'vs/editor/common/textModelEvents'; @@ -2535,42 +2535,4 @@ class DidChangeContentEmitter extends Disposable { } } -/** - * @internal - */ -export class AttachedViews { - private readonly _onDidChangeVisibleRanges = new Emitter<{ view: model.IAttachedView; state: IAttachedViewState | undefined }>(); - public readonly onDidChangeVisibleRanges = this._onDidChangeVisibleRanges.event; - - private readonly _views = new Set(); - - public attachView(): model.IAttachedView { - const view = new AttachedViewImpl((state) => { - this._onDidChangeVisibleRanges.fire({ view, state }); - }); - this._views.add(view); - return view; - } - - public detachView(view: model.IAttachedView): void { - this._views.delete(view as AttachedViewImpl); - this._onDidChangeVisibleRanges.fire({ view, state: undefined }); - } -} - -/** - * @internal - */ -export interface IAttachedViewState { - readonly visibleLineRanges: readonly LineRange[]; - readonly stabilized: boolean; -} - -class AttachedViewImpl implements model.IAttachedView { - constructor(private readonly handleStateChange: (state: IAttachedViewState) => void) { } - setVisibleLines(visibleLines: { startLineNumber: number; endLineNumber: number }[], stabilized: boolean): void { - const visibleLineRanges = visibleLines.map((line) => new LineRange(line.startLineNumber, line.endLineNumber + 1)); - this.handleStateChange({ visibleLineRanges, stabilized }); - } -} diff --git a/src/vs/editor/common/model/tokenizationTextModelPart.ts b/src/vs/editor/common/model/tokenizationTextModelPart.ts index eda1fbb2ffbf5..d4a7f0e8b5aa4 100644 --- a/src/vs/editor/common/model/tokenizationTextModelPart.ts +++ b/src/vs/editor/common/model/tokenizationTextModelPart.ts @@ -3,12 +3,10 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { equals } from 'vs/base/common/arrays'; -import { RunOnceScheduler } from 'vs/base/common/async'; import { CharCode } from 'vs/base/common/charCode'; import { BugIndicatingError, onUnexpectedError } from 'vs/base/common/errors'; import { Emitter, Event } from 'vs/base/common/event'; -import { Disposable, DisposableMap, MutableDisposable } from 'vs/base/common/lifecycle'; +import { MutableDisposable } from 'vs/base/common/lifecycle'; import { countEOL } from 'vs/editor/common/core/eolCounter'; import { LineRange } from 'vs/editor/common/core/lineRange'; import { IPosition, Position } from 'vs/editor/common/core/position'; @@ -18,11 +16,11 @@ import { StandardTokenType } from 'vs/editor/common/encodedTokenAttributes'; import { IBackgroundTokenizationStore, IBackgroundTokenizer, ILanguageIdCodec, IState, ITokenizationSupport, TokenizationRegistry, TreeSitterTokenizationRegistry } from 'vs/editor/common/languages'; import { ILanguageService } from 'vs/editor/common/languages/language'; import { ILanguageConfigurationService, ResolvedLanguageConfiguration } from 'vs/editor/common/languages/languageConfigurationRegistry'; -import { IAttachedView } from 'vs/editor/common/model'; import { BracketPairsTextModelPart } from 'vs/editor/common/model/bracketPairsTextModelPart/bracketPairsImpl'; -import { AttachedViews, IAttachedViewState, TextModel } from 'vs/editor/common/model/textModel'; +import { TextModel } from 'vs/editor/common/model/textModel'; import { TextModelPart } from 'vs/editor/common/model/textModelPart'; import { DefaultBackgroundTokenizer, TokenizerWithStateStoreAndTextModel, TrackingTokenizationStateStore } from 'vs/editor/common/model/textModelTokens'; +import { AbstractTokens, AttachedViews } from 'vs/editor/common/model/tokens'; import { TreeSitterTokens } from 'vs/editor/common/model/treeSitterTokens'; import { ITreeSitterTokenizationService } from 'vs/editor/common/services/treeSitterTokenizationFeature'; import { IModelContentChangedEvent, IModelLanguageChangedEvent, IModelLanguageConfigurationChangedEvent, IModelTokensChangedEvent } from 'vs/editor/common/textModelEvents'; @@ -52,8 +50,7 @@ export class TokenizationTextModelPart extends TextModelPart implements ITokeniz private readonly _onDidChangeTokens: Emitter = this._register(new Emitter()); public readonly onDidChangeTokens: Event = this._onDidChangeTokens.event; - private grammarTokens: GrammarTokens | undefined; - private treeSitterTokens: TreeSitterTokens | undefined; + private tokens!: AbstractTokens; constructor( private readonly _languageService: ILanguageService, @@ -79,37 +76,38 @@ export class TokenizationTextModelPart extends TextModelPart implements ITokeniz } private createGrammarTokens() { - this.grammarTokens = this._register(new GrammarTokens(this._languageService.languageIdCodec, this._textModel, () => this._languageId, this._attachedViews)); - this._register(this.grammarTokens.onDidChangeTokens(e => { + return this._register(new GrammarTokens(this._languageService.languageIdCodec, this._textModel, () => this._languageId, this._attachedViews)); + } + + private createTreeSitterTokens(): AbstractTokens { + return this._register(new TreeSitterTokens(this._fileService, this._themeService, this._treeSitterService, this._languageService.languageIdCodec, this._textModel, () => this._languageId, this._attachedViews)); + } + + private createTokens(useTreeSitter: boolean): void { + this.tokens?.dispose(); + this.tokens = useTreeSitter ? this.createTreeSitterTokens() : this.createGrammarTokens(); + this._register(this.tokens.onDidChangeTokens(e => { this._emitModelTokensChangedEvent(e); })); - this._register(this.grammarTokens.onDidChangeBackgroundTokenizationState(e => { + this._register(this.tokens.onDidChangeBackgroundTokenizationState(e => { this._bracketPairsTextModelPart.handleDidChangeBackgroundTokenizationState(); })); } - private createTreeSitterTokens() { - this.treeSitterTokens = this._register(new TreeSitterTokens(this._fileService, this._themeService, this._treeSitterService, this._languageService.languageIdCodec, this._textModel, () => this._languageId)); - } - private createPreferredTokenProvider() { const preferTreeSitter: string[] = this._configurationService.getValue(TOKENIZATION_PROVIDER_SETTING) ?? []; if ((preferTreeSitter.includes(this._languageId) && TreeSitterTokenizationRegistry.get(this._languageId))) { - if (this.treeSitterTokens) { - this.treeSitterTokens.resetTokenization(true); + if (this.tokens instanceof TreeSitterTokens) { + this.tokens.resetTokenization(true); } else { - this.grammarTokens?.dispose(); - this.grammarTokens = undefined; - this.createTreeSitterTokens(); + this.createTokens(true); } } else { - if (this.grammarTokens) { - this.grammarTokens.resetTokenization(true); + if (this.tokens instanceof GrammarTokens) { + this.tokens.resetTokenization(true); } else { - this.treeSitterTokens?.dispose(); - this.treeSitterTokens = undefined; - this.createGrammarTokens(); + this.createTokens(false); } } } @@ -137,11 +135,11 @@ export class TokenizationTextModelPart extends TextModelPart implements ITokeniz } } - this.grammarTokens?.handleDidChangeContent(e); + this.tokens.handleDidChangeContent(e); } public handleDidChangeAttached(): void { - this.grammarTokens?.handleDidChangeAttached(); + this.tokens.handleDidChangeAttached(); } /** @@ -149,7 +147,7 @@ export class TokenizationTextModelPart extends TextModelPart implements ITokeniz */ public getLineTokens(lineNumber: number): LineTokens { this.validateLineNumber(lineNumber); - const syntacticTokens = (this.treeSitterTokens?.getLineTokens(lineNumber) ?? this.grammarTokens?.getLineTokens(lineNumber))!; + const syntacticTokens = this.tokens.getLineTokens(lineNumber); return this._semanticTokens.addSparseTokens(lineNumber, syntacticTokens); } @@ -169,43 +167,43 @@ export class TokenizationTextModelPart extends TextModelPart implements ITokeniz } public get hasTokens(): boolean { - return !!this.grammarTokens?.hasTokens; + return !!this.tokens.hasTokens; } public resetTokenization() { - this.grammarTokens?.resetTokenization(); + this.tokens.resetTokenization(); } public get backgroundTokenizationState() { - return this.grammarTokens?.backgroundTokenizationState ?? BackgroundTokenizationState.InProgress; + return this.tokens.backgroundTokenizationState ?? BackgroundTokenizationState.InProgress; } public forceTokenization(lineNumber: number): void { this.validateLineNumber(lineNumber); - this.grammarTokens?.forceTokenization(lineNumber); + this.tokens.forceTokenization(lineNumber); } public hasAccurateTokensForLine(lineNumber: number): boolean { this.validateLineNumber(lineNumber); - return !!this.grammarTokens?.hasAccurateTokensForLine(lineNumber); + return !!this.tokens.hasAccurateTokensForLine(lineNumber); } public isCheapToTokenize(lineNumber: number): boolean { this.validateLineNumber(lineNumber); - return !!this.grammarTokens?.isCheapToTokenize(lineNumber); + return !!this.tokens.isCheapToTokenize(lineNumber); } public tokenizeIfCheap(lineNumber: number): void { this.validateLineNumber(lineNumber); - this.grammarTokens?.tokenizeIfCheap(lineNumber); + this.tokens.tokenizeIfCheap(lineNumber); } public getTokenTypeIfInsertingCharacter(lineNumber: number, column: number, character: string): StandardTokenType { - return this.grammarTokens?.getTokenTypeIfInsertingCharacter(lineNumber, column, character) ?? StandardTokenType.Other; + return this.tokens.getTokenTypeIfInsertingCharacter(lineNumber, column, character) ?? StandardTokenType.Other; } public tokenizeLineWithEdit(position: IPosition, length: number, newText: string): LineTokens | null { - return this.grammarTokens?.tokenizeLineWithEdit(position, length, newText) ?? null; + return this.tokens.tokenizeLineWithEdit(position, length, newText) ?? null; } // #endregion @@ -378,7 +376,7 @@ export class TokenizationTextModelPart extends TextModelPart implements ITokeniz // #endregion } -class GrammarTokens extends Disposable { +class GrammarTokens extends AbstractTokens { private _tokenizer: TokenizerWithStateStoreAndTextModel | null = null; private _defaultBackgroundTokenizer: DefaultBackgroundTokenizer | null = null; private readonly _backgroundTokenizer = this._register(new MutableDisposable()); @@ -389,51 +387,13 @@ class GrammarTokens extends Disposable { private readonly _debugBackgroundTokenizer = this._register(new MutableDisposable()); - private _backgroundTokenizationState = BackgroundTokenizationState.InProgress; - public get backgroundTokenizationState(): BackgroundTokenizationState { - return this._backgroundTokenizationState; - } - - private readonly _onDidChangeBackgroundTokenizationState = this._register(new Emitter()); - /** @internal, should not be exposed by the text model! */ - public readonly onDidChangeBackgroundTokenizationState: Event = this._onDidChangeBackgroundTokenizationState.event; - - private readonly _onDidChangeTokens = this._register(new Emitter()); - /** @internal, should not be exposed by the text model! */ - public readonly onDidChangeTokens: Event = this._onDidChangeTokens.event; - - private readonly _attachedViewStates = this._register(new DisposableMap()); - constructor( - private readonly _languageIdCodec: ILanguageIdCodec, - private readonly _textModel: TextModel, - private getLanguageId: () => string, + languageIdCodec: ILanguageIdCodec, + textModel: TextModel, + getLanguageId: () => string, attachedViews: AttachedViews, ) { - super(); - - this._register(TokenizationRegistry.onDidChange((e) => { - const languageId = this.getLanguageId(); - if (e.changedLanguages.indexOf(languageId) === -1) { - return; - } - this.resetTokenization(); - })); - - this.resetTokenization(); - - this._register(attachedViews.onDidChangeVisibleRanges(({ view, state }) => { - if (state) { - let existing = this._attachedViewStates.get(view); - if (!existing) { - existing = new AttachedViewHandler(() => this.refreshRanges(existing!.lineRanges)); - this._attachedViewStates.set(view, existing); - } - existing.handleStateChange(state); - } else { - this._attachedViewStates.deleteAndDispose(view); - } - })); + super(languageIdCodec, textModel, getLanguageId, attachedViews); } public resetTokenization(fireTokenChangeEvent: boolean = true): void { @@ -579,7 +539,7 @@ class GrammarTokens extends Disposable { this.refreshRanges(ranges); } - private refreshRanges(ranges: readonly LineRange[]): void { + protected refreshRanges(ranges: readonly LineRange[]): void { for (const range of ranges) { this.refreshRange(range.startLineNumber, range.endLineNumberExclusive - 1); } @@ -630,12 +590,6 @@ class GrammarTokens extends Disposable { return this._tokenizer.isCheapToTokenize(lineNumber); } - public tokenizeIfCheap(lineNumber: number): void { - if (this.isCheapToTokenize(lineNumber)) { - this.forceTokenization(lineNumber); - } - } - public getLineTokens(lineNumber: number): LineTokens { const lineText = this._textModel.getLineContent(lineNumber); const result = this._tokens.getTokens( @@ -682,33 +636,3 @@ class GrammarTokens extends Disposable { return this._tokens.hasTokens; } } - -class AttachedViewHandler extends Disposable { - private readonly runner = this._register(new RunOnceScheduler(() => this.update(), 50)); - - private _computedLineRanges: readonly LineRange[] = []; - private _lineRanges: readonly LineRange[] = []; - public get lineRanges(): readonly LineRange[] { return this._lineRanges; } - - constructor(private readonly _refreshTokens: () => void) { - super(); - } - - private update(): void { - if (equals(this._computedLineRanges, this._lineRanges, (a, b) => a.equals(b))) { - return; - } - this._computedLineRanges = this._lineRanges; - this._refreshTokens(); - } - - public handleStateChange(state: IAttachedViewState): void { - this._lineRanges = state.visibleLineRanges; - if (state.stabilized) { - this.runner.cancel(); - this.update(); - } else { - this.runner.schedule(); - } - } -} diff --git a/src/vs/editor/common/model/tokens.ts b/src/vs/editor/common/model/tokens.ts new file mode 100644 index 0000000000000..760e901fa1a20 --- /dev/null +++ b/src/vs/editor/common/model/tokens.ts @@ -0,0 +1,166 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { equals } from 'vs/base/common/arrays'; +import { RunOnceScheduler } from 'vs/base/common/async'; +import { Emitter, Event } from 'vs/base/common/event'; +import { Disposable, DisposableMap } from 'vs/base/common/lifecycle'; +import { LineRange } from 'vs/editor/common/core/lineRange'; +import { IPosition } from 'vs/editor/common/core/position'; +import { StandardTokenType } from 'vs/editor/common/encodedTokenAttributes'; +import { ILanguageIdCodec, TokenizationRegistry } from 'vs/editor/common/languages'; +import { IAttachedView } from 'vs/editor/common/model'; +import { TextModel } from 'vs/editor/common/model/textModel'; +import { IModelContentChangedEvent, IModelTokensChangedEvent } from 'vs/editor/common/textModelEvents'; +import { BackgroundTokenizationState } from 'vs/editor/common/tokenizationTextModelPart'; +import { LineTokens } from 'vs/editor/common/tokens/lineTokens'; + +/** + * @internal + */ +export class AttachedViews { + private readonly _onDidChangeVisibleRanges = new Emitter<{ view: IAttachedView; state: IAttachedViewState | undefined }>(); + public readonly onDidChangeVisibleRanges = this._onDidChangeVisibleRanges.event; + + private readonly _views = new Set(); + + public attachView(): IAttachedView { + const view = new AttachedViewImpl((state) => { + this._onDidChangeVisibleRanges.fire({ view, state }); + }); + this._views.add(view); + return view; + } + + public detachView(view: IAttachedView): void { + this._views.delete(view as AttachedViewImpl); + this._onDidChangeVisibleRanges.fire({ view, state: undefined }); + } +} + +/** + * @internal + */ +export interface IAttachedViewState { + readonly visibleLineRanges: readonly LineRange[]; + readonly stabilized: boolean; +} + +class AttachedViewImpl implements IAttachedView { + constructor(private readonly handleStateChange: (state: IAttachedViewState) => void) { } + + setVisibleLines(visibleLines: { startLineNumber: number; endLineNumber: number }[], stabilized: boolean): void { + const visibleLineRanges = visibleLines.map((line) => new LineRange(line.startLineNumber, line.endLineNumber + 1)); + this.handleStateChange({ visibleLineRanges, stabilized }); + } +} + + +export class AttachedViewHandler extends Disposable { + private readonly runner = this._register(new RunOnceScheduler(() => this.update(), 50)); + + private _computedLineRanges: readonly LineRange[] = []; + private _lineRanges: readonly LineRange[] = []; + public get lineRanges(): readonly LineRange[] { return this._lineRanges; } + + constructor(private readonly _refreshTokens: () => void) { + super(); + } + + private update(): void { + if (equals(this._computedLineRanges, this._lineRanges, (a, b) => a.equals(b))) { + return; + } + this._computedLineRanges = this._lineRanges; + this._refreshTokens(); + } + + public handleStateChange(state: IAttachedViewState): void { + this._lineRanges = state.visibleLineRanges; + if (state.stabilized) { + this.runner.cancel(); + this.update(); + } else { + this.runner.schedule(); + } + } +} + +export abstract class AbstractTokens extends Disposable { + protected _backgroundTokenizationState = BackgroundTokenizationState.InProgress; + public get backgroundTokenizationState(): BackgroundTokenizationState { + return this._backgroundTokenizationState; + } + + protected readonly _onDidChangeBackgroundTokenizationState = this._register(new Emitter()); + /** @internal, should not be exposed by the text model! */ + public readonly onDidChangeBackgroundTokenizationState: Event = this._onDidChangeBackgroundTokenizationState.event; + + protected readonly _onDidChangeTokens = this._register(new Emitter()); + /** @internal, should not be exposed by the text model! */ + public readonly onDidChangeTokens: Event = this._onDidChangeTokens.event; + + protected readonly _attachedViewStates = this._register(new DisposableMap()); + + constructor( + protected readonly _languageIdCodec: ILanguageIdCodec, + protected readonly _textModel: TextModel, + protected getLanguageId: () => string, + attachedViews: AttachedViews, + ) { + super(); + + this._register(TokenizationRegistry.onDidChange((e) => { + const languageId = this.getLanguageId(); + if (e.changedLanguages.indexOf(languageId) === -1) { + return; + } + this.resetTokenization(); + })); + + this.resetTokenization(); + + this._register(attachedViews.onDidChangeVisibleRanges(({ view, state }) => { + if (state) { + let existing = this._attachedViewStates.get(view); + if (!existing) { + existing = new AttachedViewHandler(() => this.refreshRanges(existing!.lineRanges)); + this._attachedViewStates.set(view, existing); + } + existing.handleStateChange(state); + } else { + this._attachedViewStates.deleteAndDispose(view); + } + })); + } + + public abstract resetTokenization(fireTokenChangeEvent?: boolean): void; + + public abstract handleDidChangeAttached(): void; + + public abstract handleDidChangeContent(e: IModelContentChangedEvent): void; + + protected abstract refreshRanges(ranges: readonly LineRange[]): void; + + public abstract forceTokenization(lineNumber: number): void; + + public abstract hasAccurateTokensForLine(lineNumber: number): boolean; + + public abstract isCheapToTokenize(lineNumber: number): boolean; + + public tokenizeIfCheap(lineNumber: number): void { + if (this.isCheapToTokenize(lineNumber)) { + this.forceTokenization(lineNumber); + } + } + + public abstract getLineTokens(lineNumber: number): LineTokens; + + public abstract getTokenTypeIfInsertingCharacter(lineNumber: number, column: number, character: string): StandardTokenType; + + public abstract tokenizeLineWithEdit(position: IPosition, length: number, newText: string): LineTokens | null; + + public abstract get hasTokens(): boolean; +} diff --git a/src/vs/editor/common/model/treeSitterTokens.ts b/src/vs/editor/common/model/treeSitterTokens.ts index ae189a1b7d5a2..38080d14277cf 100644 --- a/src/vs/editor/common/model/treeSitterTokens.ts +++ b/src/vs/editor/common/model/treeSitterTokens.ts @@ -10,14 +10,17 @@ import { LineTokens } from 'vs/editor/common/tokens/lineTokens'; import { IFileService } from 'vs/platform/files/common/files'; import { Parser } from 'vs/base/common/web-tree-sitter/tree-sitter-web'; import { IThemeService } from 'vs/platform/theme/common/themeService'; -import { FontStyle, MetadataConsts } from 'vs/editor/common/encodedTokenAttributes'; +import { FontStyle, MetadataConsts, StandardTokenType } from 'vs/editor/common/encodedTokenAttributes'; import { TokenStyle } from 'vs/platform/theme/common/tokenClassificationRegistry'; import { ColorThemeData } from 'vs/workbench/services/themes/common/colorThemeData'; import { TextModel } from 'vs/editor/common/model/textModel'; import { ITreeSitterTokenizationService } from 'vs/editor/common/services/treeSitterTokenizationFeature'; import { IModelContentChangedEvent } from 'vs/editor/common/textModelEvents'; +import { AbstractTokens, AttachedViews } from 'vs/editor/common/model/tokens'; +import { LineRange } from 'vs/editor/common/core/lineRange'; +import { IPosition } from 'vs/editor/common/core/position'; -export class TreeSitterTokens extends Disposable { +export class TreeSitterTokens extends AbstractTokens { private _colorThemeData: ColorThemeData; private _parser: Parser | undefined; private _language: Parser.Language | undefined; @@ -28,10 +31,11 @@ export class TreeSitterTokens extends Disposable { constructor(private readonly _fileService: IFileService, private readonly _themeService: IThemeService, private readonly _treeSitterService: ITreeSitterTokenizationService, - private readonly _languageIdCoded: ILanguageIdCodec, - private readonly _textModel: TextModel, - private readonly _languageId: () => string) { - super(); + languageIdCodec: ILanguageIdCodec, + textModel: TextModel, + languageId: () => string, + attachedViews: AttachedViews) { + super(languageIdCodec, textModel, languageId, attachedViews); // TODO @alexr00 respond to language changes this._initialize(); @@ -42,14 +46,13 @@ export class TreeSitterTokens extends Disposable { private async _initialize() { const parser = await this._getParser(); - const newLanguage = this._languageId(); + const newLanguage = this.getLanguageId(); const [language, queries] = await Promise.all([this._getLanguage(newLanguage), this._getQueries(newLanguage)]); parser.setLanguage(language); if (!this._tokens || this._lastLanguageId !== newLanguage) { this._tokens?.dispose(); this._tokens = new TextModelTokens(this._textModel, parser, queries, language, this._colorThemeData); } - } private async _getParser(): Promise { @@ -68,7 +71,7 @@ export class TreeSitterTokens extends Disposable { } private async _fetchLanguage() { - const grammarName = TreeSitterTokenizationRegistry.get(this._languageId()); + const grammarName = TreeSitterTokenizationRegistry.get(this.getLanguageId()); const wasmPath: AppResourcePath = `vs/base/common/treeSitterLanguages/${grammarName?.name}/${grammarName?.name}.wasm`; const languageFile = await (this._fileService.readFile(FileAccess.asFileUri(wasmPath))); return Parser.Language.load(languageFile.value.buffer); @@ -91,13 +94,67 @@ export class TreeSitterTokens extends Disposable { public getLineTokens(lineNumber: number): LineTokens { if (this._tokens) { - return new LineTokens(this._tokens.lineTokens(lineNumber), this._textModel.getLineContent(lineNumber), this._languageIdCoded); + return new LineTokens(this._tokens.lineTokens(lineNumber), this._textModel.getLineContent(lineNumber), this._languageIdCodec); } - return LineTokens.createEmpty('', this._languageIdCoded); + return LineTokens.createEmpty('', this._languageIdCodec); } public resetTokenization(fireTokenChangeEvent: boolean = true): void { - // TODO @alexr00 determine if needed + this._tokens?.reset(); + if (fireTokenChangeEvent) { + this._onDidChangeTokens.fire({ + semanticTokensApplied: false, + ranges: [ + { + fromLineNumber: 1, + toLineNumber: this._textModel.getLineCount(), + }, + ], + }); + } + } + + public override handleDidChangeAttached(): void { + // TODO @alexr00 implement for background tokenization + } + + public override handleDidChangeContent(e: IModelContentChangedEvent): void { + if (e.isFlush) { + // Don't fire the event, as the view might not have got the text change event yet + this.resetTokenization(false); + } else if (!e.isEolChange) { // We don't have to do anything on an EOL change + this._tokens?.onDidChangeContent(e); + } + } + protected override refreshRanges(ranges: readonly LineRange[]): void { + // TODO @alexr00 implement + } + + public override forceTokenization(lineNumber: number): void { + // TODO @alexr00 implement + } + + public override hasAccurateTokensForLine(lineNumber: number): boolean { + // TODO @alexr00 update for background tokenization + return true; + } + + public override isCheapToTokenize(lineNumber: number): boolean { + // TODO @alexr00 update for background tokenization + return true; + } + + public override getTokenTypeIfInsertingCharacter(lineNumber: number, column: number, character: string): StandardTokenType { + // TODO @alexr00 implement once we have custom parsing and don't just feed in the whole text model value + return StandardTokenType.Other; + } + public override tokenizeLineWithEdit(position: IPosition, length: number, newText: string): LineTokens | null { + // TODO @alexr00 understand what this is for and implement + return null; + } + public override get hasTokens(): boolean { + // TODO @alexr00 once we have a token store, implement properly + return true; } } @@ -116,10 +173,9 @@ class TextModelTokens extends Disposable { private readonly _language: Parser.Language, private readonly _colorThemeData: ColorThemeData) { super(); - this._register(this._textModel.onDidChangeContent((e) => this._onDidChangeContent(e))); } - private _onDidChangeContent(e: IModelContentChangedEvent) { + public onDidChangeContent(e: IModelContentChangedEvent) { if (!this._tree) { return; } @@ -152,6 +208,11 @@ class TextModelTokens extends Disposable { return this._query; } + public reset() { + this._tree = undefined; + this._parser.reset(); + } + /** * Gets the tokens for a given line. * Each token takes 2 elements in the array. The first element is the offset of the end of the token *in the line, not in the document*, and the second element is the metadata. From edde1847d5c02b0b576e681db47cb48b476e1e42 Mon Sep 17 00:00:00 2001 From: Alex Ross Date: Wed, 22 May 2024 11:47:48 +0200 Subject: [PATCH 06/37] Handle theme changes --- .../common/model/tokenizationTextModelPart.ts | 1 + src/vs/editor/common/model/tokens.ts | 2 -- src/vs/editor/common/model/treeSitterTokens.ts | 18 +++++++++++++----- 3 files changed, 14 insertions(+), 7 deletions(-) diff --git a/src/vs/editor/common/model/tokenizationTextModelPart.ts b/src/vs/editor/common/model/tokenizationTextModelPart.ts index d4a7f0e8b5aa4..96d94624c46f2 100644 --- a/src/vs/editor/common/model/tokenizationTextModelPart.ts +++ b/src/vs/editor/common/model/tokenizationTextModelPart.ts @@ -394,6 +394,7 @@ class GrammarTokens extends AbstractTokens { attachedViews: AttachedViews, ) { super(languageIdCodec, textModel, getLanguageId, attachedViews); + this.resetTokenization(); } public resetTokenization(fireTokenChangeEvent: boolean = true): void { diff --git a/src/vs/editor/common/model/tokens.ts b/src/vs/editor/common/model/tokens.ts index 760e901fa1a20..2d2be3710ef4e 100644 --- a/src/vs/editor/common/model/tokens.ts +++ b/src/vs/editor/common/model/tokens.ts @@ -120,8 +120,6 @@ export abstract class AbstractTokens extends Disposable { this.resetTokenization(); })); - this.resetTokenization(); - this._register(attachedViews.onDidChangeVisibleRanges(({ view, state }) => { if (state) { let existing = this._attachedViewStates.get(view); diff --git a/src/vs/editor/common/model/treeSitterTokens.ts b/src/vs/editor/common/model/treeSitterTokens.ts index 38080d14277cf..19e891f21132c 100644 --- a/src/vs/editor/common/model/treeSitterTokens.ts +++ b/src/vs/editor/common/model/treeSitterTokens.ts @@ -41,7 +41,10 @@ export class TreeSitterTokens extends AbstractTokens { // TODO @alexr00 remove the cast this._colorThemeData = this._themeService.getColorTheme() as ColorThemeData; - // TODO @alexr00 respond to theme changes + this._register(this._themeService.onDidColorThemeChange(() => { + this._colorThemeData = this._themeService.getColorTheme() as ColorThemeData; + this._tokens?.reset(this._colorThemeData); + })); } private async _initialize() { @@ -171,7 +174,7 @@ class TextModelTokens extends Disposable { private readonly _parser: Parser, private readonly _queries: string, private readonly _language: Parser.Language, - private readonly _colorThemeData: ColorThemeData) { + private _colorThemeData: ColorThemeData) { super(); } @@ -208,9 +211,14 @@ class TextModelTokens extends Disposable { return this._query; } - public reset() { - this._tree = undefined; - this._parser.reset(); + public reset(colorThemeData?: ColorThemeData) { + if (colorThemeData) { + this._colorThemeData = colorThemeData; + } else { + this._tree?.delete(); + this._tree = undefined; + this._parser.reset(); + } } /** From 5c20e642b5ba92319467ba8807f7932046950878 Mon Sep 17 00:00:00 2001 From: Alex Ross Date: Wed, 22 May 2024 12:54:41 +0200 Subject: [PATCH 07/37] Replace entire text model value with parse callback --- .../editor/common/model/treeSitterTokens.ts | 22 ++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/src/vs/editor/common/model/treeSitterTokens.ts b/src/vs/editor/common/model/treeSitterTokens.ts index 19e891f21132c..68563c0bd7b63 100644 --- a/src/vs/editor/common/model/treeSitterTokens.ts +++ b/src/vs/editor/common/model/treeSitterTokens.ts @@ -18,7 +18,8 @@ import { ITreeSitterTokenizationService } from 'vs/editor/common/services/treeSi import { IModelContentChangedEvent } from 'vs/editor/common/textModelEvents'; import { AbstractTokens, AttachedViews } from 'vs/editor/common/model/tokens'; import { LineRange } from 'vs/editor/common/core/lineRange'; -import { IPosition } from 'vs/editor/common/core/position'; +import { IPosition, Position } from 'vs/editor/common/core/position'; +import { Range } from 'vs/editor/common/core/range'; export class TreeSitterTokens extends AbstractTokens { private _colorThemeData: ColorThemeData; @@ -194,12 +195,27 @@ class TextModelTokens extends Disposable { newEndPosition: { row: newEndPosition.lineNumber - 1, column: newEndPosition.column - 1 } }); } - this._tree = this._parser.parse(this._textModel.getValue(), this._tree); + this._tree = this._parser.parse((index: number, position?: Parser.Point) => this._parseCallback(index, position), this._tree); + } + + private _parseCallback(index: number, position?: Parser.Point): string | null { + try { + const modelPositionStart: Position = position ? new Position(position.row + 1, position.column + 1) : this._textModel.getPositionAt(index); + let modelPositionEnd = this._textModel.getPositionAt(index + 1); + let value = this._textModel.getValueInRange(Range.fromPositions(modelPositionStart, modelPositionEnd)); + if (value.length === 0) { // When we hit the end of the line the value is an empty string, we need to get the next character. + modelPositionEnd = this._textModel.getPositionAt(index + 2); + value = this._textModel.getValueInRange(Range.fromPositions(modelPositionStart, modelPositionEnd)); + } + return value; + } catch (e) { + return null; + } } private _ensureTree() { if (!this._tree) { - this._tree = this._parser.parse(this._textModel.getValue()); + this._tree = this._parser.parse((index: number, position?: Parser.Point) => this._parseCallback(index, position)); } return this._tree; } From 4cd3e084a26e0940ddf3ff2d52994ce10dad6300 Mon Sep 17 00:00:00 2001 From: Alex Ross Date: Thu, 23 May 2024 10:31:31 +0200 Subject: [PATCH 08/37] Perf improvements --- .../editor/common/model/treeSitterTokens.ts | 26 +++++++++++++------ 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/src/vs/editor/common/model/treeSitterTokens.ts b/src/vs/editor/common/model/treeSitterTokens.ts index 68563c0bd7b63..87dbd6de6cae2 100644 --- a/src/vs/editor/common/model/treeSitterTokens.ts +++ b/src/vs/editor/common/model/treeSitterTokens.ts @@ -201,10 +201,10 @@ class TextModelTokens extends Disposable { private _parseCallback(index: number, position?: Parser.Point): string | null { try { const modelPositionStart: Position = position ? new Position(position.row + 1, position.column + 1) : this._textModel.getPositionAt(index); - let modelPositionEnd = this._textModel.getPositionAt(index + 1); - let value = this._textModel.getValueInRange(Range.fromPositions(modelPositionStart, modelPositionEnd)); - if (value.length === 0) { // When we hit the end of the line the value is an empty string, we need to get the next character. - modelPositionEnd = this._textModel.getPositionAt(index + 2); + const lineContent = this._textModel.getLineContent(modelPositionStart.lineNumber); + let value = lineContent.substring(modelPositionStart.column - 1); + if (value.length === 0 && (lineContent.length <= modelPositionStart.column)) { // When we hit the end of the line the value is an empty string, we need to get the next character. + const modelPositionEnd = this._textModel.getPositionAt(index + 2); value = this._textModel.getValueInRange(Range.fromPositions(modelPositionStart, modelPositionEnd)); } return value; @@ -248,7 +248,7 @@ class TextModelTokens extends Disposable { const tree = this._ensureTree(); const query = this._ensureQuery(); const lineLength = this._textModel.getLineMaxColumn(lineNumber); - const captures = query.captures(tree.rootNode, { startPosition: { row: lineNumber - 1, column: 0 }, endPosition: { row: lineNumber - 1, column: lineLength - 1 } }); + const captures = query.captures(tree.rootNode, { startPosition: { row: lineNumber - 1, column: 0 }, endPosition: { row: lineNumber - 1, column: lineLength } }); if (captures.length === 0 && lineLength > 0) { // No captures, but we always want to return at least one token for each line return new Uint32Array([lineLength, 0]); @@ -256,16 +256,18 @@ class TextModelTokens extends Disposable { let tokens: Uint32Array = new Uint32Array(captures.length * 2); let tokenIndex = 0; + const lineStartOffset = this._textModel.getOffsetAt({ lineNumber: lineNumber, column: 0 }); + for (let captureIndex = 0; captureIndex < captures.length; captureIndex++) { const capture = captures[captureIndex]; const metadata = this.findMetadata(capture.name); - const lineStartOffset = this._textModel.getOffsetAt({ lineNumber: lineNumber, column: 0 }); - const offset = this._textModel.getOffsetAt({ lineNumber: capture.node.endPosition.row + 1, column: capture.node.endPosition.column + 1 }) - lineStartOffset; + + const offset = capture.node.endIndex - lineStartOffset; // Not every character will get captured, so we need to make sure that our current capture doesn't bleed toward the start of the line and cover characters that it doesn't apply to. // We do this by creating a new token in the array if the previous token ends before the current token starts. if (captureIndex > 0) { const previousTokenEnd = tokens[(tokenIndex - 1) * 2]; - const currentTokenLength = capture.node.text.length; + const currentTokenLength = capture.node.endIndex - capture.node.startIndex; const intermediateTokenOffset = offset - currentTokenLength; if (previousTokenEnd < intermediateTokenOffset) { tokens[tokenIndex * 2] = intermediateTokenOffset; @@ -280,6 +282,14 @@ class TextModelTokens extends Disposable { tokens[tokenIndex * 2 + 1] = metadata; tokenIndex++; } + + if (captures[captures.length - 1].node.endPosition.column + 1 < lineLength) { + const newTokens = new Uint32Array(tokens.length + 2); + newTokens.set(tokens); + tokens = newTokens; + tokens[tokenIndex * 2] = lineLength; + tokens[tokenIndex * 2 + 1] = 0; + } return tokens; } From fef5067706d9f656b4bdae5b49bb919a5fbd688c Mon Sep 17 00:00:00 2001 From: Alex Ross Date: Thu, 23 May 2024 15:13:44 +0200 Subject: [PATCH 09/37] Add tree-sitter-typescript --- package.json | 1 + yarn.lock | 39 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 40 insertions(+) diff --git a/package.json b/package.json index 6b46533ca76a2..73be0c0ff9dee 100644 --- a/package.json +++ b/package.json @@ -207,6 +207,7 @@ "style-loader": "^3.3.2", "tree-sitter-cli": "^0.22.6", "tree-sitter-html": "^0.20.3", + "tree-sitter-typescript": "0.20.4", "ts-loader": "^9.4.2", "ts-node": "^10.9.1", "tsec": "0.2.7", diff --git a/yarn.lock b/yarn.lock index d0eb11f846e45..383fc57e63ce2 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7158,6 +7158,11 @@ nan@^2.12.1: resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.2.tgz#f5376400695168f4cc694ac9393d0c9585eeea19" integrity sha512-M2ufzIiINKCuDfBSAUr1vWQ+vuVcA9kqx8JJUsbQi6yf1uGRyb7HfpdfUr5qLXf3B/t8dPvcjhKMmlfnP47EzQ== +nan@^2.18.0: + version "2.19.0" + resolved "https://registry.yarnpkg.com/nan/-/nan-2.19.0.tgz#bb58122ad55a6c5bc973303908d5b16cfdd5a8c0" + integrity sha512-nO1xXxfh/RWNxfd/XPfbIfFk5vgLsAxUR9y5O0cHMJu/AW9U95JLXqthYHjEp+8gQ5p96K9jUp8nbVOxCdRbtw== + nanoid@3.3.3: version "3.3.3" resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.3.tgz#fd8e8b7aa761fe807dba2d1b98fb7241bb724a25" @@ -8282,6 +8287,24 @@ prebuild-install@7.1.1: tar-fs "^2.0.0" tunnel-agent "^0.6.0" +prebuild-install@^7.1.1: + version "7.1.2" + resolved "https://registry.yarnpkg.com/prebuild-install/-/prebuild-install-7.1.2.tgz#a5fd9986f5a6251fbc47e1e5c65de71e68c0a056" + integrity sha512-UnNke3IQb6sgarcZIDU3gbMeTp/9SSU1DAIkil7PrqG1vZlBtY5msYccSKSHDqa3hNg436IXK+SNImReuA1wEQ== + dependencies: + detect-libc "^2.0.0" + expand-template "^2.0.3" + github-from-package "0.0.0" + minimist "^1.2.3" + mkdirp-classic "^0.5.3" + napi-build-utils "^1.0.1" + node-abi "^3.3.0" + pump "^3.0.0" + rc "^1.2.7" + simple-get "^4.0.0" + tar-fs "^2.0.0" + tunnel-agent "^0.6.0" + prelude-ls@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396" @@ -9912,6 +9935,22 @@ tree-sitter-html@^0.20.3: node-addon-api "^8.0.0" node-gyp-build "^4.8.1" +tree-sitter-typescript@0.20.4: + version "0.20.4" + resolved "https://registry.yarnpkg.com/tree-sitter-typescript/-/tree-sitter-typescript-0.20.4.tgz#57f922ca5ccd740bc2f2ca3d82a40539f5809c93" + integrity sha512-pB5uk+Dr8ijsINYvZW37LijhHEIPObOVmMkElMBNxoEUaMiRzJEfjVIZUYdmkjUUCbp8B5CV3XVWfYp9iiEv5Q== + dependencies: + nan "^2.18.0" + tree-sitter "^0.20.6" + +tree-sitter@^0.20.6: + version "0.20.6" + resolved "https://registry.yarnpkg.com/tree-sitter/-/tree-sitter-0.20.6.tgz#fec52e5d7cc6c583135756479f2440dd89b25cbe" + integrity sha512-GxJodajVpfgb3UREzzIbtA1hyRnTxVbWVXrbC6sk4xTMH5ERMBJk9HJNq4c8jOJeUaIOmLcwg+t6mez/PDvGqg== + dependencies: + nan "^2.18.0" + prebuild-install "^7.1.1" + ts-api-utils@^1.0.1: version "1.3.0" resolved "https://registry.yarnpkg.com/ts-api-utils/-/ts-api-utils-1.3.0.tgz#4b490e27129f1e8e686b45cc4ab63714dc60eea1" From 5c65dfa4ee3bd8850ddfc0cd1ae2d1b5a8247c35 Mon Sep 17 00:00:00 2001 From: Alex Ross Date: Fri, 24 May 2024 10:20:52 +0200 Subject: [PATCH 10/37] Add typescript + better initial parsing --- .../tree-sitter-typescript/highlights.scm | 4 ++++ .../tree-sitter-typescript.wasm | Bin 0 -> 2310637 bytes .../treeSitterTokenizationFeatureImpl.ts | 1 + .../editor/common/model/treeSitterTokens.ts | 11 +++++++++-- 4 files changed, 14 insertions(+), 2 deletions(-) create mode 100644 src/vs/base/common/treeSitterLanguages/tree-sitter-typescript/highlights.scm create mode 100644 src/vs/base/common/treeSitterLanguages/tree-sitter-typescript/tree-sitter-typescript.wasm diff --git a/src/vs/base/common/treeSitterLanguages/tree-sitter-typescript/highlights.scm b/src/vs/base/common/treeSitterLanguages/tree-sitter-typescript/highlights.scm new file mode 100644 index 0000000000000..414c20b9af52a --- /dev/null +++ b/src/vs/base/common/treeSitterLanguages/tree-sitter-typescript/highlights.scm @@ -0,0 +1,4 @@ +; Variables + +(identifier) @variable + diff --git a/src/vs/base/common/treeSitterLanguages/tree-sitter-typescript/tree-sitter-typescript.wasm b/src/vs/base/common/treeSitterLanguages/tree-sitter-typescript/tree-sitter-typescript.wasm new file mode 100644 index 0000000000000000000000000000000000000000..5f295f05d97fdb307e3d6fceb63463af047d07ea GIT binary patch literal 2310637 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

04B~rFA~`I*S+f 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%0Dx70I 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

xspb}X5Zl8St`64| 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%0DASUgWiI>-4$7#s-V&ENN$4ihO0s1|_CyFY}>X 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 C4+O;k literal 0 HcmV?d00001 diff --git a/src/vs/editor/browser/services/treeSitter/treeSitterTokenizationFeatureImpl.ts b/src/vs/editor/browser/services/treeSitter/treeSitterTokenizationFeatureImpl.ts index 9b24f062344a5..1bc581100b2a1 100644 --- a/src/vs/editor/browser/services/treeSitter/treeSitterTokenizationFeatureImpl.ts +++ b/src/vs/editor/browser/services/treeSitter/treeSitterTokenizationFeatureImpl.ts @@ -21,6 +21,7 @@ export class TreeSitterTokenizationService implements ITreeSitterTokenizationSer }); // Eventually, this should actually use an extension point to add tree sitter grammars, but for now they are hard coded in core this._addGrammar('html', 'tree-sitter-html'); + this._addGrammar('typescript', 'tree-sitter-typescript'); } public initTreeSitter(): Promise { diff --git a/src/vs/editor/common/model/treeSitterTokens.ts b/src/vs/editor/common/model/treeSitterTokens.ts index 87dbd6de6cae2..c6dcf2627c95f 100644 --- a/src/vs/editor/common/model/treeSitterTokens.ts +++ b/src/vs/editor/common/model/treeSitterTokens.ts @@ -20,6 +20,7 @@ import { AbstractTokens, AttachedViews } from 'vs/editor/common/model/tokens'; import { LineRange } from 'vs/editor/common/core/lineRange'; import { IPosition, Position } from 'vs/editor/common/core/position'; import { Range } from 'vs/editor/common/core/range'; +import { ITextSnapshot } from 'vs/editor/common/model'; export class TreeSitterTokens extends AbstractTokens { private _colorThemeData: ColorThemeData; @@ -198,7 +199,10 @@ class TextModelTokens extends Disposable { this._tree = this._parser.parse((index: number, position?: Parser.Point) => this._parseCallback(index, position), this._tree); } - private _parseCallback(index: number, position?: Parser.Point): string | null { + private _parseCallback(index: number, position?: Parser.Point, snapshot?: ITextSnapshot): string | null { + if (snapshot) { + return snapshot.read(); + } try { const modelPositionStart: Position = position ? new Position(position.row + 1, position.column + 1) : this._textModel.getPositionAt(index); const lineContent = this._textModel.getLineContent(modelPositionStart.lineNumber); @@ -215,7 +219,10 @@ class TextModelTokens extends Disposable { private _ensureTree() { if (!this._tree) { - this._tree = this._parser.parse((index: number, position?: Parser.Point) => this._parseCallback(index, position)); + const timer = performance.now(); + const snapshot = this._textModel.createSnapshot(); + this._tree = this._parser.parse((index: number, position?: Parser.Point) => this._parseCallback(index, position, snapshot)); + console.log('Tree parsing took ' + (performance.now() - timer) + 'ms'); } return this._tree; } From c372e40b1cd90e09711cfc8fc091ce3f61213c81 Mon Sep 17 00:00:00 2001 From: Alex Ross Date: Mon, 27 May 2024 14:41:55 +0200 Subject: [PATCH 11/37] Refactor into tree parsing service and fix flaw in parse callback --- .../tree-sitter-typescript/highlights.scm | 3 +- .../treeSitter/treeSitterParserService.ts | 258 ++++++++++++++++++ .../treeSitterTokenizationFeatureImpl.ts | 34 --- src/vs/editor/common/model/textModel.ts | 19 +- .../common/model/tokenizationTextModelPart.ts | 10 +- .../editor/common/model/treeSitterTokens.ts | 128 ++------- src/vs/editor/common/services/modelService.ts | 13 +- .../services/treeSitterParserService.ts | 19 ++ .../services/treeSitterTokenizationFeature.ts | 13 - .../browser/peek/referencesWidget.ts | 11 +- .../browser/documentSemanticTokens.test.ts | 7 +- .../browser/services/testTreeSitterService.ts | 18 +- .../mainThreadDocumentsAndEditors.test.ts | 7 +- .../test/browser/mainThreadEditors.test.ts | 6 +- .../bulkEdit/browser/preview/bulkEditTree.ts | 12 +- .../services/model/common/modelService.ts | 10 +- ...eSitterTokenizationFeature.contribution.ts | 8 +- 17 files changed, 352 insertions(+), 224 deletions(-) create mode 100644 src/vs/editor/browser/services/treeSitter/treeSitterParserService.ts delete mode 100644 src/vs/editor/browser/services/treeSitter/treeSitterTokenizationFeatureImpl.ts create mode 100644 src/vs/editor/common/services/treeSitterParserService.ts delete mode 100644 src/vs/editor/common/services/treeSitterTokenizationFeature.ts diff --git a/src/vs/base/common/treeSitterLanguages/tree-sitter-typescript/highlights.scm b/src/vs/base/common/treeSitterLanguages/tree-sitter-typescript/highlights.scm index 414c20b9af52a..2fe6f45e4af1c 100644 --- a/src/vs/base/common/treeSitterLanguages/tree-sitter-typescript/highlights.scm +++ b/src/vs/base/common/treeSitterLanguages/tree-sitter-typescript/highlights.scm @@ -1,4 +1,3 @@ -; Variables - (identifier) @variable +(comment) @comment \ No newline at end of file diff --git a/src/vs/editor/browser/services/treeSitter/treeSitterParserService.ts b/src/vs/editor/browser/services/treeSitter/treeSitterParserService.ts new file mode 100644 index 0000000000000..4bd113f796ae7 --- /dev/null +++ b/src/vs/editor/browser/services/treeSitter/treeSitterParserService.ts @@ -0,0 +1,258 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { TreeSitterTokenizationRegistry } from 'vs/editor/common/languages'; +import { Parser } from 'vs/base/common/web-tree-sitter/tree-sitter-web'; +import { AppResourcePath, FileAccess } from 'vs/base/common/network'; +import { ITreeSitterParserService } from 'vs/editor/common/services/treeSitterParserService'; +import { IModelService } from 'vs/editor/common/services/model'; +import { Disposable, DisposableMap, DisposableStore, IDisposable } from 'vs/base/common/lifecycle'; +import { ITextModel, ITextSnapshot } from 'vs/editor/common/model'; +import { IFileService } from 'vs/platform/files/common/files'; +import { Position } from 'vs/editor/common/core/position'; +import { IModelContentChangedEvent, IModelLanguageChangedEvent } from 'vs/editor/common/textModelEvents'; +import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; +import { ILogService } from 'vs/platform/log/common/log'; +import { Range } from 'vs/editor/common/core/range'; + +export class TreeSitterTree implements IDisposable { + private _tree: Parser.Tree | undefined; + private _language: Parser.Language | undefined; + constructor(public readonly parser: Parser, private readonly disposables: DisposableStore) { } + dispose(): void { + this._tree?.delete(); + this.parser?.delete(); + this.disposables.dispose(); + } + get tree() { return this._tree; } + set tree(newTree: Parser.Tree | undefined) { + this._tree?.delete(); + this._tree = newTree; + this._snapshot = undefined; + this._snapshotChunks = []; + } + get language() { return this._language; } + set language(newLanguage: Parser.Language | undefined) { + this.parser?.setLanguage(newLanguage); + this._language = newLanguage; + if (this._language === undefined) { + this.tree = undefined; + } + } + private _snapshot: ITextSnapshot | undefined; + get snapshot() { return this._snapshot; } + public createSnapshot(textModel: ITextModel) { + this._snapshot = textModel.createSnapshot(); + } + public clearSnapshot() { + this._snapshot = undefined; + } + private _snapshotChunks: { chunk: string; startOffset: number }[] = []; + get snapshotChunks() { return this._snapshotChunks; } + public addSnapshotChunk(chunk: string, startOffset: number) { + this._snapshotChunks.push({ chunk, startOffset }); + } +} + +export class TreeSitterParserService extends Disposable implements ITreeSitterParserService { + readonly _serviceBrand: undefined; + private _init: Promise; + private _treeSitterTrees: DisposableMap = new DisposableMap(); + private _languages: Map = new Map(); + + constructor(@IModelService private readonly _modelService: IModelService, + @IFileService private readonly _fileService: IFileService, + @ITelemetryService private readonly _telemetryService: ITelemetryService, + @ILogService private readonly _logService: ILogService + ) { + super(); + this._init = Parser.init({ + locateFile(_file: string, _folder: string) { + const wasmPath: AppResourcePath = `vs/base/common/web-tree-sitter/tree-sitter.wasm`; + return FileAccess.asBrowserUri(wasmPath).toString(true); + } + }); + // Eventually, this should actually use an extension point to add tree sitter grammars, but for now they are hard coded in core + this._addGrammar('html', 'tree-sitter-html'); + this._addGrammar('typescript', 'tree-sitter-typescript'); + this._registerModelServiceListeners(); + + } + getLanguageLocation(languageId: string): AppResourcePath | undefined { + const grammarName = TreeSitterTokenizationRegistry.get(languageId); + if (!grammarName) { + return undefined; + } + const languageLocation: AppResourcePath = `vs/base/common/treeSitterLanguages/${grammarName?.name}`; + return languageLocation; + } + + private _registerModelServiceListeners() { + this._register(this._modelService.onModelAdded(model => { + this._registerModelListeners(model); + })); + this._register(this._modelService.onModelRemoved(model => { + this._treeSitterTrees.deleteAndDispose(model); + })); + this._modelService.getModels().forEach(model => this._registerModelListeners(model)); + } + + private async _registerModelListeners(model: ITextModel) { + await this._init; + const disposables = new DisposableStore(); + disposables.add(model.onDidChangeContent(e => this._onDidChangeContent(model, e))); + disposables.add(model.onDidChangeLanguage(e => this._onDidChangeLanguage(model, e))); + const parser = new Parser(); + const treeSitterTree = new TreeSitterTree(parser, disposables); + this._treeSitterTrees.set(model, treeSitterTree); + this._setLanguageAndTree(model, treeSitterTree); + } + + private async _setLanguageAndTree(model: ITextModel, treeSitterTree: TreeSitterTree) { + const languageId = model.getLanguageId(); + const language = await this._ensureLanguage(languageId); + if (!language) { + return; + } + treeSitterTree.language = language; + treeSitterTree.tree = this._doInitialParse(model, treeSitterTree, languageId); + } + + + private _doInitialParse(model: ITextModel, treeSitterTree: TreeSitterTree, language: string): Parser.Tree { + treeSitterTree.createSnapshot(model); + const timer = performance.now(); + const newTree = treeSitterTree.parser.parse((index: number, position?: Parser.Point) => this._parseCallback(model, index, position, treeSitterTree)); + this.sendParseTimeTelemetry('fullParse', language, performance.now() - timer); + return newTree; + } + + private sendParseTimeTelemetry(eventName: string, languageId: string, time: number): void { + this._logService.info(`Tree parsing (${eventName}) took ${time} ms`); + type ParseTimeClassification = { + owner: 'alros'; + comment: 'Used to understand how long it takes to parse a tree-sitter tree'; + languageId: { classification: 'SystemMetaData'; purpose: 'FeatureInsight'; comment: 'The programming language ID.' }; + time: { classification: 'SystemMetaData'; purpose: 'FeatureInsight'; comment: 'The ms it took to parse' }; + }; + this._telemetryService.publicLog2<{ languageId: string; time: number }, ParseTimeClassification>(`treeSitter.${eventName}`, { languageId, time }); + } + + private async _onDidChangeLanguage(model: ITextModel, e: IModelLanguageChangedEvent) { + const tree = this._treeSitterTrees.get(model); + if (!tree) { + return; + } + const language = await this._ensureLanguage(e.newLanguage); + if (!language) { + // not supported for this language + tree.language = undefined; + return; + } + tree.language = language; + const newTree = this._doInitialParse(model, tree, e.newLanguage); + tree.tree = newTree; + } + + private _onDidChangeContent(model: ITextModel, e: IModelContentChangedEvent) { + const tree = this._treeSitterTrees.get(model); + if (!tree?.language) { + return; + } + for (const change of e.changes) { + const newEndOffset = change.rangeOffset + change.text.length; + const newEndPosition = model.getPositionAt(newEndOffset); + // TODO @alexr00 need to take into account the previous edits in the loop (text edits class) + tree.tree?.edit({ + startIndex: change.rangeOffset, + oldEndIndex: change.rangeOffset + change.rangeLength, + newEndIndex: change.rangeOffset + change.text.length, + startPosition: { row: change.range.startLineNumber - 1, column: change.range.startColumn - 1 }, + oldEndPosition: { row: change.range.endLineNumber - 1, column: change.range.endColumn - 1 }, + newEndPosition: { row: newEndPosition.lineNumber - 1, column: newEndPosition.column - 1 } + }); + } + const timer = performance.now(); + tree.tree = tree.parser.parse((index: number, position?: Parser.Point) => this._parseCallback(model, index, position), tree.tree); + this.sendParseTimeTelemetry('incrementalParse', model.getLanguageId(), performance.now() - timer); + } + + private async _fetchLanguage(languageId: string): Promise { + const grammarName = TreeSitterTokenizationRegistry.get(languageId); + const languageLocation = this.getLanguageLocation(languageId); + if (!grammarName || !languageLocation) { + return undefined; + } + const wasmPath: AppResourcePath = `${languageLocation}/${grammarName.name}.wasm`; + const languageFile = await (this._fileService.readFile(FileAccess.asFileUri(wasmPath))); + return Parser.Language.load(languageFile.value.buffer); + } + + private async _ensureLanguage(languageId: string): Promise { + let language = this._languages.get(languageId); + if (!language) { + language = await this._fetchLanguage(languageId); + if (!language) { + return undefined; + } + this._languages.set(languageId, language); + } + return language; + } + + private _parseCallback(textModel: ITextModel, index: number, position?: Parser.Point, treeSitterTree?: TreeSitterTree): string | null { + if (treeSitterTree?.snapshot) { + for (let i = 0; i < treeSitterTree.snapshotChunks.length; i++) { + const snapshotChunk = treeSitterTree.snapshotChunks[i]; + if ((snapshotChunk.startOffset <= index) && (index < (snapshotChunk.chunk.length + snapshotChunk.startOffset))) { + return snapshotChunk.chunk.substring(index - snapshotChunk.startOffset); + } + } + + let readValue = treeSitterTree.snapshot.read(); + if (readValue === null) { + treeSitterTree.clearSnapshot(); + } else { + const startOffset = treeSitterTree.snapshotChunks.length === 0 ? 0 : treeSitterTree.snapshotChunks[treeSitterTree.snapshotChunks.length - 1].startOffset + treeSitterTree.snapshotChunks[treeSitterTree.snapshotChunks.length - 1].chunk.length; + treeSitterTree.addSnapshotChunk(readValue, startOffset); + readValue = readValue.substring(index - startOffset); + } + return readValue; + } + try { + const modelPositionStart: Position = position ? new Position(position.row + 1, position.column + 1) : textModel.getPositionAt(index); + const lineContent = textModel.getLineContent(modelPositionStart.lineNumber); + let value = lineContent.substring(modelPositionStart.column - 1); + if (value.length === 0 && (lineContent.length <= modelPositionStart.column)) { // When we hit the end of the line the value is an empty string, we need to get the next character. + const modelPositionEnd = textModel.getPositionAt(index + 2); + value = textModel.getValueInRange(Range.fromPositions(modelPositionStart, modelPositionEnd)); + } + return value; + } catch (e) { + return null; + } + } + + public initTreeSitter(): Promise { + return this._init; + } + + getTree(model: ITextModel): Parser.Tree | undefined { + return this._treeSitterTrees.get(model)?.tree; + } + + getLanguage(model: ITextModel): Parser.Language | undefined { + return this._treeSitterTrees.get(model)?.language; + } + + private _addGrammar(languageId: string, grammarName: string) { + TreeSitterTokenizationRegistry.register(languageId, { name: grammarName }); + } + + public override dispose(): void { + super.dispose(); + this._treeSitterTrees.dispose(); + } +} diff --git a/src/vs/editor/browser/services/treeSitter/treeSitterTokenizationFeatureImpl.ts b/src/vs/editor/browser/services/treeSitter/treeSitterTokenizationFeatureImpl.ts deleted file mode 100644 index 1bc581100b2a1..0000000000000 --- a/src/vs/editor/browser/services/treeSitter/treeSitterTokenizationFeatureImpl.ts +++ /dev/null @@ -1,34 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import { TreeSitterTokenizationRegistry } from 'vs/editor/common/languages'; -import { Parser } from 'vs/base/common/web-tree-sitter/tree-sitter-web'; -import { AppResourcePath, FileAccess } from 'vs/base/common/network'; -import { ITreeSitterTokenizationService } from 'vs/editor/common/services/treeSitterTokenizationFeature'; - -export class TreeSitterTokenizationService implements ITreeSitterTokenizationService { - readonly _serviceBrand: undefined; - private _init: Promise; - - constructor() { - this._init = Parser.init({ - locateFile(_file: string, _folder: string) { - const wasmPath: AppResourcePath = `vs/base/common/web-tree-sitter/tree-sitter.wasm`; - return FileAccess.asBrowserUri(wasmPath).toString(true); - } - }); - // Eventually, this should actually use an extension point to add tree sitter grammars, but for now they are hard coded in core - this._addGrammar('html', 'tree-sitter-html'); - this._addGrammar('typescript', 'tree-sitter-typescript'); - } - - public initTreeSitter(): Promise { - return this._init; - } - - private _addGrammar(languageId: string, grammarName: string) { - TreeSitterTokenizationRegistry.register(languageId, { name: grammarName }); - } -} diff --git a/src/vs/editor/common/model/textModel.ts b/src/vs/editor/common/model/textModel.ts index 8dbfa3018a831..b96243b28df7f 100644 --- a/src/vs/editor/common/model/textModel.ts +++ b/src/vs/editor/common/model/textModel.ts @@ -39,14 +39,12 @@ import { PieceTreeTextBufferBuilder } from 'vs/editor/common/model/pieceTreeText import { SearchParams, TextModelSearch } from 'vs/editor/common/model/textModelSearch'; import { TokenizationTextModelPart } from 'vs/editor/common/model/tokenizationTextModelPart'; import { AttachedViews } from 'vs/editor/common/model/tokens'; -import { ITreeSitterTokenizationService } from 'vs/editor/common/services/treeSitterTokenizationFeature'; import { IBracketPairsTextModelPart } from 'vs/editor/common/textModelBracketPairs'; import { IModelContentChangedEvent, IModelDecorationsChangedEvent, IModelOptionsChangedEvent, InternalModelContentChangeEvent, LineInjectedText, ModelInjectedTextChangedEvent, ModelRawChange, ModelRawContentChangedEvent, ModelRawEOLChanged, ModelRawFlush, ModelRawLineChanged, ModelRawLinesDeleted, ModelRawLinesInserted } from 'vs/editor/common/textModelEvents'; import { IGuidesTextModelPart } from 'vs/editor/common/textModelGuides'; import { ITokenizationTextModelPart } from 'vs/editor/common/tokenizationTextModelPart'; -import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; -import { IFileService } from 'vs/platform/files/common/files'; -import { IColorTheme, IThemeService } from 'vs/platform/theme/common/themeService'; +import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; +import { IColorTheme } from 'vs/platform/theme/common/themeService'; import { IUndoRedoService, ResourceEditStackSnapshot, UndoRedoGroup } from 'vs/platform/undoRedo/common/undoRedo'; export function createTextBufferFactory(text: string): model.ITextBufferFactory { @@ -302,10 +300,7 @@ export class TextModel extends Disposable implements model.ITextModel, IDecorati @IUndoRedoService private readonly _undoRedoService: IUndoRedoService, @ILanguageService private readonly _languageService: ILanguageService, @ILanguageConfigurationService private readonly _languageConfigurationService: ILanguageConfigurationService, - @IConfigurationService configurationService: IConfigurationService, - @IFileService fileService: IFileService, - @IThemeService themeService: IThemeService, - @ITreeSitterTokenizationService treeSitterService: ITreeSitterTokenizationService, + @IInstantiationService private readonly instantiationService: IInstantiationService ) { super(); @@ -334,17 +329,13 @@ export class TextModel extends Disposable implements model.ITextModel, IDecorati this._bracketPairs = this._register(new BracketPairsTextModelPart(this, this._languageConfigurationService)); this._guidesTextModelPart = this._register(new GuidesTextModelPart(this, this._languageConfigurationService)); this._decorationProvider = this._register(new ColorizedBracketPairsDecorationProvider(this)); - this._tokenizationTextModelPart = new TokenizationTextModelPart( + this._tokenizationTextModelPart = this.instantiationService.createInstance(TokenizationTextModelPart, this._languageService, this._languageConfigurationService, this, this._bracketPairs, languageId, - this._attachedViews, - configurationService, - fileService, - themeService, - treeSitterService + this._attachedViews ); const bufferLineCount = this._buffer.getLineCount(); diff --git a/src/vs/editor/common/model/tokenizationTextModelPart.ts b/src/vs/editor/common/model/tokenizationTextModelPart.ts index 96d94624c46f2..cb245c39c5986 100644 --- a/src/vs/editor/common/model/tokenizationTextModelPart.ts +++ b/src/vs/editor/common/model/tokenizationTextModelPart.ts @@ -22,7 +22,7 @@ import { TextModelPart } from 'vs/editor/common/model/textModelPart'; import { DefaultBackgroundTokenizer, TokenizerWithStateStoreAndTextModel, TrackingTokenizationStateStore } from 'vs/editor/common/model/textModelTokens'; import { AbstractTokens, AttachedViews } from 'vs/editor/common/model/tokens'; import { TreeSitterTokens } from 'vs/editor/common/model/treeSitterTokens'; -import { ITreeSitterTokenizationService } from 'vs/editor/common/services/treeSitterTokenizationFeature'; +import { ITreeSitterParserService } from 'vs/editor/common/services/treeSitterParserService'; import { IModelContentChangedEvent, IModelLanguageChangedEvent, IModelLanguageConfigurationChangedEvent, IModelTokensChangedEvent } from 'vs/editor/common/textModelEvents'; import { BackgroundTokenizationState, ITokenizationTextModelPart } from 'vs/editor/common/tokenizationTextModelPart'; import { ContiguousMultilineTokens } from 'vs/editor/common/tokens/contiguousMultilineTokens'; @@ -59,10 +59,10 @@ export class TokenizationTextModelPart extends TextModelPart implements ITokeniz private readonly _bracketPairsTextModelPart: BracketPairsTextModelPart, private _languageId: string, private readonly _attachedViews: AttachedViews, - private readonly _configurationService: IConfigurationService, - private readonly _fileService: IFileService, - private readonly _themeService: IThemeService, - private readonly _treeSitterService: ITreeSitterTokenizationService, + @IConfigurationService private readonly _configurationService: IConfigurationService, + @IFileService private readonly _fileService: IFileService, + @IThemeService private readonly _themeService: IThemeService, + @ITreeSitterParserService private readonly _treeSitterService: ITreeSitterParserService, ) { super(); diff --git a/src/vs/editor/common/model/treeSitterTokens.ts b/src/vs/editor/common/model/treeSitterTokens.ts index c6dcf2627c95f..29d2a3841e14e 100644 --- a/src/vs/editor/common/model/treeSitterTokens.ts +++ b/src/vs/editor/common/model/treeSitterTokens.ts @@ -5,7 +5,7 @@ import { Disposable } from 'vs/base/common/lifecycle'; import { AppResourcePath, FileAccess } from 'vs/base/common/network'; -import { ILanguageIdCodec, TreeSitterTokenizationRegistry } from 'vs/editor/common/languages'; +import { ILanguageIdCodec } from 'vs/editor/common/languages'; import { LineTokens } from 'vs/editor/common/tokens/lineTokens'; import { IFileService } from 'vs/platform/files/common/files'; import { Parser } from 'vs/base/common/web-tree-sitter/tree-sitter-web'; @@ -14,25 +14,21 @@ import { FontStyle, MetadataConsts, StandardTokenType } from 'vs/editor/common/e import { TokenStyle } from 'vs/platform/theme/common/tokenClassificationRegistry'; import { ColorThemeData } from 'vs/workbench/services/themes/common/colorThemeData'; import { TextModel } from 'vs/editor/common/model/textModel'; -import { ITreeSitterTokenizationService } from 'vs/editor/common/services/treeSitterTokenizationFeature'; +import { ITreeSitterParserService } from 'vs/editor/common/services/treeSitterParserService'; import { IModelContentChangedEvent } from 'vs/editor/common/textModelEvents'; import { AbstractTokens, AttachedViews } from 'vs/editor/common/model/tokens'; import { LineRange } from 'vs/editor/common/core/lineRange'; -import { IPosition, Position } from 'vs/editor/common/core/position'; -import { Range } from 'vs/editor/common/core/range'; -import { ITextSnapshot } from 'vs/editor/common/model'; +import { IPosition } from 'vs/editor/common/core/position'; export class TreeSitterTokens extends AbstractTokens { private _colorThemeData: ColorThemeData; - private _parser: Parser | undefined; - private _language: Parser.Language | undefined; private _queries: string | undefined; private _tokens: TextModelTokens | undefined; private _lastLanguageId: string | undefined; constructor(private readonly _fileService: IFileService, private readonly _themeService: IThemeService, - private readonly _treeSitterService: ITreeSitterTokenizationService, + private readonly _treeSitterService: ITreeSitterParserService, languageIdCodec: ILanguageIdCodec, textModel: TextModel, languageId: () => string, @@ -50,38 +46,14 @@ export class TreeSitterTokens extends AbstractTokens { } private async _initialize() { - const parser = await this._getParser(); const newLanguage = this.getLanguageId(); - const [language, queries] = await Promise.all([this._getLanguage(newLanguage), this._getQueries(newLanguage)]); - parser.setLanguage(language); + const queries = await this._getQueries(newLanguage); if (!this._tokens || this._lastLanguageId !== newLanguage) { this._tokens?.dispose(); - this._tokens = new TextModelTokens(this._textModel, parser, queries, language, this._colorThemeData); + this._tokens = new TextModelTokens(this._treeSitterService, this._textModel, queries, this._colorThemeData); } } - private async _getParser(): Promise { - if (!this._parser) { - await this._treeSitterService.initTreeSitter(); - this._parser = new Parser(); - } - return this._parser; - } - - private async _getLanguage(newLanguage: string): Promise { - if (!this._language || this._lastLanguageId !== newLanguage) { - this._language = await this._fetchLanguage(); - } - return this._language; - } - - private async _fetchLanguage() { - const grammarName = TreeSitterTokenizationRegistry.get(this.getLanguageId()); - const wasmPath: AppResourcePath = `vs/base/common/treeSitterLanguages/${grammarName?.name}/${grammarName?.name}.wasm`; - const languageFile = await (this._fileService.readFile(FileAccess.asFileUri(wasmPath))); - return Parser.Language.load(languageFile.value.buffer); - } - private async _getQueries(newLanguage: string): Promise { if (!this._queries || this._lastLanguageId !== newLanguage) { this._queries = await this._fetchQueries(newLanguage); @@ -90,13 +62,15 @@ export class TreeSitterTokens extends AbstractTokens { } private async _fetchQueries(newLanguage: string): Promise { - const grammarName = TreeSitterTokenizationRegistry.get(newLanguage); - const scmPath: AppResourcePath = `vs/base/common/treeSitterLanguages/${grammarName?.name}/highlights.scm`; + const languageLocation = this._treeSitterService.getLanguageLocation(newLanguage); + if (!languageLocation) { + throw new Error(`No language location for ${newLanguage}`); + } + const scmPath: AppResourcePath = `${languageLocation}/highlights.scm`; const query = await this._fileService.readFile(FileAccess.asFileUri(scmPath)); return query.value.toString(); } - public getLineTokens(lineNumber: number): LineTokens { if (this._tokens) { return new LineTokens(this._tokens.lineTokens(lineNumber), this._textModel.getLineContent(lineNumber), this._languageIdCodec); @@ -127,8 +101,6 @@ export class TreeSitterTokens extends AbstractTokens { if (e.isFlush) { // Don't fire the event, as the view might not have got the text change event yet this.resetTokenization(false); - } else if (!e.isEolChange) { // We don't have to do anything on an EOL change - this._tokens?.onDidChangeContent(e); } } protected override refreshRanges(ranges: readonly LineRange[]): void { @@ -159,77 +131,34 @@ export class TreeSitterTokens extends AbstractTokens { } public override get hasTokens(): boolean { // TODO @alexr00 once we have a token store, implement properly - return true; + const hasTree = this._treeSitterService.getTree(this._textModel) !== undefined; + return hasTree; } } - -/** - * For handling the text model changes. - */ class TextModelTokens extends Disposable { - private _tree: Parser.Tree | undefined; private _query: Parser.Query | undefined; - constructor(private readonly _textModel: TextModel, - private readonly _parser: Parser, + constructor( + private readonly _treeSitterService: ITreeSitterParserService, + private readonly _textModel: TextModel, private readonly _queries: string, - private readonly _language: Parser.Language, private _colorThemeData: ColorThemeData) { super(); } - public onDidChangeContent(e: IModelContentChangedEvent) { - if (!this._tree) { - return; - } - for (const change of e.changes) { - const newEndOffset = change.rangeOffset + change.text.length; - const newEndPosition = this._textModel.getPositionAt(newEndOffset); - this._tree.edit({ - startIndex: change.rangeOffset, - oldEndIndex: change.rangeOffset + change.rangeLength, - newEndIndex: change.rangeOffset + change.text.length, - startPosition: { row: change.range.startLineNumber - 1, column: change.range.startColumn - 1 }, - oldEndPosition: { row: change.range.endLineNumber - 1, column: change.range.endColumn - 1 }, - newEndPosition: { row: newEndPosition.lineNumber - 1, column: newEndPosition.column - 1 } - }); - } - this._tree = this._parser.parse((index: number, position?: Parser.Point) => this._parseCallback(index, position), this._tree); - } - - private _parseCallback(index: number, position?: Parser.Point, snapshot?: ITextSnapshot): string | null { - if (snapshot) { - return snapshot.read(); - } - try { - const modelPositionStart: Position = position ? new Position(position.row + 1, position.column + 1) : this._textModel.getPositionAt(index); - const lineContent = this._textModel.getLineContent(modelPositionStart.lineNumber); - let value = lineContent.substring(modelPositionStart.column - 1); - if (value.length === 0 && (lineContent.length <= modelPositionStart.column)) { // When we hit the end of the line the value is an empty string, we need to get the next character. - const modelPositionEnd = this._textModel.getPositionAt(index + 2); - value = this._textModel.getValueInRange(Range.fromPositions(modelPositionStart, modelPositionEnd)); - } - return value; - } catch (e) { - return null; - } - } - - private _ensureTree() { - if (!this._tree) { - const timer = performance.now(); - const snapshot = this._textModel.createSnapshot(); - this._tree = this._parser.parse((index: number, position?: Parser.Point) => this._parseCallback(index, position, snapshot)); - console.log('Tree parsing took ' + (performance.now() - timer) + 'ms'); - } - return this._tree; + private _getTree(): Parser.Tree | undefined { + return this._treeSitterService.getTree(this._textModel); } private _ensureQuery() { if (!this._query) { - this._query = this._language.query(this._queries); + const language = this._treeSitterService.getLanguage(this._textModel); + if (!language) { + return; + } + this._query = language.query(this._queries); } return this._query; } @@ -237,10 +166,6 @@ class TextModelTokens extends Disposable { public reset(colorThemeData?: ColorThemeData) { if (colorThemeData) { this._colorThemeData = colorThemeData; - } else { - this._tree?.delete(); - this._tree = undefined; - this._parser.reset(); } } @@ -252,8 +177,11 @@ class TextModelTokens extends Disposable { * @returns */ public lineTokens(lineNumber: number): Uint32Array { - const tree = this._ensureTree(); + const tree = this._getTree(); const query = this._ensureQuery(); + if (!tree || !query) { + return new Uint32Array([0, 0]); + } const lineLength = this._textModel.getLineMaxColumn(lineNumber); const captures = query.captures(tree.rootNode, { startPosition: { row: lineNumber - 1, column: 0 }, endPosition: { row: lineNumber - 1, column: lineLength } }); if (captures.length === 0 && lineLength > 0) { @@ -334,9 +262,7 @@ class TextModelTokens extends Disposable { override dispose() { super.dispose(); - this._tree?.delete(); this._query?.delete(); - this._tree = undefined; this._query = undefined; } } diff --git a/src/vs/editor/common/services/modelService.ts b/src/vs/editor/common/services/modelService.ts index c7834669c8f67..9e1dc62fc9bd6 100644 --- a/src/vs/editor/common/services/modelService.ts +++ b/src/vs/editor/common/services/modelService.ts @@ -24,9 +24,7 @@ import { isEditStackElement } from 'vs/editor/common/model/editStack'; import { Schemas } from 'vs/base/common/network'; import { equals } from 'vs/base/common/objects'; import { ILanguageConfigurationService } from 'vs/editor/common/languages/languageConfigurationRegistry'; -import { IFileService } from 'vs/platform/files/common/files'; -import { IThemeService } from 'vs/platform/theme/common/themeService'; -import { ITreeSitterTokenizationService } from 'vs/editor/common/services/treeSitterTokenizationFeature'; +import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; function MODEL_ID(resource: URI): string { return resource.toString(); @@ -112,9 +110,7 @@ export class ModelService extends Disposable implements IModelService { @IUndoRedoService private readonly _undoRedoService: IUndoRedoService, @ILanguageService private readonly _languageService: ILanguageService, @ILanguageConfigurationService private readonly _languageConfigurationService: ILanguageConfigurationService, - @IFileService private readonly _fileService: IFileService, - @IThemeService private readonly _themeService: IThemeService, - @ITreeSitterTokenizationService private readonly _treeSitterService: ITreeSitterTokenizationService + @IInstantiationService private readonly _instantiationService: IInstantiationService ) { super(); this._modelCreationOptionsByLanguageAndResource = Object.create(null); @@ -328,10 +324,7 @@ export class ModelService extends Disposable implements IModelService { this._undoRedoService, this._languageService, this._languageConfigurationService, - this._configurationService, - this._fileService, - this._themeService, - this._treeSitterService + this._instantiationService ); if (resource && this._disposedModels.has(MODEL_ID(resource))) { const disposedModelData = this._removeDisposedModel(resource)!; diff --git a/src/vs/editor/common/services/treeSitterParserService.ts b/src/vs/editor/common/services/treeSitterParserService.ts new file mode 100644 index 0000000000000..71870a088eb21 --- /dev/null +++ b/src/vs/editor/common/services/treeSitterParserService.ts @@ -0,0 +1,19 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { AppResourcePath } from 'vs/base/common/network'; +import { Parser } from 'vs/base/common/web-tree-sitter/tree-sitter-web'; +import { ITextModel } from 'vs/editor/common/model'; +import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; + +export const ITreeSitterParserService = createDecorator('treeSitterParserService'); + +export interface ITreeSitterParserService { + readonly _serviceBrand: undefined; + initTreeSitter(): Promise; + getTree(model: ITextModel): Parser.Tree | undefined; + getLanguage(model: ITextModel): Parser.Language | undefined; + getLanguageLocation(languageId: string): AppResourcePath | undefined; +} diff --git a/src/vs/editor/common/services/treeSitterTokenizationFeature.ts b/src/vs/editor/common/services/treeSitterTokenizationFeature.ts deleted file mode 100644 index d7b612ded72b4..0000000000000 --- a/src/vs/editor/common/services/treeSitterTokenizationFeature.ts +++ /dev/null @@ -1,13 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; - -export const ITreeSitterTokenizationService = createDecorator('treeSitterTokenizationService'); - -export interface ITreeSitterTokenizationService { - readonly _serviceBrand: undefined; - initTreeSitter(): Promise; -} diff --git a/src/vs/editor/contrib/gotoSymbol/browser/peek/referencesWidget.ts b/src/vs/editor/contrib/gotoSymbol/browser/peek/referencesWidget.ts index a0f7b1b74df42..ec41dc692a21b 100644 --- a/src/vs/editor/contrib/gotoSymbol/browser/peek/referencesWidget.ts +++ b/src/vs/editor/contrib/gotoSymbol/browser/peek/referencesWidget.ts @@ -37,9 +37,6 @@ import { IWorkbenchAsyncDataTreeOptions, WorkbenchAsyncDataTree } from 'vs/platf import { IColorTheme, IThemeService } from 'vs/platform/theme/common/themeService'; import { IUndoRedoService } from 'vs/platform/undoRedo/common/undoRedo'; import { FileReferences, OneReference, ReferencesModel } from '../referencesModel'; -import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; -import { IFileService } from 'vs/platform/files/common/files'; -import { ITreeSitterTokenizationService } from 'vs/editor/common/services/treeSitterTokenizationFeature'; class DecorationsManager implements IDisposable { @@ -230,11 +227,7 @@ export class ReferenceWidget extends peekView.PeekViewWidget { @IUndoRedoService private readonly _undoRedoService: IUndoRedoService, @IKeybindingService private readonly _keybindingService: IKeybindingService, @ILanguageService private readonly _languageService: ILanguageService, - @ILanguageConfigurationService private readonly _languageConfigurationService: ILanguageConfigurationService, - @IConfigurationService private readonly _configurationService: IConfigurationService, - @IFileService private readonly _fileService: IFileService, - @IThemeService private readonly _themeService: IThemeService, - @ITreeSitterTokenizationService private readonly _treeSitterService: ITreeSitterTokenizationService, + @ILanguageConfigurationService private readonly _languageConfigurationService: ILanguageConfigurationService ) { super(editor, { showFrame: false, showArrow: true, isResizeable: true, isAccessible: true, supportOnTitleClick: true }, _instantiationService); @@ -322,7 +315,7 @@ export class ReferenceWidget extends peekView.PeekViewWidget { }; this._preview = this._instantiationService.createInstance(EmbeddedCodeEditorWidget, this._previewContainer, options, {}, this.editor); dom.hide(this._previewContainer); - this._previewNotAvailableMessage = new TextModel(nls.localize('missingPreviewMessage', "no preview available"), PLAINTEXT_LANGUAGE_ID, TextModel.DEFAULT_CREATION_OPTIONS, null, this._undoRedoService, this._languageService, this._languageConfigurationService, this._configurationService, this._fileService, this._themeService, this._treeSitterService); + this._previewNotAvailableMessage = new TextModel(nls.localize('missingPreviewMessage', "no preview available"), PLAINTEXT_LANGUAGE_ID, TextModel.DEFAULT_CREATION_OPTIONS, null, this._undoRedoService, this._languageService, this._languageConfigurationService, this._instantiationService); // tree this._treeContainer = dom.append(containerElement, dom.$('div.ref-tree.inline')); diff --git a/src/vs/editor/contrib/semanticTokens/test/browser/documentSemanticTokens.test.ts b/src/vs/editor/contrib/semanticTokens/test/browser/documentSemanticTokens.test.ts index bbc71c813062d..61a1ccb69afda 100644 --- a/src/vs/editor/contrib/semanticTokens/test/browser/documentSemanticTokens.test.ts +++ b/src/vs/editor/contrib/semanticTokens/test/browser/documentSemanticTokens.test.ts @@ -24,13 +24,12 @@ import { ModelService } from 'vs/editor/common/services/modelService'; import { SemanticTokensStylingService } from 'vs/editor/common/services/semanticTokensStylingService'; import { DocumentSemanticTokensFeature } from 'vs/editor/contrib/semanticTokens/browser/documentSemanticTokens'; import { getDocumentSemanticTokens, isSemanticTokens } from 'vs/editor/contrib/semanticTokens/common/getSemanticTokens'; -import { TestTreeSitterTokenizationService } from 'vs/editor/test/browser/services/testTreeSitterService'; import { TestLanguageConfigurationService } from 'vs/editor/test/common/modes/testLanguageConfigurationService'; import { TestTextResourcePropertiesService } from 'vs/editor/test/common/services/testTextResourcePropertiesService'; import { TestConfigurationService } from 'vs/platform/configuration/test/common/testConfigurationService'; import { TestDialogService } from 'vs/platform/dialogs/test/common/testDialogService'; import { IEnvironmentService } from 'vs/platform/environment/common/environment'; -import { TestFileService } from 'vs/platform/files/test/browser/workbenchTestServices'; +import { TestInstantiationService } from 'vs/platform/instantiation/test/common/instantiationServiceMock'; import { NullLogService } from 'vs/platform/log/common/log'; import { TestNotificationService } from 'vs/platform/notification/test/common/testNotificationService'; import { ColorScheme } from 'vs/platform/theme/common/theme'; @@ -58,9 +57,7 @@ suite('ModelSemanticColoring', () => { new UndoRedoService(new TestDialogService(), new TestNotificationService()), languageService, new TestLanguageConfigurationService(), - new TestFileService(), - new TestThemeService(), - new TestTreeSitterTokenizationService() + new TestInstantiationService() )); const envService = new class extends mock() { override isBuilt: boolean = true; diff --git a/src/vs/editor/test/browser/services/testTreeSitterService.ts b/src/vs/editor/test/browser/services/testTreeSitterService.ts index 395b68f898a21..bd795c6b4cf6f 100644 --- a/src/vs/editor/test/browser/services/testTreeSitterService.ts +++ b/src/vs/editor/test/browser/services/testTreeSitterService.ts @@ -3,13 +3,25 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { ITreeSitterTokenizationService } from 'vs/editor/common/services/treeSitterTokenizationFeature'; +import { AppResourcePath } from 'vs/base/common/network'; +import { Parser } from 'vs/base/common/web-tree-sitter/tree-sitter-web'; +import { ITextModel } from 'vs/editor/common/model'; +import { ITreeSitterParserService } from 'vs/editor/common/services/treeSitterParserService'; - -export class TestTreeSitterTokenizationService implements ITreeSitterTokenizationService { +export class TestTreeSitterParserService implements ITreeSitterParserService { + getLanguage(model: ITextModel): Parser.Language | undefined { + throw new Error('Method not implemented.'); + } + getLanguageLocation(languageId: string): AppResourcePath { + throw new Error('Method not implemented.'); + } readonly _serviceBrand: undefined; public initTreeSitter(): Promise { return Promise.resolve(); } + + public getTree(_model: ITextModel): Parser.Tree | undefined { + return undefined; + } } diff --git a/src/vs/workbench/api/test/browser/mainThreadDocumentsAndEditors.test.ts b/src/vs/workbench/api/test/browser/mainThreadDocumentsAndEditors.test.ts index acf8a8afa5d48..47b490371c8a1 100644 --- a/src/vs/workbench/api/test/browser/mainThreadDocumentsAndEditors.test.ts +++ b/src/vs/workbench/api/test/browser/mainThreadDocumentsAndEditors.test.ts @@ -14,7 +14,6 @@ import { ExtHostDocumentsAndEditorsShape, IDocumentsAndEditorsDelta } from 'vs/w import { createTestCodeEditor, ITestCodeEditor } from 'vs/editor/test/browser/testCodeEditor'; import { mock } from 'vs/base/test/common/mock'; import { TestEditorService, TestEditorGroupsService, TestEnvironmentService, TestPathService } from 'vs/workbench/test/browser/workbenchTestServices'; -import { TestFileService } from 'vs/platform/files/test/browser/workbenchTestServices'; import { Event } from 'vs/base/common/event'; import { ITextModel } from 'vs/editor/common/model'; import { ServiceCollection } from 'vs/platform/instantiation/common/serviceCollection'; @@ -33,7 +32,7 @@ import { TextModel } from 'vs/editor/common/model/textModel'; import { LanguageService } from 'vs/editor/common/services/languageService'; import { DisposableStore } from 'vs/base/common/lifecycle'; import { ensureNoDisposablesAreLeakedInTestSuite } from 'vs/base/test/common/utils'; -import { TestTreeSitterTokenizationService } from 'vs/editor/test/browser/services/testTreeSitterService'; +import { TestInstantiationService } from 'vs/platform/instantiation/test/common/instantiationServiceMock'; suite('MainThreadDocumentsAndEditors', () => { @@ -69,9 +68,7 @@ suite('MainThreadDocumentsAndEditors', () => { undoRedoService, disposables.add(new LanguageService()), new TestLanguageConfigurationService(), - new TestFileService(), - new TestThemeService(), - new TestTreeSitterTokenizationService() + new TestInstantiationService() ); codeEditorService = new TestCodeEditorService(themeService); textFileService = new class extends mock() { diff --git a/src/vs/workbench/api/test/browser/mainThreadEditors.test.ts b/src/vs/workbench/api/test/browser/mainThreadEditors.test.ts index 2885144cfe4a7..0c5a495051bd3 100644 --- a/src/vs/workbench/api/test/browser/mainThreadEditors.test.ts +++ b/src/vs/workbench/api/test/browser/mainThreadEditors.test.ts @@ -58,7 +58,7 @@ import { IWorkingCopyService } from 'vs/workbench/services/workingCopy/common/wo import { TestEditorGroupsService, TestEditorService, TestEnvironmentService, TestLifecycleService, TestWorkingCopyService } from 'vs/workbench/test/browser/workbenchTestServices'; import { TestContextService, TestTextResourcePropertiesService } from 'vs/workbench/test/common/workbenchTestServices'; import { TestFileService } from 'vs/platform/files/test/browser/workbenchTestServices'; -import { TestTreeSitterTokenizationService } from 'vs/editor/test/browser/services/testTreeSitterService'; +import { TestInstantiationService } from 'vs/platform/instantiation/test/common/instantiationServiceMock'; suite('MainThreadEditors', () => { @@ -94,9 +94,7 @@ suite('MainThreadEditors', () => { undoRedoService, disposables.add(new LanguageService()), new TestLanguageConfigurationService(), - new TestFileService(), - new TestThemeService(), - new TestTreeSitterTokenizationService() + new TestInstantiationService() ); const services = new ServiceCollection(); diff --git a/src/vs/workbench/contrib/bulkEdit/browser/preview/bulkEditTree.ts b/src/vs/workbench/contrib/bulkEdit/browser/preview/bulkEditTree.ts index 3f44bb729d4fc..bc043ca27aa77 100644 --- a/src/vs/workbench/contrib/bulkEdit/browser/preview/bulkEditTree.ts +++ b/src/vs/workbench/contrib/bulkEdit/browser/preview/bulkEditTree.ts @@ -15,7 +15,7 @@ import { ITextModel } from 'vs/editor/common/model'; import { IDisposable, DisposableStore } from 'vs/base/common/lifecycle'; import { TextModel } from 'vs/editor/common/model/textModel'; import { BulkFileOperations, BulkFileOperation, BulkFileOperationType, BulkTextEdit, BulkCategory } from 'vs/workbench/contrib/bulkEdit/browser/preview/bulkEditPreview'; -import { FileKind, IFileService } from 'vs/platform/files/common/files'; +import { FileKind } from 'vs/platform/files/common/files'; import { localize } from 'vs/nls'; import { ILabelService } from 'vs/platform/label/common/label'; import type { IListAccessibilityProvider } from 'vs/base/browser/ui/list/listWidget'; @@ -32,8 +32,7 @@ import { ILanguageService } from 'vs/editor/common/languages/language'; import { PLAINTEXT_LANGUAGE_ID } from 'vs/editor/common/languages/modesRegistry'; import { SnippetParser } from 'vs/editor/contrib/snippet/browser/snippetParser'; import { AriaRole } from 'vs/base/browser/ui/aria/aria'; -import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; -import { ITreeSitterTokenizationService } from 'vs/editor/common/services/treeSitterTokenizationFeature'; +import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; // --- VIEW MODEL @@ -207,10 +206,7 @@ export class BulkEditDataSource implements IAsyncDataSource Date: Mon, 27 May 2024 15:35:00 +0200 Subject: [PATCH 12/37] Remove things that aren't the parser service --- src/vs/editor/common/model/textModel.ts | 40 ++- .../common/model/tokenizationTextModelPart.ts | 170 ++++++----- src/vs/editor/common/model/tokens.ts | 164 ----------- .../editor/common/model/treeSitterTokens.ts | 268 ------------------ .../browser/peek/referencesWidget.ts | 2 +- src/vs/platform/theme/common/themeService.ts | 14 - .../theme/test/common/testThemeService.ts | 7 +- .../textMateTokenizationFeatureImpl.ts | 3 +- .../services/themes/common/colorThemeData.ts | 6 +- .../themes/common/themeCompatibility.ts | 3 +- .../themes/common/workbenchThemeService.ts | 14 +- 11 files changed, 160 insertions(+), 531 deletions(-) delete mode 100644 src/vs/editor/common/model/tokens.ts delete mode 100644 src/vs/editor/common/model/treeSitterTokens.ts diff --git a/src/vs/editor/common/model/textModel.ts b/src/vs/editor/common/model/textModel.ts index b96243b28df7f..acf8c788d3636 100644 --- a/src/vs/editor/common/model/textModel.ts +++ b/src/vs/editor/common/model/textModel.ts @@ -18,6 +18,7 @@ import { URI } from 'vs/base/common/uri'; import { ISingleEditOperation } from 'vs/editor/common/core/editOperation'; import { countEOL } from 'vs/editor/common/core/eolCounter'; import { normalizeIndentation } from 'vs/editor/common/core/indentation'; +import { LineRange } from 'vs/editor/common/core/lineRange'; import { IPosition, Position } from 'vs/editor/common/core/position'; import { IRange, Range } from 'vs/editor/common/core/range'; import { Selection } from 'vs/editor/common/core/selection'; @@ -38,7 +39,6 @@ import { PieceTreeTextBuffer } from 'vs/editor/common/model/pieceTreeTextBuffer/ import { PieceTreeTextBufferBuilder } from 'vs/editor/common/model/pieceTreeTextBuffer/pieceTreeTextBufferBuilder'; import { SearchParams, TextModelSearch } from 'vs/editor/common/model/textModelSearch'; import { TokenizationTextModelPart } from 'vs/editor/common/model/tokenizationTextModelPart'; -import { AttachedViews } from 'vs/editor/common/model/tokens'; import { IBracketPairsTextModelPart } from 'vs/editor/common/textModelBracketPairs'; import { IModelContentChangedEvent, IModelDecorationsChangedEvent, IModelOptionsChangedEvent, InternalModelContentChangeEvent, LineInjectedText, ModelInjectedTextChangedEvent, ModelRawChange, ModelRawContentChangedEvent, ModelRawEOLChanged, ModelRawFlush, ModelRawLineChanged, ModelRawLinesDeleted, ModelRawLinesInserted } from 'vs/editor/common/textModelEvents'; import { IGuidesTextModelPart } from 'vs/editor/common/textModelGuides'; @@ -2526,4 +2526,42 @@ class DidChangeContentEmitter extends Disposable { } } +/** + * @internal + */ +export class AttachedViews { + private readonly _onDidChangeVisibleRanges = new Emitter<{ view: model.IAttachedView; state: IAttachedViewState | undefined }>(); + public readonly onDidChangeVisibleRanges = this._onDidChangeVisibleRanges.event; + + private readonly _views = new Set(); + + public attachView(): model.IAttachedView { + const view = new AttachedViewImpl((state) => { + this._onDidChangeVisibleRanges.fire({ view, state }); + }); + this._views.add(view); + return view; + } + + public detachView(view: model.IAttachedView): void { + this._views.delete(view as AttachedViewImpl); + this._onDidChangeVisibleRanges.fire({ view, state: undefined }); + } +} + +/** + * @internal + */ +export interface IAttachedViewState { + readonly visibleLineRanges: readonly LineRange[]; + readonly stabilized: boolean; +} + +class AttachedViewImpl implements model.IAttachedView { + constructor(private readonly handleStateChange: (state: IAttachedViewState) => void) { } + setVisibleLines(visibleLines: { startLineNumber: number; endLineNumber: number }[], stabilized: boolean): void { + const visibleLineRanges = visibleLines.map((line) => new LineRange(line.startLineNumber, line.endLineNumber + 1)); + this.handleStateChange({ visibleLineRanges, stabilized }); + } +} diff --git a/src/vs/editor/common/model/tokenizationTextModelPart.ts b/src/vs/editor/common/model/tokenizationTextModelPart.ts index cb245c39c5986..804f63c6a2800 100644 --- a/src/vs/editor/common/model/tokenizationTextModelPart.ts +++ b/src/vs/editor/common/model/tokenizationTextModelPart.ts @@ -3,26 +3,26 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +import { equals } from 'vs/base/common/arrays'; +import { RunOnceScheduler } from 'vs/base/common/async'; import { CharCode } from 'vs/base/common/charCode'; import { BugIndicatingError, onUnexpectedError } from 'vs/base/common/errors'; import { Emitter, Event } from 'vs/base/common/event'; -import { MutableDisposable } from 'vs/base/common/lifecycle'; +import { Disposable, DisposableMap, MutableDisposable } from 'vs/base/common/lifecycle'; import { countEOL } from 'vs/editor/common/core/eolCounter'; import { LineRange } from 'vs/editor/common/core/lineRange'; import { IPosition, Position } from 'vs/editor/common/core/position'; import { Range } from 'vs/editor/common/core/range'; import { IWordAtPosition, getWordAtText } from 'vs/editor/common/core/wordHelper'; import { StandardTokenType } from 'vs/editor/common/encodedTokenAttributes'; -import { IBackgroundTokenizationStore, IBackgroundTokenizer, ILanguageIdCodec, IState, ITokenizationSupport, TokenizationRegistry, TreeSitterTokenizationRegistry } from 'vs/editor/common/languages'; +import { IBackgroundTokenizationStore, IBackgroundTokenizer, ILanguageIdCodec, IState, ITokenizationSupport, TokenizationRegistry } from 'vs/editor/common/languages'; import { ILanguageService } from 'vs/editor/common/languages/language'; import { ILanguageConfigurationService, ResolvedLanguageConfiguration } from 'vs/editor/common/languages/languageConfigurationRegistry'; +import { IAttachedView } from 'vs/editor/common/model'; import { BracketPairsTextModelPart } from 'vs/editor/common/model/bracketPairsTextModelPart/bracketPairsImpl'; -import { TextModel } from 'vs/editor/common/model/textModel'; +import { AttachedViews, IAttachedViewState, TextModel } from 'vs/editor/common/model/textModel'; import { TextModelPart } from 'vs/editor/common/model/textModelPart'; import { DefaultBackgroundTokenizer, TokenizerWithStateStoreAndTextModel, TrackingTokenizationStateStore } from 'vs/editor/common/model/textModelTokens'; -import { AbstractTokens, AttachedViews } from 'vs/editor/common/model/tokens'; -import { TreeSitterTokens } from 'vs/editor/common/model/treeSitterTokens'; -import { ITreeSitterParserService } from 'vs/editor/common/services/treeSitterParserService'; import { IModelContentChangedEvent, IModelLanguageChangedEvent, IModelLanguageConfigurationChangedEvent, IModelTokensChangedEvent } from 'vs/editor/common/textModelEvents'; import { BackgroundTokenizationState, ITokenizationTextModelPart } from 'vs/editor/common/tokenizationTextModelPart'; import { ContiguousMultilineTokens } from 'vs/editor/common/tokens/contiguousMultilineTokens'; @@ -31,12 +31,6 @@ import { ContiguousTokensStore } from 'vs/editor/common/tokens/contiguousTokensS import { LineTokens } from 'vs/editor/common/tokens/lineTokens'; import { SparseMultilineTokens } from 'vs/editor/common/tokens/sparseMultilineTokens'; import { SparseTokensStore } from 'vs/editor/common/tokens/sparseTokensStore'; -import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; -import { IFileService } from 'vs/platform/files/common/files'; -import { IThemeService } from 'vs/platform/theme/common/themeService'; - -// Setting value will be an array of language IDs that will prefer tree sitter tokenization over textmate when they both exist. -const TOKENIZATION_PROVIDER_SETTING = 'editor.experimental.preferTreeSitter'; export class TokenizationTextModelPart extends TextModelPart implements ITokenizationTextModelPart { private readonly _semanticTokens: SparseTokensStore = new SparseTokensStore(this._languageService.languageIdCodec); @@ -50,7 +44,7 @@ export class TokenizationTextModelPart extends TextModelPart implements ITokeniz private readonly _onDidChangeTokens: Emitter = this._register(new Emitter()); public readonly onDidChangeTokens: Event = this._onDidChangeTokens.event; - private tokens!: AbstractTokens; + private readonly grammarTokens = this._register(new GrammarTokens(this._languageService.languageIdCodec, this._textModel, () => this._languageId, this._attachedViews)); constructor( private readonly _languageService: ILanguageService, @@ -59,10 +53,6 @@ export class TokenizationTextModelPart extends TextModelPart implements ITokeniz private readonly _bracketPairsTextModelPart: BracketPairsTextModelPart, private _languageId: string, private readonly _attachedViews: AttachedViews, - @IConfigurationService private readonly _configurationService: IConfigurationService, - @IFileService private readonly _fileService: IFileService, - @IThemeService private readonly _themeService: IThemeService, - @ITreeSitterParserService private readonly _treeSitterService: ITreeSitterParserService, ) { super(); @@ -72,46 +62,15 @@ export class TokenizationTextModelPart extends TextModelPart implements ITokeniz } })); - this.createPreferredTokenProvider(); - } - - private createGrammarTokens() { - return this._register(new GrammarTokens(this._languageService.languageIdCodec, this._textModel, () => this._languageId, this._attachedViews)); - } - - private createTreeSitterTokens(): AbstractTokens { - return this._register(new TreeSitterTokens(this._fileService, this._themeService, this._treeSitterService, this._languageService.languageIdCodec, this._textModel, () => this._languageId, this._attachedViews)); - } - - private createTokens(useTreeSitter: boolean): void { - this.tokens?.dispose(); - this.tokens = useTreeSitter ? this.createTreeSitterTokens() : this.createGrammarTokens(); - this._register(this.tokens.onDidChangeTokens(e => { + this._register(this.grammarTokens.onDidChangeTokens(e => { this._emitModelTokensChangedEvent(e); })); - this._register(this.tokens.onDidChangeBackgroundTokenizationState(e => { + this._register(this.grammarTokens.onDidChangeBackgroundTokenizationState(e => { this._bracketPairsTextModelPart.handleDidChangeBackgroundTokenizationState(); })); } - private createPreferredTokenProvider() { - const preferTreeSitter: string[] = this._configurationService.getValue(TOKENIZATION_PROVIDER_SETTING) ?? []; - if ((preferTreeSitter.includes(this._languageId) && TreeSitterTokenizationRegistry.get(this._languageId))) { - if (this.tokens instanceof TreeSitterTokens) { - this.tokens.resetTokenization(true); - } else { - this.createTokens(true); - } - } else { - if (this.tokens instanceof GrammarTokens) { - this.tokens.resetTokenization(true); - } else { - this.createTokens(false); - } - } - } - _hasListeners(): boolean { return (this._onDidChangeLanguage.hasListeners() || this._onDidChangeLanguageConfiguration.hasListeners() @@ -135,11 +94,11 @@ export class TokenizationTextModelPart extends TextModelPart implements ITokeniz } } - this.tokens.handleDidChangeContent(e); + this.grammarTokens.handleDidChangeContent(e); } public handleDidChangeAttached(): void { - this.tokens.handleDidChangeAttached(); + this.grammarTokens.handleDidChangeAttached(); } /** @@ -147,7 +106,7 @@ export class TokenizationTextModelPart extends TextModelPart implements ITokeniz */ public getLineTokens(lineNumber: number): LineTokens { this.validateLineNumber(lineNumber); - const syntacticTokens = this.tokens.getLineTokens(lineNumber); + const syntacticTokens = this.grammarTokens.getLineTokens(lineNumber); return this._semanticTokens.addSparseTokens(lineNumber, syntacticTokens); } @@ -167,43 +126,43 @@ export class TokenizationTextModelPart extends TextModelPart implements ITokeniz } public get hasTokens(): boolean { - return !!this.tokens.hasTokens; + return this.grammarTokens.hasTokens; } public resetTokenization() { - this.tokens.resetTokenization(); + this.grammarTokens.resetTokenization(); } public get backgroundTokenizationState() { - return this.tokens.backgroundTokenizationState ?? BackgroundTokenizationState.InProgress; + return this.grammarTokens.backgroundTokenizationState; } public forceTokenization(lineNumber: number): void { this.validateLineNumber(lineNumber); - this.tokens.forceTokenization(lineNumber); + this.grammarTokens.forceTokenization(lineNumber); } public hasAccurateTokensForLine(lineNumber: number): boolean { this.validateLineNumber(lineNumber); - return !!this.tokens.hasAccurateTokensForLine(lineNumber); + return this.grammarTokens.hasAccurateTokensForLine(lineNumber); } public isCheapToTokenize(lineNumber: number): boolean { this.validateLineNumber(lineNumber); - return !!this.tokens.isCheapToTokenize(lineNumber); + return this.grammarTokens.isCheapToTokenize(lineNumber); } public tokenizeIfCheap(lineNumber: number): void { this.validateLineNumber(lineNumber); - this.tokens.tokenizeIfCheap(lineNumber); + this.grammarTokens.tokenizeIfCheap(lineNumber); } public getTokenTypeIfInsertingCharacter(lineNumber: number, column: number, character: string): StandardTokenType { - return this.tokens.getTokenTypeIfInsertingCharacter(lineNumber, column, character) ?? StandardTokenType.Other; + return this.grammarTokens.getTokenTypeIfInsertingCharacter(lineNumber, column, character); } public tokenizeLineWithEdit(position: IPosition, length: number, newText: string): LineTokens | null { - return this.tokens.tokenizeLineWithEdit(position, length, newText) ?? null; + return this.grammarTokens.tokenizeLineWithEdit(position, length, newText); } // #endregion @@ -368,7 +327,7 @@ export class TokenizationTextModelPart extends TextModelPart implements ITokeniz this._languageId = languageId; this._bracketPairsTextModelPart.handleDidChangeLanguage(e); - this.createPreferredTokenProvider(); + this.grammarTokens.resetTokenization(); this._onDidChangeLanguage.fire(e); this._onDidChangeLanguageConfiguration.fire({}); } @@ -376,7 +335,7 @@ export class TokenizationTextModelPart extends TextModelPart implements ITokeniz // #endregion } -class GrammarTokens extends AbstractTokens { +class GrammarTokens extends Disposable { private _tokenizer: TokenizerWithStateStoreAndTextModel | null = null; private _defaultBackgroundTokenizer: DefaultBackgroundTokenizer | null = null; private readonly _backgroundTokenizer = this._register(new MutableDisposable()); @@ -387,14 +346,51 @@ class GrammarTokens extends AbstractTokens { private readonly _debugBackgroundTokenizer = this._register(new MutableDisposable()); + private _backgroundTokenizationState = BackgroundTokenizationState.InProgress; + public get backgroundTokenizationState(): BackgroundTokenizationState { + return this._backgroundTokenizationState; + } + + private readonly _onDidChangeBackgroundTokenizationState = this._register(new Emitter()); + /** @internal, should not be exposed by the text model! */ + public readonly onDidChangeBackgroundTokenizationState: Event = this._onDidChangeBackgroundTokenizationState.event; + + private readonly _onDidChangeTokens = this._register(new Emitter()); + /** @internal, should not be exposed by the text model! */ + public readonly onDidChangeTokens: Event = this._onDidChangeTokens.event; + + private readonly _attachedViewStates = this._register(new DisposableMap()); + constructor( - languageIdCodec: ILanguageIdCodec, - textModel: TextModel, - getLanguageId: () => string, + private readonly _languageIdCodec: ILanguageIdCodec, + private readonly _textModel: TextModel, + private getLanguageId: () => string, attachedViews: AttachedViews, ) { - super(languageIdCodec, textModel, getLanguageId, attachedViews); + super(); + + this._register(TokenizationRegistry.onDidChange((e) => { + const languageId = this.getLanguageId(); + if (e.changedLanguages.indexOf(languageId) === -1) { + return; + } + this.resetTokenization(); + })); + this.resetTokenization(); + + this._register(attachedViews.onDidChangeVisibleRanges(({ view, state }) => { + if (state) { + let existing = this._attachedViewStates.get(view); + if (!existing) { + existing = new AttachedViewHandler(() => this.refreshRanges(existing!.lineRanges)); + this._attachedViewStates.set(view, existing); + } + existing.handleStateChange(state); + } else { + this._attachedViewStates.deleteAndDispose(view); + } + })); } public resetTokenization(fireTokenChangeEvent: boolean = true): void { @@ -540,7 +536,7 @@ class GrammarTokens extends AbstractTokens { this.refreshRanges(ranges); } - protected refreshRanges(ranges: readonly LineRange[]): void { + private refreshRanges(ranges: readonly LineRange[]): void { for (const range of ranges) { this.refreshRange(range.startLineNumber, range.endLineNumberExclusive - 1); } @@ -591,6 +587,12 @@ class GrammarTokens extends AbstractTokens { return this._tokenizer.isCheapToTokenize(lineNumber); } + public tokenizeIfCheap(lineNumber: number): void { + if (this.isCheapToTokenize(lineNumber)) { + this.forceTokenization(lineNumber); + } + } + public getLineTokens(lineNumber: number): LineTokens { const lineText = this._textModel.getLineContent(lineNumber); const result = this._tokens.getTokens( @@ -637,3 +639,33 @@ class GrammarTokens extends AbstractTokens { return this._tokens.hasTokens; } } + +class AttachedViewHandler extends Disposable { + private readonly runner = this._register(new RunOnceScheduler(() => this.update(), 50)); + + private _computedLineRanges: readonly LineRange[] = []; + private _lineRanges: readonly LineRange[] = []; + public get lineRanges(): readonly LineRange[] { return this._lineRanges; } + + constructor(private readonly _refreshTokens: () => void) { + super(); + } + + private update(): void { + if (equals(this._computedLineRanges, this._lineRanges, (a, b) => a.equals(b))) { + return; + } + this._computedLineRanges = this._lineRanges; + this._refreshTokens(); + } + + public handleStateChange(state: IAttachedViewState): void { + this._lineRanges = state.visibleLineRanges; + if (state.stabilized) { + this.runner.cancel(); + this.update(); + } else { + this.runner.schedule(); + } + } +} diff --git a/src/vs/editor/common/model/tokens.ts b/src/vs/editor/common/model/tokens.ts deleted file mode 100644 index 2d2be3710ef4e..0000000000000 --- a/src/vs/editor/common/model/tokens.ts +++ /dev/null @@ -1,164 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import { equals } from 'vs/base/common/arrays'; -import { RunOnceScheduler } from 'vs/base/common/async'; -import { Emitter, Event } from 'vs/base/common/event'; -import { Disposable, DisposableMap } from 'vs/base/common/lifecycle'; -import { LineRange } from 'vs/editor/common/core/lineRange'; -import { IPosition } from 'vs/editor/common/core/position'; -import { StandardTokenType } from 'vs/editor/common/encodedTokenAttributes'; -import { ILanguageIdCodec, TokenizationRegistry } from 'vs/editor/common/languages'; -import { IAttachedView } from 'vs/editor/common/model'; -import { TextModel } from 'vs/editor/common/model/textModel'; -import { IModelContentChangedEvent, IModelTokensChangedEvent } from 'vs/editor/common/textModelEvents'; -import { BackgroundTokenizationState } from 'vs/editor/common/tokenizationTextModelPart'; -import { LineTokens } from 'vs/editor/common/tokens/lineTokens'; - -/** - * @internal - */ -export class AttachedViews { - private readonly _onDidChangeVisibleRanges = new Emitter<{ view: IAttachedView; state: IAttachedViewState | undefined }>(); - public readonly onDidChangeVisibleRanges = this._onDidChangeVisibleRanges.event; - - private readonly _views = new Set(); - - public attachView(): IAttachedView { - const view = new AttachedViewImpl((state) => { - this._onDidChangeVisibleRanges.fire({ view, state }); - }); - this._views.add(view); - return view; - } - - public detachView(view: IAttachedView): void { - this._views.delete(view as AttachedViewImpl); - this._onDidChangeVisibleRanges.fire({ view, state: undefined }); - } -} - -/** - * @internal - */ -export interface IAttachedViewState { - readonly visibleLineRanges: readonly LineRange[]; - readonly stabilized: boolean; -} - -class AttachedViewImpl implements IAttachedView { - constructor(private readonly handleStateChange: (state: IAttachedViewState) => void) { } - - setVisibleLines(visibleLines: { startLineNumber: number; endLineNumber: number }[], stabilized: boolean): void { - const visibleLineRanges = visibleLines.map((line) => new LineRange(line.startLineNumber, line.endLineNumber + 1)); - this.handleStateChange({ visibleLineRanges, stabilized }); - } -} - - -export class AttachedViewHandler extends Disposable { - private readonly runner = this._register(new RunOnceScheduler(() => this.update(), 50)); - - private _computedLineRanges: readonly LineRange[] = []; - private _lineRanges: readonly LineRange[] = []; - public get lineRanges(): readonly LineRange[] { return this._lineRanges; } - - constructor(private readonly _refreshTokens: () => void) { - super(); - } - - private update(): void { - if (equals(this._computedLineRanges, this._lineRanges, (a, b) => a.equals(b))) { - return; - } - this._computedLineRanges = this._lineRanges; - this._refreshTokens(); - } - - public handleStateChange(state: IAttachedViewState): void { - this._lineRanges = state.visibleLineRanges; - if (state.stabilized) { - this.runner.cancel(); - this.update(); - } else { - this.runner.schedule(); - } - } -} - -export abstract class AbstractTokens extends Disposable { - protected _backgroundTokenizationState = BackgroundTokenizationState.InProgress; - public get backgroundTokenizationState(): BackgroundTokenizationState { - return this._backgroundTokenizationState; - } - - protected readonly _onDidChangeBackgroundTokenizationState = this._register(new Emitter()); - /** @internal, should not be exposed by the text model! */ - public readonly onDidChangeBackgroundTokenizationState: Event = this._onDidChangeBackgroundTokenizationState.event; - - protected readonly _onDidChangeTokens = this._register(new Emitter()); - /** @internal, should not be exposed by the text model! */ - public readonly onDidChangeTokens: Event = this._onDidChangeTokens.event; - - protected readonly _attachedViewStates = this._register(new DisposableMap()); - - constructor( - protected readonly _languageIdCodec: ILanguageIdCodec, - protected readonly _textModel: TextModel, - protected getLanguageId: () => string, - attachedViews: AttachedViews, - ) { - super(); - - this._register(TokenizationRegistry.onDidChange((e) => { - const languageId = this.getLanguageId(); - if (e.changedLanguages.indexOf(languageId) === -1) { - return; - } - this.resetTokenization(); - })); - - this._register(attachedViews.onDidChangeVisibleRanges(({ view, state }) => { - if (state) { - let existing = this._attachedViewStates.get(view); - if (!existing) { - existing = new AttachedViewHandler(() => this.refreshRanges(existing!.lineRanges)); - this._attachedViewStates.set(view, existing); - } - existing.handleStateChange(state); - } else { - this._attachedViewStates.deleteAndDispose(view); - } - })); - } - - public abstract resetTokenization(fireTokenChangeEvent?: boolean): void; - - public abstract handleDidChangeAttached(): void; - - public abstract handleDidChangeContent(e: IModelContentChangedEvent): void; - - protected abstract refreshRanges(ranges: readonly LineRange[]): void; - - public abstract forceTokenization(lineNumber: number): void; - - public abstract hasAccurateTokensForLine(lineNumber: number): boolean; - - public abstract isCheapToTokenize(lineNumber: number): boolean; - - public tokenizeIfCheap(lineNumber: number): void { - if (this.isCheapToTokenize(lineNumber)) { - this.forceTokenization(lineNumber); - } - } - - public abstract getLineTokens(lineNumber: number): LineTokens; - - public abstract getTokenTypeIfInsertingCharacter(lineNumber: number, column: number, character: string): StandardTokenType; - - public abstract tokenizeLineWithEdit(position: IPosition, length: number, newText: string): LineTokens | null; - - public abstract get hasTokens(): boolean; -} diff --git a/src/vs/editor/common/model/treeSitterTokens.ts b/src/vs/editor/common/model/treeSitterTokens.ts deleted file mode 100644 index 29d2a3841e14e..0000000000000 --- a/src/vs/editor/common/model/treeSitterTokens.ts +++ /dev/null @@ -1,268 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import { Disposable } from 'vs/base/common/lifecycle'; -import { AppResourcePath, FileAccess } from 'vs/base/common/network'; -import { ILanguageIdCodec } from 'vs/editor/common/languages'; -import { LineTokens } from 'vs/editor/common/tokens/lineTokens'; -import { IFileService } from 'vs/platform/files/common/files'; -import { Parser } from 'vs/base/common/web-tree-sitter/tree-sitter-web'; -import { IThemeService } from 'vs/platform/theme/common/themeService'; -import { FontStyle, MetadataConsts, StandardTokenType } from 'vs/editor/common/encodedTokenAttributes'; -import { TokenStyle } from 'vs/platform/theme/common/tokenClassificationRegistry'; -import { ColorThemeData } from 'vs/workbench/services/themes/common/colorThemeData'; -import { TextModel } from 'vs/editor/common/model/textModel'; -import { ITreeSitterParserService } from 'vs/editor/common/services/treeSitterParserService'; -import { IModelContentChangedEvent } from 'vs/editor/common/textModelEvents'; -import { AbstractTokens, AttachedViews } from 'vs/editor/common/model/tokens'; -import { LineRange } from 'vs/editor/common/core/lineRange'; -import { IPosition } from 'vs/editor/common/core/position'; - -export class TreeSitterTokens extends AbstractTokens { - private _colorThemeData: ColorThemeData; - private _queries: string | undefined; - private _tokens: TextModelTokens | undefined; - private _lastLanguageId: string | undefined; - - constructor(private readonly _fileService: IFileService, - private readonly _themeService: IThemeService, - private readonly _treeSitterService: ITreeSitterParserService, - languageIdCodec: ILanguageIdCodec, - textModel: TextModel, - languageId: () => string, - attachedViews: AttachedViews) { - super(languageIdCodec, textModel, languageId, attachedViews); - // TODO @alexr00 respond to language changes - this._initialize(); - - // TODO @alexr00 remove the cast - this._colorThemeData = this._themeService.getColorTheme() as ColorThemeData; - this._register(this._themeService.onDidColorThemeChange(() => { - this._colorThemeData = this._themeService.getColorTheme() as ColorThemeData; - this._tokens?.reset(this._colorThemeData); - })); - } - - private async _initialize() { - const newLanguage = this.getLanguageId(); - const queries = await this._getQueries(newLanguage); - if (!this._tokens || this._lastLanguageId !== newLanguage) { - this._tokens?.dispose(); - this._tokens = new TextModelTokens(this._treeSitterService, this._textModel, queries, this._colorThemeData); - } - } - - private async _getQueries(newLanguage: string): Promise { - if (!this._queries || this._lastLanguageId !== newLanguage) { - this._queries = await this._fetchQueries(newLanguage); - } - return this._queries; - } - - private async _fetchQueries(newLanguage: string): Promise { - const languageLocation = this._treeSitterService.getLanguageLocation(newLanguage); - if (!languageLocation) { - throw new Error(`No language location for ${newLanguage}`); - } - const scmPath: AppResourcePath = `${languageLocation}/highlights.scm`; - const query = await this._fileService.readFile(FileAccess.asFileUri(scmPath)); - return query.value.toString(); - } - - public getLineTokens(lineNumber: number): LineTokens { - if (this._tokens) { - return new LineTokens(this._tokens.lineTokens(lineNumber), this._textModel.getLineContent(lineNumber), this._languageIdCodec); - } - return LineTokens.createEmpty('', this._languageIdCodec); - } - - public resetTokenization(fireTokenChangeEvent: boolean = true): void { - this._tokens?.reset(); - if (fireTokenChangeEvent) { - this._onDidChangeTokens.fire({ - semanticTokensApplied: false, - ranges: [ - { - fromLineNumber: 1, - toLineNumber: this._textModel.getLineCount(), - }, - ], - }); - } - } - - public override handleDidChangeAttached(): void { - // TODO @alexr00 implement for background tokenization - } - - public override handleDidChangeContent(e: IModelContentChangedEvent): void { - if (e.isFlush) { - // Don't fire the event, as the view might not have got the text change event yet - this.resetTokenization(false); - } - } - protected override refreshRanges(ranges: readonly LineRange[]): void { - // TODO @alexr00 implement - } - - public override forceTokenization(lineNumber: number): void { - // TODO @alexr00 implement - } - - public override hasAccurateTokensForLine(lineNumber: number): boolean { - // TODO @alexr00 update for background tokenization - return true; - } - - public override isCheapToTokenize(lineNumber: number): boolean { - // TODO @alexr00 update for background tokenization - return true; - } - - public override getTokenTypeIfInsertingCharacter(lineNumber: number, column: number, character: string): StandardTokenType { - // TODO @alexr00 implement once we have custom parsing and don't just feed in the whole text model value - return StandardTokenType.Other; - } - public override tokenizeLineWithEdit(position: IPosition, length: number, newText: string): LineTokens | null { - // TODO @alexr00 understand what this is for and implement - return null; - } - public override get hasTokens(): boolean { - // TODO @alexr00 once we have a token store, implement properly - const hasTree = this._treeSitterService.getTree(this._textModel) !== undefined; - return hasTree; - } - -} - -class TextModelTokens extends Disposable { - private _query: Parser.Query | undefined; - - constructor( - private readonly _treeSitterService: ITreeSitterParserService, - private readonly _textModel: TextModel, - private readonly _queries: string, - private _colorThemeData: ColorThemeData) { - super(); - } - - private _getTree(): Parser.Tree | undefined { - return this._treeSitterService.getTree(this._textModel); - } - - private _ensureQuery() { - if (!this._query) { - const language = this._treeSitterService.getLanguage(this._textModel); - if (!language) { - return; - } - this._query = language.query(this._queries); - } - return this._query; - } - - public reset(colorThemeData?: ColorThemeData) { - if (colorThemeData) { - this._colorThemeData = colorThemeData; - } - } - - /** - * Gets the tokens for a given line. - * Each token takes 2 elements in the array. The first element is the offset of the end of the token *in the line, not in the document*, and the second element is the metadata. - * - * @param lineNumber - * @returns - */ - public lineTokens(lineNumber: number): Uint32Array { - const tree = this._getTree(); - const query = this._ensureQuery(); - if (!tree || !query) { - return new Uint32Array([0, 0]); - } - const lineLength = this._textModel.getLineMaxColumn(lineNumber); - const captures = query.captures(tree.rootNode, { startPosition: { row: lineNumber - 1, column: 0 }, endPosition: { row: lineNumber - 1, column: lineLength } }); - if (captures.length === 0 && lineLength > 0) { - // No captures, but we always want to return at least one token for each line - return new Uint32Array([lineLength, 0]); - } - - let tokens: Uint32Array = new Uint32Array(captures.length * 2); - let tokenIndex = 0; - const lineStartOffset = this._textModel.getOffsetAt({ lineNumber: lineNumber, column: 0 }); - - for (let captureIndex = 0; captureIndex < captures.length; captureIndex++) { - const capture = captures[captureIndex]; - const metadata = this.findMetadata(capture.name); - - const offset = capture.node.endIndex - lineStartOffset; - // Not every character will get captured, so we need to make sure that our current capture doesn't bleed toward the start of the line and cover characters that it doesn't apply to. - // We do this by creating a new token in the array if the previous token ends before the current token starts. - if (captureIndex > 0) { - const previousTokenEnd = tokens[(tokenIndex - 1) * 2]; - const currentTokenLength = capture.node.endIndex - capture.node.startIndex; - const intermediateTokenOffset = offset - currentTokenLength; - if (previousTokenEnd < intermediateTokenOffset) { - tokens[tokenIndex * 2] = intermediateTokenOffset; - tokens[tokenIndex * 2 + 1] = 0; - tokenIndex++; - const newTokens = new Uint32Array(tokens.length + 2); - newTokens.set(tokens); - tokens = newTokens; - } - } - tokens[tokenIndex * 2] = offset; - tokens[tokenIndex * 2 + 1] = metadata; - tokenIndex++; - } - - if (captures[captures.length - 1].node.endPosition.column + 1 < lineLength) { - const newTokens = new Uint32Array(tokens.length + 2); - newTokens.set(tokens); - tokens = newTokens; - tokens[tokenIndex * 2] = lineLength; - tokens[tokenIndex * 2 + 1] = 0; - } - return tokens; - } - - private findMetadata(captureName: string): number { - const tokenStyle: TokenStyle | undefined = this._colorThemeData.resolveScopes([[captureName]]); - if (!tokenStyle) { - return 0; - } - - let metadata = 0; - if (typeof tokenStyle.italic !== 'undefined') { - const italicBit = (tokenStyle.italic ? FontStyle.Italic : 0); - metadata |= italicBit | MetadataConsts.ITALIC_MASK; - } - if (typeof tokenStyle.bold !== 'undefined') { - const boldBit = (tokenStyle.bold ? FontStyle.Bold : 0); - metadata |= boldBit | MetadataConsts.BOLD_MASK; - } - if (typeof tokenStyle.underline !== 'undefined') { - const underlineBit = (tokenStyle.underline ? FontStyle.Underline : 0); - metadata |= underlineBit | MetadataConsts.UNDERLINE_MASK; - } - if (typeof tokenStyle.strikethrough !== 'undefined') { - const strikethroughBit = (tokenStyle.strikethrough ? FontStyle.Strikethrough : 0); - metadata |= strikethroughBit | MetadataConsts.STRIKETHROUGH_MASK; - } - if (tokenStyle.foreground) { - const tokenStyleForeground = this._colorThemeData.getTokenColorIndex().get(tokenStyle?.foreground); - const foregroundBits = tokenStyleForeground << MetadataConsts.FOREGROUND_OFFSET; - metadata |= foregroundBits; - } - - return metadata; - } - - override dispose() { - super.dispose(); - this._query?.delete(); - this._query = undefined; - } -} diff --git a/src/vs/editor/contrib/gotoSymbol/browser/peek/referencesWidget.ts b/src/vs/editor/contrib/gotoSymbol/browser/peek/referencesWidget.ts index ec41dc692a21b..b6ab421cb28d8 100644 --- a/src/vs/editor/contrib/gotoSymbol/browser/peek/referencesWidget.ts +++ b/src/vs/editor/contrib/gotoSymbol/browser/peek/referencesWidget.ts @@ -227,7 +227,7 @@ export class ReferenceWidget extends peekView.PeekViewWidget { @IUndoRedoService private readonly _undoRedoService: IUndoRedoService, @IKeybindingService private readonly _keybindingService: IKeybindingService, @ILanguageService private readonly _languageService: ILanguageService, - @ILanguageConfigurationService private readonly _languageConfigurationService: ILanguageConfigurationService + @ILanguageConfigurationService private readonly _languageConfigurationService: ILanguageConfigurationService, ) { super(editor, { showFrame: false, showArrow: true, isResizeable: true, isAccessible: true, supportOnTitleClick: true }, _instantiationService); diff --git a/src/vs/platform/theme/common/themeService.ts b/src/vs/platform/theme/common/themeService.ts index fee5d879f40c6..f89940c9f1e15 100644 --- a/src/vs/platform/theme/common/themeService.ts +++ b/src/vs/platform/theme/common/themeService.ts @@ -40,20 +40,6 @@ export interface ITokenStyle { readonly italic: boolean | undefined; } -export interface ITextMateThemingRule { - name?: string; - scope?: string | string[]; - settings: ITokenColorizationSetting; -} - -export interface ITokenColorizationSetting { - foreground?: string; - background?: string; - fontStyle?: string; /* [italic|bold|underline|strikethrough] */ -} - -export type ProbeScope = string[]; - export interface IColorTheme { readonly type: ColorScheme; diff --git a/src/vs/platform/theme/test/common/testThemeService.ts b/src/vs/platform/theme/test/common/testThemeService.ts index 1ca1abacdbd84..5109b055e4c4e 100644 --- a/src/vs/platform/theme/test/common/testThemeService.ts +++ b/src/vs/platform/theme/test/common/testThemeService.ts @@ -7,8 +7,7 @@ import { Color } from 'vs/base/common/color'; import { Emitter, Event } from 'vs/base/common/event'; import { IconContribution } from 'vs/platform/theme/common/iconRegistry'; import { ColorScheme } from 'vs/platform/theme/common/theme'; -import { IColorTheme, IFileIconTheme, IProductIconTheme, ITextMateThemingRule, IThemeService, ITokenStyle, ProbeScope } from 'vs/platform/theme/common/themeService'; -import { TokenStyle } from 'vs/platform/theme/common/tokenClassificationRegistry'; +import { IColorTheme, IFileIconTheme, IProductIconTheme, IThemeService, ITokenStyle } from 'vs/platform/theme/common/themeService'; export class TestColorTheme implements IColorTheme { @@ -20,10 +19,6 @@ export class TestColorTheme implements IColorTheme { public readonly semanticHighlighting = false ) { } - resolveScopes(scopes: ProbeScope[], definitions?: ITextMateThemingRule): TokenStyle | undefined { - throw new Error('Method not implemented.'); - } - getColor(color: string, useDefault?: boolean): Color | undefined { const value = this.colors[color]; if (value) { diff --git a/src/vs/workbench/services/textMate/browser/textMateTokenizationFeatureImpl.ts b/src/vs/workbench/services/textMate/browser/textMateTokenizationFeatureImpl.ts index 3ba242b633f06..74a52fae9ff3f 100644 --- a/src/vs/workbench/services/textMate/browser/textMateTokenizationFeatureImpl.ts +++ b/src/vs/workbench/services/textMate/browser/textMateTokenizationFeatureImpl.ts @@ -36,9 +36,8 @@ import { ThreadedBackgroundTokenizerFactory } from 'vs/workbench/services/textMa import { TMGrammarFactory, missingTMGrammarErrorMessage } from 'vs/workbench/services/textMate/common/TMGrammarFactory'; import { ITMSyntaxExtensionPoint, grammarsExtPoint } from 'vs/workbench/services/textMate/common/TMGrammars'; import { IValidEmbeddedLanguagesMap, IValidGrammarDefinition, IValidTokenTypeMap } from 'vs/workbench/services/textMate/common/TMScopeRegistry'; -import { IWorkbenchColorTheme, IWorkbenchThemeService } from 'vs/workbench/services/themes/common/workbenchThemeService'; +import { ITextMateThemingRule, IWorkbenchColorTheme, IWorkbenchThemeService } from 'vs/workbench/services/themes/common/workbenchThemeService'; import type { IGrammar, IOnigLib, IRawTheme } from 'vscode-textmate'; -import { ITextMateThemingRule } from 'vs/platform/theme/common/themeService'; export class TextMateTokenizationFeature extends Disposable implements ITextMateTokenizationService { private static reportTokenizationTimeCounter = { sync: 0, async: 0 }; diff --git a/src/vs/workbench/services/themes/common/colorThemeData.ts b/src/vs/workbench/services/themes/common/colorThemeData.ts index b37cfe30cd70e..dd7a8f0d03f11 100644 --- a/src/vs/workbench/services/themes/common/colorThemeData.ts +++ b/src/vs/workbench/services/themes/common/colorThemeData.ts @@ -6,13 +6,13 @@ import { basename } from 'vs/base/common/path'; import * as Json from 'vs/base/common/json'; import { Color } from 'vs/base/common/color'; -import { ExtensionData, ITokenColorCustomizations, IWorkbenchColorTheme, IColorMap, IThemeExtensionPoint, VS_LIGHT_THEME, VS_HC_THEME, IColorCustomizations, ISemanticTokenRules, ISemanticTokenColorizationSetting, ISemanticTokenColorCustomizations, IThemeScopableCustomizations, IThemeScopedCustomizations, THEME_SCOPE_CLOSE_PAREN, THEME_SCOPE_OPEN_PAREN, themeScopeRegex, THEME_SCOPE_WILDCARD, VS_HC_LIGHT_THEME } from 'vs/workbench/services/themes/common/workbenchThemeService'; +import { ExtensionData, ITokenColorCustomizations, ITextMateThemingRule, IWorkbenchColorTheme, IColorMap, IThemeExtensionPoint, VS_LIGHT_THEME, VS_HC_THEME, IColorCustomizations, ISemanticTokenRules, ISemanticTokenColorizationSetting, ISemanticTokenColorCustomizations, IThemeScopableCustomizations, IThemeScopedCustomizations, THEME_SCOPE_CLOSE_PAREN, THEME_SCOPE_OPEN_PAREN, themeScopeRegex, THEME_SCOPE_WILDCARD, VS_HC_LIGHT_THEME } from 'vs/workbench/services/themes/common/workbenchThemeService'; import { convertSettings } from 'vs/workbench/services/themes/common/themeCompatibility'; import * as nls from 'vs/nls'; import * as types from 'vs/base/common/types'; import * as resources from 'vs/base/common/resources'; import { Extensions as ColorRegistryExtensions, IColorRegistry, ColorIdentifier, editorBackground, editorForeground } from 'vs/platform/theme/common/colorRegistry'; -import { ITextMateThemingRule, ITokenStyle, getThemeTypeSelector } from 'vs/platform/theme/common/themeService'; +import { ITokenStyle, getThemeTypeSelector } from 'vs/platform/theme/common/themeService'; import { Registry } from 'vs/platform/registry/common/platform'; import { getParseErrorMessage } from 'vs/base/common/jsonErrorMessages'; import { URI } from 'vs/base/common/uri'; @@ -236,7 +236,7 @@ export class ColorThemeData implements IWorkbenchColorTheme { return undefined; } - public getTokenColorIndex(): TokenColorIndex { + private getTokenColorIndex(): TokenColorIndex { // collect all colors that tokens can have if (!this.tokenColorIndex) { const index = new TokenColorIndex(); diff --git a/src/vs/workbench/services/themes/common/themeCompatibility.ts b/src/vs/workbench/services/themes/common/themeCompatibility.ts index 8b698db8a7214..21c643584f06d 100644 --- a/src/vs/workbench/services/themes/common/themeCompatibility.ts +++ b/src/vs/workbench/services/themes/common/themeCompatibility.ts @@ -3,12 +3,11 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { IColorMap } from 'vs/workbench/services/themes/common/workbenchThemeService'; +import { ITextMateThemingRule, IColorMap } from 'vs/workbench/services/themes/common/workbenchThemeService'; import { Color } from 'vs/base/common/color'; import * as colorRegistry from 'vs/platform/theme/common/colorRegistry'; import * as editorColorRegistry from 'vs/editor/common/core/editorColorRegistry'; -import { ITextMateThemingRule } from 'vs/platform/theme/common/themeService'; const settingToColorIdMapping: { [settingId: string]: string[] } = {}; function addSettingMapping(settingId: string, colorId: string) { diff --git a/src/vs/workbench/services/themes/common/workbenchThemeService.ts b/src/vs/workbench/services/themes/common/workbenchThemeService.ts index c60a281d054fe..aac853941a768 100644 --- a/src/vs/workbench/services/themes/common/workbenchThemeService.ts +++ b/src/vs/workbench/services/themes/common/workbenchThemeService.ts @@ -6,7 +6,7 @@ import { refineServiceDecorator } from 'vs/platform/instantiation/common/instantiation'; import { Event } from 'vs/base/common/event'; import { Color } from 'vs/base/common/color'; -import { IColorTheme, IThemeService, IFileIconTheme, IProductIconTheme, ITextMateThemingRule, ITokenColorizationSetting } from 'vs/platform/theme/common/themeService'; +import { IColorTheme, IThemeService, IFileIconTheme, IProductIconTheme } from 'vs/platform/theme/common/themeService'; import { ConfigurationTarget } from 'vs/platform/configuration/common/configuration'; import { isBoolean, isString } from 'vs/base/common/types'; import { IconContribution, IconDefinition } from 'vs/platform/theme/common/iconRegistry'; @@ -233,6 +233,18 @@ export interface ISemanticTokenRules { [selector: string]: string | ISemanticTokenColorizationSetting | undefined; } +export interface ITextMateThemingRule { + name?: string; + scope?: string | string[]; + settings: ITokenColorizationSetting; +} + +export interface ITokenColorizationSetting { + foreground?: string; + background?: string; + fontStyle?: string; /* [italic|bold|underline|strikethrough] */ +} + export interface ISemanticTokenColorizationSetting { foreground?: string; fontStyle?: string; /* [italic|bold|underline|strikethrough] */ From 7c0e5d5f7d61239d932982f62a10c0d28db84d17 Mon Sep 17 00:00:00 2001 From: Alex Ross Date: Mon, 27 May 2024 16:10:30 +0200 Subject: [PATCH 13/37] Add yielding --- .../treeSitter/treeSitterParserService.ts | 70 ++++++++++++++----- 1 file changed, 54 insertions(+), 16 deletions(-) diff --git a/src/vs/editor/browser/services/treeSitter/treeSitterParserService.ts b/src/vs/editor/browser/services/treeSitter/treeSitterParserService.ts index 4bd113f796ae7..76eaf38f4dc5a 100644 --- a/src/vs/editor/browser/services/treeSitter/treeSitterParserService.ts +++ b/src/vs/editor/browser/services/treeSitter/treeSitterParserService.ts @@ -16,6 +16,10 @@ import { IModelContentChangedEvent, IModelLanguageChangedEvent } from 'vs/editor import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { ILogService } from 'vs/platform/log/common/log'; import { Range } from 'vs/editor/common/core/range'; +import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; +import { setTimeout0 } from 'vs/base/common/platform'; + +const EDITOR_EXPERIMENTAL_PREFER_TREESITTER = 'editor.experimental.preferTreeSitter'; export class TreeSitterTree implements IDisposable { private _tree: Parser.Tree | undefined; @@ -65,9 +69,17 @@ export class TreeSitterParserService extends Disposable implements ITreeSitterPa constructor(@IModelService private readonly _modelService: IModelService, @IFileService private readonly _fileService: IFileService, @ITelemetryService private readonly _telemetryService: ITelemetryService, - @ILogService private readonly _logService: ILogService + @ILogService private readonly _logService: ILogService, + @IConfigurationService private readonly _configurationService: IConfigurationService ) { super(); + + const setting = this._getSetting(); + if (setting.length === 0) { + this._init = Promise.resolve(); + return; + } + this._init = Parser.init({ locateFile(_file: string, _folder: string) { const wasmPath: AppResourcePath = `vs/base/common/web-tree-sitter/tree-sitter.wasm`; @@ -75,11 +87,20 @@ export class TreeSitterParserService extends Disposable implements ITreeSitterPa } }); // Eventually, this should actually use an extension point to add tree sitter grammars, but for now they are hard coded in core - this._addGrammar('html', 'tree-sitter-html'); - this._addGrammar('typescript', 'tree-sitter-typescript'); + if (setting.includes('html')) { + this._addGrammar('html', 'tree-sitter-html'); + } + if (setting.includes('typescript')) { + this._addGrammar('typescript', 'tree-sitter-typescript'); + } this._registerModelServiceListeners(); } + + private _getSetting(): string[] { + return this._configurationService.getValue(EDITOR_EXPERIMENTAL_PREFER_TREESITTER) || []; + } + getLanguageLocation(languageId: string): AppResourcePath | undefined { const grammarName = TreeSitterTokenizationRegistry.get(languageId); if (!grammarName) { @@ -105,6 +126,7 @@ export class TreeSitterParserService extends Disposable implements ITreeSitterPa disposables.add(model.onDidChangeContent(e => this._onDidChangeContent(model, e))); disposables.add(model.onDidChangeLanguage(e => this._onDidChangeLanguage(model, e))); const parser = new Parser(); + parser.setTimeoutMicros(300 * 1000); // 300 ms const treeSitterTree = new TreeSitterTree(parser, disposables); this._treeSitterTrees.set(model, treeSitterTree); this._setLanguageAndTree(model, treeSitterTree); @@ -117,27 +139,45 @@ export class TreeSitterParserService extends Disposable implements ITreeSitterPa return; } treeSitterTree.language = language; - treeSitterTree.tree = this._doInitialParse(model, treeSitterTree, languageId); + treeSitterTree.tree = await this._doInitialParse(model, treeSitterTree, languageId); } + private async _parseAndYield(model: ITextModel, treeSitterTree: TreeSitterTree, language: string, telemetryTag: string): Promise { + let tree: Parser.Tree | undefined; + let time: number = 0; + let passes: number = 0; + do { + const timer = performance.now(); + try { + tree = treeSitterTree.parser.parse((index: number, position?: Parser.Point) => this._parseCallback(model, index, position, treeSitterTree)); + } catch (e) { + // parsing can fail when the timeout is reached, will resume upon next loop + } finally { + time += performance.now() - timer; + passes++; + } + await new Promise(resolve => setTimeout0(resolve)); + } while (!tree); + this.sendParseTimeTelemetry(telemetryTag, language, time, passes); + return tree; + } - private _doInitialParse(model: ITextModel, treeSitterTree: TreeSitterTree, language: string): Parser.Tree { + private _doInitialParse(model: ITextModel, treeSitterTree: TreeSitterTree, language: string): Promise { treeSitterTree.createSnapshot(model); - const timer = performance.now(); - const newTree = treeSitterTree.parser.parse((index: number, position?: Parser.Point) => this._parseCallback(model, index, position, treeSitterTree)); - this.sendParseTimeTelemetry('fullParse', language, performance.now() - timer); + const newTree = this._parseAndYield(model, treeSitterTree, language, 'fullParse'); return newTree; } - private sendParseTimeTelemetry(eventName: string, languageId: string, time: number): void { - this._logService.info(`Tree parsing (${eventName}) took ${time} ms`); + private sendParseTimeTelemetry(eventName: string, languageId: string, time: number, passes: number): void { + this._logService.info(`Tree parsing (${eventName}) took ${time} ms and ${passes} passes.`); type ParseTimeClassification = { owner: 'alros'; comment: 'Used to understand how long it takes to parse a tree-sitter tree'; languageId: { classification: 'SystemMetaData'; purpose: 'FeatureInsight'; comment: 'The programming language ID.' }; time: { classification: 'SystemMetaData'; purpose: 'FeatureInsight'; comment: 'The ms it took to parse' }; + passes: { classification: 'SystemMetaData'; purpose: 'FeatureInsight'; comment: 'The number of passes it took to parse' }; }; - this._telemetryService.publicLog2<{ languageId: string; time: number }, ParseTimeClassification>(`treeSitter.${eventName}`, { languageId, time }); + this._telemetryService.publicLog2<{ languageId: string; time: number; passes: number }, ParseTimeClassification>(`treeSitter.${eventName}`, { languageId, time, passes }); } private async _onDidChangeLanguage(model: ITextModel, e: IModelLanguageChangedEvent) { @@ -152,11 +192,11 @@ export class TreeSitterParserService extends Disposable implements ITreeSitterPa return; } tree.language = language; - const newTree = this._doInitialParse(model, tree, e.newLanguage); + const newTree = await this._doInitialParse(model, tree, e.newLanguage); tree.tree = newTree; } - private _onDidChangeContent(model: ITextModel, e: IModelContentChangedEvent) { + private async _onDidChangeContent(model: ITextModel, e: IModelContentChangedEvent) { const tree = this._treeSitterTrees.get(model); if (!tree?.language) { return; @@ -174,9 +214,7 @@ export class TreeSitterParserService extends Disposable implements ITreeSitterPa newEndPosition: { row: newEndPosition.lineNumber - 1, column: newEndPosition.column - 1 } }); } - const timer = performance.now(); - tree.tree = tree.parser.parse((index: number, position?: Parser.Point) => this._parseCallback(model, index, position), tree.tree); - this.sendParseTimeTelemetry('incrementalParse', model.getLanguageId(), performance.now() - timer); + tree.tree = await this._parseAndYield(model, tree, model.getLanguageId(), 'incrementalParse'); } private async _fetchLanguage(languageId: string): Promise { From e32a24d76f3581f5a6cf99e88f910f5780e955ea Mon Sep 17 00:00:00 2001 From: Alex Ross Date: Mon, 27 May 2024 16:22:00 +0200 Subject: [PATCH 14/37] Remove changes that aren't required for PR --- .../tree-sitter-html/highlights.scm | 15 -- .../tree-sitter-typescript/highlights.scm | 3 - .../test/browser/workbenchTestServices.ts | 190 ------------------ .../test/browser/mainThreadEditors.test.ts | 3 +- .../debug/test/browser/mockDebugModel.ts | 2 +- .../files/test/browser/editorAutoSave.test.ts | 3 +- .../files/test/browser/explorerModel.test.ts | 3 +- .../files/test/browser/explorerView.test.ts | 2 +- .../browser/textFileEditorTracker.test.ts | 3 +- .../gettingStartedMarkdownRenderer.test.ts | 2 +- .../test/browser/extensionService.test.ts | 3 +- .../workingCopyBackupTracker.test.ts | 3 +- .../workingCopyHistoryTracker.test.ts | 3 +- .../test/browser/workbenchTestServices.ts | 173 +++++++++++++++- .../electron-sandbox/workbenchTestServices.ts | 3 +- 15 files changed, 177 insertions(+), 234 deletions(-) delete mode 100644 src/vs/base/common/treeSitterLanguages/tree-sitter-html/highlights.scm delete mode 100644 src/vs/base/common/treeSitterLanguages/tree-sitter-typescript/highlights.scm delete mode 100644 src/vs/platform/files/test/browser/workbenchTestServices.ts diff --git a/src/vs/base/common/treeSitterLanguages/tree-sitter-html/highlights.scm b/src/vs/base/common/treeSitterLanguages/tree-sitter-html/highlights.scm deleted file mode 100644 index 2107ae1cbc1ee..0000000000000 --- a/src/vs/base/common/treeSitterLanguages/tree-sitter-html/highlights.scm +++ /dev/null @@ -1,15 +0,0 @@ -(tag_name) @entity.name.tag -(attribute_name) @entity.other.attribute-name -(attribute_value) @string -"\"" @string -(comment) @comment - -"=" @punctuation.separator.key-value - -[ - "<" - ">" - "" -] @meta.tag diff --git a/src/vs/base/common/treeSitterLanguages/tree-sitter-typescript/highlights.scm b/src/vs/base/common/treeSitterLanguages/tree-sitter-typescript/highlights.scm deleted file mode 100644 index 2fe6f45e4af1c..0000000000000 --- a/src/vs/base/common/treeSitterLanguages/tree-sitter-typescript/highlights.scm +++ /dev/null @@ -1,3 +0,0 @@ -(identifier) @variable - -(comment) @comment \ No newline at end of file diff --git a/src/vs/platform/files/test/browser/workbenchTestServices.ts b/src/vs/platform/files/test/browser/workbenchTestServices.ts deleted file mode 100644 index 85d60d6076a57..0000000000000 --- a/src/vs/platform/files/test/browser/workbenchTestServices.ts +++ /dev/null @@ -1,190 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import { timeout } from 'vs/base/common/async'; -import { VSBuffer, bufferToStream, VSBufferReadable } from 'vs/base/common/buffer'; -import { Emitter, Event } from 'vs/base/common/event'; -import { Iterable } from 'vs/base/common/iterator'; -import { toDisposable, IDisposable } from 'vs/base/common/lifecycle'; -import { ResourceMap } from 'vs/base/common/map'; -import { Schemas } from 'vs/base/common/network'; -import { isLinux } from 'vs/base/common/platform'; -import { basename } from 'vs/base/common/resources'; -import { URI } from 'vs/base/common/uri'; -import { IFileService, FileChangesEvent, FileOperationEvent, IFileSystemProviderCapabilitiesChangeEvent, IFileSystemProviderActivationEvent, IResolveMetadataFileOptions, IFileStatWithMetadata, IResolveFileOptions, IFileStat, IFileStatWithPartialMetadata, IFileStatResult, IReadFileOptions, IFileContent, IReadFileStreamOptions, IFileStreamContent, IWriteFileOptions, ICreateFileOptions, IFileSystemProvider, FileSystemProviderCapabilities, IWatchOptions, IFileSystemWatcher, IWatchOptionsWithCorrelation } from 'vs/platform/files/common/files'; - -export function createFileStat(resource: URI, readonly = false): IFileStatWithMetadata { - return { - resource, - etag: Date.now().toString(), - mtime: Date.now(), - ctime: Date.now(), - size: 42, - isFile: true, - isDirectory: false, - isSymbolicLink: false, - readonly, - locked: false, - name: basename(resource), - children: undefined - }; -} - -export class TestFileService implements IFileService { - - declare readonly _serviceBrand: undefined; - - private readonly _onDidFilesChange = new Emitter(); - get onDidFilesChange(): Event { return this._onDidFilesChange.event; } - fireFileChanges(event: FileChangesEvent): void { this._onDidFilesChange.fire(event); } - - private readonly _onDidRunOperation = new Emitter(); - get onDidRunOperation(): Event { return this._onDidRunOperation.event; } - fireAfterOperation(event: FileOperationEvent): void { this._onDidRunOperation.fire(event); } - - private readonly _onDidChangeFileSystemProviderCapabilities = new Emitter(); - get onDidChangeFileSystemProviderCapabilities(): Event { return this._onDidChangeFileSystemProviderCapabilities.event; } - fireFileSystemProviderCapabilitiesChangeEvent(event: IFileSystemProviderCapabilitiesChangeEvent): void { this._onDidChangeFileSystemProviderCapabilities.fire(event); } - - private _onWillActivateFileSystemProvider = new Emitter(); - readonly onWillActivateFileSystemProvider = this._onWillActivateFileSystemProvider.event; - readonly onDidWatchError = Event.None; - - private content = 'Hello Html'; - private lastReadFileUri!: URI; - - readonly = false; - - setContent(content: string): void { this.content = content; } - getContent(): string { return this.content; } - getLastReadFileUri(): URI { return this.lastReadFileUri; } - - resolve(resource: URI, _options: IResolveMetadataFileOptions): Promise; - resolve(resource: URI, _options?: IResolveFileOptions): Promise; - async resolve(resource: URI, _options?: IResolveFileOptions): Promise { - return createFileStat(resource, this.readonly); - } - - stat(resource: URI): Promise { - return this.resolve(resource, { resolveMetadata: true }); - } - - async resolveAll(toResolve: { resource: URI; options?: IResolveFileOptions }[]): Promise { - const stats = await Promise.all(toResolve.map(resourceAndOption => this.resolve(resourceAndOption.resource, resourceAndOption.options))); - - return stats.map(stat => ({ stat, success: true })); - } - - readonly notExistsSet = new ResourceMap(); - - async exists(_resource: URI): Promise { return !this.notExistsSet.has(_resource); } - - readShouldThrowError: Error | undefined = undefined; - - async readFile(resource: URI, options?: IReadFileOptions | undefined): Promise { - if (this.readShouldThrowError) { - throw this.readShouldThrowError; - } - - this.lastReadFileUri = resource; - - return { - ...createFileStat(resource, this.readonly), - value: VSBuffer.fromString(this.content) - }; - } - - async readFileStream(resource: URI, options?: IReadFileStreamOptions | undefined): Promise { - if (this.readShouldThrowError) { - throw this.readShouldThrowError; - } - - this.lastReadFileUri = resource; - - return { - ...createFileStat(resource, this.readonly), - value: bufferToStream(VSBuffer.fromString(this.content)) - }; - } - - writeShouldThrowError: Error | undefined = undefined; - - async writeFile(resource: URI, bufferOrReadable: VSBuffer | VSBufferReadable, options?: IWriteFileOptions): Promise { - await timeout(0); - - if (this.writeShouldThrowError) { - throw this.writeShouldThrowError; - } - - return createFileStat(resource, this.readonly); - } - - move(_source: URI, _target: URI, _overwrite?: boolean): Promise { return Promise.resolve(null!); } - copy(_source: URI, _target: URI, _overwrite?: boolean): Promise { return Promise.resolve(null!); } - async cloneFile(_source: URI, _target: URI): Promise { } - createFile(_resource: URI, _content?: VSBuffer | VSBufferReadable, _options?: ICreateFileOptions): Promise { return Promise.resolve(null!); } - createFolder(_resource: URI): Promise { return Promise.resolve(null!); } - - onDidChangeFileSystemProviderRegistrations = Event.None; - - private providers = new Map(); - - registerProvider(scheme: string, provider: IFileSystemProvider) { - this.providers.set(scheme, provider); - - return toDisposable(() => this.providers.delete(scheme)); - } - - getProvider(scheme: string) { - return this.providers.get(scheme); - } - - async activateProvider(_scheme: string): Promise { - this._onWillActivateFileSystemProvider.fire({ scheme: _scheme, join: () => { } }); - } - async canHandleResource(resource: URI): Promise { return this.hasProvider(resource); } - hasProvider(resource: URI): boolean { return resource.scheme === Schemas.file || this.providers.has(resource.scheme); } - listCapabilities() { - return [ - { scheme: Schemas.file, capabilities: FileSystemProviderCapabilities.FileOpenReadWriteClose }, - ...Iterable.map(this.providers, ([scheme, p]) => { return { scheme, capabilities: p.capabilities }; }) - ]; - } - hasCapability(resource: URI, capability: FileSystemProviderCapabilities): boolean { - if (capability === FileSystemProviderCapabilities.PathCaseSensitive && isLinux) { - return true; - } - - const provider = this.getProvider(resource.scheme); - - return !!(provider && (provider.capabilities & capability)); - } - - async del(_resource: URI, _options?: { useTrash?: boolean; recursive?: boolean }): Promise { } - - createWatcher(resource: URI, options: IWatchOptions): IFileSystemWatcher { - return { - onDidChange: Event.None, - dispose: () => { } - }; - } - - - readonly watches: URI[] = []; - watch(_resource: URI, options: IWatchOptionsWithCorrelation): IFileSystemWatcher; - watch(_resource: URI): IDisposable; - watch(_resource: URI): IDisposable { - this.watches.push(_resource); - - return toDisposable(() => this.watches.splice(this.watches.indexOf(_resource), 1)); - } - - dispose(): void { } - - async canCreateFile(source: URI, options?: ICreateFileOptions): Promise { return true; } - async canMove(source: URI, target: URI, overwrite?: boolean | undefined): Promise { return true; } - async canCopy(source: URI, target: URI, overwrite?: boolean | undefined): Promise { return true; } - async canDelete(resource: URI, options?: { useTrash?: boolean | undefined; recursive?: boolean | undefined } | undefined): Promise { return true; } -} diff --git a/src/vs/workbench/api/test/browser/mainThreadEditors.test.ts b/src/vs/workbench/api/test/browser/mainThreadEditors.test.ts index 0c5a495051bd3..b6b7983569d1a 100644 --- a/src/vs/workbench/api/test/browser/mainThreadEditors.test.ts +++ b/src/vs/workbench/api/test/browser/mainThreadEditors.test.ts @@ -55,9 +55,8 @@ import { IPaneCompositePartService } from 'vs/workbench/services/panecomposite/b import { ITextFileService } from 'vs/workbench/services/textfile/common/textfiles'; import { ICopyOperation, ICreateFileOperation, ICreateOperation, IDeleteOperation, IMoveOperation, IWorkingCopyFileService } from 'vs/workbench/services/workingCopy/common/workingCopyFileService'; import { IWorkingCopyService } from 'vs/workbench/services/workingCopy/common/workingCopyService'; -import { TestEditorGroupsService, TestEditorService, TestEnvironmentService, TestLifecycleService, TestWorkingCopyService } from 'vs/workbench/test/browser/workbenchTestServices'; +import { TestEditorGroupsService, TestEditorService, TestEnvironmentService, TestFileService, TestLifecycleService, TestWorkingCopyService } from 'vs/workbench/test/browser/workbenchTestServices'; import { TestContextService, TestTextResourcePropertiesService } from 'vs/workbench/test/common/workbenchTestServices'; -import { TestFileService } from 'vs/platform/files/test/browser/workbenchTestServices'; import { TestInstantiationService } from 'vs/platform/instantiation/test/common/instantiationServiceMock'; suite('MainThreadEditors', () => { diff --git a/src/vs/workbench/contrib/debug/test/browser/mockDebugModel.ts b/src/vs/workbench/contrib/debug/test/browser/mockDebugModel.ts index 411c343237dae..385b4c1ae66ea 100644 --- a/src/vs/workbench/contrib/debug/test/browser/mockDebugModel.ts +++ b/src/vs/workbench/contrib/debug/test/browser/mockDebugModel.ts @@ -8,7 +8,7 @@ import { NullLogService } from 'vs/platform/log/common/log'; import { UriIdentityService } from 'vs/platform/uriIdentity/common/uriIdentityService'; import { DebugModel } from 'vs/workbench/contrib/debug/common/debugModel'; import { MockDebugStorage } from 'vs/workbench/contrib/debug/test/common/mockDebug'; -import { TestFileService } from 'vs/platform/files/test/browser/workbenchTestServices'; +import { TestFileService } from 'vs/workbench/test/browser/workbenchTestServices'; import { TestStorageService } from 'vs/workbench/test/common/workbenchTestServices'; const fileService = new TestFileService(); diff --git a/src/vs/workbench/contrib/files/test/browser/editorAutoSave.test.ts b/src/vs/workbench/contrib/files/test/browser/editorAutoSave.test.ts index 6d4628a5941ce..7e78480060e79 100644 --- a/src/vs/workbench/contrib/files/test/browser/editorAutoSave.test.ts +++ b/src/vs/workbench/contrib/files/test/browser/editorAutoSave.test.ts @@ -7,8 +7,7 @@ import * as assert from 'assert'; import { Event } from 'vs/base/common/event'; import { ensureNoDisposablesAreLeakedInTestSuite, toResource } from 'vs/base/test/common/utils'; import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; -import { TestFilesConfigurationService, workbenchInstantiationService, TestServiceAccessor, registerTestFileEditor, createEditorPart, TestEnvironmentService, TestTextResourceConfigurationService } from 'vs/workbench/test/browser/workbenchTestServices'; -import { TestFileService } from 'vs/platform/files/test/browser/workbenchTestServices'; +import { TestFilesConfigurationService, workbenchInstantiationService, TestServiceAccessor, registerTestFileEditor, createEditorPart, TestEnvironmentService, TestTextResourceConfigurationService, TestFileService } from 'vs/workbench/test/browser/workbenchTestServices'; import { ITextFileEditorModel } from 'vs/workbench/services/textfile/common/textfiles'; import { IEditorGroupsService } from 'vs/workbench/services/editor/common/editorGroupsService'; import { DisposableStore } from 'vs/base/common/lifecycle'; diff --git a/src/vs/workbench/contrib/files/test/browser/explorerModel.test.ts b/src/vs/workbench/contrib/files/test/browser/explorerModel.test.ts index c98fcf38c1c6d..938fed848a2de 100644 --- a/src/vs/workbench/contrib/files/test/browser/explorerModel.test.ts +++ b/src/vs/workbench/contrib/files/test/browser/explorerModel.test.ts @@ -10,10 +10,9 @@ import { join } from 'vs/base/common/path'; import { validateFileName } from 'vs/workbench/contrib/files/browser/fileActions'; import { ExplorerItem } from 'vs/workbench/contrib/files/common/explorerModel'; import { ensureNoDisposablesAreLeakedInTestSuite, toResource } from 'vs/base/test/common/utils'; -import { TestPathService } from 'vs/workbench/test/browser/workbenchTestServices'; +import { TestFileService, TestPathService } from 'vs/workbench/test/browser/workbenchTestServices'; import { TestConfigurationService } from 'vs/platform/configuration/test/common/testConfigurationService'; import { NullFilesConfigurationService } from 'vs/workbench/test/common/workbenchTestServices'; -import { TestFileService } from 'vs/platform/files/test/browser/workbenchTestServices'; suite('Files - View Model', function () { diff --git a/src/vs/workbench/contrib/files/test/browser/explorerView.test.ts b/src/vs/workbench/contrib/files/test/browser/explorerView.test.ts index 10a2ff238aa7a..cea1d9c71724f 100644 --- a/src/vs/workbench/contrib/files/test/browser/explorerView.test.ts +++ b/src/vs/workbench/contrib/files/test/browser/explorerView.test.ts @@ -6,7 +6,7 @@ import * as assert from 'assert'; import { Emitter } from 'vs/base/common/event'; import { ensureNoDisposablesAreLeakedInTestSuite, toResource } from 'vs/base/test/common/utils'; -import { TestFileService } from 'vs/platform/files/test/browser/workbenchTestServices'; +import { TestFileService } from 'vs/workbench/test/browser/workbenchTestServices'; import { ExplorerItem } from 'vs/workbench/contrib/files/common/explorerModel'; import { getContext } from 'vs/workbench/contrib/files/browser/views/explorerView'; import { listInvalidItemForeground } from 'vs/platform/theme/common/colorRegistry'; diff --git a/src/vs/workbench/contrib/files/test/browser/textFileEditorTracker.test.ts b/src/vs/workbench/contrib/files/test/browser/textFileEditorTracker.test.ts index 2babdb1f4a724..624ea86664016 100644 --- a/src/vs/workbench/contrib/files/test/browser/textFileEditorTracker.test.ts +++ b/src/vs/workbench/contrib/files/test/browser/textFileEditorTracker.test.ts @@ -8,8 +8,7 @@ import { Event } from 'vs/base/common/event'; import { TextFileEditorTracker } from 'vs/workbench/contrib/files/browser/editors/textFileEditorTracker'; import { ensureNoDisposablesAreLeakedInTestSuite, toResource } from 'vs/base/test/common/utils'; import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; -import { workbenchInstantiationService, TestServiceAccessor, TestFilesConfigurationService, registerTestFileEditor, registerTestResourceEditor, createEditorPart, TestEnvironmentService, workbenchTeardown, TestTextResourceConfigurationService } from 'vs/workbench/test/browser/workbenchTestServices'; -import { TestFileService } from 'vs/platform/files/test/browser/workbenchTestServices'; +import { workbenchInstantiationService, TestServiceAccessor, TestFilesConfigurationService, registerTestFileEditor, registerTestResourceEditor, createEditorPart, TestEnvironmentService, workbenchTeardown, TestTextResourceConfigurationService, TestFileService } from 'vs/workbench/test/browser/workbenchTestServices'; import { IResolvedTextFileEditorModel, snapshotToString, ITextFileService } from 'vs/workbench/services/textfile/common/textfiles'; import { FileChangesEvent, FileChangeType, FileOperationError, FileOperationResult } from 'vs/platform/files/common/files'; import { IEditorGroupsService } from 'vs/workbench/services/editor/common/editorGroupsService'; diff --git a/src/vs/workbench/contrib/welcomeGettingStarted/test/browser/gettingStartedMarkdownRenderer.test.ts b/src/vs/workbench/contrib/welcomeGettingStarted/test/browser/gettingStartedMarkdownRenderer.test.ts index a6c56e731a7bb..b7b09ca9417ca 100644 --- a/src/vs/workbench/contrib/welcomeGettingStarted/test/browser/gettingStartedMarkdownRenderer.test.ts +++ b/src/vs/workbench/contrib/welcomeGettingStarted/test/browser/gettingStartedMarkdownRenderer.test.ts @@ -10,7 +10,7 @@ import { LanguageService } from 'vs/editor/common/services/languageService'; import { TestNotificationService } from 'vs/platform/notification/test/common/testNotificationService'; import { GettingStartedDetailsRenderer } from 'vs/workbench/contrib/welcomeGettingStarted/browser/gettingStartedDetailsRenderer'; import { convertInternalMediaPathToFileURI } from 'vs/workbench/contrib/welcomeGettingStarted/browser/gettingStartedService'; -import { TestFileService } from 'vs/platform/files/test/browser/workbenchTestServices'; +import { TestFileService } from 'vs/workbench/test/browser/workbenchTestServices'; import { TestExtensionService } from 'vs/workbench/test/common/workbenchTestServices'; diff --git a/src/vs/workbench/services/extensions/test/browser/extensionService.test.ts b/src/vs/workbench/services/extensions/test/browser/extensionService.test.ts index b182d5fdee87e..3ced43a5f42ae 100644 --- a/src/vs/workbench/services/extensions/test/browser/extensionService.test.ts +++ b/src/vs/workbench/services/extensions/test/browser/extensionService.test.ts @@ -14,7 +14,6 @@ import { TestDialogService } from 'vs/platform/dialogs/test/common/testDialogSer import { ExtensionKind, IEnvironmentService } from 'vs/platform/environment/common/environment'; import { ExtensionIdentifier, IExtension, IRelaxedExtensionDescription } from 'vs/platform/extensions/common/extensions'; import { IFileService } from 'vs/platform/files/common/files'; -import { TestFileService } from 'vs/platform/files/test/browser/workbenchTestServices'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { TestInstantiationService, createServices } from 'vs/platform/instantiation/test/common/instantiationServiceMock'; import { ILogService, NullLogService } from 'vs/platform/log/common/log'; @@ -47,7 +46,7 @@ import { ILifecycleService } from 'vs/workbench/services/lifecycle/common/lifecy import { IRemoteAgentService } from 'vs/workbench/services/remote/common/remoteAgentService'; import { IUserDataProfileService } from 'vs/workbench/services/userDataProfile/common/userDataProfile'; import { WorkspaceTrustEnablementService } from 'vs/workbench/services/workspaces/common/workspaceTrust'; -import { TestEnvironmentService, TestLifecycleService, TestRemoteAgentService, TestRemoteExtensionsScannerService, TestUserDataProfileService, TestWebExtensionsScannerService, TestWorkbenchExtensionEnablementService, TestWorkbenchExtensionManagementService } from 'vs/workbench/test/browser/workbenchTestServices'; +import { TestEnvironmentService, TestFileService, TestLifecycleService, TestRemoteAgentService, TestRemoteExtensionsScannerService, TestUserDataProfileService, TestWebExtensionsScannerService, TestWorkbenchExtensionEnablementService, TestWorkbenchExtensionManagementService } from 'vs/workbench/test/browser/workbenchTestServices'; import { TestContextService } from 'vs/workbench/test/common/workbenchTestServices'; suite('BrowserExtensionService', () => { diff --git a/src/vs/workbench/services/workingCopy/test/electron-sandbox/workingCopyBackupTracker.test.ts b/src/vs/workbench/services/workingCopy/test/electron-sandbox/workingCopyBackupTracker.test.ts index 628af00c751c0..fa293b361cf92 100644 --- a/src/vs/workbench/services/workingCopy/test/electron-sandbox/workingCopyBackupTracker.test.ts +++ b/src/vs/workbench/services/workingCopy/test/electron-sandbox/workingCopyBackupTracker.test.ts @@ -28,8 +28,7 @@ import { INativeHostService } from 'vs/platform/native/common/native'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { TestConfigurationService } from 'vs/platform/configuration/test/common/testConfigurationService'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; -import { createEditorPart, registerTestFileEditor, TestBeforeShutdownEvent, TestEnvironmentService, TestFilesConfigurationService, TestTextResourceConfigurationService, workbenchTeardown } from 'vs/workbench/test/browser/workbenchTestServices'; -import { TestFileService } from 'vs/platform/files/test/browser/workbenchTestServices'; +import { createEditorPart, registerTestFileEditor, TestBeforeShutdownEvent, TestEnvironmentService, TestFilesConfigurationService, TestFileService, TestTextResourceConfigurationService, workbenchTeardown } from 'vs/workbench/test/browser/workbenchTestServices'; import { MockContextKeyService } from 'vs/platform/keybinding/test/common/mockKeybindingService'; import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; import { IEnvironmentService } from 'vs/platform/environment/common/environment'; diff --git a/src/vs/workbench/services/workingCopy/test/electron-sandbox/workingCopyHistoryTracker.test.ts b/src/vs/workbench/services/workingCopy/test/electron-sandbox/workingCopyHistoryTracker.test.ts index 257e265bfd5d1..ef04d7041db52 100644 --- a/src/vs/workbench/services/workingCopy/test/electron-sandbox/workingCopyHistoryTracker.test.ts +++ b/src/vs/workbench/services/workingCopy/test/electron-sandbox/workingCopyHistoryTracker.test.ts @@ -12,8 +12,7 @@ import { URI } from 'vs/base/common/uri'; import { WorkingCopyHistoryTracker } from 'vs/workbench/services/workingCopy/common/workingCopyHistoryTracker'; import { WorkingCopyService } from 'vs/workbench/services/workingCopy/common/workingCopyService'; import { UriIdentityService } from 'vs/platform/uriIdentity/common/uriIdentityService'; -import { TestPathService } from 'vs/workbench/test/browser/workbenchTestServices'; -import { TestFileService } from 'vs/platform/files/test/browser/workbenchTestServices'; +import { TestFileService, TestPathService } from 'vs/workbench/test/browser/workbenchTestServices'; import { DeferredPromise } from 'vs/base/common/async'; import { IFileService } from 'vs/platform/files/common/files'; import { Schemas } from 'vs/base/common/network'; diff --git a/src/vs/workbench/test/browser/workbenchTestServices.ts b/src/vs/workbench/test/browser/workbenchTestServices.ts index b191e1c1519db..e7c8dbf262aff 100644 --- a/src/vs/workbench/test/browser/workbenchTestServices.ts +++ b/src/vs/workbench/test/browser/workbenchTestServices.ts @@ -23,11 +23,11 @@ import { IUntitledTextEditorService, UntitledTextEditorService } from 'vs/workbe import { IWorkspaceContextService, IWorkspaceIdentifier } from 'vs/platform/workspace/common/workspace'; import { ILifecycleService, ShutdownReason, StartupKind, LifecyclePhase, WillShutdownEvent, BeforeShutdownErrorEvent, InternalBeforeShutdownEvent, IWillShutdownEventJoiner } from 'vs/workbench/services/lifecycle/common/lifecycle'; import { ServiceCollection } from 'vs/platform/instantiation/common/serviceCollection'; -import { IFileService, IFileSystemProvider, FileSystemProviderCapabilities, IFileChange, IWatchOptions, IStat, FileType, IFileDeleteOptions, IFileOverwriteOptions, IFileWriteOptions, IFileOpenOptions, IFileStatWithMetadata, FileOperationError, IFileSystemProviderWithFileReadStreamCapability, IFileReadStreamOptions } from 'vs/platform/files/common/files'; +import { FileOperationEvent, IFileService, IFileStat, IFileStatResult, FileChangesEvent, IResolveFileOptions, ICreateFileOptions, IFileSystemProvider, FileSystemProviderCapabilities, IFileChange, IWatchOptions, IStat, FileType, IFileDeleteOptions, IFileOverwriteOptions, IFileWriteOptions, IFileOpenOptions, IFileStatWithMetadata, IResolveMetadataFileOptions, IWriteFileOptions, IReadFileOptions, IFileContent, IFileStreamContent, FileOperationError, IFileSystemProviderWithFileReadStreamCapability, IFileReadStreamOptions, IReadFileStreamOptions, IFileSystemProviderCapabilitiesChangeEvent, IFileStatWithPartialMetadata, IFileSystemWatcher, IWatchOptionsWithCorrelation, IFileSystemProviderActivationEvent } from 'vs/platform/files/common/files'; import { IModelService } from 'vs/editor/common/services/model'; import { LanguageService } from 'vs/editor/common/services/languageService'; import { ModelService } from 'vs/editor/common/services/modelService'; -import { ITextFileService, IReadTextFileOptions, ITextFileStreamContent, IWriteTextFileOptions, ITextFileEditorModel, ITextFileEditorModelManager } from 'vs/workbench/services/textfile/common/textfiles'; +import { IResourceEncoding, ITextFileService, IReadTextFileOptions, ITextFileStreamContent, IWriteTextFileOptions, ITextFileEditorModel, ITextFileEditorModelManager } from 'vs/workbench/services/textfile/common/textfiles'; import { ILanguageService } from 'vs/editor/common/languages/language'; import { IHistoryService } from 'vs/workbench/services/history/common/history'; import { IInstantiationService, ServiceIdentifier } from 'vs/platform/instantiation/common/instantiation'; @@ -51,7 +51,7 @@ import { TestNotificationService } from 'vs/platform/notification/test/common/te import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions'; import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; import { IDecorationsService, IResourceDecorationChangeEvent, IDecoration, IDecorationData, IDecorationsProvider } from 'vs/workbench/services/decorations/common/decorations'; -import { IDisposable, Disposable, DisposableStore } from 'vs/base/common/lifecycle'; +import { IDisposable, toDisposable, Disposable, DisposableStore } from 'vs/base/common/lifecycle'; import { IEditorGroupsService, IEditorGroup, GroupsOrder, GroupsArrangement, GroupDirection, IMergeGroupOptions, IEditorReplacement, IFindGroupScope, EditorGroupLayout, ICloseEditorOptions, GroupOrientation, ICloseAllEditorsOptions, ICloseEditorsFilter, IEditorDropTargetDelegate, IEditorPart, IAuxiliaryEditorPart, IEditorGroupsContainer, IAuxiliaryEditorPartCreateEvent, IEditorWorkingSet, IEditorGroupContextKeyProvider, IEditorWorkingSetOptions } from 'vs/workbench/services/editor/common/editorGroupsService'; import { IEditorService, ISaveEditorsOptions, IRevertAllEditorsOptions, PreferredGroup, IEditorsChangeEvent, ISaveEditorsResult } from 'vs/workbench/services/editor/common/editorService'; import { ICodeEditorService } from 'vs/editor/browser/services/codeEditorService'; @@ -62,10 +62,10 @@ import { ILabelService } from 'vs/platform/label/common/label'; import { DeferredPromise, timeout } from 'vs/base/common/async'; import { PaneComposite, PaneCompositeDescriptor } from 'vs/workbench/browser/panecomposite'; import { IStorageService, StorageScope, StorageTarget } from 'vs/platform/storage/common/storage'; -import { IProcessEnvironment, isWindows, OperatingSystem } from 'vs/base/common/platform'; +import { IProcessEnvironment, isLinux, isWindows, OperatingSystem } from 'vs/base/common/platform'; import { LabelService } from 'vs/workbench/services/label/common/labelService'; import { Part } from 'vs/workbench/browser/part'; -import { VSBuffer, VSBufferReadable, VSBufferReadableStream } from 'vs/base/common/buffer'; +import { bufferToStream, VSBuffer, VSBufferReadable, VSBufferReadableStream } from 'vs/base/common/buffer'; import { Schemas } from 'vs/base/common/network'; import { IProductService } from 'vs/platform/product/common/productService'; import product from 'vs/platform/product/common/product'; @@ -98,7 +98,7 @@ import { IInputBox, IInputOptions, IPickOptions, IQuickInputButton, IQuickInputS import { QuickInputService } from 'vs/workbench/services/quickinput/browser/quickInputService'; import { IListService } from 'vs/platform/list/browser/listService'; import { win32, posix } from 'vs/base/common/path'; -import { TestContextService, TestStorageService, TestTextResourcePropertiesService, TestExtensionService, TestProductService, TestLoggerService, TestWorkspaceTrustManagementService, TestWorkspaceTrustRequestService, TestMarkerService, TestHistoryService } from 'vs/workbench/test/common/workbenchTestServices'; +import { TestContextService, TestStorageService, TestTextResourcePropertiesService, TestExtensionService, TestProductService, createFileStat, TestLoggerService, TestWorkspaceTrustManagementService, TestWorkspaceTrustRequestService, TestMarkerService, TestHistoryService } from 'vs/workbench/test/common/workbenchTestServices'; import { IView, ViewContainer, ViewContainerLocation } from 'vs/workbench/common/views'; import { IViewsService } from 'vs/workbench/services/views/common/viewsService'; import { IPaneComposite } from 'vs/workbench/common/panecomposite'; @@ -109,6 +109,7 @@ import { newWriteableStream, ReadableStreamEvents } from 'vs/base/common/stream' import { EncodingOracle, IEncodingOverride } from 'vs/workbench/services/textfile/browser/textFileService'; import { UTF16le, UTF16be, UTF8_with_bom } from 'vs/workbench/services/textfile/common/encoding'; import { ColorScheme } from 'vs/platform/theme/common/theme'; +import { Iterable } from 'vs/base/common/iterator'; import { InMemoryWorkingCopyBackupService } from 'vs/workbench/services/workingCopy/common/workingCopyBackupService'; import { BrowserWorkingCopyBackupService } from 'vs/workbench/services/workingCopy/browser/workingCopyBackupService'; import { FileService } from 'vs/platform/files/common/fileService'; @@ -131,6 +132,7 @@ import { IWorkingCopyEditorService, WorkingCopyEditorService } from 'vs/workbenc import { IElevatedFileService } from 'vs/workbench/services/files/common/elevatedFileService'; import { BrowserElevatedFileService } from 'vs/workbench/services/files/browser/elevatedFileService'; import { IEditorWorkerService } from 'vs/editor/common/services/editorWorker'; +import { ResourceMap } from 'vs/base/common/map'; import { SideBySideEditorInput } from 'vs/workbench/common/editor/sideBySideEditorInput'; import { ITextEditorService, TextEditorService } from 'vs/workbench/services/textfile/common/textEditorService'; import { IPaneCompositePartService } from 'vs/workbench/services/panecomposite/browser/panecomposite'; @@ -177,7 +179,6 @@ import { TerminalLogService } from 'vs/platform/terminal/common/terminalLogServi import { IEnvironmentVariableService } from 'vs/workbench/contrib/terminal/common/environmentVariable'; import { EnvironmentVariableService } from 'vs/workbench/contrib/terminal/common/environmentVariableService'; import { ContextMenuService } from 'vs/platform/contextview/browser/contextMenuService'; -import { TestFileService } from 'vs/platform/files/test/browser/workbenchTestServices'; export function createFileEditorInput(instantiationService: IInstantiationService, resource: URI): FileEditorInput { return instantiationService.createInstance(FileEditorInput, resource, undefined, undefined, undefined, undefined, undefined, undefined); @@ -1048,6 +1049,164 @@ export class TestEditorService extends Disposable implements EditorServiceImpl { revertAll(options?: IRevertAllEditorsOptions): Promise { throw new Error('Method not implemented.'); } } +export class TestFileService implements IFileService { + + declare readonly _serviceBrand: undefined; + + private readonly _onDidFilesChange = new Emitter(); + get onDidFilesChange(): Event { return this._onDidFilesChange.event; } + fireFileChanges(event: FileChangesEvent): void { this._onDidFilesChange.fire(event); } + + private readonly _onDidRunOperation = new Emitter(); + get onDidRunOperation(): Event { return this._onDidRunOperation.event; } + fireAfterOperation(event: FileOperationEvent): void { this._onDidRunOperation.fire(event); } + + private readonly _onDidChangeFileSystemProviderCapabilities = new Emitter(); + get onDidChangeFileSystemProviderCapabilities(): Event { return this._onDidChangeFileSystemProviderCapabilities.event; } + fireFileSystemProviderCapabilitiesChangeEvent(event: IFileSystemProviderCapabilitiesChangeEvent): void { this._onDidChangeFileSystemProviderCapabilities.fire(event); } + + private _onWillActivateFileSystemProvider = new Emitter(); + readonly onWillActivateFileSystemProvider = this._onWillActivateFileSystemProvider.event; + readonly onDidWatchError = Event.None; + + private content = 'Hello Html'; + private lastReadFileUri!: URI; + + readonly = false; + + setContent(content: string): void { this.content = content; } + getContent(): string { return this.content; } + getLastReadFileUri(): URI { return this.lastReadFileUri; } + + resolve(resource: URI, _options: IResolveMetadataFileOptions): Promise; + resolve(resource: URI, _options?: IResolveFileOptions): Promise; + async resolve(resource: URI, _options?: IResolveFileOptions): Promise { + return createFileStat(resource, this.readonly); + } + + stat(resource: URI): Promise { + return this.resolve(resource, { resolveMetadata: true }); + } + + async resolveAll(toResolve: { resource: URI; options?: IResolveFileOptions }[]): Promise { + const stats = await Promise.all(toResolve.map(resourceAndOption => this.resolve(resourceAndOption.resource, resourceAndOption.options))); + + return stats.map(stat => ({ stat, success: true })); + } + + readonly notExistsSet = new ResourceMap(); + + async exists(_resource: URI): Promise { return !this.notExistsSet.has(_resource); } + + readShouldThrowError: Error | undefined = undefined; + + async readFile(resource: URI, options?: IReadFileOptions | undefined): Promise { + if (this.readShouldThrowError) { + throw this.readShouldThrowError; + } + + this.lastReadFileUri = resource; + + return { + ...createFileStat(resource, this.readonly), + value: VSBuffer.fromString(this.content) + }; + } + + async readFileStream(resource: URI, options?: IReadFileStreamOptions | undefined): Promise { + if (this.readShouldThrowError) { + throw this.readShouldThrowError; + } + + this.lastReadFileUri = resource; + + return { + ...createFileStat(resource, this.readonly), + value: bufferToStream(VSBuffer.fromString(this.content)) + }; + } + + writeShouldThrowError: Error | undefined = undefined; + + async writeFile(resource: URI, bufferOrReadable: VSBuffer | VSBufferReadable, options?: IWriteFileOptions): Promise { + await timeout(0); + + if (this.writeShouldThrowError) { + throw this.writeShouldThrowError; + } + + return createFileStat(resource, this.readonly); + } + + move(_source: URI, _target: URI, _overwrite?: boolean): Promise { return Promise.resolve(null!); } + copy(_source: URI, _target: URI, _overwrite?: boolean): Promise { return Promise.resolve(null!); } + async cloneFile(_source: URI, _target: URI): Promise { } + createFile(_resource: URI, _content?: VSBuffer | VSBufferReadable, _options?: ICreateFileOptions): Promise { return Promise.resolve(null!); } + createFolder(_resource: URI): Promise { return Promise.resolve(null!); } + + onDidChangeFileSystemProviderRegistrations = Event.None; + + private providers = new Map(); + + registerProvider(scheme: string, provider: IFileSystemProvider) { + this.providers.set(scheme, provider); + + return toDisposable(() => this.providers.delete(scheme)); + } + + getProvider(scheme: string) { + return this.providers.get(scheme); + } + + async activateProvider(_scheme: string): Promise { + this._onWillActivateFileSystemProvider.fire({ scheme: _scheme, join: () => { } }); + } + async canHandleResource(resource: URI): Promise { return this.hasProvider(resource); } + hasProvider(resource: URI): boolean { return resource.scheme === Schemas.file || this.providers.has(resource.scheme); } + listCapabilities() { + return [ + { scheme: Schemas.file, capabilities: FileSystemProviderCapabilities.FileOpenReadWriteClose }, + ...Iterable.map(this.providers, ([scheme, p]) => { return { scheme, capabilities: p.capabilities }; }) + ]; + } + hasCapability(resource: URI, capability: FileSystemProviderCapabilities): boolean { + if (capability === FileSystemProviderCapabilities.PathCaseSensitive && isLinux) { + return true; + } + + const provider = this.getProvider(resource.scheme); + + return !!(provider && (provider.capabilities & capability)); + } + + async del(_resource: URI, _options?: { useTrash?: boolean; recursive?: boolean }): Promise { } + + createWatcher(resource: URI, options: IWatchOptions): IFileSystemWatcher { + return { + onDidChange: Event.None, + dispose: () => { } + }; + } + + + readonly watches: URI[] = []; + watch(_resource: URI, options: IWatchOptionsWithCorrelation): IFileSystemWatcher; + watch(_resource: URI): IDisposable; + watch(_resource: URI): IDisposable { + this.watches.push(_resource); + + return toDisposable(() => this.watches.splice(this.watches.indexOf(_resource), 1)); + } + + getWriteEncoding(_resource: URI): IResourceEncoding { return { encoding: 'utf8', hasBOM: false }; } + dispose(): void { } + + async canCreateFile(source: URI, options?: ICreateFileOptions): Promise { return true; } + async canMove(source: URI, target: URI, overwrite?: boolean | undefined): Promise { return true; } + async canCopy(source: URI, target: URI, overwrite?: boolean | undefined): Promise { return true; } + async canDelete(resource: URI, options?: { useTrash?: boolean | undefined; recursive?: boolean | undefined } | undefined): Promise { return true; } +} + export class TestWorkingCopyBackupService extends InMemoryWorkingCopyBackupService { readonly resolved: Set = new Set(); diff --git a/src/vs/workbench/test/electron-sandbox/workbenchTestServices.ts b/src/vs/workbench/test/electron-sandbox/workbenchTestServices.ts index 62860d15462e8..45f6d6d98f43f 100644 --- a/src/vs/workbench/test/electron-sandbox/workbenchTestServices.ts +++ b/src/vs/workbench/test/electron-sandbox/workbenchTestServices.ts @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import { Event } from 'vs/base/common/event'; -import { workbenchInstantiationService as browserWorkbenchInstantiationService, ITestInstantiationService, TestEncodingOracle, TestEnvironmentService, TestFileDialogService, TestFilesConfigurationService, TestLifecycleService, TestTextFileService } from 'vs/workbench/test/browser/workbenchTestServices'; +import { workbenchInstantiationService as browserWorkbenchInstantiationService, ITestInstantiationService, TestEncodingOracle, TestEnvironmentService, TestFileDialogService, TestFilesConfigurationService, TestFileService, TestLifecycleService, TestTextFileService } from 'vs/workbench/test/browser/workbenchTestServices'; import { ISharedProcessService } from 'vs/platform/ipc/electron-sandbox/services'; import { INativeHostService, INativeHostOptions, IOSProperties, IOSStatistics } from 'vs/platform/native/common/native'; import { VSBuffer, VSBufferReadable, VSBufferReadableStream } from 'vs/base/common/buffer'; @@ -48,7 +48,6 @@ import { NativeWorkingCopyBackupService } from 'vs/workbench/services/workingCop import { CancellationToken } from 'vs/base/common/cancellation'; import { UriIdentityService } from 'vs/platform/uriIdentity/common/uriIdentityService'; import { UserDataProfilesService } from 'vs/platform/userDataProfile/common/userDataProfile'; -import { TestFileService } from 'vs/platform/files/test/browser/workbenchTestServices'; export class TestSharedProcessService implements ISharedProcessService { From 7f0678a1a67f21266aab3cd3eceb1d7ff1e7e3d1 Mon Sep 17 00:00:00 2001 From: Alex Ross Date: Mon, 27 May 2024 16:25:58 +0200 Subject: [PATCH 15/37] Remove more file changes --- .../workbench/contrib/files/test/browser/editorAutoSave.test.ts | 2 +- .../contrib/files/test/browser/textFileEditorTracker.test.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/contrib/files/test/browser/editorAutoSave.test.ts b/src/vs/workbench/contrib/files/test/browser/editorAutoSave.test.ts index 7e78480060e79..f104ba762eb04 100644 --- a/src/vs/workbench/contrib/files/test/browser/editorAutoSave.test.ts +++ b/src/vs/workbench/contrib/files/test/browser/editorAutoSave.test.ts @@ -7,7 +7,7 @@ import * as assert from 'assert'; import { Event } from 'vs/base/common/event'; import { ensureNoDisposablesAreLeakedInTestSuite, toResource } from 'vs/base/test/common/utils'; import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; -import { TestFilesConfigurationService, workbenchInstantiationService, TestServiceAccessor, registerTestFileEditor, createEditorPart, TestEnvironmentService, TestTextResourceConfigurationService, TestFileService } from 'vs/workbench/test/browser/workbenchTestServices'; +import { TestFilesConfigurationService, workbenchInstantiationService, TestServiceAccessor, registerTestFileEditor, createEditorPart, TestEnvironmentService, TestFileService, TestTextResourceConfigurationService } from 'vs/workbench/test/browser/workbenchTestServices'; import { ITextFileEditorModel } from 'vs/workbench/services/textfile/common/textfiles'; import { IEditorGroupsService } from 'vs/workbench/services/editor/common/editorGroupsService'; import { DisposableStore } from 'vs/base/common/lifecycle'; diff --git a/src/vs/workbench/contrib/files/test/browser/textFileEditorTracker.test.ts b/src/vs/workbench/contrib/files/test/browser/textFileEditorTracker.test.ts index 624ea86664016..75e6c3b5cdc8b 100644 --- a/src/vs/workbench/contrib/files/test/browser/textFileEditorTracker.test.ts +++ b/src/vs/workbench/contrib/files/test/browser/textFileEditorTracker.test.ts @@ -8,7 +8,7 @@ import { Event } from 'vs/base/common/event'; import { TextFileEditorTracker } from 'vs/workbench/contrib/files/browser/editors/textFileEditorTracker'; import { ensureNoDisposablesAreLeakedInTestSuite, toResource } from 'vs/base/test/common/utils'; import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; -import { workbenchInstantiationService, TestServiceAccessor, TestFilesConfigurationService, registerTestFileEditor, registerTestResourceEditor, createEditorPart, TestEnvironmentService, workbenchTeardown, TestTextResourceConfigurationService, TestFileService } from 'vs/workbench/test/browser/workbenchTestServices'; +import { workbenchInstantiationService, TestServiceAccessor, TestFilesConfigurationService, registerTestFileEditor, registerTestResourceEditor, createEditorPart, TestEnvironmentService, TestFileService, workbenchTeardown, TestTextResourceConfigurationService } from 'vs/workbench/test/browser/workbenchTestServices'; import { IResolvedTextFileEditorModel, snapshotToString, ITextFileService } from 'vs/workbench/services/textfile/common/textfiles'; import { FileChangesEvent, FileChangeType, FileOperationError, FileOperationResult } from 'vs/platform/files/common/files'; import { IEditorGroupsService } from 'vs/workbench/services/editor/common/editorGroupsService'; From eb1bba2057d2fccf15f3271576de774c8f509da0 Mon Sep 17 00:00:00 2001 From: Alex Ross Date: Tue, 18 Jun 2024 12:41:57 +0200 Subject: [PATCH 16/37] Reduce yield to 50 ms --- .../browser/services/treeSitter/treeSitterParserService.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/editor/browser/services/treeSitter/treeSitterParserService.ts b/src/vs/editor/browser/services/treeSitter/treeSitterParserService.ts index 76eaf38f4dc5a..dad3da54829a1 100644 --- a/src/vs/editor/browser/services/treeSitter/treeSitterParserService.ts +++ b/src/vs/editor/browser/services/treeSitter/treeSitterParserService.ts @@ -126,7 +126,7 @@ export class TreeSitterParserService extends Disposable implements ITreeSitterPa disposables.add(model.onDidChangeContent(e => this._onDidChangeContent(model, e))); disposables.add(model.onDidChangeLanguage(e => this._onDidChangeLanguage(model, e))); const parser = new Parser(); - parser.setTimeoutMicros(300 * 1000); // 300 ms + parser.setTimeoutMicros(50 * 1000); // 50 ms const treeSitterTree = new TreeSitterTree(parser, disposables); this._treeSitterTrees.set(model, treeSitterTree); this._setLanguageAndTree(model, treeSitterTree); From d56de4265ec71a7f86038a9a4e18c3c07f68a1aa Mon Sep 17 00:00:00 2001 From: Alex Ross Date: Tue, 18 Jun 2024 12:58:33 +0200 Subject: [PATCH 17/37] Fix incremental parsing --- .../browser/services/treeSitter/treeSitterParserService.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/editor/browser/services/treeSitter/treeSitterParserService.ts b/src/vs/editor/browser/services/treeSitter/treeSitterParserService.ts index dad3da54829a1..90d1ca379c1e3 100644 --- a/src/vs/editor/browser/services/treeSitter/treeSitterParserService.ts +++ b/src/vs/editor/browser/services/treeSitter/treeSitterParserService.ts @@ -149,7 +149,7 @@ export class TreeSitterParserService extends Disposable implements ITreeSitterPa do { const timer = performance.now(); try { - tree = treeSitterTree.parser.parse((index: number, position?: Parser.Point) => this._parseCallback(model, index, position, treeSitterTree)); + tree = treeSitterTree.parser.parse((index: number, position?: Parser.Point) => this._parseCallback(model, index, position, treeSitterTree), treeSitterTree.tree); } catch (e) { // parsing can fail when the timeout is reached, will resume upon next loop } finally { From df28801e31e3d672a0754eb9edc55a7208d7cde8 Mon Sep 17 00:00:00 2001 From: Alex Ross Date: Tue, 18 Jun 2024 15:31:22 +0200 Subject: [PATCH 18/37] Try update node-abi --- package.json | 1 + yarn.lock | 15 +++++---------- 2 files changed, 6 insertions(+), 10 deletions(-) diff --git a/package.json b/package.json index bf53124ad0d17..202ed62a63a9d 100644 --- a/package.json +++ b/package.json @@ -98,6 +98,7 @@ "native-is-elevated": "0.7.0", "native-keymap": "^3.3.5", "native-watchdog": "^1.4.1", + "node-abi": "^3.65.0", "node-pty": "1.1.0-beta11", "tas-client-umd": "0.2.0", "v8-inspect-profiler": "^0.1.1", diff --git a/yarn.lock b/yarn.lock index 2cae48ab5fd9e..8e279776aaade 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7251,10 +7251,10 @@ nise@^5.1.0: just-extend "^4.0.2" path-to-regexp "^1.7.0" -node-abi@^3.3.0: - version "3.8.0" - resolved "https://registry.yarnpkg.com/node-abi/-/node-abi-3.8.0.tgz#679957dc8e7aa47b0a02589dbfde4f77b29ccb32" - integrity sha512-tzua9qWWi7iW4I42vUPKM+SfaF0vQSLAm4yO5J83mSwB7GeoWrDKC/K+8YCnYNwqP5duwazbw2X9l4m8SC2cUw== +node-abi@^3.3.0, node-abi@^3.65.0: + version "3.65.0" + resolved "https://registry.yarnpkg.com/node-abi/-/node-abi-3.65.0.tgz#ca92d559388e1e9cab1680a18c1a18757cdac9d3" + integrity sha512-ThjYBfoDNr08AWx6hGaRbfPwxKV9kVzAzOzlLKbk2CuqXE2xnCh+cbAGnwM3t8Lq4v9rUB7VfondlkBckcJrVA== dependencies: semver "^7.3.5" @@ -7307,12 +7307,7 @@ node-fetch@^2.6.0, node-fetch@^2.6.7: dependencies: whatwg-url "^5.0.0" -node-gyp-build@4.8.1, node-gyp-build@^4.3.0: - version "4.8.1" - resolved "https://registry.yarnpkg.com/node-gyp-build/-/node-gyp-build-4.8.1.tgz#976d3ad905e71b76086f4f0b0d3637fe79b6cda5" - integrity sha512-OSs33Z9yWr148JZcbZd5WiAXhh/n9z8TxQcdMhIOlpN9AhWpLfvVFO73+m77bBABQMaY9XSvIa+qk0jlI7Gcaw== - -node-gyp-build@^4.8.1: +node-gyp-build@4.8.1, node-gyp-build@^4.3.0, node-gyp-build@^4.8.1: version "4.8.1" resolved "https://registry.yarnpkg.com/node-gyp-build/-/node-gyp-build-4.8.1.tgz#976d3ad905e71b76086f4f0b0d3637fe79b6cda5" integrity sha512-OSs33Z9yWr148JZcbZd5WiAXhh/n9z8TxQcdMhIOlpN9AhWpLfvVFO73+m77bBABQMaY9XSvIa+qk0jlI7Gcaw== From 85ba149090a367a09e09d86c7fdf2ada429cee58 Mon Sep 17 00:00:00 2001 From: Alex Ross Date: Tue, 18 Jun 2024 15:42:27 +0200 Subject: [PATCH 19/37] Revert "Try update node-abi" This reverts commit df28801e31e3d672a0754eb9edc55a7208d7cde8. --- package.json | 1 - yarn.lock | 15 ++++++++++----- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/package.json b/package.json index 202ed62a63a9d..bf53124ad0d17 100644 --- a/package.json +++ b/package.json @@ -98,7 +98,6 @@ "native-is-elevated": "0.7.0", "native-keymap": "^3.3.5", "native-watchdog": "^1.4.1", - "node-abi": "^3.65.0", "node-pty": "1.1.0-beta11", "tas-client-umd": "0.2.0", "v8-inspect-profiler": "^0.1.1", diff --git a/yarn.lock b/yarn.lock index 8e279776aaade..2cae48ab5fd9e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7251,10 +7251,10 @@ nise@^5.1.0: just-extend "^4.0.2" path-to-regexp "^1.7.0" -node-abi@^3.3.0, node-abi@^3.65.0: - version "3.65.0" - resolved "https://registry.yarnpkg.com/node-abi/-/node-abi-3.65.0.tgz#ca92d559388e1e9cab1680a18c1a18757cdac9d3" - integrity sha512-ThjYBfoDNr08AWx6hGaRbfPwxKV9kVzAzOzlLKbk2CuqXE2xnCh+cbAGnwM3t8Lq4v9rUB7VfondlkBckcJrVA== +node-abi@^3.3.0: + version "3.8.0" + resolved "https://registry.yarnpkg.com/node-abi/-/node-abi-3.8.0.tgz#679957dc8e7aa47b0a02589dbfde4f77b29ccb32" + integrity sha512-tzua9qWWi7iW4I42vUPKM+SfaF0vQSLAm4yO5J83mSwB7GeoWrDKC/K+8YCnYNwqP5duwazbw2X9l4m8SC2cUw== dependencies: semver "^7.3.5" @@ -7307,7 +7307,12 @@ node-fetch@^2.6.0, node-fetch@^2.6.7: dependencies: whatwg-url "^5.0.0" -node-gyp-build@4.8.1, node-gyp-build@^4.3.0, node-gyp-build@^4.8.1: +node-gyp-build@4.8.1, node-gyp-build@^4.3.0: + version "4.8.1" + resolved "https://registry.yarnpkg.com/node-gyp-build/-/node-gyp-build-4.8.1.tgz#976d3ad905e71b76086f4f0b0d3637fe79b6cda5" + integrity sha512-OSs33Z9yWr148JZcbZd5WiAXhh/n9z8TxQcdMhIOlpN9AhWpLfvVFO73+m77bBABQMaY9XSvIa+qk0jlI7Gcaw== + +node-gyp-build@^4.8.1: version "4.8.1" resolved "https://registry.yarnpkg.com/node-gyp-build/-/node-gyp-build-4.8.1.tgz#976d3ad905e71b76086f4f0b0d3637fe79b6cda5" integrity sha512-OSs33Z9yWr148JZcbZd5WiAXhh/n9z8TxQcdMhIOlpN9AhWpLfvVFO73+m77bBABQMaY9XSvIa+qk0jlI7Gcaw== From 70e6fdd7b96a27ca912445798f761837b1afd22f Mon Sep 17 00:00:00 2001 From: Peng Lyu Date: Tue, 18 Jun 2024 08:20:55 -0700 Subject: [PATCH 20/37] Update text buffer chunk api --- .../treeSitter/treeSitterParserService.ts | 32 +------------------ 1 file changed, 1 insertion(+), 31 deletions(-) diff --git a/src/vs/editor/browser/services/treeSitter/treeSitterParserService.ts b/src/vs/editor/browser/services/treeSitter/treeSitterParserService.ts index 90d1ca379c1e3..0fd4b55f84291 100644 --- a/src/vs/editor/browser/services/treeSitter/treeSitterParserService.ts +++ b/src/vs/editor/browser/services/treeSitter/treeSitterParserService.ts @@ -11,7 +11,6 @@ import { IModelService } from 'vs/editor/common/services/model'; import { Disposable, DisposableMap, DisposableStore, IDisposable } from 'vs/base/common/lifecycle'; import { ITextModel, ITextSnapshot } from 'vs/editor/common/model'; import { IFileService } from 'vs/platform/files/common/files'; -import { Position } from 'vs/editor/common/core/position'; import { IModelContentChangedEvent, IModelLanguageChangedEvent } from 'vs/editor/common/textModelEvents'; import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { ILogService } from 'vs/platform/log/common/log'; @@ -241,36 +240,7 @@ export class TreeSitterParserService extends Disposable implements ITreeSitterPa } private _parseCallback(textModel: ITextModel, index: number, position?: Parser.Point, treeSitterTree?: TreeSitterTree): string | null { - if (treeSitterTree?.snapshot) { - for (let i = 0; i < treeSitterTree.snapshotChunks.length; i++) { - const snapshotChunk = treeSitterTree.snapshotChunks[i]; - if ((snapshotChunk.startOffset <= index) && (index < (snapshotChunk.chunk.length + snapshotChunk.startOffset))) { - return snapshotChunk.chunk.substring(index - snapshotChunk.startOffset); - } - } - - let readValue = treeSitterTree.snapshot.read(); - if (readValue === null) { - treeSitterTree.clearSnapshot(); - } else { - const startOffset = treeSitterTree.snapshotChunks.length === 0 ? 0 : treeSitterTree.snapshotChunks[treeSitterTree.snapshotChunks.length - 1].startOffset + treeSitterTree.snapshotChunks[treeSitterTree.snapshotChunks.length - 1].chunk.length; - treeSitterTree.addSnapshotChunk(readValue, startOffset); - readValue = readValue.substring(index - startOffset); - } - return readValue; - } - try { - const modelPositionStart: Position = position ? new Position(position.row + 1, position.column + 1) : textModel.getPositionAt(index); - const lineContent = textModel.getLineContent(modelPositionStart.lineNumber); - let value = lineContent.substring(modelPositionStart.column - 1); - if (value.length === 0 && (lineContent.length <= modelPositionStart.column)) { // When we hit the end of the line the value is an empty string, we need to get the next character. - const modelPositionEnd = textModel.getPositionAt(index + 2); - value = textModel.getValueInRange(Range.fromPositions(modelPositionStart, modelPositionEnd)); - } - return value; - } catch (e) { - return null; - } + return textModel.getTextBuffer().getNearestChunk(index); } public initTreeSitter(): Promise { From b728bd93e0d37593ae220045b558d35b5caa7da8 Mon Sep 17 00:00:00 2001 From: Peng Lyu Date: Tue, 18 Jun 2024 10:13:05 -0700 Subject: [PATCH 21/37] fix build --- .../browser/services/treeSitter/treeSitterParserService.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/vs/editor/browser/services/treeSitter/treeSitterParserService.ts b/src/vs/editor/browser/services/treeSitter/treeSitterParserService.ts index 0fd4b55f84291..9c97919639ce4 100644 --- a/src/vs/editor/browser/services/treeSitter/treeSitterParserService.ts +++ b/src/vs/editor/browser/services/treeSitter/treeSitterParserService.ts @@ -14,7 +14,6 @@ import { IFileService } from 'vs/platform/files/common/files'; import { IModelContentChangedEvent, IModelLanguageChangedEvent } from 'vs/editor/common/textModelEvents'; import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { ILogService } from 'vs/platform/log/common/log'; -import { Range } from 'vs/editor/common/core/range'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { setTimeout0 } from 'vs/base/common/platform'; From 0563837281c9c8060b257ce5944dea8f7a6149ca Mon Sep 17 00:00:00 2001 From: Alex Ross Date: Wed, 19 Jun 2024 12:10:32 +0200 Subject: [PATCH 22/37] Remove tree-sitter dependency --- package.json | 2 - .../base/common/treeSitterLanguages/README.md | 23 ++++++++ .../tree-sitter-html/cgmanifest.json | 18 ++++++ .../tree-sitter-typescript/cgmanifest.json | 18 ++++++ yarn.lock | 57 ------------------- 5 files changed, 59 insertions(+), 59 deletions(-) create mode 100644 src/vs/base/common/treeSitterLanguages/README.md create mode 100644 src/vs/base/common/treeSitterLanguages/tree-sitter-html/cgmanifest.json create mode 100644 src/vs/base/common/treeSitterLanguages/tree-sitter-typescript/cgmanifest.json diff --git a/package.json b/package.json index bf53124ad0d17..6d09bae270d7b 100644 --- a/package.json +++ b/package.json @@ -205,8 +205,6 @@ "source-map-support": "^0.3.2", "style-loader": "^3.3.2", "tree-sitter-cli": "^0.22.6", - "tree-sitter-html": "^0.20.3", - "tree-sitter-typescript": "0.20.4", "ts-loader": "^9.4.2", "ts-node": "^10.9.1", "tsec": "0.2.7", diff --git a/src/vs/base/common/treeSitterLanguages/README.md b/src/vs/base/common/treeSitterLanguages/README.md new file mode 100644 index 0000000000000..a6ab9edeb7608 --- /dev/null +++ b/src/vs/base/common/treeSitterLanguages/README.md @@ -0,0 +1,23 @@ +# Generating Tree-Sitter wasm files + +> **Note:** guidance is from https://www.npmjs.com/package/web-tree-sitter + +> **Note:** does not work on Windows + +> **Note:** we don't commit these as devDependencies in package.json because they have build errors: https://github.com/tree-sitter/node-tree-sitter/pull/204 + +The following example shows how to generate .wasm file for tree-sitter JavaScript grammar. + +IMPORTANT: emscripten, docker, or podman need to be installed. + +First install `tree-sitter-cli` and the `tree-sitter` language for which to generate `.wasm` (`tree-sitter-javascript` in this example): + +``` +npm install --save-dev tree-sitter-cli tree-sitter-javascript +``` +Then just use tree-sitter cli tool to generate the .wasm. + +``` +npx tree-sitter build --wasm node_modules/tree-sitter-javascript +``` +If everything is fine, file tree-sitter-javascript.wasm should be generated in current directory. diff --git a/src/vs/base/common/treeSitterLanguages/tree-sitter-html/cgmanifest.json b/src/vs/base/common/treeSitterLanguages/tree-sitter-html/cgmanifest.json new file mode 100644 index 0000000000000..e97c1fbb947e2 --- /dev/null +++ b/src/vs/base/common/treeSitterLanguages/tree-sitter-html/cgmanifest.json @@ -0,0 +1,18 @@ +{ + "registrations": [ + { + "component": { + "type": "git", + "git": { + "name": "tree-sitter-html", + "repositoryUrl": "https://github.com/tree-sitter/tree-sitter-html", + "commitHash": "e4d834eb4918df01dcad5c27d1b15d56e3bd94cd" + } + }, + "license": "MIT", + "version": "0.20.3", + "description": "The tree-sitter-html.wasm file is generated from the tree-sitter-html repository." + } + ], + "version": 1 +} diff --git a/src/vs/base/common/treeSitterLanguages/tree-sitter-typescript/cgmanifest.json b/src/vs/base/common/treeSitterLanguages/tree-sitter-typescript/cgmanifest.json new file mode 100644 index 0000000000000..395f7fafbe069 --- /dev/null +++ b/src/vs/base/common/treeSitterLanguages/tree-sitter-typescript/cgmanifest.json @@ -0,0 +1,18 @@ +{ + "registrations": [ + { + "component": { + "type": "git", + "git": { + "name": "tree-sitter-typescript", + "repositoryUrl": "https://github.com/tree-sitter/tree-sitter-typescript", + "commitHash": "eb6b845dee9ee22987262699a152312604313662" + } + }, + "license": "MIT", + "version": "0.20.4", + "description": "The tree-sitter-typescript.wasm file is generated from the tree-sitter-typescript repository." + } + ], + "version": 1 +} diff --git a/yarn.lock b/yarn.lock index 2cae48ab5fd9e..6d14c93288c76 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7163,11 +7163,6 @@ nan@^2.12.1: resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.2.tgz#f5376400695168f4cc694ac9393d0c9585eeea19" integrity sha512-M2ufzIiINKCuDfBSAUr1vWQ+vuVcA9kqx8JJUsbQi6yf1uGRyb7HfpdfUr5qLXf3B/t8dPvcjhKMmlfnP47EzQ== -nan@^2.18.0: - version "2.19.0" - resolved "https://registry.yarnpkg.com/nan/-/nan-2.19.0.tgz#bb58122ad55a6c5bc973303908d5b16cfdd5a8c0" - integrity sha512-nO1xXxfh/RWNxfd/XPfbIfFk5vgLsAxUR9y5O0cHMJu/AW9U95JLXqthYHjEp+8gQ5p96K9jUp8nbVOxCdRbtw== - nanoid@3.3.3: version "3.3.3" resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.3.tgz#fd8e8b7aa761fe807dba2d1b98fb7241bb724a25" @@ -7288,11 +7283,6 @@ node-addon-api@^6.0.0: resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-6.0.0.tgz#cfb3574e6df708ff71a30db6c4762d9e06e11c27" integrity sha512-GyHvgPvUXBvAkXa0YvYnhilSB1A+FRYMpIVggKzPZqdaZfevZOuzfWzyvgzOwRLHBeo/MMswmJFsrNF4Nw1pmA== -node-addon-api@^8.0.0: - version "8.0.0" - resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-8.0.0.tgz#5453b7ad59dd040d12e0f1a97a6fa1c765c5c9d2" - integrity sha512-ipO7rsHEBqa9STO5C5T10fj732ml+5kLN1cAG8/jdHd56ldQeGj3Q7+scUS+VHK/qy1zLEwC4wMK5+yM0btPvw== - node-fetch@2.6.8: version "2.6.8" resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.8.tgz#a68d30b162bc1d8fd71a367e81b997e1f4d4937e" @@ -7312,11 +7302,6 @@ node-gyp-build@4.8.1, node-gyp-build@^4.3.0: resolved "https://registry.yarnpkg.com/node-gyp-build/-/node-gyp-build-4.8.1.tgz#976d3ad905e71b76086f4f0b0d3637fe79b6cda5" integrity sha512-OSs33Z9yWr148JZcbZd5WiAXhh/n9z8TxQcdMhIOlpN9AhWpLfvVFO73+m77bBABQMaY9XSvIa+qk0jlI7Gcaw== -node-gyp-build@^4.8.1: - version "4.8.1" - resolved "https://registry.yarnpkg.com/node-gyp-build/-/node-gyp-build-4.8.1.tgz#976d3ad905e71b76086f4f0b0d3637fe79b6cda5" - integrity sha512-OSs33Z9yWr148JZcbZd5WiAXhh/n9z8TxQcdMhIOlpN9AhWpLfvVFO73+m77bBABQMaY9XSvIa+qk0jlI7Gcaw== - node-html-markdown@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/node-html-markdown/-/node-html-markdown-1.3.0.tgz#ef0b19a3bbfc0f1a880abb9ff2a0c9aa6bbff2a9" @@ -8292,24 +8277,6 @@ prebuild-install@7.1.1: tar-fs "^2.0.0" tunnel-agent "^0.6.0" -prebuild-install@^7.1.1: - version "7.1.2" - resolved "https://registry.yarnpkg.com/prebuild-install/-/prebuild-install-7.1.2.tgz#a5fd9986f5a6251fbc47e1e5c65de71e68c0a056" - integrity sha512-UnNke3IQb6sgarcZIDU3gbMeTp/9SSU1DAIkil7PrqG1vZlBtY5msYccSKSHDqa3hNg436IXK+SNImReuA1wEQ== - dependencies: - detect-libc "^2.0.0" - expand-template "^2.0.3" - github-from-package "0.0.0" - minimist "^1.2.3" - mkdirp-classic "^0.5.3" - napi-build-utils "^1.0.1" - node-abi "^3.3.0" - pump "^3.0.0" - rc "^1.2.7" - simple-get "^4.0.0" - tar-fs "^2.0.0" - tunnel-agent "^0.6.0" - prelude-ls@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396" @@ -9953,30 +9920,6 @@ tree-sitter-cli@^0.22.6: resolved "https://registry.yarnpkg.com/tree-sitter-cli/-/tree-sitter-cli-0.22.6.tgz#f0542bce4095952c292d3f0300d72aeab442b765" integrity sha512-s7mYOJXi8sIFkt/nLJSqlYZP96VmKTc3BAwIX0rrrlRxWjWuCwixFqwzxWZBQz4R8Hx01iP7z3cT3ih58BUmZQ== -tree-sitter-html@^0.20.3: - version "0.20.3" - resolved "https://registry.yarnpkg.com/tree-sitter-html/-/tree-sitter-html-0.20.3.tgz#b7043448d7df482083e32f9ba9a8f366629e7704" - integrity sha512-D+hfQyGUnptdL909C5/hJRCuj1C6TtQ6/meHPtBNvCR4jp04Ir+BFhzhwKf8lwe5OcsCTYymU5ljMAd9yNXzfQ== - dependencies: - node-addon-api "^8.0.0" - node-gyp-build "^4.8.1" - -tree-sitter-typescript@0.20.4: - version "0.20.4" - resolved "https://registry.yarnpkg.com/tree-sitter-typescript/-/tree-sitter-typescript-0.20.4.tgz#57f922ca5ccd740bc2f2ca3d82a40539f5809c93" - integrity sha512-pB5uk+Dr8ijsINYvZW37LijhHEIPObOVmMkElMBNxoEUaMiRzJEfjVIZUYdmkjUUCbp8B5CV3XVWfYp9iiEv5Q== - dependencies: - nan "^2.18.0" - tree-sitter "^0.20.6" - -tree-sitter@^0.20.6: - version "0.20.6" - resolved "https://registry.yarnpkg.com/tree-sitter/-/tree-sitter-0.20.6.tgz#fec52e5d7cc6c583135756479f2440dd89b25cbe" - integrity sha512-GxJodajVpfgb3UREzzIbtA1hyRnTxVbWVXrbC6sk4xTMH5ERMBJk9HJNq4c8jOJeUaIOmLcwg+t6mez/PDvGqg== - dependencies: - nan "^2.18.0" - prebuild-install "^7.1.1" - ts-api-utils@^1.0.1: version "1.3.0" resolved "https://registry.yarnpkg.com/ts-api-utils/-/ts-api-utils-1.3.0.tgz#4b490e27129f1e8e686b45cc4ab63714dc60eea1" From c28ede5c9efd769abf7178ef613f0bd3e5daf310 Mon Sep 17 00:00:00 2001 From: Alex Ross Date: Wed, 10 Jul 2024 15:08:58 +0200 Subject: [PATCH 23/37] Adopt new, as yet unpublished, `@vscode/tree-sitter-wasm` package --- .eslintrc.json | 4 +- build/filters.js | 3 - package.json | 1 - src/bootstrap-window.js | 1 + .../base/common/treeSitterLanguages/README.md | 23 - .../tree-sitter-html/cgmanifest.json | 18 - .../tree-sitter-html/tree-sitter-html.wasm | Bin 17906 -> 0 bytes .../tree-sitter-typescript/cgmanifest.json | 18 - .../tree-sitter-typescript.wasm | Bin 2310637 -> 0 bytes .../common/web-tree-sitter/cgmanifest.json | 17 - .../web-tree-sitter/tree-sitter-web.d.ts | 239 - .../common/web-tree-sitter/tree-sitter-web.js | 4029 ----------------- .../common/web-tree-sitter/tree-sitter.wasm | Bin 192649 -> 0 bytes .../treeSitter/treeSitterParserService.ts | 16 +- .../services/treeSitterParserService.ts | 2 +- .../browser/services/testTreeSitterService.ts | 2 +- yarn.lock | 5 - 17 files changed, 13 insertions(+), 4365 deletions(-) delete mode 100644 src/vs/base/common/treeSitterLanguages/README.md delete mode 100644 src/vs/base/common/treeSitterLanguages/tree-sitter-html/cgmanifest.json delete mode 100644 src/vs/base/common/treeSitterLanguages/tree-sitter-html/tree-sitter-html.wasm delete mode 100644 src/vs/base/common/treeSitterLanguages/tree-sitter-typescript/cgmanifest.json delete mode 100644 src/vs/base/common/treeSitterLanguages/tree-sitter-typescript/tree-sitter-typescript.wasm delete mode 100644 src/vs/base/common/web-tree-sitter/cgmanifest.json delete mode 100644 src/vs/base/common/web-tree-sitter/tree-sitter-web.d.ts delete mode 100644 src/vs/base/common/web-tree-sitter/tree-sitter-web.js delete mode 100644 src/vs/base/common/web-tree-sitter/tree-sitter.wasm diff --git a/.eslintrc.json b/.eslintrc.json index c39a66311e4fc..5160622cc4b31 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -642,6 +642,7 @@ "@vscode/policy-watcher", "@vscode/proxy-agent", "@vscode/spdlog", + "@vscode/tree-sitter-wasm", "@vscode/windows-process-tree", "assert", "child_process", @@ -755,7 +756,8 @@ "vs/base/~", "vs/base/parts/*/~", "vs/platform/*/~", - "vs/editor/~" + "vs/editor/~", + "@vscode/tree-sitter-wasm" // node module allowed even in /common/ ] }, { diff --git a/build/filters.js b/build/filters.js index 8e56023dc783a..915240f0f0bf7 100644 --- a/build/filters.js +++ b/build/filters.js @@ -75,8 +75,6 @@ module.exports.indentationFilter = [ '!src/vs/base/browser/dompurify/*', '!src/vs/base/common/marked/marked.js', '!src/vs/base/common/semver/semver.js', - '!src/vs/base/common/web-tree-sitter/tree-sitter-web.js', - '!src/vs/base/common/treeSitterLanguages/*/highlights.scm', '!src/vs/base/node/terminateProcess.sh', '!src/vs/base/node/cpuUsage.sh', '!test/unit/assert.js', @@ -174,7 +172,6 @@ module.exports.copyrightFilter = [ '!extensions/typescript-language-features/node-maintainer/**', '!extensions/html-language-features/server/src/modes/typescript/*', '!extensions/*/server/bin/*', - '!src/vs/base/common/web-tree-sitter/tree-sitter-web.js', '!src/vs/editor/test/node/classification/typescript-test.ts', ]; diff --git a/package.json b/package.json index 910f11424b832..cc00db38c76a7 100644 --- a/package.json +++ b/package.json @@ -205,7 +205,6 @@ "source-map": "0.6.1", "source-map-support": "^0.3.2", "style-loader": "^3.3.2", - "tree-sitter-cli": "^0.22.6", "ts-loader": "^9.4.2", "ts-node": "^10.9.1", "tsec": "0.2.7", diff --git a/src/bootstrap-window.js b/src/bootstrap-window.js index 59ddc3fdfbf38..ccc437c304f40 100644 --- a/src/bootstrap-window.js +++ b/src/bootstrap-window.js @@ -197,6 +197,7 @@ const isESM = false; // using a fallback such as node.js require which does not exist in sandbox const baseNodeModulesPath = isDev ? '../node_modules' : '../node_modules.asar'; loaderConfig.paths = { + '@vscode/tree-sitter-wasm': `${baseNodeModulesPath}/@vscode/tree-sitter-wasm/wasm/tree-sitter.js`, 'vscode-textmate': `${baseNodeModulesPath}/vscode-textmate/release/main.js`, 'vscode-oniguruma': `${baseNodeModulesPath}/vscode-oniguruma/release/main.js`, 'vsda': `${baseNodeModulesPath}/vsda/index.js`, diff --git a/src/vs/base/common/treeSitterLanguages/README.md b/src/vs/base/common/treeSitterLanguages/README.md deleted file mode 100644 index a6ab9edeb7608..0000000000000 --- a/src/vs/base/common/treeSitterLanguages/README.md +++ /dev/null @@ -1,23 +0,0 @@ -# Generating Tree-Sitter wasm files - -> **Note:** guidance is from https://www.npmjs.com/package/web-tree-sitter - -> **Note:** does not work on Windows - -> **Note:** we don't commit these as devDependencies in package.json because they have build errors: https://github.com/tree-sitter/node-tree-sitter/pull/204 - -The following example shows how to generate .wasm file for tree-sitter JavaScript grammar. - -IMPORTANT: emscripten, docker, or podman need to be installed. - -First install `tree-sitter-cli` and the `tree-sitter` language for which to generate `.wasm` (`tree-sitter-javascript` in this example): - -``` -npm install --save-dev tree-sitter-cli tree-sitter-javascript -``` -Then just use tree-sitter cli tool to generate the .wasm. - -``` -npx tree-sitter build --wasm node_modules/tree-sitter-javascript -``` -If everything is fine, file tree-sitter-javascript.wasm should be generated in current directory. diff --git a/src/vs/base/common/treeSitterLanguages/tree-sitter-html/cgmanifest.json b/src/vs/base/common/treeSitterLanguages/tree-sitter-html/cgmanifest.json deleted file mode 100644 index e97c1fbb947e2..0000000000000 --- a/src/vs/base/common/treeSitterLanguages/tree-sitter-html/cgmanifest.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "registrations": [ - { - "component": { - "type": "git", - "git": { - "name": "tree-sitter-html", - "repositoryUrl": "https://github.com/tree-sitter/tree-sitter-html", - "commitHash": "e4d834eb4918df01dcad5c27d1b15d56e3bd94cd" - } - }, - "license": "MIT", - "version": "0.20.3", - "description": "The tree-sitter-html.wasm file is generated from the tree-sitter-html repository." - } - ], - "version": 1 -} diff --git a/src/vs/base/common/treeSitterLanguages/tree-sitter-html/tree-sitter-html.wasm b/src/vs/base/common/treeSitterLanguages/tree-sitter-html/tree-sitter-html.wasm deleted file mode 100644 index 8c024d45b6874494ef32a381e5f571d910d7088d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 17906 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 diff --git a/src/vs/base/common/treeSitterLanguages/tree-sitter-typescript/cgmanifest.json b/src/vs/base/common/treeSitterLanguages/tree-sitter-typescript/cgmanifest.json deleted file mode 100644 index 395f7fafbe069..0000000000000 --- a/src/vs/base/common/treeSitterLanguages/tree-sitter-typescript/cgmanifest.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "registrations": [ - { - "component": { - "type": "git", - "git": { - "name": "tree-sitter-typescript", - "repositoryUrl": "https://github.com/tree-sitter/tree-sitter-typescript", - "commitHash": "eb6b845dee9ee22987262699a152312604313662" - } - }, - "license": "MIT", - "version": "0.20.4", - "description": "The tree-sitter-typescript.wasm file is generated from the tree-sitter-typescript repository." - } - ], - "version": 1 -} diff --git a/src/vs/base/common/treeSitterLanguages/tree-sitter-typescript/tree-sitter-typescript.wasm b/src/vs/base/common/treeSitterLanguages/tree-sitter-typescript/tree-sitter-typescript.wasm deleted file mode 100644 index 5f295f05d97fdb307e3d6fceb63463af047d07ea..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2310637 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

04B~rFA~`I*S+f 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%0Dx70I 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

xspb}X5Zl8St`64| zhxN2vJu(Sh&Bw_msVM>5h{!MtJ&NojeRdj8pL%-R?tFk)SN>RPUa^(P>Hr(cY30!9 zOXW;8x6p&w>TjTOzkl+-bJ|G1f%@N-@!`AX)Ubo`Ko4EWWU46+vA%I6jUhzrM@N4D zFIGT2$MBiHy1cE6gJ1RI*yZiaQI#0U>SZ}Jy0e_A`UM_XKQAzX2YTp2CR0sui1m#l zX$&D^KlZuH*U0dfE91jroE{j@13h#hlc}aS z#QMgOG=>ndA07GqzgPkB9K&b&>hiWO4t~{-W0$uxM^$1ZtC!`_=%34(s$bxN^&R2w zq*C;7{Wx}c zJ9AVeMzVTY4vqeAIaBouJgEMwTfZ3o!v}};w0v=k$y8%BBI2g0F;^o(nuWC#*+=^9 zG@d^7^tRpk0I{z8vDCa`E0NU!HWX_g+6r6_jqWOEs_{Y(h#t9cRoDY@SWnAUBa_h8 ze4K2Oni#N+hzzsPqsTteXQ%P>si(K?&IgEf<&UN26-gm`pWBBO-2^5_2^oq*+)?k$t4kPUGoQPjB0u4-o6hA4|MZjmr3N0k02tsXWj_7c!Y@ibJe# z97$sc5&O}R-~Wph5YI7urmrq<>*C;7{Wx}cJ9AVeMzVTY4voH9&Q$#Z52`<8>z{-j z42Si!{K*!Rsm5qT#7$FUu11733u`H|kM!ATJbmivZM*XUVqN)Tsd>d#BC7*zDAxX> zus#0n%J^^rZw`AP5A@K5Os1OR5bGO9(ilR-estvb|6&Eia}1y9tIONEIQUgRj$Pi) z994;ttX`Hwqi>ZnRlmRk>n8?A@IVh;$YiQ14za#*B#j|N>_=bSDX;=-rkTDvE8uso z(lnDeN=Wk(_R{LWYAC0bL!*1jnQCsK2eCbB;ehaWQaG%q<$$qC=xRPrHc3qh*hWN# zS?Ez@AL+Bxc>2`S+ji#z#JcjwQuB(fL{}&S zTu&b8p$nNzHN_#;H;$w+goypFt6ydAoxBwZH9v4(7lU0M3&c^c<>b(U#am`oV~V-HB7<3&XdlO=wl2gtI^Cu zd%xairx~hjG4+*ex<(E^*y(etR>sHQHU4`CqyXMMIm+2M_o$4YTv6`Ky0VnI?v(l& zAfK2ZuOvq@mWV6#D{J@s+12Z_Q?DvpOx@$tH8T7imGR9VZh2q0&&6RqE${0*kiPji zZ-=h6l`ae8SVK0&t}K0a8cm;idfV=NfZ$=T7?aD{nWIWElGV#{_V~6kK3uqZR}=r7 z@INiUYhcgsUG;Jp|DekFaQX1;jR&8?@o5~N)YmB>EVGUa`_9rd4#B zi$?dUs%$a!>7-wuSl?6`9~PwU@$<9CKe#f!dGx};VUNdQJuL^1O+r`mak5EjM*+4G zkzp2k6xm1m>@=P}_4Kyg`2ex5{IS%$Vk?o=0XCG=%DJoATp8ayX5q+iJ#ko1%aLP~ z(A9jLY?9&wu#Jcev(Tf+KGJ8W@${*ux9!dch;`+UrREh|iL4H=p`2C@v0zUmQte2od|yk>CG|6%fxce5S81Z|maVSN%A4c{_7dB}TG(Sq|g3 zR>p@5cW!tR!2>;XA(N@5IK=wKku-)7u^%1z{l8cN@f^cv`s(twE)IUxk7Jj&Ge=co zB&(O@F#bC$*e8Z3vpOa%jH{4 zrW&IW5jWWJ#axX@tQwSz>({de$4xVG_1o@znBnK1M#tDAs{^Z{So?Tk?^m;n8`EgTV^z2UH)mLtX{p{w~g*(9|C0^5klFbh43>?3`48c&~kdfV=N zfLK@lSZZFemB{J<8_H?rymH;EGCo|u`@*vf9_XP9nM^gsA=WpJq%nku{piT=|HTT3 z=NLZISC_YSaqz2t9J{=oIjRyPS-mWW@!wS$-|W9|c-X;kSWnC0W0TO;e4K2O;sLOY zhzzsPqsTteXQ%P>si(K?&IgEf<&UN26C@SLy*@<0z=$YiQ1 z4za#*B#j|N>_)wx z<`r9stPZfDoL0^r|Io_#Z~^NcKRKIeYxWD&xZiJTY8P9_XP9nM^gs zrMn|X(ilR-estvb|6&!ya}1vu&w!r#{_%c=y#DaY_^=#gGg*n%sf_0eh$%6W)ys1B z_(xR6H;)~^B<$=stf%EABa^AdXhg(~JfO`+#K>sMVpRX$XQx^8si(K?&IgEf<&UN2 z66J0l`v_D0&{zq>NNdHljb;n^Dw>uEV?Y!bSfkCRPO zJOQ>5kzp2k6xm1m>@=P}_4Kyg`2ex5{IS%$Vk?o=0XCG=%Gu)|RT@=P}_4Kyg`2ex5{IS%$Vk?o=0X7tCPgnph zhw=ZWGQN4@!hvB2!(lxw2aZibSMzbQNn#Xy0aH%k1j|B6d%vEe`|&JKl`RJEJ83mI zlQ>F<^Aw6@T)|LID~Iuqu8eP=>JbuIA%plN29-ZA4_4g&sxrkv=<( zr%ye-ZFfFEtSf&kHLuu8WOaZI<+O4b|8Fbf!v(CbT<7PN>tib8n;W;>5bjcOSWn9h zod?n^KAIliYX@Y8MuapAYbmmi^x0`Ved_6LyYm5JUHN0FdBs*Ds{?E()^415%Gu-p zU1fZ@fR713vw5J0E@U#*6o**fIFiN?BKD&rzyB92Af99ROkZ8z*2TfE`f=>?cIK!` zjAZq)9LDcg86Pg(BLgFNpocDGGSw7^Sl>93#tdNX5A@K5Os1OR5bGO9(ilR-estvb|6&Eia}1y9 ztIONEIQUgRj$Pi)994;ttX`ILSM$Wm_~xYX8G#Wvtf%FSk;znJG$P_A9xzuULYjrO z6xm1m>@=P}_4Kyg`2ex5{IS%$Vk?o=0XCG=%3=HuRK_>&AD~L zV_Xj7|6^r*W&B)y^4Sko##hGA732R?Wqf7)TrvKKD&w1r$NCKve;0+G7B9`>qj&wy zjqY!ms}VUSGBvv5`bpMdcA62-f!_K~tLZ8U|8Qk|W&B+I2I@yD<16Fmit#^M8DAMc zSB!shWqh;m!ZqRk8i)0?Tr)D6YK%ri+;qRlT#X267S>W^AL+Bxc>2`S+ji#z#Jcjw zQuB(fL{YKVr|;va_kConji_8@L9XVDb&z2dlpoK5*80AaTAfrL zSQ+2!Shy}ciNIk!E!T}qrW&IW5jU+cb2TEQSy)SveWcG$W^AL+Bxc>2`S z+ji#z#JcjwQuB(fL{CG220tf%Fak;znJG$P_AJ}_4!LYjrO z6xm1m>@=P}_4Kyg`2ex5{IS%$Vk?o=0XCG=%3=IZR>n8Sjo%TjCl2drdB@0PsxcZ7 zaT6bys}Uj1!di;#BYk!nPoH{v+wOdTSXcg7YF@FG$m#$a%4y{={^^zR&1=RdgzJgJ zdRk5xnM^fCBO-3%19LSZq*+)?k$t4kPUGoQPjB0u4-o6hA4|rH}QeF8WGYgtfk04(r2gf^r@$}?al{?b>)wx<`r9s ztPZfDoK_Cwf4VZhexB>(lV*4QL|0?>?mo|zQROiHXDZ{HM=o3yb}$^)({k0wWU4V5 z5pg2}Fp?jUSQbh}_K~c?nrVEle%qZ7GyL4s=oousbzn7=)5>A|Gb-bo$1PkLt|t!b zX}NM_GSwK3h`5Ol%+-jHW??Nw_K`k2ji*mNy=`|sK&&f&EH$s#N@R6_4dt|Q82_`C z@y+q$+r#z5VLdIkk4&Z-qY)7|@qxJ-5z;KIrN}si(K?&IgEf<&UN26$9d8T2U%_ELE!#Q|q*;74J-!zon4u9N&B9uW>?3`48c&~kdfV=N zfLK@lSZZFemB{J<8_H?rF#eg9@y+Sui^2|u!+KgS8ktNrMk69_;sbLvBBWVZOObt~ z&raj%Q%`T(oevP}${$P3E4C6@9biK_tsKT5Tp8c&u`muh7!K=c8HX>}_!Vo6md~X4 z0E>;NTxBV$ujKfCJj=A&s@XJccRtMUXOTw7*rT|Dp`2C@@=P}_4Kyg`2ex5{IS%$Vk?o=0XCG=%3=H=mGSkz z{^shx{(i19zWMt2apC?0hxN2PuJb^e#YfZQd+mVC(1?&`VJ$`Wkv=<(r%ye-ZFfFE ztSf&kHLuu8WOaZI<+O74_-9wf*LUHYt9Rl1`O5g_?(ycZgW<5Amd%|9(kwoj9^Y#R zWQInBGz)7fvXAuHX*_-E>21670b*VGW2t$?RwAndY$&Idv&SD=8DIDKx!U7@p)$Vt z!1#jjBm#%^v|KPUnQDwiMBKCkGFKx)nuWC#*+=^9G@d^7^tRpk0I{z8vDCa`E0NU! zHk8xK+2aqZjBoB4KR*1-#$i1zkMBH?X7SPV_+ETqhDL-m3u`H|kM!ATJbmivZM*XU zVqN)Tsd>d#BC7*zD5sUf_~%r{H>Zxz4?7qR>uEWEWHQwljfl9356snwkY-^mMfQ332>9f;#`qb0gcIN}cy7I?T^NOuRRtMNnPAiA;zgQXH?7eVpxSlwyr{&s_ z$y8%BBH|`KFjpf&nuWC#*+=^9G@d^7^tRpk0I{z8vDCa`E0NU!Hk8xKVf^zdgt;0K(k!f{$Uf3%r}6Zu zr?>6S2Z(j$kEP}nTZya=u%Vn*&K`ewWqkd+nz{PBnqRJruZ*87#vf4`Ul~7FjDLP* zd}aJxG5*NP_{#XXV*IaE#y4*ozbHJ3z+pWtFX}vyX7SPV_+C#kn4u9N&B9uW>?3`4 z8c&~kdfV=NfLK@lSZZFemB{J<8_H?rJga#@WqjS^=W37t)ynwhz2kGkZxnG@Ps_O@ zlc~mNM8r)yAagY$q*+)?k$t4kPUGoQPjB0u4-o6hA4|Iiz?%r+s5~VpV>I9r{$iJ$y8%BBI2f>`OMXbkY-^mMfQBY-CO$A%BSM;mwG`P$`s_5GKK1mr-T45quKcmoykaYn)d4n?)5>A| zODf}=M=u;4e!qgldRh)1n@lxEBO-3%19LSZq*+)?k$t4kPUGoQPjB0u4-o6hA4|21670b*VGW2t$?RwAnd zY$&Idb60b0Wqkb&)Li`r>enmdn>TNH^zWW@zM17UOON&G$N!~SWA(8 zq|Z*{=~GW{+no;(>&hQX%`3JNSsh?QIjx*M{^gbNb&sE`J^nW;`IIO4T ztdYr7V>BY-rX7&E8WGYgtfk04(r2gf^r@$}?al{?b>)wx<`r9stPZfDoL0^r|BA}^ z<}Ks*hUKIgJ0!%J^o}!V|*pS8!NQ%M->XQ;pGxh@1GpT#X267S>W^AL+Bxc>2`S+ji#z z#JcjwQuB(fL{@=P}_4Kyg`2ex5{IS%$Vk?o=0XCG=%3=I(RmL~hjqeISvvF8Y%UvUrsm5qT#7%r) zu11733u`H|kM!ATJbmivZM*XUVqN)Tsd>d#BC7*zD5sUf_*YfNH`k269uLG= z$YiQ98WC|5ADF8VACitHnOb{bEgdV1ULe1KS2{#a^Wv6aZ`02|6_ea>$M@m`Gc+QkSy)SveWcG$gjE}^8sRA z`D3Yh#a1G#18gX#mBaYgR>n8Sk8cmx6NmM*+&(gyYK%ri+{6dwYD7r0u$ChGNS~d? z)2E)^wmTmn)|Ee&npbQkvO2(qa#}fzKdv&qGCuj975k0Z8;S9+tBh}6HQpoKrQ)!j zmOVNTq*;74J-!!Dn4u9N&B9uW>?3`48c&~kdfV=NfLK@lSZZFemB{J<8_H?r?D4O! zjIVqATBY-rn_9` zYD7r0u$ChGNS~d?)2E)^wmTmn)|Ee&npbQkvO2(qa#}g}@o%b(Z?-KwDO^t+*3@=P}_4Kyg`2ex5{IS%$Vk?o=0XCG=%3=JQE909J z$1e!i6NmM*yrA3fZ4#nQDwiMBKy&=4wPpv#^#T`$(Ui z#?z;s-nKg*Al8*XmYP>=C9*oehH_dtj6b0=zIo}E7l;2_#$i1zFYY{$X7SPV_+ETq zhDL-m3u`H|kM!ATJbmivZM*XUVqN)Tsd>d#BC7*zD5sUf_}{6FZ%!Lu7=C8su%4C+ zMoJx zC*QMTzcG6wG5&We<16Fmit%r)jIV!JGgp6C^Pel@o3D*e4|l0Jtf%Glk;znJG$P`r zdjaNZL`bu+mLmH|pPk0jr=H%nJ0Bp{l|Po6S8OG+I>3fUeZ>x;2d;DDO@o%q; zZ>}DHKI~vPtf%GkBa^AdXhg(KJ0Np4BBWVZOObt~&raj%Q%`T(oevP}${$P3E4C6@ z9biK_t(-mn9hLFTcwwLL`xPA4)3VRlWU4V55pfeAn5z*X&B9uW>?3`48c&~kdfV=N zfLK@lSZZFemB{J<8_H?rF#h){W^AL+Bxc>2`S+ji#z#JcjwQuB(fL{si(K?&IgEf<&UN26=C9*oe zhH_dtjQ{=0`1)UebM;?;@2-rmuUzNqmFpi=##hGA72{8?jBoZ|I6S;A!(lxwhmTFB z8lw>rH{InjS0h52g|!sfNBZnEo<8;Tw%z#vv9A2F)VyLVk<|eBY-CO$A%BSM;mwG`P$`s_5GKK1mr-T45quKcmoykaYn)d4n? z)5>A|DV6c{u4b<8YTi>BU-$UrrGjBh?NzBF7<9M;ov>BwZNF&YtZ6CaqX5h2aOT8iu= zeRdj8pL%-R?tFk)SN>RPUa^(P>Hr(cY2`5fk1FHq)5*DdI{AUh_-4O_Bf@VKaad2w z5o437#%M&uO*&hQX%`3JNSsh?QIjx*M{*No; zo5w618LlS|>uEW1Y%mEN>d;A%d@y#D@ zd0%*UbR5>x^1jXkX%-(%kMFeuGD9OmnuWC#*+=^9G@d^7^tRpk0I{z8vDCa`E0NU! zHk8xK+2jADGQRHdbG65xSs7m$KUa+Z)5`efQ40rzr_DI5r{#dL$y8%BBI2f>`OMXb zkY-^mMfQqjP2jnRmRoA|(7jR332>9f;#`qb0gcIN}cy7I?T^NOuRRtMNnPAiA;e_k2id}(}NxSlwyr{%tp$y8%B zBH|`KFjpf&nuWC#*+=^9G@d^7^tRpk0I{z8vDCa`E0NU!Hk8xKVf;rb^zWW@zM17UVLDNMuapAYbmmi^x0`Ved_6LyYm5JUHN0FdBs*Ds{?E(r332>9f;#`qb0gcIN}cy7I?T z^NOuRRtMNnPAiA;=T^oyPg>X!b}$^))3Rf1GSwK3h`5Ol%+-jHW??Nw_K`k2ji*mN zy=`|sK&&f&EH$s#N@R6_4dt|Q82=ZQ@y(aVTf_ClVLdHdI}fB;d^A127ay3R5h2aO zT8iu=eRdj8pL%-R?tFk)SN>RPUa^(P>Hr(cY2`5fyvq3ccQteMcQqfajBjol9};#j z9M;ovNaukxi;t$q_u2uOp%Ed?!di;#BYk!nPoH{v+wOdTSXcg7YF@FG$m#$a%4y~7 z@#j~@*FAo&_W1u+8Q=WC*4Kt75jd=;<+WQ(rW&IW5jX9C%+-jHW??Nw_K`k2ji*mN zy=`|sK&&f&EH$s#N@R6_4dt|Q_V^1bn8SjGq$jQgK*M%TqcJq*;74 zJ-*it$PA4LX%^N}WFP6X(|G#S)7y6E1H`)W$5Qi(twdG_*icR@XOF+IGQN4`_^si0 z=s2vW<*g%=sm5qT#7%r)u11733u`H|kM!ATJbmivZM*XUVqN)Tsd>d#BC7*zD5sUf z_`j-*Z+?HvJHuTn4(n-oXXk-5i;t$q_u>OHG$N!~SWA(8q|Z*{=~GW{+no;(>&hQX z%`3JNSsh?QIjtPVUsM_2+%o=B*uijEPs^7^CR2^kh=`l`z+8<8X%^N}WFP6X(|G#S z)7y6E1H`)W$5Qi(twdG_*icR@hw*=18QRPUa^(P>Hr(cY2`5f;>!5uGvhCZ>xsj9TE09onQDwi zMBKy&=4wPpv#^#T`$(Ui#?z;s-nKg*Al8*XmYP>=C9*oehH_dtjQ^X;_~x?lt>Jp& zu%4D%MAkG~SGCl2dr`O3&-sxcZ7aT6bys}Uj1!di;#BYk!nPoH{v+wOdTSXcg7YF@FG z$m#$a%4y{={%uLGg$YiQ98WC|5ADF8VACitHnOb{bEgdV1UL ze1KS2{#a^Wv6aZ`02|6_rH}QeF8WGYgtfk04 z(r2gf^r@$}?al{?b>)wx<`r9stPZfDoK_Cw|9fS8bLse&a6NHYPs=SMlc~mNM8r*e zV6H}lGz)7fvXAuHX*_-E>21670b*VGW2t$?RwAndY$&Id!}!Z8d#BC7*zD5sUf_{%Hf z>s?K9U#2@8WA;Y6tGS{wzPV(4Q}~&U!+Kh78ktNrMk69_;t6v#BBWVZOObt~&raj% zQ%`T(oevP}${$P3E4C6@9biK_t(-mne^kcTzZRaWzZSl-GQKi?t{DHZ%J}Aj@y_rw z8;A9@>>Qa)HAW*MZu*(eT#X267S>W^AL+Bxc>2`S+ji#z#JcjwQuB(fL{3fW^AL+Bxc>2`S z+ji#z#JcjwQuB(fL{KIgJ0i%J}Bk@yX$O;;^2UlSd{~jnRmR zoA|(7jR332>9f;#`qb0gcIN}cy7I?T^NOuRRtMNnPAiA;*Hp&Wckf8ve?;%( zVa(o0@80qEmGR9FE?gCUhmON~TCN(KOf^O$B5vXdb2TEQSy)SveWcG$uGt$*kr0P8WC|5 zADF8VACitHnOb{bEgdV1ULe1KS2{#a^Wv6aZ`02|6_RPUa^(P>Hr(cY2`5fla=w! zdE?8%lL#Ev({kC!WU4V55pfeAn5z*X&B9uW>?3`48c&~kdfV=NfLK@lSZZFemB{J< z8_H?rF#h_=_;3M#XaQI874A}gviXr?Nx+X4G>wKY224>iWov`A>0q z9}MXqYR=t!ZkKglCi@dziSsvK(0SYD!lk&2CfdcJzi2ZX!Y`RvFYhubKG9hFSmZJA z@u2=)^Y@d;PcE6)n(-fg#8T;1DaS9~kYW6vPDcBQhplR;N$?{V`{jIf&x0Sv_L+T7 zT>RaT_4dUR7vCP5&j*I(?Tg<#(S#6l;=UFMJF`!W@-1Q|Eywr+24MVwj=466%6MCg zX|?GYzw-fR{KM8Q74oKM{HGpZ#=ra_>tT;SBrp?)^+NOM$LhsVLYkMbmsSH-Lpg1&U%BSy(9d>rhVlI} zH&RsYl`GEg{ywXDc9tjgmFxZI&h&fyKV%rcmd|RAdsyA$`&@tSy@=d(xApt7ymgOX zZdGr|Fn+n%jcY$N?8P{&7oz9T1vGd~W3((LwMwwqh{{!#qWVhJ)eL=})mBa1)v&tN zi=%`zFJUjO2CRm1S~+($|5zCxE+BSB?vCoc)E;X0ycR8=N$~*|=lb!DoRE6ksP1nr14f;HR~Rqu94x} zD&xaqcn)K2#2iX7sxsbqlWOJM$Ny7he7JbCdOCSn_Vr$UI+=dItR7GQbn-J9#?Rl= z$yqV}xs~y&Cv&fi=^6jo%J{Itvts=7D&u?cclANjGye9<_^{mdK3=a?yfhy2^^D3a&Pwwmp(=+~mRmO)EofYGcs*KO__5K^DXZ#l` z<7deD7gfgJe{yF>n4a-ptc(vUTAxn(r;^f*Y8&b4rGvoIp!xcDd^IN(LG2MHT<*(w(jQ4pT z3}A@&Bs(^o?u2J z^!Wc=-|OB9ZP)iCd+g*L%8)zz_asA=`}?2W7-QG3l^OpO_p{-HVSphRU*ClfSK|1^ zFE7jZwRso5_3@wGub43G0CzKb>_oq8X^(%p^Ifs@j*eKv<-e|6Chn?b?D>%n4wVnt zboJ(|yR6*%P9D?E?wZZlc2R9}-BOk7C)z8+IbOe+4V7-1SdVn))ilR!vUXJD(cE6O z@S@9wnlIZ&O} zG^b3o_lEwI1vZTI{)zR}r6|}=TCnzk$OA9FPFpxV*w0uva}vo_f_+!UpY{;gXZ7{b zDLH!Q_OE0Z|G6pOx3y`GTY+)Ex?{h+ZvL*Od4apDxq16dA#3OMo44-_?Y7|67x2!B z?}mxCbNlNi2>zG3Ge#7%Z(gCkMo#6Kll^XX_wi>%>{j3)njK8}wehnCZab^4fEcZi9&-iau#;*b6FR6_8 zbR9sSp7Hlo#;*b6FRhFpfaQLO=^6k3D&yCH@t0M`d%6ywPtW*!E92LI@mEyF55RIi z#Pp2+c4hn;F#gKQcu&^>^ywLYUuFCnF#f8__yJh%hnSx6&C>sd*?9HuqD{~EJu2hF6`1wk$6r$!KM2olkm(u!9hLEG!1!w``BoVEmnx@q_T(2AQ7mdsfD;0pq`18E<4AM4O)RdsW7-0pq_? z89xZmZIJ01|6P^wVHv+RVdU;U`Rp#o*|RfiX4k^BbC!v#pL}L(G_5v06%tG)@J>Gu3vZGFHKV!AFuv2 zXnMv!WK9`Aub=hzjmr3GXuX@9=^4LIWqerIS?}?8SH|y#z00;^_T`t&-jP0DdR8P^V^eW zHGeh0vl?5c_5ZBK<_fJcK3NUr~T5> z)8k!S0~n@f{3Dmv#ilX4=kfFUbkf!qTHWL0^_T`t&-m|NQ^qgs^^k|){GPJT_V`OD zt8jqZsE(cJmu-GacR8N!d{<=FEO*teTqf?SW$d{zn&#k8`H)RlZ@#+AIxmxbOgFo0 zHecI$+vd8Zxa%j{&d^`KnGKb0nplr?=hZaFY_fJ#^A}zw>;{_BZT6o!{GT)tT0I=PSk zbbaO8`!atpM1H6_ck{X3mCEh$^*+Auavs0<=rv{hDSN(o!ua=8#`nEMO=Wy;sixoK z|LvMG{zrG5Ke?-U%B1I+)MquhD{8h62DR?-wjR``XZ&N+HThI^}E4JGcM44C6odh-qhfT#r|d&kg(gFSuR_6rgEA#K;j}7N||DVUde4+32 zc(-6PP^aJH_glKAHm%vcaz%|F4$pIb#68oA?`q)H7k;z!_JH5M_`MVD?Te3{Aox$* zS5ffa-@lK)Z^HOJT^spO9{PP3*%0)|iSo#Z&Ie|FG?QGK{}s%F&wU)8C1+-~CrRYMKXyLtmfTcGI?|xpCX4w%r&Sy!ryZ zapHU3M7wd@gC+?6&pO5oZC z{qy+!GmM|z^LU*7Q^TFdFSxsp_<20M`r7q*{Epz|Gy7qm$3JeepFQ5~YEPKxPh7G* zX-R9EA9T9rnv*}YOq~A-m&=Q7PY$CzW$}Q}XwU8O2X?-{Xg=B{x6RX*sy}_A{dDM` zzQ~54XH2XIEk(h0;G(sIBM-dzI%M(L!G7rCVUtL%66|Ze$G^wj)uMjiuN$`h`wZh> zGxZ+-(yc33z97V0sJH%;?{rM`o+-T)fey=C%$_o+84L})&#--vx6Mra$LipT@6T;nmmLy>hL0HC%K18-rsu z<^Rf{{JWa}kYW66?`n*(Uu$<)Q=ipv&Fx9e-isUcS%Z1L2Z*1?!>g~gdmjJXQ1y9>hld^-`Xd&PTztXO zTxiw2j#{$IV)8}KceK+H@sbW7lh`d=+SjBk$zvCf?Xq&uY82-GT3EKGdHLeYlZr<+ zuULHL;;TZ#xxQx7j$3?g)Lx(D*mzz$zKi0snoqjFm-12fU%xus?H(Hb{una<^{Vg6 z+h6gBGu+=TAF%!V9OEB0`P=oTdEaEzLmzrZXoo)Z(~AdmRaSdGFI#xeaOxPuvaT=liba;>AmrnA!iX=F+8{@V{|R2d6jUUCm|PIr2XKwB!ym z{Z5`94|gB`1FK;CYR_j@_wlFgdD_x_JoI=Sr@4>M@9}mYU-$TUjSZFe%JoUBV0`)- z(at-s&5H5EzjD1I>{M4y?rNYl%@vconyZ%fXj*laM=jZ9F}b^EHCK0e*X$;rBhCJ< z=Gw*U7OxKt=el#!Zd$w|Y8&;g=08@(2a@HVPTsu4%=&cFzNcfYygmL0E91i@#C`g% zPbY6#VtoJm_}%UC8}UBAJjVa0%J^j&Z+A77@$t@Xs6591P-T3$eEH|`w=V7R^?AH; zJl0BJeEdBAhj+vHd4C>%+Y;mJvznOahDu<3{5<|gcEkAjc^<#~dy?tePWPYPpIQ2z z(KwLv@t$PTqqZQzvCjZTAIF9<)R@fq5-ALc#LDc@J*$IhbB?Vkx*-^DSo8n-`|xh&ozBqX=Wlv)hVee4 zzy78N_m5qh$e(!VqupOr?5^e)HVEUtw0P&7F#Zqr*xmJ9-goF8KQ*>$#&r7h zuUrqvFn;#0T=#W9-PXe^*Zf`0{oUj1T}{g7^>A17)C}X(d6tU%-_^`&kNG${pGmM}89{-Xeo=*PD(sM>!wi52+>(j}VzQLZq=_fLbUnwi^Uw=<0AJhBkWd5$^ z{xZJa)uc>W4|g?B8;tSk**);MKjUY0SM!Z}S2H6TOn+DNlNrX({;uXjMcmcg-&d}7 zAB5kB@@uxw)0+_3paI=gD%vt<&%EKb2wp?DzOr zuCqNp{~M_LdmpcTeeHhdT7Ltz(znu~d;D~U@hfHJ{p;^HP!Ifle14_sZ=mw)vKs63 zd;HI27(e?x{w$HI?!6!}w=DAdFvpi0$R;f${fDz5^fcz7IFvC!gIL&hGwy@>$b7 zJB(BEC!ZahVf<`ABLrOkC-+Gp@n?kCcLF{QE&b#(ehwO9hW+HT%6P83ebV27iwC>! ze}7dho(6!F?K{$rlzPRD(G$$R`E8OBe4 zAK&NGEwOmty^k&7iHm0h{(o`niHqFP&9l2b-v4Je;+U;>{jxFoX=}U3SH}0dD!YrC z{*%vsZXGcG)H!4P1M>;S=^j7bCm5H1AOGwO<7a;#|2OOGuBJYZ=YG2K=eagb>7P>n z^BKm^{(1b%+~-%Vhv)H?@$vzkHoBer@mL>s`(6?$G=BroWH>g$(0oe^>K& z>+G(k{sxLXn}^@I9+qMJ^v`M@89nP-{=0Qc{SDOei<5X}^>lJxU%5Uf!}!_n@xQaq z_V{{N!*4VHJbt782I{#F2;;w18K3Or%fq_I=hkNW`}kjcKp6kAb;kJnCU;|dxO=j8 zqHkKVY+lluW~a?WTZk-1ez$H-=_**l4+N+v_Hp5Mn;NuSLSn>`z7c z7O|36pH6ax=HYq#FJ%}%`{(hWs(&B9(l_Cf|ARsMP;>6)bGs{*+v7jcMW4U&EZSyVy8a)XEnz;#@D|Vww2Fm^*%ngD%0P` z|8j=$vwv3ewsm$NU+-$js(HApIU>XO+27Ut$~yamFb7 zfBpSxhVirCkFURT)%{25zjHk*!}!_n@t3c&J-$AxA)n{rSukE7R=DMXTd;LVK@4|d(V(pnmNEVf?Er<86akL92UwZh@wMr`4k$5XK+3&KO_s zt))--Q%x@GLDov=*YiObk` z9RZfNhUm8~ydyOFbNBHlb-s5kyt~ud=HyOmno}m))^LueEU;mu_fM>+E=9q1(t@=Q zL>_qgb$YO$v2f-jlB)#!TK|3gM<3ozXO-g4?JvnN{&Q3Ref)9m_cXhk%GX`o&D(DZ zXy^8ux9<$iX92^qbNdYwO$aeBb7u@Yvu}>_{aCx#>mJYbnTI|8r5VQ0evkL>;=3OH zuBI}6ei(nu1H$<4bHBk{4~(zRYRLF`cvkbW4C812bn+EkQ z>mENpd;D)^7(e^FnrGHMUR&mhvc4x-Zi%LUPqJ5L7(e?x{)Tn7$Jb{yWYs)8tNE=A z<7fY@<^=c3bv-<*see~P#@k=joV2h}|E}g$8OG24?`j_D{&uqdT}|$%w%I-y)cP)b zwjR_zJmueh9l!YM4C80N$G>Zx{gpx8%C}I(tvD%J}(V{OcYN#{b+pdmdjI zKR=9r{R6`IUted8udiIm`2XMDc>q{ZGjTlo-W^prL_rXw*n96Nh>D7ey?l1;y(@MF z73>8SQA9;W!GayTf(5aH3N~zj1rU4he3N98Y<{<=c;3nBz0>9GKT|T9Ov+}nyY=D9 z^^}~5ul+06-Rjtt>pvUuBXfLiBQEdX+Ir5_ej}vn=Uku3Ge**$mE+(1oa?DM-mm_Z z>zqF4+Ol$upIF*0JjYYnp~6|(Wk7dTf0x0TIT2s`vzoUT3?=ASv5s8t zo>$SY;yn2;r0X=Ba$d!9=FB0@lf81)=~lYBSFWW#-uk^h^zmoqM11Y{@fGug$gT@t z#rbFF@#AuQ9{jf}CEEI95b>Hp@{$$mNBul;>BO*2=nb>UqGrL`K{ z&g#QjP5+#Tul-rgeVK@_f6qYuwL4Iyd#)VyG_L-7{Mj`c@zuNM`oUbk=UVFH>rWql zPK`$VoUX^mSFT;>`juu0;Ix zbu8jbSFSeV>%;2gg*g#l`?H$(%C)(yRi0PTyQRIS8b&yc^HJ9f^eC^L_E-cMzI80ZGhYF=MtD$?UKdTv-6Y;e_ zt0`vQJ6RWY8I+y~u@RMhviraKM93965nuaHgdCJvovaH_gp?w_{zUwsxf1aQ*0FDP zm-f}zh_4U(YOc(Q_}ae%^>(I@uM4|{OMQI(>Eo};iTK)|)ohzttEmgKn$qf|jrjVo zIypEe;%ooP^_NV<*M%$BU(Ef1{Iw1JeN+Z4}JW#IT2s`ef;b?*2kBwTy?xFRUfWgugi(} z+P`ugUdOInOA%jxB7W#xiTHb4SP$!eOKUa37kOu;wVFJyRDZ4J`kaWb{dxRpb!;AA z>f>!x)rVQl4LK2C`?H#7>e#HNv{qvyzCNtg+?W&bwcp3zRmb}H(k=rV@%3Tv7T`w{VLkrloIbwx*W;U& zz7gWOmp}b2eIq2#Mb-a;@$j68ul+v$(>k_4zO+_jqpCiv)r`oA_}X8q`7AS!uM6w( zrFp!K`1)|=dP`2k*M1-WPN|R28>(~DhDvJb$!@x)`cHP>niKK0-^Vv?6-rR*b`_f|V z_wno1u|B@E9&aPQKCH*zk<-W5{(Af_b!>lpsgJKeef*s{5nua#e9t=8$CuXQZN%4y z_4vDTBEI(5YM!cN>+z*oP5qhG)5QO6!G;Z;_u1n<7+?Sx2V?Xo!v~SbDNzn|5h*2kAtCw08nk2kG8niKKWzXLU=>+!o}?iAI9)yY!C*Pn>D_nK{a z-M_UT@dwngh%fCHwsl`0o`HHir;o4wdHhb9SxsGd>aXE)!3S^5BqAyd_nLj|K)yX{PRDX5yiJXY9{aMYqr6;@d zsxddM6!Cd(seZ&iIaeaSR~=iAZ)&b9dK=gFD6_v?m2Fj)^|ejaDZQ1Z1f1nkhGtVN zpOtXjZ>4fW)F1t)wa@u~F1Ow)`#o2eV{9E!T*jC>XBxE3tN-}-TrbSbi({+*7+u@= zsho)aW0|U`x6R?+_^RaRW_mW_C#5m@hI%71Db#;&LkT!y%Sc&1P1VtB|LR)A$7M{7 zOn;osacUm=H%0u@rHGd*oLBnzisrk@)rCIO|L$HfU-S9=ijqxrb-hpKD#WGb{btu- zHGP3pUn{RSPfDkKRf%v|#bIf#dG}l$`wIYiUKR2`KdU(^b0zr4_QljiTaC*^d`$bRXkyyy{#CiUz`s}xM*ItNG2)kKzEnCM z|JNh_&Fr-8FNDzcWzW`F#J}-RKhFLa%K2xk%hX`Rzcd#ke!1o=)RTxGTg`}nsrX!t zMf_l2(|;CUb&vj;xk|I6xSiE}QNb}iV0#vDwmiL6i1@GkwckHAs|l9W(LTOau<);) zRitxQ_dDm(ug@3rK3`)IAM5>hp_Tq4ef%oTSF0y|{L)GFB5axDg&K?a&egP`dY0F$ z)Ebo{{?GgPSIQ>kjB44QztqRGmaeSEI-1qt`gZqA%~j(K(Z|17V-a6?x#xOJx~_K$ zToNL@x6-tLW5ysCIKn*sid3$4Rww`ZE`$1a&vkr__3{7aT?SJtUAb0{=xqGz7!Nob z@x9dqKi3HyA>wOyJ^q7=kJ78<|9T&PtM_u&`+t7ENBM*ri}=$U{CR$Ll_R^a#_c2v zQEIKu#;;BZI9sZ0YB&$NYB%EldLN&)o#(-RQnGmN+<~h8PO_J4EaLyoeSA%>PKG;B zr7PEL%h2aT=E9XLS0`Vov505s{!O?#SFV4)RulTjf2xl!UAg{Q)E(OR)f$WV|H_r? zjecKEh*<5%fb3bov6n-7i1TnZvR3!i%#B%%F8x2hucrF5nu#?Q@&D#o%{n!>I{CW4 zrpk-`+MUO*+uVIA_rHGSI=-5_4DK$QRAUj};9tD2X8r$2#Bb1iBU2Kk{_7FHPBrg$ zu9v)4V-bH@HEoFJ1ak+~+*(aM`*FQ|X;xFy^;-Q|&FeK5@&D#o&Bis@$A`5V7w@_i zxbxbb)oj{)vwG6UuV2mnb*-PO>f*XvLH{#cn^1 z`<+ucc~%hnYTm4|h@W#C>KTI3$bj^>SDytjeRx$ zw%x+-*I2~=o7ZaoYQ*c94=v!2TZX2F)^SBDS67~aifxZkRV9qMH2OE~B%4x-c&V{1 zGWT3RFSe>39SM*UwY;B=LoufL&V#&fJ5!aXMrPV`>s~k zYHH)kHIyPQT^9YD=J6laSj7KVu3UdHF&Sdi)oiGFdlsyf5@Wf~KO-?#3^zo&=ld+Ggi>e>-(@POAPR~aCv^3)RwyqH2_AKDI)~5UG z-MomOm1-~b@v+zbDyn|O&nQKF70z}W76ES$e!JT*&~23kyjejj47j1$KN;}Z=9!3q?aq>b4+8ydv!)y9?*P97 zTr{kKe_oVl8u+(D`9A=C7V!PR_W}O^{0i)u2|U5PODx#?A?#@d{vVOFEIS(AFV0%zfxzmi|wLcmN%}gEO$Hdzr(!UD%8X6z^9{~ zHJUfhcUIdNpVKtPdzkyGLI2U9|E}3H{y7Kb?}<3Q1LYnGd?w^?2YpEsSHYeqto}5? z`8W8@wS#LSzq$4i^t6oVN_`GHc0*jfVZLP-`&P|v3c5b@N zyK~cJ{+*jH^YGmC^Q&mr$5&AHu zd4#2XM_Af*grz-4SlV%frTs=&+HHiTy+&BtSA?ZqMOfNXgryxtSmGwa5-$<9?>r0s zl=z6~5*HDcc*x+SpzAxtLsIsfpwE5%Cq<3-4C^FSj$5)`B1Tjm&t#n>H(l0Ca?@qq zBsX2cEm@VWt}BAUDi`_)3>UkT(Z8B%P;FJ zx#_arlAA8;F1hKl{*s$6>oB?LvL2J0F6%P6>9XFEn=b1vx#_b0lAA8;FuCcnzLA?Q z>m0f1vfh!KF6$n->9YQjn=b1hk}m(Jf3KiDeggc6VGaD_Fz-JP{l$Hde-iYsKtC6B zh3mj_;B8EY9qc&;_MHp-Ij+y2vH7J6l4O|iL(n%G`k#h<9kGtr6!v{>%jfhLsDA;h zpX>>IXA^Buu;&Z->wNULkAi*&@Obb~2mLwVQ&HZhL4O^12JqX!JD8$`@>~o3Bf)uE9mxZX(2zejFYMV z#;E@jQUCVM_(A?Clz$BTcL#8r1>^WQ8}zN=zehoT5V$$?H35DA{I8?Fn`3_Z9@^tY zsQ=60-yc!_VX*%=`2SeQ+izV5e~w1|zK(d91bi0s9{~N^fNsA+8S*pTNv8fAp#BG= zeD=GoL4JSG7l(ZZ0AGjtIUfDP3GiQU(2oNi27NaH9|itbQU4uK|F@yP9fyCT0W(7sN={H+LFfWD*Q-~Rz$3fv3!+HdIu ze{7HW#ooqWMo3DYB#nesSJ{5>!zh&FQpD*+DEGsN(;rc;!O+k9R+mTh=p^4*E@>;rr~@E*YX0&ff41oibR{1e}wQ))@jyF~Iy zp-lYKF+0w{Uu}V>BfjrPJil!GYlO@h{r7E@zfzrG-;TicJBC5u8t5mlg?-nVDh&K5 zW1e{f=pV!0Gl0)Q`G$bL2Iw=OzX$Al8}yUV{trNXuZeMIceIb)fNw*2O?H|39S3`! z2i_L`Z-(;ijq)Fb{0)01zuTbyR^W?~-vHoi;V=6hZKK3kvM%DOCH2Gp1)=XMl;=+5 ze-p5Mraa_-74+W&eWyUaAMm%Z$G)W@=sz3!e?|GOM}GHV9%NQXPci&%n zLfA#Tnb8yE-2MPtUm@N0&z1X`_uz-O3=VQmUw7Ei5^|TJKe!wIS{(9Ep!`!nXMV>* z{}SN88}?idyao8}vrM6WFNeMN!@f6BpP!@tUq*i8fV)9|Q_zQj{t)tiAN+3uZvpw% zpx*-e2eAK1Z>d8Ex_*r9|qhK_RI%+H^KaH z6~x=4uzy$ZUxxCW3H%`Nq0oOM@MzfI4*8#o@v0a4|LuWa#QezaTs2CKWv3zkMc|+3 zFyHtd_0<>hKY_jm{51ypw?zGHgz~on{eQr#Lf?VF_G?z5yeq@rYvAA0QD2uLzd@k? z278Z2{j3E49}0XR>gy-y-x%dt7x;Q$`y5Xw@4YDBl_<}h$ZsUd^B(3yzk&aB^T_zE#P|KUD$gE=*^J-Gq87Y;GKc(d&`1<*FyOQL4P;ce>uvx zF6bYC-WT{n)ZewBPlmqDf%kxYpM!n`{JRI@b4&CG$AkVq;9p?h*6`;Rz*hm=CozM+ zhr#|AVE^;LGm!s4`0ruRFM|Bpz`G#-Jwbm3{omP$M>{nSsL zApZjRpGALhDe6zJpJm&})hJ(I;I$F|qac4O?C%VFZ$SS001rogJ%HZFe&w;S# zSI~PSze9i2OxhEW5_=R`L`fHjq5vezQQo2Kr9~{tWyBk>78iZ;AYV1^rs+KLxlk^xq0R8~Pr? z{j48BzZ&}c0{;a5k;tzMcu|zE3Fy~B|4G0Nz~2b_AQZ}TCECxcW+PST?|;H`eRm-~ zcgOvc>%c!0c)101hC%^XNa&`=fnbf%3eL^6U$HzD0XF3iP9a4}<+%qWy0L zd@}664D~Y{_V&d1u^sSv;C~kN$@{lALH-=bkB0vSV&BO*(7zbsvlaM%g1(y|ed^_yzivE2H*5`TwKMwwzfY*nAE{)`qWJ_ybYM{r)D*ex%D9=v7ucH39 z!Tq-#;GY-4zdh)iKz|$f?>zJex59s`qx?gm?*?G|4vJ7e8^Hda$iFr48fZUPz`i?R z-z~;IGiVDXNe;03k^>{XNg=-PlN4Tw^dyB>EjCj6bfVo4m16QMwM*pZB+={m<(Yn} zYouT1UA7-|`YQ3i1V2syE&>mQUq&In2TXp3NhtJ-QsQNNTFzqk6G{SKQ{ z{Z9u=_xQM|pG+FOBb1rmKS_hPEl%|*)id_Dqo?|kB#z4@8E+{5Jsl1^{sQcE*wfQ> zI#(X^lwBBSlHz3H+(rCm1w3~0hQ2fCf*rk}<3Sz?aPkhPbfwlZXO3T~H!)7W9^s^* z_ld|O6<%M8U49Lw%Gui?{{~YmPWhGU4F9Hd;nIIexvrlvLB3qqk6CD_Y%fP6|f(pp}ZC!4>vSFo4w2>F!m znoy<$;j^+(Up1(xMhTW`|lR z&CXv*gQVc(uTzYON` z7wrEE^{@MnY<&D?=~~GA?Q6$tuWw0vU6Eqn|9JX_$nOY4@nkh4nrF&bYOiZN!?9N0 zWv`C3_2uciM*4kw_Vn(cr|s3#H;w2@onR==KZ)yKJbw@HpKSTPeZAZ1Q_rqmxAEr_ zUbOO_|2Xg;ZReGqf78gnO05m~3e2C*1Kt4mY~cBUmjGVNVsFn*u;*z*@nkg=*AW+* zk_P%x(BD16NwP$wFGtygj!? z@_s(*?R(MoH=ch8?7KCRS8Bb;A4;tWdscz`#vm@GlAaf{4f4alJGa_KnAQb}Z<|oJ@aZvd>^seHr`$?0XXU z2VA$`0Q>Gk{?9`GY2Ze{H$vaN&^I6aTL#=7`ksWoiO}~U{I@3J^E<55><#`l$iEfv z!mwu??0F9M%!2-xp>G!SeGa?^@F?W>Jo5Vl`L#rT^8+sj{m(#ux*lP2(f`bV{=x9) zr_k3N`K<=}Xyo?-%JTv8TNwIgLSIMV2cdrw^nVQf%R+v2;HS`D`a%CC&~Lvw6#B0_ zpl>AjFNQr|fd5g-c|e5oaWQ@FR#W(pJNN@c&^Rcvk3C*1YBXC=k)yPb8IPg z?|(FtC}U@wf3TbHyG`E@>h&IldHBlkTlzjw&!4^z)Z_GhpdP2sr+Lih-`>J{?_`5n z4yEoec9}}fDW6i!O%9di_O2u*;|2gny`dqlD?+JVEXsZ)K{cQ*R^TVHg;m^%rU;5m%&o6y$+G9R9T?T)B z4*QDm*V^b;C&T{bVb2OEPx>AWZ%;SGL;4;KPv0B%oQn3fBJ|&m>zw`JuXSNx`ko1& zU;3U2kNKX7M)21cu&)LD^(x|P4D4?Tdp1OQ()Uhydp<{erSF~a^nGE^1k}$)(0?-G zYiIat9@v+@m%-7=1Fe+_G(m9V@G8^j?WKSe|r57 z10M{0BJdHmyk345=syDAWaG*6-vYc1__qeW9sEB4&xF6G0gr&b;lLk({{!GjQGQ8b zw3MW2X5FHIdG&g>zI}NoBfr;xo1#B_81j$6o<}YA6+Z^!{ZkRHY;T`d+B7e&jx`YC?_=nj5#gku*9k(rB;^`^mGSQ=)%{-|7@{Y}n6pWcsiQAVHM-*j~bFKk#nzqwB@_nn;mWw*=O9swJA z=Du`!g|OZp=!QRIuemRqz0a)m?HKsWwSD&kKaj!N9}fpy)c*P(a5g{f@5ck(*qgb} zZ}NLG(95*_Ck5O<`{(Hlen<3W?n^gF?^{W#{_BGV?liByvQ2W10 zkT2?W?!|)s;zNR$$l!YgXUbpH@k!h%@SFSiD`#*g$#3rr*6}wm;NnZMzA{bE#D8&| znmxO1;4gzchCgGE!8>L6QNA*r-+sP-kbN&v|CJPV{@VxnqPBmtfXf~i`XL@GwT<9R z{sq0RCjGNW*}whE^>4sOTbxppG990XdVNVzx91)iobJy{^;PQsjlG%t4Q>@=m9*@)U)M1v-`Nz@ScpKrc&nt1`tEcPnN5)f+)A2LH zGJblTj-L*@@iW5N@@jv}`040w{PbAoC*!BXZv1rEjh`N;_3yCjKOHvXi;S-hyZ*vq zH{N`>9Fhn z9X9kap*G<7v<*=d4`0214-#kvo50BIF%whHy4W~+JWc>B?bo_PLjlT|? z@lnP@huwJWup5s(PRC=1U4QDZo3D7>NzP^ry^_&wDBsmSkf=z9$K@C9_PAzo)e{w&~g zk^iZ{4effbR%-sPf&bozy=OyyD(JT({)WNdi$MQ0;CX?Y0N(78u(M> zHyZvu8uYCoe+=l0puMaLd#=U!djsO(8R#F0`NcdYv_gC>3;m0N-UsnH6y;kL_IHK- zH$nd(=zABq0{g<6122yJTEm{jk^gGQe+c}gkpFP#dk6Br15bwh+VJ;Uz>Q(wn$UM7 z_z#5st6|?0klzpd3!%Idp#MeS1z_Lm&_5dZZsd0(?7IQ{!@&Or@P@Fb8}L}f_iK<} z5&7+h@+=Fy2KWzwznVb*2$b(i$Uh7IpMaM`d6oh0kNi&uE&?Bb_OS!T>s!j=@njy{ zKb;r&LbU((pf3!(AM)E4_QlVw$TL*%|8)4TIs9<}{CyJmUk6?S`M&}DBKVI3y)EpU z0em{-PX~Q3Lob+7O~&ygeScoEKm2+H@?8RYHU@nV@UHOF)rf;Dfse+#;w^h$HMLW| z=ZJB30`LRiKMVBJftN&iF97{~;0sayBjM+lk^kk8zYKV7e-UwB03IC8 z>yzS4@#Genb($2rI56}rK^N@kX8&+@-glb`A-9lV_sz&##8Ux>-F{=or&MdmeQI(D z@i@U?FX!?%_Vt8)f>XLur^k8=-L1bo!)d@9V_(C{Vy2D=I;ZZ-8lxhCU0>8sfUm=|*r5Pj+dwomUcytD+-BJFY*yr*M=zXyd zq^&7$s3-ltcAc5^d(qk9;v}*3B++p`ZzxBKE60iDW4cl;%zP^3>*6Ejcm7E8RVuBQ z)E=c4v3A2grCR0cmHoXar_D$13FA8DMjJ2Q-)9;e>~#JaWz&&=;{D?k{9-tq*^VCj zL+{^@-{+!~{k}oSSNkW!=hUl*OuUm%?#-JlL%OrumdCZ*%J$^fuTt%eDpwArZ21FT z%hG+qd=YpbGIZl#?FZ+8mL?zbkM@w)+b8PR zlfrLCz>BHl%xS=D*!g{$Q29FtJEPrw4EZjge-Y7>;_s4w=r@$w-}K{^+gIAI;0L+? z4*#wa`B(Off&N>Rzfu?4aU(6CQon+Jv!PdxOC1kcf0rTOr)+=X^~T?qNQ%E2zZ)T4 zKfXOTfxR(KiYti5;IE`$^~CL4K=%euKSE^7=N7 z>P_Ai1ODsneMVp2WkA0f^rb<6AO2VY^p}9ogueCR?^}UeV7`1T>g!bK>kE81^!)&Q z5A5#*{UdPQ`5nr$0Iutr0Y3=+BcX2>&>sPA2z%~B{v!|%cZ1#>_H=;0kKm6Dfj5FZ zchG*+&&J??7W#(4-ZNp(!N3bZ|BY7O$M^9VFTOI79QxA}KyL(nADVGG^jrQpN8`uJ z=`-y*NSeRD{_yr(X4Z)-%h~4#E2rD%3@fLfVETp1>FM*HzP*k^|F#v@X;uP#J@h}{ zN7pY(Ed}|*P+uEBepS%#1N}_o-xclicf`}V_Ik^g?=HmCVX$v0<9Y9X^$6Azu7iD# zgMKjVeFb;|@RGO>a69Zf2lkzg{H}yOSA%{g@*4;IB=At=-yZtc0smv5uL*ij;P-&v z1zr{P*#rLh2KHSJ`6j?e!oGPyKMwdY;75T+B0jExJr99@GU{Vr*z+dn8$teM;8%ec z!gD3JBVHbWz2BpKYz=?k2l*v{FNVH5(Z4PRd=To4nhfDeNlvw70a#lHA`bSAOPRQ_A=97LhS6=3Wx#`l6=BCSiq}+6Q z-)?TYymvP@UG6{Srb~aFn=bu!Zo2f}x#`l6=cY@4o|`WHdTzSRUvtx?-G!TuR+YWMgFn&i{Dc^u~N&L$Z+CGL9a7x82E|Pbq=Rb_KHUSaO)S2o>W># z=o!^#QkY-zTOgBPjOAH4TOMbiYG}t1kDJ>3)A+XKs|fncdaYnbFQoS&(uBleM=z%D zQ+9NRJzakf?A)Ngm|{mSbP;;jKzG>D%hwY6v_J<|s*B-t{*!05;_?+b8_OI$aX8hl z)Q`6P87`gJ3-S3=)IQ~T8M~jv^S8zRlJB7JTU@vN4Eit7U$p(3*Pmiyjt!{p@rrBqrTpMM4P5jO|@am3%=@b8LI{z-ZI{j;?E9;f*yh0TQ0D8z%q zp1zxrboM8O6np!xL3`Rz_%rK#g%o>z8wtH{CchMWy5{emp{Ll>HUAkIdWt$a>|Kt=AEh=i@njm6@VM)GnWxxw0H-&7FOs}R z6yw{KXpb#HKN0idvm$y@M148z@-3wA=}ile04vokj?ZKj!|CJMVXtppp>GiUQ;4xV z3mfYzqCW&y>g8y@loV8m3YH%1O!?FPIoKJedwpebJ57M)K5caUpA_ed?RD7MTZVqe zVNcidsQW_wm8ICxi`|5NVW2x4(Jug9u%jnEV*7|qdkFV?5~Kef=o9Sp8T#Fz-<{L% z#P4%Uid{v;V;Q*=JH4hIG)O`m>vkpB(F-5TS#~}EjQe;=5#zVRPG2#df20{C4tx5} zhT;rJiYaz5nb-b1Mg$8*S9z5DfaX|K;Iqmy8`bF{@7j_&%qz}OWuB;|8~$v zye;T!NBR@EG?!X% z46escH8q=7ukb7beeEK9l^TTgfaSrzip6Pe(w0C^v8S&C`nr%`4|sj>v-}%^|1Fb~ zi*H{(pMMYNBi;=3L3Tdt9kz+xm+A2tk^dzd*mJJ&rymE4lZ0hsnU~G7zp0+YrF%QC zj_QH@O7)BAat&j#mp=pa6nlDK(EC9CG~iRgZ_5?@dkVpq?_&%_=X z7hD0=LdM?#e{1LGj^D&Z?+_P$pQ)W^`uae6(ANX|T_?r!|Dv7;t?BJa9F|o5mlS`o zzs??qO{%8rcDF`GKE_IQir1A3h}RVR_TuR2`lK%((w+N~^0y`bCqn+jg@X;N=QrPv zT0QVP?8~F|tp<7q7hX1;!M~fK{(3|>DcAcq9`Ww~V<@6Qyw{0lQ8{Yi?0A1u96 ze^=CTy;a8U7|VJv)*m;H*59R#n06WRas6M~?w!3p&h$Raip+J0-hV6c;MUEZ!_{Ku zdOzrO_NVhTBPDWWKg-$a!G2(Q7ajE2alrM@Ucc|JFdi8HY#sDF?D8+__1PfT3x5ZbN3PJh)%I5kO`Zhxl)IbhM*Rtp6FDT0pA@TXW( z^Go=yEp=at<3SbiKkJhdo{U^~6m1 zG?wwz*-`jh@SY*gQtan@j<1-uORrbgf7VYH2S2ztOvf)Tr}OXa^Oxtg=hq}>k5Uce z{<9428Cbqui1mxq&n~~Bj)x9jzpbxO4>B*eaqr8S$~!ry$IO%F4|;%Qjj@qtP1Oh= z#%+haJ{|upGx}2O=w_U3m#G)m9@F@68L8!>@l4*q2Yi63lHlJy)=n?~xH${-7ovH3 zQuxwXmYw73gXF7SeWGY5mQWTl*&)Cm+V+Kyji_ z<$A#9OFxZ9IoD|#>)X-9QRVoJ^G#e_c!#_f*`d_8cK+q*J#{udF65nixUM-F^|KAG zn|gwObI?<4a?$^E27Oh?uME62_*475{q4X%+2rK>EcbP+{XYK%p^x}`l=mfr%|D{U zUB@dG`(3Gb;O94hw>1`cJ-#2Np5Cy3w4HzY@*dh!GlcTZL_PyhzfBE2( z_$m1F7x?RNyWiO7cbvUn;c+kIKNL1XHhnwom3QYrnBV|5J|m zf5lX3h>sL|{xP7Z^1ghJS-R(c*PMB>y4m{6)6atc`U7tSJOuLFE}&Hf{Y_C{yS9kw zyQ2MW34hK;`F=-v#)JMe=ud*4=I6`%DCoowfWB;0KS{E*6t!`f7y9|MP50vt(ksua zUtcKem!$Z!z@>b@;IX&+*k~T&zT*=7{zTL+lfnUp6zD?`cP|6)j_cmtfVV)sUKQt8 z$uHI)EO%0DASUgWiI>-4$7#s-V&ENN$4ihO0s1|_CyFY}>X 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 C4+O;k diff --git a/src/vs/base/common/web-tree-sitter/cgmanifest.json b/src/vs/base/common/web-tree-sitter/cgmanifest.json deleted file mode 100644 index 48bb91c66763e..0000000000000 --- a/src/vs/base/common/web-tree-sitter/cgmanifest.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "registrations": [ - { - "component": { - "type": "git", - "git": { - "name": "web-tree-sitter", - "repositoryUrl": "https://github.com/tree-sitter/tree-sitter", - "commitHash": "fc15f621334a262039ffaded5937e2844f88da61" - } - }, - "license": "MIT", - "version": "0.22.2" - } - ], - "version": 1 -} diff --git a/src/vs/base/common/web-tree-sitter/tree-sitter-web.d.ts b/src/vs/base/common/web-tree-sitter/tree-sitter-web.d.ts deleted file mode 100644 index 45967662482f0..0000000000000 --- a/src/vs/base/common/web-tree-sitter/tree-sitter-web.d.ts +++ /dev/null @@ -1,239 +0,0 @@ -export class Parser { - /** - * - * @param moduleOptions Optional emscripten module-object, see https://emscripten.org/docs/api_reference/module.html - */ - static init(moduleOptions?: object): Promise; - delete(): void; - parse(input: string | Parser.Input, oldTree?: Parser.Tree, options?: Parser.Options): Parser.Tree; - getIncludedRanges(): Parser.Range[]; - getTimeoutMicros(): number; - setTimeoutMicros(timeout: number): void; - reset(): void; - getLanguage(): Parser.Language; - setLanguage(language?: Parser.Language | null): void; - getLogger(): Parser.Logger; - setLogger(logFunc?: Parser.Logger | false | null): void; - } - -export namespace Parser { - export type Options = { - includedRanges?: Range[]; - }; - - export type Point = { - row: number; - column: number; - }; - - export type Range = { - startIndex: number, - endIndex: number, - startPosition: Point, - endPosition: Point - }; - - export type Edit = { - startIndex: number; - oldEndIndex: number; - newEndIndex: number; - startPosition: Point; - oldEndPosition: Point; - newEndPosition: Point; - }; - - export type Logger = ( - message: string, - params: { [param: string]: string }, - type: "parse" | "lex" - ) => void; - - export interface Input { - (index: number, position?: Point): string | null; - } - - export interface SyntaxNode { - tree: Tree; - id: number; - typeId: number; - grammarId: number; - type: string; - grammarType: string; - isNamed: boolean; - isMissing: boolean; - isExtra: boolean; - hasChanges: boolean; - hasError: boolean; - isError: boolean; - text: string; - parseState: number; - nextParseState: number; - startPosition: Point; - endPosition: Point; - startIndex: number; - endIndex: number; - parent: SyntaxNode | null; - children: Array; - namedChildren: Array; - childCount: number; - namedChildCount: number; - firstChild: SyntaxNode | null; - firstNamedChild: SyntaxNode | null; - lastChild: SyntaxNode | null; - lastNamedChild: SyntaxNode | null; - nextSibling: SyntaxNode | null; - nextNamedSibling: SyntaxNode | null; - previousSibling: SyntaxNode | null; - previousNamedSibling: SyntaxNode | null; - descendantCount: number; - - equals(other: SyntaxNode): boolean; - toString(): string; - child(index: number): SyntaxNode | null; - namedChild(index: number): SyntaxNode | null; - childForFieldName(fieldName: string): SyntaxNode | null; - childForFieldId(fieldId: number): SyntaxNode | null; - fieldNameForChild(childIndex: number): string | null; - childrenForFieldName(fieldName: string, cursor: TreeCursor): Array; - childrenForFieldId(fieldId: number, cursor: TreeCursor): Array; - firstChildForIndex(index: number): SyntaxNode | null; - firstNamedChildForIndex(index: number): SyntaxNode | null; - - descendantForIndex(index: number): SyntaxNode; - descendantForIndex(startIndex: number, endIndex: number): SyntaxNode; - namedDescendantForIndex(index: number): SyntaxNode; - namedDescendantForIndex(startIndex: number, endIndex: number): SyntaxNode; - descendantForPosition(position: Point): SyntaxNode; - descendantForPosition(startPosition: Point, endPosition: Point): SyntaxNode; - namedDescendantForPosition(position: Point): SyntaxNode; - namedDescendantForPosition(startPosition: Point, endPosition: Point): SyntaxNode; - descendantsOfType(types: String | Array, startPosition?: Point, endPosition?: Point): Array; - - walk(): TreeCursor; - } - - export interface TreeCursor { - nodeType: string; - nodeTypeId: number; - nodeStateId: number; - nodeText: string; - nodeId: number; - nodeIsNamed: boolean; - nodeIsMissing: boolean; - startPosition: Point; - endPosition: Point; - startIndex: number; - endIndex: number; - readonly currentNode: SyntaxNode; - readonly currentFieldName: string; - readonly currentFieldId: number; - readonly currentDepth: number; - readonly currentDescendantIndex: number; - - reset(node: SyntaxNode): void; - resetTo(cursor: TreeCursor): void; - delete(): void; - gotoParent(): boolean; - gotoFirstChild(): boolean; - gotoLastChild(): boolean; - gotoFirstChildForIndex(goalIndex: number): boolean; - gotoFirstChildForPosition(goalPosition: Point): boolean; - gotoNextSibling(): boolean; - gotoPreviousSibling(): boolean; - gotoDescendant(goalDescendantIndex: number): void; - } - - export interface Tree { - readonly rootNode: SyntaxNode; - - rootNodeWithOffset(offsetBytes: number, offsetExtent: Point): SyntaxNode; - copy(): Tree; - delete(): void; - edit(edit: Edit): Tree; - walk(): TreeCursor; - getChangedRanges(other: Tree): Range[]; - getIncludedRanges(): Range[]; - getEditedRange(other: Tree): Range; - getLanguage(): Language; - } - - export interface QueryCapture { - name: string; - text?: string; - node: SyntaxNode; - setProperties?: { [prop: string]: string | null }; - assertedProperties?: { [prop: string]: string | null }; - refutedProperties?: { [prop: string]: string | null }; - } - - export interface QueryMatch { - pattern: number; - captures: QueryCapture[]; - } - - export type QueryOptions = { - startPosition?: Point; - endPosition?: Point; - startIndex?: number; - endIndex?: number; - matchLimit?: number; - maxStartDepth?: number; - }; - - export interface PredicateResult { - operator: string; - operands: { name: string; type: string }[]; - } - - export class Query { - captureNames: string[]; - readonly predicates: { [name: string]: Function }[]; - readonly setProperties: any[]; - readonly assertedProperties: any[]; - readonly refutedProperties: any[]; - readonly matchLimit: number; - - delete(): void; - captures(node: SyntaxNode, options?: QueryOptions): QueryCapture[]; - matches(node: SyntaxNode, options?: QueryOptions): QueryMatch[]; - predicatesForPattern(patternIndex: number): PredicateResult[]; - disableCapture(captureName: string): void; - disablePattern(patternIndex: number): void; - isPatternGuaranteedAtStep(byteOffset: number): boolean; - isPatternRooted(patternIndex: number): boolean; - isPatternNonLocal(patternIndex: number): boolean; - startIndexForPattern(patternIndex: number): number; - didExceedMatchLimit(): boolean; - } - - class Language { - static load(input: string | Uint8Array): Promise; - - readonly version: number; - readonly fieldCount: number; - readonly stateCount: number; - readonly nodeTypeCount: number; - - fieldNameForId(fieldId: number): string | null; - fieldIdForName(fieldName: string): number | null; - idForNodeType(type: string, named: boolean): number; - nodeTypeForId(typeId: number): string | null; - nodeTypeIsNamed(typeId: number): boolean; - nodeTypeIsVisible(typeId: number): boolean; - nextState(stateId: number, typeId: number): number; - query(source: string): Query; - lookaheadIterator(stateId: number): LookaheadIterable | null; - } - - export class LookaheadIterable { - readonly language: Language; - readonly currentTypeId: number; - readonly currentType: string; - - delete(): void; - reset(language: Language, stateId: number): boolean; - resetState(stateId: number): boolean; - [Symbol.iterator](): Iterator; - } - } - diff --git a/src/vs/base/common/web-tree-sitter/tree-sitter-web.js b/src/vs/base/common/web-tree-sitter/tree-sitter-web.js deleted file mode 100644 index 643a79a701c91..0000000000000 --- a/src/vs/base/common/web-tree-sitter/tree-sitter-web.js +++ /dev/null @@ -1,4029 +0,0 @@ -/* eslint-disable no-eval */ -/* eslint-disable no-case-declarations */ -/* eslint-disable no-throw-literal */ -/* eslint-disable eqeqeq */ -/* eslint-disable curly */ -/* eslint-disable local/code-no-unused-expressions */ -/* eslint-disable local/code-no-unexternalized-strings */ -/* eslint-disable no-var */ -/* eslint-disable header/header */ - -(function (global, factory) { - typeof define === 'function' && define.amd ? define(['exports'], factory) : - typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : - (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.Parser = {})); -})(this, (function () { - - var Module = void 0 !== Module ? Module : {}; - - TreeSitter = (function () { - var initPromise, - document = - "object" == typeof window - ? { currentScript: window.document.currentScript } - : null; - class Parser { - constructor() { - this.initialize(); - } - initialize() { - throw new Error("cannot construct a Parser before calling `init()`"); - } - static init(moduleOptions) { - return ( - initPromise || - ((Module = Object.assign({}, Module, moduleOptions)), - (initPromise = new Promise((resolveInitPromise) => { - var moduleOverrides = Object.assign({}, Module), - arguments_ = [], - thisProgram = "./this.program", - quit_ = (e, t) => { - throw t; - }, - ENVIRONMENT_IS_WEB = "object" == typeof window, - ENVIRONMENT_IS_WORKER = "function" == typeof importScripts, - ENVIRONMENT_IS_NODE = - "object" == typeof process && - "object" == typeof process.versions && - "string" == typeof process.versions.node, - scriptDirectory = "", - read_, - readAsync, - readBinary, - setWindowTitle; - function locateFile(e) { - return Module.locateFile - ? Module.locateFile(e, scriptDirectory) - : scriptDirectory + e; - } - if (ENVIRONMENT_IS_NODE) { - var fs = require("fs"), - nodePath = require("path"); - (scriptDirectory = ENVIRONMENT_IS_WORKER - ? nodePath.dirname(scriptDirectory) + "/" - : __dirname + "/"), - (read_ = (e, t) => ( - (e = isFileURI(e) ? new URL(e) : nodePath.normalize(e)), - fs.readFileSync(e, t ? void 0 : "utf8") - )), - (readBinary = (e) => { - var t = read_(e, !0); - return t.buffer || (t = new Uint8Array(t)), t; - }), - (readAsync = (e, t, r, _ = !0) => { - (e = isFileURI(e) ? new URL(e) : nodePath.normalize(e)), - fs.readFile(e, _ ? void 0 : "utf8", (e, s) => { - e ? r(e) : t(_ ? s.buffer : s); - }); - }), - !Module.thisProgram && - process.argv.length > 1 && - (thisProgram = process.argv[1].replace(/\\/g, "/")), - (arguments_ = process.argv.slice(2)), - "undefined" != typeof module && (module.exports = Module), - (quit_ = (e, t) => { - throw ((process.exitCode = e), t); - }), - (Module.inspect = () => "[Emscripten Module object]"); - } else - (ENVIRONMENT_IS_WEB || ENVIRONMENT_IS_WORKER) && - (ENVIRONMENT_IS_WORKER - ? (scriptDirectory = self.location.href) - : void 0 !== document && - document.currentScript && - (scriptDirectory = document.currentScript.src), - (scriptDirectory = - 0 !== scriptDirectory.indexOf("blob:") - ? scriptDirectory.substr( - 0, - scriptDirectory - .replace(/[?#].*/, "") - .lastIndexOf("/") + 1 - ) - : ""), - (read_ = (e) => { - var t = new XMLHttpRequest(); - return t.open("GET", e, !1), t.send(null), t.responseText; - }), - ENVIRONMENT_IS_WORKER && - (readBinary = (e) => { - var t = new XMLHttpRequest(); - return ( - t.open("GET", e, !1), - (t.responseType = "arraybuffer"), - t.send(null), - new Uint8Array(t.response) - ); - }), - (readAsync = (e, t, r) => { - var _ = new XMLHttpRequest(); - _.open("GET", e, !0), - (_.responseType = "arraybuffer"), - (_.onload = () => { - 200 == _.status || (0 == _.status && _.response) - ? t(_.response) - : r(); - }), - (_.onerror = r), - _.send(null); - }), - (setWindowTitle = (e) => (document.title = e))); - var out = Module.print || console.log.bind(console), - err = Module.printErr || console.warn.bind(console); - Object.assign(Module, moduleOverrides), - (moduleOverrides = null), - Module.arguments && (arguments_ = Module.arguments), - Module.thisProgram && (thisProgram = Module.thisProgram), - Module.quit && (quit_ = Module.quit); - var dynamicLibraries = Module.dynamicLibraries || [], - wasmBinary; - Module.wasmBinary && (wasmBinary = Module.wasmBinary); - var noExitRuntime = Module.noExitRuntime || !0, - wasmMemory; - "object" != typeof WebAssembly && - abort("no native wasm support detected"); - var ABORT = !1, - EXITSTATUS, - HEAP8, - HEAPU8, - HEAP16, - HEAPU16, - HEAP32, - HEAPU32, - HEAPF32, - HEAPF64; - function assert(e, t) { - e || abort(t); - } - function updateMemoryViews() { - var e = wasmMemory.buffer; - (Module.HEAP8 = HEAP8 = new Int8Array(e)), - (Module.HEAP16 = HEAP16 = new Int16Array(e)), - (Module.HEAP32 = HEAP32 = new Int32Array(e)), - (Module.HEAPU8 = HEAPU8 = new Uint8Array(e)), - (Module.HEAPU16 = HEAPU16 = new Uint16Array(e)), - (Module.HEAPU32 = HEAPU32 = new Uint32Array(e)), - (Module.HEAPF32 = HEAPF32 = new Float32Array(e)), - (Module.HEAPF64 = HEAPF64 = new Float64Array(e)); - } - var INITIAL_MEMORY = Module.INITIAL_MEMORY || 33554432; - assert( - INITIAL_MEMORY >= 65536, - "INITIAL_MEMORY should be larger than STACK_SIZE, was " + - INITIAL_MEMORY + - "! (STACK_SIZE=65536)" - ), - (wasmMemory = Module.wasmMemory - ? Module.wasmMemory - : new WebAssembly.Memory({ - initial: INITIAL_MEMORY / 65536, - maximum: 32768, - })), - updateMemoryViews(), - (INITIAL_MEMORY = wasmMemory.buffer.byteLength); - var wasmTable = new WebAssembly.Table({ - initial: 25, - element: "anyfunc", - }), - __ATPRERUN__ = [], - __ATINIT__ = [], - __ATMAIN__ = [], - __ATPOSTRUN__ = [], - __RELOC_FUNCS__ = [], - runtimeInitialized = !1, - runtimeKeepaliveCounter = 0; - function keepRuntimeAlive() { - return noExitRuntime || runtimeKeepaliveCounter > 0; - } - function preRun() { - if (Module.preRun) - for ( - "function" == typeof Module.preRun && - (Module.preRun = [Module.preRun]); - Module.preRun.length; - - ) - addOnPreRun(Module.preRun.shift()); - callRuntimeCallbacks(__ATPRERUN__); - } - function initRuntime() { - (runtimeInitialized = !0), - callRuntimeCallbacks(__RELOC_FUNCS__), - callRuntimeCallbacks(__ATINIT__); - } - function preMain() { - callRuntimeCallbacks(__ATMAIN__); - } - function postRun() { - if (Module.postRun) - for ( - "function" == typeof Module.postRun && - (Module.postRun = [Module.postRun]); - Module.postRun.length; - - ) - addOnPostRun(Module.postRun.shift()); - callRuntimeCallbacks(__ATPOSTRUN__); - } - function addOnPreRun(e) { - __ATPRERUN__.unshift(e); - } - function addOnInit(e) { - __ATINIT__.unshift(e); - } - function addOnPostRun(e) { - __ATPOSTRUN__.unshift(e); - } - var runDependencies = 0, - runDependencyWatcher = null, - dependenciesFulfilled = null; - function getUniqueRunDependency(e) { - return e; - } - function addRunDependency(e) { - runDependencies++, - Module.monitorRunDependencies && - Module.monitorRunDependencies(runDependencies); - } - function removeRunDependency(e) { - if ( - (runDependencies--, - Module.monitorRunDependencies && - Module.monitorRunDependencies(runDependencies), - 0 == runDependencies && - (null !== runDependencyWatcher && - (clearInterval(runDependencyWatcher), - (runDependencyWatcher = null)), - dependenciesFulfilled)) - ) { - var t = dependenciesFulfilled; - (dependenciesFulfilled = null), t(); - } - } - function abort(e) { - throw ( - (Module.onAbort && Module.onAbort(e), - err((e = "Aborted(" + e + ")")), - (ABORT = !0), - (EXITSTATUS = 1), - (e += ". Build with -sASSERTIONS for more info."), - new WebAssembly.RuntimeError(e)) - ); - } - var dataURIPrefix = "data:application/octet-stream;base64,", - wasmBinaryFile, - tempDouble, - tempI64; - function isDataURI(e) { - return e.startsWith(dataURIPrefix); - } - function isFileURI(e) { - return e.startsWith("file://"); - } - function getBinary(e) { - try { - if (e == wasmBinaryFile && wasmBinary) - return new Uint8Array(wasmBinary); - if (readBinary) return readBinary(e); - throw "both async and sync fetching of the wasm failed"; - } catch (e) { - abort(e); - } - } - function getBinaryPromise(e) { - if ( - !wasmBinary && - (ENVIRONMENT_IS_WEB || ENVIRONMENT_IS_WORKER) - ) { - if ("function" == typeof fetch && !isFileURI(e)) - return fetch(e, { credentials: "same-origin" }) - .then((t) => { - if (!t.ok) - throw ( - "failed to load wasm binary file at '" + e + "'" - ); - return t.arrayBuffer(); - }) - .catch(() => getBinary(e)); - if (readAsync) - return new Promise((t, r) => { - readAsync(e, (e) => t(new Uint8Array(e)), r); - }); - } - return Promise.resolve().then(() => getBinary(e)); - } - function instantiateArrayBuffer(e, t, r) { - return getBinaryPromise(e) - .then((e) => WebAssembly.instantiate(e, t)) - .then((e) => e) - .then(r, (e) => { - err("failed to asynchronously prepare wasm: " + e), - abort(e); - }); - } - function instantiateAsync(e, t, r, _) { - return e || - "function" != typeof WebAssembly.instantiateStreaming || - isDataURI(t) || - isFileURI(t) || - ENVIRONMENT_IS_NODE || - "function" != typeof fetch - ? instantiateArrayBuffer(t, r, _) - : fetch(t, { credentials: "same-origin" }).then((e) => - WebAssembly.instantiateStreaming(e, r).then( - _, - function (e) { - return ( - err("wasm streaming compile failed: " + e), - err("falling back to ArrayBuffer instantiation"), - instantiateArrayBuffer(t, r, _) - ); - } - ) - ); - } - function createWasm() { - var e = { - env: wasmImports, - wasi_snapshot_preview1: wasmImports, - "GOT.mem": new Proxy(wasmImports, GOTHandler), - "GOT.func": new Proxy(wasmImports, GOTHandler), - }; - function t(e, t) { - var r = e.exports; - r = relocateExports(r, 1024); - var _ = getDylinkMetadata(t); - return ( - _.neededDynlibs && - (dynamicLibraries = - _.neededDynlibs.concat(dynamicLibraries)), - mergeLibSymbols(r, "main"), - (Module.asm = r), - addOnInit(Module.asm.__wasm_call_ctors), - __RELOC_FUNCS__.push(Module.asm.__wasm_apply_data_relocs), - removeRunDependency("wasm-instantiate"), - r - ); - } - if ( - (addRunDependency("wasm-instantiate"), Module.instantiateWasm) - ) - try { - return Module.instantiateWasm(e, t); - } catch (e) { - return ( - err( - "Module.instantiateWasm callback failed with error: " + - e - ), - !1 - ); - } - return ( - instantiateAsync(wasmBinary, wasmBinaryFile, e, function (e) { - t(e.instance, e.module); - }), - {} - ); - } - (wasmBinaryFile = "tree-sitter.wasm"), - isDataURI(wasmBinaryFile) || - (wasmBinaryFile = locateFile(wasmBinaryFile)); - var ASM_CONSTS = {}; - function ExitStatus(e) { - (this.name = "ExitStatus"), - (this.message = "Program terminated with exit(" + e + ")"), - (this.status = e); - } - var GOT = {}, - currentModuleWeakSymbols = new Set([]), - GOTHandler = { - get: function (e, t) { - var r = GOT[t]; - return ( - r || - (r = GOT[t] = - new WebAssembly.Global({ - value: "i32", - mutable: !0, - })), - currentModuleWeakSymbols.has(t) || (r.required = !0), - r - ); - }, - }; - function callRuntimeCallbacks(e) { - for (; e.length > 0; ) e.shift()(Module); - } - var UTF8Decoder = - "undefined" != typeof TextDecoder - ? new TextDecoder("utf8") - : void 0; - function UTF8ArrayToString(e, t, r) { - for (var _ = t + r, s = t; e[s] && !(s >= _); ) ++s; - if (s - t > 16 && e.buffer && UTF8Decoder) - return UTF8Decoder.decode(e.subarray(t, s)); - for (var n = ""; t < s; ) { - var a = e[t++]; - if (128 & a) { - var o = 63 & e[t++]; - if (192 != (224 & a)) { - var l = 63 & e[t++]; - if ( - (a = - 224 == (240 & a) - ? ((15 & a) << 12) | (o << 6) | l - : ((7 & a) << 18) | - (o << 12) | - (l << 6) | - (63 & e[t++])) < 65536 - ) - n += String.fromCharCode(a); - else { - var i = a - 65536; - n += String.fromCharCode( - 55296 | (i >> 10), - 56320 | (1023 & i) - ); - } - } else n += String.fromCharCode(((31 & a) << 6) | o); - } else n += String.fromCharCode(a); - } - return n; - } - function getDylinkMetadata(e) { - var t = 0, - r = 0; - function _() { - for (var r = 0, _ = 1; ; ) { - var s = e[t++]; - if (((r += (127 & s) * _), (_ *= 128), !(128 & s))) break; - } - return r; - } - function s() { - var r = _(); - return UTF8ArrayToString(e, (t += r) - r, r); - } - function n(e, t) { - if (e) throw new Error(t); - } - var a = "dylink.0"; - if (e instanceof WebAssembly.Module) { - var o = WebAssembly.Module.customSections(e, a); - 0 === o.length && - ((a = "dylink"), - (o = WebAssembly.Module.customSections(e, a))), - n(0 === o.length, "need dylink section"), - (r = (e = new Uint8Array(o[0])).length); - } else { - n( - !( - 1836278016 == - new Uint32Array( - new Uint8Array(e.subarray(0, 24)).buffer - )[0] - ), - "need to see wasm magic number" - ), - n(0 !== e[8], "need the dylink section to be first"), - (t = 9); - var l = _(); - (r = t + l), (a = s()); - } - var i = { - neededDynlibs: [], - tlsExports: new Set(), - weakImports: new Set(), - }; - if ("dylink" == a) { - (i.memorySize = _()), - (i.memoryAlign = _()), - (i.tableSize = _()), - (i.tableAlign = _()); - for (var u = _(), d = 0; d < u; ++d) { - var m = s(); - i.neededDynlibs.push(m); - } - } else { - n("dylink.0" !== a); - for (; t < r; ) { - var c = e[t++], - p = _(); - if (1 === c) - (i.memorySize = _()), - (i.memoryAlign = _()), - (i.tableSize = _()), - (i.tableAlign = _()); - else if (2 === c) - for (u = _(), d = 0; d < u; ++d) - (m = s()), i.neededDynlibs.push(m); - else if (3 === c) - for (var h = _(); h--; ) { - var f = s(); - 256 & _() && i.tlsExports.add(f); - } - else if (4 === c) - for (h = _(); h--; ) { - s(), (f = s()); - 1 == (3 & _()) && i.weakImports.add(f); - } - else t += p; - } - } - return i; - } - function getValue(e, t = "i8") { - switch ((t.endsWith("*") && (t = "*"), t)) { - case "i1": - case "i8": - return HEAP8[e | 0]; - case "i16": - return HEAP16[e >> 1]; - case "i32": - case "i64": - return HEAP32[e >> 2]; - case "float": - return HEAPF32[e >> 2]; - case "double": - return HEAPF64[e >> 3]; - case "*": - return HEAPU32[e >> 2]; - default: - abort("invalid type for getValue: " + t); - } - } - function newDSO(e, t, r) { - var _ = { refcount: 1 / 0, name: e, exports: r, global: !0 }; - return ( - (LDSO.loadedLibsByName[e] = _), - null != t && (LDSO.loadedLibsByHandle[t] = _), - _ - ); - } - var LDSO = { - loadedLibsByName: {}, - loadedLibsByHandle: {}, - init: () => newDSO("__main__", 0, wasmImports), - }, - ___heap_base = 78144; - function zeroMemory(e, t) { - return HEAPU8.fill(0, e, e + t), e; - } - function getMemory(e) { - if (runtimeInitialized) return zeroMemory(_malloc(e), e); - var t = ___heap_base, - r = (t + e + 15) & -16; - return (___heap_base = r), (GOT.__heap_base.value = r), t; - } - function isInternalSym(e) { - return [ - "__cpp_exception", - "__c_longjmp", - "__wasm_apply_data_relocs", - "__dso_handle", - "__tls_size", - "__tls_align", - "__set_stack_limits", - "_emscripten_tls_init", - "__wasm_init_tls", - "__wasm_call_ctors", - "__start_em_asm", - "__stop_em_asm", - ].includes(e); - } - function uleb128Encode(e, t) { - e < 128 ? t.push(e) : t.push(e % 128 | 128, e >> 7); - } - function sigToWasmTypes(e) { - for ( - var t = { i: "i32", j: "i32", f: "f32", d: "f64", p: "i32" }, - r = { - parameters: [], - results: "v" == e[0] ? [] : [t[e[0]]], - }, - _ = 1; - _ < e.length; - ++_ - ) - r.parameters.push(t[e[_]]), - "j" === e[_] && r.parameters.push("i32"); - return r; - } - function generateFuncType(e, t) { - var r = e.slice(0, 1), - _ = e.slice(1), - s = { i: 127, p: 127, j: 126, f: 125, d: 124 }; - t.push(96), uleb128Encode(_.length, t); - for (var n = 0; n < _.length; ++n) t.push(s[_[n]]); - "v" == r ? t.push(0) : t.push(1, s[r]); - } - function convertJsFunctionToWasm(e, t) { - if ("function" == typeof WebAssembly.Function) - return new WebAssembly.Function(sigToWasmTypes(t), e); - var r = [1]; - generateFuncType(t, r); - var _ = [0, 97, 115, 109, 1, 0, 0, 0, 1]; - uleb128Encode(r.length, _), - _.push.apply(_, r), - _.push(2, 7, 1, 1, 101, 1, 102, 0, 0, 7, 5, 1, 1, 102, 0, 0); - var s = new WebAssembly.Module(new Uint8Array(_)); - return new WebAssembly.Instance(s, { e: { f: e } }).exports.f; - } - var wasmTableMirror = []; - function getWasmTableEntry(e) { - var t = wasmTableMirror[e]; - return ( - t || - (e >= wasmTableMirror.length && - (wasmTableMirror.length = e + 1), - (wasmTableMirror[e] = t = wasmTable.get(e))), - t - ); - } - function updateTableMap(e, t) { - if (functionsInTableMap) - for (var r = e; r < e + t; r++) { - var _ = getWasmTableEntry(r); - _ && functionsInTableMap.set(_, r); - } - } - var functionsInTableMap = void 0; - function getFunctionAddress(e) { - return ( - functionsInTableMap || - ((functionsInTableMap = new WeakMap()), - updateTableMap(0, wasmTable.length)), - functionsInTableMap.get(e) || 0 - ); - } - var freeTableIndexes = []; - function getEmptyTableSlot() { - if (freeTableIndexes.length) return freeTableIndexes.pop(); - try { - wasmTable.grow(1); - } catch (e) { - if (!(e instanceof RangeError)) throw e; - throw "Unable to grow wasm table. Set ALLOW_TABLE_GROWTH."; - } - return wasmTable.length - 1; - } - function setWasmTableEntry(e, t) { - wasmTable.set(e, t), (wasmTableMirror[e] = wasmTable.get(e)); - } - function addFunction(e, t) { - var r = getFunctionAddress(e); - if (r) return r; - var _ = getEmptyTableSlot(); - try { - setWasmTableEntry(_, e); - } catch (r) { - if (!(r instanceof TypeError)) throw r; - setWasmTableEntry(_, convertJsFunctionToWasm(e, t)); - } - return functionsInTableMap.set(e, _), _; - } - function updateGOT(e, t) { - for (var r in e) - if (!isInternalSym(r)) { - var _ = e[r]; - r.startsWith("orig$") && ((r = r.split("$")[1]), (t = !0)), - GOT[r] || - (GOT[r] = new WebAssembly.Global({ - value: "i32", - mutable: !0, - })), - (t || 0 == GOT[r].value) && - ("function" == typeof _ - ? (GOT[r].value = addFunction(_)) - : "number" == typeof _ - ? (GOT[r].value = _) - : err( - "unhandled export type for `" + - r + - "`: " + - typeof _ - )); - } - } - function relocateExports(e, t, r) { - var _ = {}; - for (var s in e) { - var n = e[s]; - "object" == typeof n && (n = n.value), - "number" == typeof n && (n += t), - (_[s] = n); - } - return updateGOT(_, r), _; - } - function isSymbolDefined(e) { - var t = wasmImports[e]; - return !(!t || t.stub); - } - function resolveGlobalSymbol(e, t = !1) { - var r; - return ( - t && "orig$" + e in wasmImports && (e = "orig$" + e), - isSymbolDefined(e) - ? (r = wasmImports[e]) - : e.startsWith("invoke_") && - (r = wasmImports[e] = - createInvokeFunction(e.split("_")[1])), - { sym: r, name: e } - ); - } - function alignMemory(e, t) { - return Math.ceil(e / t) * t; - } - function dynCallLegacy(e, t, r) { - var _ = Module["dynCall_" + e]; - return r && r.length - ? _.apply(null, [t].concat(r)) - : _.call(null, t); - } - function dynCall(e, t, r) { - return e.includes("j") - ? dynCallLegacy(e, t, r) - : getWasmTableEntry(t).apply(null, r); - } - function createInvokeFunction(e) { - return function () { - var t = stackSave(); - try { - return dynCall( - e, - arguments[0], - Array.prototype.slice.call(arguments, 1) - ); - } catch (e) { - if ((stackRestore(t), e !== e + 0)) throw e; - _setThrew(1, 0); - } - }; - } - function UTF8ToString(e, t) { - return e ? UTF8ArrayToString(HEAPU8, e, t) : ""; - } - function loadWebAssemblyModule( - binary, - flags, - localScope, - handle - ) { - var metadata = getDylinkMetadata(binary); - function loadModule() { - var firstLoad = !handle || !HEAP8[(handle + 8) | 0]; - if (firstLoad) { - var memAlign = Math.pow(2, metadata.memoryAlign); - memAlign = Math.max(memAlign, 16); - var memoryBase = metadata.memorySize - ? alignMemory( - getMemory(metadata.memorySize + memAlign), - memAlign - ) - : 0, - tableBase = metadata.tableSize ? wasmTable.length : 0; - handle && - ((HEAP8[(handle + 8) | 0] = 1), - (HEAPU32[(handle + 12) >> 2] = memoryBase), - (HEAP32[(handle + 16) >> 2] = metadata.memorySize), - (HEAPU32[(handle + 20) >> 2] = tableBase), - (HEAP32[(handle + 24) >> 2] = metadata.tableSize)); - } else - (memoryBase = HEAPU32[(handle + 12) >> 2]), - (tableBase = HEAPU32[(handle + 20) >> 2]); - var tableGrowthNeeded = - tableBase + metadata.tableSize - wasmTable.length, - moduleExports; - function resolveSymbol(e) { - var t = resolveGlobalSymbol(e).sym; - return ( - !t && localScope && (t = localScope[e]), - t || (t = moduleExports[e]), - t - ); - } - tableGrowthNeeded > 0 && wasmTable.grow(tableGrowthNeeded); - var proxyHandler = { - get: function (e, t) { - switch (t) { - case "__memory_base": - return memoryBase; - case "__table_base": - return tableBase; - } - if (t in wasmImports && !wasmImports[t].stub) - return wasmImports[t]; - var r; - t in e || - (e[t] = function () { - return ( - r || (r = resolveSymbol(t)), - r.apply(null, arguments) - ); - }); - return e[t]; - }, - }, - proxy = new Proxy({}, proxyHandler), - info = { - "GOT.mem": new Proxy({}, GOTHandler), - "GOT.func": new Proxy({}, GOTHandler), - env: proxy, - wasi_snapshot_preview1: proxy, - }; - function postInstantiation(instance) { - function addEmAsm(addr, body) { - for ( - var args = [], arity = 0; - arity < 16 && -1 != body.indexOf("$" + arity); - arity++ - ) - args.push("$" + arity); - args = args.join(","); - var func = "(" + args + " ) => { " + body + "};"; - ASM_CONSTS[start] = eval(func); - } - if ( - (updateTableMap(tableBase, metadata.tableSize), - (moduleExports = relocateExports( - instance.exports, - memoryBase - )), - flags.allowUndefined || reportUndefinedSymbols(), - "__start_em_asm" in moduleExports) - ) - for ( - var start = moduleExports.__start_em_asm, - stop = moduleExports.__stop_em_asm; - start < stop; - - ) { - var jsString = UTF8ToString(start); - addEmAsm(start, jsString), - (start = HEAPU8.indexOf(0, start) + 1); - } - var applyRelocs = moduleExports.__wasm_apply_data_relocs; - applyRelocs && - (runtimeInitialized - ? applyRelocs() - : __RELOC_FUNCS__.push(applyRelocs)); - var init = moduleExports.__wasm_call_ctors; - return ( - init && - (runtimeInitialized ? init() : __ATINIT__.push(init)), - moduleExports - ); - } - if (flags.loadAsync) { - if (binary instanceof WebAssembly.Module) { - var instance = new WebAssembly.Instance(binary, info); - return Promise.resolve(postInstantiation(instance)); - } - return WebAssembly.instantiate(binary, info).then((e) => - postInstantiation(e.instance) - ); - } - var module = - binary instanceof WebAssembly.Module - ? binary - : new WebAssembly.Module(binary), - instance = new WebAssembly.Instance(module, info); - return postInstantiation(instance); - } - return ( - (currentModuleWeakSymbols = metadata.weakImports), - flags.loadAsync - ? metadata.neededDynlibs - .reduce( - (e, t) => e.then(() => loadDynamicLibrary(t, flags)), - Promise.resolve() - ) - .then(loadModule) - : (metadata.neededDynlibs.forEach((e) => - loadDynamicLibrary(e, flags, localScope) - ), - loadModule()) - ); - } - function mergeLibSymbols(e, t) { - for (var r in e) { - if (!e.hasOwnProperty(r)) continue; - const t = (t) => { - isSymbolDefined(t) || (wasmImports[t] = e[r]); - }; - t(r); - const _ = "__main_argc_argv"; - "main" == r && t(_), - r == _ && t("main"), - r.startsWith("dynCall_") && - !Module.hasOwnProperty(r) && - (Module[r] = e[r]); - } - } - function asyncLoad(e, t, r, _) { - var s = _ ? "" : getUniqueRunDependency("al " + e); - readAsync( - e, - (r) => { - assert( - r, - 'Loading data file "' + e + '" failed (no arrayBuffer).' - ), - t(new Uint8Array(r)), - s && removeRunDependency(s); - }, - (t) => { - if (!r) throw 'Loading data file "' + e + '" failed.'; - r(); - } - ), - s && addRunDependency(s); - } - function loadDynamicLibrary( - e, - t = { global: !0, nodelete: !0 }, - r, - _ - ) { - var s = LDSO.loadedLibsByName[e]; - if (s) - return ( - t.global && - !s.global && - ((s.global = !0), - "loading" !== s.exports && mergeLibSymbols(s.exports, e)), - t.nodelete && s.refcount !== 1 / 0 && (s.refcount = 1 / 0), - s.refcount++, - _ && (LDSO.loadedLibsByHandle[_] = s), - !t.loadAsync || Promise.resolve(!0) - ); - function n() { - if (t.fs && t.fs.findObject(e)) { - var r = t.fs.readFile(e, { encoding: "binary" }); - return ( - r instanceof Uint8Array || (r = new Uint8Array(r)), - t.loadAsync ? Promise.resolve(r) : r - ); - } - var _ = locateFile(e); - if (t.loadAsync) - return new Promise(function (e, t) { - asyncLoad(_, (t) => e(t), t); - }); - if (!readBinary) - throw new Error( - _ + - ": file not found, and synchronous loading of external files is not available" - ); - return readBinary(_); - } - function a() { - if ("undefined" != typeof preloadedWasm && preloadedWasm[e]) { - var s = preloadedWasm[e]; - return t.loadAsync ? Promise.resolve(s) : s; - } - return t.loadAsync - ? n().then((e) => loadWebAssemblyModule(e, t, r, _)) - : loadWebAssemblyModule(n(), t, r, _); - } - function o(t) { - s.global ? mergeLibSymbols(t, e) : r && Object.assign(r, t), - (s.exports = t); - } - return ( - ((s = newDSO(e, _, "loading")).refcount = t.nodelete - ? 1 / 0 - : 1), - (s.global = t.global), - t.loadAsync ? a().then((e) => (o(e), !0)) : (o(a()), !0) - ); - } - function reportUndefinedSymbols() { - for (var e in GOT) - if (0 == GOT[e].value) { - var t = resolveGlobalSymbol(e, !0).sym; - if (!t && !GOT[e].required) continue; - if ("function" == typeof t) - GOT[e].value = addFunction(t, t.sig); - else { - if ("number" != typeof t) - throw new Error( - "bad export type for `" + e + "`: " + typeof t - ); - GOT[e].value = t; - } - } - } - function loadDylibs() { - dynamicLibraries.length - ? (addRunDependency("loadDylibs"), - dynamicLibraries - .reduce( - (e, t) => - e.then(() => - loadDynamicLibrary(t, { - loadAsync: !0, - global: !0, - nodelete: !0, - allowUndefined: !0, - }) - ), - Promise.resolve() - ) - .then(() => { - reportUndefinedSymbols(), - removeRunDependency("loadDylibs"); - })) - : reportUndefinedSymbols(); - } - function setValue(e, t, r = "i8") { - switch ((r.endsWith("*") && (r = "*"), r)) { - case "i1": - case "i8": - HEAP8[e | 0] = t; - break; - case "i16": - HEAP16[e >> 1] = t; - break; - case "i32": - HEAP32[e >> 2] = t; - break; - case "i64": - (tempI64 = [ - t >>> 0, - ((tempDouble = t), - +Math.abs(tempDouble) >= 1 - ? tempDouble > 0 - ? +Math.floor(tempDouble / 4294967296) >>> 0 - : ~~+Math.ceil( - (tempDouble - +(~~tempDouble >>> 0)) / 4294967296 - ) >>> 0 - : 0), - ]), - (HEAP32[e >> 2] = tempI64[0]), - (HEAP32[(e + 4) >> 2] = tempI64[1]); - break; - case "float": - HEAPF32[e >> 2] = t; - break; - case "double": - HEAPF64[e >> 3] = t; - break; - case "*": - HEAPU32[e >> 2] = t; - break; - default: - abort("invalid type for setValue: " + r); - } - } - var ___memory_base = new WebAssembly.Global( - { value: "i32", mutable: !1 }, - 1024 - ), - ___stack_pointer = new WebAssembly.Global( - { value: "i32", mutable: !0 }, - 78144 - ), - ___table_base = new WebAssembly.Global( - { value: "i32", mutable: !1 }, - 1 - ), - nowIsMonotonic = !0, - _emscripten_get_now; - function __emscripten_get_now_is_monotonic() { - return nowIsMonotonic; - } - function _abort() { - abort(""); - } - function _emscripten_date_now() { - return Date.now(); - } - function _emscripten_memcpy_big(e, t, r) { - HEAPU8.copyWithin(e, t, t + r); - } - function getHeapMax() { - return 2147483648; - } - function emscripten_realloc_buffer(e) { - var t = wasmMemory.buffer; - try { - return ( - wasmMemory.grow((e - t.byteLength + 65535) >>> 16), - updateMemoryViews(), - 1 - ); - } catch (e) {} - } - function _emscripten_resize_heap(e) { - var t = HEAPU8.length; - e >>>= 0; - var r = getHeapMax(); - if (e > r) return !1; - for (var _ = 1; _ <= 4; _ *= 2) { - var s = t * (1 + 0.2 / _); - if ( - ((s = Math.min(s, e + 100663296)), - emscripten_realloc_buffer( - Math.min( - r, - (n = Math.max(e, s)) + (((a = 65536) - (n % a)) % a) - ) - )) - ) - return !0; - } - var n, a; - return !1; - } - (__emscripten_get_now_is_monotonic.sig = "i"), - (_abort.sig = "v"), - (_emscripten_date_now.sig = "d"), - (_emscripten_get_now = ENVIRONMENT_IS_NODE - ? () => { - var e = process.hrtime(); - return 1e3 * e[0] + e[1] / 1e6; - } - : () => performance.now()), - (_emscripten_get_now.sig = "d"), - (_emscripten_memcpy_big.sig = "vppp"), - (_emscripten_resize_heap.sig = "ip"); - var SYSCALLS = { - DEFAULT_POLLMASK: 5, - calculateAt: function (e, t, r) { - if (PATH.isAbs(t)) return t; - var _; - -100 === e - ? (_ = FS.cwd()) - : (_ = SYSCALLS.getStreamFromFD(e).path); - if (0 == t.length) { - if (!r) throw new FS.ErrnoError(44); - return _; - } - return PATH.join2(_, t); - }, - doStat: function (e, t, r) { - try { - var _ = e(t); - } catch (e) { - if ( - e && - e.node && - PATH.normalize(t) !== PATH.normalize(FS.getPath(e.node)) - ) - return -54; - throw e; - } - (HEAP32[r >> 2] = _.dev), - (HEAP32[(r + 8) >> 2] = _.ino), - (HEAP32[(r + 12) >> 2] = _.mode), - (HEAPU32[(r + 16) >> 2] = _.nlink), - (HEAP32[(r + 20) >> 2] = _.uid), - (HEAP32[(r + 24) >> 2] = _.gid), - (HEAP32[(r + 28) >> 2] = _.rdev), - (tempI64 = [ - _.size >>> 0, - ((tempDouble = _.size), - +Math.abs(tempDouble) >= 1 - ? tempDouble > 0 - ? +Math.floor(tempDouble / 4294967296) >>> 0 - : ~~+Math.ceil( - (tempDouble - +(~~tempDouble >>> 0)) / 4294967296 - ) >>> 0 - : 0), - ]), - (HEAP32[(r + 40) >> 2] = tempI64[0]), - (HEAP32[(r + 44) >> 2] = tempI64[1]), - (HEAP32[(r + 48) >> 2] = 4096), - (HEAP32[(r + 52) >> 2] = _.blocks); - var s = _.atime.getTime(), - n = _.mtime.getTime(), - a = _.ctime.getTime(); - return ( - (tempI64 = [ - Math.floor(s / 1e3) >>> 0, - ((tempDouble = Math.floor(s / 1e3)), - +Math.abs(tempDouble) >= 1 - ? tempDouble > 0 - ? +Math.floor(tempDouble / 4294967296) >>> 0 - : ~~+Math.ceil( - (tempDouble - +(~~tempDouble >>> 0)) / 4294967296 - ) >>> 0 - : 0), - ]), - (HEAP32[(r + 56) >> 2] = tempI64[0]), - (HEAP32[(r + 60) >> 2] = tempI64[1]), - (HEAPU32[(r + 64) >> 2] = (s % 1e3) * 1e3), - (tempI64 = [ - Math.floor(n / 1e3) >>> 0, - ((tempDouble = Math.floor(n / 1e3)), - +Math.abs(tempDouble) >= 1 - ? tempDouble > 0 - ? +Math.floor(tempDouble / 4294967296) >>> 0 - : ~~+Math.ceil( - (tempDouble - +(~~tempDouble >>> 0)) / 4294967296 - ) >>> 0 - : 0), - ]), - (HEAP32[(r + 72) >> 2] = tempI64[0]), - (HEAP32[(r + 76) >> 2] = tempI64[1]), - (HEAPU32[(r + 80) >> 2] = (n % 1e3) * 1e3), - (tempI64 = [ - Math.floor(a / 1e3) >>> 0, - ((tempDouble = Math.floor(a / 1e3)), - +Math.abs(tempDouble) >= 1 - ? tempDouble > 0 - ? +Math.floor(tempDouble / 4294967296) >>> 0 - : ~~+Math.ceil( - (tempDouble - +(~~tempDouble >>> 0)) / 4294967296 - ) >>> 0 - : 0), - ]), - (HEAP32[(r + 88) >> 2] = tempI64[0]), - (HEAP32[(r + 92) >> 2] = tempI64[1]), - (HEAPU32[(r + 96) >> 2] = (a % 1e3) * 1e3), - (tempI64 = [ - _.ino >>> 0, - ((tempDouble = _.ino), - +Math.abs(tempDouble) >= 1 - ? tempDouble > 0 - ? +Math.floor(tempDouble / 4294967296) >>> 0 - : ~~+Math.ceil( - (tempDouble - +(~~tempDouble >>> 0)) / 4294967296 - ) >>> 0 - : 0), - ]), - (HEAP32[(r + 104) >> 2] = tempI64[0]), - (HEAP32[(r + 108) >> 2] = tempI64[1]), - 0 - ); - }, - doMsync: function (e, t, r, _, s) { - if (!FS.isFile(t.node.mode)) throw new FS.ErrnoError(43); - if (2 & _) return 0; - var n = HEAPU8.slice(e, e + r); - FS.msync(t, n, s, r, _); - }, - varargs: void 0, - get: function () { - return ( - (SYSCALLS.varargs += 4), HEAP32[(SYSCALLS.varargs - 4) >> 2] - ); - }, - getStr: function (e) { - return UTF8ToString(e); - }, - getStreamFromFD: function (e) { - var t = FS.getStream(e); - if (!t) throw new FS.ErrnoError(8); - return t; - }, - }; - function _fd_close(e) { - try { - var t = SYSCALLS.getStreamFromFD(e); - return FS.close(t), 0; - } catch (e) { - if ("undefined" == typeof FS || "ErrnoError" !== e.name) - throw e; - return e.errno; - } - } - function convertI32PairToI53Checked(e, t) { - return (t + 2097152) >>> 0 < 4194305 - !!e - ? (e >>> 0) + 4294967296 * t - : NaN; - } - function _fd_seek(e, t, r, _, s) { - try { - var n = convertI32PairToI53Checked(t, r); - if (isNaN(n)) return 61; - var a = SYSCALLS.getStreamFromFD(e); - return ( - FS.llseek(a, n, _), - (tempI64 = [ - a.position >>> 0, - ((tempDouble = a.position), - +Math.abs(tempDouble) >= 1 - ? tempDouble > 0 - ? +Math.floor(tempDouble / 4294967296) >>> 0 - : ~~+Math.ceil( - (tempDouble - +(~~tempDouble >>> 0)) / 4294967296 - ) >>> 0 - : 0), - ]), - (HEAP32[s >> 2] = tempI64[0]), - (HEAP32[(s + 4) >> 2] = tempI64[1]), - a.getdents && 0 === n && 0 === _ && (a.getdents = null), - 0 - ); - } catch (e) { - if ("undefined" == typeof FS || "ErrnoError" !== e.name) - throw e; - return e.errno; - } - } - function doWritev(e, t, r, _) { - for (var s = 0, n = 0; n < r; n++) { - var a = HEAPU32[t >> 2], - o = HEAPU32[(t + 4) >> 2]; - t += 8; - var l = FS.write(e, HEAP8, a, o, _); - if (l < 0) return -1; - (s += l), void 0 !== _ && (_ += l); - } - return s; - } - function _fd_write(e, t, r, _) { - try { - var s = doWritev(SYSCALLS.getStreamFromFD(e), t, r); - return (HEAPU32[_ >> 2] = s), 0; - } catch (e) { - if ("undefined" == typeof FS || "ErrnoError" !== e.name) - throw e; - return e.errno; - } - } - function _tree_sitter_log_callback(e, t) { - if (currentLogCallback) { - const r = UTF8ToString(t); - currentLogCallback(r, 0 !== e); - } - } - function _tree_sitter_parse_callback(e, t, r, _, s) { - const n = currentParseCallback(t, { row: r, column: _ }); - "string" == typeof n - ? (setValue(s, n.length, "i32"), stringToUTF16(n, e, 10240)) - : setValue(s, 0, "i32"); - } - function _proc_exit(e) { - (EXITSTATUS = e), - keepRuntimeAlive() || - (Module.onExit && Module.onExit(e), (ABORT = !0)), - quit_(e, new ExitStatus(e)); - } - function exitJS(e, t) { - (EXITSTATUS = e), _proc_exit(e); - } - function handleException(e) { - if (e instanceof ExitStatus || "unwind" == e) return EXITSTATUS; - quit_(1, e); - } - function lengthBytesUTF8(e) { - for (var t = 0, r = 0; r < e.length; ++r) { - var _ = e.charCodeAt(r); - _ <= 127 - ? t++ - : _ <= 2047 - ? (t += 2) - : _ >= 55296 && _ <= 57343 - ? ((t += 4), ++r) - : (t += 3); - } - return t; - } - function stringToUTF8Array(e, t, r, _) { - if (!(_ > 0)) return 0; - for (var s = r, n = r + _ - 1, a = 0; a < e.length; ++a) { - var o = e.charCodeAt(a); - if (o >= 55296 && o <= 57343) - o = - (65536 + ((1023 & o) << 10)) | (1023 & e.charCodeAt(++a)); - if (o <= 127) { - if (r >= n) break; - t[r++] = o; - } else if (o <= 2047) { - if (r + 1 >= n) break; - (t[r++] = 192 | (o >> 6)), (t[r++] = 128 | (63 & o)); - } else if (o <= 65535) { - if (r + 2 >= n) break; - (t[r++] = 224 | (o >> 12)), - (t[r++] = 128 | ((o >> 6) & 63)), - (t[r++] = 128 | (63 & o)); - } else { - if (r + 3 >= n) break; - (t[r++] = 240 | (o >> 18)), - (t[r++] = 128 | ((o >> 12) & 63)), - (t[r++] = 128 | ((o >> 6) & 63)), - (t[r++] = 128 | (63 & o)); - } - } - return (t[r] = 0), r - s; - } - function stringToUTF8(e, t, r) { - return stringToUTF8Array(e, HEAPU8, t, r); - } - function stringToUTF8OnStack(e) { - var t = lengthBytesUTF8(e) + 1, - r = stackAlloc(t); - return stringToUTF8(e, r, t), r; - } - function stringToUTF16(e, t, r) { - if ((void 0 === r && (r = 2147483647), r < 2)) return 0; - for ( - var _ = t, - s = (r -= 2) < 2 * e.length ? r / 2 : e.length, - n = 0; - n < s; - ++n - ) { - var a = e.charCodeAt(n); - (HEAP16[t >> 1] = a), (t += 2); - } - return (HEAP16[t >> 1] = 0), t - _; - } - function AsciiToString(e) { - for (var t = ""; ; ) { - var r = HEAPU8[e++ | 0]; - if (!r) return t; - t += String.fromCharCode(r); - } - } - (_fd_close.sig = "ii"), - (_fd_seek.sig = "iijip"), - (_fd_write.sig = "iippp"), - (_proc_exit.sig = "vi"); - var wasmImports = { - __heap_base: ___heap_base, - __indirect_function_table: wasmTable, - __memory_base: ___memory_base, - __stack_pointer: ___stack_pointer, - __table_base: ___table_base, - _emscripten_get_now_is_monotonic: - __emscripten_get_now_is_monotonic, - abort: _abort, - emscripten_get_now: _emscripten_get_now, - emscripten_memcpy_big: _emscripten_memcpy_big, - emscripten_resize_heap: _emscripten_resize_heap, - fd_close: _fd_close, - fd_seek: _fd_seek, - fd_write: _fd_write, - memory: wasmMemory, - tree_sitter_log_callback: _tree_sitter_log_callback, - tree_sitter_parse_callback: _tree_sitter_parse_callback, - }, - asm = createWasm(), - ___wasm_call_ctors = function () { - return (___wasm_call_ctors = - Module.asm.__wasm_call_ctors).apply(null, arguments); - }, - ___wasm_apply_data_relocs = (Module.___wasm_apply_data_relocs = - function () { - return (___wasm_apply_data_relocs = - Module.___wasm_apply_data_relocs = - Module.asm.__wasm_apply_data_relocs).apply( - null, - arguments - ); - }), - _malloc = (Module._malloc = function () { - return (_malloc = Module._malloc = Module.asm.malloc).apply( - null, - arguments - ); - }), - _calloc = (Module._calloc = function () { - return (_calloc = Module._calloc = Module.asm.calloc).apply( - null, - arguments - ); - }), - _realloc = (Module._realloc = function () { - return (_realloc = Module._realloc = - Module.asm.realloc).apply(null, arguments); - }), - _free = (Module._free = function () { - return (_free = Module._free = Module.asm.free).apply( - null, - arguments - ); - }), - _ts_language_symbol_count = (Module._ts_language_symbol_count = - function () { - return (_ts_language_symbol_count = - Module._ts_language_symbol_count = - Module.asm.ts_language_symbol_count).apply( - null, - arguments - ); - }), - _ts_language_state_count = (Module._ts_language_state_count = - function () { - return (_ts_language_state_count = - Module._ts_language_state_count = - Module.asm.ts_language_state_count).apply( - null, - arguments - ); - }), - _ts_language_version = (Module._ts_language_version = - function () { - return (_ts_language_version = Module._ts_language_version = - Module.asm.ts_language_version).apply(null, arguments); - }), - _ts_language_field_count = (Module._ts_language_field_count = - function () { - return (_ts_language_field_count = - Module._ts_language_field_count = - Module.asm.ts_language_field_count).apply( - null, - arguments - ); - }), - _ts_language_next_state = (Module._ts_language_next_state = - function () { - return (_ts_language_next_state = - Module._ts_language_next_state = - Module.asm.ts_language_next_state).apply( - null, - arguments - ); - }), - _ts_language_symbol_name = (Module._ts_language_symbol_name = - function () { - return (_ts_language_symbol_name = - Module._ts_language_symbol_name = - Module.asm.ts_language_symbol_name).apply( - null, - arguments - ); - }), - _ts_language_symbol_for_name = - (Module._ts_language_symbol_for_name = function () { - return (_ts_language_symbol_for_name = - Module._ts_language_symbol_for_name = - Module.asm.ts_language_symbol_for_name).apply( - null, - arguments - ); - }), - _ts_language_symbol_type = (Module._ts_language_symbol_type = - function () { - return (_ts_language_symbol_type = - Module._ts_language_symbol_type = - Module.asm.ts_language_symbol_type).apply( - null, - arguments - ); - }), - _ts_language_field_name_for_id = - (Module._ts_language_field_name_for_id = function () { - return (_ts_language_field_name_for_id = - Module._ts_language_field_name_for_id = - Module.asm.ts_language_field_name_for_id).apply( - null, - arguments - ); - }), - _ts_lookahead_iterator_new = - (Module._ts_lookahead_iterator_new = function () { - return (_ts_lookahead_iterator_new = - Module._ts_lookahead_iterator_new = - Module.asm.ts_lookahead_iterator_new).apply( - null, - arguments - ); - }), - _ts_lookahead_iterator_delete = - (Module._ts_lookahead_iterator_delete = function () { - return (_ts_lookahead_iterator_delete = - Module._ts_lookahead_iterator_delete = - Module.asm.ts_lookahead_iterator_delete).apply( - null, - arguments - ); - }), - _ts_lookahead_iterator_reset_state = - (Module._ts_lookahead_iterator_reset_state = function () { - return (_ts_lookahead_iterator_reset_state = - Module._ts_lookahead_iterator_reset_state = - Module.asm.ts_lookahead_iterator_reset_state).apply( - null, - arguments - ); - }), - _ts_lookahead_iterator_reset = - (Module._ts_lookahead_iterator_reset = function () { - return (_ts_lookahead_iterator_reset = - Module._ts_lookahead_iterator_reset = - Module.asm.ts_lookahead_iterator_reset).apply( - null, - arguments - ); - }), - _ts_lookahead_iterator_next = - (Module._ts_lookahead_iterator_next = function () { - return (_ts_lookahead_iterator_next = - Module._ts_lookahead_iterator_next = - Module.asm.ts_lookahead_iterator_next).apply( - null, - arguments - ); - }), - _ts_lookahead_iterator_current_symbol = - (Module._ts_lookahead_iterator_current_symbol = function () { - return (_ts_lookahead_iterator_current_symbol = - Module._ts_lookahead_iterator_current_symbol = - Module.asm.ts_lookahead_iterator_current_symbol).apply( - null, - arguments - ); - }), - _memset = (Module._memset = function () { - return (_memset = Module._memset = Module.asm.memset).apply( - null, - arguments - ); - }), - _memcpy = (Module._memcpy = function () { - return (_memcpy = Module._memcpy = Module.asm.memcpy).apply( - null, - arguments - ); - }), - _ts_parser_delete = (Module._ts_parser_delete = function () { - return (_ts_parser_delete = Module._ts_parser_delete = - Module.asm.ts_parser_delete).apply(null, arguments); - }), - _ts_parser_reset = (Module._ts_parser_reset = function () { - return (_ts_parser_reset = Module._ts_parser_reset = - Module.asm.ts_parser_reset).apply(null, arguments); - }), - _ts_parser_set_language = (Module._ts_parser_set_language = - function () { - return (_ts_parser_set_language = - Module._ts_parser_set_language = - Module.asm.ts_parser_set_language).apply( - null, - arguments - ); - }), - _ts_parser_timeout_micros = (Module._ts_parser_timeout_micros = - function () { - return (_ts_parser_timeout_micros = - Module._ts_parser_timeout_micros = - Module.asm.ts_parser_timeout_micros).apply( - null, - arguments - ); - }), - _ts_parser_set_timeout_micros = - (Module._ts_parser_set_timeout_micros = function () { - return (_ts_parser_set_timeout_micros = - Module._ts_parser_set_timeout_micros = - Module.asm.ts_parser_set_timeout_micros).apply( - null, - arguments - ); - }), - _ts_parser_set_included_ranges = - (Module._ts_parser_set_included_ranges = function () { - return (_ts_parser_set_included_ranges = - Module._ts_parser_set_included_ranges = - Module.asm.ts_parser_set_included_ranges).apply( - null, - arguments - ); - }), - _memmove = (Module._memmove = function () { - return (_memmove = Module._memmove = - Module.asm.memmove).apply(null, arguments); - }), - _memcmp = (Module._memcmp = function () { - return (_memcmp = Module._memcmp = Module.asm.memcmp).apply( - null, - arguments - ); - }), - _ts_query_new = (Module._ts_query_new = function () { - return (_ts_query_new = Module._ts_query_new = - Module.asm.ts_query_new).apply(null, arguments); - }), - _ts_query_delete = (Module._ts_query_delete = function () { - return (_ts_query_delete = Module._ts_query_delete = - Module.asm.ts_query_delete).apply(null, arguments); - }), - _iswspace = (Module._iswspace = function () { - return (_iswspace = Module._iswspace = - Module.asm.iswspace).apply(null, arguments); - }), - _iswalnum = (Module._iswalnum = function () { - return (_iswalnum = Module._iswalnum = - Module.asm.iswalnum).apply(null, arguments); - }), - _ts_query_pattern_count = (Module._ts_query_pattern_count = - function () { - return (_ts_query_pattern_count = - Module._ts_query_pattern_count = - Module.asm.ts_query_pattern_count).apply( - null, - arguments - ); - }), - _ts_query_capture_count = (Module._ts_query_capture_count = - function () { - return (_ts_query_capture_count = - Module._ts_query_capture_count = - Module.asm.ts_query_capture_count).apply( - null, - arguments - ); - }), - _ts_query_string_count = (Module._ts_query_string_count = - function () { - return (_ts_query_string_count = - Module._ts_query_string_count = - Module.asm.ts_query_string_count).apply( - null, - arguments - ); - }), - _ts_query_capture_name_for_id = - (Module._ts_query_capture_name_for_id = function () { - return (_ts_query_capture_name_for_id = - Module._ts_query_capture_name_for_id = - Module.asm.ts_query_capture_name_for_id).apply( - null, - arguments - ); - }), - _ts_query_string_value_for_id = - (Module._ts_query_string_value_for_id = function () { - return (_ts_query_string_value_for_id = - Module._ts_query_string_value_for_id = - Module.asm.ts_query_string_value_for_id).apply( - null, - arguments - ); - }), - _ts_query_predicates_for_pattern = - (Module._ts_query_predicates_for_pattern = function () { - return (_ts_query_predicates_for_pattern = - Module._ts_query_predicates_for_pattern = - Module.asm.ts_query_predicates_for_pattern).apply( - null, - arguments - ); - }), - _ts_query_disable_capture = (Module._ts_query_disable_capture = - function () { - return (_ts_query_disable_capture = - Module._ts_query_disable_capture = - Module.asm.ts_query_disable_capture).apply( - null, - arguments - ); - }), - _ts_tree_copy = (Module._ts_tree_copy = function () { - return (_ts_tree_copy = Module._ts_tree_copy = - Module.asm.ts_tree_copy).apply(null, arguments); - }), - _ts_tree_delete = (Module._ts_tree_delete = function () { - return (_ts_tree_delete = Module._ts_tree_delete = - Module.asm.ts_tree_delete).apply(null, arguments); - }), - _ts_init = (Module._ts_init = function () { - return (_ts_init = Module._ts_init = - Module.asm.ts_init).apply(null, arguments); - }), - _ts_parser_new_wasm = (Module._ts_parser_new_wasm = - function () { - return (_ts_parser_new_wasm = Module._ts_parser_new_wasm = - Module.asm.ts_parser_new_wasm).apply(null, arguments); - }), - _ts_parser_enable_logger_wasm = - (Module._ts_parser_enable_logger_wasm = function () { - return (_ts_parser_enable_logger_wasm = - Module._ts_parser_enable_logger_wasm = - Module.asm.ts_parser_enable_logger_wasm).apply( - null, - arguments - ); - }), - _ts_parser_parse_wasm = (Module._ts_parser_parse_wasm = - function () { - return (_ts_parser_parse_wasm = - Module._ts_parser_parse_wasm = - Module.asm.ts_parser_parse_wasm).apply(null, arguments); - }), - _ts_parser_included_ranges_wasm = - (Module._ts_parser_included_ranges_wasm = function () { - return (_ts_parser_included_ranges_wasm = - Module._ts_parser_included_ranges_wasm = - Module.asm.ts_parser_included_ranges_wasm).apply( - null, - arguments - ); - }), - _ts_language_type_is_named_wasm = - (Module._ts_language_type_is_named_wasm = function () { - return (_ts_language_type_is_named_wasm = - Module._ts_language_type_is_named_wasm = - Module.asm.ts_language_type_is_named_wasm).apply( - null, - arguments - ); - }), - _ts_language_type_is_visible_wasm = - (Module._ts_language_type_is_visible_wasm = function () { - return (_ts_language_type_is_visible_wasm = - Module._ts_language_type_is_visible_wasm = - Module.asm.ts_language_type_is_visible_wasm).apply( - null, - arguments - ); - }), - _ts_tree_root_node_wasm = (Module._ts_tree_root_node_wasm = - function () { - return (_ts_tree_root_node_wasm = - Module._ts_tree_root_node_wasm = - Module.asm.ts_tree_root_node_wasm).apply( - null, - arguments - ); - }), - _ts_tree_root_node_with_offset_wasm = - (Module._ts_tree_root_node_with_offset_wasm = function () { - return (_ts_tree_root_node_with_offset_wasm = - Module._ts_tree_root_node_with_offset_wasm = - Module.asm.ts_tree_root_node_with_offset_wasm).apply( - null, - arguments - ); - }), - _ts_tree_edit_wasm = (Module._ts_tree_edit_wasm = function () { - return (_ts_tree_edit_wasm = Module._ts_tree_edit_wasm = - Module.asm.ts_tree_edit_wasm).apply(null, arguments); - }), - _ts_tree_included_ranges_wasm = - (Module._ts_tree_included_ranges_wasm = function () { - return (_ts_tree_included_ranges_wasm = - Module._ts_tree_included_ranges_wasm = - Module.asm.ts_tree_included_ranges_wasm).apply( - null, - arguments - ); - }), - _ts_tree_get_changed_ranges_wasm = - (Module._ts_tree_get_changed_ranges_wasm = function () { - return (_ts_tree_get_changed_ranges_wasm = - Module._ts_tree_get_changed_ranges_wasm = - Module.asm.ts_tree_get_changed_ranges_wasm).apply( - null, - arguments - ); - }), - _ts_tree_cursor_new_wasm = (Module._ts_tree_cursor_new_wasm = - function () { - return (_ts_tree_cursor_new_wasm = - Module._ts_tree_cursor_new_wasm = - Module.asm.ts_tree_cursor_new_wasm).apply( - null, - arguments - ); - }), - _ts_tree_cursor_delete_wasm = - (Module._ts_tree_cursor_delete_wasm = function () { - return (_ts_tree_cursor_delete_wasm = - Module._ts_tree_cursor_delete_wasm = - Module.asm.ts_tree_cursor_delete_wasm).apply( - null, - arguments - ); - }), - _ts_tree_cursor_reset_wasm = - (Module._ts_tree_cursor_reset_wasm = function () { - return (_ts_tree_cursor_reset_wasm = - Module._ts_tree_cursor_reset_wasm = - Module.asm.ts_tree_cursor_reset_wasm).apply( - null, - arguments - ); - }), - _ts_tree_cursor_reset_to_wasm = - (Module._ts_tree_cursor_reset_to_wasm = function () { - return (_ts_tree_cursor_reset_to_wasm = - Module._ts_tree_cursor_reset_to_wasm = - Module.asm.ts_tree_cursor_reset_to_wasm).apply( - null, - arguments - ); - }), - _ts_tree_cursor_goto_first_child_wasm = - (Module._ts_tree_cursor_goto_first_child_wasm = function () { - return (_ts_tree_cursor_goto_first_child_wasm = - Module._ts_tree_cursor_goto_first_child_wasm = - Module.asm.ts_tree_cursor_goto_first_child_wasm).apply( - null, - arguments - ); - }), - _ts_tree_cursor_goto_last_child_wasm = - (Module._ts_tree_cursor_goto_last_child_wasm = function () { - return (_ts_tree_cursor_goto_last_child_wasm = - Module._ts_tree_cursor_goto_last_child_wasm = - Module.asm.ts_tree_cursor_goto_last_child_wasm).apply( - null, - arguments - ); - }), - _ts_tree_cursor_goto_first_child_for_index_wasm = - (Module._ts_tree_cursor_goto_first_child_for_index_wasm = - function () { - return (_ts_tree_cursor_goto_first_child_for_index_wasm = - Module._ts_tree_cursor_goto_first_child_for_index_wasm = - Module.asm.ts_tree_cursor_goto_first_child_for_index_wasm).apply( - null, - arguments - ); - }), - _ts_tree_cursor_goto_first_child_for_position_wasm = - (Module._ts_tree_cursor_goto_first_child_for_position_wasm = - function () { - return (_ts_tree_cursor_goto_first_child_for_position_wasm = - Module._ts_tree_cursor_goto_first_child_for_position_wasm = - Module.asm.ts_tree_cursor_goto_first_child_for_position_wasm).apply( - null, - arguments - ); - }), - _ts_tree_cursor_goto_next_sibling_wasm = - (Module._ts_tree_cursor_goto_next_sibling_wasm = function () { - return (_ts_tree_cursor_goto_next_sibling_wasm = - Module._ts_tree_cursor_goto_next_sibling_wasm = - Module.asm.ts_tree_cursor_goto_next_sibling_wasm).apply( - null, - arguments - ); - }), - _ts_tree_cursor_goto_previous_sibling_wasm = - (Module._ts_tree_cursor_goto_previous_sibling_wasm = - function () { - return (_ts_tree_cursor_goto_previous_sibling_wasm = - Module._ts_tree_cursor_goto_previous_sibling_wasm = - Module.asm.ts_tree_cursor_goto_previous_sibling_wasm).apply( - null, - arguments - ); - }), - _ts_tree_cursor_goto_descendant_wasm = - (Module._ts_tree_cursor_goto_descendant_wasm = function () { - return (_ts_tree_cursor_goto_descendant_wasm = - Module._ts_tree_cursor_goto_descendant_wasm = - Module.asm.ts_tree_cursor_goto_descendant_wasm).apply( - null, - arguments - ); - }), - _ts_tree_cursor_goto_parent_wasm = - (Module._ts_tree_cursor_goto_parent_wasm = function () { - return (_ts_tree_cursor_goto_parent_wasm = - Module._ts_tree_cursor_goto_parent_wasm = - Module.asm.ts_tree_cursor_goto_parent_wasm).apply( - null, - arguments - ); - }), - _ts_tree_cursor_current_node_type_id_wasm = - (Module._ts_tree_cursor_current_node_type_id_wasm = - function () { - return (_ts_tree_cursor_current_node_type_id_wasm = - Module._ts_tree_cursor_current_node_type_id_wasm = - Module.asm.ts_tree_cursor_current_node_type_id_wasm).apply( - null, - arguments - ); - }), - _ts_tree_cursor_current_node_state_id_wasm = - (Module._ts_tree_cursor_current_node_state_id_wasm = - function () { - return (_ts_tree_cursor_current_node_state_id_wasm = - Module._ts_tree_cursor_current_node_state_id_wasm = - Module.asm.ts_tree_cursor_current_node_state_id_wasm).apply( - null, - arguments - ); - }), - _ts_tree_cursor_current_node_is_named_wasm = - (Module._ts_tree_cursor_current_node_is_named_wasm = - function () { - return (_ts_tree_cursor_current_node_is_named_wasm = - Module._ts_tree_cursor_current_node_is_named_wasm = - Module.asm.ts_tree_cursor_current_node_is_named_wasm).apply( - null, - arguments - ); - }), - _ts_tree_cursor_current_node_is_missing_wasm = - (Module._ts_tree_cursor_current_node_is_missing_wasm = - function () { - return (_ts_tree_cursor_current_node_is_missing_wasm = - Module._ts_tree_cursor_current_node_is_missing_wasm = - Module.asm.ts_tree_cursor_current_node_is_missing_wasm).apply( - null, - arguments - ); - }), - _ts_tree_cursor_current_node_id_wasm = - (Module._ts_tree_cursor_current_node_id_wasm = function () { - return (_ts_tree_cursor_current_node_id_wasm = - Module._ts_tree_cursor_current_node_id_wasm = - Module.asm.ts_tree_cursor_current_node_id_wasm).apply( - null, - arguments - ); - }), - _ts_tree_cursor_start_position_wasm = - (Module._ts_tree_cursor_start_position_wasm = function () { - return (_ts_tree_cursor_start_position_wasm = - Module._ts_tree_cursor_start_position_wasm = - Module.asm.ts_tree_cursor_start_position_wasm).apply( - null, - arguments - ); - }), - _ts_tree_cursor_end_position_wasm = - (Module._ts_tree_cursor_end_position_wasm = function () { - return (_ts_tree_cursor_end_position_wasm = - Module._ts_tree_cursor_end_position_wasm = - Module.asm.ts_tree_cursor_end_position_wasm).apply( - null, - arguments - ); - }), - _ts_tree_cursor_start_index_wasm = - (Module._ts_tree_cursor_start_index_wasm = function () { - return (_ts_tree_cursor_start_index_wasm = - Module._ts_tree_cursor_start_index_wasm = - Module.asm.ts_tree_cursor_start_index_wasm).apply( - null, - arguments - ); - }), - _ts_tree_cursor_end_index_wasm = - (Module._ts_tree_cursor_end_index_wasm = function () { - return (_ts_tree_cursor_end_index_wasm = - Module._ts_tree_cursor_end_index_wasm = - Module.asm.ts_tree_cursor_end_index_wasm).apply( - null, - arguments - ); - }), - _ts_tree_cursor_current_field_id_wasm = - (Module._ts_tree_cursor_current_field_id_wasm = function () { - return (_ts_tree_cursor_current_field_id_wasm = - Module._ts_tree_cursor_current_field_id_wasm = - Module.asm.ts_tree_cursor_current_field_id_wasm).apply( - null, - arguments - ); - }), - _ts_tree_cursor_current_depth_wasm = - (Module._ts_tree_cursor_current_depth_wasm = function () { - return (_ts_tree_cursor_current_depth_wasm = - Module._ts_tree_cursor_current_depth_wasm = - Module.asm.ts_tree_cursor_current_depth_wasm).apply( - null, - arguments - ); - }), - _ts_tree_cursor_current_descendant_index_wasm = - (Module._ts_tree_cursor_current_descendant_index_wasm = - function () { - return (_ts_tree_cursor_current_descendant_index_wasm = - Module._ts_tree_cursor_current_descendant_index_wasm = - Module.asm.ts_tree_cursor_current_descendant_index_wasm).apply( - null, - arguments - ); - }), - _ts_tree_cursor_current_node_wasm = - (Module._ts_tree_cursor_current_node_wasm = function () { - return (_ts_tree_cursor_current_node_wasm = - Module._ts_tree_cursor_current_node_wasm = - Module.asm.ts_tree_cursor_current_node_wasm).apply( - null, - arguments - ); - }), - _ts_node_symbol_wasm = (Module._ts_node_symbol_wasm = - function () { - return (_ts_node_symbol_wasm = Module._ts_node_symbol_wasm = - Module.asm.ts_node_symbol_wasm).apply(null, arguments); - }), - _ts_node_field_name_for_child_wasm = - (Module._ts_node_field_name_for_child_wasm = function () { - return (_ts_node_field_name_for_child_wasm = - Module._ts_node_field_name_for_child_wasm = - Module.asm.ts_node_field_name_for_child_wasm).apply( - null, - arguments - ); - }), - _ts_node_children_by_field_id_wasm = - (Module._ts_node_children_by_field_id_wasm = function () { - return (_ts_node_children_by_field_id_wasm = - Module._ts_node_children_by_field_id_wasm = - Module.asm.ts_node_children_by_field_id_wasm).apply( - null, - arguments - ); - }), - _ts_node_first_child_for_byte_wasm = - (Module._ts_node_first_child_for_byte_wasm = function () { - return (_ts_node_first_child_for_byte_wasm = - Module._ts_node_first_child_for_byte_wasm = - Module.asm.ts_node_first_child_for_byte_wasm).apply( - null, - arguments - ); - }), - _ts_node_first_named_child_for_byte_wasm = - (Module._ts_node_first_named_child_for_byte_wasm = - function () { - return (_ts_node_first_named_child_for_byte_wasm = - Module._ts_node_first_named_child_for_byte_wasm = - Module.asm.ts_node_first_named_child_for_byte_wasm).apply( - null, - arguments - ); - }), - _ts_node_grammar_symbol_wasm = - (Module._ts_node_grammar_symbol_wasm = function () { - return (_ts_node_grammar_symbol_wasm = - Module._ts_node_grammar_symbol_wasm = - Module.asm.ts_node_grammar_symbol_wasm).apply( - null, - arguments - ); - }), - _ts_node_child_count_wasm = (Module._ts_node_child_count_wasm = - function () { - return (_ts_node_child_count_wasm = - Module._ts_node_child_count_wasm = - Module.asm.ts_node_child_count_wasm).apply( - null, - arguments - ); - }), - _ts_node_named_child_count_wasm = - (Module._ts_node_named_child_count_wasm = function () { - return (_ts_node_named_child_count_wasm = - Module._ts_node_named_child_count_wasm = - Module.asm.ts_node_named_child_count_wasm).apply( - null, - arguments - ); - }), - _ts_node_child_wasm = (Module._ts_node_child_wasm = - function () { - return (_ts_node_child_wasm = Module._ts_node_child_wasm = - Module.asm.ts_node_child_wasm).apply(null, arguments); - }), - _ts_node_named_child_wasm = (Module._ts_node_named_child_wasm = - function () { - return (_ts_node_named_child_wasm = - Module._ts_node_named_child_wasm = - Module.asm.ts_node_named_child_wasm).apply( - null, - arguments - ); - }), - _ts_node_child_by_field_id_wasm = - (Module._ts_node_child_by_field_id_wasm = function () { - return (_ts_node_child_by_field_id_wasm = - Module._ts_node_child_by_field_id_wasm = - Module.asm.ts_node_child_by_field_id_wasm).apply( - null, - arguments - ); - }), - _ts_node_next_sibling_wasm = - (Module._ts_node_next_sibling_wasm = function () { - return (_ts_node_next_sibling_wasm = - Module._ts_node_next_sibling_wasm = - Module.asm.ts_node_next_sibling_wasm).apply( - null, - arguments - ); - }), - _ts_node_prev_sibling_wasm = - (Module._ts_node_prev_sibling_wasm = function () { - return (_ts_node_prev_sibling_wasm = - Module._ts_node_prev_sibling_wasm = - Module.asm.ts_node_prev_sibling_wasm).apply( - null, - arguments - ); - }), - _ts_node_next_named_sibling_wasm = - (Module._ts_node_next_named_sibling_wasm = function () { - return (_ts_node_next_named_sibling_wasm = - Module._ts_node_next_named_sibling_wasm = - Module.asm.ts_node_next_named_sibling_wasm).apply( - null, - arguments - ); - }), - _ts_node_prev_named_sibling_wasm = - (Module._ts_node_prev_named_sibling_wasm = function () { - return (_ts_node_prev_named_sibling_wasm = - Module._ts_node_prev_named_sibling_wasm = - Module.asm.ts_node_prev_named_sibling_wasm).apply( - null, - arguments - ); - }), - _ts_node_descendant_count_wasm = - (Module._ts_node_descendant_count_wasm = function () { - return (_ts_node_descendant_count_wasm = - Module._ts_node_descendant_count_wasm = - Module.asm.ts_node_descendant_count_wasm).apply( - null, - arguments - ); - }), - _ts_node_parent_wasm = (Module._ts_node_parent_wasm = - function () { - return (_ts_node_parent_wasm = Module._ts_node_parent_wasm = - Module.asm.ts_node_parent_wasm).apply(null, arguments); - }), - _ts_node_descendant_for_index_wasm = - (Module._ts_node_descendant_for_index_wasm = function () { - return (_ts_node_descendant_for_index_wasm = - Module._ts_node_descendant_for_index_wasm = - Module.asm.ts_node_descendant_for_index_wasm).apply( - null, - arguments - ); - }), - _ts_node_named_descendant_for_index_wasm = - (Module._ts_node_named_descendant_for_index_wasm = - function () { - return (_ts_node_named_descendant_for_index_wasm = - Module._ts_node_named_descendant_for_index_wasm = - Module.asm.ts_node_named_descendant_for_index_wasm).apply( - null, - arguments - ); - }), - _ts_node_descendant_for_position_wasm = - (Module._ts_node_descendant_for_position_wasm = function () { - return (_ts_node_descendant_for_position_wasm = - Module._ts_node_descendant_for_position_wasm = - Module.asm.ts_node_descendant_for_position_wasm).apply( - null, - arguments - ); - }), - _ts_node_named_descendant_for_position_wasm = - (Module._ts_node_named_descendant_for_position_wasm = - function () { - return (_ts_node_named_descendant_for_position_wasm = - Module._ts_node_named_descendant_for_position_wasm = - Module.asm.ts_node_named_descendant_for_position_wasm).apply( - null, - arguments - ); - }), - _ts_node_start_point_wasm = (Module._ts_node_start_point_wasm = - function () { - return (_ts_node_start_point_wasm = - Module._ts_node_start_point_wasm = - Module.asm.ts_node_start_point_wasm).apply( - null, - arguments - ); - }), - _ts_node_end_point_wasm = (Module._ts_node_end_point_wasm = - function () { - return (_ts_node_end_point_wasm = - Module._ts_node_end_point_wasm = - Module.asm.ts_node_end_point_wasm).apply( - null, - arguments - ); - }), - _ts_node_start_index_wasm = (Module._ts_node_start_index_wasm = - function () { - return (_ts_node_start_index_wasm = - Module._ts_node_start_index_wasm = - Module.asm.ts_node_start_index_wasm).apply( - null, - arguments - ); - }), - _ts_node_end_index_wasm = (Module._ts_node_end_index_wasm = - function () { - return (_ts_node_end_index_wasm = - Module._ts_node_end_index_wasm = - Module.asm.ts_node_end_index_wasm).apply( - null, - arguments - ); - }), - _ts_node_to_string_wasm = (Module._ts_node_to_string_wasm = - function () { - return (_ts_node_to_string_wasm = - Module._ts_node_to_string_wasm = - Module.asm.ts_node_to_string_wasm).apply( - null, - arguments - ); - }), - _ts_node_children_wasm = (Module._ts_node_children_wasm = - function () { - return (_ts_node_children_wasm = - Module._ts_node_children_wasm = - Module.asm.ts_node_children_wasm).apply( - null, - arguments - ); - }), - _ts_node_named_children_wasm = - (Module._ts_node_named_children_wasm = function () { - return (_ts_node_named_children_wasm = - Module._ts_node_named_children_wasm = - Module.asm.ts_node_named_children_wasm).apply( - null, - arguments - ); - }), - _ts_node_descendants_of_type_wasm = - (Module._ts_node_descendants_of_type_wasm = function () { - return (_ts_node_descendants_of_type_wasm = - Module._ts_node_descendants_of_type_wasm = - Module.asm.ts_node_descendants_of_type_wasm).apply( - null, - arguments - ); - }), - _ts_node_is_named_wasm = (Module._ts_node_is_named_wasm = - function () { - return (_ts_node_is_named_wasm = - Module._ts_node_is_named_wasm = - Module.asm.ts_node_is_named_wasm).apply( - null, - arguments - ); - }), - _ts_node_has_changes_wasm = (Module._ts_node_has_changes_wasm = - function () { - return (_ts_node_has_changes_wasm = - Module._ts_node_has_changes_wasm = - Module.asm.ts_node_has_changes_wasm).apply( - null, - arguments - ); - }), - _ts_node_has_error_wasm = (Module._ts_node_has_error_wasm = - function () { - return (_ts_node_has_error_wasm = - Module._ts_node_has_error_wasm = - Module.asm.ts_node_has_error_wasm).apply( - null, - arguments - ); - }), - _ts_node_is_error_wasm = (Module._ts_node_is_error_wasm = - function () { - return (_ts_node_is_error_wasm = - Module._ts_node_is_error_wasm = - Module.asm.ts_node_is_error_wasm).apply( - null, - arguments - ); - }), - _ts_node_is_missing_wasm = (Module._ts_node_is_missing_wasm = - function () { - return (_ts_node_is_missing_wasm = - Module._ts_node_is_missing_wasm = - Module.asm.ts_node_is_missing_wasm).apply( - null, - arguments - ); - }), - _ts_node_is_extra_wasm = (Module._ts_node_is_extra_wasm = - function () { - return (_ts_node_is_extra_wasm = - Module._ts_node_is_extra_wasm = - Module.asm.ts_node_is_extra_wasm).apply( - null, - arguments - ); - }), - _ts_node_parse_state_wasm = (Module._ts_node_parse_state_wasm = - function () { - return (_ts_node_parse_state_wasm = - Module._ts_node_parse_state_wasm = - Module.asm.ts_node_parse_state_wasm).apply( - null, - arguments - ); - }), - _ts_node_next_parse_state_wasm = - (Module._ts_node_next_parse_state_wasm = function () { - return (_ts_node_next_parse_state_wasm = - Module._ts_node_next_parse_state_wasm = - Module.asm.ts_node_next_parse_state_wasm).apply( - null, - arguments - ); - }), - _ts_query_matches_wasm = (Module._ts_query_matches_wasm = - function () { - return (_ts_query_matches_wasm = - Module._ts_query_matches_wasm = - Module.asm.ts_query_matches_wasm).apply( - null, - arguments - ); - }), - _ts_query_captures_wasm = (Module._ts_query_captures_wasm = - function () { - return (_ts_query_captures_wasm = - Module._ts_query_captures_wasm = - Module.asm.ts_query_captures_wasm).apply( - null, - arguments - ); - }), - ___errno_location = function () { - return (___errno_location = - Module.asm.__errno_location).apply(null, arguments); - }, - _iswdigit = (Module._iswdigit = function () { - return (_iswdigit = Module._iswdigit = - Module.asm.iswdigit).apply(null, arguments); - }), - _iswalpha = (Module._iswalpha = function () { - return (_iswalpha = Module._iswalpha = - Module.asm.iswalpha).apply(null, arguments); - }), - _iswblank = (Module._iswblank = function () { - return (_iswblank = Module._iswblank = - Module.asm.iswblank).apply(null, arguments); - }), - _iswlower = (Module._iswlower = function () { - return (_iswlower = Module._iswlower = - Module.asm.iswlower).apply(null, arguments); - }), - _iswupper = (Module._iswupper = function () { - return (_iswupper = Module._iswupper = - Module.asm.iswupper).apply(null, arguments); - }), - _iswxdigit = (Module._iswxdigit = function () { - return (_iswxdigit = Module._iswxdigit = - Module.asm.iswxdigit).apply(null, arguments); - }), - _memchr = (Module._memchr = function () { - return (_memchr = Module._memchr = Module.asm.memchr).apply( - null, - arguments - ); - }), - _strlen = (Module._strlen = function () { - return (_strlen = Module._strlen = Module.asm.strlen).apply( - null, - arguments - ); - }), - _strcmp = (Module._strcmp = function () { - return (_strcmp = Module._strcmp = Module.asm.strcmp).apply( - null, - arguments - ); - }), - _strncpy = (Module._strncpy = function () { - return (_strncpy = Module._strncpy = - Module.asm.strncpy).apply(null, arguments); - }), - _towlower = (Module._towlower = function () { - return (_towlower = Module._towlower = - Module.asm.towlower).apply(null, arguments); - }), - _towupper = (Module._towupper = function () { - return (_towupper = Module._towupper = - Module.asm.towupper).apply(null, arguments); - }), - _setThrew = function () { - return (_setThrew = Module.asm.setThrew).apply( - null, - arguments - ); - }, - stackSave = function () { - return (stackSave = Module.asm.stackSave).apply( - null, - arguments - ); - }, - stackRestore = function () { - return (stackRestore = Module.asm.stackRestore).apply( - null, - arguments - ); - }, - stackAlloc = function () { - return (stackAlloc = Module.asm.stackAlloc).apply( - null, - arguments - ); - }, - dynCall_jiji = (Module.dynCall_jiji = function () { - return (dynCall_jiji = Module.dynCall_jiji = - Module.asm.dynCall_jiji).apply(null, arguments); - }), - _orig$ts_parser_timeout_micros = - (Module._orig$ts_parser_timeout_micros = function () { - return (_orig$ts_parser_timeout_micros = - Module._orig$ts_parser_timeout_micros = - Module.asm.orig$ts_parser_timeout_micros).apply( - null, - arguments - ); - }), - _orig$ts_parser_set_timeout_micros = - (Module._orig$ts_parser_set_timeout_micros = function () { - return (_orig$ts_parser_set_timeout_micros = - Module._orig$ts_parser_set_timeout_micros = - Module.asm.orig$ts_parser_set_timeout_micros).apply( - null, - arguments - ); - }), - calledRun; - function callMain(e = []) { - var t = resolveGlobalSymbol("main").sym; - if (t) { - e.unshift(thisProgram); - var r = e.length, - _ = stackAlloc(4 * (r + 1)), - s = _ >> 2; - e.forEach((e) => { - HEAP32[s++] = stringToUTF8OnStack(e); - }), - (HEAP32[s] = 0); - try { - var n = t(r, _); - return exitJS(n, !0), n; - } catch (e) { - return handleException(e); - } - } - } - (Module.AsciiToString = AsciiToString), - (Module.stringToUTF16 = stringToUTF16), - (dependenciesFulfilled = function e() { - calledRun || run(), calledRun || (dependenciesFulfilled = e); - }); - var dylibsLoaded = !1; - function run(e = arguments_) { - function t() { - calledRun || - ((calledRun = !0), - (Module.calledRun = !0), - ABORT || - (initRuntime(), - preMain(), - Module.onRuntimeInitialized && - Module.onRuntimeInitialized(), - shouldRunNow && callMain(e), - postRun())); - } - runDependencies > 0 || - (!dylibsLoaded && - (loadDylibs(), (dylibsLoaded = !0), runDependencies > 0)) || - (preRun(), - runDependencies > 0 || - (Module.setStatus - ? (Module.setStatus("Running..."), - setTimeout(function () { - setTimeout(function () { - Module.setStatus(""); - }, 1), - t(); - }, 1)) - : t())); - } - if ((LDSO.init(), Module.preInit)) - for ( - "function" == typeof Module.preInit && - (Module.preInit = [Module.preInit]); - Module.preInit.length > 0; - - ) - Module.preInit.pop()(); - var shouldRunNow = !0; - Module.noInitialRun && (shouldRunNow = !1), run(); - const C = Module, - INTERNAL = {}, - SIZE_OF_INT = 4, - SIZE_OF_CURSOR = 3 * SIZE_OF_INT, - SIZE_OF_NODE = 5 * SIZE_OF_INT, - SIZE_OF_POINT = 2 * SIZE_OF_INT, - SIZE_OF_RANGE = 2 * SIZE_OF_INT + 2 * SIZE_OF_POINT, - ZERO_POINT = { row: 0, column: 0 }, - QUERY_WORD_REGEX = /[\w-.]*/g, - PREDICATE_STEP_TYPE_CAPTURE = 1, - PREDICATE_STEP_TYPE_STRING = 2, - LANGUAGE_FUNCTION_REGEX = /^_?tree_sitter_\w+/; - let VERSION, - MIN_COMPATIBLE_VERSION, - TRANSFER_BUFFER, - currentParseCallback, - currentLogCallback; - class ParserImpl { - static init() { - (TRANSFER_BUFFER = C._ts_init()), - (VERSION = getValue(TRANSFER_BUFFER, "i32")), - (MIN_COMPATIBLE_VERSION = getValue( - TRANSFER_BUFFER + SIZE_OF_INT, - "i32" - )); - } - initialize() { - C._ts_parser_new_wasm(), - (this[0] = getValue(TRANSFER_BUFFER, "i32")), - (this[1] = getValue(TRANSFER_BUFFER + SIZE_OF_INT, "i32")); - } - delete() { - C._ts_parser_delete(this[0]), - C._free(this[1]), - (this[0] = 0), - (this[1] = 0); - } - setLanguage(e) { - let t; - if (e) { - if (e.constructor !== Language) - throw new Error("Argument must be a Language"); - { - t = e[0]; - const r = C._ts_language_version(t); - if (r < MIN_COMPATIBLE_VERSION || VERSION < r) - throw new Error( - `Incompatible language version ${r}. Compatibility range ${MIN_COMPATIBLE_VERSION} through ${VERSION}.` - ); - } - } else (t = 0), (e = null); - return ( - (this.language = e), - C._ts_parser_set_language(this[0], t), - this - ); - } - getLanguage() { - return this.language; - } - parse(e, t, r) { - if ("string" == typeof e) - currentParseCallback = (t, r) => e.slice(t); - else { - if ("function" != typeof e) - throw new Error( - "Argument must be a string or a function" - ); - currentParseCallback = e; - } - this.logCallback - ? ((currentLogCallback = this.logCallback), - C._ts_parser_enable_logger_wasm(this[0], 1)) - : ((currentLogCallback = null), - C._ts_parser_enable_logger_wasm(this[0], 0)); - let _ = 0, - s = 0; - if (r && r.includedRanges) { - (_ = r.includedRanges.length), - (s = C._calloc(_, SIZE_OF_RANGE)); - let e = s; - for (let t = 0; t < _; t++) - marshalRange(e, r.includedRanges[t]), - (e += SIZE_OF_RANGE); - } - const n = C._ts_parser_parse_wasm( - this[0], - this[1], - t ? t[0] : 0, - s, - _ - ); - if (!n) - throw ( - ((currentParseCallback = null), - (currentLogCallback = null), - new Error("Parsing failed")) - ); - const a = new Tree( - INTERNAL, - n, - this.language, - currentParseCallback - ); - return ( - (currentParseCallback = null), - (currentLogCallback = null), - a - ); - } - reset() { - C._ts_parser_reset(this[0]); - } - getIncludedRanges() { - C._ts_parser_included_ranges_wasm(this[0]); - const e = getValue(TRANSFER_BUFFER, "i32"), - t = getValue(TRANSFER_BUFFER + SIZE_OF_INT, "i32"), - r = new Array(e); - if (e > 0) { - let _ = t; - for (let t = 0; t < e; t++) - (r[t] = unmarshalRange(_)), (_ += SIZE_OF_RANGE); - C._free(t); - } - return r; - } - getTimeoutMicros() { - return C._ts_parser_timeout_micros(this[0]); - } - setTimeoutMicros(e) { - C._ts_parser_set_timeout_micros(this[0], e); - } - setLogger(e) { - if (e) { - if ("function" != typeof e) - throw new Error("Logger callback must be a function"); - } else e = null; - return (this.logCallback = e), this; - } - getLogger() { - return this.logCallback; - } - } - class Tree { - constructor(e, t, r, _) { - assertInternal(e), - (this[0] = t), - (this.language = r), - (this.textCallback = _); - } - copy() { - const e = C._ts_tree_copy(this[0]); - return new Tree( - INTERNAL, - e, - this.language, - this.textCallback - ); - } - delete() { - C._ts_tree_delete(this[0]), (this[0] = 0); - } - edit(e) { - marshalEdit(e), C._ts_tree_edit_wasm(this[0]); - } - get rootNode() { - return ( - C._ts_tree_root_node_wasm(this[0]), unmarshalNode(this) - ); - } - rootNodeWithOffset(e, t) { - const r = TRANSFER_BUFFER + SIZE_OF_NODE; - return ( - setValue(r, e, "i32"), - marshalPoint(r + SIZE_OF_INT, t), - C._ts_tree_root_node_with_offset_wasm(this[0]), - unmarshalNode(this) - ); - } - getLanguage() { - return this.language; - } - walk() { - return this.rootNode.walk(); - } - getChangedRanges(e) { - if (e.constructor !== Tree) - throw new TypeError("Argument must be a Tree"); - C._ts_tree_get_changed_ranges_wasm(this[0], e[0]); - const t = getValue(TRANSFER_BUFFER, "i32"), - r = getValue(TRANSFER_BUFFER + SIZE_OF_INT, "i32"), - _ = new Array(t); - if (t > 0) { - let e = r; - for (let r = 0; r < t; r++) - (_[r] = unmarshalRange(e)), (e += SIZE_OF_RANGE); - C._free(r); - } - return _; - } - getIncludedRanges() { - C._ts_tree_included_ranges_wasm(this[0]); - const e = getValue(TRANSFER_BUFFER, "i32"), - t = getValue(TRANSFER_BUFFER + SIZE_OF_INT, "i32"), - r = new Array(e); - if (e > 0) { - let _ = t; - for (let t = 0; t < e; t++) - (r[t] = unmarshalRange(_)), (_ += SIZE_OF_RANGE); - C._free(t); - } - return r; - } - } - class Node { - constructor(e, t) { - assertInternal(e), (this.tree = t); - } - get typeId() { - return ( - marshalNode(this), C._ts_node_symbol_wasm(this.tree[0]) - ); - } - get grammarId() { - return ( - marshalNode(this), - C._ts_node_grammar_symbol_wasm(this.tree[0]) - ); - } - get type() { - return this.tree.language.types[this.typeId] || "ERROR"; - } - get grammarType() { - return this.tree.language.types[this.grammarId] || "ERROR"; - } - get endPosition() { - return ( - marshalNode(this), - C._ts_node_end_point_wasm(this.tree[0]), - unmarshalPoint(TRANSFER_BUFFER) - ); - } - get endIndex() { - return ( - marshalNode(this), C._ts_node_end_index_wasm(this.tree[0]) - ); - } - get text() { - return getText(this.tree, this.startIndex, this.endIndex); - } - get parseState() { - return ( - marshalNode(this), C._ts_node_parse_state_wasm(this.tree[0]) - ); - } - get nextParseState() { - return ( - marshalNode(this), - C._ts_node_next_parse_state_wasm(this.tree[0]) - ); - } - get isNamed() { - return ( - marshalNode(this), - 1 === C._ts_node_is_named_wasm(this.tree[0]) - ); - } - get hasError() { - return ( - marshalNode(this), - 1 === C._ts_node_has_error_wasm(this.tree[0]) - ); - } - get hasChanges() { - return ( - marshalNode(this), - 1 === C._ts_node_has_changes_wasm(this.tree[0]) - ); - } - get isError() { - return ( - marshalNode(this), - 1 === C._ts_node_is_error_wasm(this.tree[0]) - ); - } - get isMissing() { - return ( - marshalNode(this), - 1 === C._ts_node_is_missing_wasm(this.tree[0]) - ); - } - get isExtra() { - return ( - marshalNode(this), - 1 === C._ts_node_is_extra_wasm(this.tree[0]) - ); - } - equals(e) { - return this.id === e.id; - } - child(e) { - return ( - marshalNode(this), - C._ts_node_child_wasm(this.tree[0], e), - unmarshalNode(this.tree) - ); - } - namedChild(e) { - return ( - marshalNode(this), - C._ts_node_named_child_wasm(this.tree[0], e), - unmarshalNode(this.tree) - ); - } - childForFieldId(e) { - return ( - marshalNode(this), - C._ts_node_child_by_field_id_wasm(this.tree[0], e), - unmarshalNode(this.tree) - ); - } - childForFieldName(e) { - const t = this.tree.language.fields.indexOf(e); - if (-1 !== t) return this.childForFieldId(t); - } - fieldNameForChild(e) { - marshalNode(this); - const t = C._ts_node_field_name_for_child_wasm( - this.tree[0], - e - ); - if (!t) return null; - return AsciiToString(t); - } - childrenForFieldName(e) { - const t = this.tree.language.fields.indexOf(e); - if (-1 !== t && 0 !== t) return this.childrenForFieldId(t); - } - childrenForFieldId(e) { - marshalNode(this), - C._ts_node_children_by_field_id_wasm(this.tree[0], e); - const t = getValue(TRANSFER_BUFFER, "i32"), - r = getValue(TRANSFER_BUFFER + SIZE_OF_INT, "i32"), - _ = new Array(t); - if (t > 0) { - let e = r; - for (let r = 0; r < t; r++) - (_[r] = unmarshalNode(this.tree, e)), (e += SIZE_OF_NODE); - C._free(r); - } - return _; - } - firstChildForIndex(e) { - marshalNode(this); - return ( - setValue(TRANSFER_BUFFER + SIZE_OF_NODE, e, "i32"), - C._ts_node_first_child_for_byte_wasm(this.tree[0]), - unmarshalNode(this.tree) - ); - } - firstNamedChildForIndex(e) { - marshalNode(this); - return ( - setValue(TRANSFER_BUFFER + SIZE_OF_NODE, e, "i32"), - C._ts_node_first_named_child_for_byte_wasm(this.tree[0]), - unmarshalNode(this.tree) - ); - } - get childCount() { - return ( - marshalNode(this), C._ts_node_child_count_wasm(this.tree[0]) - ); - } - get namedChildCount() { - return ( - marshalNode(this), - C._ts_node_named_child_count_wasm(this.tree[0]) - ); - } - get firstChild() { - return this.child(0); - } - get firstNamedChild() { - return this.namedChild(0); - } - get lastChild() { - return this.child(this.childCount - 1); - } - get lastNamedChild() { - return this.namedChild(this.namedChildCount - 1); - } - get children() { - if (!this._children) { - marshalNode(this), C._ts_node_children_wasm(this.tree[0]); - const e = getValue(TRANSFER_BUFFER, "i32"), - t = getValue(TRANSFER_BUFFER + SIZE_OF_INT, "i32"); - if (((this._children = new Array(e)), e > 0)) { - let r = t; - for (let t = 0; t < e; t++) - (this._children[t] = unmarshalNode(this.tree, r)), - (r += SIZE_OF_NODE); - C._free(t); - } - } - return this._children; - } - get namedChildren() { - if (!this._namedChildren) { - marshalNode(this), - C._ts_node_named_children_wasm(this.tree[0]); - const e = getValue(TRANSFER_BUFFER, "i32"), - t = getValue(TRANSFER_BUFFER + SIZE_OF_INT, "i32"); - if (((this._namedChildren = new Array(e)), e > 0)) { - let r = t; - for (let t = 0; t < e; t++) - (this._namedChildren[t] = unmarshalNode(this.tree, r)), - (r += SIZE_OF_NODE); - C._free(t); - } - } - return this._namedChildren; - } - descendantsOfType(e, t, r) { - Array.isArray(e) || (e = [e]), - t || (t = ZERO_POINT), - r || (r = ZERO_POINT); - const _ = [], - s = this.tree.language.types; - for (let t = 0, r = s.length; t < r; t++) - e.includes(s[t]) && _.push(t); - const n = C._malloc(SIZE_OF_INT * _.length); - for (let e = 0, t = _.length; e < t; e++) - setValue(n + e * SIZE_OF_INT, _[e], "i32"); - marshalNode(this), - C._ts_node_descendants_of_type_wasm( - this.tree[0], - n, - _.length, - t.row, - t.column, - r.row, - r.column - ); - const a = getValue(TRANSFER_BUFFER, "i32"), - o = getValue(TRANSFER_BUFFER + SIZE_OF_INT, "i32"), - l = new Array(a); - if (a > 0) { - let e = o; - for (let t = 0; t < a; t++) - (l[t] = unmarshalNode(this.tree, e)), (e += SIZE_OF_NODE); - } - return C._free(o), C._free(n), l; - } - get nextSibling() { - return ( - marshalNode(this), - C._ts_node_next_sibling_wasm(this.tree[0]), - unmarshalNode(this.tree) - ); - } - get previousSibling() { - return ( - marshalNode(this), - C._ts_node_prev_sibling_wasm(this.tree[0]), - unmarshalNode(this.tree) - ); - } - get nextNamedSibling() { - return ( - marshalNode(this), - C._ts_node_next_named_sibling_wasm(this.tree[0]), - unmarshalNode(this.tree) - ); - } - get previousNamedSibling() { - return ( - marshalNode(this), - C._ts_node_prev_named_sibling_wasm(this.tree[0]), - unmarshalNode(this.tree) - ); - } - get descendantCount() { - return ( - marshalNode(this), - C._ts_node_descendant_count_wasm(this.tree[0]) - ); - } - get parent() { - return ( - marshalNode(this), - C._ts_node_parent_wasm(this.tree[0]), - unmarshalNode(this.tree) - ); - } - descendantForIndex(e, t = e) { - if ("number" != typeof e || "number" != typeof t) - throw new Error("Arguments must be numbers"); - marshalNode(this); - const r = TRANSFER_BUFFER + SIZE_OF_NODE; - return ( - setValue(r, e, "i32"), - setValue(r + SIZE_OF_INT, t, "i32"), - C._ts_node_descendant_for_index_wasm(this.tree[0]), - unmarshalNode(this.tree) - ); - } - namedDescendantForIndex(e, t = e) { - if ("number" != typeof e || "number" != typeof t) - throw new Error("Arguments must be numbers"); - marshalNode(this); - const r = TRANSFER_BUFFER + SIZE_OF_NODE; - return ( - setValue(r, e, "i32"), - setValue(r + SIZE_OF_INT, t, "i32"), - C._ts_node_named_descendant_for_index_wasm(this.tree[0]), - unmarshalNode(this.tree) - ); - } - descendantForPosition(e, t = e) { - if (!isPoint(e) || !isPoint(t)) - throw new Error("Arguments must be {row, column} objects"); - marshalNode(this); - const r = TRANSFER_BUFFER + SIZE_OF_NODE; - return ( - marshalPoint(r, e), - marshalPoint(r + SIZE_OF_POINT, t), - C._ts_node_descendant_for_position_wasm(this.tree[0]), - unmarshalNode(this.tree) - ); - } - namedDescendantForPosition(e, t = e) { - if (!isPoint(e) || !isPoint(t)) - throw new Error("Arguments must be {row, column} objects"); - marshalNode(this); - const r = TRANSFER_BUFFER + SIZE_OF_NODE; - return ( - marshalPoint(r, e), - marshalPoint(r + SIZE_OF_POINT, t), - C._ts_node_named_descendant_for_position_wasm(this.tree[0]), - unmarshalNode(this.tree) - ); - } - walk() { - return ( - marshalNode(this), - C._ts_tree_cursor_new_wasm(this.tree[0]), - new TreeCursor(INTERNAL, this.tree) - ); - } - toString() { - marshalNode(this); - const e = C._ts_node_to_string_wasm(this.tree[0]), - t = AsciiToString(e); - return C._free(e), t; - } - } - class TreeCursor { - constructor(e, t) { - assertInternal(e), (this.tree = t), unmarshalTreeCursor(this); - } - delete() { - marshalTreeCursor(this), - C._ts_tree_cursor_delete_wasm(this.tree[0]), - (this[0] = this[1] = this[2] = 0); - } - reset(e) { - marshalNode(e), - marshalTreeCursor(this, TRANSFER_BUFFER + SIZE_OF_NODE), - C._ts_tree_cursor_reset_wasm(this.tree[0]), - unmarshalTreeCursor(this); - } - resetTo(e) { - marshalTreeCursor(this, TRANSFER_BUFFER), - marshalTreeCursor(e, TRANSFER_BUFFER + SIZE_OF_CURSOR), - C._ts_tree_cursor_reset_to_wasm(this.tree[0], e.tree[0]), - unmarshalTreeCursor(this); - } - get nodeType() { - return this.tree.language.types[this.nodeTypeId] || "ERROR"; - } - get nodeTypeId() { - return ( - marshalTreeCursor(this), - C._ts_tree_cursor_current_node_type_id_wasm(this.tree[0]) - ); - } - get nodeStateId() { - return ( - marshalTreeCursor(this), - C._ts_tree_cursor_current_node_state_id_wasm(this.tree[0]) - ); - } - get nodeId() { - return ( - marshalTreeCursor(this), - C._ts_tree_cursor_current_node_id_wasm(this.tree[0]) - ); - } - get nodeIsNamed() { - return ( - marshalTreeCursor(this), - 1 === - C._ts_tree_cursor_current_node_is_named_wasm(this.tree[0]) - ); - } - get nodeIsMissing() { - return ( - marshalTreeCursor(this), - 1 === - C._ts_tree_cursor_current_node_is_missing_wasm( - this.tree[0] - ) - ); - } - get nodeText() { - marshalTreeCursor(this); - const e = C._ts_tree_cursor_start_index_wasm(this.tree[0]), - t = C._ts_tree_cursor_end_index_wasm(this.tree[0]); - return getText(this.tree, e, t); - } - get startPosition() { - return ( - marshalTreeCursor(this), - C._ts_tree_cursor_start_position_wasm(this.tree[0]), - unmarshalPoint(TRANSFER_BUFFER) - ); - } - get endPosition() { - return ( - marshalTreeCursor(this), - C._ts_tree_cursor_end_position_wasm(this.tree[0]), - unmarshalPoint(TRANSFER_BUFFER) - ); - } - get startIndex() { - return ( - marshalTreeCursor(this), - C._ts_tree_cursor_start_index_wasm(this.tree[0]) - ); - } - get endIndex() { - return ( - marshalTreeCursor(this), - C._ts_tree_cursor_end_index_wasm(this.tree[0]) - ); - } - get currentNode() { - return ( - marshalTreeCursor(this), - C._ts_tree_cursor_current_node_wasm(this.tree[0]), - unmarshalNode(this.tree) - ); - } - get currentFieldId() { - return ( - marshalTreeCursor(this), - C._ts_tree_cursor_current_field_id_wasm(this.tree[0]) - ); - } - get currentFieldName() { - return this.tree.language.fields[this.currentFieldId]; - } - get currentDepth() { - return ( - marshalTreeCursor(this), - C._ts_tree_cursor_current_depth_wasm(this.tree[0]) - ); - } - get currentDescendantIndex() { - return ( - marshalTreeCursor(this), - C._ts_tree_cursor_current_descendant_index_wasm( - this.tree[0] - ) - ); - } - gotoFirstChild() { - marshalTreeCursor(this); - const e = C._ts_tree_cursor_goto_first_child_wasm( - this.tree[0] - ); - return unmarshalTreeCursor(this), 1 === e; - } - gotoLastChild() { - marshalTreeCursor(this); - const e = C._ts_tree_cursor_goto_last_child_wasm( - this.tree[0] - ); - return unmarshalTreeCursor(this), 1 === e; - } - gotoFirstChildForIndex(e) { - marshalTreeCursor(this), - setValue(TRANSFER_BUFFER + SIZE_OF_CURSOR, e, "i32"); - const t = C._ts_tree_cursor_goto_first_child_for_index_wasm( - this.tree[0] - ); - return unmarshalTreeCursor(this), 1 === t; - } - gotoFirstChildForPosition(e) { - marshalTreeCursor(this), - marshalPoint(TRANSFER_BUFFER + SIZE_OF_CURSOR, e); - const t = - C._ts_tree_cursor_goto_first_child_for_position_wasm( - this.tree[0] - ); - return unmarshalTreeCursor(this), 1 === t; - } - gotoNextSibling() { - marshalTreeCursor(this); - const e = C._ts_tree_cursor_goto_next_sibling_wasm( - this.tree[0] - ); - return unmarshalTreeCursor(this), 1 === e; - } - gotoPreviousSibling() { - marshalTreeCursor(this); - const e = C._ts_tree_cursor_goto_previous_sibling_wasm( - this.tree[0] - ); - return unmarshalTreeCursor(this), 1 === e; - } - gotoDescendant(e) { - marshalTreeCursor(this), - C._ts_tree_cursor_goto_descendant_wasm(this.tree[0], e), - unmarshalTreeCursor(this); - } - gotoParent() { - marshalTreeCursor(this); - const e = C._ts_tree_cursor_goto_parent_wasm(this.tree[0]); - return unmarshalTreeCursor(this), 1 === e; - } - } - class Language { - constructor(e, t) { - assertInternal(e), - (this[0] = t), - (this.types = new Array( - C._ts_language_symbol_count(this[0]) - )); - for (let e = 0, t = this.types.length; e < t; e++) - C._ts_language_symbol_type(this[0], e) < 2 && - (this.types[e] = UTF8ToString( - C._ts_language_symbol_name(this[0], e) - )); - this.fields = new Array( - C._ts_language_field_count(this[0]) + 1 - ); - for (let e = 0, t = this.fields.length; e < t; e++) { - const t = C._ts_language_field_name_for_id(this[0], e); - this.fields[e] = 0 !== t ? UTF8ToString(t) : null; - } - } - get version() { - return C._ts_language_version(this[0]); - } - get fieldCount() { - return this.fields.length - 1; - } - get stateCount() { - return C._ts_language_state_count(this[0]); - } - fieldIdForName(e) { - const t = this.fields.indexOf(e); - return -1 !== t ? t : null; - } - fieldNameForId(e) { - return this.fields[e] || null; - } - idForNodeType(e, t) { - const r = lengthBytesUTF8(e), - _ = C._malloc(r + 1); - stringToUTF8(e, _, r + 1); - const s = C._ts_language_symbol_for_name(this[0], _, r, t); - return C._free(_), s || null; - } - get nodeTypeCount() { - return C._ts_language_symbol_count(this[0]); - } - nodeTypeForId(e) { - const t = C._ts_language_symbol_name(this[0], e); - return t ? UTF8ToString(t) : null; - } - nodeTypeIsNamed(e) { - return !!C._ts_language_type_is_named_wasm(this[0], e); - } - nodeTypeIsVisible(e) { - return !!C._ts_language_type_is_visible_wasm(this[0], e); - } - nextState(e, t) { - return C._ts_language_next_state(this[0], e, t); - } - lookaheadIterator(e) { - const t = C._ts_lookahead_iterator_new(this[0], e); - if (t) return new LookaheadIterable(INTERNAL, t, this); - } - query(e) { - const t = lengthBytesUTF8(e), - r = C._malloc(t + 1); - stringToUTF8(e, r, t + 1); - const _ = C._ts_query_new( - this[0], - r, - t, - TRANSFER_BUFFER, - TRANSFER_BUFFER + SIZE_OF_INT - ); - if (!_) { - const t = getValue(TRANSFER_BUFFER + SIZE_OF_INT, "i32"), - _ = UTF8ToString( - r, - getValue(TRANSFER_BUFFER, "i32") - ).length, - s = e.substr(_, 100).split("\n")[0]; - let n, - a = s.match(QUERY_WORD_REGEX)[0]; - switch (t) { - case 2: - n = new RangeError(`Bad node name '${a}'`); - break; - case 3: - n = new RangeError(`Bad field name '${a}'`); - break; - case 4: - n = new RangeError(`Bad capture name @${a}`); - break; - case 5: - (n = new TypeError( - `Bad pattern structure at offset ${_}: '${s}'...` - )), - (a = ""); - break; - default: - (n = new SyntaxError( - `Bad syntax at offset ${_}: '${s}'...` - )), - (a = ""); - } - throw ((n.index = _), (n.length = a.length), C._free(r), n); - } - const s = C._ts_query_string_count(_), - n = C._ts_query_capture_count(_), - a = C._ts_query_pattern_count(_), - o = new Array(n), - l = new Array(s); - for (let e = 0; e < n; e++) { - const t = C._ts_query_capture_name_for_id( - _, - e, - TRANSFER_BUFFER - ), - r = getValue(TRANSFER_BUFFER, "i32"); - o[e] = UTF8ToString(t, r); - } - for (let e = 0; e < s; e++) { - const t = C._ts_query_string_value_for_id( - _, - e, - TRANSFER_BUFFER - ), - r = getValue(TRANSFER_BUFFER, "i32"); - l[e] = UTF8ToString(t, r); - } - const i = new Array(a), - u = new Array(a), - d = new Array(a), - m = new Array(a), - c = new Array(a); - for (let e = 0; e < a; e++) { - const t = C._ts_query_predicates_for_pattern( - _, - e, - TRANSFER_BUFFER - ), - r = getValue(TRANSFER_BUFFER, "i32"); - (m[e] = []), (c[e] = []); - const s = []; - let n = t; - for (let t = 0; t < r; t++) { - const t = getValue(n, "i32"); - n += SIZE_OF_INT; - const r = getValue(n, "i32"); - if ( - ((n += SIZE_OF_INT), t === PREDICATE_STEP_TYPE_CAPTURE) - ) - s.push({ type: "capture", name: o[r] }); - else if (t === PREDICATE_STEP_TYPE_STRING) - s.push({ type: "string", value: l[r] }); - else if (s.length > 0) { - if ("string" !== s[0].type) - throw new Error( - "Predicates must begin with a literal value" - ); - const t = s[0].value; - let r, - _ = !0, - n = !0; - switch (t) { - case "any-not-eq?": - case "not-eq?": - _ = !1; - case "any-eq?": - case "eq?": - if (3 !== s.length) - throw new Error( - `Wrong number of arguments to \`#${t}\` predicate. Expected 2, got ${ - s.length - 1 - }` - ); - if ("capture" !== s[1].type) - throw new Error( - `First argument of \`#${t}\` predicate must be a capture. Got "${s[1].value}"` - ); - if ( - ((n = !t.startsWith("any-")), - "capture" === s[2].type) - ) { - const t = s[1].name, - r = s[2].name; - c[e].push(function (e) { - const s = [], - a = []; - for (const _ of e) - _.name === t && s.push(_.node), - _.name === r && a.push(_.node); - const o = (e, t, r) => - r ? e.text === t.text : e.text !== t.text; - return n - ? s.every((e) => a.some((t) => o(e, t, _))) - : s.some((e) => a.some((t) => o(e, t, _))); - }); - } else { - r = s[1].name; - const t = s[2].value, - a = (e) => e.text === t, - o = (e) => e.text !== t; - c[e].push(function (e) { - const t = []; - for (const _ of e) - _.name === r && t.push(_.node); - const s = _ ? a : o; - return n ? t.every(s) : t.some(s); - }); - } - break; - case "any-not-match?": - case "not-match?": - _ = !1; - case "any-match?": - case "match?": - if (3 !== s.length) - throw new Error( - `Wrong number of arguments to \`#${t}\` predicate. Expected 2, got ${ - s.length - 1 - }.` - ); - if ("capture" !== s[1].type) - throw new Error( - `First argument of \`#${t}\` predicate must be a capture. Got "${s[1].value}".` - ); - if ("string" !== s[2].type) - throw new Error( - `Second argument of \`#${t}\` predicate must be a string. Got @${s[2].value}.` - ); - r = s[1].name; - const a = new RegExp(s[2].value); - (n = !t.startsWith("any-")), - c[e].push(function (e) { - const t = []; - for (const _ of e) - _.name === r && t.push(_.node.text); - const s = (e, t) => - t ? a.test(e) : !a.test(e); - return 0 === t.length - ? !_ - : n - ? t.every((e) => s(e, _)) - : t.some((e) => s(e, _)); - }); - break; - case "set!": - if (s.length < 2 || s.length > 3) - throw new Error( - `Wrong number of arguments to \`#set!\` predicate. Expected 1 or 2. Got ${ - s.length - 1 - }.` - ); - if (s.some((e) => "string" !== e.type)) - throw new Error( - 'Arguments to `#set!` predicate must be a strings.".' - ); - i[e] || (i[e] = {}), - (i[e][s[1].value] = s[2] ? s[2].value : null); - break; - case "is?": - case "is-not?": - if (s.length < 2 || s.length > 3) - throw new Error( - `Wrong number of arguments to \`#${t}\` predicate. Expected 1 or 2. Got ${ - s.length - 1 - }.` - ); - if (s.some((e) => "string" !== e.type)) - throw new Error( - `Arguments to \`#${t}\` predicate must be a strings.".` - ); - const o = "is?" === t ? u : d; - o[e] || (o[e] = {}), - (o[e][s[1].value] = s[2] ? s[2].value : null); - break; - case "not-any-of?": - _ = !1; - case "any-of?": - if (s.length < 2) - throw new Error( - `Wrong number of arguments to \`#${t}\` predicate. Expected at least 1. Got ${ - s.length - 1 - }.` - ); - if ("capture" !== s[1].type) - throw new Error( - `First argument of \`#${t}\` predicate must be a capture. Got "${s[1].value}".` - ); - for (let e = 2; e < s.length; e++) - if ("string" !== s[e].type) - throw new Error( - `Arguments to \`#${t}\` predicate must be a strings.".` - ); - r = s[1].name; - const l = s.slice(2).map((e) => e.value); - c[e].push(function (e) { - const t = []; - for (const _ of e) - _.name === r && t.push(_.node.text); - return 0 === t.length - ? !_ - : t.every((e) => l.includes(e)) === _; - }); - break; - default: - m[e].push({ operator: t, operands: s.slice(1) }); - } - s.length = 0; - } - } - Object.freeze(i[e]), - Object.freeze(u[e]), - Object.freeze(d[e]); - } - return ( - C._free(r), - new Query( - INTERNAL, - _, - o, - c, - m, - Object.freeze(i), - Object.freeze(u), - Object.freeze(d) - ) - ); - } - static load(e) { - let t; - if (e instanceof Uint8Array) t = Promise.resolve(e); - else { - const r = e; - if ( - "undefined" != typeof process && - process.versions && - process.versions.node - ) { - const e = require("fs"); - t = Promise.resolve(e.readFileSync(r)); - } else - t = fetch(r).then((e) => - e.arrayBuffer().then((t) => { - if (e.ok) return new Uint8Array(t); - { - const r = new TextDecoder("utf-8").decode(t); - throw new Error( - `Language.load failed with status ${e.status}.\n\n${r}` - ); - } - }) - ); - } - return t - .then((e) => loadWebAssemblyModule(e, { loadAsync: !0 })) - .then((e) => { - const t = Object.keys(e), - r = t.find( - (e) => - LANGUAGE_FUNCTION_REGEX.test(e) && - !e.includes("external_scanner_") - ); - r || - console.log( - `Couldn't find language function in WASM file. Symbols:\n${JSON.stringify( - t, - null, - 2 - )}` - ); - const _ = e[r](); - return new Language(INTERNAL, _); - }); - } - } - class LookaheadIterable { - constructor(e, t, r) { - assertInternal(e), (this[0] = t), (this.language = r); - } - get currentTypeId() { - return C._ts_lookahead_iterator_current_symbol(this[0]); - } - get currentType() { - return this.language.types[this.currentTypeId] || "ERROR"; - } - delete() { - C._ts_lookahead_iterator_delete(this[0]), (this[0] = 0); - } - resetState(e) { - return C._ts_lookahead_iterator_reset_state(this[0], e); - } - reset(e, t) { - return ( - !!C._ts_lookahead_iterator_reset(this[0], e[0], t) && - ((this.language = e), !0) - ); - } - [Symbol.iterator]() { - const e = this; - return { - next: () => - C._ts_lookahead_iterator_next(e[0]) - ? { done: !1, value: e.currentType } - : { done: !0, value: "" }, - }; - } - } - class Query { - constructor(e, t, r, _, s, n, a, o) { - assertInternal(e), - (this[0] = t), - (this.captureNames = r), - (this.textPredicates = _), - (this.predicates = s), - (this.setProperties = n), - (this.assertedProperties = a), - (this.refutedProperties = o), - (this.exceededMatchLimit = !1); - } - delete() { - C._ts_query_delete(this[0]), (this[0] = 0); - } - matches( - e, - { - startPosition: t = ZERO_POINT, - endPosition: r = ZERO_POINT, - startIndex: _ = 0, - endIndex: s = 0, - matchLimit: n = 4294967295, - maxStartDepth: a = 4294967295, - } = {} - ) { - if ("number" != typeof n) - throw new Error("Arguments must be numbers"); - marshalNode(e), - C._ts_query_matches_wasm( - this[0], - e.tree[0], - t.row, - t.column, - r.row, - r.column, - _, - s, - n, - a - ); - const o = getValue(TRANSFER_BUFFER, "i32"), - l = getValue(TRANSFER_BUFFER + SIZE_OF_INT, "i32"), - i = getValue(TRANSFER_BUFFER + 2 * SIZE_OF_INT, "i32"), - u = new Array(o); - this.exceededMatchLimit = !!i; - let d = 0, - m = l; - for (let t = 0; t < o; t++) { - const t = getValue(m, "i32"); - m += SIZE_OF_INT; - const r = getValue(m, "i32"); - m += SIZE_OF_INT; - const _ = new Array(r); - if ( - ((m = unmarshalCaptures(this, e.tree, m, _)), - this.textPredicates[t].every((e) => e(_))) - ) { - u[d] = { pattern: t, captures: _ }; - const e = this.setProperties[t]; - e && (u[d].setProperties = e); - const r = this.assertedProperties[t]; - r && (u[d].assertedProperties = r); - const s = this.refutedProperties[t]; - s && (u[d].refutedProperties = s), d++; - } - } - return (u.length = d), C._free(l), u; - } - captures( - e, - { - startPosition: t = ZERO_POINT, - endPosition: r = ZERO_POINT, - startIndex: _ = 0, - endIndex: s = 0, - matchLimit: n = 4294967295, - maxStartDepth: a = 4294967295, - } = {} - ) { - if ("number" != typeof n) - throw new Error("Arguments must be numbers"); - marshalNode(e), - C._ts_query_captures_wasm( - this[0], - e.tree[0], - t.row, - t.column, - r.row, - r.column, - _, - s, - n, - a - ); - const o = getValue(TRANSFER_BUFFER, "i32"), - l = getValue(TRANSFER_BUFFER + SIZE_OF_INT, "i32"), - i = getValue(TRANSFER_BUFFER + 2 * SIZE_OF_INT, "i32"), - u = []; - this.exceededMatchLimit = !!i; - const d = []; - let m = l; - for (let t = 0; t < o; t++) { - const t = getValue(m, "i32"); - m += SIZE_OF_INT; - const r = getValue(m, "i32"); - m += SIZE_OF_INT; - const _ = getValue(m, "i32"); - if ( - ((m += SIZE_OF_INT), - (d.length = r), - (m = unmarshalCaptures(this, e.tree, m, d)), - this.textPredicates[t].every((e) => e(d))) - ) { - const e = d[_], - r = this.setProperties[t]; - r && (e.setProperties = r); - const s = this.assertedProperties[t]; - s && (e.assertedProperties = s); - const n = this.refutedProperties[t]; - n && (e.refutedProperties = n), u.push(e); - } - } - return C._free(l), u; - } - predicatesForPattern(e) { - return this.predicates[e]; - } - disableCapture(e) { - const t = lengthBytesUTF8(e), - r = C._malloc(t + 1); - stringToUTF8(e, r, t + 1), - C._ts_query_disable_capture(this[0], r, t), - C._free(r); - } - didExceedMatchLimit() { - return this.exceededMatchLimit; - } - } - function getText(e, t, r) { - const _ = r - t; - let s = e.textCallback(t, null, r); - for (t += s.length; t < r; ) { - const _ = e.textCallback(t, null, r); - if (!(_ && _.length > 0)) break; - (t += _.length), (s += _); - } - return t > r && (s = s.slice(0, _)), s; - } - function unmarshalCaptures(e, t, r, _) { - for (let s = 0, n = _.length; s < n; s++) { - const n = getValue(r, "i32"), - a = unmarshalNode(t, (r += SIZE_OF_INT)); - (r += SIZE_OF_NODE), - (_[s] = { name: e.captureNames[n], node: a }); - } - return r; - } - function assertInternal(e) { - if (e !== INTERNAL) throw new Error("Illegal constructor"); - } - function isPoint(e) { - return ( - e && "number" == typeof e.row && "number" == typeof e.column - ); - } - function marshalNode(e) { - let t = TRANSFER_BUFFER; - setValue(t, e.id, "i32"), - (t += SIZE_OF_INT), - setValue(t, e.startIndex, "i32"), - (t += SIZE_OF_INT), - setValue(t, e.startPosition.row, "i32"), - (t += SIZE_OF_INT), - setValue(t, e.startPosition.column, "i32"), - (t += SIZE_OF_INT), - setValue(t, e[0], "i32"); - } - function unmarshalNode(e, t = TRANSFER_BUFFER) { - const r = getValue(t, "i32"); - if (0 === r) return null; - const _ = getValue((t += SIZE_OF_INT), "i32"), - s = getValue((t += SIZE_OF_INT), "i32"), - n = getValue((t += SIZE_OF_INT), "i32"), - a = getValue((t += SIZE_OF_INT), "i32"), - o = new Node(INTERNAL, e); - return ( - (o.id = r), - (o.startIndex = _), - (o.startPosition = { row: s, column: n }), - (o[0] = a), - o - ); - } - function marshalTreeCursor(e, t = TRANSFER_BUFFER) { - setValue(t + 0 * SIZE_OF_INT, e[0], "i32"), - setValue(t + 1 * SIZE_OF_INT, e[1], "i32"), - setValue(t + 2 * SIZE_OF_INT, e[2], "i32"); - } - function unmarshalTreeCursor(e) { - (e[0] = getValue(TRANSFER_BUFFER + 0 * SIZE_OF_INT, "i32")), - (e[1] = getValue(TRANSFER_BUFFER + 1 * SIZE_OF_INT, "i32")), - (e[2] = getValue(TRANSFER_BUFFER + 2 * SIZE_OF_INT, "i32")); - } - function marshalPoint(e, t) { - setValue(e, t.row, "i32"), - setValue(e + SIZE_OF_INT, t.column, "i32"); - } - function unmarshalPoint(e) { - return { - row: getValue(e, "i32") >>> 0, - column: getValue(e + SIZE_OF_INT, "i32") >>> 0, - }; - } - function marshalRange(e, t) { - marshalPoint(e, t.startPosition), - marshalPoint((e += SIZE_OF_POINT), t.endPosition), - setValue((e += SIZE_OF_POINT), t.startIndex, "i32"), - setValue((e += SIZE_OF_INT), t.endIndex, "i32"), - (e += SIZE_OF_INT); - } - function unmarshalRange(e) { - const t = {}; - return ( - (t.startPosition = unmarshalPoint(e)), - (e += SIZE_OF_POINT), - (t.endPosition = unmarshalPoint(e)), - (e += SIZE_OF_POINT), - (t.startIndex = getValue(e, "i32") >>> 0), - (e += SIZE_OF_INT), - (t.endIndex = getValue(e, "i32") >>> 0), - t - ); - } - function marshalEdit(e) { - let t = TRANSFER_BUFFER; - marshalPoint(t, e.startPosition), - (t += SIZE_OF_POINT), - marshalPoint(t, e.oldEndPosition), - (t += SIZE_OF_POINT), - marshalPoint(t, e.newEndPosition), - (t += SIZE_OF_POINT), - setValue(t, e.startIndex, "i32"), - (t += SIZE_OF_INT), - setValue(t, e.oldEndIndex, "i32"), - (t += SIZE_OF_INT), - setValue(t, e.newEndIndex, "i32"), - (t += SIZE_OF_INT); - } - for (const e of Object.getOwnPropertyNames(ParserImpl.prototype)) - Object.defineProperty(Parser.prototype, e, { - value: ParserImpl.prototype[e], - enumerable: !1, - writable: !1, - }); - (Parser.Language = Language), - (Module.onRuntimeInitialized = () => { - ParserImpl.init(), resolveInitPromise(); - }); - }))) - ); - } - } - return Parser; - })(); - "object" == typeof exports && (module.exports = TreeSitter); - - return { Parser: TreeSitter }; -})); diff --git a/src/vs/base/common/web-tree-sitter/tree-sitter.wasm b/src/vs/base/common/web-tree-sitter/tree-sitter.wasm deleted file mode 100644 index 700cbe18713c97b1814eceee176e92f96eecb3b3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 192649 zcmdqK3zS{gdEa;TIrn|<%v=Bia!5epxtFLjPyiE(S&$JJYYxI^NkwYIm8E8>3xvQC ziJ2iDgCRww3;~(6!^CdNq-w&Xj*Yr<=(uLeCQ7QfN{uwCtJG>N$B(Lh#ER=UYT`6< zs=9JwoBjR&d!Kvn3IDM6AiBDZc|6@#UmGdBYPs_KYn$5 zn?Ibl(|Ptp>+%aa=UQ?3#mnKvCwl1?hwO=*OP6`Z|74TbxR$?gIlPd%ev$TH0K^wF z0sCV9*Nb7XdhWUA>5rb@+{${leEjsKv!^bdJAL8O)91HNUD#ZG?(FKv-`n}vlczqu zd3I|xYu(_9HcwnyU0u&QYVMZRXD*%DJbPhl_1vk=)k|mp$m*%5S5IHaGTq!ebMvXy ztyAaDe>}TIH_B7j-#K;m(y3?8pF6*G{@mF!SznLspLyz;)o0FJ_{6D?o_#7SZUC8J zKeKWE(rWDe_N~p;)l-+wZf&h@p1N>)^U~_6Gp9E;K6?7hde&C+OS2DboPTP1yQ$j? zr%qkk;^9*l&YwL;8^z_I%X6nr0n7PKU^#thwYcn&4o;ogI{nd&)%sfdp$|U(%{(s}dJ$Gj7?D=!Cxo{y{DqhMznKzrQ zMx&ACMZ4K(HjAv8XPtIYWZ9lZv&i>`R+cqFKFAx5PP6E?8+j7Thgm+;V^{_(Nda{h1#d8<=2 zdwm|D?U40)t#9pK4pr9Y&nrLa!F(_5!u;!ZFG2F`+w*O2eC+J%1`O>tzAe9H_KkC^&u@u25!2tZ?VSX`xzo?AX1^8=%)XOu zeeC?^Dc^q2ZZB?q;=*e7z`JJOi(u%LQ+oI8liA-3x9NfN=hsgo>rb9STWp>No2SmL zemwh|;o$B!pIqHo1>XNUjCQ||_CQ6%LH%F^{rVpKQ1%1i_TAeMUb4R!4()#T%(I)D ztLNy$RLZ_DNEGQbThIyGC7T=ard7q}sRZwz2n*9|vHQD3i}aLWuF0SM@gQzUcec(x zvwHs7ty9mOJ+pcKQub$zmzlSA-2YF5us(DD?71@=&px^Oc8Ef#@`A0KiD~Y>Eo9!oIbOfZRqs$#<^#o$!^mC;&T^H zOFf=TZ1!@P-Z^vn!q&5!HOsyf_D|lqw6%Hm9NIE+rpFZ`K0u(}ZF0WnGZHHA|P(b8a15@Dw&fx+44SusD6oFURY@8Qwj;zJpfriGSfI zYUVg4(UOf5a^)1Ci2jCp(KowHj{ zpF01skBKk+{;!8U^-~}>UHrd1XurBE=wCNcd|!6^%+q4QniFHY|7Vc?@FU38r6~RJ z)<3s+&fbc|hJ;jivK#wS-VomoBiMiVo99kD^R%OnP0pPk+CIwx0*ZtzLogSW@aAvh3ojY20EJA z8tR|7m7Hy;e(uTD3rM)h_H*IL4G=cN12dif>~({z8=WeZ|24=p@$cj?xT`N49$((! z56lSN|1y2ZS7ESIAN>TvDLwD%qofhaZ0$E_jahqADt2|c75YV{|Af0PB_%wcG3KNcu!4(U7Otg^xvM+rj~Pp zw@B~*-lo(&M(Lj1`CB{Rnvt4o+uxeG^CQzc*r4Rxm<#?pdrR(VA_>0nxhc2C!EC?% z-&#U<;N%kaJbDjq;)kbgZ`YrHV>*bZPhUz#`%)bGXQ!a*-s%dZv1r{ zc*C+&_5QW(?>xV?c{(=snJEa-Rf^`o9sSiQ-`Vh8_rRNOHTrqaoZdR~G;W~Z{I3lB zHWxG9`O860?UQGp!oB-TK0m#2;px-aGrIgy9IN&0KlkO0^B-T`%wF^PvllLK{ue@* zXP%GmUUevN=IPCBy#*aNR?lUx2c4b4%l@;W&DlA{2j3GqTjxI>8#|-Z*w*O|?$+Z^ zZ{mZ0Z|E}SGwXlwG>-az76$(D@2y@UJX+2EeCYXiMj2H4=+A67y3MzRd0oh<3ewI=)t*6 z$Hj53!_Yr@KCB(j7t6fN-j`*AykCa07@i*louq!$Vo~M?j^~fL``>A!Zi_}~62NaS z$rsR6zyA-Kc}p2E26Qybs&EkiGu<2N!3;QaAF8l^JkJE`gAENo1Nw0Tz0wXEG~WEqmVRVe ze?+@wA+*rz@q94taRh>VZRlpo292(j;c%YalV{u#WZ{9itN=>J8P>;v;pB#Szy+Sx zkQ&SRp>f_=sj?Bs5Fp%Hr?qhLz^GYhkj?lsEsr~|Lu_N`dW<|Ym&MkH<6;IQZDFJh zM%uzi%NS{akyhC13k?< z+rn@zbOUwcXm+H!mR$s2dgkHkHlEVivHCf)@N(W6!{zYCa^4t2V%n_AM?LUR<{D|v zNI{WkANY57+9N$`0=|;ilwo$HVM_Z@n)V$I&~B#J5j^5+4L1X`X`~IF5%)AEFzYT{ zz<~SxKh+4$%XengaDCi91VzME1AbqHGa6i=DX9KE0Um-l$Ma8x>hh?`W%CZgpdLSf zU^(bs707Q6$x^2=5_;h6^9!(X9GjiSrSkeoCj0=PR_8J=|D9NqqgM zvbE~>C4gI%BpwcI0MD1islWs7j^|$lhd{UnM`hLWZ~=*xKzpK|ohu z%GS!_&YVa0uZ^1s*)411*6^%*WGJ~%13n%@S&cv`=pPk2JX~duK?aHCsf$3=PpXYu z#~#oPT0Wj1@vO`uGIL`m zA$F7(X62)qXi3M&Bkf5<&?pENKad8oA}tlw3m4Iw*D{HjfL?)Q$Wd&AVKE$$7BM@X zqmy*jIi4e0IvYq4`fMl-?X$&bI=H)ZT*gPw9TdHMRvypGcy>r!>TAo#^W}JUMA-JV zV)Gorr*flqcfLwU=nDKX5oFA@W)yHzDzcSv*LXjI%az>H8cf%+?XC^fvyJX ztpC;AhP;Ge(FlX}wQ*y;;)oJk|GK=$EP0>?&KOq=0ArPs9nI_fmba1vp{G2d9&?HR% zb0#gKhY<}(2}v_SBi$C(<4^jRK!90M*$32MRixWRl}{dQPac$O(U@HC`g%np>tJyV z^9deYuj-TE_Ht)KPCzE(T0&&Wpu|&e>vE&=+q@uA^FjVVC*97g!Q?^PM?bL?A6$%w zVLTw77@F8>UM)_}mL_Kh>!t+##cF92t^<@(;De{+sxr!2sW$G21kd{4SA-Vo*t)*Vj%GtxTjNA;cCZjp>dMBEEW?c3J4LZn z0oRP~FcWi`8J#EBW$cj<-*^IT>67zOJc?=o$5z&qnWr8`NGw|7QUsc9KKC3BlVl)N z@4q-|Rrx5`Trlph!Pa_@TU(FL6}9=SJ{Zr)+ z&cPugj55lhx^nr_xMgy`pBAOa{VTm@4-(Yjk|V5G>Ot9rLmQQJeyC19qU$_+$HlQ8 z1r=y4TGoKnw2{=T-v0rf15J{6Hv${KFB?`NS`HvAn;0aGYvPqn?#rkRcoA(dWVY^C zMI*=yO$Nga>5}2__GC{7)d}2eU-5nMK@Mr=`$bm&Q^?odNnw+17b+8y5QD(o8k(dT z8jIN5DV$e{!g-Y_97JKgmM9#i6wYTToYxeNz6Qe=h4mg??W8bb7bzU36jlSgB?=qJ z93UqYMr3bB;puA#w+;jA(0 zmd)jCfNaNCW2A#aj?XE-5ZO^AsGy*$(B_k&j>X}qS?KEps3VJ^Lqo!sY*{91>LpoXj~!PAy|~avhQD(z+)@WL5^r269m+DtXO$a; z%T#42g5Kx)ePAKKD;%kQ1OwDM5sv8B$#JIMgrgwDWE;ZEXdmtCaYd;^N2Y*)gS(io zltb|lcZTDE4vea;mX=3z(jQz|9L+PN#d43rqcQkyD4@A3v_>N7yy80sOMBymO$b#S z&5l}EtH&0cvT5kVHJ#^1d#zLywJ)e&9zIfCF+cd>P(Qo}Ocy{SV9MffPW&miwJkrE z>%gSLa5T_iNs#WDlOQz3-&PgnUerx=c4K}+?^YQvA|bzBTm+i&pdY>5`RMlI5f5of zzyVvPC+0ZN;u@iY+5;T-pbiDbnDN5(!kNI)9}s8|mqv3SJ)0vS;p(6d(nNu5h>94i zCk>~ZUmMTAfn3e4i9*ZSQrSMR_QuKbJ6^s=NgQJU0VxM2OWAc)rKFJ)N8mrA5ih-L zugTCuIYNTpeyezhY{V}$MxugAl3#3G<^qo_=Via_tc?i;IBAx>M@I-dyrGBn{#^B2 zZ{ZEPwIky$qN%_m8?>b0aA~UBx2ijyrLl{#5#ZY^Jq$K_CI3HqVAKQCSf{!@;CW=O zeLELO;9TU4V~%iD*`O_dwLz9k?lf-^qxq=rs$WJtVWzp9s7_ChGAT`o|1W2;Z(2Yf z1N|{BZS;8^9XuVKhSi7D)Nmr&ebx~`x)(70^sQ^-TM;Nh$Kz-llkDF9+PJHzWq*xq z@oxOL+$Wv1uiP*3l1ya$7B$4vNwJ}cpvDn=9#mW2uYx&%yZIB26 zQS0-0tBE~EiXVpi&~3Ofa}5o10Wzpf#i6)TBFoL1js0iBbS~Q>oCD|0U$G*#C5q8z zL~eo^{M@b15ww!Tz%7J#Gf>HiQ2qxbNSd!@wKR(>MPaEzB{Yi@;XQr?hgGVJKB5Vz z^5;w?P*@eufvZbvqy1i9#3U{&^dzLiAOPhEgNC-G)%bfHa4aPzc)PWxdkF6o4|J|jvNpa2tg=e7zY@6U zPIIAuBCPcL|0slZ%5xQDIb@1u;j8A>xDCVevte5WH^=}C#P?<6a6V8xf#Rq-YeUmY zuaH4PSNf6G;e7F)LY_#W`&`F!5b@MOhc-KP+AUf+l)kJV4meMuLHqS>5_G)62oJ55 z&Eb+E)P2+-faZiUx}``H})FBVnl27NQb|jP+v3vR*Y-xTV-D2kh9G z`I^Qijc~SGBVrfhjiC*j_za^a@S-Rh==}F8j#3ugJ{KdGJJwMo*dd$RK~s&}CHdmA zP2RXI|BFm|TY2Mlm2Zt2m_1&}#x0s@k^Y>?q&KG7RN9plR?z4uFmag<0@o4U7Meoto&S(YS zF-9x-G+I$W3%@E_F__z;mA8pUr>}wf6s<@BrI@ssD`c}LAt^!q%|cQKD|oFjSgG4l zNaEN76PC%Jmh(B#K_QGtYv>iRc+}EEVU2s}!r^U_9Mr?Os7Aza)w@4Hsy38itNP?u zu3TwcJiz^;`o)Z-K)-*S@TCe;&5@dS=2dTP_%Px&pJ#b=tcQ;{gP=4Q&`5{%|J=9a zb3`FghWm$Tzm|%@xFr?as(vARh`)y)QoN*myun5f!tSG9WSk4*HhkX`v>ONnt}dQE z+V#OW??%vq7Sr9WaaS`GU1SRTy*2JwraH)!giJEkkxX@H0ztHr+;H0n->givrZPpl zCC=Cu2jpi%y#S6SS?J~31q=D8WeFv=nL>#q_fCWcE?Bp0q1Zq__?9qc)qQKDZbatv zFL)TQ&$siSe;TCe5%%imvi139#)U!{C3V1`JtY{Hd)$`-9)h;HDjRhRi`mL(zHSl# zgVYj_57&n8l4hjMW_4NaoO~X^BMN|&0e(=~M|X`gkUgUlx)03FmEBrL4CeY!VqV@t zLohU~>lwXX9ktc7PMIgvjSj{iJV&+FoJDbS7R8McW!}Lz1f6In=}fZwh)vmAgM=Ln zgxI3VHH-*dqbRW~bH3WbH*69kV|Dy$*~GVK;3d_NpfJ^9Q?Te&!8PuPQQk)R0y)oS zLK~p8XTfhz!DpaR>v|LseEDH|6pb>V%o4jB|M+J;cBSq_zR8Fgyn z#be#fcn>$n?fE8U;YCLCovQf=It15|vk%S{C$D_lE3cGg=Z%wZg_lki-|@=pqxR%( ze)5yM+{F*^yFqtfy9PeCy`1+?e%s5hT)pnP#k);ZSGJYmWpoliR9wven@2N=!HUiK zN=YtC5f8(S9C{z|H#q^0vDlJ^>W&~5L@=HmxE#He9- z+Or(uEXE|Ivp_p&n+0hbT2;%B9^j0C8f~*6H;e5$s`l( zW;Cv`TFKB7=l72X;?@Bj(XG@P9hAGMwZ#q8tJT_lNv%yf-PR?(NoloqKLJj00HFYABR@>cP9eL))+zbqJml^48Z%CD_f(%AR|A< z*jhF`Qaq$_ZC#-9(TC<>C@zweLcbk|r){e`>!|m^K=Kc;U8Ox4G@H_>dTUpm$RM_< zKJmsb+N~mJ!^&NLkWv6O2DZPO_E9gb^^%FkwggU(+83B&h{ z+gQsPe1K(}7f?acyeZG3JN$RS0dK5$8vi(`=f{0eXeU9-wh~u}9xPuRuvp!IsxDbc z=#K5JKt#!{+P;6hy%OT>*i@KI9_{alP1WO0HjPBsjZNRdsAddnt$b}685{O^F60IO z1pO&gcp{rjwh^T>YlJ6nM#gJZ-~1o}NzI({o}q1RhZ(_q9+PC`>|Bg)d2g9RCCOGD~6resHbK*M~=IzwN_F0?dJ5x}1Mx+>j_V&|$|MTQG^6HmkjfH`xG8Fw=k#612E3Sx-eG$v*) z(wNla&M^gz$>DdEVcO7R8qw*oukzB)A#Kd(whs56F9E z&ye>7c~6iR(V{$_%D9T!jLD)DwGrzxkHhm3a%TJzZj5U>~>qdwV=MfU$4G)MX z#c0DAAX%u2b){YvJ1BRXi*ZpKBuLHJ)OmR#g9peL@P`T7vN0rC3IuuN))rC=&h^{+ zVrn}ej5r6w(V$|Z5H-x^{{}IO)Cf>2YX)M;VGQ@!n;@lxt+S(lBd?-HEuoH48}lgm z{|Vdm^meG5)+AWUU&L&0huFZ& za=-N72Ob_Q6^F=_tjQ4Qo3;S*NvN3oqU<+RBhLupznAi&F=0R%KD)W-wEU(Cu- zDjm^hZZbyV(R3qbAX5O71EGdOp|br)3NBPrAt#9o^4U<)B3C1lD?x*agiJky#{8L} zaxwt_oKg(JNdfS@0Dz4~sXF$BF(CY08q9)T$GS+*QwBx^ z7t-%atV>Dao^mdtfcGCN$+VNnym&y-g&M%??Z)VASk9XnyC;GmAo@!#;}!DZZY$3b>!wkX}$HYD1HMq6N8@NRzS)`zf_7jpk|Ug5Q9aoFHq;AI?)$sz~ixDy%NUTtv)?VqOMQe(p$2f&!-f^&1@$l^2pG~^~gkoIvjh! zbd1!pD2psLUKhYCy1n-98e*Lp?@k#C^BpmVd`v2pDQ6=VvEaeph!|rO6T;osGW24S zwr2I7_4!)@i{P*OCvQYuSyT;JgGB7tsO-V=Ii`2QIr*-%EE(7q&u+&cu`&O4!C+Up zI|ApfypJwCQ)3Vf2(j>?Z{mG0A*gs31io!NOSYtrXQN^S@+()ahT}oyT_o+4d~iT( zSv(PXWeb$anxs(?iC=l)Vzs>0M z4is%k#(`ZPzi5i-r*JOL`!=f zs-|jAQXNhP0w*;o7#4V;>3L7NFif>DRj@V6xZ0}i`g|i~fp`l|@*1oXq)8NEQop0B zI5iL-^(gAZT~D4GlMrn7krjxiOts<-4$O(jEn`ptGHDW1%CuKD$>^!IsMARY1EFTG zk?wz;eT&cDdEW(@fawrp(wDp>lhMqtX^ur6jz&e3jFB<>)@_;@)(y~ ziWK-!#vdXTO)TQKai9(fyb{*wj|zTuT#}2Xf^c_69g>3RY&j#uq1OiJ16m|f*T|-= zy@6F~X-0wHJ zDA`4NOdU}SqEN7*_%U&YCX`8_ z4rRGr46Wy|K8~~Y^Pn_H&9obo8&h%$5)=2*8xTjKvx;gUb6m9hFKa;4(BStYyt~|th z{iE3dUgdDR!Y)S91Lh6@I;1W;HOG`47{)=j68;pngp_J48>;ajl96g^rN_xC^SDsF zNP=826~F=}2qXDH=2vAEeL>KZXU;9=*ZSo?m_!foG!HP7+vX89&i|yP)1!yNb^o_B6?Z>nGh*IKdHZ zm9IYdJrPbW1aOvq44gN_KOr15^KC+yPIFv{t?NhkYX$JV(YSlmExbU(4#RMNxkVOw(8X|nM(8AVE`m%9$o2Dq#_k6FH?~UcNM4R!#j8c z7lu$kO+13Vvkw8VFo;`JF6}yeVRZzkP~+(5YIqEWM9?JYV&~NAJka%t@;c5w#|582 ztx6rx_bIqMV#c$=-wlRnW1f3S!_P@Frq2|mK*4}8+k<74D zLb;X(K}PA(8RVdwBXVGsSVZ%wZkS6|OdTvQZ*WbM?IN9Xuemextk?e{9lvOhd zkiw6H0AqS`UhbIW?n=^kOA5e-DXp^f4yGhX3WyCQIny2`)V_vWDUcfGKkSGYuaHq- ziKW(ibq*Ipv7gV-Oo?9wx?ZW4)+w>oOOE{$4_LV}z&ws^4gwJ)G83*DA`NPGhG-6= zfvqOkf%-a;gtwmPQ^ki% z`~KqZ4*gU_N?lgXAJZcm=IbFQcCP)5wmTq5sD@nauT{@q)KLloKVqCchmq5A##~t- zJxnmcN-EZ}PzRoSiUMA&mL<3VeoSh)GtNjQ)X%r77t8$PTAD2FYs$!|p#Y9yT(Pnv zSR8y7TWXJmSLkuAE40prg>+>A>orq@4$r-WYX+(co1^zpE$f@SpKV>F!Z>3Y;l-yl z0t9wDn83Hu{3>3C0@Z9t?9Q0Sq|lffI3C^|dcY+M~f5qI=V8T1TN+fx+pXYB32m zXRNmn!->M_N%{hmGS?a=8+-sg0JNFc2cjqtGhBTRY!N}(^kk4U>neYkL|`UX=nN>7 zDXK-tE^c(cyekNBNeU&tU5ALHT8fa92jTyQ@5%?^ahZ;`tcxd3wFN*{{m5nIa>U)R z!t(@oGk8fFUc92==L}t}p5t6Yan@+z(pK`X*t&zM0fM<^^-W^i=bjpeb%jX$V5xES zt!sTU{NF=bb!=xjp7=cY%C!=EZy4DqFW3B=pA|01(!tu zRS;`A?Yo}CuSaIt8R0=D=*!lD5kjSu3nZ}B0wtUDO&eH^va^*WVY6%_6yOs+(0C;q zvjC4|bw%c4WtPw|-XkMb(g08-H3E77Kw$=8z{CZ6kBfa{A4MglluvL>Y`dmK2rW*GBo;?RnhR2S0@-+mb?7Sci@to*_sL*Pyr3VlTh?O(~1St4F)N+V2 z;C&aQOH8Bes&s7%6vBe*nQ#X_Fdk_MCf$NSE&-JNE*hIaHqlL12PzrJMuPG#G*y0? z=3e_*i@KYR=N*8*GmLZJV#pu}&2jRwEMho$<*IV%PQ~O_`?~)*kbyNCtW_5-R$uw-CD2h_Df?qAl(HRUkvc5P)V>1k2?Kn#P?l-(^UXp?W&KUbM1hdOs_hOwLwew7 z_PGKEhul#XCpX5*so0?gq5@~VSP@f7U35jRuFmn9STK(Vz&Qk#I8ahGMq^xNp|O}{ zf(+I_DC-3;Df5HQT$lA$0w!N)-I;i$WOo;&#R!nY_hx}qa%4n`T2v519*?qPnSLt% z@nKtZhLfuqdBQ3Zkn1HF(N!!7utp#Wq)KMwJ!7wPlG4Q08b!`>shF!Y#aMSKk8@pM zHP%_gG8}6pyiLz=z8+_^3{OQ%HK+i#47Hd|6w$D*UCpVrBaxwWu<0zOW zW{RJacFfFgVwKEtoWR?kkv^D^Q?}_diqYz>c_I=CtR*7Ffx{J|535+@W>3fy2OGT* zw262KkPblp)S`^UP@GysGI0BNehpAmY+u6Xk^`9Yi(FEP@#l3cYKCXKjAGIff{Gu& zpzN+_DHuDsAJlLw1VUX&1uv4`!iUi0PXY4S;T)m7J&*Ju(aO5CKEwC_5oolWcru(2UqW1}>8?ykY?;`b0B~t90WsLN# zy#zq^z}<^{Hl}SrtYILTxEl=4l4w;MxKq+9;Tc_7YDlzd7NiN!&PFjF2Fc5FhaI+`>(si+wg;>yB7Bwf+T(chdw3wfWNFUrLN_e{V0 zMb$#47iAmPoFTPXis9k9i{5an%;kJ^Wo5`GV|!%J27qGQr!{(0=x9BY-;9qKU1xL! zj2&4{uAfW~?=7h+A1b*e+0@vW`C5^U>=_pu`c#Wb8Nh%K z9zcQn75kfx+6duf$O*sWfK(*RGfPImqIU_4H$;|nLq!O@g^q(~PCFUV39)ED-|4hViNRm+hYsQ^Qw}Z>IS{}*1eaY(u|ZaS z6aVkxQOZIvv7n4fQ>l_+4W7mVx#1)`b6FVL%q#?Z& zM=m@#n*gv<^H@i#Rl=g{BzoLkANTYcDnJw@zF)$w_mWD}^5Uq{r1PU2Bee?k+tu%4 zZE94~oa^ksT6Gt`6QGKN31~yb_Fq=Xhx0EKV3S)+hF#-SZb&pMKxZ40C!3<4H1qKV zWQkf>dmVX&{uL^Sy>w9K5P-F(jppvC4(DNEvXK~0KiT-9R?Q$!EY8~NnIK$V!>%mX zFw5B^O5_)?J6TR7f%lVhnM7X)1&`Prvz%6Yzty(pf#on}*9S3TIllx}x3L_)#th3z z>yVAq%#K-(EhVNB!J?kTazF&jMJcw%x-rYOV7bePlILVE+h!a9M&j=p=v?UY_0~2?CPp?FDvP%oW?~9LQE|=VG<&kS|^*> z0oao~$P^+7?lB2Mjvye&2tpR4c?`Lud6^84dnyPh>DtDPLcRhXaQKvW+NN-EJ~pT%&Trkwl}pYe?3HszQ2UGtf5O!*9^+0JLw?(O6=l`};)#Ll+QFr zEfQbjGsHX3CE2G z&IeoCi6I*@Ct{~tt=J7M+0}}MCYq(X+~^R6HJQs(BPi5CY{dDo4mmL(RLi=n&6(U0(-k(ZJZdFnMoI1>FPdHZe=865 zmZ!}_09I;>PoS|>6hJ8HVebG*%)ZQu>Nl>3bOPnpJmA4lvqbJV5ivAsx_pEy3^tlsoA96EHN;@G>^`&O9vT`GCetW;VF^QX5CQjr zox5p2zZmxk6V|5xsz;f_a!!-ru>W4IUFem(@9nfWQ`H_jt+YX}wr;D!XhFUw4^l{X z{e!*__Ir{*>R095Xbu^y`#mmn=!d%Os&gl2pF^n|= zDmIeVbpz_l4G3pkoGmk|$1A>Krif_KAbYTcOgM-FP2hK_;=@0UL+CODhV4PHX_;i? zR(5~m4K7OmDXFQ;(zx^GtvYBa3L_a)&ZMV_0u&t=mUlFtF6*&=d^!!Qt6_Dg!}6Y0 zscUY;rl{WA)-n4Exv7?$Qus^V8?GTH(+@c*pbbh_B5J7n12~O)Qab!Q1Hx9R~J}mrAl*(1mE; zqQNd#!s60~b}B-jA%rMT$=*JWlp?YV*7|6Vv_*t|1Q?TwYq()NuzxH;T~tnf?r3(9 zLdH2RQ1i%P5zWG3IP$hF>HsNcgHxm*_*6{Nim#v<^a=;P!hu)7hQt+}E3jSpwIs=q zWn{M_pMfGVgA|8!mR=~weNZGe;D1!M7^YRuqps#lD!EWs^HNtGek^TFRJIg5+Z2=> z92zEAw`nBxWOY>b4i{Kw6X$S&?Upv;8n)XuFe)@XODP3AQDpncV$Biy=O-ck$q?$0DC zps-xk7W=mgw;PxUH>j3yvzOCsA0@e{4E$3d%HL>oIN?>+6GYDCd@vr$mJT5dTh2-` z(M+j=3k3!uOkafQGk6zes%JLnLS@`=lM;Ba?8{W5CanJJ9#tpmYoJ*e5Jn|HRJ9;p zvK1sp<5;#SLk)t<)niTTN|c&RY!UHA@)VG z9*3n;PfQPJSJfO<5=R;vA*ZS$iv%HKYosD>FojdCa7*62z{Dr1=&Mm~j$MiWF~3K1dz@_`7%3L-hW@>~^+u&>(R(++Ai68Y*%YIKll zL6jvWfg$lkQe{xoqZJHhN@P#G0ePtc{{S3BzyvU`Pxmn(8w=(L zx@wCiuxIu$P)L$eGPsiiK@fZNVqSUNq@~c&rJ^=X6_dEpjDc+uOp4B1cfFoPy#L!x zVv*dLl%v^FdB`*8QG2nP zs_j_gP#h^9(!b>}#cPuwDw<4OH8Fg_%QPLcYkPF)jQ5uNUSC^NFe>zuC5xN+YWjjJ zay|Cw6^8u?!rFVIT+nq~sB)iFDI2%0#XWLI`h&h!6ucudxILs)1qIPIW^k4pLBYXTnA`#`rUGW^I`f&KL{|tJa~^bn3X$oV zh#_ycqehS`s84KQGATipqoXZ>nWrLW7;R!+?voEAGS=c#zY8TDup7EA00-5*yL;ZWJ!ASIp@9Jl36&r@oF*&^awO8e9E z&LRT?c3%L;jR}3a@6DPg7hW1KzD@$RXHv0O?&1s1+bz8GGR`bHNG%YNwwBSJi@S^! z(Y9B)Z)lCT9Tv8vdIUa1guEfF!ia(WA~9^0_5WtW-<_K5;u&T5)oz@V#d==}@f4uH z(XBE74SR}c5I?PjHn2kV>0Wg5$%$3pp!%3BiWXk*@bUc9J+Xe^$JdD6xqzmrzB)O@ zlQw#|L9y>i0+CWUU2&m;_1H(Wv{-o;NXz^k1_7a?mQLCi^(Xwh#yZ_qjDz?pwekdq zwi}ejI2gfTA0)-T^zkHIt+mmpP<}m4>DMFLejuyZ9~p5n^iRjb{guo3l(zIm<r3xN0Gg>5RTaQ^`QH3AU)13-E%C+ zzFez7<&txS(puri3mvW6LXc5OovL-QVu={&#A^=KPj=THnrq!I^~8#>BP>2*4@{nG z!Ul7y&tT3rIS#cTwQGuGZYTP}GCaW)wdfEYJ>ciQQ;Vpo zuViaH+gMDvZ)c zo^qPgzk2(arefFT7qY;2=>1QTH=7Nw?Gg0o26QXtg2iL@mtN(!ZK%f{9n3bFWo zFE2#rdBj46h^x88DpJ5Twj-{;9)|}+D8QE4NL-?+uhZz?6@wUcaibI-fB8i{GyWq*~F#TOWiJXd;#J_&>*e-4UGvoVMY7>|zJWOfe z?PV8?i1UPCBNr_X28G;C!i<9j?ST?EL!ZI1Crg$o>!(t*{xYJ$#Ic!L%xoIUV3W*-8|CHsZt^ z=lM~MbZI_>fgl1e72UK@4#)WLa@K9x;5eoPO0%BUEvcFNL~El3B+JluNVDjzM-=ug z^dV(E9^RCrBZtx!QMp(_v;JeOCu}(iJcC9Rn=nrzrwV`=7fm?iw@R1v z5{tQk$RN;++ILIXm-whAcpI0I5i!Iy>A9|AHH|vZGL(+AedV&e=z)I#)Rn z;NTOAN^uzj$pJ>6tIm!twWtaP_tK46XBYSO7aUm`=EAmdQGZl6Vx1l1Vu=rRb|iw* z41IhhIhrW$G((>=IK(%4#XM8b&=a16EZvaTtQ(9)3-DQrX%hyP9sH4ZP~0*hC&fD3$VIq0DSfT$HpN4+eOLoGisfxJ9uP`p zkbGG5RCvuL*EM@xRp+$XS+KQ)q=Zc~0~-rDL4cTyp@_*i+?>hasqIV_5gD0`$~iX! zlTDDok{LI;3%{|6%ap?~cmG=Wjj_RRba_3$32l-7H{~~mIKyvERfN?1#$a710cFkW z*Yg|K7h^hT8^4KVYC=yaLU=!se6k|xhdB@)yD1OKA>C1e_pe&@nWic^3;>o9>mUv! zUb+M6ekVnr7AGp=_`mZANmyv1+4~}hCni?~N$NXjEh8L=LBtNgXi{s+c42AhLi6<~ z2hZxK@pF(?jMd>#Oz6PMNgxZ!rPhM;N{yqLx*2?fQpq&7)Gss2Hp_nhZx^8>(~-~Y zjJITncz8gZ9MM5FJq*RABl>d;G*G+`+N9+%y#8j4ci44-wkGt*q^DM) zFg@|KZ{JOu$~IAfkSR|c;1Z_la$Fm(@RJL`rIHtAgbsLnCQ<(FhAPiUzLmmJnMmLh zeX+M1f!bt(nr$Cs*##B%o7}(ASUseYf)2)t>}#B%?A&aephhq#x#sPNF7|(Gk}(*P zNMjISCf5Dvj5WV9a)-v=-Gg#z^njR!Ggqf%Iv&Io5jz%J6)Z)=v3vl;P+e#%$SyJk zf&<2_HN{}K?b^YC_iWejqKaj(J(Cqi9>l6a9$&cFA8RKebJX?+C#h{e7_-@cd2kd2 z?IAB(MrMQ_@4UyS1aaKl8ptr#EZOwV!Z0wd5*~qpB}A0T^7`lv4HzzBKnV�wN$k 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 z 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 Date: Thu, 11 Jul 2024 16:50:50 +0200 Subject: [PATCH 24/37] Use published `@vscode/tree-sitter-wasm` package --- package.json | 1 + yarn.lock | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/package.json b/package.json index cc00db38c76a7..a847b63fcd88a 100644 --- a/package.json +++ b/package.json @@ -78,6 +78,7 @@ "@vscode/spdlog": "^0.15.0", "@vscode/sqlite3": "5.1.6-vscode", "@vscode/sudo-prompt": "9.3.1", + "@vscode/tree-sitter-wasm": "^0.0.1", "@vscode/vscode-languagedetection": "1.0.21", "@vscode/windows-mutex": "^0.5.0", "@vscode/windows-process-tree": "^0.6.0", diff --git a/yarn.lock b/yarn.lock index f31bd180a3b9b..80704e7a43bdf 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1666,6 +1666,11 @@ tar-fs "^3.0.6" vscode-uri "^3.0.8" +"@vscode/tree-sitter-wasm@^0.0.1": + version "0.0.1" + resolved "https://registry.yarnpkg.com/@vscode/tree-sitter-wasm/-/tree-sitter-wasm-0.0.1.tgz#ffb2e295a416698f4c77cbffeca3b28567d6754b" + integrity sha512-m0GKnQ3BxWnVd+20KLGwr1+Qvt/RiiaJmKAqHNU35pNydDtduUzyBm7ETz/T0vOVKoeIAaiYsJOA1aKWs7Y1tA== + "@vscode/v8-heap-parser@^0.1.0": version "0.1.0" resolved "https://registry.yarnpkg.com/@vscode/v8-heap-parser/-/v8-heap-parser-0.1.0.tgz#f3fe61ce954cc3dd78ed42e09f865450685e351f" From 8c7116ccbe7cbfd8a11b1adabdddd7c147672e0b Mon Sep 17 00:00:00 2001 From: Alex Ross Date: Fri, 12 Jul 2024 18:38:44 +0200 Subject: [PATCH 25/37] Break `TreeSitterTree` and `TreeSitterParserService` into better pieces and: - document the order of editor changes - use service injection where `TextModel` is constructed --- .../treeSitter/treeSitterParserService.ts | 349 ++++++++++-------- src/vs/editor/common/model/textModel.ts | 2 - .../common/model/tokenizationTextModelPart.ts | 4 +- src/vs/editor/common/services/modelService.ts | 13 +- .../services/treeSitterParserService.ts | 11 +- src/vs/editor/common/textModelEvents.ts | 3 + .../browser/peek/referencesWidget.ts | 8 +- .../browser/documentSemanticTokens.test.ts | 3 - src/vs/monaco.d.ts | 3 + .../mainThreadDocumentsAndEditors.test.ts | 4 - .../test/browser/mainThreadEditors.test.ts | 4 - .../bulkEdit/browser/preview/bulkEditTree.ts | 8 +- .../services/model/common/modelService.ts | 6 +- ...eSitterTokenizationFeature.contribution.ts | 4 +- 14 files changed, 216 insertions(+), 206 deletions(-) diff --git a/src/vs/editor/browser/services/treeSitter/treeSitterParserService.ts b/src/vs/editor/browser/services/treeSitter/treeSitterParserService.ts index 097fd3fb21dbe..882fffebf8ada 100644 --- a/src/vs/editor/browser/services/treeSitter/treeSitterParserService.ts +++ b/src/vs/editor/browser/services/treeSitter/treeSitterParserService.ts @@ -9,10 +9,10 @@ import { Parser } from '@vscode/tree-sitter-wasm'; import { AppResourcePath, FileAccess, nodeModulesPath } from 'vs/base/common/network'; import { ITreeSitterParserService } from 'vs/editor/common/services/treeSitterParserService'; import { IModelService } from 'vs/editor/common/services/model'; -import { Disposable, DisposableMap, DisposableStore, IDisposable } from 'vs/base/common/lifecycle'; -import { ITextModel, ITextSnapshot } from 'vs/editor/common/model'; +import { Disposable, DisposableMap, IDisposable } from 'vs/base/common/lifecycle'; +import { ITextModel } from 'vs/editor/common/model'; import { IFileService } from 'vs/platform/files/common/files'; -import { IModelContentChangedEvent, IModelLanguageChangedEvent } from 'vs/editor/common/textModelEvents'; +import { IModelContentChangedEvent } from 'vs/editor/common/textModelEvents'; import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { ILogService } from 'vs/platform/log/common/log'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; @@ -22,146 +22,143 @@ const EDITOR_EXPERIMENTAL_PREFER_TREESITTER = 'editor.experimental.preferTreeSit const moduleLocationTreeSitter: AppResourcePath = `${nodeModulesPath}/@vscode/tree-sitter-wasm/wasm`; const moduleLocationTreeSitterWasm: AppResourcePath = `${moduleLocationTreeSitter}/tree-sitter.wasm`; -export class TreeSitterTree implements IDisposable { - private _tree: Parser.Tree | undefined; - private _language: Parser.Language | undefined; - constructor(public readonly parser: Parser, private readonly disposables: DisposableStore) { } - dispose(): void { - this._tree?.delete(); - this.parser?.delete(); - this.disposables.dispose(); - } - get tree() { return this._tree; } - set tree(newTree: Parser.Tree | undefined) { - this._tree?.delete(); - this._tree = newTree; - this._snapshot = undefined; - this._snapshotChunks = []; - } - get language() { return this._language; } - set language(newLanguage: Parser.Language | undefined) { - this.parser?.setLanguage(newLanguage); - this._language = newLanguage; - if (this._language === undefined) { - this.tree = undefined; - } - } - private _snapshot: ITextSnapshot | undefined; - get snapshot() { return this._snapshot; } - public createSnapshot(textModel: ITextModel) { - this._snapshot = textModel.createSnapshot(); +class TextModelTreeSitter extends Disposable { + private _treeSitterTree: TreeSitterTree | undefined; + private _contentChangedListener: IDisposable | undefined; + + constructor(readonly model: ITextModel, + private readonly _treeSitterParser: TreeSitterParser + ) { + super(); + this._register(this.model.onDidChangeLanguage(e => this._onDidChangeLanguage(e))); + this._onDidChangeLanguage({ newLanguage: this.model.getLanguageId() }); } - public clearSnapshot() { - this._snapshot = undefined; + + private _registerModelListeners() { + this._contentChangedListener = this.model.onDidChangeContent(e => this._onDidChangeContent(e)); + this._onDidChangeContent(); } - private _snapshotChunks: { chunk: string; startOffset: number }[] = []; - get snapshotChunks() { return this._snapshotChunks; } - public addSnapshotChunk(chunk: string, startOffset: number) { - this._snapshotChunks.push({ chunk, startOffset }); + + private _unregisterModelListeners() { + this._contentChangedListener?.dispose(); } -} -export class TreeSitterParserService extends Disposable implements ITreeSitterParserService { - readonly _serviceBrand: undefined; - private _init: Promise; - private _treeSitterTrees: DisposableMap = new DisposableMap(); - private _languages: Map = new Map(); + private async _onDidChangeLanguage(e: { newLanguage: string }) { + if (this._treeSitterTree) { + this._treeSitterTree.dispose(); + } + const language = await this._treeSitterParser.getLanguage(e.newLanguage); + if (!language || this.model.isDisposed()) { + this._unregisterModelListeners(); + return; + } - constructor(@IModelService private readonly _modelService: IModelService, - @IFileService private readonly _fileService: IFileService, - @ITelemetryService private readonly _telemetryService: ITelemetryService, - @ILogService private readonly _logService: ILogService, - @IConfigurationService private readonly _configurationService: IConfigurationService - ) { - super(); + this._treeSitterTree = new TreeSitterTree(language); + this._registerModelListeners(); + } - const setting = this._getSetting(); - if (setting.length === 0) { - this._init = Promise.resolve(); + private async _onDidChangeContent(e?: IModelContentChangedEvent) { + if (!this._treeSitterTree) { return; } - this._init = Parser.init({ - locateFile(_file: string, _folder: string) { - return FileAccess.asBrowserUri(moduleLocationTreeSitterWasm).toString(true); + if (e) { + for (const change of e.changes) { + const newEndOffset = change.rangeOffset + change.text.length; + const newEndPosition = this.model.getPositionAt(newEndOffset); + + this._treeSitterTree.tree?.edit({ + startIndex: change.rangeOffset, + oldEndIndex: change.rangeOffset + change.rangeLength, + newEndIndex: change.rangeOffset + change.text.length, + startPosition: { row: change.range.startLineNumber - 1, column: change.range.startColumn - 1 }, + oldEndPosition: { row: change.range.endLineNumber - 1, column: change.range.endColumn - 1 }, + newEndPosition: { row: newEndPosition.lineNumber - 1, column: newEndPosition.column - 1 } + }); } - }); - // Eventually, this should actually use an extension point to add tree sitter grammars, but for now they are hard coded in core - if (setting.includes('typescript')) { - this._addGrammar('typescript', 'tree-sitter-typescript'); } - this._registerModelServiceListeners(); + this._treeSitterTree.tree = await this._treeSitterParser.parse(this.model, this._treeSitterTree); } - private _getSetting(): string[] { - return this._configurationService.getValue(EDITOR_EXPERIMENTAL_PREFER_TREESITTER) || []; + override dispose() { + super.dispose(); + this._treeSitterTree?.dispose(); + this._unregisterModelListeners(); } +} - getLanguageLocation(languageId: string): AppResourcePath | undefined { - const grammarName = TreeSitterTokenizationRegistry.get(languageId); - if (!grammarName) { - return undefined; - } - return moduleLocationTreeSitter; +export class TreeSitterTree implements IDisposable { + private _tree: Parser.Tree | undefined; + public readonly parser: Parser; + private _isDisposed: boolean = false; + constructor(language: Parser.Language) { + this.parser = new Parser(); + this.parser.setTimeoutMicros(50 * 1000); // 50 ms + this.parser.setLanguage(language); } - - private _registerModelServiceListeners() { - this._register(this._modelService.onModelAdded(model => { - this._registerModelListeners(model); - })); - this._register(this._modelService.onModelRemoved(model => { - this._treeSitterTrees.deleteAndDispose(model); - })); - this._modelService.getModels().forEach(model => this._registerModelListeners(model)); + dispose(): void { + this._isDisposed = true; + this._tree?.delete(); + this.parser?.delete(); + } + get tree() { return this._tree; } + set tree(newTree: Parser.Tree | undefined) { + this._tree?.delete(); + this._tree = newTree; } + get isDisposed() { return this._isDisposed; } +} - private async _registerModelListeners(model: ITextModel) { - await this._init; - const disposables = new DisposableStore(); - disposables.add(model.onDidChangeContent(e => this._onDidChangeContent(model, e))); - disposables.add(model.onDidChangeLanguage(e => this._onDidChangeLanguage(model, e))); - const parser = new Parser(); - parser.setTimeoutMicros(50 * 1000); // 50 ms - const treeSitterTree = new TreeSitterTree(parser, disposables); - this._treeSitterTrees.set(model, treeSitterTree); - this._setLanguageAndTree(model, treeSitterTree); +class TreeSitterParser extends Disposable { + private _languages: Map = new Map(); + + constructor(private readonly _fileService: IFileService, + private readonly _logService: ILogService, + private readonly _telemetryService: ITelemetryService + ) { + super(); } - private async _setLanguageAndTree(model: ITextModel, treeSitterTree: TreeSitterTree) { - const languageId = model.getLanguageId(); - const language = await this._ensureLanguage(languageId); - if (!language) { - return; + public parse(model: ITextModel, treeSitterTree: TreeSitterTree): Promise { + let telemetryTag: string; + if (treeSitterTree.tree) { + telemetryTag = 'incrementalParse'; + } else { + telemetryTag = 'fullParse'; } - treeSitterTree.language = language; - treeSitterTree.tree = await this._doInitialParse(model, treeSitterTree, languageId); + return this._parseAndYield(model, treeSitterTree, telemetryTag); } - private async _parseAndYield(model: ITextModel, treeSitterTree: TreeSitterTree, language: string, telemetryTag: string): Promise { + private async _parseAndYield(model: ITextModel, treeSitterTree: TreeSitterTree, telemetryTag: string): Promise { + const language = model.getLanguageId(); let tree: Parser.Tree | undefined; let time: number = 0; let passes: number = 0; do { const timer = performance.now(); try { - tree = treeSitterTree.parser.parse((index: number, position?: Parser.Point) => this._parseCallback(model, index, position, treeSitterTree), treeSitterTree.tree); + tree = treeSitterTree.parser.parse((index: number, position?: Parser.Point) => this._parseCallback(model, index), treeSitterTree.tree); } catch (e) { // parsing can fail when the timeout is reached, will resume upon next loop } finally { time += performance.now() - timer; passes++; } + + // Even if the model changes and edits are applied, the tree parsing will continue correctly after the await. await new Promise(resolve => setTimeout0(resolve)); + + if (model.isDisposed() || treeSitterTree.isDisposed) { + return; + } } while (!tree); this.sendParseTimeTelemetry(telemetryTag, language, time, passes); return tree; } - private _doInitialParse(model: ITextModel, treeSitterTree: TreeSitterTree, language: string): Promise { - treeSitterTree.createSnapshot(model); - const newTree = this._parseAndYield(model, treeSitterTree, language, 'fullParse'); - return newTree; + private _parseCallback(textModel: ITextModel, index: number): string | null { + return textModel.getTextBuffer().getNearestChunk(index); } private sendParseTimeTelemetry(eventName: string, languageId: string, time: number, passes: number): void { @@ -176,46 +173,21 @@ export class TreeSitterParserService extends Disposable implements ITreeSitterPa this._telemetryService.publicLog2<{ languageId: string; time: number; passes: number }, ParseTimeClassification>(`treeSitter.${eventName}`, { languageId, time, passes }); } - private async _onDidChangeLanguage(model: ITextModel, e: IModelLanguageChangedEvent) { - const tree = this._treeSitterTrees.get(model); - if (!tree) { - return; - } - const language = await this._ensureLanguage(e.newLanguage); + public async getLanguage(languageId: string): Promise { + let language = this._languages.get(languageId); if (!language) { - // not supported for this language - tree.language = undefined; - return; - } - tree.language = language; - const newTree = await this._doInitialParse(model, tree, e.newLanguage); - tree.tree = newTree; - } - - private async _onDidChangeContent(model: ITextModel, e: IModelContentChangedEvent) { - const tree = this._treeSitterTrees.get(model); - if (!tree?.language) { - return; - } - for (const change of e.changes) { - const newEndOffset = change.rangeOffset + change.text.length; - const newEndPosition = model.getPositionAt(newEndOffset); - // TODO @alexr00 need to take into account the previous edits in the loop (text edits class) - tree.tree?.edit({ - startIndex: change.rangeOffset, - oldEndIndex: change.rangeOffset + change.rangeLength, - newEndIndex: change.rangeOffset + change.text.length, - startPosition: { row: change.range.startLineNumber - 1, column: change.range.startColumn - 1 }, - oldEndPosition: { row: change.range.endLineNumber - 1, column: change.range.endColumn - 1 }, - newEndPosition: { row: newEndPosition.lineNumber - 1, column: newEndPosition.column - 1 } - }); + language = await this._fetchLanguage(languageId); + if (!language) { + return undefined; + } + this._languages.set(languageId, language); } - tree.tree = await this._parseAndYield(model, tree, model.getLanguageId(), 'incrementalParse'); + return language; } private async _fetchLanguage(languageId: string): Promise { const grammarName = TreeSitterTokenizationRegistry.get(languageId); - const languageLocation = this.getLanguageLocation(languageId); + const languageLocation = this._getLanguageLocation(languageId); if (!grammarName || !languageLocation) { return undefined; } @@ -224,40 +196,111 @@ export class TreeSitterParserService extends Disposable implements ITreeSitterPa return Parser.Language.load(languageFile.value.buffer); } - private async _ensureLanguage(languageId: string): Promise { - let language = this._languages.get(languageId); - if (!language) { - language = await this._fetchLanguage(languageId); - if (!language) { - return undefined; - } - this._languages.set(languageId, language); + private _getLanguageLocation(languageId: string): AppResourcePath | undefined { + const grammarName = TreeSitterTokenizationRegistry.get(languageId); + if (!grammarName) { + return undefined; } - return language; + return moduleLocationTreeSitter; } +} - private _parseCallback(textModel: ITextModel, index: number, position?: Parser.Point, treeSitterTree?: TreeSitterTree): string | null { - return textModel.getTextBuffer().getNearestChunk(index); +export class TreeSitterTextModelService extends Disposable implements ITreeSitterParserService { + readonly _serviceBrand: undefined; + private _init!: Promise; + private _textModelTreeSitters: DisposableMap = this._register(new DisposableMap()); + private _registeredLanguages: DisposableMap = new DisposableMap(); + private readonly _treeSitterParser: TreeSitterParser; + + constructor(@IModelService private readonly _modelService: IModelService, + @IFileService fileService: IFileService, + @ITelemetryService telemetryService: ITelemetryService, + @ILogService logService: ILogService, + @IConfigurationService private readonly _configurationService: IConfigurationService, + ) { + super(); + this._treeSitterParser = this._register(new TreeSitterParser(fileService, logService, telemetryService)); + this._register(this._configurationService.onDidChangeConfiguration(e => { + if (e.affectsConfiguration(EDITOR_EXPERIMENTAL_PREFER_TREESITTER)) { + this._supportedLanguagesChanged(); + } + })); + this._supportedLanguagesChanged(); } - public initTreeSitter(): Promise { + private _hasInit: boolean = false; + private async _initParser(hasLanguages: boolean): Promise { + if (this._hasInit) { + return this._init; + } + + if (hasLanguages) { + this._hasInit = true; + this._init = new Promise((resolve, reject) => Parser.init({ + locateFile(_file: string, _folder: string) { + return FileAccess.asBrowserUri(moduleLocationTreeSitterWasm).toString(true); + } + }).then(() => resolve(true), reject)); + + // New init, we need to deal with all the existing text models and set up listeners + this._init.then(() => this._registerModelServiceListeners()); + } else { + this._init = Promise.resolve(false); + } return this._init; } - getTree(model: ITextModel): Parser.Tree | undefined { - return this._treeSitterTrees.get(model)?.tree; + private async _supportedLanguagesChanged() { + const setting = this._getSetting(); + + let hasLanguages = true; + if (setting.length === 0) { + hasLanguages = false; + } + + if (await this._initParser(hasLanguages)) { + // Eventually, this should actually use an extension point to add tree sitter grammars, but for now they are hard coded in core + if (setting.includes('typescript')) { + this._addGrammar('typescript', 'tree-sitter-typescript'); + } else { + this._removeGrammar('typescript'); + } + } } - getLanguage(model: ITextModel): Parser.Language | undefined { - return this._treeSitterTrees.get(model)?.language; + private _getSetting(): string[] { + return this._configurationService.getValue(EDITOR_EXPERIMENTAL_PREFER_TREESITTER) || []; + } + + private async _registerModelServiceListeners() { + this._register(this._modelService.onModelAdded(model => { + this._createTextModelTreeSitter(model); + })); + this._register(this._modelService.onModelRemoved(model => { + this._textModelTreeSitters.deleteAndDispose(model); + })); + this._modelService.getModels().forEach(model => this._createTextModelTreeSitter(model)); + } + + private async _createTextModelTreeSitter(model: ITextModel) { + const textModelTreeSitter = new TextModelTreeSitter(model, this._treeSitterParser); + this._textModelTreeSitters.set(model, textModelTreeSitter); } private _addGrammar(languageId: string, grammarName: string) { - TreeSitterTokenizationRegistry.register(languageId, { name: grammarName }); + if (!TreeSitterTokenizationRegistry.get(languageId)) { + this._registeredLanguages.set(languageId, TreeSitterTokenizationRegistry.register(languageId, { name: grammarName })); + } + } + + private _removeGrammar(languageId: string) { + if (this._registeredLanguages.has(languageId)) { + this._registeredLanguages.deleteAndDispose('typescript'); + } } public override dispose(): void { super.dispose(); - this._treeSitterTrees.dispose(); + this._textModelTreeSitters.dispose(); } } diff --git a/src/vs/editor/common/model/textModel.ts b/src/vs/editor/common/model/textModel.ts index 5903008e32599..04f76ee800bd8 100644 --- a/src/vs/editor/common/model/textModel.ts +++ b/src/vs/editor/common/model/textModel.ts @@ -330,8 +330,6 @@ export class TextModel extends Disposable implements model.ITextModel, IDecorati this._guidesTextModelPart = this._register(new GuidesTextModelPart(this, this._languageConfigurationService)); this._decorationProvider = this._register(new ColorizedBracketPairsDecorationProvider(this)); this._tokenizationTextModelPart = this.instantiationService.createInstance(TokenizationTextModelPart, - this._languageService, - this._languageConfigurationService, this, this._bracketPairs, languageId, diff --git a/src/vs/editor/common/model/tokenizationTextModelPart.ts b/src/vs/editor/common/model/tokenizationTextModelPart.ts index 40c6c921afc34..30972f1a33bde 100644 --- a/src/vs/editor/common/model/tokenizationTextModelPart.ts +++ b/src/vs/editor/common/model/tokenizationTextModelPart.ts @@ -47,12 +47,12 @@ export class TokenizationTextModelPart extends TextModelPart implements ITokeniz private readonly grammarTokens = this._register(new GrammarTokens(this._languageService.languageIdCodec, this._textModel, () => this._languageId, this._attachedViews)); constructor( - private readonly _languageService: ILanguageService, - private readonly _languageConfigurationService: ILanguageConfigurationService, private readonly _textModel: TextModel, private readonly _bracketPairsTextModelPart: BracketPairsTextModelPart, private _languageId: string, private readonly _attachedViews: AttachedViews, + @ILanguageService private readonly _languageService: ILanguageService, + @ILanguageConfigurationService private readonly _languageConfigurationService: ILanguageConfigurationService, ) { super(); diff --git a/src/vs/editor/common/services/modelService.ts b/src/vs/editor/common/services/modelService.ts index 9e1dc62fc9bd6..00019d6f96197 100644 --- a/src/vs/editor/common/services/modelService.ts +++ b/src/vs/editor/common/services/modelService.ts @@ -14,7 +14,7 @@ import { TextModel, createTextBuffer } from 'vs/editor/common/model/textModel'; import { EDITOR_MODEL_DEFAULTS } from 'vs/editor/common/core/textModelDefaults'; import { IModelLanguageChangedEvent } from 'vs/editor/common/textModelEvents'; import { PLAINTEXT_LANGUAGE_ID } from 'vs/editor/common/languages/modesRegistry'; -import { ILanguageSelection, ILanguageService } from 'vs/editor/common/languages/language'; +import { ILanguageSelection } from 'vs/editor/common/languages/language'; import { IModelService } from 'vs/editor/common/services/model'; import { ITextResourcePropertiesService } from 'vs/editor/common/services/textResourceConfiguration'; import { IConfigurationChangeEvent, IConfigurationService } from 'vs/platform/configuration/common/configuration'; @@ -23,7 +23,6 @@ import { StringSHA1 } from 'vs/base/common/hash'; import { isEditStackElement } from 'vs/editor/common/model/editStack'; import { Schemas } from 'vs/base/common/network'; import { equals } from 'vs/base/common/objects'; -import { ILanguageConfigurationService } from 'vs/editor/common/languages/languageConfigurationRegistry'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; function MODEL_ID(resource: URI): string { @@ -108,8 +107,6 @@ export class ModelService extends Disposable implements IModelService { @IConfigurationService private readonly _configurationService: IConfigurationService, @ITextResourcePropertiesService private readonly _resourcePropertiesService: ITextResourcePropertiesService, @IUndoRedoService private readonly _undoRedoService: IUndoRedoService, - @ILanguageService private readonly _languageService: ILanguageService, - @ILanguageConfigurationService private readonly _languageConfigurationService: ILanguageConfigurationService, @IInstantiationService private readonly _instantiationService: IInstantiationService ) { super(); @@ -316,15 +313,11 @@ export class ModelService extends Disposable implements IModelService { private _createModelData(value: string | ITextBufferFactory, languageIdOrSelection: string | ILanguageSelection, resource: URI | undefined, isForSimpleWidget: boolean): ModelData { // create & save the model const options = this.getCreationOptions(languageIdOrSelection, resource, isForSimpleWidget); - const model: TextModel = new TextModel( + const model: TextModel = this._instantiationService.createInstance(TextModel, value, languageIdOrSelection, options, - resource, - this._undoRedoService, - this._languageService, - this._languageConfigurationService, - this._instantiationService + resource ); if (resource && this._disposedModels.has(MODEL_ID(resource))) { const disposedModelData = this._removeDisposedModel(resource)!; diff --git a/src/vs/editor/common/services/treeSitterParserService.ts b/src/vs/editor/common/services/treeSitterParserService.ts index d1dc0b059ab3d..e3e911efc497f 100644 --- a/src/vs/editor/common/services/treeSitterParserService.ts +++ b/src/vs/editor/common/services/treeSitterParserService.ts @@ -3,17 +3,14 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { AppResourcePath } from 'vs/base/common/network'; -import type { Parser } from '@vscode/tree-sitter-wasm'; -import { ITextModel } from 'vs/editor/common/model'; import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; export const ITreeSitterParserService = createDecorator('treeSitterParserService'); +/** + * Currently this service just logs telemetry about how long it takes to parse files. + * Actual API will come later as we add features like syntax highlighting. + */ export interface ITreeSitterParserService { readonly _serviceBrand: undefined; - initTreeSitter(): Promise; - getTree(model: ITextModel): Parser.Tree | undefined; - getLanguage(model: ITextModel): Parser.Language | undefined; - getLanguageLocation(languageId: string): AppResourcePath | undefined; } diff --git a/src/vs/editor/common/textModelEvents.ts b/src/vs/editor/common/textModelEvents.ts index 58c720ac87c09..7d63afec8e883 100644 --- a/src/vs/editor/common/textModelEvents.ts +++ b/src/vs/editor/common/textModelEvents.ts @@ -55,6 +55,9 @@ export interface IModelContentChange { * An event describing a change in the text of a model. */ export interface IModelContentChangedEvent { + /** + * The changes are ordered from the end of the document to the beginning, so they should be safe to apply in sequence. + */ readonly changes: IModelContentChange[]; /** * The (new) end-of-line character. diff --git a/src/vs/editor/contrib/gotoSymbol/browser/peek/referencesWidget.ts b/src/vs/editor/contrib/gotoSymbol/browser/peek/referencesWidget.ts index f44cec2d60dbb..6503b7df22079 100644 --- a/src/vs/editor/contrib/gotoSymbol/browser/peek/referencesWidget.ts +++ b/src/vs/editor/contrib/gotoSymbol/browser/peek/referencesWidget.ts @@ -23,9 +23,7 @@ import { ScrollType } from 'vs/editor/common/editorCommon'; import { IModelDeltaDecoration, TrackedRangeStickiness } from 'vs/editor/common/model'; import { ModelDecorationOptions, TextModel } from 'vs/editor/common/model/textModel'; import { Location } from 'vs/editor/common/languages'; -import { ILanguageConfigurationService } from 'vs/editor/common/languages/languageConfigurationRegistry'; import { PLAINTEXT_LANGUAGE_ID } from 'vs/editor/common/languages/modesRegistry'; -import { ILanguageService } from 'vs/editor/common/languages/language'; import { ITextEditorModel, ITextModelService } from 'vs/editor/common/services/resolverService'; import { AccessibilityProvider, DataSource, Delegate, FileReferencesRenderer, IdentityProvider, OneReferenceRenderer, StringRepresentationProvider, TreeElement } from 'vs/editor/contrib/gotoSymbol/browser/peek/referencesTree'; import * as peekView from 'vs/editor/contrib/peekView/browser/peekView'; @@ -35,7 +33,6 @@ import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; import { ILabelService } from 'vs/platform/label/common/label'; import { IWorkbenchAsyncDataTreeOptions, WorkbenchAsyncDataTree } from 'vs/platform/list/browser/listService'; import { IColorTheme, IThemeService } from 'vs/platform/theme/common/themeService'; -import { IUndoRedoService } from 'vs/platform/undoRedo/common/undoRedo'; import { FileReferences, OneReference, ReferencesModel } from '../referencesModel'; class DecorationsManager implements IDisposable { @@ -224,10 +221,7 @@ export class ReferenceWidget extends peekView.PeekViewWidget { @IInstantiationService private readonly _instantiationService: IInstantiationService, @peekView.IPeekViewService private readonly _peekViewService: peekView.IPeekViewService, @ILabelService private readonly _uriLabel: ILabelService, - @IUndoRedoService private readonly _undoRedoService: IUndoRedoService, @IKeybindingService private readonly _keybindingService: IKeybindingService, - @ILanguageService private readonly _languageService: ILanguageService, - @ILanguageConfigurationService private readonly _languageConfigurationService: ILanguageConfigurationService, ) { super(editor, { showFrame: false, showArrow: true, isResizeable: true, isAccessible: true, supportOnTitleClick: true }, _instantiationService); @@ -315,7 +309,7 @@ export class ReferenceWidget extends peekView.PeekViewWidget { }; this._preview = this._instantiationService.createInstance(EmbeddedCodeEditorWidget, this._previewContainer, options, {}, this.editor); dom.hide(this._previewContainer); - this._previewNotAvailableMessage = new TextModel(nls.localize('missingPreviewMessage', "no preview available"), PLAINTEXT_LANGUAGE_ID, TextModel.DEFAULT_CREATION_OPTIONS, null, this._undoRedoService, this._languageService, this._languageConfigurationService, this._instantiationService); + this._previewNotAvailableMessage = this._instantiationService.createInstance(TextModel, nls.localize('missingPreviewMessage', "no preview available"), PLAINTEXT_LANGUAGE_ID, TextModel.DEFAULT_CREATION_OPTIONS, null); // tree this._treeContainer = dom.append(containerElement, dom.$('div.ref-tree.inline')); diff --git a/src/vs/editor/contrib/semanticTokens/test/browser/documentSemanticTokens.test.ts b/src/vs/editor/contrib/semanticTokens/test/browser/documentSemanticTokens.test.ts index f4d8f10779fc6..b48c4220e0032 100644 --- a/src/vs/editor/contrib/semanticTokens/test/browser/documentSemanticTokens.test.ts +++ b/src/vs/editor/contrib/semanticTokens/test/browser/documentSemanticTokens.test.ts @@ -24,7 +24,6 @@ import { ModelService } from 'vs/editor/common/services/modelService'; import { SemanticTokensStylingService } from 'vs/editor/common/services/semanticTokensStylingService'; import { DocumentSemanticTokensFeature } from 'vs/editor/contrib/semanticTokens/browser/documentSemanticTokens'; import { getDocumentSemanticTokens, isSemanticTokens } from 'vs/editor/contrib/semanticTokens/common/getSemanticTokens'; -import { TestLanguageConfigurationService } from 'vs/editor/test/common/modes/testLanguageConfigurationService'; import { TestTextResourcePropertiesService } from 'vs/editor/test/common/services/testTextResourcePropertiesService'; import { TestConfigurationService } from 'vs/platform/configuration/test/common/testConfigurationService'; import { TestDialogService } from 'vs/platform/dialogs/test/common/testDialogService'; @@ -55,8 +54,6 @@ suite('ModelSemanticColoring', () => { configService, new TestTextResourcePropertiesService(configService), new UndoRedoService(new TestDialogService(), new TestNotificationService()), - languageService, - new TestLanguageConfigurationService(), new TestInstantiationService() )); const envService = new class extends mock() { diff --git a/src/vs/monaco.d.ts b/src/vs/monaco.d.ts index 584faab47accf..eaceca0bd2997 100644 --- a/src/vs/monaco.d.ts +++ b/src/vs/monaco.d.ts @@ -2919,6 +2919,9 @@ declare namespace monaco.editor { * An event describing a change in the text of a model. */ export interface IModelContentChangedEvent { + /** + * The changes are ordered from the end of the document to the beginning, so they should be safe to apply in sequence. + */ readonly changes: IModelContentChange[]; /** * The (new) end-of-line character. diff --git a/src/vs/workbench/api/test/browser/mainThreadDocumentsAndEditors.test.ts b/src/vs/workbench/api/test/browser/mainThreadDocumentsAndEditors.test.ts index 9f55229faeb86..ee6337fc7b3f1 100644 --- a/src/vs/workbench/api/test/browser/mainThreadDocumentsAndEditors.test.ts +++ b/src/vs/workbench/api/test/browser/mainThreadDocumentsAndEditors.test.ts @@ -27,9 +27,7 @@ import { TestTextResourcePropertiesService, TestWorkingCopyFileService } from 'v import { UriIdentityService } from 'vs/platform/uriIdentity/common/uriIdentityService'; import { IClipboardService } from 'vs/platform/clipboard/common/clipboardService'; import { IPaneCompositePartService } from 'vs/workbench/services/panecomposite/browser/panecomposite'; -import { TestLanguageConfigurationService } from 'vs/editor/test/common/modes/testLanguageConfigurationService'; import { TextModel } from 'vs/editor/common/model/textModel'; -import { LanguageService } from 'vs/editor/common/services/languageService'; import { DisposableStore } from 'vs/base/common/lifecycle'; import { ensureNoDisposablesAreLeakedInTestSuite } from 'vs/base/test/common/utils'; import { TestInstantiationService } from 'vs/platform/instantiation/test/common/instantiationServiceMock'; @@ -66,8 +64,6 @@ suite('MainThreadDocumentsAndEditors', () => { configService, new TestTextResourcePropertiesService(configService), undoRedoService, - disposables.add(new LanguageService()), - new TestLanguageConfigurationService(), new TestInstantiationService() ); codeEditorService = new TestCodeEditorService(themeService); diff --git a/src/vs/workbench/api/test/browser/mainThreadEditors.test.ts b/src/vs/workbench/api/test/browser/mainThreadEditors.test.ts index 1e22dbe36eee7..675932ed7a0ce 100644 --- a/src/vs/workbench/api/test/browser/mainThreadEditors.test.ts +++ b/src/vs/workbench/api/test/browser/mainThreadEditors.test.ts @@ -16,12 +16,10 @@ import { Position } from 'vs/editor/common/core/position'; import { Range } from 'vs/editor/common/core/range'; import { ITextSnapshot } from 'vs/editor/common/model'; import { IEditorWorkerService } from 'vs/editor/common/services/editorWorker'; -import { LanguageService } from 'vs/editor/common/services/languageService'; import { IModelService } from 'vs/editor/common/services/model'; import { ModelService } from 'vs/editor/common/services/modelService'; import { IResolvedTextEditorModel, ITextModelService } from 'vs/editor/common/services/resolverService'; import { TestCodeEditorService } from 'vs/editor/test/browser/editorTestServices'; -import { TestLanguageConfigurationService } from 'vs/editor/test/common/modes/testLanguageConfigurationService'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { TestConfigurationService } from 'vs/platform/configuration/test/common/testConfigurationService'; import { IDialogService } from 'vs/platform/dialogs/common/dialogs'; @@ -91,8 +89,6 @@ suite('MainThreadEditors', () => { configService, new TestTextResourcePropertiesService(configService), undoRedoService, - disposables.add(new LanguageService()), - new TestLanguageConfigurationService(), new TestInstantiationService() ); diff --git a/src/vs/workbench/contrib/bulkEdit/browser/preview/bulkEditTree.ts b/src/vs/workbench/contrib/bulkEdit/browser/preview/bulkEditTree.ts index bc043ca27aa77..45a97a0c67a22 100644 --- a/src/vs/workbench/contrib/bulkEdit/browser/preview/bulkEditTree.ts +++ b/src/vs/workbench/contrib/bulkEdit/browser/preview/bulkEditTree.ts @@ -25,10 +25,7 @@ import { IThemeService } from 'vs/platform/theme/common/themeService'; import { ThemeIcon } from 'vs/base/common/themables'; import { compare } from 'vs/base/common/strings'; import { URI } from 'vs/base/common/uri'; -import { IUndoRedoService } from 'vs/platform/undoRedo/common/undoRedo'; import { ResourceFileEdit } from 'vs/editor/browser/services/bulkEditService'; -import { ILanguageConfigurationService } from 'vs/editor/common/languages/languageConfigurationRegistry'; -import { ILanguageService } from 'vs/editor/common/languages/language'; import { PLAINTEXT_LANGUAGE_ID } from 'vs/editor/common/languages/modesRegistry'; import { SnippetParser } from 'vs/editor/contrib/snippet/browser/snippetParser'; import { AriaRole } from 'vs/base/browser/ui/aria/aria'; @@ -203,9 +200,6 @@ export class BulkEditDataSource implements IAsyncDataSource Date: Mon, 15 Jul 2024 11:06:18 +0200 Subject: [PATCH 26/37] Fix tests --- .../browser/documentSemanticTokens.test.ts | 7 +++++- .../mainThreadDocumentsAndEditors.test.ts | 13 +++++++++-- .../test/browser/mainThreadEditors.test.ts | 22 ++++++++++++------- 3 files changed, 31 insertions(+), 11 deletions(-) diff --git a/src/vs/editor/contrib/semanticTokens/test/browser/documentSemanticTokens.test.ts b/src/vs/editor/contrib/semanticTokens/test/browser/documentSemanticTokens.test.ts index b48c4220e0032..9eb8d2f000694 100644 --- a/src/vs/editor/contrib/semanticTokens/test/browser/documentSemanticTokens.test.ts +++ b/src/vs/editor/contrib/semanticTokens/test/browser/documentSemanticTokens.test.ts @@ -14,6 +14,7 @@ import { ensureNoDisposablesAreLeakedInTestSuite } from 'vs/base/test/common/uti import { Range } from 'vs/editor/common/core/range'; import { DocumentSemanticTokensProvider, SemanticTokens, SemanticTokensEdits, SemanticTokensLegend } from 'vs/editor/common/languages'; import { ILanguageService } from 'vs/editor/common/languages/language'; +import { ILanguageConfigurationService } from 'vs/editor/common/languages/languageConfigurationRegistry'; import { ITextModel } from 'vs/editor/common/model'; import { LanguageFeatureDebounceService } from 'vs/editor/common/services/languageFeatureDebounce'; import { ILanguageFeaturesService } from 'vs/editor/common/services/languageFeatures'; @@ -24,6 +25,7 @@ import { ModelService } from 'vs/editor/common/services/modelService'; import { SemanticTokensStylingService } from 'vs/editor/common/services/semanticTokensStylingService'; import { DocumentSemanticTokensFeature } from 'vs/editor/contrib/semanticTokens/browser/documentSemanticTokens'; import { getDocumentSemanticTokens, isSemanticTokens } from 'vs/editor/contrib/semanticTokens/common/getSemanticTokens'; +import { TestLanguageConfigurationService } from 'vs/editor/test/common/modes/testLanguageConfigurationService'; import { TestTextResourcePropertiesService } from 'vs/editor/test/common/services/testTextResourcePropertiesService'; import { TestConfigurationService } from 'vs/platform/configuration/test/common/testConfigurationService'; import { TestDialogService } from 'vs/platform/dialogs/test/common/testDialogService'; @@ -50,11 +52,14 @@ suite('ModelSemanticColoring', () => { languageFeaturesService = new LanguageFeaturesService(); languageService = disposables.add(new LanguageService(false)); const semanticTokensStylingService = disposables.add(new SemanticTokensStylingService(themeService, logService, languageService)); + const instantiationService = new TestInstantiationService(); + instantiationService.set(ILanguageService, languageService); + instantiationService.set(ILanguageConfigurationService, new TestLanguageConfigurationService()); modelService = disposables.add(new ModelService( configService, new TestTextResourcePropertiesService(configService), new UndoRedoService(new TestDialogService(), new TestNotificationService()), - new TestInstantiationService() + instantiationService )); const envService = new class extends mock() { override isBuilt: boolean = true; diff --git a/src/vs/workbench/api/test/browser/mainThreadDocumentsAndEditors.test.ts b/src/vs/workbench/api/test/browser/mainThreadDocumentsAndEditors.test.ts index ee6337fc7b3f1..5d678b1c43a6d 100644 --- a/src/vs/workbench/api/test/browser/mainThreadDocumentsAndEditors.test.ts +++ b/src/vs/workbench/api/test/browser/mainThreadDocumentsAndEditors.test.ts @@ -11,7 +11,7 @@ import { ModelService } from 'vs/editor/common/services/modelService'; import { TestCodeEditorService } from 'vs/editor/test/browser/editorTestServices'; import { ITextFileService } from 'vs/workbench/services/textfile/common/textfiles'; import { ExtHostDocumentsAndEditorsShape, IDocumentsAndEditorsDelta } from 'vs/workbench/api/common/extHost.protocol'; -import { createTestCodeEditor, ITestCodeEditor } from 'vs/editor/test/browser/testCodeEditor'; +import { createTestCodeEditor, instantiateTestCodeEditor, ITestCodeEditor } from 'vs/editor/test/browser/testCodeEditor'; import { mock } from 'vs/base/test/common/mock'; import { TestEditorService, TestEditorGroupsService, TestEnvironmentService, TestPathService } from 'vs/workbench/test/browser/workbenchTestServices'; import { Event } from 'vs/base/common/event'; @@ -31,6 +31,11 @@ import { TextModel } from 'vs/editor/common/model/textModel'; import { DisposableStore } from 'vs/base/common/lifecycle'; import { ensureNoDisposablesAreLeakedInTestSuite } from 'vs/base/test/common/utils'; import { TestInstantiationService } from 'vs/platform/instantiation/test/common/instantiationServiceMock'; +import { ILanguageService } from 'vs/editor/common/languages/language'; +import { LanguageService } from 'vs/editor/common/services/languageService'; +import { ILanguageConfigurationService } from 'vs/editor/common/languages/languageConfigurationRegistry'; +import { TestLanguageConfigurationService } from 'vs/editor/test/common/modes/testLanguageConfigurationService'; +import { IUndoRedoService } from 'vs/platform/undoRedo/common/undoRedo'; suite('MainThreadDocumentsAndEditors', () => { @@ -60,11 +65,15 @@ suite('MainThreadDocumentsAndEditors', () => { const notificationService = new TestNotificationService(); const undoRedoService = new UndoRedoService(dialogService, notificationService); const themeService = new TestThemeService(); + const instantiationService = new TestInstantiationService(); + instantiationService.set(ILanguageService, disposables.add(new LanguageService())); + instantiationService.set(ILanguageConfigurationService, new TestLanguageConfigurationService()); + instantiationService.set(IUndoRedoService, undoRedoService); modelService = new ModelService( configService, new TestTextResourcePropertiesService(configService), undoRedoService, - new TestInstantiationService() + instantiationService ); codeEditorService = new TestCodeEditorService(themeService); textFileService = new class extends mock() { diff --git a/src/vs/workbench/api/test/browser/mainThreadEditors.test.ts b/src/vs/workbench/api/test/browser/mainThreadEditors.test.ts index 675932ed7a0ce..d83a5ebcf42b4 100644 --- a/src/vs/workbench/api/test/browser/mainThreadEditors.test.ts +++ b/src/vs/workbench/api/test/browser/mainThreadEditors.test.ts @@ -55,7 +55,10 @@ import { ICopyOperation, ICreateFileOperation, ICreateOperation, IDeleteOperatio import { IWorkingCopyService } from 'vs/workbench/services/workingCopy/common/workingCopyService'; import { TestEditorGroupsService, TestEditorService, TestEnvironmentService, TestFileService, TestLifecycleService, TestWorkingCopyService } from 'vs/workbench/test/browser/workbenchTestServices'; import { TestContextService, TestTextResourcePropertiesService } from 'vs/workbench/test/common/workbenchTestServices'; -import { TestInstantiationService } from 'vs/platform/instantiation/test/common/instantiationServiceMock'; +import { ILanguageService } from 'vs/editor/common/languages/language'; +import { LanguageService } from 'vs/editor/common/services/languageService'; +import { ILanguageConfigurationService } from 'vs/editor/common/languages/languageConfigurationRegistry'; +import { TestLanguageConfigurationService } from 'vs/editor/test/common/modes/testLanguageConfigurationService'; suite('MainThreadEditors', () => { @@ -79,18 +82,11 @@ suite('MainThreadEditors', () => { createdResources.clear(); deletedResources.clear(); - const configService = new TestConfigurationService(); const dialogService = new TestDialogService(); const notificationService = new TestNotificationService(); const undoRedoService = new UndoRedoService(dialogService, notificationService); const themeService = new TestThemeService(); - modelService = new ModelService( - configService, - new TestTextResourcePropertiesService(configService), - undoRedoService, - new TestInstantiationService() - ); const services = new ServiceCollection(); services.set(IBulkEditService, new SyncDescriptor(BulkEditService)); @@ -176,8 +172,18 @@ suite('MainThreadEditors', () => { } }); + services.set(ILanguageService, disposables.add(new LanguageService())); + services.set(ILanguageConfigurationService, new TestLanguageConfigurationService()); + const instaService = new InstantiationService(services); + modelService = new ModelService( + configService, + new TestTextResourcePropertiesService(configService), + undoRedoService, + instaService + ); + bulkEdits = instaService.createInstance(MainThreadBulkEdits, SingleProxyRPCProtocol(null)); }); From 2c2e321debbf35367caf61db08c18a467613154a Mon Sep 17 00:00:00 2001 From: Alex Ross Date: Mon, 15 Jul 2024 11:19:50 +0200 Subject: [PATCH 27/37] Remove unneeded import --- .../api/test/browser/mainThreadDocumentsAndEditors.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/api/test/browser/mainThreadDocumentsAndEditors.test.ts b/src/vs/workbench/api/test/browser/mainThreadDocumentsAndEditors.test.ts index 5d678b1c43a6d..17a9049d0643b 100644 --- a/src/vs/workbench/api/test/browser/mainThreadDocumentsAndEditors.test.ts +++ b/src/vs/workbench/api/test/browser/mainThreadDocumentsAndEditors.test.ts @@ -11,7 +11,7 @@ import { ModelService } from 'vs/editor/common/services/modelService'; import { TestCodeEditorService } from 'vs/editor/test/browser/editorTestServices'; import { ITextFileService } from 'vs/workbench/services/textfile/common/textfiles'; import { ExtHostDocumentsAndEditorsShape, IDocumentsAndEditorsDelta } from 'vs/workbench/api/common/extHost.protocol'; -import { createTestCodeEditor, instantiateTestCodeEditor, ITestCodeEditor } from 'vs/editor/test/browser/testCodeEditor'; +import { createTestCodeEditor, ITestCodeEditor } from 'vs/editor/test/browser/testCodeEditor'; import { mock } from 'vs/base/test/common/mock'; import { TestEditorService, TestEditorGroupsService, TestEnvironmentService, TestPathService } from 'vs/workbench/test/browser/workbenchTestServices'; import { Event } from 'vs/base/common/event'; From 028c7704abb71794791169daa405a1eefdc6a054 Mon Sep 17 00:00:00 2001 From: Alex Ross Date: Tue, 16 Jul 2024 12:33:47 +0200 Subject: [PATCH 28/37] Fix missing tree-sitter-wasm in web and remote --- build/.webignore | 1 + remote/package.json | 1 + remote/web/package.json | 1 + remote/web/yarn.lock | 5 +++++ remote/yarn.lock | 5 +++++ 5 files changed, 13 insertions(+) diff --git a/build/.webignore b/build/.webignore index 15935edce8a61..860ab59616b2b 100644 --- a/build/.webignore +++ b/build/.webignore @@ -38,6 +38,7 @@ vscode-textmate/webpack.config.js # This makes sure the model is included in the package !@vscode/vscode-languagedetection/model/** +!@vscode/tree-sitter-wasm/wasm/** # Ensure only the required telemetry pieces are loaded in web to reduce bundle size @microsoft/1ds-core-js/** diff --git a/remote/package.json b/remote/package.json index b840d2208597b..17d88c580c21f 100644 --- a/remote/package.json +++ b/remote/package.json @@ -11,6 +11,7 @@ "@vscode/proxy-agent": "^0.22.0", "@vscode/ripgrep": "^1.15.9", "@vscode/spdlog": "^0.15.0", + "@vscode/tree-sitter-wasm": "0.0.1", "@vscode/vscode-languagedetection": "1.0.21", "@vscode/windows-process-tree": "^0.6.0", "@vscode/windows-registry": "^1.1.0", diff --git a/remote/web/package.json b/remote/web/package.json index 49f093c2a571c..d6238f3907d2f 100644 --- a/remote/web/package.json +++ b/remote/web/package.json @@ -6,6 +6,7 @@ "@microsoft/1ds-core-js": "^3.2.13", "@microsoft/1ds-post-js": "^3.2.13", "@vscode/iconv-lite-umd": "0.7.0", + "@vscode/tree-sitter-wasm": "0.0.1", "@vscode/vscode-languagedetection": "1.0.21", "@xterm/addon-clipboard": "0.2.0-beta.29", "@xterm/addon-image": "0.9.0-beta.46", diff --git a/remote/web/yarn.lock b/remote/web/yarn.lock index ea4a9a7908d91..9dfe2190e1f69 100644 --- a/remote/web/yarn.lock +++ b/remote/web/yarn.lock @@ -43,6 +43,11 @@ resolved "https://registry.yarnpkg.com/@vscode/iconv-lite-umd/-/iconv-lite-umd-0.7.0.tgz#d2f1e0664ee6036408f9743fee264ea0699b0e48" integrity sha512-bRRFxLfg5dtAyl5XyiVWz/ZBPahpOpPrNYnnHpOpUZvam4tKH35wdhP4Kj6PbM0+KdliOsPzbGWpkxcdpNB/sg== +"@vscode/tree-sitter-wasm@0.0.1": + version "0.0.1" + resolved "https://registry.yarnpkg.com/@vscode/tree-sitter-wasm/-/tree-sitter-wasm-0.0.1.tgz#ffb2e295a416698f4c77cbffeca3b28567d6754b" + integrity sha512-m0GKnQ3BxWnVd+20KLGwr1+Qvt/RiiaJmKAqHNU35pNydDtduUzyBm7ETz/T0vOVKoeIAaiYsJOA1aKWs7Y1tA== + "@vscode/vscode-languagedetection@1.0.21": version "1.0.21" resolved "https://registry.yarnpkg.com/@vscode/vscode-languagedetection/-/vscode-languagedetection-1.0.21.tgz#89b48f293f6aa3341bb888c1118d16ff13b032d3" diff --git a/remote/yarn.lock b/remote/yarn.lock index 3236bed2b807d..516011ad62516 100644 --- a/remote/yarn.lock +++ b/remote/yarn.lock @@ -98,6 +98,11 @@ mkdirp "^1.0.4" node-addon-api "7.1.0" +"@vscode/tree-sitter-wasm@0.0.1": + version "0.0.1" + resolved "https://registry.yarnpkg.com/@vscode/tree-sitter-wasm/-/tree-sitter-wasm-0.0.1.tgz#ffb2e295a416698f4c77cbffeca3b28567d6754b" + integrity sha512-m0GKnQ3BxWnVd+20KLGwr1+Qvt/RiiaJmKAqHNU35pNydDtduUzyBm7ETz/T0vOVKoeIAaiYsJOA1aKWs7Y1tA== + "@vscode/vscode-languagedetection@1.0.21": version "1.0.21" resolved "https://registry.yarnpkg.com/@vscode/vscode-languagedetection/-/vscode-languagedetection-1.0.21.tgz#89b48f293f6aa3341bb888c1118d16ff13b032d3" From 539a2730d9572e645032f6a7cc6d29d5363e8535 Mon Sep 17 00:00:00 2001 From: Alex Ross Date: Tue, 16 Jul 2024 15:01:44 +0200 Subject: [PATCH 29/37] Make package.jsons match --- remote/package.json | 2 +- remote/web/package.json | 2 +- remote/web/yarn.lock | 2 +- remote/yarn.lock | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/remote/package.json b/remote/package.json index 17d88c580c21f..03d5dfcde312f 100644 --- a/remote/package.json +++ b/remote/package.json @@ -11,7 +11,7 @@ "@vscode/proxy-agent": "^0.22.0", "@vscode/ripgrep": "^1.15.9", "@vscode/spdlog": "^0.15.0", - "@vscode/tree-sitter-wasm": "0.0.1", + "@vscode/tree-sitter-wasm": "^0.0.1", "@vscode/vscode-languagedetection": "1.0.21", "@vscode/windows-process-tree": "^0.6.0", "@vscode/windows-registry": "^1.1.0", diff --git a/remote/web/package.json b/remote/web/package.json index d6238f3907d2f..e6e49be1ea25c 100644 --- a/remote/web/package.json +++ b/remote/web/package.json @@ -6,7 +6,7 @@ "@microsoft/1ds-core-js": "^3.2.13", "@microsoft/1ds-post-js": "^3.2.13", "@vscode/iconv-lite-umd": "0.7.0", - "@vscode/tree-sitter-wasm": "0.0.1", + "@vscode/tree-sitter-wasm": "^0.0.1", "@vscode/vscode-languagedetection": "1.0.21", "@xterm/addon-clipboard": "0.2.0-beta.29", "@xterm/addon-image": "0.9.0-beta.46", diff --git a/remote/web/yarn.lock b/remote/web/yarn.lock index 9dfe2190e1f69..f518caaa32858 100644 --- a/remote/web/yarn.lock +++ b/remote/web/yarn.lock @@ -43,7 +43,7 @@ resolved "https://registry.yarnpkg.com/@vscode/iconv-lite-umd/-/iconv-lite-umd-0.7.0.tgz#d2f1e0664ee6036408f9743fee264ea0699b0e48" integrity sha512-bRRFxLfg5dtAyl5XyiVWz/ZBPahpOpPrNYnnHpOpUZvam4tKH35wdhP4Kj6PbM0+KdliOsPzbGWpkxcdpNB/sg== -"@vscode/tree-sitter-wasm@0.0.1": +"@vscode/tree-sitter-wasm@^0.0.1": version "0.0.1" resolved "https://registry.yarnpkg.com/@vscode/tree-sitter-wasm/-/tree-sitter-wasm-0.0.1.tgz#ffb2e295a416698f4c77cbffeca3b28567d6754b" integrity sha512-m0GKnQ3BxWnVd+20KLGwr1+Qvt/RiiaJmKAqHNU35pNydDtduUzyBm7ETz/T0vOVKoeIAaiYsJOA1aKWs7Y1tA== diff --git a/remote/yarn.lock b/remote/yarn.lock index 516011ad62516..26162a33e04ed 100644 --- a/remote/yarn.lock +++ b/remote/yarn.lock @@ -98,7 +98,7 @@ mkdirp "^1.0.4" node-addon-api "7.1.0" -"@vscode/tree-sitter-wasm@0.0.1": +"@vscode/tree-sitter-wasm@^0.0.1": version "0.0.1" resolved "https://registry.yarnpkg.com/@vscode/tree-sitter-wasm/-/tree-sitter-wasm-0.0.1.tgz#ffb2e295a416698f4c77cbffeca3b28567d6754b" integrity sha512-m0GKnQ3BxWnVd+20KLGwr1+Qvt/RiiaJmKAqHNU35pNydDtduUzyBm7ETz/T0vOVKoeIAaiYsJOA1aKWs7Y1tA== From e6c2529c4f1d513ef0ba513b5dbc0f4103c2a791 Mon Sep 17 00:00:00 2001 From: Alex Ross Date: Wed, 17 Jul 2024 09:58:17 +0200 Subject: [PATCH 30/37] Add @vscode/tree-sitter-wasm to web loader config --- test/unit/browser/renderer.html | 1 + 1 file changed, 1 insertion(+) diff --git a/test/unit/browser/renderer.html b/test/unit/browser/renderer.html index 7187baf7bf647..28e6912fcad19 100644 --- a/test/unit/browser/renderer.html +++ b/test/unit/browser/renderer.html @@ -59,6 +59,7 @@ 'sinon-test': new URL('../../../node_modules/sinon-test/dist/sinon-test.js', baseUrl).href, '@xterm/xterm': new URL('../../../node_modules/@xterm/xterm/lib/xterm.js', baseUrl).href, '@vscode/iconv-lite-umd': new URL('../../../node_modules/@vscode/iconv-lite-umd/lib/iconv-lite-umd.js', baseUrl).href, + '@vscode/tree-sitter-wasm': new URL('../../../node_modules/@vscode/tree-sitter-wasm/wasm/tree-sitter.js', baseUrl).href, jschardet: new URL('../../../node_modules/jschardet/dist/jschardet.min.js', baseUrl).href } }); From 04232a41c7f0c9a6870618c24b23b32ecf2006e5 Mon Sep 17 00:00:00 2001 From: Alex Ross Date: Wed, 17 Jul 2024 13:01:19 +0200 Subject: [PATCH 31/37] Try using importAMDNodeModule --- .eslintrc.json | 1 - .../treeSitter/treeSitterParserService.ts | 57 ++++++++++++++----- 2 files changed, 42 insertions(+), 16 deletions(-) diff --git a/.eslintrc.json b/.eslintrc.json index 5160622cc4b31..d7f317c85b9f0 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -642,7 +642,6 @@ "@vscode/policy-watcher", "@vscode/proxy-agent", "@vscode/spdlog", - "@vscode/tree-sitter-wasm", "@vscode/windows-process-tree", "assert", "child_process", diff --git a/src/vs/editor/browser/services/treeSitter/treeSitterParserService.ts b/src/vs/editor/browser/services/treeSitter/treeSitterParserService.ts index 882fffebf8ada..b90095b21f1af 100644 --- a/src/vs/editor/browser/services/treeSitter/treeSitterParserService.ts +++ b/src/vs/editor/browser/services/treeSitter/treeSitterParserService.ts @@ -4,8 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import { TreeSitterTokenizationRegistry } from 'vs/editor/common/languages'; -// eslint-disable-next-line local/code-amd-node-module -import { Parser } from '@vscode/tree-sitter-wasm'; +import type { Parser } from '@vscode/tree-sitter-wasm'; import { AppResourcePath, FileAccess, nodeModulesPath } from 'vs/base/common/network'; import { ITreeSitterParserService } from 'vs/editor/common/services/treeSitterParserService'; import { IModelService } from 'vs/editor/common/services/model'; @@ -17,6 +16,7 @@ import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { ILogService } from 'vs/platform/log/common/log'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { setTimeout0 } from 'vs/base/common/platform'; +import { importAMDNodeModule } from 'vs/amdX'; const EDITOR_EXPERIMENTAL_PREFER_TREESITTER = 'editor.experimental.preferTreeSitter'; const moduleLocationTreeSitter: AppResourcePath = `${nodeModulesPath}/@vscode/tree-sitter-wasm/wasm`; @@ -27,7 +27,8 @@ class TextModelTreeSitter extends Disposable { private _contentChangedListener: IDisposable | undefined; constructor(readonly model: ITextModel, - private readonly _treeSitterParser: TreeSitterParser + private readonly _treeSitterParser: TreeSitterParser, + private readonly _treeSitterImporter: TreeSitterImporter, ) { super(); this._register(this.model.onDidChangeLanguage(e => this._onDidChangeLanguage(e))); @@ -53,7 +54,8 @@ class TextModelTreeSitter extends Disposable { return; } - this._treeSitterTree = new TreeSitterTree(language); + const Parser = await this._treeSitterImporter.getParserClass(); + this._treeSitterTree = new TreeSitterTree(new Parser(), language); this._registerModelListeners(); } @@ -90,10 +92,8 @@ class TextModelTreeSitter extends Disposable { export class TreeSitterTree implements IDisposable { private _tree: Parser.Tree | undefined; - public readonly parser: Parser; private _isDisposed: boolean = false; - constructor(language: Parser.Language) { - this.parser = new Parser(); + constructor(public readonly parser: Parser, language: Parser.Language) { this.parser.setTimeoutMicros(50 * 1000); // 50 ms this.parser.setLanguage(language); } @@ -113,7 +113,8 @@ export class TreeSitterTree implements IDisposable { class TreeSitterParser extends Disposable { private _languages: Map = new Map(); - constructor(private readonly _fileService: IFileService, + constructor(private readonly _treeSitterImporter: TreeSitterImporter, + private readonly _fileService: IFileService, private readonly _logService: ILogService, private readonly _telemetryService: ITelemetryService ) { @@ -193,6 +194,7 @@ class TreeSitterParser extends Disposable { } const wasmPath: AppResourcePath = `${languageLocation}/${grammarName.name}.wasm`; const languageFile = await (this._fileService.readFile(FileAccess.asFileUri(wasmPath))); + const Parser = await this._treeSitterImporter.getParserClass(); return Parser.Language.load(languageFile.value.buffer); } @@ -205,11 +207,30 @@ class TreeSitterParser extends Disposable { } } +class TreeSitterImporter { + private _treeSitterImport: typeof import('@vscode/tree-sitter-wasm') | undefined; + private async _getTreeSitterImport() { + if (!this._treeSitterImport) { + this._treeSitterImport = await importAMDNodeModule('@vscode/tree-sitter-wasm', 'wasm/tree-sitter.js'); + } + return this._treeSitterImport; + } + + private _parserClass: typeof Parser | undefined; + public async getParserClass() { + if (!this._parserClass) { + this._parserClass = (await this._getTreeSitterImport()).Parser; + } + return this._parserClass; + } +} + export class TreeSitterTextModelService extends Disposable implements ITreeSitterParserService { readonly _serviceBrand: undefined; private _init!: Promise; private _textModelTreeSitters: DisposableMap = this._register(new DisposableMap()); private _registeredLanguages: DisposableMap = new DisposableMap(); + private readonly _treeSitterImporter: TreeSitterImporter = new TreeSitterImporter(); private readonly _treeSitterParser: TreeSitterParser; constructor(@IModelService private readonly _modelService: IModelService, @@ -219,7 +240,7 @@ export class TreeSitterTextModelService extends Disposable implements ITreeSitte @IConfigurationService private readonly _configurationService: IConfigurationService, ) { super(); - this._treeSitterParser = this._register(new TreeSitterParser(fileService, logService, telemetryService)); + this._treeSitterParser = this._register(new TreeSitterParser(this._treeSitterImporter, fileService, logService, telemetryService)); this._register(this._configurationService.onDidChangeConfiguration(e => { if (e.affectsConfiguration(EDITOR_EXPERIMENTAL_PREFER_TREESITTER)) { this._supportedLanguagesChanged(); @@ -228,6 +249,16 @@ export class TreeSitterTextModelService extends Disposable implements ITreeSitte this._supportedLanguagesChanged(); } + private async _doInitParser() { + const Parser = await this._treeSitterImporter.getParserClass(); + await Parser.init({ + locateFile(_file: string, _folder: string) { + return FileAccess.asBrowserUri(moduleLocationTreeSitterWasm).toString(true); + } + }); + return true; + } + private _hasInit: boolean = false; private async _initParser(hasLanguages: boolean): Promise { if (this._hasInit) { @@ -236,11 +267,7 @@ export class TreeSitterTextModelService extends Disposable implements ITreeSitte if (hasLanguages) { this._hasInit = true; - this._init = new Promise((resolve, reject) => Parser.init({ - locateFile(_file: string, _folder: string) { - return FileAccess.asBrowserUri(moduleLocationTreeSitterWasm).toString(true); - } - }).then(() => resolve(true), reject)); + this._init = this._doInitParser(); // New init, we need to deal with all the existing text models and set up listeners this._init.then(() => this._registerModelServiceListeners()); @@ -283,7 +310,7 @@ export class TreeSitterTextModelService extends Disposable implements ITreeSitte } private async _createTextModelTreeSitter(model: ITextModel) { - const textModelTreeSitter = new TextModelTreeSitter(model, this._treeSitterParser); + const textModelTreeSitter = new TextModelTreeSitter(model, this._treeSitterParser, this._treeSitterImporter); this._textModelTreeSitters.set(model, textModelTreeSitter); } From 0ca55da333a97330c81658025f7e100cf22a11ad Mon Sep 17 00:00:00 2001 From: Alex Ross Date: Thu, 18 Jul 2024 11:01:36 +0200 Subject: [PATCH 32/37] PR feedback --- .../treeSitter/treeSitterParserService.ts | 65 ++++++++++--------- 1 file changed, 34 insertions(+), 31 deletions(-) diff --git a/src/vs/editor/browser/services/treeSitter/treeSitterParserService.ts b/src/vs/editor/browser/services/treeSitter/treeSitterParserService.ts index b90095b21f1af..4b2e4e8476d65 100644 --- a/src/vs/editor/browser/services/treeSitter/treeSitterParserService.ts +++ b/src/vs/editor/browser/services/treeSitter/treeSitterParserService.ts @@ -8,7 +8,7 @@ import type { Parser } from '@vscode/tree-sitter-wasm'; import { AppResourcePath, FileAccess, nodeModulesPath } from 'vs/base/common/network'; import { ITreeSitterParserService } from 'vs/editor/common/services/treeSitterParserService'; import { IModelService } from 'vs/editor/common/services/model'; -import { Disposable, DisposableMap, IDisposable } from 'vs/base/common/lifecycle'; +import { Disposable, DisposableMap, DisposableStore, IDisposable } from 'vs/base/common/lifecycle'; import { ITextModel } from 'vs/editor/common/model'; import { IFileService } from 'vs/platform/files/common/files'; import { IModelContentChangedEvent } from 'vs/editor/common/textModelEvents'; @@ -17,59 +17,63 @@ import { ILogService } from 'vs/platform/log/common/log'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { setTimeout0 } from 'vs/base/common/platform'; import { importAMDNodeModule } from 'vs/amdX'; +import { Event } from 'vs/base/common/event'; +import { cancelOnDispose } from 'vs/base/common/cancellation'; const EDITOR_EXPERIMENTAL_PREFER_TREESITTER = 'editor.experimental.preferTreeSitter'; const moduleLocationTreeSitter: AppResourcePath = `${nodeModulesPath}/@vscode/tree-sitter-wasm/wasm`; const moduleLocationTreeSitterWasm: AppResourcePath = `${moduleLocationTreeSitter}/tree-sitter.wasm`; -class TextModelTreeSitter extends Disposable { +export class TextModelTreeSitter extends Disposable { private _treeSitterTree: TreeSitterTree | undefined; - private _contentChangedListener: IDisposable | undefined; + + // Not currently used since we just get telemetry, but later this will be needed. + get tree() { return this._treeSitterTree?.tree; } constructor(readonly model: ITextModel, private readonly _treeSitterParser: TreeSitterParser, private readonly _treeSitterImporter: TreeSitterImporter, ) { super(); - this._register(this.model.onDidChangeLanguage(e => this._onDidChangeLanguage(e))); - this._onDidChangeLanguage({ newLanguage: this.model.getLanguageId() }); - } - - private _registerModelListeners() { - this._contentChangedListener = this.model.onDidChangeContent(e => this._onDidChangeContent(e)); - this._onDidChangeContent(); + this._register(Event.runAndSubscribe(this.model.onDidChangeLanguage, (e => this._onDidChangeLanguage(e ? e.newLanguage : this.model.getLanguageId())))); } - private _unregisterModelListeners() { - this._contentChangedListener?.dispose(); - } - - private async _onDidChangeLanguage(e: { newLanguage: string }) { - if (this._treeSitterTree) { - this._treeSitterTree.dispose(); - } - const language = await this._treeSitterParser.getLanguage(e.newLanguage); - if (!language || this.model.isDisposed()) { - this._unregisterModelListeners(); + private readonly _languageSessionDisposables = this._register(new DisposableStore()); + /** + * Be very careful when making changes to this method as it is easy to introduce race conditions. + */ + private async _onDidChangeLanguage(languageId: string) { + this._languageSessionDisposables.clear(); + this._treeSitterTree = undefined; + + const token = cancelOnDispose(this._languageSessionDisposables); + const language = await this._treeSitterParser.getLanguage(languageId); + if (!language || token.isCancellationRequested) { return; } const Parser = await this._treeSitterImporter.getParserClass(); - this._treeSitterTree = new TreeSitterTree(new Parser(), language); - this._registerModelListeners(); - } + if (token.isCancellationRequested) { + return; + } - private async _onDidChangeContent(e?: IModelContentChangedEvent) { - if (!this._treeSitterTree) { + const treeSitterTree = this._languageSessionDisposables.add(new TreeSitterTree(new Parser(), language)); + this._languageSessionDisposables.add(this.model.onDidChangeContent(e => this._onDidChangeContent(treeSitterTree, e))); + await this._onDidChangeContent(treeSitterTree); + if (token.isCancellationRequested) { return; } + this._treeSitterTree = treeSitterTree; + } + + private async _onDidChangeContent(treeSitterTree: TreeSitterTree, e?: IModelContentChangedEvent) { if (e) { for (const change of e.changes) { const newEndOffset = change.rangeOffset + change.text.length; const newEndPosition = this.model.getPositionAt(newEndOffset); - this._treeSitterTree.tree?.edit({ + treeSitterTree.tree?.edit({ startIndex: change.rangeOffset, oldEndIndex: change.rangeOffset + change.rangeLength, newEndIndex: change.rangeOffset + change.text.length, @@ -80,13 +84,12 @@ class TextModelTreeSitter extends Disposable { } } - this._treeSitterTree.tree = await this._treeSitterParser.parse(this.model, this._treeSitterTree); + treeSitterTree.tree = await this._treeSitterParser.parse(this.model, treeSitterTree); } override dispose() { super.dispose(); - this._treeSitterTree?.dispose(); - this._unregisterModelListeners(); + this._languageSessionDisposables.dispose(); } } @@ -229,7 +232,7 @@ export class TreeSitterTextModelService extends Disposable implements ITreeSitte readonly _serviceBrand: undefined; private _init!: Promise; private _textModelTreeSitters: DisposableMap = this._register(new DisposableMap()); - private _registeredLanguages: DisposableMap = new DisposableMap(); + private _registeredLanguages: DisposableMap = this._register(new DisposableMap()); private readonly _treeSitterImporter: TreeSitterImporter = new TreeSitterImporter(); private readonly _treeSitterParser: TreeSitterParser; From 6435924727192bb6725041d4770b7cc2f014d957 Mon Sep 17 00:00:00 2001 From: Alex Ross Date: Thu, 18 Jul 2024 12:08:05 +0200 Subject: [PATCH 33/37] Add race condition test for changing language while loading language --- .../treeSitter/treeSitterParserService.ts | 10 +- .../services/treeSitterParserService.test.ts | 135 ++++++++++++++++++ 2 files changed, 140 insertions(+), 5 deletions(-) create mode 100644 src/vs/editor/test/browser/services/treeSitterParserService.test.ts diff --git a/src/vs/editor/browser/services/treeSitter/treeSitterParserService.ts b/src/vs/editor/browser/services/treeSitter/treeSitterParserService.ts index 4b2e4e8476d65..a047122178d71 100644 --- a/src/vs/editor/browser/services/treeSitter/treeSitterParserService.ts +++ b/src/vs/editor/browser/services/treeSitter/treeSitterParserService.ts @@ -28,7 +28,7 @@ export class TextModelTreeSitter extends Disposable { private _treeSitterTree: TreeSitterTree | undefined; // Not currently used since we just get telemetry, but later this will be needed. - get tree() { return this._treeSitterTree?.tree; } + get tree() { return this._treeSitterTree; } constructor(readonly model: ITextModel, private readonly _treeSitterParser: TreeSitterParser, @@ -96,7 +96,7 @@ export class TextModelTreeSitter extends Disposable { export class TreeSitterTree implements IDisposable { private _tree: Parser.Tree | undefined; private _isDisposed: boolean = false; - constructor(public readonly parser: Parser, language: Parser.Language) { + constructor(public readonly parser: Parser, public /** exposed for tests **/ readonly language: Parser.Language) { this.parser.setTimeoutMicros(50 * 1000); // 50 ms this.parser.setLanguage(language); } @@ -113,7 +113,7 @@ export class TreeSitterTree implements IDisposable { get isDisposed() { return this._isDisposed; } } -class TreeSitterParser extends Disposable { +export class TreeSitterParser extends Disposable { private _languages: Map = new Map(); constructor(private readonly _treeSitterImporter: TreeSitterImporter, @@ -210,7 +210,7 @@ class TreeSitterParser extends Disposable { } } -class TreeSitterImporter { +export class TreeSitterImporter { private _treeSitterImport: typeof import('@vscode/tree-sitter-wasm') | undefined; private async _getTreeSitterImport() { if (!this._treeSitterImport) { @@ -312,7 +312,7 @@ export class TreeSitterTextModelService extends Disposable implements ITreeSitte this._modelService.getModels().forEach(model => this._createTextModelTreeSitter(model)); } - private async _createTextModelTreeSitter(model: ITextModel) { + private _createTextModelTreeSitter(model: ITextModel) { const textModelTreeSitter = new TextModelTreeSitter(model, this._treeSitterParser, this._treeSitterImporter); this._textModelTreeSitters.set(model, textModelTreeSitter); } diff --git a/src/vs/editor/test/browser/services/treeSitterParserService.test.ts b/src/vs/editor/test/browser/services/treeSitterParserService.test.ts new file mode 100644 index 0000000000000..b65cc00510413 --- /dev/null +++ b/src/vs/editor/test/browser/services/treeSitterParserService.test.ts @@ -0,0 +1,135 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +import assert from 'assert'; +import { ensureNoDisposablesAreLeakedInTestSuite } from 'vs/base/test/common/utils'; +import { TextModelTreeSitter, TreeSitterImporter, TreeSitterParser, TreeSitterTree } from 'vs/editor/browser/services/treeSitter/treeSitterParserService'; +import type { Parser } from '@vscode/tree-sitter-wasm'; +import { ITextModel } from 'vs/editor/common/model'; +import { createTextModel } from 'vs/editor/test/common/testTextModel'; +import { timeout } from 'vs/base/common/async'; + +class MockParser implements Parser { + static async init(): Promise { } + delete(): void { } + parse(input: string | Parser.Input, oldTree?: Parser.Tree, options?: Parser.Options): Parser.Tree { + return new MockTree(); + } + getIncludedRanges(): Parser.Range[] { + return []; + } + getTimeoutMicros(): number { return 0; } + setTimeoutMicros(timeout: number): void { } + reset(): void { } + getLanguage(): Parser.Language { return {} as any; } + setLanguage(): void { } + getLogger(): Parser.Logger { + throw new Error('Method not implemented.'); + } + setLogger(logFunc?: Parser.Logger | false | null): void { + throw new Error('Method not implemented.'); + } +} + +class MockTreeSitterImporter extends TreeSitterImporter { + public override async getParserClass(): Promise { + return MockParser as any; + } +} + +class MockTree implements Parser.Tree { + editorLanguage: string = ''; + rootNode: Parser.SyntaxNode = {} as any; + rootNodeWithOffset(offsetBytes: number, offsetExtent: Parser.Point): Parser.SyntaxNode { + throw new Error('Method not implemented.'); + } + copy(): Parser.Tree { + throw new Error('Method not implemented.'); + } + delete(): void { } + edit(edit: Parser.Edit): Parser.Tree { + throw new Error('Method not implemented.'); + } + walk(): Parser.TreeCursor { + throw new Error('Method not implemented.'); + } + getChangedRanges(other: Parser.Tree): Parser.Range[] { + throw new Error('Method not implemented.'); + } + getIncludedRanges(): Parser.Range[] { + throw new Error('Method not implemented.'); + } + getEditedRange(other: Parser.Tree): Parser.Range { + throw new Error('Method not implemented.'); + } + getLanguage(): Parser.Language { + throw new Error('Method not implemented.'); + } +} + +class MockLanguage implements Parser.Language { + version: number = 0; + fieldCount: number = 0; + stateCount: number = 0; + nodeTypeCount: number = 0; + fieldNameForId(fieldId: number): string | null { + throw new Error('Method not implemented.'); + } + fieldIdForName(fieldName: string): number | null { + throw new Error('Method not implemented.'); + } + idForNodeType(type: string, named: boolean): number { + throw new Error('Method not implemented.'); + } + nodeTypeForId(typeId: number): string | null { + throw new Error('Method not implemented.'); + } + nodeTypeIsNamed(typeId: number): boolean { + throw new Error('Method not implemented.'); + } + nodeTypeIsVisible(typeId: number): boolean { + throw new Error('Method not implemented.'); + } + nextState(stateId: number, typeId: number): number { + throw new Error('Method not implemented.'); + } + query(source: string): Parser.Query { + throw new Error('Method not implemented.'); + } + lookaheadIterator(stateId: number): Parser.LookaheadIterable | null { + throw new Error('Method not implemented.'); + } + languageId: string = ''; +} + +class MockTreeSitterParser extends TreeSitterParser { + public override async parse(model: ITextModel, treeSitterTree: TreeSitterTree): Promise { + return new MockTree(); + } + public override async getLanguage(languageId: string): Promise { + if (languageId === 'javascript') { + await new Promise(resolve => setTimeout(resolve, 200)); + } + const language = new MockLanguage(); + language.languageId = languageId; + return language; + } +} + +suite('TreeSitterParserService', function () { + const treeSitterImporter: TreeSitterImporter = new MockTreeSitterImporter(); + setup(function () { + }); + + const store = ensureNoDisposablesAreLeakedInTestSuite(); + + test('TextModelTreeSitter race condition: first language is slow to load', async function () { + const treeSitterParser: TreeSitterParser = store.add(new MockTreeSitterParser(treeSitterImporter, {} as any, {} as any, {} as any)); + const textModel = store.add(createTextModel('console.log("Hello, world!");', 'javascript')); + const textModelTreeSitter = store.add(new TextModelTreeSitter(textModel, treeSitterParser, treeSitterImporter)); + textModel.setLanguage('typescript'); + await timeout(300); + assert.strictEqual((textModelTreeSitter.tree?.language as MockLanguage).languageId, 'typescript'); + }); +}); From 7e82f060964a5538fcd6f068d557ae113976e3d1 Mon Sep 17 00:00:00 2001 From: Alex Ross Date: Thu, 18 Jul 2024 12:08:56 +0200 Subject: [PATCH 34/37] Use same timeout --- .../test/browser/services/treeSitterParserService.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/editor/test/browser/services/treeSitterParserService.test.ts b/src/vs/editor/test/browser/services/treeSitterParserService.test.ts index b65cc00510413..08b97ccc71808 100644 --- a/src/vs/editor/test/browser/services/treeSitterParserService.test.ts +++ b/src/vs/editor/test/browser/services/treeSitterParserService.test.ts @@ -109,7 +109,7 @@ class MockTreeSitterParser extends TreeSitterParser { } public override async getLanguage(languageId: string): Promise { if (languageId === 'javascript') { - await new Promise(resolve => setTimeout(resolve, 200)); + await timeout(200); } const language = new MockLanguage(); language.languageId = languageId; From 13a6a3b3f4183854faff746b6da8ec41ece5625b Mon Sep 17 00:00:00 2001 From: Alex Ross Date: Thu, 18 Jul 2024 15:15:55 +0200 Subject: [PATCH 35/37] Queue content changes --- .../treeSitter/treeSitterParserService.ts | 12 +++- .../services/treeSitterParserService.test.ts | 58 ++++++++++++++----- 2 files changed, 53 insertions(+), 17 deletions(-) diff --git a/src/vs/editor/browser/services/treeSitter/treeSitterParserService.ts b/src/vs/editor/browser/services/treeSitter/treeSitterParserService.ts index a047122178d71..6ea45b37a22da 100644 --- a/src/vs/editor/browser/services/treeSitter/treeSitterParserService.ts +++ b/src/vs/editor/browser/services/treeSitter/treeSitterParserService.ts @@ -58,8 +58,8 @@ export class TextModelTreeSitter extends Disposable { } const treeSitterTree = this._languageSessionDisposables.add(new TreeSitterTree(new Parser(), language)); - this._languageSessionDisposables.add(this.model.onDidChangeContent(e => this._onDidChangeContent(treeSitterTree, e))); - await this._onDidChangeContent(treeSitterTree); + this._languageSessionDisposables.add(this.model.onDidChangeContent(e => this._queueOnDidChangeContent(treeSitterTree, e))); + await this._queueOnDidChangeContent(treeSitterTree); if (token.isCancellationRequested) { return; } @@ -67,6 +67,13 @@ export class TextModelTreeSitter extends Disposable { this._treeSitterTree = treeSitterTree; } + private _onDidChangeContentQueue: Promise = Promise.resolve(); + private async _queueOnDidChangeContent(treeSitterTree: TreeSitterTree, e?: IModelContentChangedEvent) { + await this._onDidChangeContentQueue; + this._onDidChangeContentQueue = this._onDidChangeContentQueue.then(() => this._onDidChangeContent(treeSitterTree, e)).catch(() => { }); + return this._onDidChangeContentQueue; + } + private async _onDidChangeContent(treeSitterTree: TreeSitterTree, e?: IModelContentChangedEvent) { if (e) { for (const change of e.changes) { @@ -89,7 +96,6 @@ export class TextModelTreeSitter extends Disposable { override dispose() { super.dispose(); - this._languageSessionDisposables.dispose(); } } diff --git a/src/vs/editor/test/browser/services/treeSitterParserService.test.ts b/src/vs/editor/test/browser/services/treeSitterParserService.test.ts index 08b97ccc71808..cec28c4973999 100644 --- a/src/vs/editor/test/browser/services/treeSitterParserService.test.ts +++ b/src/vs/editor/test/browser/services/treeSitterParserService.test.ts @@ -40,6 +40,7 @@ class MockTreeSitterImporter extends TreeSitterImporter { class MockTree implements Parser.Tree { editorLanguage: string = ''; + editorContents: string = ''; rootNode: Parser.SyntaxNode = {} as any; rootNodeWithOffset(offsetBytes: number, offsetExtent: Parser.Point): Parser.SyntaxNode { throw new Error('Method not implemented.'); @@ -49,7 +50,7 @@ class MockTree implements Parser.Tree { } delete(): void { } edit(edit: Parser.Edit): Parser.Tree { - throw new Error('Method not implemented.'); + return this; } walk(): Parser.TreeCursor { throw new Error('Method not implemented.'); @@ -103,19 +104,7 @@ class MockLanguage implements Parser.Language { languageId: string = ''; } -class MockTreeSitterParser extends TreeSitterParser { - public override async parse(model: ITextModel, treeSitterTree: TreeSitterTree): Promise { - return new MockTree(); - } - public override async getLanguage(languageId: string): Promise { - if (languageId === 'javascript') { - await timeout(200); - } - const language = new MockLanguage(); - language.languageId = languageId; - return language; - } -} + suite('TreeSitterParserService', function () { const treeSitterImporter: TreeSitterImporter = new MockTreeSitterImporter(); @@ -125,6 +114,20 @@ suite('TreeSitterParserService', function () { const store = ensureNoDisposablesAreLeakedInTestSuite(); test('TextModelTreeSitter race condition: first language is slow to load', async function () { + class MockTreeSitterParser extends TreeSitterParser { + public override async parse(model: ITextModel, treeSitterTree: TreeSitterTree): Promise { + return new MockTree(); + } + public override async getLanguage(languageId: string): Promise { + if (languageId === 'javascript') { + await timeout(200); + } + const language = new MockLanguage(); + language.languageId = languageId; + return language; + } + } + const treeSitterParser: TreeSitterParser = store.add(new MockTreeSitterParser(treeSitterImporter, {} as any, {} as any, {} as any)); const textModel = store.add(createTextModel('console.log("Hello, world!");', 'javascript')); const textModelTreeSitter = store.add(new TextModelTreeSitter(textModel, treeSitterParser, treeSitterImporter)); @@ -132,4 +135,31 @@ suite('TreeSitterParserService', function () { await timeout(300); assert.strictEqual((textModelTreeSitter.tree?.language as MockLanguage).languageId, 'typescript'); }); + + test('TextModelTreeSitter race condition: earlier parse is much slower than later parse', async function () { + class MockTreeSitterParser extends TreeSitterParser { + private _parseCount = 0; + public override async parse(model: ITextModel, treeSitterTree: TreeSitterTree): Promise { + const tree = new MockTree(); + tree.editorContents = model.getValue(); + this._parseCount++; + if (this._parseCount === 1) { + await timeout(200); + } + return tree; + } + public override async getLanguage(languageId: string): Promise { + return new MockLanguage(); + } + } + + const treeSitterParser: TreeSitterParser = store.add(new MockTreeSitterParser(treeSitterImporter, {} as any, {} as any, {} as any)); + const textModel = store.add(createTextModel('console.log("Hello, world!");', 'typescript')); + const textModelTreeSitter = store.add(new TextModelTreeSitter(textModel, treeSitterParser, treeSitterImporter)); + const secondEditorValue = 'console.log("Hi, world!");'; + await timeout(100); + textModel.setValue(secondEditorValue); + await timeout(400); + assert.strictEqual((textModelTreeSitter.tree?.tree as MockTree).editorContents, secondEditorValue); + }); }); From d08bbb180e3d7c5f605721bede4bb109ded78e73 Mon Sep 17 00:00:00 2001 From: Alex Ross Date: Fri, 19 Jul 2024 17:04:45 +0200 Subject: [PATCH 36/37] Remove override dispose --- .../services/treeSitter/treeSitterParserService.ts | 9 --------- 1 file changed, 9 deletions(-) diff --git a/src/vs/editor/browser/services/treeSitter/treeSitterParserService.ts b/src/vs/editor/browser/services/treeSitter/treeSitterParserService.ts index 6ea45b37a22da..0d9715f896690 100644 --- a/src/vs/editor/browser/services/treeSitter/treeSitterParserService.ts +++ b/src/vs/editor/browser/services/treeSitter/treeSitterParserService.ts @@ -93,10 +93,6 @@ export class TextModelTreeSitter extends Disposable { treeSitterTree.tree = await this._treeSitterParser.parse(this.model, treeSitterTree); } - - override dispose() { - super.dispose(); - } } export class TreeSitterTree implements IDisposable { @@ -334,9 +330,4 @@ export class TreeSitterTextModelService extends Disposable implements ITreeSitte this._registeredLanguages.deleteAndDispose('typescript'); } } - - public override dispose(): void { - super.dispose(); - this._textModelTreeSitters.dispose(); - } } From 26edd5cf2a5a4703cc7ac9d224b69db8bbb18e63 Mon Sep 17 00:00:00 2001 From: Alex Ross Date: Mon, 22 Jul 2024 11:26:22 +0200 Subject: [PATCH 37/37] Move queue into TreeSitterTree --- .../treeSitter/treeSitterParserService.ts | 114 ++++++++++-------- .../services/treeSitterParserService.test.ts | 53 +++----- 2 files changed, 80 insertions(+), 87 deletions(-) diff --git a/src/vs/editor/browser/services/treeSitter/treeSitterParserService.ts b/src/vs/editor/browser/services/treeSitter/treeSitterParserService.ts index 0d9715f896690..7b1b17c613357 100644 --- a/src/vs/editor/browser/services/treeSitter/treeSitterParserService.ts +++ b/src/vs/editor/browser/services/treeSitter/treeSitterParserService.ts @@ -31,8 +31,10 @@ export class TextModelTreeSitter extends Disposable { get tree() { return this._treeSitterTree; } constructor(readonly model: ITextModel, - private readonly _treeSitterParser: TreeSitterParser, + private readonly _treeSitterParser: TreeSitterLanguages, private readonly _treeSitterImporter: TreeSitterImporter, + private readonly _logService: ILogService, + private readonly _telemetryService: ITelemetryService ) { super(); this._register(Event.runAndSubscribe(this.model.onDidChangeLanguage, (e => this._onDidChangeLanguage(e ? e.newLanguage : this.model.getLanguageId())))); @@ -57,9 +59,9 @@ export class TextModelTreeSitter extends Disposable { return; } - const treeSitterTree = this._languageSessionDisposables.add(new TreeSitterTree(new Parser(), language)); - this._languageSessionDisposables.add(this.model.onDidChangeContent(e => this._queueOnDidChangeContent(treeSitterTree, e))); - await this._queueOnDidChangeContent(treeSitterTree); + const treeSitterTree = this._languageSessionDisposables.add(new TreeSitterTree(new Parser(), language, this._logService, this._telemetryService)); + this._languageSessionDisposables.add(this.model.onDidChangeContent(e => this._onDidChangeContent(treeSitterTree, e))); + await this._onDidChangeContent(treeSitterTree); if (token.isCancellationRequested) { return; } @@ -67,38 +69,18 @@ export class TextModelTreeSitter extends Disposable { this._treeSitterTree = treeSitterTree; } - private _onDidChangeContentQueue: Promise = Promise.resolve(); - private async _queueOnDidChangeContent(treeSitterTree: TreeSitterTree, e?: IModelContentChangedEvent) { - await this._onDidChangeContentQueue; - this._onDidChangeContentQueue = this._onDidChangeContentQueue.then(() => this._onDidChangeContent(treeSitterTree, e)).catch(() => { }); - return this._onDidChangeContentQueue; - } - private async _onDidChangeContent(treeSitterTree: TreeSitterTree, e?: IModelContentChangedEvent) { - if (e) { - for (const change of e.changes) { - const newEndOffset = change.rangeOffset + change.text.length; - const newEndPosition = this.model.getPositionAt(newEndOffset); - - treeSitterTree.tree?.edit({ - startIndex: change.rangeOffset, - oldEndIndex: change.rangeOffset + change.rangeLength, - newEndIndex: change.rangeOffset + change.text.length, - startPosition: { row: change.range.startLineNumber - 1, column: change.range.startColumn - 1 }, - oldEndPosition: { row: change.range.endLineNumber - 1, column: change.range.endColumn - 1 }, - newEndPosition: { row: newEndPosition.lineNumber - 1, column: newEndPosition.column - 1 } - }); - } - } - - treeSitterTree.tree = await this._treeSitterParser.parse(this.model, treeSitterTree); + return treeSitterTree.onDidChangeContent(this.model, e); } } export class TreeSitterTree implements IDisposable { private _tree: Parser.Tree | undefined; private _isDisposed: boolean = false; - constructor(public readonly parser: Parser, public /** exposed for tests **/ readonly language: Parser.Language) { + constructor(public readonly parser: Parser, + public /** exposed for tests **/ readonly language: Parser.Language, + private readonly _logService: ILogService, + private readonly _telemetryService: ITelemetryService) { this.parser.setTimeoutMicros(50 * 1000); // 50 ms this.parser.setLanguage(language); } @@ -113,30 +95,52 @@ export class TreeSitterTree implements IDisposable { this._tree = newTree; } get isDisposed() { return this._isDisposed; } -} -export class TreeSitterParser extends Disposable { - private _languages: Map = new Map(); + private _onDidChangeContentQueue: Promise = Promise.resolve(); + public async onDidChangeContent(model: ITextModel, e?: IModelContentChangedEvent) { + this._onDidChangeContentQueue = this._onDidChangeContentQueue.then(() => { + if (this.isDisposed) { + // No need to continue the queue if we are disposed + return; + } + return this._onDidChangeContent(model, e); + }).catch((e) => { + this._logService.error('Error parsing tree-sitter tree', e); + }); + return this._onDidChangeContentQueue; + } - constructor(private readonly _treeSitterImporter: TreeSitterImporter, - private readonly _fileService: IFileService, - private readonly _logService: ILogService, - private readonly _telemetryService: ITelemetryService - ) { - super(); + private async _onDidChangeContent(model: ITextModel, e?: IModelContentChangedEvent) { + if (e) { + for (const change of e.changes) { + const newEndOffset = change.rangeOffset + change.text.length; + const newEndPosition = model.getPositionAt(newEndOffset); + + this.tree?.edit({ + startIndex: change.rangeOffset, + oldEndIndex: change.rangeOffset + change.rangeLength, + newEndIndex: change.rangeOffset + change.text.length, + startPosition: { row: change.range.startLineNumber - 1, column: change.range.startColumn - 1 }, + oldEndPosition: { row: change.range.endLineNumber - 1, column: change.range.endColumn - 1 }, + newEndPosition: { row: newEndPosition.lineNumber - 1, column: newEndPosition.column - 1 } + }); + } + } + + this.tree = await this.parse(model); } - public parse(model: ITextModel, treeSitterTree: TreeSitterTree): Promise { + private parse(model: ITextModel): Promise { let telemetryTag: string; - if (treeSitterTree.tree) { + if (this.tree) { telemetryTag = 'incrementalParse'; } else { telemetryTag = 'fullParse'; } - return this._parseAndYield(model, treeSitterTree, telemetryTag); + return this._parseAndYield(model, telemetryTag); } - private async _parseAndYield(model: ITextModel, treeSitterTree: TreeSitterTree, telemetryTag: string): Promise { + private async _parseAndYield(model: ITextModel, telemetryTag: string): Promise { const language = model.getLanguageId(); let tree: Parser.Tree | undefined; let time: number = 0; @@ -144,7 +148,7 @@ export class TreeSitterParser extends Disposable { do { const timer = performance.now(); try { - tree = treeSitterTree.parser.parse((index: number, position?: Parser.Point) => this._parseCallback(model, index), treeSitterTree.tree); + tree = this.parser.parse((index: number, position?: Parser.Point) => this._parseCallback(model, index), this.tree); } catch (e) { // parsing can fail when the timeout is reached, will resume upon next loop } finally { @@ -155,7 +159,7 @@ export class TreeSitterParser extends Disposable { // Even if the model changes and edits are applied, the tree parsing will continue correctly after the await. await new Promise(resolve => setTimeout0(resolve)); - if (model.isDisposed() || treeSitterTree.isDisposed) { + if (model.isDisposed() || this.isDisposed) { return; } } while (!tree); @@ -168,7 +172,7 @@ export class TreeSitterParser extends Disposable { } private sendParseTimeTelemetry(eventName: string, languageId: string, time: number, passes: number): void { - this._logService.info(`Tree parsing (${eventName}) took ${time} ms and ${passes} passes.`); + this._logService.debug(`Tree parsing (${eventName}) took ${time} ms and ${passes} passes.`); type ParseTimeClassification = { owner: 'alros'; comment: 'Used to understand how long it takes to parse a tree-sitter tree'; @@ -178,6 +182,16 @@ export class TreeSitterParser extends Disposable { }; this._telemetryService.publicLog2<{ languageId: string; time: number; passes: number }, ParseTimeClassification>(`treeSitter.${eventName}`, { languageId, time, passes }); } +} + +export class TreeSitterLanguages extends Disposable { + private _languages: Map = new Map(); + + constructor(private readonly _treeSitterImporter: TreeSitterImporter, + private readonly _fileService: IFileService + ) { + super(); + } public async getLanguage(languageId: string): Promise { let language = this._languages.get(languageId); @@ -236,16 +250,16 @@ export class TreeSitterTextModelService extends Disposable implements ITreeSitte private _textModelTreeSitters: DisposableMap = this._register(new DisposableMap()); private _registeredLanguages: DisposableMap = this._register(new DisposableMap()); private readonly _treeSitterImporter: TreeSitterImporter = new TreeSitterImporter(); - private readonly _treeSitterParser: TreeSitterParser; + private readonly _treeSitterParser: TreeSitterLanguages; constructor(@IModelService private readonly _modelService: IModelService, @IFileService fileService: IFileService, - @ITelemetryService telemetryService: ITelemetryService, - @ILogService logService: ILogService, + @ITelemetryService private readonly _telemetryService: ITelemetryService, + @ILogService private readonly _logService: ILogService, @IConfigurationService private readonly _configurationService: IConfigurationService, ) { super(); - this._treeSitterParser = this._register(new TreeSitterParser(this._treeSitterImporter, fileService, logService, telemetryService)); + this._treeSitterParser = this._register(new TreeSitterLanguages(this._treeSitterImporter, fileService)); this._register(this._configurationService.onDidChangeConfiguration(e => { if (e.affectsConfiguration(EDITOR_EXPERIMENTAL_PREFER_TREESITTER)) { this._supportedLanguagesChanged(); @@ -315,7 +329,7 @@ export class TreeSitterTextModelService extends Disposable implements ITreeSitte } private _createTextModelTreeSitter(model: ITextModel) { - const textModelTreeSitter = new TextModelTreeSitter(model, this._treeSitterParser, this._treeSitterImporter); + const textModelTreeSitter = new TextModelTreeSitter(model, this._treeSitterParser, this._treeSitterImporter, this._logService, this._telemetryService); this._textModelTreeSitters.set(model, textModelTreeSitter); } diff --git a/src/vs/editor/test/browser/services/treeSitterParserService.test.ts b/src/vs/editor/test/browser/services/treeSitterParserService.test.ts index cec28c4973999..be1b58185ad25 100644 --- a/src/vs/editor/test/browser/services/treeSitterParserService.test.ts +++ b/src/vs/editor/test/browser/services/treeSitterParserService.test.ts @@ -4,11 +4,14 @@ *--------------------------------------------------------------------------------------------*/ import assert from 'assert'; import { ensureNoDisposablesAreLeakedInTestSuite } from 'vs/base/test/common/utils'; -import { TextModelTreeSitter, TreeSitterImporter, TreeSitterParser, TreeSitterTree } from 'vs/editor/browser/services/treeSitter/treeSitterParserService'; +import { TextModelTreeSitter, TreeSitterImporter, TreeSitterLanguages } from 'vs/editor/browser/services/treeSitter/treeSitterParserService'; import type { Parser } from '@vscode/tree-sitter-wasm'; -import { ITextModel } from 'vs/editor/common/model'; import { createTextModel } from 'vs/editor/test/common/testTextModel'; import { timeout } from 'vs/base/common/async'; +import { ConsoleMainLogger, ILogService } from 'vs/platform/log/common/log'; +import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; +import { LogService } from 'vs/platform/log/common/logService'; +import { mock } from 'vs/base/test/common/mock'; class MockParser implements Parser { static async init(): Promise { } @@ -104,20 +107,23 @@ class MockLanguage implements Parser.Language { languageId: string = ''; } - - suite('TreeSitterParserService', function () { const treeSitterImporter: TreeSitterImporter = new MockTreeSitterImporter(); + let logService: ILogService; + let telemetryService: ITelemetryService; setup(function () { + logService = new LogService(new ConsoleMainLogger()); + telemetryService = new class extends mock() { + override async publicLog2() { + // + } + }; }); const store = ensureNoDisposablesAreLeakedInTestSuite(); test('TextModelTreeSitter race condition: first language is slow to load', async function () { - class MockTreeSitterParser extends TreeSitterParser { - public override async parse(model: ITextModel, treeSitterTree: TreeSitterTree): Promise { - return new MockTree(); - } + class MockTreeSitterParser extends TreeSitterLanguages { public override async getLanguage(languageId: string): Promise { if (languageId === 'javascript') { await timeout(200); @@ -128,38 +134,11 @@ suite('TreeSitterParserService', function () { } } - const treeSitterParser: TreeSitterParser = store.add(new MockTreeSitterParser(treeSitterImporter, {} as any, {} as any, {} as any)); + const treeSitterParser: TreeSitterLanguages = store.add(new MockTreeSitterParser(treeSitterImporter, {} as any)); const textModel = store.add(createTextModel('console.log("Hello, world!");', 'javascript')); - const textModelTreeSitter = store.add(new TextModelTreeSitter(textModel, treeSitterParser, treeSitterImporter)); + const textModelTreeSitter = store.add(new TextModelTreeSitter(textModel, treeSitterParser, treeSitterImporter, logService, telemetryService)); textModel.setLanguage('typescript'); await timeout(300); assert.strictEqual((textModelTreeSitter.tree?.language as MockLanguage).languageId, 'typescript'); }); - - test('TextModelTreeSitter race condition: earlier parse is much slower than later parse', async function () { - class MockTreeSitterParser extends TreeSitterParser { - private _parseCount = 0; - public override async parse(model: ITextModel, treeSitterTree: TreeSitterTree): Promise { - const tree = new MockTree(); - tree.editorContents = model.getValue(); - this._parseCount++; - if (this._parseCount === 1) { - await timeout(200); - } - return tree; - } - public override async getLanguage(languageId: string): Promise { - return new MockLanguage(); - } - } - - const treeSitterParser: TreeSitterParser = store.add(new MockTreeSitterParser(treeSitterImporter, {} as any, {} as any, {} as any)); - const textModel = store.add(createTextModel('console.log("Hello, world!");', 'typescript')); - const textModelTreeSitter = store.add(new TextModelTreeSitter(textModel, treeSitterParser, treeSitterImporter)); - const secondEditorValue = 'console.log("Hi, world!");'; - await timeout(100); - textModel.setValue(secondEditorValue); - await timeout(400); - assert.strictEqual((textModelTreeSitter.tree?.tree as MockTree).editorContents, secondEditorValue); - }); });