private getGroupedTasks()

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;
			});
		});
	}