gen-typescript-from-tolk-dev 0.2.4 → 0.3.1

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.
@@ -1,7 +1,13 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.emitLoadOfStruct = emitLoadOfStruct;
4
+ exports.emitLoadOfAlias = emitLoadOfAlias;
5
+ exports.emitLoadOfEnum = emitLoadOfEnum;
3
6
  exports.emitLoadExpr = emitLoadExpr;
4
7
  exports.emitLoadCallback = emitLoadCallback;
8
+ exports.emitStoreOfStruct = emitStoreOfStruct;
9
+ exports.emitStoreOfAlias = emitStoreOfAlias;
10
+ exports.emitStoreOfEnum = emitStoreOfEnum;
5
11
  exports.emitStoreStatement = emitStoreStatement;
6
12
  exports.emitStoreCallback = emitStoreCallback;
7
13
  exports.emitMakeCellFromExpr = emitMakeCellFromExpr;
@@ -12,10 +18,49 @@ const emit_ts_types_1 = require("./emit-ts-types");
12
18
  const formatting_1 = require("./formatting");
13
19
  const unsupported_errors_1 = require("./unsupported-errors");
14
20
  const types_kernel_1 = require("./types-kernel");
21
+ // Emit body of `SomeStruct.fromSlice` method.
22
+ // Also called to load `Wrapper<int32>`, because `fromSlice` is not generated for generics, they are in-place (monomorphization).
23
+ function emitLoadOfStruct(ctx, structRef, instantiationTyIdx) {
24
+ if (structRef.custom_pack_unpack?.pack_to_builder) {
25
+ return `return invokeCustomUnpackFromSlice<${(0, formatting_1.safeJsIdent)(structRef.name)}>('${structRef.name}', s);`;
26
+ }
27
+ let buf = new formatting_1.OutBuf();
28
+ if (structRef.prefix && structRef.prefix.prefix_len === 32) {
29
+ buf.push(`${codegen_ctx_1.RUNTIME.loadAndCheckPrefix32}(s, ${(0, emit_ts_types_1.emitPrefixHex)(structRef.prefix)}, '${structRef.name}');`);
30
+ }
31
+ else if (structRef.prefix) {
32
+ ctx.has_non32Prefixes = true;
33
+ buf.push(`${codegen_ctx_1.RUNTIME.loadAndCheckPrefix}(s, ${(0, emit_ts_types_1.emitPrefixHex)(structRef.prefix)}, ${structRef.prefix.prefix_len}, '${structRef.name}');`);
34
+ }
35
+ buf.push(`return {`);
36
+ buf.push(`$: '${structRef.name}',`);
37
+ for (let f of ctx.symbols.structFieldsOf(instantiationTyIdx)) {
38
+ buf.push(`${(0, formatting_1.safeFieldDecl)(f.name)}: ${emitLoadExpr(ctx, `${(0, formatting_1.safeJsIdent)(structRef.name)}${(0, formatting_1.safeFieldRead)(f.name)}`, f.ty_idx, f.uLabelTyIdx)},`);
39
+ }
40
+ buf.push('}');
41
+ return buf.toString();
42
+ }
43
+ // Emit body of `SomeAlias.fromSlice` method.
44
+ // Also called to load `Either<int32, int64>`, because `fromSlice` is not generated for generics.
45
+ function emitLoadOfAlias(ctx, aliasRef, instantiationTyIdx) {
46
+ if (aliasRef.custom_pack_unpack?.unpack_from_slice) {
47
+ return `return invokeCustomUnpackFromSlice<${(0, formatting_1.safeJsIdent)(aliasRef.name)}>('${aliasRef.name}', s);`;
48
+ }
49
+ let target = ctx.symbols.aliasTargetOf(instantiationTyIdx);
50
+ return `return ${emitLoadExpr(ctx, aliasRef.name, target.ty_idx, target.uLabelTyIdx)};`;
51
+ }
52
+ // Emit body of `SomeEnum.fromSlice` method.
53
+ function emitLoadOfEnum(ctx, enumRef) {
54
+ if (enumRef.custom_pack_unpack?.unpack_from_slice) {
55
+ return `return invokeCustomUnpackFromSlice<${(0, formatting_1.safeJsIdent)(enumRef.name)}>('${enumRef.name}', s);`;
56
+ }
57
+ return `return ${emitLoadExpr(ctx, enumRef.name, enumRef.encoded_as_ty_idx)};`;
58
+ }
15
59
  // Emit a TS "load {ty} from slice `s`" expression.
16
60
  // Parameter `fieldPath` is used for error messages only: e.g. when an input opcode is incorrect,
17
61
  // the fired Error will contain struct/field name.
