From f0f6181e0de4591f9fb0f587743b55b3ada1fab8 Mon Sep 17 00:00:00 2001 From: Anton Kosyakov Date: Tue, 6 Aug 2019 11:59:07 +0000 Subject: [PATCH] fix #5861: ensure that plugin tasks are registered before accessing them Signed-off-by: Anton Kosyakov --- packages/cpp/src/browser/cpp-task-provider.ts | 2 +- .../src/hosted/browser/hosted-plugin.ts | 13 +++++++++++++ .../src/browser/provided-task-configurations.ts | 2 +- packages/task/src/browser/task-contribution.ts | 16 +++++++++++++--- packages/task/src/browser/task-service.ts | 2 +- tsconfig.json | 3 +++ 6 files changed, 32 insertions(+), 6 deletions(-) diff --git a/packages/cpp/src/browser/cpp-task-provider.ts b/packages/cpp/src/browser/cpp-task-provider.ts index 7bc023c9fb0af..1754dd7e60351 100644 --- a/packages/cpp/src/browser/cpp-task-provider.ts +++ b/packages/cpp/src/browser/cpp-task-provider.ts @@ -78,7 +78,7 @@ export class CppTaskProvider implements TaskContribution, TaskProvider, TaskReso } async resolveTask(task: CppBuildTaskConfiguration): Promise { - const resolver = this.taskResolverRegistry.getResolver('shell'); + const resolver = await this.taskResolverRegistry.getResolver('shell'); if (!resolver) { throw new Error('No shell resolver found, cannot build.'); } diff --git a/packages/plugin-ext/src/hosted/browser/hosted-plugin.ts b/packages/plugin-ext/src/hosted/browser/hosted-plugin.ts index 076a1a667eb87..bd4c86a261fe8 100644 --- a/packages/plugin-ext/src/hosted/browser/hosted-plugin.ts +++ b/packages/plugin-ext/src/hosted/browser/hosted-plugin.ts @@ -49,6 +49,7 @@ import { FileSearchService } from '@theia/file-search/lib/common/file-search-ser import { isCancelled } from '@theia/core'; import { FrontendApplicationStateService } from '@theia/core/lib/browser/frontend-application-state'; import { PluginViewRegistry } from '../../main/browser/view/plugin-view-registry'; +import { TaskProviderRegistry, TaskResolverRegistry } from '@theia/task/lib/browser/task-contribution'; export type PluginHost = 'frontend' | string; export type DebugActivationEvent = 'onDebugResolve' | 'onDebugInitialConfigurations' | 'onDebugAdapterProtocolTracker'; @@ -112,6 +113,12 @@ export class HostedPluginSupport { @inject(PluginViewRegistry) protected readonly viewRegistry: PluginViewRegistry; + @inject(TaskProviderRegistry) + protected readonly taskProviderRegistry: TaskProviderRegistry; + + @inject(TaskResolverRegistry) + protected readonly taskResolverRegistry: TaskResolverRegistry; + private theiaReadyPromise: Promise; protected readonly managers: PluginManagerExt[] = []; @@ -135,6 +142,8 @@ export class HostedPluginSupport { this.debugSessionManager.onWillResolveDebugConfiguration(event => this.ensureDebugActivation(event, 'onDebugResolve', event.debugType)); this.debugConfigurationManager.onWillProvideDebugConfiguration(event => this.ensureDebugActivation(event, 'onDebugInitialConfigurations')); this.viewRegistry.onDidExpandView(id => this.activateByView(id)); + this.taskProviderRegistry.onWillProvideTaskProvider(event => this.ensureTaskActivation(event)); + this.taskResolverRegistry.onWillProvideTaskResolver(event => this.ensureTaskActivation(event)); } checkAndLoadPlugin(container: interfaces.Container): void { @@ -290,6 +299,10 @@ export class HostedPluginSupport { event.waitUntil(p); } + protected ensureTaskActivation(event: WaitUntilEvent): void { + event.waitUntil(this.activateByCommand('workbench.action.tasks.runTask')); + } + protected ensureDebugActivation(event: WaitUntilEvent, activationEvent?: DebugActivationEvent, debugType?: string): void { event.waitUntil(this.activateByDebug(activationEvent, debugType)); } diff --git a/packages/task/src/browser/provided-task-configurations.ts b/packages/task/src/browser/provided-task-configurations.ts index 11dfee12c2432..cf40340081dc3 100644 --- a/packages/task/src/browser/provided-task-configurations.ts +++ b/packages/task/src/browser/provided-task-configurations.ts @@ -37,7 +37,7 @@ export class ProvidedTaskConfigurations { /** returns a list of provided tasks */ async getTasks(): Promise { - const providers = this.taskProviderRegistry.getProviders(); + const providers = await this.taskProviderRegistry.getProviders(); const providedTasks: TaskConfiguration[] = (await Promise.all(providers.map(p => p.provideTasks()))) .reduce((acc, taskArray) => acc.concat(taskArray), []); this.cacheTasks(providedTasks); diff --git a/packages/task/src/browser/task-contribution.ts b/packages/task/src/browser/task-contribution.ts index 7693e3119d644..fdf9fa78a8331 100644 --- a/packages/task/src/browser/task-contribution.ts +++ b/packages/task/src/browser/task-contribution.ts @@ -17,6 +17,7 @@ import { injectable, postConstruct } from 'inversify'; import { Disposable } from '@theia/core/lib/common/disposable'; import { TaskConfiguration } from '../common/task-protocol'; +import { WaitUntilEvent, Emitter } from '@theia/core/src/common/event'; export const TaskContribution = Symbol('TaskContribution'); @@ -39,6 +40,9 @@ export interface TaskProvider { @injectable() export class TaskResolverRegistry { + protected readonly onWillProvideTaskResolverEmitter = new Emitter(); + readonly onWillProvideTaskResolver = this.onWillProvideTaskResolverEmitter.event; + protected resolvers: Map; @postConstruct() @@ -54,7 +58,8 @@ export class TaskResolverRegistry { }; } - getResolver(type: string): TaskResolver | undefined { + async getResolver(type: string): Promise { + await WaitUntilEvent.fire(this.onWillProvideTaskResolverEmitter, {}); return this.resolvers.get(type); } } @@ -62,6 +67,9 @@ export class TaskResolverRegistry { @injectable() export class TaskProviderRegistry { + protected readonly onWillProvideTaskProviderEmitter = new Emitter(); + readonly onWillProvideTaskProvider = this.onWillProvideTaskProviderEmitter.event; + protected providers: Map; @postConstruct() @@ -78,12 +86,14 @@ export class TaskProviderRegistry { }; } - getProvider(type: string): TaskProvider | undefined { + async getProvider(type: string): Promise { + await WaitUntilEvent.fire(this.onWillProvideTaskProviderEmitter, {}); return this.providers.get(type); } /** Returns all registered Task Providers. */ - getProviders(): TaskProvider[] { + async getProviders(): Promise { + await WaitUntilEvent.fire(this.onWillProvideTaskProviderEmitter, {}); return [...this.providers.values()]; } } diff --git a/packages/task/src/browser/task-service.ts b/packages/task/src/browser/task-service.ts index f98f6164ee02e..5ce0c6f31d288 100644 --- a/packages/task/src/browser/task-service.ts +++ b/packages/task/src/browser/task-service.ts @@ -366,7 +366,7 @@ export class TaskService implements TaskConfigurationClient { } } - const resolver = this.taskResolverRegistry.getResolver(task.type); + const resolver = await this.taskResolverRegistry.getResolver(task.type); let resolvedTask: TaskConfiguration; try { resolvedTask = resolver ? await resolver.resolveTask(task) : task; diff --git a/tsconfig.json b/tsconfig.json index 89626631288c6..fe54e5e4da180 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -126,6 +126,9 @@ ], "@theia/userstorage/lib/*": [ "packages/userstorage/src/*" + ], + "@theia/task/lib/*": [ + "packages/task/src/*" ] }, "plugins": [