@spyglassmc/core 0.1.0
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.
- package/README.md +10 -0
- package/lib/common/Heap.d.ts +1 -0
- package/lib/common/Heap.js +2 -0
- package/lib/common/index.d.ts +2 -0
- package/lib/common/index.js +14 -0
- package/lib/common/util.d.ts +120 -0
- package/lib/common/util.js +292 -0
- package/lib/index.d.ts +8 -0
- package/lib/index.js +20 -0
- package/lib/node/AstNode.d.ts +64 -0
- package/lib/node/AstNode.js +108 -0
- package/lib/node/BooleanNode.d.ts +13 -0
- package/lib/node/BooleanNode.js +20 -0
- package/lib/node/CommentNode.d.ts +12 -0
- package/lib/node/CommentNode.js +11 -0
- package/lib/node/ErrorNode.d.ts +8 -0
- package/lib/node/ErrorNode.js +12 -0
- package/lib/node/FileNode.d.ts +21 -0
- package/lib/node/FileNode.js +11 -0
- package/lib/node/FloatNode.d.ts +13 -0
- package/lib/node/FloatNode.js +21 -0
- package/lib/node/IntegerNode.d.ts +13 -0
- package/lib/node/IntegerNode.js +20 -0
- package/lib/node/ListNode.d.ts +15 -0
- package/lib/node/ListNode.js +11 -0
- package/lib/node/LiteralNode.d.ts +19 -0
- package/lib/node/LiteralNode.js +22 -0
- package/lib/node/LongNode.d.ts +13 -0
- package/lib/node/LongNode.js +20 -0
- package/lib/node/RecordNode.d.ts +20 -0
- package/lib/node/RecordNode.js +11 -0
- package/lib/node/ResourceLocationNode.d.ts +41 -0
- package/lib/node/ResourceLocationNode.js +65 -0
- package/lib/node/Sequence.d.ts +22 -0
- package/lib/node/Sequence.js +11 -0
- package/lib/node/StringNode.d.ts +63 -0
- package/lib/node/StringNode.js +43 -0
- package/lib/node/SymbolNode.d.ts +21 -0
- package/lib/node/SymbolNode.js +22 -0
- package/lib/node/TableNode.d.ts +17 -0
- package/lib/node/TableNode.js +11 -0
- package/lib/node/index.d.ts +16 -0
- package/lib/node/index.js +28 -0
- package/lib/parser/Parser.d.ts +16 -0
- package/lib/parser/Parser.js +5 -0
- package/lib/parser/boolean.d.ts +4 -0
- package/lib/parser/boolean.js +11 -0
- package/lib/parser/comment.d.ts +12 -0
- package/lib/parser/comment.js +34 -0
- package/lib/parser/empty.d.ts +3 -0
- package/lib/parser/empty.js +7 -0
- package/lib/parser/error.d.ts +8 -0
- package/lib/parser/error.js +22 -0
- package/lib/parser/file.d.ts +9 -0
- package/lib/parser/file.js +37 -0
- package/lib/parser/float.d.ts +33 -0
- package/lib/parser/float.js +57 -0
- package/lib/parser/index.d.ts +17 -0
- package/lib/parser/index.js +36 -0
- package/lib/parser/integer.d.ts +33 -0
- package/lib/parser/integer.js +46 -0
- package/lib/parser/list.d.ts +12 -0
- package/lib/parser/list.js +70 -0
- package/lib/parser/literal.d.ts +5 -0
- package/lib/parser/literal.js +41 -0
- package/lib/parser/long.d.ts +33 -0
- package/lib/parser/long.js +50 -0
- package/lib/parser/record.d.ts +22 -0
- package/lib/parser/record.js +97 -0
- package/lib/parser/resourceLocation.d.ts +4 -0
- package/lib/parser/resourceLocation.js +67 -0
- package/lib/parser/string.d.ts +18 -0
- package/lib/parser/string.js +129 -0
- package/lib/parser/symbol.d.ts +12 -0
- package/lib/parser/symbol.js +33 -0
- package/lib/parser/table.d.ts +22 -0
- package/lib/parser/table.js +97 -0
- package/lib/parser/util.d.ts +134 -0
- package/lib/parser/util.js +224 -0
- package/lib/processor/ColorInfoProvider.d.ts +87 -0
- package/lib/processor/ColorInfoProvider.js +141 -0
- package/lib/processor/InlayHintProvider.d.ts +8 -0
- package/lib/processor/InlayHintProvider.js +3 -0
- package/lib/processor/SignatureHelpProvider.d.ts +18 -0
- package/lib/processor/SignatureHelpProvider.js +3 -0
- package/lib/processor/checker/Checker.d.ts +7 -0
- package/lib/processor/checker/Checker.js +7 -0
- package/lib/processor/checker/builtin.d.ts +23 -0
- package/lib/processor/checker/builtin.js +83 -0
- package/lib/processor/checker/index.d.ts +3 -0
- package/lib/processor/checker/index.js +28 -0
- package/lib/processor/colorizer/Colorizer.d.ts +23 -0
- package/lib/processor/colorizer/Colorizer.js +70 -0
- package/lib/processor/colorizer/builtin.d.ts +17 -0
- package/lib/processor/colorizer/builtin.js +84 -0
- package/lib/processor/colorizer/index.d.ts +3 -0
- package/lib/processor/colorizer/index.js +28 -0
- package/lib/processor/completer/Completer.d.ts +75 -0
- package/lib/processor/completer/Completer.js +92 -0
- package/lib/processor/completer/builtin.d.ts +30 -0
- package/lib/processor/completer/builtin.js +172 -0
- package/lib/processor/completer/index.d.ts +3 -0
- package/lib/processor/completer/index.js +28 -0
- package/lib/processor/formatter/Formatter.d.ts +6 -0
- package/lib/processor/formatter/Formatter.js +19 -0
- package/lib/processor/formatter/builtin.d.ts +15 -0
- package/lib/processor/formatter/builtin.js +60 -0
- package/lib/processor/formatter/index.d.ts +3 -0
- package/lib/processor/formatter/index.js +28 -0
- package/lib/processor/index.d.ts +10 -0
- package/lib/processor/index.js +22 -0
- package/lib/processor/linter/Linter.d.ts +4 -0
- package/lib/processor/linter/Linter.js +3 -0
- package/lib/processor/linter/builtin/undeclaredSymbol.d.ts +4 -0
- package/lib/processor/linter/builtin/undeclaredSymbol.js +73 -0
- package/lib/processor/linter/builtin.d.ts +15 -0
- package/lib/processor/linter/builtin.js +120 -0
- package/lib/processor/linter/index.d.ts +3 -0
- package/lib/processor/linter/index.js +28 -0
- package/lib/processor/util.d.ts +17 -0
- package/lib/processor/util.js +32 -0
- package/lib/service/CacheService.d.ts +54 -0
- package/lib/service/CacheService.js +195 -0
- package/lib/service/CommandExecutor.d.ts +3 -0
- package/lib/service/CommandExecutor.js +7 -0
- package/lib/service/Config.d.ts +218 -0
- package/lib/service/Config.js +264 -0
- package/lib/service/Context.d.ts +143 -0
- package/lib/service/Context.js +143 -0
- package/lib/service/Dependency.d.ts +10 -0
- package/lib/service/Dependency.js +11 -0
- package/lib/service/Downloader.d.ts +67 -0
- package/lib/service/Downloader.js +185 -0
- package/lib/service/ErrorReporter.d.ts +27 -0
- package/lib/service/ErrorReporter.js +49 -0
- package/lib/service/FileService.d.ts +96 -0
- package/lib/service/FileService.js +224 -0
- package/lib/service/Hover.d.ts +10 -0
- package/lib/service/Hover.js +16 -0
- package/lib/service/Logger.d.ts +31 -0
- package/lib/service/Logger.js +30 -0
- package/lib/service/MetaRegistry.d.ts +106 -0
- package/lib/service/MetaRegistry.js +192 -0
- package/lib/service/Operations.d.ts +8 -0
- package/lib/service/Operations.js +26 -0
- package/lib/service/Profiler.d.ts +33 -0
- package/lib/service/Profiler.js +76 -0
- package/lib/service/Project.d.ts +173 -0
- package/lib/service/Project.js +593 -0
- package/lib/service/Service.d.ts +55 -0
- package/lib/service/Service.js +207 -0
- package/lib/service/SymbolLocations.d.ts +17 -0
- package/lib/service/SymbolLocations.js +16 -0
- package/lib/service/SymbolRegistrar.d.ts +5 -0
- package/lib/service/SymbolRegistrar.js +3 -0
- package/lib/service/fileUtil.d.ts +121 -0
- package/lib/service/fileUtil.js +268 -0
- package/lib/service/index.d.ts +18 -0
- package/lib/service/index.js +33 -0
- package/lib/source/IndexMap.d.ts +16 -0
- package/lib/source/IndexMap.js +46 -0
- package/lib/source/LanguageError.d.ts +27 -0
- package/lib/source/LanguageError.js +15 -0
- package/lib/source/Location.d.ts +19 -0
- package/lib/source/Location.js +25 -0
- package/lib/source/Offset.d.ts +13 -0
- package/lib/source/Offset.js +25 -0
- package/lib/source/Position.d.ts +23 -0
- package/lib/source/Position.js +43 -0
- package/lib/source/PositionRange.d.ts +38 -0
- package/lib/source/PositionRange.js +83 -0
- package/lib/source/Range.d.ts +68 -0
- package/lib/source/Range.js +155 -0
- package/lib/source/Source.d.ts +110 -0
- package/lib/source/Source.js +222 -0
- package/lib/source/index.d.ts +9 -0
- package/lib/source/index.js +21 -0
- package/lib/symbol/Symbol.d.ts +219 -0
- package/lib/symbol/Symbol.js +324 -0
- package/lib/symbol/SymbolUtil.d.ts +407 -0
- package/lib/symbol/SymbolUtil.js +880 -0
- package/lib/symbol/UriBinder.d.ts +3 -0
- package/lib/symbol/UriBinder.js +3 -0
- package/lib/symbol/index.d.ts +4 -0
- package/lib/symbol/index.js +16 -0
- package/package.json +41 -0
|
@@ -0,0 +1,880 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
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;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
|
|
9
|
+
if (kind === "m") throw new TypeError("Private method is not writable");
|
|
10
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
|
|
11
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
|
|
12
|
+
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
|
|
13
|
+
};
|
|
14
|
+
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
|
|
15
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
|
|
16
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
17
|
+
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
18
|
+
};
|
|
19
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
20
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
21
|
+
};
|
|
22
|
+
var _SymbolUtil_global, _SymbolUtil_trimmableSymbols, _SymbolUtil_cache, _SymbolUtil_currentContributor, _SymbolQuery_doc, _SymbolQuery_node, _SymbolQuery_createdWithUri, _SymbolQuery_currentContributor, _SymbolQuery_hasTriggeredIf, _SymbolQuery_map, _SymbolQuery_parentSymbol, _SymbolQuery_symbol;
|
|
23
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
24
|
+
exports.SymbolFormatter = exports.SymbolQuery = exports.SymbolUtil = void 0;
|
|
25
|
+
const assert_1 = require("assert");
|
|
26
|
+
const events_1 = __importDefault(require("events"));
|
|
27
|
+
const vscode_languageserver_textdocument_1 = require("vscode-languageserver-textdocument");
|
|
28
|
+
const source_1 = require("../source");
|
|
29
|
+
const Symbol_1 = require("./Symbol");
|
|
30
|
+
class SymbolUtil extends events_1.default {
|
|
31
|
+
constructor(global,
|
|
32
|
+
/** @internal */
|
|
33
|
+
_currentContributor,
|
|
34
|
+
/** @internal */
|
|
35
|
+
_inDelayMode = false) {
|
|
36
|
+
super();
|
|
37
|
+
_SymbolUtil_global.set(this, void 0);
|
|
38
|
+
_SymbolUtil_trimmableSymbols.set(this, new Set());
|
|
39
|
+
_SymbolUtil_cache.set(this, Object.create(null));
|
|
40
|
+
_SymbolUtil_currentContributor.set(this, void 0);
|
|
41
|
+
/**
|
|
42
|
+
* @internal
|
|
43
|
+
*/
|
|
44
|
+
this._delayedOps = [];
|
|
45
|
+
__classPrivateFieldSet(this, _SymbolUtil_global, global, "f");
|
|
46
|
+
__classPrivateFieldSet(this, _SymbolUtil_currentContributor, _currentContributor, "f");
|
|
47
|
+
this._inDelayMode = _inDelayMode;
|
|
48
|
+
this
|
|
49
|
+
.on('symbolCreated', ({ symbol }) => {
|
|
50
|
+
__classPrivateFieldGet(this, _SymbolUtil_trimmableSymbols, "f").add(Symbol_1.SymbolPath.toString(symbol));
|
|
51
|
+
})
|
|
52
|
+
.on('symbolRemoved', ({ symbol }) => {
|
|
53
|
+
__classPrivateFieldGet(this, _SymbolUtil_trimmableSymbols, "f").delete(Symbol_1.SymbolPath.toString(symbol));
|
|
54
|
+
})
|
|
55
|
+
.on('symbolLocationCreated', ({ symbol, location }) => {
|
|
56
|
+
var _a, _b, _c;
|
|
57
|
+
const cache = (_a = __classPrivateFieldGet(this, _SymbolUtil_cache, "f"))[_b = location.contributor ?? 'undefined'] ?? (_a[_b] = Object.create(null));
|
|
58
|
+
const fileSymbols = cache[_c = location.uri] ?? (cache[_c] = new Set());
|
|
59
|
+
const path = Symbol_1.SymbolPath.toString(symbol);
|
|
60
|
+
fileSymbols.add(path);
|
|
61
|
+
__classPrivateFieldGet(this, _SymbolUtil_trimmableSymbols, "f").delete(path);
|
|
62
|
+
})
|
|
63
|
+
.on('symbolLocationRemoved', ({ symbol }) => {
|
|
64
|
+
const path = Symbol_1.SymbolPath.toString(symbol);
|
|
65
|
+
__classPrivateFieldGet(this, _SymbolUtil_trimmableSymbols, "f").add(path);
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
get global() {
|
|
69
|
+
return __classPrivateFieldGet(this, _SymbolUtil_global, "f");
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Build the internal cache of the SymbolUtil according to the current global symbol table.
|
|
73
|
+
*/
|
|
74
|
+
buildCache() {
|
|
75
|
+
SymbolUtil.forEachSymbol(this.global, symbol => {
|
|
76
|
+
this.emit('symbolCreated', { symbol });
|
|
77
|
+
SymbolUtil.forEachLocationOfSymbol(symbol, ({ type, location }) => {
|
|
78
|
+
this.emit('symbolLocationCreated', { symbol, type, location });
|
|
79
|
+
});
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* @returns A clone of this SymbolUtil that is in delay mode: changes to the symbol table happened in the clone will
|
|
84
|
+
* not take effect until the {@link SymbolUtil.applyDelayedEdits} method is called on that clone.
|
|
85
|
+
*
|
|
86
|
+
* The clone shares the same reference of the global symbol table and symbol stacks, meaning that after
|
|
87
|
+
* `applyDelayedEdits` is called, the original SymbolUtil will also be modified.
|
|
88
|
+
*/
|
|
89
|
+
clone() {
|
|
90
|
+
return new SymbolUtil(__classPrivateFieldGet(this, _SymbolUtil_global, "f"), __classPrivateFieldGet(this, _SymbolUtil_currentContributor, "f"), true);
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Apply edits done during the delay mode.
|
|
94
|
+
*/
|
|
95
|
+
applyDelayedEdits() {
|
|
96
|
+
this._delayedOps.forEach(f => f());
|
|
97
|
+
this._delayedOps = [];
|
|
98
|
+
this._inDelayMode = false;
|
|
99
|
+
}
|
|
100
|
+
contributeAs(contributor, fn) {
|
|
101
|
+
const originalValue = __classPrivateFieldGet(this, _SymbolUtil_currentContributor, "f");
|
|
102
|
+
__classPrivateFieldSet(this, _SymbolUtil_currentContributor, contributor, "f");
|
|
103
|
+
try {
|
|
104
|
+
fn();
|
|
105
|
+
}
|
|
106
|
+
finally {
|
|
107
|
+
__classPrivateFieldSet(this, _SymbolUtil_currentContributor, originalValue, "f");
|
|
108
|
+
}
|
|
109
|
+
return this;
|
|
110
|
+
}
|
|
111
|
+
async contributeAsAsync(contributor, fn) {
|
|
112
|
+
const originalValue = __classPrivateFieldGet(this, _SymbolUtil_currentContributor, "f");
|
|
113
|
+
__classPrivateFieldSet(this, _SymbolUtil_currentContributor, contributor, "f");
|
|
114
|
+
try {
|
|
115
|
+
await fn();
|
|
116
|
+
}
|
|
117
|
+
finally {
|
|
118
|
+
__classPrivateFieldSet(this, _SymbolUtil_currentContributor, originalValue, "f");
|
|
119
|
+
}
|
|
120
|
+
return this;
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* @param
|
|
124
|
+
* - `contributor` - clear symbol locations contributed by this contributor. Pass in `undefined`
|
|
125
|
+
* to select all symbol locations that don't have a contributor.
|
|
126
|
+
* - `uri` - clear symbol locations associated with this URI.
|
|
127
|
+
* - `predicate` - clear symbol locations matching this predicate
|
|
128
|
+
*/
|
|
129
|
+
clear({ uri, contributor, predicate = () => true }) {
|
|
130
|
+
const getCaches = () => {
|
|
131
|
+
if (contributor) {
|
|
132
|
+
return __classPrivateFieldGet(this, _SymbolUtil_cache, "f")[contributor] ? [__classPrivateFieldGet(this, _SymbolUtil_cache, "f")[contributor]] : [];
|
|
133
|
+
}
|
|
134
|
+
else {
|
|
135
|
+
return Object.values(__classPrivateFieldGet(this, _SymbolUtil_cache, "f"));
|
|
136
|
+
}
|
|
137
|
+
};
|
|
138
|
+
const getPaths = () => {
|
|
139
|
+
const caches = getCaches();
|
|
140
|
+
const sets = uri
|
|
141
|
+
? caches.map(cache => cache[uri] ?? new Set())
|
|
142
|
+
: caches.map(cache => Object.values(cache)).flat();
|
|
143
|
+
return sets.map(s => [...s]).flat().map(Symbol_1.SymbolPath.fromString);
|
|
144
|
+
};
|
|
145
|
+
const getTables = () => {
|
|
146
|
+
return uri
|
|
147
|
+
? [__classPrivateFieldGet(this, _SymbolUtil_global, "f")]
|
|
148
|
+
: [__classPrivateFieldGet(this, _SymbolUtil_global, "f")];
|
|
149
|
+
};
|
|
150
|
+
const paths = getPaths();
|
|
151
|
+
const tables = getTables();
|
|
152
|
+
for (const table of tables) {
|
|
153
|
+
for (const path of paths) {
|
|
154
|
+
const { symbol } = SymbolUtil.lookupTable(table, path.category, path.path);
|
|
155
|
+
if (!symbol) {
|
|
156
|
+
continue;
|
|
157
|
+
}
|
|
158
|
+
this.removeLocationsFromSymbol(symbol, uri
|
|
159
|
+
? data => data.location.uri === uri && predicate(data)
|
|
160
|
+
: predicate);
|
|
161
|
+
}
|
|
162
|
+
this.trim(table);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
lookup(category, path, node) {
|
|
166
|
+
return SymbolUtil.lookupTable(this.global, category, path);
|
|
167
|
+
}
|
|
168
|
+
query(doc, category, ...path) {
|
|
169
|
+
const uri = SymbolUtil.toUri(doc);
|
|
170
|
+
const { parentSymbol, parentMap, symbol } = this.lookup(category, path, isDocAndNode(doc) ? doc.node : undefined);
|
|
171
|
+
const visible = symbol ? SymbolUtil.isVisible(symbol, uri) : true;
|
|
172
|
+
return new SymbolQuery({
|
|
173
|
+
category,
|
|
174
|
+
doc,
|
|
175
|
+
contributor: __classPrivateFieldGet(this, _SymbolUtil_currentContributor, "f"),
|
|
176
|
+
map: visible ? parentMap : undefined,
|
|
177
|
+
parentSymbol: parentSymbol,
|
|
178
|
+
path,
|
|
179
|
+
symbol: visible ? symbol : undefined,
|
|
180
|
+
util: this,
|
|
181
|
+
});
|
|
182
|
+
}
|
|
183
|
+
getVisibleSymbols(category, uri) {
|
|
184
|
+
const map = this.lookup(category, [], undefined).parentMap ?? undefined;
|
|
185
|
+
return SymbolUtil.filterVisibleSymbols(uri, map);
|
|
186
|
+
}
|
|
187
|
+
static toUri(uri) {
|
|
188
|
+
if (typeof uri === 'string') {
|
|
189
|
+
return uri;
|
|
190
|
+
}
|
|
191
|
+
if (isDocAndNode(uri)) {
|
|
192
|
+
return uri.doc.uri;
|
|
193
|
+
}
|
|
194
|
+
return uri.uri;
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* @see {@link SymbolUtil.trimMap}
|
|
198
|
+
*/
|
|
199
|
+
trim(table) {
|
|
200
|
+
const trimSymbol = (symbol) => {
|
|
201
|
+
if (!symbol) {
|
|
202
|
+
return;
|
|
203
|
+
}
|
|
204
|
+
if (SymbolUtil.isTrimmable(symbol)) {
|
|
205
|
+
delete symbol.parentMap[symbol.identifier];
|
|
206
|
+
this.emit('symbolRemoved', { symbol });
|
|
207
|
+
trimSymbol(symbol.parentSymbol);
|
|
208
|
+
}
|
|
209
|
+
};
|
|
210
|
+
for (const pathString of __classPrivateFieldGet(this, _SymbolUtil_trimmableSymbols, "f")) {
|
|
211
|
+
const path = Symbol_1.SymbolPath.fromString(pathString);
|
|
212
|
+
const { symbol } = SymbolUtil.lookupTable(table, path.category, path.path);
|
|
213
|
+
trimSymbol(symbol);
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
removeLocationsFromSymbol(symbol, predicate) {
|
|
217
|
+
for (const type of Symbol_1.SymbolUsageTypes) {
|
|
218
|
+
if (!symbol[type]) {
|
|
219
|
+
continue;
|
|
220
|
+
}
|
|
221
|
+
symbol[type] = symbol[type].reduce((result, location) => {
|
|
222
|
+
if (predicate({ location, symbol, type })) {
|
|
223
|
+
this.emit('symbolLocationRemoved', { symbol, type, location });
|
|
224
|
+
}
|
|
225
|
+
else {
|
|
226
|
+
result.push(location);
|
|
227
|
+
}
|
|
228
|
+
return result;
|
|
229
|
+
}, []);
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
enterMap(parentSymbol, map, category, path, identifier, addition, doc, contributor) {
|
|
233
|
+
let ans = map[identifier];
|
|
234
|
+
if (ans) {
|
|
235
|
+
this.amendSymbol(ans, addition, doc, contributor);
|
|
236
|
+
}
|
|
237
|
+
else {
|
|
238
|
+
ans = this.createSymbol(category, parentSymbol, map, path, identifier, addition, doc, contributor);
|
|
239
|
+
}
|
|
240
|
+
this.emit('symbolAmended', { symbol: ans });
|
|
241
|
+
return ans;
|
|
242
|
+
}
|
|
243
|
+
static lookupTable(table, category, path) {
|
|
244
|
+
let parentMap = table[category];
|
|
245
|
+
let parentSymbol;
|
|
246
|
+
let symbol;
|
|
247
|
+
for (let i = 0; i < path.length; i++) {
|
|
248
|
+
symbol = parentMap?.[path[i]];
|
|
249
|
+
if (!symbol) {
|
|
250
|
+
if (i !== path.length - 1) {
|
|
251
|
+
parentSymbol = undefined;
|
|
252
|
+
parentMap = undefined;
|
|
253
|
+
}
|
|
254
|
+
break;
|
|
255
|
+
}
|
|
256
|
+
if (i === path.length - 1) {
|
|
257
|
+
break;
|
|
258
|
+
}
|
|
259
|
+
parentSymbol = symbol;
|
|
260
|
+
parentMap = symbol.members;
|
|
261
|
+
}
|
|
262
|
+
return { parentSymbol, parentMap, symbol };
|
|
263
|
+
}
|
|
264
|
+
static lookupTables(tables, category, path) {
|
|
265
|
+
let parentMap;
|
|
266
|
+
let parentSymbol;
|
|
267
|
+
// Traverse from the last table to the first one.
|
|
268
|
+
for (let i = tables.length - 1; i >= 0; i--) {
|
|
269
|
+
const table = tables[i];
|
|
270
|
+
const result = this.lookupTable(table, category, path);
|
|
271
|
+
if (result.symbol) {
|
|
272
|
+
return result;
|
|
273
|
+
}
|
|
274
|
+
if (!parentSymbol && !parentMap && (result.parentSymbol || result.parentMap)) {
|
|
275
|
+
parentSymbol = result.parentSymbol;
|
|
276
|
+
parentMap = result.parentMap;
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
return { parentSymbol, parentMap, symbol: undefined };
|
|
280
|
+
}
|
|
281
|
+
createSymbol(category, parentSymbol, parentMap, path, identifier, addition, doc, contributor) {
|
|
282
|
+
const ans = parentMap[identifier] = {
|
|
283
|
+
category,
|
|
284
|
+
identifier,
|
|
285
|
+
...parentSymbol ? { parentSymbol } : {},
|
|
286
|
+
parentMap,
|
|
287
|
+
path,
|
|
288
|
+
...addition.data,
|
|
289
|
+
};
|
|
290
|
+
this.emit('symbolCreated', { symbol: ans });
|
|
291
|
+
this.amendSymbolUsage(ans, addition.usage, doc, contributor);
|
|
292
|
+
return ans;
|
|
293
|
+
}
|
|
294
|
+
amendSymbol(symbol, addition, doc, contributor) {
|
|
295
|
+
this.amendSymbolMetadata(symbol, addition.data);
|
|
296
|
+
this.amendSymbolUsage(symbol, addition.usage, doc, contributor);
|
|
297
|
+
}
|
|
298
|
+
amendSymbolMetadata(symbol, addition) {
|
|
299
|
+
if (addition) {
|
|
300
|
+
if ('data' in addition) {
|
|
301
|
+
symbol.data = addition.data;
|
|
302
|
+
}
|
|
303
|
+
if ('desc' in addition) {
|
|
304
|
+
symbol.desc = addition.desc;
|
|
305
|
+
}
|
|
306
|
+
if (addition.relations && Object.keys(addition.relations).length) {
|
|
307
|
+
symbol.relations ?? (symbol.relations = {});
|
|
308
|
+
for (const relationship of Object.keys(addition.relations)) {
|
|
309
|
+
symbol.relations[relationship] = addition.relations[relationship];
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
if ('subcategory' in addition) {
|
|
313
|
+
symbol.subcategory = addition.subcategory;
|
|
314
|
+
}
|
|
315
|
+
if ('visibility' in addition) {
|
|
316
|
+
// Visibility changes are only accepted if the change wouldn't result in the
|
|
317
|
+
// symbol being stored in a different symbol table.
|
|
318
|
+
const inGlobalTable = (v) => v === undefined || v === 2 /* Public */ || v === 3 /* Restricted */;
|
|
319
|
+
if (symbol.visibility === addition.visibility || (inGlobalTable(symbol.visibility) && inGlobalTable(addition.visibility))) {
|
|
320
|
+
symbol.visibility = addition.visibility;
|
|
321
|
+
}
|
|
322
|
+
else {
|
|
323
|
+
throw new Error(`Cannot change visibility from ${symbol.visibility} to ${addition.visibility}: ${JSON.stringify(Symbol_1.SymbolPath.fromSymbol(symbol))}`);
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
if (addition.visibilityRestriction?.length) {
|
|
327
|
+
symbol.visibilityRestriction = (symbol.visibilityRestriction ?? []).concat(addition.visibilityRestriction);
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
amendSymbolUsage(symbol, addition, doc, contributor) {
|
|
332
|
+
if (addition) {
|
|
333
|
+
const type = addition.type ?? 'reference';
|
|
334
|
+
const arr = symbol[type] ?? (symbol[type] = []);
|
|
335
|
+
const range = source_1.Range.get((SymbolAdditionUsageWithNode.is(addition) ? addition.node : addition.range) ?? 0);
|
|
336
|
+
const location = Symbol_1.SymbolLocation.create(doc, range, addition.fullRange, contributor, {
|
|
337
|
+
accessType: addition.accessType,
|
|
338
|
+
skipRenaming: addition.skipRenaming,
|
|
339
|
+
});
|
|
340
|
+
if (!doc.uri.startsWith('file:')) {
|
|
341
|
+
delete location.range;
|
|
342
|
+
delete location.posRange;
|
|
343
|
+
delete location.fullRange;
|
|
344
|
+
delete location.fullPosRange;
|
|
345
|
+
}
|
|
346
|
+
arr.push(location);
|
|
347
|
+
this.emit('symbolLocationCreated', { symbol, type, location });
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
/**
|
|
351
|
+
* @returns The ultimate symbol being pointed by the passed-in `symbol`'s alias.
|
|
352
|
+
*/
|
|
353
|
+
resolveAlias(symbol) {
|
|
354
|
+
return symbol?.relations?.aliasOf
|
|
355
|
+
? this.resolveAlias(this.lookup(symbol.relations.aliasOf.category, symbol.relations.aliasOf.path).symbol)
|
|
356
|
+
: symbol;
|
|
357
|
+
}
|
|
358
|
+
static filterVisibleSymbols(uri, map = {}) {
|
|
359
|
+
const ans = {};
|
|
360
|
+
for (const [identifier, symbol] of Object.entries(map)) {
|
|
361
|
+
if (SymbolUtil.isVisible(symbol, uri)) {
|
|
362
|
+
ans[identifier] = symbol;
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
return ans;
|
|
366
|
+
}
|
|
367
|
+
static isTrimmable(symbol) {
|
|
368
|
+
return !Object.keys(symbol.members ?? {}).length && !symbol.declaration?.length && !symbol.definition?.length && !symbol.implementation?.length && !symbol.reference?.length && !symbol.typeDefinition?.length;
|
|
369
|
+
}
|
|
370
|
+
static isVisible(symbol, _uri) {
|
|
371
|
+
switch (symbol.visibility) {
|
|
372
|
+
case 3 /* Restricted */:
|
|
373
|
+
return false; // FIXME: check with workspace root URIs.
|
|
374
|
+
case 0 /* Block */:
|
|
375
|
+
case 1 /* File */:
|
|
376
|
+
case 2 /* Public */:
|
|
377
|
+
default:
|
|
378
|
+
return true;
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
/**
|
|
382
|
+
* @returns If the symbol has declarations or definitions.
|
|
383
|
+
*/
|
|
384
|
+
static isDeclared(symbol) {
|
|
385
|
+
return !!(symbol?.declaration?.length || symbol?.definition?.length);
|
|
386
|
+
}
|
|
387
|
+
/**
|
|
388
|
+
* @returns If the symbol has definitions, or declarations and implementations.
|
|
389
|
+
*/
|
|
390
|
+
static isDefined(symbol) {
|
|
391
|
+
return !!(symbol?.definition?.length || (symbol?.definition?.length && symbol?.implementation?.length));
|
|
392
|
+
}
|
|
393
|
+
/**
|
|
394
|
+
* @returns If the symbol has implementations or definitions.
|
|
395
|
+
*/
|
|
396
|
+
static isImplemented(symbol) {
|
|
397
|
+
return !!(symbol?.implementation?.length || symbol?.definition?.length);
|
|
398
|
+
}
|
|
399
|
+
/**
|
|
400
|
+
* @returns If the symbol has references.
|
|
401
|
+
*/
|
|
402
|
+
static isReferenced(symbol) {
|
|
403
|
+
return !!symbol?.reference?.length;
|
|
404
|
+
}
|
|
405
|
+
/**
|
|
406
|
+
* @returns If the symbol has type definitions.
|
|
407
|
+
*/
|
|
408
|
+
static isTypeDefined(symbol) {
|
|
409
|
+
return !!symbol?.typeDefinition?.length;
|
|
410
|
+
}
|
|
411
|
+
/**
|
|
412
|
+
* @throws If the symbol does not have any declarations or definitions.
|
|
413
|
+
*/
|
|
414
|
+
static getDeclaredLocation(symbol) {
|
|
415
|
+
return symbol.declaration?.[0] ?? symbol.definition?.[0] ?? (() => { throw new Error(`Cannot get declared location of ${JSON.stringify(Symbol_1.SymbolPath.fromSymbol(symbol))}`); })();
|
|
416
|
+
}
|
|
417
|
+
static forEachSymbolInMap(map, fn) {
|
|
418
|
+
for (const symbol of Object.values(map)) {
|
|
419
|
+
fn(symbol);
|
|
420
|
+
if (symbol.members) {
|
|
421
|
+
this.forEachSymbolInMap(symbol.members, fn);
|
|
422
|
+
}
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
static forEachSymbol(table, fn) {
|
|
426
|
+
for (const map of Object.values(table)) {
|
|
427
|
+
this.forEachSymbolInMap(map, fn);
|
|
428
|
+
}
|
|
429
|
+
}
|
|
430
|
+
static forEachLocationOfSymbol(symbol, fn) {
|
|
431
|
+
for (const type of Symbol_1.SymbolUsageTypes) {
|
|
432
|
+
symbol[type]?.forEach(location => fn({ type, location }));
|
|
433
|
+
}
|
|
434
|
+
}
|
|
435
|
+
static isVisibilityInGlobal(v) {
|
|
436
|
+
return v === undefined || v === 2 /* Public */ || v === 3 /* Restricted */;
|
|
437
|
+
}
|
|
438
|
+
static areVisibilitiesCompatible(v1, v2) {
|
|
439
|
+
return ((this.isVisibilityInGlobal(v1) && this.isVisibilityInGlobal(v2)) ||
|
|
440
|
+
(v1 === 0 /* Block */ && v2 === 0 /* Block */) ||
|
|
441
|
+
(v1 === 1 /* File */ && v2 === 1 /* File */));
|
|
442
|
+
}
|
|
443
|
+
}
|
|
444
|
+
_SymbolUtil_global = new WeakMap(), _SymbolUtil_trimmableSymbols = new WeakMap(), _SymbolUtil_cache = new WeakMap(), _SymbolUtil_currentContributor = new WeakMap();
|
|
445
|
+
__decorate([
|
|
446
|
+
DelayModeSupport()
|
|
447
|
+
], SymbolUtil.prototype, "clear", null);
|
|
448
|
+
__decorate([
|
|
449
|
+
DelayModeSupport()
|
|
450
|
+
], SymbolUtil.prototype, "trim", null);
|
|
451
|
+
__decorate([
|
|
452
|
+
DelayModeSupport()
|
|
453
|
+
], SymbolUtil.prototype, "removeLocationsFromSymbol", null);
|
|
454
|
+
exports.SymbolUtil = SymbolUtil;
|
|
455
|
+
var SymbolAdditionUsageWithRange;
|
|
456
|
+
(function (SymbolAdditionUsageWithRange) {
|
|
457
|
+
/* istanbul ignore next */
|
|
458
|
+
function is(usage) {
|
|
459
|
+
return !!usage?.range;
|
|
460
|
+
}
|
|
461
|
+
SymbolAdditionUsageWithRange.is = is;
|
|
462
|
+
})(SymbolAdditionUsageWithRange || (SymbolAdditionUsageWithRange = {}));
|
|
463
|
+
var SymbolAdditionUsageWithNode;
|
|
464
|
+
(function (SymbolAdditionUsageWithNode) {
|
|
465
|
+
/* istanbul ignore next */
|
|
466
|
+
function is(usage) {
|
|
467
|
+
return !!usage?.node;
|
|
468
|
+
}
|
|
469
|
+
SymbolAdditionUsageWithNode.is = is;
|
|
470
|
+
})(SymbolAdditionUsageWithNode || (SymbolAdditionUsageWithNode = {}));
|
|
471
|
+
/* istanbul ignore next */
|
|
472
|
+
class SymbolQuery {
|
|
473
|
+
constructor({ category, contributor, doc, map, parentSymbol, path, symbol, util }) {
|
|
474
|
+
_SymbolQuery_doc.set(this, void 0);
|
|
475
|
+
_SymbolQuery_node.set(this, void 0);
|
|
476
|
+
/**
|
|
477
|
+
* If only a string URI (instead of a {@link TextDocument}) is provided when constructing this class.
|
|
478
|
+
*
|
|
479
|
+
* If this is `true`, {@link SymbolAdditionUsageWithRange.range} is ignored and treated as `[0, 0)` when entering symbols through this class.
|
|
480
|
+
*/
|
|
481
|
+
_SymbolQuery_createdWithUri.set(this, void 0);
|
|
482
|
+
_SymbolQuery_currentContributor.set(this, void 0);
|
|
483
|
+
_SymbolQuery_hasTriggeredIf.set(this, false
|
|
484
|
+
/**
|
|
485
|
+
* The map where the queried symbol is stored. `undefined` if the map hasn't been created yet.
|
|
486
|
+
*/
|
|
487
|
+
);
|
|
488
|
+
/**
|
|
489
|
+
* The map where the queried symbol is stored. `undefined` if the map hasn't been created yet.
|
|
490
|
+
*/
|
|
491
|
+
_SymbolQuery_map.set(this, void 0);
|
|
492
|
+
_SymbolQuery_parentSymbol.set(this, void 0);
|
|
493
|
+
/**
|
|
494
|
+
* The queried symbol. `undefined` if the symbol hasn't been created yet.
|
|
495
|
+
*/
|
|
496
|
+
_SymbolQuery_symbol.set(this, void 0);
|
|
497
|
+
this.category = category;
|
|
498
|
+
this.path = path;
|
|
499
|
+
if (typeof doc === 'string') {
|
|
500
|
+
doc = vscode_languageserver_textdocument_1.TextDocument.create(doc, '', 0, '');
|
|
501
|
+
__classPrivateFieldSet(this, _SymbolQuery_createdWithUri, true, "f");
|
|
502
|
+
}
|
|
503
|
+
else if (isDocAndNode(doc)) {
|
|
504
|
+
__classPrivateFieldSet(this, _SymbolQuery_node, doc.node, "f");
|
|
505
|
+
doc = doc.doc;
|
|
506
|
+
}
|
|
507
|
+
__classPrivateFieldSet(this, _SymbolQuery_doc, doc, "f");
|
|
508
|
+
__classPrivateFieldSet(this, _SymbolQuery_currentContributor, contributor, "f");
|
|
509
|
+
__classPrivateFieldSet(this, _SymbolQuery_map, map, "f");
|
|
510
|
+
__classPrivateFieldSet(this, _SymbolQuery_parentSymbol, parentSymbol, "f");
|
|
511
|
+
__classPrivateFieldSet(this, _SymbolQuery_symbol, symbol, "f");
|
|
512
|
+
this.util = util;
|
|
513
|
+
}
|
|
514
|
+
get symbol() {
|
|
515
|
+
return __classPrivateFieldGet(this, _SymbolQuery_symbol, "f");
|
|
516
|
+
}
|
|
517
|
+
get visibleMembers() {
|
|
518
|
+
return SymbolUtil.filterVisibleSymbols(__classPrivateFieldGet(this, _SymbolQuery_doc, "f").uri, this.path.length === 0 ? __classPrivateFieldGet(this, _SymbolQuery_map, "f") : __classPrivateFieldGet(this, _SymbolQuery_symbol, "f")?.members);
|
|
519
|
+
}
|
|
520
|
+
heyGimmeDaSymbol() {
|
|
521
|
+
return __classPrivateFieldGet(this, _SymbolQuery_symbol, "f");
|
|
522
|
+
}
|
|
523
|
+
with(fn) {
|
|
524
|
+
fn(this);
|
|
525
|
+
return this;
|
|
526
|
+
}
|
|
527
|
+
if(predicate, fn) {
|
|
528
|
+
if (predicate.call(this, __classPrivateFieldGet(this, _SymbolQuery_symbol, "f"), this)) {
|
|
529
|
+
fn.call(this, __classPrivateFieldGet(this, _SymbolQuery_symbol, "f"), this);
|
|
530
|
+
__classPrivateFieldSet(this, _SymbolQuery_hasTriggeredIf, true, "f");
|
|
531
|
+
}
|
|
532
|
+
return this;
|
|
533
|
+
}
|
|
534
|
+
/**
|
|
535
|
+
* Calls `fn` if the queried symbol does not exist.
|
|
536
|
+
*/
|
|
537
|
+
ifUnknown(fn) {
|
|
538
|
+
return this.if(s => s === undefined, fn);
|
|
539
|
+
}
|
|
540
|
+
/**
|
|
541
|
+
* Calls `fn` if the queried symbol exists (i.e. has any of declarations/definitions/implementations/references/typeDefinitions).
|
|
542
|
+
*/
|
|
543
|
+
ifKnown(fn) {
|
|
544
|
+
return this.if(s => s !== undefined, fn);
|
|
545
|
+
}
|
|
546
|
+
/**
|
|
547
|
+
* Calls `fn` if the queried symbol has declarations or definitions.
|
|
548
|
+
*/
|
|
549
|
+
ifDeclared(fn) {
|
|
550
|
+
return this.if((s) => SymbolUtil.isDeclared(s), fn);
|
|
551
|
+
}
|
|
552
|
+
/**
|
|
553
|
+
* Calls `fn` if the queried symbol has definitions, or both declarations and implementations.
|
|
554
|
+
*/
|
|
555
|
+
ifDefined(fn) {
|
|
556
|
+
return this.if(SymbolUtil.isDefined, fn);
|
|
557
|
+
}
|
|
558
|
+
/**
|
|
559
|
+
* Calls `fn` if the queried symbol has implementations or definitions.
|
|
560
|
+
*/
|
|
561
|
+
ifImplemented(fn) {
|
|
562
|
+
return this.if(SymbolUtil.isImplemented, fn);
|
|
563
|
+
}
|
|
564
|
+
/**
|
|
565
|
+
* Calls `fn` if the queried symbol has references.
|
|
566
|
+
*/
|
|
567
|
+
ifReferenced(fn) {
|
|
568
|
+
return this.if(SymbolUtil.isReferenced, fn);
|
|
569
|
+
}
|
|
570
|
+
/**
|
|
571
|
+
* Calls `fn` if the queried symbol has type definitions.
|
|
572
|
+
*/
|
|
573
|
+
ifTypeDefined(fn) {
|
|
574
|
+
return this.if(SymbolUtil.isTypeDefined, fn);
|
|
575
|
+
}
|
|
576
|
+
/**
|
|
577
|
+
* Calls `fn` if none of the former `if` conditions are met.
|
|
578
|
+
*/
|
|
579
|
+
else(fn) {
|
|
580
|
+
if (!__classPrivateFieldGet(this, _SymbolQuery_hasTriggeredIf, "f")) {
|
|
581
|
+
fn.call(this, __classPrivateFieldGet(this, _SymbolQuery_symbol, "f"), this);
|
|
582
|
+
}
|
|
583
|
+
return this;
|
|
584
|
+
}
|
|
585
|
+
/**
|
|
586
|
+
* Enters the queried symbol if none of the former `if` conditions are met.
|
|
587
|
+
*/
|
|
588
|
+
elseEnter(symbol) {
|
|
589
|
+
return this.else(() => this.enter(symbol));
|
|
590
|
+
}
|
|
591
|
+
/**
|
|
592
|
+
* Resolves the queried symbol if it is an alias and if none of the former `if` conditions are met.
|
|
593
|
+
*
|
|
594
|
+
* @throws If the current symbol points to an non-existent symbol.
|
|
595
|
+
*/
|
|
596
|
+
elseResolveAlias() {
|
|
597
|
+
return this.else(() => this.resolveAlias());
|
|
598
|
+
}
|
|
599
|
+
_enter(addition) {
|
|
600
|
+
const getMap = (addition) => {
|
|
601
|
+
var _a, _b;
|
|
602
|
+
if (__classPrivateFieldGet(this, _SymbolQuery_map, "f") && SymbolUtil.areVisibilitiesCompatible(addition.data?.visibility, __classPrivateFieldGet(this, _SymbolQuery_symbol, "f")?.visibility)) {
|
|
603
|
+
return __classPrivateFieldGet(this, _SymbolQuery_map, "f");
|
|
604
|
+
}
|
|
605
|
+
if (this.path.length > 1) {
|
|
606
|
+
if (__classPrivateFieldGet(this, _SymbolQuery_parentSymbol, "f")) {
|
|
607
|
+
if (!SymbolUtil.areVisibilitiesCompatible(addition.data?.visibility, __classPrivateFieldGet(this, _SymbolQuery_parentSymbol, "f").visibility)) {
|
|
608
|
+
throw new Error(`Cannot enter member “${this.getPath()}” of ${SymbolFormatter.stringifyVisibility(addition.data?.visibility)} visibility to parent of ${SymbolFormatter.stringifyVisibility(__classPrivateFieldGet(this, _SymbolQuery_parentSymbol, "f").visibility)} visibility`);
|
|
609
|
+
}
|
|
610
|
+
return (_a = __classPrivateFieldGet(this, _SymbolQuery_parentSymbol, "f")).members ?? (_a.members = {});
|
|
611
|
+
}
|
|
612
|
+
}
|
|
613
|
+
else {
|
|
614
|
+
let table;
|
|
615
|
+
if (SymbolUtil.isVisibilityInGlobal(addition.data?.visibility)) {
|
|
616
|
+
table = this.util.global;
|
|
617
|
+
}
|
|
618
|
+
else if (addition.data?.visibility === 1 /* File */) {
|
|
619
|
+
if (!__classPrivateFieldGet(this, _SymbolQuery_node, "f")) {
|
|
620
|
+
throw new Error(`Cannot enter “${this.getPath()}” with ${SymbolFormatter.stringifyVisibility(addition.data?.visibility)} visibility as no node is supplied`);
|
|
621
|
+
}
|
|
622
|
+
let node = __classPrivateFieldGet(this, _SymbolQuery_node, "f");
|
|
623
|
+
while (node) {
|
|
624
|
+
if (node.type === 'file') {
|
|
625
|
+
table = node.locals;
|
|
626
|
+
break;
|
|
627
|
+
}
|
|
628
|
+
node = node.parent;
|
|
629
|
+
}
|
|
630
|
+
if (!table) {
|
|
631
|
+
throw new Error(`Cannot enter “${this.getPath()}” with ${SymbolFormatter.stringifyVisibility(addition.data?.visibility)} visibility as no file node is supplied`);
|
|
632
|
+
}
|
|
633
|
+
}
|
|
634
|
+
else {
|
|
635
|
+
if (!__classPrivateFieldGet(this, _SymbolQuery_node, "f")) {
|
|
636
|
+
throw new Error(`Cannot enter “${this.getPath()}” with ${SymbolFormatter.stringifyVisibility(addition.data?.visibility)} visibility as no node is supplied`);
|
|
637
|
+
}
|
|
638
|
+
let node = __classPrivateFieldGet(this, _SymbolQuery_node, "f");
|
|
639
|
+
while (node) {
|
|
640
|
+
if (node.locals) {
|
|
641
|
+
table = node.locals;
|
|
642
|
+
break;
|
|
643
|
+
}
|
|
644
|
+
node = node.parent;
|
|
645
|
+
}
|
|
646
|
+
if (!table) {
|
|
647
|
+
throw new Error(`Cannot enter “${this.getPath()}” with ${SymbolFormatter.stringifyVisibility(addition.data?.visibility)} visibility as no node with locals is supplied`);
|
|
648
|
+
}
|
|
649
|
+
}
|
|
650
|
+
// TODO: Move part of symbol from global to table.
|
|
651
|
+
return table[_b = this.category] ?? (table[_b] = {});
|
|
652
|
+
}
|
|
653
|
+
throw new Error(`Cannot create the symbol map for “${this.getPath()}”`);
|
|
654
|
+
};
|
|
655
|
+
// Treat `usage.range` as `[0, 0)` if this class was constructed with a string URI (instead of a `TextDocument`).
|
|
656
|
+
if (__classPrivateFieldGet(this, _SymbolQuery_createdWithUri, "f") && SymbolAdditionUsageWithRange.is(addition.usage)) {
|
|
657
|
+
addition.usage.range = source_1.Range.create(0, 0);
|
|
658
|
+
}
|
|
659
|
+
__classPrivateFieldSet(this, _SymbolQuery_map, getMap(addition), "f");
|
|
660
|
+
__classPrivateFieldSet(this, _SymbolQuery_symbol, this.util.enterMap(__classPrivateFieldGet(this, _SymbolQuery_parentSymbol, "f"), __classPrivateFieldGet(this, _SymbolQuery_map, "f"), this.category, this.path, this.path[this.path.length - 1], addition, __classPrivateFieldGet(this, _SymbolQuery_doc, "f"), __classPrivateFieldGet(this, _SymbolQuery_currentContributor, "f")), "f");
|
|
661
|
+
if (addition.usage?.node) {
|
|
662
|
+
addition.usage.node.symbol = __classPrivateFieldGet(this, _SymbolQuery_symbol, "f");
|
|
663
|
+
}
|
|
664
|
+
}
|
|
665
|
+
/**
|
|
666
|
+
* Enters the queried symbol.
|
|
667
|
+
*
|
|
668
|
+
* @throws If the parent of this symbol doesn't exist either.
|
|
669
|
+
*/
|
|
670
|
+
enter(addition) {
|
|
671
|
+
this._enter(addition);
|
|
672
|
+
return this;
|
|
673
|
+
}
|
|
674
|
+
/**
|
|
675
|
+
* Amends the queried symbol if the queried symbol exists (i.e. has any of declarations/definitions/implementations/references/typeDefinitions) and is visible at the current scope.
|
|
676
|
+
*
|
|
677
|
+
* This is equivalent to calling
|
|
678
|
+
* ```typescript
|
|
679
|
+
* query.ifKnown(function () {
|
|
680
|
+
* this.enter(symbol)
|
|
681
|
+
* })
|
|
682
|
+
* ```
|
|
683
|
+
*
|
|
684
|
+
* Therefore, if the symbol is successfully amended, `elseX` methods afterwards will **not** be executed.
|
|
685
|
+
*/
|
|
686
|
+
amend(symbol) {
|
|
687
|
+
return this.ifKnown(() => this.enter(symbol));
|
|
688
|
+
}
|
|
689
|
+
/**
|
|
690
|
+
* Resolves this symbol if it exists and is an alias.
|
|
691
|
+
*
|
|
692
|
+
* @throws If the current symbol points to an non-existent symbol. The state of this object will not be changed
|
|
693
|
+
* after the error is thrown.
|
|
694
|
+
*/
|
|
695
|
+
resolveAlias() {
|
|
696
|
+
if (__classPrivateFieldGet(this, _SymbolQuery_symbol, "f")) {
|
|
697
|
+
const result = this.util.resolveAlias(__classPrivateFieldGet(this, _SymbolQuery_symbol, "f"));
|
|
698
|
+
if (!result) {
|
|
699
|
+
throw new Error('The current symbol points to an non-existent symbol.');
|
|
700
|
+
}
|
|
701
|
+
__classPrivateFieldSet(this, _SymbolQuery_symbol, result, "f");
|
|
702
|
+
__classPrivateFieldSet(this, _SymbolQuery_map, result.parentMap, "f");
|
|
703
|
+
}
|
|
704
|
+
return this;
|
|
705
|
+
}
|
|
706
|
+
member() {
|
|
707
|
+
// Handle overloads.
|
|
708
|
+
let doc, identifier, fn;
|
|
709
|
+
if (arguments.length === 2) {
|
|
710
|
+
// Ensure the member query result will not unknowingly have a dummy TextDocument passed down from this class.
|
|
711
|
+
doc = __classPrivateFieldGet(this, _SymbolQuery_createdWithUri, "f") ? __classPrivateFieldGet(this, _SymbolQuery_doc, "f").uri : __classPrivateFieldGet(this, _SymbolQuery_doc, "f");
|
|
712
|
+
identifier = arguments[0];
|
|
713
|
+
fn = arguments[1];
|
|
714
|
+
}
|
|
715
|
+
else {
|
|
716
|
+
doc = arguments[0];
|
|
717
|
+
identifier = arguments[1];
|
|
718
|
+
fn = arguments[2];
|
|
719
|
+
}
|
|
720
|
+
if (__classPrivateFieldGet(this, _SymbolQuery_symbol, "f") === undefined) {
|
|
721
|
+
throw new Error(`Tried to query member symbol “${identifier}” from an undefined symbol (path “${this.path.join('.')}”)`);
|
|
722
|
+
}
|
|
723
|
+
const memberDoc = typeof doc === 'string' && doc === __classPrivateFieldGet(this, _SymbolQuery_doc, "f").uri && !__classPrivateFieldGet(this, _SymbolQuery_createdWithUri, "f")
|
|
724
|
+
? __classPrivateFieldGet(this, _SymbolQuery_doc, "f")
|
|
725
|
+
: doc;
|
|
726
|
+
const memberMap = __classPrivateFieldGet(this, _SymbolQuery_symbol, "f").members;
|
|
727
|
+
const memberSymbol = memberMap?.[identifier];
|
|
728
|
+
const memberQueryResult = new SymbolQuery({
|
|
729
|
+
category: this.category,
|
|
730
|
+
doc: memberDoc,
|
|
731
|
+
contributor: __classPrivateFieldGet(this, _SymbolQuery_currentContributor, "f"),
|
|
732
|
+
map: memberMap,
|
|
733
|
+
parentSymbol: __classPrivateFieldGet(this, _SymbolQuery_symbol, "f"),
|
|
734
|
+
path: [...this.path, identifier],
|
|
735
|
+
symbol: memberSymbol,
|
|
736
|
+
util: this.util,
|
|
737
|
+
});
|
|
738
|
+
fn(memberQueryResult);
|
|
739
|
+
return this;
|
|
740
|
+
}
|
|
741
|
+
/**
|
|
742
|
+
* Do something with this query on each value in a given iterable. The query itself will be included
|
|
743
|
+
* in the callback function as the second parameter.
|
|
744
|
+
*/
|
|
745
|
+
onEach(values, fn) {
|
|
746
|
+
for (const value of values) {
|
|
747
|
+
fn.call(this, value, this);
|
|
748
|
+
}
|
|
749
|
+
return this;
|
|
750
|
+
}
|
|
751
|
+
forEachMember(fn) {
|
|
752
|
+
return this.onEach(Object.keys(this.visibleMembers), identifier => this.member(identifier, query => fn(identifier, query)));
|
|
753
|
+
}
|
|
754
|
+
getPath() {
|
|
755
|
+
return `${this.category}.${this.path.join('/')}`;
|
|
756
|
+
}
|
|
757
|
+
}
|
|
758
|
+
_SymbolQuery_doc = new WeakMap(), _SymbolQuery_node = new WeakMap(), _SymbolQuery_createdWithUri = new WeakMap(), _SymbolQuery_currentContributor = new WeakMap(), _SymbolQuery_hasTriggeredIf = new WeakMap(), _SymbolQuery_map = new WeakMap(), _SymbolQuery_parentSymbol = new WeakMap(), _SymbolQuery_symbol = new WeakMap();
|
|
759
|
+
__decorate([
|
|
760
|
+
DelayModeSupport((self) => self.util)
|
|
761
|
+
], SymbolQuery.prototype, "_enter", null);
|
|
762
|
+
exports.SymbolQuery = SymbolQuery;
|
|
763
|
+
/* istanbul ignore next */
|
|
764
|
+
/**
|
|
765
|
+
* A series of methods for converting symbol structures to human-readable outputs. Mostly for debug purposes.
|
|
766
|
+
*/
|
|
767
|
+
var SymbolFormatter;
|
|
768
|
+
(function (SymbolFormatter) {
|
|
769
|
+
const IndentChar = '+ ';
|
|
770
|
+
function stringifySymbolStack(stack) {
|
|
771
|
+
return stack.map(table => stringifySymbolTable(table)).join('\n------------\n');
|
|
772
|
+
}
|
|
773
|
+
SymbolFormatter.stringifySymbolStack = stringifySymbolStack;
|
|
774
|
+
function stringifySymbolTable(table, indent = '') {
|
|
775
|
+
const ans = [];
|
|
776
|
+
for (const category of Object.keys(table)) {
|
|
777
|
+
const map = table[category];
|
|
778
|
+
ans.push([category, stringifySymbolMap(map, `${indent}${IndentChar}`)]);
|
|
779
|
+
}
|
|
780
|
+
return ans.map(v => `CATEGORY ${v[0]}\n${v[1]}`).join(`\n${indent}------------\n`) || 'EMPTY TABLE';
|
|
781
|
+
}
|
|
782
|
+
SymbolFormatter.stringifySymbolTable = stringifySymbolTable;
|
|
783
|
+
function stringifySymbolMap(map, indent = '') {
|
|
784
|
+
if (!map) {
|
|
785
|
+
return 'undefined';
|
|
786
|
+
}
|
|
787
|
+
const ans = [];
|
|
788
|
+
for (const identifier of Object.keys(map)) {
|
|
789
|
+
const symbol = map[identifier];
|
|
790
|
+
assert_1.strict.equal(identifier, symbol.identifier);
|
|
791
|
+
ans.push(stringifySymbol(symbol, indent));
|
|
792
|
+
}
|
|
793
|
+
return ans.join(`\n${indent}------------\n`);
|
|
794
|
+
}
|
|
795
|
+
SymbolFormatter.stringifySymbolMap = stringifySymbolMap;
|
|
796
|
+
function stringifySymbol(symbol, indent = '') {
|
|
797
|
+
if (!symbol) {
|
|
798
|
+
return 'undefined';
|
|
799
|
+
}
|
|
800
|
+
const ans = [];
|
|
801
|
+
assert_1.strict.equal(symbol.path[symbol.path.length - 1], symbol.identifier);
|
|
802
|
+
ans.push(`SYMBOL ${symbol.path.join('.')}` +
|
|
803
|
+
` {${symbol.category}${symbol.subcategory ? ` (${symbol.subcategory})` : ''}}` +
|
|
804
|
+
` [${stringifyVisibility(symbol.visibility, symbol.visibilityRestriction)}]`);
|
|
805
|
+
if (symbol.data) {
|
|
806
|
+
ans.push(`${IndentChar}data: ${JSON.stringify(symbol.data)}`);
|
|
807
|
+
}
|
|
808
|
+
if (symbol.desc) {
|
|
809
|
+
ans.push(`${IndentChar}description: ${symbol.desc}`);
|
|
810
|
+
}
|
|
811
|
+
for (const type of Symbol_1.SymbolUsageTypes) {
|
|
812
|
+
if (symbol[type]) {
|
|
813
|
+
ans.push(`${IndentChar}${type}:\n${symbol[type].map(v => `${indent}${IndentChar.repeat(2)}${JSON.stringify(v)}`).join(`\n${indent}${IndentChar.repeat(2)}------------\n`)}`);
|
|
814
|
+
}
|
|
815
|
+
}
|
|
816
|
+
if (symbol.relations) {
|
|
817
|
+
ans.push(`${IndentChar}relations: ${JSON.stringify(symbol.relations)}`);
|
|
818
|
+
}
|
|
819
|
+
if (symbol.members) {
|
|
820
|
+
ans.push(`${IndentChar}members:\n${stringifySymbolMap(symbol.members, `${indent}${IndentChar.repeat(2)}`)}`);
|
|
821
|
+
}
|
|
822
|
+
return ans.map(v => `${indent}${v}`).join('\n');
|
|
823
|
+
}
|
|
824
|
+
SymbolFormatter.stringifySymbol = stringifySymbol;
|
|
825
|
+
function stringifyVisibility(visibility, visibilityRestriction) {
|
|
826
|
+
let stringVisibility;
|
|
827
|
+
// Const enums cannot be indexed even if `--preserveConstEnums` is on: https://github.com/microsoft/TypeScript/issues/31353
|
|
828
|
+
switch (visibility) {
|
|
829
|
+
case 0 /* Block */:
|
|
830
|
+
stringVisibility = 'Block';
|
|
831
|
+
break;
|
|
832
|
+
case 1 /* File */:
|
|
833
|
+
stringVisibility = 'File';
|
|
834
|
+
break;
|
|
835
|
+
case 3 /* Restricted */:
|
|
836
|
+
stringVisibility = 'Restricted';
|
|
837
|
+
break;
|
|
838
|
+
default:
|
|
839
|
+
stringVisibility = 'Public';
|
|
840
|
+
break;
|
|
841
|
+
}
|
|
842
|
+
return `${stringVisibility}${visibilityRestriction ? ` ${visibilityRestriction.map(v => `“${v}”`).join(', ')}` : ''}`;
|
|
843
|
+
}
|
|
844
|
+
SymbolFormatter.stringifyVisibility = stringifyVisibility;
|
|
845
|
+
function stringifyLookupResult(result) {
|
|
846
|
+
return `parentSymbol:
|
|
847
|
+
${stringifySymbol(result.parentSymbol, IndentChar)}
|
|
848
|
+
parentMap:
|
|
849
|
+
${stringifySymbolMap(result.parentMap, IndentChar)}
|
|
850
|
+
symbol:
|
|
851
|
+
${stringifySymbol(result.symbol, IndentChar)}`;
|
|
852
|
+
}
|
|
853
|
+
SymbolFormatter.stringifyLookupResult = stringifyLookupResult;
|
|
854
|
+
})(SymbolFormatter = exports.SymbolFormatter || (exports.SymbolFormatter = {}));
|
|
855
|
+
/**
|
|
856
|
+
* Make a method support delay mode: if the {@link SymbolUtil} is in delay mode, the actual invocation of the method will be
|
|
857
|
+
* stored to the {@link SymbolUtil._delayedOps} array.
|
|
858
|
+
*
|
|
859
|
+
* The decorated method MUST have return type `void`.
|
|
860
|
+
*/
|
|
861
|
+
function DelayModeSupport(getUtil = self => self) {
|
|
862
|
+
return (_target, _key, descripter) => {
|
|
863
|
+
const decoratedMethod = descripter.value;
|
|
864
|
+
// The `function` syntax is used to preserve `this` context from the decorated method.
|
|
865
|
+
descripter.value = function (...args) {
|
|
866
|
+
const util = getUtil(this);
|
|
867
|
+
if (util._inDelayMode) {
|
|
868
|
+
util._delayedOps.push(decoratedMethod.bind(this, ...args));
|
|
869
|
+
}
|
|
870
|
+
else {
|
|
871
|
+
decoratedMethod.apply(this, args);
|
|
872
|
+
}
|
|
873
|
+
};
|
|
874
|
+
return descripter;
|
|
875
|
+
};
|
|
876
|
+
}
|
|
877
|
+
function isDocAndNode(doc) {
|
|
878
|
+
return !!doc.doc;
|
|
879
|
+
}
|
|
880
|
+
//# sourceMappingURL=SymbolUtil.js.map
|