@theia/plugin-ext 1.13.0-next.df062f62 → 1.13.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (81) hide show
  1. package/lib/common/plugin-api-rpc.d.ts +2 -0
  2. package/lib/common/plugin-api-rpc.d.ts.map +1 -1
  3. package/lib/common/plugin-api-rpc.js.map +1 -1
  4. package/lib/common/plugin-protocol.d.ts +7 -4
  5. package/lib/common/plugin-protocol.d.ts.map +1 -1
  6. package/lib/common/plugin-protocol.js +2 -1
  7. package/lib/common/plugin-protocol.js.map +1 -1
  8. package/lib/common/rpc-protocol.d.ts +4 -6
  9. package/lib/common/rpc-protocol.d.ts.map +1 -1
  10. package/lib/common/rpc-protocol.js +65 -64
  11. package/lib/common/rpc-protocol.js.map +1 -1
  12. package/lib/hosted/browser/hosted-plugin-watcher.d.ts +4 -1
  13. package/lib/hosted/browser/hosted-plugin-watcher.d.ts.map +1 -1
  14. package/lib/hosted/browser/hosted-plugin-watcher.js +2 -2
  15. package/lib/hosted/browser/hosted-plugin-watcher.js.map +1 -1
  16. package/lib/hosted/browser/hosted-plugin.d.ts.map +1 -1
  17. package/lib/hosted/browser/hosted-plugin.js +11 -8
  18. package/lib/hosted/browser/hosted-plugin.js.map +1 -1
  19. package/lib/hosted/browser/worker/worker-main.js.map +1 -1
  20. package/lib/hosted/node/hosted-plugin-process.d.ts +2 -2
  21. package/lib/hosted/node/hosted-plugin-process.d.ts.map +1 -1
  22. package/lib/hosted/node/hosted-plugin-process.js +5 -5
  23. package/lib/hosted/node/hosted-plugin-process.js.map +1 -1
  24. package/lib/hosted/node/hosted-plugin.d.ts +1 -1
  25. package/lib/hosted/node/hosted-plugin.d.ts.map +1 -1
  26. package/lib/hosted/node/hosted-plugin.js +4 -5
  27. package/lib/hosted/node/hosted-plugin.js.map +1 -1
  28. package/lib/hosted/node/metadata-scanner.d.ts.map +1 -1
  29. package/lib/hosted/node/metadata-scanner.js +1 -1
  30. package/lib/hosted/node/metadata-scanner.js.map +1 -1
  31. package/lib/hosted/node/plugin-host.js +2 -2
  32. package/lib/hosted/node/plugin-host.js.map +1 -1
  33. package/lib/hosted/node/plugin-service.d.ts +1 -1
  34. package/lib/hosted/node/plugin-service.d.ts.map +1 -1
  35. package/lib/hosted/node/plugin-service.js +2 -2
  36. package/lib/hosted/node/plugin-service.js.map +1 -1
  37. package/lib/hosted/node/scanners/scanner-theia.d.ts.map +1 -1
  38. package/lib/hosted/node/scanners/scanner-theia.js +2 -1
  39. package/lib/hosted/node/scanners/scanner-theia.js.map +1 -1
  40. package/lib/main/browser/keybindings/keybindings-contribution-handler.js +2 -2
  41. package/lib/main/browser/keybindings/keybindings-contribution-handler.js.map +1 -1
  42. package/lib/main/browser/plugin-worker.js.map +1 -1
  43. package/lib/main/browser/tasks-main.js +1 -1
  44. package/lib/main/browser/tasks-main.js.map +1 -1
  45. package/lib/plugin/plugin-context.d.ts.map +1 -1
  46. package/lib/plugin/plugin-context.js +1 -0
  47. package/lib/plugin/plugin-context.js.map +1 -1
  48. package/lib/plugin/tasks/tasks.d.ts +7 -5
  49. package/lib/plugin/tasks/tasks.d.ts.map +1 -1
  50. package/lib/plugin/tasks/tasks.js +27 -42
  51. package/lib/plugin/tasks/tasks.js.map +1 -1
  52. package/lib/plugin/type-converters.d.ts.map +1 -1
  53. package/lib/plugin/type-converters.js +6 -3
  54. package/lib/plugin/type-converters.js.map +1 -1
  55. package/lib/plugin/type-converters.spec.js +2 -0
  56. package/lib/plugin/type-converters.spec.js.map +1 -1
  57. package/lib/plugin/types-impl.d.ts +19 -7
  58. package/lib/plugin/types-impl.d.ts.map +1 -1
  59. package/lib/plugin/types-impl.js +21 -93
  60. package/lib/plugin/types-impl.js.map +1 -1
  61. package/package.json +22 -22
  62. package/src/common/plugin-api-rpc.ts +2 -0
  63. package/src/common/plugin-protocol.ts +10 -4
  64. package/src/common/rpc-protocol.ts +55 -73
  65. package/src/hosted/browser/hosted-plugin-watcher.ts +4 -4
  66. package/src/hosted/browser/hosted-plugin.ts +11 -8
  67. package/src/hosted/browser/worker/worker-main.ts +2 -2
  68. package/src/hosted/node/hosted-plugin-process.ts +6 -6
  69. package/src/hosted/node/hosted-plugin.ts +4 -5
  70. package/src/hosted/node/metadata-scanner.ts +2 -3
  71. package/src/hosted/node/plugin-host.ts +4 -4
  72. package/src/hosted/node/plugin-service.ts +2 -2
  73. package/src/hosted/node/scanners/scanner-theia.ts +2 -1
  74. package/src/main/browser/keybindings/keybindings-contribution-handler.ts +2 -2
  75. package/src/main/browser/plugin-worker.ts +2 -2
  76. package/src/main/browser/tasks-main.ts +1 -1
  77. package/src/plugin/plugin-context.ts +2 -0
  78. package/src/plugin/tasks/tasks.ts +28 -47
  79. package/src/plugin/type-converters.spec.ts +2 -0
  80. package/src/plugin/type-converters.ts +9 -6
  81. package/src/plugin/types-impl.ts +21 -71
