@theia/plugin-ext 1.25.0-next.4 → 1.25.0-next.42

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 (122) hide show
  1. package/lib/common/plugin-api-rpc-model.d.ts +1 -15
  2. package/lib/common/plugin-api-rpc-model.d.ts.map +1 -1
  3. package/lib/common/plugin-api-rpc-model.js.map +1 -1
  4. package/lib/common/plugin-api-rpc.d.ts +15 -22
  5. package/lib/common/plugin-api-rpc.d.ts.map +1 -1
  6. package/lib/common/plugin-api-rpc.js +2 -0
  7. package/lib/common/plugin-api-rpc.js.map +1 -1
  8. package/lib/common/uri-components.d.ts +2 -9
  9. package/lib/common/uri-components.d.ts.map +1 -1
  10. package/lib/common/uri-components.js +1 -7
  11. package/lib/common/uri-components.js.map +1 -1
  12. package/lib/hosted/node/hosted-plugin-localization-service.js +17 -2
  13. package/lib/hosted/node/hosted-plugin-localization-service.js.map +1 -1
  14. package/lib/main/browser/callhierarchy/callhierarchy-type-converters.d.ts +9 -9
  15. package/lib/main/browser/callhierarchy/callhierarchy-type-converters.d.ts.map +1 -1
  16. package/lib/main/browser/callhierarchy/callhierarchy-type-converters.js +70 -89
  17. package/lib/main/browser/callhierarchy/callhierarchy-type-converters.js.map +1 -1
  18. package/lib/main/browser/debug/plugin-debug-adapter-contribution.d.ts +0 -12
  19. package/lib/main/browser/debug/plugin-debug-adapter-contribution.d.ts.map +1 -1
  20. package/lib/main/browser/debug/plugin-debug-adapter-contribution.js +0 -18
  21. package/lib/main/browser/debug/plugin-debug-adapter-contribution.js.map +1 -1
  22. package/lib/main/browser/debug/plugin-debug-configuration-provider.d.ts +2 -2
  23. package/lib/main/browser/debug/plugin-debug-configuration-provider.d.ts.map +1 -1
  24. package/lib/main/browser/debug/plugin-debug-configuration-provider.js.map +1 -1
  25. package/lib/main/browser/debug/plugin-debug-service.d.ts +3 -2
  26. package/lib/main/browser/debug/plugin-debug-service.d.ts.map +1 -1
  27. package/lib/main/browser/debug/plugin-debug-service.js +28 -29
  28. package/lib/main/browser/debug/plugin-debug-service.js.map +1 -1
  29. package/lib/main/browser/languages-main.d.ts.map +1 -1
  30. package/lib/main/browser/languages-main.js +7 -1
  31. package/lib/main/browser/languages-main.js.map +1 -1
  32. package/lib/main/browser/main-context.d.ts.map +1 -1
  33. package/lib/main/browser/main-context.js +3 -0
  34. package/lib/main/browser/main-context.js.map +1 -1
  35. package/lib/main/browser/notification-main.d.ts +2 -1
  36. package/lib/main/browser/notification-main.d.ts.map +1 -1
  37. package/lib/main/browser/notification-main.js +12 -4
  38. package/lib/main/browser/notification-main.js.map +1 -1
  39. package/lib/main/browser/plugin-ext-frontend-module.d.ts.map +1 -1
  40. package/lib/main/browser/plugin-ext-frontend-module.js +3 -0
  41. package/lib/main/browser/plugin-ext-frontend-module.js.map +1 -1
  42. package/lib/main/browser/status-bar-message-registry-main.d.ts +2 -1
  43. package/lib/main/browser/status-bar-message-registry-main.d.ts.map +1 -1
  44. package/lib/main/browser/status-bar-message-registry-main.js +9 -1
  45. package/lib/main/browser/status-bar-message-registry-main.js.map +1 -1
  46. package/lib/main/browser/view/tree-view-decorator-service.d.ts +33 -0
  47. package/lib/main/browser/view/tree-view-decorator-service.d.ts.map +1 -0
  48. package/lib/main/browser/view/tree-view-decorator-service.js +70 -0
  49. package/lib/main/browser/view/tree-view-decorator-service.js.map +1 -0
  50. package/lib/main/browser/view/tree-view-widget.d.ts +2 -0
  51. package/lib/main/browser/view/tree-view-widget.d.ts.map +1 -1
  52. package/lib/main/browser/view/tree-view-widget.js +9 -1
  53. package/lib/main/browser/view/tree-view-widget.js.map +1 -1
  54. package/lib/plugin/comments.js.map +1 -1
  55. package/lib/plugin/languages/call-hierarchy.d.ts +8 -7
  56. package/lib/plugin/languages/call-hierarchy.d.ts.map +1 -1
  57. package/lib/plugin/languages/call-hierarchy.js +39 -31
  58. package/lib/plugin/languages/call-hierarchy.js.map +1 -1
  59. package/lib/plugin/languages/lens.js.map +1 -1
  60. package/lib/plugin/languages.d.ts +5 -4
  61. package/lib/plugin/languages.d.ts.map +1 -1
  62. package/lib/plugin/languages.js +3 -0
  63. package/lib/plugin/languages.js.map +1 -1
  64. package/lib/plugin/node/debug/debug.d.ts +2 -5
  65. package/lib/plugin/node/debug/debug.d.ts.map +1 -1
  66. package/lib/plugin/node/debug/debug.js +1 -60
  67. package/lib/plugin/node/debug/debug.js.map +1 -1
  68. package/lib/plugin/notification.d.ts +2 -0
  69. package/lib/plugin/notification.d.ts.map +1 -1
  70. package/lib/plugin/notification.js +14 -2
  71. package/lib/plugin/notification.js.map +1 -1
  72. package/lib/plugin/quick-open.d.ts +3 -1
  73. package/lib/plugin/quick-open.d.ts.map +1 -1
  74. package/lib/plugin/quick-open.js +9 -30
  75. package/lib/plugin/quick-open.js.map +1 -1
  76. package/lib/plugin/status-bar/status-bar-item.d.ts +13 -2
  77. package/lib/plugin/status-bar/status-bar-item.d.ts.map +1 -1
  78. package/lib/plugin/status-bar/status-bar-item.js +38 -1
  79. package/lib/plugin/status-bar/status-bar-item.js.map +1 -1
  80. package/lib/plugin/tree/tree-views.d.ts.map +1 -1
  81. package/lib/plugin/tree/tree-views.js +4 -2
  82. package/lib/plugin/tree/tree-views.js.map +1 -1
  83. package/lib/plugin/type-converters.d.ts +1 -1
  84. package/lib/plugin/type-converters.d.ts.map +1 -1
  85. package/lib/plugin/type-converters.js +10 -6
  86. package/lib/plugin/type-converters.js.map +1 -1
  87. package/lib/plugin/type-converters.spec.js +16 -1
  88. package/lib/plugin/type-converters.spec.js.map +1 -1
  89. package/lib/plugin/types-impl.d.ts +5 -2
  90. package/lib/plugin/types-impl.d.ts.map +1 -1
  91. package/lib/plugin/types-impl.js.map +1 -1
  92. package/lib/plugin/workspace.d.ts +1 -1
  93. package/lib/plugin/workspace.d.ts.map +1 -1
  94. package/package.json +23 -23
  95. package/src/common/plugin-api-rpc-model.ts +1 -17
  96. package/src/common/plugin-api-rpc.ts +34 -26
  97. package/src/common/uri-components.ts +4 -17
  98. package/src/hosted/node/hosted-plugin-localization-service.ts +23 -2
  99. package/src/main/browser/callhierarchy/callhierarchy-type-converters.ts +85 -97
  100. package/src/main/browser/debug/plugin-debug-adapter-contribution.ts +0 -21
  101. package/src/main/browser/debug/plugin-debug-configuration-provider.ts +8 -2
  102. package/src/main/browser/debug/plugin-debug-service.ts +53 -31
  103. package/src/main/browser/languages-main.ts +8 -4
  104. package/src/main/browser/main-context.ts +4 -0
  105. package/src/main/browser/notification-main.ts +13 -4
  106. package/src/main/browser/plugin-ext-frontend-module.ts +3 -0
  107. package/src/main/browser/status-bar-message-registry-main.ts +12 -0
  108. package/src/main/browser/view/tree-view-decorator-service.ts +52 -0
  109. package/src/main/browser/view/tree-view-widget.tsx +15 -1
  110. package/src/plugin/comments.ts +1 -1
  111. package/src/plugin/languages/call-hierarchy.ts +44 -50
  112. package/src/plugin/languages/lens.ts +1 -1
  113. package/src/plugin/languages.ts +11 -6
  114. package/src/plugin/node/debug/debug.ts +22 -78
  115. package/src/plugin/notification.ts +18 -2
  116. package/src/plugin/quick-open.ts +11 -33
  117. package/src/plugin/status-bar/status-bar-item.ts +57 -5
  118. package/src/plugin/tree/tree-views.ts +4 -2
  119. package/src/plugin/type-converters.spec.ts +20 -1
  120. package/src/plugin/type-converters.ts +13 -7
  121. package/src/plugin/types-impl.ts +6 -2
  122. package/src/plugin/workspace.ts +1 -1
