@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,340 @@
|
|
|
1
|
+
package main
|
|
2
|
+
|
|
3
|
+
import (
|
|
4
|
+
"fmt"
|
|
5
|
+
"sort"
|
|
6
|
+
"strings"
|
|
7
|
+
|
|
8
|
+
shimast "github.com/microsoft/typescript-go/shim/ast"
|
|
9
|
+
"github.com/samchon/ttsc/packages/ttsc/driver"
|
|
10
|
+
)
|
|
11
|
+
|
|
12
|
+
type emissionPlans map[string]*fileEmissionPlan
|
|
13
|
+
|
|
14
|
+
type fileEmissionPlan struct {
|
|
15
|
+
calls map[int]callEmissionPlan
|
|
16
|
+
classes map[int]classEmissionPlan
|
|
17
|
+
aliases *expressionTemplate
|
|
18
|
+
metadataTypes []expressionTemplate
|
|
19
|
+
metadataTypeResolver string
|
|
20
|
+
commonJS bool
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
type callEmissionPlan struct {
|
|
24
|
+
name string
|
|
25
|
+
metadataArgIndex int
|
|
26
|
+
metadata expressionTemplate
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
type classEmissionPlan struct {
|
|
30
|
+
name string
|
|
31
|
+
metadata expressionTemplate
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
type metadataTypeInterner struct {
|
|
35
|
+
names map[string]string
|
|
36
|
+
expressions []expressionTemplate
|
|
37
|
+
prefix string
|
|
38
|
+
err error
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
func newMetadataTypeInterner(sourceText string) *metadataTypeInterner {
|
|
42
|
+
prefix := "__tsf_metadata_type"
|
|
43
|
+
for strings.Contains(sourceText, prefix) {
|
|
44
|
+
prefix = "_" + prefix
|
|
45
|
+
}
|
|
46
|
+
return &metadataTypeInterner{names: map[string]string{}, prefix: prefix}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
func (interner *metadataTypeInterner) reference(expr string) string {
|
|
50
|
+
template, err := parseExpressionTemplate(expr)
|
|
51
|
+
if err != nil {
|
|
52
|
+
if interner.err == nil {
|
|
53
|
+
interner.err = err
|
|
54
|
+
}
|
|
55
|
+
return expr
|
|
56
|
+
}
|
|
57
|
+
if !isShareableMetadataType(template.parsed) {
|
|
58
|
+
return expr
|
|
59
|
+
}
|
|
60
|
+
if name := interner.names[expr]; name != "" {
|
|
61
|
+
return fmt.Sprintf("%s(%s)", interner.prefix, name)
|
|
62
|
+
}
|
|
63
|
+
name := fmt.Sprintf("%d", len(interner.expressions))
|
|
64
|
+
interner.names[expr] = name
|
|
65
|
+
interner.expressions = append(interner.expressions, template)
|
|
66
|
+
return fmt.Sprintf("%s(%s)", interner.prefix, name)
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// Shared metadata is emitted at module scope. Only JSON data and primitive
|
|
70
|
+
// values that cannot capture a lexical binding are safe to move there. Class
|
|
71
|
+
// and validator thunks must remain at their original class or call site.
|
|
72
|
+
func isShareableMetadataType(expression *shimast.Node) bool {
|
|
73
|
+
encoding := encodeCompactMetadata(expression)
|
|
74
|
+
for _, reference := range encoding.references {
|
|
75
|
+
if reference == nil {
|
|
76
|
+
return false
|
|
77
|
+
}
|
|
78
|
+
switch reference.Kind {
|
|
79
|
+
case shimast.KindBigIntLiteral:
|
|
80
|
+
continue
|
|
81
|
+
case shimast.KindIdentifier:
|
|
82
|
+
if reference.Text() == "undefined" {
|
|
83
|
+
continue
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
return false
|
|
87
|
+
}
|
|
88
|
+
return true
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
func buildEmissionPlans(reg *registry, program *driver.Program, emitTypeAliases bool, emitMetadataRuntimeImport bool) (emissionPlans, error) {
|
|
92
|
+
plans := emissionPlans{}
|
|
93
|
+
for _, info := range reg.files {
|
|
94
|
+
if info == nil || info.file == nil || info.file.IsDeclarationFile {
|
|
95
|
+
continue
|
|
96
|
+
}
|
|
97
|
+
plan := &fileEmissionPlan{
|
|
98
|
+
calls: map[int]callEmissionPlan{},
|
|
99
|
+
classes: map[int]classEmissionPlan{},
|
|
100
|
+
}
|
|
101
|
+
metadataTypes := newMetadataTypeInterner(info.file.Text())
|
|
102
|
+
if program != nil && program.TSProgram != nil {
|
|
103
|
+
plan.commonJS = program.TSProgram.GetEmitModuleFormatOfFile(info.file).String() == "CommonJS"
|
|
104
|
+
}
|
|
105
|
+
for _, call := range info.calls {
|
|
106
|
+
if call.nodePos < 0 {
|
|
107
|
+
return nil, fmt.Errorf("%s:%d: metadata call %s could not be correlated to a CallExpression", info.file.FileName(), call.pos, call.name)
|
|
108
|
+
}
|
|
109
|
+
expr := metadataTypes.reference(cachedTypeExpr(info, reg, call.typeText, call.typeNode, call.pos, call.metadataText))
|
|
110
|
+
template, err := parseExpressionTemplate(expr)
|
|
111
|
+
if err != nil {
|
|
112
|
+
return nil, fmt.Errorf("%s:%d: metadata call %s: %w", info.file.FileName(), call.pos, call.name, err)
|
|
113
|
+
}
|
|
114
|
+
plan.calls[call.nodePos] = callEmissionPlan{
|
|
115
|
+
name: call.name,
|
|
116
|
+
metadataArgIndex: call.metadataArgIndex,
|
|
117
|
+
metadata: template,
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
classes := append([]*classInfo(nil), info.classes...)
|
|
121
|
+
sort.Slice(classes, func(i, j int) bool { return classes[i].pos < classes[j].pos })
|
|
122
|
+
for _, class := range classes {
|
|
123
|
+
if class.ambient {
|
|
124
|
+
continue
|
|
125
|
+
}
|
|
126
|
+
template, err := parseExpressionTemplate(classMetadata(info, reg, class, metadataTypes.reference))
|
|
127
|
+
if err != nil {
|
|
128
|
+
return nil, fmt.Errorf("%s:%d: class metadata for %s: %w", info.file.FileName(), class.pos, class.name, err)
|
|
129
|
+
}
|
|
130
|
+
plan.classes[class.pos] = classEmissionPlan{name: class.name, metadata: template}
|
|
131
|
+
}
|
|
132
|
+
if metadataTypes.err != nil {
|
|
133
|
+
return nil, fmt.Errorf("%s: shared metadata type: %w", info.file.FileName(), metadataTypes.err)
|
|
134
|
+
}
|
|
135
|
+
plan.metadataTypes = metadataTypes.expressions
|
|
136
|
+
if len(plan.metadataTypes) != 0 {
|
|
137
|
+
plan.metadataTypeResolver = metadataTypes.prefix
|
|
138
|
+
}
|
|
139
|
+
if emitTypeAliases && !hasAliasMetadataSourceDeclaration(info.file) {
|
|
140
|
+
if expr := aliasMetadataExpression(info, reg); expr != "" {
|
|
141
|
+
template, err := parseExpressionTemplate(expr)
|
|
142
|
+
if err != nil {
|
|
143
|
+
return nil, fmt.Errorf("%s: alias metadata: %w", info.file.FileName(), err)
|
|
144
|
+
}
|
|
145
|
+
plan.aliases = &template
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
if !emitMetadataRuntimeImport {
|
|
149
|
+
if requirement := metadataRuntimeRequirement(plan); requirement != "" {
|
|
150
|
+
return nil, fmt.Errorf(
|
|
151
|
+
"%s: %s requires %s, but emitMetadataRuntimeImport is false",
|
|
152
|
+
info.file.FileName(),
|
|
153
|
+
requirement,
|
|
154
|
+
compactMetadataRuntimeSpec,
|
|
155
|
+
)
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
if len(plan.calls) != 0 || len(plan.classes) != 0 || plan.aliases != nil {
|
|
159
|
+
plans[info.file.FileName()] = plan
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
return plans, nil
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
// metadataRuntimeRequirement reports the first generated construct that cannot
|
|
166
|
+
// be emitted without TSF's compact metadata runtime. Alias registries made only
|
|
167
|
+
// of JSON stay self-contained; all other current metadata surfaces use runtime
|
|
168
|
+
// decoding or a shared runtime registry by design.
|
|
169
|
+
func metadataRuntimeRequirement(plan *fileEmissionPlan) string {
|
|
170
|
+
if plan == nil {
|
|
171
|
+
return ""
|
|
172
|
+
}
|
|
173
|
+
if plan.aliases != nil && !compactMetadataIsPureJSON(plan.aliases.parsed) {
|
|
174
|
+
if names := runtimeAliasMetadataNames(plan.aliases.parsed); len(names) != 0 {
|
|
175
|
+
return "reflected alias metadata for " + strings.Join(names, ", ")
|
|
176
|
+
}
|
|
177
|
+
return "reflected alias metadata"
|
|
178
|
+
}
|
|
179
|
+
if len(plan.classes) != 0 {
|
|
180
|
+
return "reflected class metadata"
|
|
181
|
+
}
|
|
182
|
+
if len(plan.calls) != 0 {
|
|
183
|
+
return "reflected call metadata"
|
|
184
|
+
}
|
|
185
|
+
if len(plan.metadataTypes) != 0 {
|
|
186
|
+
return "the reflected metadata registry"
|
|
187
|
+
}
|
|
188
|
+
return ""
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
func runtimeAliasMetadataNames(metadata *shimast.Node) []string {
|
|
192
|
+
for metadata != nil && metadata.Kind == shimast.KindParenthesizedExpression {
|
|
193
|
+
metadata = metadata.AsParenthesizedExpression().Expression
|
|
194
|
+
}
|
|
195
|
+
if metadata == nil || metadata.Kind != shimast.KindObjectLiteralExpression {
|
|
196
|
+
return nil
|
|
197
|
+
}
|
|
198
|
+
names := []string{}
|
|
199
|
+
for _, property := range metadata.AsObjectLiteralExpression().Properties.Nodes {
|
|
200
|
+
name, ok := compactMetadataPropertyName(property)
|
|
201
|
+
if !ok {
|
|
202
|
+
continue
|
|
203
|
+
}
|
|
204
|
+
assignment := property.AsPropertyAssignment()
|
|
205
|
+
if assignment == nil || compactMetadataIsPureJSON(assignment.Initializer) {
|
|
206
|
+
continue
|
|
207
|
+
}
|
|
208
|
+
names = append(names, name)
|
|
209
|
+
}
|
|
210
|
+
return names
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
func compactMetadataIsPureJSON(metadata *shimast.Node) bool {
|
|
214
|
+
encoding := encodeCompactMetadata(metadata)
|
|
215
|
+
return len(encoding.references) == 0 && !strings.Contains(encoding.serialized, `"$tsf`)
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
func aliasMetadataExpression(info *fileInfo, reg *registry) string {
|
|
219
|
+
names := exportedTypeAliasNames(info, reg, map[string]bool{})
|
|
220
|
+
if len(names) == 0 {
|
|
221
|
+
return ""
|
|
222
|
+
}
|
|
223
|
+
entries := []string{}
|
|
224
|
+
for _, name := range names {
|
|
225
|
+
if alias, ok := info.aliases[name]; ok {
|
|
226
|
+
if len(alias.params) == 0 {
|
|
227
|
+
if expr := cachedAliasTypeExpr(info, reg, alias); expr != "" && !metadataExprTooLarge(expr) {
|
|
228
|
+
entries = append(entries, quote(name)+": "+withTypeName(expr, name))
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
continue
|
|
232
|
+
}
|
|
233
|
+
if decl, ok := chooseInterface(info, name, 0); ok {
|
|
234
|
+
if expr := interfaceObjectLiteralExpr(info, reg, name, decl, &typeContext{seen: map[string]bool{}}); !metadataExprTooLarge(expr) {
|
|
235
|
+
entries = append(entries, quote(name)+": "+expr)
|
|
236
|
+
}
|
|
237
|
+
continue
|
|
238
|
+
}
|
|
239
|
+
if alias, owner, _, ok := resolveExportedAlias(info, reg, name, map[string]bool{}); ok {
|
|
240
|
+
if len(alias.params) == 0 {
|
|
241
|
+
if expr := cachedAliasTypeExpr(owner, reg, alias); expr != "" && !metadataExprTooLarge(expr) {
|
|
242
|
+
entries = append(entries, quote(name)+": "+withTypeName(expr, name))
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
continue
|
|
246
|
+
}
|
|
247
|
+
if decl, owner, _, ok := resolveExportedInterfaceDecl(info, reg, name, map[string]bool{}); ok {
|
|
248
|
+
if expr := interfaceObjectLiteralExpr(owner, reg, name, decl, &typeContext{seen: map[string]bool{}}); !metadataExprTooLarge(expr) {
|
|
249
|
+
entries = append(entries, quote(name)+": "+expr)
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
if len(entries) == 0 {
|
|
254
|
+
return ""
|
|
255
|
+
}
|
|
256
|
+
return "{" + strings.Join(entries, ", ") + "}"
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
func cachedAliasTypeExpr(info *fileInfo, reg *registry, alias aliasInfo) string {
|
|
260
|
+
if alias.metadataTooLarge {
|
|
261
|
+
return ""
|
|
262
|
+
}
|
|
263
|
+
if strings.TrimSpace(alias.metadataText) != "" {
|
|
264
|
+
return alias.metadataText
|
|
265
|
+
}
|
|
266
|
+
return internalTypeExprForNode(info, reg, alias.body, alias.typeNode, alias.pos)
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
func metadataExprTooLarge(expr string) bool {
|
|
270
|
+
return len(expr) > 1000000
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
func hasAliasMetadataSourceDeclaration(file *shimast.SourceFile) bool {
|
|
274
|
+
if file == nil || file.Statements == nil {
|
|
275
|
+
return false
|
|
276
|
+
}
|
|
277
|
+
for _, statement := range file.Statements.Nodes {
|
|
278
|
+
if statement == nil || statement.Kind != shimast.KindVariableStatement {
|
|
279
|
+
continue
|
|
280
|
+
}
|
|
281
|
+
if statement.ModifierFlags()&shimast.ModifierFlagsAmbient != 0 {
|
|
282
|
+
continue
|
|
283
|
+
}
|
|
284
|
+
list := statement.AsVariableStatement().DeclarationList
|
|
285
|
+
if list == nil {
|
|
286
|
+
continue
|
|
287
|
+
}
|
|
288
|
+
for _, declaration := range list.AsVariableDeclarationList().Declarations.Nodes {
|
|
289
|
+
if declaration != nil && declaration.Name() != nil && declaration.Name().Kind == shimast.KindIdentifier && declaration.Name().Text() == "__tsfTypeAliases" {
|
|
290
|
+
return true
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
return false
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
func exportedTypeAliasNames(info *fileInfo, reg *registry, seen map[string]bool) []string {
|
|
298
|
+
if seen[info.moduleKey] {
|
|
299
|
+
return nil
|
|
300
|
+
}
|
|
301
|
+
seen[info.moduleKey] = true
|
|
302
|
+
names := map[string]bool{}
|
|
303
|
+
for name, alias := range info.aliases {
|
|
304
|
+
if alias.exported && len(alias.params) == 0 {
|
|
305
|
+
names[name] = true
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
for name, declarations := range info.interfaces {
|
|
309
|
+
for _, declaration := range declarations {
|
|
310
|
+
if declaration.exported {
|
|
311
|
+
names[name] = true
|
|
312
|
+
break
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
for name := range info.reexports {
|
|
317
|
+
if alias, _, _, ok := resolveExportedAlias(info, reg, name, map[string]bool{}); ok && len(alias.params) == 0 {
|
|
318
|
+
names[name] = true
|
|
319
|
+
continue
|
|
320
|
+
}
|
|
321
|
+
if _, _, _, ok := resolveExportedInterfaceDecl(info, reg, name, map[string]bool{}); ok {
|
|
322
|
+
names[name] = true
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
for _, ref := range info.exportStar {
|
|
326
|
+
target := reg.byPath[ref.source]
|
|
327
|
+
if target == nil {
|
|
328
|
+
continue
|
|
329
|
+
}
|
|
330
|
+
for _, name := range exportedTypeAliasNames(target, reg, seen) {
|
|
331
|
+
names[name] = true
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
out := make([]string, 0, len(names))
|
|
335
|
+
for name := range names {
|
|
336
|
+
out = append(out, name)
|
|
337
|
+
}
|
|
338
|
+
sort.Strings(out)
|
|
339
|
+
return out
|
|
340
|
+
}
|