a26b77bb18d8e6a3952130ec33763ca00c1e05dd19a8331c316b2a2e061ec198f0bb78d8ca8c33838434a1a960609320431bf792cbfe2358ff9c7fcdd8cd96 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488
  1. /*---------------------------------------------------------------------------------------------
  2. * Copyright (c) Microsoft Corporation. All rights reserved.
  3. * Licensed under the MIT License. See License.txt in the project root for license information.
  4. *--------------------------------------------------------------------------------------------*/
  5. var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
  6. var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
  7. if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
  8. else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
  9. return c > 3 && r && Object.defineProperty(target, key, r), r;
  10. };
  11. var __param = (this && this.__param) || function (paramIndex, decorator) {
  12. return function (target, key) { decorator(target, key, paramIndex); }
  13. };
  14. var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
  15. function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
  16. return new (P || (P = Promise))(function (resolve, reject) {
  17. function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
  18. function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
  19. function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
  20. step((generator = generator.apply(thisArg, _arguments || [])).next());
  21. });
  22. };
  23. import * as dom from '../../../../base/browser/dom.js';
  24. import { List } from '../../../../base/browser/ui/list/listWidget.js';
  25. import { Action, Separator } from '../../../../base/common/actions.js';
  26. import { canceled } from '../../../../base/common/errors.js';
  27. import { Lazy } from '../../../../base/common/lazy.js';
  28. import { Disposable, dispose, MutableDisposable, DisposableStore } from '../../../../base/common/lifecycle.js';
  29. import './media/action.css';
  30. import { Position } from '../../../common/core/position.js';
  31. import { ILanguageFeaturesService } from '../../../common/services/languageFeatures.js';
  32. import { codeActionCommandId, CodeActionItem, fixAllCommandId, organizeImportsCommandId, refactorCommandId, sourceActionCommandId } from './codeAction.js';
  33. import { CodeActionCommandArgs, CodeActionKind, CodeActionTriggerSource } from './types.js';
  34. import { localize } from '../../../../nls.js';
  35. import { IConfigurationService } from '../../../../platform/configuration/common/configuration.js';
  36. import { IContextKeyService, RawContextKey } from '../../../../platform/contextkey/common/contextkey.js';
  37. import { IContextMenuService, IContextViewService } from '../../../../platform/contextview/browser/contextView.js';
  38. import { IKeybindingService } from '../../../../platform/keybinding/common/keybinding.js';
  39. import { ITelemetryService } from '../../../../platform/telemetry/common/telemetry.js';
  40. import { IThemeService } from '../../../../platform/theme/common/themeService.js';
  41. export const Context = {
  42. Visible: new RawContextKey('CodeActionMenuVisible', false, localize('CodeActionMenuVisible', "Whether the code action list widget is visible"))
  43. };
  44. class CodeActionAction extends Action {
  45. constructor(action, callback) {
  46. super(action.command ? action.command.id : action.title, stripNewlines(action.title), undefined, !action.disabled, callback);
  47. this.action = action;
  48. }
  49. }
  50. function stripNewlines(str) {
  51. return str.replace(/\r\n|\r|\n/g, ' ');
  52. }
  53. const TEMPLATE_ID = 'codeActionWidget';
  54. const codeActionLineHeight = 26;
  55. let CodeMenuRenderer = class CodeMenuRenderer {
  56. constructor(acceptKeybindings, keybindingService) {
  57. this.acceptKeybindings = acceptKeybindings;
  58. this.keybindingService = keybindingService;
  59. }
  60. get templateId() { return TEMPLATE_ID; }
  61. renderTemplate(container) {
  62. const data = Object.create(null);
  63. data.disposables = [];
  64. data.root = container;
  65. data.text = document.createElement('span');
  66. // data.detail = document.createElement('');
  67. container.append(data.text);
  68. // container.append(data.detail);
  69. return data;
  70. }
  71. renderElement(element, index, templateData) {
  72. const data = templateData;
  73. const text = element.title;
  74. // const detail = element.detail;
  75. const isEnabled = element.isEnabled;
  76. const isSeparator = element.isSeparator;
  77. const isDocumentation = element.isDocumentation;
  78. data.text.textContent = text;
  79. // data.detail.textContent = detail;
  80. if (!isEnabled) {
  81. data.root.classList.add('option-disabled');
  82. data.root.style.backgroundColor = 'transparent !important';
  83. }
  84. else {
  85. data.root.classList.remove('option-disabled');
  86. }
  87. if (isSeparator) {
  88. data.root.classList.add('separator');
  89. data.root.style.height = '10px';
  90. }
  91. if (!isDocumentation) {
  92. const updateLabel = () => {
  93. var _a, _b;
  94. const [accept, preview] = this.acceptKeybindings;
  95. data.root.title = localize({ key: 'label', comment: ['placeholders are keybindings, e.g "F2 to Refactor, Shift+F2 to Preview"'] }, "{0} to Refactor, {1} to Preview", (_a = this.keybindingService.lookupKeybinding(accept)) === null || _a === void 0 ? void 0 : _a.getLabel(), (_b = this.keybindingService.lookupKeybinding(preview)) === null || _b === void 0 ? void 0 : _b.getLabel());
  96. // data.root.title = this.keybindingService.lookupKeybinding(accept)?.getLabel() + ' to Refactor, ' + this.keybindingService.lookupKeybinding(preview)?.getLabel() + ' to Preview';
  97. };
  98. updateLabel();
  99. }
  100. }
  101. disposeTemplate(templateData) {
  102. templateData.disposables = dispose(templateData.disposables);
  103. }
  104. };
  105. CodeMenuRenderer = __decorate([
  106. __param(1, IKeybindingService)
  107. ], CodeMenuRenderer);
  108. let CodeActionMenu = class CodeActionMenu extends Disposable {
  109. constructor(_editor, _delegate, _contextMenuService, keybindingService, _languageFeaturesService, _telemetryService, _themeService, _configurationService, _contextViewService, _contextKeyService) {
  110. super();
  111. this._editor = _editor;
  112. this._delegate = _delegate;
  113. this._contextMenuService = _contextMenuService;
  114. this._languageFeaturesService = _languageFeaturesService;
  115. this._telemetryService = _telemetryService;
  116. this._configurationService = _configurationService;
  117. this._contextViewService = _contextViewService;
  118. this._contextKeyService = _contextKeyService;
  119. this._showingActions = this._register(new MutableDisposable());
  120. this.codeActionList = this._register(new MutableDisposable());
  121. this.options = [];
  122. this._visible = false;
  123. this.viewItems = [];
  124. this.hasSeperator = false;
  125. this._keybindingResolver = new CodeActionKeybindingResolver({
  126. getKeybindings: () => keybindingService.getKeybindings()
  127. });
  128. this._ctxMenuWidgetVisible = Context.Visible.bindTo(this._contextKeyService);
  129. this.listRenderer = new CodeMenuRenderer([`onEnterSelectCodeAction`, `onEnterSelectCodeActionWithPreview`], keybindingService);
  130. }
  131. get isVisible() {
  132. return this._visible;
  133. }
  134. isCodeActionWidgetEnabled(model) {
  135. return this._configurationService.getValue('editor.experimental.useCustomCodeActionMenu', {
  136. resource: model.uri
  137. });
  138. }
  139. _onListSelection(e) {
  140. if (e.elements.length) {
  141. e.elements.forEach(element => {
  142. if (element.isEnabled) {
  143. element.action.run();
  144. this.hideCodeActionWidget();
  145. }
  146. });
  147. }
  148. }
  149. _onListHover(e) {
  150. var _a, _b, _c, _d;
  151. if (!e.element) {
  152. this.currSelectedItem = undefined;
  153. (_a = this.codeActionList.value) === null || _a === void 0 ? void 0 : _a.setFocus([]);
  154. }
  155. else {
  156. if ((_b = e.element) === null || _b === void 0 ? void 0 : _b.isEnabled) {
  157. (_c = this.codeActionList.value) === null || _c === void 0 ? void 0 : _c.setFocus([e.element.index]);
  158. this.focusedEnabledItem = this.viewItems.indexOf(e.element);
  159. this.currSelectedItem = e.element.index;
  160. }
  161. else {
  162. this.currSelectedItem = undefined;
  163. (_d = this.codeActionList.value) === null || _d === void 0 ? void 0 : _d.setFocus([e.element.index]);
  164. }
  165. }
  166. }
  167. renderCodeActionMenuList(element, inputArray) {
  168. var _a;
  169. const renderDisposables = new DisposableStore();
  170. const renderMenu = document.createElement('div');
  171. // Render invisible div to block mouse interaction in the rest of the UI
  172. const menuBlock = document.createElement('div');
  173. this.block = element.appendChild(menuBlock);
  174. this.block.classList.add('context-view-block');
  175. this.block.style.position = 'fixed';
  176. this.block.style.cursor = 'initial';
  177. this.block.style.left = '0';
  178. this.block.style.top = '0';
  179. this.block.style.width = '100%';
  180. this.block.style.height = '100%';
  181. this.block.style.zIndex = '-1';
  182. renderDisposables.add(dom.addDisposableListener(this.block, dom.EventType.MOUSE_DOWN, e => e.stopPropagation()));
  183. renderMenu.id = 'codeActionMenuWidget';
  184. renderMenu.classList.add('codeActionMenuWidget');
  185. element.appendChild(renderMenu);
  186. this.codeActionList.value = new List('codeActionWidget', renderMenu, {
  187. getHeight(element) {
  188. if (element.isSeparator) {
  189. return 10;
  190. }
  191. return codeActionLineHeight;
  192. },
  193. getTemplateId(element) {
  194. return 'codeActionWidget';
  195. }
  196. }, [this.listRenderer], { keyboardSupport: false });
  197. renderDisposables.add(this.codeActionList.value.onMouseOver(e => this._onListHover(e)));
  198. renderDisposables.add(this.codeActionList.value.onDidChangeFocus(e => { var _a; return (_a = this.codeActionList.value) === null || _a === void 0 ? void 0 : _a.domFocus(); }));
  199. renderDisposables.add(this.codeActionList.value.onDidChangeSelection(e => this._onListSelection(e)));
  200. renderDisposables.add(this._editor.onDidLayoutChange(e => this.hideCodeActionWidget()));
  201. // Populating the list widget and tracking enabled options.
  202. inputArray.forEach((item, index) => {
  203. const currIsSeparator = item.class === 'separator';
  204. let isDocumentation = false;
  205. if (item instanceof CodeActionAction) {
  206. isDocumentation = item.action.kind === CodeActionMenu.documentationID;
  207. }
  208. if (currIsSeparator) {
  209. // set to true forever
  210. this.hasSeperator = true;
  211. }
  212. const menuItem = { title: item.label, detail: item.tooltip, action: inputArray[index], isEnabled: item.enabled, isSeparator: currIsSeparator, index, isDocumentation };
  213. if (item.enabled) {
  214. this.viewItems.push(menuItem);
  215. }
  216. this.options.push(menuItem);
  217. });
  218. this.codeActionList.value.splice(0, this.codeActionList.value.length, this.options);
  219. const height = this.hasSeperator ? (inputArray.length - 1) * codeActionLineHeight + 10 : inputArray.length * codeActionLineHeight;
  220. renderMenu.style.height = String(height) + 'px';
  221. this.codeActionList.value.layout(height);
  222. // For finding width dynamically (not using resize observer)
  223. const arr = [];
  224. this.options.forEach((item, index) => {
  225. var _a, _b;
  226. if (!this.codeActionList.value) {
  227. return;
  228. }
  229. const element = (_b = document.getElementById((_a = this.codeActionList.value) === null || _a === void 0 ? void 0 : _a.getElementID(index))) === null || _b === void 0 ? void 0 : _b.getElementsByTagName('span')[0].offsetWidth;
  230. arr.push(Number(element));
  231. });
  232. // resize observer - can be used in the future since list widget supports dynamic height but not width
  233. const maxWidth = Math.max(...arr);
  234. // 40 is the additional padding for the list widget (20 left, 20 right)
  235. renderMenu.style.width = maxWidth + 52 + 'px';
  236. (_a = this.codeActionList.value) === null || _a === void 0 ? void 0 : _a.layout(height, maxWidth);
  237. // List selection
  238. if (this.viewItems.length < 1 || this.viewItems.every(item => item.isDocumentation)) {
  239. this.currSelectedItem = undefined;
  240. }
  241. else {
  242. this.focusedEnabledItem = 0;
  243. this.currSelectedItem = this.viewItems[0].index;
  244. this.codeActionList.value.setFocus([this.currSelectedItem]);
  245. }
  246. // List Focus
  247. this.codeActionList.value.domFocus();
  248. const focusTracker = dom.trackFocus(element);
  249. const blurListener = focusTracker.onDidBlur(() => {
  250. this.hideCodeActionWidget();
  251. // this._contextViewService.hideContextView({ source: this });
  252. });
  253. renderDisposables.add(blurListener);
  254. renderDisposables.add(focusTracker);
  255. this._ctxMenuWidgetVisible.set(true);
  256. return renderDisposables;
  257. }
  258. focusPrevious() {
  259. var _a;
  260. if (typeof this.focusedEnabledItem === 'undefined') {
  261. this.focusedEnabledItem = this.viewItems[0].index;
  262. }
  263. else if (this.viewItems.length < 1) {
  264. return false;
  265. }
  266. const startIndex = this.focusedEnabledItem;
  267. let item;
  268. do {
  269. this.focusedEnabledItem = this.focusedEnabledItem - 1;
  270. if (this.focusedEnabledItem < 0) {
  271. this.focusedEnabledItem = this.viewItems.length - 1;
  272. }
  273. item = this.viewItems[this.focusedEnabledItem];
  274. (_a = this.codeActionList.value) === null || _a === void 0 ? void 0 : _a.setFocus([item.index]);
  275. this.currSelectedItem = item.index;
  276. } while (this.focusedEnabledItem !== startIndex && ((!item.isEnabled) || item.action.id === Separator.ID));
  277. return true;
  278. }
  279. focusNext() {
  280. var _a;
  281. if (typeof this.focusedEnabledItem === 'undefined') {
  282. this.focusedEnabledItem = this.viewItems.length - 1;
  283. }
  284. else if (this.viewItems.length < 1) {
  285. return false;
  286. }
  287. const startIndex = this.focusedEnabledItem;
  288. let item;
  289. do {
  290. this.focusedEnabledItem = (this.focusedEnabledItem + 1) % this.viewItems.length;
  291. item = this.viewItems[this.focusedEnabledItem];
  292. (_a = this.codeActionList.value) === null || _a === void 0 ? void 0 : _a.setFocus([item.index]);
  293. this.currSelectedItem = item.index;
  294. } while (this.focusedEnabledItem !== startIndex && ((!item.isEnabled) || item.action.id === Separator.ID));
  295. return true;
  296. }
  297. navigateListWithKeysUp() {
  298. this.focusPrevious();
  299. }
  300. navigateListWithKeysDown() {
  301. this.focusNext();
  302. }
  303. onEnterSet() {
  304. var _a;
  305. if (typeof this.currSelectedItem === 'number') {
  306. (_a = this.codeActionList.value) === null || _a === void 0 ? void 0 : _a.setSelection([this.currSelectedItem]);
  307. }
  308. }
  309. dispose() {
  310. super.dispose();
  311. }
  312. hideCodeActionWidget() {
  313. this._ctxMenuWidgetVisible.reset();
  314. this.options = [];
  315. this.viewItems = [];
  316. this.focusedEnabledItem = 0;
  317. this.currSelectedItem = undefined;
  318. this.hasSeperator = false;
  319. this._contextViewService.hideContextView({ source: this });
  320. }
  321. codeActionTelemetry(openedFromString, didCancel, CodeActions) {
  322. this._telemetryService.publicLog2('codeAction.applyCodeAction', {
  323. codeActionFrom: openedFromString,
  324. validCodeActions: CodeActions.validActions.length,
  325. cancelled: didCancel,
  326. });
  327. }
  328. show(trigger, codeActions, at, options) {
  329. return __awaiter(this, void 0, void 0, function* () {
  330. const model = this._editor.getModel();
  331. if (!model) {
  332. return;
  333. }
  334. const actionsToShow = options.includeDisabledActions ? codeActions.allActions : codeActions.validActions;
  335. if (!actionsToShow.length) {
  336. this._visible = false;
  337. return;
  338. }
  339. if (!this._editor.getDomNode()) {
  340. // cancel when editor went off-dom
  341. this._visible = false;
  342. throw canceled();
  343. }
  344. this._visible = true;
  345. this._showingActions.value = codeActions;
  346. const menuActions = this.getMenuActions(trigger, actionsToShow, codeActions.documentation);
  347. const anchor = Position.isIPosition(at) ? this._toCoords(at) : at || { x: 0, y: 0 };
  348. const resolver = this._keybindingResolver.getResolver();
  349. const useShadowDOM = this._editor.getOption(117 /* EditorOption.useShadowDOM */);
  350. if (this.isCodeActionWidgetEnabled(model)) {
  351. this._contextViewService.showContextView({
  352. getAnchor: () => anchor,
  353. render: (container) => this.renderCodeActionMenuList(container, menuActions),
  354. onHide: (didCancel) => {
  355. const openedFromString = (options.fromLightbulb) ? CodeActionTriggerSource.Lightbulb : trigger.triggerAction;
  356. this.codeActionTelemetry(openedFromString, didCancel, codeActions);
  357. this._visible = false;
  358. this._editor.focus();
  359. },
  360. }, this._editor.getDomNode(), false);
  361. }
  362. else {
  363. this._contextMenuService.showContextMenu({
  364. domForShadowRoot: useShadowDOM ? this._editor.getDomNode() : undefined,
  365. getAnchor: () => anchor,
  366. getActions: () => menuActions,
  367. onHide: (didCancel) => {
  368. const openedFromString = (options.fromLightbulb) ? CodeActionTriggerSource.Lightbulb : trigger.triggerAction;
  369. this.codeActionTelemetry(openedFromString, didCancel, codeActions);
  370. this._visible = false;
  371. this._editor.focus();
  372. },
  373. autoSelectFirstItem: true,
  374. getKeyBinding: action => action instanceof CodeActionAction ? resolver(action.action) : undefined,
  375. });
  376. }
  377. });
  378. }
  379. getMenuActions(trigger, actionsToShow, documentation) {
  380. var _a, _b;
  381. const toCodeActionAction = (item) => new CodeActionAction(item.action, () => this._delegate.onSelectCodeAction(item, trigger));
  382. const result = actionsToShow
  383. .map(toCodeActionAction);
  384. const allDocumentation = [...documentation];
  385. const model = this._editor.getModel();
  386. if (model && result.length) {
  387. for (const provider of this._languageFeaturesService.codeActionProvider.all(model)) {
  388. if (provider._getAdditionalMenuItems) {
  389. allDocumentation.push(...provider._getAdditionalMenuItems({ trigger: trigger.type, only: (_b = (_a = trigger.filter) === null || _a === void 0 ? void 0 : _a.include) === null || _b === void 0 ? void 0 : _b.value }, actionsToShow.map(item => item.action)));
  390. }
  391. }
  392. }
  393. if (allDocumentation.length) {
  394. result.push(new Separator(), ...allDocumentation.map(command => toCodeActionAction(new CodeActionItem({
  395. title: command.title,
  396. command: command,
  397. kind: CodeActionMenu.documentationID
  398. }, undefined))));
  399. }
  400. return result;
  401. }
  402. _toCoords(position) {
  403. if (!this._editor.hasModel()) {
  404. return { x: 0, y: 0 };
  405. }
  406. this._editor.revealPosition(position, 1 /* ScrollType.Immediate */);
  407. this._editor.render();
  408. // Translate to absolute editor position
  409. const cursorCoords = this._editor.getScrolledVisiblePosition(position);
  410. const editorCoords = dom.getDomNodePagePosition(this._editor.getDomNode());
  411. const x = editorCoords.left + cursorCoords.left;
  412. const y = editorCoords.top + cursorCoords.top + cursorCoords.height;
  413. return { x, y };
  414. }
  415. };
  416. CodeActionMenu.documentationID = '_documentation';
  417. CodeActionMenu = __decorate([
  418. __param(2, IContextMenuService),
  419. __param(3, IKeybindingService),
  420. __param(4, ILanguageFeaturesService),
  421. __param(5, ITelemetryService),
  422. __param(6, IThemeService),
  423. __param(7, IConfigurationService),
  424. __param(8, IContextViewService),
  425. __param(9, IContextKeyService)
  426. ], CodeActionMenu);
  427. export { CodeActionMenu };
  428. export class CodeActionKeybindingResolver {
  429. constructor(_keybindingProvider) {
  430. this._keybindingProvider = _keybindingProvider;
  431. }
  432. getResolver() {
  433. // Lazy since we may not actually ever read the value
  434. const allCodeActionBindings = new Lazy(() => this._keybindingProvider.getKeybindings()
  435. .filter(item => CodeActionKeybindingResolver.codeActionCommands.indexOf(item.command) >= 0)
  436. .filter(item => item.resolvedKeybinding)
  437. .map((item) => {
  438. // Special case these commands since they come built-in with VS Code and don't use 'commandArgs'
  439. let commandArgs = item.commandArgs;
  440. if (item.command === organizeImportsCommandId) {
  441. commandArgs = { kind: CodeActionKind.SourceOrganizeImports.value };
  442. }
  443. else if (item.command === fixAllCommandId) {
  444. commandArgs = { kind: CodeActionKind.SourceFixAll.value };
  445. }
  446. return Object.assign({ resolvedKeybinding: item.resolvedKeybinding }, CodeActionCommandArgs.fromUser(commandArgs, {
  447. kind: CodeActionKind.None,
  448. apply: "never" /* CodeActionAutoApply.Never */
  449. }));
  450. }));
  451. return (action) => {
  452. if (action.kind) {
  453. const binding = this.bestKeybindingForCodeAction(action, allCodeActionBindings.getValue());
  454. return binding === null || binding === void 0 ? void 0 : binding.resolvedKeybinding;
  455. }
  456. return undefined;
  457. };
  458. }
  459. bestKeybindingForCodeAction(action, candidates) {
  460. if (!action.kind) {
  461. return undefined;
  462. }
  463. const kind = new CodeActionKind(action.kind);
  464. return candidates
  465. .filter(candidate => candidate.kind.contains(kind))
  466. .filter(candidate => {
  467. if (candidate.preferred) {
  468. // If the candidate keybinding only applies to preferred actions, the this action must also be preferred
  469. return action.isPreferred;
  470. }
  471. return true;
  472. })
  473. .reduceRight((currentBest, candidate) => {
  474. if (!currentBest) {
  475. return candidate;
  476. }
  477. // Select the more specific binding
  478. return currentBest.kind.contains(candidate.kind) ? candidate : currentBest;
  479. }, undefined);
  480. }
  481. }
  482. CodeActionKeybindingResolver.codeActionCommands = [
  483. refactorCommandId,
  484. codeActionCommandId,
  485. sourceActionCommandId,
  486. organizeImportsCommandId,
  487. fixAllCommandId
  488. ];