@@ -28,16 +28,19 @@ import { RPCProtocol, ConnectionClosedError } from '../../common/rpc-protocol';
28
28
  import { TaskProviderAdapter } from './task-provider';
29
29
  import { Emitter, Event } from '@theia/core/lib/common/event';
30
30
  import { TerminalServiceExtImpl } from '../terminal-ext';
31
+ import { UUID } from '@theia/core/shared/@phosphor/coreutils';
31
32
 
33
+ type ExecutionCallback = (resolvedDefintion: theia.TaskDefinition) => Thenable<theia.Pseudoterminal>;
32
34
  export class TasksExtImpl implements TasksExt {
33
35
  private proxy: TasksMain;
34
36
 
35
37
  private callId = 0;
36
38
  private adaptersMap = new Map<number, TaskProviderAdapter>();
37
39
  private executions = new Map<number, theia.TaskExecution>();
38
- protected providedCustomExecutions: Map<number, CustomExecution>;
39
- protected notProvidedCustomExecutions: Set<number>;
40
- protected activeCustomExecutions: Map<number, CustomExecution>;
40
+ protected callbackIdBase: string = UUID.uuid4();
41
+ protected callbackId: number;
42
+ protected customExecutionIds: Map<ExecutionCallback, string> = new Map();
43
+ protected customExecutionFunctions: Map<string, ExecutionCallback> = new Map();
41
44
  protected lastStartedTask: number | undefined;
42
45
 
43
46
  private readonly onDidExecuteTask: Emitter<theia.TaskStartEvent> = new Emitter<theia.TaskStartEvent>();
@@ -49,9 +52,6 @@ export class TasksExtImpl implements TasksExt {
49
52
 
50
53
  constructor(rpc: RPCProtocol, readonly terminalExt: TerminalServiceExtImpl) {
51
54
  this.proxy = rpc.getProxy(PLUGIN_RPC_CONTEXT.TASKS_MAIN);
52
- this.providedCustomExecutions = new Map<number, CustomExecution>();
53
- this.notProvidedCustomExecutions = new Set<number>();
54
- this.activeCustomExecutions = new Map<number, CustomExecution>();
55
55
  this.fetchTaskExecutions();
56
56
  }
57
57
 
@@ -68,16 +68,10 @@ export class TasksExtImpl implements TasksExt {
68
68
  }
69
69
 
70
70
  async $onDidStartTask(execution: TaskExecutionDto, terminalId: number): Promise<void> {
71
- const customExecution: CustomExecution | undefined = this.providedCustomExecutions.get(execution.task.id);
71
+ const customExecution = this.customExecutionFunctions.get(execution.task.executionId || '');
72
72
  if (customExecution) {
73
- if (this.activeCustomExecutions.get(execution.id) !== undefined) {
74
- throw new Error('We should not be trying to start the same custom task executions twice.');
75
- }
76
-
77
- // Clone the custom execution to keep the original untouched. This is important for multiple runs of the same task.
78
- this.activeCustomExecutions.set(execution.id, customExecution);
79
73
  const taskDefinition = converter.toTask(execution.task).definition;
80
- const pty = await customExecution.callback(taskDefinition);
74
+ const pty = await customExecution(taskDefinition);
81
75
  this.terminalExt.attachPtyToTerminal(terminalId, pty);
82
76
  if (pty.onDidClose) {
83
77
  const disposable = pty.onDidClose((e: number | void = undefined) => {
@@ -105,7 +99,6 @@ export class TasksExtImpl implements TasksExt {
105
99
  }
106
100
 
107
101
  this.executions.delete(id);
108
- this.customExecutionComplete(id);
109
102
 
110
103
  this.onDidTerminateTask.fire({
111
104
  execution: taskExecution
@@ -159,7 +152,7 @@ export class TasksExtImpl implements TasksExt {
159
152
  // in the provided custom execution map that is cleaned up after the
160
153
  // task is executed.
161
154
  if (CustomExecution.is(task.execution!)) {
162
- this.addCustomExecution(taskDto, false);
155
+ taskDto.executionId = this.addCustomExecution(task.execution!.callback);
163
156
  }
164
157
  const executionDto = await this.proxy.$executeTask(taskDto);
165
158
  if (executionDto) {
@@ -177,8 +170,9 @@ export class TasksExtImpl implements TasksExt {
177
170
  return adapter.provideTasks(token).then(tasks => {
178
171
  if (tasks) {
179
172
  for (const task of tasks) {
180
- if (task.type === 'customExecution' || task.taskType === 'customExecution') {
181
- this.addCustomExecution(task, true);
173
+ if (task.taskType === 'customExecution') {
174
+ task.executionId = this.addCustomExecution(task.callback);
175
+ task.callback = undefined;
182
176
  }
183
177
  }
184
178
  }
@@ -192,7 +186,13 @@ export class TasksExtImpl implements TasksExt {
192
186
  $resolveTask(handle: number, task: TaskDto, token: theia.CancellationToken): Promise<TaskDto | undefined> {
193
187
  const adapter = this.adaptersMap.get(handle);
194
188
  if (adapter) {
195
- return adapter.resolveTask(task, token);
189
+ return adapter.resolveTask(task, token).then(resolvedTask => {
190
+ if (resolvedTask && resolvedTask.taskType === 'customExecution') {
191
+ resolvedTask.executionId = this.addCustomExecution(resolvedTask.callback);
192
+ resolvedTask.callback = undefined;
193
+ }
194
+ return resolvedTask;
195
+ });
196
196
  } else {
197
197
  return Promise.reject(new Error('No adapter found to resolve task'));
198
198
  }
@@ -244,36 +244,17 @@ export class TasksExtImpl implements TasksExt {
244
244
  return result;
245
245
  }
246
246
 
247
- private addCustomExecution(taskDto: TaskDto, isProvided: boolean): void {
248
- const taskId = taskDto.id;
249
- if (!isProvided && !this.providedCustomExecutions.has(taskId)) {
250
- this.notProvidedCustomExecutions.add(taskId);
247
+ private addCustomExecution(callback: ExecutionCallback): string {
248
+ let id = this.customExecutionIds.get(callback);
249
+ if (!id) {
250
+ id = this.nextCallbackId();
251
+ this.customExecutionIds.set(callback, id);
252
+ this.customExecutionFunctions.set(id, callback);
251
253
  }
252
- this.providedCustomExecutions.set(taskDto.id, new CustomExecution(taskDto.callback));
254
+ return id;
253
255
  }
254
256
 
255
- private customExecutionComplete(id: number): void {
256
- const extensionCallback2: CustomExecution | undefined = this.activeCustomExecutions.get(id);
257
- if (extensionCallback2) {
258
- this.activeCustomExecutions.delete(id);
259
- }
260
-
261
- // Technically we don't really need to do this, however, if an extension
262
- // is executing a task through "executeTask" over and over again
263
- // with different properties in the task definition, then the map of executions
264
- // could grow indefinitely, something we don't want.
265
- if (this.notProvidedCustomExecutions.has(id) && (this.lastStartedTask !== id)) {
266
- this.providedCustomExecutions.delete(id);
267
- this.notProvidedCustomExecutions.delete(id);
268
- }
269
- const iterator = this.notProvidedCustomExecutions.values();
270
- let iteratorResult = iterator.next();
271
- while (!iteratorResult.done) {
272
- if (!this.activeCustomExecutions.has(iteratorResult.value) && (this.lastStartedTask !== iteratorResult.value)) {
273
- this.providedCustomExecutions.delete(iteratorResult.value);
274
- this.notProvidedCustomExecutions.delete(iteratorResult.value);
275
- }
276
- iteratorResult = iterator.next();
277
- }
257
+ private nextCallbackId(): string {
258
+ return this.callbackIdBase + this.callbackId++;
278
259
  }
279
260
  }
@@ -187,6 +187,7 @@ describe('Type converters:', () => {
187
187
 
188
188
  const shellTaskDto: TaskDto = {
189
189
  type: shellType,
190
+ taskType: shellType,
190
191
  label,
191
192
  source,
192
193
  scope: 1,
@@ -203,6 +204,7 @@ describe('Type converters:', () => {
203
204
 
204
205
  const shellTaskDtoWithCommandLine: TaskDto = {
205
206
  type: shellType,
207
+ taskType: shellType,
206
208
  label,
207
209
  source,
208
210
  scope: 2,
@@ -750,16 +750,16 @@ export function fromTask(task: theia.Task): TaskDto | undefined {
750
750
  return taskDto;
751
751
  }
752
752
 
753
- if (taskDefinition.taskType === 'shell' || types.ShellExecution.is(execution)) {
754
- return fromShellExecution(<theia.ShellExecution>execution, taskDto);
753
+ if (types.ShellExecution.is(execution)) {
754
+ return fromShellExecution(execution, taskDto);
755
755
  }
756
756
 
757
- if (taskDefinition.taskType === 'process' || types.ProcessExecution.is(execution)) {
758
- return fromProcessExecution(<theia.ProcessExecution>execution, taskDto);
757
+ if (types.ProcessExecution.is(execution)) {
758
+ return fromProcessExecution(execution, taskDto);
759
759
  }
760
760
 
761
- if (taskDefinition.taskType === 'customExecution' || types.CustomExecution.is(execution)) {
762
- return fromCustomExecution(<theia.CustomExecution>execution, taskDto);
761
+ if (types.CustomExecution.is(execution)) {
762
+ return fromCustomExecution(execution, taskDto);
763
763
  }
764
764
 
765
765
  return taskDto;
@@ -839,6 +839,7 @@ export function toTask(taskDto: TaskDto): theia.Task {
839
839
  }
840
840
 
841
841
  export function fromProcessExecution(execution: theia.ProcessExecution, taskDto: TaskDto): TaskDto {
842
+ taskDto.taskType = 'process';
842
843
  taskDto.command = execution.process;
843
844
  taskDto.args = execution.args;
844
845
 
@@ -850,6 +851,7 @@ export function fromProcessExecution(execution: theia.ProcessExecution, taskDto:
850
851
  }
851
852
 
852
853
  export function fromShellExecution(execution: theia.ShellExecution, taskDto: TaskDto): TaskDto {
854
+ taskDto.taskType = 'shell';
853
855
  const options = execution.options;
854
856
  if (options) {
855
857
  taskDto.options = getShellExecutionOptions(options);
@@ -872,6 +874,7 @@ export function fromShellExecution(execution: theia.ShellExecution, taskDto: Tas
872
874
  }
873
875
 
874
876
  export function fromCustomExecution(execution: theia.CustomExecution, taskDto: TaskDto): TaskDto {
877
+ taskDto.taskType = 'customExecution';
875
878
  const callback = execution.callback;
876
879
  if (callback) {
877
880
  taskDto.callback = callback;
@@ -1012,6 +1012,24 @@ export enum CodeActionTrigger {
1012
1012
  Manual = 2,
1013
1013
  }
1014
1014
 
1015
+ /**
1016
+ * The reason why code actions were requested.
1017
+ */
1018
+ export enum CodeActionTriggerKind {
1019
+ /**
1020
+ * Code actions were explicitly requested by the user or by an extension.
1021
+ */
1022
+ Invoke = 1,
1023
+
1024
+ /**
1025
+ * Code actions were requested automatically.
1026
+ *
1027
+ * This typically happens when current selection in a file changes, but can
1028
+ * also be triggered when file content changes.
1029
+ */
1030
+ Automatic = 2,
1031
+ }
1032
+
1015
1033
  export class CodeActionKind {
1016
1034
  private static readonly sep = '.';
1017
1035
 
@@ -1466,14 +1484,6 @@ export enum ProgressLocation {
1466
1484
  Notification = 15
1467
1485
  }
1468
1486
 
1469
- function computeTaskExecutionId(values: string[]): string {
1470
- let id: string = '';
1471
- for (let i = 0; i < values.length; i++) {
1472
- id += values[i].replace(/,/g, ',,') + ',';
1473
- }
1474
- return id;
1475
- }
1476
-
1477
1487
  export class ProcessExecution {
1478
1488
  private executionProcess: string;
1479
1489
  private arguments: string[];
@@ -1529,21 +1539,7 @@ export class ProcessExecution {
1529
1539
  this.executionOptions = value;
1530
1540
  }
1531
1541
 
1532
- public computeId(): string {
1533
- const props: string[] = [];
1534
- props.push('process');
1535
- if (this.executionProcess !== undefined) {
1536
- props.push(this.executionProcess);
1537
- }
1538
- if (this.arguments && this.arguments.length > 0) {
1539
- for (const arg of this.arguments) {
1540
- props.push(arg);
1541
- }
1542
- }
1543
- return computeTaskExecutionId(props);
1544
- }
1545
-
1546
- public static is(value: theia.ShellExecution | theia.ProcessExecution | theia.CustomExecution): boolean {
1542
+ public static is(value: theia.ShellExecution | theia.ProcessExecution | theia.CustomExecution): value is ProcessExecution {
1547
1543
  const candidate = value as ProcessExecution;
1548
1544
  return candidate && !!candidate.process;
1549
1545
  }
@@ -1634,24 +1630,7 @@ export class ShellExecution {
1634
1630
  this.shellOptions = value;
1635
1631
  }
1636
1632
 
1637
- public computeId(): string {
1638
- const props: string[] = [];
1639
- props.push('shell');
1640
- if (this.shellCommandLine !== undefined) {
1641
- props.push(this.shellCommandLine);
1642
- }
1643
- if (this.shellCommand !== undefined) {
1644
- props.push(typeof this.shellCommand === 'string' ? this.shellCommand : this.shellCommand.value);
1645
- }
1646
- if (this.arguments && this.arguments.length > 0) {
1647
- for (const arg of this.arguments) {
1648
- props.push(typeof arg === 'string' ? arg : arg.value);
1649
- }
1650
- }
1651
- return computeTaskExecutionId(props);
1652
- }
1653
-
1654
- public static is(value: theia.ShellExecution | theia.ProcessExecution | theia.CustomExecution): boolean {
1633
+ public static is(value: theia.ShellExecution | theia.ProcessExecution | theia.CustomExecution): value is ShellExecution {
1655
1634
  const candidate = value as ShellExecution;
1656
1635
  return candidate && (!!candidate.commandLine || !!candidate.command);
1657
1636
  }
@@ -1662,9 +1641,6 @@ export class CustomExecution {
1662
1641
  constructor(callback: (resolvedDefintion: theia.TaskDefinition) => Thenable<theia.Pseudoterminal>) {
1663
1642
  this._callback = callback;
1664
1643
  }
1665
- public computeId(): string {
1666
- return 'customExecution' + UUID.uuid4();
1667
- }
1668
1644
 
1669
1645
  public set callback(value: (resolvedDefintion: theia.TaskDefinition) => Thenable<theia.Pseudoterminal>) {
1670
1646
  this._callback = value;
@@ -1674,7 +1650,7 @@ export class CustomExecution {
1674
1650
  return this._callback;
1675
1651
  }
1676
1652
 
1677
- public static is(value: theia.ShellExecution | theia.ProcessExecution | theia.CustomExecution): boolean {
1653
+ public static is(value: theia.ShellExecution | theia.ProcessExecution | theia.CustomExecution): value is CustomExecution {
1678
1654
  const candidate = value as CustomExecution;
1679
1655
  return candidate && (!!candidate._callback);
1680
1656
  }
@@ -1842,7 +1818,6 @@ export class Task {
1842
1818
  value = undefined;
1843
1819
  }
1844
1820
  this.taskExecution = value;
1845
- this.updateDefinitionBasedOnExecution();
1846
1821
  }
1847
1822
 
1848
1823
  get problemMatchers(): string[] {
@@ -1907,31 +1882,6 @@ export class Task {
1907
1882
  }
1908
1883
  this.taskPresentationOptions = value;
1909
1884
  }
1910
-
1911
- private updateDefinitionBasedOnExecution(): void {
1912
- if (this.taskExecution instanceof ProcessExecution) {
1913
- Object.assign(this.taskDefinition, {
1914
- id: this.taskExecution.computeId(),
1915
- taskType: 'process'
1916
- });
1917
- } else if (this.taskExecution instanceof ShellExecution) {
1918
- Object.assign(this.taskDefinition, {
1919
- id: this.taskExecution.computeId(),
1920
- taskType: 'shell'
1921
- });
1922
- } else if (this.taskExecution instanceof CustomExecution) {
1923
- Object.assign(this.taskDefinition, {
1924
- id: this.taskDefinition.id ? this.taskDefinition.id : this.taskExecution.computeId(),
1925
- taskType: 'customExecution'
1926
- });
1927
- } else {
1928
- Object.assign(this.taskDefinition, {
1929
- type: '$empty',
1930
- id: UUID.uuid4(),
1931
- taskType: this.taskDefinition!.type
1932
- });
1933
- }
1934
- }
1935
1885
  }
1936
1886
 
1937
1887
  export class Task2 extends Task {