mirror of
https://github.com/microsoft/vscode.git
synced 2026-04-26 03:29:00 +01:00
Fixes #22069: Define extension story for tasks
This commit is contained in:
@@ -34,6 +34,7 @@ import { ExtHostLanguages } from 'vs/workbench/api/node/extHostLanguages';
|
||||
import { ExtHostLanguageFeatures } from 'vs/workbench/api/node/extHostLanguageFeatures';
|
||||
import { ExtHostApiCommands } from 'vs/workbench/api/node/extHostApiCommands';
|
||||
import { computeDiff } from 'vs/workbench/api/node/extHostFunctions';
|
||||
import { ExtHostTask } from 'vs/workbench/api/node/extHostTask';
|
||||
import * as extHostTypes from 'vs/workbench/api/node/extHostTypes';
|
||||
import URI from 'vs/base/common/uri';
|
||||
import Severity from 'vs/base/common/severity';
|
||||
@@ -111,6 +112,7 @@ export function createApiFactory(initData: IInitData, threadService: IThreadServ
|
||||
const extHostQuickOpen = col.define(ExtHostContext.ExtHostQuickOpen).set<ExtHostQuickOpen>(new ExtHostQuickOpen(threadService));
|
||||
const extHostTerminalService = col.define(ExtHostContext.ExtHostTerminalService).set<ExtHostTerminalService>(new ExtHostTerminalService(threadService));
|
||||
const extHostSCM = col.define(ExtHostContext.ExtHostSCM).set<ExtHostSCM>(new ExtHostSCM(threadService));
|
||||
const extHostTask = col.define(ExtHostContext.ExtHostTask).set<ExtHostTask>(new ExtHostTask(threadService));
|
||||
col.define(ExtHostContext.ExtHostExtensionService).set(extensionService);
|
||||
col.finish(false, threadService);
|
||||
|
||||
@@ -412,7 +414,10 @@ export function createApiFactory(initData: IInitData, threadService: IThreadServ
|
||||
},
|
||||
getConfiguration: (section?: string): vscode.WorkspaceConfiguration => {
|
||||
return extHostConfiguration.getConfiguration(section);
|
||||
}
|
||||
},
|
||||
registerTaskProvider: proposedApiFunction(extension, (provider: vscode.TaskProvider) => {
|
||||
return extHostTask.registerTaskProvider(extension, provider);
|
||||
})
|
||||
};
|
||||
|
||||
class SCM {
|
||||
@@ -494,7 +499,12 @@ export function createApiFactory(initData: IInitData, threadService: IThreadServ
|
||||
ViewColumn: extHostTypes.ViewColumn,
|
||||
WorkspaceEdit: extHostTypes.WorkspaceEdit,
|
||||
// functions
|
||||
computeDiff
|
||||
computeDiff,
|
||||
FileLocationKind: extHostTypes.FileLocationKind,
|
||||
ApplyToKind: extHostTypes.ApplyToKind,
|
||||
RevealKind: extHostTypes.RevealKind,
|
||||
ShellTask: extHostTypes.ShellTask,
|
||||
ProcessTask: extHostTypes.ProcessTask
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
@@ -33,6 +33,7 @@ import { MainThreadTerminalService } from './mainThreadTerminalService';
|
||||
import { MainThreadWorkspace } from './mainThreadWorkspace';
|
||||
import { MainProcessExtensionService } from './mainThreadExtensionService';
|
||||
import { MainThreadFileSystemEventService } from './mainThreadFileSystemEventService';
|
||||
import { MainThreadTask } from './mainThreadTask';
|
||||
import { MainThreadSCM } from './mainThreadSCM';
|
||||
|
||||
// --- other interested parties
|
||||
@@ -86,6 +87,7 @@ export class ExtHostContribution implements IWorkbenchContribution {
|
||||
col.define(MainContext.MainThreadTerminalService).set(create(MainThreadTerminalService));
|
||||
col.define(MainContext.MainThreadWorkspace).set(create(MainThreadWorkspace));
|
||||
col.define(MainContext.MainThreadSCM).set(create(MainThreadSCM));
|
||||
col.define(MainContext.MainThreadTask).set(create(MainThreadTask));
|
||||
if (this.extensionService instanceof MainProcessExtensionService) {
|
||||
col.define(MainContext.MainProcessExtensionService).set(<MainProcessExtensionService>this.extensionService);
|
||||
}
|
||||
|
||||
@@ -37,6 +37,7 @@ import { SaveReason } from 'vs/workbench/services/textfile/common/textfiles';
|
||||
import { IApplyEditsOptions, IUndoStopOptions, TextEditorRevealType, ITextEditorConfigurationUpdate, IResolvedTextEditorConfiguration, ISelectionChangeEvent } from './mainThreadEditor';
|
||||
|
||||
import { InternalTreeExplorerNodeContent } from 'vs/workbench/parts/explorers/common/treeExplorerViewModel';
|
||||
import { TaskSet } from 'vs/workbench/parts/tasks/common/tasks';
|
||||
|
||||
export interface IEnvironment {
|
||||
enableProposedApi: boolean;
|
||||
@@ -236,6 +237,11 @@ export abstract class MainThreadWorkspaceShape {
|
||||
$applyWorkspaceEdit(edits: IResourceEdit[]): TPromise<boolean> { throw ni(); }
|
||||
}
|
||||
|
||||
export abstract class MainThreadTaskShape {
|
||||
$registerTaskProvider(handle: number): TPromise<any> { throw ni(); }
|
||||
$unregisterTaskProvider(handle: number): TPromise<any> { throw ni(); }
|
||||
}
|
||||
|
||||
export abstract class MainProcessExtensionServiceShape {
|
||||
$localShowMessage(severity: Severity, msg: string): void { throw ni(); }
|
||||
$onExtensionActivated(extensionId: string): void { throw ni(); }
|
||||
@@ -410,6 +416,10 @@ export abstract class ExtHostSCMShape {
|
||||
$onInputBoxValueChange(value: string): TPromise<void> { throw ni(); }
|
||||
}
|
||||
|
||||
export abstract class ExtHostTaskShape {
|
||||
$provideTasks(handle: number): TPromise<TaskSet> { throw ni(); }
|
||||
}
|
||||
|
||||
// --- proxy identifiers
|
||||
|
||||
export const MainContext = {
|
||||
@@ -432,7 +442,8 @@ export const MainContext = {
|
||||
MainThreadTerminalService: createMainId<MainThreadTerminalServiceShape>('MainThreadTerminalService', MainThreadTerminalServiceShape),
|
||||
MainThreadWorkspace: createMainId<MainThreadWorkspaceShape>('MainThreadWorkspace', MainThreadWorkspaceShape),
|
||||
MainProcessExtensionService: createMainId<MainProcessExtensionServiceShape>('MainProcessExtensionService', MainProcessExtensionServiceShape),
|
||||
MainThreadSCM: createMainId<MainThreadSCMShape>('MainThreadSCM', MainThreadSCMShape)
|
||||
MainThreadSCM: createMainId<MainThreadSCMShape>('MainThreadSCM', MainThreadSCMShape),
|
||||
MainThreadTask: createMainId<MainThreadTaskShape>('MainThreadTask', MainThreadTaskShape)
|
||||
};
|
||||
|
||||
export const ExtHostContext = {
|
||||
@@ -450,5 +461,6 @@ export const ExtHostContext = {
|
||||
ExtHostQuickOpen: createExtId<ExtHostQuickOpenShape>('ExtHostQuickOpen', ExtHostQuickOpenShape),
|
||||
ExtHostExtensionService: createExtId<ExtHostExtensionServiceShape>('ExtHostExtensionService', ExtHostExtensionServiceShape),
|
||||
ExtHostTerminalService: createExtId<ExtHostTerminalServiceShape>('ExtHostTerminalService', ExtHostTerminalServiceShape),
|
||||
ExtHostSCM: createExtId<ExtHostSCMShape>('ExtHostSCM', ExtHostSCMShape)
|
||||
ExtHostSCM: createExtId<ExtHostSCMShape>('ExtHostSCM', ExtHostSCMShape),
|
||||
ExtHostTask: createExtId<ExtHostTaskShape>('ExtHostTask', ExtHostTaskShape)
|
||||
};
|
||||
|
||||
478
src/vs/workbench/api/node/extHostTask.ts
Normal file
478
src/vs/workbench/api/node/extHostTask.ts
Normal file
@@ -0,0 +1,478 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
'use strict';
|
||||
|
||||
import { TPromise } from 'vs/base/common/winjs.base';
|
||||
import * as UUID from 'vs/base/common/uuid';
|
||||
import { asWinJsPromise } from 'vs/base/common/async';
|
||||
|
||||
import * as Problems from 'vs/platform/markers/common/problemMatcher';
|
||||
import { IExtensionDescription } from 'vs/platform/extensions/common/extensions';
|
||||
import * as TaskSystem from 'vs/workbench/parts/tasks/common/tasks';
|
||||
|
||||
import { IThreadService } from 'vs/workbench/services/thread/common/threadService';
|
||||
import { MainContext, MainThreadTaskShape, ExtHostTaskShape } from 'vs/workbench/api/node/extHost.protocol';
|
||||
import { fromDiagnosticSeverity } from 'vs/workbench/api/node/extHostTypeConverters';
|
||||
|
||||
import * as types from 'vs/workbench/api/node/extHostTypes';
|
||||
import * as vscode from 'vscode';
|
||||
|
||||
interface StringMap<V> {
|
||||
[key: string]: V;
|
||||
}
|
||||
|
||||
namespace ProblemPattern {
|
||||
export function from(value: vscode.ProblemPattern | vscode.MultiLineProblemPattern): Problems.ProblemPattern | Problems.MultiLineProblemPattern {
|
||||
if (value === void 0 || value === null) {
|
||||
return undefined;
|
||||
}
|
||||
if (Array.isArray(value)) {
|
||||
let result: Problems.ProblemPattern[] = [];
|
||||
for (let pattern of value) {
|
||||
let converted = fromSingle(pattern);
|
||||
if (!converted) {
|
||||
return undefined;
|
||||
}
|
||||
result.push(converted);
|
||||
}
|
||||
return result;
|
||||
} else {
|
||||
return fromSingle(value);
|
||||
}
|
||||
}
|
||||
|
||||
function copyProperty(target: Problems.ProblemPattern, source: vscode.ProblemPattern, tk: keyof Problems.ProblemPattern) {
|
||||
let sk: keyof vscode.ProblemPattern = tk;
|
||||
let value = source[sk];
|
||||
if (typeof value === 'number') {
|
||||
target[tk] = value;
|
||||
}
|
||||
}
|
||||
|
||||
function getValue(value: number, defaultValue: number): number {
|
||||
if (value !== void 0 && value === null) {
|
||||
return value;
|
||||
}
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
function fromSingle(problemPattern: vscode.ProblemPattern): Problems.ProblemPattern {
|
||||
if (problemPattern === void 0 || problemPattern === null || !(problemPattern.regexp instanceof RegExp)) {
|
||||
return undefined;
|
||||
}
|
||||
let result: Problems.ProblemPattern = {
|
||||
regexp: problemPattern.regexp
|
||||
};
|
||||
copyProperty(result, problemPattern, 'file');
|
||||
copyProperty(result, problemPattern, 'location');
|
||||
copyProperty(result, problemPattern, 'line');
|
||||
copyProperty(result, problemPattern, 'character');
|
||||
copyProperty(result, problemPattern, 'endLine');
|
||||
copyProperty(result, problemPattern, 'endCharacter');
|
||||
copyProperty(result, problemPattern, 'severity');
|
||||
copyProperty(result, problemPattern, 'code');
|
||||
copyProperty(result, problemPattern, 'message');
|
||||
if (problemPattern.loop === true || problemPattern.loop === false) {
|
||||
result.loop = problemPattern.loop;
|
||||
}
|
||||
if (result.location) {
|
||||
result.file = getValue(result.file, 1);
|
||||
result.message = getValue(result.message, 0);
|
||||
} else {
|
||||
result.file = getValue(result.file, 1);
|
||||
result.line = getValue(result.line, 2);
|
||||
result.character = getValue(result.character, 3);
|
||||
result.message = getValue(result.message, 0);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
namespace ApplyTo {
|
||||
export function from(value: vscode.ApplyToKind): Problems.ApplyToKind {
|
||||
if (value === void 0 || value === null) {
|
||||
return Problems.ApplyToKind.allDocuments;
|
||||
}
|
||||
switch (value) {
|
||||
case types.ApplyToKind.OpenDocuments:
|
||||
return Problems.ApplyToKind.openDocuments;
|
||||
case types.ApplyToKind.ClosedDocuments:
|
||||
return Problems.ApplyToKind.closedDocuments;
|
||||
}
|
||||
return Problems.ApplyToKind.allDocuments;
|
||||
}
|
||||
}
|
||||
|
||||
namespace FileLocation {
|
||||
export function from(value: vscode.FileLocationKind | string): { kind: Problems.FileLocationKind; prefix?: string } {
|
||||
if (value === void 0 || value === null) {
|
||||
return { kind: Problems.FileLocationKind.Auto };
|
||||
}
|
||||
if (typeof value === 'string') {
|
||||
return { kind: Problems.FileLocationKind.Relative, prefix: value };
|
||||
}
|
||||
switch (value) {
|
||||
case types.FileLocationKind.Absolute:
|
||||
return { kind: Problems.FileLocationKind.Absolute };
|
||||
case types.FileLocationKind.Relative:
|
||||
return { kind: Problems.FileLocationKind.Relative, prefix: '${workspaceRoot}' };
|
||||
}
|
||||
return { kind: Problems.FileLocationKind.Auto };
|
||||
}
|
||||
}
|
||||
|
||||
namespace WatchingPattern {
|
||||
export function from(value: RegExp | vscode.BackgroundPattern): Problems.WatchingPattern {
|
||||
if (value === void 0 || value === null) {
|
||||
return undefined;
|
||||
}
|
||||
if (value instanceof RegExp) {
|
||||
return { regexp: value };
|
||||
}
|
||||
if (!(value.regexp instanceof RegExp)) {
|
||||
return undefined;
|
||||
}
|
||||
let result: Problems.WatchingPattern = {
|
||||
regexp: value.regexp
|
||||
};
|
||||
if (typeof value.file === 'number') {
|
||||
result.file = value.file;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
namespace WathingMatcher {
|
||||
export function from(value: vscode.BackgroundMonitor): Problems.WatchingMatcher {
|
||||
if (value === void 0 || value === null) {
|
||||
return undefined;
|
||||
}
|
||||
let result: Problems.WatchingMatcher = {
|
||||
activeOnStart: !!value.activeOnStart,
|
||||
beginsPattern: WatchingPattern.from(value.beginsPattern),
|
||||
endsPattern: WatchingPattern.from(value.endsPattern)
|
||||
};
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
namespace ProblemMatcher {
|
||||
export function from(values: vscode.ProblemMatcher[]): Problems.ProblemMatcher[] {
|
||||
if (values === void 0 || values === null) {
|
||||
return undefined;
|
||||
}
|
||||
let result: Problems.ProblemMatcher[];
|
||||
for (let value of values) {
|
||||
let converted = fromSingle(value);
|
||||
if (converted) {
|
||||
result.push(converted);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
function fromSingle(problemMatcher: vscode.ProblemMatcher): Problems.ProblemMatcher {
|
||||
if (problemMatcher === void 0 || problemMatcher === null) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
let location = FileLocation.from(problemMatcher.fileLocation);
|
||||
let result: Problems.ProblemMatcher = {
|
||||
owner: typeof problemMatcher.owner === 'string' ? problemMatcher.owner : UUID.generateUuid(),
|
||||
applyTo: ApplyTo.from(problemMatcher.applyTo),
|
||||
fileLocation: location.kind,
|
||||
filePrefix: location.prefix,
|
||||
pattern: ProblemPattern.from(problemMatcher.pattern),
|
||||
severity: fromDiagnosticSeverity(problemMatcher.severity),
|
||||
|
||||
};
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
namespace RevealKind {
|
||||
export function from(value: vscode.RevealKind): TaskSystem.ShowOutput {
|
||||
if (value === void 0 || value === null) {
|
||||
return TaskSystem.ShowOutput.Always;
|
||||
}
|
||||
switch (value) {
|
||||
case types.RevealKind.Silent:
|
||||
return TaskSystem.ShowOutput.Silent;
|
||||
case types.RevealKind.Never:
|
||||
return TaskSystem.ShowOutput.Never;
|
||||
}
|
||||
return TaskSystem.ShowOutput.Always;
|
||||
}
|
||||
}
|
||||
|
||||
namespace TerminalBehaviour {
|
||||
export function from(value: vscode.TerminalBehaviour): { showOutput: TaskSystem.ShowOutput } {
|
||||
if (value === void 0 || value === null) {
|
||||
return { showOutput: TaskSystem.ShowOutput.Always };
|
||||
}
|
||||
return { showOutput: RevealKind.from(value.reveal) };
|
||||
}
|
||||
}
|
||||
|
||||
namespace Strings {
|
||||
export function from(value: string[]): string[] {
|
||||
if (value === void 0 || value === null) {
|
||||
return undefined;
|
||||
}
|
||||
for (let element of value) {
|
||||
if (typeof element !== 'string') {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
namespace CommandOptions {
|
||||
export function from(value: { cwd?: string; env?: { [key: string]: string; } }): TaskSystem.CommandOptions {
|
||||
if (value === void 0 || value === null) {
|
||||
return undefined;
|
||||
}
|
||||
let result: TaskSystem.CommandOptions = {
|
||||
};
|
||||
if (typeof value.cwd === 'string') {
|
||||
result.cwd = value.cwd;
|
||||
}
|
||||
if (value.env) {
|
||||
result.env = Object.create(null);
|
||||
Object.keys(value.env).forEach(key => {
|
||||
let envValue = value.env[key];
|
||||
if (typeof envValue === 'string') {
|
||||
result.env[key] = envValue;
|
||||
}
|
||||
});
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
namespace ShellConfiguration {
|
||||
export function from(value: { executable?: string, args?: string[] }): boolean | TaskSystem.ShellConfiguration {
|
||||
if (value === void 0 || value === null || typeof value.executable !== 'string') {
|
||||
return true;
|
||||
}
|
||||
|
||||
let result: TaskSystem.ShellConfiguration = {
|
||||
executable: value.executable,
|
||||
args: Strings.from(value.args)
|
||||
};
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
namespace Tasks {
|
||||
|
||||
export function from(tasks: vscode.Task[], uuidMap: UUIDMap): TaskSystem.Task[] {
|
||||
if (tasks === void 0 || tasks === null) {
|
||||
return [];
|
||||
}
|
||||
let result: TaskSystem.Task[] = [];
|
||||
try {
|
||||
uuidMap.start();
|
||||
for (let task of tasks) {
|
||||
let converted = fromSingle(task, uuidMap);
|
||||
if (converted) {
|
||||
result.push(converted);
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
uuidMap.finish();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
function fromSingle(task: vscode.Task, uuidMap: UUIDMap): TaskSystem.Task {
|
||||
if (typeof task.name !== 'string' || typeof task.identifier !== 'string') {
|
||||
return undefined;
|
||||
}
|
||||
let command: TaskSystem.CommandConfiguration;
|
||||
if (task instanceof types.ProcessTask) {
|
||||
command = getProcessCommand(task);
|
||||
} else if (task instanceof types.ShellTask) {
|
||||
command = getShellCommand(task);
|
||||
} else {
|
||||
return undefined;
|
||||
}
|
||||
if (command === void 0) {
|
||||
return undefined;
|
||||
}
|
||||
let outputChannel = TerminalBehaviour.from(task.terminal);
|
||||
let result: TaskSystem.Task = {
|
||||
_id: uuidMap.getUUID(task.identifier),
|
||||
name: task.name,
|
||||
identifier: task.identifier,
|
||||
command: command,
|
||||
showOutput: outputChannel.showOutput,
|
||||
isBackground: !!task.isBackground,
|
||||
suppressTaskName: true,
|
||||
problemMatchers: ProblemMatcher.from(task.problemMatchers)
|
||||
};
|
||||
return result;
|
||||
}
|
||||
|
||||
function getProcessCommand(value: vscode.ProcessTask): TaskSystem.CommandConfiguration {
|
||||
if (typeof value.process !== 'string') {
|
||||
return undefined;
|
||||
}
|
||||
let result: TaskSystem.CommandConfiguration = {
|
||||
name: value.process,
|
||||
args: Strings.from(value.args),
|
||||
isShellCommand: false,
|
||||
echo: false,
|
||||
};
|
||||
if (value.options) {
|
||||
result.options = CommandOptions.from(value.options);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
function getShellCommand(value: vscode.ShellTask): TaskSystem.CommandConfiguration {
|
||||
if (typeof value.commandLine !== 'string') {
|
||||
return undefined;
|
||||
}
|
||||
let result: TaskSystem.CommandConfiguration = {
|
||||
name: value.commandLine,
|
||||
isShellCommand: ShellConfiguration.from(value.options),
|
||||
echo: false
|
||||
};
|
||||
if (value.options) {
|
||||
result.options = CommandOptions.from(value.options);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
class UUIDMap {
|
||||
|
||||
private _map: StringMap<string>;
|
||||
private _unused: StringMap<boolean>;
|
||||
|
||||
constructor() {
|
||||
this._map = Object.create(null);
|
||||
}
|
||||
|
||||
public start(): void {
|
||||
this._unused = Object.create(null);
|
||||
Object.keys(this._map).forEach(key => this._unused[key] = true);
|
||||
}
|
||||
|
||||
public getUUID(identifier: string): string {
|
||||
delete this._unused[identifier];
|
||||
let result = this._map[identifier];
|
||||
if (result) {
|
||||
return result;
|
||||
}
|
||||
result = UUID.generateUuid();
|
||||
this._map[identifier] = result;
|
||||
return result;
|
||||
}
|
||||
|
||||
public finish(): void {
|
||||
Object.keys(this._unused).forEach(key => delete this._map[key]);
|
||||
this._unused = null;
|
||||
}
|
||||
}
|
||||
|
||||
namespace TaskSet {
|
||||
|
||||
const idMaps: Map<string, UUIDMap> = new Map<string, UUIDMap>();
|
||||
|
||||
function getUUIDMap(extensionId: string): UUIDMap {
|
||||
let result = idMaps.get(extensionId);
|
||||
if (result) {
|
||||
return result;
|
||||
}
|
||||
result = new UUIDMap();
|
||||
idMaps.set(extensionId, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
export function from(extension: IExtensionDescription, value: vscode.TaskSet): TaskSystem.TaskSet {
|
||||
if (value === void 0 || value === null || !Array.isArray(value.tasks)) {
|
||||
return { tasks: Object.create(null) };
|
||||
}
|
||||
|
||||
let tasks = Tasks.from(value.tasks, getUUIDMap(extension.id));
|
||||
let buildTasks: string[];
|
||||
let testTasks: string[];
|
||||
if (value.buildTasks || value.testTasks) {
|
||||
let map: Map<string, TaskSystem.Task> = new Map<string, TaskSystem.Task>();
|
||||
tasks.forEach(task => map.set(task.identifier, task));
|
||||
if (Array.isArray(value.buildTasks)) {
|
||||
buildTasks = [];
|
||||
for (let elem of value.buildTasks) {
|
||||
if (typeof elem === 'string' && map.has(elem)) {
|
||||
buildTasks.push(map.get(elem)._id);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (Array.isArray(value.testTasks)) {
|
||||
testTasks = [];
|
||||
for (let elem of value.testTasks) {
|
||||
if (typeof elem === 'string' && map.has(elem)) {
|
||||
testTasks.push(map.get(elem)._id);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
tasks,
|
||||
buildTasks,
|
||||
testTasks
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
interface HandlerData {
|
||||
provider: vscode.TaskProvider;
|
||||
extension: IExtensionDescription;
|
||||
}
|
||||
|
||||
export class ExtHostTask extends ExtHostTaskShape {
|
||||
|
||||
private _proxy: MainThreadTaskShape;
|
||||
private _handleCounter: number;
|
||||
private _handlers: Map<number, HandlerData>;
|
||||
|
||||
constructor(threadService: IThreadService) {
|
||||
super();
|
||||
this._proxy = threadService.get(MainContext.MainThreadTask);
|
||||
this._handleCounter = 0;
|
||||
this._handlers = new Map<number, HandlerData>();
|
||||
};
|
||||
|
||||
public registerTaskProvider(extension: IExtensionDescription, provider: vscode.TaskProvider): vscode.Disposable {
|
||||
if (!provider) {
|
||||
return new types.Disposable(() => { });
|
||||
}
|
||||
let handle = this.nextHandle();
|
||||
this._handlers.set(handle, { provider, extension });
|
||||
this._proxy.$registerTaskProvider(handle);
|
||||
return new types.Disposable(() => {
|
||||
this._handlers.delete(handle);
|
||||
this._proxy.$unregisterTaskProvider(handle);
|
||||
});
|
||||
}
|
||||
|
||||
public $provideTasks(handle: number): TPromise<TaskSystem.TaskSet> {
|
||||
let handler = this._handlers.get(handle);
|
||||
if (!handler) {
|
||||
return TPromise.wrapError<TaskSystem.TaskSet>(new Error('no handler found'));
|
||||
}
|
||||
return asWinJsPromise(token => handler.provider.provideTasks(token)).then(value => {
|
||||
return TaskSet.from(handler.extension, value);
|
||||
});
|
||||
}
|
||||
|
||||
private nextHandle(): number {
|
||||
return this._handleCounter++;
|
||||
}
|
||||
}
|
||||
@@ -963,3 +963,156 @@ export class DocumentLink {
|
||||
this.target = target;
|
||||
}
|
||||
}
|
||||
|
||||
export enum FileLocationKind {
|
||||
Auto = 1,
|
||||
|
||||
Relative = 2,
|
||||
|
||||
Absolute = 3
|
||||
}
|
||||
|
||||
export enum ApplyToKind {
|
||||
AllDocuments = 1,
|
||||
|
||||
OpenDocuments = 2,
|
||||
|
||||
ClosedDocuments = 3
|
||||
}
|
||||
|
||||
export enum RevealKind {
|
||||
Always = 1,
|
||||
|
||||
Silent = 2,
|
||||
|
||||
Never = 3
|
||||
}
|
||||
|
||||
export class BaseTask {
|
||||
|
||||
private _name: string;
|
||||
private _problemMatchers: vscode.ProblemMatcher[];
|
||||
|
||||
public isBackground: boolean;
|
||||
public identifier: string;
|
||||
public terminal: vscode.TerminalBehaviour;
|
||||
|
||||
constructor(name: string, problemMatchers: vscode.ProblemMatcher[]) {
|
||||
if (typeof name !== 'string') {
|
||||
throw illegalArgument('name');
|
||||
}
|
||||
this._name = name;
|
||||
this.identifier = name;
|
||||
this._problemMatchers = problemMatchers;
|
||||
this.isBackground = false;
|
||||
}
|
||||
|
||||
get name(): string {
|
||||
return this._name;
|
||||
}
|
||||
|
||||
get problemMatchers(): vscode.ProblemMatcher[] {
|
||||
return this._problemMatchers;
|
||||
}
|
||||
}
|
||||
|
||||
namespace ProblemMatcher {
|
||||
export function is(value: any): value is vscode.ProblemMatcher {
|
||||
let candidate: vscode.ProblemMatcher = value;
|
||||
return candidate && !!candidate.pattern;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
export class ProcessTask extends BaseTask {
|
||||
|
||||
private _process: string;
|
||||
|
||||
public args: string[];
|
||||
public options: vscode.ProcessOptions;
|
||||
|
||||
private static parseArguments(restArgs: any[]): { args: string[]; options: vscode.ProcessOptions; problemMatchers: vscode.ProblemMatcher[] } {
|
||||
let args: string[] = [];
|
||||
let options: vscode.ProcessOptions = undefined;
|
||||
let problemMatchers: vscode.ProblemMatcher[] = [];
|
||||
if (!restArgs || restArgs.length === 0) {
|
||||
return { args, options, problemMatchers };
|
||||
}
|
||||
let current: any = restArgs[0];
|
||||
if (Array.isArray(current)) {
|
||||
args = current;
|
||||
restArgs.shift();
|
||||
current = restArgs[0];
|
||||
}
|
||||
if (ProblemMatcher.is(current)) {
|
||||
problemMatchers = restArgs;
|
||||
} else if (current) {
|
||||
options = current;
|
||||
restArgs.shift();
|
||||
if (restArgs.length > 0) {
|
||||
problemMatchers = restArgs;
|
||||
}
|
||||
}
|
||||
return { args, options, problemMatchers };
|
||||
}
|
||||
|
||||
constructor(name: string, process: string, ...problemMatchers: vscode.ProblemMatcher[]);
|
||||
constructor(name: string, process: string, args: string[], ...problemMatchers: vscode.ProblemMatcher[]);
|
||||
constructor(name: string, process: string, args: string[], options: vscode.ProcessOptions, ...problemMatchers: vscode.ProblemMatcher[]);
|
||||
constructor(name: string, process: string, ...rest: any[]) {
|
||||
if (typeof process !== 'string') {
|
||||
throw illegalArgument('process');
|
||||
}
|
||||
let { args, options, problemMatchers } = ProcessTask.parseArguments(rest);
|
||||
super(name, problemMatchers);
|
||||
this._process = process;
|
||||
this.args = args;
|
||||
this.options = options;
|
||||
}
|
||||
|
||||
get process(): string {
|
||||
return this._process;
|
||||
}
|
||||
}
|
||||
|
||||
export class ShellTask extends BaseTask {
|
||||
|
||||
private _commandLine: string;
|
||||
|
||||
public options: vscode.ShellOptions;
|
||||
|
||||
private static parseArguments(restArgs: any[]): { options: vscode.ShellOptions; problemMatchers: vscode.ProblemMatcher[] } {
|
||||
let options: vscode.ShellOptions = undefined;
|
||||
let problemMatchers: vscode.ProblemMatcher[] = [];
|
||||
if (!restArgs || restArgs.length === 0) {
|
||||
return { options, problemMatchers };
|
||||
}
|
||||
let current: any = restArgs[0];
|
||||
if (current && !ProblemMatcher.is(current)) {
|
||||
options = current;
|
||||
restArgs.shift();
|
||||
current = restArgs[0];
|
||||
}
|
||||
if (ProblemMatcher.is(current)) {
|
||||
problemMatchers = restArgs;
|
||||
}
|
||||
return { options, problemMatchers };
|
||||
}
|
||||
|
||||
constructor(name: string, commandLine: string, ...problemMatchers: vscode.ProblemMatcher[]);
|
||||
constructor(name: string, commandLine: string, options: vscode.ShellOptions, ...problemMatchers: vscode.ProblemMatcher[]);
|
||||
constructor(name: string, commandLine: string, ...rest: any[]) {
|
||||
if (typeof commandLine !== 'string') {
|
||||
throw illegalArgument('commandLine');
|
||||
}
|
||||
let { options, problemMatchers } = ShellTask.parseArguments(rest);
|
||||
|
||||
super(name, problemMatchers);
|
||||
this._commandLine = commandLine;
|
||||
this.options = options;
|
||||
}
|
||||
|
||||
get commandLine(): string {
|
||||
return this._commandLine;
|
||||
}
|
||||
}
|
||||
36
src/vs/workbench/api/node/mainThreadTask.ts
Normal file
36
src/vs/workbench/api/node/mainThreadTask.ts
Normal file
@@ -0,0 +1,36 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
'use strict';
|
||||
|
||||
import { TPromise } from 'vs/base/common/winjs.base';
|
||||
|
||||
import { ITaskService } from 'vs/workbench/parts/tasks/common/taskService';
|
||||
import { IThreadService } from 'vs/workbench/services/thread/common/threadService';
|
||||
|
||||
import { ExtHostContext, MainThreadTaskShape, ExtHostTaskShape } from './extHost.protocol';
|
||||
|
||||
export class MainThreadTask extends MainThreadTaskShape {
|
||||
|
||||
private _proxy: ExtHostTaskShape;
|
||||
|
||||
constructor( @IThreadService threadService: IThreadService, @ITaskService private _taskService: ITaskService) {
|
||||
super();
|
||||
this._proxy = threadService.get(ExtHostContext.ExtHostTask);
|
||||
}
|
||||
|
||||
public $registerTaskProvider(handle: number): TPromise<void> {
|
||||
this._taskService.registerTaskProvider(handle, {
|
||||
provideTasks: () => {
|
||||
return this._proxy.$provideTasks(handle);
|
||||
}
|
||||
});
|
||||
return TPromise.as<void>(undefined);
|
||||
}
|
||||
|
||||
public $unregisterTaskProvider(handle: number): TPromise<any> {
|
||||
this._taskService.unregisterTaskProvider(handle);
|
||||
return TPromise.as<void>(undefined);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user