typia 14.0.3 → 14.0.5

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 (23) hide show
  1. package/native/cmd/ttsc-typia/bigint_literal_precision_transform_test.go +135 -0
  2. package/native/cmd/ttsc-typia/recursive_container_helper_index_transform_test.go +206 -0
  3. package/native/cmd/ttsc-typia/reflect_literals_bigint_transform_test.go +148 -0
  4. package/native/cmd/ttsc-typia/reflect_literals_non_literal_rejection_transform_test.go +24 -18
  5. package/native/cmd/ttsc-typia/reflect_schema_bigint_transform_test.go +173 -0
  6. package/native/cmd/ttsc-typia/wrong_type_tag_target_diagnostic_test.go +88 -0
  7. package/native/core/factories/ExpressionFactory.go +11 -1
  8. package/native/core/factories/LiteralFactory.go +3 -0
  9. package/native/core/factories/MetadataTypeTagFactory.go +27 -6
  10. package/native/core/factories/internal/metadata/iterate_metadata_constant.go +3 -0
  11. package/native/core/programmers/RandomProgrammer.go +10 -4
  12. package/native/core/programmers/internal/CheckerProgrammer.go +14 -6
  13. package/native/core/programmers/json/JsonStringifyProgrammer.go +14 -6
  14. package/native/core/programmers/notations/NotationGeneralProgrammer.go +14 -6
  15. package/native/core/programmers/plain/PlainClassifyProgrammer.go +14 -6
  16. package/native/core/programmers/plain/PlainCloneProgrammer.go +14 -6
  17. package/native/core/programmers/plain/PlainPruneProgrammer.go +30 -10
  18. package/native/core/programmers/reflect/ReflectLiteralsProgrammer.go +10 -27
  19. package/native/core/schemas/metadata/MetadataBigint.go +37 -0
  20. package/native/core/schemas/metadata/metadata_bigint_is_comparable_test.go +65 -0
  21. package/native/transform/features/reflect/ReflectSchemaTransformer.go +15 -46
  22. package/package.json +3 -3
  23. package/native/cmd/ttsc-typia/reflect_literals_empty_union_transform_test.go +0 -161
