typia 4.1.7 → 4.1.8-dev.20230726

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.
Files changed (161) hide show
  1. package/lib/metadata/Metadata.js +4 -2
  2. package/lib/metadata/Metadata.js.map +1 -1
  3. package/package.json +2 -2
  4. package/src/factories/MetadataCollection.ts +255 -255
  5. package/src/factories/MetadataFactory.ts +30 -30
  6. package/src/factories/MetadataTagFactory.ts +355 -355
  7. package/src/factories/internal/metadata/MetadataHelper.ts +12 -12
  8. package/src/factories/internal/metadata/emend_metadata_atomics.ts +33 -33
  9. package/src/factories/internal/metadata/emplace_metadata_alias.ts +40 -40
  10. package/src/factories/internal/metadata/emplace_metadata_array.ts +34 -34
  11. package/src/factories/internal/metadata/emplace_metadata_object.ts +136 -136
  12. package/src/factories/internal/metadata/emplace_metadata_tuple.ts +50 -50
  13. package/src/factories/internal/metadata/explore_metadata.ts +40 -40
  14. package/src/factories/internal/metadata/iterate_metadata.ts +81 -81
  15. package/src/factories/internal/metadata/iterate_metadata_alias.ts +30 -30
  16. package/src/factories/internal/metadata/iterate_metadata_array.ts +24 -24
  17. package/src/factories/internal/metadata/iterate_metadata_atomic.ts +59 -59
  18. package/src/factories/internal/metadata/iterate_metadata_coalesce.ts +33 -33
  19. package/src/factories/internal/metadata/iterate_metadata_collection.ts +133 -133
  20. package/src/factories/internal/metadata/iterate_metadata_constant.ts +58 -58
  21. package/src/factories/internal/metadata/iterate_metadata_intersection.ts +83 -83
  22. package/src/factories/internal/metadata/iterate_metadata_map.ts +41 -41
  23. package/src/factories/internal/metadata/iterate_metadata_native.ts +219 -219
  24. package/src/factories/internal/metadata/iterate_metadata_object.ts +43 -43
  25. package/src/factories/internal/metadata/iterate_metadata_resolve.ts +49 -49
  26. package/src/factories/internal/metadata/iterate_metadata_set.ts +33 -33
  27. package/src/factories/internal/metadata/iterate_metadata_sort.ts +69 -69
  28. package/src/factories/internal/metadata/iterate_metadata_tag.ts +31 -31
  29. package/src/factories/internal/metadata/iterate_metadata_template.ts +38 -38
  30. package/src/factories/internal/metadata/iterate_metadata_tuple.ts +24 -24
  31. package/src/factories/internal/metadata/iterate_metadata_union.ts +24 -24
  32. package/src/functional/$number.ts +12 -12
  33. package/src/metadata/ICommentTag.ts +4 -4
  34. package/src/metadata/IJsDocTagInfo.ts +10 -10
  35. package/src/metadata/IMetadata.ts +28 -28
  36. package/src/metadata/IMetadataAlias.ts +14 -14
  37. package/src/metadata/IMetadataApplication.ts +7 -7
  38. package/src/metadata/IMetadataArray.ts +10 -10
  39. package/src/metadata/IMetadataCollection.ts +11 -11
  40. package/src/metadata/IMetadataConstant.ts +16 -16
  41. package/src/metadata/IMetadataDictionary.ts +14 -14
  42. package/src/metadata/IMetadataEntry.ts +6 -6
  43. package/src/metadata/IMetadataObject.ts +18 -18
  44. package/src/metadata/IMetadataProperty.ts +11 -11
  45. package/src/metadata/IMetadataResolved.ts +6 -6
  46. package/src/metadata/IMetadataTag.ts +105 -105
  47. package/src/metadata/IMetadataTuple.ts +10 -10
  48. package/src/metadata/Metadata.ts +605 -603
  49. package/src/metadata/MetadataAlias.ts +66 -66
  50. package/src/metadata/MetadataArray.ts +55 -55
  51. package/src/metadata/MetadataConstant.ts +3 -3
  52. package/src/metadata/MetadataObject.ts +129 -129
  53. package/src/metadata/MetadataProperty.ts +64 -64
  54. package/src/metadata/MetadataResolved.ts +51 -51
  55. package/src/metadata/MetadataTuple.ts +53 -53
  56. package/src/module.ts +2038 -2038
  57. package/src/programmers/ApplicationProgrammer.ts +47 -47
  58. package/src/programmers/AssertCloneProgrammer.ts +71 -71
  59. package/src/programmers/AssertParseProgrammer.ts +66 -66
  60. package/src/programmers/AssertPruneProgrammer.ts +68 -68
  61. package/src/programmers/AssertStringifyProgrammer.ts +66 -66
  62. package/src/programmers/CheckerProgrammer.ts +1182 -1182
  63. package/src/programmers/CloneProgrammer.ts +587 -587
  64. package/src/programmers/FeatureProgrammer.ts +495 -495
  65. package/src/programmers/IsCloneProgrammer.ts +78 -78
  66. package/src/programmers/IsParseProgrammer.ts +72 -72
  67. package/src/programmers/IsProgrammer.ts +239 -239
  68. package/src/programmers/IsPruneProgrammer.ts +73 -73
  69. package/src/programmers/IsStringifyProgrammer.ts +76 -76
  70. package/src/programmers/LiteralsProgrammer.ts +63 -63
  71. package/src/programmers/PruneProgrammer.ts +542 -542
  72. package/src/programmers/RandomProgrammer.ts +581 -581
  73. package/src/programmers/StringifyProgrammer.ts +978 -978
  74. package/src/programmers/ValidateCloneProgrammer.ts +85 -85
  75. package/src/programmers/ValidateParseProgrammer.ts +70 -70
  76. package/src/programmers/ValidatePruneProgrammer.ts +78 -78
  77. package/src/programmers/ValidateStringifyProgrammer.ts +84 -84
  78. package/src/programmers/helpers/AtomicPredicator.ts +31 -31
  79. package/src/programmers/helpers/IExpressionEntry.ts +12 -12
  80. package/src/programmers/helpers/PruneJoiner.ts +143 -143
  81. package/src/programmers/helpers/RandomJoiner.ts +173 -173
  82. package/src/programmers/helpers/RandomRanger.ts +216 -216
  83. package/src/programmers/helpers/StringifyPredicator.ts +13 -13
  84. package/src/programmers/helpers/UnionExplorer.ts +301 -301
  85. package/src/programmers/helpers/UnionPredicator.ts +81 -81
  86. package/src/programmers/internal/application_alias.ts +66 -66
  87. package/src/programmers/internal/application_array.ts +30 -30
  88. package/src/programmers/internal/application_constant.ts +26 -26
  89. package/src/programmers/internal/application_default.ts +17 -17
  90. package/src/programmers/internal/application_default_string.ts +33 -33
  91. package/src/programmers/internal/application_native.ts +39 -39
  92. package/src/programmers/internal/application_number.ts +74 -74
  93. package/src/programmers/internal/application_object.ts +162 -162
  94. package/src/programmers/internal/application_resolved.ts +55 -55
  95. package/src/programmers/internal/application_schema.ts +157 -157
  96. package/src/programmers/internal/application_string.ts +44 -44
  97. package/src/programmers/internal/application_templates.ts +25 -25
  98. package/src/programmers/internal/application_tuple.ts +57 -57
  99. package/src/programmers/internal/check_array.ts +30 -30
  100. package/src/programmers/internal/check_array_length.ts +35 -35
  101. package/src/programmers/internal/check_bigint.ts +82 -82
  102. package/src/programmers/internal/check_custom.ts +31 -31
  103. package/src/programmers/internal/check_number.ts +177 -177
  104. package/src/programmers/internal/check_string.ts +25 -25
  105. package/src/programmers/internal/check_string_tags.ts +67 -67
  106. package/src/programmers/internal/check_template.ts +56 -56
  107. package/src/programmers/internal/check_union_array_like.ts +329 -329
  108. package/src/programmers/internal/decode_union_object.ts +73 -73
  109. package/src/programmers/internal/feature_object_entries.ts +63 -63
  110. package/src/programmers/internal/get_comment_tags.ts +23 -23
  111. package/src/programmers/internal/metadata_to_pattern.ts +34 -34
  112. package/src/programmers/internal/prune_object_properties.ts +60 -60
  113. package/src/programmers/internal/random_custom.ts +29 -29
  114. package/src/programmers/internal/stringify_regular_properties.ts +83 -83
  115. package/src/programmers/internal/template_to_pattern.ts +15 -15
  116. package/src/programmers/internal/wrap_metadata_rest_tuple.ts +16 -16
  117. package/src/schemas/IJsonApplication.ts +8 -8
  118. package/src/schemas/IJsonComponents.ts +33 -33
  119. package/src/schemas/IJsonSchema.ts +133 -133
  120. package/src/transformers/CallExpressionTransformer.ts +179 -179
  121. package/src/transformers/features/miscellaneous/ApplicationTransformer.ts +104 -104
  122. package/src/transformers/features/miscellaneous/AssertCloneTransformer.ts +9 -9
  123. package/src/transformers/features/miscellaneous/AssertPruneTransformer.ts +9 -9
  124. package/src/transformers/features/miscellaneous/CloneTransformer.ts +9 -9
  125. package/src/transformers/features/miscellaneous/CreateAssertCloneTransformer.ts +9 -9
  126. package/src/transformers/features/miscellaneous/CreateAssertPruneTransformer.ts +9 -9
  127. package/src/transformers/features/miscellaneous/CreateCloneTransformer.ts +9 -9
  128. package/src/transformers/features/miscellaneous/CreateIsCloneTransformer.ts +9 -9
  129. package/src/transformers/features/miscellaneous/CreateIsPruneTransformer.ts +9 -9
  130. package/src/transformers/features/miscellaneous/CreatePruneTransformer.ts +9 -9
  131. package/src/transformers/features/miscellaneous/CreateRandomTransformer.ts +39 -39
  132. package/src/transformers/features/miscellaneous/CreateValidateCloneTransformer.ts +9 -9
  133. package/src/transformers/features/miscellaneous/CreateValidatePruneTransformer.ts +9 -9
  134. package/src/transformers/features/miscellaneous/IsCloneTransformer.ts +9 -9
  135. package/src/transformers/features/miscellaneous/IsPruneTransformer.ts +9 -9
  136. package/src/transformers/features/miscellaneous/LiteralsTransformer.ts +28 -28
  137. package/src/transformers/features/miscellaneous/MetadataTransformer.ts +53 -53
  138. package/src/transformers/features/miscellaneous/PruneTransformer.ts +9 -9
  139. package/src/transformers/features/miscellaneous/RandomTransformer.ts +42 -42
  140. package/src/transformers/features/miscellaneous/ValidateCloneTransformer.ts +9 -9
  141. package/src/transformers/features/miscellaneous/ValidatePruneTransformer.ts +9 -9
  142. package/src/transformers/features/parsers/AssertParseTransformer.ts +9 -9
  143. package/src/transformers/features/parsers/CreateAssertParseTransformer.ts +9 -9
  144. package/src/transformers/features/parsers/CreateIsParseTransformer.ts +9 -9
  145. package/src/transformers/features/parsers/CreateValidateParseTransformer.ts +9 -9
  146. package/src/transformers/features/parsers/IsParseTransformer.ts +9 -9
  147. package/src/transformers/features/parsers/ValidateParseTransformer.ts +9 -9
  148. package/src/transformers/features/stringifiers/AssertStringifyTransformer.ts +10 -10
  149. package/src/transformers/features/stringifiers/CreateAssertStringifyTransformer.ts +12 -12
  150. package/src/transformers/features/stringifiers/CreateIsStringifyTransformer.ts +9 -9
  151. package/src/transformers/features/stringifiers/CreateStringifyTransformer.ts +9 -9
  152. package/src/transformers/features/stringifiers/CreateValidateStringifyProgrammer.ts +12 -12
  153. package/src/transformers/features/stringifiers/IsStringifyTransformer.ts +9 -9
  154. package/src/transformers/features/stringifiers/StringifyTransformer.ts +9 -9
  155. package/src/transformers/features/stringifiers/ValidateStringifyTransformer.ts +10 -10
  156. package/src/transformers/features/validators/AssertTransformer.ts +11 -11
  157. package/src/transformers/features/validators/CreateAssertTransformer.ts +13 -13
  158. package/src/transformers/features/validators/CreateIsTransformer.ts +11 -11
  159. package/src/transformers/features/validators/CreateValidateTransformer.ts +13 -13
  160. package/src/transformers/features/validators/IsTransformer.ts +11 -11
  161. package/src/transformers/features/validators/ValidateTransformer.ts +11 -11
