82a82534054684b5ecfd3a62b0a140e459df881da3922ba51ec7d3104a1013aaeb9150e4cd0cfca3658498c3884ed528d7304eb5a3440570554d4a052d4e4b 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  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. import { createCancelablePromise, RunOnceScheduler } from '../../../../base/common/async.js';
  15. import { Disposable } from '../../../../base/common/lifecycle.js';
  16. import { registerEditorContribution } from '../../../browser/editorExtensions.js';
  17. import { getDocumentRangeSemanticTokens, hasDocumentRangeSemanticTokensProvider } from '../../../common/services/getSemanticTokens.js';
  18. import { IModelService } from '../../../common/services/model.js';
  19. import { isSemanticColoringEnabled, SEMANTIC_HIGHLIGHTING_SETTING_ID } from '../../../common/services/modelService.js';
  20. import { toMultilineTokens2 } from '../../../common/services/semanticTokensProviderStyling.js';
  21. import { IConfigurationService } from '../../../../platform/configuration/common/configuration.js';
  22. import { IThemeService } from '../../../../platform/theme/common/themeService.js';
  23. import { ILanguageFeatureDebounceService } from '../../../common/services/languageFeatureDebounce.js';
  24. import { StopWatch } from '../../../../base/common/stopwatch.js';
  25. import { ILanguageFeaturesService } from '../../../common/services/languageFeatures.js';
  26. let ViewportSemanticTokensContribution = class ViewportSemanticTokensContribution extends Disposable {
  27. constructor(editor, _modelService, _themeService, _configurationService, languageFeatureDebounceService, languageFeaturesService) {
  28. super();
  29. this._modelService = _modelService;
  30. this._themeService = _themeService;
  31. this._configurationService = _configurationService;
  32. this._editor = editor;
  33. this._provider = languageFeaturesService.documentRangeSemanticTokensProvider;
  34. this._debounceInformation = languageFeatureDebounceService.for(this._provider, 'DocumentRangeSemanticTokens', { min: 100, max: 500 });
  35. this._tokenizeViewport = this._register(new RunOnceScheduler(() => this._tokenizeViewportNow(), 100));
  36. this._outstandingRequests = [];
  37. const scheduleTokenizeViewport = () => {
  38. if (this._editor.hasModel()) {
  39. this._tokenizeViewport.schedule(this._debounceInformation.get(this._editor.getModel()));
  40. }
  41. };
  42. this._register(this._editor.onDidScrollChange(() => {
  43. scheduleTokenizeViewport();
  44. }));
  45. this._register(this._editor.onDidChangeModel(() => {
  46. this._cancelAll();
  47. scheduleTokenizeViewport();
  48. }));
  49. this._register(this._editor.onDidChangeModelContent((e) => {
  50. this._cancelAll();
  51. scheduleTokenizeViewport();
  52. }));
  53. this._register(this._provider.onDidChange(() => {
  54. this._cancelAll();
  55. scheduleTokenizeViewport();
  56. }));
  57. this._register(this._configurationService.onDidChangeConfiguration(e => {
  58. if (e.affectsConfiguration(SEMANTIC_HIGHLIGHTING_SETTING_ID)) {
  59. this._cancelAll();
  60. scheduleTokenizeViewport();
  61. }
  62. }));
  63. this._register(this._themeService.onDidColorThemeChange(() => {
  64. this._cancelAll();
  65. scheduleTokenizeViewport();
  66. }));
  67. }
  68. _cancelAll() {
  69. for (const request of this._outstandingRequests) {
  70. request.cancel();
  71. }
  72. this._outstandingRequests = [];
  73. }
  74. _removeOutstandingRequest(req) {
  75. for (let i = 0, len = this._outstandingRequests.length; i < len; i++) {
  76. if (this._outstandingRequests[i] === req) {
  77. this._outstandingRequests.splice(i, 1);
  78. return;
  79. }
  80. }
  81. }
  82. _tokenizeViewportNow() {
  83. if (!this._editor.hasModel()) {
  84. return;
  85. }
  86. const model = this._editor.getModel();
  87. if (model.tokenization.hasCompleteSemanticTokens()) {
  88. return;
  89. }
  90. if (!isSemanticColoringEnabled(model, this._themeService, this._configurationService)) {
  91. if (model.tokenization.hasSomeSemanticTokens()) {
  92. model.tokenization.setSemanticTokens(null, false);
  93. }
  94. return;
  95. }
  96. if (!hasDocumentRangeSemanticTokensProvider(this._provider, model)) {
  97. if (model.tokenization.hasSomeSemanticTokens()) {
  98. model.tokenization.setSemanticTokens(null, false);
  99. }
  100. return;
  101. }
  102. const visibleRanges = this._editor.getVisibleRangesPlusViewportAboveBelow();
  103. this._outstandingRequests = this._outstandingRequests.concat(visibleRanges.map(range => this._requestRange(model, range)));
  104. }
  105. _requestRange(model, range) {
  106. const requestVersionId = model.getVersionId();
  107. const request = createCancelablePromise(token => Promise.resolve(getDocumentRangeSemanticTokens(this._provider, model, range, token)));
  108. const sw = new StopWatch(false);
  109. request.then((r) => {
  110. this._debounceInformation.update(model, sw.elapsed());
  111. if (!r || !r.tokens || model.isDisposed() || model.getVersionId() !== requestVersionId) {
  112. return;
  113. }
  114. const { provider, tokens: result } = r;
  115. const styling = this._modelService.getSemanticTokensProviderStyling(provider);
  116. model.tokenization.setPartialSemanticTokens(range, toMultilineTokens2(result, styling, model.getLanguageId()));
  117. }).then(() => this._removeOutstandingRequest(request), () => this._removeOutstandingRequest(request));
  118. return request;
  119. }
  120. };
  121. ViewportSemanticTokensContribution.ID = 'editor.contrib.viewportSemanticTokens';
  122. ViewportSemanticTokensContribution = __decorate([
  123. __param(1, IModelService),
  124. __param(2, IThemeService),
  125. __param(3, IConfigurationService),
  126. __param(4, ILanguageFeatureDebounceService),
  127. __param(5, ILanguageFeaturesService)
  128. ], ViewportSemanticTokensContribution);
  129. registerEditorContribution(ViewportSemanticTokensContribution.ID, ViewportSemanticTokensContribution);