-
Notifications
You must be signed in to change notification settings - Fork 55
/
GradleTasksTreeDataProvider.ts
204 lines (182 loc) · 6.4 KB
/
GradleTasksTreeDataProvider.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
import * as vscode from 'vscode';
import * as path from 'path';
import {
GradleTaskTreeItem,
RootProjectTreeItem,
ProjectTreeItem,
GroupTreeItem,
NoGradleTasksTreeItem,
TreeItemWithTasksOrGroups,
} from '..';
import { GradleTaskDefinition, GradleTaskProvider } from '../../tasks';
import { isWorkspaceFolder } from '../../util';
import { isGradleTask } from '../../tasks/taskUtil';
import { RootProjectsStore } from '../../stores';
import { Icons } from '../../icons';
const gradleTaskTreeItemMap: Map<string, GradleTaskTreeItem> = new Map();
const gradleProjectTreeItemMap: Map<string, RootProjectTreeItem> = new Map();
const projectTreeItemMap: Map<string, ProjectTreeItem> = new Map();
const groupTreeItemMap: Map<string, GroupTreeItem> = new Map();
export function getGradleTaskTreeItemMap(): Map<string, GradleTaskTreeItem> {
return gradleTaskTreeItemMap;
}
export function getProjectTreeItemMap(): Map<string, ProjectTreeItem> {
return projectTreeItemMap;
}
function resetCachedTreeItems(): void {
gradleTaskTreeItemMap.clear();
gradleProjectTreeItemMap.clear();
projectTreeItemMap.clear();
groupTreeItemMap.clear();
}
export class GradleTasksTreeDataProvider
implements vscode.TreeDataProvider<vscode.TreeItem> {
private collapsed = true;
private readonly _onDidChangeTreeData: vscode.EventEmitter<vscode.TreeItem | null> = new vscode.EventEmitter<vscode.TreeItem | null>();
public readonly onDidChangeTreeData: vscode.Event<vscode.TreeItem | null> = this
._onDidChangeTreeData.event;
constructor(
private readonly context: vscode.ExtensionContext,
private readonly rootProjectStore: RootProjectsStore,
private readonly gradleTaskProvider: GradleTaskProvider,
private readonly icons: Icons
) {
const collapsed = this.context.workspaceState.get(
'gradleTasksCollapsed',
false
);
// eslint-disable-next-line @typescript-eslint/no-floating-promises
this.setCollapsed(collapsed);
}
public async setCollapsed(collapsed: boolean): Promise<void> {
this.collapsed = collapsed;
await this.context.workspaceState.update('gradleTasksCollapsed', collapsed);
await vscode.commands.executeCommand(
'setContext',
'gradle:gradleTasksCollapsed',
collapsed
);
this.refresh();
}
private async buildTreeItems(): Promise<vscode.TreeItem[]> {
resetCachedTreeItems();
// using vscode.tasks.fetchTasks({ type: 'gradle' }) is *incredibly slow* which
// is why we get them directly from the task provider
const tasks = await this.gradleTaskProvider.loadTasks();
return tasks.length === 0
? [new NoGradleTasksTreeItem(this.context)]
: this.buildItemsTreeFromTasks(tasks);
}
public refresh(treeItem: vscode.TreeItem | null = null): void {
this._onDidChangeTreeData.fire(treeItem);
}
public getTreeItem(element: vscode.TreeItem): vscode.TreeItem {
return element;
}
public getParent(element: vscode.TreeItem): vscode.TreeItem | null {
if (
element instanceof RootProjectTreeItem ||
element instanceof ProjectTreeItem ||
element instanceof TreeItemWithTasksOrGroups ||
element instanceof GradleTaskTreeItem
) {
return element.parentTreeItem || null;
}
return null;
}
public async getChildren(
element?: vscode.TreeItem
): Promise<vscode.TreeItem[]> {
if (element instanceof RootProjectTreeItem) {
return element.projects;
}
if (element instanceof ProjectTreeItem) {
return [...element.groups, ...element.tasks];
}
if (element instanceof GroupTreeItem) {
return element.tasks;
}
if (
element instanceof GradleTaskTreeItem ||
element instanceof NoGradleTasksTreeItem
) {
return [];
}
if (!element) {
return await this.buildTreeItems();
}
return [];
}
// eslint-disable-next-line sonarjs/cognitive-complexity
public buildItemsTreeFromTasks(
tasks: vscode.Task[]
): RootProjectTreeItem[] | NoGradleTasksTreeItem[] {
let gradleProjectTreeItem = null;
tasks.forEach((task) => {
const definition = task.definition as GradleTaskDefinition;
if (isWorkspaceFolder(task.scope) && isGradleTask(task)) {
const rootProject = this.rootProjectStore.get(definition.projectFolder);
if (!rootProject) {
return;
}
gradleProjectTreeItem = gradleProjectTreeItemMap.get(
definition.projectFolder
);
if (!gradleProjectTreeItem) {
gradleProjectTreeItem = new RootProjectTreeItem(
path.basename(definition.projectFolder),
rootProject.getProjectUri()
);
gradleProjectTreeItemMap.set(
definition.projectFolder,
gradleProjectTreeItem
);
}
let projectTreeItem = projectTreeItemMap.get(definition.buildFile);
if (!projectTreeItem) {
projectTreeItem = new ProjectTreeItem(
definition.project,
gradleProjectTreeItem,
vscode.Uri.file(definition.buildFile)
);
gradleProjectTreeItem.addProject(projectTreeItem);
projectTreeItemMap.set(definition.buildFile, projectTreeItem);
}
const taskName = definition.script.slice(
definition.script.lastIndexOf(':') + 1
);
let parentTreeItem: ProjectTreeItem | GroupTreeItem = projectTreeItem;
if (!this.collapsed) {
const groupId = definition.group + definition.project;
let groupTreeItem = groupTreeItemMap.get(groupId);
if (!groupTreeItem) {
groupTreeItem = new GroupTreeItem(
definition.group,
projectTreeItem,
undefined
);
projectTreeItem.addGroup(groupTreeItem);
groupTreeItemMap.set(groupId, groupTreeItem);
}
parentTreeItem = groupTreeItem;
}
const taskTreeItem = new GradleTaskTreeItem(
parentTreeItem,
task,
taskName,
definition.description || taskName,
'',
this.icons,
rootProject.getJavaDebug()
);
taskTreeItem.setContext();
gradleTaskTreeItemMap.set(task.definition.id, taskTreeItem);
parentTreeItem.addTask(taskTreeItem);
}
});
if (gradleProjectTreeItemMap.size === 1) {
return gradleProjectTreeItemMap.values().next().value.projects;
}
return [...gradleProjectTreeItemMap.values()];
}
}