@@ -1,603 +1,605 @@
1
- import { Atomic } from "../typings/Atomic";
2
- import { ClassProperties } from "../typings/ClassProperties";
3
- import { Writable } from "../typings/Writable";
4
-
5
- import { ArrayUtil } from "../utils/ArrayUtil";
6
-
7
- import { IMetadata } from "./IMetadata";
8
- import { IMetadataCollection } from "./IMetadataCollection";
9
- import { IMetadataDictionary } from "./IMetadataDictionary";
10
- import { MetadataAlias } from "./MetadataAlias";
11
- import { MetadataArray } from "./MetadataArray";
12
- import { MetadataConstant } from "./MetadataConstant";
13
- import { MetadataObject } from "./MetadataObject";
14
- import { MetadataProperty } from "./MetadataProperty";
15
- import { MetadataResolved } from "./MetadataResolved";
16
- import { MetadataTuple } from "./MetadataTuple";
17
-
18
- export class Metadata {
19
- public any: boolean;
20
- public required: boolean;
21
- public optional: boolean;
22
- public nullable: boolean;
23
- public functional: boolean;
24
-
25
- public resolved: MetadataResolved | null;
26
- public atomics: Atomic.Literal[];
27
- public constants: MetadataConstant[];
28
- public templates: Metadata[][];
29
-
30
- public rest: Metadata | null;
31
- public aliases: MetadataAlias[];
32
- public arrays: MetadataArray[];
33
- public tuples: MetadataTuple[];
34
- public objects: MetadataObject[];
35
-
36
- public natives: string[];
37
- public sets: Metadata[];
38
- public maps: Metadata.Entry[];
39
-
40
- /** @internal */ private name_?: string;
41
- /** @internal */ private parent_resolved_: boolean = false;
42
- /** @internal */ public union_index?: number;
43
-
44
- /* -----------------------------------------------------------
45
- CONSTRUCTORS
46
- ----------------------------------------------------------- */
47
- /**
48
- * @hidden
49
- */
50
- private constructor(props: ClassProperties<Metadata>) {
51
- this.any = props.any;
52
- this.required = props.required;
53
- this.optional = props.optional;
54
- this.nullable = props.nullable;
55
- this.functional = props.functional;
56
-
57
- this.resolved = props.resolved;
58
- this.atomics = props.atomics;
59
- this.constants = props.constants;
60
- this.templates = props.templates;
61
-
62
- this.rest = props.rest;
63
- this.arrays = props.arrays;
64
- this.tuples = props.tuples;
65
- this.objects = props.objects;
66
- this.aliases = props.aliases;
67
-
68
- this.natives = props.natives;
69
- this.sets = props.sets;
70
- this.maps = props.maps;
71
- }
72
-
73
- /**
74
- * @internal
75
- */
76
- public static create(props: ClassProperties<Metadata>): Metadata {
77
- return new Metadata(props);
78
- }
79
-
80
- /**
81
- * @internal
82
- */
83
- public static initialize(parentResolved: boolean = false): Metadata {
84
- const meta: Metadata = this.create({
85
- any: false,
86
- nullable: false,
87
- required: true,
88
- optional: false,
89
- functional: false,
90
-
91
- resolved: null,
92
- constants: [],
93
- atomics: [],
94
- templates: [],
95
- arrays: [],
96
- tuples: [],
97
- objects: [],
98
- aliases: [],
99
-
100
- rest: null,
101
- natives: [],
102
- sets: [],
103
- maps: [],
104
- });
105
- meta.parent_resolved_ = parentResolved;
106
- return meta;
107
- }
108
-
109
- public toJSON(): IMetadata {
110
- return {
111
- any: this.any,
112
- required: this.required,
113
- optional: this.optional,
114
- nullable: this.nullable,
115
- functional: this.functional,
116
-
117
- atomics: this.atomics.slice(),
118
- constants: JSON.parse(JSON.stringify(this.constants)),
119
- templates: this.templates.map((tpl) =>
120
- tpl.map((meta) => meta.toJSON()),
121
- ),
122
- resolved: this.resolved ? this.resolved.toJSON() : null,
123
-
124
- rest: this.rest ? this.rest.toJSON() : null,
125
- arrays: this.arrays.map((array) => array.name),
126
- tuples: this.tuples.map((tuple) => tuple.name),
127
- objects: this.objects.map((obj) => obj.name),
128
- aliases: this.aliases.map((alias) => alias.name),
129
-
130
- natives: this.natives.slice(),
131
- sets: this.sets.map((meta) => meta.toJSON()),
132
- maps: this.maps.map((entry) => ({
133
- key: entry.key.toJSON(),
134
- value: entry.value.toJSON(),
135
- })),
136
- };
137
- }
138
-
139
- public static from(
140
- meta: IMetadata,
141
- collection: IMetadataCollection,
142
- ): Metadata {
143
- const dict: IMetadataDictionary = {
144
- objects: new Map(
145
- collection.objects.map((obj) => [
146
- obj.name,
147
- MetadataObject._From_without_properties(obj),
148
- ]),
149
- ),
150
- aliases: new Map(
151
- collection.aliases.map((alias) => [
152
- alias.name,
153
- MetadataAlias._From_without_value(alias),
154
- ]),
155
- ),
156
- arrays: new Map(
157
- collection.arrays.map((arr) => [
158
- arr.name,
159
- MetadataArray._From_without_value(arr),
160
- ]),
161
- ),
162
- tuples: new Map(
163
- collection.tuples.map((tpl) => [
164
- tpl.name,
165
- MetadataTuple._From_without_elements(tpl),
166
- ]),
167
- ),
168
- };
169
-
170
- for (const obj of collection.objects) {
171
- const initialized = dict.objects.get(obj.name)!;
172
- initialized.properties.push(
173
- ...obj.properties.map((prop) =>
174
- MetadataProperty._From(prop, dict),
175
- ),
176
- );
177
- }
178
- for (const alias of collection.aliases)
179
- Writable(dict.aliases.get(alias.name)!).value = this._From(
180
- alias.value,
181
- dict,
182
- );
183
- for (const array of collection.arrays)
184
- Writable(dict.arrays.get(array.name)!).value = this._From(
185
- array.value,
186
- dict,
187
- );
188
- for (const tuple of collection.tuples)
189
- Writable(dict.tuples.get(tuple.name)!).elements =
190
- tuple.elements.map((elem) => this._From(elem, dict));
191
-
192
- return this._From(meta, dict);
193
- }
194
-
195
- /**
196
- * @internal
197
- */
198
- public static _From(meta: IMetadata, dict: IMetadataDictionary): Metadata {
199
- return this.create({
200
- any: meta.any,
201
- required: meta.required,
202
- optional: meta.optional,
203
- nullable: meta.nullable,
204
- functional: meta.functional,
205
-
206
- constants: JSON.parse(JSON.stringify(meta.constants)),
207
- atomics: meta.atomics.slice(),
208
- templates: meta.templates.map((tpl) =>
209
- tpl.map((meta) => this._From(meta, dict)),
210
- ),
211
- resolved: meta.resolved
212
- ? MetadataResolved._From(meta.resolved, dict)
213
- : null,
214
-
215
- rest: meta.rest ? this._From(meta.rest, dict) : null,
216
- arrays: meta.arrays.map((id) => {
217
- const array = dict.arrays.get(id);
218
- if (array === undefined)
219
- throw new Error(
220
- `Error on Metadata.from(): failed to find array "${id}".`,
221
- );
222
- return array;
223
- }),
224
- tuples: meta.tuples.map((id) => {
225
- const tuple = dict.tuples.get(id);
226
- if (tuple === undefined)
227
- throw new Error(
228
- `Error on Metadata.from(): failed to find tuple "${id}".`,
229
- );
230
- return tuple;
231
- }),
232
- objects: meta.objects.map((name) => {
233
- const found = dict.objects.get(name);
234
- if (found === undefined)
235
- throw new Error(
236
- `Error on Metadata.from(): failed to find object "${name}".`,
237
- );
238
- return found;
239
- }),
240
- aliases: meta.aliases.map((alias) => {
241
- const found = dict.aliases.get(alias);
242
- if (found === undefined)
243
- throw new Error(
244
- `Error on Metadata.from(): failed to find alias "${alias}".`,
245
- );
246
- return found;
247
- }),
248
-
249
- natives: meta.natives.slice(),
250
- sets: meta.sets.map((meta) => this._From(meta, dict)),
251
- maps: meta.maps.map((entry) => ({
252
- key: this._From(entry.key, dict),
253
- value: this._From(entry.value, dict),
254
- })),
255
- });
256
- }
257
-
258
- /* -----------------------------------------------------------
259
- ACCESSORS
260
- ----------------------------------------------------------- */
261
- public getName(): string {
262
- this.name_ ??= getName(this);
263
- return this.name_;
264
- }
265
-
266
- public empty(): boolean {
267
- return this.bucket() === 0 || this.size() === 0;
268
- }
269
- public size(): number {
270
- return (
271
- (this.resolved ? 1 : 0) +
272
- (this.functional ? 1 : 0) +
273
- (this.rest ? this.rest.size() : 0) +
274
- this.templates.length +
275
- this.atomics.length +
276
- this.constants
277
- .map((c) => c.values.length)
278
- .reduce((x, y) => x + y, 0) +
279
- this.arrays.length +
280
- this.tuples.length +
281
- this.natives.length +
282
- this.maps.length +
283
- this.sets.length +
284
- this.objects.length +
285
- this.aliases.length
286
- );
287
- }
288
- public bucket(): number {
289
- return (
290
- (this.resolved ? 1 : 0) +
291
- (this.functional ? 1 : 0) +
292
- (this.templates.length ? 1 : 0) +
293
- (this.atomics.length ? 1 : 0) +
294
- (this.constants.length ? 1 : 0) +
295
- (this.rest ? this.rest.size() : 0) +
296
- (this.arrays.length ? 1 : 0) +
297
- (this.tuples.length ? 1 : 0) +
298
- (this.natives.length ? 1 : 0) +
299
- (this.sets.length ? 1 : 0) +
300
- (this.maps.length ? 1 : 0) +
301
- (this.objects.length ? 1 : 0) +
302
- (this.aliases.length ? 1 : 0)
303
- );
304
- }
305
- public isConstant(): boolean {
306
- return this.bucket() === (this.constants.length ? 1 : 0);
307
- }
308
-
309
- public isRequired(): boolean {
310
- return this.required === true && this.optional === false;
311
- }
312
-
313
- /**
314
- * @internal
315
- */
316
- public isUnionBucket(): boolean {
317
- const size: number = this.bucket();
318
- const emended: number = this.constants.length ? size - 1 : size;
319
- return emended > 1;
320
- }
321
-
322
- /**
323
- * @internal
324
- */
325
- public getSoleLiteral(): string | null {
326
- if (
327
- this.size() === 1 &&
328
- this.constants.length === 1 &&
329
- this.constants[0]!.type === "string" &&
330
- this.constants[0]!.values.length === 1
331
- )
332
- return this.constants[0]!.values[0] as string;
333
- else return null;
334
- }
335
-
336
- /**
337
- * @internal
338
- */
339
- public isSoleLiteral(): boolean {
340
- return this.getSoleLiteral() !== null;
341
- }
342
-
343
- /**
344
- * @internal
345
- */
346
- public isParentResolved(): boolean {
347
- return this.parent_resolved_;
348
- }
349
- }
350
- export namespace Metadata {
351
- export const intersects = (x: Metadata, y: Metadata): boolean => {
352
- // CHECK ANY & OPTIONAL
353
- if (x.any || y.any) return true;
354
- if (x.isRequired() === false && false === y.isRequired()) return true;
355
- if (x.nullable === true && true === y.nullable) return true;
356
- if (x.functional === true && y.functional === true) return true;
357
-
358
- //----
359
- // INSTANCES
360
- //----
361
- // ARRAYS
362
- if (x.arrays.length && y.arrays.length) return true;
363
- if (x.tuples.length && y.tuples.length) return true;
364
- if (x.objects.length && y.objects.length) return true;
365
- if (x.aliases.length && y.aliases.length) return true;
366
-
367
- //----
368
- // VALUES
369
- //----
370
- // ATOMICS
371
- for (const atomic of x.atomics)
372
- if (y.atomics.includes(atomic)) return true;
373
-
374
- // CONSTANTS
375
- for (const constant of x.constants) {
376
- const opposite: MetadataConstant | undefined = y.constants.find(
377
- (elem) => elem.type === constant.type,
378
- );
379
- if (opposite === undefined) continue;
380
-
381
- const values: Set<any> = new Set([
382
- ...constant.values,
383
- ...opposite.values,
384
- ]);
385
- if (values.size !== constant.values.length + opposite.values.length)
386
- return true;
387
- }
388
- return false;
389
- };
390
-
391
- export const covers = (
392
- x: Metadata,
393
- y: Metadata,
394
- level: number = 0,
395
- ): boolean => {
396
- // CHECK ANY
397
- if (x === y) return false;
398
- else if (x.any) return true;
399
- else if (y.any) return false;
400
-
401
- //----
402
- // INSTANCES
403
- //----
404
- if (level === 0) {
405
- // ARRAYS
406
- for (const ya of y.arrays)
407
- if (
408
- !x.arrays.some((xa) =>
409
- covers(xa.value, ya.value, level + 1),
410
- )
411
- ) {
412
- return false;
413
- }
414
-
415
- // TUPLES
416
- for (const yt of y.tuples)
417
- if (
418
- yt.elements.length !== 0 &&
419
- x.tuples.some(
420
- (xt) =>
421
- xt.elements.length >= yt.elements.length &&
422
- xt.elements
423
- .slice(yt.elements.length)
424
- .every((xv, i) =>
425
- covers(xv, yt.elements[i]!, level + 1),
426
- ),
427
- ) === false
428
- )
429
- return false;
430
- }
431
-
432
- // OBJECTS
433
- for (const yo of y.objects)
434
- if (x.objects.some((xo) => MetadataObject.covers(xo, yo)) === false)
435
- return false;
436
-
437
- // ALIASES
438
- for (const yd of y.aliases)
439
- if (x.aliases.some((xd) => xd.name === yd.name) === false)
440
- return false;
441
-
442
- // NATIVES
443
- for (const yn of y.natives)
444
- if (x.natives.some((xn) => xn === yn) === false) return false;
445
-
446
- // SETS
447
- for (const ys of y.sets)
448
- if (x.sets.some((xs) => covers(xs, ys)) === false) return false;
449
-
450
- //----
451
- // VALUES
452
- //----
453
- // ATOMICS
454
- if (y.atomics.some((atomic) => x.atomics.includes(atomic) === false))
455
- return false;
456
-
457
- // CONSTANTS
458
- for (const yc of y.constants) {
459
- if (x.atomics.some((type) => yc.type === type)) continue;
460
- const xc: MetadataConstant | undefined = x.constants.find(
461
- (elem) => elem.type === yc.type,
462
- );
463
- if (xc === undefined) return false;
464
- else if (
465
- (yc.values as number[]).some(
466
- (yv) => xc.values.includes(yv as never) === false,
467
- )
468
- )
469
- return false;
470
- }
471
-
472
- // FUNCTIONAL
473
- if (x.functional === false && y.functional) return false;
474
-
475
- // SUCCESS
476
- return true;
477
- };
478
-
479
- /**
480
- * @internal
481
- */
482
- export const merge = (x: Metadata, y: Metadata): Metadata => {
483
- const output: Metadata = Metadata.create({
484
- any: x.any || y.any,
485
- nullable: x.nullable || y.nullable,
486
- required: x.required && y.required,
487
- optional: x.optional || y.optional,
488
- functional: x.functional || y.functional,
489
-
490
- resolved:
491
- x.resolved !== null && y.resolved !== null
492
- ? //? merge(x.resolved, y.resolved)
493
- MetadataResolved.create({
494
- original: merge(
495
- x.resolved.original,
496
- y.resolved.original,
497
- ),
498
- returns: merge(
499
- x.resolved.returns,
500
- y.resolved.returns,
501
- ),
502
- })
503
- : x.resolved ?? y.resolved,
504
- atomics: [...new Set([...x.atomics, ...y.atomics])],
505
- constants: [...x.constants],
506
- templates: x.templates.slice(),
507
-
508
- rest:
509
- x.rest !== null && y.rest !== null
510
- ? merge(x.rest, y.rest)
511
- : x.rest ?? y.rest,
512
- arrays: x.arrays.slice(),
513
- tuples: x.tuples.slice(),
514
- objects: x.objects.slice(),
515
- aliases: x.aliases.slice(),
516
-
517
- natives: [...new Set([...x.natives, ...y.natives])],
518
- sets: x.sets.slice(),
519
- maps: x.maps.slice(),
520
- });
521
- for (const constant of y.constants) {
522
- const target: MetadataConstant = ArrayUtil.take(
523
- output.constants,
524
- (elem) => elem.type === constant.type,
525
- () => ({
526
- type: constant.type,
527
- values: [],
528
- }),
529
- );
530
- for (const value of constant.values)
531
- ArrayUtil.add(target.values, value);
532
- }
533
- for (const array of y.arrays)
534
- ArrayUtil.set(output.arrays, array, (elem) => elem.name);
535
- for (const tuple of y.tuples)
536
- ArrayUtil.set(output.tuples, tuple, (elem) => elem.name);
537
- for (const obj of y.objects)
538
- ArrayUtil.set(output.objects, obj, (elem) => elem.name);
539
- for (const alias of y.aliases)
540
- ArrayUtil.set(output.aliases, alias, (elem) => elem.name);
541
-
542
- return output;
543
- };
544
- }
545
-
546
- const getName = (metadata: Metadata): string => {
547
- if (metadata.any === true) return "any";
548
-
549
- const elements: string[] = [];
550
-
551
- // OPTIONAL
552
- if (metadata.nullable === true) elements.push("null");
553
- if (metadata.isRequired() === false) elements.push("undefined");
554
-
555
- // ATOMIC
556
- for (const type of metadata.atomics) {
557
- elements.push(type);
558
- }
559
- for (const constant of metadata.constants)
560
- for (const value of constant.values)
561
- elements.push(JSON.stringify(value));
562
- for (const template of metadata.templates)
563
- elements.push(
564
- "`" +
565
- template
566
- .map((child) =>
567
- child.isConstant() && child.size() === 1
568
- ? child.constants[0]!.values[0]!
569
- : `$\{${child.getName()}\}`,
570
- )
571
- .join("")
572
- .split("`")
573
- .join("\\`") +
574
- "`",
575
- );
576
-
577
- // NATIVES
578
- for (const native of metadata.natives) elements.push(native);
579
- for (const set of metadata.sets) elements.push(`Set<${set.getName()}>`);
580
- for (const map of metadata.maps)
581
- elements.push(`Map<${map.key.getName()}, ${map.value.getName()}>`);
582
-
583
- // INSTANCES
584
- if (metadata.rest !== null) elements.push(`...${metadata.rest.getName()}`);
585
- for (const tuple of metadata.tuples) elements.push(tuple.name);
586
- for (const array of metadata.arrays) elements.push(array.name);
587
- for (const object of metadata.objects) elements.push(object.name);
588
- for (const alias of metadata.aliases) elements.push(alias.name);
589
- if (metadata.resolved !== null) elements.push(metadata.resolved.getName());
590
-
591
- // RETURNS
592
- if (elements.length === 0) return "unknown";
593
- else if (elements.length === 1) return elements[0]!;
594
-
595
- elements.sort();
596
- return `(${elements.join(" | ")})`;
597
- };
598
- export namespace Metadata {
599
- export interface Entry {
600
- key: Metadata;
601
- value: Metadata;
602
- }
603
- }
1
+ import { Atomic } from "../typings/Atomic";
2
+ import { ClassProperties } from "../typings/ClassProperties";
3
+ import { Writable } from "../typings/Writable";
4
+
5
+ import { ArrayUtil } from "../utils/ArrayUtil";
6
+
7
+ import { IMetadata } from "./IMetadata";
8
+ import { IMetadataCollection } from "./IMetadataCollection";
9
+ import { IMetadataDictionary } from "./IMetadataDictionary";
10
+ import { MetadataAlias } from "./MetadataAlias";
11
+ import { MetadataArray } from "./MetadataArray";
12
+ import { MetadataConstant } from "./MetadataConstant";
13
+ import { MetadataObject } from "./MetadataObject";
14
+ import { MetadataProperty } from "./MetadataProperty";
15
+ import { MetadataResolved } from "./MetadataResolved";
16
+ import { MetadataTuple } from "./MetadataTuple";
17
+
18
+ export class Metadata {
19
+ public any: boolean;
20
+ public required: boolean;
21
+ public optional: boolean;
22
+ public nullable: boolean;
23
+ public functional: boolean;
24
+
25
+ public resolved: MetadataResolved | null;
26
+ public atomics: Atomic.Literal[];
27
+ public constants: MetadataConstant[];
28
+ public templates: Metadata[][];
29
+
30
+ public rest: Metadata | null;
31
+ public aliases: MetadataAlias[];
32
+ public arrays: MetadataArray[];
33
+ public tuples: MetadataTuple[];
34
+ public objects: MetadataObject[];
35
+
36
+ public natives: string[];
37
+ public sets: Metadata[];
38
+ public maps: Metadata.Entry[];
39
+
40
+ /** @internal */ private name_?: string;
41
+ /** @internal */ private parent_resolved_: boolean = false;
42
+ /** @internal */ public union_index?: number;
43
+
44
+ /* -----------------------------------------------------------
45
+ CONSTRUCTORS
46
+ ----------------------------------------------------------- */
47
+ /**
48
+ * @hidden
49
+ */
50
+ private constructor(props: ClassProperties<Metadata>) {
51
+ this.any = props.any;
52
+ this.required = props.required;
53
+ this.optional = props.optional;
54
+ this.nullable = props.nullable;
55
+ this.functional = props.functional;
56
+
57
+ this.resolved = props.resolved;
58
+ this.atomics = props.atomics;
59
+ this.constants = props.constants;
60
+ this.templates = props.templates;
61
+
62
+ this.rest = props.rest;
63
+ this.arrays = props.arrays;
64
+ this.tuples = props.tuples;
65
+ this.objects = props.objects;
66
+ this.aliases = props.aliases;
67
+
68
+ this.natives = props.natives;
69
+ this.sets = props.sets;
70
+ this.maps = props.maps;
71
+ }
72
+
73
+ /**
74
+ * @internal
75
+ */
76
+ public static create(props: ClassProperties<Metadata>): Metadata {
77
+ return new Metadata(props);
78
+ }
79
+
80
+ /**
81
+ * @internal
82
+ */
83
+ public static initialize(parentResolved: boolean = false): Metadata {
84
+ const meta: Metadata = this.create({
85
+ any: false,
86
+ nullable: false,
87
+ required: true,
88
+ optional: false,
89
+ functional: false,
90
+
91
+ resolved: null,
92
+ constants: [],
93
+ atomics: [],
94
+ templates: [],
95
+ arrays: [],
96
+ tuples: [],
97
+ objects: [],
98
+ aliases: [],
99
+
100
+ rest: null,
101
+ natives: [],
102
+ sets: [],
103
+ maps: [],
104
+ });
105
+ meta.parent_resolved_ = parentResolved;
106
+ return meta;
107
+ }
108
+
109
+ public toJSON(): IMetadata {
110
+ return {
111
+ any: this.any,
112
+ required: this.required,
113
+ optional: this.optional,
114
+ nullable: this.nullable,
115
+ functional: this.functional,
116
+
117
+ atomics: this.atomics.slice(),
118
+ constants: JSON.parse(JSON.stringify(this.constants)),
119
+ templates: this.templates.map((tpl) =>
120
+ tpl.map((meta) => meta.toJSON()),
121
+ ),
122
+ resolved: this.resolved ? this.resolved.toJSON() : null,
123
+
124
+ rest: this.rest ? this.rest.toJSON() : null,
125
+ arrays: this.arrays.map((array) => array.name),
126
+ tuples: this.tuples.map((tuple) => tuple.name),
127
+ objects: this.objects.map((obj) => obj.name),
128
+ aliases: this.aliases.map((alias) => alias.name),
129
+
130
+ natives: this.natives.slice(),
131
+ sets: this.sets.map((meta) => meta.toJSON()),
132
+ maps: this.maps.map((entry) => ({
133
+ key: entry.key.toJSON(),
134
+ value: entry.value.toJSON(),
135
+ })),
136
+ };
137
+ }
138
+
139
+ public static from(
140
+ meta: IMetadata,
141
+ collection: IMetadataCollection,
142
+ ): Metadata {
143
+ const dict: IMetadataDictionary = {
144
+ objects: new Map(
145
+ collection.objects.map((obj) => [
146
+ obj.name,
147
+ MetadataObject._From_without_properties(obj),
148
+ ]),
149
+ ),
150
+ aliases: new Map(
151
+ collection.aliases.map((alias) => [
152
+ alias.name,
153
+ MetadataAlias._From_without_value(alias),
154
+ ]),
155
+ ),
156
+ arrays: new Map(
157
+ collection.arrays.map((arr) => [
158
+ arr.name,
159
+ MetadataArray._From_without_value(arr),
160
+ ]),
161
+ ),
162
+ tuples: new Map(
163
+ collection.tuples.map((tpl) => [
164
+ tpl.name,
165
+ MetadataTuple._From_without_elements(tpl),
166
+ ]),
167
+ ),
168
+ };
169
+
170
+ for (const obj of collection.objects) {
171
+ const initialized = dict.objects.get(obj.name)!;
172
+ initialized.properties.push(
173
+ ...obj.properties.map((prop) =>
174
+ MetadataProperty._From(prop, dict),
175
+ ),
176
+ );
177
+ }
178
+ for (const alias of collection.aliases)
179
+ Writable(dict.aliases.get(alias.name)!).value = this._From(
180
+ alias.value,
181
+ dict,
182
+ );
183
+ for (const array of collection.arrays)
184
+ Writable(dict.arrays.get(array.name)!).value = this._From(
185
+ array.value,
186
+ dict,
187
+ );
188
+ for (const tuple of collection.tuples)
189
+ Writable(dict.tuples.get(tuple.name)!).elements =
190
+ tuple.elements.map((elem) => this._From(elem, dict));
191
+
192
+ return this._From(meta, dict);
193
+ }
194
+
195
+ /**
196
+ * @internal
197
+ */
198
+ public static _From(meta: IMetadata, dict: IMetadataDictionary): Metadata {
199
+ return this.create({
200
+ any: meta.any,
201
+ required: meta.required,
202
+ optional: meta.optional,
203
+ nullable: meta.nullable,
204
+ functional: meta.functional,
205
+
206
+ constants: JSON.parse(JSON.stringify(meta.constants)),
207
+ atomics: meta.atomics.slice(),
208
+ templates: meta.templates.map((tpl) =>
209
+ tpl.map((meta) => this._From(meta, dict)),
210
+ ),
211
+ resolved: meta.resolved
212
+ ? MetadataResolved._From(meta.resolved, dict)
213
+ : null,
214
+
215
+ rest: meta.rest ? this._From(meta.rest, dict) : null,
216
+ arrays: meta.arrays.map((id) => {
217
+ const array = dict.arrays.get(id);
218
+ if (array === undefined)
219
+ throw new Error(
220
+ `Error on Metadata.from(): failed to find array "${id}".`,
221
+ );
222
+ return array;
223
+ }),
224
+ tuples: meta.tuples.map((id) => {
225
+ const tuple = dict.tuples.get(id);
226
+ if (tuple === undefined)
227
+ throw new Error(
228
+ `Error on Metadata.from(): failed to find tuple "${id}".`,
229
+ );
230
+ return tuple;
231
+ }),
232
+ objects: meta.objects.map((name) => {
233
+ const found = dict.objects.get(name);
234
+ if (found === undefined)
235
+ throw new Error(
236
+ `Error on Metadata.from(): failed to find object "${name}".`,
237
+ );
238
+ return found;
239
+ }),
240
+ aliases: meta.aliases.map((alias) => {
241
+ const found = dict.aliases.get(alias);
242
+ if (found === undefined)
243
+ throw new Error(
244
+ `Error on Metadata.from(): failed to find alias "${alias}".`,
245
+ );
246
+ return found;
247
+ }),
248
+
249
+ natives: meta.natives.slice(),
250
+ sets: meta.sets.map((meta) => this._From(meta, dict)),
251
+ maps: meta.maps.map((entry) => ({
252
+ key: this._From(entry.key, dict),
253
+ value: this._From(entry.value, dict),
254
+ })),
255
+ });
256
+ }
257
+
258
+ /* -----------------------------------------------------------
259
+ ACCESSORS
260
+ ----------------------------------------------------------- */
261
+ public getName(): string {
262
+ this.name_ ??= getName(this);
263
+ return this.name_;
264
+ }
265
+
266
+ public empty(): boolean {
267
+ return this.bucket() === 0 || this.size() === 0;
268
+ }
269
+ public size(): number {
270
+ return (
271
+ (this.any ? 1 : 0) +
272
+ (this.resolved ? 1 : 0) +
273
+ (this.functional ? 1 : 0) +
274
+ (this.rest ? this.rest.size() : 0) +
275
+ this.templates.length +
276
+ this.atomics.length +
277
+ this.constants
278
+ .map((c) => c.values.length)
279
+ .reduce((x, y) => x + y, 0) +
280
+ this.arrays.length +
281
+ this.tuples.length +
282
+ this.natives.length +
283
+ this.maps.length +
284
+ this.sets.length +
285
+ this.objects.length +
286
+ this.aliases.length
287
+ );
288
+ }
289
+ public bucket(): number {
290
+ return (
291
+ (this.any ? 1 : 0) +
292
+ (this.resolved ? 1 : 0) +
293
+ (this.functional ? 1 : 0) +
294
+ (this.templates.length ? 1 : 0) +
295
+ (this.atomics.length ? 1 : 0) +
296
+ (this.constants.length ? 1 : 0) +
297
+ (this.rest ? this.rest.size() : 0) +
298
+ (this.arrays.length ? 1 : 0) +
299
+ (this.tuples.length ? 1 : 0) +
300
+ (this.natives.length ? 1 : 0) +
301
+ (this.sets.length ? 1 : 0) +
302
+ (this.maps.length ? 1 : 0) +
303
+ (this.objects.length ? 1 : 0) +
304
+ (this.aliases.length ? 1 : 0)
305
+ );
306
+ }
307
+ public isConstant(): boolean {
308
+ return this.bucket() === (this.constants.length ? 1 : 0);
309
+ }
310
+
311
+ public isRequired(): boolean {
312
+ return this.required === true && this.optional === false;
313
+ }
314
+
315
+ /**
316
+ * @internal
317
+ */
318
+ public isUnionBucket(): boolean {
319
+ const size: number = this.bucket();
320
+ const emended: number = this.constants.length ? size - 1 : size;
321
+ return emended > 1;
322
+ }
323
+
324
+ /**
325
+ * @internal
326
+ */
327
+ public getSoleLiteral(): string | null {
328
+ if (
329
+ this.size() === 1 &&
330
+ this.constants.length === 1 &&
331
+ this.constants[0]!.type === "string" &&
332
+ this.constants[0]!.values.length === 1
333
+ )
334
+ return this.constants[0]!.values[0] as string;
335
+ else return null;
336
+ }
337
+
338
+ /**
339
+ * @internal
340
+ */
341
+ public isSoleLiteral(): boolean {
342
+ return this.getSoleLiteral() !== null;
343
+ }
344
+
345
+ /**
346
+ * @internal
347
+ */
348
+ public isParentResolved(): boolean {
349
+ return this.parent_resolved_;
350
+ }
351
+ }
352
+ export namespace Metadata {
353
+ export const intersects = (x: Metadata, y: Metadata): boolean => {
354
+ // CHECK ANY & OPTIONAL
355
+ if (x.any || y.any) return true;
356
+ if (x.isRequired() === false && false === y.isRequired()) return true;
357
+ if (x.nullable === true && true === y.nullable) return true;
358
+ if (x.functional === true && y.functional === true) return true;
359
+
360
+ //----
361
+ // INSTANCES
362
+ //----
363
+ // ARRAYS
364
+ if (x.arrays.length && y.arrays.length) return true;
365
+ if (x.tuples.length && y.tuples.length) return true;
366
+ if (x.objects.length && y.objects.length) return true;
367
+ if (x.aliases.length && y.aliases.length) return true;
368
+
369
+ //----
370
+ // VALUES
371
+ //----
372
+ // ATOMICS
373
+ for (const atomic of x.atomics)
374
+ if (y.atomics.includes(atomic)) return true;
375
+
376
+ // CONSTANTS
377
+ for (const constant of x.constants) {
378
+ const opposite: MetadataConstant | undefined = y.constants.find(
379
+ (elem) => elem.type === constant.type,
380
+ );
381
+ if (opposite === undefined) continue;
382
+
383
+ const values: Set<any> = new Set([
384
+ ...constant.values,
385
+ ...opposite.values,
386
+ ]);
387
+ if (values.size !== constant.values.length + opposite.values.length)
388
+ return true;
389
+ }
390
+ return false;
391
+ };
392
+
393
+ export const covers = (
394
+ x: Metadata,
395
+ y: Metadata,
396
+ level: number = 0,
397
+ ): boolean => {
398
+ // CHECK ANY
399
+ if (x === y) return false;
400
+ else if (x.any) return true;
401
+ else if (y.any) return false;
402
+
403
+ //----
404
+ // INSTANCES
405
+ //----
406
+ if (level === 0) {
407
+ // ARRAYS
408
+ for (const ya of y.arrays)
409
+ if (
410
+ !x.arrays.some((xa) =>
411
+ covers(xa.value, ya.value, level + 1),
412
+ )
413
+ ) {
414
+ return false;
415
+ }
416
+
417
+ // TUPLES
418
+ for (const yt of y.tuples)
419
+ if (
420
+ yt.elements.length !== 0 &&
421
+ x.tuples.some(
422
+ (xt) =>
423
+ xt.elements.length >= yt.elements.length &&
424
+ xt.elements
425
+ .slice(yt.elements.length)
426
+ .every((xv, i) =>
427
+ covers(xv, yt.elements[i]!, level + 1),
428
+ ),
429
+ ) === false
430
+ )
431
+ return false;
432
+ }
433
+
434
+ // OBJECTS
435
+ for (const yo of y.objects)
436
+ if (x.objects.some((xo) => MetadataObject.covers(xo, yo)) === false)
437
+ return false;
438
+
439
+ // ALIASES
440
+ for (const yd of y.aliases)
441
+ if (x.aliases.some((xd) => xd.name === yd.name) === false)
442
+ return false;
443
+
444
+ // NATIVES
445
+ for (const yn of y.natives)
446
+ if (x.natives.some((xn) => xn === yn) === false) return false;
447
+
448
+ // SETS
449
+ for (const ys of y.sets)
450
+ if (x.sets.some((xs) => covers(xs, ys)) === false) return false;
451
+
452
+ //----
453
+ // VALUES
454
+ //----
455
+ // ATOMICS
456
+ if (y.atomics.some((atomic) => x.atomics.includes(atomic) === false))
457
+ return false;
458
+
459
+ // CONSTANTS
460
+ for (const yc of y.constants) {
461
+ if (x.atomics.some((type) => yc.type === type)) continue;
462
+ const xc: MetadataConstant | undefined = x.constants.find(
463
+ (elem) => elem.type === yc.type,
464
+ );
465
+ if (xc === undefined) return false;
466
+ else if (
467
+ (yc.values as number[]).some(
468
+ (yv) => xc.values.includes(yv as never) === false,
469
+ )
470
+ )
471
+ return false;
472
+ }
473
+
474
+ // FUNCTIONAL
475
+ if (x.functional === false && y.functional) return false;
476
+
477
+ // SUCCESS
478
+ return true;
479
+ };
480
+
481
+ /**
482
+ * @internal
483
+ */
484
+ export const merge = (x: Metadata, y: Metadata): Metadata => {
485
+ const output: Metadata = Metadata.create({
486
+ any: x.any || y.any,
487
+ nullable: x.nullable || y.nullable,
488
+ required: x.required && y.required,
489
+ optional: x.optional || y.optional,
490
+ functional: x.functional || y.functional,
491
+
492
+ resolved:
493
+ x.resolved !== null && y.resolved !== null
494
+ ? //? merge(x.resolved, y.resolved)
495
+ MetadataResolved.create({
496
+ original: merge(
497
+ x.resolved.original,
498
+ y.resolved.original,
499
+ ),
500
+ returns: merge(
501
+ x.resolved.returns,
502
+ y.resolved.returns,
503
+ ),
504
+ })
505
+ : x.resolved ?? y.resolved,
506
+ atomics: [...new Set([...x.atomics, ...y.atomics])],
507
+ constants: [...x.constants],
508
+ templates: x.templates.slice(),
509
+
510
+ rest:
511
+ x.rest !== null && y.rest !== null
512
+ ? merge(x.rest, y.rest)
513
+ : x.rest ?? y.rest,
514
+ arrays: x.arrays.slice(),
515
+ tuples: x.tuples.slice(),
516
+ objects: x.objects.slice(),
517
+ aliases: x.aliases.slice(),
518
+
519
+ natives: [...new Set([...x.natives, ...y.natives])],
520
+ sets: x.sets.slice(),
521
+ maps: x.maps.slice(),
522
+ });
523
+ for (const constant of y.constants) {
524
+ const target: MetadataConstant = ArrayUtil.take(
525
+ output.constants,
526
+ (elem) => elem.type === constant.type,
527
+ () => ({
528
+ type: constant.type,
529
+ values: [],
530
+ }),
531
+ );
532
+ for (const value of constant.values)
533
+ ArrayUtil.add(target.values, value);
534
+ }
535
+ for (const array of y.arrays)
536
+ ArrayUtil.set(output.arrays, array, (elem) => elem.name);
537
+ for (const tuple of y.tuples)
538
+ ArrayUtil.set(output.tuples, tuple, (elem) => elem.name);
539
+ for (const obj of y.objects)
540
+ ArrayUtil.set(output.objects, obj, (elem) => elem.name);
541
+ for (const alias of y.aliases)
542
+ ArrayUtil.set(output.aliases, alias, (elem) => elem.name);
543
+
544
+ return output;
545
+ };
546
+ }
547
+
548
+ const getName = (metadata: Metadata): string => {
549
+ if (metadata.any === true) return "any";
550
+
551
+ const elements: string[] = [];
552
+
553
+ // OPTIONAL
554
+ if (metadata.nullable === true) elements.push("null");
555
+ if (metadata.isRequired() === false) elements.push("undefined");
556
+
557
+ // ATOMIC
558
+ for (const type of metadata.atomics) {
559
+ elements.push(type);
560
+ }
561
+ for (const constant of metadata.constants)
562
+ for (const value of constant.values)
563
+ elements.push(JSON.stringify(value));
564
+ for (const template of metadata.templates)
565
+ elements.push(
566
+ "`" +
567
+ template
568
+ .map((child) =>
569
+ child.isConstant() && child.size() === 1
570
+ ? child.constants[0]!.values[0]!
571
+ : `$\{${child.getName()}\}`,
572
+ )
573
+ .join("")
574
+ .split("`")
575
+ .join("\\`") +
576
+ "`",
577
+ );
578
+
579
+ // NATIVES
580
+ for (const native of metadata.natives) elements.push(native);
581
+ for (const set of metadata.sets) elements.push(`Set<${set.getName()}>`);
582
+ for (const map of metadata.maps)
583
+ elements.push(`Map<${map.key.getName()}, ${map.value.getName()}>`);
584
+
585
+ // INSTANCES
586
+ if (metadata.rest !== null) elements.push(`...${metadata.rest.getName()}`);
587
+ for (const tuple of metadata.tuples) elements.push(tuple.name);
588
+ for (const array of metadata.arrays) elements.push(array.name);
589
+ for (const object of metadata.objects) elements.push(object.name);
590
+ for (const alias of metadata.aliases) elements.push(alias.name);
591
+ if (metadata.resolved !== null) elements.push(metadata.resolved.getName());
592
+
593
+ // RETURNS
594
+ if (elements.length === 0) return "unknown";
595
+ else if (elements.length === 1) return elements[0]!;
596
+
597
+ elements.sort();
598
+ return `(${elements.join(" | ")})`;
599
+ };
600
+ export namespace Metadata {
601
+ export interface Entry {
602
+ key: Metadata;
603
+ value: Metadata;
604
+ }
605
+ }