@zyno-io/ts-reflection 26.803.2224
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 +13 -0
- package/dist/index.cjs +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +966 -0
- package/dist/reflection/annotations.d.ts +15 -0
- package/dist/reflection/annotations.d.ts.map +1 -0
- package/dist/reflection/compact-metadata.d.ts +18 -0
- package/dist/reflection/compact-metadata.d.ts.map +1 -0
- package/dist/reflection/conversion.d.ts +15 -0
- package/dist/reflection/conversion.d.ts.map +1 -0
- package/dist/reflection/deserializer.d.ts +15 -0
- package/dist/reflection/deserializer.d.ts.map +1 -0
- package/dist/reflection/errors.d.ts +8 -0
- package/dist/reflection/errors.d.ts.map +1 -0
- package/dist/reflection/index.d.ts +10 -0
- package/dist/reflection/index.d.ts.map +1 -0
- package/dist/reflection/metadata-store.d.ts +20 -0
- package/dist/reflection/metadata-store.d.ts.map +1 -0
- package/dist/reflection/model.d.ts +273 -0
- package/dist/reflection/model.d.ts.map +1 -0
- package/dist/reflection/primitive-conversion.d.ts +2 -0
- package/dist/reflection/primitive-conversion.d.ts.map +1 -0
- package/dist/reflection/reflection-class.d.ts +60 -0
- package/dist/reflection/reflection-class.d.ts.map +1 -0
- package/dist/reflection/type-utils.d.ts +34 -0
- package/dist/reflection/type-utils.d.ts.map +1 -0
- package/dist/type-compiler/download-prebuilt.cjs +114 -0
- package/dist/type-compiler/go/ast_expression.go +187 -0
- package/dist/type-compiler/go/ast_metadata.go +388 -0
- package/dist/type-compiler/go/collect.go +963 -0
- package/dist/type-compiler/go/compact_metadata.go +553 -0
- package/dist/type-compiler/go/emission_plan.go +340 -0
- package/dist/type-compiler/go/emit_ast.go +557 -0
- package/dist/type-compiler/go/emit_ast_test.go +558 -0
- package/dist/type-compiler/go/go.mod +10 -0
- package/dist/type-compiler/go/plugin.go +359 -0
- package/dist/type-compiler/go/plugin_test.go +1206 -0
- package/dist/type-compiler/go/precompute.go +86 -0
- package/dist/type-compiler/go/receive_type.go +912 -0
- package/dist/type-compiler/go/resolve.go +265 -0
- package/dist/type-compiler/go/source_scan.go +51 -0
- package/dist/type-compiler/go/text_parse.go +734 -0
- package/dist/type-compiler/go/type_expr.go +1291 -0
- package/dist/type-compiler/go/typia_expr.go +2316 -0
- package/dist/type-compiler/index.cjs +43 -0
- package/dist/type-compiler/pnp.cjs +474 -0
- package/dist/type-compiler/prebuilt.cjs +324 -0
- package/dist/type-metadata-runtime.cjs +1 -0
- package/dist/type-metadata-runtime.d.ts +2 -0
- package/dist/type-metadata-runtime.d.ts.map +1 -0
- package/dist/type-metadata-runtime.js +107 -0
- package/dist/types/index.d.ts +4 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/primitives.d.ts +33 -0
- package/dist/types/primitives.d.ts.map +1 -0
- package/dist/types/runtime.d.ts +2 -0
- package/dist/types/runtime.d.ts.map +1 -0
- package/dist/types/type-annotations.d.ts +28 -0
- package/dist/types/type-annotations.d.ts.map +1 -0
- package/package.json +47 -0
|
@@ -0,0 +1,553 @@
|
|
|
1
|
+
package main
|
|
2
|
+
|
|
3
|
+
import (
|
|
4
|
+
"bytes"
|
|
5
|
+
"encoding/json"
|
|
6
|
+
"strconv"
|
|
7
|
+
"strings"
|
|
8
|
+
|
|
9
|
+
shimast "github.com/microsoft/typescript-go/shim/ast"
|
|
10
|
+
shimprinter "github.com/microsoft/typescript-go/shim/printer"
|
|
11
|
+
)
|
|
12
|
+
|
|
13
|
+
const (
|
|
14
|
+
compactMetadataRuntimeSpec = "@zyno-io/ts-reflection/type-metadata-runtime"
|
|
15
|
+
compactMetadataDecoderName = "decodeCompactMetadataV1"
|
|
16
|
+
compactMetadataRegistryName = "createCompactMetadataRegistryV1"
|
|
17
|
+
compactMetadataAliasResolverName = "resolveCompactMetadataAliasV1"
|
|
18
|
+
compactMetadataReferenceKey = "$tsf"
|
|
19
|
+
compactMetadataImportKey = "$tsfImport"
|
|
20
|
+
compactMetadataAliasKey = "$tsfAlias"
|
|
21
|
+
compactMetadataTypeKey = "$tsfType"
|
|
22
|
+
)
|
|
23
|
+
|
|
24
|
+
type compactMetadataEncoding struct {
|
|
25
|
+
serialized string
|
|
26
|
+
references []*shimast.Node
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
type compactMetadataEncoder struct {
|
|
30
|
+
buffer bytes.Buffer
|
|
31
|
+
references []*shimast.Node
|
|
32
|
+
referenceIndexes map[string]int
|
|
33
|
+
referenceKey func(*shimast.Node) (string, bool)
|
|
34
|
+
runtimeRecipe func(*compactMetadataEncoder, *shimast.Node) bool
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
type compactMetadataRuntimeInterner struct {
|
|
38
|
+
sourceFile *shimast.SourceFile
|
|
39
|
+
printer *shimprinter.Printer
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
func newCompactMetadataRuntimeInterner(
|
|
43
|
+
ec *shimprinter.EmitContext,
|
|
44
|
+
sourceFile *shimast.SourceFile,
|
|
45
|
+
) *compactMetadataRuntimeInterner {
|
|
46
|
+
return &compactMetadataRuntimeInterner{
|
|
47
|
+
sourceFile: sourceFile,
|
|
48
|
+
printer: shimprinter.NewPrinter(shimprinter.PrinterOptions{}, shimprinter.PrintHandlers{}, ec),
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
func isCompactMetadataAliasResolverCall(expression *shimast.Node) bool {
|
|
53
|
+
if expression == nil || expression.Kind != shimast.KindCallExpression {
|
|
54
|
+
return false
|
|
55
|
+
}
|
|
56
|
+
call := expression.AsCallExpression()
|
|
57
|
+
if call == nil || call.Expression == nil || call.Expression.Kind != shimast.KindPropertyAccessExpression {
|
|
58
|
+
return false
|
|
59
|
+
}
|
|
60
|
+
name := call.Expression.AsPropertyAccessExpression().Name()
|
|
61
|
+
return name != nil && name.Text() == compactMetadataAliasResolverName
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// deduplicationKey identifies generated runtime expressions whose value may be
|
|
65
|
+
// shared inside one decoded metadata graph. Class/validator thunks and primitive
|
|
66
|
+
// non-JSON values are immutable. Imported alias lookups clone compiler-owned
|
|
67
|
+
// metadata only to attach the same type name, so sharing that clone is also
|
|
68
|
+
// equivalent and avoids emitting hundreds of repeated factory calls for large
|
|
69
|
+
// DTO graphs. Arbitrary call expressions and escaped application objects remain
|
|
70
|
+
// distinct.
|
|
71
|
+
func (interner *compactMetadataRuntimeInterner) deduplicationKey(expression *shimast.Node) (string, bool) {
|
|
72
|
+
if expression == nil {
|
|
73
|
+
return "", false
|
|
74
|
+
}
|
|
75
|
+
switch expression.Kind {
|
|
76
|
+
case shimast.KindArrowFunction, shimast.KindBigIntLiteral:
|
|
77
|
+
return interner.emit(expression), true
|
|
78
|
+
case shimast.KindIdentifier:
|
|
79
|
+
if expression.Text() == "undefined" {
|
|
80
|
+
return "undefined", true
|
|
81
|
+
}
|
|
82
|
+
case shimast.KindCallExpression:
|
|
83
|
+
if isCompactMetadataAliasResolverCall(expression) {
|
|
84
|
+
return interner.emit(expression), true
|
|
85
|
+
}
|
|
86
|
+
source := interner.emit(expression)
|
|
87
|
+
if strings.Contains(source, "__tsf_module") && strings.Contains(source, "__tsf_alias") {
|
|
88
|
+
return source, true
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
return "", false
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
func (interner *compactMetadataRuntimeInterner) emit(expression *shimast.Node) string {
|
|
95
|
+
sourceFile := shimast.GetSourceFileOfNode(expression)
|
|
96
|
+
if sourceFile == nil {
|
|
97
|
+
sourceFile = interner.sourceFile
|
|
98
|
+
}
|
|
99
|
+
return interner.printer.Emit(expression, sourceFile)
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
func encodeCompactMetadata(root *shimast.Node) compactMetadataEncoding {
|
|
103
|
+
return encodeCompactMetadataWithReferenceKeys(root, nil)
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
func encodeCompactMetadataWithReferenceKeys(
|
|
107
|
+
root *shimast.Node,
|
|
108
|
+
referenceKey func(*shimast.Node) (string, bool),
|
|
109
|
+
) compactMetadataEncoding {
|
|
110
|
+
return encodeCompactMetadataWithRuntimeRecipes(root, referenceKey, nil)
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
func encodeCompactMetadataWithRuntimeRecipes(
|
|
114
|
+
root *shimast.Node,
|
|
115
|
+
referenceKey func(*shimast.Node) (string, bool),
|
|
116
|
+
runtimeRecipe func(*compactMetadataEncoder, *shimast.Node) bool,
|
|
117
|
+
) compactMetadataEncoding {
|
|
118
|
+
encoder := &compactMetadataEncoder{
|
|
119
|
+
referenceIndexes: map[string]int{},
|
|
120
|
+
referenceKey: referenceKey,
|
|
121
|
+
runtimeRecipe: runtimeRecipe,
|
|
122
|
+
}
|
|
123
|
+
encoder.buffer.WriteString("[1,")
|
|
124
|
+
encoder.writeValue(root)
|
|
125
|
+
encoder.buffer.WriteByte(']')
|
|
126
|
+
return compactMetadataEncoding{
|
|
127
|
+
serialized: encoder.buffer.String(),
|
|
128
|
+
references: encoder.references,
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
func (encoder *compactMetadataEncoder) writeValue(node *shimast.Node) {
|
|
133
|
+
start := encoder.buffer.Len()
|
|
134
|
+
referenceStart := len(encoder.references)
|
|
135
|
+
if encoder.writeJSONValue(node) {
|
|
136
|
+
return
|
|
137
|
+
}
|
|
138
|
+
encoder.buffer.Truncate(start)
|
|
139
|
+
encoder.references = encoder.references[:referenceStart]
|
|
140
|
+
encoder.writeReference(node)
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
func (encoder *compactMetadataEncoder) writeJSONValue(node *shimast.Node) bool {
|
|
144
|
+
if node == nil {
|
|
145
|
+
return false
|
|
146
|
+
}
|
|
147
|
+
if encoder.runtimeRecipe != nil && encoder.runtimeRecipe(encoder, node) {
|
|
148
|
+
return true
|
|
149
|
+
}
|
|
150
|
+
switch node.Kind {
|
|
151
|
+
case shimast.KindParenthesizedExpression:
|
|
152
|
+
encoder.writeValue(node.AsParenthesizedExpression().Expression)
|
|
153
|
+
return true
|
|
154
|
+
case shimast.KindObjectLiteralExpression:
|
|
155
|
+
return encoder.writeObject(node.AsObjectLiteralExpression())
|
|
156
|
+
case shimast.KindArrayLiteralExpression:
|
|
157
|
+
return encoder.writeArray(node.AsArrayLiteralExpression())
|
|
158
|
+
case shimast.KindStringLiteral, shimast.KindNoSubstitutionTemplateLiteral:
|
|
159
|
+
encoder.writeJSONString(node.Text())
|
|
160
|
+
return true
|
|
161
|
+
case shimast.KindNumericLiteral:
|
|
162
|
+
return encoder.writeJSONNumber(node.Text())
|
|
163
|
+
case shimast.KindTrueKeyword:
|
|
164
|
+
encoder.buffer.WriteString("true")
|
|
165
|
+
return true
|
|
166
|
+
case shimast.KindFalseKeyword:
|
|
167
|
+
encoder.buffer.WriteString("false")
|
|
168
|
+
return true
|
|
169
|
+
case shimast.KindNullKeyword:
|
|
170
|
+
encoder.buffer.WriteString("null")
|
|
171
|
+
return true
|
|
172
|
+
case shimast.KindPrefixUnaryExpression:
|
|
173
|
+
unary := node.AsPrefixUnaryExpression()
|
|
174
|
+
if unary.Operator != shimast.KindMinusToken || unary.Operand == nil || unary.Operand.Kind != shimast.KindNumericLiteral {
|
|
175
|
+
return false
|
|
176
|
+
}
|
|
177
|
+
return encoder.writeJSONNumber("-" + unary.Operand.Text())
|
|
178
|
+
default:
|
|
179
|
+
return false
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
func (encoder *compactMetadataEncoder) writeObject(object *shimast.ObjectLiteralExpression) bool {
|
|
184
|
+
if object == nil || object.Properties == nil {
|
|
185
|
+
encoder.buffer.WriteString("{}")
|
|
186
|
+
return true
|
|
187
|
+
}
|
|
188
|
+
for _, property := range object.Properties.Nodes {
|
|
189
|
+
name, ok := compactMetadataPropertyName(property)
|
|
190
|
+
if !ok || name == "__proto__" {
|
|
191
|
+
return false
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
// An application-provided object with the same exact shape as a wire-format
|
|
195
|
+
// reference must remain ordinary data. Escaping the small object through the
|
|
196
|
+
// side table makes marker recognition unambiguous without reserving a user key.
|
|
197
|
+
if len(object.Properties.Nodes) == 1 {
|
|
198
|
+
if name, ok := compactMetadataPropertyName(object.Properties.Nodes[0]); ok && isCompactMetadataReservedKey(name) {
|
|
199
|
+
return false
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
encoder.buffer.WriteByte('{')
|
|
203
|
+
for index, property := range object.Properties.Nodes {
|
|
204
|
+
assignment := property.AsPropertyAssignment()
|
|
205
|
+
name, _ := compactMetadataPropertyName(property)
|
|
206
|
+
if index != 0 {
|
|
207
|
+
encoder.buffer.WriteByte(',')
|
|
208
|
+
}
|
|
209
|
+
encoder.writeJSONString(name)
|
|
210
|
+
encoder.buffer.WriteByte(':')
|
|
211
|
+
encoder.writeValue(assignment.Initializer)
|
|
212
|
+
}
|
|
213
|
+
encoder.buffer.WriteByte('}')
|
|
214
|
+
return true
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
func isCompactMetadataReservedKey(name string) bool {
|
|
218
|
+
return name == compactMetadataReferenceKey || name == compactMetadataImportKey || name == compactMetadataAliasKey || name == compactMetadataTypeKey
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
func compactMetadataPropertyName(property *shimast.Node) (string, bool) {
|
|
222
|
+
if property == nil || property.Kind != shimast.KindPropertyAssignment {
|
|
223
|
+
return "", false
|
|
224
|
+
}
|
|
225
|
+
name := property.AsPropertyAssignment().Name()
|
|
226
|
+
if name == nil {
|
|
227
|
+
return "", false
|
|
228
|
+
}
|
|
229
|
+
switch name.Kind {
|
|
230
|
+
case shimast.KindIdentifier, shimast.KindStringLiteral, shimast.KindNumericLiteral:
|
|
231
|
+
return name.Text(), true
|
|
232
|
+
default:
|
|
233
|
+
return "", false
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
func (encoder *compactMetadataEncoder) writeArray(array *shimast.ArrayLiteralExpression) bool {
|
|
238
|
+
if array == nil || array.Elements == nil {
|
|
239
|
+
encoder.buffer.WriteString("[]")
|
|
240
|
+
return true
|
|
241
|
+
}
|
|
242
|
+
for _, element := range array.Elements.Nodes {
|
|
243
|
+
if element == nil || element.Kind == shimast.KindOmittedExpression || element.Kind == shimast.KindSpreadElement {
|
|
244
|
+
return false
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
encoder.buffer.WriteByte('[')
|
|
248
|
+
for index, element := range array.Elements.Nodes {
|
|
249
|
+
if index != 0 {
|
|
250
|
+
encoder.buffer.WriteByte(',')
|
|
251
|
+
}
|
|
252
|
+
encoder.writeValue(element)
|
|
253
|
+
}
|
|
254
|
+
encoder.buffer.WriteByte(']')
|
|
255
|
+
return true
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
func (encoder *compactMetadataEncoder) writeJSONNumber(value string) bool {
|
|
259
|
+
if value == "" || !json.Valid([]byte(value)) {
|
|
260
|
+
return false
|
|
261
|
+
}
|
|
262
|
+
if _, err := strconv.ParseFloat(value, 64); err != nil {
|
|
263
|
+
return false
|
|
264
|
+
}
|
|
265
|
+
encoder.buffer.WriteString(value)
|
|
266
|
+
return true
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
func (encoder *compactMetadataEncoder) writeJSONString(value string) {
|
|
270
|
+
encoded, _ := json.Marshal(value)
|
|
271
|
+
encoder.buffer.Write(encoded)
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
func (encoder *compactMetadataEncoder) writeReference(node *shimast.Node) {
|
|
275
|
+
key := ""
|
|
276
|
+
if encoder.referenceKey != nil {
|
|
277
|
+
if deduplicationKey, ok := encoder.referenceKey(node); ok {
|
|
278
|
+
key = "runtime:" + deduplicationKey
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
index := encoder.referenceIndex(node, key)
|
|
282
|
+
encoder.writeReferenceMarker(index)
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
func (encoder *compactMetadataEncoder) referenceIndex(node *shimast.Node, key string) int {
|
|
286
|
+
if key != "" {
|
|
287
|
+
if existing, found := encoder.referenceIndexes[key]; found {
|
|
288
|
+
return existing
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
index := len(encoder.references)
|
|
292
|
+
encoder.references = append(encoder.references, node)
|
|
293
|
+
if key != "" {
|
|
294
|
+
encoder.referenceIndexes[key] = index
|
|
295
|
+
}
|
|
296
|
+
return index
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
func (encoder *compactMetadataEncoder) writeReferenceMarker(index int) {
|
|
300
|
+
encoder.buffer.WriteString(`{"` + compactMetadataReferenceKey + `":`)
|
|
301
|
+
encoder.buffer.WriteString(strconv.Itoa(index))
|
|
302
|
+
encoder.buffer.WriteByte('}')
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
func materializeCompactMetadataExpression(
|
|
306
|
+
ec *shimprinter.EmitContext,
|
|
307
|
+
imports *astImportRegistry,
|
|
308
|
+
runtimeReferences *compactMetadataRuntimeInterner,
|
|
309
|
+
template expressionTemplate,
|
|
310
|
+
metadataTypeResolver string,
|
|
311
|
+
) *shimast.Node {
|
|
312
|
+
metadata := template.materialize(ec, imports)
|
|
313
|
+
if _, ok := compactMetadataTypeRecipe(metadata, metadataTypeResolver); ok {
|
|
314
|
+
return metadata
|
|
315
|
+
}
|
|
316
|
+
return materializeCompactMetadataNode(ec, imports, runtimeReferences, metadata, metadataTypeResolver, false, false)
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
func materializeCompactAliasMetadataExpression(
|
|
320
|
+
ec *shimprinter.EmitContext,
|
|
321
|
+
imports *astImportRegistry,
|
|
322
|
+
runtimeReferences *compactMetadataRuntimeInterner,
|
|
323
|
+
template expressionTemplate,
|
|
324
|
+
metadataTypeResolver string,
|
|
325
|
+
) *shimast.Node {
|
|
326
|
+
metadata := template.materialize(ec, imports)
|
|
327
|
+
return materializeCompactMetadataNode(ec, imports, runtimeReferences, metadata, metadataTypeResolver, false, true)
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
func materializeCompactMetadataRegistry(
|
|
331
|
+
ec *shimprinter.EmitContext,
|
|
332
|
+
imports *astImportRegistry,
|
|
333
|
+
runtimeReferences *compactMetadataRuntimeInterner,
|
|
334
|
+
templates []expressionTemplate,
|
|
335
|
+
metadataTypeResolver string,
|
|
336
|
+
) *shimast.Node {
|
|
337
|
+
elements := make([]*shimast.Node, 0, len(templates))
|
|
338
|
+
for _, template := range templates {
|
|
339
|
+
elements = append(elements, template.materialize(ec, imports))
|
|
340
|
+
}
|
|
341
|
+
metadata := ec.Factory.NewArrayLiteralExpression(ec.Factory.NewNodeList(elements), false)
|
|
342
|
+
return materializeCompactMetadataNode(ec, imports, runtimeReferences, metadata, metadataTypeResolver, true, false)
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
func materializeCompactMetadataNode(
|
|
346
|
+
ec *shimprinter.EmitContext,
|
|
347
|
+
imports *astImportRegistry,
|
|
348
|
+
runtimeReferences *compactMetadataRuntimeInterner,
|
|
349
|
+
metadata *shimast.Node,
|
|
350
|
+
metadataTypeResolver string,
|
|
351
|
+
registry bool,
|
|
352
|
+
inlinePureJSON bool,
|
|
353
|
+
) *shimast.Node {
|
|
354
|
+
encoding := encodeCompactMetadataWithRuntimeRecipes(
|
|
355
|
+
metadata,
|
|
356
|
+
runtimeReferences.deduplicationKey,
|
|
357
|
+
func(encoder *compactMetadataEncoder, expression *shimast.Node) bool {
|
|
358
|
+
return writeCompactMetadataRuntimeRecipe(encoder, expression, imports, metadataTypeResolver)
|
|
359
|
+
},
|
|
360
|
+
)
|
|
361
|
+
references := make([]*shimast.Node, 0, len(encoding.references))
|
|
362
|
+
for _, reference := range encoding.references {
|
|
363
|
+
// Runtime values must stay beside the metadata expression that produced
|
|
364
|
+
// them. Hoisting a thunk can move it outside the lexical scope of local
|
|
365
|
+
// classes and validators, leaving the generated closure unable to resolve
|
|
366
|
+
// its original binding.
|
|
367
|
+
references = append(references, ec.Factory.DeepCloneNode(reference))
|
|
368
|
+
}
|
|
369
|
+
if inlinePureJSON && len(references) == 0 && !strings.Contains(encoding.serialized, `"$tsf`) {
|
|
370
|
+
parsed := ec.Factory.NewCallExpression(
|
|
371
|
+
ec.Factory.NewPropertyAccessExpression(
|
|
372
|
+
ec.Factory.NewIdentifier("JSON"),
|
|
373
|
+
nil,
|
|
374
|
+
ec.Factory.NewIdentifier("parse"),
|
|
375
|
+
shimast.NodeFlagsNone,
|
|
376
|
+
),
|
|
377
|
+
nil,
|
|
378
|
+
nil,
|
|
379
|
+
ec.Factory.NewNodeList([]*shimast.Node{ec.Factory.NewStringLiteral(encoding.serialized, shimast.TokenFlagsNone)}),
|
|
380
|
+
shimast.NodeFlagsNone,
|
|
381
|
+
)
|
|
382
|
+
return ec.Factory.NewElementAccessExpression(
|
|
383
|
+
parsed,
|
|
384
|
+
nil,
|
|
385
|
+
ec.Factory.NewNumericLiteral("1", shimast.TokenFlagsNone),
|
|
386
|
+
shimast.NodeFlagsNone,
|
|
387
|
+
)
|
|
388
|
+
}
|
|
389
|
+
helperName := compactMetadataDecoderName
|
|
390
|
+
if registry {
|
|
391
|
+
helperName = compactMetadataRegistryName
|
|
392
|
+
}
|
|
393
|
+
arguments := []*shimast.Node{
|
|
394
|
+
ec.Factory.NewStringLiteral(encoding.serialized, shimast.TokenFlagsNone),
|
|
395
|
+
ec.Factory.NewArrayLiteralExpression(ec.Factory.NewNodeList(references), false),
|
|
396
|
+
}
|
|
397
|
+
if !registry && metadataTypeResolver != "" {
|
|
398
|
+
arguments = append(arguments, ec.Factory.NewIdentifier(metadataTypeResolver))
|
|
399
|
+
}
|
|
400
|
+
return ec.Factory.NewCallExpression(
|
|
401
|
+
imports.staticMember(compactMetadataRuntimeSpec, helperName),
|
|
402
|
+
nil,
|
|
403
|
+
nil,
|
|
404
|
+
ec.Factory.NewNodeList(arguments),
|
|
405
|
+
shimast.NodeFlagsNone,
|
|
406
|
+
)
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
func writeCompactMetadataRuntimeRecipe(
|
|
410
|
+
encoder *compactMetadataEncoder,
|
|
411
|
+
expression *shimast.Node,
|
|
412
|
+
imports *astImportRegistry,
|
|
413
|
+
metadataTypeResolver string,
|
|
414
|
+
) bool {
|
|
415
|
+
if index, ok := compactMetadataTypeRecipe(expression, metadataTypeResolver); ok {
|
|
416
|
+
encoder.buffer.WriteString(`{"` + compactMetadataTypeKey + `":`)
|
|
417
|
+
encoder.buffer.WriteString(strconv.Itoa(index))
|
|
418
|
+
encoder.buffer.WriteByte('}')
|
|
419
|
+
return true
|
|
420
|
+
}
|
|
421
|
+
if loader, spec, exportName, typeName, ok := compactMetadataAliasRecipe(expression, imports); ok {
|
|
422
|
+
index := encoder.referenceIndex(loader, compactMetadataModuleReferenceKey(loader, imports))
|
|
423
|
+
encoder.buffer.WriteString(`{"` + compactMetadataAliasKey + `":[`)
|
|
424
|
+
encoder.buffer.WriteString(strconv.Itoa(index))
|
|
425
|
+
encoder.buffer.WriteByte(',')
|
|
426
|
+
if spec != "" {
|
|
427
|
+
encoder.writeJSONString(spec)
|
|
428
|
+
encoder.buffer.WriteByte(',')
|
|
429
|
+
}
|
|
430
|
+
encoder.writeJSONString(exportName)
|
|
431
|
+
encoder.buffer.WriteByte(',')
|
|
432
|
+
encoder.writeJSONString(typeName)
|
|
433
|
+
encoder.buffer.WriteString("]}")
|
|
434
|
+
return true
|
|
435
|
+
}
|
|
436
|
+
if spec, exportName, ok := compactMetadataCommonJSImportRecipe(expression); ok {
|
|
437
|
+
loader := imports.ec.Factory.NewIdentifier("require")
|
|
438
|
+
index := encoder.referenceIndex(loader, compactMetadataModuleReferenceKey(loader, imports))
|
|
439
|
+
encoder.buffer.WriteString(`{"` + compactMetadataImportKey + `":[`)
|
|
440
|
+
encoder.buffer.WriteString(strconv.Itoa(index))
|
|
441
|
+
encoder.buffer.WriteByte(',')
|
|
442
|
+
encoder.writeJSONString(spec)
|
|
443
|
+
encoder.buffer.WriteByte(',')
|
|
444
|
+
encoder.writeJSONString(exportName)
|
|
445
|
+
encoder.buffer.WriteString("]}")
|
|
446
|
+
return true
|
|
447
|
+
}
|
|
448
|
+
return false
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
func compactMetadataTypeRecipe(expression *shimast.Node, resolverName string) (int, bool) {
|
|
452
|
+
for expression != nil && expression.Kind == shimast.KindParenthesizedExpression {
|
|
453
|
+
expression = expression.AsParenthesizedExpression().Expression
|
|
454
|
+
}
|
|
455
|
+
if resolverName == "" || expression == nil || expression.Kind != shimast.KindCallExpression {
|
|
456
|
+
return 0, false
|
|
457
|
+
}
|
|
458
|
+
call := expression.AsCallExpression()
|
|
459
|
+
if call.Expression == nil || call.Expression.Kind != shimast.KindIdentifier || call.Expression.Text() != resolverName ||
|
|
460
|
+
call.Arguments == nil || len(call.Arguments.Nodes) != 1 || call.Arguments.Nodes[0].Kind != shimast.KindNumericLiteral {
|
|
461
|
+
return 0, false
|
|
462
|
+
}
|
|
463
|
+
index, err := strconv.Atoi(call.Arguments.Nodes[0].Text())
|
|
464
|
+
return index, err == nil && index >= 0
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
func compactMetadataAliasRecipe(
|
|
468
|
+
expression *shimast.Node,
|
|
469
|
+
imports *astImportRegistry,
|
|
470
|
+
) (*shimast.Node, string, string, string, bool) {
|
|
471
|
+
if !isCompactMetadataAliasResolverCall(expression) {
|
|
472
|
+
return nil, "", "", "", false
|
|
473
|
+
}
|
|
474
|
+
call := expression.AsCallExpression()
|
|
475
|
+
if call.Arguments == nil {
|
|
476
|
+
return nil, "", "", "", false
|
|
477
|
+
}
|
|
478
|
+
arguments := call.Arguments.Nodes
|
|
479
|
+
if len(arguments) == 3 && imports.isOptionalModuleLoader(arguments[0]) && shimast.IsStringLiteral(arguments[1]) && shimast.IsStringLiteral(arguments[2]) {
|
|
480
|
+
return arguments[0], "", arguments[1].Text(), arguments[2].Text(), true
|
|
481
|
+
}
|
|
482
|
+
if len(arguments) == 4 && isCompactMetadataCommonJSRequire(arguments[0], imports) &&
|
|
483
|
+
shimast.IsStringLiteral(arguments[1]) && shimast.IsStringLiteral(arguments[2]) && shimast.IsStringLiteral(arguments[3]) {
|
|
484
|
+
return arguments[0], arguments[1].Text(), arguments[2].Text(), arguments[3].Text(), true
|
|
485
|
+
}
|
|
486
|
+
return nil, "", "", "", false
|
|
487
|
+
}
|
|
488
|
+
|
|
489
|
+
func isCompactMetadataCommonJSRequire(expression *shimast.Node, imports *astImportRegistry) bool {
|
|
490
|
+
return imports.commonJS && expression != nil && expression.Kind == shimast.KindIdentifier && expression.Text() == "require"
|
|
491
|
+
}
|
|
492
|
+
|
|
493
|
+
func compactMetadataModuleReferenceKey(expression *shimast.Node, imports *astImportRegistry) string {
|
|
494
|
+
if isCompactMetadataCommonJSRequire(expression, imports) {
|
|
495
|
+
return "module:require"
|
|
496
|
+
}
|
|
497
|
+
return "loader:" + expression.Text()
|
|
498
|
+
}
|
|
499
|
+
|
|
500
|
+
func compactMetadataCommonJSImportRecipe(expression *shimast.Node) (string, string, bool) {
|
|
501
|
+
if expression == nil || expression.Kind != shimast.KindArrowFunction {
|
|
502
|
+
return "", "", false
|
|
503
|
+
}
|
|
504
|
+
body := expression.AsArrowFunction().Body
|
|
505
|
+
for body != nil && body.Kind == shimast.KindParenthesizedExpression {
|
|
506
|
+
body = body.AsParenthesizedExpression().Expression
|
|
507
|
+
}
|
|
508
|
+
if body == nil || body.Kind != shimast.KindConditionalExpression {
|
|
509
|
+
return "", "", false
|
|
510
|
+
}
|
|
511
|
+
conditional := body.AsConditionalExpression()
|
|
512
|
+
whenFalse := conditional.WhenFalse
|
|
513
|
+
if whenFalse == nil || whenFalse.Kind != shimast.KindIdentifier || whenFalse.Text() != "undefined" {
|
|
514
|
+
return "", "", false
|
|
515
|
+
}
|
|
516
|
+
whenTrue := conditional.WhenTrue
|
|
517
|
+
if whenTrue == nil || whenTrue.Kind != shimast.KindPropertyAccessExpression {
|
|
518
|
+
return "", "", false
|
|
519
|
+
}
|
|
520
|
+
property := whenTrue.AsPropertyAccessExpression()
|
|
521
|
+
if property.Expression == nil || property.Expression.Kind != shimast.KindCallExpression || property.Name() == nil {
|
|
522
|
+
return "", "", false
|
|
523
|
+
}
|
|
524
|
+
call := property.Expression.AsCallExpression()
|
|
525
|
+
if call.Expression == nil || call.Expression.Kind != shimast.KindIdentifier || call.Expression.Text() != "require" ||
|
|
526
|
+
call.Arguments == nil || len(call.Arguments.Nodes) != 1 || !shimast.IsStringLiteral(call.Arguments.Nodes[0]) {
|
|
527
|
+
return "", "", false
|
|
528
|
+
}
|
|
529
|
+
return call.Arguments.Nodes[0].Text(), property.Name().Text(), true
|
|
530
|
+
}
|
|
531
|
+
|
|
532
|
+
func expressionFactoryDeclaration(ec *shimprinter.EmitContext, name string, expression *shimast.Node) *shimast.Node {
|
|
533
|
+
return ec.Factory.NewVariableStatement(
|
|
534
|
+
nil,
|
|
535
|
+
ec.Factory.NewVariableDeclarationList(
|
|
536
|
+
ec.Factory.NewNodeList([]*shimast.Node{ec.Factory.NewVariableDeclaration(
|
|
537
|
+
ec.Factory.NewIdentifier(name),
|
|
538
|
+
nil,
|
|
539
|
+
nil,
|
|
540
|
+
ec.Factory.NewArrowFunction(
|
|
541
|
+
nil,
|
|
542
|
+
nil,
|
|
543
|
+
ec.Factory.NewNodeList(nil),
|
|
544
|
+
nil,
|
|
545
|
+
nil,
|
|
546
|
+
ec.Factory.NewToken(shimast.KindEqualsGreaterThanToken),
|
|
547
|
+
expression,
|
|
548
|
+
),
|
|
549
|
+
)}),
|
|
550
|
+
shimast.NodeFlagsConst,
|
|
551
|
+
),
|
|
552
|
+
)
|
|
553
|
+
}
|