18
- function emitLoadExpr(ctx, fieldPath, ty) {
62
+ function emitLoadExpr(ctx, fieldPath, tyIdx, uLabelTyIdx) {
63
+ const ty = ctx.symbols.tyByIdx(tyIdx);
19
64
  switch (ty.kind) {
20
65
  case 'int':
21
66
  case 'builder':
@@ -25,7 +70,7 @@ function emitLoadExpr(ctx, fieldPath, ty) {
25
70
  let hint = ty.kind === 'int' ? ' (not int32/uint64/etc.)' :
26
71
  ty.kind === 'builder' || ty.kind === 'slice' ? ' (it can be used for writing only)' :
27
72
  '';
28
- throw new unsupported_errors_1.CantGeneratePackUnpack(`'${fieldPath}' is '${(0, types_kernel_1.renderTy)(ty)}'${hint}`);
73
+ throw new unsupported_errors_1.CantGeneratePackUnpack(`'${fieldPath}' is '${(0, types_kernel_1.renderTy)(ctx.symbols, tyIdx)}'${hint}`);
29
74
  }
30
75
  case 'intN': return `s.loadIntBig(${ty.n})`;
31
76
  case 'uintN': return `s.loadUintBig(${ty.n})`;
@@ -43,46 +88,46 @@ function emitLoadExpr(ctx, fieldPath, ty) {
43
88
  case 'bitsN': return `${codegen_ctx_1.RUNTIME.loadTolkBitsN}(s, ${ty.n})`;
44
89
  case 'nullLiteral': return `null`;
45
90
  case 'void': return `void 0`;
46
- case 'nullable': return `s.loadBoolean() ? ${emitLoadExpr(ctx, fieldPath, ty.inner)} : null`;
47
- case 'cellOf': return `${codegen_ctx_1.RUNTIME.loadCellRef}<${(0, emit_ts_types_1.emitTsType)(ctx, ty.inner)}>(s, ${emitLoadCallback(ctx, fieldPath, ty.inner)})`;
48
- case 'arrayOf': return `${codegen_ctx_1.RUNTIME.loadArrayOf}<${(0, emit_ts_types_1.emitTsType)(ctx, ty.inner)}>(s, ${emitLoadCallback(ctx, fieldPath + '[ith]', ty.inner)})`;
49
- case 'lispListOf': return `${codegen_ctx_1.RUNTIME.loadLispListOf}<${(0, emit_ts_types_1.emitTsType)(ctx, ty.inner)}>(s, ${emitLoadCallback(ctx, fieldPath + '[ith]', ty.inner)})`;
50
- case 'tensor': return `[${ty.items.map((item, i) => emitLoadExpr(ctx, `${fieldPath}[${i}]`, item)).join(', ')}]`;
51
- case 'shapedTuple': return `[${ty.items.map((item, i) => emitLoadExpr(ctx, `${fieldPath}[${i}]`, item)).join(', ')}]`;
52
- case 'mapKV': return `c.Dictionary.load<${(0, emit_ts_types_1.emitDictKVTypeArgs)(ctx, ty.k, ty.v)}>(${emitDictKVSerializers(ctx, fieldPath, ty.k, ty.v)}, s)`;
53
- case 'EnumRef': return `${ty.enum_name}.fromSlice(s)`;
91
+ case 'nullable': return `s.loadBoolean() ? ${emitLoadExpr(ctx, fieldPath, ty.inner_ty_idx)} : null`;
92
+ case 'cellOf': return `${codegen_ctx_1.RUNTIME.loadCellRef}<${(0, emit_ts_types_1.emitTsType)(ctx, ty.inner_ty_idx)}>(s, ${emitLoadCallback(ctx, fieldPath, ty.inner_ty_idx)})`;
93
+ case 'arrayOf': return `${codegen_ctx_1.RUNTIME.loadArrayOf}<${(0, emit_ts_types_1.emitTsType)(ctx, ty.inner_ty_idx)}>(s, ${emitLoadCallback(ctx, fieldPath + '[ith]', ty.inner_ty_idx)})`;
94
+ case 'lispListOf': return `${codegen_ctx_1.RUNTIME.loadLispListOf}<${(0, emit_ts_types_1.emitTsType)(ctx, ty.inner_ty_idx)}>(s, ${emitLoadCallback(ctx, fieldPath + '[ith]', ty.inner_ty_idx)})`;
95
+ case 'tensor': return `[${ty.items_ty_idx.map((ty_idx, i) => emitLoadExpr(ctx, `${fieldPath}[${i}]`, ty_idx)).join(', ')}]`;
96
+ case 'shapedTuple': return `[${ty.items_ty_idx.map((ty_idx, i) => emitLoadExpr(ctx, `${fieldPath}[${i}]`, ty_idx)).join(', ')}]`;
97
+ case 'mapKV': return `c.Dictionary.load<${(0, emit_ts_types_1.emitDictKVTypeArgs)(ctx, ty.key_ty_idx, ty.value_ty_idx)}>(${emitDictKVSerializers(ctx, fieldPath, ty.key_ty_idx, ty.value_ty_idx)}, s)`;
98
+ case 'EnumRef': return `${(0, formatting_1.safeJsIdent)(ty.enum_name)}.fromSlice(s)`;
54
99
  case 'StructRef': {
55
- if (ty.type_args) {
56
- const cb = ty.type_args.map((ta) => emitLoadCallback(ctx, fieldPath, ta)).join(', ');
57
- return `${(0, formatting_1.safeJsIdent)(ty.struct_name)}.fromSlice<${ty.type_args.map((ta) => (0, emit_ts_types_1.emitTsType)(ctx, ta)).join(', ')}>(s, ${cb})`;
100
+ if (ty.type_args_ty_idx) {
101
+ let innerLoad = emitLoadOfStruct(ctx, ctx.symbols.getStruct(ty.struct_name), tyIdx);
102
+ return `(() => {${formatting_1.OutBuf.onNewLine(innerLoad)}})()`;
58
103
  }
59
104
  return `${(0, formatting_1.safeJsIdent)(ty.struct_name)}.fromSlice(s)`;
60
105
  }
61
106
  case 'AliasRef': {
62
- if (ty.type_args) {
63
- const cb = ty.type_args.map((ta) => emitLoadCallback(ctx, fieldPath, ta)).join(', ');
64
- return `${(0, formatting_1.safeJsIdent)(ty.alias_name)}.fromSlice<${ty.type_args.map((ta) => (0, emit_ts_types_1.emitTsType)(ctx, ta)).join(', ')}>(s, ${cb})`;
107
+ if (ty.type_args_ty_idx) {
108
+ let innerLoad = emitLoadOfAlias(ctx, ctx.symbols.getAlias(ty.alias_name), tyIdx);
109
+ return innerLoad.substring(7, innerLoad.length - 1); // `return {expr};`
65
110
  }
66
111
  return `${(0, formatting_1.safeJsIdent)(ty.alias_name)}.fromSlice(s)`;
67
112
  }
68
- case 'genericT': return `loadFn_${ty.name_t}(s)`;
113
+ case 'genericT': throw new Error(`unexpected genericT=${ty.name_t} at ${fieldPath}`);
69
114
  case 'union': {
70
- const variants = (0, types_kernel_1.createLabelsForUnion)(ctx.symbols, ty.variants);
71
- const isEither01 = variants.length === 2 && variants[0].prefix_str === '0b0' && variants[1].prefix_str === '0b1';
115
+ const variants = (0, types_kernel_1.createLabelsForUnion)(ctx.symbols, ty.variants, uLabelTyIdx);
116
+ const isEither01 = variants.length === 2 && variants[0].prefix_num === 0 && variants[1].prefix_num === 1;
72
117
  if (isEither01) {
73
- const l = (0, emit_ts_types_1.emitUnionLabelAndValue)(variants[0], emitLoadExpr(ctx, fieldPath, variants[0].variant_ty));
74
- const r = (0, emit_ts_types_1.emitUnionLabelAndValue)(variants[1], emitLoadExpr(ctx, fieldPath, variants[1].variant_ty));
118
+ const l = (0, emit_ts_types_1.emitUnionLabelAndValue)(variants[0], emitLoadExpr(ctx, fieldPath, variants[0].variant_ty_idx));
119
+ const r = (0, emit_ts_types_1.emitUnionLabelAndValue)(variants[1], emitLoadExpr(ctx, fieldPath, variants[1].variant_ty_idx));
75
120
  return `s.loadBoolean() ? ${r} : ${l}`;
76
121
  }
77
122
  let buf = new formatting_1.OutBuf();
78
123
  for (let v of variants) {
79
124
  const checkFn = v.is_prefix_implicit ? codegen_ctx_1.RUNTIME.lookupPrefixAndEat : codegen_ctx_1.RUNTIME.lookupPrefix;
80
- const body = (0, emit_ts_types_1.emitUnionLabelAndValue)(v, emitLoadExpr(ctx, fieldPath, v.variant_ty));
81
- buf.push(`${checkFn}(s, ${v.prefix_str}, ${v.prefix_len}) ? ${body} :`);
125
+ const body = (0, emit_ts_types_1.emitUnionLabelAndValue)(v, emitLoadExpr(ctx, fieldPath, v.variant_ty_idx));
126
+ buf.push(`${checkFn}(s, ${(0, emit_ts_types_1.emitPrefixHex)(v)}, ${v.prefix_len}) ? ${body} :`);
82
127
  if (v.is_prefix_implicit) {
83
128
  ctx.has_implicitUnionPrefix = true;
84
129
  }
85
- if (v.prefix_str === variants[0].prefix_str) {
130
+ if (v.prefix_num === variants[0].prefix_num && v.prefix_len === variants[0].prefix_len) {
86
131
  buf.indent();
87
132
  }
88
133
  }
@@ -96,31 +141,62 @@ function emitLoadExpr(ctx, fieldPath, ty) {
96
141
  // e.g., `loadCellRef<T>(s, {callbackForT})`.
97
142
  // We could just emit `(s) => loadExprForT(s)`, but to produce less boilerplate, shorten common cases:
98
143
  // not `(s) => SomeStruct.fromSlice(s)` but `SomeStruct.fromSlice` as a valid callback.
99
- function emitLoadCallback(ctx, fieldPath, ty) {
144
+ function emitLoadCallback(ctx, fieldPath, tyIdx) {
145
+ const ty = ctx.symbols.tyByIdx(tyIdx);
100
146
  if (ty.kind === 'addressAny')
101
147
  return codegen_ctx_1.RUNTIME.loadTolkAddressAny;
102
148
  if (ty.kind === 'remaining')
103
149
  return codegen_ctx_1.RUNTIME.loadTolkRemaining;
104
150
  if (ty.kind === 'EnumRef')
105
- return `${ty.enum_name}.fromSlice`;
106
- if (ty.kind === 'genericT')
107
- return `loadFn_${ty.name_t}`;
108
- if (ty.kind === 'StructRef' && !ty.type_args)
151
+ return `${(0, formatting_1.safeJsIdent)(ty.enum_name)}.fromSlice`;
152
+ if (ty.kind === 'StructRef' && !ty.type_args_ty_idx)
109
153
  return `${(0, formatting_1.safeJsIdent)(ty.struct_name)}.fromSlice`;
110
- if (ty.kind === 'AliasRef' && !ty.type_args)
154
+ if (ty.kind === 'AliasRef' && !ty.type_args_ty_idx)
111
155
  return `${(0, formatting_1.safeJsIdent)(ty.alias_name)}.fromSlice`;
112
- return formatting_1.OutBuf.onNewLine(`(s) => ${emitLoadExpr(ctx, fieldPath, ty)}`);
156
+ return formatting_1.OutBuf.onNewLine(`(s) => ${emitLoadExpr(ctx, fieldPath, tyIdx)}`);
157
+ }
158
+ // Emit body of `SomeStruct.store` method.
159
+ // Also called to store `Wrapper<int32>`, because `store` is not generated for generics, they are in-place (monomorphization).
160
+ function emitStoreOfStruct(ctx, tsExpr, structRef, instantiationTyIdx) {
161
+ if (structRef.custom_pack_unpack?.pack_to_builder) {
162
+ return `invokeCustomPackToBuilder<${(0, formatting_1.safeJsIdent)(structRef.name)}>('${structRef.name}', self, b);`;
163
+ }
164
+ let buf = new formatting_1.OutBuf();
165
+ if (structRef.prefix) {
166
+ buf.push(`b.storeUint(${(0, emit_ts_types_1.emitPrefixHex)(structRef.prefix)}, ${structRef.prefix.prefix_len});`);
167
+ }
168
+ for (let f of ctx.symbols.structFieldsOf(instantiationTyIdx)) {
169
+ buf.push(emitStoreStatement(ctx, `${tsExpr}${(0, formatting_1.safeFieldRead)(f.name)}`, f.ty_idx, f.uLabelTyIdx));
170
+ }
171
+ return buf.toString();
172
+ }
173
+ // Emit body of `SomeAlias.store` method.
174
+ // Also called to store `Either<int32, int64>`, because `store` is not generated for generics.
175
+ function emitStoreOfAlias(ctx, tsExpr, aliasRef, instantiationTyIdx) {
176
+ if (aliasRef.custom_pack_unpack?.pack_to_builder) {
177
+ return `invokeCustomPackToBuilder<${(0, formatting_1.safeJsIdent)(aliasRef.name)}>('${aliasRef.name}', self, b);`;
178
+ }
179
+ let target = ctx.symbols.aliasTargetOf(instantiationTyIdx);
180
+ return emitStoreStatement(ctx, tsExpr, target.ty_idx, target.uLabelTyIdx);
181
+ }
182
+ // Emit body of `SomeEnum.store` method.
183
+ function emitStoreOfEnum(ctx, tsExpr, enumRef) {
184
+ if (enumRef.custom_pack_unpack?.pack_to_builder) {
185
+ return `return invokeCustomPackToBuilder<${(0, formatting_1.safeJsIdent)(enumRef.name)}>('${enumRef.name}', self, b);`;
186
+ }
187
+ return emitStoreStatement(ctx, tsExpr, enumRef.encoded_as_ty_idx);
113
188
  }
114
189
  // Emit a TS "store {expr of type ty} into builder `b`" statement.
115
190
  // Parameter `tsExpr` is a valid expression: "self.field", "v" (inside a callback), and other.
116
- function emitStoreStatement(ctx, tsExpr, ty) {
191
+ function emitStoreStatement(ctx, tsExpr, tyIdx, uLabelTyIdx) {
192
+ const ty = ctx.symbols.tyByIdx(tyIdx);
117
193
  switch (ty.kind) {
118
194
  case 'int':
119
195
  case 'unknown':
120
196
  case 'nullLiteral':
121
197
  case 'callable': {
122
198
  let hint = ty.kind === 'int' ? ' (not int32/uint64/etc.)' : '';
123
- throw new unsupported_errors_1.CantGeneratePackUnpack(`'${tsExpr}' is '${(0, types_kernel_1.renderTy)(ty)}'${hint}`);
199
+ throw new unsupported_errors_1.CantGeneratePackUnpack(`'${tsExpr}' is '${(0, types_kernel_1.renderTy)(ctx.symbols, tyIdx)}'${hint}`);
124
200
  }
125
201
  case 'intN': return `b.storeInt(${tsExpr}, ${ty.n});`;
126
202
  case 'uintN': return `b.storeUint(${tsExpr}, ${ty.n});`;
@@ -139,49 +215,48 @@ function emitStoreStatement(ctx, tsExpr, ty) {
139
215
  case 'addressAny': return `${codegen_ctx_1.RUNTIME.storeTolkAddressAny}(${tsExpr}, b);`;
140
216
  case 'bitsN': return `${codegen_ctx_1.RUNTIME.storeTolkBitsN}(${tsExpr}, ${ty.n}, b);`;
141
217
  case 'void': return ``;
142
- case 'nullable': return `${codegen_ctx_1.RUNTIME.storeTolkNullable}<${(0, emit_ts_types_1.emitTsType)(ctx, ty.inner)}>(${tsExpr}, b, ${emitStoreCallback(ctx, ty.inner)});`;
143
- case 'cellOf': return `${codegen_ctx_1.RUNTIME.storeCellRef}<${(0, emit_ts_types_1.emitTsType)(ctx, ty.inner)}>(${tsExpr}, b, ${emitStoreCallback(ctx, ty.inner)});`;
144
- case 'arrayOf': return `${codegen_ctx_1.RUNTIME.storeArrayOf}<${(0, emit_ts_types_1.emitTsType)(ctx, ty.inner)}>(${tsExpr}, b, ${emitStoreCallback(ctx, ty.inner)});`;
145
- case 'lispListOf': return `${codegen_ctx_1.RUNTIME.storeLispListOf}<${(0, emit_ts_types_1.emitTsType)(ctx, ty.inner)}>(${tsExpr}, b, ${emitStoreCallback(ctx, ty.inner)});`;
146
- case 'tensor': return ty.items.length ? ty.items.map((_, i) => emitStoreStatement(ctx, `${tsExpr}[${i}]`, ty.items[i])).join('\n') : `{}`;
147
- case 'shapedTuple': return ty.items.length ? ty.items.map((_, i) => emitStoreStatement(ctx, `${tsExpr}[${i}]`, ty.items[i])).join('\n') : `{}`;
148
- case 'mapKV': return `b.storeDict<${(0, emit_ts_types_1.emitDictKVTypeArgs)(ctx, ty.k, ty.v)}>(${tsExpr}, ${emitDictKVSerializers(ctx, tsExpr, ty.k, ty.v)});`;
149
- case 'EnumRef': return `${ty.enum_name}.store(${tsExpr}, b);`;
218
+ case 'nullable': return `${codegen_ctx_1.RUNTIME.storeTolkNullable}<${(0, emit_ts_types_1.emitTsType)(ctx, ty.inner_ty_idx)}>(${tsExpr}, b, ${emitStoreCallback(ctx, ty.inner_ty_idx)});`;
219
+ case 'cellOf': return `${codegen_ctx_1.RUNTIME.storeCellRef}<${(0, emit_ts_types_1.emitTsType)(ctx, ty.inner_ty_idx)}>(${tsExpr}, b, ${emitStoreCallback(ctx, ty.inner_ty_idx)});`;
220
+ case 'arrayOf': return `${codegen_ctx_1.RUNTIME.storeArrayOf}<${(0, emit_ts_types_1.emitTsType)(ctx, ty.inner_ty_idx)}>(${tsExpr}, b, ${emitStoreCallback(ctx, ty.inner_ty_idx)});`;
221
+ case 'lispListOf': return `${codegen_ctx_1.RUNTIME.storeLispListOf}<${(0, emit_ts_types_1.emitTsType)(ctx, ty.inner_ty_idx)}>(${tsExpr}, b, ${emitStoreCallback(ctx, ty.inner_ty_idx)});`;
222
+ case 'tensor': return ty.items_ty_idx.length ? ty.items_ty_idx.map((ty_idx, i) => emitStoreStatement(ctx, `${tsExpr}[${i}]`, ty_idx)).join('\n') : `{}`;
223
+ case 'shapedTuple': return ty.items_ty_idx.length ? ty.items_ty_idx.map((ty_idx, i) => emitStoreStatement(ctx, `${tsExpr}[${i}]`, ty_idx)).join('\n') : `{}`;
224
+ case 'mapKV': return `b.storeDict<${(0, emit_ts_types_1.emitDictKVTypeArgs)(ctx, ty.key_ty_idx, ty.value_ty_idx)}>(${tsExpr}, ${emitDictKVSerializers(ctx, tsExpr, ty.key_ty_idx, ty.value_ty_idx)});`;
225
+ case 'EnumRef': return `${(0, formatting_1.safeJsIdent)(ty.enum_name)}.store(${tsExpr}, b);`;
150
226
  case 'StructRef': {
151
- if (ty.type_args) {
152
- const cb = ty.type_args.map(ta => emitStoreCallback(ctx, ta)).join(', ');
153
- return `${(0, formatting_1.safeJsIdent)(ty.struct_name)}.store<${ty.type_args.map(ta => (0, emit_ts_types_1.emitTsType)(ctx, ta)).join(', ')}>(${tsExpr}, b, ${cb});`;
227
+ if (ty.type_args_ty_idx) {
228
+ return emitStoreOfStruct(ctx, tsExpr, ctx.symbols.getStruct(ty.struct_name), tyIdx);
154
229
  }
155
230
  return `${(0, formatting_1.safeJsIdent)(ty.struct_name)}.store(${tsExpr}, b);`;
156
231
  }
157
232
  case 'AliasRef': {
158
- if (ty.type_args) {
159
- const cb = ty.type_args.map(ta => emitStoreCallback(ctx, ta)).join(', ');
160
- return `${(0, formatting_1.safeJsIdent)(ty.alias_name)}.store<${ty.type_args.map(ta => (0, emit_ts_types_1.emitTsType)(ctx, ta)).join(', ')}>(${tsExpr}, b, ${cb});`;
233
+ if (ty.type_args_ty_idx) {
234
+ return emitStoreOfAlias(ctx, tsExpr, ctx.symbols.getAlias(ty.alias_name), tyIdx);
161
235
  }
162
236
  return `${(0, formatting_1.safeJsIdent)(ty.alias_name)}.store(${tsExpr}, b);`;
163
237
  }
164
- case 'genericT': return `storeFn_${ty.name_t}(${tsExpr}, b);`;
238
+ case 'genericT': throw new Error(`unexpected genericT=${ty.name_t} at ${tsExpr}`);
165
239
  case 'union': {
166
240
  const buf = new formatting_1.OutBuf();
167
- const variants = (0, types_kernel_1.createLabelsForUnion)(ctx.symbols, ty.variants);
168
- const hasNull = variants.find(v => v.variant_ty.kind === 'nullLiteral');
241
+ const variants = (0, types_kernel_1.createLabelsForUnion)(ctx.symbols, ty.variants, uLabelTyIdx);
242
+ const hasNull = variants.find(v => ctx.symbols.tyByIdx(v.variant_ty_idx).kind === 'nullLiteral');
169
243
  if (hasNull) {
170
244
  buf.push(`if (${tsExpr} === null) {`);
171
- buf.push(`b.storeUint(${hasNull.prefix_str}, ${hasNull.prefix_len});`);
245
+ buf.push(`b.storeUint(${(0, emit_ts_types_1.emitPrefixHex)(hasNull)}, ${hasNull.prefix_len});`);
172
246
  buf.push(`} else switch (${tsExpr}.$) {`);
173
247
  }
174
248
  else {
175
249
  buf.push(`switch (${tsExpr}.$) {`);
176
250
  }
177
- for (let v of variants) {
178
- if (v.variant_ty.kind === 'nullLiteral')
251
+ for (let i = 0; i < variants.length; ++i) {
252
+ const v = variants[i];
253
+ if (ctx.symbols.tyByIdx(v.variant_ty_idx).kind === 'nullLiteral')
179
254
  continue;
180
255
  buf.push(`case '${v.labelStr}':`).indent();
181
256
  if (v.is_prefix_implicit) {
182
- buf.push(`b.storeUint(${v.prefix_str}, ${v.prefix_len});`);
257
+ buf.push(`b.storeUint(${(0, emit_ts_types_1.emitPrefixHex)(v)}, ${v.prefix_len});`);
183
258
  }
184
- buf.push(emitStoreStatement(ctx, v.hasValueField ? `${tsExpr}.value` : tsExpr, v.variant_ty));
259
+ buf.push(emitStoreStatement(ctx, v.hasValueField ? `${tsExpr}.value` : tsExpr, v.variant_ty_idx));
185
260
  buf.push('break;').outdent();
186
261
  }
187
262
  buf.push('}');
@@ -192,22 +267,21 @@ function emitStoreStatement(ctx, tsExpr, ty) {
192
267
  // Emit a TS "store {expr of type ty} into builder `b`" callback (not expression).
193
268
  // Callbacks are passed for generics (user-defined generic types and built-ins),
194
269
  // e.g., `storeTolkNullable<T>(s, {callbackForT})`.
195
- function emitStoreCallback(ctx, ty) {
270
+ function emitStoreCallback(ctx, tyIdx) {
271
+ const ty = ctx.symbols.tyByIdx(tyIdx);
196
272
  if (ty.kind === 'addressAny')
197
273
  return codegen_ctx_1.RUNTIME.storeTolkAddressAny;
198
274
  if (ty.kind === 'remaining')
199
275
  return codegen_ctx_1.RUNTIME.storeTolkRemaining;
200
276
  if (ty.kind === 'EnumRef')
201
- return `${ty.enum_name}.store`;
202
- if (ty.kind === 'genericT')
203
- return `storeFn_${ty.name_t}`;
204
- if (ty.kind === 'StructRef' && !ty.type_args)
277
+ return `${(0, formatting_1.safeJsIdent)(ty.enum_name)}.store`;
278
+ if (ty.kind === 'StructRef' && !ty.type_args_ty_idx)
205
279
  return `${(0, formatting_1.safeJsIdent)(ty.struct_name)}.store`;
206
- if (ty.kind === 'AliasRef' && !ty.type_args)
280
+ if (ty.kind === 'AliasRef' && !ty.type_args_ty_idx)
207
281
  return `${(0, formatting_1.safeJsIdent)(ty.alias_name)}.store`;
208
282
  // for simple statements, drop trailing `;` and use it as an expression:
209
283
  // not `(v,b) => { b.storeInt(v, 8); }` but `(v,b) => b.storeInt(v, 8)`
210
- let stmt = emitStoreStatement(ctx, 'v', ty);
284
+ let stmt = emitStoreStatement(ctx, 'v', tyIdx);
211
285
  if (stmt.indexOf(';') !== stmt.length - 1 || stmt.includes('\n') || stmt.includes('{')) {
212
286
  stmt = '{ ' + stmt + ' }';
213
287
  }
@@ -219,43 +293,43 @@ function emitStoreCallback(ctx, ty) {
219
293
  // Emit a TS "make a cell from {expr}" expression.
220
294
  // It's essentially beginCell + call storing callback + endCell.
221
295
  // Parameter `tsExpr` is a valid expression: "self.field", "v" (inside a callback), and other.
222
- function emitMakeCellFromExpr(ctx, tsExpr, ty, disableShortHand = false) {
296
+ function emitMakeCellFromExpr(ctx, tsExpr, tyIdx, disableShortHand = false) {
223
297
  if (disableShortHand) {
224
- return `${codegen_ctx_1.RUNTIME.makeCellFrom}<${(0, emit_ts_types_1.emitTsType)(ctx, ty)}>(${tsExpr}, ${emitStoreCallback(ctx, ty)})`;
298
+ return `${codegen_ctx_1.RUNTIME.makeCellFrom}<${(0, emit_ts_types_1.emitTsType)(ctx, tyIdx)}>(${tsExpr}, ${emitStoreCallback(ctx, tyIdx)})`;
225
299
  }
300
+ const ty = ctx.symbols.tyByIdx(tyIdx);
226
301
  switch (ty.kind) {
227
302
  case 'EnumRef': {
228
303
  return `${(0, formatting_1.safeJsIdent)(ty.enum_name)}.toCell(${tsExpr})`;
229
304
  }
230
305
  case 'StructRef': {
231
- if (ty.type_args) {
232
- const cb = ty.type_args.map(ta => emitStoreCallback(ctx, ta)).join(', ');
233
- return `${(0, formatting_1.safeJsIdent)(ty.struct_name)}.toCell<${ty.type_args.map(ta => (0, emit_ts_types_1.emitTsType)(ctx, ta)).join(', ')}>(${tsExpr}, ${cb})`;
306
+ if (ty.type_args_ty_idx) {
307
+ return emitMakeCellFromExpr(ctx, tsExpr, tyIdx, true);
234
308
  }
235
309
  return `${(0, formatting_1.safeJsIdent)(ty.struct_name)}.toCell(${tsExpr})`;
236
310
  }
237
311
  case 'AliasRef': {
238
- if (ty.type_args) {
239
- const cb = ty.type_args.map(ta => emitStoreCallback(ctx, ta)).join(', ');
240
- return `${(0, formatting_1.safeJsIdent)(ty.alias_name)}.toCell<${ty.type_args.map(ta => (0, emit_ts_types_1.emitTsType)(ctx, ta)).join(', ')}>(${tsExpr}, ${cb})`;
312
+ if (ty.type_args_ty_idx) {
313
+ return emitMakeCellFromExpr(ctx, tsExpr, tyIdx, true);
241
314
  }
242
315
  return `${(0, formatting_1.safeJsIdent)(ty.alias_name)}.toCell(${tsExpr})`;
243
316
  }
244
317
  default:
245
- return emitMakeCellFromExpr(ctx, tsExpr, ty, true);
318
+ return emitMakeCellFromExpr(ctx, tsExpr, tyIdx, true);
246
319
  }
247
320
  }
248
321
  // Emit a TS "StructName.create({bodyArg})" expression.
249
322
  // For instance, sendXXX and fromStorage methods accept struct fields and call create()
250
323
  // in order to enrich passed fields with `$` tag and default values.
251
- function emitCallToCreateMethodExpr(ctx, bodyArg, ty) {
324
+ function emitCallToCreateMethodExpr(ctx, bodyArg, tyIdx) {
325
+ const ty = ctx.symbols.tyByIdx(tyIdx);
252
326
  if (ty.kind === 'StructRef') {
253
- let structRef = ctx.symbols.getStruct(ty.struct_name);
254
- if (structRef.fields.length === 0) {
327
+ let fields = ctx.symbols.structFieldsOf(tyIdx);
328
+ if (fields.length === 0) {
255
329
  bodyArg = ''; // create() is without arguments, body is an empty object
256
330
  }
257
- if (ty.type_args) {
258
- return `${(0, formatting_1.safeJsIdent)(ty.struct_name)}.create<${ty.type_args.map(ta => (0, emit_ts_types_1.emitTsType)(ctx, ta)).join(', ')}>(${bodyArg})`;
331
+ if (ty.type_args_ty_idx) {
332
+ return `${(0, formatting_1.safeJsIdent)(ty.struct_name)}.create<${ty.type_args_ty_idx.map(ty_idx => (0, emit_ts_types_1.emitTsType)(ctx, ty_idx)).join(', ')}>(${bodyArg})`;
259
333
  }
260
334
  return `${(0, formatting_1.safeJsIdent)(ty.struct_name)}.create(${bodyArg})`;
261
335
  }
@@ -264,19 +338,21 @@ function emitCallToCreateMethodExpr(ctx, bodyArg, ty) {
264
338
  // Emit a key (de)serializer for c.Dictionary<K, V>.
265
339
  // Only a strict subset of KeyT is allowed by the @ton/core library.
266
340
  // For others, we can not generate wrappers at all (not only to/from cell, but even declarations).
267
- function emitDictKeySerializer(ctx, fieldPath, tyK) {
341
+ function emitDictKeySerializer(ctx, fieldPath, tyKIdx) {
342
+ const tyK = ctx.symbols.tyByIdx(tyKIdx);
268
343
  if (tyK.kind === 'intN')
269
344
  return `c.Dictionary.Keys.BigInt(${tyK.n})`;
270
345
  if (tyK.kind === 'uintN')
271
346
  return `c.Dictionary.Keys.BigUint(${tyK.n})`;
272
347
  if (tyK.kind === 'address')
273
348
  return `c.Dictionary.Keys.Address()`;
274
- throw new unsupported_errors_1.NonStandardDictKey(`'${fieldPath}' is 'map<${(0, types_kernel_1.renderTy)(tyK)}, ...>': such a non-standard map key can not be handled by @ton/core library`);
349
+ throw new unsupported_errors_1.NonStandardDictKey(`'${fieldPath}' is 'map<${(0, types_kernel_1.renderTy)(ctx.symbols, tyKIdx)}, ...>': such a non-standard map key can not be handled by @ton/core library`);
275
350
  }
276
351
  // Emit a value (de)serializer for c.Dictionary<K, V>.
277
352
  // Unlike keys, @ton/core allows arbitrary values (passing custom (de)serializers).
278
353
  // For common cases, use a built-in one; for others, create a custom.
279
- function emitDictValueSerializer(ctx, fieldPath, tyV) {
354
+ function emitDictValueSerializer(ctx, fieldPath, tyVIdx) {
355
+ const tyV = ctx.symbols.tyByIdx(tyVIdx);
280
356
  if (tyV.kind === 'intN')
281
357
  return `c.Dictionary.Values.BigInt(${tyV.n})`;
282
358
  if (tyV.kind === 'uintN')
@@ -288,9 +364,9 @@ function emitDictValueSerializer(ctx, fieldPath, tyV) {
288
364
  if (tyV.kind === 'cell')
289
365
  return `c.Dictionary.Values.Cell()`;
290
366
  ctx.has_customDictV = true;
291
- return `${codegen_ctx_1.RUNTIME.createDictionaryValue}<${(0, emit_ts_types_1.emitTsType)(ctx, tyV)}>(${emitLoadCallback(ctx, fieldPath, tyV)}, ${emitStoreCallback(ctx, tyV)})`;
367
+ return `${codegen_ctx_1.RUNTIME.createDictionaryValue}<${(0, emit_ts_types_1.emitTsType)(ctx, tyVIdx)}>(${emitLoadCallback(ctx, fieldPath, tyVIdx)}, ${emitStoreCallback(ctx, tyVIdx)})`;
292
368
  }
293
369
  // Emit (de)serializers for c.Dictionary<K, V> (two arguments separated by a comma).
294
- function emitDictKVSerializers(ctx, fieldPath, tyK, tyV) {
295
- return emitDictKeySerializer(ctx, fieldPath, tyK) + ', ' + emitDictValueSerializer(ctx, fieldPath, tyV);
370
+ function emitDictKVSerializers(ctx, fieldPath, tyKIdx, tyVIdx) {
371
+ return emitDictKeySerializer(ctx, fieldPath, tyKIdx) + ', ' + emitDictValueSerializer(ctx, fieldPath, tyVIdx);
296
372
  }
@@ -1,4 +1,3 @@
1
- import type { Ty } from './abi-types';
2
1
  import { CodegenCtx } from './codegen-ctx';
3
- export declare function emitStackReadExpr(ctx: CodegenCtx, fieldPath: string, ty: Ty, unTupleIfW?: boolean): string;
4
- export declare function emitStackWriteItems(ctx: CodegenCtx, tsExpr: string, ty: Ty, tupleIfW?: boolean): string[];
2
+ export declare function emitStackReadExpr(ctx: CodegenCtx, fieldPath: string, tyIdx: number, unTupleIfW?: boolean, uLabelTyIdx?: number): string;
3
+ export declare function emitStackWriteItems(ctx: CodegenCtx, tsExpr: string, tyIdx: number, tupleIfW?: boolean, uLabelTyIdx?: number): string[];