d2728caf32d4b9d836de00c96cd6bda45a91e223299e30172fb7b82c4c178707661233c9abb8f343443e4caa0e6a601aa5c8a07d7722681587519780befdb9 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215
  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 { IMarkerService, MarkerSeverity } from '../../../platform/markers/common/markers.js';
  15. import { Disposable, toDisposable } from '../../../base/common/lifecycle.js';
  16. import { OverviewRulerLane, MinimapPosition } from '../model.js';
  17. import { themeColorFromId } from '../../../platform/theme/common/themeService.js';
  18. import { overviewRulerWarning, overviewRulerInfo, overviewRulerError } from '../core/editorColorRegistry.js';
  19. import { IModelService } from './model.js';
  20. import { Range } from '../core/range.js';
  21. import { Schemas } from '../../../base/common/network.js';
  22. import { Emitter } from '../../../base/common/event.js';
  23. import { minimapWarning, minimapError } from '../../../platform/theme/common/colorRegistry.js';
  24. import { ResourceMap } from '../../../base/common/map.js';
  25. class MarkerDecorations extends Disposable {
  26. constructor(model) {
  27. super();
  28. this.model = model;
  29. this._markersData = new Map();
  30. this._register(toDisposable(() => {
  31. this.model.deltaDecorations([...this._markersData.keys()], []);
  32. this._markersData.clear();
  33. }));
  34. }
  35. update(markers, newDecorations) {
  36. const oldIds = [...this._markersData.keys()];
  37. this._markersData.clear();
  38. const ids = this.model.deltaDecorations(oldIds, newDecorations);
  39. for (let index = 0; index < ids.length; index++) {
  40. this._markersData.set(ids[index], markers[index]);
  41. }
  42. return oldIds.length !== 0 || ids.length !== 0;
  43. }
  44. getMarker(decoration) {
  45. return this._markersData.get(decoration.id);
  46. }
  47. }
  48. let MarkerDecorationsService = class MarkerDecorationsService extends Disposable {
  49. constructor(modelService, _markerService) {
  50. super();
  51. this._markerService = _markerService;
  52. this._onDidChangeMarker = this._register(new Emitter());
  53. this._markerDecorations = new ResourceMap();
  54. modelService.getModels().forEach(model => this._onModelAdded(model));
  55. this._register(modelService.onModelAdded(this._onModelAdded, this));
  56. this._register(modelService.onModelRemoved(this._onModelRemoved, this));
  57. this._register(this._markerService.onMarkerChanged(this._handleMarkerChange, this));
  58. }
  59. dispose() {
  60. super.dispose();
  61. this._markerDecorations.forEach(value => value.dispose());
  62. this._markerDecorations.clear();
  63. }
  64. getMarker(uri, decoration) {
  65. const markerDecorations = this._markerDecorations.get(uri);
  66. return markerDecorations ? (markerDecorations.getMarker(decoration) || null) : null;
  67. }
  68. _handleMarkerChange(changedResources) {
  69. changedResources.forEach((resource) => {
  70. const markerDecorations = this._markerDecorations.get(resource);
  71. if (markerDecorations) {
  72. this._updateDecorations(markerDecorations);
  73. }
  74. });
  75. }
  76. _onModelAdded(model) {
  77. const markerDecorations = new MarkerDecorations(model);
  78. this._markerDecorations.set(model.uri, markerDecorations);
  79. this._updateDecorations(markerDecorations);
  80. }
  81. _onModelRemoved(model) {
  82. var _a;
  83. const markerDecorations = this._markerDecorations.get(model.uri);
  84. if (markerDecorations) {
  85. markerDecorations.dispose();
  86. this._markerDecorations.delete(model.uri);
  87. }
  88. // clean up markers for internal, transient models
  89. if (model.uri.scheme === Schemas.inMemory
  90. || model.uri.scheme === Schemas.internal
  91. || model.uri.scheme === Schemas.vscode) {
  92. (_a = this._markerService) === null || _a === void 0 ? void 0 : _a.read({ resource: model.uri }).map(marker => marker.owner).forEach(owner => this._markerService.remove(owner, [model.uri]));
  93. }
  94. }
  95. _updateDecorations(markerDecorations) {
  96. // Limit to the first 500 errors/warnings
  97. const markers = this._markerService.read({ resource: markerDecorations.model.uri, take: 500 });
  98. const newModelDecorations = markers.map((marker) => {
  99. return {
  100. range: this._createDecorationRange(markerDecorations.model, marker),
  101. options: this._createDecorationOption(marker)
  102. };
  103. });
  104. if (markerDecorations.update(markers, newModelDecorations)) {
  105. this._onDidChangeMarker.fire(markerDecorations.model);
  106. }
  107. }
  108. _createDecorationRange(model, rawMarker) {
  109. let ret = Range.lift(rawMarker);
  110. if (rawMarker.severity === MarkerSeverity.Hint && !this._hasMarkerTag(rawMarker, 1 /* MarkerTag.Unnecessary */) && !this._hasMarkerTag(rawMarker, 2 /* MarkerTag.Deprecated */)) {
  111. // * never render hints on multiple lines
  112. // * make enough space for three dots
  113. ret = ret.setEndPosition(ret.startLineNumber, ret.startColumn + 2);
  114. }
  115. ret = model.validateRange(ret);
  116. if (ret.isEmpty()) {
  117. const maxColumn = model.getLineLastNonWhitespaceColumn(ret.startLineNumber) ||
  118. model.getLineMaxColumn(ret.startLineNumber);
  119. if (maxColumn === 1 || ret.endColumn >= maxColumn) {
  120. // empty line or behind eol
  121. // keep the range as is, it will be rendered 1ch wide
  122. return ret;
  123. }
  124. const word = model.getWordAtPosition(ret.getStartPosition());
  125. if (word) {
  126. ret = new Range(ret.startLineNumber, word.startColumn, ret.endLineNumber, word.endColumn);
  127. }
  128. }
  129. else if (rawMarker.endColumn === Number.MAX_VALUE && rawMarker.startColumn === 1 && ret.startLineNumber === ret.endLineNumber) {
  130. const minColumn = model.getLineFirstNonWhitespaceColumn(rawMarker.startLineNumber);
  131. if (minColumn < ret.endColumn) {
  132. ret = new Range(ret.startLineNumber, minColumn, ret.endLineNumber, ret.endColumn);
  133. rawMarker.startColumn = minColumn;
  134. }
  135. }
  136. return ret;
  137. }
  138. _createDecorationOption(marker) {
  139. let className;
  140. let color = undefined;
  141. let zIndex;
  142. let inlineClassName = undefined;
  143. let minimap;
  144. switch (marker.severity) {
  145. case MarkerSeverity.Hint:
  146. if (this._hasMarkerTag(marker, 2 /* MarkerTag.Deprecated */)) {
  147. className = undefined;
  148. }
  149. else if (this._hasMarkerTag(marker, 1 /* MarkerTag.Unnecessary */)) {
  150. className = "squiggly-unnecessary" /* ClassName.EditorUnnecessaryDecoration */;
  151. }
  152. else {
  153. className = "squiggly-hint" /* ClassName.EditorHintDecoration */;
  154. }
  155. zIndex = 0;
  156. break;
  157. case MarkerSeverity.Warning:
  158. className = "squiggly-warning" /* ClassName.EditorWarningDecoration */;
  159. color = themeColorFromId(overviewRulerWarning);
  160. zIndex = 20;
  161. minimap = {
  162. color: themeColorFromId(minimapWarning),
  163. position: MinimapPosition.Inline
  164. };
  165. break;
  166. case MarkerSeverity.Info:
  167. className = "squiggly-info" /* ClassName.EditorInfoDecoration */;
  168. color = themeColorFromId(overviewRulerInfo);
  169. zIndex = 10;
  170. break;
  171. case MarkerSeverity.Error:
  172. default:
  173. className = "squiggly-error" /* ClassName.EditorErrorDecoration */;
  174. color = themeColorFromId(overviewRulerError);
  175. zIndex = 30;
  176. minimap = {
  177. color: themeColorFromId(minimapError),
  178. position: MinimapPosition.Inline
  179. };
  180. break;
  181. }
  182. if (marker.tags) {
  183. if (marker.tags.indexOf(1 /* MarkerTag.Unnecessary */) !== -1) {
  184. inlineClassName = "squiggly-inline-unnecessary" /* ClassName.EditorUnnecessaryInlineDecoration */;
  185. }
  186. if (marker.tags.indexOf(2 /* MarkerTag.Deprecated */) !== -1) {
  187. inlineClassName = "squiggly-inline-deprecated" /* ClassName.EditorDeprecatedInlineDecoration */;
  188. }
  189. }
  190. return {
  191. description: 'marker-decoration',
  192. stickiness: 1 /* TrackedRangeStickiness.NeverGrowsWhenTypingAtEdges */,
  193. className,
  194. showIfCollapsed: true,
  195. overviewRuler: {
  196. color,
  197. position: OverviewRulerLane.Right
  198. },
  199. minimap,
  200. zIndex,
  201. inlineClassName,
  202. };
  203. }
  204. _hasMarkerTag(marker, tag) {
  205. if (marker.tags) {
  206. return marker.tags.indexOf(tag) >= 0;
  207. }
  208. return false;
  209. }
  210. };
  211. MarkerDecorationsService = __decorate([
  212. __param(0, IModelService),
  213. __param(1, IMarkerService)
  214. ], MarkerDecorationsService);
  215. export { MarkerDecorationsService };