gen-typescript-from-tolk-dev 0.2.4 → 0.3.0
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 +23 -3
- package/dist/abi-types.d.ts +33 -20
- package/dist/abi.d.ts +12 -11
- package/dist/codegen-ctx.d.ts +3 -12
- package/dist/codegen-ctx.js +4 -42
- package/dist/dynamic-ctx.d.ts +2 -2
- package/dist/dynamic-ctx.js +5 -5
- package/dist/dynamic-debug-print.d.ts +1 -2
- package/dist/dynamic-debug-print.js +36 -34
- package/dist/dynamic-get-methods.d.ts +1 -2
- package/dist/dynamic-get-methods.js +78 -78
- package/dist/dynamic-serialization.d.ts +8 -9
- package/dist/dynamic-serialization.js +85 -81
- package/dist/dynamic-validation.d.ts +8 -8
- package/dist/dynamic-validation.js +15 -15
- package/dist/emit-field-defs.d.ts +3 -3
- package/dist/emit-field-defs.js +11 -10
- package/dist/emit-pack-unpack.d.ts +14 -8
- package/dist/emit-pack-unpack.js +158 -82
- package/dist/emit-stack-rw.d.ts +2 -3
- package/dist/emit-stack-rw.js +64 -63
- package/dist/emit-ts-types.d.ts +6 -3
- package/dist/emit-ts-types.js +22 -14
- package/dist/generate-ts-wrappers.d.ts +3 -1
- package/dist/generate-ts-wrappers.js +101 -139
- package/dist/index.d.ts +3 -4
- package/dist/index.js +2 -9
- package/dist/types-kernel.d.ts +24 -6
- package/dist/types-kernel.js +154 -75
- package/dist/unsupported-errors.d.ts +1 -2
- package/dist/unsupported-errors.js +2 -3
- package/package.json +1 -1
package/dist/emit-pack-unpack.js
CHANGED
|
@@ -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,
|
|
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)(
|
|
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.
|
|
47
|
-
case 'cellOf': return `${codegen_ctx_1.RUNTIME.loadCellRef}<${(0, emit_ts_types_1.emitTsType)(ctx, ty.
|
|
48
|
-
case 'arrayOf': return `${codegen_ctx_1.RUNTIME.loadArrayOf}<${(0, emit_ts_types_1.emitTsType)(ctx, ty.
|
|
49
|
-
case 'lispListOf': return `${codegen_ctx_1.RUNTIME.loadLispListOf}<${(0, emit_ts_types_1.emitTsType)(ctx, ty.
|
|
50
|
-
case 'tensor': return `[${ty.
|
|
51
|
-
case 'shapedTuple': return `[${ty.
|
|
52
|
-
case 'mapKV': return `c.Dictionary.load<${(0, emit_ts_types_1.emitDictKVTypeArgs)(ctx, ty.
|
|
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.
|
|
56
|
-
|
|
57
|
-
return
|
|
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.
|
|
63
|
-
|
|
64
|
-
return
|
|
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':
|
|
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].
|
|
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].
|
|
74
|
-
const r = (0, emit_ts_types_1.emitUnionLabelAndValue)(variants[1], emitLoadExpr(ctx, fieldPath, variants[1].
|
|
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.
|
|
81
|
-
buf.push(`${checkFn}(s, ${v
|
|
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.
|
|
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,
|
|
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 === '
|
|
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.
|
|
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,
|
|
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,
|
|
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)(
|
|
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.
|
|
143
|
-
case 'cellOf': return `${codegen_ctx_1.RUNTIME.storeCellRef}<${(0, emit_ts_types_1.emitTsType)(ctx, ty.
|
|
144
|
-
case 'arrayOf': return `${codegen_ctx_1.RUNTIME.storeArrayOf}<${(0, emit_ts_types_1.emitTsType)(ctx, ty.
|
|
145
|
-
case 'lispListOf': return `${codegen_ctx_1.RUNTIME.storeLispListOf}<${(0, emit_ts_types_1.emitTsType)(ctx, ty.
|
|
146
|
-
case 'tensor': return ty.
|
|
147
|
-
case 'shapedTuple': return ty.
|
|
148
|
-
case 'mapKV': return `b.storeDict<${(0, emit_ts_types_1.emitDictKVTypeArgs)(ctx, ty.
|
|
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.
|
|
152
|
-
|
|
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.
|
|
159
|
-
|
|
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':
|
|
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.
|
|
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
|
|
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
|
|
178
|
-
|
|
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
|
|
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.
|
|
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,
|
|
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 === '
|
|
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.
|
|
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',
|
|
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,
|
|
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,
|
|
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.
|
|
232
|
-
|
|
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.
|
|
239
|
-
|
|
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,
|
|
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,
|
|
324
|
+
function emitCallToCreateMethodExpr(ctx, bodyArg, tyIdx) {
|
|
325
|
+
const ty = ctx.symbols.tyByIdx(tyIdx);
|
|
252
326
|
if (ty.kind === 'StructRef') {
|
|
253
|
-
let
|
|
254
|
-
if (
|
|
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.
|
|
258
|
-
return `${(0, formatting_1.safeJsIdent)(ty.struct_name)}.create<${ty.
|
|
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,
|
|
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)(
|
|
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,
|
|
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,
|
|
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,
|
|
295
|
-
return emitDictKeySerializer(ctx, fieldPath,
|
|
370
|
+
function emitDictKVSerializers(ctx, fieldPath, tyKIdx, tyVIdx) {
|
|
371
|
+
return emitDictKeySerializer(ctx, fieldPath, tyKIdx) + ', ' + emitDictValueSerializer(ctx, fieldPath, tyVIdx);
|
|
296
372
|
}
|
package/dist/emit-stack-rw.d.ts
CHANGED
|
@@ -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,
|
|
4
|
-
export declare function emitStackWriteItems(ctx: CodegenCtx, tsExpr: 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[];
|