in src/vs/workbench/contrib/tasks/browser/abstractTaskService.ts [1127:1297]
private getGroupedTasks(): Promise<TaskMap> {
return Promise.all([this.extensionService.activateByEvent('onCommand:workbench.action.tasks.runTask'), TaskDefinitionRegistry.onReady()]).then(() => {
let validTypes: IStringDictionary<boolean> = Object.create(null);
TaskDefinitionRegistry.all().forEach(definition => validTypes[definition.taskType] = true);
validTypes['shell'] = true;
validTypes['process'] = true;
return new Promise<TaskSet[]>(resolve => {
let result: TaskSet[] = [];
let counter: number = 0;
let done = (value: TaskSet) => {
if (value) {
result.push(value);
}
if (--counter === 0) {
resolve(result);
}
};
let error = (error: any) => {
try {
if (error && Types.isString(error.message)) {
this._outputChannel.append('Error: ');
this._outputChannel.append(error.message);
this._outputChannel.append('\n');
this.showOutput();
} else {
this._outputChannel.append('Unknown error received while collecting tasks from providers.\n');
this.showOutput();
}
} finally {
if (--counter === 0) {
resolve(result);
}
}
};
if (this.schemaVersion === JsonSchemaVersion.V2_0_0 && this._providers.size > 0) {
this._providers.forEach((provider) => {
counter++;
provider.provideTasks(validTypes).then(done, error);
});
} else {
resolve(result);
}
});
}).then((contributedTaskSets) => {
let result: TaskMap = new TaskMap();
let contributedTasks: TaskMap = new TaskMap();
for (let set of contributedTaskSets) {
for (let task of set.tasks) {
let workspaceFolder = task.getWorkspaceFolder();
if (workspaceFolder) {
contributedTasks.add(workspaceFolder, task);
}
}
}
return this.getWorkspaceTasks().then(async (customTasks) => {
const customTasksKeyValuePairs = Array.from(customTasks);
const customTasksPromises = customTasksKeyValuePairs.map(async ([key, folderTasks]) => {
let contributed = contributedTasks.get(key);
if (!folderTasks.set) {
if (contributed) {
result.add(key, ...contributed);
}
return;
}
if (!contributed) {
result.add(key, ...folderTasks.set.tasks);
} else {
let configurations = folderTasks.configurations;
let legacyTaskConfigurations = folderTasks.set ? this.getLegacyTaskConfigurations(folderTasks.set) : undefined;
let customTasksToDelete: Task[] = [];
if (configurations || legacyTaskConfigurations) {
let unUsedConfigurations: Set<string> = new Set<string>();
if (configurations) {
Object.keys(configurations.byIdentifier).forEach(key => unUsedConfigurations.add(key));
}
for (let task of contributed) {
if (!ContributedTask.is(task)) {
continue;
}
if (configurations) {
let configuringTask = configurations.byIdentifier[task.defines._key];
if (configuringTask) {
unUsedConfigurations.delete(task.defines._key);
result.add(key, TaskConfig.createCustomTask(task, configuringTask));
} else {
result.add(key, task);
}
} else if (legacyTaskConfigurations) {
let configuringTask = legacyTaskConfigurations[task.defines._key];
if (configuringTask) {
result.add(key, TaskConfig.createCustomTask(task, configuringTask));
customTasksToDelete.push(configuringTask);
} else {
result.add(key, task);
}
} else {
result.add(key, task);
}
}
if (customTasksToDelete.length > 0) {
let toDelete = customTasksToDelete.reduce<IStringDictionary<boolean>>((map, task) => {
map[task._id] = true;
return map;
}, Object.create(null));
for (let task of folderTasks.set.tasks) {
if (toDelete[task._id]) {
continue;
}
result.add(key, task);
}
} else {
result.add(key, ...folderTasks.set.tasks);
}
const unUsedConfigurationsAsArray = Array.from(unUsedConfigurations);
const unUsedConfigurationPromises = unUsedConfigurationsAsArray.map(async (value) => {
let configuringTask = configurations!.byIdentifier[value];
for (const [handle, provider] of this._providers) {
if (configuringTask.type === this._providerTypes.get(handle)) {
try {
const resolvedTask = await provider.resolveTask(configuringTask);
if (resolvedTask && (resolvedTask._id === configuringTask._id)) {
result.add(key, TaskConfig.createCustomTask(resolvedTask, configuringTask));
return;
}
} catch (error) {
// Ignore errors. The task could not be provided by any of the providers.
}
}
}
this._outputChannel.append(nls.localize(
'TaskService.noConfiguration',
'Error: The {0} task detection didn\'t contribute a task for the following configuration:\n{1}\nThe task will be ignored.\n',
configuringTask.configures.type,
JSON.stringify(configuringTask._source.config.element, undefined, 4)
));
this.showOutput();
});
await Promise.all(unUsedConfigurationPromises);
} else {
result.add(key, ...folderTasks.set.tasks);
result.add(key, ...contributed);
}
}
});
await Promise.all(customTasksPromises);
return result;
}, () => {
// If we can't read the tasks.json file provide at least the contributed tasks
let result: TaskMap = new TaskMap();
for (let set of contributedTaskSets) {
for (let task of set.tasks) {
const folder = task.getWorkspaceFolder();
if (folder) {
result.add(folder, task);
}
}
}
return result;
});
});
}