Skip to content

Commit

Permalink
add registered ProblemMatchers to tasks schema
Browse files Browse the repository at this point in the history
- With this pull request, task schemas are updated on problem matchers
being added / disposed, and users are benefited from having content assist while specifying the name(s) of problem matcher(s) in tasks.json.
- resolves #6134

Signed-off-by: Liang Huang <liang.huang@ericsson.com>
  • Loading branch information
Liang Huang committed Oct 22, 2019
1 parent f255f5a commit 0099776
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 15 deletions.
14 changes: 12 additions & 2 deletions packages/task/src/browser/task-problem-matcher-registry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
*--------------------------------------------------------------------------------------------*/

import { inject, injectable, postConstruct } from 'inversify';
import { Event, Emitter } from '@theia/core/lib/common';
import { Disposable, DisposableCollection } from '@theia/core/lib/common/disposable';
import {
ApplyToKind, FileLocationKind, NamedProblemMatcher, Severity,
Expand All @@ -36,11 +37,17 @@ export class ProblemMatcherRegistry {
@inject(ProblemPatternRegistry)
protected readonly problemPatternRegistry: ProblemPatternRegistry;

protected readonly onDidChangeProblemMatcherEmitter = new Emitter<void>();
get onDidChangeProblemMatcher(): Event<void> {
return this.onDidChangeProblemMatcherEmitter.event;
}

@postConstruct()
protected init(): void {
this.problemPatternRegistry.onReady().then(() => {
this.fillDefaults();
this.readyPromise = new Promise<void>((res, rej) => res(undefined));
this.onDidChangeProblemMatcherEmitter.fire(undefined);
});
}

Expand All @@ -58,8 +65,11 @@ export class ProblemMatcherRegistry {
console.error('Only named Problem Matchers can be registered.');
return Disposable.NULL;
}
const toDispose = new DisposableCollection(Disposable.create(() => {/* mark as not disposed */ }));
this.doRegister(matcher, toDispose);
const toDispose = new DisposableCollection(Disposable.create(() => {
/* mark as not disposed */
this.onDidChangeProblemMatcherEmitter.fire(undefined);
}));
this.doRegister(matcher, toDispose).then(() => this.onDidChangeProblemMatcherEmitter.fire(undefined));
return toDispose;
}
protected async doRegister(matcher: ProblemMatcherContribution, toDispose: DisposableCollection): Promise<void> {
Expand Down
55 changes: 42 additions & 13 deletions packages/task/src/browser/task-schema-updater.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,14 @@
*
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
********************************************************************************/
import { injectable, inject } from 'inversify';
import { injectable, inject, postConstruct } from 'inversify';
import { JsonSchemaStore } from '@theia/core/lib/browser/json-schema-store';
import { InMemoryResources, deepClone } from '@theia/core/lib/common';
import { IJSONSchema } from '@theia/core/lib/common/json-schema';
import { inputsSchema } from '@theia/variable-resolver/lib/browser/variable-input-schema';
import URI from '@theia/core/lib/common/uri';
import { TaskService } from './task-service';
import { ProblemMatcherRegistry } from './task-problem-matcher-registry';

export const taskSchemaId = 'vscode://schemas/tasks';

Expand All @@ -34,8 +35,31 @@ export class TaskSchemaUpdater {
@inject(TaskService)
protected readonly taskService: TaskService;

@inject(ProblemMatcherRegistry)
protected readonly problemMatcherRegistry: ProblemMatcherRegistry;

@postConstruct()
protected init(): void {
this.updateProblemMatcherNames();
// update problem matcher names in the task schema every time a problem matcher is added or disposed
this.problemMatcherRegistry.onDidChangeProblemMatcher(() => this.updateProblemMatcherNames());
}

async update(): Promise<void> {
const taskSchemaUri = new URI(taskSchemaId);
const schemaContent = await this.getTaskSchema();
try {
this.inmemoryResources.update(taskSchemaUri, schemaContent);
} catch (e) {
this.inmemoryResources.add(taskSchemaUri, schemaContent);
this.jsonSchemaStore.registerSchema({
fileMatch: ['tasks.json'],
url: taskSchemaUri.toString()
});
}
}

private async getTaskSchema(): Promise<string> {
const taskSchema = {
properties: {
tasks: {
Expand All @@ -49,17 +73,15 @@ export class TaskSchemaUpdater {
};
const taskTypes = await this.taskService.getRegisteredTaskTypes();
taskSchema.properties.tasks.items.oneOf![0].allOf![0].properties!.type.enum = taskTypes;
const taskSchemaUri = new URI(taskSchemaId);
const contents = JSON.stringify(taskSchema);
try {
this.inmemoryResources.update(taskSchemaUri, contents);
} catch (e) {
this.inmemoryResources.add(taskSchemaUri, contents);
this.jsonSchemaStore.registerSchema({
fileMatch: ['tasks.json'],
url: taskSchemaUri.toString()
});
}
return JSON.stringify(taskSchema);
}

/** Gets the most up-to-date names of problem matchers from the registry and update the task schema */
private updateProblemMatcherNames(): void {
const matcherNames = this.problemMatcherRegistry.getAll().map(m => m.name.startsWith('$') ? m.name : `$${m.name}`);
problemMatcherNames.length = 0;
problemMatcherNames.push(...matcherNames);
this.update();
}
}

Expand Down Expand Up @@ -110,6 +132,7 @@ const commandOptionsSchema: IJSONSchema = {
}
};

const problemMatcherNames: string[] = [];
const taskConfigurationSchema: IJSONSchema = {
$id: taskSchemaId,
oneOf: [
Expand Down Expand Up @@ -161,6 +184,11 @@ const taskConfigurationSchema: IJSONSchema = {
},
problemMatcher: {
oneOf: [
{
type: 'string',
description: 'Name of the problem matcher to parse the output of the task',
enum: problemMatcherNames
},
{
type: 'object',
description: 'User defined problem matcher(s) to parse the output of the task',
Expand All @@ -169,7 +197,8 @@ const taskConfigurationSchema: IJSONSchema = {
type: 'array',
description: 'Name(s) of the problem matcher(s) to parse the output of the task',
items: {
type: 'string'
type: 'string',
enum: problemMatcherNames
}
}
]
Expand Down

0 comments on commit 0099776

Please sign in to comment.