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.
@@ -11,7 +11,8 @@ const types_kernel_1 = require("./types-kernel");
11
11
  // Emit a TS "read {ty} from a stack `r`" expression.
12
12
  // Parameter `fieldPath` is used for error messages only.
13
13
  // Used to read getters return value, since contract getters work via the stack, not serialization.
14
- function emitStackReadExpr(ctx, fieldPath, ty, unTupleIfW = false) {
14
+ function emitStackReadExpr(ctx, fieldPath, tyIdx, unTupleIfW = false, uLabelTyIdx) {
15
+ const ty = ctx.symbols.tyByIdx(tyIdx);
15
16
  ctx.stackReadsUnknown || (ctx.stackReadsUnknown = ty.kind === 'unknown');
16
17
  ctx.stackReadsArrayOf || (ctx.stackReadsArrayOf = ty.kind === 'arrayOf');
17
18
  ctx.stackReadsLispListOf || (ctx.stackReadsLispListOf = ty.kind === 'lispListOf');
@@ -19,15 +20,15 @@ function emitStackReadExpr(ctx, fieldPath, ty, unTupleIfW = false) {
19
20
  ctx.stackReadsTuple || (ctx.stackReadsTuple = ty.kind === 'arrayOf' || ty.kind === 'lispListOf' || ty.kind === 'shapedTuple');
20
21
  ctx.stackReadsMapKV || (ctx.stackReadsMapKV = ty.kind === 'mapKV');
21
22
  ctx.stackReadsBuilder || (ctx.stackReadsBuilder = ty.kind === 'builder');
22
- ctx.stackReadsNullable || (ctx.stackReadsNullable = ty.kind === 'nullable');
23
+ ctx.stackReadsNullable || (ctx.stackReadsNullable = ty.kind === 'nullable' || ty.kind === 'addressOpt');
23
24
  ctx.stackReadsWideNullable || (ctx.stackReadsWideNullable = ty.kind === 'nullable' && ty.stack_type_id !== undefined);
24
25
  ctx.stackReadsUnionType || (ctx.stackReadsUnionType = ty.kind === 'union');
25
26
  ctx.stackReadsCellRef || (ctx.stackReadsCellRef = ty.kind === 'cellOf');
26
27
  ctx.stackReadsNullLiteral || (ctx.stackReadsNullLiteral = ty.kind === 'nullLiteral');
27
28
  if (unTupleIfW) { // inside `array<T>` or `[T, ...]`, if T is non-primitive, it's a sub-tuple
28
- let wOnStack = (0, types_kernel_1.calcWidthOnStack)(ctx.symbols, ty);
29
+ let wOnStack = (0, types_kernel_1.calcWidthOnStack)(ctx.symbols, tyIdx);
29
30
  if (wOnStack !== 1) {
30
- return `r.readTuple<${(0, emit_ts_types_1.emitTsType)(ctx, ty)}>(${wOnStack}, ${emitStackReadCallback(ctx, fieldPath, ty, false)})`;
31
+ return `r.readTuple<${(0, emit_ts_types_1.emitTsType)(ctx, tyIdx)}>(${wOnStack}, ${emitStackReadCallback(ctx, fieldPath, tyIdx, false, uLabelTyIdx)})`;
31
32
  }
32
33
  }
33
34
  switch (ty.kind) {
@@ -44,67 +45,68 @@ function emitStackReadExpr(ctx, fieldPath, ty, unTupleIfW = false) {
44
45
  case 'string': return `r.readSnakeString()`;
45
46
  case 'remaining': return `r.readSlice()`;
46
47
  case 'address': return `r.readSlice().loadAddress()`;
47
- case 'addressOpt': return emitStackReadExpr(ctx, fieldPath, { kind: 'nullable', inner: { kind: 'address' } });
48
+ case 'addressOpt': return `r.readNullable<c.Address>(${formatting_1.OutBuf.onNewLine('(r) => r.readSlice().loadAddress()')})`;
48
49
  case 'addressExt': return `r.readSlice().loadExternalAddress()`;
49
50
  case 'addressAny': return `${codegen_ctx_1.RUNTIME.loadTolkAddressAny}(r.readSlice())`;
50
51
  case 'bitsN': return `r.readSlice()`;
51
52
  case 'nullLiteral': return `r.readNullLiteral()`;
52
- case 'callable': throw new unsupported_errors_1.NotSupportedTypeOnStack(ty, fieldPath);
53
+ case 'callable': throw new unsupported_errors_1.NotSupportedTypeOnStack((0, types_kernel_1.renderTy)(ctx.symbols, tyIdx), fieldPath);
53
54
  case 'void': return `void 0`;
54
55
  case 'unknown': return `r.readUnknown()`;
55
56
  case 'nullable': {
56
57
  if (ty.stack_type_id) {
57
- return `r.readWideNullable<${(0, emit_ts_types_1.emitTsType)(ctx, ty.inner)}>(${ty.stack_width}, ${emitStackReadCallback(ctx, fieldPath, ty.inner, false)})`;
58
+ return `r.readWideNullable<${(0, emit_ts_types_1.emitTsType)(ctx, ty.inner_ty_idx)}>(${ty.stack_width}, ${emitStackReadCallback(ctx, fieldPath, ty.inner_ty_idx, false)})`;
58
59
  }
59
- return `r.readNullable<${(0, emit_ts_types_1.emitTsType)(ctx, ty.inner)}>(${emitStackReadCallback(ctx, fieldPath, ty.inner, false)})`;
60
+ return `r.readNullable<${(0, emit_ts_types_1.emitTsType)(ctx, ty.inner_ty_idx)}>(${emitStackReadCallback(ctx, fieldPath, ty.inner_ty_idx, false)})`;
60
61
  }
61
- case 'cellOf': return `r.readCellRef<${(0, emit_ts_types_1.emitTsType)(ctx, ty.inner)}>(${(0, emit_pack_unpack_1.emitLoadCallback)(ctx, fieldPath + '.ref', ty.inner)})`;
62
- case 'arrayOf': return `r.readArrayOf<${(0, emit_ts_types_1.emitTsType)(ctx, ty.inner)}>(${emitStackReadCallback(ctx, fieldPath, ty.inner, true)})`;
63
- case 'lispListOf': return `r.readLispListOf<${(0, emit_ts_types_1.emitTsType)(ctx, ty.inner)}>(${emitStackReadCallback(ctx, fieldPath, ty.inner, true)})`;
62
+ case 'cellOf': return `r.readCellRef<${(0, emit_ts_types_1.emitTsType)(ctx, ty.inner_ty_idx)}>(${(0, emit_pack_unpack_1.emitLoadCallback)(ctx, fieldPath + '.ref', ty.inner_ty_idx)})`;
63
+ case 'arrayOf': return `r.readArrayOf<${(0, emit_ts_types_1.emitTsType)(ctx, ty.inner_ty_idx)}>(${emitStackReadCallback(ctx, fieldPath, ty.inner_ty_idx, true)})`;
64
+ case 'lispListOf': return `r.readLispListOf<${(0, emit_ts_types_1.emitTsType)(ctx, ty.inner_ty_idx)}>(${emitStackReadCallback(ctx, fieldPath, ty.inner_ty_idx, true)})`;
64
65
  case 'tensor': {
65
66
  let buf = new formatting_1.OutBuf();
66
67
  buf.push(`[`);
67
- for (let i = 0; i < ty.items.length; ++i) {
68
- buf.push(emitStackReadExpr(ctx, `${fieldPath}[${i}]`, ty.items[i]) + ',');
68
+ for (let i = 0; i < ty.items_ty_idx.length; ++i) {
69
+ buf.push(emitStackReadExpr(ctx, `${fieldPath}[${i}]`, ty.items_ty_idx[i]) + ',');
69
70
  }
70
71
  buf.push(']');
71
72
  return buf.toString();
72
73
  }
73
74
  case 'shapedTuple': {
74
75
  let buf = new formatting_1.OutBuf();
75
- buf.push(`r.readTuple<${(0, emit_ts_types_1.emitTsType)(ctx, ty)}>(${ty.items.length}, (r) => [`);
76
- for (let i = 0; i < ty.items.length; ++i) {
77
- buf.push(emitStackReadExpr(ctx, `${fieldPath}[${i}]`, ty.items[i], true) + ',');
76
+ buf.push(`r.readTuple<${(0, emit_ts_types_1.emitTsType)(ctx, tyIdx)}>(${ty.items_ty_idx.length}, (r) => [`);
77
+ for (let i = 0; i < ty.items_ty_idx.length; ++i) {
78
+ buf.push(emitStackReadExpr(ctx, `${fieldPath}[${i}]`, ty.items_ty_idx[i], true) + ',');
78
79
  }
79
80
  buf.push('])');
80
81
  return buf.toString();
81
82
  }
82
- case 'mapKV': return `r.readDictionary<${(0, emit_ts_types_1.emitDictKVTypeArgs)(ctx, ty.k, ty.v)}>(${(0, emit_pack_unpack_1.emitDictKVSerializers)(ctx, fieldPath, ty.k, ty.v)})`;
83
+ case 'mapKV': return `r.readDictionary<${(0, emit_ts_types_1.emitDictKVTypeArgs)(ctx, ty.key_ty_idx, ty.value_ty_idx)}>(${(0, emit_pack_unpack_1.emitDictKVSerializers)(ctx, fieldPath, ty.key_ty_idx, ty.value_ty_idx)})`;
83
84
  case 'EnumRef': return `r.readBigInt()`;
84
85
  case 'StructRef': {
85
- const structRef = ctx.symbols.getStruct(ty.struct_name);
86
86
  let buf = new formatting_1.OutBuf();
87
87
  buf.push(`({`);
88
88
  buf.push(`$: '${ty.struct_name}',`);
89
- for (let f of structRef.fields) {
90
- const fTy = ty.type_args ? (0, types_kernel_1.instantiateGenerics)(f.ty, structRef.type_params, ty.type_args) : f.ty;
91
- buf.push(`${(0, formatting_1.safeFieldDecl)(f.name)}: ${emitStackReadExpr(ctx, `${fieldPath}.${f.name}`, fTy)},`);
89
+ for (let f of ctx.symbols.structFieldsOf(tyIdx)) {
90
+ buf.push(`${(0, formatting_1.safeFieldDecl)(f.name)}: ${emitStackReadExpr(ctx, `${fieldPath}.${f.name}`, f.ty_idx, false, f.uLabelTyIdx)},`);
92
91
  }
93
92
  buf.push(`})`);
94
93
  return buf.toString();
95
94
  }
96
95
  case 'AliasRef': {
97
- const aliasRef = ctx.symbols.getAlias(ty.alias_name);
98
- const targetTy = ty.type_args ? (0, types_kernel_1.instantiateGenerics)(aliasRef.target_ty, aliasRef.type_params, ty.type_args) : aliasRef.target_ty;
99
- return emitStackReadExpr(ctx, fieldPath, targetTy);
96
+ const target = ctx.symbols.aliasTargetOf(tyIdx);
97
+ return emitStackReadExpr(ctx, fieldPath, target.ty_idx, unTupleIfW, target.uLabelTyIdx);
100
98
  }
101
- case 'genericT': throw new Error(`unexpected genericT=${ty.name_t} in '${fieldPath}'`);
99
+ case 'genericT': throw new Error(`unexpected genericT=${ty.name_t} at '${fieldPath}'`);
102
100
  case 'union': {
103
- const variants = (0, types_kernel_1.createLabelsForUnion)(ctx.symbols, ty.variants);
101
+ if (ty.stack_width === undefined) {
102
+ throw new Error(`unexpected stack_width=undefined at ${fieldPath}`);
103
+ }
104
+ const variants = (0, types_kernel_1.createLabelsForUnion)(ctx.symbols, ty.variants, uLabelTyIdx);
104
105
  let buf = new formatting_1.OutBuf();
105
- buf.push(`r.readUnionType<${(0, emit_ts_types_1.emitTsType)(ctx, ty)}>(${ty.stack_width}, {`);
106
+ let tsUniTypeStr = variants.map(v => (0, emit_ts_types_1.emitUnionLabelAndValue)(v, (0, emit_ts_types_1.emitTsType)(ctx, v.variant_ty_idx))).join(' | ');
107
+ buf.push(`r.readUnionType<${tsUniTypeStr}>(${ty.stack_width}, {`);
106
108
  for (let v of variants) {
107
- buf.push(`${v.stack_type_id}: [${v.stack_width}, ${v.hasValueField ? `'${v.labelStr}'` : 'null'}, ${emitStackReadCallback(ctx, `${fieldPath}#${v.stack_type_id}`, v.variant_ty, false)}],`);
109
+ buf.push(`${v.stack_type_id}: [${v.stack_width}, ${v.hasValueField ? `'${v.labelStr}'` : 'null'}, ${emitStackReadCallback(ctx, `${fieldPath}#${v.stack_type_id}`, v.variant_ty_idx, false, uLabelTyIdx)}],`);
108
110
  }
109
111
  buf.push(`})`);
110
112
  return buf.toString();
@@ -113,20 +115,21 @@ function emitStackReadExpr(ctx, fieldPath, ty, unTupleIfW = false) {
113
115
  }
114
116
  // Emit a TS "read {ty} from a stack `r`" callback (not expression).
115
117
  // Callbacks are passed for generics — for example, to read a nullable (when a stack slot is not null).
116
- function emitStackReadCallback(ctx, fieldPath, ty, unTupleIfW) {
117
- return formatting_1.OutBuf.onNewLine(`(r) => ${emitStackReadExpr(ctx, fieldPath, ty, unTupleIfW)}`);
118
+ function emitStackReadCallback(ctx, fieldPath, tyIdx, unTupleIfW, uLabelTyIdx) {
119
+ return formatting_1.OutBuf.onNewLine(`(r) => ${emitStackReadExpr(ctx, fieldPath, tyIdx, unTupleIfW, uLabelTyIdx)}`);
118
120
  }
119
121
  // Emit a TS "write {expr of type ty} to a stack" expression compatible with @ton/core TupleItem.
120
122
  // Used to pass getters arguments, since contract getters work via the stack, not serialization.
121
123
  // Parameter `tsExpr` is a valid expression: "p1.field", "p2[0]", "ith" (inside a callback), and other.
122
- function emitStackWriteItems(ctx, tsExpr, ty, tupleIfW = false) {
124
+ function emitStackWriteItems(ctx, tsExpr, tyIdx, tupleIfW = false, uLabelTyIdx) {
125
+ const ty = ctx.symbols.tyByIdx(tyIdx);
123
126
  if (tupleIfW) { // inside `array<T>` or `[T, ...]`, if T is non-primitive, it's a sub-tuple
124
- if ((0, types_kernel_1.calcWidthOnStack)(ctx.symbols, ty) === 1) {
125
- return emitStackWriteItems(ctx, tsExpr, ty, false);
127
+ if ((0, types_kernel_1.calcWidthOnStack)(ctx.symbols, tyIdx) === 1) {
128
+ return emitStackWriteItems(ctx, tsExpr, tyIdx, false, uLabelTyIdx);
126
129
  }
127
130
  let buf = new formatting_1.OutBuf();
128
131
  buf.push(`{ type: 'tuple', items: [`);
129
- for (let line of emitStackWriteItems(ctx, tsExpr, ty, false)) {
132
+ for (let line of emitStackWriteItems(ctx, tsExpr, tyIdx, false, uLabelTyIdx)) {
130
133
  buf.push(line + ',');
131
134
  }
132
135
  buf.push(`]}`);
@@ -141,17 +144,17 @@ function emitStackWriteItems(ctx, tsExpr, ty, tupleIfW = false) {
141
144
  case 'coins': return [`{ type: 'int', value: ${tsExpr} }`];
142
145
  case 'bool': return [`{ type: 'int', value: (${tsExpr} ? -1n : 0n) }`];
143
146
  case 'cell': return [`{ type: 'cell', cell: ${tsExpr} }`];
144
- case 'builder': return [`{ type: 'builder', cell: ${(0, emit_pack_unpack_1.emitMakeCellFromExpr)(ctx, tsExpr, ty)} }`];
147
+ case 'builder': return [`{ type: 'builder', cell: ${(0, emit_pack_unpack_1.emitMakeCellFromExpr)(ctx, tsExpr, tyIdx)} }`];
145
148
  case 'slice': return [`{ type: 'slice', cell: ${codegen_ctx_1.RUNTIME.beginCell}().storeSlice(${tsExpr}).endCell() }`];
146
149
  case 'string': return [`{ type: 'cell', cell: ${codegen_ctx_1.RUNTIME.beginCell}().storeStringTail(${tsExpr}).endCell() }`];
147
- case 'remaining': return [`{ type: 'slice', cell: ${(0, emit_pack_unpack_1.emitMakeCellFromExpr)(ctx, tsExpr, ty)} }`];
148
- case 'address': return [`{ type: 'slice', cell: ${(0, emit_pack_unpack_1.emitMakeCellFromExpr)(ctx, tsExpr, ty)} }`];
149
- case 'addressOpt': return emitStackWriteItems(ctx, tsExpr, { kind: 'nullable', inner: { kind: 'address' } });
150
- case 'addressExt': return [`{ type: 'slice', cell: ${(0, emit_pack_unpack_1.emitMakeCellFromExpr)(ctx, tsExpr, ty)} }`];
151
- case 'addressAny': return [`{ type: 'slice', cell: ${(0, emit_pack_unpack_1.emitMakeCellFromExpr)(ctx, tsExpr, ty)} }`];
152
- case 'bitsN': return [`{ type: 'slice', cell: ${(0, emit_pack_unpack_1.emitMakeCellFromExpr)(ctx, tsExpr, ty)} }`];
150
+ case 'remaining': return [`{ type: 'slice', cell: ${(0, emit_pack_unpack_1.emitMakeCellFromExpr)(ctx, tsExpr, tyIdx)} }`];
151
+ case 'address': return [`{ type: 'slice', cell: ${(0, emit_pack_unpack_1.emitMakeCellFromExpr)(ctx, tsExpr, tyIdx)} }`];
152
+ case 'addressOpt': return [`${tsExpr} === null ? { type: 'null' } : { type: 'slice', cell: ${(0, emit_pack_unpack_1.emitMakeCellFromExpr)(ctx, tsExpr, tyIdx)} }`];
153
+ case 'addressExt': return [`{ type: 'slice', cell: ${(0, emit_pack_unpack_1.emitMakeCellFromExpr)(ctx, tsExpr, tyIdx)} }`];
154
+ case 'addressAny': return [`{ type: 'slice', cell: ${(0, emit_pack_unpack_1.emitMakeCellFromExpr)(ctx, tsExpr, tyIdx)} }`];
155
+ case 'bitsN': return [`{ type: 'slice', cell: ${(0, emit_pack_unpack_1.emitMakeCellFromExpr)(ctx, tsExpr, tyIdx)} }`];
153
156
  case 'nullLiteral': return [`{ type: 'null' }`];
154
- case 'callable': throw new unsupported_errors_1.NotSupportedTypeOnStack(ty, tsExpr);
157
+ case 'callable': throw new unsupported_errors_1.NotSupportedTypeOnStack((0, types_kernel_1.renderTy)(ctx.symbols, tyIdx), tsExpr);
155
158
  case 'void': return [];
156
159
  case 'unknown': return [tsExpr];
157
160
  case 'nullable': {
@@ -164,22 +167,22 @@ function emitStackWriteItems(ctx, tsExpr, ty, tupleIfW = false) {
164
167
  }
165
168
  buf.push(`{ type: 'int', value: 0n },`);
166
169
  buf.push(`] : [`);
167
- emitStackWriteItems(ctx, tsExpr, ty.inner).forEach(w => buf.push(w + ','));
170
+ emitStackWriteItems(ctx, tsExpr, ty.inner_ty_idx).forEach(w => buf.push(w + ','));
168
171
  buf.push(`{ type: 'int', value: ${ty.stack_type_id}n },`);
169
172
  buf.push(`]`);
170
173
  buf.push(`) as c.TupleItem[]`);
171
174
  return [buf.toString()];
172
175
  }
173
- return [`${tsExpr} === null ? { type: 'null' } : ${emitStackWriteItems(ctx, tsExpr, ty.inner)[0]}`];
176
+ return [`${tsExpr} === null ? { type: 'null' } : ${emitStackWriteItems(ctx, tsExpr, ty.inner_ty_idx)[0]}`];
174
177
  }
175
- case 'cellOf': return [`{ type: 'cell', cell: ${(0, emit_pack_unpack_1.emitMakeCellFromExpr)(ctx, `${tsExpr}.ref`, ty.inner)} }`];
176
- case 'arrayOf': return [`{ type: 'tuple', items: ${tsExpr}.map(${formatting_1.OutBuf.onNewLine(`(ith) => (${emitStackWriteItems(ctx, 'ith', ty.inner, true)})`)})}`];
177
- case 'tensor': return ty.items.flatMap((item, idx) => emitStackWriteItems(ctx, `${tsExpr}[${idx}]`, item));
178
+ case 'cellOf': return [`{ type: 'cell', cell: ${(0, emit_pack_unpack_1.emitMakeCellFromExpr)(ctx, `${tsExpr}.ref`, ty.inner_ty_idx)} }`];
179
+ case 'arrayOf': return [`{ type: 'tuple', items: ${tsExpr}.map(${formatting_1.OutBuf.onNewLine(`(ith) => (${emitStackWriteItems(ctx, 'ith', ty.inner_ty_idx, true)})`)})}`];
180
+ case 'tensor': return ty.items_ty_idx.flatMap((ty_idx, idx) => emitStackWriteItems(ctx, `${tsExpr}[${idx}]`, ty_idx));
178
181
  case 'shapedTuple': {
179
182
  let buf = new formatting_1.OutBuf();
180
183
  buf.push(`{ type: 'tuple', items: [`);
181
- for (let i = 0; i < ty.items.length; ++i) {
182
- buf.push(emitStackWriteItems(ctx, `${tsExpr}[${i}]`, ty.items[i], true)[0] + ',');
184
+ for (let i = 0; i < ty.items_ty_idx.length; ++i) {
185
+ buf.push(emitStackWriteItems(ctx, `${tsExpr}[${i}]`, ty.items_ty_idx[i], true)[0] + ',');
183
186
  }
184
187
  buf.push(']}');
185
188
  return [buf.toString()];
@@ -187,32 +190,30 @@ function emitStackWriteItems(ctx, tsExpr, ty, tupleIfW = false) {
187
190
  case 'lispListOf': {
188
191
  let buf = new formatting_1.OutBuf();
189
192
  buf.push(`${tsExpr}.reduceRight((tail, head) => ({ type: 'tuple', items: [`);
190
- buf.push(emitStackWriteItems(ctx, `head`, ty.inner, true)[0] + ',');
193
+ buf.push(emitStackWriteItems(ctx, `head`, ty.inner_ty_idx, true)[0] + ',');
191
194
  buf.push('tail');
192
195
  buf.push(`]}), { type: 'null' } as c.TupleItem)`);
193
196
  return [buf.toString()];
194
197
  }
195
- case 'mapKV': return [`${tsExpr}.size === 0 ? { type: 'null' } : { type: 'cell', cell: ${codegen_ctx_1.RUNTIME.beginCell}().storeDictDirect<${(0, emit_ts_types_1.emitDictKVTypeArgs)(ctx, ty.k, ty.v)}>(${tsExpr}, ${(0, emit_pack_unpack_1.emitDictKVSerializers)(ctx, tsExpr, ty.k, ty.v)}).endCell() }`];
198
+ case 'mapKV': return [`${tsExpr}.size === 0 ? { type: 'null' } : { type: 'cell', cell: ${codegen_ctx_1.RUNTIME.beginCell}().storeDictDirect<${(0, emit_ts_types_1.emitDictKVTypeArgs)(ctx, ty.key_ty_idx, ty.value_ty_idx)}>(${tsExpr}, ${(0, emit_pack_unpack_1.emitDictKVSerializers)(ctx, tsExpr, ty.key_ty_idx, ty.value_ty_idx)}).endCell() }`];
196
199
  case 'EnumRef': return [`{ type: 'int', value: ${tsExpr} }`];
197
200
  case 'StructRef': {
198
- const structRef = ctx.symbols.getStruct(ty.struct_name);
199
- return structRef.fields.flatMap(f => {
200
- const fTy = ty.type_args ? (0, types_kernel_1.instantiateGenerics)(f.ty, structRef.type_params, ty.type_args) : f.ty;
201
- return emitStackWriteItems(ctx, `${tsExpr}.${f.name}`, fTy);
202
- });
201
+ return ctx.symbols.structFieldsOf(tyIdx).flatMap(f => emitStackWriteItems(ctx, `${tsExpr}${(0, formatting_1.safeFieldRead)(f.name)}`, f.ty_idx, false, f.uLabelTyIdx));
203
202
  }
204
203
  case 'AliasRef': {
205
- const aliasRef = ctx.symbols.getAlias(ty.alias_name);
206
- const targetTy = ty.type_args ? (0, types_kernel_1.instantiateGenerics)(aliasRef.target_ty, aliasRef.type_params, ty.type_args) : aliasRef.target_ty;
207
- return emitStackWriteItems(ctx, tsExpr, targetTy);
204
+ const target = ctx.symbols.aliasTargetOf(tyIdx);
205
+ return emitStackWriteItems(ctx, tsExpr, target.ty_idx, tupleIfW, target.uLabelTyIdx);
208
206
  }
209
- case 'genericT': throw new Error(`unexpected genericT=${ty.name_t} in '${tsExpr}'`);
207
+ case 'genericT': throw new Error(`unexpected genericT=${ty.name_t} at '${tsExpr}'`);
210
208
  case 'union': {
211
- const variants = (0, types_kernel_1.createLabelsForUnion)(ctx.symbols, ty.variants);
209
+ if (ty.stack_width === undefined) {
210
+ throw new Error(`unexpected stack_width=undefined at ${tsExpr}`);
211
+ }
212
+ const variants = (0, types_kernel_1.createLabelsForUnion)(ctx.symbols, ty.variants, uLabelTyIdx);
212
213
  variants.sort((a, b) => a.stack_type_id - b.stack_type_id); // move `null` variant (if exists) to the top
213
214
  let buf = new formatting_1.OutBuf();
214
215
  buf.push(`...(`);
215
- for (let v of variants) {
216
+ for (const v of variants) {
216
217
  if (v.labelStr === '')
217
218
  buf.push(`${tsExpr} === null ? [`);
218
219
  else
@@ -220,7 +221,7 @@ function emitStackWriteItems(ctx, tsExpr, ty, tupleIfW = false) {
220
221
  for (let i = 0; i < ty.stack_width - 1 - v.stack_width; ++i) {
221
222
  buf.push(`{ type: 'null' },`);
222
223
  }
223
- emitStackWriteItems(ctx, v.hasValueField ? tsExpr + '.value' : tsExpr, v.variant_ty).forEach(w => buf.push(w + ','));
224
+ emitStackWriteItems(ctx, v.hasValueField ? tsExpr + '.value' : tsExpr, v.variant_ty_idx, false).forEach(w => buf.push(w + ','));
224
225
  buf.push(`{ type: 'int', value: ${v.stack_type_id}n },`);
225
226
  buf.push(`] :`);
226
227
  }
@@ -1,6 +1,9 @@
1
- import type { Ty } from './abi-types';
2
1
  import { CodegenCtx } from './codegen-ctx';
3
2
  import { UnionVariantLabeled } from './types-kernel';
4
3
  export declare function emitUnionLabelAndValue(label: UnionVariantLabeled, contents: string): string;
5
- export declare function emitTsType(ctx: CodegenCtx, ty: Ty): string;
6
- export declare function emitDictKVTypeArgs(ctx: CodegenCtx, tyK: Ty, tyV: Ty): string;
4
+ export declare function emitPrefixHex(prefix: {
5
+ prefix_num: number;
6
+ prefix_len: number;
7
+ }): string;
8
+ export declare function emitTsType(ctx: CodegenCtx, tyIdx: number): string;
9
+ export declare function emitDictKVTypeArgs(ctx: CodegenCtx, tyKIdx: number, tyVIdx: number): string;
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.emitUnionLabelAndValue = emitUnionLabelAndValue;
4
+ exports.emitPrefixHex = emitPrefixHex;
4
5
  exports.emitTsType = emitTsType;
5
6
  exports.emitDictKVTypeArgs = emitDictKVTypeArgs;
6
7
  const formatting_1 = require("./formatting");
@@ -10,10 +11,17 @@ const types_kernel_1 = require("./types-kernel");
10
11
  function emitUnionLabelAndValue(label, contents) {
11
12
  return label.hasValueField ? `{ $: '${label.labelStr}', value: ${contents} }` : contents;
12
13
  }
14
+ // given prefix_num=305419896 of prefix_len=32, format a string "0x12345678" (opcode)
15
+ function emitPrefixHex(prefix) {
16
+ return prefix.prefix_len % 4
17
+ ? `0b${prefix.prefix_num.toString(2).padStart(prefix.prefix_len, '0')}`
18
+ : `0x${prefix.prefix_num.toString(16).padStart(prefix.prefix_len / 4, '0')}`;
19
+ }
13
20
  // Convert any Tolk type (ABI representation) to a corresponding TypeScript type.
14
21
  // Tolk `int32` -> TS `bigint`, but for readability, `type int32 = bigint` is created.
15
22
  // `c.` is import @ton/core.
16
- function emitTsType(ctx, ty) {
23
+ function emitTsType(ctx, tyIdx) {
24
+ const ty = ctx.symbols.tyByIdx(tyIdx);
17
25
  if (ty.kind === 'intN')
18
26
  ctx.intNOccurred.add(`int${ty.n}`);
19
27
  if (ty.kind === 'uintN')
@@ -54,21 +62,21 @@ function emitTsType(ctx, ty) {
54
62
  case 'callable': return `any`;
55
63
  case 'void': return `void`;
56
64
  case 'unknown': return `c.TupleItem`;
57
- case 'nullable': return `${emitTsType(ctx, ty.inner)} | null`;
58
- case 'cellOf': return `CellRef<${emitTsType(ctx, ty.inner)}>`;
59
- case 'arrayOf': return `array<${emitTsType(ctx, ty.inner)}>`;
60
- case 'lispListOf': return `lisp_list<${emitTsType(ctx, ty.inner)}>`;
61
- case 'tensor': return `[${ty.items.map(item => emitTsType(ctx, item)).join(', ')}]`;
62
- case 'shapedTuple': return `[${ty.items.map(item => emitTsType(ctx, item)).join(', ')}]`;
63
- case 'mapKV': return `c.Dictionary<${emitDictKVTypeArgs(ctx, ty.k, ty.v)}>`;
64
- case 'EnumRef': return ty.enum_name;
65
- case 'StructRef': return (0, formatting_1.safeJsIdent)(ty.struct_name) + (ty.type_args ? `<${ty.type_args.map(ta => emitTsType(ctx, ta)).join(', ')}>` : '');
66
- case 'AliasRef': return (0, formatting_1.safeJsIdent)(ty.alias_name) + (ty.type_args ? `<${ty.type_args.map(ta => emitTsType(ctx, ta)).join(', ')}>` : '');
65
+ case 'nullable': return `${emitTsType(ctx, ty.inner_ty_idx)} | null`;
66
+ case 'cellOf': return `CellRef<${emitTsType(ctx, ty.inner_ty_idx)}>`;
67
+ case 'arrayOf': return `array<${emitTsType(ctx, ty.inner_ty_idx)}>`;
68
+ case 'lispListOf': return `lisp_list<${emitTsType(ctx, ty.inner_ty_idx)}>`;
69
+ case 'tensor': return `[${ty.items_ty_idx.map(ty_idx => emitTsType(ctx, ty_idx)).join(', ')}]`;
70
+ case 'shapedTuple': return `[${ty.items_ty_idx.map(ty_idx => emitTsType(ctx, ty_idx)).join(', ')}]`;
71
+ case 'mapKV': return `c.Dictionary<${emitDictKVTypeArgs(ctx, ty.key_ty_idx, ty.value_ty_idx)}>`;
72
+ case 'EnumRef': return (0, formatting_1.safeJsIdent)(ty.enum_name);
73
+ case 'StructRef': return (0, formatting_1.safeJsIdent)(ty.struct_name) + (ty.type_args_ty_idx ? `<${ty.type_args_ty_idx.map(ty_idx => emitTsType(ctx, ty_idx)).join(', ')}>` : '');
74
+ case 'AliasRef': return (0, formatting_1.safeJsIdent)(ty.alias_name) + (ty.type_args_ty_idx ? `<${ty.type_args_ty_idx.map(ty_idx => emitTsType(ctx, ty_idx)).join(', ')}>` : '');
67
75
  case 'genericT': return ty.name_t;
68
- case 'union': return (0, types_kernel_1.createLabelsForUnion)(ctx.symbols, ty.variants).map(v => emitUnionLabelAndValue(v, emitTsType(ctx, v.variant_ty))).join(' | ');
76
+ case 'union': return (0, types_kernel_1.createLabelsForUnion)(ctx.symbols, ty.variants).map(v => emitUnionLabelAndValue(v, emitTsType(ctx, v.variant_ty_idx))).join(' | ');
69
77
  }
70
78
  }
71
79
  // Emit c.Dictionary<K, V> (K and V — inside brackets, two types separated by comma).
72
- function emitDictKVTypeArgs(ctx, tyK, tyV) {
73
- return emitTsType(ctx, tyK) + ', ' + emitTsType(ctx, tyV);
80
+ function emitDictKVTypeArgs(ctx, tyKIdx, tyVIdx) {
81
+ return emitTsType(ctx, tyKIdx) + ', ' + emitTsType(ctx, tyVIdx);
74
82
  }
@@ -4,4 +4,6 @@ import type { ContractABI } from './abi';
4
4
  * and returns the full TypeScript wrapper with all serializers, send, and get methods.
5
5
  * @throws CantGenerateWrappersAtAll
6
6
  */
7
- export declare function generateTypeScriptFileForContract(contract: ContractABI): string;
7
+ export declare function generateTypeScriptFileForContract(abi: ContractABI & {
8
+ code_boc64: string;
9
+ }): string;