@@ -0,0 +1,173 @@
1
+ package main
2
+
3
+ import (
4
+ "os"
5
+ "os/exec"
6
+ "path/filepath"
7
+ "testing"
8
+ )
9
+
10
+ // TestReflectSchemaBigintTransform verifies the metadata a reflect operation
11
+ // hands back carries a bigint constant as a bigint.
12
+ //
13
+ // `IMetadataSchema.IValue<Atomic.Type>` declares `value: bigint` for a bigint
14
+ // constant, but this transformer lowered the whole metadata tree through
15
+ // `encoding/json` before writing it. JSON has no bigint, so that one member
16
+ // could not survive the trip: it arrived as whatever object its fields happened
17
+ // to spell. The trip was also redundant -- it marshaled structs into maps and
18
+ // lowercased each key's initial, which is what `LiteralFactory` already does
19
+ // when it reflects a struct -- so writing the tree directly both fixes the
20
+ // value and removes the step.
21
+ //
22
+ // `literals` and `schema` reach the emit by different routes, so a case on one
23
+ // says nothing about the other.
24
+ //
25
+ // 1. Reflect a bigint constant union through `schema` and through `schemas`.
26
+ // 2. Execute the emitted CommonJS.
27
+ // 3. Assert each reported value is `typeof "bigint"` and exact, and that the
28
+ // surrounding metadata still reports the constant and its neighbors.
29
+ func TestReflectSchemaBigintTransform(t *testing.T) {
30
+ node, err := exec.LookPath("node")
31
+ if err != nil {
32
+ t.Skip("node executable not found")
33
+ }
34
+ root := ttscTypiaTestRepoRoot(t)
35
+ base := filepath.Join(root, "packages", "typia", "native", ".tmp-ttsc-typia-tests")
36
+ if err := os.MkdirAll(base, 0o755); err != nil {
37
+ t.Fatalf("mkdir temp base: %v", err)
38
+ }
39
+ dir, err := os.MkdirTemp(base, "reflect-schema-bigint-")
40
+ if err != nil {
41
+ t.Fatalf("create temp fixture: %v", err)
42
+ }
43
+ t.Cleanup(func() { _ = os.RemoveAll(dir) })
44
+ src := filepath.Join(dir, "src")
45
+ if err := os.MkdirAll(src, 0o755); err != nil {
46
+ t.Fatalf("mkdir fixture src: %v", err)
47
+ }
48
+ if err := os.WriteFile(filepath.Join(dir, "tsconfig.json"), []byte(atomicIntersectionSchemaTSConfig), 0o644); err != nil {
49
+ t.Fatalf("write tsconfig: %v", err)
50
+ }
51
+ if err := os.WriteFile(filepath.Join(src, "main.ts"), []byte(reflectSchemaBigintSource), 0o644); err != nil {
52
+ t.Fatalf("write source: %v", err)
53
+ }
54
+ ttscTypiaTestTypecheck(t, dir)
55
+
56
+ out, errText, code := ttscTypiaTestCapture(func() int {
57
+ return runTransform([]string{
58
+ "--cwd", dir,
59
+ "--tsconfig", "tsconfig.json",
60
+ "--file", "src/main.ts",
61
+ "--output", "js",
62
+ })
63
+ })
64
+ if code != 0 {
65
+ t.Fatalf("reflect.schema bigint transform failed: code=%d stderr=\n%s", code, errText)
66
+ }
67
+
68
+ runtimeDir := filepath.Join(dir, "runtime")
69
+ if err := os.MkdirAll(runtimeDir, 0o755); err != nil {
70
+ t.Fatalf("mkdir runtime dir: %v", err)
71
+ }
72
+ ttscTypiaTestWriteCommonRuntimeStubs(t, runtimeDir)
73
+ runtimeJS := ttscTypiaTestRewriteCommonJS(t, out)
74
+ if err := os.WriteFile(filepath.Join(runtimeDir, "main.cjs"), []byte(runtimeJS), 0o644); err != nil {
75
+ t.Fatalf("write runtime module: %v", err)
76
+ }
77
+ runner := filepath.Join(runtimeDir, "run.cjs")
78
+ if err := os.WriteFile(runner, []byte(reflectSchemaBigintRunner), 0o644); err != nil {
79
+ t.Fatalf("write runtime runner: %v", err)
80
+ }
81
+ cmd := exec.Command(node, runner)
82
+ cmd.Dir = runtimeDir
83
+ output, err := cmd.CombinedOutput()
84
+ if err != nil {
85
+ t.Fatalf("reflect.schema bigint runtime cases failed: %v\n%s", err, output)
86
+ }
87
+ }
88
+
89
+ const reflectSchemaBigintSource = `import typia, { tags } from "typia";
90
+
91
+ export const unit = typia.reflect.schema<1n | 9007199254740993n>();
92
+ export const collection = typia.reflect.schemas<[2n, "a" | 3]>();
93
+ export const objects = typia.reflect.schema<{ big: 7n; name: string }>();
94
+
95
+ // A tag reaches a constant by matching the child's value against the merged
96
+ // parent's, so the constant value has to compare by value. The number and
97
+ // string constants are the controls that were never at risk.
98
+ export const tagged = typia.reflect.schema<(1n | 2n) & tags.Type<"int64">>();
99
+ export const taggedNumber = typia.reflect.schema<(1 | 2) & tags.Type<"uint32">>();
100
+ `
101
+
102
+ const reflectSchemaBigintRunner = `const mod = require("./main.cjs");
103
+
104
+ const render = (value) =>
105
+ typeof value === "bigint" ? value.toString() + "n" : JSON.stringify(value);
106
+
107
+ const constantsOf = (schema, type) => {
108
+ const constant = (schema.constants ?? []).find((c) => c.type === type);
109
+ return constant === undefined ? [] : constant.values.map((v) => v.value);
110
+ };
111
+
112
+ const check = (label, actual, expected) => {
113
+ if (actual.length !== expected.length) {
114
+ throw new Error(
115
+ label + ": expected " + expected.map(render).join(", ") +
116
+ ", got " + actual.map(render).join(", "),
117
+ );
118
+ }
119
+ actual.forEach((item, index) => {
120
+ if (typeof item !== typeof expected[index] || item !== expected[index]) {
121
+ throw new Error(
122
+ label + "[" + index + "]: expected " + render(expected[index]) +
123
+ " (" + typeof expected[index] + "), got " + render(item) +
124
+ " (" + typeof item + ")",
125
+ );
126
+ }
127
+ });
128
+ };
129
+
130
+ check("schema", constantsOf(mod.unit.schema, "bigint"), [1n, 9007199254740993n]);
131
+ check("schemas[0]", constantsOf(mod.collection.schemas[0], "bigint"), [2n]);
132
+
133
+ // A neighboring constant kind must keep its own representation.
134
+ check("schemas[1] string", constantsOf(mod.collection.schemas[1], "string"), ["a"]);
135
+ check("schemas[1] number", constantsOf(mod.collection.schemas[1], "number"), [3]);
136
+
137
+ // The surrounding tree still reports the object and its members.
138
+ const object = mod.objects.components.objects[0];
139
+ if (object === undefined || object.properties.length !== 2) {
140
+ throw new Error("object metadata was not emitted: " + JSON.stringify(mod.objects, (k, v) => typeof v === "bigint" ? v.toString() : v));
141
+ }
142
+ const big = object.properties.find(
143
+ (p) => constantsOf(p.key, "string")[0] === "big",
144
+ );
145
+ if (big === undefined) {
146
+ throw new Error("the 'big' property is missing from the object metadata");
147
+ }
148
+ check("object property", constantsOf(big.value, "bigint"), [7n]);
149
+
150
+ const tagNames = (schema, type) => {
151
+ const constant = (schema.constants ?? []).find((c) => c.type === type);
152
+ if (constant === undefined) {
153
+ throw new Error("no " + type + " constant was emitted");
154
+ }
155
+ return constant.values.map((v) =>
156
+ (v.tags ?? []).flat().map((t) => t.name).join(","),
157
+ );
158
+ };
159
+
160
+ // Every member keeps the tag the intersection put on it.
161
+ const expectTags = (label, actual, expected) => {
162
+ if (actual.length === 0 || actual.some((names) => names !== expected)) {
163
+ throw new Error(
164
+ label + ": expected every member tagged " + expected +
165
+ ", got " + JSON.stringify(actual),
166
+ );
167
+ }
168
+ };
169
+ expectTags("bigint constant", tagNames(mod.tagged.schema, "bigint"), 'Type<"int64">');
170
+ expectTags("number constant", tagNames(mod.taggedNumber.schema, "number"), 'Type<"uint32">');
171
+
172
+ console.log("ok");
173
+ `
@@ -0,0 +1,88 @@
1
+ package main
2
+
3
+ import (
4
+ "os"
5
+ "path/filepath"
6
+ "strings"
7
+ "testing"
8
+ )
9
+
10
+ // TestWrongTypeTagTargetDiagnostic verifies a rejected tag names its declared
11
+ // target once and leaves a compatible tag untouched.
12
+ func TestWrongTypeTagTargetDiagnostic(t *testing.T) {
13
+ project := wrongTypeTagTargetDiagnosticProject(t)
14
+ _, errText, code := ttscTypiaTestCapture(func() int {
15
+ return runTransform([]string{
16
+ "--cwd", project,
17
+ "--tsconfig", "tsconfig.json",
18
+ "--file", "src/main.ts",
19
+ "--output", "js",
20
+ })
21
+ })
22
+ if code == 0 {
23
+ t.Fatal("wrong-target tag unexpectedly transformed without diagnostics")
24
+ }
25
+ const expected = `the property ["typia.tag"] target must contain array type.`
26
+ if count := strings.Count(errText, expected); count != 1 {
27
+ t.Fatalf("wrong-target diagnostic count mismatch: got %d, want 1\n%s", count, errText)
28
+ }
29
+ if count := strings.Count(errText, "Payload.invalid:"); count != 1 {
30
+ t.Fatalf("diagnostic ownership mismatch: got %d, want 1\n%s", count, errText)
31
+ }
32
+ if strings.Contains(errText, "target must contain boolean type") {
33
+ t.Fatalf("diagnostic named the host type:\n%s", errText)
34
+ }
35
+ if strings.Contains(errText, "Payload.valid:") {
36
+ t.Fatalf("valid array control produced a diagnostic:\n%s", errText)
37
+ }
38
+ }
39
+
40
+ func wrongTypeTagTargetDiagnosticProject(t *testing.T) string {
41
+ t.Helper()
42
+ root := ttscTypiaTestRepoRoot(t)
43
+ base := filepath.Join(root, "packages", "typia", "native", ".tmp-ttsc-typia-tests")
44
+ if err := os.MkdirAll(base, 0o755); err != nil {
45
+ t.Fatalf("mkdir temp base: %v", err)
46
+ }
47
+ project, err := os.MkdirTemp(base, "wrong-tag-target-")
48
+ if err != nil {
49
+ t.Fatalf("create temp fixture: %v", err)
50
+ }
51
+ t.Cleanup(func() { _ = os.RemoveAll(project) })
52
+ src := filepath.Join(project, "src")
53
+ if err := os.MkdirAll(src, 0o755); err != nil {
54
+ t.Fatalf("mkdir fixture src: %v", err)
55
+ }
56
+ if err := os.WriteFile(filepath.Join(project, "tsconfig.json"), []byte(wrongTypeTagTargetDiagnosticTSConfig), 0o644); err != nil {
57
+ t.Fatalf("write tsconfig: %v", err)
58
+ }
59
+ if err := os.WriteFile(filepath.Join(src, "main.ts"), []byte(wrongTypeTagTargetDiagnosticSource), 0o644); err != nil {
60
+ t.Fatalf("write source: %v", err)
61
+ }
62
+ return project
63
+ }
64
+
65
+ const wrongTypeTagTargetDiagnosticTSConfig = `{
66
+ "compilerOptions": {
67
+ "target": "ES2022",
68
+ "module": "commonjs",
69
+ "moduleResolution": "bundler",
70
+ "ignoreDeprecations": "6.0",
71
+ "types": ["*"],
72
+ "esModuleInterop": true,
73
+ "strict": true,
74
+ "skipLibCheck": true
75
+ },
76
+ "include": ["src"]
77
+ }
78
+ `
79
+
80
+ const wrongTypeTagTargetDiagnosticSource = `import typia, { tags } from "typia";
81
+
82
+ interface Payload {
83
+ invalid: boolean & tags.MinItems<1>;
84
+ valid: string[] & tags.MinItems<1>;
85
+ }
86
+
87
+ export const test = (input: unknown) => typia.is<Payload>(input);
88
+ `
@@ -66,6 +66,16 @@ func (expressionFactoryNamespace) Number(value any, emit ...*shimprinter.EmitCon
66
66
  return f.NewNumericLiteral(text, shimast.TokenFlagsNone)
67
67
  }
