From 180356641c5b286be761b1072375bdb9c10f8208 Mon Sep 17 00:00:00 2001 From: Henning Dieterichs Date: Sun, 5 Jun 2022 15:29:43 +0200 Subject: [PATCH 001/117] Makes diff editor more reactive. Now, changes to inputs or base are handled gracefully. --- .../contrib/audioCues/browser/observable.ts | 104 +++- .../mergeEditor/browser/mergeEditor.ts | 107 ++-- .../mergeEditor/browser/mergeEditorInput.ts | 22 +- .../mergeEditor/browser/mergeEditorModel.ts | 538 ++++++------------ .../mergeEditor/browser/textModelDiffs.ts | 233 ++++++++ 5 files changed, 569 insertions(+), 435 deletions(-) create mode 100644 src/vs/workbench/contrib/mergeEditor/browser/textModelDiffs.ts diff --git a/src/vs/workbench/contrib/audioCues/browser/observable.ts b/src/vs/workbench/contrib/audioCues/browser/observable.ts index c3974606057..32fe7ccda98 100644 --- a/src/vs/workbench/contrib/audioCues/browser/observable.ts +++ b/src/vs/workbench/contrib/audioCues/browser/observable.ts @@ -3,10 +3,13 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +import { BugIndicatingError } from 'vs/base/common/errors'; import { Event } from 'vs/base/common/event'; import { DisposableStore, IDisposable, toDisposable } from 'vs/base/common/lifecycle'; -export interface IObservable { +export interface IObservable { + _change: TChange; + /** * Reads the current value. * @@ -39,7 +42,7 @@ export interface IReader { * * Is called by `Observable.read`. */ - handleBeforeReadObservable(observable: IObservable): void; + handleBeforeReadObservable(observable: IObservable): void; } export interface IObserver { @@ -61,7 +64,7 @@ export interface IObserver { * Implementations must not call into other observables! * The change should be processed when {@link IObserver.endUpdate} is called. */ - handleChange(observable: IObservable): void; + handleChange(observable: IObservable, change: TChange): void; /** * Indicates that an update operation has completed. @@ -69,8 +72,8 @@ export interface IObserver { endUpdate(observable: IObservable): void; } -export interface ISettable { - set(value: T, transaction: ITransaction | undefined): void; +export interface ISettable { + set(value: T, transaction: ITransaction | undefined, change: TChange): void; } export interface ITransaction { @@ -80,12 +83,14 @@ export interface ITransaction { */ updateObserver( observer: IObserver, - observable: IObservable + observable: IObservable ): void; } // === Base === -export abstract class ConvenientObservable implements IObservable { +export abstract class ConvenientObservable implements IObservable { + get _change(): TChange { return null!; } + public abstract get(): T; public abstract subscribe(observer: IObserver): void; public abstract unsubscribe(observer: IObserver): void; @@ -100,7 +105,7 @@ export abstract class ConvenientObservable implements IObservable { } } -export abstract class BaseObservable extends ConvenientObservable { +export abstract class BaseObservable extends ConvenientObservable { protected readonly observers = new Set(); public subscribe(observer: IObserver): void { @@ -151,9 +156,9 @@ class TransactionImpl implements ITransaction { } } -export class ObservableValue - extends BaseObservable - implements ISettable +export class ObservableValue + extends BaseObservable + implements ISettable { private value: T; @@ -166,14 +171,14 @@ export class ObservableValue return this.value; } - public set(value: T, tx: ITransaction | undefined): void { + public set(value: T, tx: ITransaction | undefined, change: TChange): void { if (this.value === value) { return; } if (!tx) { transaction((tx) => { - this.set(value, tx); + this.set(value, tx, change); }); return; } @@ -182,7 +187,7 @@ export class ObservableValue for (const observer of this.observers) { tx.updateObserver(observer, this); - observer.handleChange(this); + observer.handleChange(this, change); } } } @@ -191,7 +196,7 @@ export function constObservable(value: T): IObservable { return new ConstObservable(value); } -class ConstObservable extends ConvenientObservable { +class ConstObservable extends ConvenientObservable { constructor(private readonly value: T) { super(); } @@ -208,11 +213,28 @@ class ConstObservable extends ConvenientObservable { } // == autorun == -export function autorun( - fn: (reader: IReader) => void, - name: string +export function autorun(fn: (reader: IReader) => void, name: string): IDisposable { + return new AutorunObserver(fn, name, undefined); +} + +interface IChangeContext { + readonly changedObservable: IObservable; + readonly change: unknown; + + didChange(observable: IObservable): this is { change: TChange }; +} + +export function autorunHandleChanges( + name: string, + options: { + /** + * Returns if this change should cause a re-run of the autorun. + */ + handleChange: (context: IChangeContext) => boolean; + }, + fn: (reader: IReader) => void ): IDisposable { - return new AutorunObserver(fn, name); + return new AutorunObserver(fn, name, options.handleChange); } export function autorunWithStore( @@ -252,7 +274,8 @@ export class AutorunObserver implements IObserver, IReader, IDisposable { constructor( private readonly runFn: (reader: IReader) => void, - public readonly name: string + public readonly name: string, + private readonly _handleChange: ((context: IChangeContext) => boolean) | undefined ) { this.runIfNeeded(); } @@ -264,8 +287,13 @@ export class AutorunObserver implements IObserver, IReader, IDisposable { } } - public handleChange() { - this.needsToRun = true; + public handleChange(observable: IObservable, change: TChange): void { + const shouldReact = this._handleChange ? this._handleChange({ + changedObservable: observable, + change, + didChange: o => o === observable as any, + }) : true; + this.needsToRun = this.needsToRun || shouldReact; if (this.updateCount === 0) { this.runIfNeeded(); @@ -337,7 +365,7 @@ export function autorunDelta( export function derivedObservable(name: string, computeFn: (reader: IReader) => T): IObservable { return new LazyDerived(computeFn, name); } -export class LazyDerived extends ConvenientObservable { +export class LazyDerived extends ConvenientObservable { private readonly observer: LazyDerivedObserver; constructor(computeFn: (reader: IReader) => T, name: string) { @@ -366,7 +394,7 @@ export class LazyDerived extends ConvenientObservable { * @internal */ class LazyDerivedObserver - extends BaseObservable + extends BaseObservable implements IReader, IObserver { private hadValue = false; private hasValue = false; @@ -486,9 +514,8 @@ class LazyDerivedObserver this.hasValue = true; if (this.hadValue && oldValue !== this.value) { - // for (const r of this.observers) { - r.handleChange(this); + r.handleChange(this, undefined); } } } @@ -508,6 +535,20 @@ export function observableFromPromise(promise: Promise): IObservable<{ val return observable; } +export function waitForState(observable: IObservable, predicate: (state: T) => state is TState): Promise; +export function waitForState(observable: IObservable, predicate: (state: T) => boolean): Promise; +export function waitForState(observable: IObservable, predicate: (state: T) => boolean): Promise { + return new Promise(resolve => { + const d = autorun(reader => { + const currentState = observable.read(reader); + if (predicate(currentState)) { + d.dispose(); + resolve(currentState); + } + }, 'waitForState'); + }); +} + export function observableFromEvent( event: Event, getValue: (args: TArgs | undefined) => T @@ -540,7 +581,7 @@ class FromEventObservable extends BaseObservable { transaction(tx => { for (const o of this.observers) { tx.updateObserver(o, this); - o.handleChange(this); + o.handleChange(this, undefined); } }); } @@ -622,3 +663,12 @@ export function keepAlive(observable: IObservable): IDisposable { observable.read(reader); }, 'keep-alive'); } + +export function derivedObservableWithCache(name: string, computeFn: (reader: IReader, lastValue: T | undefined) => T): IObservable { + let lastValue: T | undefined = undefined; + const observable = derivedObservable(name, reader => { + lastValue = computeFn(reader, lastValue); + return lastValue; + }); + return observable; +} diff --git a/src/vs/workbench/contrib/mergeEditor/browser/mergeEditor.ts b/src/vs/workbench/contrib/mergeEditor/browser/mergeEditor.ts index d90564b396a..992bae6cda7 100644 --- a/src/vs/workbench/contrib/mergeEditor/browser/mergeEditor.ts +++ b/src/vs/workbench/contrib/mergeEditor/browser/mergeEditor.ts @@ -30,6 +30,7 @@ import { ITextResourceConfigurationService } from 'vs/editor/common/services/tex import { localize } from 'vs/nls'; import { createAndFillInActionBarActions } from 'vs/platform/actions/browser/menuEntryActionViewItem'; import { IMenuService, MenuId } from 'vs/platform/actions/common/actions'; +import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { IContextKey, IContextKeyService, RawContextKey } from 'vs/platform/contextkey/common/contextkey'; import { IEditorOptions } from 'vs/platform/editor/common/editor'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; @@ -41,7 +42,7 @@ import { FloatingClickWidget } from 'vs/workbench/browser/codeeditor'; import { EditorPane } from 'vs/workbench/browser/parts/editor/editorPane'; import { IEditorControl, IEditorOpenContext } from 'vs/workbench/common/editor'; import { EditorInput } from 'vs/workbench/common/editor/editorInput'; -import { autorun, derivedObservable, IObservable, ITransaction, keepAlive, ObservableValue } from 'vs/workbench/contrib/audioCues/browser/observable'; +import { autorun, autorunWithStore, derivedObservable, IObservable, ITransaction, keepAlive, ObservableValue, transaction } from 'vs/workbench/contrib/audioCues/browser/observable'; import { MergeEditorInput } from 'vs/workbench/contrib/mergeEditor/browser/mergeEditorInput'; import { MergeEditorModel } from 'vs/workbench/contrib/mergeEditor/browser/mergeEditorModel'; import { LineRange, ModifiedBaseRange } from 'vs/workbench/contrib/mergeEditor/browser/model'; @@ -60,8 +61,8 @@ export class MergeEditor extends EditorPane { private _grid!: Grid; - private readonly input1View = this.instantiation.createInstance(InputCodeEditorView, 1, { readonly: true }); - private readonly input2View = this.instantiation.createInstance(InputCodeEditorView, 2, { readonly: true }); + private readonly input1View = this.instantiation.createInstance(InputCodeEditorView, 1, { readonly: !this.inputsWritable }); + private readonly input2View = this.instantiation.createInstance(InputCodeEditorView, 2, { readonly: !this.inputsWritable }); private readonly inputResultView = this.instantiation.createInstance(ResultCodeEditorView, { readonly: false }); private readonly _ctxIsMergeEditor: IContextKey; @@ -70,6 +71,10 @@ export class MergeEditor extends EditorPane { private _model: MergeEditorModel | undefined; public get model(): MergeEditorModel | undefined { return this._model; } + private get inputsWritable(): boolean { + return !!this._configurationService.getValue('mergeEditor.writableInputs'); + } + constructor( @IInstantiationService private readonly instantiation: IInstantiationService, @ILabelService private readonly _labelService: ILabelService, @@ -79,6 +84,7 @@ export class MergeEditor extends EditorPane { @IStorageService storageService: IStorageService, @IThemeService themeService: IThemeService, @ITextResourceConfigurationService private readonly textResourceConfigurationService: ITextResourceConfigurationService, + @IConfigurationService private readonly _configurationService: IConfigurationService, ) { super(MergeEditor.ID, telemetryService, themeService, storageService); @@ -93,7 +99,7 @@ export class MergeEditor extends EditorPane { return undefined; } const resultDiffs = model.resultDiffs.read(reader); - const modifiedBaseRanges = ModifiedBaseRange.fromDiffs(model.base, model.input1, model.input1LinesDiffs, model.result, resultDiffs); + const modifiedBaseRanges = ModifiedBaseRange.fromDiffs(model.base, model.input1, model.input1LinesDiffs.read(reader), model.result, resultDiffs); return modifiedBaseRanges; }); const input2ResultMapping = derivedObservable('input2ResultMapping', reader => { @@ -102,7 +108,7 @@ export class MergeEditor extends EditorPane { return undefined; } const resultDiffs = model.resultDiffs.read(reader); - const modifiedBaseRanges = ModifiedBaseRange.fromDiffs(model.base, model.input2, model.input2LinesDiffs, model.result, resultDiffs); + const modifiedBaseRanges = ModifiedBaseRange.fromDiffs(model.base, model.input2, model.input2LinesDiffs.read(reader), model.result, resultDiffs); return modifiedBaseRanges; }); @@ -227,42 +233,44 @@ export class MergeEditor extends EditorPane { // TODO: Update editor options! - const input1ViewZoneIds: string[] = []; - const input2ViewZoneIds: string[] = []; - for (const m of model.modifiedBaseRanges) { - const max = Math.max(m.input1Range.lineCount, m.input2Range.lineCount, 1); + this._sessionDisposables.add(autorunWithStore((reader, store) => { + const input1ViewZoneIds: string[] = []; + const input2ViewZoneIds: string[] = []; + for (const m of model.modifiedBaseRanges.read(reader)) { + const max = Math.max(m.input1Range.lineCount, m.input2Range.lineCount, 1); - this.input1View.editor.changeViewZones(a => { - input1ViewZoneIds.push(a.addZone({ - afterLineNumber: m.input1Range.endLineNumberExclusive - 1, - heightInLines: max - m.input1Range.lineCount, - domNode: $('div.diagonal-fill'), - })); - }); - - this.input2View.editor.changeViewZones(a => { - input2ViewZoneIds.push(a.addZone({ - afterLineNumber: m.input2Range.endLineNumberExclusive - 1, - heightInLines: max - m.input2Range.lineCount, - domNode: $('div.diagonal-fill'), - })); - }); - } - - this._sessionDisposables.add({ - dispose: () => { this.input1View.editor.changeViewZones(a => { - for (const zone of input1ViewZoneIds) { - a.removeZone(zone); - } + input1ViewZoneIds.push(a.addZone({ + afterLineNumber: m.input1Range.endLineNumberExclusive - 1, + heightInLines: max - m.input1Range.lineCount, + domNode: $('div.diagonal-fill'), + })); }); + this.input2View.editor.changeViewZones(a => { - for (const zone of input2ViewZoneIds) { - a.removeZone(zone); - } + input2ViewZoneIds.push(a.addZone({ + afterLineNumber: m.input2Range.endLineNumberExclusive - 1, + heightInLines: max - m.input2Range.lineCount, + domNode: $('div.diagonal-fill'), + })); }); } - }); + + store.add({ + dispose: () => { + this.input1View.editor.changeViewZones(a => { + for (const zone of input1ViewZoneIds) { + a.removeZone(zone); + } + }); + this.input2View.editor.changeViewZones(a => { + for (const zone of input2ViewZoneIds) { + a.removeZone(zone); + } + }); + } + }); + }, 'update alignment view zones')); } protected override setEditorVisible(visible: boolean): void { @@ -448,7 +456,7 @@ class InputCodeEditorView extends CodeEditorView { return []; } const result = new Array(); - for (const m of model.modifiedBaseRanges) { + for (const m of model.modifiedBaseRanges.read(reader)) { const range = m.getInputRange(this.inputNumber); if (!range.isEmpty) { result.push({ @@ -478,13 +486,14 @@ class InputCodeEditorView extends CodeEditorView { getIntersectingGutterItems: (range, reader) => { const model = this.model.read(reader); if (!model) { return []; } - return model.modifiedBaseRanges + return model.modifiedBaseRanges.read(reader) .filter((r) => r.getInputDiffs(this.inputNumber).length > 0) .map((baseRange, idx) => ({ id: idx.toString(), additionalHeightInPx: 0, offsetInPx: 0, range: baseRange.getInputRange(this.inputNumber), + enabled: model.isUpToDate, toggleState: derivedObservable('toggle', (reader) => model .getState(baseRange) @@ -510,14 +519,19 @@ class InputCodeEditorView extends CodeEditorView { } interface ModifiedBaseRangeGutterItemInfo extends IGutterItemInfo { + enabled: IObservable; toggleState: IObservable; - setState(value: boolean, tx: ITransaction | undefined): void; + setState(value: boolean, tx: ITransaction): void; } class MergeConflictGutterItemView extends Disposable implements IGutterItemView { - constructor(private item: ModifiedBaseRangeGutterItemInfo, private readonly target: HTMLElement) { + private readonly item = new ObservableValue(undefined, 'item'); + + constructor(item: ModifiedBaseRangeGutterItemInfo, private readonly target: HTMLElement) { super(); + this.item.set(item, undefined); + target.classList.add('merge-accept-gutter-marker'); // TODO: localized title @@ -526,7 +540,8 @@ class MergeConflictGutterItemView extends Disposable implements IGutterItemView< this._register( autorun((reader) => { - const value = this.item.toggleState.read(reader); + const item = this.item.read(reader)!; + const value = item.toggleState.read(reader); checkBox.setIcon( value === true ? Codicon.check @@ -535,11 +550,19 @@ class MergeConflictGutterItemView extends Disposable implements IGutterItemView< : Codicon.circleFilled ); checkBox.checked = value === true; + + if (!item.enabled.read(reader)) { + checkBox.disable(); + } else { + checkBox.enable(); + } }, 'Update Toggle State') ); this._register(checkBox.onChange(() => { - this.item.setState(checkBox.checked, undefined); + transaction(tx => { + this.item.get()!.setState(checkBox.checked, tx); + }); })); target.appendChild(n('div.background', [noBreakWhitespace]).root); @@ -555,7 +578,7 @@ class MergeConflictGutterItemView extends Disposable implements IGutterItemView< } update(baseRange: ModifiedBaseRangeGutterItemInfo): void { - this.item = baseRange; + this.item.set(baseRange, undefined); } } diff --git a/src/vs/workbench/contrib/mergeEditor/browser/mergeEditorInput.ts b/src/vs/workbench/contrib/mergeEditor/browser/mergeEditorInput.ts index f6b69488351..efa8b0360e0 100644 --- a/src/vs/workbench/contrib/mergeEditor/browser/mergeEditorInput.ts +++ b/src/vs/workbench/contrib/mergeEditor/browser/mergeEditorInput.ts @@ -14,7 +14,7 @@ import { ILabelService } from 'vs/platform/label/common/label'; import { IUntypedEditorInput, EditorInputCapabilities } from 'vs/workbench/common/editor'; import { EditorInput } from 'vs/workbench/common/editor/editorInput'; import { AbstractTextResourceEditorInput } from 'vs/workbench/common/editor/textResourceEditorInput'; -import { MergeEditorModel, MergeEditorModelFactory } from 'vs/workbench/contrib/mergeEditor/browser/mergeEditorModel'; +import { MergeEditorModel } from 'vs/workbench/contrib/mergeEditor/browser/mergeEditorModel'; import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; import { ITextFileEditorModel, ITextFileService } from 'vs/workbench/services/textfile/common/textfiles'; @@ -39,10 +39,9 @@ export class MergeEditorInput extends AbstractTextResourceEditorInput { private _model?: MergeEditorModel; private _outTextModel?: ITextFileEditorModel; - private readonly mergeEditorModelFactory = this._instaService.createInstance(MergeEditorModelFactory); constructor( - private readonly _anchestor: URI, + private readonly _base: URI, private readonly _input1: MergeEditorInputData, private readonly _input2: MergeEditorInputData, private readonly _result: URI, @@ -101,13 +100,14 @@ export class MergeEditorInput extends AbstractTextResourceEditorInput { if (!this._model) { - const anchestor = await this._textModelService.createModelReference(this._anchestor); + const base = await this._textModelService.createModelReference(this._base); const input1 = await this._textModelService.createModelReference(this._input1.uri); const input2 = await this._textModelService.createModelReference(this._input2.uri); const result = await this._textModelService.createModelReference(this._result); - this._model = await this.mergeEditorModelFactory.create( - anchestor.object.textEditorModel, + this._model = this._instaService.createInstance( + MergeEditorModel, + base.object.textEditorModel, input1.object.textEditorModel, this._input1.detail, this._input1.description, @@ -117,13 +117,13 @@ export class MergeEditorInput extends AbstractTextResourceEditorInput { result.object.textEditorModel ); + await this._model.onInitialized; + this._store.add(this._model); - this._store.add(anchestor); + this._store.add(base); this._store.add(input1); this._store.add(input2); this._store.add(result); - - // result.object. } return this._model; } @@ -132,7 +132,7 @@ export class MergeEditorInput extends AbstractTextResourceEditorInput { if (!(otherInput instanceof MergeEditorInput)) { return false; } - return isEqual(this._anchestor, otherInput._anchestor) + return isEqual(this._base, otherInput._base) && isEqual(this._input1.uri, otherInput._input1.uri) && isEqual(this._input2.uri, otherInput._input2.uri) && isEqual(this._result, otherInput._result); @@ -140,7 +140,7 @@ export class MergeEditorInput extends AbstractTextResourceEditorInput { toJSON(): MergeEditorInputJSON { return { - anchestor: this._anchestor, + anchestor: this._base, inputOne: this._input1, inputTwo: this._input2, result: this._result, diff --git a/src/vs/workbench/contrib/mergeEditor/browser/mergeEditorModel.ts b/src/vs/workbench/contrib/mergeEditor/browser/mergeEditorModel.ts index 9e32d53e6cc..0d1907a4eb9 100644 --- a/src/vs/workbench/contrib/mergeEditor/browser/mergeEditorModel.ts +++ b/src/vs/workbench/contrib/mergeEditor/browser/mergeEditorModel.ts @@ -3,96 +3,72 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { Emitter } from 'vs/base/common/event'; -import { compareBy, CompareResult, equals, numberComparator } from 'vs/base/common/arrays'; +import { compareBy, CompareResult, equals } from 'vs/base/common/arrays'; import { BugIndicatingError } from 'vs/base/common/errors'; import { ITextModel } from 'vs/editor/common/model'; import { IEditorWorkerService } from 'vs/editor/common/services/editorWorker'; import { EditorModel } from 'vs/workbench/common/editor/editorModel'; -import { IObservable, ITransaction, ObservableValue, transaction } from 'vs/workbench/contrib/audioCues/browser/observable'; -import { ModifiedBaseRange, LineEdit, LineDiff, ModifiedBaseRangeState, LineRange } from 'vs/workbench/contrib/mergeEditor/browser/model'; -import { leftJoin, ReentrancyBarrier } from 'vs/workbench/contrib/mergeEditor/browser/utils'; +import { autorunHandleChanges, derivedObservable, derivedObservableWithCache, IObservable, ITransaction, keepAlive, ObservableValue, transaction, waitForState } from 'vs/workbench/contrib/audioCues/browser/observable'; +import { LineDiff, LineEdit, LineRange, ModifiedBaseRange, ModifiedBaseRangeState } from 'vs/workbench/contrib/mergeEditor/browser/model'; +import { EditorWorkerServiceDiffComputer, TextModelDiffChangeReason, TextModelDiffs, TextModelDiffState } from 'vs/workbench/contrib/mergeEditor/browser/textModelDiffs'; +import { leftJoin } from 'vs/workbench/contrib/mergeEditor/browser/utils'; -export class MergeEditorModelFactory { - constructor( - @IEditorWorkerService private readonly _editorWorkerService: IEditorWorkerService - ) { - } - - public async create( - base: ITextModel, - input1: ITextModel, - input1Detail: string | undefined, - input1Description: string | undefined, - input2: ITextModel, - input2Detail: string | undefined, - input2Description: string | undefined, - result: ITextModel, - ): Promise { - - const baseToInput1DiffPromise = this._editorWorkerService.computeDiff( - base.uri, - input1.uri, - false, - 1000 - ); - const baseToInput2DiffPromise = this._editorWorkerService.computeDiff( - base.uri, - input2.uri, - false, - 1000 - ); - const baseToResultDiffPromise = this._editorWorkerService.computeDiff( - base.uri, - result.uri, - false, - 1000 - ); - - const [baseToInput1Diff, baseToInput2Diff, baseToResultDiff] = await Promise.all([ - baseToInput1DiffPromise, - baseToInput2DiffPromise, - baseToResultDiffPromise - ]); - - const changesInput1 = - baseToInput1Diff?.changes.map((c) => - LineDiff.fromLineChange(c, base, input1) - ) || []; - const changesInput2 = - baseToInput2Diff?.changes.map((c) => - LineDiff.fromLineChange(c, base, input2) - ) || []; - const changesResult = - baseToResultDiff?.changes.map((c) => - LineDiff.fromLineChange(c, base, result) - ) || []; - - return new MergeEditorModel( - InternalSymbol, - base, - input1, - input1Detail, - input1Description, - input2, - input2Detail, - input2Description, - result, - changesInput1, - changesInput2, - changesResult, - this._editorWorkerService, - ); - } +export const enum MergeEditorModelState { + initializing = 1, + upToDate = 2, + updating = 3, } -const InternalSymbol: unique symbol = null!; - export class MergeEditorModel extends EditorModel { - private resultEdits: ResultEdits; + private readonly diffComputer = new EditorWorkerServiceDiffComputer(this.editorWorkerService); + private readonly input1TextModelDiffs = new TextModelDiffs(this.base, this.input1, this.diffComputer); + private readonly input2TextModelDiffs = new TextModelDiffs(this.base, this.input2, this.diffComputer); + private readonly resultTextModelDiffs = new TextModelDiffs(this.base, this.result, this.diffComputer); + + public readonly state = derivedObservable('state', reader => { + const states = [ + this.input1TextModelDiffs, + this.input2TextModelDiffs, + this.resultTextModelDiffs, + ].map((s) => s.state.read(reader)); + + if (states.some((s) => s === TextModelDiffState.initializing)) { + return MergeEditorModelState.initializing; + } + if (states.some((s) => s === TextModelDiffState.updating)) { + return MergeEditorModelState.updating; + } + return MergeEditorModelState.upToDate; + }); + + public readonly isUpToDate = derivedObservable('isUpdating', reader => this.state.read(reader) === MergeEditorModelState.upToDate); + + public readonly onInitialized = waitForState(this.state, state => state === MergeEditorModelState.upToDate); + + public readonly modifiedBaseRanges = derivedObservableWithCache('modifiedBaseRanges', (reader, lastValue) => { + if (this.state.read(reader) !== MergeEditorModelState.upToDate) { + return lastValue || []; + } + + const input1Diffs = this.input1TextModelDiffs.diffs.read(reader); + const input2Diffs = this.input2TextModelDiffs.diffs.read(reader); + + return ModifiedBaseRange.fromDiffs(this.base, this.input1, input1Diffs, this.input2, input2Diffs); + }); + + public readonly input1LinesDiffs = this.input1TextModelDiffs.diffs; + public readonly input2LinesDiffs = this.input2TextModelDiffs.diffs; + public readonly resultDiffs = this.resultTextModelDiffs.diffs; + + private readonly modifiedBaseRangeStateStores = + derivedObservable('modifiedBaseRangeStateStores', reader => { + const map = new Map( + this.modifiedBaseRanges.read(reader).map(s => ([s, new ObservableValue(ModifiedBaseRangeState.default, 'State')])) + ); + return map; + }); constructor( - _symbol: typeof InternalSymbol, readonly base: ITextModel, readonly input1: ITextModel, readonly input1Detail: string | undefined, @@ -101,27 +77,43 @@ export class MergeEditorModel extends EditorModel { readonly input2Detail: string | undefined, readonly input2Description: string | undefined, readonly result: ITextModel, - public readonly input1LinesDiffs: readonly LineDiff[], - public readonly input2LinesDiffs: readonly LineDiff[], - resultDiffs: LineDiff[], - private readonly editorWorkerService: IEditorWorkerService + @IEditorWorkerService private readonly editorWorkerService: IEditorWorkerService ) { super(); - this.resultEdits = new ResultEdits(resultDiffs, this.base, this.result, this.editorWorkerService); - this.resultEdits.onDidChange(() => { - this.recomputeState(); - }); - this.recomputeState(); + this._register(keepAlive(this.modifiedBaseRangeStateStores)); - this.resetUnknown(); + this._register( + autorunHandleChanges( + 'Recompute State', + { + handleChange: (ctx) => + ctx.didChange(this.resultTextModelDiffs.diffs) + // Ignore non-text changes as we update the state directly + ? ctx.change === TextModelDiffChangeReason.textChange + : true, + }, + (reader) => { + if (!this.isUpToDate.read(reader)) { + return; + } + const resultDiffs = this.resultTextModelDiffs.diffs.read(reader); + const stores = this.modifiedBaseRangeStateStores.read(reader); + this.recomputeState(resultDiffs, stores); + } + ) + ); + + this.onInitialized.then(() => { + this.resetUnknown(); + }); } - private recomputeState(): void { + private recomputeState(resultDiffs: LineDiff[], stores: Map>): void { transaction(tx => { const baseRangeWithStoreAndTouchingDiffs = leftJoin( - this.modifiedBaseRangeStateStores, - this.resultEdits.diffs.get(), + stores, + resultDiffs, (baseRange, diff) => baseRange[0].baseRange.touches(diff.originalRange) ? CompareResult.neitherLessOrGreaterThan @@ -132,14 +124,14 @@ export class MergeEditorModel extends EditorModel { ); for (const row of baseRangeWithStoreAndTouchingDiffs) { - row.left[1].set(this.computeState(row.left[0], row.rights), tx); + row.left[1].set(computeState(row.left[0], row.rights), tx); } }); } public resetUnknown(): void { transaction(tx => { - for (const range of this.modifiedBaseRanges) { + for (const range of this.modifiedBaseRanges.get()) { if (this.getState(range).get().conflicting) { this.setState(range, ModifiedBaseRangeState.default, tx); } @@ -149,7 +141,7 @@ export class MergeEditorModel extends EditorModel { public mergeNonConflictingDiffs(): void { transaction((tx) => { - for (const m of this.modifiedBaseRanges) { + for (const m of this.modifiedBaseRanges.get()) { if (m.isConflicting) { continue; } @@ -164,54 +156,8 @@ export class MergeEditorModel extends EditorModel { }); } - public get resultDiffs(): IObservable { - return this.resultEdits.diffs; - } - - public readonly modifiedBaseRanges = ModifiedBaseRange.fromDiffs( - this.base, - this.input1, - this.input1LinesDiffs, - this.input2, - this.input2LinesDiffs - ); - - private readonly modifiedBaseRangeStateStores: ReadonlyMap> = new Map( - this.modifiedBaseRanges.map(s => ([s, new ObservableValue(ModifiedBaseRangeState.default, 'State')])) - ); - - private computeState(baseRange: ModifiedBaseRange, conflictingDiffs?: LineDiff[]): ModifiedBaseRangeState { - if (!conflictingDiffs) { - conflictingDiffs = this.resultEdits.findTouchingDiffs( - baseRange.baseRange - ); - } - - if (conflictingDiffs.length === 0) { - return ModifiedBaseRangeState.default; - } - const conflictingEdits = conflictingDiffs.map((d) => d.getLineEdit()); - - function editsAgreeWithDiffs(diffs: readonly LineDiff[]): boolean { - return equals( - conflictingEdits, - diffs.map((d) => d.getLineEdit()), - (a, b) => a.equals(b) - ); - } - - if (editsAgreeWithDiffs(baseRange.input1Diffs)) { - return ModifiedBaseRangeState.default.withInput1(true); - } - if (editsAgreeWithDiffs(baseRange.input2Diffs)) { - return ModifiedBaseRangeState.default.withInput2(true); - } - - return ModifiedBaseRangeState.conflicting; - } - public getState(baseRange: ModifiedBaseRange): IObservable { - const existingState = this.modifiedBaseRangeStateStores.get(baseRange); + const existingState = this.modifiedBaseRangeStateStores.get().get(baseRange); if (!existingState) { throw new BugIndicatingError('object must be from this instance'); } @@ -221,240 +167,122 @@ export class MergeEditorModel extends EditorModel { public setState( baseRange: ModifiedBaseRange, state: ModifiedBaseRangeState, - transaction: ITransaction | undefined + transaction: ITransaction ): void { - const existingState = this.modifiedBaseRangeStateStores.get(baseRange); + if (!this.isUpToDate.get()) { + throw new BugIndicatingError('Cannot set state while updating'); + } + + const existingState = this.modifiedBaseRangeStateStores.get().get(baseRange); if (!existingState) { throw new BugIndicatingError('object must be from this instance'); } - - const conflictingDiffs = this.resultEdits.findTouchingDiffs( + const conflictingDiffs = this.resultTextModelDiffs.findTouchingDiffs( baseRange.baseRange ); if (conflictingDiffs) { - this.resultEdits.removeDiffs(conflictingDiffs, transaction); + this.resultTextModelDiffs.removeDiffs(conflictingDiffs, transaction); } - function getEdit(baseRange: ModifiedBaseRange, state: ModifiedBaseRangeState): { edit: LineEdit | undefined; effectiveState: ModifiedBaseRangeState } { - interface LineDiffWithInputNumber { - diff: LineDiff; - inputNumber: 1 | 2; - } - - const diffs = new Array(); - if (state.input1) { - if (baseRange.input1CombinedDiff) { - diffs.push({ diff: baseRange.input1CombinedDiff, inputNumber: 1 }); - } - } - if (state.input2) { - if (baseRange.input2CombinedDiff) { - diffs.push({ diff: baseRange.input2CombinedDiff, inputNumber: 2 }); - } - } - if (state.input2First) { - diffs.reverse(); - } - const firstDiff: LineDiffWithInputNumber | undefined = diffs[0]; - const secondDiff: LineDiffWithInputNumber | undefined = diffs[1]; - diffs.sort(compareBy(d => d.diff.originalRange, LineRange.compareByStart)); - - if (!firstDiff) { - return { edit: undefined, effectiveState: state }; - } - - if (!secondDiff) { - return { edit: firstDiff.diff.getLineEdit(), effectiveState: state }; - } - - // Two inserts - if ( - firstDiff.diff.originalRange.lineCount === 0 && - firstDiff.diff.originalRange.equals(secondDiff.diff.originalRange) - ) { - return { - edit: new LineEdit( - firstDiff.diff.originalRange, - firstDiff.diff - .getLineEdit() - .newLines.concat(secondDiff.diff.getLineEdit().newLines) - ), - effectiveState: state, - }; - } - - // Technically non-conflicting diffs - if (diffs.length === 2 && diffs[0].diff.originalRange.endLineNumberExclusive === diffs[1].diff.originalRange.startLineNumber) { - return { - edit: new LineEdit( - LineRange.join(diffs.map(d => d.diff.originalRange))!, - diffs.flatMap(d => d.diff.getLineEdit().newLines) - ), - effectiveState: state, - }; - } - - return { edit: firstDiff.diff.getLineEdit(), effectiveState: state }; - } - const { edit, effectiveState } = getEdit(baseRange, state); + const { edit, effectiveState } = getEditForBase(baseRange, state); existingState.set(effectiveState, transaction); if (edit) { - this.resultEdits.applyEditRelativeToOriginal(edit, transaction); + this.resultTextModelDiffs.applyEditRelativeToOriginal(edit, transaction); } } - - public getResultRange(baseRange: LineRange): LineRange { - return this.resultEdits.getResultRange(baseRange); - } } -class ResultEdits { - private readonly barrier = new ReentrancyBarrier(); - private readonly onDidChangeEmitter = new Emitter(); - public readonly onDidChange = this.onDidChangeEmitter.event; +function getEditForBase(baseRange: ModifiedBaseRange, state: ModifiedBaseRangeState): { edit: LineEdit | undefined; effectiveState: ModifiedBaseRangeState } { + interface LineDiffWithInputNumber { + diff: LineDiff; + inputNumber: 1 | 2; + } - constructor( - diffs: LineDiff[], - private readonly baseTextModel: ITextModel, - private readonly resultTextModel: ITextModel, - private readonly _editorWorkerService: IEditorWorkerService + const diffs = new Array(); + if (state.input1) { + if (baseRange.input1CombinedDiff) { + diffs.push({ diff: baseRange.input1CombinedDiff, inputNumber: 1 }); + } + } + if (state.input2) { + if (baseRange.input2CombinedDiff) { + diffs.push({ diff: baseRange.input2CombinedDiff, inputNumber: 2 }); + } + } + if (state.input2First) { + diffs.reverse(); + } + const firstDiff: LineDiffWithInputNumber | undefined = diffs[0]; + const secondDiff: LineDiffWithInputNumber | undefined = diffs[1]; + diffs.sort(compareBy(d => d.diff.originalRange, LineRange.compareByStart)); + + if (!firstDiff) { + return { edit: undefined, effectiveState: ModifiedBaseRangeState.default }; + } + + if (!secondDiff) { + return { edit: firstDiff.diff.getLineEdit(), effectiveState: ModifiedBaseRangeState.default.withInputValue(firstDiff.inputNumber, true) }; + } + + // Two inserts + if ( + firstDiff.diff.originalRange.lineCount === 0 && + firstDiff.diff.originalRange.equals(secondDiff.diff.originalRange) ) { - diffs.sort(compareBy((d) => d.originalRange.startLineNumber, numberComparator)); - this._diffs.set(diffs, undefined); - - resultTextModel.onDidChangeContent(e => { - this.barrier.runExclusively(() => { - this._editorWorkerService.computeDiff( - baseTextModel.uri, - resultTextModel.uri, - false, - 1000 - ).then(e => { - const diffs = - e?.changes.map((c) => - LineDiff.fromLineChange(c, baseTextModel, resultTextModel) - ) || []; - this._diffs.set(diffs, undefined); - - this.onDidChangeEmitter.fire(undefined); - }); - }); - }); + return { + edit: new LineEdit( + firstDiff.diff.originalRange, + firstDiff.diff + .getLineEdit() + .newLines.concat(secondDiff.diff.getLineEdit().newLines) + ), + effectiveState: state, + }; } - private readonly _diffs = new ObservableValue([], 'diffs'); - - public readonly diffs: IObservable = this._diffs; - - public removeDiffs(diffToRemoves: LineDiff[], transaction: ITransaction | undefined): void { - diffToRemoves.sort(compareBy((d) => d.originalRange.startLineNumber, numberComparator)); - diffToRemoves.reverse(); - - let diffs = this._diffs.get(); - - for (const diffToRemove of diffToRemoves) { - // TODO improve performance - const len = diffs.length; - diffs = diffs.filter((d) => d !== diffToRemove); - if (len === diffs.length) { - throw new BugIndicatingError(); - } - - this.barrier.runExclusivelyOrThrow(() => { - diffToRemove.getReverseLineEdit().apply(this.resultTextModel); - }); - - diffs = diffs.map((d) => - d.modifiedRange.isAfter(diffToRemove.modifiedRange) - ? new LineDiff( - d.originalTextModel, - d.originalRange, - d.modifiedTextModel, - d.modifiedRange.delta( - diffToRemove.originalRange.lineCount - diffToRemove.modifiedRange.lineCount - ) - ) - : d - ); - } - - this._diffs.set(diffs, transaction); + // Technically non-conflicting diffs + if (diffs.length === 2 && diffs[0].diff.originalRange.endLineNumberExclusive === diffs[1].diff.originalRange.startLineNumber) { + return { + edit: new LineEdit( + LineRange.join(diffs.map(d => d.diff.originalRange))!, + diffs.flatMap(d => d.diff.getLineEdit().newLines) + ), + effectiveState: state, + }; } - /** - * Edit must be conflict free. - */ - public applyEditRelativeToOriginal(edit: LineEdit, transaction: ITransaction | undefined): void { - let firstAfter = false; - let delta = 0; - const newDiffs = new Array(); - for (const diff of this._diffs.get()) { - if (diff.originalRange.touches(edit.range)) { - throw new BugIndicatingError('Edit must be conflict free.'); - } else if (diff.originalRange.isAfter(edit.range)) { - if (!firstAfter) { - firstAfter = true; - - newDiffs.push(new LineDiff( - this.baseTextModel, - edit.range, - this.resultTextModel, - new LineRange(edit.range.startLineNumber + delta, edit.newLines.length) - )); - } - - newDiffs.push(new LineDiff( - diff.originalTextModel, - diff.originalRange, - diff.modifiedTextModel, - diff.modifiedRange.delta(edit.newLines.length - edit.range.lineCount) - )); - } else { - newDiffs.push(diff); - } - - if (!firstAfter) { - delta += diff.modifiedRange.lineCount - diff.originalRange.lineCount; - } - } - - if (!firstAfter) { - firstAfter = true; - - newDiffs.push(new LineDiff( - this.baseTextModel, - edit.range, - this.resultTextModel, - new LineRange(edit.range.startLineNumber + delta, edit.newLines.length) - )); - } - - this.barrier.runExclusivelyOrThrow(() => { - new LineEdit(edit.range.delta(delta), edit.newLines).apply(this.resultTextModel); - }); - this._diffs.set(newDiffs, transaction); - } - - public findTouchingDiffs(baseRange: LineRange): LineDiff[] { - return this.diffs.get().filter(d => d.originalRange.touches(baseRange)); - } - - public getResultRange(baseRange: LineRange): LineRange { - let startOffset = 0; - let lengthOffset = 0; - for (const diff of this.diffs.get()) { - if (diff.originalRange.endLineNumberExclusive <= baseRange.startLineNumber) { - startOffset += diff.resultingDeltaFromOriginalToModified; - } else if (diff.originalRange.startLineNumber <= baseRange.endLineNumberExclusive) { - lengthOffset += diff.resultingDeltaFromOriginalToModified; - } else { - break; - } - } - - return new LineRange(baseRange.startLineNumber + startOffset, baseRange.lineCount + lengthOffset); - } + return { + edit: secondDiff.diff.getLineEdit(), + effectiveState: ModifiedBaseRangeState.default.withInputValue( + secondDiff.inputNumber, + true + ), + }; +} + +function computeState(baseRange: ModifiedBaseRange, conflictingDiffs: LineDiff[]): ModifiedBaseRangeState { + if (conflictingDiffs.length === 0) { + return ModifiedBaseRangeState.default; + } + const conflictingEdits = conflictingDiffs.map((d) => d.getLineEdit()); + + function editsAgreeWithDiffs(diffs: readonly LineDiff[]): boolean { + return equals( + conflictingEdits, + diffs.map((d) => d.getLineEdit()), + (a, b) => a.equals(b) + ); + } + + if (editsAgreeWithDiffs(baseRange.input1Diffs)) { + return ModifiedBaseRangeState.default.withInput1(true); + } + if (editsAgreeWithDiffs(baseRange.input2Diffs)) { + return ModifiedBaseRangeState.default.withInput2(true); + } + + return ModifiedBaseRangeState.conflicting; } diff --git a/src/vs/workbench/contrib/mergeEditor/browser/textModelDiffs.ts b/src/vs/workbench/contrib/mergeEditor/browser/textModelDiffs.ts new file mode 100644 index 00000000000..348aabaef38 --- /dev/null +++ b/src/vs/workbench/contrib/mergeEditor/browser/textModelDiffs.ts @@ -0,0 +1,233 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { compareBy, numberComparator } from 'vs/base/common/arrays'; +import { BugIndicatingError } from 'vs/base/common/errors'; +import { Disposable } from 'vs/base/common/lifecycle'; +import { ITextModel } from 'vs/editor/common/model'; +import { IEditorWorkerService } from 'vs/editor/common/services/editorWorker'; +import { IObservable, ITransaction, ObservableValue, transaction } from 'vs/workbench/contrib/audioCues/browser/observable'; +import { LineDiff, LineEdit, LineRange } from 'vs/workbench/contrib/mergeEditor/browser/model'; +import { ReentrancyBarrier } from 'vs/workbench/contrib/mergeEditor/browser/utils'; + +export class TextModelDiffs extends Disposable { + private updateCount = 0; + private readonly _state = new ObservableValue(TextModelDiffState.initializing, 'LiveDiffState'); + private readonly _diffs = new ObservableValue([], 'LiveDiffs'); + + private readonly barrier = new ReentrancyBarrier(); + + constructor( + private readonly baseTextModel: ITextModel, + private readonly textModel: ITextModel, + private readonly diffComputer: IDiffComputer, + ) { + super(); + + this.update(true); + this._register(baseTextModel.onDidChangeContent(this.barrier.makeExclusive(() => this.update()))); + this._register(textModel.onDidChangeContent(this.barrier.makeExclusive(() => this.update()))); + } + + public get state(): IObservable { + return this._state; + } + + public get diffs(): IObservable { + return this._diffs; + } + + private async update(initializing: boolean = false): Promise { + this.updateCount++; + const currentUpdateCount = this.updateCount; + + if (this._state.get() === TextModelDiffState.initializing) { + initializing = true; + } + + transaction(tx => { + this._state.set( + initializing ? TextModelDiffState.initializing : TextModelDiffState.updating, + tx, + TextModelDiffChangeReason.other + ); + }); + + const result = await this.diffComputer.computeDiff(this.baseTextModel, this.textModel); + + if (currentUpdateCount !== this.updateCount) { + // There is a newer update call + return; + } + + transaction(tx => { + if (result) { + this._state.set(TextModelDiffState.upToDate, tx, TextModelDiffChangeReason.textChange); + this._diffs.set(result, tx, TextModelDiffChangeReason.textChange); + } else { + this._state.set(TextModelDiffState.error, tx, TextModelDiffChangeReason.textChange); + } + }); + } + + private ensureUpToDate(): void { + if (this.state.get() !== TextModelDiffState.upToDate) { + throw new BugIndicatingError('Cannot remove diffs when the model is not up to date'); + } + } + + public removeDiffs(diffToRemoves: LineDiff[], transaction: ITransaction | undefined): void { + this.ensureUpToDate(); + + diffToRemoves.sort(compareBy((d) => d.originalRange.startLineNumber, numberComparator)); + diffToRemoves.reverse(); + + let diffs = this._diffs.get(); + + for (const diffToRemove of diffToRemoves) { + // TODO improve performance + const len = diffs.length; + diffs = diffs.filter((d) => d !== diffToRemove); + if (len === diffs.length) { + throw new BugIndicatingError(); + } + + this.barrier.runExclusivelyOrThrow(() => { + diffToRemove.getReverseLineEdit().apply(this.textModel); + }); + + diffs = diffs.map((d) => + d.modifiedRange.isAfter(diffToRemove.modifiedRange) + ? new LineDiff( + d.originalTextModel, + d.originalRange, + d.modifiedTextModel, + d.modifiedRange.delta( + diffToRemove.originalRange.lineCount - diffToRemove.modifiedRange.lineCount + ) + ) + : d + ); + } + + this._diffs.set(diffs, transaction, TextModelDiffChangeReason.other); + } + + /** + * Edit must be conflict free. + */ + public applyEditRelativeToOriginal(edit: LineEdit, transaction: ITransaction | undefined): void { + this.ensureUpToDate(); + + let firstAfter = false; + let delta = 0; + const newDiffs = new Array(); + for (const diff of this.diffs.get()) { + if (diff.originalRange.touches(edit.range)) { + throw new BugIndicatingError('Edit must be conflict free.'); + } else if (diff.originalRange.isAfter(edit.range)) { + if (!firstAfter) { + firstAfter = true; + + newDiffs.push(new LineDiff( + this.baseTextModel, + edit.range, + this.textModel, + new LineRange(edit.range.startLineNumber + delta, edit.newLines.length) + )); + } + + newDiffs.push(new LineDiff( + diff.originalTextModel, + diff.originalRange, + diff.modifiedTextModel, + diff.modifiedRange.delta(edit.newLines.length - edit.range.lineCount) + )); + } else { + newDiffs.push(diff); + } + + if (!firstAfter) { + delta += diff.modifiedRange.lineCount - diff.originalRange.lineCount; + } + } + + if (!firstAfter) { + firstAfter = true; + + newDiffs.push(new LineDiff( + this.baseTextModel, + edit.range, + this.textModel, + new LineRange(edit.range.startLineNumber + delta, edit.newLines.length) + )); + } + + this.barrier.runExclusivelyOrThrow(() => { + new LineEdit(edit.range.delta(delta), edit.newLines).apply(this.textModel); + }); + this._diffs.set(newDiffs, transaction, TextModelDiffChangeReason.other); + } + + public findTouchingDiffs(baseRange: LineRange): LineDiff[] { + return this.diffs.get().filter(d => d.originalRange.touches(baseRange)); + } + + /* + public getResultRange(baseRange: LineRange): LineRange { + let startOffset = 0; + let lengthOffset = 0; + for (const diff of this.diffs.get()) { + if (diff.originalRange.endLineNumberExclusive <= baseRange.startLineNumber) { + startOffset += diff.resultingDeltaFromOriginalToModified; + } else if (diff.originalRange.startLineNumber <= baseRange.endLineNumberExclusive) { + lengthOffset += diff.resultingDeltaFromOriginalToModified; + } else { + break; + } + } + + return new LineRange(baseRange.startLineNumber + startOffset, baseRange.lineCount + lengthOffset); + } + */ +} + +export const enum TextModelDiffChangeReason { + other = 0, + textChange = 1, +} + +export const enum TextModelDiffState { + initializing = 1, + upToDate = 2, + updating = 3, + error = 4, +} + +export interface ITextModelDiffsState { + state: TextModelDiffState; + diffs: LineDiff[]; +} + +export interface IDiffComputer { + computeDiff(textModel1: ITextModel, textModel2: ITextModel): Promise; +} + +export class EditorWorkerServiceDiffComputer implements IDiffComputer { + constructor(@IEditorWorkerService private readonly editorWorkerService: IEditorWorkerService) { } + + async computeDiff(textModel1: ITextModel, textModel2: ITextModel): Promise { + //await wait(1000); + const diffs = await this.editorWorkerService.computeDiff(textModel1.uri, textModel2.uri, false, 1000); + if (!diffs || diffs.quitEarly) { + return null; + } + return diffs.changes.map((c) => LineDiff.fromLineChange(c, textModel1, textModel2)); + } +} + +function wait(ms: number): Promise { + return new Promise(r => setTimeout(r, ms)); +} From 105eef7a3079eee9d5c4c461387026b59be349f0 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Tue, 7 Jun 2022 11:33:37 +0200 Subject: [PATCH 002/117] debt - ensure models are resolved (#151405) --- .../editor/common/services/resolverService.ts | 6 +++ .../common/textModelResolverService.ts | 41 ++++++++++++++----- 2 files changed, 36 insertions(+), 11 deletions(-) diff --git a/src/vs/editor/common/services/resolverService.ts b/src/vs/editor/common/services/resolverService.ts index 5e8ea806aed..dcd5373ca5c 100644 --- a/src/vs/editor/common/services/resolverService.ts +++ b/src/vs/editor/common/services/resolverService.ts @@ -70,3 +70,9 @@ export interface IResolvedTextEditorModel extends ITextEditorModel { */ readonly textEditorModel: ITextModel; } + +export function isResolvedTextEditorModel(model: ITextEditorModel): model is IResolvedTextEditorModel { + const candidate = model as IResolvedTextEditorModel; + + return !!candidate.textEditorModel; +} diff --git a/src/vs/workbench/services/textmodelResolver/common/textModelResolverService.ts b/src/vs/workbench/services/textmodelResolver/common/textModelResolverService.ts index 8f84c7dd937..ad472a25211 100644 --- a/src/vs/workbench/services/textmodelResolver/common/textModelResolverService.ts +++ b/src/vs/workbench/services/textmodelResolver/common/textModelResolverService.ts @@ -11,7 +11,7 @@ import { IModelService } from 'vs/editor/common/services/model'; import { TextResourceEditorModel } from 'vs/workbench/common/editor/textResourceEditorModel'; import { ITextFileService, TextFileResolveReason } from 'vs/workbench/services/textfile/common/textfiles'; import { Schemas } from 'vs/base/common/network'; -import { ITextModelService, ITextModelContentProvider, ITextEditorModel, IResolvedTextEditorModel } from 'vs/editor/common/services/resolverService'; +import { ITextModelService, ITextModelContentProvider, ITextEditorModel, IResolvedTextEditorModel, isResolvedTextEditorModel } from 'vs/editor/common/services/resolverService'; import { TextFileEditorModel } from 'vs/workbench/services/textfile/common/textFileEditorModel'; import { IFileService } from 'vs/platform/files/common/files'; import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; @@ -19,7 +19,7 @@ import { IUndoRedoService } from 'vs/platform/undoRedo/common/undoRedo'; import { ModelUndoRedoParticipant } from 'vs/editor/common/services/modelUndoRedoParticipant'; import { IUriIdentityService } from 'vs/platform/uriIdentity/common/uriIdentity'; -class ResourceModelCollection extends ReferenceCollection> { +class ResourceModelCollection extends ReferenceCollection> { private readonly providers = new Map(); private readonly modelsToDispose = new Set(); @@ -33,11 +33,11 @@ class ResourceModelCollection extends ReferenceCollection { + createReferencedObject(key: string): Promise { return this.doCreateReferencedObject(key); } - private async doCreateReferencedObject(key: string, skipActivateProvider?: boolean): Promise { + private async doCreateReferencedObject(key: string, skipActivateProvider?: boolean): Promise { // Untrack as being disposed this.modelsToDispose.delete(key); @@ -50,24 +50,36 @@ class ResourceModelCollection extends ReferenceCollection): void { // untitled and inMemory are bound to a different lifecycle @@ -173,7 +193,7 @@ export class TextModelResolverService extends Disposable implements ITextModelSe declare readonly _serviceBrand: undefined; - private readonly resourceModelCollection = this.instantiationService.createInstance(ResourceModelCollection); + private readonly resourceModelCollection: ResourceModelCollection & ReferenceCollection> /* TS Fail */ = this.instantiationService.createInstance(ResourceModelCollection); private readonly asyncModelCollection = new AsyncReferenceCollection(this.resourceModelCollection); constructor( @@ -195,8 +215,7 @@ export class TextModelResolverService extends Disposable implements ITextModelSe // with different resource forms (e.g. path casing on Windows) resource = this.uriIdentityService.asCanonicalUri(resource); - const result = await this.asyncModelCollection.acquire(resource.toString()); - return result as IReference; // TODO@Ben: why is this cast here? + return await this.asyncModelCollection.acquire(resource.toString()); } registerTextModelContentProvider(scheme: string, provider: ITextModelContentProvider): IDisposable { From 2a63d7baf2db7eabf141f876581ea4c808a6b8e4 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Tue, 7 Jun 2022 11:34:58 +0200 Subject: [PATCH 003/117] watcher - fix #151009, fix #148245 (#151407) --- src/vs/platform/files/common/watcher.ts | 27 ++++++++------ .../node/watcher/nodejs/nodejsWatcher.ts | 2 +- .../node/watcher/parcel/parcelWatcher.ts | 2 +- .../api/browser/mainThreadFileSystem.ts | 36 ++++++++++++++++--- 4 files changed, 49 insertions(+), 18 deletions(-) diff --git a/src/vs/platform/files/common/watcher.ts b/src/vs/platform/files/common/watcher.ts index 57277a9ece9..ff21eee96e0 100644 --- a/src/vs/platform/files/common/watcher.ts +++ b/src/vs/platform/files/common/watcher.ts @@ -291,21 +291,26 @@ export function coalesceEvents(changes: IDiskFileChange[]): IDiskFileChange[] { return coalescer.coalesce(); } +export function normalizeWatcherPattern(path: string, pattern: string | IRelativePattern): string | IRelativePattern { + + // Patterns are always matched on the full absolute path + // of the event. As such, if the pattern is not absolute + // and is a string and does not start with a leading + // `**`, we have to convert it to a relative pattern with + // the given `base` + + if (typeof pattern === 'string' && !pattern.startsWith(GLOBSTAR) && !isAbsolute(pattern)) { + return { base: path, pattern }; + } + + return pattern; +} + export function parseWatcherPatterns(path: string, patterns: Array): ParsedPattern[] { const parsedPatterns: ParsedPattern[] = []; for (const pattern of patterns) { - let normalizedPattern = pattern; - - // Patterns are always matched on the full absolute path - // of the event. As such, if the pattern is not absolute - // and does not start with a leading `**`, we have to - // convert it to a relative pattern with the given `base` - if (typeof normalizedPattern === 'string' && !normalizedPattern.startsWith(GLOBSTAR) && !isAbsolute(normalizedPattern)) { - normalizedPattern = { base: path, pattern: normalizedPattern }; - } - - parsedPatterns.push(parse(normalizedPattern)); + parsedPatterns.push(parse(normalizeWatcherPattern(path, pattern))); } return parsedPatterns; diff --git a/src/vs/platform/files/node/watcher/nodejs/nodejsWatcher.ts b/src/vs/platform/files/node/watcher/nodejs/nodejsWatcher.ts index a737ca54510..3a5c43c9ff5 100644 --- a/src/vs/platform/files/node/watcher/nodejs/nodejsWatcher.ts +++ b/src/vs/platform/files/node/watcher/nodejs/nodejsWatcher.ts @@ -61,7 +61,7 @@ export class NodeJSWatcher extends Disposable implements INonRecursiveWatcher { // Logging if (requestsToStartWatching.length) { - this.trace(`Request to start watching: ${requestsToStartWatching.map(request => `${request.path} (excludes: ${request.excludes.length > 0 ? request.excludes : ''}, includes: ${request.includes && request.includes.length > 0 ? request.includes : ''})`).join(',')}`); + this.trace(`Request to start watching: ${requestsToStartWatching.map(request => `${request.path} (excludes: ${request.excludes.length > 0 ? request.excludes : ''}, includes: ${request.includes && request.includes.length > 0 ? JSON.stringify(request.includes) : ''})`).join(',')}`); } if (pathsToStopWatching.length) { diff --git a/src/vs/platform/files/node/watcher/parcel/parcelWatcher.ts b/src/vs/platform/files/node/watcher/parcel/parcelWatcher.ts index 21759ab776c..56509eb740f 100644 --- a/src/vs/platform/files/node/watcher/parcel/parcelWatcher.ts +++ b/src/vs/platform/files/node/watcher/parcel/parcelWatcher.ts @@ -145,7 +145,7 @@ export class ParcelWatcher extends Disposable implements IRecursiveWatcher { // Logging if (requestsToStartWatching.length) { - this.trace(`Request to start watching: ${requestsToStartWatching.map(request => `${request.path} (excludes: ${request.excludes.length > 0 ? request.excludes : ''}, includes: ${request.includes && request.includes.length > 0 ? request.includes : ''})`).join(',')}`); + this.trace(`Request to start watching: ${requestsToStartWatching.map(request => `${request.path} (excludes: ${request.excludes.length > 0 ? request.excludes : ''}, includes: ${request.includes && request.includes.length > 0 ? JSON.stringify(request.includes) : ''})`).join(',')}`); } if (pathsToStopWatching.length) { diff --git a/src/vs/workbench/api/browser/mainThreadFileSystem.ts b/src/vs/workbench/api/browser/mainThreadFileSystem.ts index bbf3476b101..b9cb1aa89be 100644 --- a/src/vs/workbench/api/browser/mainThreadFileSystem.ts +++ b/src/vs/workbench/api/browser/mainThreadFileSystem.ts @@ -14,6 +14,9 @@ import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace import { ILogService } from 'vs/platform/log/common/log'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { IWorkbenchFileService } from 'vs/workbench/services/files/common/files'; +import { normalizeWatcherPattern } from 'vs/platform/files/common/watcher'; +import { GLOBSTAR } from 'vs/base/common/glob'; +import { rtrim } from 'vs/base/common/strings'; @extHostNamedCustomer(MainContext.MainThreadFileSystem) export class MainThreadFileSystem implements MainThreadFileSystemShape { @@ -163,9 +166,26 @@ export class MainThreadFileSystem implements MainThreadFileSystemShape { return this._fileService.activateProvider(scheme); } - $watch(extensionId: string, session: number, resource: UriComponents, opts: IWatchOptions): void { + async $watch(extensionId: string, session: number, resource: UriComponents, unvalidatedOpts: IWatchOptions): Promise { const uri = URI.revive(resource); - const isInsideWorkspace = this._contextService.isInsideWorkspace(uri); + const workspaceFolder = this._contextService.getWorkspaceFolder(uri); + + const opts = { ...unvalidatedOpts }; + + // Convert a recursive watcher to a flat watcher if the path + // turns out to not be a folder. Recursive watching is only + // possible on folders, so we help all file watchers by checking + // early. + if (opts.recursive) { + try { + const stat = await this._fileService.stat(uri); + if (!stat.isDirectory) { + opts.recursive = false; + } + } catch (error) { + this._logService.error(`MainThreadFileSystem#$watch(): failed to stat a resource for file watching (extension: ${extensionId}, path: ${uri.toString(true)}, recursive: ${opts.recursive}, session: ${session}): ${error}`); + } + } // Refuse to watch anything that is already watched via // our workspace watchers in case the request is a @@ -173,7 +193,7 @@ export class MainThreadFileSystem implements MainThreadFileSystemShape { // Still allow for non-recursive watch requests as a way // to bypass configured exlcude rules though // (see https://github.com/microsoft/vscode/issues/146066) - if (isInsideWorkspace && opts.recursive) { + if (workspaceFolder && opts.recursive) { this._logService.trace(`MainThreadFileSystem#$watch(): ignoring request to start watching because path is inside workspace (extension: ${extensionId}, path: ${uri.toString(true)}, recursive: ${opts.recursive}, session: ${session})`); return; } @@ -200,7 +220,12 @@ export class MainThreadFileSystem implements MainThreadFileSystemShape { // excluded via `files.watcherExclude`. As such, we configure // to include each configured exclude pattern so that only those // events are reported that are otherwise excluded. - else if (isInsideWorkspace) { + // However, we cannot just use the pattern as is, because a pattern + // such as `bar` for a exclude, will work to exclude any of + // `/bar` but will not work as include for files within + // `bar` unless a suffix of `/**` if added. + // (https://github.com/microsoft/vscode/issues/148245) + else if (workspaceFolder) { const config = this._configurationService.getValue(); if (config.files?.watcherExclude) { for (const key in config.files.watcherExclude) { @@ -209,7 +234,8 @@ export class MainThreadFileSystem implements MainThreadFileSystemShape { opts.includes = []; } - opts.includes.push(key); + const includePattern = `${rtrim(key, '/')}/${GLOBSTAR}`; + opts.includes.push(normalizeWatcherPattern(workspaceFolder.uri.fsPath, includePattern)); } } } From a0a9b7868d4557933dd95aed6624d647b0f1889f Mon Sep 17 00:00:00 2001 From: Alex Ross Date: Tue, 7 Jun 2022 14:35:24 +0200 Subject: [PATCH 004/117] Dragging multi-line `text/uri-list` from tree to editor results in error (#151224) Fixes #148411 --- src/vs/workbench/browser/dnd.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/browser/dnd.ts b/src/vs/workbench/browser/dnd.ts index 6a79fc3c337..8cda2f318c7 100644 --- a/src/vs/workbench/browser/dnd.ts +++ b/src/vs/workbench/browser/dnd.ts @@ -60,7 +60,7 @@ export async function extractTreeDropData(dataTransfer: VSDataTransfer): Promise if (dataTransfer.has(resourcesKey)) { try { const asString = await dataTransfer.get(resourcesKey)?.asString(); - const rawResourcesData = JSON.stringify(asString?.split('\\n').filter(value => !value.startsWith('#'))); + const rawResourcesData = JSON.stringify(asString?.split('\n').filter(value => !value.startsWith('#'))); editors.push(...createDraggedEditorInputFromRawResourcesData(rawResourcesData)); } catch (error) { // Invalid transfer From 6a58b4017c4ff76a15b8af57506e3094becbe75c Mon Sep 17 00:00:00 2001 From: Alex Ross Date: Tue, 7 Jun 2022 14:35:57 +0200 Subject: [PATCH 005/117] Can't drag an item and drop it to an empty treeview (#151213) Fixes #149890 --- src/vs/workbench/browser/parts/views/treeView.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/browser/parts/views/treeView.ts b/src/vs/workbench/browser/parts/views/treeView.ts index b1c7115bc1c..64ce4c648e5 100644 --- a/src/vs/workbench/browser/parts/views/treeView.ts +++ b/src/vs/workbench/browser/parts/views/treeView.ts @@ -826,7 +826,10 @@ abstract class AbstractTreeView extends Disposable implements ITreeView { const isTreeEmpty = !this.root.children || this.root.children.length === 0; // Hide tree container only when there is a message and tree is empty and not refreshing if (this._messageValue && isTreeEmpty && !this.refreshing) { - this.treeContainer.classList.add('hide'); + // If there's a dnd controller then hiding the tree prevents it from being dragged into. + if (!this.dragAndDropController) { + this.treeContainer.classList.add('hide'); + } this.domNode.setAttribute('tabindex', '0'); } else { this.treeContainer.classList.remove('hide'); From c59119306db373e965e7e413bd1cbcf776770480 Mon Sep 17 00:00:00 2001 From: Alex Ross Date: Tue, 7 Jun 2022 15:01:16 +0200 Subject: [PATCH 006/117] Clear tasks schema when there are new definitions (#151079) Fixes #142642 --- src/vs/workbench/contrib/tasks/common/taskDefinitionRegistry.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/vs/workbench/contrib/tasks/common/taskDefinitionRegistry.ts b/src/vs/workbench/contrib/tasks/common/taskDefinitionRegistry.ts index 340990cb62c..b3fe1e79f8e 100644 --- a/src/vs/workbench/contrib/tasks/common/taskDefinitionRegistry.ts +++ b/src/vs/workbench/contrib/tasks/common/taskDefinitionRegistry.ts @@ -111,6 +111,7 @@ export class TaskDefinitionRegistryImpl implements ITaskDefinitionRegistry { this.taskTypes = Object.create(null); this.readyPromise = new Promise((resolve, reject) => { taskDefinitionsExtPoint.setHandler((extensions, delta) => { + this._schema = undefined; try { for (let extension of delta.removed) { let taskTypes = extension.value; From e3a8e502ad7263836d0bc34cbcefbfc7bd65104f Mon Sep 17 00:00:00 2001 From: Mitch Schutt Date: Tue, 7 Jun 2022 09:06:53 -0400 Subject: [PATCH 007/117] Focus editor for tab after dragged over for 1500 millis (#149604) * Focus editor for tab after dragged over for 1500 millis * :lipstick: Co-authored-by: Benjamin Pasero --- src/vs/base/browser/dom.ts | 15 ++++++++++++--- .../browser/parts/editor/tabsTitleControl.ts | 11 +++++++++++ 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/src/vs/base/browser/dom.ts b/src/vs/base/browser/dom.ts index d2fa1bd3ba8..a59a09e21f1 100644 --- a/src/vs/base/browser/dom.ts +++ b/src/vs/base/browser/dom.ts @@ -1702,8 +1702,7 @@ export interface IDragAndDropObserverCallbacks { readonly onDragLeave: (e: DragEvent) => void; readonly onDrop: (e: DragEvent) => void; readonly onDragEnd: (e: DragEvent) => void; - - readonly onDragOver?: (e: DragEvent) => void; + readonly onDragOver?: (e: DragEvent, dragDuration: number) => void; } export class DragAndDropObserver extends Disposable { @@ -1714,6 +1713,9 @@ export class DragAndDropObserver extends Disposable { // repeadedly. private counter: number = 0; + // Allows to measure the duration of the drag operation. + private dragStartTime = 0; + constructor(private readonly element: HTMLElement, private readonly callbacks: IDragAndDropObserverCallbacks) { super(); @@ -1723,6 +1725,7 @@ export class DragAndDropObserver extends Disposable { private registerListeners(): void { this._register(addDisposableListener(this.element, EventType.DRAG_ENTER, (e: DragEvent) => { this.counter++; + this.dragStartTime = e.timeStamp; this.callbacks.onDragEnter(e); })); @@ -1731,7 +1734,7 @@ export class DragAndDropObserver extends Disposable { e.preventDefault(); // needed so that the drop event fires (https://stackoverflow.com/questions/21339924/drop-event-not-firing-in-chrome) if (this.callbacks.onDragOver) { - this.callbacks.onDragOver(e); + this.callbacks.onDragOver(e, e.timeStamp - this.dragStartTime); } })); @@ -1739,17 +1742,23 @@ export class DragAndDropObserver extends Disposable { this.counter--; if (this.counter === 0) { + this.dragStartTime = 0; + this.callbacks.onDragLeave(e); } })); this._register(addDisposableListener(this.element, EventType.DRAG_END, (e: DragEvent) => { this.counter = 0; + this.dragStartTime = 0; + this.callbacks.onDragEnd(e); })); this._register(addDisposableListener(this.element, EventType.DROP, (e: DragEvent) => { this.counter = 0; + this.dragStartTime = 0; + this.callbacks.onDrop(e); })); } diff --git a/src/vs/workbench/browser/parts/editor/tabsTitleControl.ts b/src/vs/workbench/browser/parts/editor/tabsTitleControl.ts index 6d834b41807..386e13b2e0b 100644 --- a/src/vs/workbench/browser/parts/editor/tabsTitleControl.ts +++ b/src/vs/workbench/browser/parts/editor/tabsTitleControl.ts @@ -97,6 +97,8 @@ export class TabsTitleControl extends TitleControl { private static readonly TAB_HEIGHT = 35; + private static readonly DRAG_OVER_OPEN_TAB_THRESHOLD = 1500; + private static readonly MOUSE_WHEEL_EVENT_THRESHOLD = 150; private static readonly MOUSE_WHEEL_DISTANCE_THRESHOLD = 1.5; @@ -898,6 +900,15 @@ export class TabsTitleControl extends TitleControl { this.updateDropFeedback(tab, true, index); }, + onDragOver: (_, dragDuration) => { + if (dragDuration >= TabsTitleControl.DRAG_OVER_OPEN_TAB_THRESHOLD) { + const draggedOverTab = this.group.getEditorByIndex(index); + if (draggedOverTab && this.group.activeEditor !== draggedOverTab) { + this.group.openEditor(draggedOverTab, { preserveFocus: true }); + } + } + }, + onDragLeave: () => { tab.classList.remove('dragged-over'); this.updateDropFeedback(tab, false, index); From 3e8d82d2f7e2b06de12bdbda3993caba18ce45ee Mon Sep 17 00:00:00 2001 From: Martin Aeschlimann Date: Tue, 7 Jun 2022 15:40:32 +0200 Subject: [PATCH 008/117] Remote menu not showing when browsing marketplace (#151199) Remote menu not showing when browsing marketplace #151198 --- .../contrib/remote/browser/remoteIndicator.ts | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/src/vs/workbench/contrib/remote/browser/remoteIndicator.ts b/src/vs/workbench/contrib/remote/browser/remoteIndicator.ts index 954266d0fa3..a974d00c0fc 100644 --- a/src/vs/workbench/contrib/remote/browser/remoteIndicator.ts +++ b/src/vs/workbench/contrib/remote/browser/remoteIndicator.ts @@ -306,7 +306,7 @@ export class RemoteStatusIndicator extends Disposable implements IWorkbenchContr } return; } - // show when in a virtual workspace + // Show when in a virtual workspace if (this.virtualWorkspaceLocation) { // Workspace with label: indicate editing source const workspaceLabel = this.labelService.getHostLabel(this.virtualWorkspaceLocation.scheme, this.virtualWorkspaceLocation.authority); @@ -330,8 +330,8 @@ export class RemoteStatusIndicator extends Disposable implements IWorkbenchContr return; } } - // Remote actions: offer menu - if (this.getRemoteMenuActions().length > 0) { + // Show when there are commands other than the 'install additional remote extensions' command. + if (this.hasRemoteMenuCommands(true)) { this.renderRemoteStatusIndicator(`$(remote)`, nls.localize('noHost.tooltip', "Open a Remote Window")); return; } @@ -343,7 +343,7 @@ export class RemoteStatusIndicator extends Disposable implements IWorkbenchContr private renderRemoteStatusIndicator(text: string, tooltip?: string | IMarkdownString, command?: string, showProgress?: boolean): void { const name = nls.localize('remoteHost', "Remote Host"); - if (typeof command !== 'string' && this.getRemoteMenuActions().length > 0) { + if (typeof command !== 'string' && (this.hasRemoteMenuCommands(false))) { command = RemoteStatusIndicator.REMOTE_ACTIONS_COMMAND_ID; } @@ -493,4 +493,15 @@ export class RemoteStatusIndicator extends Disposable implements IWorkbenchContr quickPick.show(); } + + private hasRemoteMenuCommands(ignoreInstallAdditional: boolean): boolean { + if (this.remoteAuthority !== undefined || this.virtualWorkspaceLocation !== undefined) { + if (RemoteStatusIndicator.SHOW_CLOSE_REMOTE_COMMAND_ID) { + return true; + } + } else if (!ignoreInstallAdditional && this.extensionGalleryService.isEnabled()) { + return true; + } + return this.getRemoteMenuActions().length > 0; + } } From 9daa6e91253350286f23b218afad8df72f283611 Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Tue, 7 Jun 2022 17:02:48 +0200 Subject: [PATCH 009/117] Fix #151400 (#151432) --- .../browser/extensionsWorkbenchService.ts | 21 +++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/src/vs/workbench/contrib/extensions/browser/extensionsWorkbenchService.ts b/src/vs/workbench/contrib/extensions/browser/extensionsWorkbenchService.ts index c77ee7bf963..50b9b8c606e 100644 --- a/src/vs/workbench/contrib/extensions/browser/extensionsWorkbenchService.ts +++ b/src/vs/workbench/contrib/extensions/browser/extensionsWorkbenchService.ts @@ -14,7 +14,7 @@ import { IPager, singlePagePager } from 'vs/base/common/paging'; import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { IExtensionGalleryService, ILocalExtension, IGalleryExtension, IQueryOptions, - InstallExtensionEvent, DidUninstallExtensionEvent, IExtensionIdentifier, InstallOperation, InstallOptions, WEB_EXTENSION_TAG, InstallExtensionResult, + InstallExtensionEvent, DidUninstallExtensionEvent, InstallOperation, InstallOptions, WEB_EXTENSION_TAG, InstallExtensionResult, IExtensionsControlManifest, InstallVSIXOptions, IExtensionInfo, IExtensionQueryOptions, IDeprecationInfo } from 'vs/platform/extensionManagement/common/extensionManagement'; import { IWorkbenchExtensionEnablementService, EnablementState, IExtensionManagementServerService, IExtensionManagementServer, IWorkbenchExtensionManagementService, DefaultIconPath } from 'vs/workbench/services/extensionManagement/common/extensionManagement'; @@ -34,7 +34,7 @@ import * as resources from 'vs/base/common/resources'; import { CancellationToken } from 'vs/base/common/cancellation'; import { IStorageService, StorageScope, StorageTarget } from 'vs/platform/storage/common/storage'; import { IFileService } from 'vs/platform/files/common/files'; -import { IExtensionManifest, ExtensionType, IExtension as IPlatformExtension, TargetPlatform, ExtensionIdentifier } from 'vs/platform/extensions/common/extensions'; +import { IExtensionManifest, ExtensionType, IExtension as IPlatformExtension, TargetPlatform, ExtensionIdentifier, IExtensionIdentifier } from 'vs/platform/extensions/common/extensions'; import { ILanguageService } from 'vs/editor/common/languages/language'; import { IProductService } from 'vs/platform/product/common/productService'; import { FileAccess } from 'vs/base/common/network'; @@ -1331,7 +1331,7 @@ export class ExtensionsWorkbenchService extends Disposable implements IExtension this.ignoreAutoUpdate(new ExtensionKey(identifier, manifest.version)); } - return this.local.filter(local => areSameExtensions(local.identifier, identifier))[0]; + return this.waitAndGetInstalledExtension(identifier); } private async installFromGallery(extension: IExtension, gallery: IGalleryExtension, installOptions?: InstallOptions): Promise { @@ -1343,13 +1343,26 @@ export class ExtensionsWorkbenchService extends Disposable implements IExtension } else { await this.extensionManagementService.installFromGallery(gallery, installOptions); } - return this.local.filter(local => areSameExtensions(local.identifier, gallery.identifier))[0]; + return this.waitAndGetInstalledExtension(gallery.identifier); } finally { this.installing = this.installing.filter(e => e !== extension); this._onChange.fire(this.local.filter(e => areSameExtensions(e.identifier, extension.identifier))[0]); } } + private async waitAndGetInstalledExtension(identifier: IExtensionIdentifier): Promise { + let installedExtension = this.local.find(local => areSameExtensions(local.identifier, identifier)); + if (!installedExtension) { + await Event.toPromise(Event.filter(this.onChange, e => !!e && this.local.some(local => areSameExtensions(local.identifier, identifier)))); + } + installedExtension = this.local.find(local => areSameExtensions(local.identifier, identifier)); + if (!installedExtension) { + // This should not happen + throw new Error('Extension should have been installed'); + } + return installedExtension; + } + private promptAndSetEnablement(extensions: IExtension[], enablementState: EnablementState): Promise { const enable = enablementState === EnablementState.EnabledGlobally || enablementState === EnablementState.EnabledWorkspace; if (enable) { From 75a6ddc8626b831f01f91f9f60f27de3d5bb6f38 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Tue, 7 Jun 2022 08:06:00 -0700 Subject: [PATCH 010/117] Add DataTransferItem.kind (#151384) Fixes #150963 The new `.kind` property makes it easier to tell the type of a data transfer item --- src/vs/workbench/api/common/extHost.api.impl.ts | 1 + src/vs/workbench/api/common/extHostTypeConverters.ts | 2 ++ src/vs/workbench/api/common/extHostTypes.ts | 8 ++++++++ src/vscode-dts/vscode.proposed.dataTransferFiles.d.ts | 9 +++++++++ 4 files changed, 20 insertions(+) diff --git a/src/vs/workbench/api/common/extHost.api.impl.ts b/src/vs/workbench/api/common/extHost.api.impl.ts index 7d6ec043a9a..e649eb3a21a 100644 --- a/src/vs/workbench/api/common/extHost.api.impl.ts +++ b/src/vs/workbench/api/common/extHost.api.impl.ts @@ -1330,6 +1330,7 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I TextSearchCompleteMessageType: TextSearchCompleteMessageType, DataTransfer: extHostTypes.DataTransfer, DataTransferItem: extHostTypes.DataTransferItem, + DataTransferItemKind: extHostTypes.DataTransferItemKind, CoveredCount: extHostTypes.CoveredCount, FileCoverage: extHostTypes.FileCoverage, StatementCoverage: extHostTypes.StatementCoverage, diff --git a/src/vs/workbench/api/common/extHostTypeConverters.ts b/src/vs/workbench/api/common/extHostTypeConverters.ts index 18d71be8a26..f008c948af3 100644 --- a/src/vs/workbench/api/common/extHostTypeConverters.ts +++ b/src/vs/workbench/api/common/extHostTypeConverters.ts @@ -1965,6 +1965,8 @@ export namespace DataTransferItem { const file = item.fileData; if (file) { return new class extends types.DataTransferItem { + override get kind() { return types.DataTransferItemKind.File; } + override asFile(): vscode.DataTransferFile { return { name: file.name, diff --git a/src/vs/workbench/api/common/extHostTypes.ts b/src/vs/workbench/api/common/extHostTypes.ts index b5e2cd04ef9..97453151e46 100644 --- a/src/vs/workbench/api/common/extHostTypes.ts +++ b/src/vs/workbench/api/common/extHostTypes.ts @@ -2438,8 +2438,16 @@ export enum TreeItemCollapsibleState { Expanded = 2 } +export enum DataTransferItemKind { + String = 1, + File = 2, +} + @es5ClassCompat export class DataTransferItem { + + get kind(): DataTransferItemKind { return DataTransferItemKind.String; } + async asString(): Promise { return typeof this.value === 'string' ? this.value : JSON.stringify(this.value); } diff --git a/src/vscode-dts/vscode.proposed.dataTransferFiles.d.ts b/src/vscode-dts/vscode.proposed.dataTransferFiles.d.ts index 24baea79897..a202f9a9ed6 100644 --- a/src/vscode-dts/vscode.proposed.dataTransferFiles.d.ts +++ b/src/vscode-dts/vscode.proposed.dataTransferFiles.d.ts @@ -7,6 +7,15 @@ declare module 'vscode' { // https://github.com/microsoft/vscode/issues/147481 + enum DataTransferItemKind { + String = 1, + File = 2, + } + + interface DataTransferItem { + readonly kind: DataTransferItemKind; + } + /** * A file associated with a {@linkcode DataTransferItem}. */ From c51f8ff55c79d9cda39358a3788e7ea151127138 Mon Sep 17 00:00:00 2001 From: SteVen Batten <6561887+sbatten@users.noreply.github.com> Date: Tue, 7 Jun 2022 08:53:13 -0700 Subject: [PATCH 011/117] fixes #149366 (#151051) --- src/vs/workbench/browser/layout.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/vs/workbench/browser/layout.ts b/src/vs/workbench/browser/layout.ts index 10a0a5e03ec..1ac35c898f9 100644 --- a/src/vs/workbench/browser/layout.ts +++ b/src/vs/workbench/browser/layout.ts @@ -1241,6 +1241,7 @@ export abstract class Layout extends Disposable implements IWorkbenchLayoutServi this.setEditorHidden(!visible, true); } this._onDidChangePartVisibility.fire(); + this._onDidLayout.fire(this._dimension); })); } From 7c22caad555b7b654ce4021ebf5b70e60c3cef23 Mon Sep 17 00:00:00 2001 From: Megan Rogge Date: Tue, 7 Jun 2022 08:27:44 -0800 Subject: [PATCH 012/117] Use `I` prefix for task interfaces (#151350) --- extensions/npm/src/commands.ts | 8 +- extensions/npm/src/npmView.ts | 12 +- extensions/npm/src/tasks.ts | 36 +- .../workspace.tasks.test.ts | 8 +- .../workbench/api/browser/mainThreadTask.ts | 132 ++++---- .../workbench/api/common/extHost.protocol.ts | 22 +- src/vs/workbench/api/common/extHostTask.ts | 108 +++--- src/vs/workbench/api/common/shared/tasks.ts | 68 ++-- src/vs/workbench/api/node/extHostTask.ts | 8 +- .../contrib/debug/browser/debugTaskRunner.ts | 8 +- .../workbench/contrib/debug/common/debug.ts | 12 +- .../tasks/browser/abstractTaskService.ts | 194 +++++------ .../tasks/browser/runAutomaticTasks.ts | 10 +- .../tasks/browser/task.contribution.ts | 4 +- .../contrib/tasks/browser/taskQuickPick.ts | 46 +-- .../contrib/tasks/browser/taskService.ts | 8 +- .../tasks/browser/taskTerminalStatus.ts | 14 +- .../contrib/tasks/browser/tasksQuickAccess.ts | 6 +- .../tasks/browser/terminalTaskSystem.ts | 84 ++--- .../contrib/tasks/common/problemCollectors.ts | 34 +- .../contrib/tasks/common/problemMatcher.ts | 190 +++++------ .../contrib/tasks/common/taskConfiguration.ts | 318 +++++++++--------- .../tasks/common/taskDefinitionRegistry.ts | 16 +- .../contrib/tasks/common/taskService.ts | 34 +- .../contrib/tasks/common/taskSystem.ts | 22 +- .../contrib/tasks/common/taskTemplates.ts | 14 +- .../workbench/contrib/tasks/common/tasks.ts | 140 ++++---- .../tasks/electron-sandbox/taskService.ts | 10 +- .../test/browser/taskTerminalStatus.test.ts | 8 +- .../tasks/test/common/problemMatcher.test.ts | 4 +- .../test/common/taskConfiguration.test.ts | 172 +++++----- 31 files changed, 875 insertions(+), 875 deletions(-) diff --git a/extensions/npm/src/commands.ts b/extensions/npm/src/commands.ts index 6847f322631..295ae306c3f 100644 --- a/extensions/npm/src/commands.ts +++ b/extensions/npm/src/commands.ts @@ -10,7 +10,7 @@ import { detectNpmScriptsForFolder, findScriptAtPosition, runScript, - FolderTaskItem + IFolderTaskItem } from './tasks'; const localize = nls.loadMessageBundle(); @@ -37,17 +37,17 @@ export async function selectAndRunScriptFromFolder(context: vscode.ExtensionCont } const selectedFolder = selectedFolders[0]; - let taskList: FolderTaskItem[] = await detectNpmScriptsForFolder(context, selectedFolder); + let taskList: IFolderTaskItem[] = await detectNpmScriptsForFolder(context, selectedFolder); if (taskList && taskList.length > 0) { - const quickPick = vscode.window.createQuickPick(); + const quickPick = vscode.window.createQuickPick(); quickPick.title = 'Run NPM script in Folder'; quickPick.placeholder = 'Select an npm script'; quickPick.items = taskList; const toDispose: vscode.Disposable[] = []; - let pickPromise = new Promise((c) => { + let pickPromise = new Promise((c) => { toDispose.push(quickPick.onDidAccept(() => { toDispose.forEach(d => d.dispose()); c(quickPick.selectedItems[0]); diff --git a/extensions/npm/src/npmView.ts b/extensions/npm/src/npmView.ts index 41e28e9bdf5..e7bfd08bd7c 100644 --- a/extensions/npm/src/npmView.ts +++ b/extensions/npm/src/npmView.ts @@ -14,10 +14,10 @@ import { import * as nls from 'vscode-nls'; import { readScripts } from './readScripts'; import { - createTask, getPackageManager, getTaskName, isAutoDetectionEnabled, isWorkspaceFolder, NpmTaskDefinition, + createTask, getPackageManager, getTaskName, isAutoDetectionEnabled, isWorkspaceFolder, INpmTaskDefinition, NpmTaskProvider, startDebugging, - TaskWithLocation + ITaskWithLocation } from './tasks'; const localize = nls.loadMessageBundle(); @@ -78,7 +78,7 @@ class NpmScript extends TreeItem { package: PackageJSON; taskLocation?: Location; - constructor(_context: ExtensionContext, packageJson: PackageJSON, task: TaskWithLocation) { + constructor(_context: ExtensionContext, packageJson: PackageJSON, task: ITaskWithLocation) { const name = packageJson.path.length > 0 ? task.task.name.substring(0, task.task.name.length - packageJson.path.length - 2) : task.task.name; @@ -284,7 +284,7 @@ export class NpmScriptsTreeDataProvider implements TreeDataProvider { }); } - private buildTaskTree(tasks: TaskWithLocation[]): TaskTree { + private buildTaskTree(tasks: ITaskWithLocation[]): TaskTree { let folders: Map = new Map(); let packages: Map = new Map(); @@ -301,7 +301,7 @@ export class NpmScriptsTreeDataProvider implements TreeDataProvider { } const regularExpressions = (location && excludeConfig.has(location.uri.toString())) ? excludeConfig.get(location.uri.toString()) : undefined; - if (regularExpressions && regularExpressions.some((regularExpression) => (each.task.definition).script.match(regularExpression))) { + if (regularExpressions && regularExpressions.some((regularExpression) => (each.task.definition).script.match(regularExpression))) { return; } @@ -311,7 +311,7 @@ export class NpmScriptsTreeDataProvider implements TreeDataProvider { folder = new Folder(each.task.scope); folders.set(each.task.scope.name, folder); } - let definition: NpmTaskDefinition = each.task.definition; + let definition: INpmTaskDefinition = each.task.definition; let relativePath = definition.path ? definition.path : ''; let fullPath = path.join(each.task.scope.name, relativePath); packageJson = packages.get(fullPath); diff --git a/extensions/npm/src/tasks.ts b/extensions/npm/src/tasks.ts index d05b7bbc8bf..47237442d98 100644 --- a/extensions/npm/src/tasks.ts +++ b/extensions/npm/src/tasks.ts @@ -17,28 +17,28 @@ import { readScripts } from './readScripts'; const localize = nls.loadMessageBundle(); -export interface NpmTaskDefinition extends TaskDefinition { +export interface INpmTaskDefinition extends TaskDefinition { script: string; path?: string; } -export interface FolderTaskItem extends QuickPickItem { +export interface IFolderTaskItem extends QuickPickItem { label: string; task: Task; } type AutoDetect = 'on' | 'off'; -let cachedTasks: TaskWithLocation[] | undefined = undefined; +let cachedTasks: ITaskWithLocation[] | undefined = undefined; const INSTALL_SCRIPT = 'install'; -export interface TaskLocation { +export interface ITaskLocation { document: Uri; line: Position; } -export interface TaskWithLocation { +export interface ITaskWithLocation { task: Task; location?: Location; } @@ -48,7 +48,7 @@ export class NpmTaskProvider implements TaskProvider { constructor(private context: ExtensionContext) { } - get tasksWithLocation(): Promise { + get tasksWithLocation(): Promise { return provideNpmScripts(this.context, false); } @@ -60,7 +60,7 @@ export class NpmTaskProvider implements TaskProvider { public async resolveTask(_task: Task): Promise { const npmTask = (_task.definition).script; if (npmTask) { - const kind: NpmTaskDefinition = (_task.definition); + const kind: INpmTaskDefinition = (_task.definition); let packageJsonUri: Uri; if (_task.scope === undefined || _task.scope === TaskScope.Global || _task.scope === TaskScope.Workspace) { // scope is required to be a WorkspaceFolder for resolveTask @@ -170,10 +170,10 @@ export async function hasNpmScripts(): Promise { } } -async function detectNpmScripts(context: ExtensionContext, showWarning: boolean): Promise { +async function detectNpmScripts(context: ExtensionContext, showWarning: boolean): Promise { - let emptyTasks: TaskWithLocation[] = []; - let allTasks: TaskWithLocation[] = []; + let emptyTasks: ITaskWithLocation[] = []; + let allTasks: ITaskWithLocation[] = []; let visitedPackageJsonFiles: Set = new Set(); let folders = workspace.workspaceFolders; @@ -201,9 +201,9 @@ async function detectNpmScripts(context: ExtensionContext, showWarning: boolean) } -export async function detectNpmScriptsForFolder(context: ExtensionContext, folder: Uri): Promise { +export async function detectNpmScriptsForFolder(context: ExtensionContext, folder: Uri): Promise { - let folderTasks: FolderTaskItem[] = []; + let folderTasks: IFolderTaskItem[] = []; try { let relativePattern = new RelativePattern(folder.fsPath, '**/package.json'); @@ -223,7 +223,7 @@ export async function detectNpmScriptsForFolder(context: ExtensionContext, folde } } -export async function provideNpmScripts(context: ExtensionContext, showWarning: boolean): Promise { +export async function provideNpmScripts(context: ExtensionContext, showWarning: boolean): Promise { if (!cachedTasks) { cachedTasks = await detectNpmScripts(context, showWarning); } @@ -261,8 +261,8 @@ function isDebugScript(script: string): boolean { return match !== null; } -async function provideNpmScriptsForFolder(context: ExtensionContext, packageJsonUri: Uri, showWarning: boolean): Promise { - let emptyTasks: TaskWithLocation[] = []; +async function provideNpmScriptsForFolder(context: ExtensionContext, packageJsonUri: Uri, showWarning: boolean): Promise { + let emptyTasks: ITaskWithLocation[] = []; let folder = workspace.getWorkspaceFolder(packageJsonUri); if (!folder) { @@ -273,7 +273,7 @@ async function provideNpmScriptsForFolder(context: ExtensionContext, packageJson return emptyTasks; } - const result: TaskWithLocation[] = []; + const result: ITaskWithLocation[] = []; const packageManager = await getPackageManager(context, folder.uri, showWarning); @@ -294,8 +294,8 @@ export function getTaskName(script: string, relativePath: string | undefined) { return script; } -export async function createTask(packageManager: string, script: NpmTaskDefinition | string, cmd: string[], folder: WorkspaceFolder, packageJsonUri: Uri, scriptValue?: string, matcher?: any): Promise { - let kind: NpmTaskDefinition; +export async function createTask(packageManager: string, script: INpmTaskDefinition | string, cmd: string[], folder: WorkspaceFolder, packageJsonUri: Uri, scriptValue?: string, matcher?: any): Promise { + let kind: INpmTaskDefinition; if (typeof script === 'string') { kind = { type: 'npm', script: script }; } else { diff --git a/extensions/vscode-api-tests/src/singlefolder-tests/workspace.tasks.test.ts b/extensions/vscode-api-tests/src/singlefolder-tests/workspace.tasks.test.ts index a7b497e5467..4167e15ce00 100644 --- a/extensions/vscode-api-tests/src/singlefolder-tests/workspace.tasks.test.ts +++ b/extensions/vscode-api-tests/src/singlefolder-tests/workspace.tasks.test.ts @@ -147,7 +147,7 @@ import { assertNoRpc } from '../utils'; suite('CustomExecution', () => { test('task should start and shutdown successfully', async () => { window.terminals.forEach(terminal => terminal.dispose()); - interface CustomTestingTaskDefinition extends TaskDefinition { + interface ICustomTestingTaskDefinition extends TaskDefinition { /** * One of the task properties. This can be used to customize the task in the tasks.json */ @@ -179,7 +179,7 @@ import { assertNoRpc } from '../utils'; disposables.push(tasks.registerTaskProvider(taskType, { provideTasks: () => { const result: Task[] = []; - const kind: CustomTestingTaskDefinition = { + const kind: ICustomTestingTaskDefinition = { type: taskType, customProp1: 'testing task one' }; @@ -235,7 +235,7 @@ import { assertNoRpc } from '../utils'; }); test('sync task should flush all data on close', async () => { - interface CustomTestingTaskDefinition extends TaskDefinition { + interface ICustomTestingTaskDefinition extends TaskDefinition { /** * One of the task properties. This can be used to customize the task in the tasks.json */ @@ -250,7 +250,7 @@ import { assertNoRpc } from '../utils'; disposables.push(tasks.registerTaskProvider(taskType, { provideTasks: () => { const result: Task[] = []; - const kind: CustomTestingTaskDefinition = { + const kind: ICustomTestingTaskDefinition = { type: taskType, customProp1: 'testing task one' }; diff --git a/src/vs/workbench/api/browser/mainThreadTask.ts b/src/vs/workbench/api/browser/mainThreadTask.ts index 9cd5c8235f9..d23e70f39d2 100644 --- a/src/vs/workbench/api/browser/mainThreadTask.ts +++ b/src/vs/workbench/api/browser/mainThreadTask.ts @@ -15,27 +15,27 @@ import { IDisposable } from 'vs/base/common/lifecycle'; import { IWorkspace, IWorkspaceContextService, IWorkspaceFolder } from 'vs/platform/workspace/common/workspace'; import { - ContributedTask, ConfiguringTask, KeyedTaskIdentifier, TaskExecution, Task, TaskEvent, TaskEventKind, - PresentationOptions, CommandOptions, CommandConfiguration, RuntimeType, CustomTask, TaskScope, TaskSource, - TaskSourceKind, ExtensionTaskSource, RunOptions, TaskSet, TaskDefinition, TaskGroup + ContributedTask, ConfiguringTask, KeyedTaskIdentifier, ITaskExecution, Task, ITaskEvent, TaskEventKind, + IPresentationOptions, CommandOptions, ICommandConfiguration, RuntimeType, CustomTask, TaskScope, TaskSource, + TaskSourceKind, IExtensionTaskSource, IRunOptions, ITaskSet, TaskGroup, TaskDefinition, PresentationOptions, RunOptions } from 'vs/workbench/contrib/tasks/common/tasks'; -import { ResolveSet, ResolvedVariables } from 'vs/workbench/contrib/tasks/common/taskSystem'; -import { ITaskService, TaskFilter, ITaskProvider } from 'vs/workbench/contrib/tasks/common/taskService'; +import { IResolveSet, IResolvedVariables } from 'vs/workbench/contrib/tasks/common/taskSystem'; +import { ITaskService, ITaskFilter, ITaskProvider } from 'vs/workbench/contrib/tasks/common/taskService'; import { extHostNamedCustomer, IExtHostContext } from 'vs/workbench/services/extensions/common/extHostCustomers'; import { ExtHostContext, MainThreadTaskShape, ExtHostTaskShape, MainContext } from 'vs/workbench/api/common/extHost.protocol'; import { - TaskDefinitionDTO, TaskExecutionDTO, ProcessExecutionOptionsDTO, TaskPresentationOptionsDTO, - ProcessExecutionDTO, ShellExecutionDTO, ShellExecutionOptionsDTO, CustomExecutionDTO, TaskDTO, TaskSourceDTO, TaskHandleDTO, TaskFilterDTO, TaskProcessStartedDTO, TaskProcessEndedDTO, TaskSystemInfoDTO, - RunOptionsDTO, TaskGroupDTO + ITaskDefinitionDTO, ITaskExecutionDTO, IProcessExecutionOptionsDTO, ITaskPresentationOptionsDTO, + IProcessExecutionDTO, IShellExecutionDTO, IShellExecutionOptionsDTO, ICustomExecutionDTO, ITaskDTO, ITaskSourceDTO, ITaskHandleDTO, ITaskFilterDTO, ITaskProcessStartedDTO, ITaskProcessEndedDTO, ITaskSystemInfoDTO, + IRunOptionsDTO, ITaskGroupDTO } from 'vs/workbench/api/common/shared/tasks'; import { IConfigurationResolverService } from 'vs/workbench/services/configurationResolver/common/configurationResolver'; import { ConfigurationTarget } from 'vs/platform/configuration/common/configuration'; namespace TaskExecutionDTO { - export function from(value: TaskExecution): TaskExecutionDTO { + export function from(value: ITaskExecution): ITaskExecutionDTO { return { id: value.id, task: TaskDTO.from(value.task) @@ -44,7 +44,7 @@ namespace TaskExecutionDTO { } namespace TaskProcessStartedDTO { - export function from(value: TaskExecution, processId: number): TaskProcessStartedDTO { + export function from(value: ITaskExecution, processId: number): ITaskProcessStartedDTO { return { id: value.id, processId @@ -53,7 +53,7 @@ namespace TaskProcessStartedDTO { } namespace TaskProcessEndedDTO { - export function from(value: TaskExecution, exitCode: number | undefined): TaskProcessEndedDTO { + export function from(value: ITaskExecution, exitCode: number | undefined): ITaskProcessEndedDTO { return { id: value.id, exitCode @@ -62,12 +62,12 @@ namespace TaskProcessEndedDTO { } namespace TaskDefinitionDTO { - export function from(value: KeyedTaskIdentifier): TaskDefinitionDTO { + export function from(value: KeyedTaskIdentifier): ITaskDefinitionDTO { const result = Object.assign(Object.create(null), value); delete result._key; return result; } - export function to(value: TaskDefinitionDTO, executeOnly: boolean): KeyedTaskIdentifier | undefined { + export function to(value: ITaskDefinitionDTO, executeOnly: boolean): KeyedTaskIdentifier | undefined { let result = TaskDefinition.createTaskIdentifier(value, console); if (result === undefined && executeOnly) { result = { @@ -80,13 +80,13 @@ namespace TaskDefinitionDTO { } namespace TaskPresentationOptionsDTO { - export function from(value: PresentationOptions | undefined): TaskPresentationOptionsDTO | undefined { + export function from(value: IPresentationOptions | undefined): ITaskPresentationOptionsDTO | undefined { if (value === undefined || value === null) { return undefined; } return Object.assign(Object.create(null), value); } - export function to(value: TaskPresentationOptionsDTO | undefined): PresentationOptions { + export function to(value: ITaskPresentationOptionsDTO | undefined): IPresentationOptions { if (value === undefined || value === null) { return PresentationOptions.defaults; } @@ -95,13 +95,13 @@ namespace TaskPresentationOptionsDTO { } namespace RunOptionsDTO { - export function from(value: RunOptions): RunOptionsDTO | undefined { + export function from(value: IRunOptions): IRunOptionsDTO | undefined { if (value === undefined || value === null) { return undefined; } return Object.assign(Object.create(null), value); } - export function to(value: RunOptionsDTO | undefined): RunOptions { + export function to(value: IRunOptionsDTO | undefined): IRunOptions { if (value === undefined || value === null) { return RunOptions.defaults; } @@ -110,7 +110,7 @@ namespace RunOptionsDTO { } namespace ProcessExecutionOptionsDTO { - export function from(value: CommandOptions): ProcessExecutionOptionsDTO | undefined { + export function from(value: CommandOptions): IProcessExecutionOptionsDTO | undefined { if (value === undefined || value === null) { return undefined; } @@ -119,7 +119,7 @@ namespace ProcessExecutionOptionsDTO { env: value.env }; } - export function to(value: ProcessExecutionOptionsDTO | undefined): CommandOptions { + export function to(value: IProcessExecutionOptionsDTO | undefined): CommandOptions { if (value === undefined || value === null) { return CommandOptions.defaults; } @@ -131,14 +131,14 @@ namespace ProcessExecutionOptionsDTO { } namespace ProcessExecutionDTO { - export function is(value: ShellExecutionDTO | ProcessExecutionDTO | CustomExecutionDTO): value is ProcessExecutionDTO { - const candidate = value as ProcessExecutionDTO; + export function is(value: IShellExecutionDTO | IProcessExecutionDTO | ICustomExecutionDTO): value is IProcessExecutionDTO { + const candidate = value as IProcessExecutionDTO; return candidate && !!candidate.process; } - export function from(value: CommandConfiguration): ProcessExecutionDTO { + export function from(value: ICommandConfiguration): IProcessExecutionDTO { const process: string = Types.isString(value.name) ? value.name : value.name!.value; const args: string[] = value.args ? value.args.map(value => Types.isString(value) ? value : value.value) : []; - const result: ProcessExecutionDTO = { + const result: IProcessExecutionDTO = { process: process, args: args }; @@ -147,8 +147,8 @@ namespace ProcessExecutionDTO { } return result; } - export function to(value: ProcessExecutionDTO): CommandConfiguration { - const result: CommandConfiguration = { + export function to(value: IProcessExecutionDTO): ICommandConfiguration { + const result: ICommandConfiguration = { runtime: RuntimeType.Process, name: value.process, args: value.args, @@ -160,11 +160,11 @@ namespace ProcessExecutionDTO { } namespace ShellExecutionOptionsDTO { - export function from(value: CommandOptions): ShellExecutionOptionsDTO | undefined { + export function from(value: CommandOptions): IShellExecutionOptionsDTO | undefined { if (value === undefined || value === null) { return undefined; } - const result: ShellExecutionOptionsDTO = { + const result: IShellExecutionOptionsDTO = { cwd: value.cwd || CommandOptions.defaults.cwd, env: value.env }; @@ -175,7 +175,7 @@ namespace ShellExecutionOptionsDTO { } return result; } - export function to(value: ShellExecutionOptionsDTO): CommandOptions | undefined { + export function to(value: IShellExecutionOptionsDTO): CommandOptions | undefined { if (value === undefined || value === null) { return undefined; } @@ -199,12 +199,12 @@ namespace ShellExecutionOptionsDTO { } namespace ShellExecutionDTO { - export function is(value: ShellExecutionDTO | ProcessExecutionDTO | CustomExecutionDTO): value is ShellExecutionDTO { - const candidate = value as ShellExecutionDTO; + export function is(value: IShellExecutionDTO | IProcessExecutionDTO | ICustomExecutionDTO): value is IShellExecutionDTO { + const candidate = value as IShellExecutionDTO; return candidate && (!!candidate.commandLine || !!candidate.command); } - export function from(value: CommandConfiguration): ShellExecutionDTO { - const result: ShellExecutionDTO = {}; + export function from(value: ICommandConfiguration): IShellExecutionDTO { + const result: IShellExecutionDTO = {}; if (value.name && Types.isString(value.name) && (value.args === undefined || value.args === null || value.args.length === 0)) { result.commandLine = value.name; } else { @@ -216,8 +216,8 @@ namespace ShellExecutionDTO { } return result; } - export function to(value: ShellExecutionDTO): CommandConfiguration { - const result: CommandConfiguration = { + export function to(value: IShellExecutionDTO): ICommandConfiguration { + const result: ICommandConfiguration = { runtime: RuntimeType.Shell, name: value.commandLine ? value.commandLine : value.command, args: value.args, @@ -231,18 +231,18 @@ namespace ShellExecutionDTO { } namespace CustomExecutionDTO { - export function is(value: ShellExecutionDTO | ProcessExecutionDTO | CustomExecutionDTO): value is CustomExecutionDTO { - const candidate = value as CustomExecutionDTO; + export function is(value: IShellExecutionDTO | IProcessExecutionDTO | ICustomExecutionDTO): value is ICustomExecutionDTO { + const candidate = value as ICustomExecutionDTO; return candidate && candidate.customExecution === 'customExecution'; } - export function from(value: CommandConfiguration): CustomExecutionDTO { + export function from(value: ICommandConfiguration): ICustomExecutionDTO { return { customExecution: 'customExecution' }; } - export function to(value: CustomExecutionDTO): CommandConfiguration { + export function to(value: ICustomExecutionDTO): ICommandConfiguration { return { runtime: RuntimeType.CustomExecution, presentation: undefined @@ -251,8 +251,8 @@ namespace CustomExecutionDTO { } namespace TaskSourceDTO { - export function from(value: TaskSource): TaskSourceDTO { - const result: TaskSourceDTO = { + export function from(value: TaskSource): ITaskSourceDTO { + const result: ITaskSourceDTO = { label: value.label }; if (value.kind === TaskSourceKind.Extension) { @@ -268,7 +268,7 @@ namespace TaskSourceDTO { } return result; } - export function to(value: TaskSourceDTO, workspace: IWorkspaceContextService): ExtensionTaskSource { + export function to(value: ITaskSourceDTO, workspace: IWorkspaceContextService): IExtensionTaskSource { let scope: TaskScope; let workspaceFolder: IWorkspaceFolder | undefined; if ((value.scope === undefined) || ((typeof value.scope === 'number') && (value.scope !== TaskScope.Global))) { @@ -285,7 +285,7 @@ namespace TaskSourceDTO { scope = TaskScope.Folder; workspaceFolder = Types.withNullAsUndefined(workspace.getWorkspaceFolder(URI.revive(value.scope))); } - const result: ExtensionTaskSource = { + const result: IExtensionTaskSource = { kind: TaskSourceKind.Extension, label: value.label, extension: value.extensionId, @@ -297,18 +297,18 @@ namespace TaskSourceDTO { } namespace TaskHandleDTO { - export function is(value: any): value is TaskHandleDTO { - const candidate: TaskHandleDTO = value; + export function is(value: any): value is ITaskHandleDTO { + const candidate: ITaskHandleDTO = value; return candidate && Types.isString(candidate.id) && !!candidate.workspaceFolder; } } namespace TaskDTO { - export function from(task: Task | ConfiguringTask): TaskDTO | undefined { + export function from(task: Task | ConfiguringTask): ITaskDTO | undefined { if (task === undefined || task === null || (!CustomTask.is(task) && !ContributedTask.is(task) && !ConfiguringTask.is(task))) { return undefined; } - const result: TaskDTO = { + const result: ITaskDTO = { _id: task._id, name: task.configurationProperties.name, definition: TaskDefinitionDTO.from(task.getDefinition(true)), @@ -342,12 +342,12 @@ namespace TaskDTO { return result; } - export function to(task: TaskDTO | undefined, workspace: IWorkspaceContextService, executeOnly: boolean): ContributedTask | undefined { + export function to(task: ITaskDTO | undefined, workspace: IWorkspaceContextService, executeOnly: boolean): ContributedTask | undefined { if (!task || (typeof task.name !== 'string')) { return undefined; } - let command: CommandConfiguration | undefined; + let command: ICommandConfiguration | undefined; if (task.execution) { if (ShellExecutionDTO.is(task.execution)) { command = ShellExecutionDTO.to(task.execution); @@ -390,7 +390,7 @@ namespace TaskDTO { } namespace TaskGroupDTO { - export function from(value: string | TaskGroup | undefined): TaskGroupDTO | undefined { + export function from(value: string | TaskGroup | undefined): ITaskGroupDTO | undefined { if (value === undefined) { return undefined; } @@ -402,10 +402,10 @@ namespace TaskGroupDTO { } namespace TaskFilterDTO { - export function from(value: TaskFilter): TaskFilterDTO { + export function from(value: ITaskFilter): ITaskFilterDTO { return value; } - export function to(value: TaskFilterDTO | undefined): TaskFilter | undefined { + export function to(value: ITaskFilterDTO | undefined): ITaskFilter | undefined { return value; } } @@ -425,11 +425,11 @@ export class MainThreadTask implements MainThreadTaskShape { ) { this._proxy = extHostContext.getProxy(ExtHostContext.ExtHostTask); this._providers = new Map(); - this._taskService.onDidStateChange(async (event: TaskEvent) => { + this._taskService.onDidStateChange(async (event: ITaskEvent) => { const task = event.__task!; if (event.kind === TaskEventKind.Start) { const execution = TaskExecutionDTO.from(task.getTaskExecution()); - let resolvedDefinition: TaskDefinitionDTO = execution.task!.definition; + let resolvedDefinition: ITaskDefinitionDTO = execution.task!.definition; if (execution.task?.execution && CustomExecutionDTO.is(execution.task.execution) && event.resolvedVariables) { const dictionary: IStringDictionary = {}; Array.from(event.resolvedVariables.entries()).forEach(entry => dictionary[entry[0]] = entry[1]); @@ -454,7 +454,7 @@ export class MainThreadTask implements MainThreadTaskShape { this._providers.clear(); } - $createTaskId(taskDTO: TaskDTO): Promise { + $createTaskId(taskDTO: ITaskDTO): Promise { return new Promise((resolve, reject) => { let task = TaskDTO.to(taskDTO, this._workspaceContextServer, true); if (task) { @@ -481,7 +481,7 @@ export class MainThreadTask implements MainThreadTaskShape { return { tasks, extension: value.extension - } as TaskSet; + } as ITaskSet; }); }, resolveTask: (task: ConfiguringTask) => { @@ -514,9 +514,9 @@ export class MainThreadTask implements MainThreadTaskShape { return Promise.resolve(undefined); } - public $fetchTasks(filter?: TaskFilterDTO): Promise { + public $fetchTasks(filter?: ITaskFilterDTO): Promise { return this._taskService.tasks(TaskFilterDTO.to(filter)).then((tasks) => { - const result: TaskDTO[] = []; + const result: ITaskDTO[] = []; for (let task of tasks) { const item = TaskDTO.from(task); if (item) { @@ -543,7 +543,7 @@ export class MainThreadTask implements MainThreadTaskShape { return workspace; } - public async $getTaskExecution(value: TaskHandleDTO | TaskDTO): Promise { + public async $getTaskExecution(value: ITaskHandleDTO | ITaskDTO): Promise { if (TaskHandleDTO.is(value)) { const workspace = this.getWorkspace(value.workspaceFolder); if (workspace) { @@ -569,8 +569,8 @@ export class MainThreadTask implements MainThreadTaskShape { // Passing in a TaskHandleDTO will cause the task to get re-resolved, which is important for tasks are coming from the core, // such as those gotten from a fetchTasks, since they can have missing configuration properties. - public $executeTask(value: TaskHandleDTO | TaskDTO): Promise { - return new Promise((resolve, reject) => { + public $executeTask(value: ITaskHandleDTO | ITaskDTO): Promise { + return new Promise((resolve, reject) => { if (TaskHandleDTO.is(value)) { const workspace = this.getWorkspace(value.workspaceFolder); if (workspace) { @@ -578,7 +578,7 @@ export class MainThreadTask implements MainThreadTaskShape { if (!task) { reject(new Error('Task not found')); } else { - const result: TaskExecutionDTO = { + const result: ITaskExecutionDTO = { id: value.id, task: TaskDTO.from(task) }; @@ -604,7 +604,7 @@ export class MainThreadTask implements MainThreadTaskShape { this._taskService.run(task).then(undefined, reason => { // eat the error, it has already been surfaced to the user and we don't care about it here }); - const result: TaskExecutionDTO = { + const result: ITaskExecutionDTO = { id: task._id, task: TaskDTO.from(task) }; @@ -650,7 +650,7 @@ export class MainThreadTask implements MainThreadTaskShape { }); } - public $registerTaskSystem(key: string, info: TaskSystemInfoDTO): void { + public $registerTaskSystem(key: string, info: ITaskSystemInfoDTO): void { let platform: Platform.Platform; switch (info.platform) { case 'Web': @@ -674,7 +674,7 @@ export class MainThreadTask implements MainThreadTaskShape { return URI.from({ scheme: info.scheme, authority: info.authority, path }); }, context: this._extHostContext, - resolveVariables: (workspaceFolder: IWorkspaceFolder, toResolve: ResolveSet, target: ConfigurationTarget): Promise => { + resolveVariables: (workspaceFolder: IWorkspaceFolder, toResolve: IResolveSet, target: ConfigurationTarget): Promise => { const vars: string[] = []; toResolve.variables.forEach(item => vars.push(item)); return Promise.resolve(this._proxy.$resolveVariables(workspaceFolder.uri, { process: toResolve.process, variables: vars })).then(values => { @@ -682,13 +682,13 @@ export class MainThreadTask implements MainThreadTaskShape { forEach(values.variables, (entry) => { partiallyResolvedVars.push(entry.value); }); - return new Promise((resolve, reject) => { + return new Promise((resolve, reject) => { this._configurationResolverService.resolveWithInteraction(workspaceFolder, partiallyResolvedVars, 'tasks', undefined, target).then(resolvedVars => { if (!resolvedVars) { resolve(undefined); } - const result: ResolvedVariables = { + const result: IResolvedVariables = { process: undefined, variables: new Map() }; diff --git a/src/vs/workbench/api/common/extHost.protocol.ts b/src/vs/workbench/api/common/extHost.protocol.ts index 3b29ae91432..865a0e5c4eb 100644 --- a/src/vs/workbench/api/common/extHost.protocol.ts +++ b/src/vs/workbench/api/common/extHost.protocol.ts @@ -1111,14 +1111,14 @@ export interface MainThreadSearchShape extends IDisposable { } export interface MainThreadTaskShape extends IDisposable { - $createTaskId(task: tasks.TaskDTO): Promise; + $createTaskId(task: tasks.ITaskDTO): Promise; $registerTaskProvider(handle: number, type: string): Promise; $unregisterTaskProvider(handle: number): Promise; - $fetchTasks(filter?: tasks.TaskFilterDTO): Promise; - $getTaskExecution(value: tasks.TaskHandleDTO | tasks.TaskDTO): Promise; - $executeTask(task: tasks.TaskHandleDTO | tasks.TaskDTO): Promise; + $fetchTasks(filter?: tasks.ITaskFilterDTO): Promise; + $getTaskExecution(value: tasks.ITaskHandleDTO | tasks.ITaskDTO): Promise; + $executeTask(task: tasks.ITaskHandleDTO | tasks.ITaskDTO): Promise; $terminateTask(id: string): Promise; - $registerTaskSystem(scheme: string, info: tasks.TaskSystemInfoDTO): void; + $registerTaskSystem(scheme: string, info: tasks.ITaskSystemInfoDTO): void; $customExecutionComplete(id: string, result?: number): Promise; $registerSupportedExecutions(custom?: boolean, shell?: boolean, process?: boolean): Promise; } @@ -1841,12 +1841,12 @@ export interface ExtHostSCMShape { } export interface ExtHostTaskShape { - $provideTasks(handle: number, validTypes: { [key: string]: boolean }): Promise; - $resolveTask(handle: number, taskDTO: tasks.TaskDTO): Promise; - $onDidStartTask(execution: tasks.TaskExecutionDTO, terminalId: number, resolvedDefinition: tasks.TaskDefinitionDTO): void; - $onDidStartTaskProcess(value: tasks.TaskProcessStartedDTO): void; - $onDidEndTaskProcess(value: tasks.TaskProcessEndedDTO): void; - $OnDidEndTask(execution: tasks.TaskExecutionDTO): void; + $provideTasks(handle: number, validTypes: { [key: string]: boolean }): Promise; + $resolveTask(handle: number, taskDTO: tasks.ITaskDTO): Promise; + $onDidStartTask(execution: tasks.ITaskExecutionDTO, terminalId: number, resolvedDefinition: tasks.ITaskDefinitionDTO): void; + $onDidStartTaskProcess(value: tasks.ITaskProcessStartedDTO): void; + $onDidEndTaskProcess(value: tasks.ITaskProcessEndedDTO): void; + $OnDidEndTask(execution: tasks.ITaskExecutionDTO): void; $resolveVariables(workspaceFolder: UriComponents, toResolve: { process?: { name: string; cwd?: string }; variables: string[] }): Promise<{ process?: string; variables: { [key: string]: string } }>; $jsonTasksSupported(): Promise; $findExecutable(command: string, cwd?: string, paths?: string[]): Promise; diff --git a/src/vs/workbench/api/common/extHostTask.ts b/src/vs/workbench/api/common/extHostTask.ts index c05d65eee9e..9c556708217 100644 --- a/src/vs/workbench/api/common/extHostTask.ts +++ b/src/vs/workbench/api/common/extHostTask.ts @@ -38,20 +38,20 @@ export interface IExtHostTask extends ExtHostTaskShape { onDidEndTaskProcess: Event; registerTaskProvider(extension: IExtensionDescription, type: string, provider: vscode.TaskProvider): vscode.Disposable; - registerTaskSystem(scheme: string, info: tasks.TaskSystemInfoDTO): void; + registerTaskSystem(scheme: string, info: tasks.ITaskSystemInfoDTO): void; fetchTasks(filter?: vscode.TaskFilter): Promise; executeTask(extension: IExtensionDescription, task: vscode.Task): Promise; terminateTask(execution: vscode.TaskExecution): Promise; } export namespace TaskDefinitionDTO { - export function from(value: vscode.TaskDefinition): tasks.TaskDefinitionDTO | undefined { + export function from(value: vscode.TaskDefinition): tasks.ITaskDefinitionDTO | undefined { if (value === undefined || value === null) { return undefined; } return value; } - export function to(value: tasks.TaskDefinitionDTO): vscode.TaskDefinition | undefined { + export function to(value: tasks.ITaskDefinitionDTO): vscode.TaskDefinition | undefined { if (value === undefined || value === null) { return undefined; } @@ -60,13 +60,13 @@ export namespace TaskDefinitionDTO { } export namespace TaskPresentationOptionsDTO { - export function from(value: vscode.TaskPresentationOptions): tasks.TaskPresentationOptionsDTO | undefined { + export function from(value: vscode.TaskPresentationOptions): tasks.ITaskPresentationOptionsDTO | undefined { if (value === undefined || value === null) { return undefined; } return value; } - export function to(value: tasks.TaskPresentationOptionsDTO): vscode.TaskPresentationOptions | undefined { + export function to(value: tasks.ITaskPresentationOptionsDTO): vscode.TaskPresentationOptions | undefined { if (value === undefined || value === null) { return undefined; } @@ -75,13 +75,13 @@ export namespace TaskPresentationOptionsDTO { } export namespace ProcessExecutionOptionsDTO { - export function from(value: vscode.ProcessExecutionOptions): tasks.ProcessExecutionOptionsDTO | undefined { + export function from(value: vscode.ProcessExecutionOptions): tasks.IProcessExecutionOptionsDTO | undefined { if (value === undefined || value === null) { return undefined; } return value; } - export function to(value: tasks.ProcessExecutionOptionsDTO): vscode.ProcessExecutionOptions | undefined { + export function to(value: tasks.IProcessExecutionOptionsDTO): vscode.ProcessExecutionOptions | undefined { if (value === undefined || value === null) { return undefined; } @@ -90,19 +90,19 @@ export namespace ProcessExecutionOptionsDTO { } export namespace ProcessExecutionDTO { - export function is(value: tasks.ShellExecutionDTO | tasks.ProcessExecutionDTO | tasks.CustomExecutionDTO | undefined): value is tasks.ProcessExecutionDTO { + export function is(value: tasks.IShellExecutionDTO | tasks.IProcessExecutionDTO | tasks.ICustomExecutionDTO | undefined): value is tasks.IProcessExecutionDTO { if (value) { - const candidate = value as tasks.ProcessExecutionDTO; + const candidate = value as tasks.IProcessExecutionDTO; return candidate && !!candidate.process; } else { return false; } } - export function from(value: vscode.ProcessExecution): tasks.ProcessExecutionDTO | undefined { + export function from(value: vscode.ProcessExecution): tasks.IProcessExecutionDTO | undefined { if (value === undefined || value === null) { return undefined; } - const result: tasks.ProcessExecutionDTO = { + const result: tasks.IProcessExecutionDTO = { process: value.process, args: value.args }; @@ -111,7 +111,7 @@ export namespace ProcessExecutionDTO { } return result; } - export function to(value: tasks.ProcessExecutionDTO): types.ProcessExecution | undefined { + export function to(value: tasks.IProcessExecutionDTO): types.ProcessExecution | undefined { if (value === undefined || value === null) { return undefined; } @@ -120,13 +120,13 @@ export namespace ProcessExecutionDTO { } export namespace ShellExecutionOptionsDTO { - export function from(value: vscode.ShellExecutionOptions): tasks.ShellExecutionOptionsDTO | undefined { + export function from(value: vscode.ShellExecutionOptions): tasks.IShellExecutionOptionsDTO | undefined { if (value === undefined || value === null) { return undefined; } return value; } - export function to(value: tasks.ShellExecutionOptionsDTO): vscode.ShellExecutionOptions | undefined { + export function to(value: tasks.IShellExecutionOptionsDTO): vscode.ShellExecutionOptions | undefined { if (value === undefined || value === null) { return undefined; } @@ -135,19 +135,19 @@ export namespace ShellExecutionOptionsDTO { } export namespace ShellExecutionDTO { - export function is(value: tasks.ShellExecutionDTO | tasks.ProcessExecutionDTO | tasks.CustomExecutionDTO | undefined): value is tasks.ShellExecutionDTO { + export function is(value: tasks.IShellExecutionDTO | tasks.IProcessExecutionDTO | tasks.ICustomExecutionDTO | undefined): value is tasks.IShellExecutionDTO { if (value) { - const candidate = value as tasks.ShellExecutionDTO; + const candidate = value as tasks.IShellExecutionDTO; return candidate && (!!candidate.commandLine || !!candidate.command); } else { return false; } } - export function from(value: vscode.ShellExecution): tasks.ShellExecutionDTO | undefined { + export function from(value: vscode.ShellExecution): tasks.IShellExecutionDTO | undefined { if (value === undefined || value === null) { return undefined; } - const result: tasks.ShellExecutionDTO = { + const result: tasks.IShellExecutionDTO = { }; if (value.commandLine !== undefined) { result.commandLine = value.commandLine; @@ -160,7 +160,7 @@ export namespace ShellExecutionDTO { } return result; } - export function to(value: tasks.ShellExecutionDTO): types.ShellExecution | undefined { + export function to(value: tasks.IShellExecutionDTO): types.ShellExecution | undefined { if (value === undefined || value === null || (value.command === undefined && value.commandLine === undefined)) { return undefined; } @@ -173,16 +173,16 @@ export namespace ShellExecutionDTO { } export namespace CustomExecutionDTO { - export function is(value: tasks.ShellExecutionDTO | tasks.ProcessExecutionDTO | tasks.CustomExecutionDTO | undefined): value is tasks.CustomExecutionDTO { + export function is(value: tasks.IShellExecutionDTO | tasks.IProcessExecutionDTO | tasks.ICustomExecutionDTO | undefined): value is tasks.ICustomExecutionDTO { if (value) { - let candidate = value as tasks.CustomExecutionDTO; + let candidate = value as tasks.ICustomExecutionDTO; return candidate && candidate.customExecution === 'customExecution'; } else { return false; } } - export function from(value: vscode.CustomExecution): tasks.CustomExecutionDTO { + export function from(value: vscode.CustomExecution): tasks.ICustomExecutionDTO { return { customExecution: 'customExecution' }; @@ -195,7 +195,7 @@ export namespace CustomExecutionDTO { export namespace TaskHandleDTO { - export function from(value: types.Task, workspaceService?: IExtHostWorkspace): tasks.TaskHandleDTO { + export function from(value: types.Task, workspaceService?: IExtHostWorkspace): tasks.ITaskHandleDTO { let folder: UriComponents | string; if (value.scope !== undefined && typeof value.scope !== 'number') { folder = value.scope.uri; @@ -213,7 +213,7 @@ export namespace TaskHandleDTO { } } export namespace TaskGroupDTO { - export function from(value: vscode.TaskGroup): tasks.TaskGroupDTO | undefined { + export function from(value: vscode.TaskGroup): tasks.ITaskGroupDTO | undefined { if (value === undefined || value === null) { return undefined; } @@ -222,11 +222,11 @@ export namespace TaskGroupDTO { } export namespace TaskDTO { - export function fromMany(tasks: vscode.Task[], extension: IExtensionDescription): tasks.TaskDTO[] { + export function fromMany(tasks: vscode.Task[], extension: IExtensionDescription): tasks.ITaskDTO[] { if (tasks === undefined || tasks === null) { return []; } - const result: tasks.TaskDTO[] = []; + const result: tasks.ITaskDTO[] = []; for (let task of tasks) { const converted = from(task, extension); if (converted) { @@ -236,11 +236,11 @@ export namespace TaskDTO { return result; } - export function from(value: vscode.Task, extension: IExtensionDescription): tasks.TaskDTO | undefined { + export function from(value: vscode.Task, extension: IExtensionDescription): tasks.ITaskDTO | undefined { if (value === undefined || value === null) { return undefined; } - let execution: tasks.ShellExecutionDTO | tasks.ProcessExecutionDTO | tasks.CustomExecutionDTO | undefined; + let execution: tasks.IShellExecutionDTO | tasks.IProcessExecutionDTO | tasks.ICustomExecutionDTO | undefined; if (value.execution instanceof types.ProcessExecution) { execution = ProcessExecutionDTO.from(value.execution); } else if (value.execution instanceof types.ShellExecution) { @@ -249,7 +249,7 @@ export namespace TaskDTO { execution = CustomExecutionDTO.from(value.execution); } - const definition: tasks.TaskDefinitionDTO | undefined = TaskDefinitionDTO.from(value.definition); + const definition: tasks.ITaskDefinitionDTO | undefined = TaskDefinitionDTO.from(value.definition); let scope: number | UriComponents; if (value.scope) { if (typeof value.scope === 'number') { @@ -264,7 +264,7 @@ export namespace TaskDTO { if (!definition || !scope) { return undefined; } - const result: tasks.TaskDTO = { + const result: tasks.ITaskDTO = { _id: (value as types.Task)._id!, definition, name: value.name, @@ -284,7 +284,7 @@ export namespace TaskDTO { }; return result; } - export async function to(value: tasks.TaskDTO | undefined, workspace: IExtHostWorkspaceProvider, providedCustomExeutions: Map): Promise { + export async function to(value: tasks.ITaskDTO | undefined, workspace: IExtHostWorkspaceProvider, providedCustomExeutions: Map): Promise { if (value === undefined || value === null) { return undefined; } @@ -339,11 +339,11 @@ export namespace TaskDTO { } export namespace TaskFilterDTO { - export function from(value: vscode.TaskFilter | undefined): tasks.TaskFilterDTO | undefined { + export function from(value: vscode.TaskFilter | undefined): tasks.ITaskFilterDTO | undefined { return value; } - export function to(value: tasks.TaskFilterDTO): vscode.TaskFilter | undefined { + export function to(value: tasks.ITaskFilterDTO): vscode.TaskFilter | undefined { if (!value) { return undefined; } @@ -367,15 +367,15 @@ class TaskExecutionImpl implements vscode.TaskExecution { this.#tasks.terminateTask(this); } - public fireDidStartProcess(value: tasks.TaskProcessStartedDTO): void { + public fireDidStartProcess(value: tasks.ITaskProcessStartedDTO): void { } - public fireDidEndProcess(value: tasks.TaskProcessEndedDTO): void { + public fireDidEndProcess(value: tasks.ITaskProcessEndedDTO): void { } } export namespace TaskExecutionDTO { - export function from(value: vscode.TaskExecution): tasks.TaskExecutionDTO { + export function from(value: vscode.TaskExecution): tasks.ITaskExecutionDTO { return { id: (value as TaskExecutionImpl)._id, task: undefined @@ -453,7 +453,7 @@ export abstract class ExtHostTaskBase implements ExtHostTaskShape, IExtHostTask }); } - public registerTaskSystem(scheme: string, info: tasks.TaskSystemInfoDTO): void { + public registerTaskSystem(scheme: string, info: tasks.ITaskSystemInfoDTO): void { this._proxy.$registerTaskSystem(scheme, info); } @@ -489,7 +489,7 @@ export abstract class ExtHostTaskBase implements ExtHostTaskShape, IExtHostTask return this._onDidExecuteTask.event; } - public async $onDidStartTask(execution: tasks.TaskExecutionDTO, terminalId: number, resolvedDefinition: tasks.TaskDefinitionDTO): Promise { + public async $onDidStartTask(execution: tasks.ITaskExecutionDTO, terminalId: number, resolvedDefinition: tasks.ITaskDefinitionDTO): Promise { const customExecution: types.CustomExecution | undefined = this._providedCustomExecutions2.get(execution.id); if (customExecution) { // Clone the custom execution to keep the original untouched. This is important for multiple runs of the same task. @@ -507,7 +507,7 @@ export abstract class ExtHostTaskBase implements ExtHostTaskShape, IExtHostTask return this._onDidTerminateTask.event; } - public async $OnDidEndTask(execution: tasks.TaskExecutionDTO): Promise { + public async $OnDidEndTask(execution: tasks.ITaskExecutionDTO): Promise { const _execution = await this.getTaskExecution(execution); this._taskExecutionPromises.delete(execution.id); this._taskExecutions.delete(execution.id); @@ -521,7 +521,7 @@ export abstract class ExtHostTaskBase implements ExtHostTaskShape, IExtHostTask return this._onDidTaskProcessStarted.event; } - public async $onDidStartTaskProcess(value: tasks.TaskProcessStartedDTO): Promise { + public async $onDidStartTaskProcess(value: tasks.ITaskProcessStartedDTO): Promise { const execution = await this.getTaskExecution(value.id); this._onDidTaskProcessStarted.fire({ execution: execution, @@ -533,7 +533,7 @@ export abstract class ExtHostTaskBase implements ExtHostTaskShape, IExtHostTask return this._onDidTaskProcessEnded.event; } - public async $onDidEndTaskProcess(value: tasks.TaskProcessEndedDTO): Promise { + public async $onDidEndTaskProcess(value: tasks.ITaskProcessEndedDTO): Promise { const execution = await this.getTaskExecution(value.id); this._onDidTaskProcessEnded.fire({ execution: execution, @@ -541,9 +541,9 @@ export abstract class ExtHostTaskBase implements ExtHostTaskShape, IExtHostTask }); } - protected abstract provideTasksInternal(validTypes: { [key: string]: boolean }, taskIdPromises: Promise[], handler: HandlerData, value: vscode.Task[] | null | undefined): { tasks: tasks.TaskDTO[]; extension: IExtensionDescription }; + protected abstract provideTasksInternal(validTypes: { [key: string]: boolean }, taskIdPromises: Promise[], handler: HandlerData, value: vscode.Task[] | null | undefined): { tasks: tasks.ITaskDTO[]; extension: IExtensionDescription }; - public $provideTasks(handle: number, validTypes: { [key: string]: boolean }): Promise { + public $provideTasks(handle: number, validTypes: { [key: string]: boolean }): Promise { const handler = this._handlers.get(handle); if (!handler) { return Promise.reject(new Error('no handler found')); @@ -571,9 +571,9 @@ export abstract class ExtHostTaskBase implements ExtHostTaskShape, IExtHostTask }); } - protected abstract resolveTaskInternal(resolvedTaskDTO: tasks.TaskDTO): Promise; + protected abstract resolveTaskInternal(resolvedTaskDTO: tasks.ITaskDTO): Promise; - public async $resolveTask(handle: number, taskDTO: tasks.TaskDTO): Promise { + public async $resolveTask(handle: number, taskDTO: tasks.ITaskDTO): Promise { const handler = this._handlers.get(handle); if (!handler) { return Promise.reject(new Error('no handler found')); @@ -595,7 +595,7 @@ export abstract class ExtHostTaskBase implements ExtHostTaskShape, IExtHostTask this.checkDeprecation(resolvedTask, handler); - const resolvedTaskDTO: tasks.TaskDTO | undefined = TaskDTO.from(resolvedTask, handler.extension); + const resolvedTaskDTO: tasks.ITaskDTO | undefined = TaskDTO.from(resolvedTask, handler.extension); if (!resolvedTaskDTO) { throw new Error('Unexpected: Task cannot be resolved.'); } @@ -617,7 +617,7 @@ export abstract class ExtHostTaskBase implements ExtHostTaskShape, IExtHostTask return this._handleCounter++; } - protected async addCustomExecution(taskDTO: tasks.TaskDTO, task: vscode.Task, isProvided: boolean): Promise { + protected async addCustomExecution(taskDTO: tasks.ITaskDTO, task: vscode.Task, isProvided: boolean): Promise { const taskId = await this._proxy.$createTaskId(taskDTO); if (!isProvided && !this._providedCustomExecutions2.has(taskId)) { this._notProvidedCustomExecutions.add(taskId); @@ -627,7 +627,7 @@ export abstract class ExtHostTaskBase implements ExtHostTaskShape, IExtHostTask this._providedCustomExecutions2.set(taskId, task.execution); } - protected async getTaskExecution(execution: tasks.TaskExecutionDTO | string, task?: vscode.Task): Promise { + protected async getTaskExecution(execution: tasks.ITaskExecutionDTO | string, task?: vscode.Task): Promise { if (typeof execution === 'string') { const taskExecution = this._taskExecutionPromises.get(execution); if (!taskExecution) { @@ -641,7 +641,7 @@ export abstract class ExtHostTaskBase implements ExtHostTaskShape, IExtHostTask return result; } const createdResult: Promise = new Promise((resolve, reject) => { - function resolvePromiseWithCreatedTask(that: ExtHostTaskBase, execution: tasks.TaskExecutionDTO, taskToCreate: vscode.Task | types.Task | undefined) { + function resolvePromiseWithCreatedTask(that: ExtHostTaskBase, execution: tasks.ITaskExecutionDTO, taskToCreate: vscode.Task | types.Task | undefined) { if (!taskToCreate) { reject('Unexpected: Task does not exist.'); } else { @@ -673,7 +673,7 @@ export abstract class ExtHostTaskBase implements ExtHostTaskShape, IExtHostTask } } - private customExecutionComplete(execution: tasks.TaskExecutionDTO): void { + private customExecutionComplete(execution: tasks.ITaskExecutionDTO): void { const extensionCallback2: vscode.CustomExecution | undefined = this._activeCustomExecutions2.get(execution.id); if (extensionCallback2) { this._activeCustomExecutions2.delete(execution.id); @@ -747,8 +747,8 @@ export class WorkerExtHostTask extends ExtHostTaskBase { return execution; } - protected provideTasksInternal(validTypes: { [key: string]: boolean }, taskIdPromises: Promise[], handler: HandlerData, value: vscode.Task[] | null | undefined): { tasks: tasks.TaskDTO[]; extension: IExtensionDescription } { - const taskDTOs: tasks.TaskDTO[] = []; + protected provideTasksInternal(validTypes: { [key: string]: boolean }, taskIdPromises: Promise[], handler: HandlerData, value: vscode.Task[] | null | undefined): { tasks: tasks.ITaskDTO[]; extension: IExtensionDescription } { + const taskDTOs: tasks.ITaskDTO[] = []; if (value) { for (let task of value) { this.checkDeprecation(task, handler); @@ -756,7 +756,7 @@ export class WorkerExtHostTask extends ExtHostTaskBase { this._logService.warn(`The task [${task.source}, ${task.name}] uses an undefined task type. The task will be ignored in the future.`); } - const taskDTO: tasks.TaskDTO | undefined = TaskDTO.from(task, handler.extension); + const taskDTO: tasks.ITaskDTO | undefined = TaskDTO.from(task, handler.extension); if (taskDTO && CustomExecutionDTO.is(taskDTO.execution)) { taskDTOs.push(taskDTO); // The ID is calculated on the main thread task side, so, let's call into it here. @@ -774,7 +774,7 @@ export class WorkerExtHostTask extends ExtHostTaskBase { }; } - protected async resolveTaskInternal(resolvedTaskDTO: tasks.TaskDTO): Promise { + protected async resolveTaskInternal(resolvedTaskDTO: tasks.ITaskDTO): Promise { if (CustomExecutionDTO.is(resolvedTaskDTO.execution)) { return resolvedTaskDTO; } else { diff --git a/src/vs/workbench/api/common/shared/tasks.ts b/src/vs/workbench/api/common/shared/tasks.ts index 61c0d091a59..0bfd54a28d2 100644 --- a/src/vs/workbench/api/common/shared/tasks.ts +++ b/src/vs/workbench/api/common/shared/tasks.ts @@ -7,12 +7,12 @@ import { UriComponents } from 'vs/base/common/uri'; import { IExtensionDescription } from 'vs/platform/extensions/common/extensions'; import type { Dto } from 'vs/workbench/services/extensions/common/proxyIdentifier'; -export interface TaskDefinitionDTO { +export interface ITaskDefinitionDTO { type: string; [name: string]: any; } -export interface TaskPresentationOptionsDTO { +export interface ITaskPresentationOptionsDTO { reveal?: number; echo?: boolean; focus?: boolean; @@ -23,25 +23,25 @@ export interface TaskPresentationOptionsDTO { close?: boolean; } -export interface RunOptionsDTO { +export interface IRunOptionsDTO { reevaluateOnRerun?: boolean; } -export interface ExecutionOptionsDTO { +export interface IExecutionOptionsDTO { cwd?: string; env?: { [key: string]: string }; } -export interface ProcessExecutionOptionsDTO extends ExecutionOptionsDTO { +export interface IProcessExecutionOptionsDTO extends IExecutionOptionsDTO { } -export interface ProcessExecutionDTO { +export interface IProcessExecutionDTO { process: string; args: string[]; - options?: ProcessExecutionOptionsDTO; + options?: IProcessExecutionOptionsDTO; } -export interface ShellQuotingOptionsDTO { +export interface IShellQuotingOptionsDTO { escape?: string | { escapeChar: string; charsToEscape: string; @@ -50,86 +50,86 @@ export interface ShellQuotingOptionsDTO { weak?: string; } -export interface ShellExecutionOptionsDTO extends ExecutionOptionsDTO { +export interface IShellExecutionOptionsDTO extends IExecutionOptionsDTO { executable?: string; shellArgs?: string[]; - shellQuoting?: ShellQuotingOptionsDTO; + shellQuoting?: IShellQuotingOptionsDTO; } -export interface ShellQuotedStringDTO { +export interface IShellQuotedStringDTO { value: string; quoting: number; } -export interface ShellExecutionDTO { +export interface IShellExecutionDTO { commandLine?: string; - command?: string | ShellQuotedStringDTO; - args?: Array; - options?: ShellExecutionOptionsDTO; + command?: string | IShellQuotedStringDTO; + args?: Array; + options?: IShellExecutionOptionsDTO; } -export interface CustomExecutionDTO { +export interface ICustomExecutionDTO { customExecution: 'customExecution'; } -export interface TaskSourceDTO { +export interface ITaskSourceDTO { label: string; extensionId?: string; scope?: number | UriComponents; } -export interface TaskHandleDTO { +export interface ITaskHandleDTO { id: string; workspaceFolder: UriComponents | string; } -export interface TaskGroupDTO { +export interface ITaskGroupDTO { isDefault?: boolean; _id: string; } -export interface TaskDTO { +export interface ITaskDTO { _id: string; name?: string; - execution: ProcessExecutionDTO | ShellExecutionDTO | CustomExecutionDTO | undefined; - definition: TaskDefinitionDTO; + execution: IProcessExecutionDTO | IShellExecutionDTO | ICustomExecutionDTO | undefined; + definition: ITaskDefinitionDTO; isBackground?: boolean; - source: TaskSourceDTO; - group?: TaskGroupDTO; + source: ITaskSourceDTO; + group?: ITaskGroupDTO; detail?: string; - presentationOptions?: TaskPresentationOptionsDTO; + presentationOptions?: ITaskPresentationOptionsDTO; problemMatchers: string[]; hasDefinedMatchers: boolean; - runOptions?: RunOptionsDTO; + runOptions?: IRunOptionsDTO; } -export interface TaskSetDTO { - tasks: TaskDTO[]; +export interface ITaskSetDTO { + tasks: ITaskDTO[]; extension: Dto; } -export interface TaskExecutionDTO { +export interface ITaskExecutionDTO { id: string; - task: TaskDTO | undefined; + task: ITaskDTO | undefined; } -export interface TaskProcessStartedDTO { +export interface ITaskProcessStartedDTO { id: string; processId: number; } -export interface TaskProcessEndedDTO { +export interface ITaskProcessEndedDTO { id: string; exitCode: number | undefined; } -export interface TaskFilterDTO { +export interface ITaskFilterDTO { version?: string; type?: string; } -export interface TaskSystemInfoDTO { +export interface ITaskSystemInfoDTO { scheme: string; authority: string; platform: string; diff --git a/src/vs/workbench/api/node/extHostTask.ts b/src/vs/workbench/api/node/extHostTask.ts index 7afdfc40ea0..25f5085b4e7 100644 --- a/src/vs/workbench/api/node/extHostTask.ts +++ b/src/vs/workbench/api/node/extHostTask.ts @@ -92,8 +92,8 @@ export class ExtHostTask extends ExtHostTaskBase { } } - protected provideTasksInternal(validTypes: { [key: string]: boolean }, taskIdPromises: Promise[], handler: HandlerData, value: vscode.Task[] | null | undefined): { tasks: tasks.TaskDTO[]; extension: IExtensionDescription } { - const taskDTOs: tasks.TaskDTO[] = []; + protected provideTasksInternal(validTypes: { [key: string]: boolean }, taskIdPromises: Promise[], handler: HandlerData, value: vscode.Task[] | null | undefined): { tasks: tasks.ITaskDTO[]; extension: IExtensionDescription } { + const taskDTOs: tasks.ITaskDTO[] = []; if (value) { for (let task of value) { this.checkDeprecation(task, handler); @@ -102,7 +102,7 @@ export class ExtHostTask extends ExtHostTaskBase { this._logService.warn(`The task [${task.source}, ${task.name}] uses an undefined task type. The task will be ignored in the future.`); } - const taskDTO: tasks.TaskDTO | undefined = TaskDTO.from(task, handler.extension); + const taskDTO: tasks.ITaskDTO | undefined = TaskDTO.from(task, handler.extension); if (taskDTO) { taskDTOs.push(taskDTO); @@ -121,7 +121,7 @@ export class ExtHostTask extends ExtHostTaskBase { }; } - protected async resolveTaskInternal(resolvedTaskDTO: tasks.TaskDTO): Promise { + protected async resolveTaskInternal(resolvedTaskDTO: tasks.ITaskDTO): Promise { return resolvedTaskDTO; } diff --git a/src/vs/workbench/contrib/debug/browser/debugTaskRunner.ts b/src/vs/workbench/contrib/debug/browser/debugTaskRunner.ts index 8f4255fb1d2..d9ee132c153 100644 --- a/src/vs/workbench/contrib/debug/browser/debugTaskRunner.ts +++ b/src/vs/workbench/contrib/debug/browser/debugTaskRunner.ts @@ -10,7 +10,7 @@ import { Markers } from 'vs/workbench/contrib/markers/common/markers'; import { ITaskService, ITaskSummary } from 'vs/workbench/contrib/tasks/common/taskService'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { IWorkspaceFolder, IWorkspace } from 'vs/platform/workspace/common/workspace'; -import { TaskEvent, TaskEventKind, TaskIdentifier } from 'vs/workbench/contrib/tasks/common/tasks'; +import { ITaskEvent, TaskEventKind, ITaskIdentifier } from 'vs/workbench/contrib/tasks/common/tasks'; import { IDialogService } from 'vs/platform/dialogs/common/dialogs'; import { withUndefinedAsNull } from 'vs/base/common/types'; import { IMarkerService, MarkerSeverity } from 'vs/platform/markers/common/markers'; @@ -22,7 +22,7 @@ import { Action } from 'vs/base/common/actions'; import { DEBUG_CONFIGURE_COMMAND_ID, DEBUG_CONFIGURE_LABEL } from 'vs/workbench/contrib/debug/browser/debugCommands'; import { ICommandService } from 'vs/platform/commands/common/commands'; -function once(match: (e: TaskEvent) => boolean, event: Event): Event { +function once(match: (e: ITaskEvent) => boolean, event: Event): Event { return (listener, thisArgs = null, disposables?) => { const result = event(e => { if (match(e)) { @@ -59,7 +59,7 @@ export class DebugTaskRunner { this.canceled = true; } - async runTaskAndCheckErrors(root: IWorkspaceFolder | IWorkspace | undefined, taskId: string | TaskIdentifier | undefined): Promise { + async runTaskAndCheckErrors(root: IWorkspaceFolder | IWorkspace | undefined, taskId: string | ITaskIdentifier | undefined): Promise { try { this.canceled = false; const taskSummary = await this.runTask(root, taskId); @@ -149,7 +149,7 @@ export class DebugTaskRunner { } } - async runTask(root: IWorkspace | IWorkspaceFolder | undefined, taskId: string | TaskIdentifier | undefined): Promise { + async runTask(root: IWorkspace | IWorkspaceFolder | undefined, taskId: string | ITaskIdentifier | undefined): Promise { if (!taskId) { return Promise.resolve(null); } diff --git a/src/vs/workbench/contrib/debug/common/debug.ts b/src/vs/workbench/contrib/debug/common/debug.ts index 74160cd5166..5a19cdff64f 100644 --- a/src/vs/workbench/contrib/debug/common/debug.ts +++ b/src/vs/workbench/contrib/debug/common/debug.ts @@ -24,7 +24,7 @@ import { IWorkspaceFolder } from 'vs/platform/workspace/common/workspace'; import { IEditorPane } from 'vs/workbench/common/editor'; import { DebugCompoundRoot } from 'vs/workbench/contrib/debug/common/debugCompoundRoot'; import { Source } from 'vs/workbench/contrib/debug/common/debugSource'; -import { TaskIdentifier } from 'vs/workbench/contrib/tasks/common/tasks'; +import { ITaskIdentifier } from 'vs/workbench/contrib/tasks/common/tasks'; import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; export const VIEWLET_ID = 'workbench.view.debug'; @@ -650,10 +650,10 @@ export interface IGlobalConfig { export interface IEnvConfig { internalConsoleOptions?: 'neverOpen' | 'openOnSessionStart' | 'openOnFirstSessionStart'; - preRestartTask?: string | TaskIdentifier; - postRestartTask?: string | TaskIdentifier; - preLaunchTask?: string | TaskIdentifier; - postDebugTask?: string | TaskIdentifier; + preRestartTask?: string | ITaskIdentifier; + postRestartTask?: string | ITaskIdentifier; + preLaunchTask?: string | ITaskIdentifier; + postDebugTask?: string | ITaskIdentifier; debugServer?: number; noDebug?: boolean; } @@ -687,7 +687,7 @@ export interface IConfig extends IEnvConfig { export interface ICompound { name: string; stopAll?: boolean; - preLaunchTask?: string | TaskIdentifier; + preLaunchTask?: string | ITaskIdentifier; configurations: (string | { name: string; folder: string })[]; presentation?: IConfigPresentation; } diff --git a/src/vs/workbench/contrib/tasks/browser/abstractTaskService.ts b/src/vs/workbench/contrib/tasks/browser/abstractTaskService.ts index 42f69229199..64a03a0b4ef 100644 --- a/src/vs/workbench/contrib/tasks/browser/abstractTaskService.ts +++ b/src/vs/workbench/contrib/tasks/browser/abstractTaskService.ts @@ -26,7 +26,7 @@ import { IConfigurationService, ConfigurationTarget } from 'vs/platform/configur import { IFileService, IFileStatWithPartialMetadata } from 'vs/platform/files/common/files'; import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions'; import { CommandsRegistry, ICommandService } from 'vs/platform/commands/common/commands'; -import { ProblemMatcherRegistry, NamedProblemMatcher } from 'vs/workbench/contrib/tasks/common/problemMatcher'; +import { ProblemMatcherRegistry, INamedProblemMatcher } from 'vs/workbench/contrib/tasks/common/problemMatcher'; import { IStorageService, StorageScope, StorageTarget } from 'vs/platform/storage/common/storage'; import { IProgressService, IProgressOptions, ProgressLocation } from 'vs/platform/progress/common/progress'; @@ -47,15 +47,15 @@ import { IOutputService, IOutputChannel } from 'vs/workbench/services/output/com import { ITerminalGroupService, ITerminalService } from 'vs/workbench/contrib/terminal/browser/terminal'; import { ITerminalProfileResolverService } from 'vs/workbench/contrib/terminal/common/terminal'; -import { ITaskSystem, ITaskResolver, ITaskSummary, TaskExecuteKind, TaskError, TaskErrors, TaskTerminateResponse, TaskSystemInfo, ITaskExecuteResult } from 'vs/workbench/contrib/tasks/common/taskSystem'; +import { ITaskSystem, ITaskResolver, ITaskSummary, TaskExecuteKind, TaskError, TaskErrors, ITaskTerminateResponse, ITaskSystemInfo, ITaskExecuteResult } from 'vs/workbench/contrib/tasks/common/taskSystem'; import { - Task, CustomTask, ConfiguringTask, ContributedTask, InMemoryTask, TaskEvent, - TaskSet, TaskGroup, ExecutionEngine, JsonSchemaVersion, TaskSourceKind, - TaskSorter, TaskIdentifier, KeyedTaskIdentifier, TASK_RUNNING_STATE, TaskRunSource, - KeyedTaskIdentifier as NKeyedTaskIdentifier, TaskDefinition, RuntimeType, + Task, CustomTask, ConfiguringTask, ContributedTask, InMemoryTask, ITaskEvent, + ITaskSet, TaskGroup, ExecutionEngine, JsonSchemaVersion, TaskSourceKind, + TaskSorter, ITaskIdentifier, TASK_RUNNING_STATE, TaskRunSource, + KeyedTaskIdentifier as KeyedTaskIdentifier, TaskDefinition, RuntimeType, USER_TASKS_GROUP_KEY } from 'vs/workbench/contrib/tasks/common/tasks'; -import { ITaskService, ITaskProvider, ProblemMatcherRunOptions, CustomizationProperties, TaskFilter, WorkspaceFolderTaskResult, CustomExecutionSupportedContext, ShellExecutionSupportedContext, ProcessExecutionSupportedContext } from 'vs/workbench/contrib/tasks/common/taskService'; +import { ITaskService, ITaskProvider, IProblemMatcherRunOptions, ICustomizationProperties, ITaskFilter, IWorkspaceFolderTaskResult, CustomExecutionSupportedContext, ShellExecutionSupportedContext, ProcessExecutionSupportedContext } from 'vs/workbench/contrib/tasks/common/taskService'; import { getTemplates as getTaskTemplates } from 'vs/workbench/contrib/tasks/common/taskTemplates'; import * as TaskConfig from '../common/taskConfiguration'; @@ -76,7 +76,7 @@ import { ITextEditorSelection, TextEditorSelectionRevealType } from 'vs/platform import { IPreferencesService } from 'vs/workbench/services/preferences/common/preferences'; import { CancellationToken, CancellationTokenSource } from 'vs/base/common/cancellation'; import { IViewsService, IViewDescriptorService } from 'vs/workbench/common/views'; -import { isWorkspaceFolder, TaskQuickPickEntry, QUICKOPEN_DETAIL_CONFIG, TaskQuickPick, QUICKOPEN_SKIP_CONFIG, configureTaskIcon } from 'vs/workbench/contrib/tasks/browser/taskQuickPick'; +import { isWorkspaceFolder, ITaskQuickPickEntry, QUICKOPEN_DETAIL_CONFIG, TaskQuickPick, QUICKOPEN_SKIP_CONFIG, configureTaskIcon } from 'vs/workbench/contrib/tasks/browser/taskQuickPick'; import { ILogService } from 'vs/platform/log/common/log'; import { once } from 'vs/base/common/functional'; import { ThemeIcon } from 'vs/platform/theme/common/themeService'; @@ -129,13 +129,13 @@ class ProblemReporter implements TaskConfig.IProblemReporter { } } -export interface WorkspaceFolderConfigurationResult { +export interface IWorkspaceFolderConfigurationResult { workspaceFolder: IWorkspaceFolder; - config: TaskConfig.ExternalTaskRunnerConfiguration | undefined; + config: TaskConfig.IExternalTaskRunnerConfiguration | undefined; hasErrors: boolean; } -interface CommandUpgrade { +interface ICommandUpgrade { command?: string; args?: string[]; } @@ -206,9 +206,9 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer private _showIgnoreMessage?: boolean; private _providers: Map; private _providerTypes: Map; - protected _taskSystemInfos: Map; + protected _taskSystemInfos: Map; - protected _workspaceTasksPromise?: Promise>; + protected _workspaceTasksPromise?: Promise>; protected _taskSystem?: ITaskSystem; protected _taskSystemListener?: IDisposable; @@ -218,7 +218,7 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer protected _taskRunningState: IContextKey; protected _outputChannel: IOutputChannel; - protected readonly _onDidStateChange: Emitter; + protected readonly _onDidStateChange: Emitter; private _waitForSupportedExecutions: Promise; private _onDidRegisterSupportedExecutions: Emitter = new Emitter(); private _onDidChangeTaskSystemInfo: Emitter = new Emitter(); @@ -266,7 +266,7 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer this._outputChannel = this.outputService.getChannel(AbstractTaskService.OutputChannelId)!; this._providers = new Map(); this._providerTypes = new Map(); - this._taskSystemInfos = new Map(); + this._taskSystemInfos = new Map(); this._register(this.contextService.onDidChangeWorkspaceFolders(() => { let folderSetup = this.computeWorkspaceFolderSetup(); if (this.executionEngine !== folderSetup[2]) { @@ -301,7 +301,7 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer } } - let entry: TaskQuickPickEntry | null | undefined; + let entry: ITaskQuickPickEntry | null | undefined; if (tasks && tasks.length > 0) { entry = await this.showQuickPick(tasks, nls.localize('TaskService.pickBuildTaskForLabel', 'Select the build task (there is no default build task defined)')); } @@ -336,7 +336,7 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer this._onDidRegisterSupportedExecutions.fire(); } - public get onDidStateChange(): Event { + public get onDidStateChange(): Event { return this._onDidStateChange.event; } @@ -577,7 +577,7 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer return infosCount > 0; } - public registerTaskSystem(key: string, info: TaskSystemInfo): void { + public registerTaskSystem(key: string, info: ITaskSystemInfo): void { // Ideally the Web caller of registerRegisterTaskSystem would use the correct key. // However, the caller doesn't know about the workspace folders at the time of the call, even though we know about them here. if (info.platform === Platform.Platform.Web) { @@ -600,7 +600,7 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer } } - private getTaskSystemInfo(key: string): TaskSystemInfo | undefined { + private getTaskSystemInfo(key: string): ITaskSystemInfo | undefined { const infos = this._taskSystemInfos.get(key); return (infos && infos.length) ? infos[0] : undefined; } @@ -650,7 +650,7 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer }); } - public async getTask(folder: IWorkspace | IWorkspaceFolder | string, identifier: string | TaskIdentifier, compareId: boolean = false): Promise { + public async getTask(folder: IWorkspace | IWorkspaceFolder | string, identifier: string | ITaskIdentifier, compareId: boolean = false): Promise { if (!(await this.trust())) { return; } @@ -750,9 +750,9 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer return; } - protected abstract versionAndEngineCompatible(filter?: TaskFilter): boolean; + protected abstract versionAndEngineCompatible(filter?: ITaskFilter): boolean; - public async tasks(filter?: TaskFilter): Promise { + public async tasks(filter?: ITaskFilter): Promise { if (!(await this.trust())) { return []; } @@ -1056,7 +1056,7 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer }); } - public async run(task: Task | undefined, options?: ProblemMatcherRunOptions, runSource: TaskRunSource = TaskRunSource.System): Promise { + public async run(task: Task | undefined, options?: IProblemMatcherRunOptions, runSource: TaskRunSource = TaskRunSource.System): Promise { if (!(await this.trust())) { return; } @@ -1111,7 +1111,7 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer private getTypeForTask(task: Task): string { let type: string; if (CustomTask.is(task)) { - let configProperties: TaskConfig.ConfigurationProperties = task._source.config.element; + let configProperties: TaskConfig.IConfigurationProperties = task._source.config.element; type = (configProperties).type; } else { type = task.getDefinition()!.type; @@ -1137,7 +1137,7 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer return !task.hasDefinedMatchers && !!task.configurationProperties.problemMatchers && (task.configurationProperties.problemMatchers.length === 0); } if (CustomTask.is(task)) { - let configProperties: TaskConfig.ConfigurationProperties = task._source.config.element; + let configProperties: TaskConfig.IConfigurationProperties = task._source.config.element; return configProperties.problemMatcher === undefined && !task.hasDefinedMatchers; } return false; @@ -1159,13 +1159,13 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer } private attachProblemMatcher(task: ContributedTask | CustomTask): Promise { - interface ProblemMatcherPickEntry extends IQuickPickItem { - matcher: NamedProblemMatcher | undefined; + interface IProblemMatcherPickEntry extends IQuickPickItem { + matcher: INamedProblemMatcher | undefined; never?: boolean; learnMore?: boolean; setting?: string; } - let entries: QuickPickInput[] = []; + let entries: QuickPickInput[] = []; for (let key of ProblemMatcherRegistry.keys()) { let matcher = ProblemMatcherRegistry.get(key); if (matcher.deprecated) { @@ -1192,7 +1192,7 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer entries.unshift({ type: 'separator', label: nls.localize('TaskService.associate', 'associate') }); let taskType: string; if (CustomTask.is(task)) { - let configProperties: TaskConfig.ConfigurationProperties = task._source.config.element; + let configProperties: TaskConfig.IConfigurationProperties = task._source.config.element; taskType = (configProperties).type; } else { taskType = task.getDefinition().type; @@ -1216,7 +1216,7 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer } else if (selected.matcher) { let newTask = task.clone(); let matcherReference = `$${selected.matcher.name}`; - let properties: CustomizationProperties = { problemMatcher: [matcherReference] }; + let properties: ICustomizationProperties = { problemMatcher: [matcherReference] }; newTask.configurationProperties.problemMatchers = [matcherReference]; let matcher = ProblemMatcherRegistry.get(selected.matcher.name); if (matcher && matcher.watching !== undefined) { @@ -1271,7 +1271,7 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer return false; } - private async formatTaskForJson(resource: URI, task: TaskConfig.CustomTask | TaskConfig.ConfiguringTask): Promise { + private async formatTaskForJson(resource: URI, task: TaskConfig.ICustomTask | TaskConfig.IConfiguringTask): Promise { let reference: IReference | undefined; let stringValue: string = ''; try { @@ -1292,7 +1292,7 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer return stringValue; } - private openEditorAtTask(resource: URI | undefined, task: TaskConfig.CustomTask | TaskConfig.ConfiguringTask | string | undefined, configIndex: number = -1): Promise { + private openEditorAtTask(resource: URI | undefined, task: TaskConfig.ICustomTask | TaskConfig.IConfiguringTask | string | undefined, configIndex: number = -1): Promise { if (resource === undefined) { return Promise.resolve(false); } @@ -1305,7 +1305,7 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer const contentValue = content.toString(); let stringValue: string | undefined; if (configIndex !== -1) { - const json: TaskConfig.ExternalTaskRunnerConfiguration = this.configurationService.getValue('tasks', { resource }); + const json: TaskConfig.IExternalTaskRunnerConfiguration = this.configurationService.getValue('tasks', { resource }); if (json.tasks && (json.tasks.length > configIndex)) { stringValue = await this.formatTaskForJson(resource, json.tasks[configIndex]); } @@ -1346,15 +1346,15 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer }); } - private createCustomizableTask(task: ContributedTask | CustomTask | ConfiguringTask): TaskConfig.CustomTask | TaskConfig.ConfiguringTask | undefined { - let toCustomize: TaskConfig.CustomTask | TaskConfig.ConfiguringTask | undefined; + private createCustomizableTask(task: ContributedTask | CustomTask | ConfiguringTask): TaskConfig.ICustomTask | TaskConfig.IConfiguringTask | undefined { + let toCustomize: TaskConfig.ICustomTask | TaskConfig.IConfiguringTask | undefined; let taskConfig = CustomTask.is(task) || ConfiguringTask.is(task) ? task._source.config : undefined; if (taskConfig && taskConfig.element) { toCustomize = { ...(taskConfig.element) }; } else if (ContributedTask.is(task)) { toCustomize = { }; - let identifier: TaskConfig.TaskIdentifier = Object.assign(Object.create(null), task.defines); + let identifier: TaskConfig.ITaskIdentifier = Object.assign(Object.create(null), task.defines); delete identifier['_key']; Object.keys(identifier).forEach(key => (toCustomize)![key] = identifier[key]); if (task.configurationProperties.problemMatchers && task.configurationProperties.problemMatchers.length > 0 && Types.isStringArray(task.configurationProperties.problemMatchers)) { @@ -1379,7 +1379,7 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer return toCustomize; } - public async customize(task: ContributedTask | CustomTask | ConfiguringTask, properties?: CustomizationProperties, openConfig?: boolean): Promise { + public async customize(task: ContributedTask | CustomTask | ConfiguringTask, properties?: ICustomizationProperties, openConfig?: boolean): Promise { if (!(await this.trust())) { return; } @@ -1519,13 +1519,13 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer } private createRunnableTask(tasks: TaskMap, group: TaskGroup): { task: Task; resolver: ITaskResolver } | undefined { - interface ResolverData { + interface IResolverData { id: Map; label: Map; identifier: Map; } - let resolverData: Map = new Map(); + let resolverData: Map = new Map(); let workspaceTasks: Task[] = []; let extensionTasks: Task[] = []; tasks.forEach((tasks, folder) => { @@ -1603,7 +1603,7 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer let resolverData: Map | undefined; - async function quickResolve(that: AbstractTaskService, uri: URI | string, identifier: string | TaskIdentifier) { + async function quickResolve(that: AbstractTaskService, uri: URI | string, identifier: string | ITaskIdentifier) { const foundTasks = await that._findWorkspaceTasks((task: Task | ConfiguringTask): boolean => { const taskUri = ((ConfiguringTask.is(task) || CustomTask.is(task)) ? task._source.config.workspaceFolder?.uri : undefined); const originalUri = (typeof uri === 'string' ? uri : uri.toString()); @@ -1652,7 +1652,7 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer return resolverData; } - async function fullResolve(that: AbstractTaskService, uri: URI | string, identifier: string | TaskIdentifier) { + async function fullResolve(that: AbstractTaskService, uri: URI | string, identifier: string | ITaskIdentifier) { const allResolverData = await getResolverData(that); let data = allResolverData.get(typeof uri === 'string' ? uri : uri.toString()); if (!data) { @@ -1667,7 +1667,7 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer } return { - resolve: async (uri: URI | string, identifier: string | TaskIdentifier | undefined) => { + resolve: async (uri: URI | string, identifier: string | ITaskIdentifier | undefined) => { if (!identifier) { return undefined; } @@ -1775,7 +1775,7 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer }); } - public async terminate(task: Task): Promise { + public async terminate(task: Task): Promise { if (!(await this.trust())) { return { success: true, task: undefined }; } @@ -1786,9 +1786,9 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer return this._taskSystem.terminate(task); } - private terminateAll(): Promise { + private terminateAll(): Promise { if (!this._taskSystem) { - return Promise.resolve([]); + return Promise.resolve([]); } return this._taskSystem.terminateAll(); } @@ -1832,10 +1832,10 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer TaskDefinitionRegistry.all().forEach(definition => validTypes[definition.taskType] = true); validTypes['shell'] = true; validTypes['process'] = true; - return new Promise(resolve => { - let result: TaskSet[] = []; + return new Promise(resolve => { + let result: ITaskSet[] = []; let counter: number = 0; - let done = (value: TaskSet | undefined) => { + let done = (value: ITaskSet | undefined) => { if (value) { result.push(value); } @@ -1870,7 +1870,7 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer } foundAnyProviders = true; counter++; - provider.provideTasks(validTypes).then((taskSet: TaskSet) => { + provider.provideTasks(validTypes).then((taskSet: ITaskSet) => { // Check that the tasks provided are of the correct type for (const task of taskSet.tasks) { if (task.type !== this._providerTypes.get(handle)) { @@ -2043,7 +2043,7 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer }); } - private getLegacyTaskConfigurations(workspaceTasks: TaskSet): IStringDictionary | undefined { + private getLegacyTaskConfigurations(workspaceTasks: ITaskSet): IStringDictionary | undefined { let result: IStringDictionary | undefined; function getResult(): IStringDictionary { if (result) { @@ -2058,7 +2058,7 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer // This is for backwards compatibility with the 0.1.0 task annotation code // if we had a gulp, jake or grunt command a task specification was a annotation if (commandName === 'gulp' || commandName === 'grunt' || commandName === 'jake') { - let identifier = NKeyedTaskIdentifier.create({ + let identifier = KeyedTaskIdentifier.create({ type: commandName, task: task.configurationProperties.name }); @@ -2069,7 +2069,7 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer return result; } - public async getWorkspaceTasks(runSource: TaskRunSource = TaskRunSource.User): Promise> { + public async getWorkspaceTasks(runSource: TaskRunSource = TaskRunSource.User): Promise> { if (!(await this.trust())) { return new Map(); } @@ -2080,7 +2080,7 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer return this.updateWorkspaceTasks(runSource); } - private updateWorkspaceTasks(runSource: TaskRunSource = TaskRunSource.User): Promise> { + private updateWorkspaceTasks(runSource: TaskRunSource = TaskRunSource.User): Promise> { this._workspaceTasksPromise = this.computeWorkspaceTasks(runSource); return this._workspaceTasksPromise; } @@ -2094,13 +2094,13 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer return folder; } - protected computeWorkspaceTasks(runSource: TaskRunSource = TaskRunSource.User): Promise> { - let promises: Promise[] = []; + protected computeWorkspaceTasks(runSource: TaskRunSource = TaskRunSource.User): Promise> { + let promises: Promise[] = []; for (let folder of this.workspaceFolders) { promises.push(this.computeWorkspaceFolderTasks(folder, runSource).then((value) => value, () => undefined)); } return Promise.all(promises).then(async (values) => { - let result = new Map(); + let result = new Map(); for (let value of values) { if (value) { result.set(value.workspaceFolder.uri.toString(), value); @@ -2127,7 +2127,7 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer return !!ShellExecutionSupportedContext.getValue(this.contextKeyService) && !!ProcessExecutionSupportedContext.getValue(this.contextKeyService); } - private computeWorkspaceFolderTasks(workspaceFolder: IWorkspaceFolder, runSource: TaskRunSource = TaskRunSource.User): Promise { + private computeWorkspaceFolderTasks(workspaceFolder: IWorkspaceFolder, runSource: TaskRunSource = TaskRunSource.User): Promise { return (this.executionEngine === ExecutionEngine.Process ? this.computeLegacyConfiguration(workspaceFolder) : this.computeConfiguration(workspaceFolder)). @@ -2135,8 +2135,8 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer if (!workspaceFolderConfiguration || !workspaceFolderConfiguration.config || workspaceFolderConfiguration.hasErrors) { return Promise.resolve({ workspaceFolder, set: undefined, configurations: undefined, hasErrors: workspaceFolderConfiguration ? workspaceFolderConfiguration.hasErrors : false }); } - return ProblemMatcherRegistry.onReady().then(async (): Promise => { - let taskSystemInfo: TaskSystemInfo | undefined = this.getTaskSystemInfo(workspaceFolder.uri.scheme); + return ProblemMatcherRegistry.onReady().then(async (): Promise => { + let taskSystemInfo: ITaskSystemInfo | undefined = this.getTaskSystemInfo(workspaceFolder.uri.scheme); let problemReporter = new ProblemReporter(this._outputChannel); let parseResult = TaskConfig.parse(workspaceFolder, undefined, taskSystemInfo ? taskSystemInfo.platform : Platform.platform, workspaceFolderConfiguration.config!, problemReporter, TaskConfig.TaskConfigSource.TasksJson, this.contextKeyService); let hasErrors = false; @@ -2165,7 +2165,7 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer }); } - private testParseExternalConfig(config: TaskConfig.ExternalTaskRunnerConfiguration | undefined, location: string): { config: TaskConfig.ExternalTaskRunnerConfiguration | undefined; hasParseErrors: boolean } { + private testParseExternalConfig(config: TaskConfig.IExternalTaskRunnerConfiguration | undefined, location: string): { config: TaskConfig.IExternalTaskRunnerConfiguration | undefined; hasParseErrors: boolean } { if (!config) { return { config: undefined, hasParseErrors: false }; } @@ -2187,7 +2187,7 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer return { config, hasParseErrors: false }; } - private async computeWorkspaceFileTasks(workspaceFolder: IWorkspaceFolder, runSource: TaskRunSource = TaskRunSource.User): Promise { + private async computeWorkspaceFileTasks(workspaceFolder: IWorkspaceFolder, runSource: TaskRunSource = TaskRunSource.User): Promise { if (this.executionEngine === ExecutionEngine.Process) { return this.emptyWorkspaceTaskResults(workspaceFolder); } @@ -2207,7 +2207,7 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer return { workspaceFolder, set: { tasks: custom }, configurations: customizedTasks, hasErrors: configuration.hasParseErrors }; } - private async computeUserTasks(workspaceFolder: IWorkspaceFolder, runSource: TaskRunSource = TaskRunSource.User): Promise { + private async computeUserTasks(workspaceFolder: IWorkspaceFolder, runSource: TaskRunSource = TaskRunSource.User): Promise { if (this.executionEngine === ExecutionEngine.Process) { return this.emptyWorkspaceTaskResults(workspaceFolder); } @@ -2227,15 +2227,15 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer return { workspaceFolder, set: { tasks: custom }, configurations: customizedTasks, hasErrors: configuration.hasParseErrors }; } - private emptyWorkspaceTaskResults(workspaceFolder: IWorkspaceFolder): WorkspaceFolderTaskResult { + private emptyWorkspaceTaskResults(workspaceFolder: IWorkspaceFolder): IWorkspaceFolderTaskResult { return { workspaceFolder, set: undefined, configurations: undefined, hasErrors: false }; } - private async computeTasksForSingleConfig(workspaceFolder: IWorkspaceFolder, config: TaskConfig.ExternalTaskRunnerConfiguration | undefined, runSource: TaskRunSource, custom: CustomTask[], customized: IStringDictionary, source: TaskConfig.TaskConfigSource, isRecentTask: boolean = false): Promise { + private async computeTasksForSingleConfig(workspaceFolder: IWorkspaceFolder, config: TaskConfig.IExternalTaskRunnerConfiguration | undefined, runSource: TaskRunSource, custom: CustomTask[], customized: IStringDictionary, source: TaskConfig.TaskConfigSource, isRecentTask: boolean = false): Promise { if (!config) { return false; } - let taskSystemInfo: TaskSystemInfo | undefined = workspaceFolder ? this.getTaskSystemInfo(workspaceFolder.uri.scheme) : undefined; + let taskSystemInfo: ITaskSystemInfo | undefined = workspaceFolder ? this.getTaskSystemInfo(workspaceFolder.uri.scheme) : undefined; let problemReporter = new ProblemReporter(this._outputChannel); let parseResult = TaskConfig.parse(workspaceFolder, this._workspace, taskSystemInfo ? taskSystemInfo.platform : Platform.platform, config, problemReporter, source, this.contextKeyService, isRecentTask); let hasErrors = false; @@ -2262,12 +2262,12 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer return hasErrors; } - private computeConfiguration(workspaceFolder: IWorkspaceFolder): Promise { + private computeConfiguration(workspaceFolder: IWorkspaceFolder): Promise { let { config, hasParseErrors } = this.getConfiguration(workspaceFolder); - return Promise.resolve({ workspaceFolder, config, hasErrors: hasParseErrors }); + return Promise.resolve({ workspaceFolder, config, hasErrors: hasParseErrors }); } - protected abstract computeLegacyConfiguration(workspaceFolder: IWorkspaceFolder): Promise; + protected abstract computeLegacyConfiguration(workspaceFolder: IWorkspaceFolder): Promise; private computeWorkspaceFolderSetup(): [IWorkspaceFolder[], IWorkspaceFolder[], ExecutionEngine, JsonSchemaVersion, IWorkspace | undefined] { let workspaceFolders: IWorkspaceFolder[] = []; @@ -2324,12 +2324,12 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer return TaskConfig.JsonSchemaVersion.from(config); } - protected getConfiguration(workspaceFolder: IWorkspaceFolder, source?: string): { config: TaskConfig.ExternalTaskRunnerConfiguration | undefined; hasParseErrors: boolean } { + protected getConfiguration(workspaceFolder: IWorkspaceFolder, source?: string): { config: TaskConfig.IExternalTaskRunnerConfiguration | undefined; hasParseErrors: boolean } { let result; if ((source !== TaskSourceKind.User) && (this.contextService.getWorkbenchState() === WorkbenchState.EMPTY)) { result = undefined; } else { - const wholeConfig = this.configurationService.inspect('tasks', { resource: workspaceFolder.uri }); + const wholeConfig = this.configurationService.inspect('tasks', { resource: workspaceFolder.uri }); switch (source) { case TaskSourceKind.User: { if (wholeConfig.userValue !== wholeConfig.workspaceFolderValue) { @@ -2427,12 +2427,12 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer return this.configurationService.getValue(QUICKOPEN_DETAIL_CONFIG); } - private async createTaskQuickPickEntries(tasks: Task[], group: boolean = false, sort: boolean = false, selectedEntry?: TaskQuickPickEntry, includeRecents: boolean = true): Promise { - let encounteredTasks: { [key: string]: TaskQuickPickEntry[] } = {}; + private async createTaskQuickPickEntries(tasks: Task[], group: boolean = false, sort: boolean = false, selectedEntry?: ITaskQuickPickEntry, includeRecents: boolean = true): Promise { + let encounteredTasks: { [key: string]: ITaskQuickPickEntry[] } = {}; if (tasks === undefined || tasks === null || tasks.length === 0) { return []; } - const TaskQuickPickEntry = (task: Task): TaskQuickPickEntry => { + const TaskQuickPickEntry = (task: Task): ITaskQuickPickEntry => { const newEntry = { label: task._label, description: this.getTaskDescription(task), task, detail: this.showDetail() ? task.configurationProperties.detail : undefined }; if (encounteredTasks[task._id]) { if (encounteredTasks[task._id].length === 1) { @@ -2446,12 +2446,12 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer return newEntry; }; - function fillEntries(entries: QuickPickInput[], tasks: Task[], groupLabel: string): void { + function fillEntries(entries: QuickPickInput[], tasks: Task[], groupLabel: string): void { if (tasks.length) { entries.push({ type: 'separator', label: groupLabel }); } for (let task of tasks) { - let entry: TaskQuickPickEntry = TaskQuickPickEntry(task); + let entry: ITaskQuickPickEntry = TaskQuickPickEntry(task); entry.buttons = [{ iconClass: ThemeIcon.asClassName(configureTaskIcon), tooltip: nls.localize('configureTask', "Configure Task") }]; if (selectedEntry && (task === selectedEntry.task)) { entries.unshift(selectedEntry); @@ -2460,7 +2460,7 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer } } } - let entries: TaskQuickPickEntry[]; + let entries: ITaskQuickPickEntry[]; if (group) { entries = []; if (tasks.length === 1) { @@ -2512,20 +2512,20 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer const sorter = this.createSorter(); tasks = tasks.sort((a, b) => sorter.compare(a, b)); } - entries = tasks.map(task => TaskQuickPickEntry(task)); + entries = tasks.map(task => TaskQuickPickEntry(task)); } encounteredTasks = {}; return entries; } - private async showTwoLevelQuickPick(placeHolder: string, defaultEntry?: TaskQuickPickEntry) { + private async showTwoLevelQuickPick(placeHolder: string, defaultEntry?: ITaskQuickPickEntry) { return TaskQuickPick.show(this, this.configurationService, this.quickInputService, this.notificationService, this.dialogService, placeHolder, defaultEntry); } - private async showQuickPick(tasks: Promise | Task[], placeHolder: string, defaultEntry?: TaskQuickPickEntry, group: boolean = false, sort: boolean = false, selectedEntry?: TaskQuickPickEntry, additionalEntries?: TaskQuickPickEntry[]): Promise { + private async showQuickPick(tasks: Promise | Task[], placeHolder: string, defaultEntry?: ITaskQuickPickEntry, group: boolean = false, sort: boolean = false, selectedEntry?: ITaskQuickPickEntry, additionalEntries?: ITaskQuickPickEntry[]): Promise { const tokenSource = new CancellationTokenSource(); const cancellationToken: CancellationToken = tokenSource.token; - let _createEntries = new Promise[]>((resolve) => { + let _createEntries = new Promise[]>((resolve) => { if (Array.isArray(tasks)) { resolve(this.createTaskQuickPickEntries(tasks, group, sort, selectedEntry)); } else { @@ -2543,7 +2543,7 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer })]); if (!timeout && ((await _createEntries).length === 1) && this.configurationService.getValue(QUICKOPEN_SKIP_CONFIG)) { - return ((await _createEntries)[0]); + return ((await _createEntries)[0]); } const pickEntries = _createEntries.then((entries) => { @@ -2558,7 +2558,7 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer return entries; }); - const picker: IQuickPick = this.quickInputService.createQuickPick(); + const picker: IQuickPick = this.quickInputService.createQuickPick(); picker.placeholder = placeHolder; picker.matchOnDescription = true; @@ -2578,14 +2578,14 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer }); picker.show(); - return new Promise(resolve => { + return new Promise(resolve => { this._register(picker.onDidAccept(async () => { let selection = picker.selectedItems ? picker.selectedItems[0] : undefined; if (cancellationToken.isCancellationRequested) { // canceled when there's only one task const task = (await pickEntries)[0]; if ((task).task) { - selection = task; + selection = task; } } picker.dispose(); @@ -2682,7 +2682,7 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer } } - private tasksAndGroupedTasks(filter?: TaskFilter): { tasks: Promise; grouped: Promise } { + private tasksAndGroupedTasks(filter?: ITaskFilter): { tasks: Promise; grouped: Promise } { if (!this.versionAndEngineCompatible(filter)) { return { tasks: Promise.resolve([]), grouped: Promise.resolve(new TaskMap()) }; } @@ -2816,7 +2816,7 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer let taskGroupTasks: (Task | ConfiguringTask)[] = []; - async function runSingleTask(task: Task | undefined, problemMatcherOptions: ProblemMatcherRunOptions | undefined, that: AbstractTaskService) { + async function runSingleTask(task: Task | undefined, problemMatcherOptions: IProblemMatcherRunOptions | undefined, that: AbstractTaskService) { that.run(task, problemMatcherOptions, TaskRunSource.User).then(undefined, reason => { // eat the error, it has already been surfaced to the user and we don't care about it here }); @@ -3056,13 +3056,13 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer let result: string | KeyedTaskIdentifier | undefined = undefined; if (Types.isString(arg)) { result = arg; - } else if (arg && Types.isString((arg as TaskIdentifier).type)) { - result = TaskDefinition.createTaskIdentifier(arg as TaskIdentifier, console); + } else if (arg && Types.isString((arg as ITaskIdentifier).type)) { + result = TaskDefinition.createTaskIdentifier(arg as ITaskIdentifier, console); } return result; } - private configHasTasks(taskConfig?: TaskConfig.ExternalTaskRunnerConfiguration): boolean { + private configHasTasks(taskConfig?: TaskConfig.IExternalTaskRunnerConfiguration): boolean { return !!taskConfig && !!taskConfig.tasks && taskConfig.tasks.length > 0; } @@ -3070,7 +3070,7 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer let configFileCreated = false; this.fileService.stat(resource).then((stat) => stat, () => undefined).then(async (stat) => { const fileExists: boolean = !!stat; - const configValue = this.configurationService.inspect('tasks'); + const configValue = this.configurationService.inspect('tasks'); let tasksExistInFile: boolean; let target: ConfigurationTarget; switch (taskSource) { @@ -3270,7 +3270,7 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer return; } let selectedTask: Task | undefined; - let selectedEntry: TaskQuickPickEntry; + let selectedEntry: ITaskQuickPickEntry; for (let task of tasks) { let taskGroup: TaskGroup | undefined = TaskGroup.from(task.configurationProperties.group); if (taskGroup && taskGroup.isDefault && taskGroup._id === TaskGroup.Build._id) { @@ -3322,7 +3322,7 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer return; } let selectedTask: Task | undefined; - let selectedEntry: TaskQuickPickEntry; + let selectedEntry: ITaskQuickPickEntry; for (let task of tasks) { let taskGroup: TaskGroup | undefined = TaskGroup.from(task.configurationProperties.group); @@ -3412,7 +3412,7 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer return undefined; } - private upgradeTask(task: Task, suppressTaskName: boolean, globalConfig: { windows?: CommandUpgrade; osx?: CommandUpgrade; linux?: CommandUpgrade }): TaskConfig.CustomTask | TaskConfig.ConfiguringTask | undefined { + private upgradeTask(task: Task, suppressTaskName: boolean, globalConfig: { windows?: ICommandUpgrade; osx?: ICommandUpgrade; linux?: ICommandUpgrade }): TaskConfig.ICustomTask | TaskConfig.IConfiguringTask | undefined { if (!CustomTask.is(task)) { return; } @@ -3488,12 +3488,12 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer continue; } - const configTasks: (TaskConfig.CustomTask | TaskConfig.ConfiguringTask)[] = []; + const configTasks: (TaskConfig.ICustomTask | TaskConfig.IConfiguringTask)[] = []; const suppressTaskName = !!this.configurationService.getValue('tasks.suppressTaskName', { resource: folder.uri }); const globalConfig = { - windows: this.configurationService.getValue('tasks.windows', { resource: folder.uri }), - osx: this.configurationService.getValue('tasks.osx', { resource: folder.uri }), - linux: this.configurationService.getValue('tasks.linux', { resource: folder.uri }) + windows: this.configurationService.getValue('tasks.windows', { resource: folder.uri }), + osx: this.configurationService.getValue('tasks.osx', { resource: folder.uri }), + linux: this.configurationService.getValue('tasks.linux', { resource: folder.uri }) }; tasks.get(folder).forEach(task => { const configTask = this.upgradeTask(task, suppressTaskName, globalConfig); diff --git a/src/vs/workbench/contrib/tasks/browser/runAutomaticTasks.ts b/src/vs/workbench/contrib/tasks/browser/runAutomaticTasks.ts index 270dafb67c2..74deb605b11 100644 --- a/src/vs/workbench/contrib/tasks/browser/runAutomaticTasks.ts +++ b/src/vs/workbench/contrib/tasks/browser/runAutomaticTasks.ts @@ -7,9 +7,9 @@ import * as nls from 'vs/nls'; import * as resources from 'vs/base/common/resources'; import { Disposable } from 'vs/base/common/lifecycle'; import { IWorkbenchContribution } from 'vs/workbench/common/contributions'; -import { ITaskService, WorkspaceFolderTaskResult } from 'vs/workbench/contrib/tasks/common/taskService'; +import { ITaskService, IWorkspaceFolderTaskResult } from 'vs/workbench/contrib/tasks/common/taskService'; import { forEach } from 'vs/base/common/collections'; -import { RunOnOptions, Task, TaskRunSource, TaskSource, TaskSourceKind, TASKS_CATEGORY, WorkspaceFileTaskSource, WorkspaceTaskSource } from 'vs/workbench/contrib/tasks/common/tasks'; +import { RunOnOptions, Task, TaskRunSource, TaskSource, TaskSourceKind, TASKS_CATEGORY, WorkspaceFileTaskSource, IWorkspaceTaskSource } from 'vs/workbench/contrib/tasks/common/tasks'; import { IStorageService, StorageScope, StorageTarget } from 'vs/platform/storage/common/storage'; import { INotificationService, Severity } from 'vs/platform/notification/common/notification'; import { IQuickPickItem, IQuickInputService } from 'vs/platform/quickinput/common/quickInput'; @@ -77,7 +77,7 @@ export class RunAutomaticTasks extends Disposable implements IWorkbenchContribut const taskKind = TaskSourceKind.toConfigurationTarget(source.kind); switch (taskKind) { case ConfigurationTarget.WORKSPACE_FOLDER: { - return resources.joinPath((source).config.workspaceFolder!.uri, (source).config.file); + return resources.joinPath((source).config.workspaceFolder!.uri, (source).config.file); } case ConfigurationTarget.WORKSPACE: { return (source).config.workspace?.configuration ?? undefined; @@ -86,7 +86,7 @@ export class RunAutomaticTasks extends Disposable implements IWorkbenchContribut return undefined; } - private static findAutoTasks(taskService: ITaskService, workspaceTaskResult: Map): { tasks: Array>; taskNames: Array; locations: Map } { + private static findAutoTasks(taskService: ITaskService, workspaceTaskResult: Map): { tasks: Array>; taskNames: Array; locations: Map } { const tasks = new Array>(); const taskNames = new Array(); const locations = new Map(); @@ -129,7 +129,7 @@ export class RunAutomaticTasks extends Disposable implements IWorkbenchContribut } public static async promptForPermission(taskService: ITaskService, storageService: IStorageService, notificationService: INotificationService, workspaceTrustManagementService: IWorkspaceTrustManagementService, - openerService: IOpenerService, workspaceTaskResult: Map) { + openerService: IOpenerService, workspaceTaskResult: Map) { const isWorkspaceTrusted = workspaceTrustManagementService.isWorkspaceTrusted; if (!isWorkspaceTrusted) { return; diff --git a/src/vs/workbench/contrib/tasks/browser/task.contribution.ts b/src/vs/workbench/contrib/tasks/browser/task.contribution.ts index e6af1d10e89..4fa5859c889 100644 --- a/src/vs/workbench/contrib/tasks/browser/task.contribution.ts +++ b/src/vs/workbench/contrib/tasks/browser/task.contribution.ts @@ -20,7 +20,7 @@ import { StatusbarAlignment, IStatusbarService, IStatusbarEntryAccessor, IStatus import { IOutputChannelRegistry, Extensions as OutputExt } from 'vs/workbench/services/output/common/output'; -import { TaskEvent, TaskEventKind, TaskGroup, TASKS_CATEGORY, TASK_RUNNING_STATE } from 'vs/workbench/contrib/tasks/common/tasks'; +import { ITaskEvent, TaskEventKind, TaskGroup, TASKS_CATEGORY, TASK_RUNNING_STATE } from 'vs/workbench/contrib/tasks/common/tasks'; import { ITaskService, ProcessExecutionSupportedContext, ShellExecutionSupportedContext } from 'vs/workbench/contrib/tasks/common/taskService'; import { Extensions as WorkbenchExtensions, IWorkbenchContributionsRegistry, IWorkbenchContribution } from 'vs/workbench/common/contributions'; @@ -146,7 +146,7 @@ export class TaskStatusBarContributions extends Disposable implements IWorkbench } } - private ignoreEventForUpdateRunningTasksCount(event: TaskEvent): boolean { + private ignoreEventForUpdateRunningTasksCount(event: ITaskEvent): boolean { if (!this.taskService.inTerminal()) { return false; } diff --git a/src/vs/workbench/contrib/tasks/browser/taskQuickPick.ts b/src/vs/workbench/contrib/tasks/browser/taskQuickPick.ts index c78e28e9d0c..fd9f0ff7a6e 100644 --- a/src/vs/workbench/contrib/tasks/browser/taskQuickPick.ts +++ b/src/vs/workbench/contrib/tasks/browser/taskQuickPick.ts @@ -8,7 +8,7 @@ import * as Objects from 'vs/base/common/objects'; import { Task, ContributedTask, CustomTask, ConfiguringTask, TaskSorter, KeyedTaskIdentifier } from 'vs/workbench/contrib/tasks/common/tasks'; import { IWorkspace, IWorkspaceFolder } from 'vs/platform/workspace/common/workspace'; import * as Types from 'vs/base/common/types'; -import { ITaskService, WorkspaceFolderTaskResult } from 'vs/workbench/contrib/tasks/common/taskService'; +import { ITaskService, IWorkspaceFolderTaskResult } from 'vs/workbench/contrib/tasks/common/taskService'; import { IQuickPickItem, QuickPickInput, IQuickPick, IQuickInputButton } from 'vs/base/parts/quickinput/common/quickInput'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { IQuickInputService } from 'vs/platform/quickinput/common/quickInput'; @@ -27,11 +27,11 @@ export function isWorkspaceFolder(folder: IWorkspace | IWorkspaceFolder): folder return 'uri' in folder; } -export interface TaskQuickPickEntry extends IQuickPickItem { +export interface ITaskQuickPickEntry extends IQuickPickItem { task: Task | undefined | null; } -export interface TaskTwoLevelQuickPickEntry extends IQuickPickItem { +export interface ITaskTwoLevelQuickPickEntry extends IQuickPickItem { task: Task | ConfiguringTask | string | undefined | null; settingType?: string; } @@ -43,7 +43,7 @@ const removeTaskIcon = registerIcon('tasks-remove', Codicon.close, nls.localize( export class TaskQuickPick extends Disposable { private sorter: TaskSorter; - private topLevelEntries: QuickPickInput[] | undefined; + private topLevelEntries: QuickPickInput[] | undefined; constructor( private taskService: ITaskService, private configurationService: IConfigurationService, @@ -74,13 +74,13 @@ export class TaskQuickPick extends Disposable { return ''; } - private createTaskEntry(task: Task | ConfiguringTask, extraButtons: IQuickInputButton[] = []): TaskTwoLevelQuickPickEntry { - const entry: TaskTwoLevelQuickPickEntry = { label: this.guessTaskLabel(task), description: this.taskService.getTaskDescription(task), task, detail: this.showDetail() ? task.configurationProperties.detail : undefined }; + private createTaskEntry(task: Task | ConfiguringTask, extraButtons: IQuickInputButton[] = []): ITaskTwoLevelQuickPickEntry { + const entry: ITaskTwoLevelQuickPickEntry = { label: this.guessTaskLabel(task), description: this.taskService.getTaskDescription(task), task, detail: this.showDetail() ? task.configurationProperties.detail : undefined }; entry.buttons = [{ iconClass: ThemeIcon.asClassName(configureTaskIcon), tooltip: nls.localize('configureTask', "Configure Task") }, ...extraButtons]; return entry; } - private createEntriesForGroup(entries: QuickPickInput[], tasks: (Task | ConfiguringTask)[], + private createEntriesForGroup(entries: QuickPickInput[], tasks: (Task | ConfiguringTask)[], groupLabel: string, extraButtons: IQuickInputButton[] = []) { entries.push({ type: 'separator', label: groupLabel }); tasks.forEach(task => { @@ -88,7 +88,7 @@ export class TaskQuickPick extends Disposable { }); } - private createTypeEntries(entries: QuickPickInput[], types: string[]) { + private createTypeEntries(entries: QuickPickInput[], types: string[]) { entries.push({ type: 'separator', label: nls.localize('contributedTasks', "contributed") }); types.forEach(type => { entries.push({ label: `$(folder) ${type}`, task: type, ariaLabel: nls.localize('taskType', "All {0} tasks", type) }); @@ -96,7 +96,7 @@ export class TaskQuickPick extends Disposable { entries.push({ label: SHOW_ALL, task: SHOW_ALL, alwaysShow: true }); } - private handleFolderTaskResult(result: Map): (Task | ConfiguringTask)[] { + private handleFolderTaskResult(result: Map): (Task | ConfiguringTask)[] { let tasks: (Task | ConfiguringTask)[] = []; Array.from(result).forEach(([key, folderTasks]) => { if (folderTasks.set) { @@ -142,7 +142,7 @@ export class TaskQuickPick extends Disposable { return { configuredTasks: dedupedConfiguredTasks, recentTasks: prunedRecentTasks }; } - public async getTopLevelEntries(defaultEntry?: TaskQuickPickEntry): Promise<{ entries: QuickPickInput[]; isSingleConfigured?: Task | ConfiguringTask }> { + public async getTopLevelEntries(defaultEntry?: ITaskQuickPickEntry): Promise<{ entries: QuickPickInput[]; isSingleConfigured?: Task | ConfiguringTask }> { if (this.topLevelEntries !== undefined) { return { entries: this.topLevelEntries }; } @@ -193,8 +193,8 @@ export class TaskQuickPick extends Disposable { return undefined; } - public async show(placeHolder: string, defaultEntry?: TaskQuickPickEntry, startAtType?: string): Promise { - const picker: IQuickPick = this.quickInputService.createQuickPick(); + public async show(placeHolder: string, defaultEntry?: ITaskQuickPickEntry, startAtType?: string): Promise { + const picker: IQuickPick = this.quickInputService.createQuickPick(); picker.placeholder = placeHolder; picker.matchOnDescription = true; picker.ignoreFocusOut = false; @@ -237,7 +237,7 @@ export class TaskQuickPick extends Disposable { picker.dispose(); return this.toTask(topLevelEntriesResult.isSingleConfigured); } - const taskQuickPickEntries: QuickPickInput[] = topLevelEntriesResult.entries; + const taskQuickPickEntries: QuickPickInput[] = topLevelEntriesResult.entries; firstLevelTask = await this.doPickerFirstLevel(picker, taskQuickPickEntries); } do { @@ -265,9 +265,9 @@ export class TaskQuickPick extends Disposable { return; } - private async doPickerFirstLevel(picker: IQuickPick, taskQuickPickEntries: QuickPickInput[]): Promise { + private async doPickerFirstLevel(picker: IQuickPick, taskQuickPickEntries: QuickPickInput[]): Promise { picker.items = taskQuickPickEntries; - const firstLevelPickerResult = await new Promise(resolve => { + const firstLevelPickerResult = await new Promise(resolve => { Event.once(picker.onDidAccept)(async () => { resolve(picker.selectedItems ? picker.selectedItems[0] : undefined); }); @@ -275,7 +275,7 @@ export class TaskQuickPick extends Disposable { return firstLevelPickerResult?.task; } - private async doPickerSecondLevel(picker: IQuickPick, type: string) { + private async doPickerSecondLevel(picker: IQuickPick, type: string) { picker.busy = true; if (type === SHOW_ALL) { const items = (await this.taskService.tasks()).sort((a, b) => this.sorter.compare(a, b)).map(task => this.createTaskEntry(task)); @@ -286,7 +286,7 @@ export class TaskQuickPick extends Disposable { picker.items = await this.getEntriesForProvider(type); } picker.busy = false; - const secondLevelPickerResult = await new Promise(resolve => { + const secondLevelPickerResult = await new Promise(resolve => { Event.once(picker.onDidAccept)(async () => { resolve(picker.selectedItems ? picker.selectedItems[0] : undefined); }); @@ -295,8 +295,8 @@ export class TaskQuickPick extends Disposable { return secondLevelPickerResult; } - public static allSettingEntries(configurationService: IConfigurationService): (TaskTwoLevelQuickPickEntry & { settingType: string })[] { - const entries: (TaskTwoLevelQuickPickEntry & { settingType: string })[] = []; + public static allSettingEntries(configurationService: IConfigurationService): (ITaskTwoLevelQuickPickEntry & { settingType: string })[] { + const entries: (ITaskTwoLevelQuickPickEntry & { settingType: string })[] = []; const gruntEntry = TaskQuickPick.getSettingEntry(configurationService, 'grunt'); if (gruntEntry) { entries.push(gruntEntry); @@ -312,7 +312,7 @@ export class TaskQuickPick extends Disposable { return entries; } - public static getSettingEntry(configurationService: IConfigurationService, type: string): (TaskTwoLevelQuickPickEntry & { settingType: string }) | undefined { + public static getSettingEntry(configurationService: IConfigurationService, type: string): (ITaskTwoLevelQuickPickEntry & { settingType: string }) | undefined { if (configurationService.getValue(`${type}.autoDetect`) === 'off') { return { label: nls.localize('TaskQuickPick.changeSettingsOptions', "$(gear) {0} task detection is turned off. Enable {1} task detection...", @@ -325,9 +325,9 @@ export class TaskQuickPick extends Disposable { return undefined; } - private async getEntriesForProvider(type: string): Promise[]> { + private async getEntriesForProvider(type: string): Promise[]> { const tasks = (await this.taskService.tasks({ type })).sort((a, b) => this.sorter.compare(a, b)); - let taskQuickPickEntries: QuickPickInput[]; + let taskQuickPickEntries: QuickPickInput[]; if (tasks.length > 0) { taskQuickPickEntries = tasks.map(task => this.createTaskEntry(task)); taskQuickPickEntries.push({ @@ -367,7 +367,7 @@ export class TaskQuickPick extends Disposable { static async show(taskService: ITaskService, configurationService: IConfigurationService, quickInputService: IQuickInputService, notificationService: INotificationService, - dialogService: IDialogService, placeHolder: string, defaultEntry?: TaskQuickPickEntry) { + dialogService: IDialogService, placeHolder: string, defaultEntry?: ITaskQuickPickEntry) { const taskQuickPick = new TaskQuickPick(taskService, configurationService, quickInputService, notificationService, dialogService); return taskQuickPick.show(placeHolder, defaultEntry); } diff --git a/src/vs/workbench/contrib/tasks/browser/taskService.ts b/src/vs/workbench/contrib/tasks/browser/taskService.ts index e34ad9e5794..65028c8ab75 100644 --- a/src/vs/workbench/contrib/tasks/browser/taskService.ts +++ b/src/vs/workbench/contrib/tasks/browser/taskService.ts @@ -7,8 +7,8 @@ import * as nls from 'vs/nls'; import { IWorkspaceFolder } from 'vs/platform/workspace/common/workspace'; import { ITaskSystem } from 'vs/workbench/contrib/tasks/common/taskSystem'; import { ExecutionEngine } from 'vs/workbench/contrib/tasks/common/tasks'; -import { AbstractTaskService, WorkspaceFolderConfigurationResult } from 'vs/workbench/contrib/tasks/browser/abstractTaskService'; -import { TaskFilter, ITaskService } from 'vs/workbench/contrib/tasks/common/taskService'; +import { AbstractTaskService, IWorkspaceFolderConfigurationResult } from 'vs/workbench/contrib/tasks/browser/abstractTaskService'; +import { ITaskFilter, ITaskService } from 'vs/workbench/contrib/tasks/common/taskService'; import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; export class TaskService extends AbstractTaskService { @@ -32,11 +32,11 @@ export class TaskService extends AbstractTaskService { return this._taskSystem!; } - protected computeLegacyConfiguration(workspaceFolder: IWorkspaceFolder): Promise { + protected computeLegacyConfiguration(workspaceFolder: IWorkspaceFolder): Promise { throw new Error(TaskService.ProcessTaskSystemSupportMessage); } - protected versionAndEngineCompatible(filter?: TaskFilter): boolean { + protected versionAndEngineCompatible(filter?: ITaskFilter): boolean { return this.executionEngine === ExecutionEngine.Terminal; } } diff --git a/src/vs/workbench/contrib/tasks/browser/taskTerminalStatus.ts b/src/vs/workbench/contrib/tasks/browser/taskTerminalStatus.ts index 3c6dc5ca458..73c5f8502c6 100644 --- a/src/vs/workbench/contrib/tasks/browser/taskTerminalStatus.ts +++ b/src/vs/workbench/contrib/tasks/browser/taskTerminalStatus.ts @@ -8,14 +8,14 @@ import { Codicon } from 'vs/base/common/codicons'; import { Disposable, IDisposable } from 'vs/base/common/lifecycle'; import Severity from 'vs/base/common/severity'; import { AbstractProblemCollector, StartStopProblemCollector } from 'vs/workbench/contrib/tasks/common/problemCollectors'; -import { TaskEvent, TaskEventKind, TaskRunType } from 'vs/workbench/contrib/tasks/common/tasks'; +import { ITaskEvent, TaskEventKind, TaskRunType } from 'vs/workbench/contrib/tasks/common/tasks'; import { ITaskService, Task } from 'vs/workbench/contrib/tasks/common/taskService'; import { ITerminalInstance } from 'vs/workbench/contrib/terminal/browser/terminal'; import { ITerminalStatus } from 'vs/workbench/contrib/terminal/browser/terminalStatusList'; import { MarkerSeverity } from 'vs/platform/markers/common/markers'; import { spinningLoading } from 'vs/platform/theme/common/iconRegistry'; -interface TerminalData { +interface ITerminalData { terminal: ITerminalInstance; task: Task; status: ITerminalStatus; @@ -36,7 +36,7 @@ const INFO_TASK_STATUS: ITerminalStatus = { id: TASK_TERMINAL_STATUS_ID, icon: C const INFO_INACTIVE_TASK_STATUS: ITerminalStatus = { id: TASK_TERMINAL_STATUS_ID, icon: Codicon.info, severity: Severity.Info, tooltip: nls.localize('taskTerminalStatus.infosInactive', "Task has infos and is waiting...") }; export class TaskTerminalStatus extends Disposable { - private terminalMap: Map = new Map(); + private terminalMap: Map = new Map(); constructor(taskService: ITaskService) { super(); @@ -56,7 +56,7 @@ export class TaskTerminalStatus extends Disposable { this.terminalMap.set(task._id, { terminal, task, status, problemMatcher, taskRunEnded: false }); } - private terminalFromEvent(event: TaskEvent): TerminalData | undefined { + private terminalFromEvent(event: ITaskEvent): ITerminalData | undefined { if (!event.__task) { return undefined; } @@ -64,7 +64,7 @@ export class TaskTerminalStatus extends Disposable { return this.terminalMap.get(event.__task._id); } - private eventEnd(event: TaskEvent) { + private eventEnd(event: ITaskEvent) { const terminalData = this.terminalFromEvent(event); if (!terminalData) { return; @@ -82,7 +82,7 @@ export class TaskTerminalStatus extends Disposable { } } - private eventInactive(event: TaskEvent) { + private eventInactive(event: ITaskEvent) { const terminalData = this.terminalFromEvent(event); if (!terminalData || !terminalData.problemMatcher || terminalData.taskRunEnded) { return; @@ -99,7 +99,7 @@ export class TaskTerminalStatus extends Disposable { } } - private eventActive(event: TaskEvent) { + private eventActive(event: ITaskEvent) { const terminalData = this.terminalFromEvent(event); if (!terminalData) { return; diff --git a/src/vs/workbench/contrib/tasks/browser/tasksQuickAccess.ts b/src/vs/workbench/contrib/tasks/browser/tasksQuickAccess.ts index 24b9b2d9779..6c4080090bb 100644 --- a/src/vs/workbench/contrib/tasks/browser/tasksQuickAccess.ts +++ b/src/vs/workbench/contrib/tasks/browser/tasksQuickAccess.ts @@ -12,7 +12,7 @@ import { ITaskService, Task } from 'vs/workbench/contrib/tasks/common/taskServic import { CustomTask, ContributedTask, ConfiguringTask } from 'vs/workbench/contrib/tasks/common/tasks'; import { CancellationToken } from 'vs/base/common/cancellation'; import { DisposableStore } from 'vs/base/common/lifecycle'; -import { TaskQuickPick, TaskTwoLevelQuickPickEntry } from 'vs/workbench/contrib/tasks/browser/taskQuickPick'; +import { TaskQuickPick, ITaskTwoLevelQuickPickEntry } from 'vs/workbench/contrib/tasks/browser/taskQuickPick'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { isString } from 'vs/base/common/types'; import { INotificationService } from 'vs/platform/notification/common/notification'; @@ -56,8 +56,8 @@ export class TasksQuickAccessProvider extends PickerQuickAccessProviderentry).task!; - const quickAccessEntry: IPickerQuickAccessItem = entry; + const task: Task | ConfiguringTask | string = (entry).task!; + const quickAccessEntry: IPickerQuickAccessItem = entry; quickAccessEntry.highlights = { label: highlights }; quickAccessEntry.trigger = (index) => { if ((index === 1) && (quickAccessEntry.buttons?.length === 2)) { diff --git a/src/vs/workbench/contrib/tasks/browser/terminalTaskSystem.ts b/src/vs/workbench/contrib/tasks/browser/terminalTaskSystem.ts index 2c06dbc8717..db3cdbd6a79 100644 --- a/src/vs/workbench/contrib/tasks/browser/terminalTaskSystem.ts +++ b/src/vs/workbench/contrib/tasks/browser/terminalTaskSystem.ts @@ -30,12 +30,12 @@ import { ITerminalService, ITerminalInstance, ITerminalGroupService } from 'vs/w import { IOutputService } from 'vs/workbench/services/output/common/output'; import { StartStopProblemCollector, WatchingProblemCollector, ProblemCollectorEventKind, ProblemHandlingStrategy } from 'vs/workbench/contrib/tasks/common/problemCollectors'; import { - Task, CustomTask, ContributedTask, RevealKind, CommandOptions, ShellConfiguration, RuntimeType, PanelKind, - TaskEvent, TaskEventKind, ShellQuotingOptions, ShellQuoting, CommandString, CommandConfiguration, ExtensionTaskSource, TaskScope, RevealProblemKind, DependsOrder, TaskSourceKind, InMemoryTask + Task, CustomTask, ContributedTask, RevealKind, CommandOptions, IShellConfiguration, RuntimeType, PanelKind, + TaskEvent, TaskEventKind, IShellQuotingOptions, ShellQuoting, CommandString, ICommandConfiguration, IExtensionTaskSource, TaskScope, RevealProblemKind, DependsOrder, TaskSourceKind, InMemoryTask, ITaskEvent } from 'vs/workbench/contrib/tasks/common/tasks'; import { ITaskSystem, ITaskSummary, ITaskExecuteResult, TaskExecuteKind, TaskError, TaskErrors, ITaskResolver, - Triggers, TaskTerminateResponse, TaskSystemInfoResolver, TaskSystemInfo, ResolveSet, ResolvedVariables + Triggers, ITaskTerminateResponse, ITaskSystemInfoResolver, ITaskSystemInfo, IResolveSet, IResolvedVariables } from 'vs/workbench/contrib/tasks/common/taskSystem'; import { URI } from 'vs/base/common/uri'; import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService'; @@ -51,13 +51,13 @@ import { ITaskService } from 'vs/workbench/contrib/tasks/common/taskService'; import { IPaneCompositePartService } from 'vs/workbench/services/panecomposite/browser/panecomposite'; import { INotificationService } from 'vs/platform/notification/common/notification'; -interface TerminalData { +interface ITerminalData { terminal: ITerminalInstance; lastTask: string; group?: string; } -interface ActiveTerminalData { +interface IActiveTerminalData { terminal: ITerminalInstance; task: Task; promise: Promise; @@ -85,7 +85,7 @@ class InstanceManager { class VariableResolver { private static regex = /\$\{(.*?)\}/g; - constructor(public workspaceFolder: IWorkspaceFolder | undefined, public taskSystemInfo: TaskSystemInfo | undefined, public readonly values: Map, private _service: IConfigurationResolverService | undefined) { + constructor(public workspaceFolder: IWorkspaceFolder | undefined, public taskSystemInfo: ITaskSystemInfo | undefined, public readonly values: Map, private _service: IConfigurationResolverService | undefined) { } async resolve(value: string): Promise { const replacers: Promise[] = []; @@ -115,8 +115,8 @@ export class VerifiedTask { readonly task: Task; readonly resolver: ITaskResolver; readonly trigger: string; - resolvedVariables?: ResolvedVariables; - systemInfo?: TaskSystemInfo; + resolvedVariables?: IResolvedVariables; + systemInfo?: ITaskSystemInfo; workspaceFolder?: IWorkspaceFolder; shellLaunchConfig?: IShellLaunchConfig; @@ -134,7 +134,7 @@ export class VerifiedTask { return verified; } - public getVerifiedTask(): { task: Task; resolver: ITaskResolver; trigger: string; resolvedVariables: ResolvedVariables; systemInfo: TaskSystemInfo; workspaceFolder: IWorkspaceFolder; shellLaunchConfig: IShellLaunchConfig } { + public getVerifiedTask(): { task: Task; resolver: ITaskResolver; trigger: string; resolvedVariables: IResolvedVariables; systemInfo: ITaskSystemInfo; workspaceFolder: IWorkspaceFolder; shellLaunchConfig: IShellLaunchConfig } { if (this.verify()) { return { task: this.task, resolver: this.resolver, trigger: this.trigger, resolvedVariables: this.resolvedVariables!, systemInfo: this.systemInfo!, workspaceFolder: this.workspaceFolder!, shellLaunchConfig: this.shellLaunchConfig! }; } else { @@ -149,7 +149,7 @@ export class TerminalTaskSystem extends Disposable implements ITaskSystem { private static readonly ProcessVarName = '__process__'; - private static shellQuotes: IStringDictionary = { + private static shellQuotes: IStringDictionary = { 'cmd': { strong: '"' }, @@ -179,19 +179,19 @@ export class TerminalTaskSystem extends Disposable implements ITaskSystem { } }; - private static osShellQuotes: IStringDictionary = { + private static osShellQuotes: IStringDictionary = { 'Linux': TerminalTaskSystem.shellQuotes['bash'], 'Mac': TerminalTaskSystem.shellQuotes['bash'], 'Windows': TerminalTaskSystem.shellQuotes['powershell'] }; - private activeTasks: IStringDictionary; + private activeTasks: IStringDictionary; private instances: IStringDictionary; private busyTasks: IStringDictionary; - private terminals: IStringDictionary; + private terminals: IStringDictionary; private idleTaskTerminals: LinkedMap; private sameTaskTerminals: IStringDictionary; - private taskSystemInfoResolver: TaskSystemInfoResolver; + private taskSystemInfoResolver: ITaskSystemInfoResolver; private lastTask: VerifiedTask | undefined; // Should always be set in run private currentTask!: VerifiedTask; @@ -201,7 +201,7 @@ export class TerminalTaskSystem extends Disposable implements ITaskSystem { private terminalStatusManager: TaskTerminalStatus; private terminalCreationQueue: Promise = Promise.resolve(); - private readonly _onDidStateChange: Emitter; + private readonly _onDidStateChange: Emitter; constructor( private terminalService: ITerminalService, @@ -222,7 +222,7 @@ export class TerminalTaskSystem extends Disposable implements ITaskSystem { private configurationService: IConfigurationService, private notificationService: INotificationService, taskService: ITaskService, - taskSystemInfoResolver: TaskSystemInfoResolver, + taskSystemInfoResolver: ITaskSystemInfoResolver, ) { super(); @@ -238,7 +238,7 @@ export class TerminalTaskSystem extends Disposable implements ITaskSystem { this._register(this.terminalStatusManager = new TaskTerminalStatus(taskService)); } - public get onDidStateChange(): Event { + public get onDidStateChange(): Event { return this._onDidStateChange.event; } @@ -425,7 +425,7 @@ export class TerminalTaskSystem extends Disposable implements ITaskSystem { this.removeInstances(task); } - private fireTaskEvent(event: TaskEvent) { + private fireTaskEvent(event: ITaskEvent) { if (event.__task) { const activeTask = this.activeTasks[event.__task.getMapKey()]; if (activeTask) { @@ -435,12 +435,12 @@ export class TerminalTaskSystem extends Disposable implements ITaskSystem { this._onDidStateChange.fire(event); } - public terminate(task: Task): Promise { + public terminate(task: Task): Promise { let activeTerminal = this.activeTasks[task.getMapKey()]; if (!activeTerminal) { - return Promise.resolve({ success: false, task: undefined }); + return Promise.resolve({ success: false, task: undefined }); } - return new Promise((resolve, reject) => { + return new Promise((resolve, reject) => { let terminal = activeTerminal.terminal; const onExit = terminal.onExit(() => { @@ -457,12 +457,12 @@ export class TerminalTaskSystem extends Disposable implements ITaskSystem { }); } - public terminateAll(): Promise { - let promises: Promise[] = []; + public terminateAll(): Promise { + let promises: Promise[] = []; Object.keys(this.activeTasks).forEach((key) => { let terminalData = this.activeTasks[key]; let terminal = terminalData.terminal; - promises.push(new Promise((resolve, reject) => { + promises.push(new Promise((resolve, reject) => { const onExit = terminal.onExit(() => { let task = terminalData.task; try { @@ -477,7 +477,7 @@ export class TerminalTaskSystem extends Disposable implements ITaskSystem { terminal.dispose(); }); this.activeTasks = Object.create(null); - return Promise.all(promises); + return Promise.all(promises); } @@ -571,7 +571,7 @@ export class TerminalTaskSystem extends Disposable implements ITaskSystem { }); } - private async getDependencyPromise(task: ActiveTerminalData): Promise { + private async getDependencyPromise(task: IActiveTerminalData): Promise { if (!task.task.configurationProperties.isBackground) { return task.promise; } @@ -595,7 +595,7 @@ export class TerminalTaskSystem extends Disposable implements ITaskSystem { return Promise.race([inactivePromise, this.executeTask(task, resolver, trigger, encounteredDependencies, alreadyResolved)]); } - private async resolveAndFindExecutable(systemInfo: TaskSystemInfo | undefined, workspaceFolder: IWorkspaceFolder | undefined, task: CustomTask | ContributedTask, cwd: string | undefined, envPath: string | undefined): Promise { + private async resolveAndFindExecutable(systemInfo: ITaskSystemInfo | undefined, workspaceFolder: IWorkspaceFolder | undefined, task: CustomTask | ContributedTask, cwd: string | undefined, envPath: string | undefined): Promise { const command = await this.configurationResolverService.resolveAsync(workspaceFolder, CommandString.value(task.command.name!)); cwd = cwd ? await this.configurationResolverService.resolveAsync(workspaceFolder, cwd) : undefined; const paths = envPath ? await Promise.all(envPath.split(path.delimiter).map(p => this.configurationResolverService.resolveAsync(workspaceFolder, p))) : undefined; @@ -627,13 +627,13 @@ export class TerminalTaskSystem extends Disposable implements ITaskSystem { } } - private async acquireInput(taskSystemInfo: TaskSystemInfo | undefined, workspaceFolder: IWorkspaceFolder | undefined, task: CustomTask | ContributedTask, variables: Set, alreadyResolved: Map): Promise { + private async acquireInput(taskSystemInfo: ITaskSystemInfo | undefined, workspaceFolder: IWorkspaceFolder | undefined, task: CustomTask | ContributedTask, variables: Set, alreadyResolved: Map): Promise { const resolved = await this.resolveVariablesFromSet(taskSystemInfo, workspaceFolder, task, variables, alreadyResolved); this.fireTaskEvent(TaskEvent.create(TaskEventKind.AcquiredInput, task)); return resolved; } - private resolveVariablesFromSet(taskSystemInfo: TaskSystemInfo | undefined, workspaceFolder: IWorkspaceFolder | undefined, task: CustomTask | ContributedTask, variables: Set, alreadyResolved: Map): Promise { + private resolveVariablesFromSet(taskSystemInfo: ITaskSystemInfo | undefined, workspaceFolder: IWorkspaceFolder | undefined, task: CustomTask | ContributedTask, variables: Set, alreadyResolved: Map): Promise { let isProcess = task.command && task.command.runtime === RuntimeType.Process; let options = task.command && task.command.options ? task.command.options : undefined; let cwd = options ? options.cwd : undefined; @@ -649,9 +649,9 @@ export class TerminalTaskSystem extends Disposable implements ITaskSystem { } } const unresolved = this.findUnresolvedVariables(variables, alreadyResolved); - let resolvedVariables: Promise; + let resolvedVariables: Promise; if (taskSystemInfo && workspaceFolder) { - let resolveSet: ResolveSet = { + let resolveSet: IResolveSet = { variables: unresolved }; @@ -685,7 +685,7 @@ export class TerminalTaskSystem extends Disposable implements ITaskSystem { let variablesArray = new Array(); unresolved.forEach(variable => variablesArray.push(variable)); - return new Promise((resolve, reject) => { + return new Promise((resolve, reject) => { this.configurationResolverService.resolveWithInteraction(workspaceFolder, variablesArray, 'tasks', undefined, TaskSourceKind.toConfigurationTarget(task._source.kind)).then(async (resolvedVariablesMap: Map | undefined) => { if (resolvedVariablesMap) { this.mergeMaps(alreadyResolved, resolvedVariablesMap); @@ -699,7 +699,7 @@ export class TerminalTaskSystem extends Disposable implements ITaskSystem { } resolvedVariablesMap.set(TerminalTaskSystem.ProcessVarName, processVarValue); } - let resolvedVariablesResult: ResolvedVariables = { + let resolvedVariablesResult: IResolvedVariables = { variables: resolvedVariablesMap, }; resolve(resolvedVariablesResult); @@ -722,7 +722,7 @@ export class TerminalTaskSystem extends Disposable implements ITaskSystem { const folders = this.contextService.getWorkspace().folders; workspaceFolder = folders.length > 0 ? folders[0] : undefined; } - const systemInfo: TaskSystemInfo | undefined = this.currentTask.systemInfo = this.taskSystemInfoResolver(workspaceFolder); + const systemInfo: ITaskSystemInfo | undefined = this.currentTask.systemInfo = this.taskSystemInfoResolver(workspaceFolder); let variables = new Set(); this.collectTaskVariables(variables, task); @@ -1037,7 +1037,7 @@ export class TerminalTaskSystem extends Disposable implements ITaskSystem { waitOnExit }; let shellSpecified: boolean = false; - let shellOptions: ShellConfiguration | undefined = task.command.options && task.command.options.shell; + let shellOptions: IShellConfiguration | undefined = task.command.options && task.command.options.shell; if (shellOptions) { if (shellOptions.executable) { // Clear out the args so that we don't end up with mismatched args. @@ -1260,7 +1260,7 @@ export class TerminalTaskSystem extends Disposable implements ITaskSystem { let group = presentationOptions.group; let taskKey = task.getMapKey(); - let terminalToReuse: TerminalData | undefined; + let terminalToReuse: ITerminalData | undefined; if (prefersSameTerminal) { let terminalId = this.sameTaskTerminals[taskKey]; if (terminalId) { @@ -1326,7 +1326,7 @@ export class TerminalTaskSystem extends Disposable implements ITaskSystem { return [result, undefined]; } - private buildShellCommandLine(platform: Platform.Platform, shellExecutable: string, shellOptions: ShellConfiguration | undefined, command: CommandString, originalCommand: CommandString | undefined, args: CommandString[]): string { + private buildShellCommandLine(platform: Platform.Platform, shellExecutable: string, shellOptions: IShellConfiguration | undefined, command: CommandString, originalCommand: CommandString | undefined, args: CommandString[]): string { let basename = path.parse(shellExecutable).name.toLowerCase(); let shellQuoteOptions = this.getQuotingOptions(basename, shellOptions, platform); @@ -1425,7 +1425,7 @@ export class TerminalTaskSystem extends Disposable implements ITaskSystem { return commandLine; } - private getQuotingOptions(shellBasename: string, shellOptions: ShellConfiguration | undefined, platform: Platform.Platform): ShellQuotingOptions { + private getQuotingOptions(shellBasename: string, shellOptions: IShellConfiguration | undefined, platform: Platform.Platform): IShellQuotingOptions { if (shellOptions && shellOptions.quoting) { return shellOptions.quoting; } @@ -1463,7 +1463,7 @@ export class TerminalTaskSystem extends Disposable implements ITaskSystem { } } - private collectCommandVariables(variables: Set, command: CommandConfiguration, task: CustomTask | ContributedTask): void { + private collectCommandVariables(variables: Set, command: ICommandConfiguration, task: CustomTask | ContributedTask): void { // The custom execution should have everything it needs already as it provided // the callback. if (command.runtime === RuntimeType.CustomExecution) { @@ -1478,7 +1478,7 @@ export class TerminalTaskSystem extends Disposable implements ITaskSystem { command.args.forEach(arg => this.collectVariables(variables, arg)); } // Try to get a scope. - const scope = (task._source).scope; + const scope = (task._source).scope; if (scope !== TaskScope.Global) { variables.add('${workspaceFolder}'); } @@ -1540,7 +1540,7 @@ export class TerminalTaskSystem extends Disposable implements ITaskSystem { } while (matches); } - private async resolveCommandAndArgs(resolver: VariableResolver, commandConfig: CommandConfiguration): Promise<{ command: CommandString; args: CommandString[] }> { + private async resolveCommandAndArgs(resolver: VariableResolver, commandConfig: ICommandConfiguration): Promise<{ command: CommandString; args: CommandString[] }> { // First we need to use the command args: let args: CommandString[] = commandConfig.args ? commandConfig.args.slice() : []; args = await this.resolveVariables(resolver, args); @@ -1574,7 +1574,7 @@ export class TerminalTaskSystem extends Disposable implements ITaskSystem { this.appendOutput(nls.localize('unknownProblemMatcher', 'Problem matcher {0} can\'t be resolved. The matcher will be ignored')); continue; } - let taskSystemInfo: TaskSystemInfo | undefined = resolver.taskSystemInfo; + let taskSystemInfo: ITaskSystemInfo | undefined = resolver.taskSystemInfo; let hasFilePrefix = matcher.filePrefix !== undefined; let hasUriProvider = taskSystemInfo !== undefined && taskSystemInfo.uriProvider !== undefined; if (!hasFilePrefix && !hasUriProvider) { diff --git a/src/vs/workbench/contrib/tasks/common/problemCollectors.ts b/src/vs/workbench/contrib/tasks/common/problemCollectors.ts index 081843db236..7fa7589e838 100644 --- a/src/vs/workbench/contrib/tasks/common/problemCollectors.ts +++ b/src/vs/workbench/contrib/tasks/common/problemCollectors.ts @@ -10,7 +10,7 @@ import { IDisposable, DisposableStore } from 'vs/base/common/lifecycle'; import { IModelService } from 'vs/editor/common/services/model'; -import { ILineMatcher, createLineMatcher, ProblemMatcher, ProblemMatch, ApplyToKind, WatchingPattern, getResource } from 'vs/workbench/contrib/tasks/common/problemMatcher'; +import { ILineMatcher, createLineMatcher, ProblemMatcher, IProblemMatch, ApplyToKind, IWatchingPattern, getResource } from 'vs/workbench/contrib/tasks/common/problemMatcher'; import { IMarkerService, IMarkerData, MarkerSeverity } from 'vs/platform/markers/common/markers'; import { generateUuid } from 'vs/base/common/uuid'; import { IFileService } from 'vs/platform/files/common/files'; @@ -21,11 +21,11 @@ export const enum ProblemCollectorEventKind { BackgroundProcessingEnds = 'backgroundProcessingEnds' } -export interface ProblemCollectorEvent { +export interface IProblemCollectorEvent { kind: ProblemCollectorEventKind; } -namespace ProblemCollectorEvent { +namespace IProblemCollectorEvent { export function create(kind: ProblemCollectorEventKind) { return Object.freeze({ kind }); } @@ -56,7 +56,7 @@ export abstract class AbstractProblemCollector implements IDisposable { // [owner] -> [resource] -> number; private deliveredMarkers: Map>; - protected _onDidStateChange: Emitter; + protected _onDidStateChange: Emitter; constructor(public readonly problemMatchers: ProblemMatcher[], protected markerService: IMarkerService, protected modelService: IModelService, fileService?: IFileService) { this.matchers = Object.create(null); @@ -101,7 +101,7 @@ export abstract class AbstractProblemCollector implements IDisposable { this._onDidStateChange = new Emitter(); } - public get onDidStateChange(): Event { + public get onDidStateChange(): Event { return this._onDidStateChange.event; } @@ -130,8 +130,8 @@ export abstract class AbstractProblemCollector implements IDisposable { return this._maxMarkerSeverity; } - protected tryFindMarker(line: string): ProblemMatch | null { - let result: ProblemMatch | null = null; + protected tryFindMarker(line: string): IProblemMatch | null { + let result: IProblemMatch | null = null; if (this.activeMatcher) { result = this.activeMatcher.next(line); if (result) { @@ -158,7 +158,7 @@ export abstract class AbstractProblemCollector implements IDisposable { return result; } - protected async shouldApplyMatch(result: ProblemMatch): Promise { + protected async shouldApplyMatch(result: IProblemMatch): Promise { switch (result.description.applyTo) { case ApplyToKind.allDocuments: return true; @@ -178,7 +178,7 @@ export abstract class AbstractProblemCollector implements IDisposable { return ApplyToKind.allDocuments; } - private tryMatchers(): ProblemMatch | null { + private tryMatchers(): IProblemMatch | null { this.activeMatcher = null; let length = this.buffer.length; for (let startIndex = 0; startIndex < length; startIndex++) { @@ -200,7 +200,7 @@ export abstract class AbstractProblemCollector implements IDisposable { return null; } - private captureMatch(match: ProblemMatch): void { + private captureMatch(match: IProblemMatch): void { this._numberOfMatches++; if (this._maxMarkerSeverity === undefined || match.marker.severity > this._maxMarkerSeverity) { this._maxMarkerSeverity = match.marker.severity; @@ -387,16 +387,16 @@ export class StartStopProblemCollector extends AbstractProblemCollector implemen } } -interface BackgroundPatterns { +interface IBackgroundPatterns { key: string; matcher: ProblemMatcher; - begin: WatchingPattern; - end: WatchingPattern; + begin: IWatchingPattern; + end: IWatchingPattern; } export class WatchingProblemCollector extends AbstractProblemCollector implements IProblemMatcher { - private backgroundPatterns: BackgroundPatterns[]; + private backgroundPatterns: IBackgroundPatterns[]; // workaround for https://github.com/microsoft/vscode/issues/44018 private _activeBackgroundMatchers: Set; @@ -450,7 +450,7 @@ export class WatchingProblemCollector extends AbstractProblemCollector implement for (let background of this.backgroundPatterns) { if (background.matcher.watching && background.matcher.watching.activeOnStart) { this._activeBackgroundMatchers.add(background.key); - this._onDidStateChange.fire(ProblemCollectorEvent.create(ProblemCollectorEventKind.BackgroundProcessingBegins)); + this._onDidStateChange.fire(IProblemCollectorEvent.create(ProblemCollectorEventKind.BackgroundProcessingBegins)); this.recordResourcesToClean(background.matcher.owner); } } @@ -496,7 +496,7 @@ export class WatchingProblemCollector extends AbstractProblemCollector implement result = true; this.lines = []; this.lines.push(line); - this._onDidStateChange.fire(ProblemCollectorEvent.create(ProblemCollectorEventKind.BackgroundProcessingBegins)); + this._onDidStateChange.fire(IProblemCollectorEvent.create(ProblemCollectorEventKind.BackgroundProcessingBegins)); this.cleanMarkerCaches(); this.resetCurrentResource(); let owner = background.matcher.owner; @@ -520,7 +520,7 @@ export class WatchingProblemCollector extends AbstractProblemCollector implement if (this._activeBackgroundMatchers.has(background.key)) { this._activeBackgroundMatchers.delete(background.key); this.resetCurrentResource(); - this._onDidStateChange.fire(ProblemCollectorEvent.create(ProblemCollectorEventKind.BackgroundProcessingEnds)); + this._onDidStateChange.fire(IProblemCollectorEvent.create(ProblemCollectorEventKind.BackgroundProcessingEnds)); result = true; this.lines.push(line); let owner = background.matcher.owner; diff --git a/src/vs/workbench/contrib/tasks/common/problemMatcher.ts b/src/vs/workbench/contrib/tasks/common/problemMatcher.ts index 296d268d888..544942e78d5 100644 --- a/src/vs/workbench/contrib/tasks/common/problemMatcher.ts +++ b/src/vs/workbench/contrib/tasks/common/problemMatcher.ts @@ -63,7 +63,7 @@ export module ProblemLocationKind { } } -export interface ProblemPattern { +export interface IProblemPattern { regexp: RegExp; kind?: ProblemLocationKind; @@ -89,21 +89,21 @@ export interface ProblemPattern { loop?: boolean; } -export interface NamedProblemPattern extends ProblemPattern { +export interface INamedProblemPattern extends IProblemPattern { name: string; } -export type MultiLineProblemPattern = ProblemPattern[]; +export type MultiLineProblemPattern = IProblemPattern[]; -export interface WatchingPattern { +export interface IWatchingPattern { regexp: RegExp; file?: number; } -export interface WatchingMatcher { +export interface IWatchingMatcher { activeOnStart: boolean; - beginsPattern: WatchingPattern; - endsPattern: WatchingPattern; + beginsPattern: IWatchingPattern; + endsPattern: IWatchingPattern; } export enum ApplyToKind { @@ -133,36 +133,36 @@ export interface ProblemMatcher { applyTo: ApplyToKind; fileLocation: FileLocationKind; filePrefix?: string; - pattern: ProblemPattern | ProblemPattern[]; + pattern: IProblemPattern | IProblemPattern[]; severity?: Severity; - watching?: WatchingMatcher; + watching?: IWatchingMatcher; uriProvider?: (path: string) => URI; } -export interface NamedProblemMatcher extends ProblemMatcher { +export interface INamedProblemMatcher extends ProblemMatcher { name: string; label: string; deprecated?: boolean; } -export interface NamedMultiLineProblemPattern { +export interface INamedMultiLineProblemPattern { name: string; label: string; patterns: MultiLineProblemPattern; } -export function isNamedProblemMatcher(value: ProblemMatcher | undefined): value is NamedProblemMatcher { - return value && Types.isString((value).name) ? true : false; +export function isNamedProblemMatcher(value: ProblemMatcher | undefined): value is INamedProblemMatcher { + return value && Types.isString((value).name) ? true : false; } -interface Location { +interface ILocation { startLineNumber: number; startCharacter: number; endLineNumber: number; endCharacter: number; } -interface ProblemData { +interface IProblemData { kind?: ProblemLocationKind; file?: string; location?: string; @@ -175,14 +175,14 @@ interface ProblemData { code?: string; } -export interface ProblemMatch { +export interface IProblemMatch { resource: Promise; marker: IMarkerData; description: ProblemMatcher; } -export interface HandleResult { - match: ProblemMatch | null; +export interface IHandleResult { + match: IProblemMatch | null; continue: boolean; } @@ -230,8 +230,8 @@ export async function getResource(filename: string, matcher: ProblemMatcher, fil export interface ILineMatcher { matchLength: number; - next(line: string): ProblemMatch | null; - handle(lines: string[], start?: number): HandleResult; + next(line: string): IProblemMatch | null; + handle(lines: string[], start?: number): IHandleResult; } export function createLineMatcher(matcher: ProblemMatcher, fileService?: IFileService): ILineMatcher { @@ -254,17 +254,17 @@ abstract class AbstractLineMatcher implements ILineMatcher { this.fileService = fileService; } - public handle(lines: string[], start: number = 0): HandleResult { + public handle(lines: string[], start: number = 0): IHandleResult { return { match: null, continue: false }; } - public next(line: string): ProblemMatch | null { + public next(line: string): IProblemMatch | null { return null; } public abstract get matchLength(): number; - protected fillProblemData(data: ProblemData | undefined, pattern: ProblemPattern, matches: RegExpExecArray): data is ProblemData { + protected fillProblemData(data: IProblemData | undefined, pattern: IProblemPattern, matches: RegExpExecArray): data is IProblemData { if (data) { this.fillProperty(data, 'file', pattern, matches, true); this.appendProperty(data, 'message', pattern, matches, true); @@ -281,7 +281,7 @@ abstract class AbstractLineMatcher implements ILineMatcher { } } - private appendProperty(data: ProblemData, property: keyof ProblemData, pattern: ProblemPattern, matches: RegExpExecArray, trim: boolean = false): void { + private appendProperty(data: IProblemData, property: keyof IProblemData, pattern: IProblemPattern, matches: RegExpExecArray, trim: boolean = false): void { const patternProperty = pattern[property]; if (Types.isUndefined(data[property])) { this.fillProperty(data, property, pattern, matches, trim); @@ -295,7 +295,7 @@ abstract class AbstractLineMatcher implements ILineMatcher { } } - private fillProperty(data: ProblemData, property: keyof ProblemData, pattern: ProblemPattern, matches: RegExpExecArray, trim: boolean = false): void { + private fillProperty(data: IProblemData, property: keyof IProblemData, pattern: IProblemPattern, matches: RegExpExecArray, trim: boolean = false): void { const patternAtProperty = pattern[property]; if (Types.isUndefined(data[property]) && !Types.isUndefined(patternAtProperty) && patternAtProperty < matches.length) { let value = matches[patternAtProperty]; @@ -308,7 +308,7 @@ abstract class AbstractLineMatcher implements ILineMatcher { } } - protected getMarkerMatch(data: ProblemData): ProblemMatch | undefined { + protected getMarkerMatch(data: IProblemData): IProblemMatch | undefined { try { let location = this.getLocation(data); if (data.file && location && data.message) { @@ -342,7 +342,7 @@ abstract class AbstractLineMatcher implements ILineMatcher { return getResource(filename, this.matcher, this.fileService); } - private getLocation(data: ProblemData): Location | null { + private getLocation(data: IProblemData): ILocation | null { if (data.kind === ProblemLocationKind.File) { return this.createLocation(0, 0, 0, 0); } @@ -359,7 +359,7 @@ abstract class AbstractLineMatcher implements ILineMatcher { return this.createLocation(startLine, startColumn, endLine, endColumn); } - private parseLocationInfo(value: string): Location | null { + private parseLocationInfo(value: string): ILocation | null { if (!value || !value.match(/(\d+|\d+,\d+|\d+,\d+,\d+,\d+)/)) { return null; } @@ -373,7 +373,7 @@ abstract class AbstractLineMatcher implements ILineMatcher { } } - private createLocation(startLine: number, startColumn: number | undefined, endLine: number | undefined, endColumn: number | undefined): Location { + private createLocation(startLine: number, startColumn: number | undefined, endLine: number | undefined, endColumn: number | undefined): ILocation { if (startColumn !== undefined && endColumn !== undefined) { return { startLineNumber: startLine, startCharacter: startColumn, endLineNumber: endLine || startLine, endCharacter: endColumn }; } @@ -383,7 +383,7 @@ abstract class AbstractLineMatcher implements ILineMatcher { return { startLineNumber: startLine, startCharacter: 1, endLineNumber: startLine, endCharacter: 2 ** 31 - 1 }; // See https://github.com/microsoft/vscode/issues/80288#issuecomment-650636442 for discussion } - private getSeverity(data: ProblemData): MarkerSeverity { + private getSeverity(data: IProblemData): MarkerSeverity { let result: Severity | null = null; if (data.severity) { let value = data.severity; @@ -413,20 +413,20 @@ abstract class AbstractLineMatcher implements ILineMatcher { class SingleLineMatcher extends AbstractLineMatcher { - private pattern: ProblemPattern; + private pattern: IProblemPattern; constructor(matcher: ProblemMatcher, fileService?: IFileService) { super(matcher, fileService); - this.pattern = matcher.pattern; + this.pattern = matcher.pattern; } public get matchLength(): number { return 1; } - public override handle(lines: string[], start: number = 0): HandleResult { + public override handle(lines: string[], start: number = 0): IHandleResult { Assert.ok(lines.length - start === 1); - let data: ProblemData = Object.create(null); + let data: IProblemData = Object.create(null); if (this.pattern.kind !== undefined) { data.kind = this.pattern.kind; } @@ -441,26 +441,26 @@ class SingleLineMatcher extends AbstractLineMatcher { return { match: null, continue: false }; } - public override next(line: string): ProblemMatch | null { + public override next(line: string): IProblemMatch | null { return null; } } class MultiLineMatcher extends AbstractLineMatcher { - private patterns: ProblemPattern[]; - private data: ProblemData | undefined; + private patterns: IProblemPattern[]; + private data: IProblemData | undefined; constructor(matcher: ProblemMatcher, fileService?: IFileService) { super(matcher, fileService); - this.patterns = matcher.pattern; + this.patterns = matcher.pattern; } public get matchLength(): number { return this.patterns.length; } - public override handle(lines: string[], start: number = 0): HandleResult { + public override handle(lines: string[], start: number = 0): IHandleResult { Assert.ok(lines.length - start === this.patterns.length); this.data = Object.create(null); let data = this.data!; @@ -486,7 +486,7 @@ class MultiLineMatcher extends AbstractLineMatcher { return { match: markerMatch ? markerMatch : null, continue: loop }; } - public override next(line: string): ProblemMatch | null { + public override next(line: string): IProblemMatch | null { let pattern = this.patterns[this.patterns.length - 1]; Assert.ok(pattern.loop === true && this.data !== null); let matches = pattern.regexp.exec(line); @@ -495,7 +495,7 @@ class MultiLineMatcher extends AbstractLineMatcher { return null; } let data = Objects.deepClone(this.data); - let problemMatch: ProblemMatch | undefined; + let problemMatch: IProblemMatch | undefined; if (this.fillProblemData(data, pattern, matches)) { problemMatch = this.getMarkerMatch(data); } @@ -505,7 +505,7 @@ class MultiLineMatcher extends AbstractLineMatcher { export namespace Config { - export interface ProblemPattern { + export interface IProblemPattern { /** * The regular expression to find a problem in the console output of an @@ -591,7 +591,7 @@ export namespace Config { loop?: boolean; } - export interface CheckedProblemPattern extends ProblemPattern { + export interface ICheckedProblemPattern extends IProblemPattern { /** * The regular expression to find a problem in the console output of an * executed task. @@ -600,13 +600,13 @@ export namespace Config { } export namespace CheckedProblemPattern { - export function is(value: any): value is CheckedProblemPattern { - let candidate: ProblemPattern = value as ProblemPattern; + export function is(value: any): value is ICheckedProblemPattern { + let candidate: IProblemPattern = value as IProblemPattern; return candidate && Types.isString(candidate.regexp); } } - export interface NamedProblemPattern extends ProblemPattern { + export interface INamedProblemPattern extends IProblemPattern { /** * The name of the problem pattern. */ @@ -619,13 +619,13 @@ export namespace Config { } export namespace NamedProblemPattern { - export function is(value: any): value is NamedProblemPattern { - let candidate: NamedProblemPattern = value as NamedProblemPattern; + export function is(value: any): value is INamedProblemPattern { + let candidate: INamedProblemPattern = value as INamedProblemPattern; return candidate && Types.isString(candidate.name); } } - export interface NamedCheckedProblemPattern extends NamedProblemPattern { + export interface INamedCheckedProblemPattern extends INamedProblemPattern { /** * The regular expression to find a problem in the console output of an * executed task. @@ -634,13 +634,13 @@ export namespace Config { } export namespace NamedCheckedProblemPattern { - export function is(value: any): value is NamedCheckedProblemPattern { - let candidate: NamedProblemPattern = value as NamedProblemPattern; + export function is(value: any): value is INamedCheckedProblemPattern { + let candidate: INamedProblemPattern = value as INamedProblemPattern; return candidate && NamedProblemPattern.is(candidate) && Types.isString(candidate.regexp); } } - export type MultiLineProblemPattern = ProblemPattern[]; + export type MultiLineProblemPattern = IProblemPattern[]; export namespace MultiLineProblemPattern { export function is(value: any): value is MultiLineProblemPattern { @@ -648,7 +648,7 @@ export namespace Config { } } - export type MultiLineCheckedProblemPattern = CheckedProblemPattern[]; + export type MultiLineCheckedProblemPattern = ICheckedProblemPattern[]; export namespace MultiLineCheckedProblemPattern { export function is(value: any): value is MultiLineCheckedProblemPattern { @@ -664,7 +664,7 @@ export namespace Config { } } - export interface NamedMultiLineCheckedProblemPattern { + export interface INamedMultiLineCheckedProblemPattern { /** * The name of the problem pattern. */ @@ -682,18 +682,18 @@ export namespace Config { } export namespace NamedMultiLineCheckedProblemPattern { - export function is(value: any): value is NamedMultiLineCheckedProblemPattern { - let candidate = value as NamedMultiLineCheckedProblemPattern; + export function is(value: any): value is INamedMultiLineCheckedProblemPattern { + let candidate = value as INamedMultiLineCheckedProblemPattern; return candidate && Types.isString(candidate.name) && Types.isArray(candidate.patterns) && MultiLineCheckedProblemPattern.is(candidate.patterns); } } - export type NamedProblemPatterns = (Config.NamedProblemPattern | Config.NamedMultiLineCheckedProblemPattern)[]; + export type NamedProblemPatterns = (Config.INamedProblemPattern | Config.INamedMultiLineCheckedProblemPattern)[]; /** * A watching pattern */ - export interface WatchingPattern { + export interface IWatchingPattern { /** * The actual regular expression */ @@ -709,7 +709,7 @@ export namespace Config { /** * A description to track the start and end of a watching task. */ - export interface BackgroundMonitor { + export interface IBackgroundMonitor { /** * If set to true the watcher is in active mode when the task @@ -721,12 +721,12 @@ export namespace Config { /** * If matched in the output the start of a watching task is signaled. */ - beginsPattern?: string | WatchingPattern; + beginsPattern?: string | IWatchingPattern; /** * If matched in the output the end of a watching task is signaled. */ - endsPattern?: string | WatchingPattern; + endsPattern?: string | IWatchingPattern; } /** @@ -804,7 +804,7 @@ export namespace Config { * of a problem pattern or an array of problem patterns to match * problems spread over multiple lines. */ - pattern?: string | ProblemPattern | ProblemPattern[]; + pattern?: string | IProblemPattern | IProblemPattern[]; /** * A regular expression signaling that a watched tasks begins executing @@ -820,13 +820,13 @@ export namespace Config { /** * @deprecated Use background instead. */ - watching?: BackgroundMonitor; - background?: BackgroundMonitor; + watching?: IBackgroundMonitor; + background?: IBackgroundMonitor; } export type ProblemMatcherType = string | ProblemMatcher | Array; - export interface NamedProblemMatcher extends ProblemMatcher { + export interface INamedProblemMatcher extends ProblemMatcher { /** * This name can be used to refer to the * problem matcher from within a task. @@ -839,8 +839,8 @@ export namespace Config { label?: string; } - export function isNamedProblemMatcher(value: ProblemMatcher): value is NamedProblemMatcher { - return Types.isString((value).name); + export function isNamedProblemMatcher(value: ProblemMatcher): value is INamedProblemMatcher { + return Types.isString((value).name); } } @@ -850,17 +850,17 @@ export class ProblemPatternParser extends Parser { super(logger); } - public parse(value: Config.ProblemPattern): ProblemPattern; + public parse(value: Config.IProblemPattern): IProblemPattern; public parse(value: Config.MultiLineProblemPattern): MultiLineProblemPattern; - public parse(value: Config.NamedProblemPattern): NamedProblemPattern; - public parse(value: Config.NamedMultiLineCheckedProblemPattern): NamedMultiLineProblemPattern; - public parse(value: Config.ProblemPattern | Config.MultiLineProblemPattern | Config.NamedProblemPattern | Config.NamedMultiLineCheckedProblemPattern): any { + public parse(value: Config.INamedProblemPattern): INamedProblemPattern; + public parse(value: Config.INamedMultiLineCheckedProblemPattern): INamedMultiLineProblemPattern; + public parse(value: Config.IProblemPattern | Config.MultiLineProblemPattern | Config.INamedProblemPattern | Config.INamedMultiLineCheckedProblemPattern): any { if (Config.NamedMultiLineCheckedProblemPattern.is(value)) { return this.createNamedMultiLineProblemPattern(value); } else if (Config.MultiLineCheckedProblemPattern.is(value)) { return this.createMultiLineProblemPattern(value); } else if (Config.NamedCheckedProblemPattern.is(value)) { - let result = this.createSingleProblemPattern(value) as NamedProblemPattern; + let result = this.createSingleProblemPattern(value) as INamedProblemPattern; result.name = value.name; return result; } else if (Config.CheckedProblemPattern.is(value)) { @@ -871,7 +871,7 @@ export class ProblemPatternParser extends Parser { } } - private createSingleProblemPattern(value: Config.CheckedProblemPattern): ProblemPattern | null { + private createSingleProblemPattern(value: Config.ICheckedProblemPattern): IProblemPattern | null { let result = this.doCreateSingleProblemPattern(value, true); if (result === undefined) { return null; @@ -881,7 +881,7 @@ export class ProblemPatternParser extends Parser { return this.validateProblemPattern([result]) ? result : null; } - private createNamedMultiLineProblemPattern(value: Config.NamedMultiLineCheckedProblemPattern): NamedMultiLineProblemPattern | null { + private createNamedMultiLineProblemPattern(value: Config.INamedMultiLineCheckedProblemPattern): INamedMultiLineProblemPattern | null { const validPatterns = this.createMultiLineProblemPattern(value.patterns); if (!validPatterns) { return null; @@ -915,17 +915,17 @@ export class ProblemPatternParser extends Parser { return this.validateProblemPattern(result) ? result : null; } - private doCreateSingleProblemPattern(value: Config.CheckedProblemPattern, setDefaults: boolean): ProblemPattern | undefined { + private doCreateSingleProblemPattern(value: Config.ICheckedProblemPattern, setDefaults: boolean): IProblemPattern | undefined { const regexp = this.createRegularExpression(value.regexp); if (regexp === undefined) { return undefined; } - let result: ProblemPattern = { regexp }; + let result: IProblemPattern = { regexp }; if (value.kind) { result.kind = ProblemLocationKind.fromString(value.kind); } - function copyProperty(result: ProblemPattern, source: Config.ProblemPattern, resultKey: keyof ProblemPattern, sourceKey: keyof Config.ProblemPattern) { + function copyProperty(result: IProblemPattern, source: Config.IProblemPattern, resultKey: keyof IProblemPattern, sourceKey: keyof Config.IProblemPattern) { const value = source[sourceKey]; if (typeof value === 'number') { (result as any)[resultKey] = value; @@ -945,13 +945,13 @@ export class ProblemPatternParser extends Parser { } if (setDefaults) { if (result.location || result.kind === ProblemLocationKind.File) { - let defaultValue: Partial = { + let defaultValue: Partial = { file: 1, message: 0 }; result = Objects.mixin(result, defaultValue, false); } else { - let defaultValue: Partial = { + let defaultValue: Partial = { file: 1, line: 2, character: 3, @@ -963,7 +963,7 @@ export class ProblemPatternParser extends Parser { return result; } - private validateProblemPattern(values: ProblemPattern[]): boolean { + private validateProblemPattern(values: IProblemPattern[]): boolean { let file: boolean = false, message: boolean = false, location: boolean = false, line: boolean = false; let locationKind = (values[0].kind === undefined) ? ProblemLocationKind.Location : values[0].kind; @@ -1136,12 +1136,12 @@ const problemPatternExtPoint = ExtensionsRegistry.registerExtensionPoint; - get(key: string): ProblemPattern | MultiLineProblemPattern; + get(key: string): IProblemPattern | MultiLineProblemPattern; } class ProblemPatternRegistryImpl implements IProblemPatternRegistry { - private patterns: IStringDictionary; + private patterns: IStringDictionary; private readyPromise: Promise; constructor() { @@ -1196,11 +1196,11 @@ class ProblemPatternRegistryImpl implements IProblemPatternRegistry { return this.readyPromise; } - public add(key: string, value: ProblemPattern | ProblemPattern[]): void { + public add(key: string, value: IProblemPattern | IProblemPattern[]): void { this.patterns[key] = value; } - public get(key: string): ProblemPattern | ProblemPattern[] { + public get(key: string): IProblemPattern | IProblemPattern[] { return this.patterns[key]; } @@ -1447,13 +1447,13 @@ export class ProblemMatcherParser extends Parser { } } if (Config.isNamedProblemMatcher(description)) { - (result as NamedProblemMatcher).name = description.name; - (result as NamedProblemMatcher).label = Types.isString(description.label) ? description.label : description.name; + (result as INamedProblemMatcher).name = description.name; + (result as INamedProblemMatcher).label = Types.isString(description.label) ? description.label : description.name; } return result; } - private createProblemPattern(value: string | Config.ProblemPattern | Config.MultiLineProblemPattern): ProblemPattern | ProblemPattern[] | null { + private createProblemPattern(value: string | Config.IProblemPattern | Config.MultiLineProblemPattern): IProblemPattern | IProblemPattern[] | null { if (Types.isString(value)) { let variableName: string = value; if (variableName.length > 1 && variableName[0] === '$') { @@ -1495,8 +1495,8 @@ export class ProblemMatcherParser extends Parser { if (Types.isUndefinedOrNull(backgroundMonitor)) { return; } - let begins: WatchingPattern | null = this.createWatchingPattern(backgroundMonitor.beginsPattern); - let ends: WatchingPattern | null = this.createWatchingPattern(backgroundMonitor.endsPattern); + let begins: IWatchingPattern | null = this.createWatchingPattern(backgroundMonitor.beginsPattern); + let ends: IWatchingPattern | null = this.createWatchingPattern(backgroundMonitor.endsPattern); if (begins && ends) { internal.watching = { activeOnStart: Types.isBoolean(backgroundMonitor.activeOnStart) ? backgroundMonitor.activeOnStart : false, @@ -1510,7 +1510,7 @@ export class ProblemMatcherParser extends Parser { } } - private createWatchingPattern(external: string | Config.WatchingPattern | undefined): WatchingPattern | null { + private createWatchingPattern(external: string | Config.IWatchingPattern | undefined): IWatchingPattern | null { if (Types.isUndefinedOrNull(external)) { return null; } @@ -1703,7 +1703,7 @@ export namespace Schemas { }; } -const problemMatchersExtPoint = ExtensionsRegistry.registerExtensionPoint({ +const problemMatchersExtPoint = ExtensionsRegistry.registerExtensionPoint({ extensionPoint: 'problemMatchers', deps: [problemPatternExtPoint], jsonSchema: { @@ -1715,14 +1715,14 @@ const problemMatchersExtPoint = ExtensionsRegistry.registerExtensionPoint; - get(name: string): NamedProblemMatcher; + get(name: string): INamedProblemMatcher; keys(): string[]; readonly onMatcherChanged: Event; } class ProblemMatcherRegistryImpl implements IProblemMatcherRegistry { - private matchers: IStringDictionary; + private matchers: IStringDictionary; private readyPromise: Promise; private readonly _onMatchersChanged: Emitter = new Emitter(); public readonly onMatcherChanged: Event = this._onMatchersChanged.event; @@ -1771,11 +1771,11 @@ class ProblemMatcherRegistryImpl implements IProblemMatcherRegistry { return this.readyPromise; } - public add(matcher: NamedProblemMatcher): void { + public add(matcher: INamedProblemMatcher): void { this.matchers[matcher.name] = matcher; } - public get(name: string): NamedProblemMatcher { + public get(name: string): INamedProblemMatcher { return this.matchers[name]; } diff --git a/src/vs/workbench/contrib/tasks/common/taskConfiguration.ts b/src/vs/workbench/contrib/tasks/common/taskConfiguration.ts index 938472b690d..a2b5524e808 100644 --- a/src/vs/workbench/contrib/tasks/common/taskConfiguration.ts +++ b/src/vs/workbench/contrib/tasks/common/taskConfiguration.ts @@ -14,7 +14,7 @@ import * as UUID from 'vs/base/common/uuid'; import { ValidationStatus, IProblemReporter as IProblemReporterBase } from 'vs/base/common/parsers'; import { - NamedProblemMatcher, ProblemMatcherParser, Config as ProblemMatcherConfig, + INamedProblemMatcher, ProblemMatcherParser, Config as ProblemMatcherConfig, isNamedProblemMatcher, ProblemMatcherRegistry, ProblemMatcher } from 'vs/workbench/contrib/tasks/common/problemMatcher'; @@ -43,7 +43,7 @@ export const enum ShellQuoting { weak = 3 } -export interface ShellQuotingOptions { +export interface IShellQuotingOptions { /** * The character used to do character escaping. */ @@ -63,13 +63,13 @@ export interface ShellQuotingOptions { weak?: string; } -export interface ShellConfiguration { +export interface IShellConfiguration { executable?: string; args?: string[]; - quoting?: ShellQuotingOptions; + quoting?: IShellQuotingOptions; } -export interface CommandOptionsConfig { +export interface ICommandOptionsConfig { /** * The current working directory of the executed program or shell. * If omitted VSCode's current workspace root is used. @@ -85,10 +85,10 @@ export interface CommandOptionsConfig { /** * The shell configuration; */ - shell?: ShellConfiguration; + shell?: IShellConfiguration; } -export interface PresentationOptionsConfig { +export interface IPresentationOptionsConfig { /** * Controls whether the terminal executing a task is brought to front or not. * Defaults to `RevealKind.Always`. @@ -137,25 +137,25 @@ export interface PresentationOptionsConfig { close?: boolean; } -export interface RunOptionsConfig { +export interface IRunOptionsConfig { reevaluateOnRerun?: boolean; runOn?: string; instanceLimit?: number; } -export interface TaskIdentifier { +export interface ITaskIdentifier { type?: string; [name: string]: any; } -export namespace TaskIdentifier { - export function is(value: any): value is TaskIdentifier { - let candidate: TaskIdentifier = value; +export namespace ITaskIdentifier { + export function is(value: any): value is ITaskIdentifier { + let candidate: ITaskIdentifier = value; return candidate !== undefined && Types.isString(value.type); } } -export interface LegacyTaskProperties { +export interface ILegacyTaskProperties { /** * @deprecated Use `isBackground` instead. * Whether the executed command is kept alive and is watching the file system. @@ -175,7 +175,7 @@ export interface LegacyTaskProperties { isTestCommand?: boolean; } -export interface LegacyCommandProperties { +export interface ILegacyCommandProperties { /** * Whether this is a shell or process @@ -198,7 +198,7 @@ export interface LegacyCommandProperties { /** * @deprecated Use presentation instead */ - terminal?: PresentationOptionsConfig; + terminal?: IPresentationOptionsConfig; /** * @deprecated Use inline commands. @@ -220,7 +220,7 @@ export interface LegacyCommandProperties { * * Defaults to false if omitted. */ - isShellCommand?: boolean | ShellConfiguration; + isShellCommand?: boolean | IShellConfiguration; } export type CommandString = string | string[] | { value: string | string[]; quoting: 'escape' | 'strong' | 'weak' }; @@ -241,7 +241,7 @@ export namespace CommandString { } } -export interface BaseCommandProperties { +export interface IBaseCommandProperties { /** * The command to be executed. Can be an external program or a shell @@ -252,7 +252,7 @@ export interface BaseCommandProperties { /** * The command options used when the command is executed. Can be omitted. */ - options?: CommandOptionsConfig; + options?: ICommandOptionsConfig; /** * The arguments passed to the command or additional arguments passed to the @@ -262,30 +262,30 @@ export interface BaseCommandProperties { } -export interface CommandProperties extends BaseCommandProperties { +export interface ICommandProperties extends IBaseCommandProperties { /** * Windows specific command properties */ - windows?: BaseCommandProperties; + windows?: IBaseCommandProperties; /** * OSX specific command properties */ - osx?: BaseCommandProperties; + osx?: IBaseCommandProperties; /** * linux specific command properties */ - linux?: BaseCommandProperties; + linux?: IBaseCommandProperties; } -export interface GroupKind { +export interface IGroupKind { kind?: string; isDefault?: boolean | string; } -export interface ConfigurationProperties { +export interface IConfigurationProperties { /** * The task's name */ @@ -315,7 +315,7 @@ export interface ConfigurationProperties { /** * Defines the group the task belongs too. */ - group?: string | GroupKind; + group?: string | IGroupKind; /** * A description of the task. @@ -325,7 +325,7 @@ export interface ConfigurationProperties { /** * The other tasks the task depend on */ - dependsOn?: string | TaskIdentifier | Array; + dependsOn?: string | ITaskIdentifier | Array; /** * The order the dependsOn tasks should be executed in. @@ -335,12 +335,12 @@ export interface ConfigurationProperties { /** * Controls the behavior of the used terminal */ - presentation?: PresentationOptionsConfig; + presentation?: IPresentationOptionsConfig; /** * Controls shell options. */ - options?: CommandOptionsConfig; + options?: ICommandOptionsConfig; /** * The problem matcher(s) to use to capture problems in the tasks @@ -351,10 +351,10 @@ export interface ConfigurationProperties { /** * Task run options. Control run related properties. */ - runOptions?: RunOptionsConfig; + runOptions?: IRunOptionsConfig; } -export interface CustomTask extends CommandProperties, ConfigurationProperties { +export interface ICustomTask extends ICommandProperties, IConfigurationProperties { /** * Custom tasks have the type CUSTOMIZED_TASK_TYPE */ @@ -362,7 +362,7 @@ export interface CustomTask extends CommandProperties, ConfigurationProperties { } -export interface ConfiguringTask extends ConfigurationProperties { +export interface IConfiguringTask extends IConfigurationProperties { /** * The contributed type of the task */ @@ -372,7 +372,7 @@ export interface ConfiguringTask extends ConfigurationProperties { /** * The base task runner configuration */ -export interface BaseTaskRunnerConfiguration { +export interface IBaseTaskRunnerConfiguration { /** * The command to be executed. Can be an external program or a shell @@ -398,7 +398,7 @@ export interface BaseTaskRunnerConfiguration { /** * The command options used when the command is executed. Can be omitted. */ - options?: CommandOptionsConfig; + options?: ICommandOptionsConfig; /** * The arguments passed to the command. Can be omitted. @@ -424,12 +424,12 @@ export interface BaseTaskRunnerConfiguration { /** * The group */ - group?: string | GroupKind; + group?: string | IGroupKind; /** * Controls the behavior of the used terminal */ - presentation?: PresentationOptionsConfig; + presentation?: IPresentationOptionsConfig; /** * If set to false the task name is added as an additional argument to the @@ -475,12 +475,12 @@ export interface BaseTaskRunnerConfiguration { * The configuration of the available tasks. A tasks.json file can either * contain a global problemMatcher property or a tasks property but not both. */ - tasks?: Array; + tasks?: Array; /** * Problem matcher declarations. */ - declares?: ProblemMatcherConfig.NamedProblemMatcher[]; + declares?: ProblemMatcherConfig.INamedProblemMatcher[]; /** * Optional user input variables. @@ -492,7 +492,7 @@ export interface BaseTaskRunnerConfiguration { * A configuration of an external build system. BuildConfiguration.buildSystem * must be set to 'program' */ -export interface ExternalTaskRunnerConfiguration extends BaseTaskRunnerConfiguration { +export interface IExternalTaskRunnerConfiguration extends IBaseTaskRunnerConfiguration { _runner?: string; @@ -509,17 +509,17 @@ export interface ExternalTaskRunnerConfiguration extends BaseTaskRunnerConfigura /** * Windows specific task configuration */ - windows?: BaseTaskRunnerConfiguration; + windows?: IBaseTaskRunnerConfiguration; /** * Mac specific task configuration */ - osx?: BaseTaskRunnerConfiguration; + osx?: IBaseTaskRunnerConfiguration; /** * Linux specific task configuration */ - linux?: BaseTaskRunnerConfiguration; + linux?: IBaseTaskRunnerConfiguration; } enum ProblemMatcherKind { @@ -552,21 +552,21 @@ function fillProperty(target: T, source: Partial, key: } -interface ParserType { +interface IParserType { isEmpty(value: T | undefined): boolean; assignProperties(target: T | undefined, source: T | undefined): T | undefined; fillProperties(target: T | undefined, source: T | undefined): T | undefined; - fillDefaults(value: T | undefined, context: ParseContext): T | undefined; + fillDefaults(value: T | undefined, context: IParseContext): T | undefined; freeze(value: T): Readonly | undefined; } -interface MetaData { +interface IMetaData { property: keyof T; - type?: ParserType; + type?: IParserType; } -function _isEmpty(this: void, value: T | undefined, properties: MetaData[] | undefined, allowEmptyArray: boolean = false): boolean { +function _isEmpty(this: void, value: T | undefined, properties: IMetaData[] | undefined, allowEmptyArray: boolean = false): boolean { if (value === undefined || value === null || properties === undefined) { return true; } @@ -583,7 +583,7 @@ function _isEmpty(this: void, value: T | undefined, properties: MetaData(this: void, target: T | undefined, source: T | undefined, properties: MetaData[]): T | undefined { +function _assignProperties(this: void, target: T | undefined, source: T | undefined, properties: IMetaData[]): T | undefined { if (!source || _isEmpty(source, properties)) { return target; } @@ -605,7 +605,7 @@ function _assignProperties(this: void, target: T | undefined, source: T | und return target; } -function _fillProperties(this: void, target: T | undefined, source: T | undefined, properties: MetaData[] | undefined, allowEmptyArray: boolean = false): T | undefined { +function _fillProperties(this: void, target: T | undefined, source: T | undefined, properties: IMetaData[] | undefined, allowEmptyArray: boolean = false): T | undefined { if (!source || _isEmpty(source, properties)) { return target; } @@ -627,7 +627,7 @@ function _fillProperties(this: void, target: T | undefined, source: T | undef return target; } -function _fillDefaults(this: void, target: T | undefined, defaults: T | undefined, properties: MetaData[], context: ParseContext): T | undefined { +function _fillDefaults(this: void, target: T | undefined, defaults: T | undefined, properties: IMetaData[], context: IParseContext): T | undefined { if (target && Object.isFrozen(target)) { return target; } @@ -657,7 +657,7 @@ function _fillDefaults(this: void, target: T | undefined, defaults: T | undef return target; } -function _freeze(this: void, target: T, properties: MetaData[]): Readonly | undefined { +function _freeze(this: void, target: T, properties: IMetaData[]): Readonly | undefined { if (target === undefined || target === null) { return undefined; } @@ -692,8 +692,8 @@ export namespace RunOnOptions { } export namespace RunOptions { - const properties: MetaData[] = [{ property: 'reevaluateOnRerun' }, { property: 'runOn' }, { property: 'instanceLimit' }]; - export function fromConfiguration(value: RunOptionsConfig | undefined): Tasks.RunOptions { + const properties: IMetaData[] = [{ property: 'reevaluateOnRerun' }, { property: 'runOn' }, { property: 'instanceLimit' }]; + export function fromConfiguration(value: IRunOptionsConfig | undefined): Tasks.IRunOptions { return { reevaluateOnRerun: value ? value.reevaluateOnRerun : true, runOn: value ? RunOnOptions.fromString(value.runOn) : Tasks.RunOnOptions.default, @@ -701,20 +701,20 @@ export namespace RunOptions { }; } - export function assignProperties(target: Tasks.RunOptions, source: Tasks.RunOptions | undefined): Tasks.RunOptions { + export function assignProperties(target: Tasks.IRunOptions, source: Tasks.IRunOptions | undefined): Tasks.IRunOptions { return _assignProperties(target, source, properties)!; } - export function fillProperties(target: Tasks.RunOptions, source: Tasks.RunOptions | undefined): Tasks.RunOptions { + export function fillProperties(target: Tasks.IRunOptions, source: Tasks.IRunOptions | undefined): Tasks.IRunOptions { return _fillProperties(target, source, properties)!; } } -export interface ParseContext { +export interface IParseContext { workspaceFolder: IWorkspaceFolder; workspace: IWorkspace | undefined; problemReporter: IProblemReporter; - namedProblemMatchers: IStringDictionary; + namedProblemMatchers: IStringDictionary; uuidMap: UUIDMap; engine: Tasks.ExecutionEngine; schemaVersion: Tasks.JsonSchemaVersion; @@ -726,18 +726,18 @@ export interface ParseContext { namespace ShellConfiguration { - const properties: MetaData[] = [{ property: 'executable' }, { property: 'args' }, { property: 'quoting' }]; + const properties: IMetaData[] = [{ property: 'executable' }, { property: 'args' }, { property: 'quoting' }]; - export function is(value: any): value is ShellConfiguration { - let candidate: ShellConfiguration = value; + export function is(value: any): value is IShellConfiguration { + let candidate: IShellConfiguration = value; return candidate && (Types.isString(candidate.executable) || Types.isStringArray(candidate.args)); } - export function from(this: void, config: ShellConfiguration | undefined, context: ParseContext): Tasks.ShellConfiguration | undefined { + export function from(this: void, config: IShellConfiguration | undefined, context: IParseContext): Tasks.IShellConfiguration | undefined { if (!is(config)) { return undefined; } - let result: ShellConfiguration = {}; + let result: IShellConfiguration = {}; if (config.executable !== undefined) { result.executable = config.executable; } @@ -751,23 +751,23 @@ namespace ShellConfiguration { return result; } - export function isEmpty(this: void, value: Tasks.ShellConfiguration): boolean { + export function isEmpty(this: void, value: Tasks.IShellConfiguration): boolean { return _isEmpty(value, properties, true); } - export function assignProperties(this: void, target: Tasks.ShellConfiguration | undefined, source: Tasks.ShellConfiguration | undefined): Tasks.ShellConfiguration | undefined { + export function assignProperties(this: void, target: Tasks.IShellConfiguration | undefined, source: Tasks.IShellConfiguration | undefined): Tasks.IShellConfiguration | undefined { return _assignProperties(target, source, properties); } - export function fillProperties(this: void, target: Tasks.ShellConfiguration, source: Tasks.ShellConfiguration): Tasks.ShellConfiguration | undefined { + export function fillProperties(this: void, target: Tasks.IShellConfiguration, source: Tasks.IShellConfiguration): Tasks.IShellConfiguration | undefined { return _fillProperties(target, source, properties, true); } - export function fillDefaults(this: void, value: Tasks.ShellConfiguration, context: ParseContext): Tasks.ShellConfiguration { + export function fillDefaults(this: void, value: Tasks.IShellConfiguration, context: IParseContext): Tasks.IShellConfiguration { return value; } - export function freeze(this: void, value: Tasks.ShellConfiguration): Readonly | undefined { + export function freeze(this: void, value: Tasks.IShellConfiguration): Readonly | undefined { if (!value) { return undefined; } @@ -777,10 +777,10 @@ namespace ShellConfiguration { namespace CommandOptions { - const properties: MetaData[] = [{ property: 'cwd' }, { property: 'env' }, { property: 'shell', type: ShellConfiguration }]; - const defaults: CommandOptionsConfig = { cwd: '${workspaceFolder}' }; + const properties: IMetaData[] = [{ property: 'cwd' }, { property: 'env' }, { property: 'shell', type: ShellConfiguration }]; + const defaults: ICommandOptionsConfig = { cwd: '${workspaceFolder}' }; - export function from(this: void, options: CommandOptionsConfig, context: ParseContext): Tasks.CommandOptions | undefined { + export function from(this: void, options: ICommandOptionsConfig, context: IParseContext): Tasks.CommandOptions | undefined { let result: Tasks.CommandOptions = {}; if (options.cwd !== undefined) { if (Types.isString(options.cwd)) { @@ -828,7 +828,7 @@ namespace CommandOptions { return _fillProperties(target, source, properties); } - export function fillDefaults(value: Tasks.CommandOptions | undefined, context: ParseContext): Tasks.CommandOptions | undefined { + export function fillDefaults(value: Tasks.CommandOptions | undefined, context: IParseContext): Tasks.CommandOptions | undefined { return _fillDefaults(value, defaults, properties, context); } @@ -840,13 +840,13 @@ namespace CommandOptions { namespace CommandConfiguration { export namespace PresentationOptions { - const properties: MetaData[] = [{ property: 'echo' }, { property: 'reveal' }, { property: 'revealProblems' }, { property: 'focus' }, { property: 'panel' }, { property: 'showReuseMessage' }, { property: 'clear' }, { property: 'group' }, { property: 'close' }]; + const properties: IMetaData[] = [{ property: 'echo' }, { property: 'reveal' }, { property: 'revealProblems' }, { property: 'focus' }, { property: 'panel' }, { property: 'showReuseMessage' }, { property: 'clear' }, { property: 'group' }, { property: 'close' }]; - interface PresentationOptionsShape extends LegacyCommandProperties { - presentation?: PresentationOptionsConfig; + interface IPresentationOptionsShape extends ILegacyCommandProperties { + presentation?: IPresentationOptionsConfig; } - export function from(this: void, config: PresentationOptionsShape, context: ParseContext): Tasks.PresentationOptions | undefined { + export function from(this: void, config: IPresentationOptionsShape, context: IParseContext): Tasks.IPresentationOptions | undefined { let echo: boolean; let reveal: Tasks.RevealKind; let revealProblems: Tasks.RevealProblemKind; @@ -902,24 +902,24 @@ namespace CommandConfiguration { return { echo: echo!, reveal: reveal!, revealProblems: revealProblems!, focus: focus!, panel: panel!, showReuseMessage: showReuseMessage!, clear: clear!, group, close: close }; } - export function assignProperties(target: Tasks.PresentationOptions, source: Tasks.PresentationOptions | undefined): Tasks.PresentationOptions | undefined { + export function assignProperties(target: Tasks.IPresentationOptions, source: Tasks.IPresentationOptions | undefined): Tasks.IPresentationOptions | undefined { return _assignProperties(target, source, properties); } - export function fillProperties(target: Tasks.PresentationOptions, source: Tasks.PresentationOptions | undefined): Tasks.PresentationOptions | undefined { + export function fillProperties(target: Tasks.IPresentationOptions, source: Tasks.IPresentationOptions | undefined): Tasks.IPresentationOptions | undefined { return _fillProperties(target, source, properties); } - export function fillDefaults(value: Tasks.PresentationOptions, context: ParseContext): Tasks.PresentationOptions | undefined { + export function fillDefaults(value: Tasks.IPresentationOptions, context: IParseContext): Tasks.IPresentationOptions | undefined { let defaultEcho = context.engine === Tasks.ExecutionEngine.Terminal ? true : false; return _fillDefaults(value, { echo: defaultEcho, reveal: Tasks.RevealKind.Always, revealProblems: Tasks.RevealProblemKind.Never, focus: false, panel: Tasks.PanelKind.Shared, showReuseMessage: true, clear: false }, properties, context); } - export function freeze(value: Tasks.PresentationOptions): Readonly | undefined { + export function freeze(value: Tasks.IPresentationOptions): Readonly | undefined { return _freeze(value, properties); } - export function isEmpty(this: void, value: Tasks.PresentationOptions): boolean { + export function isEmpty(this: void, value: Tasks.IPresentationOptions): boolean { return _isEmpty(value, properties); } } @@ -948,25 +948,25 @@ namespace CommandConfiguration { } } - interface BaseCommandConfigurationShape extends BaseCommandProperties, LegacyCommandProperties { + interface IBaseCommandConfigurationShape extends IBaseCommandProperties, ILegacyCommandProperties { } - interface CommandConfigurationShape extends BaseCommandConfigurationShape { - windows?: BaseCommandConfigurationShape; - osx?: BaseCommandConfigurationShape; - linux?: BaseCommandConfigurationShape; + interface ICommandConfigurationShape extends IBaseCommandConfigurationShape { + windows?: IBaseCommandConfigurationShape; + osx?: IBaseCommandConfigurationShape; + linux?: IBaseCommandConfigurationShape; } - const properties: MetaData[] = [ + const properties: IMetaData[] = [ { property: 'runtime' }, { property: 'name' }, { property: 'options', type: CommandOptions }, { property: 'args' }, { property: 'taskSelector' }, { property: 'suppressTaskName' }, { property: 'presentation', type: PresentationOptions } ]; - export function from(this: void, config: CommandConfigurationShape, context: ParseContext): Tasks.CommandConfiguration | undefined { - let result: Tasks.CommandConfiguration = fromBase(config, context)!; + export function from(this: void, config: ICommandConfigurationShape, context: IParseContext): Tasks.ICommandConfiguration | undefined { + let result: Tasks.ICommandConfiguration = fromBase(config, context)!; - let osConfig: Tasks.CommandConfiguration | undefined = undefined; + let osConfig: Tasks.ICommandConfiguration | undefined = undefined; if (config.windows && context.platform === Platform.Windows) { osConfig = fromBase(config.windows, context); } else if (config.osx && context.platform === Platform.Mac) { @@ -980,7 +980,7 @@ namespace CommandConfiguration { return isEmpty(result) ? undefined : result; } - function fromBase(this: void, config: BaseCommandConfigurationShape, context: ParseContext): Tasks.CommandConfiguration | undefined { + function fromBase(this: void, config: IBaseCommandConfigurationShape, context: IParseContext): Tasks.ICommandConfiguration | undefined { let name: Tasks.CommandString | undefined = ShellString.from(config.command); let runtime: Tasks.RuntimeType; if (Types.isString(config.type)) { @@ -995,7 +995,7 @@ namespace CommandConfiguration { runtime = !!config.isShellCommand ? Tasks.RuntimeType.Shell : Tasks.RuntimeType.Process; } - let result: Tasks.CommandConfiguration = { + let result: Tasks.ICommandConfiguration = { name: name, runtime: runtime!, presentation: PresentationOptions.from(config, context)! @@ -1020,7 +1020,7 @@ namespace CommandConfiguration { if (config.options !== undefined) { result.options = CommandOptions.from(config.options, context); if (result.options && result.options.shell === undefined && isShellConfiguration) { - result.options.shell = ShellConfiguration.from(config.isShellCommand as ShellConfiguration, context); + result.options.shell = ShellConfiguration.from(config.isShellCommand as IShellConfiguration, context); if (context.engine !== Tasks.ExecutionEngine.Terminal) { context.taskLoadIssues.push(nls.localize('ConfigurationParser.noShell', 'Warning: shell configuration is only supported when executing tasks in the terminal.')); } @@ -1037,15 +1037,15 @@ namespace CommandConfiguration { return isEmpty(result) ? undefined : result; } - export function hasCommand(value: Tasks.CommandConfiguration): boolean { + export function hasCommand(value: Tasks.ICommandConfiguration): boolean { return value && !!value.name; } - export function isEmpty(value: Tasks.CommandConfiguration | undefined): boolean { + export function isEmpty(value: Tasks.ICommandConfiguration | undefined): boolean { return _isEmpty(value, properties); } - export function assignProperties(target: Tasks.CommandConfiguration, source: Tasks.CommandConfiguration, overwriteArgs: boolean): Tasks.CommandConfiguration { + export function assignProperties(target: Tasks.ICommandConfiguration, source: Tasks.ICommandConfiguration, overwriteArgs: boolean): Tasks.ICommandConfiguration { if (isEmpty(source)) { return target; } @@ -1068,11 +1068,11 @@ namespace CommandConfiguration { return target; } - export function fillProperties(target: Tasks.CommandConfiguration, source: Tasks.CommandConfiguration): Tasks.CommandConfiguration | undefined { + export function fillProperties(target: Tasks.ICommandConfiguration, source: Tasks.ICommandConfiguration): Tasks.ICommandConfiguration | undefined { return _fillProperties(target, source, properties); } - export function fillGlobals(target: Tasks.CommandConfiguration, source: Tasks.CommandConfiguration | undefined, taskName: string | undefined): Tasks.CommandConfiguration { + export function fillGlobals(target: Tasks.ICommandConfiguration, source: Tasks.ICommandConfiguration | undefined, taskName: string | undefined): Tasks.ICommandConfiguration { if ((source === undefined) || isEmpty(source)) { return target; } @@ -1106,7 +1106,7 @@ namespace CommandConfiguration { return target; } - export function fillDefaults(value: Tasks.CommandConfiguration | undefined, context: ParseContext): void { + export function fillDefaults(value: Tasks.ICommandConfiguration | undefined, context: IParseContext): void { if (!value || Object.isFrozen(value)) { return; } @@ -1125,20 +1125,20 @@ namespace CommandConfiguration { } } - export function freeze(value: Tasks.CommandConfiguration): Readonly | undefined { + export function freeze(value: Tasks.ICommandConfiguration): Readonly | undefined { return _freeze(value, properties); } } export namespace ProblemMatcherConverter { - export function namedFrom(this: void, declares: ProblemMatcherConfig.NamedProblemMatcher[] | undefined, context: ParseContext): IStringDictionary { - let result: IStringDictionary = Object.create(null); + export function namedFrom(this: void, declares: ProblemMatcherConfig.INamedProblemMatcher[] | undefined, context: IParseContext): IStringDictionary { + let result: IStringDictionary = Object.create(null); if (!Types.isArray(declares)) { return result; } - (declares).forEach((value) => { + (declares).forEach((value) => { let namedProblemMatcher = (new ProblemMatcherParser(context.problemReporter)).parse(value); if (isNamedProblemMatcher(namedProblemMatcher)) { result[namedProblemMatcher.name] = namedProblemMatcher; @@ -1149,7 +1149,7 @@ export namespace ProblemMatcherConverter { return result; } - export function fromWithOsConfig(this: void, external: ConfigurationProperties & { [key: string]: any }, context: ParseContext): TaskConfigurationValueWithErrors { + export function fromWithOsConfig(this: void, external: IConfigurationProperties & { [key: string]: any }, context: IParseContext): TaskConfigurationValueWithErrors { let result: TaskConfigurationValueWithErrors = {}; if (external.windows && external.windows.problemMatcher && context.platform === Platform.Windows) { result = from(external.windows.problemMatcher, context); @@ -1163,7 +1163,7 @@ export namespace ProblemMatcherConverter { return result; } - export function from(this: void, config: ProblemMatcherConfig.ProblemMatcherType | undefined, context: ParseContext): TaskConfigurationValueWithErrors { + export function from(this: void, config: ProblemMatcherConfig.ProblemMatcherType | undefined, context: IParseContext): TaskConfigurationValueWithErrors { let result: ProblemMatcher[] = []; if (config === undefined) { return { value: result }; @@ -1207,7 +1207,7 @@ export namespace ProblemMatcherConverter { } } - function resolveProblemMatcher(this: void, value: string | ProblemMatcherConfig.ProblemMatcher, context: ParseContext): TaskConfigurationValueWithErrors { + function resolveProblemMatcher(this: void, value: string | ProblemMatcherConfig.ProblemMatcher, context: IParseContext): TaskConfigurationValueWithErrors { if (Types.isString(value)) { let variableName = value; if (variableName.length > 1 && variableName[0] === '$') { @@ -1216,7 +1216,7 @@ export namespace ProblemMatcherConverter { if (global) { return { value: Objects.deepClone(global) }; } - let localProblemMatcher: ProblemMatcher & Partial = context.namedProblemMatchers[variableName]; + let localProblemMatcher: ProblemMatcher & Partial = context.namedProblemMatchers[variableName]; if (localProblemMatcher) { localProblemMatcher = Objects.deepClone(localProblemMatcher); // remove the name @@ -1238,7 +1238,7 @@ const partialSource: Partial = { }; export namespace GroupKind { - export function from(this: void, external: string | GroupKind | undefined): Tasks.TaskGroup | undefined { + export function from(this: void, external: string | IGroupKind | undefined): Tasks.TaskGroup | undefined { if (external === undefined) { return undefined; } else if (Types.isString(external) && Tasks.TaskGroup.is(external)) { @@ -1252,7 +1252,7 @@ export namespace GroupKind { return undefined; } - export function to(group: Tasks.TaskGroup | string): GroupKind | string { + export function to(group: Tasks.TaskGroup | string): IGroupKind | string { if (Types.isString(group)) { return group; } else if (!group.isDefault) { @@ -1266,7 +1266,7 @@ export namespace GroupKind { } namespace TaskDependency { - function uriFromSource(context: ParseContext, source: TaskConfigSource): URI | string { + function uriFromSource(context: IParseContext, source: TaskConfigSource): URI | string { switch (source) { case TaskConfigSource.User: return Tasks.USER_TASKS_GROUP_KEY; case TaskConfigSource.TasksJson: return context.workspaceFolder.uri; @@ -1274,13 +1274,13 @@ namespace TaskDependency { } } - export function from(this: void, external: string | TaskIdentifier, context: ParseContext, source: TaskConfigSource): Tasks.TaskDependency | undefined { + export function from(this: void, external: string | ITaskIdentifier, context: IParseContext, source: TaskConfigSource): Tasks.ITaskDependency | undefined { if (Types.isString(external)) { return { uri: uriFromSource(context, source), task: external }; - } else if (TaskIdentifier.is(external)) { + } else if (ITaskIdentifier.is(external)) { return { uri: uriFromSource(context, source), - task: Tasks.TaskDefinition.createTaskIdentifier(external as Tasks.TaskIdentifier, context.problemReporter) + task: Tasks.TaskDefinition.createTaskIdentifier(external as Tasks.ITaskIdentifier, context.problemReporter) }; } else { return undefined; @@ -1302,7 +1302,7 @@ namespace DependsOrder { namespace ConfigurationProperties { - const properties: MetaData[] = [ + const properties: IMetaData[] = [ { property: 'name' }, { property: 'identifier' }, { property: 'group' }, { property: 'isBackground' }, { property: 'promptOnClose' }, { property: 'dependsOn' }, @@ -1310,12 +1310,12 @@ namespace ConfigurationProperties { { property: 'options' } ]; - export function from(this: void, external: ConfigurationProperties & { [key: string]: any }, context: ParseContext, - includeCommandOptions: boolean, source: TaskConfigSource, properties?: IJSONSchemaMap): TaskConfigurationValueWithErrors { + export function from(this: void, external: IConfigurationProperties & { [key: string]: any }, context: IParseContext, + includeCommandOptions: boolean, source: TaskConfigSource, properties?: IJSONSchemaMap): TaskConfigurationValueWithErrors { if (!external) { return {}; } - let result: Tasks.ConfigurationProperties & { [key: string]: any } = {}; + let result: Tasks.IConfigurationProperties & { [key: string]: any } = {}; if (properties) { for (const propertyName of Object.keys(properties)) { @@ -1343,7 +1343,7 @@ namespace ConfigurationProperties { result.group = GroupKind.from(external.group); if (external.dependsOn !== undefined) { if (Types.isArray(external.dependsOn)) { - result.dependsOn = external.dependsOn.reduce((dependencies: Tasks.TaskDependency[], item): Tasks.TaskDependency[] => { + result.dependsOn = external.dependsOn.reduce((dependencies: Tasks.ITaskDependency[], item): Tasks.ITaskDependency[] => { const dependency = TaskDependency.from(item, context, source); if (dependency) { dependencies.push(dependency); @@ -1356,7 +1356,7 @@ namespace ConfigurationProperties { } } result.dependsOrder = DependsOrder.from(external.dependsOrder); - if (includeCommandOptions && (external.presentation !== undefined || (external as LegacyCommandProperties).terminal !== undefined)) { + if (includeCommandOptions && (external.presentation !== undefined || (external as ILegacyCommandProperties).terminal !== undefined)) { result.presentation = CommandConfiguration.PresentationOptions.from(external, context); } if (includeCommandOptions && (external.options !== undefined)) { @@ -1372,7 +1372,7 @@ namespace ConfigurationProperties { return isEmpty(result) ? {} : { value: result, errors: configProblemMatcher.errors }; } - export function isEmpty(this: void, value: Tasks.ConfigurationProperties): boolean { + export function isEmpty(this: void, value: Tasks.IConfigurationProperties): boolean { return _isEmpty(value, properties); } } @@ -1385,16 +1385,16 @@ namespace ConfiguringTask { const npm = 'vscode.npm.'; const typescript = 'vscode.typescript.'; - interface CustomizeShape { + interface ICustomizeShape { customize: string; } - export function from(this: void, external: ConfiguringTask, context: ParseContext, index: number, source: TaskConfigSource, registry?: Partial): Tasks.ConfiguringTask | undefined { + export function from(this: void, external: IConfiguringTask, context: IParseContext, index: number, source: TaskConfigSource, registry?: Partial): Tasks.ConfiguringTask | undefined { if (!external) { return undefined; } let type = external.type; - let customize = (external as CustomizeShape).customize; + let customize = (external as ICustomizeShape).customize; if (!type && !customize) { context.problemReporter.error(nls.localize('ConfigurationParser.noTaskType', 'Error: tasks configuration must have a type property. The configuration will be ignored.\n{0}\n', JSON.stringify(external, null, 4))); return undefined; @@ -1405,7 +1405,7 @@ namespace ConfiguringTask { context.problemReporter.error(message); return undefined; } - let identifier: Tasks.TaskIdentifier | undefined; + let identifier: Tasks.ITaskIdentifier | undefined; if (Types.isString(customize)) { if (customize.indexOf(grunt) === 0) { identifier = { type: 'grunt', task: customize.substring(grunt.length) }; @@ -1420,7 +1420,7 @@ namespace ConfiguringTask { } } else { if (Types.isString(external.type)) { - identifier = external as Tasks.TaskIdentifier; + identifier = external as Tasks.ITaskIdentifier; } } if (identifier === undefined) { @@ -1438,7 +1438,7 @@ namespace ConfiguringTask { )); return undefined; } - let configElement: Tasks.TaskSourceConfigElement = { + let configElement: Tasks.ITaskSourceConfigElement = { workspaceFolder: context.workspaceFolder, file: '.vscode/tasks.json', index, @@ -1447,7 +1447,7 @@ namespace ConfiguringTask { let taskSource: Tasks.FileBasedTaskSource; switch (source) { case TaskConfigSource.User: { - taskSource = Object.assign({} as Tasks.UserTaskSource, partialSource, { kind: Tasks.TaskSourceKind.User, config: configElement }); + taskSource = Object.assign({} as Tasks.IUserTaskSource, partialSource, { kind: Tasks.TaskSourceKind.User, config: configElement }); break; } case TaskConfigSource.WorkspaceFile: { @@ -1455,7 +1455,7 @@ namespace ConfiguringTask { break; } default: { - taskSource = Object.assign({} as Tasks.WorkspaceTaskSource, partialSource, { kind: Tasks.TaskSourceKind.Workspace, config: configElement }); + taskSource = Object.assign({} as Tasks.IWorkspaceTaskSource, partialSource, { kind: Tasks.TaskSourceKind.Workspace, config: configElement }); break; } } @@ -1496,7 +1496,7 @@ namespace ConfiguringTask { } namespace CustomTask { - export function from(this: void, external: CustomTask, context: ParseContext, index: number, source: TaskConfigSource): Tasks.CustomTask | undefined { + export function from(this: void, external: ICustomTask, context: IParseContext, index: number, source: TaskConfigSource): Tasks.CustomTask | undefined { if (!external) { return undefined; } @@ -1520,7 +1520,7 @@ namespace CustomTask { let taskSource: Tasks.FileBasedTaskSource; switch (source) { case TaskConfigSource.User: { - taskSource = Object.assign({} as Tasks.UserTaskSource, partialSource, { kind: Tasks.TaskSourceKind.User, config: { index, element: external, file: '.vscode/tasks.json', workspaceFolder: context.workspaceFolder } }); + taskSource = Object.assign({} as Tasks.IUserTaskSource, partialSource, { kind: Tasks.TaskSourceKind.User, config: { index, element: external, file: '.vscode/tasks.json', workspaceFolder: context.workspaceFolder } }); break; } case TaskConfigSource.WorkspaceFile: { @@ -1528,7 +1528,7 @@ namespace CustomTask { break; } default: { - taskSource = Object.assign({} as Tasks.WorkspaceTaskSource, partialSource, { kind: Tasks.TaskSourceKind.Workspace, config: { index, element: external, file: '.vscode/tasks.json', workspaceFolder: context.workspaceFolder } }); + taskSource = Object.assign({} as Tasks.IWorkspaceTaskSource, partialSource, { kind: Tasks.TaskSourceKind.Workspace, config: { index, element: external, file: '.vscode/tasks.json', workspaceFolder: context.workspaceFolder } }); break; } } @@ -1553,7 +1553,7 @@ namespace CustomTask { } let supportLegacy: boolean = true; //context.schemaVersion === Tasks.JsonSchemaVersion.V2_0_0; if (supportLegacy) { - let legacy: LegacyTaskProperties = external as LegacyTaskProperties; + let legacy: ILegacyTaskProperties = external as ILegacyTaskProperties; if (result.configurationProperties.isBackground === undefined && legacy.isWatching !== undefined) { result.configurationProperties.isBackground = !!legacy.isWatching; } @@ -1565,7 +1565,7 @@ namespace CustomTask { } } } - let command: Tasks.CommandConfiguration = CommandConfiguration.from(external, context)!; + let command: Tasks.ICommandConfiguration = CommandConfiguration.from(external, context)!; if (command) { result.command = command; } @@ -1577,7 +1577,7 @@ namespace CustomTask { return result; } - export function fillGlobals(task: Tasks.CustomTask, globals: Globals): void { + export function fillGlobals(task: Tasks.CustomTask, globals: IGlobals): void { // We only merge a command from a global definition if there is no dependsOn // or there is a dependsOn and a defined command. if (CommandConfiguration.hasCommand(task.command) || task.configurationProperties.dependsOn === undefined) { @@ -1593,7 +1593,7 @@ namespace CustomTask { } } - export function fillDefaults(task: Tasks.CustomTask, context: ParseContext): void { + export function fillDefaults(task: Tasks.CustomTask, context: IParseContext): void { CommandConfiguration.fillDefaults(task.command, context); if (task.configurationProperties.promptOnClose === undefined) { task.configurationProperties.promptOnClose = task.configurationProperties.isBackground !== undefined ? !task.configurationProperties.isBackground : true; @@ -1621,7 +1621,7 @@ namespace CustomTask { } ); result.addTaskLoadMessages(configuredProps.taskLoadMessages); - let resultConfigProps: Tasks.ConfigurationProperties = result.configurationProperties; + let resultConfigProps: Tasks.IConfigurationProperties = result.configurationProperties; assignProperty(resultConfigProps, configuredProps.configurationProperties, 'group'); assignProperty(resultConfigProps, configuredProps.configurationProperties, 'isBackground'); @@ -1634,7 +1634,7 @@ namespace CustomTask { result.command.options = CommandOptions.assignProperties(result.command.options, configuredProps.configurationProperties.options); result.runOptions = RunOptions.assignProperties(result.runOptions, configuredProps.runOptions); - let contributedConfigProps: Tasks.ConfigurationProperties = contributedTask.configurationProperties; + let contributedConfigProps: Tasks.IConfigurationProperties = contributedTask.configurationProperties; fillProperty(resultConfigProps, contributedConfigProps, 'group'); fillProperty(resultConfigProps, contributedConfigProps, 'isBackground'); fillProperty(resultConfigProps, contributedConfigProps, 'dependsOn'); @@ -1654,14 +1654,14 @@ namespace CustomTask { } } -export interface TaskParseResult { +export interface ITaskParseResult { custom: Tasks.CustomTask[]; configured: Tasks.ConfiguringTask[]; } export namespace TaskParser { - function isCustomTask(value: CustomTask | ConfiguringTask): value is CustomTask { + function isCustomTask(value: ICustomTask | IConfiguringTask): value is ICustomTask { let type = value.type; let customize = (value as any).customize; return customize === undefined && (type === undefined || type === null || type === Tasks.CUSTOMIZED_TASK_TYPE || type === 'shell' || type === 'process'); @@ -1672,8 +1672,8 @@ export namespace TaskParser { process: ProcessExecutionSupportedContext }; - export function from(this: void, externals: Array | undefined, globals: Globals, context: ParseContext, source: TaskConfigSource, registry?: Partial): TaskParseResult { - let result: TaskParseResult = { custom: [], configured: [] }; + export function from(this: void, externals: Array | undefined, globals: IGlobals, context: IParseContext, source: TaskConfigSource, registry?: Partial): ITaskParseResult { + let result: ITaskParseResult = { custom: [], configured: [] }; if (!externals) { return result; } @@ -1795,8 +1795,8 @@ export namespace TaskParser { } } -export interface Globals { - command?: Tasks.CommandConfiguration; +export interface IGlobals { + command?: Tasks.ICommandConfiguration; problemMatcher?: ProblemMatcher[]; promptOnClose?: boolean; suppressTaskName?: boolean; @@ -1804,9 +1804,9 @@ export interface Globals { namespace Globals { - export function from(config: ExternalTaskRunnerConfiguration, context: ParseContext): Globals { + export function from(config: IExternalTaskRunnerConfiguration, context: IParseContext): IGlobals { let result = fromBase(config, context); - let osGlobals: Globals | undefined = undefined; + let osGlobals: IGlobals | undefined = undefined; if (config.windows && context.platform === Platform.Windows) { osGlobals = fromBase(config.windows, context); } else if (config.osx && context.platform === Platform.Mac) { @@ -1826,8 +1826,8 @@ namespace Globals { return result; } - export function fromBase(this: void, config: BaseTaskRunnerConfiguration, context: ParseContext): Globals { - let result: Globals = {}; + export function fromBase(this: void, config: IBaseTaskRunnerConfiguration, context: IParseContext): IGlobals { + let result: IGlobals = {}; if (config.suppressTaskName !== undefined) { result.suppressTaskName = !!config.suppressTaskName; } @@ -1840,11 +1840,11 @@ namespace Globals { return result; } - export function isEmpty(value: Globals): boolean { + export function isEmpty(value: IGlobals): boolean { return !value || value.command === undefined && value.promptOnClose === undefined && value.suppressTaskName === undefined; } - export function assignProperties(target: Globals, source: Globals): Globals { + export function assignProperties(target: IGlobals, source: IGlobals): IGlobals { if (isEmpty(source)) { return target; } @@ -1856,7 +1856,7 @@ namespace Globals { return target; } - export function fillDefaults(value: Globals, context: ParseContext): void { + export function fillDefaults(value: IGlobals, context: IParseContext): void { if (!value) { return; } @@ -1869,7 +1869,7 @@ namespace Globals { } } - export function freeze(value: Globals): void { + export function freeze(value: IGlobals): void { Object.freeze(value); if (value.command) { CommandConfiguration.freeze(value.command); @@ -1879,7 +1879,7 @@ namespace Globals { export namespace ExecutionEngine { - export function from(config: ExternalTaskRunnerConfiguration): Tasks.ExecutionEngine { + export function from(config: IExternalTaskRunnerConfiguration): Tasks.ExecutionEngine { let runner = config.runner || config._runner; let result: Tasks.ExecutionEngine | undefined; if (runner) { @@ -1907,7 +1907,7 @@ export namespace JsonSchemaVersion { const _default: Tasks.JsonSchemaVersion = Tasks.JsonSchemaVersion.V2_0_0; - export function from(config: ExternalTaskRunnerConfiguration): Tasks.JsonSchemaVersion { + export function from(config: IExternalTaskRunnerConfiguration): Tasks.JsonSchemaVersion { let version = config.version; if (!version) { return _default; @@ -1923,7 +1923,7 @@ export namespace JsonSchemaVersion { } } -export interface ParseResult { +export interface IParseResult { validationStatus: ValidationStatus; custom: Tasks.CustomTask[]; configured: Tasks.ConfiguringTask[]; @@ -2016,10 +2016,10 @@ class ConfigurationParser { this.uuidMap = uuidMap; } - public run(fileConfig: ExternalTaskRunnerConfiguration, source: TaskConfigSource, contextKeyService: IContextKeyService): ParseResult { + public run(fileConfig: IExternalTaskRunnerConfiguration, source: TaskConfigSource, contextKeyService: IContextKeyService): IParseResult { let engine = ExecutionEngine.from(fileConfig); let schemaVersion = JsonSchemaVersion.from(fileConfig); - let context: ParseContext = { + let context: IParseContext = { workspaceFolder: this.workspaceFolder, workspace: this.workspace, problemReporter: this.problemReporter, @@ -2040,14 +2040,14 @@ class ConfigurationParser { }; } - private createTaskRunnerConfiguration(fileConfig: ExternalTaskRunnerConfiguration, context: ParseContext, source: TaskConfigSource): TaskParseResult { + private createTaskRunnerConfiguration(fileConfig: IExternalTaskRunnerConfiguration, context: IParseContext, source: TaskConfigSource): ITaskParseResult { let globals = Globals.from(fileConfig, context); if (this.problemReporter.status.isFatal()) { return { custom: [], configured: [] }; } context.namedProblemMatchers = ProblemMatcherConverter.namedFrom(fileConfig.declares, context); let globalTasks: Tasks.CustomTask[] | undefined = undefined; - let externalGlobalTasks: Array | undefined = undefined; + let externalGlobalTasks: Array | undefined = undefined; if (fileConfig.windows && context.platform === Platform.Windows) { globalTasks = TaskParser.from(fileConfig.windows.tasks, globals, context, source).custom; externalGlobalTasks = fileConfig.windows.tasks; @@ -2070,7 +2070,7 @@ class ConfigurationParser { ); } - let result: TaskParseResult = { custom: [], configured: [] }; + let result: ITaskParseResult = { custom: [], configured: [] }; if (fileConfig.tasks) { result = TaskParser.from(fileConfig.tasks, globals, context, source); } @@ -2084,7 +2084,7 @@ class ConfigurationParser { let name = Tasks.CommandString.value(globals.command.name); let task: Tasks.CustomTask = new Tasks.CustomTask( context.uuidMap.getUUID(name), - Object.assign({} as Tasks.WorkspaceTaskSource, source, { config: { index: -1, element: fileConfig, workspaceFolder: context.workspaceFolder } }), + Object.assign({} as Tasks.IWorkspaceTaskSource, source, { config: { index: -1, element: fileConfig, workspaceFolder: context.workspaceFolder } }), name, Tasks.CUSTOMIZED_TASK_TYPE, { @@ -2121,7 +2121,7 @@ class ConfigurationParser { let uuidMaps: Map> = new Map(); let recentUuidMaps: Map> = new Map(); -export function parse(workspaceFolder: IWorkspaceFolder, workspace: IWorkspace | undefined, platform: Platform, configuration: ExternalTaskRunnerConfiguration, logger: IProblemReporter, source: TaskConfigSource, contextKeyService: IContextKeyService, isRecents: boolean = false): ParseResult { +export function parse(workspaceFolder: IWorkspaceFolder, workspace: IWorkspace | undefined, platform: Platform, configuration: IExternalTaskRunnerConfiguration, logger: IProblemReporter, source: TaskConfigSource, contextKeyService: IContextKeyService, isRecents: boolean = false): IParseResult { let recentOrOtherMaps = isRecents ? recentUuidMaps : uuidMaps; let selectedUuidMaps = recentOrOtherMaps.get(source); if (!selectedUuidMaps) { diff --git a/src/vs/workbench/contrib/tasks/common/taskDefinitionRegistry.ts b/src/vs/workbench/contrib/tasks/common/taskDefinitionRegistry.ts index b3fe1e79f8e..4ec81b1d469 100644 --- a/src/vs/workbench/contrib/tasks/common/taskDefinitionRegistry.ts +++ b/src/vs/workbench/contrib/tasks/common/taskDefinitionRegistry.ts @@ -47,14 +47,14 @@ const taskDefinitionSchema: IJSONSchema = { }; namespace Configuration { - export interface TaskDefinition { + export interface ITaskDefinition { type?: string; required?: string[]; properties?: IJSONSchemaMap; when?: string; } - export function from(value: TaskDefinition, extensionId: ExtensionIdentifier, messageCollector: ExtensionMessageCollector): Tasks.TaskDefinition | undefined { + export function from(value: ITaskDefinition, extensionId: ExtensionIdentifier, messageCollector: ExtensionMessageCollector): Tasks.ITaskDefinition | undefined { if (!value) { return undefined; } @@ -81,7 +81,7 @@ namespace Configuration { } -const taskDefinitionsExtPoint = ExtensionsRegistry.registerExtensionPoint({ +const taskDefinitionsExtPoint = ExtensionsRegistry.registerExtensionPoint({ extensionPoint: 'taskDefinitions', jsonSchema: { description: nls.localize('TaskDefinitionExtPoint', 'Contributes task kinds'), @@ -93,15 +93,15 @@ const taskDefinitionsExtPoint = ExtensionsRegistry.registerExtensionPoint; - get(key: string): Tasks.TaskDefinition; - all(): Tasks.TaskDefinition[]; + get(key: string): Tasks.ITaskDefinition; + all(): Tasks.ITaskDefinition[]; getJsonSchema(): IJSONSchema; onDefinitionsChanged: Event; } export class TaskDefinitionRegistryImpl implements ITaskDefinitionRegistry { - private taskTypes: IStringDictionary; + private taskTypes: IStringDictionary; private readyPromise: Promise; private _schema: IJSONSchema | undefined; private _onDefinitionsChanged: Emitter = new Emitter(); @@ -144,11 +144,11 @@ export class TaskDefinitionRegistryImpl implements ITaskDefinitionRegistry { return this.readyPromise; } - public get(key: string): Tasks.TaskDefinition { + public get(key: string): Tasks.ITaskDefinition { return this.taskTypes[key]; } - public all(): Tasks.TaskDefinition[] { + public all(): Tasks.ITaskDefinition[] { return Object.keys(this.taskTypes).map(key => this.taskTypes[key]); } diff --git a/src/vs/workbench/contrib/tasks/common/taskService.ts b/src/vs/workbench/contrib/tasks/common/taskService.ts index b75cd445666..dfe37cf6070 100644 --- a/src/vs/workbench/contrib/tasks/common/taskService.ts +++ b/src/vs/workbench/contrib/tasks/common/taskService.ts @@ -10,12 +10,12 @@ import { createDecorator } from 'vs/platform/instantiation/common/instantiation' import { IDisposable } from 'vs/base/common/lifecycle'; import { IWorkspaceFolder, IWorkspace } from 'vs/platform/workspace/common/workspace'; -import { Task, ContributedTask, CustomTask, TaskSet, TaskSorter, TaskEvent, TaskIdentifier, ConfiguringTask, TaskRunSource } from 'vs/workbench/contrib/tasks/common/tasks'; -import { ITaskSummary, TaskTerminateResponse, TaskSystemInfo } from 'vs/workbench/contrib/tasks/common/taskSystem'; +import { Task, ContributedTask, CustomTask, ITaskSet, TaskSorter, ITaskEvent, ITaskIdentifier, ConfiguringTask, TaskRunSource } from 'vs/workbench/contrib/tasks/common/tasks'; +import { ITaskSummary, ITaskTerminateResponse, ITaskSystemInfo } from 'vs/workbench/contrib/tasks/common/taskSystem'; import { IStringDictionary } from 'vs/base/common/collections'; import { RawContextKey } from 'vs/platform/contextkey/common/contextkey'; -export { ITaskSummary, Task, TaskTerminateResponse }; +export { ITaskSummary, Task, ITaskTerminateResponse as TaskTerminateResponse }; export const CustomExecutionSupportedContext = new RawContextKey('customExecutionSupported', true, nls.localize('tasks.customExecutionSupported', "Whether CustomExecution tasks are supported. Consider using in the when clause of a \'taskDefinition\' contribution.")); export const ShellExecutionSupportedContext = new RawContextKey('shellExecutionSupported', false, nls.localize('tasks.shellExecutionSupported', "Whether ShellExecution tasks are supported. Consider using in the when clause of a \'taskDefinition\' contribution.")); @@ -24,57 +24,57 @@ export const ProcessExecutionSupportedContext = new RawContextKey('proc export const ITaskService = createDecorator('taskService'); export interface ITaskProvider { - provideTasks(validTypes: IStringDictionary): Promise; + provideTasks(validTypes: IStringDictionary): Promise; resolveTask(task: ConfiguringTask): Promise; } -export interface ProblemMatcherRunOptions { +export interface IProblemMatcherRunOptions { attachProblemMatcher?: boolean; } -export interface CustomizationProperties { +export interface ICustomizationProperties { group?: string | { kind?: string; isDefault?: boolean }; problemMatcher?: string | string[]; isBackground?: boolean; } -export interface TaskFilter { +export interface ITaskFilter { version?: string; type?: string; } -interface WorkspaceTaskResult { - set: TaskSet | undefined; +interface IWorkspaceTaskResult { + set: ITaskSet | undefined; configurations: { byIdentifier: IStringDictionary; } | undefined; hasErrors: boolean; } -export interface WorkspaceFolderTaskResult extends WorkspaceTaskResult { +export interface IWorkspaceFolderTaskResult extends IWorkspaceTaskResult { workspaceFolder: IWorkspaceFolder; } export interface ITaskService { readonly _serviceBrand: undefined; - onDidStateChange: Event; + onDidStateChange: Event; supportsMultipleTaskExecutions: boolean; configureAction(): Action; - run(task: Task | undefined, options?: ProblemMatcherRunOptions): Promise; + run(task: Task | undefined, options?: IProblemMatcherRunOptions): Promise; inTerminal(): boolean; getActiveTasks(): Promise; getBusyTasks(): Promise; - terminate(task: Task): Promise; - tasks(filter?: TaskFilter): Promise; + terminate(task: Task): Promise; + tasks(filter?: ITaskFilter): Promise; taskTypes(): string[]; - getWorkspaceTasks(runSource?: TaskRunSource): Promise>; + getWorkspaceTasks(runSource?: TaskRunSource): Promise>; readRecentTasks(): Promise<(Task | ConfiguringTask)[]>; removeRecentlyUsedTask(taskRecentlyUsedKey: string): void; /** * @param alias The task's name, label or defined identifier. */ - getTask(workspaceFolder: IWorkspace | IWorkspaceFolder | string, alias: string | TaskIdentifier, compareId?: boolean): Promise; + getTask(workspaceFolder: IWorkspace | IWorkspaceFolder | string, alias: string | ITaskIdentifier, compareId?: boolean): Promise; tryResolveTask(configuringTask: ConfiguringTask): Promise; createSorter(): TaskSorter; @@ -84,7 +84,7 @@ export interface ITaskService { registerTaskProvider(taskProvider: ITaskProvider, type: string): IDisposable; - registerTaskSystem(scheme: string, taskSystemInfo: TaskSystemInfo): void; + registerTaskSystem(scheme: string, taskSystemInfo: ITaskSystemInfo): void; onDidChangeTaskSystemInfo: Event; readonly hasTaskSystemInfo: boolean; registerSupportedExecutions(custom?: boolean, shell?: boolean, process?: boolean): void; diff --git a/src/vs/workbench/contrib/tasks/common/taskSystem.ts b/src/vs/workbench/contrib/tasks/common/taskSystem.ts index 12bc7501984..e36542f6622 100644 --- a/src/vs/workbench/contrib/tasks/common/taskSystem.ts +++ b/src/vs/workbench/contrib/tasks/common/taskSystem.ts @@ -9,7 +9,7 @@ import { TerminateResponse } from 'vs/base/common/processes'; import { Event } from 'vs/base/common/event'; import { Platform } from 'vs/base/common/platform'; import { IWorkspaceFolder } from 'vs/platform/workspace/common/workspace'; -import { Task, TaskEvent, KeyedTaskIdentifier } from './tasks'; +import { Task, ITaskEvent, KeyedTaskIdentifier } from './tasks'; import { ConfigurationTarget } from 'vs/platform/configuration/common/configuration'; export const enum TaskErrors { @@ -69,11 +69,11 @@ export interface ITaskResolver { resolve(uri: URI | string, identifier: string | KeyedTaskIdentifier | undefined): Promise; } -export interface TaskTerminateResponse extends TerminateResponse { +export interface ITaskTerminateResponse extends TerminateResponse { task: Task | undefined; } -export interface ResolveSet { +export interface IResolveSet { process?: { name: string; cwd?: string; @@ -82,25 +82,25 @@ export interface ResolveSet { variables: Set; } -export interface ResolvedVariables { +export interface IResolvedVariables { process?: string; variables: Map; } -export interface TaskSystemInfo { +export interface ITaskSystemInfo { platform: Platform; context: any; uriProvider: (this: void, path: string) => URI; - resolveVariables(workspaceFolder: IWorkspaceFolder, toResolve: ResolveSet, target: ConfigurationTarget): Promise; + resolveVariables(workspaceFolder: IWorkspaceFolder, toResolve: IResolveSet, target: ConfigurationTarget): Promise; findExecutable(command: string, cwd?: string, paths?: string[]): Promise; } -export interface TaskSystemInfoResolver { - (workspaceFolder: IWorkspaceFolder | undefined): TaskSystemInfo | undefined; +export interface ITaskSystemInfoResolver { + (workspaceFolder: IWorkspaceFolder | undefined): ITaskSystemInfo | undefined; } export interface ITaskSystem { - onDidStateChange: Event; + onDidStateChange: Event; run(task: Task, resolver: ITaskResolver): ITaskExecuteResult; rerun(): ITaskExecuteResult | undefined; isActive(): Promise; @@ -109,8 +109,8 @@ export interface ITaskSystem { getLastInstance(task: Task): Task | undefined; getBusyTasks(): Task[]; canAutoTerminate(): boolean; - terminate(task: Task): Promise; - terminateAll(): Promise; + terminate(task: Task): Promise; + terminateAll(): Promise; revealTask(task: Task): boolean; customExecutionComplete(task: Task, result: number): Promise; isTaskVisible(task: Task): boolean; diff --git a/src/vs/workbench/contrib/tasks/common/taskTemplates.ts b/src/vs/workbench/contrib/tasks/common/taskTemplates.ts index c367ede9ab7..a53c07420d7 100644 --- a/src/vs/workbench/contrib/tasks/common/taskTemplates.ts +++ b/src/vs/workbench/contrib/tasks/common/taskTemplates.ts @@ -7,13 +7,13 @@ import * as nls from 'vs/nls'; import { IQuickPickItem } from 'vs/platform/quickinput/common/quickInput'; -export interface TaskEntry extends IQuickPickItem { +export interface ITaskEntry extends IQuickPickItem { sort?: string; autoDetect: boolean; content: string; } -const dotnetBuild: TaskEntry = { +const dotnetBuild: ITaskEntry = { id: 'dotnetCore', label: '.NET Core', sort: 'NET Core', @@ -47,7 +47,7 @@ const dotnetBuild: TaskEntry = { ].join('\n') }; -const msbuild: TaskEntry = { +const msbuild: ITaskEntry = { id: 'msbuild', label: 'MSBuild', autoDetect: false, @@ -82,7 +82,7 @@ const msbuild: TaskEntry = { ].join('\n') }; -const command: TaskEntry = { +const command: ITaskEntry = { id: 'externalCommand', label: 'Others', autoDetect: false, @@ -103,7 +103,7 @@ const command: TaskEntry = { ].join('\n') }; -const maven: TaskEntry = { +const maven: ITaskEntry = { id: 'maven', label: 'maven', sort: 'MVN', @@ -132,8 +132,8 @@ const maven: TaskEntry = { ].join('\n') }; -let _templates: TaskEntry[] | null = null; -export function getTemplates(): TaskEntry[] { +let _templates: ITaskEntry[] | null = null; +export function getTemplates(): ITaskEntry[] { if (!_templates) { _templates = [dotnetBuild, msbuild, maven].sort((a, b) => { return (a.sort || a.label).localeCompare(b.sort || b.label); diff --git a/src/vs/workbench/contrib/tasks/common/tasks.ts b/src/vs/workbench/contrib/tasks/common/tasks.ts index e26ad2051e5..595d07dfa93 100644 --- a/src/vs/workbench/contrib/tasks/common/tasks.ts +++ b/src/vs/workbench/contrib/tasks/common/tasks.ts @@ -60,7 +60,7 @@ export namespace ShellQuoting { } } -export interface ShellQuotingOptions { +export interface IShellQuotingOptions { /** * The character used to do character escaping. */ @@ -80,7 +80,7 @@ export interface ShellQuotingOptions { weak?: string; } -export interface ShellConfiguration { +export interface IShellConfiguration { /** * The shell executable. */ @@ -94,7 +94,7 @@ export interface ShellConfiguration { /** * Which kind of quotes the shell supports. */ - quoting?: ShellQuotingOptions; + quoting?: IShellQuotingOptions; } export interface CommandOptions { @@ -102,7 +102,7 @@ export interface CommandOptions { /** * The shell to use if the task is a shell command. */ - shell?: ShellConfiguration; + shell?: IShellConfiguration; /** * The current working directory of the executed program or shell. @@ -223,7 +223,7 @@ export namespace PanelKind { } } -export interface PresentationOptions { +export interface IPresentationOptions { /** * Controls whether the task output is reveal in the user interface. * Defaults to `RevealKind.Always`. @@ -276,7 +276,7 @@ export interface PresentationOptions { } export namespace PresentationOptions { - export const defaults: PresentationOptions = { + export const defaults: IPresentationOptions = { echo: true, reveal: RevealKind.Always, revealProblems: RevealProblemKind.Never, focus: false, panel: PanelKind.Shared, showReuseMessage: true, clear: false }; } @@ -310,12 +310,12 @@ export namespace RuntimeType { } } -export interface QuotedString { +export interface IQuotedString { value: string; quoting: ShellQuoting; } -export type CommandString = string | QuotedString; +export type CommandString = string | IQuotedString; export namespace CommandString { export function value(value: CommandString): string { @@ -327,7 +327,7 @@ export namespace CommandString { } } -export interface CommandConfiguration { +export interface ICommandConfiguration { /** * The task type @@ -363,7 +363,7 @@ export interface CommandConfiguration { /** * Describes how the task is presented in the UI. */ - presentation?: PresentationOptions; + presentation?: IPresentationOptions; } export namespace TaskGroup { @@ -420,7 +420,7 @@ export namespace TaskSourceKind { } } -export interface TaskSourceConfigElement { +export interface ITaskSourceConfigElement { workspaceFolder?: IWorkspaceFolder; workspace?: IWorkspace; file: string; @@ -428,57 +428,57 @@ export interface TaskSourceConfigElement { element: any; } -interface BaseTaskSource { +interface IBaseTaskSource { readonly kind: string; readonly label: string; } -export interface WorkspaceTaskSource extends BaseTaskSource { +export interface IWorkspaceTaskSource extends IBaseTaskSource { readonly kind: 'workspace'; - readonly config: TaskSourceConfigElement; + readonly config: ITaskSourceConfigElement; readonly customizes?: KeyedTaskIdentifier; } -export interface ExtensionTaskSource extends BaseTaskSource { +export interface IExtensionTaskSource extends IBaseTaskSource { readonly kind: 'extension'; readonly extension?: string; readonly scope: TaskScope; readonly workspaceFolder: IWorkspaceFolder | undefined; } -export interface ExtensionTaskSourceTransfer { +export interface IExtensionTaskSourceTransfer { __workspaceFolder: UriComponents; __definition: { type: string;[name: string]: any }; } -export interface InMemoryTaskSource extends BaseTaskSource { +export interface IInMemoryTaskSource extends IBaseTaskSource { readonly kind: 'inMemory'; } -export interface UserTaskSource extends BaseTaskSource { +export interface IUserTaskSource extends IBaseTaskSource { readonly kind: 'user'; - readonly config: TaskSourceConfigElement; + readonly config: ITaskSourceConfigElement; readonly customizes?: KeyedTaskIdentifier; } -export interface WorkspaceFileTaskSource extends BaseTaskSource { +export interface WorkspaceFileTaskSource extends IBaseTaskSource { readonly kind: 'workspaceFile'; - readonly config: TaskSourceConfigElement; + readonly config: ITaskSourceConfigElement; readonly customizes?: KeyedTaskIdentifier; } -export type TaskSource = WorkspaceTaskSource | ExtensionTaskSource | InMemoryTaskSource | UserTaskSource | WorkspaceFileTaskSource; -export type FileBasedTaskSource = WorkspaceTaskSource | UserTaskSource | WorkspaceFileTaskSource; -export interface TaskIdentifier { +export type TaskSource = IWorkspaceTaskSource | IExtensionTaskSource | IInMemoryTaskSource | IUserTaskSource | WorkspaceFileTaskSource; +export type FileBasedTaskSource = IWorkspaceTaskSource | IUserTaskSource | WorkspaceFileTaskSource; +export interface ITaskIdentifier { type: string; [name: string]: any; } -export interface KeyedTaskIdentifier extends TaskIdentifier { +export interface KeyedTaskIdentifier extends ITaskIdentifier { _key: string; } -export interface TaskDependency { +export interface ITaskDependency { uri: URI | string; task: string | KeyedTaskIdentifier | undefined; } @@ -488,7 +488,7 @@ export const enum DependsOrder { sequence = 'sequence' } -export interface ConfigurationProperties { +export interface IConfigurationProperties { /** * The task's name @@ -508,7 +508,7 @@ export interface ConfigurationProperties { /** * The presentation options */ - presentation?: PresentationOptions; + presentation?: IPresentationOptions; /** * The command options; @@ -528,7 +528,7 @@ export interface ConfigurationProperties { /** * The other tasks this task depends on. */ - dependsOn?: TaskDependency[]; + dependsOn?: ITaskDependency[]; /** * The order the dependsOn tasks should be executed in. @@ -551,14 +551,14 @@ export enum RunOnOptions { folderOpen = 2 } -export interface RunOptions { +export interface IRunOptions { reevaluateOnRerun?: boolean; runOn?: RunOnOptions; instanceLimit?: number; } export namespace RunOptions { - export const defaults: RunOptions = { reevaluateOnRerun: true, runOn: RunOnOptions.default, instanceLimit: 1 }; + export const defaults: IRunOptions = { reevaluateOnRerun: true, runOn: RunOnOptions.default, instanceLimit: 1 }; } export abstract class CommonTask { @@ -575,16 +575,16 @@ export abstract class CommonTask { type?: string; - runOptions: RunOptions; + runOptions: IRunOptions; - configurationProperties: ConfigurationProperties; + configurationProperties: IConfigurationProperties; - _source: BaseTaskSource; + _source: IBaseTaskSource; private _taskLoadMessages: string[] | undefined; - protected constructor(id: string, label: string | undefined, type: string | undefined, runOptions: RunOptions, - configurationProperties: ConfigurationProperties, source: BaseTaskSource) { + protected constructor(id: string, label: string | undefined, type: string | undefined, runOptions: IRunOptions, + configurationProperties: IConfigurationProperties, source: IBaseTaskSource) { this._id = id; if (label) { this._label = label; @@ -612,12 +612,12 @@ export abstract class CommonTask { protected abstract getFolderId(): string | undefined; public getCommonTaskId(): string { - interface RecentTaskKey { + interface IRecentTaskKey { folder: string | undefined; id: string; } - const key: RecentTaskKey = { folder: this.getFolderId(), id: this._id }; + const key: IRecentTaskKey = { folder: this.getFolderId(), id: this._id }; return JSON.stringify(key); } @@ -659,8 +659,8 @@ export abstract class CommonTask { } } - public getTaskExecution(): TaskExecution { - let result: TaskExecution = { + public getTaskExecution(): ITaskExecution { + let result: ITaskExecution = { id: this._id, task: this }; @@ -697,10 +697,10 @@ export class CustomTask extends CommonTask { /** * The command configuration */ - command: CommandConfiguration = {}; + command: ICommandConfiguration = {}; - public constructor(id: string, source: FileBasedTaskSource, label: string, type: string, command: CommandConfiguration | undefined, - hasDefinedMatchers: boolean, runOptions: RunOptions, configurationProperties: ConfigurationProperties) { + public constructor(id: string, source: FileBasedTaskSource, label: string, type: string, command: ICommandConfiguration | undefined, + hasDefinedMatchers: boolean, runOptions: IRunOptions, configurationProperties: IConfigurationProperties) { super(id, label, undefined, runOptions, configurationProperties, source); this._source = source; this.hasDefinedMatchers = hasDefinedMatchers; @@ -774,7 +774,7 @@ export class CustomTask extends CommonTask { } public override getRecentlyUsedKey(): string | undefined { - interface CustomKey { + interface ICustomKey { type: string; folder: string; id: string; @@ -787,7 +787,7 @@ export class CustomTask extends CommonTask { if (this._source.kind !== TaskSourceKind.Workspace) { id += this._source.kind; } - let key: CustomKey = { type: CUSTOMIZED_TASK_TYPE, folder: workspaceFolder, id }; + let key: ICustomKey = { type: CUSTOMIZED_TASK_TYPE, folder: workspaceFolder, id }; return JSON.stringify(key); } @@ -822,7 +822,7 @@ export class ConfiguringTask extends CommonTask { configures: KeyedTaskIdentifier; public constructor(id: string, source: FileBasedTaskSource, label: string | undefined, type: string | undefined, - configures: KeyedTaskIdentifier, runOptions: RunOptions, configurationProperties: ConfigurationProperties) { + configures: KeyedTaskIdentifier, runOptions: IRunOptions, configurationProperties: IConfigurationProperties) { super(id, label, type, runOptions, configurationProperties, source); this._source = source; this.configures = configures; @@ -853,7 +853,7 @@ export class ConfiguringTask extends CommonTask { } public override getRecentlyUsedKey(): string | undefined { - interface CustomKey { + interface ICustomKey { type: string; folder: string; id: string; @@ -866,7 +866,7 @@ export class ConfiguringTask extends CommonTask { if (this._source.kind !== TaskSourceKind.Workspace) { id += this._source.kind; } - let key: CustomKey = { type: CUSTOMIZED_TASK_TYPE, folder: workspaceFolder, id }; + let key: ICustomKey = { type: CUSTOMIZED_TASK_TYPE, folder: workspaceFolder, id }; return JSON.stringify(key); } } @@ -877,7 +877,7 @@ export class ContributedTask extends CommonTask { * Indicated the source of the task (e.g. tasks.json or extension) * Set in the super constructor */ - override _source!: ExtensionTaskSource; + override _source!: IExtensionTaskSource; instance: number | undefined; @@ -888,11 +888,11 @@ export class ContributedTask extends CommonTask { /** * The command configuration */ - command: CommandConfiguration; + command: ICommandConfiguration; - public constructor(id: string, source: ExtensionTaskSource, label: string, type: string | undefined, defines: KeyedTaskIdentifier, - command: CommandConfiguration, hasDefinedMatchers: boolean, runOptions: RunOptions, - configurationProperties: ConfigurationProperties) { + public constructor(id: string, source: IExtensionTaskSource, label: string, type: string | undefined, defines: KeyedTaskIdentifier, + command: ICommandConfiguration, hasDefinedMatchers: boolean, runOptions: IRunOptions, + configurationProperties: IConfigurationProperties) { super(id, label, type, runOptions, configurationProperties, source); this.defines = defines; this.hasDefinedMatchers = hasDefinedMatchers; @@ -926,14 +926,14 @@ export class ContributedTask extends CommonTask { } public override getRecentlyUsedKey(): string | undefined { - interface ContributedKey { + interface IContributedKey { type: string; scope: number; folder?: string; id: string; } - let key: ContributedKey = { type: 'contributed', scope: this._source.scope, id: this._id }; + let key: IContributedKey = { type: 'contributed', scope: this._source.scope, id: this._id }; key.folder = this.getFolderId(); return JSON.stringify(key); } @@ -955,14 +955,14 @@ export class InMemoryTask extends CommonTask { /** * Indicated the source of the task (e.g. tasks.json or extension) */ - override _source: InMemoryTaskSource; + override _source: IInMemoryTaskSource; instance: number | undefined; override type!: 'inMemory'; - public constructor(id: string, source: InMemoryTaskSource, label: string, type: string, - runOptions: RunOptions, configurationProperties: ConfigurationProperties) { + public constructor(id: string, source: IInMemoryTaskSource, label: string, type: string, + runOptions: IRunOptions, configurationProperties: IConfigurationProperties) { super(id, label, type, runOptions, configurationProperties, source); this._source = source; } @@ -994,7 +994,7 @@ export class InMemoryTask extends CommonTask { export type Task = CustomTask | ContributedTask | InMemoryTask; -export interface TaskExecution { +export interface ITaskExecution { id: string; task: Task; } @@ -1013,12 +1013,12 @@ export const enum JsonSchemaVersion { V2_0_0 = 2 } -export interface TaskSet { +export interface ITaskSet { tasks: Task[]; extension?: IExtensionDescription; } -export interface TaskDefinition { +export interface ITaskDefinition { extensionId: string; taskType: string; required: string[]; @@ -1078,7 +1078,7 @@ export const enum TaskRunType { Background = 'background' } -export interface TaskEvent { +export interface ITaskEvent { kind: TaskEventKind; taskId?: string; taskName?: string; @@ -1099,13 +1099,13 @@ export const enum TaskRunSource { } export namespace TaskEvent { - export function create(kind: TaskEventKind.ProcessStarted | TaskEventKind.ProcessEnded, task: Task, processIdOrExitCode?: number): TaskEvent; - export function create(kind: TaskEventKind.Start, task: Task, terminalId?: number, resolvedVariables?: Map): TaskEvent; - export function create(kind: TaskEventKind.AcquiredInput | TaskEventKind.DependsOnStarted | TaskEventKind.Start | TaskEventKind.Active | TaskEventKind.Inactive | TaskEventKind.Terminated | TaskEventKind.End, task: Task): TaskEvent; - export function create(kind: TaskEventKind.Changed): TaskEvent; - export function create(kind: TaskEventKind, task?: Task, processIdOrExitCodeOrTerminalId?: number, resolvedVariables?: Map): TaskEvent { + export function create(kind: TaskEventKind.ProcessStarted | TaskEventKind.ProcessEnded, task: Task, processIdOrExitCode?: number): ITaskEvent; + export function create(kind: TaskEventKind.Start, task: Task, terminalId?: number, resolvedVariables?: Map): ITaskEvent; + export function create(kind: TaskEventKind.AcquiredInput | TaskEventKind.DependsOnStarted | TaskEventKind.Start | TaskEventKind.Active | TaskEventKind.Inactive | TaskEventKind.Terminated | TaskEventKind.End, task: Task): ITaskEvent; + export function create(kind: TaskEventKind.Changed): ITaskEvent; + export function create(kind: TaskEventKind, task?: Task, processIdOrExitCodeOrTerminalId?: number, resolvedVariables?: Map): ITaskEvent { if (task) { - let result: TaskEvent = { + let result: ITaskEvent = { kind: kind, taskId: task._id, taskName: task.configurationProperties.name, @@ -1146,7 +1146,7 @@ export namespace KeyedTaskIdentifier { } return result; } - export function create(value: TaskIdentifier): KeyedTaskIdentifier { + export function create(value: ITaskIdentifier): KeyedTaskIdentifier { const resultKey = sortedStringify(value); let result = { _key: resultKey, type: value.taskType }; Object.assign(result, value); @@ -1155,7 +1155,7 @@ export namespace KeyedTaskIdentifier { } export namespace TaskDefinition { - export function createTaskIdentifier(external: TaskIdentifier, reporter: { error(message: string): void }): KeyedTaskIdentifier | undefined { + export function createTaskIdentifier(external: ITaskIdentifier, reporter: { error(message: string): void }): KeyedTaskIdentifier | undefined { let definition = TaskDefinitionRegistry.get(external.type); if (definition === undefined) { // We have no task definition so we can't sanitize the literal. Take it as is diff --git a/src/vs/workbench/contrib/tasks/electron-sandbox/taskService.ts b/src/vs/workbench/contrib/tasks/electron-sandbox/taskService.ts index a17d4185861..52844d4b3ce 100644 --- a/src/vs/workbench/contrib/tasks/electron-sandbox/taskService.ts +++ b/src/vs/workbench/contrib/tasks/electron-sandbox/taskService.ts @@ -10,7 +10,7 @@ import { ITaskSystem } from 'vs/workbench/contrib/tasks/common/taskSystem'; import { ExecutionEngine } from 'vs/workbench/contrib/tasks/common/tasks'; import * as TaskConfig from '../common/taskConfiguration'; import { AbstractTaskService } from 'vs/workbench/contrib/tasks/browser/abstractTaskService'; -import { TaskFilter, ITaskService } from 'vs/workbench/contrib/tasks/common/taskService'; +import { ITaskFilter, ITaskService } from 'vs/workbench/contrib/tasks/common/taskService'; import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; import { TerminalTaskSystem } from 'vs/workbench/contrib/tasks/browser/terminalTaskSystem'; import { IConfirmationResult, IDialogService } from 'vs/platform/dialogs/common/dialogs'; @@ -44,9 +44,9 @@ import { IWorkspaceTrustManagementService, IWorkspaceTrustRequestService } from import { ITerminalProfileResolverService } from 'vs/workbench/contrib/terminal/common/terminal'; import { IPaneCompositePartService } from 'vs/workbench/services/panecomposite/browser/panecomposite'; -interface WorkspaceFolderConfigurationResult { +interface IWorkspaceFolderConfigurationResult { workspaceFolder: IWorkspaceFolder; - config: TaskConfig.ExternalTaskRunnerConfiguration | undefined; + config: TaskConfig.IExternalTaskRunnerConfiguration | undefined; hasErrors: boolean; } @@ -133,7 +133,7 @@ export class TaskService extends AbstractTaskService { return this._taskSystem; } - protected computeLegacyConfiguration(workspaceFolder: IWorkspaceFolder): Promise { + protected computeLegacyConfiguration(workspaceFolder: IWorkspaceFolder): Promise { let { config, hasParseErrors } = this.getConfiguration(workspaceFolder); if (hasParseErrors) { return Promise.resolve({ workspaceFolder: workspaceFolder, hasErrors: true, config: undefined }); @@ -145,7 +145,7 @@ export class TaskService extends AbstractTaskService { } } - protected versionAndEngineCompatible(filter?: TaskFilter): boolean { + protected versionAndEngineCompatible(filter?: ITaskFilter): boolean { let range = filter && filter.version ? filter.version : undefined; let engine = this.executionEngine; diff --git a/src/vs/workbench/contrib/tasks/test/browser/taskTerminalStatus.test.ts b/src/vs/workbench/contrib/tasks/test/browser/taskTerminalStatus.test.ts index 3b00f83eaf5..be60def9f43 100644 --- a/src/vs/workbench/contrib/tasks/test/browser/taskTerminalStatus.test.ts +++ b/src/vs/workbench/contrib/tasks/test/browser/taskTerminalStatus.test.ts @@ -9,17 +9,17 @@ import { TestConfigurationService } from 'vs/platform/configuration/test/common/ import { TestInstantiationService } from 'vs/platform/instantiation/test/common/instantiationServiceMock'; import { ACTIVE_TASK_STATUS, FAILED_TASK_STATUS, SUCCEEDED_TASK_STATUS, TaskTerminalStatus } from 'vs/workbench/contrib/tasks/browser/taskTerminalStatus'; import { AbstractProblemCollector } from 'vs/workbench/contrib/tasks/common/problemCollectors'; -import { CommonTask, TaskEvent, TaskEventKind, TaskRunType } from 'vs/workbench/contrib/tasks/common/tasks'; +import { CommonTask, ITaskEvent, TaskEventKind, TaskRunType } from 'vs/workbench/contrib/tasks/common/tasks'; import { ITaskService, Task } from 'vs/workbench/contrib/tasks/common/taskService'; import { ITerminalInstance } from 'vs/workbench/contrib/terminal/browser/terminal'; import { ITerminalStatus, ITerminalStatusList, TerminalStatusList } from 'vs/workbench/contrib/terminal/browser/terminalStatusList'; class TestTaskService implements Partial { - private readonly _onDidStateChange: Emitter = new Emitter(); - public get onDidStateChange(): Event { + private readonly _onDidStateChange: Emitter = new Emitter(); + public get onDidStateChange(): Event { return this._onDidStateChange.event; } - public triggerStateChange(event: TaskEvent): void { + public triggerStateChange(event: ITaskEvent): void { this._onDidStateChange.fire(event); } } diff --git a/src/vs/workbench/contrib/tasks/test/common/problemMatcher.test.ts b/src/vs/workbench/contrib/tasks/test/common/problemMatcher.test.ts index 2de0e6c6100..3042641c34e 100644 --- a/src/vs/workbench/contrib/tasks/test/common/problemMatcher.test.ts +++ b/src/vs/workbench/contrib/tasks/test/common/problemMatcher.test.ts @@ -67,7 +67,7 @@ suite('ProblemPatternParser', () => { suite('single-pattern definitions', () => { test('parses a pattern defined by only a regexp', () => { - let problemPattern: matchers.Config.ProblemPattern = { + let problemPattern: matchers.Config.IProblemPattern = { regexp: 'test' }; let parsed = parser.parse(problemPattern); @@ -82,7 +82,7 @@ suite('ProblemPatternParser', () => { }); }); test('does not sets defaults for line and character if kind is File', () => { - let problemPattern: matchers.Config.ProblemPattern = { + let problemPattern: matchers.Config.IProblemPattern = { regexp: 'test', kind: 'file' }; diff --git a/src/vs/workbench/contrib/tasks/test/common/taskConfiguration.test.ts b/src/vs/workbench/contrib/tasks/test/common/taskConfiguration.test.ts index bf496555a15..1831aeb25c2 100644 --- a/src/vs/workbench/contrib/tasks/test/common/taskConfiguration.test.ts +++ b/src/vs/workbench/contrib/tasks/test/common/taskConfiguration.test.ts @@ -10,11 +10,11 @@ import * as UUID from 'vs/base/common/uuid'; import * as Types from 'vs/base/common/types'; import * as Platform from 'vs/base/common/platform'; import { ValidationStatus } from 'vs/base/common/parsers'; -import { ProblemMatcher, FileLocationKind, ProblemPattern, ApplyToKind, NamedProblemMatcher } from 'vs/workbench/contrib/tasks/common/problemMatcher'; +import { ProblemMatcher, FileLocationKind, IProblemPattern, ApplyToKind, INamedProblemMatcher } from 'vs/workbench/contrib/tasks/common/problemMatcher'; import { WorkspaceFolder, IWorkspace } from 'vs/platform/workspace/common/workspace'; import * as Tasks from 'vs/workbench/contrib/tasks/common/tasks'; -import { parse, ParseResult, IProblemReporter, ExternalTaskRunnerConfiguration, CustomTask, TaskConfigSource, ParseContext, ProblemMatcherConverter, Globals, TaskParseResult, UUIDMap, TaskParser } from 'vs/workbench/contrib/tasks/common/taskConfiguration'; +import { parse, IParseResult, IProblemReporter, IExternalTaskRunnerConfiguration, ICustomTask, TaskConfigSource, IParseContext, ProblemMatcherConverter, IGlobals, ITaskParseResult, UUIDMap, TaskParser } from 'vs/workbench/contrib/tasks/common/taskConfiguration'; import { MockContextKeyService } from 'vs/platform/keybinding/test/common/mockKeybindingService'; import { IContext } from 'vs/platform/contextkey/common/contextkey'; import { Workspace } from 'vs/platform/workspace/test/common/testWorkspace'; @@ -92,7 +92,7 @@ class ConfiguationBuilder { class PresentationBuilder { - public result: Tasks.PresentationOptions; + public result: Tasks.IPresentationOptions; constructor(public parent: CommandConfigurationBuilder) { this.result = { echo: false, reveal: Tasks.RevealKind.Always, revealProblems: Tasks.RevealProblemKind.Never, focus: false, panel: Tasks.PanelKind.Shared, showReuseMessage: true, clear: false, close: false }; @@ -133,7 +133,7 @@ class PresentationBuilder { } class CommandConfigurationBuilder { - public result: Tasks.CommandConfiguration; + public result: Tasks.ICommandConfiguration; private presentationBuilder: PresentationBuilder; @@ -303,7 +303,7 @@ class ProblemMatcherBuilder { } class PatternBuilder { - public result: ProblemPattern; + public result: IProblemPattern; constructor(public parent: ProblemMatcherBuilder, regExp: RegExp) { this.result = { @@ -376,7 +376,7 @@ class TasksMockContextKeyService extends MockContextKeyService { } } -function testDefaultProblemMatcher(external: ExternalTaskRunnerConfiguration, resolved: number) { +function testDefaultProblemMatcher(external: IExternalTaskRunnerConfiguration, resolved: number) { let reporter = new ProblemReporter(); let result = parse(workspaceFolder, workspace, Platform.platform, external, reporter, TaskConfigSource.TasksJson, new TasksMockContextKeyService()); assert.ok(!reporter.receivedMessage); @@ -386,7 +386,7 @@ function testDefaultProblemMatcher(external: ExternalTaskRunnerConfiguration, re assert.strictEqual(task.configurationProperties.problemMatchers!.length, resolved); } -function testConfiguration(external: ExternalTaskRunnerConfiguration, builder: ConfiguationBuilder): void { +function testConfiguration(external: IExternalTaskRunnerConfiguration, builder: ConfiguationBuilder): void { builder.done(); let reporter = new ProblemReporter(); let result = parse(workspaceFolder, workspace, Platform.platform, external, reporter, TaskConfigSource.TasksJson, new TasksMockContextKeyService()); @@ -437,7 +437,7 @@ class TaskGroupMap { } } -function assertConfiguration(result: ParseResult, expected: Tasks.Task[]): void { +function assertConfiguration(result: IParseResult, expected: Tasks.Task[]): void { assert.ok(result.validationStatus.isOK()); let actual = result.custom; assert.strictEqual(typeof actual, typeof expected); @@ -508,7 +508,7 @@ function assertTask(actual: Tasks.Task, expected: Tasks.Task) { } } -function assertCommandConfiguration(actual: Tasks.CommandConfiguration, expected: Tasks.CommandConfiguration) { +function assertCommandConfiguration(actual: Tasks.ICommandConfiguration, expected: Tasks.ICommandConfiguration) { assert.strictEqual(typeof actual, typeof expected); if (actual && expected) { assertPresentation(actual.presentation!, expected.presentation!); @@ -536,7 +536,7 @@ function assertGroup(actual: Tasks.TaskGroup, expected: Tasks.TaskGroup) { } } -function assertPresentation(actual: Tasks.PresentationOptions, expected: Tasks.PresentationOptions) { +function assertPresentation(actual: Tasks.IPresentationOptions, expected: Tasks.IPresentationOptions) { assert.strictEqual(typeof actual, typeof expected); if (actual && expected) { assert.strictEqual(actual.echo, expected.echo); @@ -566,21 +566,21 @@ function assertProblemMatcher(actual: string | ProblemMatcher, expected: string } } -function assertProblemPatterns(actual: ProblemPattern | ProblemPattern[], expected: ProblemPattern | ProblemPattern[]) { +function assertProblemPatterns(actual: IProblemPattern | IProblemPattern[], expected: IProblemPattern | IProblemPattern[]) { assert.strictEqual(typeof actual, typeof expected); if (Array.isArray(actual)) { - let actuals = actual; - let expecteds = expected; + let actuals = actual; + let expecteds = expected; assert.strictEqual(actuals.length, expecteds.length); for (let i = 0; i < actuals.length; i++) { assertProblemPattern(actuals[i], expecteds[i]); } } else { - assertProblemPattern(actual, expected); + assertProblemPattern(actual, expected); } } -function assertProblemPattern(actual: ProblemPattern, expected: ProblemPattern) { +function assertProblemPattern(actual: IProblemPattern, expected: IProblemPattern) { assert.strictEqual(actual.regexp.toString(), expected.regexp.toString()); assert.strictEqual(actual.file, expected.file); assert.strictEqual(actual.message, expected.message); @@ -793,7 +793,7 @@ suite('Tasks version 0.1.0', () => { task(name, name). group(Tasks.TaskGroup.Build). command().suppressTaskName(true); - let external: ExternalTaskRunnerConfiguration = { + let external: IExternalTaskRunnerConfiguration = { version: '0.1.0', command: 'tsc', windows: { @@ -811,7 +811,7 @@ suite('Tasks version 0.1.0', () => { group(Tasks.TaskGroup.Build). command().suppressTaskName(true). runtime(Tasks.RuntimeType.Shell); - let external: ExternalTaskRunnerConfiguration = { + let external: IExternalTaskRunnerConfiguration = { version: '0.1.0', command: 'tsc', isShellCommand: true, @@ -829,7 +829,7 @@ suite('Tasks version 0.1.0', () => { task(name, name). group(Tasks.TaskGroup.Build). command().suppressTaskName(true); - let external: ExternalTaskRunnerConfiguration = { + let external: IExternalTaskRunnerConfiguration = { version: '0.1.0', command: 'tsc', osx: { @@ -846,7 +846,7 @@ suite('Tasks version 0.1.0', () => { task(name, name). group(Tasks.TaskGroup.Build). command().suppressTaskName(true); - let external: ExternalTaskRunnerConfiguration = { + let external: IExternalTaskRunnerConfiguration = { version: '0.1.0', command: 'tsc', linux: { @@ -863,7 +863,7 @@ suite('Tasks version 0.1.0', () => { group(Tasks.TaskGroup.Build). command().suppressTaskName(true). presentation().reveal(Platform.isWindows ? Tasks.RevealKind.Always : Tasks.RevealKind.Never); - let external: ExternalTaskRunnerConfiguration = { + let external: IExternalTaskRunnerConfiguration = { version: '0.1.0', command: 'tsc', showOutput: 'never', @@ -882,7 +882,7 @@ suite('Tasks version 0.1.0', () => { command().suppressTaskName(true). presentation(). echo(Platform.isWindows ? false : true); - let external: ExternalTaskRunnerConfiguration = { + let external: IExternalTaskRunnerConfiguration = { version: '0.1.0', command: 'tsc', echoCommand: true, @@ -894,7 +894,7 @@ suite('Tasks version 0.1.0', () => { }); test('tasks: global problemMatcher one', () => { - let external: ExternalTaskRunnerConfiguration = { + let external: IExternalTaskRunnerConfiguration = { version: '0.1.0', command: 'tsc', problemMatcher: '$msCompile' @@ -903,7 +903,7 @@ suite('Tasks version 0.1.0', () => { }); test('tasks: global problemMatcher two', () => { - let external: ExternalTaskRunnerConfiguration = { + let external: IExternalTaskRunnerConfiguration = { version: '0.1.0', command: 'tsc', problemMatcher: ['$eslint-compact', '$msCompile'] @@ -912,7 +912,7 @@ suite('Tasks version 0.1.0', () => { }); test('tasks: task definition', () => { - let external: ExternalTaskRunnerConfiguration = { + let external: IExternalTaskRunnerConfiguration = { version: '0.1.0', command: 'tsc', tasks: [ @@ -927,14 +927,14 @@ suite('Tasks version 0.1.0', () => { }); test('tasks: build task', () => { - let external: ExternalTaskRunnerConfiguration = { + let external: IExternalTaskRunnerConfiguration = { version: '0.1.0', command: 'tsc', tasks: [ { taskName: 'taskName', isBuildCommand: true - } as CustomTask + } as ICustomTask ] }; let builder = new ConfiguationBuilder(); @@ -943,7 +943,7 @@ suite('Tasks version 0.1.0', () => { }); test('tasks: default build task', () => { - let external: ExternalTaskRunnerConfiguration = { + let external: IExternalTaskRunnerConfiguration = { version: '0.1.0', command: 'tsc', tasks: [ @@ -958,14 +958,14 @@ suite('Tasks version 0.1.0', () => { }); test('tasks: test task', () => { - let external: ExternalTaskRunnerConfiguration = { + let external: IExternalTaskRunnerConfiguration = { version: '0.1.0', command: 'tsc', tasks: [ { taskName: 'taskName', isTestCommand: true - } as CustomTask + } as ICustomTask ] }; let builder = new ConfiguationBuilder(); @@ -974,7 +974,7 @@ suite('Tasks version 0.1.0', () => { }); test('tasks: default test task', () => { - let external: ExternalTaskRunnerConfiguration = { + let external: IExternalTaskRunnerConfiguration = { version: '0.1.0', command: 'tsc', tasks: [ @@ -989,7 +989,7 @@ suite('Tasks version 0.1.0', () => { }); test('tasks: task with values', () => { - let external: ExternalTaskRunnerConfiguration = { + let external: IExternalTaskRunnerConfiguration = { version: '0.1.0', command: 'tsc', tasks: [ @@ -999,7 +999,7 @@ suite('Tasks version 0.1.0', () => { echoCommand: true, args: ['--p'], isWatching: true - } as CustomTask + } as ICustomTask ] }; let builder = new ConfiguationBuilder(); @@ -1015,7 +1015,7 @@ suite('Tasks version 0.1.0', () => { }); test('tasks: task inherits global values', () => { - let external: ExternalTaskRunnerConfiguration = { + let external: IExternalTaskRunnerConfiguration = { version: '0.1.0', command: 'tsc', showOutput: 'never', @@ -1036,7 +1036,7 @@ suite('Tasks version 0.1.0', () => { }); test('tasks: problem matcher default', () => { - let external: ExternalTaskRunnerConfiguration = { + let external: IExternalTaskRunnerConfiguration = { version: '0.1.0', command: 'tsc', tasks: [ @@ -1058,7 +1058,7 @@ suite('Tasks version 0.1.0', () => { }); test('tasks: problem matcher .* regular expression', () => { - let external: ExternalTaskRunnerConfiguration = { + let external: IExternalTaskRunnerConfiguration = { version: '0.1.0', command: 'tsc', tasks: [ @@ -1080,7 +1080,7 @@ suite('Tasks version 0.1.0', () => { }); test('tasks: problem matcher owner, applyTo, severity and fileLocation', () => { - let external: ExternalTaskRunnerConfiguration = { + let external: IExternalTaskRunnerConfiguration = { version: '0.1.0', command: 'tsc', tasks: [ @@ -1112,7 +1112,7 @@ suite('Tasks version 0.1.0', () => { }); test('tasks: problem matcher fileLocation and filePrefix', () => { - let external: ExternalTaskRunnerConfiguration = { + let external: IExternalTaskRunnerConfiguration = { version: '0.1.0', command: 'tsc', tasks: [ @@ -1138,7 +1138,7 @@ suite('Tasks version 0.1.0', () => { }); test('tasks: problem pattern location', () => { - let external: ExternalTaskRunnerConfiguration = { + let external: IExternalTaskRunnerConfiguration = { version: '0.1.0', command: 'tsc', tasks: [ @@ -1166,7 +1166,7 @@ suite('Tasks version 0.1.0', () => { }); test('tasks: problem pattern line & column', () => { - let external: ExternalTaskRunnerConfiguration = { + let external: IExternalTaskRunnerConfiguration = { version: '0.1.0', command: 'tsc', tasks: [ @@ -1199,7 +1199,7 @@ suite('Tasks version 0.1.0', () => { }); test('tasks: prompt on close default', () => { - let external: ExternalTaskRunnerConfiguration = { + let external: IExternalTaskRunnerConfiguration = { version: '0.1.0', command: 'tsc', tasks: [ @@ -1216,14 +1216,14 @@ suite('Tasks version 0.1.0', () => { }); test('tasks: prompt on close watching', () => { - let external: ExternalTaskRunnerConfiguration = { + let external: IExternalTaskRunnerConfiguration = { version: '0.1.0', command: 'tsc', tasks: [ { taskName: 'taskName', isWatching: true - } as CustomTask + } as ICustomTask ] }; let builder = new ConfiguationBuilder(); @@ -1234,7 +1234,7 @@ suite('Tasks version 0.1.0', () => { }); test('tasks: prompt on close set', () => { - let external: ExternalTaskRunnerConfiguration = { + let external: IExternalTaskRunnerConfiguration = { version: '0.1.0', command: 'tsc', tasks: [ @@ -1252,7 +1252,7 @@ suite('Tasks version 0.1.0', () => { }); test('tasks: task selector set', () => { - let external: ExternalTaskRunnerConfiguration = { + let external: IExternalTaskRunnerConfiguration = { version: '0.1.0', command: 'tsc', taskSelector: '/t:', @@ -1271,7 +1271,7 @@ suite('Tasks version 0.1.0', () => { }); test('tasks: suppress task name set', () => { - let external: ExternalTaskRunnerConfiguration = { + let external: IExternalTaskRunnerConfiguration = { version: '0.1.0', command: 'tsc', suppressTaskName: false, @@ -1279,7 +1279,7 @@ suite('Tasks version 0.1.0', () => { { taskName: 'taskName', suppressTaskName: true - } as CustomTask + } as ICustomTask ] }; let builder = new ConfiguationBuilder(); @@ -1289,7 +1289,7 @@ suite('Tasks version 0.1.0', () => { }); test('tasks: suppress task name inherit', () => { - let external: ExternalTaskRunnerConfiguration = { + let external: IExternalTaskRunnerConfiguration = { version: '0.1.0', command: 'tsc', suppressTaskName: true, @@ -1306,7 +1306,7 @@ suite('Tasks version 0.1.0', () => { }); test('tasks: two tasks', () => { - let external: ExternalTaskRunnerConfiguration = { + let external: IExternalTaskRunnerConfiguration = { version: '0.1.0', command: 'tsc', tasks: [ @@ -1327,7 +1327,7 @@ suite('Tasks version 0.1.0', () => { }); test('tasks: with command', () => { - let external: ExternalTaskRunnerConfiguration = { + let external: IExternalTaskRunnerConfiguration = { version: '0.1.0', tasks: [ { @@ -1342,7 +1342,7 @@ suite('Tasks version 0.1.0', () => { }); test('tasks: two tasks with command', () => { - let external: ExternalTaskRunnerConfiguration = { + let external: IExternalTaskRunnerConfiguration = { version: '0.1.0', tasks: [ { @@ -1362,7 +1362,7 @@ suite('Tasks version 0.1.0', () => { }); test('tasks: with command and args', () => { - let external: ExternalTaskRunnerConfiguration = { + let external: IExternalTaskRunnerConfiguration = { version: '0.1.0', tasks: [ { @@ -1376,7 +1376,7 @@ suite('Tasks version 0.1.0', () => { env: 'env' } } - } as CustomTask + } as ICustomTask ] }; let builder = new ConfiguationBuilder(); @@ -1387,7 +1387,7 @@ suite('Tasks version 0.1.0', () => { test('tasks: with command os specific', () => { let name: string = Platform.isWindows ? 'tsc.win' : 'tsc'; - let external: ExternalTaskRunnerConfiguration = { + let external: IExternalTaskRunnerConfiguration = { version: '0.1.0', tasks: [ { @@ -1406,7 +1406,7 @@ suite('Tasks version 0.1.0', () => { test('tasks: with Windows specific args', () => { let args: string[] = Platform.isWindows ? ['arg1', 'arg2'] : ['arg1']; - let external: ExternalTaskRunnerConfiguration = { + let external: IExternalTaskRunnerConfiguration = { version: '0.1.0', tasks: [ { @@ -1426,7 +1426,7 @@ suite('Tasks version 0.1.0', () => { test('tasks: with Linux specific args', () => { let args: string[] = Platform.isLinux ? ['arg1', 'arg2'] : ['arg1']; - let external: ExternalTaskRunnerConfiguration = { + let external: IExternalTaskRunnerConfiguration = { version: '0.1.0', tasks: [ { @@ -1445,14 +1445,14 @@ suite('Tasks version 0.1.0', () => { }); test('tasks: global command and task command properties', () => { - let external: ExternalTaskRunnerConfiguration = { + let external: IExternalTaskRunnerConfiguration = { version: '0.1.0', command: 'tsc', tasks: [ { taskName: 'taskNameOne', isShellCommand: true, - } as CustomTask + } as ICustomTask ] }; let builder = new ConfiguationBuilder(); @@ -1461,7 +1461,7 @@ suite('Tasks version 0.1.0', () => { }); test('tasks: global and tasks args', () => { - let external: ExternalTaskRunnerConfiguration = { + let external: IExternalTaskRunnerConfiguration = { version: '0.1.0', command: 'tsc', args: ['global'], @@ -1478,7 +1478,7 @@ suite('Tasks version 0.1.0', () => { }); test('tasks: global and tasks args with task selector', () => { - let external: ExternalTaskRunnerConfiguration = { + let external: IExternalTaskRunnerConfiguration = { version: '0.1.0', command: 'tsc', args: ['global'], @@ -1498,7 +1498,7 @@ suite('Tasks version 0.1.0', () => { suite('Tasks version 2.0.0', () => { test.skip('Build workspace task', () => { - let external: ExternalTaskRunnerConfiguration = { + let external: IExternalTaskRunnerConfiguration = { version: '2.0.0', tasks: [ { @@ -1518,7 +1518,7 @@ suite('Tasks version 2.0.0', () => { testConfiguration(external, builder); }); test('Global group none', () => { - let external: ExternalTaskRunnerConfiguration = { + let external: IExternalTaskRunnerConfiguration = { version: '2.0.0', command: 'dir', type: 'shell', @@ -1532,7 +1532,7 @@ suite('Tasks version 2.0.0', () => { testConfiguration(external, builder); }); test.skip('Global group build', () => { - let external: ExternalTaskRunnerConfiguration = { + let external: IExternalTaskRunnerConfiguration = { version: '2.0.0', command: 'dir', type: 'shell', @@ -1547,7 +1547,7 @@ suite('Tasks version 2.0.0', () => { testConfiguration(external, builder); }); test.skip('Global group default build', () => { - let external: ExternalTaskRunnerConfiguration = { + let external: IExternalTaskRunnerConfiguration = { version: '2.0.0', command: 'dir', type: 'shell', @@ -1564,7 +1564,7 @@ suite('Tasks version 2.0.0', () => { testConfiguration(external, builder); }); test('Local group none', () => { - let external: ExternalTaskRunnerConfiguration = { + let external: IExternalTaskRunnerConfiguration = { version: '2.0.0', tasks: [ { @@ -1583,7 +1583,7 @@ suite('Tasks version 2.0.0', () => { testConfiguration(external, builder); }); test.skip('Local group build', () => { - let external: ExternalTaskRunnerConfiguration = { + let external: IExternalTaskRunnerConfiguration = { version: '2.0.0', tasks: [ { @@ -1603,7 +1603,7 @@ suite('Tasks version 2.0.0', () => { testConfiguration(external, builder); }); test.skip('Local group default build', () => { - let external: ExternalTaskRunnerConfiguration = { + let external: IExternalTaskRunnerConfiguration = { version: '2.0.0', tasks: [ { @@ -1625,7 +1625,7 @@ suite('Tasks version 2.0.0', () => { testConfiguration(external, builder); }); test('Arg overwrite', () => { - let external: ExternalTaskRunnerConfiguration = { + let external: IExternalTaskRunnerConfiguration = { version: '2.0.0', tasks: [ { @@ -1678,7 +1678,7 @@ suite('Tasks version 2.0.0', () => { suite('Bugs / regression tests', () => { (Platform.isLinux ? test.skip : test)('Bug 19548', () => { - let external: ExternalTaskRunnerConfiguration = { + let external: IExternalTaskRunnerConfiguration = { version: '0.1.0', windows: { command: 'powershell', @@ -1700,7 +1700,7 @@ suite('Bugs / regression tests', () => { isBuildCommand: false, showOutput: 'always', echoCommand: true - } as CustomTask + } as ICustomTask ] }, osx: { @@ -1718,7 +1718,7 @@ suite('Bugs / regression tests', () => { ], isBuildCommand: false, showOutput: 'always' - } as CustomTask + } as ICustomTask ] } }; @@ -1770,26 +1770,26 @@ suite('Bugs / regression tests', () => { class TestNamedProblemMatcher implements Partial { } -class TestParseContext implements Partial { +class TestParseContext implements Partial { } class TestTaskDefinitionRegistry implements Partial { - private _task: Tasks.TaskDefinition | undefined; - public get(key: string): Tasks.TaskDefinition { + private _task: Tasks.ITaskDefinition | undefined; + public get(key: string): Tasks.ITaskDefinition { return this._task!; } - public set(task: Tasks.TaskDefinition) { + public set(task: Tasks.ITaskDefinition) { this._task = task; } } suite('Task configuration conversions', () => { - const globals = {} as Globals; + const globals = {} as IGlobals; const taskConfigSource = {} as TaskConfigSource; const TaskDefinitionRegistry = new TestTaskDefinitionRegistry(); let instantiationService: TestInstantiationService; - let parseContext: ParseContext; - let namedProblemMatcher: NamedProblemMatcher; + let parseContext: IParseContext; + let namedProblemMatcher: INamedProblemMatcher; let problemReporter: ProblemReporter; setup(() => { instantiationService = new TestInstantiationService(); @@ -1824,18 +1824,18 @@ suite('Task configuration conversions', () => { suite('CustomTask', () => { suite('incomplete config reports an appropriate error for missing', () => { test('name', () => { - const result = TaskParser.from([{} as CustomTask], globals, parseContext, taskConfigSource); + const result = TaskParser.from([{} as ICustomTask], globals, parseContext, taskConfigSource); assertTaskParseResult(result, undefined, problemReporter, 'Error: a task must provide a label property'); }); test('command', () => { - const result = TaskParser.from([{ taskName: 'task' } as CustomTask], globals, parseContext, taskConfigSource); + const result = TaskParser.from([{ taskName: 'task' } as ICustomTask], globals, parseContext, taskConfigSource); assertTaskParseResult(result, undefined, problemReporter, "Error: the task 'task' doesn't define a command"); }); }); test('returns expected result', () => { const expected = [ - { taskName: 'task', command: 'echo test' } as CustomTask, - { taskName: 'task 2', command: 'echo test' } as CustomTask + { taskName: 'task', command: 'echo test' } as ICustomTask, + { taskName: 'task 2', command: 'echo test' } as ICustomTask ]; const result = TaskParser.from(expected, globals, parseContext, taskConfigSource); assertTaskParseResult(result, { custom: expected }, problemReporter, undefined); @@ -1844,7 +1844,7 @@ suite('Task configuration conversions', () => { suite('ConfiguredTask', () => { test('returns expected result', () => { const expected = [{ taskName: 'task', command: 'echo test', type: 'any', label: 'task' }, { taskName: 'task 2', command: 'echo test', type: 'any', label: 'task 2' }]; - TaskDefinitionRegistry.set({ extensionId: 'registered', taskType: 'any', properties: {} } as Tasks.TaskDefinition); + TaskDefinitionRegistry.set({ extensionId: 'registered', taskType: 'any', properties: {} } as Tasks.ITaskDefinition); const result = TaskParser.from(expected, globals, parseContext, taskConfigSource, TaskDefinitionRegistry); assertTaskParseResult(result, { configured: expected }, problemReporter, undefined); }); @@ -1852,7 +1852,7 @@ suite('Task configuration conversions', () => { }); }); -function assertTaskParseResult(actual: TaskParseResult, expected: ITestTaskParseResult | undefined, problemReporter: ProblemReporter, expectedMessage?: string): void { +function assertTaskParseResult(actual: ITaskParseResult, expected: ITestTaskParseResult | undefined, problemReporter: ProblemReporter, expectedMessage?: string): void { if (expectedMessage === undefined) { assert.strictEqual(problemReporter.lastMessage, undefined); } else { @@ -1880,10 +1880,10 @@ function assertTaskParseResult(actual: TaskParseResult, expected: ITestTaskParse } interface ITestTaskParseResult { - custom?: Partial[]; - configured?: Partial[]; + custom?: Partial[]; + configured?: Partial[]; } -interface TestConfiguringTask extends Partial { +interface ITestConfiguringTask extends Partial { label: string; } From 9f3cafba7de0a48c85c0a651733c7405c9e01d3d Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Tue, 7 Jun 2022 09:37:14 -0700 Subject: [PATCH 013/117] Update grammars (#151383) Updates the markdown and JS/TS grammars --- .../syntaxes/JavaScript.tmLanguage.json | 44 +++++++++++++++++-- .../syntaxes/JavaScriptReact.tmLanguage.json | 44 +++++++++++++++++-- extensions/markdown-basics/cgmanifest.json | 2 +- .../syntaxes/markdown.tmLanguage.json | 35 ++++++++------- extensions/typescript-basics/cgmanifest.json | 2 +- .../syntaxes/TypeScript.tmLanguage.json | 44 +++++++++++++++++-- .../syntaxes/TypeScriptReact.tmLanguage.json | 44 +++++++++++++++++-- 7 files changed, 181 insertions(+), 34 deletions(-) diff --git a/extensions/javascript/syntaxes/JavaScript.tmLanguage.json b/extensions/javascript/syntaxes/JavaScript.tmLanguage.json index 04a23eca114..e957c06c1b6 100644 --- a/extensions/javascript/syntaxes/JavaScript.tmLanguage.json +++ b/extensions/javascript/syntaxes/JavaScript.tmLanguage.json @@ -4,7 +4,7 @@ "If you want to provide a fix or improvement, please create a pull request against the original repository.", "Once accepted there, we are happy to receive an update request." ], - "version": "https://github.com/microsoft/TypeScript-TmLanguage/commit/4d30ff834ec324f56291addd197aa1e423cedfdd", + "version": "https://github.com/microsoft/TypeScript-TmLanguage/commit/0dfae8cc4807fecfbf8f1add095d9817df824c95", "name": "JavaScript (with React support)", "scopeName": "source.js", "patterns": [ @@ -2271,11 +2271,47 @@ "name": "keyword.control.from.js", "match": "\\bfrom\\b" }, + { + "include": "#import-export-assert-clause" + }, { "include": "#import-export-clause" } ] }, + "import-export-assert-clause": { + "begin": "(?\\s*$)", + "begin": "^(///)\\s*(?=<(reference|amd-dependency|amd-module)(\\s+(path|types|no-default-lib|lib|name|resolution-mode)\\s*=\\s*((\\'([^\\'\\\\]|\\\\.)*\\')|(\\\"([^\\\"\\\\]|\\\\.)*\\\")|(\\`([^\\`\\\\]|\\\\.)*\\`)))+\\s*/>\\s*$)", "beginCaptures": { "1": { "name": "punctuation.definition.comment.js" @@ -5092,7 +5128,7 @@ "patterns": [ { "name": "entity.other.attribute-name.directive.js", - "match": "path|types|no-default-lib|lib|name" + "match": "path|types|no-default-lib|lib|name|resolution-mode" }, { "name": "keyword.operator.assignment.js", diff --git a/extensions/javascript/syntaxes/JavaScriptReact.tmLanguage.json b/extensions/javascript/syntaxes/JavaScriptReact.tmLanguage.json index 5d3448bdfe4..90476c2a91e 100644 --- a/extensions/javascript/syntaxes/JavaScriptReact.tmLanguage.json +++ b/extensions/javascript/syntaxes/JavaScriptReact.tmLanguage.json @@ -4,7 +4,7 @@ "If you want to provide a fix or improvement, please create a pull request against the original repository.", "Once accepted there, we are happy to receive an update request." ], - "version": "https://github.com/microsoft/TypeScript-TmLanguage/commit/4d30ff834ec324f56291addd197aa1e423cedfdd", + "version": "https://github.com/microsoft/TypeScript-TmLanguage/commit/0dfae8cc4807fecfbf8f1add095d9817df824c95", "name": "JavaScript (with React support)", "scopeName": "source.js.jsx", "patterns": [ @@ -2271,11 +2271,47 @@ "name": "keyword.control.from.js.jsx", "match": "\\bfrom\\b" }, + { + "include": "#import-export-assert-clause" + }, { "include": "#import-export-clause" } ] }, + "import-export-assert-clause": { + "begin": "(?\\s*$)", + "begin": "^(///)\\s*(?=<(reference|amd-dependency|amd-module)(\\s+(path|types|no-default-lib|lib|name|resolution-mode)\\s*=\\s*((\\'([^\\'\\\\]|\\\\.)*\\')|(\\\"([^\\\"\\\\]|\\\\.)*\\\")|(\\`([^\\`\\\\]|\\\\.)*\\`)))+\\s*/>\\s*$)", "beginCaptures": { "1": { "name": "punctuation.definition.comment.js.jsx" @@ -5092,7 +5128,7 @@ "patterns": [ { "name": "entity.other.attribute-name.directive.js.jsx", - "match": "path|types|no-default-lib|lib|name" + "match": "path|types|no-default-lib|lib|name|resolution-mode" }, { "name": "keyword.operator.assignment.js.jsx", diff --git a/extensions/markdown-basics/cgmanifest.json b/extensions/markdown-basics/cgmanifest.json index 29d1260e5f0..46b4bae2286 100644 --- a/extensions/markdown-basics/cgmanifest.json +++ b/extensions/markdown-basics/cgmanifest.json @@ -33,7 +33,7 @@ "git": { "name": "microsoft/vscode-markdown-tm-grammar", "repositoryUrl": "https://github.com/microsoft/vscode-markdown-tm-grammar", - "commitHash": "09c3e715102d08bba4c4ea828634474fc58b6f57" + "commitHash": "69d3321b4923ca2d5e8e900018887cc38b5fe04a" } }, "license": "MIT", diff --git a/extensions/markdown-basics/syntaxes/markdown.tmLanguage.json b/extensions/markdown-basics/syntaxes/markdown.tmLanguage.json index 31d9bf5922a..895836a188f 100644 --- a/extensions/markdown-basics/syntaxes/markdown.tmLanguage.json +++ b/extensions/markdown-basics/syntaxes/markdown.tmLanguage.json @@ -4,7 +4,7 @@ "If you want to provide a fix or improvement, please create a pull request against the original repository.", "Once accepted there, we are happy to receive an update request." ], - "version": "https://github.com/microsoft/vscode-markdown-tm-grammar/commit/09c3e715102d08bba4c4ea828634474fc58b6f57", + "version": "https://github.com/microsoft/vscode-markdown-tm-grammar/commit/69d3321b4923ca2d5e8e900018887cc38b5fe04a", "name": "Markdown", "scopeName": "text.html.markdown", "patterns": [ @@ -2774,47 +2774,50 @@ "5": { "name": "punctuation.definition.metadata.markdown" }, - "6": { + "7": { "name": "punctuation.definition.link.markdown" }, - "7": { + "8": { "name": "markup.underline.link.markdown" }, "9": { "name": "punctuation.definition.link.markdown" }, "10": { - "name": "string.other.link.description.title.markdown" - }, - "11": { - "name": "punctuation.definition.string.begin.markdown" + "name": "markup.underline.link.markdown" }, "12": { - "name": "punctuation.definition.string.end.markdown" + "name": "string.other.link.description.title.markdown" }, "13": { - "name": "string.other.link.description.title.markdown" + "name": "punctuation.definition.string.begin.markdown" }, "14": { - "name": "punctuation.definition.string.begin.markdown" + "name": "punctuation.definition.string.end.markdown" }, "15": { - "name": "punctuation.definition.string.end.markdown" - }, - "16": { "name": "string.other.link.description.title.markdown" }, - "17": { + "16": { "name": "punctuation.definition.string.begin.markdown" }, - "18": { + "17": { "name": "punctuation.definition.string.end.markdown" }, + "18": { + "name": "string.other.link.description.title.markdown" + }, "19": { + "name": "punctuation.definition.string.begin.markdown" + }, + "20": { + "name": "punctuation.definition.string.end.markdown" + }, + "21": { "name": "punctuation.definition.metadata.markdown" } }, - "match": "(?x)\n (\\[)((?[^\\[\\]\\\\]|\\\\.|\\[\\g*+\\])*+)(\\])\n # Match the link text.\n (\\() # Opening paren for url\n ((?>[^\\s()]+)|\\(\\g*\\))*)(>?) # The url\n [ \\t]* # Optional whitespace\n (?:\n ((\\().+?(\\))) # Match title in parens…\n | ((\").+?(\")) # or in double quotes…\n | ((').+?(')) # or in single quotes.\n )? # Title is optional\n \\s* # Optional whitespace\n (\\))\n", + "match": "(?x)\n (\\[)((?[^\\[\\]\\\\]|\\\\.|\\[\\g*+\\])*+)(\\])\n # Match the link text.\n (\\() # Opening paren for url\n # The url\n [ \\t]*\n (\n (<)([^<>\\n]*)(>)\n | ((?(?>[^\\s()]+)|\\(\\g*\\))*)\n )\n [ \\t]*\n # The title \n (?:\n ((\\()[^()]*(\\))) # Match title in parens…\n | ((\")[^\"]*(\")) # or in double quotes…\n | ((')[^']*(')) # or in single quotes.\n )? # Title is optional\n \\s* # Optional whitespace\n (\\))\n", "name": "meta.link.inline.markdown" }, "link-ref": { diff --git a/extensions/typescript-basics/cgmanifest.json b/extensions/typescript-basics/cgmanifest.json index d0fcb000eca..7e58e66ed5e 100644 --- a/extensions/typescript-basics/cgmanifest.json +++ b/extensions/typescript-basics/cgmanifest.json @@ -6,7 +6,7 @@ "git": { "name": "TypeScript-TmLanguage", "repositoryUrl": "https://github.com/microsoft/TypeScript-TmLanguage", - "commitHash": "4d30ff834ec324f56291addd197aa1e423cedfdd" + "commitHash": "0dfae8cc4807fecfbf8f1add095d9817df824c95" } }, "license": "MIT", diff --git a/extensions/typescript-basics/syntaxes/TypeScript.tmLanguage.json b/extensions/typescript-basics/syntaxes/TypeScript.tmLanguage.json index 5164273d6a4..9d97c94fd0d 100644 --- a/extensions/typescript-basics/syntaxes/TypeScript.tmLanguage.json +++ b/extensions/typescript-basics/syntaxes/TypeScript.tmLanguage.json @@ -4,7 +4,7 @@ "If you want to provide a fix or improvement, please create a pull request against the original repository.", "Once accepted there, we are happy to receive an update request." ], - "version": "https://github.com/microsoft/TypeScript-TmLanguage/commit/4d30ff834ec324f56291addd197aa1e423cedfdd", + "version": "https://github.com/microsoft/TypeScript-TmLanguage/commit/0dfae8cc4807fecfbf8f1add095d9817df824c95", "name": "TypeScript", "scopeName": "source.ts", "patterns": [ @@ -2268,11 +2268,47 @@ "name": "keyword.control.from.ts", "match": "\\bfrom\\b" }, + { + "include": "#import-export-assert-clause" + }, { "include": "#import-export-clause" } ] }, + "import-export-assert-clause": { + "begin": "(?\\s*$)", + "begin": "^(///)\\s*(?=<(reference|amd-dependency|amd-module)(\\s+(path|types|no-default-lib|lib|name|resolution-mode)\\s*=\\s*((\\'([^\\'\\\\]|\\\\.)*\\')|(\\\"([^\\\"\\\\]|\\\\.)*\\\")|(\\`([^\\`\\\\]|\\\\.)*\\`)))+\\s*/>\\s*$)", "beginCaptures": { "1": { "name": "punctuation.definition.comment.ts" @@ -5141,7 +5177,7 @@ "patterns": [ { "name": "entity.other.attribute-name.directive.ts", - "match": "path|types|no-default-lib|lib|name" + "match": "path|types|no-default-lib|lib|name|resolution-mode" }, { "name": "keyword.operator.assignment.ts", diff --git a/extensions/typescript-basics/syntaxes/TypeScriptReact.tmLanguage.json b/extensions/typescript-basics/syntaxes/TypeScriptReact.tmLanguage.json index fcecb2b8c46..040013e7dcc 100644 --- a/extensions/typescript-basics/syntaxes/TypeScriptReact.tmLanguage.json +++ b/extensions/typescript-basics/syntaxes/TypeScriptReact.tmLanguage.json @@ -4,7 +4,7 @@ "If you want to provide a fix or improvement, please create a pull request against the original repository.", "Once accepted there, we are happy to receive an update request." ], - "version": "https://github.com/microsoft/TypeScript-TmLanguage/commit/4d30ff834ec324f56291addd197aa1e423cedfdd", + "version": "https://github.com/microsoft/TypeScript-TmLanguage/commit/0dfae8cc4807fecfbf8f1add095d9817df824c95", "name": "TypeScriptReact", "scopeName": "source.tsx", "patterns": [ @@ -2271,11 +2271,47 @@ "name": "keyword.control.from.tsx", "match": "\\bfrom\\b" }, + { + "include": "#import-export-assert-clause" + }, { "include": "#import-export-clause" } ] }, + "import-export-assert-clause": { + "begin": "(?\\s*$)", + "begin": "^(///)\\s*(?=<(reference|amd-dependency|amd-module)(\\s+(path|types|no-default-lib|lib|name|resolution-mode)\\s*=\\s*((\\'([^\\'\\\\]|\\\\.)*\\')|(\\\"([^\\\"\\\\]|\\\\.)*\\\")|(\\`([^\\`\\\\]|\\\\.)*\\`)))+\\s*/>\\s*$)", "beginCaptures": { "1": { "name": "punctuation.definition.comment.tsx" @@ -5092,7 +5128,7 @@ "patterns": [ { "name": "entity.other.attribute-name.directive.tsx", - "match": "path|types|no-default-lib|lib|name" + "match": "path|types|no-default-lib|lib|name|resolution-mode" }, { "name": "keyword.operator.assignment.tsx", From 88b9d6fa4671bc8fe7b843f8c33e49c414c38d2d Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Tue, 7 Jun 2022 10:43:01 -0700 Subject: [PATCH 014/117] Debug console items don't use cursor:pointer on windows (#151443) Fixes #151021 --- src/vs/workbench/contrib/debug/browser/media/repl.css | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/contrib/debug/browser/media/repl.css b/src/vs/workbench/contrib/debug/browser/media/repl.css index 76ae10b7bb3..6803c044720 100644 --- a/src/vs/workbench/contrib/debug/browser/media/repl.css +++ b/src/vs/workbench/contrib/debug/browser/media/repl.css @@ -43,8 +43,8 @@ white-space: pre; /* Preserve whitespace but don't wrap */ } -.monaco-workbench.mac .repl .repl-tree .monaco-tl-twistie.collapsible + .monaco-tl-contents, -.monaco-workbench.mac .repl .repl-tree .monaco-tl-twistie { +.monaco-workbench .repl .repl-tree .monaco-tl-twistie.collapsible + .monaco-tl-contents, +.monaco-workbench .repl .repl-tree .monaco-tl-twistie { cursor: pointer; } From 0092b000b0fa421f3c3c70e8ed3e2227fbfdc792 Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Tue, 7 Jun 2022 20:09:35 +0200 Subject: [PATCH 015/117] assign builtin flag for overridden remote builtin extensions (#151446) * remove --enable-proposed-api flag for builtin extensions * use same dedup logic for remote extensions as local extensions --- scripts/test-remote-integration.sh | 2 +- .../server/node/remoteAgentEnvironmentImpl.ts | 34 ++----------------- 2 files changed, 4 insertions(+), 32 deletions(-) diff --git a/scripts/test-remote-integration.sh b/scripts/test-remote-integration.sh index 68c740784a6..7decdf3798f 100755 --- a/scripts/test-remote-integration.sh +++ b/scripts/test-remote-integration.sh @@ -63,7 +63,7 @@ else export ELECTRON_ENABLE_LOGGING=1 # Running from a build, we need to enable the vscode-test-resolver extension - EXTRA_INTEGRATION_TEST_ARGUMENTS="--extensions-dir=$EXT_PATH --enable-proposed-api=vscode.vscode-test-resolver --enable-proposed-api=vscode.vscode-api-tests --enable-proposed-api=vscode.markdown-language-features --enable-proposed-api=vscode.git" + EXTRA_INTEGRATION_TEST_ARGUMENTS="--extensions-dir=$EXT_PATH --enable-proposed-api=vscode.vscode-test-resolver --enable-proposed-api=vscode.vscode-api-tests" echo "Storing crash reports into '$VSCODECRASHDIR'." echo "Storing log files into '$VSCODELOGSDIR'." diff --git a/src/vs/server/node/remoteAgentEnvironmentImpl.ts b/src/vs/server/node/remoteAgentEnvironmentImpl.ts index dd7ebc3daa6..6a51d9f1514 100644 --- a/src/vs/server/node/remoteAgentEnvironmentImpl.ts +++ b/src/vs/server/node/remoteAgentEnvironmentImpl.ts @@ -9,11 +9,10 @@ import * as performance from 'vs/base/common/performance'; import { URI } from 'vs/base/common/uri'; import { createURITransformer } from 'vs/workbench/api/node/uriTransformer'; import { IRemoteAgentEnvironmentDTO, IGetEnvironmentDataArguments, IScanExtensionsArguments, IScanSingleExtensionArguments, IGetExtensionHostExitInfoArguments } from 'vs/workbench/services/remote/common/remoteAgentEnvironmentChannel'; -import * as nls from 'vs/nls'; import { Schemas } from 'vs/base/common/network'; import { IServerEnvironmentService } from 'vs/server/node/serverEnvironmentService'; import { IServerChannel } from 'vs/base/parts/ipc/common/ipc'; -import { ExtensionIdentifier, ExtensionType, IExtensionDescription } from 'vs/platform/extensions/common/extensions'; +import { ExtensionType, IExtensionDescription } from 'vs/platform/extensions/common/extensions'; import { transformOutgoingURIs } from 'vs/base/common/uriIpc'; import { ILogService } from 'vs/platform/log/common/log'; import { ContextKeyExpr, ContextKeyDefinedExpr, ContextKeyNotExpr, ContextKeyEqualsExpr, ContextKeyNotEqualsExpr, ContextKeyRegexExpr, IContextKeyExprMapper, ContextKeyExpression, ContextKeyInExpr, ContextKeyGreaterExpr, ContextKeyGreaterEqualsExpr, ContextKeySmallerExpr, ContextKeySmallerEqualsExpr } from 'vs/platform/contextkey/common/contextkey'; @@ -27,6 +26,7 @@ import { cwd } from 'vs/base/common/process'; import { ServerConnectionToken, ServerConnectionTokenType } from 'vs/server/node/serverConnectionToken'; import { IExtensionHostStatusService } from 'vs/server/node/extensionHostStatusService'; import { IExtensionsScannerService, toExtensionDescription } from 'vs/platform/extensionManagement/common/extensionsScannerService'; +import { dedupExtensions } from 'vs/workbench/services/extensions/common/extensionsUtil'; export class RemoteAgentEnvironmentChannel implements IServerChannel { @@ -310,35 +310,7 @@ export class RemoteAgentEnvironmentChannel implements IServerChannel { this._scanDevelopedExtensions(language, extensionDevelopmentPath) ]); - let result = new Map(); - - builtinExtensions.forEach((builtinExtension) => { - if (!builtinExtension) { - return; - } - result.set(ExtensionIdentifier.toKey(builtinExtension.identifier), builtinExtension); - }); - - installedExtensions.forEach((installedExtension) => { - if (!installedExtension) { - return; - } - if (result.has(ExtensionIdentifier.toKey(installedExtension.identifier))) { - console.warn(nls.localize('overwritingExtension', "Overwriting extension {0} with {1}.", result.get(ExtensionIdentifier.toKey(installedExtension.identifier))!.extensionLocation.fsPath, installedExtension.extensionLocation.fsPath)); - } - result.set(ExtensionIdentifier.toKey(installedExtension.identifier), installedExtension); - }); - - developedExtensions.forEach((developedExtension) => { - if (!developedExtension) { - return; - } - result.set(ExtensionIdentifier.toKey(developedExtension.identifier), developedExtension); - }); - - const r: IExtensionDescription[] = []; - result.forEach((v) => r.push(v)); - return r; + return dedupExtensions(builtinExtensions, installedExtensions, developedExtensions, this._logService); } private async _scanDevelopedExtensions(language: string, extensionDevelopmentPaths?: string[]): Promise { From 89606c8297e2607874e06132477818e90ed66d68 Mon Sep 17 00:00:00 2001 From: SteVen Batten <6561887+sbatten@users.noreply.github.com> Date: Tue, 7 Jun 2022 11:30:10 -0700 Subject: [PATCH 016/117] fixes #144548 (#151448) --- src/vs/platform/telemetry/browser/errorTelemetry.ts | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/vs/platform/telemetry/browser/errorTelemetry.ts b/src/vs/platform/telemetry/browser/errorTelemetry.ts index 48bb12478c4..5646d6f82b1 100644 --- a/src/vs/platform/telemetry/browser/errorTelemetry.ts +++ b/src/vs/platform/telemetry/browser/errorTelemetry.ts @@ -3,6 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +import { ErrorNoTelemetry } from 'vs/base/common/errors'; import { toDisposable } from 'vs/base/common/lifecycle'; import { globals } from 'vs/base/common/platform'; import BaseErrorTelemetry, { ErrorEvent } from 'vs/platform/telemetry/common/errorTelemetry'; @@ -37,6 +38,11 @@ export default class ErrorTelemetry extends BaseErrorTelemetry { }; if (err) { + // If it's the no telemetry error it doesn't get logged + if (err instanceof ErrorNoTelemetry) { + return; + } + let { name, message, stack } = err; data.uncaught_error_name = name; if (message) { From 070fb39a3c3dcc5a56907ef3ad0b53fcd29d6e19 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Tue, 7 Jun 2022 11:45:48 -0700 Subject: [PATCH 017/117] Document DataTransferItem (#151442) This adds missing documentation to the `DataTransferItem` api type --- src/vscode-dts/vscode.d.ts | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/src/vscode-dts/vscode.d.ts b/src/vscode-dts/vscode.d.ts index 485dff49374..88f7fdf67eb 100644 --- a/src/vscode-dts/vscode.d.ts +++ b/src/vscode-dts/vscode.d.ts @@ -10058,14 +10058,27 @@ declare module 'vscode' { } /** - * A class for encapsulating data transferred during a drag and drop event. - * - * You can use the `value` of the `DataTransferItem` to get back the object you put into it - * so long as the extension that created the `DataTransferItem` runs in the same extension host. + * Encapsulates data transferred during drag and drop operations. */ export class DataTransferItem { + /** + * Get a string representation of this item. + * + * If {@linkcode DataTransferItem.value} is an object, this returns the result of json stringifying {@linkcode DataTransferItem.value} value. + */ asString(): Thenable; + + /** + * Custom data stored on this item. + * + * You can use `value` to share data across operations. The original object can be retrieved so long as the extension that + * created the `DataTransferItem` runs in the same extension host. + */ readonly value: any; + + /** + * @param value Custom data stored on this item. Can be retrieved using {@linkcode DataTransferItem.value}. + */ constructor(value: any); } From cfecdd54612140a54d29d591a9c27ae92316417d Mon Sep 17 00:00:00 2001 From: Logan Ramos Date: Tue, 7 Jun 2022 15:53:21 -0400 Subject: [PATCH 018/117] Adopt error no telemetry for filesystem providers. (#148832) Adopt erorr no telemetry --- src/vs/platform/files/common/fileService.ts | 3 ++- src/vs/workbench/api/common/extHostFileSystem.ts | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/vs/platform/files/common/fileService.ts b/src/vs/platform/files/common/fileService.ts index c05a9374965..2117a5228f0 100644 --- a/src/vs/platform/files/common/fileService.ts +++ b/src/vs/platform/files/common/fileService.ts @@ -7,6 +7,7 @@ import { coalesce } from 'vs/base/common/arrays'; import { Promises, ResourceQueue } from 'vs/base/common/async'; import { bufferedStreamToBuffer, bufferToReadable, newWriteableBufferStream, readableToBuffer, streamToBuffer, VSBuffer, VSBufferReadable, VSBufferReadableBufferedStream, VSBufferReadableStream } from 'vs/base/common/buffer'; import { CancellationToken, CancellationTokenSource } from 'vs/base/common/cancellation'; +import { ErrorNoTelemetry } from 'vs/base/common/errors'; import { Emitter } from 'vs/base/common/event'; import { hash } from 'vs/base/common/hash'; import { Iterable } from 'vs/base/common/iterator'; @@ -136,7 +137,7 @@ export class FileService extends Disposable implements IFileService { // Assert provider const provider = this.provider.get(resource.scheme); if (!provider) { - const error = new Error(); + const error = new ErrorNoTelemetry(); error.name = 'ENOPRO'; error.message = localize('noProviderFound', "No file system provider found for resource '{0}'", resource.toString()); diff --git a/src/vs/workbench/api/common/extHostFileSystem.ts b/src/vs/workbench/api/common/extHostFileSystem.ts index 208bc41aabd..42ae83b1a41 100644 --- a/src/vs/workbench/api/common/extHostFileSystem.ts +++ b/src/vs/workbench/api/common/extHostFileSystem.ts @@ -17,6 +17,7 @@ import { CharCode } from 'vs/base/common/charCode'; import { VSBuffer } from 'vs/base/common/buffer'; import { IExtensionDescription } from 'vs/platform/extensions/common/extensions'; import { checkProposedApiEnabled } from 'vs/workbench/services/extensions/common/extensions'; +import { ErrorNoTelemetry } from 'vs/base/common/errors'; class FsLinkProvider { @@ -295,7 +296,7 @@ export class ExtHostFileSystem implements ExtHostFileSystemShape { private _getFsProvider(handle: number): vscode.FileSystemProvider { const provider = this._fsProvider.get(handle); if (!provider) { - const err = new Error(); + const err = new ErrorNoTelemetry(); err.name = 'ENOPRO'; err.message = `no provider`; throw err; From 413100c720e69b0c28771ddb272c428d3fab9a4d Mon Sep 17 00:00:00 2001 From: Alex Ross Date: Tue, 7 Jun 2022 21:59:28 +0200 Subject: [PATCH 019/117] References view shows icons even though I have icons disabled (#151420) (#151424) Fixes #151406 --- .../workbench/browser/parts/views/treeView.ts | 30 +++++++------------ 1 file changed, 11 insertions(+), 19 deletions(-) diff --git a/src/vs/workbench/browser/parts/views/treeView.ts b/src/vs/workbench/browser/parts/views/treeView.ts index 64ce4c648e5..239d853d247 100644 --- a/src/vs/workbench/browser/parts/views/treeView.ts +++ b/src/vs/workbench/browser/parts/views/treeView.ts @@ -64,7 +64,6 @@ import { Extensions, ITreeItem, ITreeItemLabel, ITreeView, ITreeViewDataProvider import { IActivityService, NumberBadge } from 'vs/workbench/services/activity/common/activity'; import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions'; import { IHoverService } from 'vs/workbench/services/hover/browser/hover'; -import { ThemeSettings } from 'vs/workbench/services/themes/common/workbenchThemeService'; import { ITreeViewsService } from 'vs/workbench/services/views/browser/treeViewsService'; import { CodeDataTransfers } from 'vs/platform/dnd/browser/dnd'; import { createFileDataTransferItemFromFile } from 'vs/editor/browser/dnd'; @@ -1019,7 +1018,7 @@ class TreeRenderer extends Disposable implements ITreeRenderer Date: Tue, 7 Jun 2022 13:30:56 -0700 Subject: [PATCH 020/117] Add hc light class to webviews (#151441) Fixes #148057 Resubmit of #148088 with merge fixed --- .../contrib/webview/browser/pre/index-no-csp.html | 7 ++++++- src/vs/workbench/contrib/webview/browser/pre/index.html | 9 +++++++-- src/vs/workbench/contrib/webview/browser/themeing.ts | 6 ++++-- 3 files changed, 17 insertions(+), 5 deletions(-) diff --git a/src/vs/workbench/contrib/webview/browser/pre/index-no-csp.html b/src/vs/workbench/contrib/webview/browser/pre/index-no-csp.html index 625c46f3115..73892574c5a 100644 --- a/src/vs/workbench/contrib/webview/browser/pre/index-no-csp.html +++ b/src/vs/workbench/contrib/webview/browser/pre/index-no-csp.html @@ -469,9 +469,14 @@ } if (body) { - body.classList.remove('vscode-light', 'vscode-dark', 'vscode-high-contrast', 'vscode-reduce-motion', 'vscode-using-screen-reader'); + body.classList.remove('vscode-light', 'vscode-dark', 'vscode-high-contrast', 'vscode-high-contrast-light', 'vscode-reduce-motion', 'vscode-using-screen-reader'); + if (initData.activeTheme) { body.classList.add(initData.activeTheme); + if (initData.activeTheme === 'vscode-high-contrast-light') { + // backwards compatibility + body.classList.add('vscode-high-contrast'); + } } if (initData.reduceMotion) { diff --git a/src/vs/workbench/contrib/webview/browser/pre/index.html b/src/vs/workbench/contrib/webview/browser/pre/index.html index 457447af38e..326a076c677 100644 --- a/src/vs/workbench/contrib/webview/browser/pre/index.html +++ b/src/vs/workbench/contrib/webview/browser/pre/index.html @@ -5,7 +5,7 @@ + content="default-src 'none'; script-src 'sha256-v9xEHcwDE5dc/lU7HYs5bG3LpPWGmQe0w/Vz6kmdd60=' 'self'; frame-src 'self'; style-src 'unsafe-inline';"> Date: Tue, 7 Jun 2022 13:58:29 -0700 Subject: [PATCH 021/117] Fix markdown link detection for links with titles (#151459) Fixes #151458 --- .../languageFeatures/documentLinkProvider.ts | 4 +- .../src/test/diagnostic.test.ts | 52 +++++++++++++++---- .../src/test/documentLinkProvider.test.ts | 19 ++++++- 3 files changed, 62 insertions(+), 13 deletions(-) diff --git a/extensions/markdown-language-features/src/languageFeatures/documentLinkProvider.ts b/extensions/markdown-language-features/src/languageFeatures/documentLinkProvider.ts index 92e0e6d1164..d1457dd3e2a 100644 --- a/extensions/markdown-language-features/src/languageFeatures/documentLinkProvider.ts +++ b/extensions/markdown-language-features/src/languageFeatures/documentLinkProvider.ts @@ -185,12 +185,12 @@ function stripAngleBrackets(link: string) { /** * Matches `[text](link)` */ -const linkPattern = /(\[((!\[[^\]]*?\]\(\s*)([^\s\(\)]+?)\s*\)\]|(?:\\\]|[^\]])*\])\(\s*)(([^\s\(\)]|\([^\s\(\)]*?\))+)\s*(".*?")?\)/g; +const linkPattern = /(\[((!\[[^\]]*?\]\(\s*)([^\s\(\)]+?)\s*\)\]|(?:\\\]|[^\]])*\])\(\s*)(([^\s\(\)]|\([^\s\(\)]*?\))+)\s*("[^"]*"|'[^']*'|\([^\(\)]*\))?\s*\)/g; /** * Matches `[text]()` */ -const linkPatternAngle = /(\[((!\[[^\]]*?\]\(\s*)([^\s\(\)]+?)\s*\)\]|(?:\\\]|[^\]])*\])\(\s*<)(([^<>]|\([^\s\(\)]*?\))+)>\s*(".*?")?\)/g; +const linkPatternAngle = /(\[((!\[[^\]]*?\]\(\s*)([^\s\(\)]+?)\s*\)\]|(?:\\\]|[^\]])*\])\(\s*<)(([^<>]|\([^\s\(\)]*?\))+)>\s*("[^"]*"|'[^']*'|\([^\(\)]*\))?\s*\)/g; /** diff --git a/extensions/markdown-language-features/src/test/diagnostic.test.ts b/extensions/markdown-language-features/src/test/diagnostic.test.ts index 1c6ae3dd6e8..d84a69dd20c 100644 --- a/extensions/markdown-language-features/src/test/diagnostic.test.ts +++ b/extensions/markdown-language-features/src/test/diagnostic.test.ts @@ -37,6 +37,14 @@ function createDiagnosticsManager(workspaceContents: MdWorkspaceContents, config return new DiagnosticManager(new DiagnosticComputer(engine, workspaceContents, linkProvider), configuration); } +function assertDiagnosticsEqual(actual: readonly vscode.Diagnostic[], expectedRanges: readonly vscode.Range[]) { + assert.strictEqual(actual.length, expectedRanges.length); + + for (let i = 0; i < actual.length; ++i) { + assertRangeEqual(actual[i].range, expectedRanges[i], `Range ${i} to be equal`); + } +} + class MemoryDiagnosticConfiguration implements DiagnosticConfiguration { private readonly _onDidChange = new vscode.EventEmitter(); @@ -87,9 +95,10 @@ suite('markdown: Diagnostics', () => { )); const diagnostics = await getComputedDiagnostics(doc, new InMemoryWorkspaceMarkdownDocuments([doc])); - assert.deepStrictEqual(diagnostics.length, 2); - assertRangeEqual(new vscode.Range(0, 6, 0, 22), diagnostics[0].range); - assertRangeEqual(new vscode.Range(3, 11, 3, 27), diagnostics[1].range); + assertDiagnosticsEqual(diagnostics, [ + new vscode.Range(0, 6, 0, 22), + new vscode.Range(3, 11, 3, 27), + ]); }); test('Should generate diagnostics for links to header that does not exist in current file', async () => { @@ -103,9 +112,10 @@ suite('markdown: Diagnostics', () => { )); const diagnostics = await getComputedDiagnostics(doc, new InMemoryWorkspaceMarkdownDocuments([doc])); - assert.deepStrictEqual(diagnostics.length, 2); - assertRangeEqual(new vscode.Range(2, 6, 2, 21), diagnostics[0].range); - assertRangeEqual(new vscode.Range(5, 11, 5, 26), diagnostics[1].range); + assertDiagnosticsEqual(diagnostics, [ + new vscode.Range(2, 6, 2, 21), + new vscode.Range(5, 11, 5, 26), + ]); }); test('Should generate diagnostics for links to non-existent headers in other files', async () => { @@ -123,8 +133,9 @@ suite('markdown: Diagnostics', () => { )); const diagnostics = await getComputedDiagnostics(doc1, new InMemoryWorkspaceMarkdownDocuments([doc1, doc2])); - assert.deepStrictEqual(diagnostics.length, 1); - assertRangeEqual(new vscode.Range(5, 6, 5, 35), diagnostics[0].range); + assertDiagnosticsEqual(diagnostics, [ + new vscode.Range(5, 6, 5, 35), + ]); }); test('Should support links both with and without .md file extension', async () => { @@ -150,8 +161,9 @@ suite('markdown: Diagnostics', () => { )); const diagnostics = await getComputedDiagnostics(doc, new InMemoryWorkspaceMarkdownDocuments([doc])); - assert.deepStrictEqual(diagnostics.length, 1); - assertRangeEqual(new vscode.Range(1, 11, 1, 18), diagnostics[0].range); + assertDiagnosticsEqual(diagnostics, [ + new vscode.Range(1, 11, 1, 18), + ]); }); test('Should not generate diagnostics when validate is disabled', async () => { @@ -281,4 +293,24 @@ suite('markdown: Diagnostics', () => { const { diagnostics } = await manager.recomputeDiagnosticState(doc1, noopToken); assert.deepStrictEqual(diagnostics.length, 0); }); + + test('Should detect invalid links with titles', async () => { + const doc = new InMemoryDocument(workspacePath('doc1.md'), joinLines( + `[link]( "text")`, + `[link]( 'text')`, + `[link]( (text))`, + `[link](no-such.md "text")`, + `[link](no-such.md 'text')`, + `[link](no-such.md (text))`, + )); + const diagnostics = await getComputedDiagnostics(doc, new InMemoryWorkspaceMarkdownDocuments([doc])); + assertDiagnosticsEqual(diagnostics, [ + new vscode.Range(0, 8, 0, 18), + new vscode.Range(1, 8, 1, 18), + new vscode.Range(2, 8, 2, 18), + new vscode.Range(3, 7, 3, 17), + new vscode.Range(4, 7, 4, 17), + new vscode.Range(5, 7, 5, 17), + ]); + }); }); diff --git a/extensions/markdown-language-features/src/test/documentLinkProvider.test.ts b/extensions/markdown-language-features/src/test/documentLinkProvider.test.ts index 29793b2a5d8..37d9330d357 100644 --- a/extensions/markdown-language-features/src/test/documentLinkProvider.test.ts +++ b/extensions/markdown-language-features/src/test/documentLinkProvider.test.ts @@ -408,5 +408,22 @@ suite('markdown.DocumentLinkProvider', () => { assertLinksEqual(links, [new vscode.Range(0, 8, 0, 13)]); }); - + test('Should find links with titles', async () => { + const links = await getLinksForFile(joinLines( + `[link]( "text")`, + `[link]( 'text')`, + `[link]( (text))`, + `[link](no-such.md "text")`, + `[link](no-such.md 'text')`, + `[link](no-such.md (text))`, + )); + assertLinksEqual(links, [ + new vscode.Range(0, 8, 0, 18), + new vscode.Range(1, 8, 1, 18), + new vscode.Range(2, 8, 2, 18), + new vscode.Range(3, 7, 3, 17), + new vscode.Range(4, 7, 4, 17), + new vscode.Range(5, 7, 5, 17), + ]); + }); }); From da6e512e1333a3e96a8f9a217ae184fa7db759d4 Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Tue, 7 Jun 2022 14:17:21 -0700 Subject: [PATCH 022/117] Fix Altair save button in the interactive window (#151389) Altair save as button doesn't work in the interactive window Fixes #150323 --- .../notebook/browser/view/renderers/backLayerWebView.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/vs/workbench/contrib/notebook/browser/view/renderers/backLayerWebView.ts b/src/vs/workbench/contrib/notebook/browser/view/renderers/backLayerWebView.ts index dedbe999773..e3e541e1d9f 100644 --- a/src/vs/workbench/contrib/notebook/browser/view/renderers/backLayerWebView.ts +++ b/src/vs/workbench/contrib/notebook/browser/view/renderers/backLayerWebView.ts @@ -37,7 +37,6 @@ import { preloadsScriptStr, RendererMetadata } from 'vs/workbench/contrib/notebo import { transformWebviewThemeVars } from 'vs/workbench/contrib/notebook/browser/view/renderers/webviewThemeMapping'; import { MarkupCellViewModel } from 'vs/workbench/contrib/notebook/browser/viewModel/markupCellViewModel'; import { CellUri, INotebookRendererInfo, NotebookSetting, RendererMessagingSpec } from 'vs/workbench/contrib/notebook/common/notebookCommon'; -import { INotebookExecutionStateService } from 'vs/workbench/contrib/notebook/common/notebookExecutionStateService'; import { INotebookKernel } from 'vs/workbench/contrib/notebook/common/notebookKernelService'; import { IScopedRendererMessaging } from 'vs/workbench/contrib/notebook/common/notebookRendererMessagingService'; import { INotebookService } from 'vs/workbench/contrib/notebook/common/notebookService'; @@ -136,7 +135,6 @@ export class BackLayerWebView extends Disposable { @ILanguageService private readonly languageService: ILanguageService, @IWorkspaceContextService private readonly workspaceContextService: IWorkspaceContextService, @IEditorGroupsService private readonly editorGroupService: IEditorGroupsService, - @INotebookExecutionStateService notebookExecutionStateService: INotebookExecutionStateService ) { super(); @@ -859,7 +857,9 @@ var requirejs = (function() { return; } - const defaultDir = dirname(this.documentUri); + const defaultDir = this.documentUri.scheme === Schemas.vscodeInteractive ? + this.workspaceContextService.getWorkspace().folders[0]?.uri ?? await this.fileDialogService.defaultFilePath() : + dirname(this.documentUri); let defaultName: string; if (event.downloadName) { defaultName = event.downloadName; From 0dfe96e423ce3b26e5499ce03af7b7f86ac8d6fe Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Tue, 7 Jun 2022 14:17:48 -0700 Subject: [PATCH 023/117] Keep webview from stealing focus from save dialog (#151391) Keep webview from stealing focus from save dialog. Not sure why this timeout was needed two years ago, but the behavior is the same now. The behavior is not perfect anyway. Fixes #151390 --- .../browser/view/renderers/backLayerWebView.ts | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/vs/workbench/contrib/notebook/browser/view/renderers/backLayerWebView.ts b/src/vs/workbench/contrib/notebook/browser/view/renderers/backLayerWebView.ts index e3e541e1d9f..29537af1c02 100644 --- a/src/vs/workbench/contrib/notebook/browser/view/renderers/backLayerWebView.ts +++ b/src/vs/workbench/contrib/notebook/browser/view/renderers/backLayerWebView.ts @@ -1336,12 +1336,10 @@ var requirejs = (function() { this.webview?.focus(); } - setTimeout(() => { // Need this, or focus decoration is not shown. No clue. - this._sendMessageToWebview({ - type: 'focus-output', - cellId, - }); - }, 50); + this._sendMessageToWebview({ + type: 'focus-output', + cellId, + }); } async find(query: string, options: { wholeWord?: boolean; caseSensitive?: boolean; includeMarkup: boolean; includeOutput: boolean }): Promise { From 8adb9e72c727c490623232b48d0fe10c7f42d7a0 Mon Sep 17 00:00:00 2001 From: Megan Rogge Date: Tue, 7 Jun 2022 14:10:46 -0800 Subject: [PATCH 024/117] wait for profiles to be ready before creating 1st terminal (#151452) fix #138999 --- .../contrib/terminal/browser/terminalService.ts | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/vs/workbench/contrib/terminal/browser/terminalService.ts b/src/vs/workbench/contrib/terminal/browser/terminalService.ts index 62d52e82cc9..06a447308f8 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalService.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalService.ts @@ -929,12 +929,10 @@ export class TerminalService implements ITerminalService { // Await the initialization of available profiles as long as this is not a pty terminal or a // local terminal in a remote workspace as profile won't be used in those cases and these // terminals need to be launched before remote connections are established. - if (!this._terminalProfileService.availableProfiles) { - const isPtyTerminal = options?.config && 'customPtyImplementation' in options.config; - const isLocalInRemoteTerminal = this._remoteAgentService.getConnection() && URI.isUri(options?.cwd) && options?.cwd.scheme === Schemas.vscodeFileResource; - if (!isPtyTerminal && !isLocalInRemoteTerminal) { - await this._terminalProfileService.refreshAvailableProfiles(); - } + const isPtyTerminal = options?.config && 'customPtyImplementation' in options.config; + const isLocalInRemoteTerminal = this._remoteAgentService.getConnection() && URI.isUri(options?.cwd) && options?.cwd.scheme === Schemas.vscodeFileResource; + if (!isPtyTerminal && !isLocalInRemoteTerminal) { + await this._terminalProfileService.profilesReady; } const config = options?.config || this._terminalProfileService.availableProfiles?.find(p => p.profileName === this._terminalProfileService.getDefaultProfileName()); From 5bbab47c7ce18a21daf4bda078aa8b29cf90f8b9 Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Tue, 7 Jun 2022 16:46:04 -0700 Subject: [PATCH 025/117] Debug breakpoint warning improvements (#151379) * Show unverified breakpoint warning on breakpoint hover For #142870 * Add warning icon to breakpoint hover as well * Filter breakpoint warning indicator for breakpoints in languages that the debugger supports * Update src/vs/workbench/contrib/debug/browser/breakpointEditorContribution.ts Co-authored-by: Connor Peet * Fix tests * Fix tests Co-authored-by: Connor Peet --- .../browser/breakpointEditorContribution.ts | 50 +++++++++++++++---- .../contrib/debug/browser/breakpointsView.ts | 20 ++++++-- .../debug/browser/debugAdapterManager.ts | 17 ++----- .../contrib/debug/browser/disassemblyView.ts | 4 +- .../contrib/debug/browser/welcomeView.ts | 2 +- .../workbench/contrib/debug/common/debug.ts | 11 +++- .../contrib/debug/common/debugger.ts | 8 ++- .../debug/test/browser/breakpoints.test.ts | 23 ++++++--- 8 files changed, 95 insertions(+), 40 deletions(-) diff --git a/src/vs/workbench/contrib/debug/browser/breakpointEditorContribution.ts b/src/vs/workbench/contrib/debug/browser/breakpointEditorContribution.ts index a99f1bec5a1..40526614fff 100644 --- a/src/vs/workbench/contrib/debug/browser/breakpointEditorContribution.ts +++ b/src/vs/workbench/contrib/debug/browser/breakpointEditorContribution.ts @@ -12,10 +12,10 @@ import { IAction, Action, SubmenuAction, Separator } from 'vs/base/common/action import { Range } from 'vs/editor/common/core/range'; import { ICodeEditor, IEditorMouseEvent, MouseTargetType, IContentWidget, IActiveCodeEditor, IContentWidgetPosition, ContentWidgetPositionPreference } from 'vs/editor/browser/editorBrowser'; import { IModelDecorationOptions, TrackedRangeStickiness, ITextModel, OverviewRulerLane, IModelDecorationOverviewRulerOptions } from 'vs/editor/common/model'; -import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; +import { IInstantiationService, ServicesAccessor } from 'vs/platform/instantiation/common/instantiation'; import { IContextKeyService, IContextKey } from 'vs/platform/contextkey/common/contextkey'; import { IContextMenuService } from 'vs/platform/contextview/browser/contextView'; -import { IDebugService, IBreakpoint, CONTEXT_BREAKPOINT_WIDGET_VISIBLE, BreakpointWidgetContext, IBreakpointEditorContribution, IBreakpointUpdateData, IDebugConfiguration, State, IDebugSession } from 'vs/workbench/contrib/debug/common/debug'; +import { IDebugService, IBreakpoint, CONTEXT_BREAKPOINT_WIDGET_VISIBLE, BreakpointWidgetContext, IBreakpointEditorContribution, IBreakpointUpdateData, IDebugConfiguration, State, IDebugSession, DebuggerUiMessage } from 'vs/workbench/contrib/debug/common/debug'; import { IDialogService } from 'vs/platform/dialogs/common/dialogs'; import { BreakpointWidget } from 'vs/workbench/contrib/debug/browser/breakpointWidget'; import { IDisposable, dispose } from 'vs/base/common/lifecycle'; @@ -36,6 +36,8 @@ import { ILabelService } from 'vs/platform/label/common/label'; import * as icons from 'vs/workbench/contrib/debug/browser/debugIcons'; import { onUnexpectedError } from 'vs/base/common/errors'; import { noBreakWhitespace } from 'vs/base/common/strings'; +import { ILanguageService } from 'vs/editor/common/languages/language'; +import { withNullAsUndefined } from 'vs/base/common/types'; const $ = dom.$; @@ -52,7 +54,7 @@ const breakpointHelperDecoration: IModelDecorationOptions = { stickiness: TrackedRangeStickiness.NeverGrowsWhenTypingAtEdges }; -export function createBreakpointDecorations(model: ITextModel, breakpoints: ReadonlyArray, state: State, breakpointsActivated: boolean, showBreakpointsInOverviewRuler: boolean): { range: Range; options: IModelDecorationOptions }[] { +export function createBreakpointDecorations(accessor: ServicesAccessor, model: ITextModel, breakpoints: ReadonlyArray, state: State, breakpointsActivated: boolean, showBreakpointsInOverviewRuler: boolean): { range: Range; options: IModelDecorationOptions }[] { const result: { range: Range; options: IModelDecorationOptions }[] = []; breakpoints.forEach((breakpoint) => { if (breakpoint.lineNumber > model.getLineCount()) { @@ -65,7 +67,7 @@ export function createBreakpointDecorations(model: ITextModel, breakpoints: Read ); result.push({ - options: getBreakpointDecorationOptions(model, breakpoint, state, breakpointsActivated, showBreakpointsInOverviewRuler), + options: getBreakpointDecorationOptions(accessor, model, breakpoint, state, breakpointsActivated, showBreakpointsInOverviewRuler), range }); }); @@ -73,17 +75,47 @@ export function createBreakpointDecorations(model: ITextModel, breakpoints: Read return result; } -function getBreakpointDecorationOptions(model: ITextModel, breakpoint: IBreakpoint, state: State, breakpointsActivated: boolean, showBreakpointsInOverviewRuler: boolean): IModelDecorationOptions { - const { icon, message } = getBreakpointMessageAndIcon(state, breakpointsActivated, breakpoint, undefined); +function getBreakpointDecorationOptions(accessor: ServicesAccessor, model: ITextModel, breakpoint: IBreakpoint, state: State, breakpointsActivated: boolean, showBreakpointsInOverviewRuler: boolean): IModelDecorationOptions { + const debugService = accessor.get(IDebugService); + const languageService = accessor.get(ILanguageService); + const { icon, message, showAdapterUnverifiedMessage } = getBreakpointMessageAndIcon(state, breakpointsActivated, breakpoint, undefined); let glyphMarginHoverMessage: MarkdownString | undefined; + let unverifiedMessage: string | undefined; + if (showAdapterUnverifiedMessage) { + let langId: string | undefined; + unverifiedMessage = debugService.getModel().getSessions().map(s => { + const dbg = debugService.getAdapterManager().getDebugger(s.configuration.type); + const message = dbg?.uiMessages?.[DebuggerUiMessage.UnverifiedBreakpoints]; + if (message) { + if (!langId) { + // Lazily compute this, only if needed for some debug adapter + langId = withNullAsUndefined(languageService.guessLanguageIdByFilepathOrFirstLine(breakpoint.uri)); + } + return langId && dbg.interestedInLanguage(langId) ? message : undefined; + } + + return undefined; + }) + .find(messages => !!messages); + } + if (message) { + glyphMarginHoverMessage = new MarkdownString(undefined, { isTrusted: true, supportThemeIcons: true }); if (breakpoint.condition || breakpoint.hitCondition) { const languageId = model.getLanguageId(); - glyphMarginHoverMessage = new MarkdownString().appendCodeblock(languageId, message); + glyphMarginHoverMessage.appendCodeblock(languageId, message); + if (unverifiedMessage) { + glyphMarginHoverMessage.appendMarkdown('$(warning) ' + unverifiedMessage); + } } else { - glyphMarginHoverMessage = new MarkdownString().appendText(message); + glyphMarginHoverMessage.appendText(message); + if (unverifiedMessage) { + glyphMarginHoverMessage.appendMarkdown('\n\n$(warning) ' + unverifiedMessage); + } } + } else if (unverifiedMessage) { + glyphMarginHoverMessage = new MarkdownString(undefined, { isTrusted: true, supportThemeIcons: true }).appendMarkdown(unverifiedMessage); } let overviewRulerDecoration: IModelDecorationOverviewRulerOptions | null = null; @@ -469,7 +501,7 @@ export class BreakpointEditorContribution implements IBreakpointEditorContributi const model = activeCodeEditor.getModel(); const breakpoints = this.debugService.getModel().getBreakpoints({ uri: model.uri }); const debugSettings = this.configurationService.getValue('debug'); - const desiredBreakpointDecorations = createBreakpointDecorations(model, breakpoints, this.debugService.state, this.debugService.getModel().areBreakpointsActivated(), debugSettings.showBreakpointsInOverviewRuler); + const desiredBreakpointDecorations = this.instantiationService.invokeFunction(accessor => createBreakpointDecorations(accessor, model, breakpoints, this.debugService.state, this.debugService.getModel().areBreakpointsActivated(), debugSettings.showBreakpointsInOverviewRuler)); try { this.ignoreDecorationsChangedEvent = true; diff --git a/src/vs/workbench/contrib/debug/browser/breakpointsView.ts b/src/vs/workbench/contrib/debug/browser/breakpointsView.ts index 1b14740bef4..2e020ea8fa6 100644 --- a/src/vs/workbench/contrib/debug/browser/breakpointsView.ts +++ b/src/vs/workbench/contrib/debug/browser/breakpointsView.ts @@ -23,6 +23,7 @@ import * as resources from 'vs/base/common/resources'; import { Constants } from 'vs/base/common/uint'; import { isCodeEditor } from 'vs/editor/browser/editorBrowser'; import { ServicesAccessor } from 'vs/editor/browser/editorExtensions'; +import { ILanguageService } from 'vs/editor/common/languages/language'; import { localize } from 'vs/nls'; import { createAndFillInActionBarActions, createAndFillInContextMenuActions } from 'vs/platform/actions/browser/menuEntryActionViewItem'; import { Action2, IMenu, IMenuService, MenuId, registerAction2 } from 'vs/platform/actions/common/actions'; @@ -106,6 +107,7 @@ export class BreakpointsView extends ViewPane { @ILabelService private readonly labelService: ILabelService, @IMenuService menuService: IMenuService, @IHoverService private readonly hoverService: IHoverService, + @ILanguageService private readonly languageService: ILanguageService, ) { super(options, keybindingService, contextMenuService, configurationService, contextKeyService, viewDescriptorService, instantiationService, openerService, themeService, telemetryService); @@ -285,12 +287,19 @@ export class BreakpointsView extends ViewPane { return; } - const hasSomeUnverified = this.debugService.getModel().getBreakpoints().some(bp => !bp.verified); - const currentType = this.debugService.getViewModel().focusedSession?.configuration.type; - const message = currentType && this.debugService.getAdapterManager().getDebuggerUiMessages(currentType)[DebuggerUiMessage.UnverifiedBreakpoints]; + const dbg = currentType ? this.debugService.getAdapterManager().getDebugger(currentType) : undefined; + const message = dbg?.uiMessages && dbg.uiMessages[DebuggerUiMessage.UnverifiedBreakpoints]; + const debuggerHasUnverifiedBps = message && this.debugService.getModel().getBreakpoints().filter(bp => { + if (bp.verified) { + return false; + } - if (message && hasSomeUnverified) { + const langId = this.languageService.guessLanguageIdByFilepathOrFirstLine(bp.uri); + return langId && dbg.interestedInLanguage(langId); + }); + + if (message && debuggerHasUnverifiedBps?.length) { if (delayed) { const mdown = new MarkdownString(undefined, { isTrusted: true }).appendMarkdown(message); this.hintContainer.setLabel('$(warning)', undefined, { title: { markdown: mdown, markdownNotSupportedFallback: message } }); @@ -1075,7 +1084,7 @@ export function openBreakpointSource(breakpoint: IBreakpoint, sideBySide: boolea }, sideBySide ? SIDE_GROUP : ACTIVE_GROUP); } -export function getBreakpointMessageAndIcon(state: State, breakpointsActivated: boolean, breakpoint: BreakpointItem, labelService?: ILabelService): { message?: string; icon: ThemeIcon } { +export function getBreakpointMessageAndIcon(state: State, breakpointsActivated: boolean, breakpoint: BreakpointItem, labelService?: ILabelService): { message?: string; icon: ThemeIcon; showAdapterUnverifiedMessage?: boolean } { const debugActive = state === State.Running || state === State.Stopped; const breakpointIcon = breakpoint instanceof DataBreakpoint ? icons.dataBreakpoint : breakpoint instanceof FunctionBreakpoint ? icons.functionBreakpoint : breakpoint.logMessage ? icons.logBreakpoint : icons.breakpoint; @@ -1094,6 +1103,7 @@ export function getBreakpointMessageAndIcon(state: State, breakpointsActivated: return { icon: breakpointIcon.unverified, message: ('message' in breakpoint && breakpoint.message) ? breakpoint.message : (breakpoint.logMessage ? localize('unverifiedLogpoint', "Unverified Logpoint") : localize('unverifiedBreakpoint', "Unverified Breakpoint")), + showAdapterUnverifiedMessage: true }; } diff --git a/src/vs/workbench/contrib/debug/browser/debugAdapterManager.ts b/src/vs/workbench/contrib/debug/browser/debugAdapterManager.ts index 8ec92069345..c4fbab00e3a 100644 --- a/src/vs/workbench/contrib/debug/browser/debugAdapterManager.ts +++ b/src/vs/workbench/contrib/debug/browser/debugAdapterManager.ts @@ -23,7 +23,7 @@ import { IQuickInputService } from 'vs/platform/quickinput/common/quickInput'; import { Registry } from 'vs/platform/registry/common/platform'; import { IWorkspaceFolder } from 'vs/platform/workspace/common/workspace'; import { Breakpoints } from 'vs/workbench/contrib/debug/common/breakpoints'; -import { CONTEXT_DEBUGGERS_AVAILABLE, CONTEXT_DEBUG_EXTENSION_AVAILABLE, DebuggerUiMessage, IAdapterDescriptor, IAdapterManager, IConfig, IDebugAdapter, IDebugAdapterDescriptorFactory, IDebugAdapterFactory, IDebugConfiguration, IDebugSession, INTERNAL_CONSOLE_OPTIONS_SCHEMA } from 'vs/workbench/contrib/debug/common/debug'; +import { CONTEXT_DEBUGGERS_AVAILABLE, CONTEXT_DEBUG_EXTENSION_AVAILABLE, IAdapterDescriptor, IAdapterManager, IConfig, IDebugAdapter, IDebugAdapterDescriptorFactory, IDebugAdapterFactory, IDebugConfiguration, IDebugSession, INTERNAL_CONSOLE_OPTIONS_SCHEMA } from 'vs/workbench/contrib/debug/common/debug'; import { Debugger } from 'vs/workbench/contrib/debug/common/debugger'; import { breakpointsExtPoint, debuggersExtPoint, launchSchema, presentationSchema } from 'vs/workbench/contrib/debug/common/debugSchemas'; import { TaskDefinitionRegistry } from 'vs/workbench/contrib/tasks/common/taskDefinitionRegistry'; @@ -273,15 +273,6 @@ export class AdapterManager extends Disposable implements IAdapterManager { return undefined; } - getDebuggerUiMessages(type: string): { [key in DebuggerUiMessage]?: string } { - const dbgr = this.getDebugger(type); - if (dbgr) { - return dbgr.uiMessages || {}; - } - - return {}; - } - get onDidRegisterDebugger(): Event { return this._onDidRegisterDebugger.event; } @@ -312,10 +303,10 @@ export class AdapterManager extends Disposable implements IAdapterManager { return adapter && adapter.enabled ? adapter : undefined; } - isDebuggerInterestedInLanguage(language: string): boolean { + someDebuggerInterestedInLanguage(languageId: string): boolean { return !!this.debuggers .filter(d => d.enabled) - .find(a => language && a.languages && a.languages.indexOf(language) >= 0); + .find(a => a.interestedInLanguage(languageId)); } async guessDebugger(gettingConfigurations: boolean): Promise { @@ -331,7 +322,7 @@ export class AdapterManager extends Disposable implements IAdapterManager { } const adapters = this.debuggers .filter(a => a.enabled) - .filter(a => language && a.languages && a.languages.indexOf(language) >= 0); + .filter(a => language && a.interestedInLanguage(language)); if (adapters.length === 1) { return adapters[0]; } diff --git a/src/vs/workbench/contrib/debug/browser/disassemblyView.ts b/src/vs/workbench/contrib/debug/browser/disassemblyView.ts index cc58a507c36..682133ef7bd 100644 --- a/src/vs/workbench/contrib/debug/browser/disassemblyView.ts +++ b/src/vs/workbench/contrib/debug/browser/disassemblyView.ts @@ -800,10 +800,10 @@ export class DisassemblyViewContribution implements IWorkbenchContribution { const language = activeTextEditorControl.getModel()?.getLanguageId(); // TODO: instead of using idDebuggerInterestedInLanguage, have a specific ext point for languages // support disassembly - this._languageSupportsDisassemleRequest?.set(!!language && debugService.getAdapterManager().isDebuggerInterestedInLanguage(language)); + this._languageSupportsDisassemleRequest?.set(!!language && debugService.getAdapterManager().someDebuggerInterestedInLanguage(language)); this._onDidChangeModelLanguage = activeTextEditorControl.onDidChangeModelLanguage(e => { - this._languageSupportsDisassemleRequest?.set(debugService.getAdapterManager().isDebuggerInterestedInLanguage(e.newLanguage)); + this._languageSupportsDisassemleRequest?.set(debugService.getAdapterManager().someDebuggerInterestedInLanguage(e.newLanguage)); }); } else { this._languageSupportsDisassemleRequest?.set(false); diff --git a/src/vs/workbench/contrib/debug/browser/welcomeView.ts b/src/vs/workbench/contrib/debug/browser/welcomeView.ts index c936f453d32..28ca270995d 100644 --- a/src/vs/workbench/contrib/debug/browser/welcomeView.ts +++ b/src/vs/workbench/contrib/debug/browser/welcomeView.ts @@ -65,7 +65,7 @@ export class WelcomeView extends ViewPane { if (isCodeEditor(editorControl)) { const model = editorControl.getModel(); const language = model ? model.getLanguageId() : undefined; - if (language && this.debugService.getAdapterManager().isDebuggerInterestedInLanguage(language)) { + if (language && this.debugService.getAdapterManager().someDebuggerInterestedInLanguage(language)) { this.debugStartLanguageContext.set(language); this.debuggerInterestedContext.set(true); storageSevice.store(debugStartLanguageKey, language, StorageScope.WORKSPACE, StorageTarget.MACHINE); diff --git a/src/vs/workbench/contrib/debug/common/debug.ts b/src/vs/workbench/contrib/debug/common/debug.ts index 5a19cdff64f..a0af68b8864 100644 --- a/src/vs/workbench/contrib/debug/common/debug.ts +++ b/src/vs/workbench/contrib/debug/common/debug.ts @@ -159,6 +159,13 @@ export interface IDebugger { getCustomTelemetryEndpoint(): ITelemetryEndpoint | undefined; } +export interface IDebuggerMetadata { + label: string; + type: string; + uiMessages?: { [key in DebuggerUiMessage]: string }; + interestedInLanguage(languageId: string): boolean; +} + export const enum State { Inactive, Initializing, @@ -859,8 +866,8 @@ export interface IAdapterManager { hasEnabledDebuggers(): boolean; getDebugAdapterDescriptor(session: IDebugSession): Promise; getDebuggerLabel(type: string): string | undefined; - isDebuggerInterestedInLanguage(language: string): boolean; - getDebuggerUiMessages(type: string): { [key in DebuggerUiMessage]?: string }; + someDebuggerInterestedInLanguage(language: string): boolean; + getDebugger(type: string): IDebuggerMetadata | undefined; activateDebuggers(activationEvent: string, debugType?: string): Promise; registerDebugAdapterFactory(debugTypes: string[], debugAdapterFactory: IDebugAdapterFactory): IDisposable; diff --git a/src/vs/workbench/contrib/debug/common/debugger.ts b/src/vs/workbench/contrib/debug/common/debugger.ts index 6345e41bf8d..072c6795e33 100644 --- a/src/vs/workbench/contrib/debug/common/debugger.ts +++ b/src/vs/workbench/contrib/debug/common/debugger.ts @@ -7,7 +7,7 @@ import * as nls from 'vs/nls'; import { isObject } from 'vs/base/common/types'; import { IJSONSchema, IJSONSchemaMap, IJSONSchemaSnippet } from 'vs/base/common/jsonSchema'; import { IWorkspaceFolder } from 'vs/platform/workspace/common/workspace'; -import { IConfig, IDebuggerContribution, IDebugAdapter, IDebugger, IDebugSession, IAdapterManager, IDebugService, debuggerDisabledMessage } from 'vs/workbench/contrib/debug/common/debug'; +import { IConfig, IDebuggerContribution, IDebugAdapter, IDebugger, IDebugSession, IAdapterManager, IDebugService, debuggerDisabledMessage, IDebuggerMetadata } from 'vs/workbench/contrib/debug/common/debug'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { IConfigurationResolverService } from 'vs/workbench/services/configurationResolver/common/configurationResolver'; import * as ConfigurationResolverUtils from 'vs/workbench/services/configurationResolver/common/configurationResolverUtils'; @@ -21,7 +21,7 @@ import { cleanRemoteAuthority } from 'vs/platform/telemetry/common/telemetryUtil import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService'; import { ContextKeyExpr, ContextKeyExpression, IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; -export class Debugger implements IDebugger { +export class Debugger implements IDebugger, IDebuggerMetadata { private debuggerContribution: IDebuggerContribution; private mergedExtensionDescriptions: IExtensionDescription[] = []; @@ -151,6 +151,10 @@ export class Debugger implements IDebugger { return this.debuggerContribution.uiMessages; } + interestedInLanguage(languageId: string): boolean { + return !!(this.languages && this.languages.indexOf(languageId) >= 0); + } + hasInitialConfiguration(): boolean { return !!this.debuggerContribution.initialConfigurations; } diff --git a/src/vs/workbench/contrib/debug/test/browser/breakpoints.test.ts b/src/vs/workbench/contrib/debug/test/browser/breakpoints.test.ts index e8d88ddaf01..8dd479109dd 100644 --- a/src/vs/workbench/contrib/debug/test/browser/breakpoints.test.ts +++ b/src/vs/workbench/contrib/debug/test/browser/breakpoints.test.ts @@ -7,15 +7,18 @@ import * as assert from 'assert'; import { URI as uri } from 'vs/base/common/uri'; import { DebugModel, Breakpoint } from 'vs/workbench/contrib/debug/common/debugModel'; import { getExpandedBodySize, getBreakpointMessageAndIcon } from 'vs/workbench/contrib/debug/browser/breakpointsView'; -import { dispose } from 'vs/base/common/lifecycle'; +import { DisposableStore, dispose } from 'vs/base/common/lifecycle'; import { Range } from 'vs/editor/common/core/range'; -import { IBreakpointData, IBreakpointUpdateData, State } from 'vs/workbench/contrib/debug/common/debug'; +import { IBreakpointData, IBreakpointUpdateData, IDebugService, State } from 'vs/workbench/contrib/debug/common/debug'; import { createBreakpointDecorations } from 'vs/workbench/contrib/debug/browser/breakpointEditorContribution'; import { OverviewRulerLane } from 'vs/editor/common/model'; import { MarkdownString } from 'vs/base/common/htmlContent'; import { createTextModel } from 'vs/editor/test/common/testTextModel'; import { createMockSession } from 'vs/workbench/contrib/debug/test/browser/callStack.test'; -import { createMockDebugModel } from 'vs/workbench/contrib/debug/test/browser/mockDebug'; +import { createMockDebugModel, MockDebugService } from 'vs/workbench/contrib/debug/test/browser/mockDebug'; +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'; function addBreakpointsAndCheckEvents(model: DebugModel, uri: uri, data: IBreakpointData[]): void { let eventCount = 0; @@ -39,11 +42,16 @@ function addBreakpointsAndCheckEvents(model: DebugModel, uri: uri, data: IBreakp suite('Debug - Breakpoints', () => { let model: DebugModel; + const disposables = new DisposableStore(); setup(() => { model = createMockDebugModel(); }); + teardown(() => { + disposables.clear(); + }); + // Breakpoints test('simple', () => { @@ -350,7 +358,10 @@ suite('Debug - Breakpoints', () => { ]); const breakpoints = model.getBreakpoints(); - let decorations = createBreakpointDecorations(textModel, breakpoints, State.Running, true, true); + const instantiationService = new TestInstantiationService(); + instantiationService.stub(IDebugService, new MockDebugService()); + instantiationService.stub(ILanguageService, disposables.add(new LanguageService())); + let decorations = instantiationService.invokeFunction(accessor => createBreakpointDecorations(accessor, textModel, breakpoints, State.Running, true, true)); assert.strictEqual(decorations.length, 3); // last breakpoint filtered out since it has a large line number assert.deepStrictEqual(decorations[0].range, new Range(1, 1, 1, 2)); assert.deepStrictEqual(decorations[1].range, new Range(2, 4, 2, 5)); @@ -358,10 +369,10 @@ suite('Debug - Breakpoints', () => { assert.strictEqual(decorations[0].options.beforeContentClassName, undefined); assert.strictEqual(decorations[1].options.before?.inlineClassName, `debug-breakpoint-placeholder`); assert.strictEqual(decorations[0].options.overviewRuler?.position, OverviewRulerLane.Left); - const expected = new MarkdownString().appendCodeblock(languageId, 'Expression condition: x > 5'); + const expected = new MarkdownString(undefined, { isTrusted: true, supportThemeIcons: true }).appendCodeblock(languageId, 'Expression condition: x > 5'); assert.deepStrictEqual(decorations[0].options.glyphMarginHoverMessage, expected); - decorations = createBreakpointDecorations(textModel, breakpoints, State.Running, true, false); + decorations = instantiationService.invokeFunction(accessor => createBreakpointDecorations(accessor, textModel, breakpoints, State.Running, true, false)); assert.strictEqual(decorations[0].options.overviewRuler, null); textModel.dispose(); From 60a68d666d7a3d39b614ecf3442bb12796bdaebd Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Tue, 7 Jun 2022 18:00:10 -0700 Subject: [PATCH 026/117] Add resourceMap helper for markdown extension (#151471) This change introduces a `ResoruceMap` map type that is essentially `Map` It also fixes a potential race condition with `MdWorkspaceCache` where two quick calls would both trigger init --- .../src/languageFeatures/references.ts | 6 +- .../src/languageFeatures/workspaceCache.ts | 41 +++++++----- .../workspaceSymbolProvider.ts | 2 +- .../src/util/resourceMap.ts | 62 +++++++++++++++++++ 4 files changed, 90 insertions(+), 21 deletions(-) create mode 100644 extensions/markdown-language-features/src/util/resourceMap.ts diff --git a/extensions/markdown-language-features/src/languageFeatures/references.ts b/extensions/markdown-language-features/src/languageFeatures/references.ts index 7695d5e4ba3..5f63973d701 100644 --- a/extensions/markdown-language-features/src/languageFeatures/references.ts +++ b/extensions/markdown-language-features/src/languageFeatures/references.ts @@ -97,7 +97,7 @@ export class MdReferencesProvider extends Disposable implements vscode.Reference } private async getReferencesToHeader(document: SkinnyTextDocument, header: TocEntry): Promise { - const links = (await this._linkCache.getAll()).flat(); + const links = (await this._linkCache.values()).flat(); const references: MdReference[] = []; @@ -150,7 +150,7 @@ export class MdReferencesProvider extends Disposable implements vscode.Reference } private async getReferencesToLink(sourceLink: MdLink, triggerPosition: vscode.Position, token: vscode.CancellationToken): Promise { - const allLinksInWorkspace = (await this._linkCache.getAll()).flat(); + const allLinksInWorkspace = (await this._linkCache.values()).flat(); if (token.isCancellationRequested) { return []; } @@ -227,7 +227,7 @@ export class MdReferencesProvider extends Disposable implements vscode.Reference } public async getAllReferencesToFile(resource: vscode.Uri, _token: vscode.CancellationToken): Promise { - const allLinksInWorkspace = (await this._linkCache.getAll()).flat(); + const allLinksInWorkspace = (await this._linkCache.values()).flat(); return Array.from(this.findAllLinksToFile(resource, allLinksInWorkspace, undefined)); } diff --git a/extensions/markdown-language-features/src/languageFeatures/workspaceCache.ts b/extensions/markdown-language-features/src/languageFeatures/workspaceCache.ts index e4039810c30..295771bfa60 100644 --- a/extensions/markdown-language-features/src/languageFeatures/workspaceCache.ts +++ b/extensions/markdown-language-features/src/languageFeatures/workspaceCache.ts @@ -6,6 +6,7 @@ import * as vscode from 'vscode'; import { Disposable } from '../util/dispose'; import { Lazy, lazy } from '../util/lazy'; +import { ResourceMap } from '../util/resourceMap'; import { MdWorkspaceContents, SkinnyTextDocument } from '../workspaceContents'; /** @@ -13,8 +14,8 @@ import { MdWorkspaceContents, SkinnyTextDocument } from '../workspaceContents'; */ export class MdWorkspaceCache extends Disposable { - private readonly _cache = new Map>>(); - private _hasPopulatedCache = false; + private readonly _cache = new ResourceMap>>(); + private _init?: Promise; public constructor( private readonly workspaceContents: MdWorkspaceContents, @@ -23,19 +24,29 @@ export class MdWorkspaceCache extends Disposable { super(); } - public async getAll(): Promise { - if (!this._hasPopulatedCache) { - await this.populateCache(); - this._hasPopulatedCache = true; - - this.workspaceContents.onDidChangeMarkdownDocument(this.onDidChangeDocument, this, this._disposables); - this.workspaceContents.onDidCreateMarkdownDocument(this.onDidChangeDocument, this, this._disposables); - this.workspaceContents.onDidDeleteMarkdownDocument(this.onDidDeleteDocument, this, this._disposables); - } + public async entries(): Promise> { + await this.ensureInit(); + return Promise.all(Array.from(this._cache.entries(), async ([key, entry]) => { + return [key, await entry.value]; + })); + } + public async values(): Promise> { + await this.ensureInit(); return Promise.all(Array.from(this._cache.values(), x => x.value)); } + private async ensureInit(): Promise { + if (!this._init) { + this._init = this.populateCache(); + + this._register(this.workspaceContents.onDidChangeMarkdownDocument(this.onDidChangeDocument, this)); + this._register(this.workspaceContents.onDidCreateMarkdownDocument(this.onDidChangeDocument, this)); + this._register(this.workspaceContents.onDidDeleteMarkdownDocument(this.onDidDeleteDocument, this)); + } + await this._init; + } + private async populateCache(): Promise { const markdownDocumentUris = await this.workspaceContents.getAllMarkdownDocuments(); for (const document of markdownDocumentUris) { @@ -43,12 +54,8 @@ export class MdWorkspaceCache extends Disposable { } } - private key(resource: vscode.Uri): string { - return resource.toString(); - } - private update(document: SkinnyTextDocument): void { - this._cache.set(this.key(document.uri), lazy(() => this.getValue(document))); + this._cache.set(document.uri, lazy(() => this.getValue(document))); } private onDidChangeDocument(document: SkinnyTextDocument) { @@ -56,6 +63,6 @@ export class MdWorkspaceCache extends Disposable { } private onDidDeleteDocument(resource: vscode.Uri) { - this._cache.delete(this.key(resource)); + this._cache.delete(resource); } } diff --git a/extensions/markdown-language-features/src/languageFeatures/workspaceSymbolProvider.ts b/extensions/markdown-language-features/src/languageFeatures/workspaceSymbolProvider.ts index f7b1dcbfd3d..5906cc1cc72 100644 --- a/extensions/markdown-language-features/src/languageFeatures/workspaceSymbolProvider.ts +++ b/extensions/markdown-language-features/src/languageFeatures/workspaceSymbolProvider.ts @@ -23,7 +23,7 @@ export class MdWorkspaceSymbolProvider extends Disposable implements vscode.Work } public async provideWorkspaceSymbols(query: string): Promise { - const allSymbols = (await this._cache.getAll()).flat(); + const allSymbols = (await this._cache.values()).flat(); return allSymbols.filter(symbolInformation => symbolInformation.name.toLowerCase().indexOf(query.toLowerCase()) !== -1); } } diff --git a/extensions/markdown-language-features/src/util/resourceMap.ts b/extensions/markdown-language-features/src/util/resourceMap.ts new file mode 100644 index 00000000000..35935314e55 --- /dev/null +++ b/extensions/markdown-language-features/src/util/resourceMap.ts @@ -0,0 +1,62 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import * as vscode from 'vscode'; + +export class ResourceMap { + + private readonly map = new Map(); + + public set(uri: vscode.Uri, value: T): this { + this.map.set(this.toKey(uri), { uri, value }); + return this; + } + + public get(resource: vscode.Uri): T | undefined { + return this.map.get(this.toKey(resource))?.value; + } + + public has(resource: vscode.Uri): boolean { + return this.map.has(this.toKey(resource)); + } + + public get size(): number { + return this.map.size; + } + + public clear(): void { + this.map.clear(); + } + + public delete(resource: vscode.Uri): boolean { + return this.map.delete(this.toKey(resource)); + } + + public *values(): IterableIterator { + for (const entry of this.map.values()) { + yield entry.value; + } + } + + public *keys(): IterableIterator { + for (const entry of this.map.values()) { + yield entry.uri; + } + } + + public *entries(): IterableIterator<[vscode.Uri, T]> { + for (const entry of this.map.values()) { + yield [entry.uri, entry.value]; + } + } + + public [Symbol.iterator](): IterableIterator<[vscode.Uri, T]> { + return this.entries(); + } + + private toKey(resource: vscode.Uri) { + return resource.toString(); + } +} From 907cc3e3d81524d667e9acae3ab20cc36cc74f46 Mon Sep 17 00:00:00 2001 From: Raymond Zhao <7199958+rzhao271@users.noreply.github.com> Date: Tue, 7 Jun 2022 18:01:04 -0700 Subject: [PATCH 027/117] Simplify default override indicator impl (#151461) Fixes #151164 --- .../browser/settingsEditorSettingIndicators.ts | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/vs/workbench/contrib/preferences/browser/settingsEditorSettingIndicators.ts b/src/vs/workbench/contrib/preferences/browser/settingsEditorSettingIndicators.ts index 7f5d1e698ed..aac1b348f1c 100644 --- a/src/vs/workbench/contrib/preferences/browser/settingsEditorSettingIndicators.ts +++ b/src/vs/workbench/contrib/preferences/browser/settingsEditorSettingIndicators.ts @@ -125,13 +125,15 @@ export class SettingsTreeIndicatorsLabel { const defaultValueSource = element.defaultValueSource; if (defaultValueSource) { this.defaultOverrideIndicatorElement.style.display = 'inline'; + let sourceToDisplay = ''; if (typeof defaultValueSource !== 'string' && defaultValueSource.id !== element.setting.extensionInfo?.id) { - const extensionSource = defaultValueSource.displayName ?? defaultValueSource.id; - this.defaultOverrideIndicatorLabel.title = localize('defaultOverriddenDetails', "Default setting value overridden by {0}", extensionSource); - this.defaultOverrideIndicatorLabel.text = localize('defaultOverrideLabelText', "$(replace) {0}", extensionSource); + sourceToDisplay = defaultValueSource.displayName ?? defaultValueSource.id; } else if (typeof defaultValueSource === 'string') { - this.defaultOverrideIndicatorLabel.title = localize('defaultOverriddenDetails', "Default setting value overridden by {0}", defaultValueSource); - this.defaultOverrideIndicatorLabel.text = localize('defaultOverrideLabelText', "$(replace) {0}", defaultValueSource); + sourceToDisplay = defaultValueSource; + } + if (sourceToDisplay) { + this.defaultOverrideIndicatorLabel.title = localize('defaultOverriddenDetails', "Default setting value overridden by {0}", sourceToDisplay); + this.defaultOverrideIndicatorLabel.text = `$(replace) ${sourceToDisplay}`; } } this.render(); From 45818d7c31c73dafc08e9ef3dbbdba502f8c1879 Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Tue, 7 Jun 2022 18:07:19 -0700 Subject: [PATCH 028/117] Use label service (#149001) * Use labelService #148410 * Fix unit tests for search using label service --- .../contrib/search/common/searchModel.ts | 62 ++++++++++++------- .../search/test/browser/searchViewlet.test.ts | 23 ++++--- .../search/test/common/searchResult.test.ts | 3 + .../label/test/common/mockLabelService.ts | 41 ++++++++++++ 4 files changed, 95 insertions(+), 34 deletions(-) create mode 100644 src/vs/workbench/services/label/test/common/mockLabelService.ts diff --git a/src/vs/workbench/contrib/search/common/searchModel.ts b/src/vs/workbench/contrib/search/common/searchModel.ts index 55d0979480b..8c56ab754f6 100644 --- a/src/vs/workbench/contrib/search/common/searchModel.ts +++ b/src/vs/workbench/contrib/search/common/searchModel.ts @@ -5,33 +5,32 @@ import { RunOnceScheduler } from 'vs/base/common/async'; import { CancellationTokenSource } from 'vs/base/common/cancellation'; +import { compareFileExtensions, compareFileNames, comparePaths } from 'vs/base/common/comparers'; +import { memoize } from 'vs/base/common/decorators'; import * as errors from 'vs/base/common/errors'; import { Emitter, Event } from 'vs/base/common/event'; -import { getBaseLabel } from 'vs/base/common/labels'; -import { Disposable, IDisposable, DisposableStore } from 'vs/base/common/lifecycle'; +import { Disposable, DisposableStore, IDisposable } from 'vs/base/common/lifecycle'; import { ResourceMap, TernarySearchTree } from 'vs/base/common/map'; +import { Schemas } from 'vs/base/common/network'; import { lcut } from 'vs/base/common/strings'; import { URI } from 'vs/base/common/uri'; import { Range } from 'vs/editor/common/core/range'; -import { FindMatch, IModelDeltaDecoration, ITextModel, OverviewRulerLane, TrackedRangeStickiness, MinimapPosition } from 'vs/editor/common/model'; +import { FindMatch, IModelDeltaDecoration, ITextModel, MinimapPosition, OverviewRulerLane, TrackedRangeStickiness } from 'vs/editor/common/model'; import { ModelDecorationOptions } from 'vs/editor/common/model/textModel'; import { IModelService } from 'vs/editor/common/services/model'; -import { createDecorator, IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; -import { IProgress, IProgressStep } from 'vs/platform/progress/common/progress'; -import { ReplacePattern } from 'vs/workbench/services/search/common/replace'; -import { IFileMatch, IPatternInfo, ISearchComplete, ISearchProgressItem, ISearchConfigurationProperties, ISearchService, ITextQuery, ITextSearchPreviewOptions, ITextSearchMatch, ITextSearchStats, resultIsMatch, ISearchRange, OneLineRange, ITextSearchContext, ITextSearchResult, SearchSortOrder, SearchCompletionExitCode } from 'vs/workbench/services/search/common/search'; -import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; -import { overviewRulerFindMatchForeground, minimapFindMatch } from 'vs/platform/theme/common/colorRegistry'; -import { themeColorFromId } from 'vs/platform/theme/common/themeService'; -import { IReplaceService } from 'vs/workbench/contrib/search/common/replace'; -import { editorMatchesToTextSearchResults, addContextToEditorMatches } from 'vs/workbench/services/search/common/searchHelpers'; -import { withNullAsUndefined } from 'vs/base/common/types'; -import { memoize } from 'vs/base/common/decorators'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; -import { compareFileNames, compareFileExtensions, comparePaths } from 'vs/base/common/comparers'; import { IFileService, IFileStatWithPartialMetadata } from 'vs/platform/files/common/files'; -import { Schemas } from 'vs/base/common/network'; +import { createDecorator, IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; +import { ILabelService } from 'vs/platform/label/common/label'; +import { IProgress, IProgressStep } from 'vs/platform/progress/common/progress'; +import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; +import { minimapFindMatch, overviewRulerFindMatchForeground } from 'vs/platform/theme/common/colorRegistry'; +import { themeColorFromId } from 'vs/platform/theme/common/themeService'; import { IUriIdentityService } from 'vs/platform/uriIdentity/common/uriIdentity'; +import { IReplaceService } from 'vs/workbench/contrib/search/common/replace'; +import { ReplacePattern } from 'vs/workbench/services/search/common/replace'; +import { IFileMatch, IPatternInfo, ISearchComplete, ISearchConfigurationProperties, ISearchProgressItem, ISearchRange, ISearchService, ITextQuery, ITextSearchContext, ITextSearchMatch, ITextSearchPreviewOptions, ITextSearchResult, ITextSearchStats, OneLineRange, resultIsMatch, SearchCompletionExitCode, SearchSortOrder } from 'vs/workbench/services/search/common/search'; +import { addContextToEditorMatches, editorMatchesToTextSearchResults } from 'vs/workbench/services/search/common/searchHelpers'; export class Match { @@ -217,8 +216,15 @@ export class FileMatch extends Disposable implements IFileMatch { return new Map(this._context); } - constructor(private _query: IPatternInfo, private _previewOptions: ITextSearchPreviewOptions | undefined, private _maxResults: number | undefined, private _parent: FolderMatch, private rawMatch: IFileMatch, - @IModelService private readonly modelService: IModelService, @IReplaceService private readonly replaceService: IReplaceService + constructor( + private _query: IPatternInfo, + private _previewOptions: ITextSearchPreviewOptions | undefined, + private _maxResults: number | undefined, + private _parent: FolderMatch, + private rawMatch: IFileMatch, + @IModelService private readonly modelService: IModelService, + @IReplaceService private readonly replaceService: IReplaceService, + @ILabelService private readonly labelService: ILabelService, ) { super(); this._resource = this.rawMatch.resource; @@ -407,7 +413,7 @@ export class FileMatch extends Disposable implements IFileMatch { } name(): string { - return getBaseLabel(this.resource); + return this.labelService.getUriBasenameLabel(this.resource); } addContext(results: ITextSearchResult[] | undefined) { @@ -472,9 +478,16 @@ export class FolderMatch extends Disposable { private _unDisposedFileMatches: ResourceMap; private _replacingAll: boolean = false; - constructor(protected _resource: URI | null, private _id: string, private _index: number, private _query: ITextQuery, private _parent: SearchResult, private _searchModel: SearchModel, + constructor( + protected _resource: URI | null, + private _id: string, + private _index: number, + private _query: ITextQuery, + private _parent: SearchResult, + private _searchModel: SearchModel, @IReplaceService private readonly replaceService: IReplaceService, - @IInstantiationService private readonly instantiationService: IInstantiationService + @IInstantiationService private readonly instantiationService: IInstantiationService, + @ILabelService private readonly labelService: ILabelService, ) { super(); this._fileMatches = new ResourceMap(); @@ -506,7 +519,7 @@ export class FolderMatch extends Disposable { } name(): string { - return getBaseLabel(withNullAsUndefined(this.resource)) || ''; + return this.resource ? this.labelService.getUriBasenameLabel(this.resource) : ''; } parent(): SearchResult { @@ -651,9 +664,10 @@ export class FolderMatch extends Disposable { export class FolderMatchWithResource extends FolderMatch { constructor(_resource: URI, _id: string, _index: number, _query: ITextQuery, _parent: SearchResult, _searchModel: SearchModel, @IReplaceService replaceService: IReplaceService, - @IInstantiationService instantiationService: IInstantiationService + @IInstantiationService instantiationService: IInstantiationService, + @ILabelService labelService: ILabelService ) { - super(_resource, _id, _index, _query, _parent, _searchModel, replaceService, instantiationService); + super(_resource, _id, _index, _query, _parent, _searchModel, replaceService, instantiationService, labelService); } override get resource(): URI { diff --git a/src/vs/workbench/contrib/search/test/browser/searchViewlet.test.ts b/src/vs/workbench/contrib/search/test/browser/searchViewlet.test.ts index ddc474564ac..b0517c6a59f 100644 --- a/src/vs/workbench/contrib/search/test/browser/searchViewlet.test.ts +++ b/src/vs/workbench/contrib/search/test/browser/searchViewlet.test.ts @@ -3,26 +3,28 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ import * as assert from 'assert'; +import { isWindows } from 'vs/base/common/platform'; import { URI as uri } from 'vs/base/common/uri'; +import { ILanguageConfigurationService } from 'vs/editor/common/languages/languageConfigurationRegistry'; import { IModelService } from 'vs/editor/common/services/model'; import { ModelService } from 'vs/editor/common/services/modelService'; +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 { FileService } from 'vs/platform/files/common/fileService'; import { TestInstantiationService } from 'vs/platform/instantiation/test/common/instantiationServiceMock'; -import { IFileMatch, ITextSearchMatch, OneLineRange, QueryType, SearchSortOrder } from 'vs/workbench/services/search/common/search'; +import { ILabelService } from 'vs/platform/label/common/label'; +import { NullLogService } from 'vs/platform/log/common/log'; +import { IThemeService } from 'vs/platform/theme/common/themeService'; +import { TestThemeService } from 'vs/platform/theme/test/common/testThemeService'; +import { IUriIdentityService } from 'vs/platform/uriIdentity/common/uriIdentity'; +import { UriIdentityService } from 'vs/platform/uriIdentity/common/uriIdentityService'; import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace'; import { TestWorkspace } from 'vs/platform/workspace/test/common/testWorkspace'; import { FileMatch, Match, searchMatchComparer, SearchResult } from 'vs/workbench/contrib/search/common/searchModel'; -import { isWindows } from 'vs/base/common/platform'; +import { MockLabelService } from 'vs/workbench/services/label/test/common/mockLabelService'; +import { IFileMatch, ITextSearchMatch, OneLineRange, QueryType, SearchSortOrder } from 'vs/workbench/services/search/common/search'; import { TestContextService } from 'vs/workbench/test/common/workbenchTestServices'; -import { IThemeService } from 'vs/platform/theme/common/themeService'; -import { TestThemeService } from 'vs/platform/theme/test/common/testThemeService'; -import { FileService } from 'vs/platform/files/common/fileService'; -import { NullLogService } from 'vs/platform/log/common/log'; -import { IUriIdentityService } from 'vs/platform/uriIdentity/common/uriIdentity'; -import { UriIdentityService } from 'vs/platform/uriIdentity/common/uriIdentityService'; -import { ILanguageConfigurationService } from 'vs/editor/common/languages/languageConfigurationRegistry'; -import { TestLanguageConfigurationService } from 'vs/editor/test/common/modes/testLanguageConfigurationService'; suite('Search - Viewlet', () => { let instantiation: TestInstantiationService; @@ -33,6 +35,7 @@ suite('Search - Viewlet', () => { instantiation.stub(IModelService, stubModelService(instantiation)); instantiation.set(IWorkspaceContextService, new TestContextService(TestWorkspace)); instantiation.stub(IUriIdentityService, new UriIdentityService(new FileService(new NullLogService()))); + instantiation.stub(ILabelService, new MockLabelService()); }); test('Data Source', function () { diff --git a/src/vs/workbench/contrib/search/test/common/searchResult.test.ts b/src/vs/workbench/contrib/search/test/common/searchResult.test.ts index 5e61596725e..651a67805bd 100644 --- a/src/vs/workbench/contrib/search/test/common/searchResult.test.ts +++ b/src/vs/workbench/contrib/search/test/common/searchResult.test.ts @@ -22,6 +22,8 @@ import { IUriIdentityService } from 'vs/platform/uriIdentity/common/uriIdentity' import { UriIdentityService } from 'vs/platform/uriIdentity/common/uriIdentityService'; import { FileService } from 'vs/platform/files/common/fileService'; import { NullLogService } from 'vs/platform/log/common/log'; +import { ILabelService } from 'vs/platform/label/common/label'; +import { MockLabelService } from 'vs/workbench/services/label/test/common/mockLabelService'; const lineOneRange = new OneLineRange(1, 0, 1); @@ -36,6 +38,7 @@ suite('SearchResult', () => { instantiationService.stub(IUriIdentityService, new UriIdentityService(new FileService(new NullLogService()))); instantiationService.stubPromise(IReplaceService, {}); instantiationService.stubPromise(IReplaceService, 'replace', null); + instantiationService.stub(ILabelService, new MockLabelService()); }); test('Line Match', function () { diff --git a/src/vs/workbench/services/label/test/common/mockLabelService.ts b/src/vs/workbench/services/label/test/common/mockLabelService.ts new file mode 100644 index 00000000000..0338dd144a2 --- /dev/null +++ b/src/vs/workbench/services/label/test/common/mockLabelService.ts @@ -0,0 +1,41 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { Emitter, Event } from 'vs/base/common/event'; +import { Disposable, IDisposable } from 'vs/base/common/lifecycle'; +import { basename, normalize } from 'vs/base/common/path'; +import { URI } from 'vs/base/common/uri'; +import { IFormatterChangeEvent, ILabelService, ResourceLabelFormatter } from 'vs/platform/label/common/label'; +import { IWorkspace, IWorkspaceIdentifier } from 'vs/platform/workspace/common/workspace'; + +export class MockLabelService implements ILabelService { + _serviceBrand: undefined; + + registerCachedFormatter(formatter: ResourceLabelFormatter): IDisposable { + throw new Error('Method not implemented.'); + } + getUriLabel(resource: URI, options?: { relative?: boolean | undefined; noPrefix?: boolean | undefined }): string { + return normalize(resource.fsPath); + } + getUriBasenameLabel(resource: URI): string { + return basename(resource.fsPath); + } + getWorkspaceLabel(workspace: URI | IWorkspaceIdentifier | IWorkspace, options?: { verbose: boolean }): string { + return ''; + } + getHostLabel(scheme: string, authority?: string): string { + return ''; + } + public getHostTooltip(): string | undefined { + return ''; + } + getSeparator(scheme: string, authority?: string): '/' | '\\' { + return '/'; + } + registerFormatter(formatter: ResourceLabelFormatter): IDisposable { + return Disposable.None; + } + onDidChangeFormatters: Event = new Emitter().event; +} From 1327d1eb5045d4da849fa2117a8a1c68292a5e6b Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Tue, 7 Jun 2022 23:34:06 -0700 Subject: [PATCH 029/117] Adopt ResourceMap in more places (#151475) This changes switches to use the new `ResourceMap` type in more places in the markdown extension where we need to have a map/set with uris as the key --- .../src/languageFeatures/diagnostics.ts | 34 ++++++++----------- .../src/preview/topmostLineMonitor.ts | 32 ++++++++--------- .../src/test/inMemoryWorkspace.ts | 21 +++++------- .../src/util/resourceMap.ts | 14 +++++--- 4 files changed, 49 insertions(+), 52 deletions(-) diff --git a/extensions/markdown-language-features/src/languageFeatures/diagnostics.ts b/extensions/markdown-language-features/src/languageFeatures/diagnostics.ts index 4db32d614f7..ed9b174ffb3 100644 --- a/extensions/markdown-language-features/src/languageFeatures/diagnostics.ts +++ b/extensions/markdown-language-features/src/languageFeatures/diagnostics.ts @@ -16,6 +16,7 @@ import { MdWorkspaceContents, SkinnyTextDocument } from '../workspaceContents'; import { InternalHref, LinkDefinitionSet, MdLink, MdLinkProvider, MdLinkSource } from './documentLinkProvider'; import { tryFindMdDocumentForLink } from './references'; import { CommandManager } from '../commandManager'; +import { ResourceMap } from '../util/resourceMap'; const localize = nls.loadMessageBundle(); @@ -85,30 +86,28 @@ class VSCodeDiagnosticConfiguration extends Disposable implements DiagnosticConf class InflightDiagnosticRequests { - private readonly inFlightRequests = new Map(); + private readonly inFlightRequests = new ResourceMap<{ readonly cts: vscode.CancellationTokenSource }>(); public trigger(resource: vscode.Uri, compute: (token: vscode.CancellationToken) => Promise) { this.cancel(resource); - const key = this.getResourceKey(resource); const cts = new vscode.CancellationTokenSource(); const entry = { cts }; - this.inFlightRequests.set(key, entry); + this.inFlightRequests.set(resource, entry); compute(cts.token).finally(() => { - if (this.inFlightRequests.get(key) === entry) { - this.inFlightRequests.delete(key); + if (this.inFlightRequests.get(resource) === entry) { + this.inFlightRequests.delete(resource); } cts.dispose(); }); } public cancel(resource: vscode.Uri) { - const key = this.getResourceKey(resource); - const existing = this.inFlightRequests.get(key); + const existing = this.inFlightRequests.get(resource); if (existing) { existing.cts.cancel(); - this.inFlightRequests.delete(key); + this.inFlightRequests.delete(resource); } } @@ -122,10 +121,6 @@ class InflightDiagnosticRequests { } this.inFlightRequests.clear(); } - - private getResourceKey(resource: vscode.Uri): string { - return resource.toString(); - } } class LinkWatcher extends Disposable { @@ -314,16 +309,16 @@ export class DiagnosticManager extends Disposable { const allOpenedTabResources = this.getAllTabResources(); await Promise.all( vscode.workspace.textDocuments - .filter(doc => allOpenedTabResources.has(doc.uri.toString()) && isMarkdownFile(doc)) + .filter(doc => allOpenedTabResources.has(doc.uri) && isMarkdownFile(doc)) .map(doc => this.triggerDiagnostics(doc))); } - private getAllTabResources() { - const openedTabDocs = new Map(); + private getAllTabResources(): ResourceMap { + const openedTabDocs = new ResourceMap(); for (const group of vscode.window.tabGroups.all) { for (const tab of group.tabs) { if (tab.input instanceof vscode.TabInputText) { - openedTabDocs.set(tab.input.uri.toString(), tab.input.uri); + openedTabDocs.set(tab.input.uri); } } } @@ -354,7 +349,7 @@ interface FileLinksData { */ class FileLinkMap { - private readonly _filesToLinksMap = new Map(); + private readonly _filesToLinksMap = new ResourceMap(); constructor(links: Iterable) { for (const link of links) { @@ -362,13 +357,12 @@ class FileLinkMap { continue; } - const fileKey = link.href.path.toString(); - const existingFileEntry = this._filesToLinksMap.get(fileKey); + const existingFileEntry = this._filesToLinksMap.get(link.href.path); const linkData = { source: link.source, fragment: link.href.fragment }; if (existingFileEntry) { existingFileEntry.links.push(linkData); } else { - this._filesToLinksMap.set(fileKey, { path: link.href.path, links: [linkData] }); + this._filesToLinksMap.set(link.href.path, { path: link.href.path, links: [linkData] }); } } } diff --git a/extensions/markdown-language-features/src/preview/topmostLineMonitor.ts b/extensions/markdown-language-features/src/preview/topmostLineMonitor.ts index bc8364c8971..0f659f9e924 100644 --- a/extensions/markdown-language-features/src/preview/topmostLineMonitor.ts +++ b/extensions/markdown-language-features/src/preview/topmostLineMonitor.ts @@ -6,6 +6,7 @@ import * as vscode from 'vscode'; import { Disposable } from '../util/dispose'; import { isMarkdownFile } from '../util/file'; +import { ResourceMap } from '../util/resourceMap'; export interface LastScrollLocation { readonly line: number; @@ -14,10 +15,10 @@ export interface LastScrollLocation { export class TopmostLineMonitor extends Disposable { - private readonly pendingUpdates = new Map(); + private readonly pendingUpdates = new ResourceMap(); private readonly throttle = 50; - private previousTextEditorInfo = new Map(); - private previousStaticEditorInfo = new Map(); + private previousTextEditorInfo = new ResourceMap(); + private previousStaticEditorInfo = new ResourceMap(); constructor() { super(); @@ -42,28 +43,28 @@ export class TopmostLineMonitor extends Disposable { public readonly onDidChanged = this._onChanged.event; public setPreviousStaticEditorLine(scrollLocation: LastScrollLocation): void { - this.previousStaticEditorInfo.set(scrollLocation.uri.toString(), scrollLocation); + this.previousStaticEditorInfo.set(scrollLocation.uri, scrollLocation); } public getPreviousStaticEditorLineByUri(resource: vscode.Uri): number | undefined { - const scrollLoc = this.previousStaticEditorInfo.get(resource.toString()); - this.previousStaticEditorInfo.delete(resource.toString()); + const scrollLoc = this.previousStaticEditorInfo.get(resource); + this.previousStaticEditorInfo.delete(resource); return scrollLoc?.line; } public setPreviousTextEditorLine(scrollLocation: LastScrollLocation): void { - this.previousTextEditorInfo.set(scrollLocation.uri.toString(), scrollLocation); + this.previousTextEditorInfo.set(scrollLocation.uri, scrollLocation); } public getPreviousTextEditorLineByUri(resource: vscode.Uri): number | undefined { - const scrollLoc = this.previousTextEditorInfo.get(resource.toString()); - this.previousTextEditorInfo.delete(resource.toString()); + const scrollLoc = this.previousTextEditorInfo.get(resource); + this.previousTextEditorInfo.delete(resource); return scrollLoc?.line; } public getPreviousStaticTextEditorLineByUri(resource: vscode.Uri): number | undefined { - const state = this.previousStaticEditorInfo.get(resource.toString()); + const state = this.previousStaticEditorInfo.get(resource); return state?.line; } @@ -71,21 +72,20 @@ export class TopmostLineMonitor extends Disposable { resource: vscode.Uri, line: number ) { - const key = resource.toString(); - if (!this.pendingUpdates.has(key)) { + if (!this.pendingUpdates.has(resource)) { // schedule update setTimeout(() => { - if (this.pendingUpdates.has(key)) { + if (this.pendingUpdates.has(resource)) { this._onChanged.fire({ resource, - line: this.pendingUpdates.get(key) as number + line: this.pendingUpdates.get(resource) as number }); - this.pendingUpdates.delete(key); + this.pendingUpdates.delete(resource); } }, this.throttle); } - this.pendingUpdates.set(key, line); + this.pendingUpdates.set(resource, line); } } diff --git a/extensions/markdown-language-features/src/test/inMemoryWorkspace.ts b/extensions/markdown-language-features/src/test/inMemoryWorkspace.ts index 4924578701d..53dab1a3e6d 100644 --- a/extensions/markdown-language-features/src/test/inMemoryWorkspace.ts +++ b/extensions/markdown-language-features/src/test/inMemoryWorkspace.ts @@ -5,15 +5,16 @@ import * as assert from 'assert'; import * as vscode from 'vscode'; +import { ResourceMap } from '../util/resourceMap'; import { MdWorkspaceContents, SkinnyTextDocument } from '../workspaceContents'; export class InMemoryWorkspaceMarkdownDocuments implements MdWorkspaceContents { - private readonly _documents = new Map(); + private readonly _documents = new ResourceMap(uri => uri.fsPath); constructor(documents: SkinnyTextDocument[]) { for (const doc of documents) { - this._documents.set(this.getKey(doc.uri), doc); + this._documents.set(doc.uri, doc); } } @@ -22,11 +23,11 @@ export class InMemoryWorkspaceMarkdownDocuments implements MdWorkspaceContents { } public async getMarkdownDocument(resource: vscode.Uri): Promise { - return this._documents.get(this.getKey(resource)); + return this._documents.get(resource); } public async pathExists(resource: vscode.Uri): Promise { - return this._documents.has(this.getKey(resource)); + return this._documents.has(resource); } private readonly _onDidChangeMarkdownDocumentEmitter = new vscode.EventEmitter(); @@ -39,23 +40,19 @@ export class InMemoryWorkspaceMarkdownDocuments implements MdWorkspaceContents { public onDidDeleteMarkdownDocument = this._onDidDeleteMarkdownDocumentEmitter.event; public updateDocument(document: SkinnyTextDocument) { - this._documents.set(this.getKey(document.uri), document); + this._documents.set(document.uri, document); this._onDidChangeMarkdownDocumentEmitter.fire(document); } public createDocument(document: SkinnyTextDocument) { - assert.ok(!this._documents.has(this.getKey(document.uri))); + assert.ok(!this._documents.has(document.uri)); - this._documents.set(this.getKey(document.uri), document); + this._documents.set(document.uri, document); this._onDidCreateMarkdownDocumentEmitter.fire(document); } public deleteDocument(resource: vscode.Uri) { - this._documents.delete(this.getKey(resource)); + this._documents.delete(resource); this._onDidDeleteMarkdownDocumentEmitter.fire(resource); } - - private getKey(resource: vscode.Uri): string { - return resource.fsPath; - } } diff --git a/extensions/markdown-language-features/src/util/resourceMap.ts b/extensions/markdown-language-features/src/util/resourceMap.ts index 35935314e55..7fe1f801bc6 100644 --- a/extensions/markdown-language-features/src/util/resourceMap.ts +++ b/extensions/markdown-language-features/src/util/resourceMap.ts @@ -5,10 +5,20 @@ import * as vscode from 'vscode'; +type ResourceToKey = (uri: vscode.Uri) => string; + +const defaultResourceToKey = (resource: vscode.Uri): string => resource.toString(); + export class ResourceMap { private readonly map = new Map(); + private readonly toKey: ResourceToKey; + + constructor(toKey: ResourceToKey = defaultResourceToKey) { + this.toKey = toKey; + } + public set(uri: vscode.Uri, value: T): this { this.map.set(this.toKey(uri), { uri, value }); return this; @@ -55,8 +65,4 @@ export class ResourceMap { public [Symbol.iterator](): IterableIterator<[vscode.Uri, T]> { return this.entries(); } - - private toKey(resource: vscode.Uri) { - return resource.toString(); - } } From 10e23028a7d7b328f5c20289df4037967bf333b5 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Wed, 8 Jun 2022 08:35:27 +0200 Subject: [PATCH 030/117] debt - remove `getBaseLabel` (#151486) --- src/vs/base/common/labels.ts | 26 ++----------------- src/vs/base/test/common/labels.test.ts | 14 ---------- .../common/extensionManagementCLIService.ts | 6 ++--- 3 files changed, 5 insertions(+), 41 deletions(-) diff --git a/src/vs/base/common/labels.ts b/src/vs/base/common/labels.ts index 19a6d4f46bc..3a4af59e9dd 100644 --- a/src/vs/base/common/labels.ts +++ b/src/vs/base/common/labels.ts @@ -4,11 +4,10 @@ *--------------------------------------------------------------------------------------------*/ import { firstOrDefault } from 'vs/base/common/arrays'; -import { hasDriveLetter, isRootOrDriveLetter, toSlashes } from 'vs/base/common/extpath'; -import { Schemas } from 'vs/base/common/network'; +import { hasDriveLetter, toSlashes } from 'vs/base/common/extpath'; import { posix, sep, win32 } from 'vs/base/common/path'; import { isMacintosh, isWindows, OperatingSystem, OS } from 'vs/base/common/platform'; -import { basename, extUri, extUriIgnorePathCase } from 'vs/base/common/resources'; +import { extUri, extUriIgnorePathCase } from 'vs/base/common/resources'; import { rtrim, startsWithIgnoreCase } from 'vs/base/common/strings'; import { URI } from 'vs/base/common/uri'; @@ -139,27 +138,6 @@ function getRelativePathLabel(resource: URI, relativePathProvider: IRelativePath return relativePathLabel; } -export function getBaseLabel(resource: URI | string): string; -export function getBaseLabel(resource: URI | string | undefined): string | undefined; -export function getBaseLabel(resource: URI | string | undefined): string | undefined { - if (!resource) { - return undefined; - } - - if (typeof resource === 'string') { - resource = URI.file(resource); - } - - const base = basename(resource) || (resource.scheme === Schemas.file ? resource.fsPath : resource.path) /* can be empty string if '/' is passed in */; - - // convert c: => C: - if (isWindows && isRootOrDriveLetter(base)) { - return normalizeDriveLetter(base); - } - - return base; -} - export function normalizeDriveLetter(path: string, isWindowsOS: boolean = isWindows): string { if (hasDriveLetter(path, isWindowsOS)) { return path.charAt(0).toUpperCase() + path.slice(1); diff --git a/src/vs/base/test/common/labels.test.ts b/src/vs/base/test/common/labels.test.ts index 49cc1699699..82bb2d98a75 100644 --- a/src/vs/base/test/common/labels.test.ts +++ b/src/vs/base/test/common/labels.test.ts @@ -139,20 +139,6 @@ suite('Labels', () => { assert.strictEqual(labels.template(t, { dirty: '* ', activeEditorShort: 'somefile.txt', rootName: 'monaco', appName: 'Visual Studio Code', separator: { label: ' - ' } }), '* somefile.txt - monaco - Visual Studio Code'); }); - (isWindows ? test.skip : test)('getBaseLabel - unix', () => { - assert.strictEqual(labels.getBaseLabel('/some/folder/file.txt'), 'file.txt'); - assert.strictEqual(labels.getBaseLabel('/some/folder'), 'folder'); - assert.strictEqual(labels.getBaseLabel('/'), '/'); - }); - - (!isWindows ? test.skip : test)('getBaseLabel - windows', () => { - assert.strictEqual(labels.getBaseLabel('c:'), 'C:'); - assert.strictEqual(labels.getBaseLabel('c:\\'), 'C:'); - assert.strictEqual(labels.getBaseLabel('c:\\some\\folder\\file.txt'), 'file.txt'); - assert.strictEqual(labels.getBaseLabel('c:\\some\\folder'), 'folder'); - assert.strictEqual(labels.getBaseLabel('c:\\some\\f:older'), 'f:older'); // https://github.com/microsoft/vscode-remote-release/issues/4227 - }); - test('mnemonicButtonLabel', () => { assert.strictEqual(labels.mnemonicButtonLabel('Hello World'), 'Hello World'); assert.strictEqual(labels.mnemonicButtonLabel(''), ''); diff --git a/src/vs/platform/extensionManagement/common/extensionManagementCLIService.ts b/src/vs/platform/extensionManagement/common/extensionManagementCLIService.ts index dc43b23fe1f..d6fe4ceea11 100644 --- a/src/vs/platform/extensionManagement/common/extensionManagementCLIService.ts +++ b/src/vs/platform/extensionManagement/common/extensionManagementCLIService.ts @@ -5,8 +5,8 @@ import { CancellationToken } from 'vs/base/common/cancellation'; import { isCancellationError } from 'vs/base/common/errors'; -import { getBaseLabel } from 'vs/base/common/labels'; import { Schemas } from 'vs/base/common/network'; +import { basename } from 'vs/base/common/resources'; import { gt } from 'vs/base/common/semver/semver'; import { URI } from 'vs/base/common/uri'; import { localize } from 'vs/nls'; @@ -177,11 +177,11 @@ export class ExtensionManagementCLIService implements IExtensionManagementCLISer if (valid) { try { await this.extensionManagementService.install(vsix, installOptions); - output.log(localize('successVsixInstall', "Extension '{0}' was successfully installed.", getBaseLabel(vsix))); + output.log(localize('successVsixInstall', "Extension '{0}' was successfully installed.", basename(vsix))); return manifest; } catch (error) { if (isCancellationError(error)) { - output.log(localize('cancelVsixInstall', "Cancelled installing extension '{0}'.", getBaseLabel(vsix))); + output.log(localize('cancelVsixInstall', "Cancelled installing extension '{0}'.", basename(vsix))); return null; } else { throw error; From 2c0a136079200e864c62989c2bd06e6fc2d7aee0 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Wed, 8 Jun 2022 09:24:49 +0200 Subject: [PATCH 031/117] ux - hide quick pickers from command palette (#151489) --- src/vs/workbench/browser/actions/windowActions.ts | 2 +- src/vs/workbench/contrib/quickaccess/browser/viewQuickAccess.ts | 2 +- src/vs/workbench/electron-sandbox/actions/windowActions.ts | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/vs/workbench/browser/actions/windowActions.ts b/src/vs/workbench/browser/actions/windowActions.ts index a0d14adf991..2f565273c1f 100644 --- a/src/vs/workbench/browser/actions/windowActions.ts +++ b/src/vs/workbench/browser/actions/windowActions.ts @@ -270,7 +270,7 @@ class QuickPickRecentAction extends BaseOpenRecentAction { id: 'workbench.action.quickOpenRecent', title: { value: localize('quickOpenRecent', "Quick Open Recent..."), original: 'Quick Open Recent...' }, category: fileCategory, - f1: true + f1: false // hide quick pickers from command palette to not confuse with the other entry that shows a input field }); } diff --git a/src/vs/workbench/contrib/quickaccess/browser/viewQuickAccess.ts b/src/vs/workbench/contrib/quickaccess/browser/viewQuickAccess.ts index 4a278af2146..913b3ba46d3 100644 --- a/src/vs/workbench/contrib/quickaccess/browser/viewQuickAccess.ts +++ b/src/vs/workbench/contrib/quickaccess/browser/viewQuickAccess.ts @@ -240,7 +240,7 @@ export class QuickAccessViewPickerAction extends Action2 { id: QuickAccessViewPickerAction.ID, title: { value: localize('quickOpenView', "Quick Open View"), original: 'Quick Open View' }, category: CATEGORIES.View, - f1: true, + f1: false, // hide quick pickers from command palette to not confuse with the other entry that shows a input field keybinding: { weight: KeybindingWeight.WorkbenchContrib, when: undefined, diff --git a/src/vs/workbench/electron-sandbox/actions/windowActions.ts b/src/vs/workbench/electron-sandbox/actions/windowActions.ts index a89681fa292..438925fd576 100644 --- a/src/vs/workbench/electron-sandbox/actions/windowActions.ts +++ b/src/vs/workbench/electron-sandbox/actions/windowActions.ts @@ -266,7 +266,7 @@ export class QuickSwitchWindowAction extends BaseSwitchWindow { super({ id: 'workbench.action.quickSwitchWindow', title: { value: localize('quickSwitchWindow', "Quick Switch Window..."), original: 'Quick Switch Window...' }, - f1: true + f1: false // hide quick pickers from command palette to not confuse with the other entry that shows a input field }); } From dc1ee4b14c2aee0cd8b276707fee78e66629d0ac Mon Sep 17 00:00:00 2001 From: Ladislau Szomoru <3372902+lszomoru@users.noreply.github.com> Date: Wed, 8 Jun 2022 10:06:18 +0200 Subject: [PATCH 032/117] Engineering - Do not run macOSTest job if VSCODE_STEP_ON_IT is set (#150794) Do not run macOSTest job if VSCODE_STEP_ON_IT is set --- .../darwin/product-build-darwin-test.yml | 3 +-- build/azure-pipelines/product-build.yml | 17 +++++++++-------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/build/azure-pipelines/darwin/product-build-darwin-test.yml b/build/azure-pipelines/darwin/product-build-darwin-test.yml index dd495426b6d..98d61becadd 100644 --- a/build/azure-pipelines/darwin/product-build-darwin-test.yml +++ b/build/azure-pipelines/darwin/product-build-darwin-test.yml @@ -158,7 +158,6 @@ steps: VSCODE_MIXIN_PASSWORD="$(github-distro-mixin-password)" \ yarn npm-run-all -lp "electron $(VSCODE_ARCH)" "playwright-install" displayName: Download Electron and Playwright - condition: and(succeeded(), eq(variables['VSCODE_STEP_ON_IT'], 'false')) - ${{ if ne(parameters.VSCODE_QUALITY, 'oss') }}: # Setting hardened entitlements is a requirement for: @@ -216,7 +215,7 @@ steps: compile-extension:vscode-notebook-tests \ compile-extension:vscode-test-resolver displayName: Build integration tests - condition: and(succeeded(), eq(variables['VSCODE_ARCH'], 'x64'), eq(variables['VSCODE_STEP_ON_IT'], 'false')) + condition: and(succeeded(), eq(variables['VSCODE_ARCH'], 'x64')) - ${{ if eq(parameters.VSCODE_RUN_INTEGRATION_TESTS, true) }}: - script: | diff --git a/build/azure-pipelines/product-build.yml b/build/azure-pipelines/product-build.yml index 3cc4fc399d9..fb8a6ff3aa4 100644 --- a/build/azure-pipelines/product-build.yml +++ b/build/azure-pipelines/product-build.yml @@ -335,14 +335,15 @@ stages: BUILDSECMON_OPT_IN: true jobs: - ${{ if eq(parameters.VSCODE_BUILD_MACOS, true) }}: - - job: macOSTest - timeoutInMinutes: 90 - variables: - VSCODE_ARCH: x64 - steps: - - template: darwin/product-build-darwin-test.yml - parameters: - VSCODE_QUALITY: ${{ variables.VSCODE_QUALITY }} + - ${{ if eq(parameters.VSCODE_STEP_ON_IT, false) }}: + - job: macOSTest + timeoutInMinutes: 90 + variables: + VSCODE_ARCH: x64 + steps: + - template: darwin/product-build-darwin-test.yml + parameters: + VSCODE_QUALITY: ${{ variables.VSCODE_QUALITY }} - ${{ if eq(variables['VSCODE_CIBUILD'], false) }}: - job: macOS From 7734233bce2024ba26ab6774a1fd6fe9f6d1a0e9 Mon Sep 17 00:00:00 2001 From: Ladislau Szomoru <3372902+lszomoru@users.noreply.github.com> Date: Wed, 8 Jun 2022 10:06:41 +0200 Subject: [PATCH 033/117] Engineering - macOS sign job optimization (#151120) --- .../darwin/product-build-darwin-sign.yml | 38 ++++++------------- 1 file changed, 12 insertions(+), 26 deletions(-) diff --git a/build/azure-pipelines/darwin/product-build-darwin-sign.yml b/build/azure-pipelines/darwin/product-build-darwin-sign.yml index f82e7a8b98d..c874c4deeac 100644 --- a/build/azure-pipelines/darwin/product-build-darwin-sign.yml +++ b/build/azure-pipelines/darwin/product-build-darwin-sign.yml @@ -1,4 +1,7 @@ steps: + - checkout: self + fetchDepth: 1 + - task: NodeTool@0 inputs: versionSpec: "16.x" @@ -8,39 +11,21 @@ steps: inputs: azureSubscription: "vscode-builds-subscription" KeyVaultName: vscode - SecretsFilter: "github-distro-mixin-password,ESRP-PKI,esrp-aad-username,esrp-aad-password" + SecretsFilter: "ESRP-PKI,esrp-aad-username,esrp-aad-password" - - script: | - set -e - cat << EOF > ~/.netrc - machine github.com - login vscode - password $(github-distro-mixin-password) - EOF - - git config user.email "vscode@microsoft.com" - git config user.name "VSCode" - displayName: Prepare tooling - - - script: | - set -e - git fetch https://github.com/$(VSCODE_MIXIN_REPO).git $VSCODE_DISTRO_REF - echo "##vso[task.setvariable variable=VSCODE_DISTRO_COMMIT;]$(git rev-parse FETCH_HEAD)" - git checkout FETCH_HEAD - condition: and(succeeded(), ne(variables.VSCODE_DISTRO_REF, ' ')) - displayName: Checkout override commit - - - script: | - set -e - git pull --no-rebase https://github.com/$(VSCODE_MIXIN_REPO).git $(node -p "require('./package.json').distro") - displayName: Merge distro + - task: Cache@2 + inputs: + key: "buildNodeModules | $(Agent.OS) | $(VSCODE_ARCH) | build/yarn.lock" + path: build/node_modules + cacheHitVar: BUILD_NODE_MODULES_RESTORED + displayName: Restore build node_modules cache - script: | set -e npx https://aka.ms/enablesecurefeed standAlone timeoutInMinutes: 5 retryCountOnTaskFailure: 3 - condition: and(succeeded(), eq(variables['ENABLE_TERRAPIN'], 'true')) + condition: and(succeeded(), eq(variables['ENABLE_TERRAPIN'], 'true'), ne(variables.BUILD_NODE_MODULES_RESTORED, 'true')) displayName: Switch to Terrapin packages - script: | @@ -54,6 +39,7 @@ steps: echo "Yarn failed $i, trying again..." done displayName: Install build dependencies + condition: and(succeeded(), ne(variables.BUILD_NODE_MODULES_RESTORED, 'true')) - download: current artifact: unsigned_vscode_client_darwin_$(VSCODE_ARCH)_archive From 19f96d6ed1c8c9e76f50f62a21223debd62c2413 Mon Sep 17 00:00:00 2001 From: Johannes Date: Wed, 8 Jun 2022 10:59:14 +0200 Subject: [PATCH 034/117] add `prefer-const` lint rule --- .eslintrc.json | 1 + 1 file changed, 1 insertion(+) diff --git a/.eslintrc.json b/.eslintrc.json index da169cdcc0c..1abec281d53 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -14,6 +14,7 @@ "constructor-super": "warn", "curly": "warn", "eqeqeq": "warn", + "prefer-const": "warn", "no-buffer-constructor": "warn", "no-caller": "warn", "no-case-declarations": "warn", From 21e6c2aac04d4a24126e5e670a0ef0459d830727 Mon Sep 17 00:00:00 2001 From: Connor Peet Date: Wed, 8 Jun 2022 11:11:13 +0200 Subject: [PATCH 035/117] debug: enable crash reporter when running debugging (#151430) --- .vscode/launch.json | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index dd295c02db4..236fc3de8c3 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -16,11 +16,7 @@ "request": "attach", "restart": true, "name": "Attach to Extension Host", - // set to a large number: if there is an issue we're debugging that keeps - // the extension host from coming up, or the renderer is paused/crashes - // before it happens, developers will get an annoying alert, e.g. #126826. - // This can be set to 0 in 1.59. - "timeout": 999999999, + "timeout": 0, "port": 5870, "outFiles": [ "${workspaceFolder}/out/**/*.js", @@ -244,6 +240,7 @@ "runtimeArgs": [ "--inspect=5875", "--no-cached-data", + "--crash-reporter-directory=${workspaceFolder}/.profile-oss/crashes", // for general runtime freezes: https://github.com/microsoft/vscode/issues/127861#issuecomment-904144910 "--disable-features=CalculateNativeWinOcclusion", ], From 13b60e192de770e8beb3122fc0df81071c5a3421 Mon Sep 17 00:00:00 2001 From: Johannes Date: Wed, 8 Jun 2022 11:16:24 +0200 Subject: [PATCH 036/117] prefer-const, ignore mixed destructuring statements for now --- .eslintrc.json | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/.eslintrc.json b/.eslintrc.json index 1abec281d53..72298423db8 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -14,7 +14,12 @@ "constructor-super": "warn", "curly": "warn", "eqeqeq": "warn", - "prefer-const": "warn", + "prefer-const": [ + "warn", + { + "destructuring": "all" + } + ], "no-buffer-constructor": "warn", "no-caller": "warn", "no-case-declarations": "warn", From d9f97a4e817399febfc82d03cf3c9051103d6663 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=BD=99=E8=85=BE=E9=9D=96?= Date: Wed, 8 Jun 2022 20:15:32 +0800 Subject: [PATCH 037/117] fix jsx text foreground in tomorrow-night theme (#151478) --- .../themes/tomorrow-night-blue-color-theme.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extensions/theme-tomorrow-night-blue/themes/tomorrow-night-blue-color-theme.json b/extensions/theme-tomorrow-night-blue/themes/tomorrow-night-blue-color-theme.json index 70b57d594fe..b37fd6b0083 100644 --- a/extensions/theme-tomorrow-night-blue/themes/tomorrow-night-blue-color-theme.json +++ b/extensions/theme-tomorrow-night-blue/themes/tomorrow-night-blue-color-theme.json @@ -65,7 +65,7 @@ } }, { - "scope": ["meta.embedded", "source.groovy.embedded"], + "scope": ["meta.embedded", "source.groovy.embedded", "meta.jsx.children"], "settings": { //"background": "#002451", "foreground": "#FFFFFF" From 793b0fd55003b731a344c32111d529fedff04eed Mon Sep 17 00:00:00 2001 From: Alexandru Dima Date: Wed, 8 Jun 2022 14:22:06 +0200 Subject: [PATCH 038/117] Fix handling of remote authorities using ipv6 (#151500) Fixes #151438: Fix handling of remote authorities using ipv6 --- .../browser/remoteAuthorityResolverService.ts | 11 ++--- src/vs/platform/remote/common/remoteHosts.ts | 43 +++++++++++++++++++ .../remote/test/common/remoteHosts.test.ts | 38 ++++++++++++++++ .../electronExtensionService.ts | 8 ++-- 4 files changed, 89 insertions(+), 11 deletions(-) create mode 100644 src/vs/platform/remote/test/common/remoteHosts.test.ts diff --git a/src/vs/platform/remote/browser/remoteAuthorityResolverService.ts b/src/vs/platform/remote/browser/remoteAuthorityResolverService.ts index e9231a1df85..db9d8a87c0e 100644 --- a/src/vs/platform/remote/browser/remoteAuthorityResolverService.ts +++ b/src/vs/platform/remote/browser/remoteAuthorityResolverService.ts @@ -9,7 +9,7 @@ import { RemoteAuthorities } from 'vs/base/common/network'; import { URI } from 'vs/base/common/uri'; import { IProductService } from 'vs/platform/product/common/productService'; import { IRemoteAuthorityResolverService, IRemoteConnectionData, ResolvedAuthority, ResolverResult } from 'vs/platform/remote/common/remoteAuthorityResolver'; -import { getRemoteServerRootPath } from 'vs/platform/remote/common/remoteHosts'; +import { getRemoteServerRootPath, parseAuthorityWithOptionalPort } from 'vs/platform/remote/common/remoteHosts'; export class RemoteAuthorityResolverService extends Disposable implements IRemoteAuthorityResolverService { @@ -62,12 +62,9 @@ export class RemoteAuthorityResolverService extends Disposable implements IRemot private _doResolveAuthority(authority: string): ResolverResult { const connectionToken = this._connectionTokens.get(authority) || this._connectionToken; - if (authority.indexOf(':') >= 0) { - const pieces = authority.split(':'); - return { authority: { authority, host: pieces[0], port: parseInt(pieces[1], 10), connectionToken } }; - } - const port = (/^https:/.test(window.location.href) ? 443 : 80); - return { authority: { authority, host: authority, port: port, connectionToken } }; + const defaultPort = (/^https:/.test(window.location.href) ? 443 : 80); + const { host, port } = parseAuthorityWithOptionalPort(authority, defaultPort); + return { authority: { authority, host: host, port: port, connectionToken } }; } _clearResolvedAuthority(authority: string): void { diff --git a/src/vs/platform/remote/common/remoteHosts.ts b/src/vs/platform/remote/common/remoteHosts.ts index 760033e5789..783ea2e0896 100644 --- a/src/vs/platform/remote/common/remoteHosts.ts +++ b/src/vs/platform/remote/common/remoteHosts.ts @@ -33,3 +33,46 @@ export function getRemoteName(authority: string | undefined): string | undefined export function getRemoteServerRootPath(product: { quality?: string; commit?: string }): string { return `/${product.quality ?? 'oss'}-${product.commit ?? 'dev'}`; } + +export function parseAuthorityWithPort(authority: string): { host: string; port: number } { + const { host, port } = parseAuthority(authority); + if (typeof port === 'undefined') { + throw new Error(`Remote authority doesn't contain a port!`); + } + return { host, port }; +} + +export function parseAuthorityWithOptionalPort(authority: string, defaultPort: number): { host: string; port: number } { + let { host, port } = parseAuthority(authority); + if (typeof port === 'undefined') { + port = defaultPort; + } + return { host, port }; +} + +function parseAuthority(authority: string): { host: string; port: number | undefined } { + if (authority.indexOf('+') >= 0) { + throw new Error(`Remote authorities containing '+' need to be resolved!`); + } + + // check for ipv6 with port + const m1 = authority.match(/^(\[[0-9a-z:]+\]):(\d+)$/); + if (m1) { + return { host: m1[1], port: parseInt(m1[2], 10) }; + } + + // check for ipv6 without port + const m2 = authority.match(/^(\[[0-9a-z:]+\])$/); + if (m2) { + return { host: m2[1], port: undefined }; + } + + // anything with a trailing port + const m3 = authority.match(/(.*):(\d+)$/); + if (m3) { + return { host: m3[1], port: parseInt(m3[2], 10) }; + } + + // doesn't contain a port + return { host: authority, port: undefined }; +} diff --git a/src/vs/platform/remote/test/common/remoteHosts.test.ts b/src/vs/platform/remote/test/common/remoteHosts.test.ts new file mode 100644 index 00000000000..da7349774f6 --- /dev/null +++ b/src/vs/platform/remote/test/common/remoteHosts.test.ts @@ -0,0 +1,38 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import * as assert from 'assert'; +import { parseAuthorityWithOptionalPort, parseAuthorityWithPort } from 'vs/platform/remote/common/remoteHosts'; + +suite('remoteHosts', () => { + + test('parseAuthority hostname', () => { + assert.deepStrictEqual(parseAuthorityWithPort('localhost:8080'), { host: 'localhost', port: 8080 }); + }); + + test('parseAuthority ipv4', () => { + assert.deepStrictEqual(parseAuthorityWithPort('127.0.0.1:8080'), { host: '127.0.0.1', port: 8080 }); + }); + + test('parseAuthority ipv6', () => { + assert.deepStrictEqual(parseAuthorityWithPort('[2001:0db8:85a3:0000:0000:8a2e:0370:7334]:8080'), { host: '[2001:0db8:85a3:0000:0000:8a2e:0370:7334]', port: 8080 }); + }); + + test('parseAuthorityWithOptionalPort hostname', () => { + assert.deepStrictEqual(parseAuthorityWithOptionalPort('localhost:8080', 123), { host: 'localhost', port: 8080 }); + assert.deepStrictEqual(parseAuthorityWithOptionalPort('localhost', 123), { host: 'localhost', port: 123 }); + }); + + test('parseAuthorityWithOptionalPort ipv4', () => { + assert.deepStrictEqual(parseAuthorityWithOptionalPort('127.0.0.1:8080', 123), { host: '127.0.0.1', port: 8080 }); + assert.deepStrictEqual(parseAuthorityWithOptionalPort('127.0.0.1', 123), { host: '127.0.0.1', port: 123 }); + }); + + test('parseAuthorityWithOptionalPort ipv6', () => { + assert.deepStrictEqual(parseAuthorityWithOptionalPort('[2001:0db8:85a3:0000:0000:8a2e:0370:7334]:8080', 123), { host: '[2001:0db8:85a3:0000:0000:8a2e:0370:7334]', port: 8080 }); + assert.deepStrictEqual(parseAuthorityWithOptionalPort('[2001:0db8:85a3:0000:0000:8a2e:0370:7334]', 123), { host: '[2001:0db8:85a3:0000:0000:8a2e:0370:7334]', port: 123 }); + }); + +}); diff --git a/src/vs/workbench/services/extensions/electron-sandbox/electronExtensionService.ts b/src/vs/workbench/services/extensions/electron-sandbox/electronExtensionService.ts index ea87ef0642a..7b25b8f9142 100644 --- a/src/vs/workbench/services/extensions/electron-sandbox/electronExtensionService.ts +++ b/src/vs/workbench/services/extensions/electron-sandbox/electronExtensionService.ts @@ -30,7 +30,7 @@ import { flatten } from 'vs/base/common/arrays'; import { INativeHostService } from 'vs/platform/native/electron-sandbox/native'; import { IRemoteExplorerService } from 'vs/workbench/services/remote/common/remoteExplorerService'; import { Action2, registerAction2 } from 'vs/platform/actions/common/actions'; -import { getRemoteName } from 'vs/platform/remote/common/remoteHosts'; +import { getRemoteName, parseAuthorityWithPort } from 'vs/platform/remote/common/remoteHosts'; import { IRemoteAgentEnvironment } from 'vs/platform/remote/common/remoteAgentEnvironment'; import { IWebWorkerExtensionHostDataProvider, IWebWorkerExtensionHostInitData, WebWorkerExtensionHost } from 'vs/workbench/services/extensions/browser/webWorkerExtensionHost'; import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace'; @@ -349,12 +349,12 @@ export abstract class ElectronExtensionService extends AbstractExtensionService const authorityPlusIndex = remoteAuthority.indexOf('+'); if (authorityPlusIndex === -1) { // This authority does not need to be resolved, simply parse the port number - const lastColon = remoteAuthority.lastIndexOf(':'); + const { host, port } = parseAuthorityWithPort(remoteAuthority); return { authority: { authority: remoteAuthority, - host: remoteAuthority.substring(0, lastColon), - port: parseInt(remoteAuthority.substring(lastColon + 1), 10), + host, + port, connectionToken: undefined } }; From da01cb05cb2d657eb778df30d0ba239fb72395d6 Mon Sep 17 00:00:00 2001 From: Johannes Date: Wed, 8 Jun 2022 15:43:12 +0200 Subject: [PATCH 039/117] update notebook milestones --- .vscode/notebooks/api.github-issues | 2 +- .vscode/notebooks/my-work.github-issues | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.vscode/notebooks/api.github-issues b/.vscode/notebooks/api.github-issues index 1b3790c8cc9..3120d4ad8fc 100644 --- a/.vscode/notebooks/api.github-issues +++ b/.vscode/notebooks/api.github-issues @@ -7,7 +7,7 @@ { "kind": 2, "language": "github-issues", - "value": "$repo=repo:microsoft/vscode\n$milestone=milestone:\"May 2022\"" + "value": "$repo=repo:microsoft/vscode\n$milestone=milestone:\"June 2022\"" }, { "kind": 1, diff --git a/.vscode/notebooks/my-work.github-issues b/.vscode/notebooks/my-work.github-issues index 143697b0c4e..f596c6e2e1c 100644 --- a/.vscode/notebooks/my-work.github-issues +++ b/.vscode/notebooks/my-work.github-issues @@ -7,7 +7,7 @@ { "kind": 2, "language": "github-issues", - "value": "// list of repos we work in\n$repos=repo:microsoft/vscode repo:microsoft/vscode-remote-release repo:microsoft/vscode-js-debug repo:microsoft/vscode-pull-request-github repo:microsoft/vscode-github-issue-notebooks repo:microsoft/vscode-internalbacklog repo:microsoft/vscode-dev repo:microsoft/vscode-unpkg repo:microsoft/vscode-references-view repo:microsoft/vscode-anycode repo:microsoft/vscode-hexeditor repo:microsoft/vscode-extension-telemetry repo:microsoft/vscode-livepreview repo:microsoft/vscode-remotehub repo:microsoft/vscode-settings-sync-server repo:microsoft/vscode-remote-repositories-github repo:microsoft/monaco-editor repo:microsoft/vscode-vsce\n\n// current milestone name\n$milestone=milestone:\"May 2022\"" + "value": "// list of repos we work in\n$repos=repo:microsoft/vscode repo:microsoft/vscode-remote-release repo:microsoft/vscode-js-debug repo:microsoft/vscode-pull-request-github repo:microsoft/vscode-github-issue-notebooks repo:microsoft/vscode-internalbacklog repo:microsoft/vscode-dev repo:microsoft/vscode-unpkg repo:microsoft/vscode-references-view repo:microsoft/vscode-anycode repo:microsoft/vscode-hexeditor repo:microsoft/vscode-extension-telemetry repo:microsoft/vscode-livepreview repo:microsoft/vscode-remotehub repo:microsoft/vscode-settings-sync-server repo:microsoft/vscode-remote-repositories-github repo:microsoft/monaco-editor repo:microsoft/vscode-vsce\n\n// current milestone name\n$milestone=milestone:\"June 2022\"" }, { "kind": 1, From 6f5fc176226b2d2a53223698cc3fac7d19c669ec Mon Sep 17 00:00:00 2001 From: Ladislau Szomoru <3372902+lszomoru@users.noreply.github.com> Date: Wed, 8 Jun 2022 15:45:27 +0200 Subject: [PATCH 040/117] Git - use editor as commit message input (#151491) --- extensions/git/extension.webpack.config.js | 3 +- extensions/git/package.json | 61 +++++++++++++----- extensions/git/package.nls.json | 2 + extensions/git/src/api/git.d.ts | 3 + extensions/git/src/askpass.ts | 14 +---- extensions/git/src/commands.ts | 39 ++++++++++-- extensions/git/src/git-editor-empty.sh | 1 + extensions/git/src/git-editor-main.ts | 21 +++++++ extensions/git/src/git-editor.sh | 4 ++ extensions/git/src/git.ts | 34 +++++++--- extensions/git/src/gitEditor.ts | 65 ++++++++++++++++++++ extensions/git/src/main.ts | 17 ++++- extensions/git/src/repository.ts | 7 +++ extensions/git/tsconfig.json | 1 + src/vs/workbench/contrib/scm/browser/util.ts | 2 +- 15 files changed, 229 insertions(+), 45 deletions(-) create mode 100755 extensions/git/src/git-editor-empty.sh create mode 100644 extensions/git/src/git-editor-main.ts create mode 100755 extensions/git/src/git-editor.sh create mode 100644 extensions/git/src/gitEditor.ts diff --git a/extensions/git/extension.webpack.config.js b/extensions/git/extension.webpack.config.js index 5efa2052e88..3324b6c1d98 100644 --- a/extensions/git/extension.webpack.config.js +++ b/extensions/git/extension.webpack.config.js @@ -13,6 +13,7 @@ module.exports = withDefaults({ context: __dirname, entry: { main: './src/main.ts', - ['askpass-main']: './src/askpass-main.ts' + ['askpass-main']: './src/askpass-main.ts', + ['git-editor-main']: './src/git-editor-main.ts' } }); diff --git a/extensions/git/package.json b/extensions/git/package.json index e2428b5e02f..111717f86c9 100644 --- a/extensions/git/package.json +++ b/extensions/git/package.json @@ -14,6 +14,7 @@ "contribMergeEditorToolbar", "contribViewsWelcome", "scmActionButton", + "scmInput", "scmSelectedProvider", "scmValidation", "timeline" @@ -213,83 +214,99 @@ "command": "git.commit", "title": "%command.commit%", "category": "Git", - "icon": "$(check)" + "icon": "$(check)", + "enablement": "!commitInProgress" }, { "command": "git.commitStaged", "title": "%command.commitStaged%", - "category": "Git" + "category": "Git", + "enablement": "!commitInProgress" }, { "command": "git.commitEmpty", "title": "%command.commitEmpty%", - "category": "Git" + "category": "Git", + "enablement": "!commitInProgress" }, { "command": "git.commitStagedSigned", "title": "%command.commitStagedSigned%", - "category": "Git" + "category": "Git", + "enablement": "!commitInProgress" }, { "command": "git.commitStagedAmend", "title": "%command.commitStagedAmend%", - "category": "Git" + "category": "Git", + "enablement": "!commitInProgress" }, { "command": "git.commitAll", "title": "%command.commitAll%", - "category": "Git" + "category": "Git", + "enablement": "!commitInProgress" }, { "command": "git.commitAllSigned", "title": "%command.commitAllSigned%", - "category": "Git" + "category": "Git", + "enablement": "!commitInProgress" }, { "command": "git.commitAllAmend", "title": "%command.commitAllAmend%", - "category": "Git" + "category": "Git", + "enablement": "!commitInProgress" }, { "command": "git.commitNoVerify", "title": "%command.commitNoVerify%", "category": "Git", - "icon": "$(check)" + "icon": "$(check)", + "enablement": "!commitInProgress" }, { "command": "git.commitStagedNoVerify", "title": "%command.commitStagedNoVerify%", - "category": "Git" + "category": "Git", + "enablement": "!commitInProgress" }, { "command": "git.commitEmptyNoVerify", "title": "%command.commitEmptyNoVerify%", - "category": "Git" + "category": "Git", + "enablement": "!commitInProgress" }, { "command": "git.commitStagedSignedNoVerify", "title": "%command.commitStagedSignedNoVerify%", - "category": "Git" + "category": "Git", + "enablement": "!commitInProgress" }, { "command": "git.commitStagedAmendNoVerify", "title": "%command.commitStagedAmendNoVerify%", - "category": "Git" + "category": "Git", + "enablement": "!commitInProgress" }, { "command": "git.commitAllNoVerify", "title": "%command.commitAllNoVerify%", - "category": "Git" + "category": "Git", + "enablement": "!commitInProgress" }, { "command": "git.commitAllSignedNoVerify", "title": "%command.commitAllSignedNoVerify%", - "category": "Git" + "category": "Git", + "enablement": "!commitInProgress" }, { "command": "git.commitAllAmendNoVerify", "title": "%command.commitAllAmendNoVerify%", - "category": "Git" + "category": "Git", + "enablement": "!commitInProgress" }, { "command": "git.restoreCommitTemplate", @@ -2013,6 +2030,18 @@ "scope": "machine", "description": "%config.defaultCloneDirectory%" }, + "git.useEditorAsCommitInput": { + "type": "boolean", + "scope": "resource", + "description": "%config.useEditorAsCommitInput%", + "default": false + }, + "git.verboseCommit": { + "type": "boolean", + "scope": "resource", + "markdownDescription": "%config.verboseCommit%", + "default": false + }, "git.enableSmartCommit": { "type": "boolean", "scope": "resource", diff --git a/extensions/git/package.nls.json b/extensions/git/package.nls.json index b729f821b61..5210e64de80 100644 --- a/extensions/git/package.nls.json +++ b/extensions/git/package.nls.json @@ -140,6 +140,8 @@ "config.ignoreLimitWarning": "Ignores the warning when there are too many changes in a repository.", "config.ignoreRebaseWarning": "Ignores the warning when it looks like the branch might have been rebased when pulling.", "config.defaultCloneDirectory": "The default location to clone a git repository.", + "config.useEditorAsCommitInput": "Use an editor to author the commit message.", + "config.verboseCommit": "Enable verbose output when `#git.useEditorAsCommitInput#` is enabled.", "config.enableSmartCommit": "Commit all changes when there are no staged changes.", "config.smartCommitChanges": "Control which changes are automatically staged by Smart Commit.", "config.smartCommitChanges.all": "Automatically stage all changes.", diff --git a/extensions/git/src/api/git.d.ts b/extensions/git/src/api/git.d.ts index 4b180dac920..14c7447e3e8 100644 --- a/extensions/git/src/api/git.d.ts +++ b/extensions/git/src/api/git.d.ts @@ -137,6 +137,8 @@ export interface CommitOptions { empty?: boolean; noVerify?: boolean; requireUserConfig?: boolean; + useEditor?: boolean; + verbose?: boolean; } export interface FetchOptions { @@ -336,4 +338,5 @@ export const enum GitErrorCodes { PatchDoesNotApply = 'PatchDoesNotApply', NoPathFound = 'NoPathFound', UnknownPath = 'UnknownPath', + EmptyCommitMessage = 'EmptyCommitMessage' } diff --git a/extensions/git/src/askpass.ts b/extensions/git/src/askpass.ts index 81895a0e0d6..ffbd7e48a0e 100644 --- a/extensions/git/src/askpass.ts +++ b/extensions/git/src/askpass.ts @@ -6,9 +6,8 @@ import { window, InputBoxOptions, Uri, Disposable, workspace } from 'vscode'; import { IDisposable, EmptyDisposable, toDisposable } from './util'; import * as path from 'path'; -import { IIPCHandler, IIPCServer, createIPCServer } from './ipc/ipcServer'; +import { IIPCHandler, IIPCServer } from './ipc/ipcServer'; import { CredentialsProvider, Credentials } from './api/git'; -import { OutputChannelLogger } from './log'; export class Askpass implements IIPCHandler { @@ -16,16 +15,7 @@ export class Askpass implements IIPCHandler { private cache = new Map(); private credentialsProviders = new Set(); - static async create(outputChannelLogger: OutputChannelLogger, context?: string): Promise { - try { - return new Askpass(await createIPCServer(context)); - } catch (err) { - outputChannelLogger.logError(`Failed to create git askpass IPC: ${err}`); - return new Askpass(); - } - } - - private constructor(private ipc?: IIPCServer) { + constructor(private ipc?: IIPCServer) { if (ipc) { this.disposable = ipc.registerHandler('askpass', this); } diff --git a/extensions/git/src/commands.ts b/extensions/git/src/commands.ts index 32812e42159..dd557053e8b 100644 --- a/extensions/git/src/commands.ts +++ b/extensions/git/src/commands.ts @@ -1516,6 +1516,14 @@ export class CommandCenter { opts.signoff = true; } + if (config.get('useEditorAsCommitInput')) { + opts.useEditor = true; + + if (config.get('verboseCommit')) { + opts.verbose = true; + } + } + const smartCommitChanges = config.get<'all' | 'tracked'>('smartCommitChanges'); if ( @@ -1563,7 +1571,7 @@ export class CommandCenter { let message = await getCommitMessage(); - if (!message && !opts.amend) { + if (!message && !opts.amend && !opts.useEditor) { return false; } @@ -1623,10 +1631,13 @@ export class CommandCenter { private async commitWithAnyInput(repository: Repository, opts?: CommitOptions): Promise { const message = repository.inputBox.value; + const root = Uri.file(repository.root); + const config = workspace.getConfiguration('git', root); + const getCommitMessage = async () => { let _message: string | undefined = message; - if (!_message) { + if (!_message && !config.get('useEditorAsCommitInput')) { let value: string | undefined = undefined; if (opts && opts.amend && repository.HEAD && repository.HEAD.commit) { @@ -3010,7 +3021,7 @@ export class CommandCenter { }; let message: string; - let type: 'error' | 'warning' = 'error'; + let type: 'error' | 'warning' | 'information' = 'error'; const choices = new Map void>(); const openOutputChannelChoice = localize('open git log', "Open Git Log"); @@ -3073,6 +3084,12 @@ export class CommandCenter { message = localize('missing user info', "Make sure you configure your 'user.name' and 'user.email' in git."); choices.set(localize('learn more', "Learn More"), () => commands.executeCommand('vscode.open', Uri.parse('https://aka.ms/vscode-setup-git'))); break; + case GitErrorCodes.EmptyCommitMessage: + message = localize('empty commit', "Commit operation was cancelled due to empty commit message."); + choices.clear(); + type = 'information'; + options.modal = false; + break; default: { const hint = (err.stderr || err.message || String(err)) .replace(/^error: /mi, '') @@ -3094,10 +3111,20 @@ export class CommandCenter { return; } + let result: string | undefined; const allChoices = Array.from(choices.keys()); - const result = type === 'error' - ? await window.showErrorMessage(message, options, ...allChoices) - : await window.showWarningMessage(message, options, ...allChoices); + + switch (type) { + case 'error': + result = await window.showErrorMessage(message, options, ...allChoices); + break; + case 'warning': + result = await window.showWarningMessage(message, options, ...allChoices); + break; + case 'information': + result = await window.showInformationMessage(message, options, ...allChoices); + break; + } if (result) { const resultFn = choices.get(result); diff --git a/extensions/git/src/git-editor-empty.sh b/extensions/git/src/git-editor-empty.sh new file mode 100755 index 00000000000..1a2485251c3 --- /dev/null +++ b/extensions/git/src/git-editor-empty.sh @@ -0,0 +1 @@ +#!/bin/sh diff --git a/extensions/git/src/git-editor-main.ts b/extensions/git/src/git-editor-main.ts new file mode 100644 index 00000000000..eb4da4a40b5 --- /dev/null +++ b/extensions/git/src/git-editor-main.ts @@ -0,0 +1,21 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +import { IPCClient } from './ipc/ipcClient'; + +function fatal(err: any): void { + console.error(err); + process.exit(1); +} + +function main(argv: string[]): void { + const ipcClient = new IPCClient('git-editor'); + const commitMessagePath = argv[argv.length - 1]; + + ipcClient.call({ commitMessagePath }).then(() => { + setTimeout(() => process.exit(0), 0); + }).catch(err => fatal(err)); +} + +main(process.argv); diff --git a/extensions/git/src/git-editor.sh b/extensions/git/src/git-editor.sh new file mode 100755 index 00000000000..1c45c2deac1 --- /dev/null +++ b/extensions/git/src/git-editor.sh @@ -0,0 +1,4 @@ +#!/bin/sh + +ELECTRON_RUN_AS_NODE="1" \ +"$VSCODE_GIT_EDITOR_NODE" "$VSCODE_GIT_EDITOR_MAIN" $VSCODE_GIT_EDITOR_EXTRA_ARGS $@ diff --git a/extensions/git/src/git.ts b/extensions/git/src/git.ts index a511db761a6..f87cefbd653 100644 --- a/extensions/git/src/git.ts +++ b/extensions/git/src/git.ts @@ -1400,20 +1400,37 @@ export class Repository { } async commit(message: string | undefined, opts: CommitOptions = Object.create(null)): Promise { - const args = ['commit', '--quiet', '--allow-empty-message']; + const args = ['commit', '--quiet']; + const options: SpawnOptions = {}; + + if (message) { + options.input = message; + args.push('--file', '-'); + } + + if (opts.verbose) { + args.push('--verbose'); + } if (opts.all) { args.push('--all'); } - if (opts.amend && message) { + if (opts.amend) { args.push('--amend'); } - if (opts.amend && !message) { - args.push('--amend', '--no-edit'); - } else { - args.push('--file', '-'); + if (!opts.useEditor) { + if (!message) { + if (opts.amend) { + args.push('--no-edit'); + } else { + options.input = ''; + args.push('--file', '-'); + } + } + + args.push('--allow-empty-message'); } if (opts.signoff) { @@ -1438,7 +1455,7 @@ export class Repository { } try { - await this.exec(args, !opts.amend || message ? { input: message || '' } : {}); + await this.exec(args, options); } catch (commitErr) { await this.handleCommitError(commitErr); } @@ -1462,6 +1479,9 @@ export class Repository { if (/not possible because you have unmerged files/.test(commitErr.stderr || '')) { commitErr.gitErrorCode = GitErrorCodes.UnmergedChanges; throw commitErr; + } else if (/Aborting commit due to empty commit message/.test(commitErr.stderr || '')) { + commitErr.gitErrorCode = GitErrorCodes.EmptyCommitMessage; + throw commitErr; } try { diff --git a/extensions/git/src/gitEditor.ts b/extensions/git/src/gitEditor.ts new file mode 100644 index 00000000000..5f65a7dbcf2 --- /dev/null +++ b/extensions/git/src/gitEditor.ts @@ -0,0 +1,65 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +import * as path from 'path'; +import { TabInputText, Uri, window, workspace } from 'vscode'; +import { IIPCHandler, IIPCServer } from './ipc/ipcServer'; +import { EmptyDisposable, IDisposable } from './util'; + +interface GitEditorRequest { + commitMessagePath?: string; +} + +export class GitEditor implements IIPCHandler { + + private disposable: IDisposable = EmptyDisposable; + + constructor(private ipc?: IIPCServer) { + if (ipc) { + this.disposable = ipc.registerHandler('git-editor', this); + } + } + + async handle({ commitMessagePath }: GitEditorRequest): Promise { + if (commitMessagePath) { + const uri = Uri.file(commitMessagePath); + const doc = await workspace.openTextDocument(uri); + await window.showTextDocument(doc, { preview: false }); + + return new Promise((c) => { + const onDidClose = window.tabGroups.onDidChangeTabs(async (tabs) => { + if (tabs.closed.some(t => t.input instanceof TabInputText && t.input.uri.toString() === uri.toString())) { + onDidClose.dispose(); + return c(true); + } + }); + }); + } + } + + getEnv(): { [key: string]: string } { + if (!this.ipc) { + return { + GIT_EDITOR: `"${path.join(__dirname, 'git-editor-empty.sh')}"` + }; + } + + let env: { [key: string]: string } = { + VSCODE_GIT_EDITOR_NODE: process.execPath, + VSCODE_GIT_EDITOR_EXTRA_ARGS: (process.versions['electron'] && process.versions['microsoft-build']) ? '--ms-enable-electron-run-as-node' : '', + VSCODE_GIT_EDITOR_MAIN: path.join(__dirname, 'git-editor-main.js') + }; + + const config = workspace.getConfiguration('git'); + if (config.get('useEditorAsCommitInput')) { + env.GIT_EDITOR = `"${path.join(__dirname, 'git-editor.sh')}"`; + } + + return env; + } + + dispose(): void { + this.disposable.dispose(); + } +} diff --git a/extensions/git/src/main.ts b/extensions/git/src/main.ts index a5e7c060f00..46f612539fb 100644 --- a/extensions/git/src/main.ts +++ b/extensions/git/src/main.ts @@ -25,6 +25,8 @@ import { GitTimelineProvider } from './timelineProvider'; import { registerAPICommands } from './api/api1'; import { TerminalEnvironmentManager } from './terminal'; import { OutputChannelLogger } from './log'; +import { createIPCServer, IIPCServer } from './ipc/ipcServer'; +import { GitEditor } from './gitEditor'; const deactivateTasks: { (): Promise }[] = []; @@ -60,10 +62,21 @@ async function createModel(context: ExtensionContext, outputChannelLogger: Outpu return !skip; }); - const askpass = await Askpass.create(outputChannelLogger, context.storagePath); + let ipc: IIPCServer | undefined = undefined; + + try { + ipc = await createIPCServer(context.storagePath); + } catch (err) { + outputChannelLogger.logError(`Failed to create git IPC: ${err}`); + } + + const askpass = new Askpass(ipc); disposables.push(askpass); - const environment = askpass.getEnv(); + const gitEditor = new GitEditor(ipc); + disposables.push(gitEditor); + + const environment = { ...askpass.getEnv(), ...gitEditor.getEnv() }; const terminalEnvironmentManager = new TerminalEnvironmentManager(context, environment); disposables.push(terminalEnvironmentManager); diff --git a/extensions/git/src/repository.ts b/extensions/git/src/repository.ts index 69c184209fa..c6fa51b5497 100644 --- a/extensions/git/src/repository.ts +++ b/extensions/git/src/repository.ts @@ -454,6 +454,13 @@ class ProgressManager { const onDidChange = filterEvent(workspace.onDidChangeConfiguration, e => e.affectsConfiguration('git', Uri.file(this.repository.root))); onDidChange(_ => this.updateEnablement()); this.updateEnablement(); + + this.repository.onDidChangeOperations(() => { + const commitInProgress = this.repository.operations.isRunning(Operation.Commit); + + this.repository.sourceControl.inputBox.enabled = !commitInProgress; + commands.executeCommand('setContext', 'commitInProgress', commitInProgress); + }); } private updateEnablement(): void { diff --git a/extensions/git/tsconfig.json b/extensions/git/tsconfig.json index 13997275056..1f1c02d3356 100644 --- a/extensions/git/tsconfig.json +++ b/extensions/git/tsconfig.json @@ -12,6 +12,7 @@ "../../src/vscode-dts/vscode.d.ts", "../../src/vscode-dts/vscode.proposed.diffCommand.d.ts", "../../src/vscode-dts/vscode.proposed.scmActionButton.d.ts", + "../../src/vscode-dts/vscode.proposed.scmInput.d.ts", "../../src/vscode-dts/vscode.proposed.scmSelectedProvider.d.ts", "../../src/vscode-dts/vscode.proposed.scmValidation.d.ts", "../../src/vscode-dts/vscode.proposed.tabs.d.ts", diff --git a/src/vs/workbench/contrib/scm/browser/util.ts b/src/vs/workbench/contrib/scm/browser/util.ts index 80d5d19302d..c8f4524d017 100644 --- a/src/vs/workbench/contrib/scm/browser/util.ts +++ b/src/vs/workbench/contrib/scm/browser/util.ts @@ -37,7 +37,7 @@ export function isSCMResource(element: any): element is ISCMResource { return !!(element as ISCMResource).sourceUri && isSCMResourceGroup((element as ISCMResource).resourceGroup); } -const compareActions = (a: IAction, b: IAction) => a.id === b.id; +const compareActions = (a: IAction, b: IAction) => a.id === b.id && a.enabled === b.enabled; export function connectPrimaryMenu(menu: IMenu, callback: (primary: IAction[], secondary: IAction[]) => void, primaryGroup?: string): IDisposable { let cachedDisposable: IDisposable = Disposable.None; From adb16fa39651a32e0c817cc77a8bba0ddc2fd303 Mon Sep 17 00:00:00 2001 From: Tyler James Leonhardt Date: Wed, 8 Jun 2022 07:52:40 -0700 Subject: [PATCH 041/117] leverage the contribution to register the locale service instead (#151450) --- .../workbench/contrib/localization/browser/localeService.ts | 3 --- .../localization/browser/localization.contribution.ts | 5 +++++ .../contrib/localization/electron-sandbox/localeService.ts | 3 --- .../electron-sandbox/localization.contribution.ts | 5 +++++ src/vs/workbench/workbench.sandbox.main.ts | 1 - src/vs/workbench/workbench.web.main.ts | 1 - 6 files changed, 10 insertions(+), 8 deletions(-) diff --git a/src/vs/workbench/contrib/localization/browser/localeService.ts b/src/vs/workbench/contrib/localization/browser/localeService.ts index ea5f4383b6e..c59d84821b2 100644 --- a/src/vs/workbench/contrib/localization/browser/localeService.ts +++ b/src/vs/workbench/contrib/localization/browser/localeService.ts @@ -4,7 +4,6 @@ *--------------------------------------------------------------------------------------------*/ import { language } from 'vs/base/common/platform'; -import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; import { ILanguagePackItem } from 'vs/platform/languagePacks/common/languagePacks'; import { ILocaleService } from 'vs/workbench/contrib/localization/common/locale'; @@ -32,5 +31,3 @@ export class WebLocaleService implements ILocaleService { return true; } } - -registerSingleton(ILocaleService, WebLocaleService, true); diff --git a/src/vs/workbench/contrib/localization/browser/localization.contribution.ts b/src/vs/workbench/contrib/localization/browser/localization.contribution.ts index 79f2f0a777b..85716e8bcb9 100644 --- a/src/vs/workbench/contrib/localization/browser/localization.contribution.ts +++ b/src/vs/workbench/contrib/localization/browser/localization.contribution.ts @@ -4,7 +4,12 @@ *--------------------------------------------------------------------------------------------*/ import { registerAction2 } from 'vs/platform/actions/common/actions'; +import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; +import { WebLocaleService } from 'vs/workbench/contrib/localization/browser/localeService'; import { ClearDisplayLanguageAction, ConfigureDisplayLanguageAction } from 'vs/workbench/contrib/localization/browser/localizationsActions'; +import { ILocaleService } from 'vs/workbench/contrib/localization/common/locale'; + +registerSingleton(ILocaleService, WebLocaleService, true); // Register action to configure locale and related settings registerAction2(ConfigureDisplayLanguageAction); diff --git a/src/vs/workbench/contrib/localization/electron-sandbox/localeService.ts b/src/vs/workbench/contrib/localization/electron-sandbox/localeService.ts index ac70935d514..506d575af55 100644 --- a/src/vs/workbench/contrib/localization/electron-sandbox/localeService.ts +++ b/src/vs/workbench/contrib/localization/electron-sandbox/localeService.ts @@ -5,7 +5,6 @@ import { language } from 'vs/base/common/platform'; import { IEnvironmentService } from 'vs/platform/environment/common/environment'; -import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; import { INotificationService } from 'vs/platform/notification/common/notification'; import { IJSONEditingService } from 'vs/workbench/services/configuration/common/jsonEditing'; import { ILocaleService } from 'vs/workbench/contrib/localization/common/locale'; @@ -75,5 +74,3 @@ export class NativeLocaleService implements ILocaleService { } } } - -registerSingleton(ILocaleService, NativeLocaleService, true); diff --git a/src/vs/workbench/contrib/localization/electron-sandbox/localization.contribution.ts b/src/vs/workbench/contrib/localization/electron-sandbox/localization.contribution.ts index b04105ab3c9..29726f689d2 100644 --- a/src/vs/workbench/contrib/localization/electron-sandbox/localization.contribution.ts +++ b/src/vs/workbench/contrib/localization/electron-sandbox/localization.contribution.ts @@ -25,6 +25,11 @@ import { IPaneCompositePartService } from 'vs/workbench/services/panecomposite/b import { ViewContainerLocation } from 'vs/workbench/common/views'; import { registerAction2 } from 'vs/platform/actions/common/actions'; import { ClearDisplayLanguageAction, ConfigureDisplayLanguageAction } from 'vs/workbench/contrib/localization/browser/localizationsActions'; +import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; +import { ILocaleService } from 'vs/workbench/contrib/localization/common/locale'; +import { NativeLocaleService } from 'vs/workbench/contrib/localization/electron-sandbox/localeService'; + +registerSingleton(ILocaleService, NativeLocaleService, true); // Register action to configure locale and related settings registerAction2(ConfigureDisplayLanguageAction); diff --git a/src/vs/workbench/workbench.sandbox.main.ts b/src/vs/workbench/workbench.sandbox.main.ts index 99705ed5b01..dd9ddd715b1 100644 --- a/src/vs/workbench/workbench.sandbox.main.ts +++ b/src/vs/workbench/workbench.sandbox.main.ts @@ -83,7 +83,6 @@ import 'vs/workbench/services/files/electron-sandbox/elevatedFileService'; import 'vs/workbench/services/search/electron-sandbox/searchService'; import 'vs/workbench/services/workingCopy/electron-sandbox/workingCopyHistoryService'; import 'vs/workbench/services/userDataSync/browser/userDataSyncEnablementService'; -import 'vs/workbench/contrib/localization/electron-sandbox/localeService'; import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; import { IUserDataInitializationService, UserDataInitializationService } from 'vs/workbench/services/userData/browser/userDataInit'; diff --git a/src/vs/workbench/workbench.web.main.ts b/src/vs/workbench/workbench.web.main.ts index 65562cad3ab..f0833043d64 100644 --- a/src/vs/workbench/workbench.web.main.ts +++ b/src/vs/workbench/workbench.web.main.ts @@ -62,7 +62,6 @@ import 'vs/workbench/services/files/browser/elevatedFileService'; import 'vs/workbench/services/workingCopy/browser/workingCopyHistoryService'; import 'vs/workbench/services/userDataSync/browser/webUserDataSyncEnablementService'; import 'vs/workbench/services/configurationResolver/browser/configurationResolverService'; -import 'vs/workbench/contrib/localization/browser/localeService'; import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; import { IAccessibilityService } from 'vs/platform/accessibility/common/accessibility'; From 737e8cc3de2f1beaa59a20a27acd1a5c82a85821 Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Wed, 8 Jun 2022 17:16:21 +0200 Subject: [PATCH 042/117] Fix #151193 (#151520) --- .../extensions/browser/extensionEditor.ts | 111 ++++-------------- .../extensions/browser/extensionsActions.ts | 3 + .../extensions/browser/extensionsWidgets.ts | 96 ++++++++++++++- .../browser/media/extensionEditor.css | 27 ++--- .../contrib/extensions/common/extensions.ts | 4 +- 5 files changed, 131 insertions(+), 110 deletions(-) diff --git a/src/vs/workbench/contrib/extensions/browser/extensionEditor.ts b/src/vs/workbench/contrib/extensions/browser/extensionEditor.ts index 9e5cc6d2f17..7df60b31868 100644 --- a/src/vs/workbench/contrib/extensions/browser/extensionEditor.ts +++ b/src/vs/workbench/contrib/extensions/browser/extensionEditor.ts @@ -16,13 +16,13 @@ import { append, $, finalHandler, join, addDisposableListener, EventType, setPar import { EditorPane } from 'vs/workbench/browser/parts/editor/editorPane'; import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { IInstantiationService, ServicesAccessor } from 'vs/platform/instantiation/common/instantiation'; -import { IExtensionIgnoredRecommendationsService, IExtensionRecommendationsService } from 'vs/workbench/services/extensionRecommendations/common/extensionRecommendations'; +import { IExtensionRecommendationsService } from 'vs/workbench/services/extensionRecommendations/common/extensionRecommendations'; import { IExtensionManifest, IKeyBinding, IView, IViewContainer } from 'vs/platform/extensions/common/extensions'; import { KeyMod, KeyCode } from 'vs/base/common/keyCodes'; import { ResolvedKeybinding } from 'vs/base/common/keybindings'; import { ExtensionsInput, IExtensionEditorOptions } from 'vs/workbench/contrib/extensions/common/extensionsInput'; -import { IExtensionsWorkbenchService, IExtensionsViewPaneContainer, VIEWLET_ID, IExtension, ExtensionContainers, ExtensionEditorTab, ExtensionState } from 'vs/workbench/contrib/extensions/common/extensions'; -import { RatingsWidget, InstallCountWidget, RemoteBadgeWidget, ExtensionWidget } from 'vs/workbench/contrib/extensions/browser/extensionsWidgets'; +import { IExtensionsWorkbenchService, IExtensionsViewPaneContainer, VIEWLET_ID, IExtension, ExtensionContainers, ExtensionEditorTab, ExtensionState, IExtensionContainer } from 'vs/workbench/contrib/extensions/common/extensions'; +import { RatingsWidget, InstallCountWidget, RemoteBadgeWidget, ExtensionWidget, ExtensionStatusWidget, ExtensionRecommendationWidget } from 'vs/workbench/contrib/extensions/browser/extensionsWidgets'; import { IEditorOpenContext } from 'vs/workbench/common/editor'; import { ActionBar } from 'vs/base/browser/ui/actionbar/actionbar'; import { @@ -66,8 +66,7 @@ import { Delegate } from 'vs/workbench/contrib/extensions/browser/extensionsList import { renderMarkdown } from 'vs/base/browser/markdownRenderer'; import { attachKeybindingLabelStyler } from 'vs/platform/theme/common/styler'; import { areSameExtensions } from 'vs/platform/extensionManagement/common/extensionManagementUtil'; -import { errorIcon, infoIcon, preReleaseIcon, starEmptyIcon, verifiedPublisherIcon as verifiedPublisherThemeIcon, warningIcon } from 'vs/workbench/contrib/extensions/browser/extensionsIcons'; -import { MarkdownString } from 'vs/base/common/htmlContent'; +import { errorIcon, infoIcon, preReleaseIcon, verifiedPublisherIcon as verifiedPublisherThemeIcon, warningIcon } from 'vs/workbench/contrib/extensions/browser/extensionsIcons'; import { IPaneCompositePartService } from 'vs/workbench/services/panecomposite/browser/panecomposite'; import { ViewContainerLocation } from 'vs/workbench/common/views'; import { IExtensionGalleryService, IGalleryExtension } from 'vs/platform/extensionManagement/common/extensionManagement'; @@ -147,8 +146,6 @@ interface IExtensionEditorTemplate { description: HTMLElement; actionsAndStatusContainer: HTMLElement; extensionActionBar: ActionBar; - status: HTMLElement; - recommendation: HTMLElement; navbar: NavBar; content: HTMLElement; header: HTMLElement; @@ -251,7 +248,6 @@ export class ExtensionEditor extends EditorPane { @INotificationService private readonly notificationService: INotificationService, @IOpenerService private readonly openerService: IOpenerService, @IExtensionRecommendationsService private readonly extensionRecommendationsService: IExtensionRecommendationsService, - @IExtensionIgnoredRecommendationsService private readonly extensionIgnoredRecommendationsService: IExtensionIgnoredRecommendationsService, @IStorageService storageService: IStorageService, @IExtensionService private readonly extensionService: IExtensionService, @IWebviewService private readonly webviewService: IWebviewService, @@ -310,7 +306,7 @@ export class ExtensionEditor extends EditorPane { rating.setAttribute('role', 'link'); // #132645 const ratingsWidget = this.instantiationService.createInstance(RatingsWidget, rating, false); - const widgets = [ + const widgets: ExtensionWidget[] = [ remoteBadge, versionWidget, preReleaseWidget, @@ -375,14 +371,30 @@ export class ExtensionEditor extends EditorPane { extensionActionBar.setFocusable(true); })); - const extensionContainers: ExtensionContainers = this.instantiationService.createInstance(ExtensionContainers, [...actions, ...widgets]); - for (const disposable of [...actions, ...widgets, extensionContainers]) { + const otherExtensionContainers: IExtensionContainer[] = []; + const extensionStatusAction = this.instantiationService.createInstance(ExtensionStatusAction); + const extensionStatusWidget = this._register(this.instantiationService.createInstance(ExtensionStatusWidget, append(actionsAndStatusContainer, $('.status')), extensionStatusAction)); + + otherExtensionContainers.push(extensionStatusAction, new class extends ExtensionWidget { + render() { + actionsAndStatusContainer.classList.toggle('list-layout', this.extension?.state === ExtensionState.Installed); + } + }()); + + const recommendationWidget = this.instantiationService.createInstance(ExtensionRecommendationWidget, append(details, $('.recommendation'))); + widgets.push(recommendationWidget); + + this._register(Event.any(extensionStatusWidget.onDidRender, recommendationWidget.onDidRender)(() => { + if (this.dimension) { + this.layout(this.dimension); + } + })); + + const extensionContainers: ExtensionContainers = this.instantiationService.createInstance(ExtensionContainers, [...actions, ...widgets, ...otherExtensionContainers]); + for (const disposable of [...actions, ...widgets, ...otherExtensionContainers, extensionContainers]) { this._register(disposable); } - const status = append(actionsAndStatusContainer, $('.status')); - const recommendation = append(details, $('.recommendation')); - this._register(Event.chain(extensionActionBar.onDidRun) .map(({ error }) => error) .filter(error => !!error) @@ -411,8 +423,6 @@ export class ExtensionEditor extends EditorPane { rating, actionsAndStatusContainer, extensionActionBar, - status, - recommendation, set extension(extension: IExtension) { extensionContainers.extension = extension; }, @@ -544,9 +554,6 @@ export class ExtensionEditor extends EditorPane { })); } - this.setStatus(extension, template); - this.setRecommendationText(extension, template); - const manifest = await this.extensionManifest.get().promise; if (token.isCancellationRequested) { return; @@ -620,72 +627,6 @@ export class ExtensionEditor extends EditorPane { template.navbar.onChange(e => this.onNavbarChange(extension, e, template), this, this.transientDisposables); } - private setStatus(extension: IExtension, template: IExtensionEditorTemplate): void { - const disposables = this.transientDisposables.add(new DisposableStore()); - const extensionStatus = disposables.add(this.instantiationService.createInstance(ExtensionStatusAction)); - extensionStatus.extension = extension; - const updateStatus = (layout: boolean) => { - disposables.clear(); - reset(template.status); - const status = extensionStatus.status; - if (status) { - if (status.icon) { - const statusIconActionBar = disposables.add(new ActionBar(template.status, { animated: false })); - statusIconActionBar.push(extensionStatus, { icon: true, label: false }); - } - disposables.add(this.renderMarkdownText(status.message.value, append(template.status, $('.status-text')))); - } - if (layout && this.dimension) { - this.layout(this.dimension); - } - }; - updateStatus(false); - this.transientDisposables.add(extensionStatus.onDidChangeStatus(() => updateStatus(true))); - - const updateActionLayout = () => template.actionsAndStatusContainer.classList.toggle('list-layout', extension.state === ExtensionState.Installed); - updateActionLayout(); - this.transientDisposables.add(this.extensionsWorkbenchService.onChange(() => updateActionLayout())); - } - - private setRecommendationText(extension: IExtension, template: IExtensionEditorTemplate): void { - const updateRecommendationText = (layout: boolean) => { - reset(template.recommendation); - const extRecommendations = this.extensionRecommendationsService.getAllRecommendationsWithReason(); - if (extRecommendations[extension.identifier.id.toLowerCase()]) { - const reasonText = extRecommendations[extension.identifier.id.toLowerCase()].reasonText; - if (reasonText) { - append(template.recommendation, $(`div${ThemeIcon.asCSSSelector(starEmptyIcon)}`)); - append(template.recommendation, $(`div.recommendation-text`, undefined, reasonText)); - } - } else if (this.extensionIgnoredRecommendationsService.globalIgnoredRecommendations.indexOf(extension.identifier.id.toLowerCase()) !== -1) { - append(template.recommendation, $(`div.recommendation-text`, undefined, localize('recommendationHasBeenIgnored', "You have chosen not to receive recommendations for this extension."))); - } - if (layout && this.dimension) { - this.layout(this.dimension); - } - }; - if (extension.deprecationInfo || extension.state === ExtensionState.Installed) { - reset(template.recommendation); - return; - } - updateRecommendationText(false); - this.transientDisposables.add(this.extensionRecommendationsService.onDidChangeRecommendations(() => updateRecommendationText(true))); - } - - private renderMarkdownText(markdownText: string, parent: HTMLElement): IDisposable { - const disposables = new DisposableStore(); - const rendered = disposables.add(renderMarkdown(new MarkdownString(markdownText, { isTrusted: true, supportThemeIcons: true }), { - actionHandler: { - callback: (content) => { - this.openerService.open(content, { allowCommands: true }).catch(onUnexpectedError); - }, - disposables: disposables - } - })); - append(parent, rendered.element); - return disposables; - } - override clearInput(): void { this.contentDisposables.clear(); this.transientDisposables.clear(); diff --git a/src/vs/workbench/contrib/extensions/browser/extensionsActions.ts b/src/vs/workbench/contrib/extensions/browser/extensionsActions.ts index 7f38b6df4be..0fd8d63b508 100644 --- a/src/vs/workbench/contrib/extensions/browser/extensionsActions.ts +++ b/src/vs/workbench/contrib/extensions/browser/extensionsActions.ts @@ -2944,6 +2944,7 @@ registerThemingParticipant((theme: IColorTheme, collector: ICssStyleCollector) = const errorColor = theme.getColor(editorErrorForeground); if (errorColor) { collector.addRule(`.monaco-action-bar .action-item .action-label.extension-action.extension-status-error { color: ${errorColor}; }`); + collector.addRule(`.extension-editor .header .actions-status-container > .status ${ThemeIcon.asCSSSelector(errorIcon)} { color: ${errorColor}; }`); collector.addRule(`.extension-editor .body .subcontent .runtime-status ${ThemeIcon.asCSSSelector(errorIcon)} { color: ${errorColor}; }`); collector.addRule(`.monaco-hover.extension-hover .markdown-hover .hover-contents ${ThemeIcon.asCSSSelector(errorIcon)} { color: ${errorColor}; }`); } @@ -2951,6 +2952,7 @@ registerThemingParticipant((theme: IColorTheme, collector: ICssStyleCollector) = const warningColor = theme.getColor(editorWarningForeground); if (warningColor) { collector.addRule(`.monaco-action-bar .action-item .action-label.extension-action.extension-status-warning { color: ${warningColor}; }`); + collector.addRule(`.extension-editor .header .actions-status-container > .status ${ThemeIcon.asCSSSelector(warningIcon)} { color: ${warningColor}; }`); collector.addRule(`.extension-editor .body .subcontent .runtime-status ${ThemeIcon.asCSSSelector(warningIcon)} { color: ${warningColor}; }`); collector.addRule(`.monaco-hover.extension-hover .markdown-hover .hover-contents ${ThemeIcon.asCSSSelector(warningIcon)} { color: ${warningColor}; }`); } @@ -2958,6 +2960,7 @@ registerThemingParticipant((theme: IColorTheme, collector: ICssStyleCollector) = const infoColor = theme.getColor(editorInfoForeground); if (infoColor) { collector.addRule(`.monaco-action-bar .action-item .action-label.extension-action.extension-status-info { color: ${infoColor}; }`); + collector.addRule(`.extension-editor .header .actions-status-container > .status ${ThemeIcon.asCSSSelector(infoIcon)} { color: ${infoColor}; }`); collector.addRule(`.extension-editor .body .subcontent .runtime-status ${ThemeIcon.asCSSSelector(infoIcon)} { color: ${infoColor}; }`); collector.addRule(`.monaco-hover.extension-hover .markdown-hover .hover-contents ${ThemeIcon.asCSSSelector(infoIcon)} { color: ${infoColor}; }`); } diff --git a/src/vs/workbench/contrib/extensions/browser/extensionsWidgets.ts b/src/vs/workbench/contrib/extensions/browser/extensionsWidgets.ts index 1760db32044..ef58205dfb2 100644 --- a/src/vs/workbench/contrib/extensions/browser/extensionsWidgets.ts +++ b/src/vs/workbench/contrib/extensions/browser/extensionsWidgets.ts @@ -7,16 +7,16 @@ import 'vs/css!./media/extensionsWidgets'; import * as semver from 'vs/base/common/semver/semver'; import { Disposable, toDisposable, DisposableStore, MutableDisposable, IDisposable } from 'vs/base/common/lifecycle'; import { IExtension, IExtensionsWorkbenchService, IExtensionContainer, ExtensionState, ExtensionEditorTab } from 'vs/workbench/contrib/extensions/common/extensions'; -import { append, $ } from 'vs/base/browser/dom'; +import { append, $, reset } from 'vs/base/browser/dom'; import * as platform from 'vs/base/common/platform'; import { localize } from 'vs/nls'; import { EnablementState, IExtensionManagementServerService } from 'vs/workbench/services/extensionManagement/common/extensionManagement'; -import { IExtensionRecommendationsService } from 'vs/workbench/services/extensionRecommendations/common/extensionRecommendations'; +import { IExtensionIgnoredRecommendationsService, IExtensionRecommendationsService } from 'vs/workbench/services/extensionRecommendations/common/extensionRecommendations'; import { ILabelService } from 'vs/platform/label/common/label'; import { extensionButtonProminentBackground, extensionButtonProminentForeground, ExtensionStatusAction, ReloadAction } from 'vs/workbench/contrib/extensions/browser/extensionsActions'; import { IThemeService, ThemeIcon, registerThemingParticipant } from 'vs/platform/theme/common/themeService'; import { EXTENSION_BADGE_REMOTE_BACKGROUND, EXTENSION_BADGE_REMOTE_FOREGROUND } from 'vs/workbench/common/theme'; -import { Event } from 'vs/base/common/event'; +import { Emitter, Event } from 'vs/base/common/event'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { CountBadge } from 'vs/base/browser/ui/countBadge/countBadge'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; @@ -32,6 +32,9 @@ import { areSameExtensions } from 'vs/platform/extensionManagement/common/extens import Severity from 'vs/base/common/severity'; import { setupCustomHover } from 'vs/base/browser/ui/iconLabel/iconLabelHover'; import { Color } from 'vs/base/common/color'; +import { renderMarkdown } from 'vs/base/browser/markdownRenderer'; +import { IOpenerService } from 'vs/platform/opener/common/opener'; +import { onUnexpectedError } from 'vs/base/common/errors'; export abstract class ExtensionWidget extends Disposable implements IExtensionContainer { private _extension: IExtension | null = null; @@ -576,6 +579,93 @@ export class ExtensionHoverWidget extends ExtensionWidget { } +export class ExtensionStatusWidget extends ExtensionWidget { + + private readonly renderDisposables = this._register(new DisposableStore()); + + private readonly _onDidRender = this._register(new Emitter()); + readonly onDidRender: Event = this._onDidRender.event; + + constructor( + private readonly container: HTMLElement, + private readonly extensionStatusAction: ExtensionStatusAction, + @IOpenerService private readonly openerService: IOpenerService, + ) { + super(); + this.render(); + this._register(extensionStatusAction.onDidChangeStatus(() => this.render())); + } + + render(): void { + reset(this.container); + const extensionStatus = this.extensionStatusAction.status; + if (extensionStatus) { + const markdown = new MarkdownString('', { isTrusted: true, supportThemeIcons: true }); + if (extensionStatus.icon) { + markdown.appendMarkdown(`$(${extensionStatus.icon.id}) `); + } + markdown.appendMarkdown(extensionStatus.message.value); + const rendered = this.renderDisposables.add(renderMarkdown(markdown, { + actionHandler: { + callback: (content) => { + this.openerService.open(content, { allowCommands: true }).catch(onUnexpectedError); + }, + disposables: this.renderDisposables + } + })); + append(this.container, rendered.element); + } + this._onDidRender.fire(); + } +} + +export class ExtensionRecommendationWidget extends ExtensionWidget { + + private readonly _onDidRender = this._register(new Emitter()); + readonly onDidRender: Event = this._onDidRender.event; + + constructor( + private readonly container: HTMLElement, + @IExtensionRecommendationsService private readonly extensionRecommendationsService: IExtensionRecommendationsService, + @IExtensionIgnoredRecommendationsService private readonly extensionIgnoredRecommendationsService: IExtensionIgnoredRecommendationsService, + ) { + super(); + this.render(); + this._register(this.extensionRecommendationsService.onDidChangeRecommendations(() => this.render())); + } + + render(): void { + reset(this.container); + const recommendationStatus = this.getRecommendationStatus(); + if (recommendationStatus) { + if (recommendationStatus.icon) { + append(this.container, $(`div${ThemeIcon.asCSSSelector(recommendationStatus.icon)}`)); + } + append(this.container, $(`div.recommendation-text`, undefined, recommendationStatus.message)); + } + this._onDidRender.fire(); + } + + private getRecommendationStatus(): { icon: ThemeIcon | undefined; message: string } | undefined { + if (!this.extension + || this.extension.deprecationInfo + || this.extension.state === ExtensionState.Installed + ) { + return undefined; + } + const extRecommendations = this.extensionRecommendationsService.getAllRecommendationsWithReason(); + if (extRecommendations[this.extension.identifier.id.toLowerCase()]) { + const reasonText = extRecommendations[this.extension.identifier.id.toLowerCase()].reasonText; + if (reasonText) { + return { icon: starEmptyIcon, message: reasonText }; + } + } else if (this.extensionIgnoredRecommendationsService.globalIgnoredRecommendations.indexOf(this.extension.identifier.id.toLowerCase()) !== -1) { + return { icon: undefined, message: localize('recommendationHasBeenIgnored', "You have chosen not to receive recommendations for this extension.") }; + } + return undefined; + } +} + // Rating icon export const extensionRatingIconColor = registerColor('extensionIcon.starForeground', { light: '#DF6100', dark: '#FF8E00', hcDark: '#FF8E00', hcLight: textLinkForeground }, localize('extensionIconStarForeground', "The icon color for extension ratings."), true); export const extensionVerifiedPublisherIconColor = registerColor('extensionIcon.verifiedForeground', { dark: textLinkForeground, light: textLinkForeground, hcDark: textLinkForeground, hcLight: textLinkForeground }, localize('extensionIconVerifiedForeground', "The icon color for extension verified publisher."), true); diff --git a/src/vs/workbench/contrib/extensions/browser/media/extensionEditor.css b/src/vs/workbench/contrib/extensions/browser/media/extensionEditor.css index 3c9a5a0e1b5..49d44c6e405 100644 --- a/src/vs/workbench/contrib/extensions/browser/media/extensionEditor.css +++ b/src/vs/workbench/contrib/extensions/browser/media/extensionEditor.css @@ -249,49 +249,36 @@ .extension-editor > .header > .details > .actions-status-container > .status { line-height: 22px; font-size: 90%; - display: flex; + margin-top: 3px; } .extension-editor > .header > .details > .actions-status-container.list-layout > .status { margin-top: 5px; } -.extension-editor > .header > .details > .actions-status-container > .status > .monaco-action-bar { - height: 22px; - margin-right: 2px; -} - -.extension-editor > .header > .details > .actions-status-container > .status > .monaco-action-bar .extension-action { - margin-top: 3px; -} - -.extension-editor > .header > .details > .actions-status-container.list-layout > .status > .monaco-action-bar .extension-action { - margin-top: 0px; -} - -.extension-editor > .header > .details > .actions-status-container:not(.list-layout) > .status > .status-text { - margin-top: 2px; +.extension-editor > .header > .details > .actions-status-container > .status .codicon { + vertical-align: text-bottom; } .extension-editor > .header > .details > .pre-release-text p, -.extension-editor > .header > .details > .actions-status-container > .status > .status-text p { +.extension-editor > .header > .details > .actions-status-container > .status p { margin-top: 0px; margin-bottom: 0px; } .extension-editor > .header > .details > .pre-release-text a, -.extension-editor > .header > .details > .actions-status-container > .status > .status-text a { +.extension-editor > .header > .details > .actions-status-container > .status a { color: var(--vscode-textLink-foreground) } .extension-editor > .header > .details > .pre-release-text a:hover, -.extension-editor > .header > .details > .actions-status-container > .status > .status-text a:hover { +.extension-editor > .header > .details > .actions-status-container > .status a:hover { text-decoration: underline; color: var(--vscode-textLink-activeForeground) } .extension-editor > .header > .details > .pre-release-text a:active, -.extension-editor > .header > .details > .actions-status-container > .status > .status-text a:active { +.extension-editor > .header > .details > .actions-status-container > .status a:active { color: var(--vscode-textLink-activeForeground) } diff --git a/src/vs/workbench/contrib/extensions/common/extensions.ts b/src/vs/workbench/contrib/extensions/common/extensions.ts index ec28a88e81f..eddd826fa33 100644 --- a/src/vs/workbench/contrib/extensions/common/extensions.ts +++ b/src/vs/workbench/contrib/extensions/common/extensions.ts @@ -9,7 +9,7 @@ import { IPager } from 'vs/base/common/paging'; import { IQueryOptions, ILocalExtension, IGalleryExtension, IExtensionIdentifier, InstallOptions, InstallVSIXOptions, IExtensionInfo, IExtensionQueryOptions, IDeprecationInfo } from 'vs/platform/extensionManagement/common/extensionManagement'; import { EnablementState, IExtensionManagementServer } from 'vs/workbench/services/extensionManagement/common/extensionManagement'; import { CancellationToken } from 'vs/base/common/cancellation'; -import { Disposable } from 'vs/base/common/lifecycle'; +import { Disposable, IDisposable } from 'vs/base/common/lifecycle'; import { areSameExtensions } from 'vs/platform/extensionManagement/common/extensionManagementUtil'; import { IExtensionManifest, ExtensionType } from 'vs/platform/extensions/common/extensions'; import { URI } from 'vs/base/common/uri'; @@ -136,7 +136,7 @@ export interface IExtensionsConfiguration { closeExtensionDetailsOnViewChange: boolean; } -export interface IExtensionContainer { +export interface IExtensionContainer extends IDisposable { extension: IExtension | null; updateWhenCounterExtensionChanges?: boolean; update(): void; From 1105ead47b4bd832255ead74087547a2d7a144ce Mon Sep 17 00:00:00 2001 From: Johannes Date: Wed, 8 Jun 2022 17:33:54 +0200 Subject: [PATCH 043/117] add a `transpileOnly` option to gulp-tsb --- build/lib/tsb/builder.js | 10 ++++++---- build/lib/tsb/builder.ts | 13 ++++++++----- 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/build/lib/tsb/builder.js b/build/lib/tsb/builder.js index cb700a54077..0bad406be79 100644 --- a/build/lib/tsb/builder.js +++ b/build/lib/tsb/builder.js @@ -30,7 +30,7 @@ function createTypeScriptBuilder(config, projectFile, cmd) { } let host = new LanguageServiceHost(cmd, projectFile, _log), service = ts.createLanguageService(host, ts.createDocumentRegistry()), lastBuildVersion = Object.create(null), lastDtsHash = Object.create(null), userWantsDeclarations = cmd.options.declaration, oldErrors = Object.create(null), headUsed = process.memoryUsage().heapUsed, emitSourceMapsInStream = true; // always emit declaraction files - host.getCompilationSettings().declaration = true; + host.getCompilationSettings().declaration = !config.transpileOnly; function file(file) { // support gulp-sourcemaps if (file.sourceMap) { @@ -149,8 +149,10 @@ function createTypeScriptBuilder(config, projectFile, cmd) { for (let fileName of host.getScriptFileNames()) { if (lastBuildVersion[fileName] !== host.getScriptVersion(fileName)) { toBeEmitted.push(fileName); - toBeCheckedSyntactically.push(fileName); - toBeCheckedSemantically.push(fileName); + if (!config.transpileOnly) { + toBeCheckedSyntactically.push(fileName); + toBeCheckedSemantically.push(fileName); + } } } return new Promise(resolve => { @@ -177,7 +179,7 @@ function createTypeScriptBuilder(config, projectFile, cmd) { // remember when this was build newLastBuildVersion.set(fileName, host.getScriptVersion(fileName)); // remeber the signature - if (value.signature && lastDtsHash[fileName] !== value.signature) { + if (!config.transpileOnly && value.signature && lastDtsHash[fileName] !== value.signature) { lastDtsHash[fileName] = value.signature; filesWithChangedSignature.push(fileName); } diff --git a/build/lib/tsb/builder.ts b/build/lib/tsb/builder.ts index d5bec6ee97b..7850d9f146d 100644 --- a/build/lib/tsb/builder.ts +++ b/build/lib/tsb/builder.ts @@ -14,6 +14,7 @@ import * as Vinyl from 'vinyl'; export interface IConfiguration { verbose: boolean; + transpileOnly?: boolean; _emitWithoutBasePath?: boolean; } @@ -55,8 +56,7 @@ export function createTypeScriptBuilder(config: IConfiguration, projectFile: str emitSourceMapsInStream = true; // always emit declaraction files - host.getCompilationSettings().declaration = true; - + host.getCompilationSettings().declaration = !config.transpileOnly; function file(file: Vinyl): void { // support gulp-sourcemaps @@ -196,8 +196,11 @@ export function createTypeScriptBuilder(config: IConfiguration, projectFile: str if (lastBuildVersion[fileName] !== host.getScriptVersion(fileName)) { toBeEmitted.push(fileName); - toBeCheckedSyntactically.push(fileName); - toBeCheckedSemantically.push(fileName); + + if (!config.transpileOnly) { + toBeCheckedSyntactically.push(fileName); + toBeCheckedSemantically.push(fileName); + } } } @@ -233,7 +236,7 @@ export function createTypeScriptBuilder(config: IConfiguration, projectFile: str newLastBuildVersion.set(fileName, host.getScriptVersion(fileName)); // remeber the signature - if (value.signature && lastDtsHash[fileName] !== value.signature) { + if (!config.transpileOnly && value.signature && lastDtsHash[fileName] !== value.signature) { lastDtsHash[fileName] = value.signature; filesWithChangedSignature.push(fileName); } From bdc8850815e78018c35753d4ae3b1df28d33e8df Mon Sep 17 00:00:00 2001 From: Jean Pierre Date: Wed, 8 Jun 2022 10:43:48 -0500 Subject: [PATCH 044/117] Fix missing symlink explorer decoration if file is opened from quickpick (#147629) Fix #147628 --- .../files/browser/views/explorerDecorationsProvider.ts | 4 ++-- .../services/decorations/browser/decorationsService.ts | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/vs/workbench/contrib/files/browser/views/explorerDecorationsProvider.ts b/src/vs/workbench/contrib/files/browser/views/explorerDecorationsProvider.ts index 062c0d23e29..41f221e0db0 100644 --- a/src/vs/workbench/contrib/files/browser/views/explorerDecorationsProvider.ts +++ b/src/vs/workbench/contrib/files/browser/views/explorerDecorationsProvider.ts @@ -65,10 +65,10 @@ export class ExplorerDecorationsProvider implements IDecorationsProvider { return this._onDidChange.event; } - provideDecorations(resource: URI): IDecorationData | undefined { + async provideDecorations(resource: URI): Promise { const fileStat = this.explorerService.findClosest(resource); if (!fileStat) { - return undefined; + throw new Error('ExplorerItem not found'); } return provideDecorations(fileStat); diff --git a/src/vs/workbench/services/decorations/browser/decorationsService.ts b/src/vs/workbench/services/decorations/browser/decorationsService.ts index 75886dc3b76..6f4dfa5acae 100644 --- a/src/vs/workbench/services/decorations/browser/decorationsService.ts +++ b/src/vs/workbench/services/decorations/browser/decorationsService.ts @@ -398,7 +398,8 @@ export class DecorationsService implements IDecorationsService { private _keepItem(map: DecorationEntry, provider: IDecorationsProvider, uri: URI, data: IDecorationData | undefined): IDecorationData | null { const deco = data ? data : null; - const old = map.set(provider, deco); + const old = map.get(provider); + map.set(provider, deco); if (deco || old) { // only fire event when something changed this._onDidChangeDecorationsDelayed.fire(uri); From aa23a0dbb749fd3a51a8ed217538c563b8ff012a Mon Sep 17 00:00:00 2001 From: Johannes Date: Wed, 8 Jun 2022 17:46:25 +0200 Subject: [PATCH 045/117] use `prefer-const` default config --- .eslintrc.json | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/.eslintrc.json b/.eslintrc.json index 72298423db8..1abec281d53 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -14,12 +14,7 @@ "constructor-super": "warn", "curly": "warn", "eqeqeq": "warn", - "prefer-const": [ - "warn", - { - "destructuring": "all" - } - ], + "prefer-const": "warn", "no-buffer-constructor": "warn", "no-caller": "warn", "no-case-declarations": "warn", From 0656d21d11910e1b241d7d6c52761d89c0ba23a4 Mon Sep 17 00:00:00 2001 From: Johannes Date: Wed, 8 Jun 2022 17:49:21 +0200 Subject: [PATCH 046/117] auto-fixed prefer-const violation --- .../common/computeNodeModulesCacheKey.ts | 2 +- build/darwin/create-universal-app.ts | 2 +- build/gulpfile.editor.js | 38 +- build/gulpfile.extensions.js | 2 +- build/gulpfile.hygiene.js | 2 +- build/gulpfile.reh.js | 2 +- build/gulpfile.vscode.js | 14 +- build/gulpfile.vscode.web.js | 4 +- build/hygiene.js | 4 +- build/lib/asar.ts | 2 +- build/lib/builtInExtensions.ts | 2 +- build/lib/compilation.ts | 10 +- .../eslint/code-no-unexternalized-strings.ts | 4 +- build/lib/eslint/vscode-dts-cancellation.ts | 2 +- build/lib/extensions.ts | 4 +- build/lib/git.ts | 2 +- build/lib/i18n.ts | 188 +++++----- build/lib/monaco-api.ts | 84 ++--- build/lib/standalone.ts | 20 +- build/lib/treeshaking.ts | 18 +- build/lib/tsb/builder.ts | 60 +-- build/lib/tsb/index.ts | 2 +- build/lib/tsb/utils.ts | 2 +- build/lib/util.ts | 4 +- .../client/src/cssClient.ts | 20 +- .../server/src/languageModelCache.ts | 22 +- .../server/src/requests.ts | 2 +- .../server/src/test/completion.test.ts | 32 +- .../server/src/test/links.test.ts | 22 +- .../server/src/utils/documentContext.ts | 4 +- .../server/src/utils/runner.ts | 2 +- .../server/src/utils/strings.ts | 2 +- extensions/debug-auto-launch/src/extension.ts | 4 +- .../debug-server-ready/src/extension.ts | 8 +- .../emmet/src/defaultCompletionProvider.ts | 16 +- extensions/emmet/src/editPoint.ts | 14 +- extensions/emmet/src/emmetCommon.ts | 4 +- extensions/emmet/src/incrementDecrement.ts | 4 +- extensions/emmet/src/matchTag.ts | 2 +- extensions/emmet/src/removeTag.ts | 4 +- extensions/emmet/src/selectItem.ts | 2 +- extensions/emmet/src/selectItemStylesheet.ts | 8 +- .../test/editPointSelectItemBalance.test.ts | 20 +- .../src/test/partialParsingStylesheet.test.ts | 26 +- extensions/emmet/src/test/tagActions.test.ts | 4 +- extensions/emmet/src/toggleComment.ts | 10 +- extensions/emmet/src/updateImageSize.ts | 4 +- extensions/emmet/src/updateTag.ts | 2 +- extensions/emmet/src/util.ts | 8 +- .../extension-editing/src/extensionLinter.ts | 4 +- extensions/git/src/askpass.ts | 2 +- extensions/git/src/commands.ts | 8 +- extensions/git/src/decorationProvider.ts | 2 +- extensions/git/src/encoding.ts | 2 +- extensions/git/src/git.ts | 10 +- extensions/git/src/staging.ts | 2 +- extensions/git/src/util.ts | 6 +- .../github-authentication/src/common/utils.ts | 2 +- extensions/github/src/remoteSourceProvider.ts | 2 +- extensions/grunt/src/main.ts | 72 ++-- extensions/gulp/src/main.ts | 66 ++-- .../client/src/htmlClient.ts | 20 +- .../client/src/node/htmlClientMain.ts | 2 +- .../server/src/modes/cssMode.ts | 26 +- .../server/src/modes/embeddedSupport.ts | 42 +-- .../server/src/modes/formatting.ts | 44 +-- .../server/src/modes/htmlFolding.ts | 30 +- .../server/src/modes/javascriptMode.ts | 80 ++-- .../server/src/modes/languageModes.ts | 20 +- .../server/src/modes/selectionRanges.ts | 2 +- .../server/src/modes/semanticTokens.ts | 12 +- .../server/src/requests.ts | 2 +- .../server/src/test/completions.test.ts | 16 +- .../server/src/test/documentContext.test.ts | 2 +- .../server/src/test/formatting.test.ts | 18 +- .../server/src/test/selectionRanges.test.ts | 2 +- .../server/src/test/semanticTokens.test.ts | 2 +- .../server/src/utils/arrays.ts | 6 +- .../server/src/utils/documentContext.ts | 4 +- .../server/src/utils/runner.ts | 2 +- .../server/src/utils/strings.ts | 8 +- extensions/image-preview/media/main.js | 2 +- extensions/ipynb/src/test/serializers.test.ts | 2 +- extensions/jake/src/main.ts | 70 ++-- .../server/src/jsonServer.ts | 4 +- .../server/src/languageModelCache.ts | 22 +- .../server/src/utils/runner.ts | 4 +- .../server/src/utils/strings.ts | 2 +- .../src/languageFeatures/smartSelect.ts | 2 +- .../src/test/util.ts | 2 +- .../src/util/openDocumentLink.ts | 2 +- .../merge-conflict/src/codelensProvider.ts | 12 +- .../merge-conflict/src/commandHandler.ts | 14 +- .../merge-conflict/src/contentProvider.ts | 4 +- extensions/merge-conflict/src/delayer.ts | 4 +- .../src/documentMergeConflict.ts | 4 +- .../merge-conflict/src/documentTracker.ts | 8 +- .../merge-conflict/src/mergeConflictParser.ts | 8 +- .../merge-conflict/src/mergeDecorator.ts | 12 +- extensions/merge-conflict/src/services.ts | 2 +- .../microsoft-authentication/src/AADHelper.ts | 4 +- extensions/notebook-renderers/src/ansi.ts | 2 +- .../notebook-renderers/src/textHelper.ts | 4 +- extensions/npm/src/commands.ts | 16 +- .../src/features/packageJSONContribution.ts | 12 +- extensions/npm/src/npmMain.ts | 12 +- extensions/npm/src/npmView.ts | 20 +- extensions/npm/src/scriptHover.ts | 20 +- extensions/npm/src/tasks.ts | 70 ++-- .../src/features/completionItemProvider.ts | 38 +- .../src/features/hoverProvider.ts | 12 +- .../src/features/signatureHelpProvider.ts | 24 +- .../src/features/utils/async.ts | 6 +- .../src/features/validationProvider.ts | 32 +- .../php-language-features/src/phpMain.ts | 2 +- .../references-view/src/references/model.ts | 22 +- extensions/references-view/src/tree.ts | 2 +- extensions/references-view/src/utils.ts | 14 +- extensions/search-result/src/extension.ts | 4 +- extensions/shared.webpack.config.js | 4 +- extensions/vscode-api-tests/src/memfs.ts | 36 +- .../src/singlefolder-tests/commands.test.ts | 28 +- .../src/singlefolder-tests/languages.test.ts | 44 +-- .../notebook.document.test.ts | 2 +- .../notebook.editor.test.ts | 2 +- .../src/singlefolder-tests/terminal.test.ts | 4 +- .../src/singlefolder-tests/window.test.ts | 42 +-- .../workspace.tasks.test.ts | 2 +- .../src/singlefolder-tests/workspace.test.ts | 140 +++---- .../src/colorizer.test.ts | 12 +- .../vscode-test-resolver/src/extension.ts | 4 +- src/server-main.js | 2 +- src/vs/base/browser/defaultWorkerFactory.ts | 2 +- src/vs/base/browser/dom.ts | 74 ++-- src/vs/base/browser/iframe.ts | 8 +- src/vs/base/browser/keyboardEvent.ts | 8 +- src/vs/base/browser/mouseEvent.ts | 6 +- src/vs/base/browser/touch.ts | 42 +-- .../ui/breadcrumbs/breadcrumbsWidget.ts | 16 +- .../browser/ui/contextview/contextview.ts | 6 +- src/vs/base/browser/ui/dialog/dialog.ts | 2 +- src/vs/base/browser/ui/findinput/findInput.ts | 4 +- .../base/browser/ui/findinput/replaceInput.ts | 6 +- src/vs/base/browser/ui/inputbox/inputBox.ts | 6 +- .../ui/keybindingLabel/keybindingLabel.ts | 2 +- src/vs/base/browser/ui/list/listView.ts | 4 +- src/vs/base/browser/ui/list/rangeMap.ts | 8 +- src/vs/base/browser/ui/menu/menu.ts | 18 +- src/vs/base/browser/ui/menu/menubar.ts | 28 +- src/vs/base/browser/ui/sash/sash.ts | 2 +- .../browser/ui/selectBox/selectBoxCustom.ts | 6 +- src/vs/base/browser/ui/splitview/splitview.ts | 2 +- src/vs/base/browser/ui/toolbar/toolbar.ts | 2 +- src/vs/base/browser/ui/tree/abstractTree.ts | 2 +- src/vs/base/common/amd.ts | 6 +- src/vs/base/common/arrays.ts | 10 +- src/vs/base/common/codicons.ts | 2 +- src/vs/base/common/collections.ts | 12 +- src/vs/base/common/comparers.ts | 2 +- src/vs/base/common/diff/diff.ts | 4 +- src/vs/base/common/errors.ts | 2 +- src/vs/base/common/event.ts | 6 +- src/vs/base/common/json.ts | 4 +- src/vs/base/common/jsonEdit.ts | 4 +- src/vs/base/common/keyCodes.ts | 4 +- src/vs/base/common/labels.ts | 4 +- src/vs/base/common/lifecycle.ts | 2 +- src/vs/base/common/map.ts | 14 +- src/vs/base/common/objects.ts | 2 +- src/vs/base/common/platform.ts | 2 +- src/vs/base/common/skipList.ts | 6 +- src/vs/base/common/strings.ts | 6 +- src/vs/base/common/types.ts | 4 +- src/vs/base/common/uriIpc.ts | 4 +- src/vs/base/common/worker/simpleWorker.ts | 10 +- src/vs/base/node/id.ts | 2 +- src/vs/base/node/macAddress.ts | 2 +- src/vs/base/node/processes.ts | 2 +- src/vs/base/parts/ipc/common/ipc.net.ts | 2 +- src/vs/base/parts/ipc/common/ipc.ts | 4 +- src/vs/base/parts/ipc/node/ipc.net.ts | 6 +- .../test/browser/quickinput.test.ts | 4 +- src/vs/base/parts/request/browser/request.ts | 2 +- .../parts/storage/test/node/storage.test.ts | 8 +- src/vs/base/test/browser/actionbar.test.ts | 20 +- src/vs/base/test/browser/dom.test.ts | 10 +- .../browser/formattedTextRenderer.test.ts | 22 +- .../test/browser/markdownRenderer.test.ts | 14 +- .../ui/scrollbar/scrollbarState.test.ts | 4 +- .../browser/ui/splitview/splitview.test.ts | 2 +- .../browser/ui/tree/asyncDataTree.test.ts | 2 +- .../browser/ui/tree/indexTreeModel.test.ts | 2 +- .../browser/ui/tree/objectTreeModel.test.ts | 2 +- src/vs/base/test/common/arrays.test.ts | 10 +- src/vs/base/test/common/async.test.ts | 148 ++++---- src/vs/base/test/common/buffer.test.ts | 38 +- src/vs/base/test/common/cancellation.test.ts | 12 +- src/vs/base/test/common/collections.test.ts | 8 +- src/vs/base/test/common/color.test.ts | 8 +- src/vs/base/test/common/diff/diff.test.ts | 18 +- src/vs/base/test/common/event.test.ts | 56 +-- src/vs/base/test/common/filters.test.ts | 26 +- src/vs/base/test/common/fuzzyScorer.test.ts | 72 ++-- src/vs/base/test/common/glob.test.ts | 78 ++-- src/vs/base/test/common/history.test.ts | 2 +- src/vs/base/test/common/iconLabels.test.ts | 2 +- src/vs/base/test/common/json.test.ts | 22 +- src/vs/base/test/common/jsonEdit.test.ts | 52 +-- src/vs/base/test/common/jsonFormatter.test.ts | 2 +- src/vs/base/test/common/lifecycle.test.ts | 10 +- src/vs/base/test/common/linkedList.test.ts | 10 +- src/vs/base/test/common/map.test.ts | 84 ++--- src/vs/base/test/common/marshalling.test.ts | 6 +- src/vs/base/test/common/network.test.ts | 10 +- src/vs/base/test/common/objects.test.ts | 26 +- src/vs/base/test/common/processes.test.ts | 2 +- src/vs/base/test/common/resourceTree.test.ts | 4 +- src/vs/base/test/common/resources.test.ts | 34 +- src/vs/base/test/common/scrollable.test.ts | 4 +- src/vs/base/test/common/skipList.test.ts | 26 +- src/vs/base/test/common/stream.test.ts | 4 +- .../base/test/common/timeTravelScheduler.ts | 4 +- src/vs/base/test/common/uri.test.ts | 30 +- src/vs/base/test/node/uri.test.perf.ts | 18 +- src/vs/base/worker/workerMain.ts | 4 +- .../contrib/languagePackCachedDataCleaner.ts | 2 +- src/vs/code/node/cli.ts | 2 +- .../services/abstractCodeEditorService.ts | 2 +- .../browser/services/editorWorkerService.ts | 4 +- .../editor/browser/widget/codeEditorWidget.ts | 12 +- src/vs/editor/common/config/editorOptions.ts | 2 +- src/vs/editor/common/core/range.ts | 8 +- src/vs/editor/common/cursor/cursor.ts | 2 +- .../common/cursor/cursorMoveCommands.ts | 2 +- .../editor/common/languageFeatureRegistry.ts | 6 +- .../supports/inplaceReplaceSupport.ts | 2 +- .../common/languages/supports/tokenization.ts | 2 +- src/vs/editor/common/model/editStack.ts | 2 +- src/vs/editor/common/model/textModelSearch.ts | 2 +- .../common/services/editorSimpleWorker.ts | 4 +- .../services/languageFeatureDebounce.ts | 4 +- .../common/services/languagesRegistry.ts | 6 +- .../services/markerDecorationsService.ts | 2 +- src/vs/editor/common/services/modelService.ts | 2 +- .../services/unicodeTextModelHighlighter.ts | 2 +- .../common/viewModel/modelLineProjection.ts | 2 +- .../browser/bracketMatching.ts | 6 +- .../caretOperations/browser/transpose.ts | 26 +- .../test/browser/codeAction.test.ts | 6 +- .../contrib/codelens/browser/codelens.ts | 2 +- .../codelens/browser/codelensController.ts | 22 +- .../codelens/browser/codelensWidget.ts | 6 +- .../contrib/colorPicker/browser/color.ts | 4 +- .../colorPicker/browser/colorDetector.ts | 6 +- .../comment/browser/blockCommentCommand.ts | 4 +- .../comment/browser/lineCommentCommand.ts | 10 +- .../contextmenu/browser/contextmenu.ts | 2 +- src/vs/editor/contrib/dnd/browser/dnd.ts | 8 +- .../contrib/dnd/browser/dragAndDropCommand.ts | 2 +- .../documentSymbols/browser/outlineModel.ts | 24 +- .../test/browser/outlineModel.test.ts | 28 +- .../test/browser/editorState.test.ts | 18 +- .../contrib/find/browser/findController.ts | 14 +- .../contrib/find/browser/findDecorations.ts | 20 +- .../editor/contrib/find/browser/findModel.ts | 60 +-- .../contrib/find/browser/findOptionsWidget.ts | 4 +- .../editor/contrib/find/browser/findState.ts | 4 +- .../editor/contrib/find/browser/findWidget.ts | 36 +- .../contrib/find/browser/replaceAllCommand.ts | 4 +- .../contrib/find/browser/replacePattern.ts | 20 +- .../contrib/find/test/browser/find.test.ts | 18 +- .../find/test/browser/findController.test.ts | 2 +- .../find/test/browser/findModel.test.ts | 182 ++++----- .../find/test/browser/replacePattern.test.ts | 50 +-- .../editor/contrib/folding/browser/folding.ts | 82 ++--- .../contrib/folding/browser/foldingModel.ts | 118 +++--- .../contrib/folding/browser/foldingRanges.ts | 30 +- .../folding/browser/hiddenRangeModel.ts | 22 +- .../folding/browser/indentRangeProvider.ts | 36 +- .../browser/intializingRangeProvider.ts | 8 +- .../folding/browser/syntaxRangeProvider.ts | 32 +- .../folding/test/browser/foldingModel.test.ts | 286 +++++++-------- .../test/browser/foldingRanges.test.ts | 24 +- .../test/browser/hiddenRangeModel.test.ts | 10 +- .../folding/test/browser/indentFold.test.ts | 26 +- .../test/browser/indentRangeProvider.test.ts | 16 +- .../folding/test/browser/syntaxFold.test.ts | 30 +- .../editor/contrib/format/browser/format.ts | 16 +- .../contrib/format/browser/formatActions.ts | 6 +- .../contrib/format/browser/formattingEdit.ts | 4 +- .../gotoError/browser/gotoErrorWidget.ts | 16 +- .../browser/markerNavigationService.ts | 4 +- .../contrib/gotoSymbol/browser/goToSymbol.ts | 2 +- .../browser/link/goToDefinitionAtPosition.ts | 8 +- .../browser/peek/referencesController.ts | 8 +- .../gotoSymbol/browser/peek/referencesTree.ts | 2 +- .../browser/peek/referencesWidget.ts | 10 +- .../gotoSymbol/browser/referencesModel.ts | 10 +- src/vs/editor/contrib/hover/browser/hover.ts | 2 +- .../inPlaceReplace/browser/inPlaceReplace.ts | 4 +- .../indentation/browser/indentUtils.ts | 2 +- .../indentation/browser/indentation.ts | 94 ++--- .../contrib/inlayHints/browser/inlayHints.ts | 2 +- .../browser/inlayHintsController.ts | 6 +- .../inlayHints/browser/inlayHintsHover.ts | 2 +- .../browser/inlineCompletionsModel.ts | 2 +- .../browser/copyLinesCommand.ts | 2 +- .../browser/linesOperations.ts | 126 +++---- .../browser/moveLinesCommand.ts | 86 ++--- .../browser/sortLinesCommand.ts | 10 +- .../test/browser/linesOperations.test.ts | 102 +++--- .../test/browser/moveLinesCommand.test.ts | 2 +- .../linkedEditing/browser/linkedEditing.ts | 2 +- .../editor/contrib/links/browser/getLinks.ts | 2 +- .../multicursor/browser/multicursor.ts | 10 +- .../test/browser/multicursor.test.ts | 50 +-- .../contrib/peekView/browser/peekView.ts | 6 +- .../editor/contrib/rename/browser/rename.ts | 4 +- .../smartSelect/browser/bracketSelections.ts | 16 +- .../smartSelect/browser/smartSelect.ts | 12 +- .../smartSelect/browser/wordSelections.ts | 8 +- .../test/browser/smartSelect.test.ts | 24 +- .../contrib/snippet/browser/snippetParser.ts | 34 +- .../contrib/snippet/browser/snippetSession.ts | 14 +- .../snippet/browser/snippetVariables.ts | 4 +- .../browser/snippetController2.old.test.ts | 4 +- .../test/browser/snippetParser.test.ts | 42 +-- .../suggest/browser/completionModel.ts | 8 +- .../editor/contrib/suggest/browser/suggest.ts | 4 +- .../suggest/browser/suggestAlternatives.ts | 2 +- .../suggest/browser/suggestController.ts | 16 +- .../contrib/suggest/browser/suggestMemory.ts | 14 +- .../contrib/suggest/browser/suggestModel.ts | 4 +- .../suggest/browser/suggestWidgetRenderer.ts | 2 +- .../suggest/browser/suggestWidgetStatus.ts | 2 +- .../contrib/suggest/browser/wordDistance.ts | 8 +- .../test/browser/completionModel.test.ts | 4 +- .../test/browser/suggestController.test.ts | 34 +- .../test/browser/suggestMemory.test.ts | 24 +- .../suggest/test/browser/suggestModel.test.ts | 2 +- .../suggest/test/browser/wordDistance.test.ts | 6 +- .../browser/unicodeHighlighter.ts | 12 +- .../browser/wordHighlighter.ts | 38 +- .../wordOperations/browser/wordOperations.ts | 4 +- .../test/browser/wordTestUtils.ts | 4 +- .../browser/wordPartOperations.ts | 4 +- .../contrib/zoneWidget/browser/zoneWidget.ts | 20 +- .../standalone/browser/standaloneServices.ts | 2 +- .../browser/standaloneThemeService.ts | 4 +- .../common/monarch/monarchCompile.ts | 6 +- .../standalone/common/monarch/monarchLexer.ts | 4 +- .../browser/commands/shiftCommand.test.ts | 20 +- .../test/browser/commands/sideEditing.test.ts | 2 +- .../trimTrailingWhitespaceCommand.test.ts | 6 +- .../config/editorConfiguration.test.ts | 32 +- .../test/browser/controller/cursor.test.ts | 66 ++-- .../test/browser/controller/imeRecorder.ts | 2 +- .../test/browser/controller/imeTester.ts | 34 +- .../browser/controller/textAreaInput.test.ts | 4 +- .../browser/controller/textAreaState.test.ts | 18 +- .../services/decorationRenderOptions.test.ts | 6 +- .../browser/services/openerService.test.ts | 2 +- src/vs/editor/test/browser/testCommand.ts | 4 +- .../browser/view/minimapCharRenderer.test.ts | 22 +- .../test/browser/view/viewLayer.test.ts | 18 +- .../viewModel/modelLineProjection.test.ts | 54 +-- .../viewModel/viewModelDecorations.test.ts | 12 +- .../browser/viewModel/viewModelImpl.test.ts | 6 +- .../common/core/characterClassifier.test.ts | 2 +- .../test/common/core/lineTokens.test.ts | 4 +- src/vs/editor/test/common/core/range.test.ts | 10 +- .../editor/test/common/core/testLineToken.ts | 2 +- .../test/common/diff/diffComputer.test.ts | 270 +++++++------- .../getBracketPairsInRange.test.ts | 4 +- .../common/model/editableTextModel.test.ts | 18 +- .../model/editableTextModelAuto.test.ts | 34 +- .../model/editableTextModelTestUtils.ts | 26 +- .../test/common/model/intervalTree.test.ts | 54 +-- .../linesTextBuffer/linesTextBuffer.test.ts | 2 +- .../textBufferAutoTestUtils.ts | 54 +-- .../test/common/model/model.line.test.ts | 18 +- src/vs/editor/test/common/model/model.test.ts | 4 +- .../common/model/modelDecorations.test.ts | 64 ++-- .../common/model/modelEditOperation.test.ts | 8 +- .../pieceTreeTextBuffer.test.ts | 240 ++++++------ .../test/common/model/textChange.test.ts | 46 +-- .../test/common/model/textModel.test.ts | 64 ++-- .../test/common/model/textModelSearch.test.ts | 88 ++--- .../common/model/textModelWithTokens.test.ts | 58 +-- .../test/common/model/tokensStore.test.ts | 12 +- .../modes/languageConfiguration.test.ts | 20 +- .../common/modes/languageSelector.test.ts | 26 +- .../test/common/modes/linkComputer.test.ts | 6 +- .../modes/supports/characterPair.test.ts | 14 +- .../modes/supports/electricCharacter.test.ts | 8 +- .../common/modes/supports/onEnter.test.ts | 24 +- .../modes/supports/richEditBrackets.test.ts | 20 +- .../modes/supports/tokenization.test.ts | 52 +-- .../common/modes/textToHtmlTokenizer.test.ts | 30 +- src/vs/editor/test/common/modesTestUtils.ts | 8 +- .../services/editorSimpleWorker.test.ts | 20 +- .../viewLayout/viewLineRenderer.test.ts | 2 +- .../browser/menuEntryActionViewItem.ts | 2 +- src/vs/platform/actions/common/actions.ts | 4 +- src/vs/platform/actions/common/menuService.ts | 14 +- .../platform/assignment/common/assignment.ts | 6 +- .../backup/electron-main/backupMainService.ts | 6 +- src/vs/platform/commands/common/commands.ts | 6 +- .../configuration/common/configuration.ts | 4 +- .../common/configurationModels.ts | 24 +- .../common/configurationRegistry.ts | 14 +- .../test/common/configuration.test.ts | 26 +- .../test/common/configurationModels.test.ts | 92 ++--- .../contextkey/browser/contextKeyService.ts | 4 +- .../platform/contextkey/common/contextkey.ts | 34 +- .../contextkey/test/common/contextkey.test.ts | 16 +- .../contextview/browser/contextMenuHandler.ts | 6 +- .../diagnostics/node/diagnosticsService.ts | 2 +- src/vs/platform/environment/node/argv.ts | 30 +- .../abstractExtensionManagementService.ts | 2 +- .../common/extensionEnablementService.ts | 6 +- .../common/extensionManagementCLIService.ts | 2 +- .../common/extensionsScannerService.ts | 26 +- .../node/extensionManagementService.ts | 2 +- .../extensions/common/extensionValidator.ts | 12 +- .../platform/extensions/common/extensions.ts | 4 +- .../test/common/extensionValidator.test.ts | 6 +- .../node/externalTerminalService.ts | 8 +- .../files/browser/htmlFileSystemProvider.ts | 2 +- .../common/inMemoryFilesystemProvider.ts | 34 +- .../node/watcher/nodejs/nodejsWatcherLib.ts | 2 +- .../files/test/common/watcher.test.ts | 2 +- .../files/test/node/diskFileService.test.ts | 8 +- .../node/nodejsWatcher.integrationTest.ts | 4 +- .../node/parcelWatcher.integrationTest.ts | 2 +- src/vs/platform/instantiation/common/graph.ts | 12 +- .../common/instantiationService.ts | 34 +- .../instantiation/common/serviceCollection.ts | 2 +- .../instantiation/test/common/graph.test.ts | 2 +- .../test/common/instantiationService.test.ts | 66 ++-- .../test/common/instantiationServiceMock.ts | 18 +- .../keybinding/common/keybindingResolver.ts | 14 +- .../common/resolvedKeybindingItem.ts | 2 +- .../common/abstractKeybindingService.test.ts | 24 +- .../test/common/mockKeybindingService.ts | 4 +- .../keyboardLayout/common/keyboardLayout.ts | 6 +- .../languagePacks/node/languagePacks.ts | 2 +- src/vs/platform/lifecycle/common/lifecycle.ts | 2 +- .../electron-main/lifecycleMainService.ts | 2 +- .../platform/markers/common/markerService.ts | 16 +- src/vs/platform/markers/common/markers.ts | 2 +- .../markers/test/common/markerService.test.ts | 24 +- .../platform/menubar/electron-main/menubar.ts | 4 +- .../opener/test/common/opener.test.ts | 2 +- .../registry/test/common/platform.test.ts | 2 +- .../state/test/electron-main/state.test.ts | 2 +- src/vs/platform/storage/common/storage.ts | 4 +- .../test/common/storageService.test.ts | 4 +- .../electron-main/storageMainService.test.ts | 14 +- .../telemetry/browser/errorTelemetry.ts | 6 +- .../telemetry/common/errorTelemetry.ts | 6 +- .../telemetry/common/telemetryService.ts | 14 +- .../telemetry/common/telemetryUtils.ts | 2 +- .../test/browser/telemetryService.test.ts | 204 +++++------ .../appInsightsAppender.test.ts | 10 +- .../terminal/common/terminalProfiles.ts | 2 +- .../terminal/node/terminalEnvironment.ts | 2 +- .../platform/terminal/node/terminalProcess.ts | 2 +- .../platform/theme/browser/iconsStyleSheet.ts | 4 +- src/vs/platform/theme/common/colorRegistry.ts | 12 +- src/vs/platform/theme/common/iconRegistry.ts | 8 +- src/vs/platform/theme/common/styler.ts | 2 +- src/vs/platform/theme/common/themeService.ts | 4 +- .../common/tokenClassificationRegistry.ts | 14 +- .../theme/test/common/testThemeService.ts | 2 +- src/vs/platform/tunnel/common/tunnel.ts | 6 +- .../undoRedo/common/undoRedoService.ts | 6 +- .../uriIdentity/common/uriIdentityService.ts | 2 +- .../test/common/uriIdentityService.test.ts | 22 +- .../userDataSync/common/extensionsSync.ts | 2 +- .../userDataSync/common/globalStateSync.ts | 4 +- .../userDataSync/common/keybindingsMerge.ts | 2 +- .../userDataSync/common/snippetsSync.ts | 2 +- .../platform/userDataSync/common/tasksSync.ts | 2 +- .../common/userDataSyncService.ts | 2 +- .../test/common/snippetsSync.test.ts | 2 +- .../test/common/userDataSyncService.test.ts | 8 +- .../electron-main/windowsMainService.ts | 4 +- .../workspace/test/common/workspace.test.ts | 10 +- .../platform/workspaces/common/workspaces.ts | 12 +- .../workspacesHistoryMainService.ts | 18 +- .../workspaces/test/common/workspaces.test.ts | 6 +- .../workspacesHistoryStorage.test.ts | 8 +- .../workspacesManagementMainService.test.ts | 4 +- src/vs/server/node/extensionHostConnection.ts | 2 +- .../server/node/remoteAgentEnvironmentImpl.ts | 4 +- .../node/remoteExtensionHostAgentServer.ts | 4 +- src/vs/server/node/remoteLanguagePacks.ts | 4 +- src/vs/server/node/server.cli.ts | 22 +- src/vs/server/node/webClientServer.ts | 2 +- .../api/browser/mainThreadBulkEdits.ts | 2 +- .../api/browser/mainThreadCommands.ts | 4 +- .../api/browser/mainThreadComments.ts | 42 +-- .../api/browser/mainThreadDebugService.ts | 2 +- .../api/browser/mainThreadDecorations.ts | 2 +- .../api/browser/mainThreadDiagnostics.ts | 4 +- .../api/browser/mainThreadDocuments.ts | 2 +- .../api/browser/mainThreadEditorTabs.ts | 2 +- .../api/browser/mainThreadEditors.ts | 6 +- .../api/browser/mainThreadFileSystem.ts | 2 +- .../api/browser/mainThreadLanguageFeatures.ts | 4 +- .../api/browser/mainThreadNotebook.ts | 2 +- .../api/browser/mainThreadNotebookEditors.ts | 2 +- .../api/browser/mainThreadNotebookKernels.ts | 4 +- .../workbench/api/browser/mainThreadTask.ts | 12 +- .../api/browser/mainThreadWorkspace.ts | 2 +- .../api/browser/viewsExtensionPoint.ts | 6 +- .../api/common/configurationExtensionPoint.ts | 12 +- .../workbench/api/common/extHostCommands.ts | 6 +- .../workbench/api/common/extHostComments.ts | 20 +- .../api/common/extHostDecorations.ts | 10 +- .../api/common/extHostDiagnostics.ts | 8 +- .../common/extHostDocumentSaveParticipant.ts | 2 +- .../api/common/extHostExtensionService.ts | 4 +- .../workbench/api/common/extHostFileSystem.ts | 2 +- .../common/extHostFileSystemEventService.ts | 12 +- .../api/common/extHostLanguageFeatures.ts | 4 +- .../workbench/api/common/extHostLanguages.ts | 2 +- src/vs/workbench/api/common/extHostMemento.ts | 2 +- .../api/common/extHostMessageService.ts | 2 +- .../api/common/extHostNotebookDocument.ts | 2 +- .../api/common/extHostRequireInterceptor.ts | 2 +- src/vs/workbench/api/common/extHostTask.ts | 12 +- .../api/common/extHostTypeConverters.ts | 2 +- src/vs/workbench/api/common/extHostTypes.ts | 12 +- .../common/jsonValidationExtensionPoint.ts | 2 +- .../api/node/extHostExtensionService.ts | 4 +- src/vs/workbench/api/node/extHostTask.ts | 4 +- .../api/node/extHostTunnelService.ts | 4 +- .../api/node/extensionHostProcess.ts | 2 +- src/vs/workbench/api/node/proxyResolver.ts | 2 +- .../test/browser/extHostApiCommands.test.ts | 90 ++--- .../browser/extHostAuthentication.test.ts | 4 +- .../api/test/browser/extHostBulkEdits.test.ts | 6 +- .../test/browser/extHostConfiguration.test.ts | 4 +- .../test/browser/extHostDecorations.test.ts | 2 +- .../test/browser/extHostDiagnostics.test.ts | 72 ++-- .../test/browser/extHostDocumentData.test.ts | 20 +- .../extHostDocumentSaveParticipant.test.ts | 52 +-- .../test/browser/extHostEditorTabs.test.ts | 6 +- .../browser/extHostLanguageFeatures.test.ts | 76 ++-- .../browser/extHostMessagerService.test.ts | 2 +- .../api/test/browser/extHostNotebook.test.ts | 12 +- .../browser/extHostNotebookKernel.test.ts | 6 +- .../test/browser/extHostTextEditor.test.ts | 8 +- .../api/test/browser/extHostTreeViews.test.ts | 6 +- .../test/browser/extHostTypeConverter.test.ts | 4 +- .../api/test/browser/extHostTypes.test.ts | 72 ++-- .../api/test/browser/extHostWorkspace.test.ts | 12 +- .../browser/mainThreadConfiguration.test.ts | 2 +- .../browser/mainThreadDiagnostics.test.ts | 6 +- ...mainThreadDocumentContentProviders.test.ts | 6 +- .../test/browser/mainThreadDocuments.test.ts | 4 +- .../mainThreadDocumentsAndEditors.test.ts | 2 +- .../test/browser/mainThreadEditors.test.ts | 14 +- .../api/test/common/testRPCProtocol.ts | 4 +- .../api/test/node/extHostSearch.test.ts | 4 +- .../api/worker/extHostExtensionService.ts | 4 +- src/vs/workbench/browser/labels.ts | 4 +- src/vs/workbench/browser/layout.ts | 4 +- .../parts/activitybar/activitybarActions.ts | 2 +- .../parts/activitybar/activitybarPart.ts | 2 +- .../parts/auxiliarybar/auxiliaryBarActions.ts | 2 +- .../workbench/browser/parts/compositeBar.ts | 2 +- .../browser/parts/editor/breadcrumbs.ts | 4 +- .../parts/editor/breadcrumbsControl.ts | 30 +- .../browser/parts/editor/breadcrumbsModel.ts | 4 +- .../browser/parts/editor/breadcrumbsPicker.ts | 2 +- .../browser/parts/editor/editorPane.ts | 2 +- .../browser/parts/editor/editorStatus.ts | 4 +- .../notifications/notificationsCenter.ts | 4 +- .../notifications/notificationsToasts.ts | 2 +- .../browser/parts/panel/panelActions.ts | 2 +- .../browser/parts/panel/panelPart.ts | 2 +- .../browser/parts/titlebar/menubarControl.ts | 10 +- .../browser/parts/titlebar/windowTitle.ts | 2 +- .../browser/parts/views/viewPaneContainer.ts | 6 +- .../browser/parts/views/viewsViewlet.ts | 2 +- src/vs/workbench/browser/workbench.ts | 2 +- src/vs/workbench/common/actions.ts | 2 +- src/vs/workbench/common/contributions.ts | 4 +- .../common/editor/editorGroupModel.ts | 4 +- .../audioCues/browser/audioCueService.ts | 2 +- .../contrib/audioCues/browser/observable.ts | 2 +- .../contrib/bulkEdit/browser/bulkCellEdits.ts | 2 +- .../bulkEdit/browser/bulkEditService.ts | 12 +- .../contrib/bulkEdit/browser/bulkFileEdits.ts | 2 +- .../contrib/bulkEdit/browser/bulkTextEdits.ts | 8 +- .../contrib/bulkEdit/browser/conflicts.ts | 4 +- .../browser/preview/bulkEdit.contribution.ts | 8 +- .../bulkEdit/browser/preview/bulkEditPane.ts | 4 +- .../browser/preview/bulkEditPreview.ts | 14 +- .../bulkEdit/browser/preview/bulkEditTree.ts | 30 +- .../browser/callHierarchyPeek.ts | 4 +- .../browser/callHierarchyTree.ts | 2 +- .../browser/accessibility/accessibility.ts | 4 +- .../browser/find/simpleFindWidget.ts | 2 +- .../inspectEditorTokens.ts | 42 +-- .../languageConfigurationExtensionPoint.ts | 2 +- .../browser/outline/documentSymbolsOutline.ts | 10 +- .../suggestEnabledInput.ts | 12 +- .../electron-sandbox/selectionClipboard.ts | 8 +- .../test/browser/saveParticipant.test.ts | 8 +- .../comments/browser/commentFormActions.ts | 2 +- .../comments/browser/commentGlyphWidget.ts | 2 +- .../contrib/comments/browser/commentNode.ts | 28 +- .../contrib/comments/browser/commentReply.ts | 10 +- .../comments/browser/commentService.ts | 12 +- .../comments/browser/commentThreadBody.ts | 26 +- .../comments/browser/commentThreadHeader.ts | 2 +- .../browser/commentThreadRangeDecorator.ts | 2 +- .../comments/browser/commentThreadWidget.ts | 2 +- .../browser/commentThreadZoneWidget.ts | 6 +- .../browser/commentsEditorContribution.ts | 46 +-- .../contrib/comments/browser/commentsView.ts | 4 +- .../comments/browser/reactionsAction.ts | 10 +- .../contrib/comments/common/commentModel.ts | 2 +- .../configurationExportHelper.ts | 4 +- .../customEditor/browser/customEditorInput.ts | 2 +- .../debug/test/browser/baseDebugView.test.ts | 2 +- .../contrib/emmet/browser/emmetActions.ts | 6 +- .../emmet/test/browser/emmetAction.test.ts | 2 +- .../abstractRuntimeExtensionsEditor.ts | 16 +- .../extensions/browser/extensionEditor.ts | 8 +- .../browser/extensions.contribution.ts | 2 +- .../extensions/browser/extensionsActions.ts | 4 +- .../extensions/browser/extensionsList.ts | 2 +- .../extensions/browser/extensionsViews.ts | 12 +- .../browser/extensionsWorkbenchService.ts | 4 +- .../browser/fileBasedRecommendations.ts | 2 +- .../extensionsAutoProfiler.ts | 4 +- .../reportExtensionIssueAction.ts | 6 +- .../runtimeExtensionsEditor.ts | 2 +- .../test/common/extensionQuery.test.ts | 2 +- .../extensionRecommendationsService.test.ts | 2 +- .../extensionsWorkbenchService.test.ts | 2 +- .../externalTerminal.contribution.ts | 2 +- .../files/browser/editors/textFileEditor.ts | 2 +- .../contrib/files/browser/explorerService.ts | 2 +- .../contrib/files/browser/explorerViewlet.ts | 4 +- .../contrib/files/browser/fileActions.ts | 24 +- .../workbench/contrib/files/browser/files.ts | 2 +- .../files/browser/views/explorerView.ts | 6 +- .../files/browser/views/openEditorsView.ts | 6 +- .../test/browser/fileEditorInput.test.ts | 4 +- .../format/browser/formatActionsMultiple.ts | 4 +- .../contrib/format/browser/formatModified.ts | 2 +- .../browser/inlayHintsAccessibilty.ts | 4 +- .../browser/interactive.contribution.ts | 2 +- .../browser/languageStatus.contribution.ts | 4 +- .../browser/localHistoryCommands.ts | 2 +- .../electron-sandbox/localeService.ts | 2 +- .../markers/browser/markersFileDecorations.ts | 4 +- .../contrib/markers/browser/markersModel.ts | 6 +- .../contrib/markers/browser/markersTable.ts | 2 +- .../contrib/markers/browser/markersView.ts | 2 +- .../markers/test/browser/markersModel.test.ts | 6 +- .../browser/mergeEditor.contribution.ts | 6 +- .../contrib/mergeEditor/browser/model.ts | 2 +- .../browser/contrib/find/notebookFind.ts | 4 +- .../contrib/find/notebookFindReplaceWidget.ts | 4 +- .../browser/contrib/format/formatting.ts | 2 +- .../notebook/browser/notebookEditorWidget.ts | 4 +- .../browser/view/cellParts/cellOutput.ts | 4 +- .../browser/view/renderers/webviewPreloads.ts | 12 +- .../notebook/test/browser/cellDnd.test.ts | 2 +- .../contrib/outline/browser/outlinePane.ts | 2 +- .../outline/browser/outlineViewState.ts | 2 +- .../contrib/output/browser/outputServices.ts | 2 +- .../contrib/output/browser/outputView.ts | 2 +- .../test/browser/outputLinkProvider.test.ts | 12 +- .../performance/browser/perfviewEditor.ts | 12 +- .../browser/keyboardLayoutPicker.ts | 18 +- .../preferences/browser/settingsEditor2.ts | 2 +- .../preferences/browser/settingsTreeModels.ts | 2 +- .../test/common/smartSnippetInserter.test.ts | 6 +- .../remote/browser/explorerViewItems.ts | 2 +- .../contrib/remote/browser/remote.ts | 14 +- .../contrib/remote/browser/remoteIndicator.ts | 8 +- .../contrib/remote/browser/tunnelView.ts | 2 +- .../contrib/scm/browser/scmViewPane.ts | 4 +- .../workbench/contrib/search/common/search.ts | 2 +- .../snippets/browser/configureSnippets.ts | 4 +- .../browser/snippetCompletionProvider.ts | 4 +- .../contrib/snippets/browser/snippetsFile.ts | 6 +- .../snippets/browser/snippetsService.ts | 10 +- .../snippets/test/browser/snippetFile.test.ts | 8 +- .../test/browser/snippetsRegistry.test.ts | 4 +- .../test/browser/snippetsService.test.ts | 80 ++-- .../electron-sandbox/workspaceTagsService.ts | 8 +- .../tasks/browser/abstractTaskService.ts | 346 +++++++++--------- .../tasks/browser/runAutomaticTasks.ts | 4 +- .../tasks/browser/task.contribution.ts | 6 +- .../contrib/tasks/browser/taskQuickPick.ts | 6 +- .../tasks/browser/terminalTaskSystem.ts | 172 ++++----- .../contrib/tasks/common/jsonSchema_v1.ts | 8 +- .../contrib/tasks/common/jsonSchema_v2.ts | 28 +- .../contrib/tasks/common/problemCollectors.ts | 72 ++-- .../contrib/tasks/common/problemMatcher.ts | 124 +++---- .../contrib/tasks/common/taskConfiguration.ts | 174 ++++----- .../tasks/common/taskDefinitionRegistry.ts | 26 +- .../contrib/tasks/common/taskSystem.ts | 4 +- .../workbench/contrib/tasks/common/tasks.ts | 46 +-- .../tasks/electron-sandbox/taskService.ts | 8 +- .../tasks/test/common/problemMatcher.test.ts | 60 +-- .../test/common/taskConfiguration.test.ts | 278 +++++++------- .../browser/links/terminalLinkManager.ts | 2 +- .../terminal/browser/terminalGroupService.ts | 2 +- .../terminal/browser/terminalInstance.ts | 8 +- .../browser/terminalMainContribution.ts | 2 +- .../terminal/browser/terminalService.ts | 4 +- .../terminal/browser/terminalTabsList.ts | 2 +- .../contrib/terminal/browser/terminalView.ts | 2 +- .../browser/xterm/commandNavigationAddon.ts | 2 +- .../test/browser/terminalConfigHelper.test.ts | 4 +- .../browser/terminalProfileService.test.ts | 10 +- .../testing/browser/testingDecorations.ts | 4 +- .../testing/browser/testingExplorerView.ts | 2 +- .../common/mainThreadTestCollection.ts | 2 +- .../contrib/testing/common/testId.ts | 2 +- .../testing/test/browser/testObjectTree.ts | 2 +- .../themes/browser/themes.contribution.ts | 4 +- .../browser/themes.test.contribution.ts | 78 ++-- .../colorRegistry.releaseTest.ts | 42 +-- .../browser/typeHierarchyPeek.ts | 4 +- .../browser/typeHierarchyTree.ts | 2 +- .../webviewView/browser/webviewViewPane.ts | 2 +- .../browser/walkThroughPart.ts | 2 +- .../parts/titlebar/menubarControl.ts | 8 +- .../actions/common/menusExtensionPoint.ts | 6 +- .../test/common/commandService.test.ts | 28 +- .../browser/configurationService.ts | 4 +- .../common/configurationEditingService.ts | 4 +- .../common/jsonEditingService.ts | 2 +- .../baseConfigurationResolverService.ts | 2 +- .../common/variableResolver.ts | 2 +- .../configurationResolverService.test.ts | 22 +- .../decorations/browser/decorationsService.ts | 16 +- .../test/browser/decorationsService.test.ts | 44 +-- .../dialogs/browser/simpleFileDialog.ts | 6 +- .../editor/browser/editorResolverService.ts | 10 +- .../services/editor/browser/editorService.ts | 2 +- .../editor/common/editorGroupFinder.ts | 4 +- .../test/browser/editorGroupsService.test.ts | 10 +- .../editor/test/browser/editorService.test.ts | 230 ++++++------ .../browser/extensionEnablementService.ts | 8 +- .../browser/webExtensionsScannerService.ts | 2 +- .../common/abstractExtensionService.ts | 18 +- .../common/extensionDescriptionRegistry.ts | 10 +- .../extensions/common/extensionDevOptions.ts | 12 +- .../extensions/common/extensionHostManager.ts | 10 +- .../services/extensions/common/extensions.ts | 2 +- .../extensions/common/extensionsRegistry.ts | 4 +- .../extensions/common/extensionsUtil.ts | 4 +- .../extensions/common/remoteExtensionHost.ts | 4 +- .../services/extensions/common/rpcProtocol.ts | 22 +- .../electron-sandbox/extensionHostProfiler.ts | 26 +- .../localProcessExtensionHost.ts | 4 +- .../test/common/rpcProtocol.test.ts | 22 +- .../history/browser/historyService.ts | 4 +- .../test/browser/historyService.test.ts | 2 +- .../electron-sandbox/integrityService.ts | 2 +- .../keybinding/browser/keybindingService.ts | 2 +- .../browser/keyboardLayoutService.ts | 22 +- .../keybinding/common/keybindingEditing.ts | 2 +- .../keybinding/common/keybindingIO.ts | 6 +- .../services/keybinding/common/keymapInfo.ts | 34 +- .../common/macLinuxKeyboardMapper.ts | 32 +- .../common/windowsKeyboardMapper.ts | 8 +- .../browser/browserKeyboardMapper.test.ts | 10 +- .../test/browser/keybindingEditing.test.ts | 2 +- .../test/browser/keybindingIO.test.ts | 38 +- .../keyboardMapperTestUtils.ts | 10 +- .../macLinuxFallbackKeyboardMapper.test.ts | 4 +- .../macLinuxKeyboardMapper.test.ts | 6 +- .../services/label/test/browser/label.test.ts | 2 +- .../language/common/languageService.ts | 6 +- .../outline/browser/outlineService.ts | 4 +- .../browser/keybindingsEditorModel.test.ts | 2 +- .../progress/browser/progressService.ts | 6 +- .../test/browser/progressIndicator.test.ts | 14 +- .../common/abstractRemoteAgentService.ts | 2 +- .../remote/common/remoteExplorerService.ts | 6 +- .../services/search/common/searchService.ts | 2 +- .../search/test/common/ignoreFile.test.ts | 12 +- .../search/test/common/replace.test.ts | 8 +- .../services/search/worker/localFileSearch.ts | 2 +- .../browser/abstractTextMateService.ts | 20 +- .../textMate/browser/nativeTextMateService.ts | 2 +- .../textMate/common/TMGrammarFactory.ts | 6 +- .../services/textMate/common/TMHelper.ts | 16 +- .../textMate/common/TMTokenization.ts | 8 +- .../textfile/common/textFileEditorModel.ts | 2 +- .../browser/browserTextFileService.io.test.ts | 2 +- .../test/browser/textEditorService.test.ts | 2 +- .../test/browser/textFileEditorModel.test.ts | 6 +- .../textFileEditorModelManager.test.ts | 10 +- .../test/browser/textFileService.test.ts | 6 +- .../test/common/textFileService.io.test.ts | 4 +- .../browser/textModelResolverService.test.ts | 18 +- .../themes/browser/productIconThemeData.ts | 6 +- .../themes/common/colorExtensionPoint.ts | 4 +- .../services/themes/common/colorThemeData.ts | 90 ++--- .../themes/common/colorThemeSchema.ts | 4 +- .../themes/common/fileIconThemeSchema.ts | 2 +- .../themes/common/iconExtensionPoint.ts | 2 +- .../services/themes/common/plistParser.ts | 28 +- .../themes/common/productIconThemeSchema.ts | 2 +- .../themes/common/textMateScopeMatcher.ts | 4 +- .../themes/common/themeCompatibility.ts | 12 +- .../themes/common/themeConfiguration.ts | 8 +- .../themes/common/themeExtensionPoints.ts | 6 +- .../tokenClassificationExtensionPoint.ts | 4 +- .../tokenStyleResolving.test.ts | 4 +- .../services/timer/browser/timerService.ts | 4 +- .../common/untitledTextEditorModel.ts | 2 +- .../test/browser/untitledTextEditor.test.ts | 2 +- .../browser/userDataSyncWorkbenchService.ts | 2 +- .../views/browser/viewDescriptorService.ts | 4 +- .../views/common/viewContainerModel.ts | 4 +- .../browser/viewDescriptorService.test.ts | 4 +- .../common/storedFileWorkingCopy.ts | 2 +- .../test/browser/resourceWorkingCopy.test.ts | 2 +- .../browser/storedFileWorkingCopy.test.ts | 2 +- .../storedFileWorkingCopyManager.test.ts | 4 +- .../browser/untitledFileWorkingCopy.test.ts | 2 +- .../browser/workingCopyBackupTracker.test.ts | 2 +- .../browser/workingCopyEditorService.test.ts | 2 +- .../browser/workingCopyFileService.test.ts | 20 +- .../workingCopyBackupService.test.ts | 18 +- .../workingCopyHistoryService.test.ts | 12 +- .../workbench/test/browser/codeeditor.test.ts | 10 +- src/vs/workbench/test/browser/part.test.ts | 12 +- .../parts/editor/breadcrumbModel.test.ts | 18 +- .../parts/editor/diffEditorInput.test.ts | 4 +- .../parts/editor/editorDiffModel.test.ts | 12 +- .../parts/editor/editorGroupModel.test.ts | 24 +- .../browser/parts/editor/editorInput.test.ts | 4 +- .../browser/parts/editor/editorModel.test.ts | 2 +- .../editor/sideBySideEditorInput.test.ts | 4 +- src/vs/workbench/test/browser/viewlet.test.ts | 6 +- .../test/browser/workbenchTestServices.ts | 8 +- src/vs/workbench/test/common/memento.test.ts | 10 +- .../test/common/notifications.test.ts | 40 +- test/automation/src/problems.ts | 4 +- test/automation/src/terminal.ts | 4 +- test/integration/browser/src/index.ts | 2 +- test/unit/browser/index.js | 6 +- test/unit/coverage.js | 4 +- test/unit/electron/renderer.js | 4 +- test/unit/node/index.js | 4 +- test/unit/reporter.js | 2 +- 862 files changed, 6489 insertions(+), 6489 deletions(-) diff --git a/build/azure-pipelines/common/computeNodeModulesCacheKey.ts b/build/azure-pipelines/common/computeNodeModulesCacheKey.ts index 2eed5fe7adb..2886b28b438 100644 --- a/build/azure-pipelines/common/computeNodeModulesCacheKey.ts +++ b/build/azure-pipelines/common/computeNodeModulesCacheKey.ts @@ -19,7 +19,7 @@ shasum.update(fs.readFileSync(path.join(ROOT, '.yarnrc'))); shasum.update(fs.readFileSync(path.join(ROOT, 'remote/.yarnrc'))); // Add `package.json` and `yarn.lock` files -for (let dir of dirs) { +for (const dir of dirs) { const packageJsonPath = path.join(ROOT, dir, 'package.json'); const packageJson = JSON.parse(fs.readFileSync(packageJsonPath).toString()); const relevantPackageJsonSections = { diff --git a/build/darwin/create-universal-app.ts b/build/darwin/create-universal-app.ts index 7d145eaec71..26542c2774b 100644 --- a/build/darwin/create-universal-app.ts +++ b/build/darwin/create-universal-app.ts @@ -45,7 +45,7 @@ async function main() { force: true }); - let productJson = await fs.readJson(productJsonPath); + const productJson = await fs.readJson(productJsonPath); Object.assign(productJson, { darwinUniversalAssetId: 'darwin-universal' }); diff --git a/build/gulpfile.editor.js b/build/gulpfile.editor.js index 41dbfe647ae..3d8a85fd7f9 100644 --- a/build/gulpfile.editor.js +++ b/build/gulpfile.editor.js @@ -17,14 +17,14 @@ const compilation = require('./lib/compilation'); const monacoapi = require('./lib/monaco-api'); const fs = require('fs'); -let root = path.dirname(__dirname); -let sha1 = util.getVersion(root); -let semver = require('./monaco/package.json').version; -let headerVersion = semver + '(' + sha1 + ')'; +const root = path.dirname(__dirname); +const sha1 = util.getVersion(root); +const semver = require('./monaco/package.json').version; +const headerVersion = semver + '(' + sha1 + ')'; // Build -let editorEntryPoints = [ +const editorEntryPoints = [ { name: 'vs/editor/editor.main', include: [], @@ -40,11 +40,11 @@ let editorEntryPoints = [ } ]; -let editorResources = [ +const editorResources = [ 'out-editor-build/vs/base/browser/ui/codicons/**/*.ttf' ]; -let BUNDLED_FILE_HEADER = [ +const BUNDLED_FILE_HEADER = [ '/*!-----------------------------------------------------------', ' * Copyright (c) Microsoft Corporation. All rights reserved.', ' * Version: ' + headerVersion, @@ -224,7 +224,7 @@ const appendJSToESMImportsTask = task.define('append-js-to-esm-imports', () => { result.push(line); continue; } - let modifiedLine = ( + const modifiedLine = ( line .replace(/^import(.*)\'([^']+)\'/, `import$1'$2.js'`) .replace(/^export \* from \'([^']+)\'/, `export * from '$1.js'`) @@ -239,10 +239,10 @@ const appendJSToESMImportsTask = task.define('append-js-to-esm-imports', () => { * @param {string} contents */ function toExternalDTS(contents) { - let lines = contents.split(/\r\n|\r|\n/); + const lines = contents.split(/\r\n|\r|\n/); let killNextCloseCurlyBrace = false; for (let i = 0; i < lines.length; i++) { - let line = lines[i]; + const line = lines[i]; if (killNextCloseCurlyBrace) { if ('}' === line) { @@ -316,7 +316,7 @@ const finalEditorResourcesTask = task.define('final-editor-resources', () => { // package.json gulp.src('build/monaco/package.json') .pipe(es.through(function (data) { - let json = JSON.parse(data.contents.toString()); + const json = JSON.parse(data.contents.toString()); json.private = false; data.contents = Buffer.from(JSON.stringify(json, null, ' ')); this.emit('data', data); @@ -360,10 +360,10 @@ const finalEditorResourcesTask = task.define('final-editor-resources', () => { return; } - let relativePathToMap = path.relative(path.join(data.relative), path.join('min-maps', data.relative + '.map')); + const relativePathToMap = path.relative(path.join(data.relative), path.join('min-maps', data.relative + '.map')); let strContents = data.contents.toString(); - let newStr = '//# sourceMappingURL=' + relativePathToMap.replace(/\\/g, '/'); + const newStr = '//# sourceMappingURL=' + relativePathToMap.replace(/\\/g, '/'); strContents = strContents.replace(/\/\/# sourceMappingURL=[^ ]+$/, newStr); data.contents = Buffer.from(strContents); @@ -483,13 +483,13 @@ function createTscCompileTask(watch) { cwd: path.join(__dirname, '..'), // stdio: [null, 'pipe', 'inherit'] }); - let errors = []; - let reporter = createReporter('monaco'); + const errors = []; + const reporter = createReporter('monaco'); /** @type {NodeJS.ReadWriteStream | undefined} */ let report; // eslint-disable-next-line no-control-regex - let magic = /[\u001b\u009b][[()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0,4})*)?[0-9A-ORZcf-nqry=><]/g; // https://stackoverflow.com/questions/25245716/remove-all-ansi-colors-styles-from-strings + const magic = /[\u001b\u009b][[()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0,4})*)?[0-9A-ORZcf-nqry=><]/g; // https://stackoverflow.com/questions/25245716/remove-all-ansi-colors-styles-from-strings child.stdout.on('data', data => { let str = String(data); @@ -502,12 +502,12 @@ function createTscCompileTask(watch) { report.end(); } else if (str) { - let match = /(.*\(\d+,\d+\): )(.*: )(.*)/.exec(str); + const match = /(.*\(\d+,\d+\): )(.*: )(.*)/.exec(str); if (match) { // trying to massage the message so that it matches the gulp-tsb error messages // e.g. src/vs/base/common/strings.ts(663,5): error TS2322: Type '1234' is not assignable to type 'string'. - let fullpath = path.join(root, match[1]); - let message = match[3]; + const fullpath = path.join(root, match[1]); + const message = match[3]; reporter(fullpath + message); } else { reporter(str); diff --git a/build/gulpfile.extensions.js b/build/gulpfile.extensions.js index ba2606861fd..c03237951bb 100644 --- a/build/gulpfile.extensions.js +++ b/build/gulpfile.extensions.js @@ -91,7 +91,7 @@ const tasks = compilations.map(function (tsconfigFile) { const baseUrl = getBaseUrl(out); let headerId, headerOut; - let index = relativeDirname.indexOf('/'); + const index = relativeDirname.indexOf('/'); if (index < 0) { headerId = 'vscode.' + relativeDirname; headerOut = 'out'; diff --git a/build/gulpfile.hygiene.js b/build/gulpfile.hygiene.js index a9691fcb0d8..c76fab7abc6 100644 --- a/build/gulpfile.hygiene.js +++ b/build/gulpfile.hygiene.js @@ -16,7 +16,7 @@ function checkPackageJSON(actualPath) { const actual = require(path.join(__dirname, '..', actualPath)); const rootPackageJSON = require('../package.json'); const checkIncluded = (set1, set2) => { - for (let depName in set1) { + for (const depName in set1) { const depVersion = set1[depName]; const rootDepVersion = set2[depName]; if (!rootDepVersion) { diff --git a/build/gulpfile.reh.js b/build/gulpfile.reh.js index 54135e9f50d..2abc3f30c43 100644 --- a/build/gulpfile.reh.js +++ b/build/gulpfile.reh.js @@ -281,7 +281,7 @@ function packageTask(type, platform, arch, sourceFolderName, destinationFolderNa ].map(resource => gulp.src(resource, { base: '.' }).pipe(rename(resource))); } - let all = es.merge( + const all = es.merge( packageJsonStream, productJsonStream, license, diff --git a/build/gulpfile.vscode.js b/build/gulpfile.vscode.js index 268650959cd..3315caf4bff 100644 --- a/build/gulpfile.vscode.js +++ b/build/gulpfile.vscode.js @@ -122,9 +122,9 @@ gulp.task(core); * @return {Object} A map of paths to checksums. */ function computeChecksums(out, filenames) { - let result = {}; + const result = {}; filenames.forEach(function (filename) { - let fullPath = path.join(process.cwd(), out, filename); + const fullPath = path.join(process.cwd(), out, filename); result[filename] = computeChecksum(fullPath); }); return result; @@ -137,9 +137,9 @@ function computeChecksums(out, filenames) { * @return {string} The checksum for `filename`. */ function computeChecksum(filename) { - let contents = fs.readFileSync(filename); + const contents = fs.readFileSync(filename); - let hash = crypto + const hash = crypto .createHash('md5') .update(contents) .digest('base64') @@ -453,20 +453,20 @@ gulp.task(task.define( gulp.task('vscode-translations-pull', function () { return es.merge([...i18n.defaultLanguages, ...i18n.extraLanguages].map(language => { - let includeDefault = !!innoSetupConfig[language.id].defaultInfo; + const includeDefault = !!innoSetupConfig[language.id].defaultInfo; return i18n.pullSetupXlfFiles(apiHostname, apiName, apiToken, language, includeDefault).pipe(vfs.dest(`../vscode-translations-import/${language.id}/setup`)); })); }); gulp.task('vscode-translations-import', function () { - let options = minimist(process.argv.slice(2), { + const options = minimist(process.argv.slice(2), { string: 'location', default: { location: '../vscode-translations-import' } }); return es.merge([...i18n.defaultLanguages, ...i18n.extraLanguages].map(language => { - let id = language.id; + const id = language.id; return gulp.src(`${options.location}/${id}/vscode-setup/messages.xlf`) .pipe(i18n.prepareIslFiles(language, innoSetupConfig[language.id])) .pipe(vfs.dest(`./build/win32/i18n`)); diff --git a/build/gulpfile.vscode.web.js b/build/gulpfile.vscode.web.js index f0ad617f405..4c1259c241c 100644 --- a/build/gulpfile.vscode.web.js +++ b/build/gulpfile.vscode.web.js @@ -208,7 +208,7 @@ function packageTask(sourceFolderName, destinationFolderName) { gulp.src('resources/server/code-512.png', { base: 'resources/server' }) ); - let all = es.merge( + const all = es.merge( packageJsonStream, license, sources, @@ -218,7 +218,7 @@ function packageTask(sourceFolderName, destinationFolderName) { pwaicons ); - let result = all + const result = all .pipe(util.skipDirectories()) .pipe(util.fixWin32DirectoryPermissions()); diff --git a/build/hygiene.js b/build/hygiene.js index 1668e508ec9..e18466c8f77 100644 --- a/build/hygiene.js +++ b/build/hygiene.js @@ -116,8 +116,8 @@ function hygiene(some, linting = true) { }) .then( (result) => { - let original = result.src.replace(/\r\n/gm, '\n'); - let formatted = result.dest.replace(/\r\n/gm, '\n'); + const original = result.src.replace(/\r\n/gm, '\n'); + const formatted = result.dest.replace(/\r\n/gm, '\n'); if (original !== formatted) { console.error( diff --git a/build/lib/asar.ts b/build/lib/asar.ts index 18ab7b01946..16c95f8ca5d 100644 --- a/build/lib/asar.ts +++ b/build/lib/asar.ts @@ -98,7 +98,7 @@ export function createAsar(folderPath: string, unpackGlobs: string[], destFilena } }, function () { - let finish = () => { + const finish = () => { { const headerPickle = pickle.createEmpty(); headerPickle.writeString(JSON.stringify(filesystem.header)); diff --git a/build/lib/builtInExtensions.ts b/build/lib/builtInExtensions.ts index 1abc85b3b09..971847c8756 100644 --- a/build/lib/builtInExtensions.ts +++ b/build/lib/builtInExtensions.ts @@ -143,7 +143,7 @@ export function getBuiltInExtensions(): Promise { const streams: Stream[] = []; for (const extension of [...builtInExtensions, ...webBuiltInExtensions]) { - let controlState = control[extension.name] || 'marketplace'; + const controlState = control[extension.name] || 'marketplace'; control[extension.name] = controlState; streams.push(syncExtension(extension, controlState)); diff --git a/build/lib/compilation.ts b/build/lib/compilation.ts index d40b6139cc0..4ee44f28596 100644 --- a/build/lib/compilation.ts +++ b/build/lib/compilation.ts @@ -26,7 +26,7 @@ const reporter = createReporter(); function getTypeScriptCompilerOptions(src: string): ts.CompilerOptions { const rootDir = path.join(__dirname, `../../${src}`); - let options: ts.CompilerOptions = {}; + const options: ts.CompilerOptions = {}; options.verbose = false; options.sourceMap = true; if (process.env['VSCODE_NO_SOURCEMAP']) { // To be used by developers in a hurry @@ -96,7 +96,7 @@ export function compileTask(src: string, out: string, build: boolean): () => Nod const compile = createCompile(src, build, true); const srcPipe = gulp.src(`${src}/**`, { base: `${src}` }); - let generator = new MonacoGenerator(false); + const generator = new MonacoGenerator(false); if (src === 'src') { generator.execute(); } @@ -116,7 +116,7 @@ export function watchTask(out: string, build: boolean): () => NodeJS.ReadWriteSt const src = gulp.src('src/**', { base: 'src' }); const watchSrc = watch('src/**', { base: 'src', readDelay: 200 }); - let generator = new MonacoGenerator(true); + const generator = new MonacoGenerator(true); generator.execute(); return watchSrc @@ -140,7 +140,7 @@ class MonacoGenerator { this._isWatch = isWatch; this.stream = es.through(); this._watchedFiles = {}; - let onWillReadFile = (moduleId: string, filePath: string) => { + const onWillReadFile = (moduleId: string, filePath: string) => { if (!this._isWatch) { return; } @@ -182,7 +182,7 @@ class MonacoGenerator { } private _run(): monacodts.IMonacoDeclarationResult | null { - let r = monacodts.run3(this._declarationResolver); + const r = monacodts.run3(this._declarationResolver); if (!r && !this._isWatch) { // The build must always be able to generate the monaco.d.ts throw new Error(`monaco.d.ts generation error - Cannot continue`); diff --git a/build/lib/eslint/code-no-unexternalized-strings.ts b/build/lib/eslint/code-no-unexternalized-strings.ts index 056a99868ea..d0c30527f7c 100644 --- a/build/lib/eslint/code-no-unexternalized-strings.ts +++ b/build/lib/eslint/code-no-unexternalized-strings.ts @@ -51,7 +51,7 @@ export = new class NoUnexternalizedStrings implements eslint.Rule.RuleModule { key = keyNode.value; } else if (keyNode.type === AST_NODE_TYPES.ObjectExpression) { - for (let property of keyNode.properties) { + for (const property of keyNode.properties) { if (property.type === AST_NODE_TYPES.Property && !property.computed) { if (property.key.type === AST_NODE_TYPES.Identifier && property.key.name === 'key') { if (isStringLiteral(property.value)) { @@ -97,7 +97,7 @@ export = new class NoUnexternalizedStrings implements eslint.Rule.RuleModule { // (2) // report all invalid NLS keys if (!key.match(NoUnexternalizedStrings._rNlsKeys)) { - for (let value of values) { + for (const value of values) { context.report({ loc: value.call.loc, messageId: 'badKey', data: { key } }); } } diff --git a/build/lib/eslint/vscode-dts-cancellation.ts b/build/lib/eslint/vscode-dts-cancellation.ts index 66f184214b9..6e253a898ca 100644 --- a/build/lib/eslint/vscode-dts-cancellation.ts +++ b/build/lib/eslint/vscode-dts-cancellation.ts @@ -20,7 +20,7 @@ export = new class ApiProviderNaming implements eslint.Rule.RuleModule { ['TSInterfaceDeclaration[id.name=/.+Provider/] TSMethodSignature[key.name=/^(provide|resolve).+/]']: (node: any) => { let found = false; - for (let param of (node).params) { + for (const param of (node).params) { if (param.type === AST_NODE_TYPES.Identifier) { found = found || param.name === 'token'; } diff --git a/build/lib/extensions.ts b/build/lib/extensions.ts index 312b830b903..4aaf668a6c4 100644 --- a/build/lib/extensions.ts +++ b/build/lib/extensions.ts @@ -430,7 +430,7 @@ export function scanBuiltinExtensions(extensionsRoot: string, exclude: string[] if (!fs.existsSync(packageJSONPath)) { continue; } - let packageJSON = JSON.parse(fs.readFileSync(packageJSONPath).toString('utf8')); + const packageJSON = JSON.parse(fs.readFileSync(packageJSONPath).toString('utf8')); if (!isWebExtension(packageJSON)) { continue; } @@ -461,7 +461,7 @@ export function translatePackageJSON(packageJSON: string, packageNLSPath: string const CharCode_PC = '%'.charCodeAt(0); const packageNls: NLSFormat = JSON.parse(fs.readFileSync(packageNLSPath).toString()); const translate = (obj: any) => { - for (let key in obj) { + for (const key in obj) { const val = obj[key]; if (Array.isArray(val)) { val.forEach(translate); diff --git a/build/lib/git.ts b/build/lib/git.ts index dc9c667c21b..35671291fc8 100644 --- a/build/lib/git.ts +++ b/build/lib/git.ts @@ -51,7 +51,7 @@ export function getVersion(repo: string): string | undefined { const refsRegex = /^([0-9a-f]{40})\s+(.+)$/gm; let refsMatch: RegExpExecArray | null; - let refs: { [ref: string]: string } = {}; + const refs: { [ref: string]: string } = {}; while (refsMatch = refsRegex.exec(refsRaw)) { refs[refsMatch[2]] = refsMatch[1]; diff --git a/build/lib/i18n.ts b/build/lib/i18n.ts index 3ea4f7efb4e..c16d31e2d83 100644 --- a/build/lib/i18n.ts +++ b/build/lib/i18n.ts @@ -87,7 +87,7 @@ interface LocalizeInfo { module LocalizeInfo { export function is(value: any): value is LocalizeInfo { - let candidate = value as LocalizeInfo; + const candidate = value as LocalizeInfo; return Is.defined(candidate) && Is.string(candidate.key) && (Is.undef(candidate.comment) || (Is.array(candidate.comment) && candidate.comment.every(element => Is.string(element)))); } } @@ -104,8 +104,8 @@ module BundledFormat { return false; } - let candidate = value as BundledFormat; - let length = Object.keys(value).length; + const candidate = value as BundledFormat; + const length = Object.keys(value).length; return length === 3 && Is.defined(candidate.keys) && Is.defined(candidate.messages) && Is.defined(candidate.bundles); } @@ -126,7 +126,7 @@ module PackageJsonFormat { return false; } return Object.keys(value).every(key => { - let element = value[key]; + const element = value[key]; return Is.string(element) || (Is.object(element) && Is.defined(element.message) && Is.defined(element.comment)); }); } @@ -218,9 +218,9 @@ export class XLF { } this.numberOfMessages += keys.length; this.files[original] = []; - let existingKeys = new Set(); + const existingKeys = new Set(); for (let i = 0; i < keys.length; i++) { - let key = keys[i]; + const key = keys[i]; let realKey: string | undefined; let comment: string | undefined; if (Is.string(key)) { @@ -236,7 +236,7 @@ export class XLF { continue; } existingKeys.add(realKey); - let message: string = encodeEntities(messages[i]); + const message: string = encodeEntities(messages[i]); this.files[original].push({ id: realKey, message: message, comment: comment }); } } @@ -269,15 +269,15 @@ export class XLF { } private appendNewLine(content: string, indent?: number): void { - let line = new Line(indent); + const line = new Line(indent); line.append(content); this.buffer.push(line.toString()); } static parsePseudo = function (xlfString: string): Promise { return new Promise((resolve) => { - let parser = new xml2js.Parser(); - let files: { messages: Map; originalFilePath: string; language: string }[] = []; + const parser = new xml2js.Parser(); + const files: { messages: Map; originalFilePath: string; language: string }[] = []; parser.parseString(xlfString, function (_err: any, result: any) { const fileNodes: any[] = result['xliff']['file']; fileNodes.forEach(file => { @@ -302,9 +302,9 @@ export class XLF { static parse = function (xlfString: string): Promise { return new Promise((resolve, reject) => { - let parser = new xml2js.Parser(); + const parser = new xml2js.Parser(); - let files: { messages: Map; originalFilePath: string; language: string }[] = []; + const files: { messages: Map; originalFilePath: string; language: string }[] = []; parser.parseString(xlfString, function (err: any, result: any) { if (err) { @@ -321,7 +321,7 @@ export class XLF { if (!originalFilePath) { reject(new Error(`XLF parsing error: XLIFF file node does not contain original attribute to determine the original location of the resource file.`)); } - let language = file.$['target-language']; + const language = file.$['target-language']; if (!language) { reject(new Error(`XLF parsing error: XLIFF file node does not contain target-language attribute to determine translated language.`)); } @@ -413,7 +413,7 @@ function stripComments(content: string): string { // Third group matches a multi line comment // Forth group matches a single line comment const regexp = /("[^"\\]*(?:\\.[^"\\]*)*")|('[^'\\]*(?:\\.[^'\\]*)*')|(\/\*[^\/\*]*(?:(?:\*|\/)[^\/\*]*)*?\*\/)|(\/{2,}.*?(?:(?:\r?\n)|$))/g; - let result = content.replace(regexp, (match, _m1: string, _m2: string, m3: string, m4: string) => { + const result = content.replace(regexp, (match, _m1: string, _m2: string, m3: string, m4: string) => { // Only one of m1, m2, m3, m4 matches if (m3) { // A block comment. Replace with nothing @@ -472,22 +472,22 @@ function escapeCharacters(value: string): string { } function processCoreBundleFormat(fileHeader: string, languages: Language[], json: BundledFormat, emitter: ThroughStream) { - let keysSection = json.keys; - let messageSection = json.messages; - let bundleSection = json.bundles; + const keysSection = json.keys; + const messageSection = json.messages; + const bundleSection = json.bundles; - let statistics: Map = Object.create(null); + const statistics: Map = Object.create(null); - let defaultMessages: Map> = Object.create(null); - let modules = Object.keys(keysSection); + const defaultMessages: Map> = Object.create(null); + const modules = Object.keys(keysSection); modules.forEach((module) => { - let keys = keysSection[module]; - let messages = messageSection[module]; + const keys = keysSection[module]; + const messages = messageSection[module]; if (!messages || keys.length !== messages.length) { emitter.emit('error', `Message for module ${module} corrupted. Mismatch in number of keys and messages.`); return; } - let messageMap: Map = Object.create(null); + const messageMap: Map = Object.create(null); defaultMessages[module] = messageMap; keys.map((key, i) => { if (typeof key === 'string') { @@ -498,28 +498,28 @@ function processCoreBundleFormat(fileHeader: string, languages: Language[], json }); }); - let languageDirectory = path.join(__dirname, '..', '..', '..', 'vscode-loc', 'i18n'); + const languageDirectory = path.join(__dirname, '..', '..', '..', 'vscode-loc', 'i18n'); if (!fs.existsSync(languageDirectory)) { log(`No VS Code localization repository found. Looking at ${languageDirectory}`); log(`To bundle translations please check out the vscode-loc repository as a sibling of the vscode repository.`); } - let sortedLanguages = sortLanguages(languages); + const sortedLanguages = sortLanguages(languages); sortedLanguages.forEach((language) => { if (process.env['VSCODE_BUILD_VERBOSE']) { log(`Generating nls bundles for: ${language.id}`); } statistics[language.id] = 0; - let localizedModules: Map = Object.create(null); - let languageFolderName = language.translationId || language.id; - let i18nFile = path.join(languageDirectory, `vscode-language-pack-${languageFolderName}`, 'translations', 'main.i18n.json'); + const localizedModules: Map = Object.create(null); + const languageFolderName = language.translationId || language.id; + const i18nFile = path.join(languageDirectory, `vscode-language-pack-${languageFolderName}`, 'translations', 'main.i18n.json'); let allMessages: I18nFormat | undefined; if (fs.existsSync(i18nFile)) { - let content = stripComments(fs.readFileSync(i18nFile, 'utf8')); + const content = stripComments(fs.readFileSync(i18nFile, 'utf8')); allMessages = JSON.parse(content); } modules.forEach((module) => { - let order = keysSection[module]; + const order = keysSection[module]; let moduleMessage: { [messageKey: string]: string } | undefined; if (allMessages) { moduleMessage = allMessages.contents[module]; @@ -531,7 +531,7 @@ function processCoreBundleFormat(fileHeader: string, languages: Language[], json moduleMessage = defaultMessages[module]; statistics[language.id] = statistics[language.id] + Object.keys(moduleMessage).length; } - let localizedMessages: string[] = []; + const localizedMessages: string[] = []; order.forEach((keyInfo) => { let key: string | null = null; if (typeof keyInfo === 'string') { @@ -552,14 +552,14 @@ function processCoreBundleFormat(fileHeader: string, languages: Language[], json localizedModules[module] = localizedMessages; }); Object.keys(bundleSection).forEach((bundle) => { - let modules = bundleSection[bundle]; - let contents: string[] = [ + const modules = bundleSection[bundle]; + const contents: string[] = [ fileHeader, `define("${bundle}.nls.${language.id}", {` ]; modules.forEach((module, index) => { contents.push(`\t"${module}": [`); - let messages = localizedModules[module]; + const messages = localizedModules[module]; if (!messages) { emitter.emit('error', `Didn't find messages for module ${module}.`); return; @@ -574,11 +574,11 @@ function processCoreBundleFormat(fileHeader: string, languages: Language[], json }); }); Object.keys(statistics).forEach(key => { - let value = statistics[key]; + const value = statistics[key]; log(`${key} has ${value} untranslated strings.`); }); sortedLanguages.forEach(language => { - let stats = statistics[language.id]; + const stats = statistics[language.id]; if (Is.undef(stats)) { log(`\tNo translations found for language ${language.id}. Using default language instead.`); } @@ -587,7 +587,7 @@ function processCoreBundleFormat(fileHeader: string, languages: Language[], json export function processNlsFiles(opts: { fileHeader: string; languages: Language[] }): ThroughStream { return through(function (this: ThroughStream, file: File) { - let fileName = path.basename(file.path); + const fileName = path.basename(file.path); if (fileName === 'nls.metadata.json') { let json = null; if (file.isBuffer()) { @@ -643,7 +643,7 @@ export function createXlfFilesForCoreBundle(): ThroughStream { if (file.isBuffer()) { const xlfs: Map = Object.create(null); const json: BundledFormat = JSON.parse((file.contents as Buffer).toString('utf8')); - for (let coreModule in json.keys) { + for (const coreModule in json.keys) { const projectResource = getResource(coreModule); const resource = projectResource.name; const project = projectResource.project; @@ -662,7 +662,7 @@ export function createXlfFilesForCoreBundle(): ThroughStream { xlf.addFile(`src/${coreModule}`, keys, messages); } } - for (let resource in xlfs) { + for (const resource in xlfs) { const xlf = xlfs[resource]; const filePath = `${xlf.project}/${resource.replace(/\//g, '_')}.xlf`; const xlfFile = new File({ @@ -692,7 +692,7 @@ export function createXlfFilesForExtensions(): ThroughStream { if (!stat.isDirectory()) { return; } - let extensionName = path.basename(extensionFolder.path); + const extensionName = path.basename(extensionFolder.path); if (extensionName === 'node_modules') { return; } @@ -725,7 +725,7 @@ export function createXlfFilesForExtensions(): ThroughStream { } else if (basename === 'nls.metadata.json') { const json: BundledExtensionFormat = JSON.parse(buffer.toString('utf8')); const relPath = path.relative(`.build/extensions/${extensionName}`, path.dirname(file.path)); - for (let file in json) { + for (const file in json) { const fileContent = json[file]; getXlf().addFile(`extensions/${extensionName}/${relPath}/${file}`, fileContent.keys, fileContent.messages); } @@ -736,7 +736,7 @@ export function createXlfFilesForExtensions(): ThroughStream { } }, function () { if (_xlf) { - let xlfFile = new File({ + const xlfFile = new File({ path: path.join(extensionsProject, extensionName + '.xlf'), contents: Buffer.from(_xlf.toString(), 'utf8') }); @@ -769,17 +769,17 @@ export function createXlfFilesForIsl(): ThroughStream { throw new Error(`Unknown input file ${file.path}`); } - let xlf = new XLF(projectName), + const xlf = new XLF(projectName), keys: string[] = [], messages: string[] = []; - let model = new TextModel(file.contents.toString()); + const model = new TextModel(file.contents.toString()); let inMessageSection = false; model.lines.forEach(line => { if (line.length === 0) { return; } - let firstChar = line.charAt(0); + const firstChar = line.charAt(0); switch (firstChar) { case ';': // Comment line; @@ -791,12 +791,12 @@ export function createXlfFilesForIsl(): ThroughStream { if (!inMessageSection) { return; } - let sections: string[] = line.split('='); + const sections: string[] = line.split('='); if (sections.length !== 2) { throw new Error(`Badly formatted message found: ${line}`); } else { - let key = sections[0]; - let value = sections[1]; + const key = sections[0]; + const value = sections[1]; if (key.length > 0 && value.length > 0) { keys.push(key); messages.push(value); @@ -815,8 +815,8 @@ export function createXlfFilesForIsl(): ThroughStream { } export function pushXlfFiles(apiHostname: string, username: string, password: string): ThroughStream { - let tryGetPromises: Array> = []; - let updateCreatePromises: Array> = []; + const tryGetPromises: Array> = []; + const updateCreatePromises: Array> = []; return through(function (this: ThroughStream, file: File) { const project = path.dirname(file.relative); @@ -857,11 +857,11 @@ function getAllResources(project: string, apiHostname: string, username: string, }; const request = https.request(options, (res) => { - let buffer: Buffer[] = []; + const buffer: Buffer[] = []; res.on('data', (chunk: Buffer) => buffer.push(chunk)); res.on('end', () => { if (res.statusCode === 200) { - let json = JSON.parse(Buffer.concat(buffer).toString()); + const json = JSON.parse(Buffer.concat(buffer).toString()); if (Array.isArray(json)) { resolve(json.map(o => o.slug)); return; @@ -880,7 +880,7 @@ function getAllResources(project: string, apiHostname: string, username: string, } export function findObsoleteResources(apiHostname: string, username: string, password: string): ThroughStream { - let resourcesByProject: Map = Object.create(null); + const resourcesByProject: Map = Object.create(null); resourcesByProject[extensionsProject] = ([] as any[]).concat(externalExtensionsWithTranslations); // clone return through(function (this: ThroughStream, file: File) { @@ -897,10 +897,10 @@ export function findObsoleteResources(apiHostname: string, username: string, pas }, function () { const json = JSON.parse(fs.readFileSync('./build/lib/i18n.resources.json', 'utf8')); - let i18Resources = [...json.editor, ...json.workbench].map((r: Resource) => r.project + '/' + r.name.replace(/\//g, '_')); - let extractedResources: string[] = []; - for (let project of [workbenchProject, editorProject]) { - for (let resource of resourcesByProject[project]) { + const i18Resources = [...json.editor, ...json.workbench].map((r: Resource) => r.project + '/' + r.name.replace(/\//g, '_')); + const extractedResources: string[] = []; + for (const project of [workbenchProject, editorProject]) { + for (const resource of resourcesByProject[project]) { if (resource !== 'setup_messages') { extractedResources.push(project + '/' + resource); } @@ -911,12 +911,12 @@ export function findObsoleteResources(apiHostname: string, username: string, pas console.log(`[i18n] Missing resources in file 'build/lib/i18n.resources.json': JSON.stringify(${extractedResources.filter(p => i18Resources.indexOf(p) === -1)})`); } - let promises: Array> = []; - for (let project in resourcesByProject) { + const promises: Array> = []; + for (const project in resourcesByProject) { promises.push( getAllResources(project, apiHostname, username, password).then(resources => { - let expectedResources = resourcesByProject[project]; - let unusedResources = resources.filter(resource => resource && expectedResources.indexOf(resource) === -1); + const expectedResources = resourcesByProject[project]; + const unusedResources = resources.filter(resource => resource && expectedResources.indexOf(resource) === -1); if (unusedResources.length) { console.log(`[transifex] Obsolete resources in project '${project}': ${unusedResources.join(', ')}`); } @@ -974,7 +974,7 @@ function createResource(project: string, slug: string, xlfFile: File, apiHostnam method: 'POST' }; - let request = https.request(options, (res) => { + const request = https.request(options, (res) => { if (res.statusCode === 201) { log(`Resource ${project}/${slug} successfully created on Transifex.`); } else { @@ -1008,7 +1008,7 @@ function updateResource(project: string, slug: string, xlfFile: File, apiHostnam method: 'PUT' }; - let request = https.request(options, (res) => { + const request = https.request(options, (res) => { if (res.statusCode === 200) { res.setEncoding('utf8'); @@ -1035,7 +1035,7 @@ function updateResource(project: string, slug: string, xlfFile: File, apiHostnam } export function pullSetupXlfFiles(apiHostname: string, username: string, password: string, language: Language, includeDefault: boolean): NodeJS.ReadableStream { - let setupResources = [{ name: 'setup_messages', project: workbenchProject }]; + const setupResources = [{ name: 'setup_messages', project: workbenchProject }]; if (includeDefault) { setupResources.push({ name: 'setup_default', project: setupProject }); } @@ -1044,7 +1044,7 @@ export function pullSetupXlfFiles(apiHostname: string, username: string, passwor function pullXlfFiles(apiHostname: string, username: string, password: string, language: Language, resources: Resource[]): NodeJS.ReadableStream { const credentials = `${username}:${password}`; - let expectedTranslationsCount = resources.length; + const expectedTranslationsCount = resources.length; let translationsRetrieved = 0, called = false; return readable(function (_count: any, callback: any) { @@ -1075,7 +1075,7 @@ function retrieveResource(language: Language, resource: Resource, apiHostname: s return limiter.queue(() => new Promise((resolve, reject) => { const slug = resource.name.replace(/\//g, '_'); const project = resource.project; - let transifexLanguageId = language.id === 'ps' ? 'en' : language.translationId || language.id; + const transifexLanguageId = language.id === 'ps' ? 'en' : language.translationId || language.id; const options = { hostname: apiHostname, path: `/api/2/project/${project}/resource/${slug}/translation/${transifexLanguageId}?file&mode=onlyreviewed`, @@ -1085,8 +1085,8 @@ function retrieveResource(language: Language, resource: Resource, apiHostname: s }; console.log('[transifex] Fetching ' + options.path); - let request = https.request(options, (res) => { - let xlfBuffer: Buffer[] = []; + const request = https.request(options, (res) => { + const xlfBuffer: Buffer[] = []; res.on('data', (chunk: Buffer) => xlfBuffer.push(chunk)); res.on('end', () => { if (res.statusCode === 200) { @@ -1107,16 +1107,16 @@ function retrieveResource(language: Language, resource: Resource, apiHostname: s } export function prepareI18nFiles(): ThroughStream { - let parsePromises: Promise[] = []; + const parsePromises: Promise[] = []; return through(function (this: ThroughStream, xlf: File) { - let stream = this; - let parsePromise = XLF.parse(xlf.contents.toString()); + const stream = this; + const parsePromise = XLF.parse(xlf.contents.toString()); parsePromises.push(parsePromise); parsePromise.then( resolvedFiles => { resolvedFiles.forEach(file => { - let translatedFile = createI18nFile(file.originalFilePath, file.messages); + const translatedFile = createI18nFile(file.originalFilePath, file.messages); stream.queue(translatedFile); }); } @@ -1129,7 +1129,7 @@ export function prepareI18nFiles(): ThroughStream { } function createI18nFile(originalFilePath: string, messages: any): File { - let result = Object.create(null); + const result = Object.create(null); result[''] = [ '--------------------------------------------------------------------------------------------', 'Copyright (c) Microsoft Corporation. All rights reserved.', @@ -1137,7 +1137,7 @@ function createI18nFile(originalFilePath: string, messages: any): File { '--------------------------------------------------------------------------------------------', 'Do not edit this file. It is machine generated.' ]; - for (let key of Object.keys(messages)) { + for (const key of Object.keys(messages)) { result[key] = messages[key]; } @@ -1166,16 +1166,16 @@ export interface TranslationPath { } export function prepareI18nPackFiles(externalExtensions: Map, resultingTranslationPaths: TranslationPath[], pseudo = false): NodeJS.ReadWriteStream { - let parsePromises: Promise[] = []; - let mainPack: I18nPack = { version: i18nPackVersion, contents: {} }; - let extensionsPacks: Map = {}; - let errors: any[] = []; + const parsePromises: Promise[] = []; + const mainPack: I18nPack = { version: i18nPackVersion, contents: {} }; + const extensionsPacks: Map = {}; + const errors: any[] = []; return through(function (this: ThroughStream, xlf: File) { - let project = path.basename(path.dirname(path.dirname(xlf.relative))); - let resource = path.basename(xlf.relative, '.xlf'); - let contents = xlf.contents.toString(); + const project = path.basename(path.dirname(path.dirname(xlf.relative))); + const resource = path.basename(xlf.relative, '.xlf'); + const contents = xlf.contents.toString(); log(`Found ${project}: ${resource}`); - let parsePromise = pseudo ? XLF.parsePseudo(contents) : XLF.parse(contents); + const parsePromise = pseudo ? XLF.parsePseudo(contents) : XLF.parse(contents); parsePromises.push(parsePromise); parsePromise.then( resolvedFiles => { @@ -1213,7 +1213,7 @@ export function prepareI18nPackFiles(externalExtensions: Map, resultingT resultingTranslationPaths.push({ id: 'vscode', resourceName: 'main.i18n.json' }); this.queue(translatedMainFile); - for (let extension in extensionsPacks) { + for (const extension in extensionsPacks) { const translatedExtFile = createI18nFile(`extensions/${extension}`, extensionsPacks[extension]); this.queue(translatedExtFile); @@ -1234,16 +1234,16 @@ export function prepareI18nPackFiles(externalExtensions: Map, resultingT } export function prepareIslFiles(language: Language, innoSetupConfig: InnoSetup): ThroughStream { - let parsePromises: Promise[] = []; + const parsePromises: Promise[] = []; return through(function (this: ThroughStream, xlf: File) { - let stream = this; - let parsePromise = XLF.parse(xlf.contents.toString()); + const stream = this; + const parsePromise = XLF.parse(xlf.contents.toString()); parsePromises.push(parsePromise); parsePromise.then( resolvedFiles => { resolvedFiles.forEach(file => { - let translatedFile = createIslFile(file.originalFilePath, file.messages, language, innoSetupConfig); + const translatedFile = createIslFile(file.originalFilePath, file.messages, language, innoSetupConfig); stream.queue(translatedFile); }); } @@ -1260,7 +1260,7 @@ export function prepareIslFiles(language: Language, innoSetupConfig: InnoSetup): } function createIslFile(originalFilePath: string, messages: Map, language: Language, innoSetup: InnoSetup): File { - let content: string[] = []; + const content: string[] = []; let originalContent: TextModel; if (path.basename(originalFilePath) === 'Default') { originalContent = new TextModel(fs.readFileSync(originalFilePath + '.isl', 'utf8')); @@ -1269,15 +1269,15 @@ function createIslFile(originalFilePath: string, messages: Map, language } originalContent.lines.forEach(line => { if (line.length > 0) { - let firstChar = line.charAt(0); + const firstChar = line.charAt(0); if (firstChar === '[' || firstChar === ';') { content.push(line); } else { - let sections: string[] = line.split('='); - let key = sections[0]; + const sections: string[] = line.split('='); + const key = sections[0]; let translated = line; if (key) { - let translatedMessage = messages[key]; + const translatedMessage = messages[key]; if (translatedMessage) { translated = `${key}=${translatedMessage}`; } @@ -1299,9 +1299,9 @@ function createIslFile(originalFilePath: string, messages: Map, language } function encodeEntities(value: string): string { - let result: string[] = []; + const result: string[] = []; for (let i = 0; i < value.length; i++) { - let ch = value[i]; + const ch = value[i]; switch (ch) { case '<': result.push('<'); diff --git a/build/lib/monaco-api.ts b/build/lib/monaco-api.ts index e6a06d21ea2..cadd0a03715 100644 --- a/build/lib/monaco-api.ts +++ b/build/lib/monaco-api.ts @@ -40,7 +40,7 @@ function isDeclaration(ts: typeof import('typescript'), a: TSTopLevelDeclare): a function visitTopLevelDeclarations(ts: typeof import('typescript'), sourceFile: ts.SourceFile, visitor: (node: TSTopLevelDeclare) => boolean): void { let stop = false; - let visit = (node: ts.Node): void => { + const visit = (node: ts.Node): void => { if (stop) { return; } @@ -67,19 +67,19 @@ function visitTopLevelDeclarations(ts: typeof import('typescript'), sourceFile: function getAllTopLevelDeclarations(ts: typeof import('typescript'), sourceFile: ts.SourceFile): TSTopLevelDeclare[] { - let all: TSTopLevelDeclare[] = []; + const all: TSTopLevelDeclare[] = []; visitTopLevelDeclarations(ts, sourceFile, (node) => { if (node.kind === ts.SyntaxKind.InterfaceDeclaration || node.kind === ts.SyntaxKind.ClassDeclaration || node.kind === ts.SyntaxKind.ModuleDeclaration) { - let interfaceDeclaration = node; - let triviaStart = interfaceDeclaration.pos; - let triviaEnd = interfaceDeclaration.name.pos; - let triviaText = getNodeText(sourceFile, { pos: triviaStart, end: triviaEnd }); + const interfaceDeclaration = node; + const triviaStart = interfaceDeclaration.pos; + const triviaEnd = interfaceDeclaration.name.pos; + const triviaText = getNodeText(sourceFile, { pos: triviaStart, end: triviaEnd }); if (triviaText.indexOf('@internal') === -1) { all.push(node); } } else { - let nodeText = getNodeText(sourceFile, node); + const nodeText = getNodeText(sourceFile, node); if (nodeText.indexOf('@internal') === -1) { all.push(node); } @@ -118,7 +118,7 @@ function getNodeText(sourceFile: ts.SourceFile, node: { pos: number; end: number function hasModifier(modifiers: ts.NodeArray | undefined, kind: ts.SyntaxKind): boolean { if (modifiers) { for (let i = 0; i < modifiers.length; i++) { - let mod = modifiers[i]; + const mod = modifiers[i]; if (mod.kind === kind) { return true; } @@ -141,7 +141,7 @@ function isDefaultExport(ts: typeof import('typescript'), declaration: ts.Interf function getMassagedTopLevelDeclarationText(ts: typeof import('typescript'), sourceFile: ts.SourceFile, declaration: TSTopLevelDeclare, importName: string, usage: string[], enums: IEnumEntry[]): string { let result = getNodeText(sourceFile, declaration); if (declaration.kind === ts.SyntaxKind.InterfaceDeclaration || declaration.kind === ts.SyntaxKind.ClassDeclaration) { - let interfaceDeclaration = declaration; + const interfaceDeclaration = declaration; const staticTypeName = ( isDefaultExport(ts, interfaceDeclaration) @@ -152,7 +152,7 @@ function getMassagedTopLevelDeclarationText(ts: typeof import('typescript'), sou let instanceTypeName = staticTypeName; const typeParametersCnt = (interfaceDeclaration.typeParameters ? interfaceDeclaration.typeParameters.length : 0); if (typeParametersCnt > 0) { - let arr: string[] = []; + const arr: string[] = []; for (let i = 0; i < typeParametersCnt; i++) { arr.push('any'); } @@ -162,7 +162,7 @@ function getMassagedTopLevelDeclarationText(ts: typeof import('typescript'), sou const members: ts.NodeArray = interfaceDeclaration.members; members.forEach((member) => { try { - let memberText = getNodeText(sourceFile, member); + const memberText = getNodeText(sourceFile, member); if (memberText.indexOf('@internal') >= 0 || memberText.indexOf('private') >= 0) { result = result.replace(memberText, ''); } else { @@ -182,7 +182,7 @@ function getMassagedTopLevelDeclarationText(ts: typeof import('typescript'), sou result = result.replace(/export default /g, 'export '); result = result.replace(/export declare /g, 'export '); result = result.replace(/declare /g, ''); - let lines = result.split(/\r\n|\r|\n/); + const lines = result.split(/\r\n|\r|\n/); for (let i = 0; i < lines.length; i++) { if (/\s*\*/.test(lines[i])) { // very likely a comment @@ -212,10 +212,10 @@ function format(ts: typeof import('typescript'), text: string, endl: string): st } // Parse the source text - let sourceFile = ts.createSourceFile('file.ts', text, ts.ScriptTarget.Latest, /*setParentPointers*/ true); + const sourceFile = ts.createSourceFile('file.ts', text, ts.ScriptTarget.Latest, /*setParentPointers*/ true); // Get the formatting edits on the input sources - let edits = (ts).formatting.formatDocument(sourceFile, getRuleProvider(tsfmt), tsfmt); + const edits = (ts).formatting.formatDocument(sourceFile, getRuleProvider(tsfmt), tsfmt); // Apply the edits on the input code return applyEdits(text, edits); @@ -242,7 +242,7 @@ function format(ts: typeof import('typescript'), text: string, endl: string): st } function preformat(text: string, endl: string): string { - let lines = text.split(endl); + const lines = text.split(endl); let inComment = false; let inCommentDeltaIndent = 0; let indent = 0; @@ -328,9 +328,9 @@ function format(ts: typeof import('typescript'), text: string, endl: string): st // Apply edits in reverse on the existing text let result = text; for (let i = edits.length - 1; i >= 0; i--) { - let change = edits[i]; - let head = result.slice(0, change.span.start); - let tail = result.slice(change.span.start + change.span.length); + const change = edits[i]; + const head = result.slice(0, change.span.start); + const tail = result.slice(change.span.start + change.span.length); result = head + change.newText + tail; } return result; @@ -348,15 +348,15 @@ function createReplacerFromDirectives(directives: [RegExp, string][]): (str: str function createReplacer(data: string): (str: string) => string { data = data || ''; - let rawDirectives = data.split(';'); - let directives: [RegExp, string][] = []; + const rawDirectives = data.split(';'); + const directives: [RegExp, string][] = []; rawDirectives.forEach((rawDirective) => { if (rawDirective.length === 0) { return; } - let pieces = rawDirective.split('=>'); + const pieces = rawDirective.split('=>'); let findStr = pieces[0]; - let replaceStr = pieces[1]; + const replaceStr = pieces[1]; findStr = findStr.replace(/[\-\\\{\}\*\+\?\|\^\$\.\,\[\]\(\)\#\s]/g, '\\$&'); findStr = '\\b' + findStr + '\\b'; @@ -380,12 +380,12 @@ interface IEnumEntry { function generateDeclarationFile(ts: typeof import('typescript'), recipe: string, sourceFileGetter: SourceFileGetter): ITempResult | null { const endl = /\r\n/.test(recipe) ? '\r\n' : '\n'; - let lines = recipe.split(endl); - let result: string[] = []; + const lines = recipe.split(endl); + const result: string[] = []; let usageCounter = 0; - let usageImports: string[] = []; - let usage: string[] = []; + const usageImports: string[] = []; + const usage: string[] = []; let failed = false; @@ -393,12 +393,12 @@ function generateDeclarationFile(ts: typeof import('typescript'), recipe: string usage.push(`var b: any;`); const generateUsageImport = (moduleId: string) => { - let importName = 'm' + (++usageCounter); + const importName = 'm' + (++usageCounter); usageImports.push(`import * as ${importName} from './${moduleId.replace(/\.d\.ts$/, '')}';`); return importName; }; - let enums: IEnumEntry[] = []; + const enums: IEnumEntry[] = []; let version: string | null = null; lines.forEach(line => { @@ -407,14 +407,14 @@ function generateDeclarationFile(ts: typeof import('typescript'), recipe: string return; } - let m0 = line.match(/^\/\/dtsv=(\d+)$/); + const m0 = line.match(/^\/\/dtsv=(\d+)$/); if (m0) { version = m0[1]; } - let m1 = line.match(/^\s*#include\(([^;)]*)(;[^)]*)?\)\:(.*)$/); + const m1 = line.match(/^\s*#include\(([^;)]*)(;[^)]*)?\)\:(.*)$/); if (m1) { - let moduleId = m1[1]; + const moduleId = m1[1]; const sourceFile = sourceFileGetter(moduleId); if (!sourceFile) { logErr(`While handling ${line}`); @@ -425,15 +425,15 @@ function generateDeclarationFile(ts: typeof import('typescript'), recipe: string const importName = generateUsageImport(moduleId); - let replacer = createReplacer(m1[2]); + const replacer = createReplacer(m1[2]); - let typeNames = m1[3].split(/,/); + const typeNames = m1[3].split(/,/); typeNames.forEach((typeName) => { typeName = typeName.trim(); if (typeName.length === 0) { return; } - let declaration = getTopLevelDeclaration(ts, sourceFile, typeName); + const declaration = getTopLevelDeclaration(ts, sourceFile, typeName); if (!declaration) { logErr(`While handling ${line}`); logErr(`Cannot find ${typeName}`); @@ -445,9 +445,9 @@ function generateDeclarationFile(ts: typeof import('typescript'), recipe: string return; } - let m2 = line.match(/^\s*#includeAll\(([^;)]*)(;[^)]*)?\)\:(.*)$/); + const m2 = line.match(/^\s*#includeAll\(([^;)]*)(;[^)]*)?\)\:(.*)$/); if (m2) { - let moduleId = m2[1]; + const moduleId = m2[1]; const sourceFile = sourceFileGetter(moduleId); if (!sourceFile) { logErr(`While handling ${line}`); @@ -458,11 +458,11 @@ function generateDeclarationFile(ts: typeof import('typescript'), recipe: string const importName = generateUsageImport(moduleId); - let replacer = createReplacer(m2[2]); + const replacer = createReplacer(m2[2]); - let typeNames = m2[3].split(/,/); - let typesToExcludeMap: { [typeName: string]: boolean } = {}; - let typesToExcludeArr: string[] = []; + const typeNames = m2[3].split(/,/); + const typesToExcludeMap: { [typeName: string]: boolean } = {}; + const typesToExcludeArr: string[] = []; typeNames.forEach((typeName) => { typeName = typeName.trim(); if (typeName.length === 0) { @@ -479,7 +479,7 @@ function generateDeclarationFile(ts: typeof import('typescript'), recipe: string } } else { // node is ts.VariableStatement - let nodeText = getNodeText(sourceFile, declaration); + const nodeText = getNodeText(sourceFile, declaration); for (let i = 0; i < typesToExcludeArr.length; i++) { if (nodeText.indexOf(typesToExcludeArr[i]) >= 0) { return; @@ -732,7 +732,7 @@ class TypeScriptLanguageServiceHost implements ts.LanguageServiceHost { } export function execute(): IMonacoDeclarationResult { - let r = run3(new DeclarationResolver(new FSProvider())); + const r = run3(new DeclarationResolver(new FSProvider())); if (!r) { throw new Error(`monaco.d.ts generation error - Cannot continue`); } diff --git a/build/lib/standalone.ts b/build/lib/standalone.ts index 3483de02a39..992d1ab5288 100644 --- a/build/lib/standalone.ts +++ b/build/lib/standalone.ts @@ -10,7 +10,7 @@ import * as tss from './treeshaking'; const REPO_ROOT = path.join(__dirname, '../../'); const SRC_DIR = path.join(REPO_ROOT, 'src'); -let dirCache: { [dir: string]: boolean } = {}; +const dirCache: { [dir: string]: boolean } = {}; function writeFile(filePath: string, contents: Buffer | string): void { function ensureDirs(dirPath: string): void { @@ -63,13 +63,13 @@ export function extractEditor(options: tss.ITreeShakingOptions & { destRoot: str }); } - let result = tss.shake(options); - for (let fileName in result) { + const result = tss.shake(options); + for (const fileName in result) { if (result.hasOwnProperty(fileName)) { writeFile(path.join(options.destRoot, fileName), result[fileName]); } } - let copied: { [fileName: string]: boolean } = {}; + const copied: { [fileName: string]: boolean } = {}; const copyFile = (fileName: string) => { if (copied[fileName]) { return; @@ -82,7 +82,7 @@ export function extractEditor(options: tss.ITreeShakingOptions & { destRoot: str const writeOutputFile = (fileName: string, contents: string | Buffer) => { writeFile(path.join(options.destRoot, fileName), contents); }; - for (let fileName in result) { + for (const fileName in result) { if (result.hasOwnProperty(fileName)) { const fileContents = result[fileName]; const info = ts.preProcessFile(fileContents); @@ -142,7 +142,7 @@ export function createESMSourcesAndResources2(options: IOptions2): void { const OUT_RESOURCES_FOLDER = path.join(REPO_ROOT, options.outResourcesFolder); const getDestAbsoluteFilePath = (file: string): string => { - let dest = options.renames[file.replace(/\\/g, '/')] || file; + const dest = options.renames[file.replace(/\\/g, '/')] || file; if (dest === 'tsconfig.json') { return path.join(OUT_FOLDER, `tsconfig.json`); } @@ -229,7 +229,7 @@ export function createESMSourcesAndResources2(options: IOptions2): void { if (dir.charAt(dir.length - 1) !== '/' || dir.charAt(dir.length - 1) !== '\\') { dir += '/'; } - let result: string[] = []; + const result: string[] = []; _walkDirRecursive(dir, result, dir.length); return result; } @@ -253,7 +253,7 @@ export function createESMSourcesAndResources2(options: IOptions2): void { writeFile(absoluteFilePath, contents); function toggleComments(fileContents: string): string { - let lines = fileContents.split(/\r\n|\r|\n/); + const lines = fileContents.split(/\r\n|\r|\n/); let mode = 0; for (let i = 0; i < lines.length; i++) { const line = lines[i]; @@ -325,14 +325,14 @@ function transportCSS(module: string, enqueue: (module: string) => void, write: if (!forceBase64 && /\.svg$/.test(url)) { // .svg => url encode as explained at https://codepen.io/tigt/post/optimizing-svgs-in-data-uris - let newText = fileContents.toString() + const newText = fileContents.toString() .replace(/"/g, '\'') .replace(//g, '%3E') .replace(/&/g, '%26') .replace(/#/g, '%23') .replace(/\s+/g, ' '); - let encodedData = ',' + newText; + const encodedData = ',' + newText; if (encodedData.length < DATA.length) { DATA = encodedData; } diff --git a/build/lib/treeshaking.ts b/build/lib/treeshaking.ts index 113340285a8..c13f4609b8c 100644 --- a/build/lib/treeshaking.ts +++ b/build/lib/treeshaking.ts @@ -73,7 +73,7 @@ function printDiagnostics(options: ITreeShakingOptions, diagnostics: ReadonlyArr result += `${path.join(options.sourcesRoot, diag.file.fileName)}`; } if (diag.file && diag.start) { - let location = diag.file.getLineAndCharacterOfPosition(diag.start); + const location = diag.file.getLineAndCharacterOfPosition(diag.start); result += `:${location.line + 1}:${location.character}`; } result += ` - ` + JSON.stringify(diag.messageText); @@ -216,7 +216,7 @@ function processLibFiles(ts: typeof import('typescript'), options: ITreeShakingO // precess dependencies and "recurse" const info = ts.preProcessFile(sourceText); - for (let ref of info.libReferenceDirectives) { + for (const ref of info.libReferenceDirectives) { stack.push(ref.fileName); } } @@ -629,7 +629,7 @@ function markNodes(ts: typeof import('typescript'), languageService: ts.Language // queue the heritage clauses if (declaration.heritageClauses) { - for (let heritageClause of declaration.heritageClauses) { + for (const heritageClause of declaration.heritageClauses) { enqueue_black(heritageClause); } } @@ -682,7 +682,7 @@ function generateResult(ts: typeof import('typescript'), languageService: ts.Lan throw new Error('Could not get program from language service'); } - let result: ITreeShakingResult = {}; + const result: ITreeShakingResult = {}; const writeFile = (filePath: string, contents: string): void => { result[filePath] = contents; }; @@ -700,7 +700,7 @@ function generateResult(ts: typeof import('typescript'), languageService: ts.Lan return; } - let text = sourceFile.text; + const text = sourceFile.text; let result = ''; function keep(node: ts.Node): void { @@ -734,7 +734,7 @@ function generateResult(ts: typeof import('typescript'), languageService: ts.Lan return keep(node); } } else { - let survivingImports: string[] = []; + const survivingImports: string[] = []; for (const importNode of node.importClause.namedBindings.elements) { if (getColor(importNode) === NodeColor.Black) { survivingImports.push(importNode.getFullText(sourceFile)); @@ -762,7 +762,7 @@ function generateResult(ts: typeof import('typescript'), languageService: ts.Lan if (ts.isExportDeclaration(node)) { if (node.exportClause && node.moduleSpecifier && ts.isNamedExports(node.exportClause)) { - let survivingExports: string[] = []; + const survivingExports: string[] = []; for (const exportSpecifier of node.exportClause.elements) { if (getColor(exportSpecifier) === NodeColor.Black) { survivingExports.push(exportSpecifier.getFullText(sourceFile)); @@ -785,8 +785,8 @@ function generateResult(ts: typeof import('typescript'), languageService: ts.Lan continue; } - let pos = member.pos - node.pos; - let end = member.end - node.pos; + const pos = member.pos - node.pos; + const end = member.end - node.pos; toWrite = toWrite.substring(0, pos) + toWrite.substring(end); } return write(toWrite); diff --git a/build/lib/tsb/builder.ts b/build/lib/tsb/builder.ts index d5bec6ee97b..c2fab0fcc93 100644 --- a/build/lib/tsb/builder.ts +++ b/build/lib/tsb/builder.ts @@ -117,8 +117,8 @@ export function createTypeScriptBuilder(config: IConfiguration, projectFile: str if (/\.d\.ts$/.test(fileName)) { // if it's already a d.ts file just emit it signature - let snapshot = host.getScriptSnapshot(fileName); - let signature = crypto.createHash('md5') + const snapshot = host.getScriptSnapshot(fileName); + const signature = crypto.createHash('md5') .update(snapshot.getText(0, snapshot.getLength())) .digest('base64'); @@ -129,11 +129,11 @@ export function createTypeScriptBuilder(config: IConfiguration, projectFile: str }); } - let output = service.getEmitOutput(fileName); - let files: Vinyl[] = []; + const output = service.getEmitOutput(fileName); + const files: Vinyl[] = []; let signature: string | undefined; - for (let file of output.outputFiles) { + for (const file of output.outputFiles) { if (!emitSourceMapsInStream && /\.js\.map$/.test(file.name)) { continue; } @@ -149,22 +149,22 @@ export function createTypeScriptBuilder(config: IConfiguration, projectFile: str } } - let vinyl = new Vinyl({ + const vinyl = new Vinyl({ path: file.name, contents: Buffer.from(file.text), base: !config._emitWithoutBasePath && baseFor(host.getScriptSnapshot(fileName)) || undefined }); if (!emitSourceMapsInStream && /\.js$/.test(file.name)) { - let sourcemapFile = output.outputFiles.filter(f => /\.js\.map$/.test(f.name))[0]; + const sourcemapFile = output.outputFiles.filter(f => /\.js\.map$/.test(f.name))[0]; if (sourcemapFile) { - let extname = path.extname(vinyl.relative); - let basename = path.basename(vinyl.relative, extname); - let dirname = path.dirname(vinyl.relative); - let tsname = (dirname === '.' ? '' : dirname + '/') + basename + '.ts'; + const extname = path.extname(vinyl.relative); + const basename = path.basename(vinyl.relative, extname); + const dirname = path.dirname(vinyl.relative); + const tsname = (dirname === '.' ? '' : dirname + '/') + basename + '.ts'; - let sourceMap = JSON.parse(sourcemapFile.text); + const sourceMap = JSON.parse(sourcemapFile.text); sourceMap.sources[0] = tsname.replace(/\\/g, '/'); (vinyl).sourceMap = sourceMap; } @@ -182,17 +182,17 @@ export function createTypeScriptBuilder(config: IConfiguration, projectFile: str }); } - let newErrors: { [path: string]: ts.Diagnostic[] } = Object.create(null); - let t1 = Date.now(); + const newErrors: { [path: string]: ts.Diagnostic[] } = Object.create(null); + const t1 = Date.now(); - let toBeEmitted: string[] = []; - let toBeCheckedSyntactically: string[] = []; - let toBeCheckedSemantically: string[] = []; - let filesWithChangedSignature: string[] = []; - let dependentFiles: string[] = []; - let newLastBuildVersion = new Map(); + const toBeEmitted: string[] = []; + const toBeCheckedSyntactically: string[] = []; + const toBeCheckedSemantically: string[] = []; + const filesWithChangedSignature: string[] = []; + const dependentFiles: string[] = []; + const newLastBuildVersion = new Map(); - for (let fileName of host.getScriptFileNames()) { + for (const fileName of host.getScriptFileNames()) { if (lastBuildVersion[fileName] !== host.getScriptVersion(fileName)) { toBeEmitted.push(fileName); @@ -203,8 +203,8 @@ export function createTypeScriptBuilder(config: IConfiguration, projectFile: str return new Promise(resolve => { - let semanticCheckInfo = new Map(); - let seenAsDependentFile = new Set(); + const semanticCheckInfo = new Map(); + const seenAsDependentFile = new Set(); function workOnNext() { @@ -221,10 +221,10 @@ export function createTypeScriptBuilder(config: IConfiguration, projectFile: str // (1st) emit code else if (toBeEmitted.length) { - let fileName = toBeEmitted.pop()!; + const fileName = toBeEmitted.pop()!; promise = emitSoon(fileName).then(value => { - for (let file of value.files) { + for (const file of value.files) { _log('[emit code]', file.path); out(file); } @@ -246,7 +246,7 @@ export function createTypeScriptBuilder(config: IConfiguration, projectFile: str // (2nd) check syntax else if (toBeCheckedSyntactically.length) { - let fileName = toBeCheckedSyntactically.pop()!; + const fileName = toBeCheckedSyntactically.pop()!; _log('[check syntax]', fileName); promise = checkSyntaxSoon(fileName).then(diagnostics => { delete oldErrors[fileName]; @@ -286,7 +286,7 @@ export function createTypeScriptBuilder(config: IConfiguration, projectFile: str // (4th) check dependents else if (filesWithChangedSignature.length) { while (filesWithChangedSignature.length) { - let fileName = filesWithChangedSignature.pop()!; + const fileName = filesWithChangedSignature.pop()!; if (!isExternalModule(service.getProgram()!.getSourceFile(fileName)!)) { _log('[check semantics*]', fileName + ' is an internal module and it has changed shape -> check whatever hasn\'t been checked yet'); @@ -308,7 +308,7 @@ export function createTypeScriptBuilder(config: IConfiguration, projectFile: str } if (fileName) { seenAsDependentFile.add(fileName); - let value = semanticCheckInfo.get(fileName); + const value = semanticCheckInfo.get(fileName); if (value === 0) { // already validated successfully -> look at dependents next host.collectDependents(fileName, dependentFiles); @@ -507,7 +507,7 @@ class LanguageServiceHost implements ts.LanguageServiceHost { } if (!old || old.getVersion() !== snapshot.getVersion()) { this._dependenciesRecomputeList.push(filename); - let node = this._dependencies.lookup(filename); + const node = this._dependencies.lookup(filename); if (node) { node.outgoing = Object.create(null); } @@ -605,7 +605,7 @@ class LanguageServiceHost implements ts.LanguageServiceHost { } if (!found) { - for (let key in this._fileNameToDeclaredModule) { + for (const key in this._fileNameToDeclaredModule) { if (this._fileNameToDeclaredModule[key] && ~this._fileNameToDeclaredModule[key].indexOf(ref.fileName)) { this._dependencies.inertEdge(filename, key); } diff --git a/build/lib/tsb/index.ts b/build/lib/tsb/index.ts index 6e8e3d6fb77..ab0c5bbb42e 100644 --- a/build/lib/tsb/index.ts +++ b/build/lib/tsb/index.ts @@ -89,7 +89,7 @@ export function create( const result = (token: builder.CancellationToken) => createStream(token); result.src = (opts?: { cwd?: string; base?: string }) => { let _pos = 0; - let _fileNames = cmdLine.fileNames.slice(0); + const _fileNames = cmdLine.fileNames.slice(0); return new class extends Readable { constructor() { super({ objectMode: true }); diff --git a/build/lib/tsb/utils.ts b/build/lib/tsb/utils.ts index 295d873b63a..3b003e3a6e1 100644 --- a/build/lib/tsb/utils.ts +++ b/build/lib/tsb/utils.ts @@ -28,7 +28,7 @@ export module collections { } export function forEach(collection: { [keys: string]: T }, callback: (entry: { key: string; value: T }) => void): void { - for (let key in collection) { + for (const key in collection) { if (hasOwnProperty.call(collection, key)) { callback({ key: key, diff --git a/build/lib/util.ts b/build/lib/util.ts index e1cb4e70be0..abbf9adc927 100644 --- a/build/lib/util.ts +++ b/build/lib/util.ts @@ -306,7 +306,7 @@ function _rreaddir(dirPath: string, prepend: string, result: string[]): void { } export function rreddir(dirPath: string): string[] { - let result: string[] = []; + const result: string[] = []; _rreaddir(dirPath, '', result); return result; } @@ -423,7 +423,7 @@ export function createExternalLoaderConfig(webEndpoint?: string, commit?: string return undefined; } webEndpoint = webEndpoint + `/${quality}/${commit}`; - let nodePaths = acquireWebNodePaths(); + const nodePaths = acquireWebNodePaths(); Object.keys(nodePaths).map(function (key, _) { nodePaths[key] = `${webEndpoint}/node_modules/${key}/${nodePaths[key]}`; }); diff --git a/extensions/css-language-features/client/src/cssClient.ts b/extensions/css-language-features/client/src/cssClient.ts index 6f6238465d8..ba234ecb2d3 100644 --- a/extensions/css-language-features/client/src/cssClient.ts +++ b/extensions/css-language-features/client/src/cssClient.ts @@ -43,14 +43,14 @@ export async function startClient(context: ExtensionContext, newLanguageClient: const customDataSource = getCustomDataSource(context.subscriptions); - let documentSelector = ['css', 'scss', 'less']; + const documentSelector = ['css', 'scss', 'less']; const formatterRegistrations: FormatterRegistration[] = documentSelector.map(languageId => ({ languageId, settingId: `${languageId}.format.enable`, provider: undefined })); // Options to control the language client - let clientOptions: LanguageClientOptions = { + const clientOptions: LanguageClientOptions = { documentSelector, synchronize: { configurationSection: ['css', 'scss', 'less'] @@ -98,7 +98,7 @@ export async function startClient(context: ExtensionContext, newLanguageClient: }; // Create the language client and start the client. - let client = newLanguageClient('css', localize('cssserver.name', 'CSS Language Server'), clientOptions); + const client = newLanguageClient('css', localize('cssserver.name', 'CSS Language Server'), clientOptions); client.registerProposedFeatures(); await client.start(); @@ -125,17 +125,17 @@ export async function startClient(context: ExtensionContext, newLanguageClient: return languages.registerCompletionItemProvider(documentSelector, { provideCompletionItems(doc: TextDocument, pos: Position) { - let lineUntilPos = doc.getText(new Range(new Position(pos.line, 0), pos)); - let match = lineUntilPos.match(regionCompletionRegExpr); + const lineUntilPos = doc.getText(new Range(new Position(pos.line, 0), pos)); + const match = lineUntilPos.match(regionCompletionRegExpr); if (match) { - let range = new Range(new Position(pos.line, match[1].length), pos); - let beginProposal = new CompletionItem('#region', CompletionItemKind.Snippet); + const range = new Range(new Position(pos.line, match[1].length), pos); + const beginProposal = new CompletionItem('#region', CompletionItemKind.Snippet); beginProposal.range = range; TextEdit.replace(range, '/* #region */'); beginProposal.insertText = new SnippetString('/* #region $1*/'); beginProposal.documentation = localize('folding.start', 'Folding Region Start'); beginProposal.filterText = match[2]; beginProposal.sortText = 'za'; - let endProposal = new CompletionItem('#endregion', CompletionItemKind.Snippet); + const endProposal = new CompletionItem('#endregion', CompletionItemKind.Snippet); endProposal.range = range; endProposal.insertText = '/* #endregion */'; endProposal.documentation = localize('folding.end', 'Folding Region End'); @@ -151,13 +151,13 @@ export async function startClient(context: ExtensionContext, newLanguageClient: commands.registerCommand('_css.applyCodeAction', applyCodeAction); function applyCodeAction(uri: string, documentVersion: number, edits: TextEdit[]) { - let textEditor = window.activeTextEditor; + const textEditor = window.activeTextEditor; if (textEditor && textEditor.document.uri.toString() === uri) { if (textEditor.document.version !== documentVersion) { window.showInformationMessage(`CSS fix is outdated and can't be applied to the document.`); } textEditor.edit(mutator => { - for (let edit of edits) { + for (const edit of edits) { mutator.replace(client.protocol2CodeConverter.asRange(edit.range), edit.newText); } }).then(success => { diff --git a/extensions/css-language-features/server/src/languageModelCache.ts b/extensions/css-language-features/server/src/languageModelCache.ts index 343d57a9ad6..f39eada6f44 100644 --- a/extensions/css-language-features/server/src/languageModelCache.ts +++ b/extensions/css-language-features/server/src/languageModelCache.ts @@ -18,10 +18,10 @@ export function getLanguageModelCache(maxEntries: number, cleanupIntervalTime let cleanupInterval: NodeJS.Timer | undefined = undefined; if (cleanupIntervalTimeInSec > 0) { cleanupInterval = setInterval(() => { - let cutoffTime = Date.now() - cleanupIntervalTimeInSec * 1000; - let uris = Object.keys(languageModels); - for (let uri of uris) { - let languageModelInfo = languageModels[uri]; + const cutoffTime = Date.now() - cleanupIntervalTimeInSec * 1000; + const uris = Object.keys(languageModels); + for (const uri of uris) { + const languageModelInfo = languageModels[uri]; if (languageModelInfo.cTime < cutoffTime) { delete languageModels[uri]; nModels--; @@ -32,14 +32,14 @@ export function getLanguageModelCache(maxEntries: number, cleanupIntervalTime return { get(document: TextDocument): T { - let version = document.version; - let languageId = document.languageId; - let languageModelInfo = languageModels[document.uri]; + const version = document.version; + const languageId = document.languageId; + const languageModelInfo = languageModels[document.uri]; if (languageModelInfo && languageModelInfo.version === version && languageModelInfo.languageId === languageId) { languageModelInfo.cTime = Date.now(); return languageModelInfo.languageModel; } - let languageModel = parse(document); + const languageModel = parse(document); languageModels[document.uri] = { languageModel, version, languageId, cTime: Date.now() }; if (!languageModelInfo) { nModels++; @@ -48,8 +48,8 @@ export function getLanguageModelCache(maxEntries: number, cleanupIntervalTime if (nModels === maxEntries) { let oldestTime = Number.MAX_VALUE; let oldestUri = null; - for (let uri in languageModels) { - let languageModelInfo = languageModels[uri]; + for (const uri in languageModels) { + const languageModelInfo = languageModels[uri]; if (languageModelInfo.cTime < oldestTime) { oldestUri = uri; oldestTime = languageModelInfo.cTime; @@ -64,7 +64,7 @@ export function getLanguageModelCache(maxEntries: number, cleanupIntervalTime }, onDocumentRemoved(document: TextDocument) { - let uri = document.uri; + const uri = document.uri; if (languageModels[uri]) { delete languageModels[uri]; nModels--; diff --git a/extensions/css-language-features/server/src/requests.ts b/extensions/css-language-features/server/src/requests.ts index 0726af35c56..3d21e542362 100644 --- a/extensions/css-language-features/server/src/requests.ts +++ b/extensions/css-language-features/server/src/requests.ts @@ -65,7 +65,7 @@ export interface RequestService { export function getRequestService(handledSchemas: string[], connection: Connection, runtime: RuntimeEnvironment): RequestService { const builtInHandlers: { [protocol: string]: RequestService | undefined } = {}; - for (let protocol of handledSchemas) { + for (const protocol of handledSchemas) { if (protocol === 'file') { builtInHandlers[protocol] = runtime.file; } else if (protocol === 'http' || protocol === 'https') { diff --git a/extensions/css-language-features/server/src/test/completion.test.ts b/extensions/css-language-features/server/src/test/completion.test.ts index 6881dd0e3e3..23570c7e1e5 100644 --- a/extensions/css-language-features/server/src/test/completion.test.ts +++ b/extensions/css-language-features/server/src/test/completion.test.ts @@ -19,13 +19,13 @@ export interface ItemDescription { suite('Completions', () => { - let assertCompletion = function (completions: CompletionList, expected: ItemDescription, document: TextDocument, _offset: number) { - let matches = completions.items.filter(completion => { + const assertCompletion = function (completions: CompletionList, expected: ItemDescription, document: TextDocument, _offset: number) { + const matches = completions.items.filter(completion => { return completion.label === expected.label; }); assert.strictEqual(matches.length, 1, `${expected.label} should only existing once: Actual: ${completions.items.map(c => c.label).join(', ')}`); - let match = matches[0]; + const match = matches[0]; if (expected.resultText && TextEdit.is(match.textEdit)) { assert.strictEqual(TextDocument.applyEdits(document, [match.textEdit]), expected.resultText); } @@ -47,21 +47,21 @@ suite('Completions', () => { const context = getDocumentContext(testUri, workspaceFolders); const stylesheet = cssLanguageService.parseStylesheet(document); - let list = await cssLanguageService.doComplete2(document, position, stylesheet, context); + const list = await cssLanguageService.doComplete2(document, position, stylesheet, context); if (expected.count) { assert.strictEqual(list.items.length, expected.count); } if (expected.items) { - for (let item of expected.items) { + for (const item of expected.items) { assertCompletion(list, item, document, offset); } } } test('CSS url() Path completion', async function () { - let testUri = URI.file(path.resolve(__dirname, '../../test/pathCompletionFixtures/about/about.css')).toString(); - let folders = [{ name: 'x', uri: URI.file(path.resolve(__dirname, '../../test')).toString() }]; + const testUri = URI.file(path.resolve(__dirname, '../../test/pathCompletionFixtures/about/about.css')).toString(); + const folders = [{ name: 'x', uri: URI.file(path.resolve(__dirname, '../../test')).toString() }]; await assertCompletions('html { background-image: url("./|")', { items: [ @@ -119,8 +119,8 @@ suite('Completions', () => { }); test('CSS url() Path Completion - Unquoted url', async function () { - let testUri = URI.file(path.resolve(__dirname, '../../test/pathCompletionFixtures/about/about.css')).toString(); - let folders = [{ name: 'x', uri: URI.file(path.resolve(__dirname, '../../test')).toString() }]; + const testUri = URI.file(path.resolve(__dirname, '../../test/pathCompletionFixtures/about/about.css')).toString(); + const folders = [{ name: 'x', uri: URI.file(path.resolve(__dirname, '../../test')).toString() }]; await assertCompletions('html { background-image: url(./|)', { items: [ @@ -148,8 +148,8 @@ suite('Completions', () => { }); test('CSS @import Path completion', async function () { - let testUri = URI.file(path.resolve(__dirname, '../../test/pathCompletionFixtures/about/about.css')).toString(); - let folders = [{ name: 'x', uri: URI.file(path.resolve(__dirname, '../../test')).toString() }]; + const testUri = URI.file(path.resolve(__dirname, '../../test/pathCompletionFixtures/about/about.css')).toString(); + const folders = [{ name: 'x', uri: URI.file(path.resolve(__dirname, '../../test')).toString() }]; await assertCompletions(`@import './|'`, { items: [ @@ -171,8 +171,8 @@ suite('Completions', () => { * For SCSS, `@import 'foo';` can be used for importing partial file `_foo.scss` */ test('SCSS @import Path completion', async function () { - let testCSSUri = URI.file(path.resolve(__dirname, '../../test/pathCompletionFixtures/about/about.css')).toString(); - let folders = [{ name: 'x', uri: URI.file(path.resolve(__dirname, '../../test')).toString() }]; + const testCSSUri = URI.file(path.resolve(__dirname, '../../test/pathCompletionFixtures/about/about.css')).toString(); + const folders = [{ name: 'x', uri: URI.file(path.resolve(__dirname, '../../test')).toString() }]; /** * We are in a CSS file, so no special treatment for SCSS partial files @@ -184,7 +184,7 @@ suite('Completions', () => { ] }, testCSSUri, folders); - let testSCSSUri = URI.file(path.resolve(__dirname, '../../test/pathCompletionFixtures/scss/main.scss')).toString(); + const testSCSSUri = URI.file(path.resolve(__dirname, '../../test/pathCompletionFixtures/scss/main.scss')).toString(); await assertCompletions(`@import './|'`, { items: [ { label: '_foo.scss', resultText: `@import './foo'` } @@ -193,8 +193,8 @@ suite('Completions', () => { }); test('Completion should ignore files/folders starting with dot', async function () { - let testUri = URI.file(path.resolve(__dirname, '../../test/pathCompletionFixtures/about/about.css')).toString(); - let folders = [{ name: 'x', uri: URI.file(path.resolve(__dirname, '../../test')).toString() }]; + const testUri = URI.file(path.resolve(__dirname, '../../test/pathCompletionFixtures/about/about.css')).toString(); + const folders = [{ name: 'x', uri: URI.file(path.resolve(__dirname, '../../test')).toString() }]; await assertCompletions('html { background-image: url("../|")', { count: 4 diff --git a/extensions/css-language-features/server/src/test/links.test.ts b/extensions/css-language-features/server/src/test/links.test.ts index bc4c6db6477..c19f67e5e4b 100644 --- a/extensions/css-language-features/server/src/test/links.test.ts +++ b/extensions/css-language-features/server/src/test/links.test.ts @@ -21,13 +21,13 @@ export interface ItemDescription { suite('Links', () => { const cssLanguageService = getCSSLanguageService({ fileSystemProvider: getNodeFSRequestService() }); - let assertLink = function (links: DocumentLink[], expected: ItemDescription, document: TextDocument) { - let matches = links.filter(link => { + const assertLink = function (links: DocumentLink[], expected: ItemDescription, document: TextDocument) { + const matches = links.filter(link => { return document.offsetAt(link.range.start) === expected.offset; }); assert.strictEqual(matches.length, 1, `${expected.offset} should only existing once: Actual: ${links.map(l => document.offsetAt(l.range.start)).join(', ')}`); - let match = matches[0]; + const match = matches[0]; assert.strictEqual(document.getText(match.range), expected.value); assert.strictEqual(match.target, expected.target); }; @@ -45,11 +45,11 @@ suite('Links', () => { const context = getDocumentContext(testUri, workspaceFolders); const stylesheet = cssLanguageService.parseStylesheet(document); - let links = await cssLanguageService.findDocumentLinks2(document, stylesheet, context)!; + const links = await cssLanguageService.findDocumentLinks2(document, stylesheet, context)!; assert.strictEqual(links.length, expected.length); - for (let item of expected) { + for (const item of expected) { assertLink(links, item, document); } } @@ -60,8 +60,8 @@ suite('Links', () => { test('url links', async function () { - let testUri = getTestResource('about.css'); - let folders = [{ name: 'x', uri: getTestResource('') }]; + const testUri = getTestResource('about.css'); + const folders = [{ name: 'x', uri: getTestResource('') }]; await assertLinks('html { background-image: url("hello.html|")', [{ offset: 29, value: '"hello.html"', target: getTestResource('hello.html') }], testUri, folders @@ -70,8 +70,8 @@ suite('Links', () => { test('node module resolving', async function () { - let testUri = getTestResource('about.css'); - let folders = [{ name: 'x', uri: getTestResource('') }]; + const testUri = getTestResource('about.css'); + const folders = [{ name: 'x', uri: getTestResource('') }]; await assertLinks('html { background-image: url("~foo/hello.html|")', [{ offset: 29, value: '"~foo/hello.html"', target: getTestResource('node_modules/foo/hello.html') }], testUri, folders @@ -80,8 +80,8 @@ suite('Links', () => { test('node module subfolder resolving', async function () { - let testUri = getTestResource('subdir/about.css'); - let folders = [{ name: 'x', uri: getTestResource('') }]; + const testUri = getTestResource('subdir/about.css'); + const folders = [{ name: 'x', uri: getTestResource('') }]; await assertLinks('html { background-image: url("~foo/hello.html|")', [{ offset: 29, value: '"~foo/hello.html"', target: getTestResource('node_modules/foo/hello.html') }], testUri, folders diff --git a/extensions/css-language-features/server/src/utils/documentContext.ts b/extensions/css-language-features/server/src/utils/documentContext.ts index a7beffd0310..0570ac92375 100644 --- a/extensions/css-language-features/server/src/utils/documentContext.ts +++ b/extensions/css-language-features/server/src/utils/documentContext.ts @@ -10,7 +10,7 @@ import { Utils, URI } from 'vscode-uri'; export function getDocumentContext(documentUri: string, workspaceFolders: WorkspaceFolder[]): DocumentContext { function getRootFolder(): string | undefined { - for (let folder of workspaceFolders) { + for (const folder of workspaceFolders) { let folderURI = folder.uri; if (!endsWith(folderURI, '/')) { folderURI = folderURI + '/'; @@ -25,7 +25,7 @@ export function getDocumentContext(documentUri: string, workspaceFolders: Worksp return { resolveReference: (ref: string, base = documentUri) => { if (ref[0] === '/') { // resolve absolute path against the current workspace folder - let folderUri = getRootFolder(); + const folderUri = getRootFolder(); if (folderUri) { return folderUri + ref.substr(1); } diff --git a/extensions/css-language-features/server/src/utils/runner.ts b/extensions/css-language-features/server/src/utils/runner.ts index 47c587537aa..383b88e4487 100644 --- a/extensions/css-language-features/server/src/utils/runner.ts +++ b/extensions/css-language-features/server/src/utils/runner.ts @@ -8,7 +8,7 @@ import { RuntimeEnvironment } from '../cssServer'; export function formatError(message: string, err: any): string { if (err instanceof Error) { - let error = err; + const error = err; return `${message}: ${error.message}\n${error.stack}`; } else if (typeof err === 'string') { return `${message}: ${err}`; diff --git a/extensions/css-language-features/server/src/utils/strings.ts b/extensions/css-language-features/server/src/utils/strings.ts index 0e9ed34f83d..1e53c4204fd 100644 --- a/extensions/css-language-features/server/src/utils/strings.ts +++ b/extensions/css-language-features/server/src/utils/strings.ts @@ -21,7 +21,7 @@ export function startsWith(haystack: string, needle: string): boolean { * Determines if haystack ends with needle. */ export function endsWith(haystack: string, needle: string): boolean { - let diff = haystack.length - needle.length; + const diff = haystack.length - needle.length; if (diff > 0) { return haystack.lastIndexOf(needle) === diff; } else if (diff === 0) { diff --git a/extensions/debug-auto-launch/src/extension.ts b/extensions/debug-auto-launch/src/extension.ts index a4a48f5c380..572c468d843 100644 --- a/extensions/debug-auto-launch/src/extension.ts +++ b/extensions/debug-auto-launch/src/extension.ts @@ -243,7 +243,7 @@ const createServerInner = async (ipcAddress: string) => { const createServerInstance = (ipcAddress: string) => new Promise((resolve, reject) => { const s = createServer(socket => { - let data: Buffer[] = []; + const data: Buffer[] = []; socket.on('data', async chunk => { if (chunk[chunk.length - 1] !== 0) { // terminated with NUL byte @@ -392,7 +392,7 @@ async function getIpcAddress(context: vscode.ExtensionContext) { } function getJsDebugSettingKey() { - let o: { [key: string]: unknown } = {}; + const o: { [key: string]: unknown } = {}; const config = vscode.workspace.getConfiguration(SETTING_SECTION); for (const setting of SETTINGS_CAUSE_REFRESH) { o[setting] = config.get(setting); diff --git a/extensions/debug-server-ready/src/extension.ts b/extensions/debug-server-ready/src/extension.ts index d112651fd09..a3214e1207b 100644 --- a/extensions/debug-server-ready/src/extension.ts +++ b/extensions/debug-server-ready/src/extension.ts @@ -57,7 +57,7 @@ class ServerReadyDetector extends vscode.Disposable { } static stop(session: vscode.DebugSession): void { - let detector = ServerReadyDetector.detectors.get(session); + const detector = ServerReadyDetector.detectors.get(session); if (detector) { ServerReadyDetector.detectors.delete(session); detector.dispose(); @@ -65,7 +65,7 @@ class ServerReadyDetector extends vscode.Disposable { } static rememberShellPid(session: vscode.DebugSession, pid: number) { - let detector = ServerReadyDetector.detectors.get(session); + const detector = ServerReadyDetector.detectors.get(session); if (detector) { detector.shellPid = pid; } @@ -77,7 +77,7 @@ class ServerReadyDetector extends vscode.Disposable { // first find the detector with a matching pid const pid = await e.terminal.processId; - for (let [, detector] of this.detectors) { + for (const [, detector] of this.detectors) { if (detector.shellPid === pid) { detector.detectPattern(e.data); return; @@ -85,7 +85,7 @@ class ServerReadyDetector extends vscode.Disposable { } // if none found, try all detectors until one matches - for (let [, detector] of this.detectors) { + for (const [, detector] of this.detectors) { if (detector.detectPattern(e.data)) { return; } diff --git a/extensions/emmet/src/defaultCompletionProvider.ts b/extensions/emmet/src/defaultCompletionProvider.ts index 1462a2ec4d7..c8a6f657d75 100644 --- a/extensions/emmet/src/defaultCompletionProvider.ts +++ b/extensions/emmet/src/defaultCompletionProvider.ts @@ -49,7 +49,7 @@ export class DefaultCompletionItemProvider implements vscode.CompletionItemProvi const mappedLanguages = getMappingForIncludedLanguages(); const isSyntaxMapped = mappedLanguages[document.languageId] ? true : false; - let emmetMode = getEmmetMode((isSyntaxMapped ? mappedLanguages[document.languageId] : document.languageId), mappedLanguages, excludedLanguages); + const emmetMode = getEmmetMode((isSyntaxMapped ? mappedLanguages[document.languageId] : document.languageId), mappedLanguages, excludedLanguages); if (!emmetMode || emmetConfig['showExpandedAbbreviation'] === 'never' @@ -135,7 +135,7 @@ export class DefaultCompletionItemProvider implements vscode.CompletionItemProvi const offset = document.offsetAt(position); if (isStyleSheet(document.languageId) && context.triggerKind !== vscode.CompletionTriggerKind.TriggerForIncompleteCompletions) { validateLocation = true; - let usePartialParsing = vscode.workspace.getConfiguration('emmet')['optimizeStylesheetParsing'] === true; + const usePartialParsing = vscode.workspace.getConfiguration('emmet')['optimizeStylesheetParsing'] === true; rootNode = usePartialParsing && document.lineCount > 1000 ? parsePartialStylesheet(document, position) : getRootNode(document, true); if (!rootNode) { return; @@ -152,8 +152,8 @@ export class DefaultCompletionItemProvider implements vscode.CompletionItemProvi if (!rootNode) { return; } - let flatNode = getFlatNode(rootNode, offset, true); - let embeddedCssNode = getEmbeddedCssNodeIfAny(document, flatNode, position); + const flatNode = getFlatNode(rootNode, offset, true); + const embeddedCssNode = getEmbeddedCssNodeIfAny(document, flatNode, position); currentNode = getFlatNode(embeddedCssNode, offset, true); } @@ -167,7 +167,7 @@ export class DefaultCompletionItemProvider implements vscode.CompletionItemProvi // Check for document symbols in js/ts/jsx/tsx and avoid triggering emmet for abbreviations of the form symbolName.sometext // Presence of > or * or + in the abbreviation denotes valid abbreviation that should trigger emmet if (!isStyleSheet(syntax) && (document.languageId === 'javascript' || document.languageId === 'javascriptreact' || document.languageId === 'typescript' || document.languageId === 'typescriptreact')) { - let abbreviation: string = extractAbbreviationResults.abbreviation; + const abbreviation: string = extractAbbreviationResults.abbreviation; // For the second condition, we don't want abbreviations that have [] characters but not ='s in them to expand // In turn, users must explicitly expand abbreviations of the form Component[attr1 attr2], but it means we don't try to expand a[i]. if (abbreviation.startsWith('this.') || /\[[^\]=]*\]/.test(abbreviation)) { @@ -194,14 +194,14 @@ export class DefaultCompletionItemProvider implements vscode.CompletionItemProvi } } - let newItems: vscode.CompletionItem[] = []; + const newItems: vscode.CompletionItem[] = []; if (result && result.items) { result.items.forEach((item: any) => { - let newItem = new vscode.CompletionItem(item.label); + const newItem = new vscode.CompletionItem(item.label); newItem.documentation = item.documentation; newItem.detail = item.detail; newItem.insertText = new vscode.SnippetString(item.textEdit.newText); - let oldrange = item.textEdit.range; + const oldrange = item.textEdit.range; newItem.range = new vscode.Range(oldrange.start.line, oldrange.start.character, oldrange.end.line, oldrange.end.character); newItem.filterText = item.filterText; diff --git a/extensions/emmet/src/editPoint.ts b/extensions/emmet/src/editPoint.ts index 239df1f4cc2..b5137795dc9 100644 --- a/extensions/emmet/src/editPoint.ts +++ b/extensions/emmet/src/editPoint.ts @@ -12,9 +12,9 @@ export function fetchEditPoint(direction: string): void { } const editor = vscode.window.activeTextEditor; - let newSelections: vscode.Selection[] = []; + const newSelections: vscode.Selection[] = []; editor.selections.forEach(selection => { - let updatedSelection = direction === 'next' ? nextEditPoint(selection, editor) : prevEditPoint(selection, editor); + const updatedSelection = direction === 'next' ? nextEditPoint(selection, editor) : prevEditPoint(selection, editor); newSelections.push(updatedSelection); }); editor.selections = newSelections; @@ -23,7 +23,7 @@ export function fetchEditPoint(direction: string): void { function nextEditPoint(selection: vscode.Selection, editor: vscode.TextEditor): vscode.Selection { for (let lineNum = selection.anchor.line; lineNum < editor.document.lineCount; lineNum++) { - let updatedSelection = findEditPoint(lineNum, editor, selection.anchor, 'next'); + const updatedSelection = findEditPoint(lineNum, editor, selection.anchor, 'next'); if (updatedSelection) { return updatedSelection; } @@ -33,7 +33,7 @@ function nextEditPoint(selection: vscode.Selection, editor: vscode.TextEditor): function prevEditPoint(selection: vscode.Selection, editor: vscode.TextEditor): vscode.Selection { for (let lineNum = selection.anchor.line; lineNum >= 0; lineNum--) { - let updatedSelection = findEditPoint(lineNum, editor, selection.anchor, 'prev'); + const updatedSelection = findEditPoint(lineNum, editor, selection.anchor, 'prev'); if (updatedSelection) { return updatedSelection; } @@ -43,7 +43,7 @@ function prevEditPoint(selection: vscode.Selection, editor: vscode.TextEditor): function findEditPoint(lineNum: number, editor: vscode.TextEditor, position: vscode.Position, direction: string): vscode.Selection | undefined { - let line = editor.document.lineAt(lineNum); + const line = editor.document.lineAt(lineNum); let lineContent = line.text; if (lineNum !== position.line && line.isEmptyOrWhitespace && lineContent.length) { @@ -53,8 +53,8 @@ function findEditPoint(lineNum: number, editor: vscode.TextEditor, position: vsc if (lineNum === position.line && direction === 'prev') { lineContent = lineContent.substr(0, position.character); } - let emptyAttrIndex = direction === 'next' ? lineContent.indexOf('""', lineNum === position.line ? position.character : 0) : lineContent.lastIndexOf('""'); - let emptyTagIndex = direction === 'next' ? lineContent.indexOf('><', lineNum === position.line ? position.character : 0) : lineContent.lastIndexOf('><'); + const emptyAttrIndex = direction === 'next' ? lineContent.indexOf('""', lineNum === position.line ? position.character : 0) : lineContent.lastIndexOf('""'); + const emptyTagIndex = direction === 'next' ? lineContent.indexOf('><', lineNum === position.line ? position.character : 0) : lineContent.lastIndexOf('><'); let winner = -1; diff --git a/extensions/emmet/src/emmetCommon.ts b/extensions/emmet/src/emmetCommon.ts index 5a5e0d872c3..53824c4de29 100644 --- a/extensions/emmet/src/emmetCommon.ts +++ b/extensions/emmet/src/emmetCommon.ts @@ -161,8 +161,8 @@ const languageMappingForCompletionProviders: Map = new Map = new Map(); function registerCompletionProviders(context: vscode.ExtensionContext) { - let completionProvider = new DefaultCompletionItemProvider(); - let includedLanguages = getMappingForIncludedLanguages(); + const completionProvider = new DefaultCompletionItemProvider(); + const includedLanguages = getMappingForIncludedLanguages(); Object.keys(includedLanguages).forEach(language => { if (languageMappingForCompletionProviders.has(language) && languageMappingForCompletionProviders.get(language) === includedLanguages[language]) { diff --git a/extensions/emmet/src/incrementDecrement.ts b/extensions/emmet/src/incrementDecrement.ts index 9e0afa4acf1..f7adf444978 100644 --- a/extensions/emmet/src/incrementDecrement.ts +++ b/extensions/emmet/src/incrementDecrement.ts @@ -21,7 +21,7 @@ export function incrementDecrement(delta: number): Thenable | undefined return editor.edit(editBuilder => { editor.selections.forEach(selection => { - let rangeToReplace = locate(editor.document, selection.isReversed ? selection.anchor : selection.active); + const rangeToReplace = locate(editor.document, selection.isReversed ? selection.anchor : selection.active); if (!rangeToReplace) { return; } @@ -40,7 +40,7 @@ export function incrementDecrement(delta: number): Thenable | undefined */ export function update(numString: string, delta: number): string { let m: RegExpMatchArray | null; - let decimals = (m = numString.match(/\.(\d+)$/)) ? m[1].length : 1; + const decimals = (m = numString.match(/\.(\d+)$/)) ? m[1].length : 1; let output = String((parseFloat(numString) + delta).toFixed(decimals)).replace(/\.0+$/, ''); if (m = numString.match(/^\-?(0\d+)/)) { diff --git a/extensions/emmet/src/matchTag.ts b/extensions/emmet/src/matchTag.ts index d7331a465b2..1c928fb7371 100644 --- a/extensions/emmet/src/matchTag.ts +++ b/extensions/emmet/src/matchTag.ts @@ -20,7 +20,7 @@ export function matchTag() { return; } - let updatedSelections: vscode.Selection[] = []; + const updatedSelections: vscode.Selection[] = []; editor.selections.forEach(selection => { const updatedSelection = getUpdatedSelections(document, rootNode, selection.start); if (updatedSelection) { diff --git a/extensions/emmet/src/removeTag.ts b/extensions/emmet/src/removeTag.ts index c43a9a03e72..b8b5b9eebdf 100644 --- a/extensions/emmet/src/removeTag.ts +++ b/extensions/emmet/src/removeTag.ts @@ -19,7 +19,7 @@ export function removeTag() { return; } - let finalRangesToRemove = Array.from(editor.selections).reverse() + const finalRangesToRemove = Array.from(editor.selections).reverse() .reduce((prev, selection) => prev.concat(getRangesToRemove(editor.document, rootNode, selection)), []); @@ -68,7 +68,7 @@ function getRangesToRemove(document: vscode.TextDocument, rootNode: HtmlFlatNode } } - let rangesToRemove = []; + const rangesToRemove = []; if (openTagRange) { rangesToRemove.push(openTagRange); if (closeTagRange) { diff --git a/extensions/emmet/src/selectItem.ts b/extensions/emmet/src/selectItem.ts index 52e672eddf3..437dbed7ec9 100644 --- a/extensions/emmet/src/selectItem.ts +++ b/extensions/emmet/src/selectItem.ts @@ -21,7 +21,7 @@ export function fetchSelectItem(direction: string): void { return; } - let newSelections: vscode.Selection[] = []; + const newSelections: vscode.Selection[] = []; editor.selections.forEach(selection => { const selectionStart = selection.isReversed ? selection.active : selection.anchor; const selectionEnd = selection.isReversed ? selection.anchor : selection.active; diff --git a/extensions/emmet/src/selectItemStylesheet.ts b/extensions/emmet/src/selectItemStylesheet.ts index 557d971361b..09f45ee8879 100644 --- a/extensions/emmet/src/selectItemStylesheet.ts +++ b/extensions/emmet/src/selectItemStylesheet.ts @@ -28,7 +28,7 @@ export function nextItemStylesheet(document: vscode.TextDocument, startPosition: if (currentNode.type === 'property' && startOffset >= (currentNode).valueToken.start && endOffset <= (currentNode).valueToken.end) { - let singlePropertyValue = getSelectionFromProperty(document, currentNode, startOffset, endOffset, false, 'next'); + const singlePropertyValue = getSelectionFromProperty(document, currentNode, startOffset, endOffset, false, 'next'); if (singlePropertyValue) { return singlePropertyValue; } @@ -77,7 +77,7 @@ export function prevItemStylesheet(document: vscode.TextDocument, startPosition: if (currentNode.type === 'property' && startOffset >= (currentNode).valueToken.start && endOffset <= (currentNode).valueToken.end) { - let singlePropertyValue = getSelectionFromProperty(document, currentNode, startOffset, endOffset, false, 'prev'); + const singlePropertyValue = getSelectionFromProperty(document, currentNode, startOffset, endOffset, false, 'prev'); if (singlePropertyValue) { return singlePropertyValue; } @@ -115,7 +115,7 @@ function getSelectionFromProperty(document: vscode.TextDocument, node: Node | un } const propertyNode = node; - let propertyValue = propertyNode.valueToken.stream.substring(propertyNode.valueToken.start, propertyNode.valueToken.end); + const propertyValue = propertyNode.valueToken.stream.substring(propertyNode.valueToken.start, propertyNode.valueToken.end); selectFullValue = selectFullValue || (direction === 'prev' && selectionStart === propertyNode.valueToken.start && selectionEnd < propertyNode.valueToken.end); @@ -144,7 +144,7 @@ function getSelectionFromProperty(document: vscode.TextDocument, node: Node | un } - let [newSelectionStartOffset, newSelectionEndOffset] = direction === 'prev' ? findPrevWord(propertyValue, pos) : findNextWord(propertyValue, pos); + const [newSelectionStartOffset, newSelectionEndOffset] = direction === 'prev' ? findPrevWord(propertyValue, pos) : findNextWord(propertyValue, pos); if (!newSelectionStartOffset && !newSelectionEndOffset) { return; } diff --git a/extensions/emmet/src/test/editPointSelectItemBalance.test.ts b/extensions/emmet/src/test/editPointSelectItemBalance.test.ts index b631b156d24..c698e85c683 100644 --- a/extensions/emmet/src/test/editPointSelectItemBalance.test.ts +++ b/extensions/emmet/src/test/editPointSelectItemBalance.test.ts @@ -62,13 +62,13 @@ suite('Tests for Next/Previous Select/Edit point and Balance actions', () => { return withRandomFileEditor(htmlContents, '.html', (editor, _) => { editor.selections = [new Selection(1, 5, 1, 5)]; - let expectedNextEditPoints: [number, number][] = [[4, 16], [6, 8], [10, 2], [10, 2]]; + const expectedNextEditPoints: [number, number][] = [[4, 16], [6, 8], [10, 2], [10, 2]]; expectedNextEditPoints.forEach(([line, col]) => { fetchEditPoint('next'); testSelection(editor.selection, col, line); }); - let expectedPrevEditPoints = [[6, 8], [4, 16], [4, 16]]; + const expectedPrevEditPoints = [[6, 8], [4, 16], [4, 16]]; expectedPrevEditPoints.forEach(([line, col]) => { fetchEditPoint('prev'); testSelection(editor.selection, col, line); @@ -82,7 +82,7 @@ suite('Tests for Next/Previous Select/Edit point and Balance actions', () => { return withRandomFileEditor(htmlContents, '.html', (editor, _) => { editor.selections = [new Selection(2, 2, 2, 2)]; - let expectedNextItemPoints: [number, number, number][] = [ + const expectedNextItemPoints: [number, number, number][] = [ [2, 1, 5], // html [2, 6, 15], // lang="en" [2, 12, 14], // en @@ -141,7 +141,7 @@ suite('Tests for Next/Previous Select/Edit point and Balance actions', () => { return withRandomFileEditor(templateContents, '.html', (editor, _) => { editor.selections = [new Selection(2, 2, 2, 2)]; - let expectedNextItemPoints: [number, number, number][] = [ + const expectedNextItemPoints: [number, number, number][] = [ [2, 2, 5], // div [2, 6, 20], // class="header" [2, 13, 19], // header @@ -170,7 +170,7 @@ suite('Tests for Next/Previous Select/Edit point and Balance actions', () => { return withRandomFileEditor(cssContents, '.css', (editor, _) => { editor.selections = [new Selection(0, 0, 0, 0)]; - let expectedNextItemPoints: [number, number, number][] = [ + const expectedNextItemPoints: [number, number, number][] = [ [1, 0, 4], // .boo [2, 1, 19], // margin: 20px 10px; [2, 9, 18], // 20px 10px @@ -201,7 +201,7 @@ suite('Tests for Next/Previous Select/Edit point and Balance actions', () => { return withRandomFileEditor(scssContents, '.scss', (editor, _) => { editor.selections = [new Selection(0, 0, 0, 0)]; - let expectedNextItemPoints: [number, number, number][] = [ + const expectedNextItemPoints: [number, number, number][] = [ [1, 0, 4], // .boo [2, 1, 19], // margin: 20px 10px; [2, 9, 18], // 20px 10px @@ -232,7 +232,7 @@ suite('Tests for Next/Previous Select/Edit point and Balance actions', () => { return withRandomFileEditor(htmlContents, 'html', (editor, _) => { editor.selections = [new Selection(14, 6, 14, 10)]; - let expectedBalanceOutRanges: [number, number, number, number][] = [ + const expectedBalanceOutRanges: [number, number, number, number][] = [ [14, 3, 14, 32], //
  • Item 1
  • [13, 23, 16, 2], // inner contents of