1 | "use strict";
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 |
|
9 |
|
10 |
|
11 |
|
12 |
|
13 |
|
14 |
|
15 |
|
16 |
|
17 | Object.defineProperty(exports, "__esModule", { value: true });
|
18 | exports.DecorationsServiceImpl = exports.DecorationsService = void 0;
|
19 | const tslib_1 = require("tslib");
|
20 | const inversify_1 = require("inversify");
|
21 | const promise_util_1 = require("../common/promise-util");
|
22 | const common_1 = require("../common");
|
23 | const ternary_search_tree_1 = require("../common/ternary-search-tree");
|
24 | exports.DecorationsService = Symbol('DecorationsService');
|
25 | class DecorationDataRequest {
|
26 | constructor(source, thenable) {
|
27 | this.source = source;
|
28 | this.thenable = thenable;
|
29 | }
|
30 | }
|
31 | class DecorationProviderWrapper {
|
32 | constructor(provider, onDidChangeDecorationsEmitter) {
|
33 | this.provider = provider;
|
34 | this.onDidChangeDecorationsEmitter = onDidChangeDecorationsEmitter;
|
35 | this.decorations = new Map();
|
36 | this.data = ternary_search_tree_1.TernarySearchTree.forUris(true);
|
37 | this.disposable = this.provider.onDidChange(async (uris) => {
|
38 | this.decorations.clear();
|
39 | if (!uris) {
|
40 | this.data.clear();
|
41 | }
|
42 | else {
|
43 | for (const uri of uris) {
|
44 | this.fetchData(uri);
|
45 | const decoration = await provider.provideDecorations(uri, common_1.CancellationToken.None);
|
46 | if (decoration) {
|
47 | this.decorations.set(uri.toString(), decoration);
|
48 | }
|
49 | }
|
50 | }
|
51 | this.onDidChangeDecorationsEmitter.fire(this.decorations);
|
52 | });
|
53 | }
|
54 | dispose() {
|
55 | this.disposable.dispose();
|
56 | this.data.clear();
|
57 | }
|
58 | knowsAbout(uri) {
|
59 | return !!this.data.get(uri) || Boolean(this.data.findSuperstr(uri));
|
60 | }
|
61 | getOrRetrieve(uri, includeChildren, callback) {
|
62 | let item = this.data.get(uri);
|
63 | if (item === undefined) {
|
64 |
|
65 | item = this.fetchData(uri);
|
66 | }
|
67 | if (item && !(item instanceof DecorationDataRequest)) {
|
68 |
|
69 | callback(item, false);
|
70 | }
|
71 | if (includeChildren) {
|
72 |
|
73 | const iter = this.data.findSuperstr(uri);
|
74 | if (iter) {
|
75 | let next = iter.next();
|
76 | while (!next.done) {
|
77 | const value = next.value;
|
78 | if (value && !(value instanceof DecorationDataRequest)) {
|
79 | callback(value, true);
|
80 | }
|
81 | next = iter.next();
|
82 | }
|
83 | }
|
84 | }
|
85 | }
|
86 | fetchData(uri) {
|
87 |
|
88 | const pendingRequest = this.data.get(uri);
|
89 | if (pendingRequest instanceof DecorationDataRequest) {
|
90 | pendingRequest.source.cancel();
|
91 | this.data.delete(uri);
|
92 | }
|
93 | const source = new common_1.CancellationTokenSource();
|
94 | const dataOrThenable = this.provider.provideDecorations(uri, source.token);
|
95 | if (!(0, promise_util_1.isThenable)(dataOrThenable)) {
|
96 |
|
97 | return this.keepItem(uri, dataOrThenable);
|
98 | }
|
99 | else {
|
100 |
|
101 | const request = new DecorationDataRequest(source, Promise.resolve(dataOrThenable).then(data => {
|
102 | if (this.data.get(uri) === request) {
|
103 | this.keepItem(uri, data);
|
104 | }
|
105 | }).catch(err => {
|
106 | if (!(err instanceof Error && err.name === 'Canceled' && err.message === 'Canceled') && this.data.get(uri) === request) {
|
107 | this.data.delete(uri);
|
108 | }
|
109 | }));
|
110 | this.data.set(uri, request);
|
111 | return undefined;
|
112 | }
|
113 | }
|
114 | keepItem(uri, data) {
|
115 | const deco = data ? data : undefined;
|
116 | this.data.set(uri, deco);
|
117 | return deco;
|
118 | }
|
119 | }
|
120 | let DecorationsServiceImpl = class DecorationsServiceImpl {
|
121 | constructor() {
|
122 | this.data = [];
|
123 | this.onDidChangeDecorationsEmitter = new common_1.Emitter();
|
124 | this.onDidChangeDecorations = this.onDidChangeDecorationsEmitter.event;
|
125 | }
|
126 | dispose() {
|
127 | this.onDidChangeDecorationsEmitter.dispose();
|
128 | }
|
129 | registerDecorationsProvider(provider) {
|
130 | const wrapper = new DecorationProviderWrapper(provider, this.onDidChangeDecorationsEmitter);
|
131 | this.data.push(wrapper);
|
132 | return common_1.Disposable.create(() => {
|
133 |
|
134 |
|
135 | this.data.splice(this.data.indexOf(wrapper), 1);
|
136 | this.onDidChangeDecorationsEmitter.fire(new Map());
|
137 | wrapper.dispose();
|
138 | });
|
139 | }
|
140 | getDecoration(uri, includeChildren) {
|
141 | const data = [];
|
142 | let containsChildren = false;
|
143 | for (const wrapper of this.data) {
|
144 | wrapper.getOrRetrieve(uri, includeChildren, (deco, isChild) => {
|
145 | if (!isChild || deco.bubble) {
|
146 | data.push(deco);
|
147 | containsChildren = isChild || containsChildren;
|
148 | }
|
149 | });
|
150 | }
|
151 | return data;
|
152 | }
|
153 | };
|
154 | DecorationsServiceImpl = (0, tslib_1.__decorate)([
|
155 | (0, inversify_1.injectable)()
|
156 | ], DecorationsServiceImpl);
|
157 | exports.DecorationsServiceImpl = DecorationsServiceImpl;
|
158 |
|
\ | No newline at end of file |