From fc7051a8975e51ae71055cf1c38d653b28e3f1ac Mon Sep 17 00:00:00 2001 From: Dirk Baeumer Date: Fri, 16 Mar 2018 11:48:23 +0100 Subject: [PATCH] Cleaner API to query tasks --- src/vs/vscode.proposed.d.ts | 20 ++++++---- src/vs/workbench/api/node/extHost.api.impl.ts | 2 +- .../workbench/api/node/extHostApiCommands.ts | 37 +++++++++++++------ src/vs/workbench/api/node/extHostWorkspace.ts | 11 ++++++ src/vs/workbench/parts/tasks/common/tasks.ts | 27 ++++++++++++-- .../electron-browser/task.contribution.ts | 25 +++++++------ .../api/extHostApiCommands.test.ts | 6 ++- 7 files changed, 92 insertions(+), 36 deletions(-) diff --git a/src/vs/vscode.proposed.d.ts b/src/vs/vscode.proposed.d.ts index e4d6cfa0911..942579406ae 100644 --- a/src/vs/vscode.proposed.d.ts +++ b/src/vs/vscode.proposed.d.ts @@ -743,26 +743,32 @@ declare module 'vscode' { //#region Tasks /** - * A task handle represents a task in the system. It can be used to - * present task and to execute them. + * A task item represents a task in the system. It can be used to + * present task information in the user interface or to execute the + * underlying task. */ - export interface TaskHandle { + export interface TaskItem { /** - * A unique ID. + * A unique ID representing the underlying task. */ - id: string; + readonly id: string; /** * A human readable label of the task. */ - label: string; + readonly label: string; + + /** + * The task definition. + */ + readonly definition: TaskDefinition; /** * The workspace folder the task belongs to. Is undefined * to tasks that aren't scoped to a workspace folder. */ - workspaceFolder: WorkspaceFolder | undefined; + readonly workspaceFolder: WorkspaceFolder | undefined; } //#endregion diff --git a/src/vs/workbench/api/node/extHost.api.impl.ts b/src/vs/workbench/api/node/extHost.api.impl.ts index 95a283b53b4..4d1319843ec 100644 --- a/src/vs/workbench/api/node/extHost.api.impl.ts +++ b/src/vs/workbench/api/node/extHost.api.impl.ts @@ -132,7 +132,7 @@ export function createApiFactory( const extHostLanguages = new ExtHostLanguages(rpcProtocol); // Register API-ish commands - ExtHostApiCommands.register(extHostCommands); + ExtHostApiCommands.register(extHostCommands, extHostWorkspace); return function (extension: IExtensionDescription): typeof vscode { diff --git a/src/vs/workbench/api/node/extHostApiCommands.ts b/src/vs/workbench/api/node/extHostApiCommands.ts index 4406a22b153..9239a90a5f2 100644 --- a/src/vs/workbench/api/node/extHostApiCommands.ts +++ b/src/vs/workbench/api/node/extHostApiCommands.ts @@ -6,6 +6,7 @@ import URI from 'vs/base/common/uri'; import { TPromise } from 'vs/base/common/winjs.base'; +import * as Objects from 'vs/base/common/objects'; import { IDisposable } from 'vs/base/common/lifecycle'; import * as vscode from 'vscode'; import * as typeConverters from 'vs/workbench/api/node/extHostTypeConverters'; @@ -18,18 +19,21 @@ import { IWorkspaceSymbolProvider } from 'vs/workbench/parts/search/common/searc import { Position as EditorPosition, ITextEditorOptions } from 'vs/platform/editor/common/editor'; import { CustomCodeAction } from 'vs/workbench/api/node/extHostLanguageFeatures'; import * as TaskSystem from 'vs/workbench/parts/tasks/common/tasks'; +import { ExtHostWorkspace } from './extHostWorkspace'; export class ExtHostApiCommands { - static register(commands: ExtHostCommands) { - return new ExtHostApiCommands(commands).registerCommands(); + static register(commands: ExtHostCommands, workspace: ExtHostWorkspace) { + return new ExtHostApiCommands(commands, workspace).registerCommands(); } private _commands: ExtHostCommands; + private _workspace: ExtHostWorkspace; private _disposables: IDisposable[] = []; - private constructor(commands: ExtHostCommands) { + private constructor(commands: ExtHostCommands, workspace: ExtHostWorkspace) { this._commands = commands; + this._workspace = workspace; } registerCommands() { @@ -472,16 +476,25 @@ export class ExtHostApiCommands { .then(tryMapWith(typeConverters.DocumentLink.to)); } - private _executeTaskProvider(): Thenable { - return this._commands.executeCommand('_executeTaskProvider').then((values) => { + private _executeTaskProvider(): Thenable { + return this._commands.executeCommand('_executeTaskProvider').then((values) => { + let workspace = this._workspace; return values.map(handle => { - return { - id: handle.id, - label: handle.label, - workspaceFolder: { - name: handle.workspaceFolder.name, - index: handle.workspaceFolder.index, - uri: URI.revive(handle.workspaceFolder.uri) + let definition: vscode.TaskDefinition = Objects.assign(Object.create(null), handle.definition); + delete definition._key; + let uri = URI.revive(handle.workspaceFolderUri); + return new class { + get id(): string { + return handle.id; + } + get label(): string { + return handle.label; + } + get definition(): vscode.TaskDefinition { + return definition; + } + get workspaceFolder(): vscode.WorkspaceFolder { + return uri ? workspace.resolveWorkspaceFolder(uri) : undefined; } }; }); diff --git a/src/vs/workbench/api/node/extHostWorkspace.ts b/src/vs/workbench/api/node/extHostWorkspace.ts index dfbc1acc3ee..61b0e73992f 100644 --- a/src/vs/workbench/api/node/extHostWorkspace.ts +++ b/src/vs/workbench/api/node/extHostWorkspace.ts @@ -125,6 +125,10 @@ class ExtHostWorkspaceImpl extends Workspace { } return this._structure.findSubstr(uri.toString()); } + + resolveWorkspaceFolder(uri: URI): vscode.WorkspaceFolder { + return this._structure.get(uri.toString()); + } } export class ExtHostWorkspace implements ExtHostWorkspaceShape { @@ -239,6 +243,13 @@ export class ExtHostWorkspace implements ExtHostWorkspaceShape { return this._actualWorkspace.getWorkspaceFolder(uri, resolveParent); } + resolveWorkspaceFolder(uri: vscode.Uri): vscode.WorkspaceFolder { + if (!this._actualWorkspace) { + return undefined; + } + return this._actualWorkspace.resolveWorkspaceFolder(uri); + } + getPath(): string { // this is legacy from the days before having diff --git a/src/vs/workbench/parts/tasks/common/tasks.ts b/src/vs/workbench/parts/tasks/common/tasks.ts index bcefab54238..08640b0476c 100644 --- a/src/vs/workbench/parts/tasks/common/tasks.ts +++ b/src/vs/workbench/parts/tasks/common/tasks.ts @@ -4,14 +4,15 @@ *--------------------------------------------------------------------------------------------*/ 'use strict'; -import { UriComponents } from 'vs/base/common/uri'; +import URI, { UriComponents } from 'vs/base/common/uri'; import * as Types from 'vs/base/common/types'; import { IJSONSchemaMap } from 'vs/base/common/jsonSchema'; import * as Objects from 'vs/base/common/objects'; import { IExtensionDescription } from 'vs/workbench/services/extensions/common/extensions'; import { ProblemMatcher } from 'vs/workbench/parts/tasks/common/problemMatcher'; -import { IWorkspaceFolder, IWorkspaceFolderData } from 'vs/platform/workspace/common/workspace'; +import { IWorkspaceFolder } from 'vs/platform/workspace/common/workspace'; +import { generateUuid } from '../../../../base/common/uuid'; export enum ShellQuoting { @@ -335,6 +336,7 @@ export type TaskSource = WorkspaceTaskSource | ExtensionTaskSource | InMemoryTas export interface TaskIdentifier { _key: string; type: string; + [name: string]: any; } export interface TaskDependency { @@ -439,6 +441,22 @@ export namespace CustomTask { let candidate: CustomTask = value; return candidate && candidate.type === 'custom'; } + export function getDefinition(task: CustomTask): TaskIdentifier { + if (task.command === void 0) { + return undefined; + } + if (task.command.runtime === RuntimeType.Shell) { + return { + _key: generateUuid(), + type: 'shell' + }; + } else { + return { + _key: generateUuid(), + type: 'process' + }; + } + } } export interface ConfiguringTask extends CommonTask, ConfigurationProperties { @@ -594,10 +612,11 @@ export namespace Task { } } -export interface TaskHandleTransfer { +export interface TaskItemTransfer { id: string; label: string; - workspaceFolder: IWorkspaceFolderData; + definition: TaskIdentifier; + workspaceFolderUri: URI; } export enum ExecutionEngine { diff --git a/src/vs/workbench/parts/tasks/electron-browser/task.contribution.ts b/src/vs/workbench/parts/tasks/electron-browser/task.contribution.ts index e1e8dbc4e9a..ea1627866a5 100644 --- a/src/vs/workbench/parts/tasks/electron-browser/task.contribution.ts +++ b/src/vs/workbench/parts/tasks/electron-browser/task.contribution.ts @@ -62,7 +62,7 @@ import Constants from 'vs/workbench/parts/markers/electron-browser/constants'; import { IPartService } from 'vs/workbench/services/part/common/partService'; import { IWorkbenchEditorService } from 'vs/workbench/services/editor/common/editorService'; import { IConfigurationResolverService } from 'vs/workbench/services/configurationResolver/common/configurationResolver'; -import { IWorkspaceContextService, WorkbenchState, IWorkspaceFolder, IWorkspaceFolderData } from 'vs/platform/workspace/common/workspace'; +import { IWorkspaceContextService, WorkbenchState, IWorkspaceFolder } from 'vs/platform/workspace/common/workspace'; import { ITextFileService } from 'vs/workbench/services/textfile/common/textfiles'; import { IOutputService, IOutputChannelRegistry, Extensions as OutputExt, IOutputChannel } from 'vs/workbench/parts/output/common/output'; @@ -74,7 +74,7 @@ import { ITaskSystem, ITaskResolver, ITaskSummary, TaskExecuteKind, TaskError, T import { Task, CustomTask, ConfiguringTask, ContributedTask, InMemoryTask, TaskEvent, TaskEventKind, TaskSet, TaskGroup, GroupType, ExecutionEngine, JsonSchemaVersion, TaskSourceKind, - TaskIdentifier, TaskSorter, TaskHandleTransfer + TaskIdentifier, TaskSorter, TaskItemTransfer } from 'vs/workbench/parts/tasks/common/tasks'; import { ITaskService, ITaskProvider, RunOptions, CustomizationProperties } from 'vs/workbench/parts/tasks/common/taskService'; import { getTemplates as getTaskTemplates } from 'vs/workbench/parts/tasks/common/taskTemplates'; @@ -582,18 +582,21 @@ class TaskService implements ITaskService { CommandsRegistry.registerCommand('_executeTaskProvider', (accessor, args) => { return this.tasks().then((tasks) => { - let result: TaskHandleTransfer[] = []; + let result: TaskItemTransfer[] = []; for (let task of tasks) { - let folder = Task.getWorkspaceFolder(task); - let folderData: IWorkspaceFolderData = folder ? { - name: folder.name, - uri: folder.uri, - index: folder.index - } : undefined; - let handle: TaskHandleTransfer = { + let folder: IWorkspaceFolder = Task.getWorkspaceFolder(task); + let folderUri = folder ? folder.uri : undefined; + let definition: TaskIdentifier; + if (ContributedTask.is(task)) { + definition = task.defines; + } else if (CustomTask.is(task) && task.command !== void 0) { + definition = CustomTask.getDefinition(task); + } + let handle: TaskItemTransfer = { id: task._id, label: task._label, - workspaceFolder: folderData + definition: definition, + workspaceFolderUri: folderUri }; result.push(handle); } diff --git a/src/vs/workbench/test/electron-browser/api/extHostApiCommands.test.ts b/src/vs/workbench/test/electron-browser/api/extHostApiCommands.test.ts index 11189793c55..133e9d9667c 100644 --- a/src/vs/workbench/test/electron-browser/api/extHostApiCommands.test.ts +++ b/src/vs/workbench/test/electron-browser/api/extHostApiCommands.test.ts @@ -33,6 +33,8 @@ import { IInstantiationService } from 'vs/platform/instantiation/common/instanti import 'vs/workbench/parts/search/electron-browser/search.contribution'; import { NullLogService } from 'vs/platform/log/common/log'; import { ITextModel } from 'vs/editor/common/model'; +import { ExtHostWorkspace } from 'vs/workbench/api/node/extHostWorkspace'; +import { generateUuid } from 'vs/base/common/uuid'; const defaultSelector = { scheme: 'far' }; const model: ITextModel = EditorModel.createFromString( @@ -49,6 +51,7 @@ let rpcProtocol: TestRPCProtocol; let extHost: ExtHostLanguageFeatures; let mainThread: MainThreadLanguageFeatures; let commands: ExtHostCommands; +let workspace: ExtHostWorkspace; let disposables: vscode.Disposable[] = []; let originalErrorHandler: (e: any) => any; @@ -115,9 +118,10 @@ suite('ExtHostLanguageFeatureCommands', function () { const heapService = new ExtHostHeapService(); commands = new ExtHostCommands(rpcProtocol, heapService, new NullLogService()); + workspace = new ExtHostWorkspace(rpcProtocol, { id: generateUuid(), name: 'Test', folders: [] }, new NullLogService()); rpcProtocol.set(ExtHostContext.ExtHostCommands, commands); rpcProtocol.set(MainContext.MainThreadCommands, inst.createInstance(MainThreadCommands, rpcProtocol)); - ExtHostApiCommands.register(commands); + ExtHostApiCommands.register(commands, workspace); const diagnostics = new ExtHostDiagnostics(rpcProtocol); rpcProtocol.set(ExtHostContext.ExtHostDiagnostics, diagnostics); -- GitLab