@spyglassmc/mcdoc 0.3.8 → 0.3.9
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/lib/binder/index.js +108 -192
- package/lib/index.d.ts +1 -0
- package/lib/index.js +4 -4
- package/lib/node/index.d.ts +5 -0
- package/lib/node/index.js +76 -131
- package/lib/parser/index.js +97 -217
- package/lib/runtime/attribute/builtin.d.ts +3 -0
- package/lib/runtime/attribute/builtin.js +130 -0
- package/lib/runtime/attribute/index.d.ts +22 -0
- package/lib/runtime/attribute/index.js +22 -0
- package/lib/runtime/attribute/validator.d.ts +16 -0
- package/lib/runtime/attribute/validator.js +85 -0
- package/lib/runtime/checker/context.d.ts +34 -0
- package/lib/runtime/checker/context.js +17 -0
- package/lib/runtime/checker/error.d.ts +70 -0
- package/lib/runtime/checker/error.js +352 -0
- package/lib/runtime/checker/index.d.ts +80 -0
- package/lib/runtime/checker/index.js +914 -0
- package/lib/runtime/completer/index.d.ts +20 -0
- package/lib/runtime/completer/index.js +123 -0
- package/lib/runtime/index.d.ts +5 -0
- package/lib/runtime/index.js +5 -0
- package/lib/type/index.d.ts +65 -82
- package/lib/type/index.js +341 -407
- package/lib/uri_processors.js +2 -8
- package/package.json +3 -3
package/lib/type/index.js
CHANGED
|
@@ -1,51 +1,298 @@
|
|
|
1
1
|
import { Arrayable, Dev } from '@spyglassmc/core';
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
2
|
+
import { getRangeDelimiter, RangeKind } from '../node/index.js';
|
|
3
|
+
export var Attributes;
|
|
4
|
+
(function (Attributes) {
|
|
5
|
+
function equals(a, b) {
|
|
6
|
+
if (a?.length !== b?.length) {
|
|
7
|
+
return false;
|
|
8
|
+
}
|
|
9
|
+
if (!a || !b) {
|
|
10
|
+
return true;
|
|
11
|
+
}
|
|
12
|
+
for (let i = 0; i < a.length; i++) {
|
|
13
|
+
if (!Attribute.equals(a[i], b[i])) {
|
|
14
|
+
return false;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
return true;
|
|
18
|
+
}
|
|
19
|
+
Attributes.equals = equals;
|
|
20
|
+
})(Attributes || (Attributes = {}));
|
|
21
|
+
export var Attribute;
|
|
22
|
+
(function (Attribute) {
|
|
23
|
+
function equals(a, b) {
|
|
24
|
+
if (a.name !== b.name) {
|
|
25
|
+
return false;
|
|
26
|
+
}
|
|
27
|
+
if (a.value && b.value) {
|
|
28
|
+
return AttributeValue.equals(a.value, b.value);
|
|
29
|
+
}
|
|
30
|
+
return a.value === b.value;
|
|
31
|
+
}
|
|
32
|
+
Attribute.equals = equals;
|
|
33
|
+
})(Attribute || (Attribute = {}));
|
|
34
|
+
export var AttributeValue;
|
|
35
|
+
(function (AttributeValue) {
|
|
36
|
+
function equals(a, b) {
|
|
37
|
+
if (a.kind !== b.kind) {
|
|
38
|
+
return false;
|
|
39
|
+
}
|
|
40
|
+
if (a.kind === 'tree') {
|
|
41
|
+
if (Object.keys(a.values).length !== Object.keys(b.values).length) {
|
|
42
|
+
return false;
|
|
43
|
+
}
|
|
44
|
+
for (const kvp of Object.entries(a.values)) {
|
|
45
|
+
const other = b.values[kvp[0]];
|
|
46
|
+
if (!other) {
|
|
47
|
+
return false;
|
|
48
|
+
}
|
|
49
|
+
if (!equals(kvp[1], other)) {
|
|
50
|
+
return false;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
return true;
|
|
54
|
+
}
|
|
55
|
+
else {
|
|
56
|
+
return McdocType.equals(a, b);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
AttributeValue.equals = equals;
|
|
60
|
+
})(AttributeValue || (AttributeValue = {}));
|
|
61
|
+
export var NumericRange;
|
|
62
|
+
(function (NumericRange) {
|
|
63
|
+
function isInRange(range, val) {
|
|
64
|
+
const { min = -Infinity, max = Infinity } = range;
|
|
65
|
+
if (RangeKind.isLeftExclusive(range.kind) ? val <= min : val < min) {
|
|
66
|
+
return false;
|
|
67
|
+
}
|
|
68
|
+
if (RangeKind.isRightExclusive(range.kind) ? val >= max : val > max) {
|
|
69
|
+
return false;
|
|
70
|
+
}
|
|
71
|
+
return true;
|
|
72
|
+
}
|
|
73
|
+
NumericRange.isInRange = isInRange;
|
|
74
|
+
function equals(a, b) {
|
|
75
|
+
return a.kind === b.kind
|
|
76
|
+
&& a.min === b.min
|
|
77
|
+
&& a.max === b.max;
|
|
78
|
+
}
|
|
79
|
+
NumericRange.equals = equals;
|
|
80
|
+
function intersect(a, b) {
|
|
81
|
+
const min = a.min !== undefined && b.min !== undefined
|
|
82
|
+
? Math.max(a.min, b.min)
|
|
83
|
+
: a.min !== undefined
|
|
84
|
+
? a.min
|
|
85
|
+
: b.min;
|
|
86
|
+
const max = a.max !== undefined && b.max !== undefined
|
|
87
|
+
? Math.min(a.max, b.max)
|
|
88
|
+
: a.max !== undefined
|
|
89
|
+
? a.max
|
|
90
|
+
: b.max;
|
|
91
|
+
let kind = 0b00;
|
|
92
|
+
if (min === a.min && RangeKind.isLeftExclusive(a.kind)) {
|
|
93
|
+
kind |= 0b10;
|
|
94
|
+
}
|
|
95
|
+
else if (min === b.min && RangeKind.isLeftExclusive(b.kind)) {
|
|
96
|
+
kind |= 0b10;
|
|
97
|
+
}
|
|
98
|
+
if (max === a.max && RangeKind.isRightExclusive(a.kind)) {
|
|
99
|
+
kind |= 0b01;
|
|
100
|
+
}
|
|
101
|
+
else if (max === b.max && RangeKind.isRightExclusive(b.kind)) {
|
|
102
|
+
kind |= 0b01;
|
|
103
|
+
}
|
|
104
|
+
return { kind: kind, min, max };
|
|
105
|
+
}
|
|
106
|
+
NumericRange.intersect = intersect;
|
|
107
|
+
function toString({ kind, min, max }) {
|
|
108
|
+
return min === max && kind === 0b00
|
|
109
|
+
? min !== undefined ? `${min}` : getRangeDelimiter(kind)
|
|
110
|
+
: `${min ?? ''}${getRangeDelimiter(kind)}${max ?? ''}`;
|
|
111
|
+
}
|
|
112
|
+
NumericRange.toString = toString;
|
|
113
|
+
})(NumericRange || (NumericRange = {}));
|
|
114
|
+
export const StaticIndexKeywords = Object.freeze(['fallback', 'none', 'unknown', 'spawnitem', 'blockitem']);
|
|
115
|
+
export var ParallelIndices;
|
|
116
|
+
(function (ParallelIndices) {
|
|
117
|
+
function equals(a, b) {
|
|
118
|
+
if (a.length !== b.length) {
|
|
119
|
+
return false;
|
|
120
|
+
}
|
|
121
|
+
for (let i = 0; i < a.length; i++) {
|
|
122
|
+
const first = a[i];
|
|
123
|
+
const second = b[i];
|
|
124
|
+
if (first.kind !== second.kind) {
|
|
125
|
+
return false;
|
|
126
|
+
}
|
|
127
|
+
if (first.kind === 'static') {
|
|
128
|
+
return first.value !== second.value;
|
|
129
|
+
}
|
|
130
|
+
if (first.accessor.length !== second.accessor.length) {
|
|
131
|
+
return false;
|
|
132
|
+
}
|
|
133
|
+
for (let j = 0; j < first.accessor.length; j++) {
|
|
134
|
+
const firstAcc = first.accessor[j];
|
|
135
|
+
const secondAcc = second.accessor[j];
|
|
136
|
+
if (typeof firstAcc === 'string' || typeof secondAcc === 'string') {
|
|
137
|
+
if (firstAcc !== secondAcc) {
|
|
138
|
+
return false;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
else if (firstAcc.keyword !== secondAcc.keyword) {
|
|
142
|
+
return false;
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
return true;
|
|
147
|
+
}
|
|
148
|
+
ParallelIndices.equals = equals;
|
|
149
|
+
})(ParallelIndices || (ParallelIndices = {}));
|
|
150
|
+
export const EmptyUnion = Object.freeze({ kind: 'union', members: [] });
|
|
15
151
|
export function createEmptyUnion(attributes) {
|
|
16
152
|
return {
|
|
17
153
|
...EmptyUnion,
|
|
18
154
|
// attributes,
|
|
19
155
|
};
|
|
20
156
|
}
|
|
21
|
-
export const NumericTypeIntKinds = Object.freeze([
|
|
22
|
-
'byte',
|
|
23
|
-
'short',
|
|
24
|
-
'int',
|
|
25
|
-
'long',
|
|
26
|
-
]);
|
|
157
|
+
export const NumericTypeIntKinds = Object.freeze(['byte', 'short', 'int', 'long']);
|
|
27
158
|
export const NumericTypeFloatKinds = Object.freeze(['float', 'double']);
|
|
28
|
-
export const NumericTypeKinds = Object.freeze([
|
|
29
|
-
|
|
30
|
-
...NumericTypeFloatKinds,
|
|
31
|
-
]);
|
|
32
|
-
export const PrimitiveArrayValueKinds = Object.freeze([
|
|
33
|
-
'byte',
|
|
34
|
-
'int',
|
|
35
|
-
'long',
|
|
36
|
-
]);
|
|
159
|
+
export const NumericTypeKinds = Object.freeze([...NumericTypeIntKinds, ...NumericTypeFloatKinds]);
|
|
160
|
+
export const PrimitiveArrayValueKinds = Object.freeze(['byte', 'int', 'long']);
|
|
37
161
|
export const PrimitiveArrayKinds = Object.freeze(PrimitiveArrayValueKinds.map((kind) => `${kind}_array`));
|
|
38
162
|
export var McdocType;
|
|
39
163
|
(function (McdocType) {
|
|
164
|
+
function equals(a, b) {
|
|
165
|
+
if (a.kind !== b.kind) {
|
|
166
|
+
return false;
|
|
167
|
+
}
|
|
168
|
+
if (!Attributes.equals(a.attributes, b.attributes)) {
|
|
169
|
+
return false;
|
|
170
|
+
}
|
|
171
|
+
switch (a.kind) {
|
|
172
|
+
case 'literal':
|
|
173
|
+
return a.value.kind === b.value.kind
|
|
174
|
+
&& a.value.value === b.value.value;
|
|
175
|
+
case 'byte':
|
|
176
|
+
case 'short':
|
|
177
|
+
case 'int':
|
|
178
|
+
case 'long':
|
|
179
|
+
case 'float':
|
|
180
|
+
case 'double':
|
|
181
|
+
return a.valueRange === b.valueRange;
|
|
182
|
+
case 'string':
|
|
183
|
+
return a.lengthRange === b.lengthRange;
|
|
184
|
+
case 'byte_array':
|
|
185
|
+
case 'int_array':
|
|
186
|
+
case 'long_array':
|
|
187
|
+
return a.lengthRange === b.lengthRange
|
|
188
|
+
&& a.valueRange === b.valueRange;
|
|
189
|
+
case 'list':
|
|
190
|
+
return a.lengthRange === b.lengthRange
|
|
191
|
+
&& equals(a.item, b.item);
|
|
192
|
+
case 'tuple':
|
|
193
|
+
if (a.items.length !== b.items.length) {
|
|
194
|
+
return false;
|
|
195
|
+
}
|
|
196
|
+
for (let i = 0; i < a.items.length; i++) {
|
|
197
|
+
if (!equals(a.items[i], b.items[i])) {
|
|
198
|
+
return false;
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
return true;
|
|
202
|
+
case 'struct':
|
|
203
|
+
return a.fields.length === b.fields.length && !a.fields.some(f => {
|
|
204
|
+
if (f.kind === 'pair') {
|
|
205
|
+
return !b.fields.some(of => of.kind === 'pair'
|
|
206
|
+
&& f.optional === of.optional
|
|
207
|
+
&& f.deprecated === of.deprecated
|
|
208
|
+
&& Attributes.equals(f.attributes, of.attributes)
|
|
209
|
+
&& (typeof f.key === 'string' || typeof of.key === 'string'
|
|
210
|
+
? f.key === of.key
|
|
211
|
+
: equals(f.key, of.key))
|
|
212
|
+
&& equals(f.type, of.type));
|
|
213
|
+
}
|
|
214
|
+
return !b.fields.some(of => of.kind === 'spread'
|
|
215
|
+
&& Attributes.equals(f.attributes, of.attributes)
|
|
216
|
+
&& equals(f.type, of.type));
|
|
217
|
+
});
|
|
218
|
+
case 'union':
|
|
219
|
+
if (a.members.length !== b.members.length) {
|
|
220
|
+
return false;
|
|
221
|
+
}
|
|
222
|
+
for (let i = 0; i < a.members.length; i++) {
|
|
223
|
+
if (!equals(a.members[i], b.members[i])) {
|
|
224
|
+
return false;
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
return true;
|
|
228
|
+
case 'enum':
|
|
229
|
+
if (a.enumKind !== b.enumKind
|
|
230
|
+
|| a.values.length !== b.values.length) {
|
|
231
|
+
return false;
|
|
232
|
+
}
|
|
233
|
+
for (let i = 0; i < a.values.length; i++) {
|
|
234
|
+
const first = a.values[i];
|
|
235
|
+
const second = b.values[i];
|
|
236
|
+
if (first.identifier !== second.identifier || first.value !== second.value
|
|
237
|
+
|| !Attributes.equals(first.attributes, second.attributes)) {
|
|
238
|
+
return false;
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
return true;
|
|
242
|
+
case 'reference':
|
|
243
|
+
return a.path === b.path;
|
|
244
|
+
case 'template':
|
|
245
|
+
if (a.typeParams.length !== b.typeParams.length) {
|
|
246
|
+
return false;
|
|
247
|
+
}
|
|
248
|
+
for (let i = 0; i < a.typeParams.length; i++) {
|
|
249
|
+
if (a.typeParams[i].path !== b.typeParams[i].path) {
|
|
250
|
+
return false;
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
return equals(a.child, b.child);
|
|
254
|
+
case 'concrete':
|
|
255
|
+
if (a.typeArgs.length !== b.typeArgs.length) {
|
|
256
|
+
return false;
|
|
257
|
+
}
|
|
258
|
+
for (let i = 0; i < a.typeArgs.length; i++) {
|
|
259
|
+
if (!equals(a.typeArgs[i], b.typeArgs[i])) {
|
|
260
|
+
return false;
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
return equals(a.child, b.child);
|
|
264
|
+
case 'indexed':
|
|
265
|
+
if (ParallelIndices.equals(a.parallelIndices, b.parallelIndices)) {
|
|
266
|
+
return false;
|
|
267
|
+
}
|
|
268
|
+
return equals(a.child, b.child);
|
|
269
|
+
case 'dispatcher':
|
|
270
|
+
if (a.registry !== b.registry) {
|
|
271
|
+
return false;
|
|
272
|
+
}
|
|
273
|
+
return ParallelIndices.equals(a.parallelIndices, b.parallelIndices);
|
|
274
|
+
case 'mapped':
|
|
275
|
+
if (Object.keys(a.mapping).length !== Object.keys(b.mapping).length) {
|
|
276
|
+
return false;
|
|
277
|
+
}
|
|
278
|
+
for (const kvp of Object.entries(a.mapping)) {
|
|
279
|
+
const other = b.mapping[kvp[0]];
|
|
280
|
+
if (!other) {
|
|
281
|
+
return false;
|
|
282
|
+
}
|
|
283
|
+
if (!equals(kvp[1], other)) {
|
|
284
|
+
return false;
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
return equals(a.child, b.child);
|
|
288
|
+
default:
|
|
289
|
+
return true;
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
McdocType.equals = equals;
|
|
40
293
|
function toString(type) {
|
|
41
294
|
const rangeToString = (range) => {
|
|
42
|
-
|
|
43
|
-
return '';
|
|
44
|
-
}
|
|
45
|
-
const { kind, min, max } = range;
|
|
46
|
-
return min === max
|
|
47
|
-
? ` @ ${min}`
|
|
48
|
-
: ` @ ${min ?? ''}${getRangeDelimiter(kind)}${max ?? ''}`;
|
|
295
|
+
return range ? ` @ ${NumericRange.toString(range)}` : '';
|
|
49
296
|
};
|
|
50
297
|
const indicesToString = (indices) => {
|
|
51
298
|
const strings = [];
|
|
@@ -56,9 +303,7 @@ export var McdocType;
|
|
|
56
303
|
else {
|
|
57
304
|
strings.push(index.kind === 'static'
|
|
58
305
|
? `[${index.value}]`
|
|
59
|
-
: `[[${index.accessor
|
|
60
|
-
.map((v) => (typeof v === 'string' ? v : v.keyword))
|
|
61
|
-
.join('.')}]]`);
|
|
306
|
+
: `[[${index.accessor.map((v) => (typeof v === 'string' ? v : v.keyword)).join('.')}]]`);
|
|
62
307
|
}
|
|
63
308
|
}
|
|
64
309
|
return `[${strings.join(', ')}]`;
|
|
@@ -66,405 +311,94 @@ export var McdocType;
|
|
|
66
311
|
if (type === undefined) {
|
|
67
312
|
return '<unknown>';
|
|
68
313
|
}
|
|
314
|
+
let attributesString = '';
|
|
315
|
+
if (type.attributes?.length) {
|
|
316
|
+
for (const attribute of type.attributes) {
|
|
317
|
+
attributesString += `#[${attribute.name}${attribute.value ? '=<value ...>' : ''}] `;
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
let typeString;
|
|
69
321
|
switch (type.kind) {
|
|
70
322
|
case 'any':
|
|
71
323
|
case 'boolean':
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
return `#[${type.attribute.name}${type.attribute.value ? '=<value ...>' : ''}] ${toString(type.child)}`;
|
|
324
|
+
typeString = type.kind;
|
|
325
|
+
break;
|
|
75
326
|
case 'byte':
|
|
76
|
-
|
|
327
|
+
typeString = `byte${rangeToString(type.valueRange)}`;
|
|
328
|
+
break;
|
|
77
329
|
case 'byte_array':
|
|
78
|
-
|
|
330
|
+
typeString = `byte${rangeToString(type.valueRange)}[]${rangeToString(type.lengthRange)}`;
|
|
331
|
+
break;
|
|
79
332
|
case 'concrete':
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
: ''}`;
|
|
333
|
+
typeString = `${toString(type.child)}${type.typeArgs.length ? `<${type.typeArgs.map(toString).join(', ')}>` : ''}`;
|
|
334
|
+
break;
|
|
83
335
|
case 'dispatcher':
|
|
84
|
-
|
|
336
|
+
typeString = `${type.registry ?? 'spyglass:unknown'}[${indicesToString(type.parallelIndices)}]`;
|
|
337
|
+
break;
|
|
85
338
|
case 'double':
|
|
86
|
-
|
|
339
|
+
typeString = `double${rangeToString(type.valueRange)}`;
|
|
340
|
+
break;
|
|
87
341
|
case 'enum':
|
|
88
|
-
|
|
342
|
+
typeString = '<enum ...>';
|
|
343
|
+
break;
|
|
89
344
|
case 'float':
|
|
90
|
-
|
|
345
|
+
typeString = `float${rangeToString(type.valueRange)}`;
|
|
346
|
+
break;
|
|
91
347
|
case 'indexed':
|
|
92
|
-
|
|
348
|
+
typeString = `${toString(type.child)}${indicesToString(type.parallelIndices)}`;
|
|
349
|
+
break;
|
|
93
350
|
case 'int':
|
|
94
|
-
|
|
351
|
+
typeString = `int${rangeToString(type.valueRange)}`;
|
|
352
|
+
break;
|
|
95
353
|
case 'int_array':
|
|
96
|
-
|
|
354
|
+
typeString = `int${rangeToString(type.valueRange)}[]${rangeToString(type.lengthRange)}`;
|
|
355
|
+
break;
|
|
97
356
|
case 'list':
|
|
98
|
-
|
|
357
|
+
typeString = `[${toString(type.item)}]${rangeToString(type.lengthRange)}`;
|
|
358
|
+
break;
|
|
99
359
|
case 'literal':
|
|
100
|
-
|
|
360
|
+
typeString = `${type.value.value}`;
|
|
361
|
+
break;
|
|
101
362
|
case 'long':
|
|
102
|
-
|
|
363
|
+
typeString = `long${rangeToString(type.valueRange)}`;
|
|
364
|
+
break;
|
|
103
365
|
case 'long_array':
|
|
104
|
-
|
|
366
|
+
typeString = `long${rangeToString(type.valueRange)}[]${rangeToString(type.lengthRange)}`;
|
|
367
|
+
break;
|
|
368
|
+
case 'mapped':
|
|
369
|
+
typeString = toString(type.child);
|
|
370
|
+
break;
|
|
105
371
|
case 'reference':
|
|
106
|
-
|
|
372
|
+
typeString = type.path ?? '<unknown_reference>';
|
|
373
|
+
break;
|
|
107
374
|
case 'short':
|
|
108
|
-
|
|
375
|
+
typeString = `short${rangeToString(type.valueRange)}`;
|
|
376
|
+
break;
|
|
109
377
|
case 'string':
|
|
110
|
-
|
|
378
|
+
typeString = `string${rangeToString(type.lengthRange)}`;
|
|
379
|
+
break;
|
|
111
380
|
case 'struct':
|
|
112
|
-
|
|
381
|
+
typeString = '<struct ...>';
|
|
382
|
+
break;
|
|
113
383
|
case 'template':
|
|
114
|
-
|
|
384
|
+
typeString = `${toString(type.child)}${type.typeParams.length
|
|
115
385
|
? `<${type.typeParams.map((v) => `?${v.path}`).join(', ')}>`
|
|
116
386
|
: ''}`;
|
|
387
|
+
break;
|
|
117
388
|
case 'tuple':
|
|
118
|
-
|
|
389
|
+
typeString = `[${type.items.map((v) => toString(v)).join(',')}${type.items.length === 1 ? ',' : ''}]`;
|
|
390
|
+
break;
|
|
119
391
|
case 'union':
|
|
120
|
-
|
|
392
|
+
typeString = `(${type.members.map(toString).join(' | ')})`;
|
|
393
|
+
break;
|
|
121
394
|
case 'unsafe':
|
|
122
|
-
|
|
395
|
+
typeString = 'unsafe';
|
|
396
|
+
break;
|
|
123
397
|
default:
|
|
124
|
-
|
|
398
|
+
Dev.assertNever(type);
|
|
125
399
|
}
|
|
400
|
+
return attributesString + typeString;
|
|
126
401
|
}
|
|
127
402
|
McdocType.toString = toString;
|
|
128
403
|
})(McdocType || (McdocType = {}));
|
|
129
|
-
var CheckResult;
|
|
130
|
-
(function (CheckResult) {
|
|
131
|
-
CheckResult[CheckResult["Nah"] = 0] = "Nah";
|
|
132
|
-
CheckResult[CheckResult["Assignable"] = 1] = "Assignable";
|
|
133
|
-
CheckResult[CheckResult["StrictlyAssignable"] = 3] = "StrictlyAssignable";
|
|
134
|
-
})(CheckResult || (CheckResult = {}));
|
|
135
|
-
const areRangesMatch = (s, t) => {
|
|
136
|
-
if (!t) {
|
|
137
|
-
return true;
|
|
138
|
-
}
|
|
139
|
-
if (!s) {
|
|
140
|
-
return false;
|
|
141
|
-
}
|
|
142
|
-
const { min: sMin, max: sMax } = s;
|
|
143
|
-
const { min: tMin, max: tMax } = t;
|
|
144
|
-
return ((tMin === undefined || (sMin !== undefined && sMin >= tMin)) &&
|
|
145
|
-
(tMax === undefined || (sMax !== undefined && sMax <= tMax)));
|
|
146
|
-
};
|
|
147
|
-
export const flattenUnionType = (union) => {
|
|
148
|
-
const set = new Set();
|
|
149
|
-
const add = (data) => {
|
|
150
|
-
for (const existingMember of set) {
|
|
151
|
-
if ((check(data, existingMember) & CheckResult.StrictlyAssignable) ===
|
|
152
|
-
CheckResult.StrictlyAssignable) {
|
|
153
|
-
return;
|
|
154
|
-
}
|
|
155
|
-
if ((check(existingMember, data) & CheckResult.StrictlyAssignable) ===
|
|
156
|
-
CheckResult.StrictlyAssignable) {
|
|
157
|
-
set.delete(existingMember);
|
|
158
|
-
}
|
|
159
|
-
}
|
|
160
|
-
set.add(data);
|
|
161
|
-
};
|
|
162
|
-
for (const member of union.members) {
|
|
163
|
-
if (member.kind === 'union') {
|
|
164
|
-
flattenUnionType(member).members.forEach(add);
|
|
165
|
-
}
|
|
166
|
-
else {
|
|
167
|
-
add(member);
|
|
168
|
-
}
|
|
169
|
-
}
|
|
170
|
-
return {
|
|
171
|
-
kind: 'union',
|
|
172
|
-
members: [...set],
|
|
173
|
-
};
|
|
174
|
-
};
|
|
175
|
-
export const unionTypes = (a, b) => {
|
|
176
|
-
if ((check(a, b) & CheckResult.StrictlyAssignable) ===
|
|
177
|
-
CheckResult.StrictlyAssignable) {
|
|
178
|
-
return b;
|
|
179
|
-
}
|
|
180
|
-
if ((check(b, a) & CheckResult.StrictlyAssignable) ===
|
|
181
|
-
CheckResult.StrictlyAssignable) {
|
|
182
|
-
return a;
|
|
183
|
-
}
|
|
184
|
-
const ans = {
|
|
185
|
-
kind: 'union',
|
|
186
|
-
members: [
|
|
187
|
-
...(a.kind === 'union' ? a.members : [a]),
|
|
188
|
-
...(b.kind === 'union' ? b.members : [b]),
|
|
189
|
-
],
|
|
190
|
-
};
|
|
191
|
-
return ans;
|
|
192
|
-
};
|
|
193
|
-
export const simplifyUnionType = (union) => {
|
|
194
|
-
union = flattenUnionType(union);
|
|
195
|
-
if (union.members.length === 1) {
|
|
196
|
-
return union.members[0];
|
|
197
|
-
}
|
|
198
|
-
return union;
|
|
199
|
-
};
|
|
200
|
-
export const simplifyListType = (list) => ({
|
|
201
|
-
kind: 'list',
|
|
202
|
-
item: simplifyType(list.item),
|
|
203
|
-
...(list.lengthRange ? { lengthRange: { ...list.lengthRange } } : {}),
|
|
204
|
-
});
|
|
205
|
-
export const simplifyType = (data) => {
|
|
206
|
-
if (data.kind === 'union') {
|
|
207
|
-
data = simplifyUnionType(data);
|
|
208
|
-
}
|
|
209
|
-
else if (data.kind === 'list') {
|
|
210
|
-
data = simplifyListType(data);
|
|
211
|
-
}
|
|
212
|
-
return data;
|
|
213
|
-
};
|
|
214
|
-
const check = (s, t, errors = []) => {
|
|
215
|
-
const strictlyAssignableIfTrue = (value) => value ? CheckResult.StrictlyAssignable : CheckResult.Nah;
|
|
216
|
-
const assignableIfTrue = (value) => value ? CheckResult.Assignable : CheckResult.Nah;
|
|
217
|
-
let ans;
|
|
218
|
-
s = simplifyType(s);
|
|
219
|
-
t = simplifyType(t);
|
|
220
|
-
if (s.kind === 'any' || s.kind === 'reference' || t.kind === 'reference') {
|
|
221
|
-
// Reference types are treated as any for now.
|
|
222
|
-
ans = CheckResult.Assignable;
|
|
223
|
-
}
|
|
224
|
-
else if (t.kind === 'any') {
|
|
225
|
-
ans = CheckResult.StrictlyAssignable;
|
|
226
|
-
}
|
|
227
|
-
else if (s.kind === 'union') {
|
|
228
|
-
ans = assignableIfTrue(s.members.every((v) => check(v, t, errors)));
|
|
229
|
-
}
|
|
230
|
-
else if (t.kind === 'union') {
|
|
231
|
-
ans = assignableIfTrue(t.members.some((v) => check(s, v)));
|
|
232
|
-
}
|
|
233
|
-
else if (s.kind === 'boolean') {
|
|
234
|
-
ans = strictlyAssignableIfTrue(t.kind === 'boolean' || t.kind === 'byte');
|
|
235
|
-
}
|
|
236
|
-
else if (s.kind === 'byte') {
|
|
237
|
-
if (t.kind === 'boolean') {
|
|
238
|
-
ans = check(s, { kind: 'byte', valueRange: { kind: 0b00, min: 0, max: 1 } }, errors);
|
|
239
|
-
}
|
|
240
|
-
else if (t.kind === 'byte') {
|
|
241
|
-
ans = strictlyAssignableIfTrue(areRangesMatch(s.valueRange, t.valueRange));
|
|
242
|
-
}
|
|
243
|
-
else if (t.kind === 'enum') {
|
|
244
|
-
ans = assignableIfTrue(!t.enumKind || t.enumKind === 'byte');
|
|
245
|
-
}
|
|
246
|
-
else {
|
|
247
|
-
ans = CheckResult.Nah;
|
|
248
|
-
}
|
|
249
|
-
}
|
|
250
|
-
else if (s.kind === 'byte_array' ||
|
|
251
|
-
s.kind === 'int_array' ||
|
|
252
|
-
s.kind === 'long_array') {
|
|
253
|
-
ans = strictlyAssignableIfTrue(t.kind === s.kind &&
|
|
254
|
-
areRangesMatch(s.lengthRange, t.lengthRange) &&
|
|
255
|
-
areRangesMatch(s.valueRange, t.valueRange));
|
|
256
|
-
}
|
|
257
|
-
else if (s.kind === 'struct' || s.kind === 'dispatcher') {
|
|
258
|
-
ans = assignableIfTrue(t.kind === 'struct' || t.kind === 'dispatcher');
|
|
259
|
-
}
|
|
260
|
-
else if (s.kind === 'enum') {
|
|
261
|
-
ans = assignableIfTrue((t.kind === 'byte' ||
|
|
262
|
-
t.kind === 'float' ||
|
|
263
|
-
t.kind === 'double' ||
|
|
264
|
-
t.kind === 'int' ||
|
|
265
|
-
t.kind === 'long' ||
|
|
266
|
-
t.kind === 'short' ||
|
|
267
|
-
t.kind === 'string') &&
|
|
268
|
-
(!s.enumKind || s.enumKind === t.kind));
|
|
269
|
-
}
|
|
270
|
-
else if (s.kind === 'float' ||
|
|
271
|
-
s.kind === 'double' ||
|
|
272
|
-
s.kind === 'int' ||
|
|
273
|
-
s.kind === 'long' ||
|
|
274
|
-
s.kind === 'short') {
|
|
275
|
-
if (t.kind === s.kind) {
|
|
276
|
-
ans = strictlyAssignableIfTrue(areRangesMatch(s.valueRange, t.valueRange));
|
|
277
|
-
}
|
|
278
|
-
else if (t.kind === 'enum') {
|
|
279
|
-
ans = assignableIfTrue(!t.enumKind || t.enumKind === s.kind);
|
|
280
|
-
}
|
|
281
|
-
else {
|
|
282
|
-
ans = CheckResult.Nah;
|
|
283
|
-
}
|
|
284
|
-
}
|
|
285
|
-
else if (s.kind === 'list') {
|
|
286
|
-
if (t.kind === 'list' && areRangesMatch(s.lengthRange, t.lengthRange)) {
|
|
287
|
-
ans = check(s.item, t.item, errors);
|
|
288
|
-
}
|
|
289
|
-
else {
|
|
290
|
-
ans = CheckResult.Nah;
|
|
291
|
-
}
|
|
292
|
-
}
|
|
293
|
-
else if (s.kind === 'string') {
|
|
294
|
-
if (t.kind === 'string') {
|
|
295
|
-
ans = CheckResult.StrictlyAssignable;
|
|
296
|
-
}
|
|
297
|
-
else {
|
|
298
|
-
ans = assignableIfTrue(t.kind === 'enum' && (!t.enumKind || t.enumKind === 'string'));
|
|
299
|
-
}
|
|
300
|
-
}
|
|
301
|
-
else {
|
|
302
|
-
ans = CheckResult.Nah;
|
|
303
|
-
}
|
|
304
|
-
if (!ans) {
|
|
305
|
-
errors.push(localize('mcdoc.checker.type-not-assignable', localeQuote(McdocType.toString(s)), localeQuote(McdocType.toString(t))));
|
|
306
|
-
}
|
|
307
|
-
return ans;
|
|
308
|
-
};
|
|
309
|
-
export const checkAssignability = ({ source, target, }) => {
|
|
310
|
-
if (source === undefined || target === undefined) {
|
|
311
|
-
return { isAssignable: true };
|
|
312
|
-
}
|
|
313
|
-
const errors = [];
|
|
314
|
-
check(source, target, errors);
|
|
315
|
-
return {
|
|
316
|
-
isAssignable: errors.length === 0,
|
|
317
|
-
...(errors.length
|
|
318
|
-
? {
|
|
319
|
-
errorMessage: errors
|
|
320
|
-
.reverse()
|
|
321
|
-
.map((m, i) => `${' '.repeat(i)}${m}`)
|
|
322
|
-
.join('\n'),
|
|
323
|
-
}
|
|
324
|
-
: {}),
|
|
325
|
-
};
|
|
326
|
-
};
|
|
327
|
-
export function resolveType(inputType, ctx, value) {
|
|
328
|
-
const type = getTangibleType(inputType, ctx, value);
|
|
329
|
-
const ans = (() => {
|
|
330
|
-
if (type.kind === 'union') {
|
|
331
|
-
return {
|
|
332
|
-
kind: 'union',
|
|
333
|
-
members: type.members.map((t) => resolveType(t, ctx, value)),
|
|
334
|
-
// attributes: type.attributes,
|
|
335
|
-
};
|
|
336
|
-
}
|
|
337
|
-
else {
|
|
338
|
-
return {
|
|
339
|
-
...type,
|
|
340
|
-
indices: undefined,
|
|
341
|
-
};
|
|
342
|
-
}
|
|
343
|
-
})();
|
|
344
|
-
// for (const parallelIndices of type.indices ?? []) {
|
|
345
|
-
// ans = navigateParallelIndices(ans, parallelIndices, ctx, value)
|
|
346
|
-
// }
|
|
347
|
-
return ans;
|
|
348
|
-
}
|
|
349
|
-
function dispatchType(type, ctx) {
|
|
350
|
-
throw '// TODO';
|
|
351
|
-
}
|
|
352
|
-
function dereferenceType(type, ctx) {
|
|
353
|
-
throw '// TODO';
|
|
354
|
-
}
|
|
355
|
-
function getTangibleType(type, ctx, value) {
|
|
356
|
-
let ans;
|
|
357
|
-
if (type.kind === 'dispatcher') {
|
|
358
|
-
const dispatchedType = dispatchType(type, ctx);
|
|
359
|
-
return getTangibleType(dispatchedType, ctx, value);
|
|
360
|
-
}
|
|
361
|
-
else if (type.kind === 'reference') {
|
|
362
|
-
const dereferencedType = dereferenceType(type, ctx);
|
|
363
|
-
return getTangibleType(dereferencedType, ctx, value);
|
|
364
|
-
}
|
|
365
|
-
else if (type.kind === 'union') {
|
|
366
|
-
ans = mapUnion(type, (t) => getTangibleType(t, ctx, value));
|
|
367
|
-
}
|
|
368
|
-
else {
|
|
369
|
-
ans = type;
|
|
370
|
-
}
|
|
371
|
-
return ans;
|
|
372
|
-
}
|
|
373
|
-
function navigateParallelIndices(type, indices, ctx, value) {
|
|
374
|
-
if (indices.length === 1) {
|
|
375
|
-
return navigateIndex(type, indices[0], ctx, value);
|
|
376
|
-
}
|
|
377
|
-
else {
|
|
378
|
-
return {
|
|
379
|
-
kind: 'union',
|
|
380
|
-
members: indices.map((i) => navigateIndex(type, i, ctx, value)),
|
|
381
|
-
// attributes: type.attributes,
|
|
382
|
-
};
|
|
383
|
-
}
|
|
384
|
-
}
|
|
385
|
-
function navigateIndex(type, index, ctx, value) {
|
|
386
|
-
if (type.kind === 'struct') {
|
|
387
|
-
const key = index.kind === 'static'
|
|
388
|
-
? typeof index.value === 'string'
|
|
389
|
-
? index.value
|
|
390
|
-
: undefined // Special static indices have no meaning on structs.
|
|
391
|
-
: resolveDynamicIndex(index, value);
|
|
392
|
-
if (key === undefined) {
|
|
393
|
-
// return createEmptyUnion(type.attributes)
|
|
394
|
-
return createEmptyUnion();
|
|
395
|
-
}
|
|
396
|
-
const flatStruct = flattenStruct(type, ctx, value);
|
|
397
|
-
return resolveType(flatStruct.fields[key], ctx, value);
|
|
398
|
-
}
|
|
399
|
-
else if (type.kind === 'union') {
|
|
400
|
-
return mapUnion(type, (t) => navigateIndex(t, index, ctx, value));
|
|
401
|
-
}
|
|
402
|
-
else {
|
|
403
|
-
// return createEmptyUnion(type.attributes)
|
|
404
|
-
return createEmptyUnion();
|
|
405
|
-
}
|
|
406
|
-
}
|
|
407
|
-
function resolveDynamicIndex(index, value) {
|
|
408
|
-
for (const key of index.accessor) {
|
|
409
|
-
if (value === undefined) {
|
|
410
|
-
break;
|
|
411
|
-
}
|
|
412
|
-
if (typeof key === 'string') {
|
|
413
|
-
value = value.getValue(key);
|
|
414
|
-
}
|
|
415
|
-
else if (key.keyword === 'key') {
|
|
416
|
-
value = value.getKeyOnParent();
|
|
417
|
-
}
|
|
418
|
-
else if (key.keyword === 'parent') {
|
|
419
|
-
value = value.getParent();
|
|
420
|
-
}
|
|
421
|
-
}
|
|
422
|
-
return value?.asString();
|
|
423
|
-
}
|
|
424
|
-
function mapUnion(type, mapper) {
|
|
425
|
-
const ans = {
|
|
426
|
-
kind: 'union',
|
|
427
|
-
members: type.members.map(mapper),
|
|
428
|
-
// attributes: type.attributes,
|
|
429
|
-
// indices: type.indices,
|
|
430
|
-
};
|
|
431
|
-
return ans;
|
|
432
|
-
}
|
|
433
|
-
function flattenStruct(type, ctx, value) {
|
|
434
|
-
const ans = {
|
|
435
|
-
kind: 'flat_struct',
|
|
436
|
-
fields: Object.create(null),
|
|
437
|
-
// attributes: type.attributes,
|
|
438
|
-
// indices: type.indices,
|
|
439
|
-
};
|
|
440
|
-
for (const field of type.fields) {
|
|
441
|
-
if (field.kind === 'spread') {
|
|
442
|
-
const target = resolveType(field.type, ctx, value);
|
|
443
|
-
// addAttributes(ans, ...target.attributes ?? [])
|
|
444
|
-
if (target.kind === 'struct') {
|
|
445
|
-
const flatTarget = flattenStruct(target, ctx, value);
|
|
446
|
-
for (const [key, value] of Object.entries(flatTarget)) {
|
|
447
|
-
ans.fields[key] = value;
|
|
448
|
-
}
|
|
449
|
-
}
|
|
450
|
-
}
|
|
451
|
-
else {
|
|
452
|
-
if (typeof field.key === 'string') {
|
|
453
|
-
ans.fields[field.key] = field.type;
|
|
454
|
-
}
|
|
455
|
-
else {
|
|
456
|
-
// TODO: Handle map keys
|
|
457
|
-
}
|
|
458
|
-
}
|
|
459
|
-
}
|
|
460
|
-
return ans;
|
|
461
|
-
}
|
|
462
|
-
function addAttributes(type, ...attributes) {
|
|
463
|
-
for (const attr of attributes) {
|
|
464
|
-
// type.attributes ??= []
|
|
465
|
-
// if (!type.attributes.some(a => a.name === attr.name)) {
|
|
466
|
-
// type.attributes.push(attr)
|
|
467
|
-
// }
|
|
468
|
-
}
|
|
469
|
-
}
|
|
470
404
|
//# sourceMappingURL=index.js.map
|