Skip to content

Commit 4d6e9b9

Browse files
jbickersvenefftinge
authored andcommitted
[problems view] Initial implementation of problems view, marker service and widget
Signed-off-by: Jan Bicker <[email protected]>
1 parent d7b6aaf commit 4d6e9b9

28 files changed

+954
-18
lines changed

examples/browser/.yo-rc.json

+2-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@
1818
"@theia/python": "../../packages/python",
1919
"@theia/cpp": "../../packages/cpp",
2020
"@theia/go": "../../packages/go",
21-
"@theia/typescript": "../../packages/typescript"
21+
"@theia/typescript": "../../packages/typescript",
22+
"@theia/markers": "../../packages/markers"
2223
},
2324
"node_modulesPath": "../../node_modules"
2425
}

examples/browser/theia.package.json

+3-2
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,8 @@
1717
"@theia/python": "^0.1.1",
1818
"@theia/cpp": "^0.1.1",
1919
"@theia/go": "^0.1.1",
20-
"@theia/typescript": "^0.1.1"
20+
"@theia/typescript": "^0.1.1",
21+
"@theia/markers": "^0.1.1"
2122
},
2223
"scripts": {
2324
"clean": "rimraf lib && rimraf errorShots",
@@ -40,4 +41,4 @@
4041
"wdio-spec-reporter": "^0.1.0",
4142
"webdriverio": "^4.6.2"
4243
}
43-
}
44+
}

examples/electron/.yo-rc.json

+3-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,9 @@
1717
"@theia/java": "../../packages/java",
1818
"@theia/python": "../../packages/python",
1919
"@theia/cpp": "../../packages/cpp",
20-
"@theia/go": "../../packages/go"
20+
"@theia/go": "../../packages/go",
21+
"@theia/typescript": "../../packages/typescript",
22+
"@theia/markers": "../../packages/markers"
2123
},
2224
"node_modulesPath": "../../node_modules"
2325
}

examples/electron/theia.package.json

+3-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,9 @@
1616
"@theia/java": "^0.1.1",
1717
"@theia/python": "^0.1.1",
1818
"@theia/cpp": "^0.1.1",
19-
"@theia/go": "^0.1.1"
19+
"@theia/go": "^0.1.1",
20+
"@theia/typescript": "^0.1.1",
21+
"@theia/markers": "^0.1.1"
2022
},
2123
"scripts": {
2224
"test": "electron-mocha --timeout 60000 --require ts-node/register \"./test/**/*.espec.ts\"",

packages/core/extension.package.json

+6-7
Original file line numberDiff line numberDiff line change
@@ -24,15 +24,14 @@
2424
"vscode-uri": "^1.0.1",
2525
"vscode-ws-jsonrpc": "0.0.1-alpha.5",
2626
"ws": "^3.0.0",
27-
"yargs": "^8.0.2"
27+
"yargs": "^8.0.2",
28+
"vscode-languageserver-types": "^3.3.0"
2829
},
2930
"publishConfig": {
3031
"access": "public"
3132
},
32-
"theiaExtensions": [
33-
{
34-
"frontend": "lib/browser/menu/browser-menu-module",
35-
"frontendElectron": "lib/electron-browser/menu/electron-menu-module"
36-
}
37-
]
33+
"theiaExtensions": [{
34+
"frontend": "lib/browser/menu/browser-menu-module",
35+
"frontendElectron": "lib/electron-browser/menu/electron-menu-module"
36+
}]
3837
}

packages/filesystem/src/browser/file-tree/file-tree-container.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -29,4 +29,4 @@ export function createFileTreeContainer(parent: interfaces.Container): Container
2929
child.bind(FileTreeWidget).toSelf();
3030

3131
return child;
32-
}
32+
}

packages/markers/.yo-rc.json

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"generator-theia": {
3+
"testSupport": true
4+
}
5+
}

