src/vs/workbench/contrib/tasks/browser/abstractTaskService.ts/AbstractTaskService/createResolver
class AbstractTaskService:	private createResolver(grouped?: TaskMap): ITaskResolver {
		interface ResolverData {
			label: Map<string, Task>;
			identifier: Map<string, Task>;
			taskIdentifier: Map<string, Task>;
		}

		let resolverData: Map<string, ResolverData> | undefined;

		return {
			resolve: async (uri: URI | string, identifier: string | TaskIdentifier | undefined) => {
				if (resolverData === undefined) {
					resolverData = new Map();
					(grouped || await this.getGroupedTasks()).forEach((tasks, folder) => {
						let data = resolverData!.get(folder);
						if (!data) {
							data = { label: new Map<string, Task>(), identifier: new Map<string, Task>(), taskIdentifier: new Map<string, Task>() };
							resolverData!.set(folder, data);
						}
						for (let task of tasks) {
							data.label.set(task._label, task);
							if (task.configurationProperties.identifier) {
								data.identifier.set(task.configurationProperties.identifier, task);
							}
							let keyedIdentifier = task.getDefinition(true);
							if (keyedIdentifier !== undefined) {
								data.taskIdentifier.set(keyedIdentifier._key, task);
							}
						}
					});
				}
				let data = resolverData.get(typeof uri === 'string' ? uri : uri.toString());
				if (!data || !identifier) {
					return undefined;
				}
				if (Types.isString(identifier)) {
					return data.label.get(identifier) || data.identifier.get(identifier);
				} else {
					let key = TaskDefinition.createTaskIdentifier(identifier, console);
					return key !== undefined ? data.taskIdentifier.get(key._key) : undefined;
				}
			}
		};
	}