68
68
 
69
+ // Bigint emits `BigInt("<value>")` for a bigint literal.
70
+ //
71
+ // The argument has to stay a string literal. This used to spell the digits as a
72
+ // bare `number` literal, so `9007199254740993n` reached the emit as
73
+ // `BigInt(9007199254740993)` and JavaScript rounded the literal to
74
+ // 9007199254740992 before `BigInt` ever parsed it -- exactly the rounding
75
+ // `numericRangeFactory_bigint_literal` and `_isTypeInt64Bigint` already spell
76
+ // out and avoid. Every bigint an argument can carry is exact in base 10, and
77
+ // `BigInt` parses the digits of a string directly, so the string form is exact
78
+ // at any magnitude.
69
79
  func (expressionFactoryNamespace) Bigint(value any, emit ...*shimprinter.EmitContext) *shimast.Node {
70
80
  f := nativecontext.EmitFactoryOf(expressionFactory_factory, emit...)
71
81
  return f.NewCallExpression(
@@ -73,7 +83,7 @@ func (expressionFactoryNamespace) Bigint(value any, emit ...*shimprinter.EmitCon
73
83
  nil,
74
84
  nil,
75
85
  f.NewNodeList([]*shimast.Node{
76
- f.NewIdentifier(fmt.Sprint(value)),
86
+ f.NewStringLiteral(fmt.Sprint(value), shimast.TokenFlagsNone),
77
87
  }),
78
88
  shimast.NodeFlagsNone,
79
89
  )
@@ -11,6 +11,7 @@ import (
11
11
  shimast "github.com/microsoft/typescript-go/shim/ast"
12
12
  shimprinter "github.com/microsoft/typescript-go/shim/printer"
13
13
  nativecontext "github.com/samchon/typia/packages/typia/native/core/context"
14
+ schemametadata "github.com/samchon/typia/packages/typia/native/core/schemas/metadata"
14
15
  )
15
16
 
16
17
  type literalFactoryNamespace struct{}
@@ -93,6 +94,8 @@ func (literalFactoryNamespace) Write(input any, emit ...*shimprinter.EmitContext
93
94
  switch value := input.(type) {
94
95
  case bool:
95
96
  return literalFactory_writeBoolean(value, emit...)
97
+ case schemametadata.MetadataBigint:
98
+ return literalFactory_writeBigint(value, emit...)
96
99
  case *big.Int:
97
100
  return literalFactory_writeBigint(value, emit...)
98
101
  case int:
@@ -2,6 +2,7 @@ package factories
2
2
 
3
3
  import (
4
4
  "fmt"
5
+ "reflect"
5
6
  "strings"
6
7
 
7
8
  schemametadata "github.com/samchon/typia/packages/typia/native/core/schemas/metadata"
@@ -162,12 +163,15 @@ func (metadataTypeTagFactoryNamespace) Analyze(props struct {
162
163
  if tag == nil {
163
164
  continue
164
165
  }
165
- target := ""
166
- if metadataTypeTagFactory_includes(tag.Target, props.Type) {
167
- target = props.Type
166
+ if metadataTypeTagFactory_includes(tag.Target, props.Type) == false {
167
+ report(struct {
168
+ Property *string
169
+ Message string
170
+ }{Property: nil, Message: metadataTypeTagFactory_target_message(tag.Target)})
171
+ continue
168
172
  }
169
173
  output = append(output, schemametadata.IMetadataTypeTag{
170
- Target: target,
174
+ Target: props.Type,
171
175
  Name: tag.Name,
172
176
  Kind: tag.Kind,
173
177
  Value: tag.Value,
@@ -195,7 +199,7 @@ func (metadataTypeTagFactoryNamespace) Analyze(props struct {
195
199
  for _, object := range props.Objects {
196
200
  names = append(names, object.Name)
197
201
  }
198
- *props.Errors = append(*props.Errors, MetadataFactory_IError{
202
+ metadataTypeTagFactory_append_error(props.Errors, MetadataFactory_IError{
199
203
  Name: strings.Join(names, " & "),
200
204
  Explore: props.Explore,
201
205
  Messages: messages,
@@ -218,10 +222,14 @@ func (metadataTypeTagFactoryNamespace) Validate(props struct {
218
222
  for _, tag := range props.Tags {
219
223
  if tag.Target != props.Type {
220
224
  if success {
225
+ target := tag.Target
226
+ if target == "" {
227
+ target = props.Type
228
+ }
221
229
  success = props.Report(struct {
222
230
  Property *string
223
231
  Message string
224
- }{Property: nil, Message: "target must contain " + props.Type + " type"})
232
+ }{Property: nil, Message: metadataTypeTagFactory_target_message([]string{target})})
225
233
  }
226
234
  }
227
235
  }
@@ -570,3 +578,16 @@ func metadataTypeTagFactory_essentialFieldsMessage() string {
570
578
  }
571
579
  return strings.Join(values, ", ")
572
580
  }
581
+
582
+ func metadataTypeTagFactory_target_message(targets []string) string {
583
+ return "target must contain " + strings.Join(targets, " or ") + " type"
584
+ }
585
+
586
+ func metadataTypeTagFactory_append_error(errors *[]MetadataFactory_IError, next MetadataFactory_IError) {
587
+ for _, previous := range *errors {
588
+ if reflect.DeepEqual(previous, next) {
589
+ return
590
+ }
591
+ }
592
+ *errors = append(*errors, next)
593
+ }
@@ -50,6 +50,9 @@ func Iterate_metadata_constant(props IMetadataIteratorProps) bool {
50
50
  typ = "number"
51
51
  } else if filter(nativechecker.TypeFlagsBigIntLiteral) {
52
52
  typ = "bigint"
53
+ // Normalize away the checker's unnameable `jsnum.PseudoBigInt`; see
54
+ // MetadataBigint for why the stand-in has to be a comparable value.
55
+ value = schemametadata.MetadataBigint{Text: fmt.Sprint(value)}
53
56
  }
54
57
  constant := iterate_metadata_constant_take(props.Metadata, typ)
55
58
  info := comment()
@@ -345,11 +345,14 @@ func randomProgrammer_write_array_functions(props struct {
345
345
  }) []*shimast.Node {
346
346
  f := nativecontext.EmitFactoryOf(randomProgrammer_factory, props.Context.Emit)
347
347
  output := []*shimast.Node{}
348
- for i, array := range props.Collection.Arrays() {
348
+ for _, array := range props.Collection.Arrays() {
349
349
  if array.Recursive == false {
350
350
  continue
351
351
  }
352
- index := i
352
+ index := 0
353
+ if array.Index != nil {
354
+ index = *array.Index
355
+ }
353
356
  array := array
354
357
  output = append(output, nativefactories.StatementFactory.Constant(nativefactories.StatementFactory_ConstantProps{
355
358
  Name: randomProgrammer_prefix_array(index),
@@ -396,11 +399,14 @@ func randomProgrammer_write_tuple_functions(props struct {
396
399
  f := nativecontext.EmitFactoryOf(randomProgrammer_factory, props.Context.Emit)
397
400
  output := []*shimast.Node{}
398
401
  _, unsatisfiableTuples := nativehelpers.RandomJoiner.UnsatisfiableRecursives(props.Collection.Objects(), props.Collection.Tuples())
399
- for i, tuple := range props.Collection.Tuples() {
402
+ for _, tuple := range props.Collection.Tuples() {
400
403
  if tuple.Recursive == false {
401
404
  continue
402
405
  }
403
- index := i
406
+ index := 0
407
+ if tuple.Index != nil {
408
+ index = *tuple.Index
409
+ }
404
410
  tuple := tuple
405
411
  if unsatisfiableTuples[tuple] {
406
412
  panic(nativecontext.NewTransformerError(nativecontext.TransformerError_IProps{
@@ -181,13 +181,17 @@ func (checkerProgrammerNamespace) Write_array_functions(props CheckerProgrammer_
181
181
  f := nativecontext.EmitFactoryOf(checkerProgrammer_factory, props.Context.Emit)
182
182
  arrays := props.Collection.Arrays()
183
183
  output := []*shimast.Node{}
184
- for i, typ := range arrays {
184
+ for _, typ := range arrays {
185
185
  if typ.Recursive == false {
186
186
  continue
187
187
  }
188
+ index := 0
189
+ if typ.Index != nil {
190
+ index = *typ.Index
191
+ }
188
192
  input := f.NewIdentifier("input")
189
193
  output = append(output, nativefactories.StatementFactory.Constant(nativefactories.StatementFactory_ConstantProps{
190
- Name: fmt.Sprintf("%sa%d", props.Config.Prefix, i),
194
+ Name: fmt.Sprintf("%sa%d", props.Config.Prefix, index),
191
195
  Value: f.NewArrowFunction(
192
196
  nil,
193
197
  nil,
@@ -200,7 +204,7 @@ func (checkerProgrammerNamespace) Write_array_functions(props CheckerProgrammer_
200
204
  nativefactories.TypeFactory.Keyword("any", props.Context.Emit),
201
205
  nil,
202
206
  f.NewToken(shimast.KindEqualsGreaterThanToken),
203
- checkerProgrammer_visit_guard(FeatureProgrammer.VisitKey(props.Config.Prefix, "a", i), checkerProgrammer_decode_array_inline(checkerProgrammer_decodeArrayInlineProps{
207
+ checkerProgrammer_visit_guard(FeatureProgrammer.VisitKey(props.Config.Prefix, "a", index), checkerProgrammer_decode_array_inline(checkerProgrammer_decodeArrayInlineProps{
204
208
  Config: props.Config,
205
209
  Context: props.Context,
206
210
  Functor: props.Functor,
@@ -226,13 +230,17 @@ func (checkerProgrammerNamespace) Write_tuple_functions(props CheckerProgrammer_
226
230
  f := nativecontext.EmitFactoryOf(checkerProgrammer_factory, props.Context.Emit)
227
231
  tuples := props.Collection.Tuples()
228
232
  output := []*shimast.Node{}
229
- for i, tuple := range tuples {
233
+ for _, tuple := range tuples {
230
234
  if tuple.Recursive == false {
231
235
  continue
232
236
  }
237
+ index := 0
238
+ if tuple.Index != nil {
239
+ index = *tuple.Index
240
+ }
233
241
  input := f.NewIdentifier("input")
234
242
  output = append(output, nativefactories.StatementFactory.Constant(nativefactories.StatementFactory_ConstantProps{
235
- Name: fmt.Sprintf("%st%d", props.Config.Prefix, i),
243
+ Name: fmt.Sprintf("%st%d", props.Config.Prefix, index),
236
244
  Value: f.NewArrowFunction(
237
245
  nil,
238
246
  nil,
@@ -245,7 +253,7 @@ func (checkerProgrammerNamespace) Write_tuple_functions(props CheckerProgrammer_
245
253
  nativefactories.TypeFactory.Keyword("any", props.Context.Emit),
246
254
  nil,
247
255
  f.NewToken(shimast.KindEqualsGreaterThanToken),
248
- checkerProgrammer_visit_guard(FeatureProgrammer.VisitKey(props.Config.Prefix, "t", i), checkerProgrammer_decode_tuple_inline(checkerProgrammer_decodeTupleInlineProps{
256
+ checkerProgrammer_visit_guard(FeatureProgrammer.VisitKey(props.Config.Prefix, "t", index), checkerProgrammer_decode_tuple_inline(checkerProgrammer_decodeTupleInlineProps{
249
257
  Config: props.Config,
250
258
  Context: props.Context,
251
259
  Functor: props.Functor,
@@ -100,12 +100,16 @@ func jsonStringifyProgrammer_write_array_functions(props struct {
100
100
  }) []*shimast.Node {
101
101
  f := nativecontext.EmitFactoryOf(jsonStringifyProgrammer_factory, props.Context.Emit)
102
102
  output := []*shimast.Node{}
103
- for i, typ := range props.Collection.Arrays() {
103
+ for _, typ := range props.Collection.Arrays() {
104
104
  if typ.Recursive == false {
105
105
  continue
106
106
  }
107
+ index := 0
108
+ if typ.Index != nil {
109
+ index = *typ.Index
110
+ }
107
111
  output = append(output, nativefactories.StatementFactory.Constant(nativefactories.StatementFactory_ConstantProps{
108
- Name: fmt.Sprintf("%sa%d", props.Config.Prefix, i),
112
+ Name: fmt.Sprintf("%sa%d", props.Config.Prefix, index),
109
113
  Value: f.NewArrowFunction(
110
114
  nil,
111
115
  nil,
@@ -118,7 +122,7 @@ func jsonStringifyProgrammer_write_array_functions(props struct {
118
122
  nil,
119
123
  f.NewToken(shimast.KindEqualsGreaterThanToken),
120
124
  nativeinternal.FeatureProgrammer.VisitGuardSerialize(
121
- nativeinternal.FeatureProgrammer.VisitKey(props.Config.Prefix, "a", i),
125
+ nativeinternal.FeatureProgrammer.VisitKey(props.Config.Prefix, "a", index),
122
126
  jsonStringifyProgrammer_circular_thrower(props.Context, props.Functor),
123
127
  jsonStringifyProgrammer_decode_array_inline(jsonStringifyProgrammer_decodeArrayProps{
124
128
  Context: props.Context,
@@ -153,12 +157,16 @@ func jsonStringifyProgrammer_write_tuple_functions(props struct {
153
157
  }) []*shimast.Node {
154
158
  f := nativecontext.EmitFactoryOf(jsonStringifyProgrammer_factory, props.Context.Emit)
155
159
  output := []*shimast.Node{}
156
- for i, tuple := range props.Collection.Tuples() {
160
+ for _, tuple := range props.Collection.Tuples() {
157
161
  if tuple.Recursive == false {
158
162
  continue
159
163
  }
164
+ index := 0
165
+ if tuple.Index != nil {
166
+ index = *tuple.Index
167
+ }
160
168
  output = append(output, nativefactories.StatementFactory.Constant(nativefactories.StatementFactory_ConstantProps{
161
- Name: fmt.Sprintf("%st%d", props.Config.Prefix, i),
169
+ Name: fmt.Sprintf("%st%d", props.Config.Prefix, index),
162
170
  Value: f.NewArrowFunction(
163
171
  nil,
164
172
  nil,
@@ -171,7 +179,7 @@ func jsonStringifyProgrammer_write_tuple_functions(props struct {
171
179
  nil,
172
180
  f.NewToken(shimast.KindEqualsGreaterThanToken),
173
181
  nativeinternal.FeatureProgrammer.VisitGuardSerialize(
174
- nativeinternal.FeatureProgrammer.VisitKey(props.Config.Prefix, "t", i),
182
+ nativeinternal.FeatureProgrammer.VisitKey(props.Config.Prefix, "t", index),
175
183
  jsonStringifyProgrammer_circular_thrower(props.Context, props.Functor),
176
184
  jsonStringifyProgrammer_decode_tuple_inline(jsonStringifyProgrammer_decodeTupleInlineProps{
177
185
  Context: props.Context,
@@ -131,12 +131,16 @@ func notationGeneralProgrammer_write_array_functions(props struct {
131
131
  }) []*shimast.Node {
132
132
  f := nativecontext.EmitFactoryOf(notationGeneralProgrammer_factory, props.Context.Emit)
133
133
  output := []*shimast.Node{}
134
- for i, typ := range props.Collection.Arrays() {
134
+ for _, typ := range props.Collection.Arrays() {
135
135
  if typ.Recursive == false {
136
136
  continue
137
137
  }
138
+ index := 0
139
+ if typ.Index != nil {
140
+ index = *typ.Index
141
+ }
138
142
  output = append(output, nativefactories.StatementFactory.Constant(nativefactories.StatementFactory_ConstantProps{
139
- Name: fmt.Sprintf("%sa%d", props.Config.Prefix, i),
143
+ Name: fmt.Sprintf("%sa%d", props.Config.Prefix, index),
140
144
  Value: f.NewArrowFunction(
141
145
  nil,
142
146
  nil,
@@ -149,7 +153,7 @@ func notationGeneralProgrammer_write_array_functions(props struct {
149
153
  nil,
150
154
  f.NewToken(shimast.KindEqualsGreaterThanToken),
151
155
  nativeinternal.FeatureProgrammer.VisitGuardRebuild(
152
- nativeinternal.FeatureProgrammer.VisitKey(props.Config.Prefix, "a", i),
156
+ nativeinternal.FeatureProgrammer.VisitKey(props.Config.Prefix, "a", index),
153
157
  true,
154
158
  notationGeneralProgrammer_decode_array_inline(notationGeneralProgrammer_decodeArrayProps{
155
159
  Context: props.Context,
@@ -184,12 +188,16 @@ func notationGeneralProgrammer_write_tuple_functions(props struct {
184
188
  }) []*shimast.Node {
185
189
  f := nativecontext.EmitFactoryOf(notationGeneralProgrammer_factory, props.Context.Emit)
186
190
  output := []*shimast.Node{}
187
- for i, tuple := range props.Collection.Tuples() {
191
+ for _, tuple := range props.Collection.Tuples() {
188
192
  if tuple.Recursive == false {
189
193
  continue
190
194
  }
195
+ index := 0
196
+ if tuple.Index != nil {
197
+ index = *tuple.Index
198
+ }
191
199
  output = append(output, nativefactories.StatementFactory.Constant(nativefactories.StatementFactory_ConstantProps{
192
- Name: fmt.Sprintf("%st%d", props.Config.Prefix, i),
200
+ Name: fmt.Sprintf("%st%d", props.Config.Prefix, index),
193
201
  Value: f.NewArrowFunction(
194
202
  nil,
195
203
  nil,
@@ -202,7 +210,7 @@ func notationGeneralProgrammer_write_tuple_functions(props struct {
202
210
  nil,
203
211
  f.NewToken(shimast.KindEqualsGreaterThanToken),
204
212
  nativeinternal.FeatureProgrammer.VisitGuardRebuild(
205
- nativeinternal.FeatureProgrammer.VisitKey(props.Config.Prefix, "t", i),
213
+ nativeinternal.FeatureProgrammer.VisitKey(props.Config.Prefix, "t", index),
206
214
  true,
207
215
  notationGeneralProgrammer_decode_tuple_inline(notationGeneralProgrammer_decodeTupleInlineProps{
208
216
  Context: props.Context,
@@ -135,12 +135,16 @@ func plainClassifyProgrammer_write_array_functions(props struct {
135
135
  }) []*shimast.Node {
136
136
  f := nativecontext.EmitFactoryOf(plainClassifyProgrammer_factory, props.Context.Emit)
137
137
  output := []*shimast.Node{}
138
- for i, typ := range props.Collection.Arrays() {
138
+ for _, typ := range props.Collection.Arrays() {
139
139
  if typ.Recursive == false {
140
140
  continue
141
141
  }
142
+ index := 0
143
+ if typ.Index != nil {
144
+ index = *typ.Index
145
+ }
142
146
  output = append(output, nativefactories.StatementFactory.Constant(nativefactories.StatementFactory_ConstantProps{
143
- Name: fmt.Sprintf("%sa%d", props.Config.Prefix, i),
147
+ Name: fmt.Sprintf("%sa%d", props.Config.Prefix, index),
144
148
  Value: f.NewArrowFunction(
145
149
  nil,
146
150
  nil,
@@ -153,7 +157,7 @@ func plainClassifyProgrammer_write_array_functions(props struct {
153
157
  nil,
154
158
  f.NewToken(shimast.KindEqualsGreaterThanToken),
155
159
  nativeinternal.FeatureProgrammer.VisitGuardRebuild(
156
- nativeinternal.FeatureProgrammer.VisitKey(props.Config.Prefix, "a", i),
160
+ nativeinternal.FeatureProgrammer.VisitKey(props.Config.Prefix, "a", index),
157
161
  true,
158
162
  plainClassifyProgrammer_decode_array_inline(plainClassifyProgrammer_decodeArrayProps{
159
163
  Context: props.Context,
@@ -187,12 +191,16 @@ func plainClassifyProgrammer_write_tuple_functions(props struct {
187
191
  }) []*shimast.Node {
188
192
  f := nativecontext.EmitFactoryOf(plainClassifyProgrammer_factory, props.Context.Emit)
189
193
  output := []*shimast.Node{}
190
- for i, tuple := range props.Collection.Tuples() {
194
+ for _, tuple := range props.Collection.Tuples() {
191
195
  if tuple.Recursive == false {
192
196
  continue
193
197
  }
198
+ index := 0
199
+ if tuple.Index != nil {
200
+ index = *tuple.Index
201
+ }
194
202
  output = append(output, nativefactories.StatementFactory.Constant(nativefactories.StatementFactory_ConstantProps{
195
- Name: fmt.Sprintf("%st%d", props.Config.Prefix, i),
203
+ Name: fmt.Sprintf("%st%d", props.Config.Prefix, index),
196
204
  Value: f.NewArrowFunction(
197
205
  nil,
198
206
  nil,
@@ -205,7 +213,7 @@ func plainClassifyProgrammer_write_tuple_functions(props struct {
205
213
  nil,
206
214
  f.NewToken(shimast.KindEqualsGreaterThanToken),
207
215
  nativeinternal.FeatureProgrammer.VisitGuardRebuild(
208
- nativeinternal.FeatureProgrammer.VisitKey(props.Config.Prefix, "t", i),
216
+ nativeinternal.FeatureProgrammer.VisitKey(props.Config.Prefix, "t", index),
209
217
  true,
210
218
  plainClassifyProgrammer_decode_tuple_inline(plainClassifyProgrammer_decodeTupleInlineProps{
211
219
  Context: props.Context,