packages/markers/README.md

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
# Theia - Markers Extension
2+
3+
See [here](https://github.com/theia-ide/theia) for a detailed documentation.
4+
5+
## License
6+
[Apache-2.0](https://github.com/theia-ide/theia/blob/master/LICENSE)
+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{
2+
"extends": "../base.tsconfig",
3+
"compilerOptions": {
4+
"rootDir": "src",
5+
"outDir": "lib"
6+
},
7+
"include": [
8+
"src"
9+
]
10+
}
+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
{
2+
"name": "@theia/markers",
3+
"version": "0.1.1",
4+
"description": "Theia - Markers Extension",
5+
"dependencies": {
6+
"@theia/core": "^0.1.1",
7+
"@theia/filesystem": "^0.1.1"
8+
},
9+
"publishConfig": {
10+
"access": "public"
11+
},
12+
"theiaExtensions": [{
13+
"frontend": "lib/browser/problem/problem-frontend-module"
14+
}]
15+
}

packages/markers/src/browser/index.ts

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
/*
2+
* Copyright (C) 2017 TypeFox and others.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License.
5+
* You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
6+
*/
7+
8+
export * from './marker-manager';
9+
export * from './problem/problem-marker';
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
/*
2+
* Copyright (C) 2017 TypeFox and others.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License.
5+
* You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
6+
*/
7+
8+
import { interfaces, Container } from "inversify";
9+
import { MarkerTreeServices } from './marker-tree-model';
10+
import { MarkerTree } from './marker-tree';
11+
import { createTreeContainer, TreeServices, Tree, ITree } from "@theia/core/lib/browser";
12+
13+
export function createMarkerTreeContainer(parent: interfaces.Container): Container {
14+
const child = createTreeContainer(parent);
15+
16+
child.unbind(Tree);
17+
child.bind(MarkerTree).toSelf();
18+
child.rebind(ITree).toDynamicValue(ctx => ctx.container.get(MarkerTree));
19+
20+
child.unbind(TreeServices);
21+
child.bind(MarkerTreeServices).toSelf();
22+
23+
return child;
24+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
/*
2+
* Copyright (C) 2017 TypeFox and others.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License.
5+
* You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
6+
*/
7+
8+
import { injectable } from "inversify";
9+
import { Disposable, Event, Emitter } from "@theia/core/lib/common";
10+
import { JSONExt } from "@phosphor/coreutils";
11+
12+
export interface Marker<T> {
13+
id: string;
14+
uri: string;
15+
owner: string;
16+
kind: string;
17+
data: T;
18+
}
19+
20+
export interface MarkerInfo {
21+
counter: number;
22+
uri: string
23+
}
24+
25+
export class MarkerCollection<T> implements Disposable {
26+
27+
protected readonly markers = new Map<string, Readonly<Marker<T>>[]>();
28+
protected readonly idSequences = new Map<string, number>();
29+
30+
constructor(
31+
public readonly owner: string,
32+
public readonly kind: string,
33+
protected readonly fireDispose: () => void,
34+
protected readonly fireChange: () => void
35+
) { }
36+
37+
dispose(): void {
38+
this.fireDispose();
39+
}
40+
41+
get uris(): string[] {
42+
return Array.from(this.markers.keys());
43+
}
44+
45+
getMarkers(uri: string): Readonly<Marker<T>>[] {
46+
return this.markers.get(uri) || [];
47+
}
48+
49+
setMarkers(uri: string, markerData: T[]): void {
50+
if (markerData.length > 0) {
51+
this.markers.set(uri, markerData.map(data => this.createMarker(uri, data)));
52+
} else {
53+
this.markers.delete(uri);
54+
}
55+
this.fireChange();
56+
}
57+
58+
protected createMarker(uri: string, data: T): Readonly<Marker<T>> {
59+
let id;
60+
const marker = this.getMarkers(uri).find((m: Marker<T>) => JSONExt.deepEqual((m.data as any), (data as any)));
61+
if (marker) {
62+
id = marker.id;
63+
} else {
64+
id = `${this.owner}_${uri}_${this.nextId(uri)}`;
65+
}
66+
return Object.freeze({
67+
uri,
68+
kind: this.kind,
69+
owner: this.owner,
70+
id,
71+
data
72+
});
73+
}
74+
75+
protected nextId(uri: string): number {
76+
const id = this.idSequences.get(uri) || 0;
77+
this.idSequences.set(uri, id + 1);
78+
return id;
79+
}
80+
81+
}
82+
83+
@injectable()
84+
export class MarkerManager {
85+
86+
protected readonly owners = new Map<string, MarkerCollection<object>>();
87+
protected readonly onDidChangeMarkersEmitter = new Emitter<void>();
88+
89+
get onDidChangeMarkers(): Event<void> {
90+
return this.onDidChangeMarkersEmitter.event;
91+
}
92+
protected fireOnDidChangeMarkers(): void {
93+
this.onDidChangeMarkersEmitter.fire(undefined);
94+
}
95+
96+
createCollection<T extends object>(owner: string, kind: string): MarkerCollection<T> {
97+
if (this.owners.has(owner)) {
98+
throw new Error('marker collection for the given owner already exists, owner: ' + owner);
99+
}
100+
const collection = new MarkerCollection<T>(owner, kind, () => this.deleteCollection(owner), () => this.fireOnDidChangeMarkers());
101+
this.owners.set(owner, collection);
102+
return collection;
103+
}
104+
105+
protected deleteCollection(owner: string): void {
106+
this.owners.delete(owner);
107+
}
108+
109+
protected forEachByKind(kind: string, cb: (mc: MarkerCollection<Object>) => void): void {
110+
this.owners.forEach(collection => {
111+
if (collection.kind === kind) {
112+
cb(collection);
113+
}
114+
});
115+
}
116+
117+
forEachMarkerInfoByKind(kind: string, cb: (markerInfo: MarkerInfo) => void): void {
118+
this.forEachByKind(kind, collection => collection.uris.forEach(uri => {
119+
const markers = collection.getMarkers(uri);
120+
cb({
121+
uri: uri,
122+
counter: markers.length
123+
});
124+
}));
125+
}
126+
127+
forEachMarkerByUriAndKind(uri: string, kind: string, cb: (marker: Readonly<Marker<Object>>) => void): void {
128+
this.forEachByKind(kind, collection => collection.getMarkers(uri).forEach(m => cb(m)));
129+
}
130+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
/*
2+
* Copyright (C) 2017 TypeFox and others.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License.
5+
* You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
6+
*/
7+
8+
import { injectable, inject } from "inversify";
9+
import { MarkerTree, MarkerNode } from './marker-tree';
10+
import { TreeModel, TreeServices, OpenerService, open, ITreeNode, OpenerOptions } from "@theia/core/lib/browser";
11+
12+
@injectable()
13+
export class MarkerTreeServices extends TreeServices {
14+
@inject(OpenerService) readonly openerService: OpenerService;
15+
}
16+
17+
@injectable()
18+
export class MarkerTreeModel extends TreeModel {
19+
20+
protected readonly openerService: OpenerService;
21+
22+
constructor(
23+
@inject(MarkerTree) protected readonly tree: MarkerTree,
24+
@inject(MarkerTreeServices) readonly services: MarkerTreeServices
25+
) {
26+
super(tree, services);
27+
}
28+
29+
protected doOpenNode(node: ITreeNode): void {
30+
if (MarkerNode.is(node)) {
31+
open(this.openerService, node.uri, this.getOpenerOptionsByMarker(node));
32+
} else {
33+
super.doOpenNode(node);
34+
}
35+
}
36+
37+
protected getOpenerOptionsByMarker(node: MarkerNode): OpenerOptions | undefined {
38+
return undefined;
39+
}
40+
}

0 commit comments

Comments
 (0)