@@ -14,17 +14,17 @@
14
14
  // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
15
15
  // *****************************************************************************
16
16
 
17
- import { NotificationMain } from '../../common/plugin-api-rpc';
17
+ import { NotificationExt, NotificationMain, MAIN_RPC_CONTEXT } from '../../common';
18
18
  import { ProgressService, Progress, ProgressMessage } from '@theia/core/lib/common';
19
19
  import { interfaces } from '@theia/core/shared/inversify';
20
20
  import { RPCProtocol } from '../../common/rpc-protocol';
21
21
  import { Disposable, DisposableCollection } from '@theia/core/lib/common/disposable';
22
22
 
23
23
  export class NotificationMainImpl implements NotificationMain, Disposable {
24
-
25
24
  private readonly progressService: ProgressService;
26
25
  private readonly progressMap = new Map<string, Progress>();
27
26
  private readonly progress2Work = new Map<string, number>();
27
+ private readonly proxy: NotificationExt;
28
28
 
29
29
  protected readonly toDispose = new DisposableCollection(
30
30
  Disposable.create(() => { /* mark as not disposed */ })
@@ -32,6 +32,7 @@ export class NotificationMainImpl implements NotificationMain, Disposable {
32
32
 
33
33
  constructor(rpc: RPCProtocol, container: interfaces.Container) {
34
34
  this.progressService = container.get(ProgressService);
35
+ this.proxy = rpc.getProxy(MAIN_RPC_CONTEXT.NOTIFICATION_EXT);
35
36
  }
36
37
 
37
38
  dispose(): void {
@@ -39,8 +40,15 @@ export class NotificationMainImpl implements NotificationMain, Disposable {
39
40
  }
40
41
 
41
42
  async $startProgress(options: NotificationMain.StartProgressOptions): Promise<string> {
43
+ const onDidCancel = () => {
44
+ // If the map does not contain current id, it has already stopped and should not be cancelled
45
+ if (this.progressMap.has(id)) {
46
+ this.proxy.$acceptProgressCanceled(id);
47
+ }
48
+ };
49
+
42
50
  const progressMessage = this.mapOptions(options);
43
- const progress = await this.progressService.showProgress(progressMessage);
51
+ const progress = await this.progressService.showProgress(progressMessage, onDidCancel);
44
52
  const id = progress.id;
45
53
  this.progressMap.set(id, progress);
46
54
  this.progress2Work.set(id, 0);
@@ -58,10 +66,11 @@ export class NotificationMainImpl implements NotificationMain, Disposable {
58
66
 
59
67
  $stopProgress(id: string): void {
60
68
  const progress = this.progressMap.get(id);
69
+
61
70
  if (progress) {
62
- progress.cancel();
63
71
  this.progressMap.delete(id);
64
72
  this.progress2Work.delete(id);
73
+ progress.cancel();
65
74
  }
66
75
  }
67
76
 
@@ -78,6 +78,7 @@ import { UndoRedoService } from './custom-editors/undo-redo-service';
78
78
  import { WebviewFrontendSecurityWarnings } from './webview/webview-frontend-security-warnings';
79
79
  import { PluginAuthenticationServiceImpl } from './plugin-authentication-service';
80
80
  import { AuthenticationService } from '@theia/core/lib/browser/authentication-service';
81
+ import { bindTreeViewDecoratorUtilities, TreeViewDecoratorService } from './view/tree-view-decorator-service';
81
82
 
82
83
  export default new ContainerModule((bind, unbind, isBound, rebind) => {
83
84
 
@@ -142,6 +143,7 @@ export default new ContainerModule((bind, unbind, isBound, rebind) => {
142
143
 
143
144
  bind(ViewContextKeyService).toSelf().inSingletonScope();
144
145
 
146
+ bindTreeViewDecoratorUtilities(bind);
145
147
  bind(PluginTreeViewNodeLabelProvider).toSelf().inSingletonScope();
146
148
  bind(LabelProviderContribution).toService(PluginTreeViewNodeLabelProvider);
147
149
  bind(WidgetFactory).toDynamicValue(({ container }) => ({
@@ -160,6 +162,7 @@ export default new ContainerModule((bind, unbind, isBound, rebind) => {
160
162
  tree: PluginTree,
161
163
  model: PluginTreeModel,
162
164
  widget: TreeViewWidget,
165
+ decoratorService: TreeViewDecoratorService
163
166
  });
164
167
  child.bind(TreeViewWidgetIdentifier).toConstantValue(identifier);
165
168
  return child.get(TreeWidget);
@@ -39,21 +39,33 @@ export class StatusBarMessageRegistryMainImpl implements StatusBarMessageRegistr
39
39
  }
40
40
 
41
41
  async $setMessage(id: string,
42
+ name: string | undefined,
42
43
  text: string | undefined,
43
44
  priority: number,
44
45
  alignment: number,
45
46
  color: string | undefined,
47
+ backgroundColor: string | undefined,
46
48
  tooltip: string | undefined,
47
49
  command: string | undefined,
50
+ accessibilityInformation: types.AccessibilityInformation,
48
51
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
49
52
  args: any[] | undefined): Promise<void> {
53
+ const ariaLabel = accessibilityInformation?.label;
54
+ const role = accessibilityInformation?.role;
55
+
50
56
  const entry = {
57
+ name,
51
58
  text: text || '',
59
+ ariaLabel,
60
+ role,
52
61
  priority,
53
62
  alignment: alignment === types.StatusBarAlignment.Left ? StatusBarAlignment.LEFT : StatusBarAlignment.RIGHT,
54
63
  color: color && (this.colorRegistry.getCurrentColor(color) || color),
64
+ // In contrast to color, the backgroundColor must be a theme color. Thus, do not hand in the plain string if it cannot be resolved.
65
+ backgroundColor: backgroundColor && (this.colorRegistry.getCurrentColor(backgroundColor)),
55
66
  tooltip,
56
67
  command,
68
+ accessibilityInformation,
57
69
  args
58
70
  };
59
71
 
@@ -0,0 +1,52 @@
1
+ /********************************************************************************
2
+ * Copyright (C) 2021 1C-Soft LLC and others.
3
+ *
4
+ * This program and the accompanying materials are made available under the
5
+ * terms of the Eclipse Public License v. 2.0 which is available at
6
+ * http://www.eclipse.org/legal/epl-2.0.
7
+ *
8
+ * This Source Code may also be made available under the following Secondary
9
+ * Licenses when the conditions for such availability set forth in the Eclipse
10
+ * Public License v. 2.0 are satisfied: GNU General Public License, version 2
11
+ * with the GNU Classpath Exception which is available at
12
+ * https://www.gnu.org/software/classpath/license.html.
13
+ *
14
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
15
+ ********************************************************************************/
16
+
17
+ import { inject, injectable, interfaces, named } from '@theia/core/shared/inversify';
18
+ import { AbstractTreeDecoratorService, TreeDecorator } from '@theia/core/lib/browser/tree/tree-decorator';
19
+ import { bindContributionProvider, ContributionProvider } from '@theia/core';
20
+ import { TreeNode } from '@theia/core/lib/browser';
21
+ import { TreeItem, Uri } from '@theia/plugin';
22
+ import URI from '@theia/core/lib/common/uri';
23
+ import { FileTreeDecoratorAdapter } from '@theia/filesystem/lib/browser';
24
+
25
+ export const TreeViewDecorator = Symbol('TreeViewDecorator');
26
+
27
+ @injectable()
28
+ export class TreeViewDecoratorAdapter extends FileTreeDecoratorAdapter {
29
+ protected override getUriForNode(node: TreeNode | TreeItem): string | undefined {
30
+ if (this.isTreeItem(node)) {
31
+ return new URI(node.resourceUri).toString();
32
+ }
33
+ }
34
+
35
+ protected isTreeItem(node: object | undefined): node is TreeItem & { resourceUri: Uri } {
36
+ const candidate = node as TreeItem;
37
+ return !!candidate && 'resourceUri' in candidate && !!candidate.resourceUri;
38
+ }
39
+ }
40
+
41
+ @injectable()
42
+ export class TreeViewDecoratorService extends AbstractTreeDecoratorService {
43
+ constructor(@inject(ContributionProvider) @named(TreeViewDecorator) contributions: ContributionProvider<TreeDecorator>) {
44
+ super(contributions.getContributions());
45
+ }
46
+ }
47
+
48
+ export function bindTreeViewDecoratorUtilities(bind: interfaces.Bind): void {
49
+ bind(TreeViewDecoratorAdapter).toSelf().inSingletonScope();
50
+ bindContributionProvider(bind, TreeViewDecorator);
51
+ bind(TreeViewDecorator).toService(TreeViewDecoratorAdapter);
52
+ }
@@ -45,6 +45,7 @@ import { ContextKeyService } from '@theia/core/lib/browser/context-key-service';
45
45
  import * as markdownit from '@theia/core/shared/markdown-it';
46
46
  import { isMarkdownString } from '../../../plugin/markdown-string';
47
47
  import { LabelParser } from '@theia/core/lib/browser/label-parser';
48
+ import { AccessibilityInformation } from '@theia/plugin';
48
49
 
49
50
  export const TREE_NODE_HYPERLINK = 'theia-TreeNodeHyperlink';
50
51
  export const VIEW_ITEM_CONTEXT_MENU: MenuPath = ['view-item-context-menu'];
@@ -63,6 +64,7 @@ export interface TreeViewNode extends SelectableTreeNode {
63
64
  tooltip?: string;
64
65
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
65
66
  description?: string | boolean | any;
67
+ accessibilityInformation?: AccessibilityInformation;
66
68
  }
67
69
  export namespace TreeViewNode {
68
70
  export function is(arg: TreeNode | undefined): arg is TreeViewNode {
@@ -159,6 +161,7 @@ export class PluginTree extends TreeImpl {
159
161
  tooltip: item.tooltip,
160
162
  contextValue: item.contextValue,
161
163
  command: item.command,
164
+ accessibilityInformation: item.accessibilityInformation,
162
165
  };
163
166
  const node = this.getNode(item.id);
164
167
  if (item.collapsibleState !== undefined && item.collapsibleState !== TreeViewItemCollapsibleState.None) {
@@ -301,6 +304,14 @@ export class TreeViewWidget extends TreeViewWelcomeWidget {
301
304
  id: node.id
302
305
  };
303
306
 
307
+ if (node.accessibilityInformation) {
308
+ attrs = {
309
+ ...attrs,
310
+ 'aria-label': node.accessibilityInformation.label,
311
+ 'role': node.accessibilityInformation.role
312
+ };
313
+ }
314
+
304
315
  if (node.tooltip && isMarkdownString(node.tooltip)) {
305
316
  // Render markdown in custom tooltip
306
317
  const tooltip = this.markdownIt.render(node.tooltip.value);
@@ -344,8 +355,11 @@ export class TreeViewWidget extends TreeViewWelcomeWidget {
344
355
  return this.contextKeys.with({ view: this.id, viewItem: node.contextValue }, () => {
345
356
  const menu = this.menus.getMenu(VIEW_ITEM_INLINE_MENU);
346
357
  const arg = this.toTreeViewSelection(node);
358
+ const inlineCommands = menu.children.filter((item): item is ActionMenuNode => item instanceof ActionMenuNode);
359
+ const tailDecorations = super.renderTailDecorations(node, props);
347
360
  return <React.Fragment>
348
- {menu.children.map((item, index) => item instanceof ActionMenuNode && this.renderInlineCommand(item, index, arg))}
361
+ {inlineCommands.length > 0 && <div className={TREE_NODE_SEGMENT_CLASS}>{inlineCommands.map((item, index) => this.renderInlineCommand(item, index, arg))}</div>}
362
+ {tailDecorations !== undefined && <div className={TREE_NODE_SEGMENT_CLASS}>{super.renderTailDecorations(node, props)}</div>}
349
363
  </React.Fragment>;
350
364
  });
351
365
  }
@@ -171,7 +171,7 @@ export class CommentsExtImpl implements CommentsExt {
171
171
 
172
172
  const documentData = this._documents.getDocumentData(URI.revive(uriComponents));
173
173
  if (documentData) {
174
- const ranges: theia.Range[] | undefined = await commentController.commentingRangeProvider!.provideCommentingRanges(documentData.document, token);
174
+ const ranges: theia.Range[] | undefined | null = await commentController.commentingRangeProvider!.provideCommentingRanges(documentData.document, token);
175
175
  if (ranges) {
176
176
  return ranges.map(x => fromRange(x));
177
177
  }
@@ -16,11 +16,11 @@
16
16
 
17
17
  import { URI } from '@theia/core/shared/vscode-uri';
18
18
  import * as theia from '@theia/plugin';
19
- import * as Converter from '../type-converters';
20
19
  import { DocumentsExtImpl } from '../documents';
21
- import * as model from '../../common/plugin-api-rpc-model';
20
+ import * as dto from '../../common/plugin-api-rpc-model';
22
21
  import * as rpc from '../../common/plugin-api-rpc';
23
22
  import * as types from '../types-impl';
23
+ import { fromRange } from '../type-converters';
24
24
 
25
25
  export class CallHierarchyAdapter {
26
26
 
@@ -29,9 +29,12 @@ export class CallHierarchyAdapter {
29
29
  private readonly documents: DocumentsExtImpl
30
30
  ) { }
31
31
 
32
+ protected sessionIds = 0;
33
+ protected readonly cache = new Map<string, Map<string, theia.CallHierarchyItem>>();
34
+
32
35
  async provideRootDefinition(
33
36
  resource: URI, position: rpc.Position, token: theia.CancellationToken
34
- ): Promise<model.CallHierarchyDefinition | model.CallHierarchyDefinition[] | undefined> {
37
+ ): Promise<dto.CallHierarchyItem[] | undefined> {
35
38
  const documentData = this.documents.getDocumentData(resource);
36
39
  if (!documentData) {
37
40
  return Promise.reject(new Error(`There is no document for ${resource}`));
@@ -48,83 +51,74 @@ export class CallHierarchyAdapter {
48
51
  if (!definition) {
49
52
  return undefined;
50
53
  }
51
-
52
- return Array.isArray(definition) ? definition.map(item => this.fromCallHierarchyItem(item)) : this.fromCallHierarchyItem(definition);
54
+ const sessionId = (this.sessionIds++).toString(36);
55
+ this.cache.set(sessionId, new Map());
56
+ return Array.isArray(definition) ? definition.map(item => this.fromCallHierarchyItem(item, sessionId)) : [this.fromCallHierarchyItem(definition, sessionId)];
53
57
  }
54
58
 
55
- async provideCallers(definition: model.CallHierarchyDefinition, token: theia.CancellationToken): Promise<model.CallHierarchyReference[] | undefined> {
59
+ async provideCallers(definition: dto.CallHierarchyItem, token: theia.CancellationToken): Promise<dto.CallHierarchyIncomingCall[] | undefined> {
56
60
  const callers = await this.provider.provideCallHierarchyIncomingCalls(this.toCallHierarchyItem(definition), token);
57
61
  if (!callers) {
58
62
  return undefined;
59
63
  }
60
64
 
61
- return callers.map(item => this.fromCallHierarchyIncomingCall(item));
65
+ return callers.map(item => this.fromCallHierarchyIncomingCall(item, definition._sessionId!));
62
66
  }
63
67
 
64
- async provideCallees(definition: model.CallHierarchyDefinition, token: theia.CancellationToken): Promise<model.CallHierarchyReference[] | undefined> {
68
+ async provideCallees(definition: dto.CallHierarchyItem, token: theia.CancellationToken): Promise<dto.CallHierarchyOutgoingCall[] | undefined> {
65
69
  const callees = await this.provider.provideCallHierarchyOutgoingCalls(this.toCallHierarchyItem(definition), token);
66
70
  if (!callees) {
67
71
  return undefined;
68
72
  }
69
73
 
70
- return callees.map(item => this.fromCallHierarchyOutgoingCall(item));
74
+ return callees.map(item => this.fromCallHierarchyOutgoingCall(item, definition._sessionId!));
71
75
  }
72
76
 
73
- private fromCallHierarchyItem(item: theia.CallHierarchyItem): model.CallHierarchyDefinition {
74
- return {
77
+ private fromCallHierarchyItem(item: theia.CallHierarchyItem, sessionId: string): dto.CallHierarchyItem {
78
+ const sessionCache = this.cache.get(sessionId)!;
79
+ const itemId = sessionCache.size.toString(36);
80
+ const definition: dto.CallHierarchyItem = {
75
81
  uri: item.uri,
76
- range: this.fromRange(item.range),
77
- selectionRange: this.fromRange(item.selectionRange),
82
+ range: fromRange(item.range),
83
+ selectionRange: fromRange(item.selectionRange),
78
84
  name: item.name,
79
85
  kind: item.kind,
80
86
  tags: item.tags,
81
- data: item.data,
82
- };
83
- }
84
-
85
- private fromRange(range: theia.Range): model.Range {
86
- return {
87
- startLineNumber: range.start.line + 1,
88
- startColumn: range.start.character + 1,
89
- endLineNumber: range.end.line + 1,
90
- endColumn: range.end.character + 1,
87
+ _itemId: itemId,
88
+ _sessionId: sessionId,
91
89
  };
90
+ sessionCache.set(itemId, item);
91
+ return definition;
92
92
  }
93
93
 
94
- private toRange(range: model.Range): types.Range {
95
- return new types.Range(
96
- range.startLineNumber - 1,
97
- range.startColumn - 1,
98
- range.endLineNumber - 1,
99
- range.endColumn - 1,
100
- );
101
- }
102
-
103
- private toCallHierarchyItem(definition: model.CallHierarchyDefinition): theia.CallHierarchyItem {
104
- const item = new types.CallHierarchyItem(
105
- Converter.SymbolKind.toSymbolKind(definition.kind),
106
- definition.name,
107
- definition.detail ? definition.detail : '',
108
- URI.revive(definition.uri),
109
- this.toRange(definition.range),
110
- this.toRange(definition.selectionRange),
111
- );
112
- item.tags = definition.tags;
113
- item.data = definition.data;
114
- return item;
94
+ private toCallHierarchyItem(definition: dto.CallHierarchyItem): theia.CallHierarchyItem {
95
+ const cached = this.cache.get(definition._sessionId!)?.get(definition._itemId!);
96
+ if (!cached) {
97
+ throw new Error(`Found no cached item corresponding to ${definition.name} in ${definition.uri.path} with ID ${definition.data}.`);
98
+ }
99
+ return cached;
115
100
  }
116
101
 
117
- private fromCallHierarchyIncomingCall(caller: theia.CallHierarchyIncomingCall): model.CallHierarchyReference {
102
+ private fromCallHierarchyIncomingCall(caller: theia.CallHierarchyIncomingCall, sessionId: string): dto.CallHierarchyIncomingCall {
118
103
  return {
119
- callerDefinition: this.fromCallHierarchyItem(caller.from),
120
- references: caller.fromRanges.map(l => this.fromRange(l))
104
+ from: this.fromCallHierarchyItem(caller.from, sessionId),
105
+ fromRanges: caller.fromRanges.map(r => fromRange(r))
121
106
  };
122
107
  }
123
108
 
124
- protected fromCallHierarchyOutgoingCall(caller: theia.CallHierarchyOutgoingCall): model.CallHierarchyReference {
109
+ protected fromCallHierarchyOutgoingCall(caller: theia.CallHierarchyOutgoingCall, sessionId: string): dto.CallHierarchyOutgoingCall {
125
110
  return {
126
- callerDefinition: this.fromCallHierarchyItem(caller.to),
127
- references: caller.fromRanges.map(this.fromRange.bind(this)),
111
+ to: this.fromCallHierarchyItem(caller.to, sessionId),
112
+ fromRanges: caller.fromRanges.map(r => fromRange(r)),
128
113
  };
129
114
  }
115
+
116
+ releaseSession(session?: string): Promise<boolean> {
117
+ if (session !== undefined) {
118
+ return Promise.resolve(this.cache.delete(session));
119
+ } else {
120
+ this.cache.clear();
121
+ return Promise.resolve(true);
122
+ }
123
+ }
130
124
  }
@@ -71,7 +71,7 @@ export class CodeLensAdapter {
71
71
  return undefined;
72
72
  }
73
73
 
74
- let newLens: theia.CodeLens | undefined;
74
+ let newLens: theia.CodeLens | undefined | null;
75
75
  if (typeof this.provider.resolveCodeLens === 'function' && !lens.isResolved) {
76
76
  newLens = await this.provider.resolveCodeLens(lens, token);
77
77
  if (token.isCancellationRequested) {
@@ -59,9 +59,10 @@ import {
59
59
  CodeAction,
60
60
  FoldingRange,
61
61
  SelectionRange,
62
- CallHierarchyDefinition,
63
- CallHierarchyReference,
64
- ChainedCacheId
62
+ ChainedCacheId,
63
+ CallHierarchyItem,
64
+ CallHierarchyIncomingCall,
65
+ CallHierarchyOutgoingCall,
65
66
  } from '../common/plugin-api-rpc-model';
66
67
  import { CompletionAdapter } from './languages/completion';
67
68
  import { Diagnostics } from './languages/diagnostics';
@@ -612,17 +613,21 @@ export class LanguagesExtImpl implements LanguagesExt {
612
613
 
613
614
  $provideRootDefinition(
614
615
  handle: number, resource: UriComponents, location: Position, token: theia.CancellationToken
615
- ): Promise<CallHierarchyDefinition | CallHierarchyDefinition[] | undefined> {
616
+ ): Promise<CallHierarchyItem[] | undefined> {
616
617
  return this.withAdapter(handle, CallHierarchyAdapter, adapter => adapter.provideRootDefinition(URI.revive(resource), location, token), undefined);
617
618
  }
618
619
 
619
- $provideCallers(handle: number, definition: CallHierarchyDefinition, token: theia.CancellationToken): Promise<CallHierarchyReference[] | undefined> {
620
+ $provideCallers(handle: number, definition: CallHierarchyItem, token: theia.CancellationToken): Promise<CallHierarchyIncomingCall[] | undefined> {
620
621
  return this.withAdapter(handle, CallHierarchyAdapter, adapter => adapter.provideCallers(definition, token), undefined);
621
622
  }
622
623
 
623
- $provideCallees(handle: number, definition: CallHierarchyDefinition, token: theia.CancellationToken): Promise<CallHierarchyReference[] | undefined> {
624
+ $provideCallees(handle: number, definition: CallHierarchyItem, token: theia.CancellationToken): Promise<CallHierarchyOutgoingCall[] | undefined> {
624
625
  return this.withAdapter(handle, CallHierarchyAdapter, adapter => adapter.provideCallees(definition, token), undefined);
625
626
  }
627
+
628
+ $releaseCallHierarchy(handle: number, session?: string): Promise<boolean> {
629
+ return this.withAdapter(handle, CallHierarchyAdapter, adapter => adapter.releaseSession(session), false);
630
+ }
626
631
  // ### Call Hierarchy Provider end
627
632
 
628
633
  // #region semantic coloring
@@ -233,6 +233,7 @@ export class DebugExtImpl implements DebugExt {
233
233
  const session = this.sessions.get(sessionId);
234
234
  if (session) {
235
235
  this.onDidTerminateDebugSessionEmitter.fire(session);
236
+ this.sessions.delete(sessionId);
236
237
  }
237
238
  }
238
239
 
@@ -322,7 +323,6 @@ export class DebugExtImpl implements DebugExt {
322
323
  const debugAdapterSession = this.sessions.get(sessionId);
323
324
  if (debugAdapterSession) {
324
325
  await debugAdapterSession.stop();
325
- this.sessions.delete(sessionId);
326
326
  }
327
327
  }
328
328
 
@@ -346,12 +346,20 @@ export class DebugExtImpl implements DebugExt {
346
346
  return { provider, type };
347
347
  }
348
348
 
349
- async $provideDebugConfigurationsByHandle(handle: number, workspaceFolderUri: string | undefined): Promise<theia.DebugConfiguration[]> {
349
+ async $provideDebugConfigurationsByHandle(
350
+ handle: number,
351
+ workspaceFolderUri: string | undefined
352
+ ): Promise<theia.DebugConfiguration[]> {
350
353
  const { provider, type } = this.getConfigurationProviderRecord(handle);
351
354
 
352
- const configurations = await provider.provideDebugConfigurations?.(this.toWorkspaceFolder(workspaceFolderUri));
355
+ const configurations = await provider.provideDebugConfigurations?.(
356
+ this.toWorkspaceFolder(workspaceFolderUri)
357
+ );
358
+
353
359
  if (!configurations) {
354
- throw new Error('nothing returned from DebugConfigurationProvider.provideDebugConfigurations, type: ' + type);
360
+ throw new Error(
361
+ 'nothing returned from DebugConfigurationProvider.provideDebugConfigurations, type: ' + type
362
+ );
355
363
  }
356
364
 
357
365
  return configurations;
@@ -361,88 +369,24 @@ export class DebugExtImpl implements DebugExt {
361
369
  handle: number,
362
370
  workspaceFolderUri: string | undefined,
363
371
  debugConfiguration: theia.DebugConfiguration
364
- ): Promise<theia.DebugConfiguration | undefined> {
365
-
372
+ ): Promise<theia.DebugConfiguration | undefined | null> {
366
373
  const { provider } = this.getConfigurationProviderRecord(handle);
367
- return provider.resolveDebugConfiguration?.(this.toWorkspaceFolder(workspaceFolderUri), debugConfiguration);
374
+ return provider.resolveDebugConfiguration?.(
375
+ this.toWorkspaceFolder(workspaceFolderUri),
376
+ debugConfiguration
377
+ );
368
378
  }
369
379
 
370
380
  async $resolveDebugConfigurationWithSubstitutedVariablesByHandle(
371
381
  handle: number,
372
382
  workspaceFolderUri: string | undefined,
373
383
  debugConfiguration: theia.DebugConfiguration
374
- ): Promise<theia.DebugConfiguration | undefined> {
375
-
384
+ ): Promise<theia.DebugConfiguration | undefined | null> {
376
385
  const { provider } = this.getConfigurationProviderRecord(handle);
377
- return provider.resolveDebugConfigurationWithSubstitutedVariables?.(this.toWorkspaceFolder(workspaceFolderUri), debugConfiguration);
378
- }
379
-
380
- async $provideDebugConfigurations(debugType: string, workspaceFolderUri: string | undefined, dynamic: boolean = false): Promise<theia.DebugConfiguration[]> {
381
- let result: theia.DebugConfiguration[] = [];
382
-
383
- const trigger = dynamic ? DebugConfigurationProviderTriggerKind.Dynamic : DebugConfigurationProviderTriggerKind.Initial;
384
- const providers = this.configurationProviders
385
- .filter(p => p.type === debugType && p.trigger === trigger)
386
- .map(p => p.provider);
387
-
388
- for (const provider of providers) {
389
- if (provider.provideDebugConfigurations) {
390
- result = result.concat(await provider.provideDebugConfigurations(this.toWorkspaceFolder(workspaceFolderUri)) || []);
391
- }
392
- }
393
-
394
- return result;
395
- }
396
-
397
- async $resolveDebugConfigurations(debugConfiguration: theia.DebugConfiguration, workspaceFolderUri: string | undefined): Promise<theia.DebugConfiguration | undefined> {
398
- let current = debugConfiguration;
399
-
400
- const providers = this.configurationProviders
401
- .filter(p => p.type === debugConfiguration.type || p.type === '*')
402
- .map(p => p.provider);
403
-
404
- for (const provider of providers) {
405
- if (provider.resolveDebugConfiguration) {
406
- try {
407
- const next = await provider.resolveDebugConfiguration(this.toWorkspaceFolder(workspaceFolderUri), current);
408
- if (next) {
409
- current = next;
410
- } else {
411
- return current;
412
- }
413
- } catch (e) {
414
- console.error(e);
415
- }
416
- }
417
- }
418
-
419
- return current;
420
- }
421
-
422
- async $resolveDebugConfigurationWithSubstitutedVariables(debugConfiguration: theia.DebugConfiguration, workspaceFolderUri: string | undefined):
423
- Promise<theia.DebugConfiguration | undefined> {
424
- let current = debugConfiguration;
425
-
426
- const providers = this.configurationProviders
427
- .filter(p => p.type === debugConfiguration.type || p.type === '*')
428
- .map(p => p.provider);
429
-
430
- for (const provider of providers) {
431
- if (provider.resolveDebugConfigurationWithSubstitutedVariables) {
432
- try {
433
- const next = await provider.resolveDebugConfigurationWithSubstitutedVariables(this.toWorkspaceFolder(workspaceFolderUri), current);
434
- if (next) {
435
- current = next;
436
- } else {
437
- return current;
438
- }
439
- } catch (e) {
440
- console.error(e);
441
- }
442
- }
443
- }
444
-
445
- return current;
386
+ return provider.resolveDebugConfigurationWithSubstitutedVariables?.(
387
+ this.toWorkspaceFolder(workspaceFolderUri),
388
+ debugConfiguration
389
+ );
446
390
  }
447
391
 
448
392
  protected async createDebugAdapterTracker(session: theia.DebugSession): Promise<theia.DebugAdapterTracker> {
@@ -23,6 +23,7 @@ import { Deferred } from '@theia/core/lib/common/promise-util';
23
23
 
24
24
  export class NotificationExtImpl implements NotificationExt {
25
25
  private readonly proxy: NotificationMain;
26
+ private mapProgressIdToCancellationSource: Map<string, CancellationTokenSource> = new Map();
26
27
 
27
28
  constructor(rpc: RPCProtocol) {
28
29
  this.proxy = rpc.getProxy(PLUGIN_RPC_CONTEXT.NOTIFICATION_MAIN);
@@ -32,13 +33,20 @@ export class NotificationExtImpl implements NotificationExt {
32
33
  options: ProgressOptions,
33
34
  task: (progress: Progress<{ message?: string; increment?: number }>, token: CancellationToken) => PromiseLike<R>
34
35
  ): Promise<R> {
36
+ const source = new CancellationTokenSource();
35
37
  const id = new Deferred<string>();
36
- const tokenSource = new CancellationTokenSource();
37
- const progress = task({ report: async item => this.proxy.$updateProgress(await id.promise, item)}, tokenSource.token);
38
+ const progress = task({ report: async item => this.proxy.$updateProgress(await id.promise, item)}, source.token);
38
39
  const title = options.title ? options.title : '';
39
40
  const location = this.mapLocation(options.location);
40
41
  const cancellable = options.cancellable;
42
+
41
43
  id.resolve(await this.proxy.$startProgress({ title, location, cancellable }));
44
+
45
+ if (cancellable) {
46
+ const progressId = await id.promise;
47
+ this.mapProgressIdToCancellationSource.set(progressId, source);
48
+ }
49
+
42
50
  const stop = async () => this.proxy.$stopProgress(await id.promise);
43
51
  const promise = Promise.all([
44
52
  progress,
@@ -48,6 +56,14 @@ export class NotificationExtImpl implements NotificationExt {
48
56
  return progress;
49
57
  }
50
58
 
59
+ public $acceptProgressCanceled(id: string): void {
60
+ const source = this.mapProgressIdToCancellationSource.get(id);
61
+ if (source) {
62
+ source.cancel();
63
+ this.mapProgressIdToCancellationSource.delete(id);
64
+ }
65
+ }
66
+
51
67
  protected mapLocation(location: ProgressLocation | { viewId: string }): string | undefined {
52
68
  if (typeof location === 'object') {
53
69
  return location.viewId;