gen-typescript-from-tolk-dev 0.1.0 → 0.2.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.
Files changed (50) hide show
  1. package/README.md +33 -29
  2. package/dist/abi-types.d.ts +169 -0
  3. package/dist/abi-types.js +8 -0
  4. package/dist/abi.d.ts +54 -0
  5. package/dist/abi.js +13 -0
  6. package/dist/cli.d.ts +2 -0
  7. package/dist/cli.js +83 -0
  8. package/dist/codegen-ctx.d.ts +66 -0
  9. package/dist/codegen-ctx.js +108 -0
  10. package/dist/emit-field-defs.d.ts +5 -0
  11. package/dist/emit-field-defs.js +61 -0
  12. package/dist/emit-pack-unpack.d.ts +9 -0
  13. package/dist/emit-pack-unpack.js +296 -0
  14. package/dist/emit-stack-rw.d.ts +4 -0
  15. package/dist/emit-stack-rw.js +232 -0
  16. package/dist/emit-ts-types.d.ts +6 -0
  17. package/dist/emit-ts-types.js +74 -0
  18. package/dist/formatting.d.ts +15 -0
  19. package/{src/formatting.ts → dist/formatting.js} +26 -28
  20. package/dist/generate-ts-wrappers.d.ts +7 -0
  21. package/dist/generate-ts-wrappers.js +444 -0
  22. package/dist/index.d.ts +4 -0
  23. package/dist/index.js +11 -0
  24. package/dist/out-template.generated.d.ts +1 -0
  25. package/dist/out-template.generated.js +6 -0
  26. package/dist/types-kernel.d.ts +10 -0
  27. package/dist/types-kernel.js +212 -0
  28. package/dist/unsupported-errors.d.ts +28 -0
  29. package/{src/unsupported-errors.ts → dist/unsupported-errors.js} +33 -39
  30. package/package.json +56 -30
  31. package/bin/generator.js +0 -15
  32. package/src/abi-types.ts +0 -157
  33. package/src/abi.ts +0 -132
  34. package/src/cli-generate-from-abi-json.ts +0 -21
  35. package/src/codegen-ctx.ts +0 -115
  36. package/src/dynamic-ctx.ts +0 -55
  37. package/src/dynamic-debug-print.ts +0 -191
  38. package/src/dynamic-get-methods.ts +0 -454
  39. package/src/dynamic-serialization.ts +0 -430
  40. package/src/dynamic-validation.ts +0 -55
  41. package/src/emit-field-defs.ts +0 -60
  42. package/src/emit-pack-unpack.ts +0 -280
  43. package/src/emit-stack-rw.ts +0 -239
  44. package/src/emit-ts-types.ts +0 -66
  45. package/src/generate-from-abi-json.ts +0 -22
  46. package/src/generate-ts-wrappers.ts +0 -477
  47. package/src/out-template.ts +0 -514
  48. package/src/tolk-to-abi.ts +0 -5
  49. package/src/types-kernel.ts +0 -215
  50. package/tsconfig.json +0 -13
@@ -1,215 +0,0 @@
1
- import type { Ty, UnionVariant } from './abi-types';
2
- import { SymTable } from './codegen-ctx';
3
-
4
- /*
5
- Contains basic functions working with ABI types,
6
- which are used both for generating wrappers and dynamic serialization.
7
- They do not emit TypeScript expressions and do not depend on CodegenCtx and DynamicCtx.
8
- */
9
-
10
- // Render intermediate representation back to a valid Tolk type, exactly as it was in original sources.
11
- export function renderTy(ty: Ty): string {
12
- switch (ty.kind) {
13
- case 'int': return `int`;
14
- case 'intN': return `int${ty.n}`;
15
- case 'uintN': return `uint${ty.n}`;
16
- case 'varintN': return `varint${ty.n}`;
17
- case 'varuintN': return `varuint${ty.n}`;
18
- case 'coins': return `coins`;
19
- case 'bool': return `bool`;
20
- case 'cell': return `cell`;
21
- case 'builder': return `builder`;
22
- case 'slice': return `slice`;
23
- case 'string': return `string`;
24
- case 'remaining': return `RemainingBitsAndRefs`;
25
- case 'address': return `address`;
26
- case 'addressOpt': return `address?`;
27
- case 'addressExt': return `ext_address`;
28
- case 'addressAny': return `any_address`;
29
- case 'bitsN': return `bits${ty.n}`;
30
- case 'nullLiteral': return `null`;
31
- case 'callable': return `continuation`;
32
- case 'void': return `void`;
33
- case 'unknown': return `unknown`;
34
- case 'nullable': return `${renderTy(ty.inner)}?`;
35
- case 'cellOf': return `Cell<${renderTy(ty.inner)}>`;
36
- case 'arrayOf': return `array<${renderTy(ty.inner)}>`;
37
- case 'lispListOf': return `lisp_list<${renderTy(ty.inner)}>`;
38
- case 'tensor': return `(${ty.items.map(renderTy).join(', ')})`;
39
- case 'shapedTuple': return `[${ty.items.map(renderTy).join(', ')}]`;
40
- case 'mapKV': return `map<${renderTy(ty.k)}, ${renderTy(ty.v)}>`;
41
- case 'EnumRef': return ty.enumName;
42
- case 'StructRef': return ty.structName + (ty.typeArgs ? `<${ty.typeArgs.map(renderTy).join(', ')}>` : '');
43
- case 'AliasRef': return ty.aliasName + (ty.typeArgs ? `<${ty.typeArgs.map(renderTy).join(', ')}>` : '');
44
- case 'genericT': return ty.nameT;
45
- case 'union': return ty.variants.map(v => renderTy(v.variantTy)).join(' | ');
46
- }
47
- }
48
-
49
- // Union types from Tolk are represented as union types in TypeScript, with some nuances.
50
- // For structures, like `A | B`, every struct (TS interface) has its own `$` field,
51
- // that's why it's emitted directly `type U = A | B`.
52
- // For primitives, like `int32 | int64`, every type is prefixed with a `$` field (label):
53
- // `type U = { $: 'int32', value: bigint } | { $: 'int64', value: bigint }`
54
- // Hence, for every union variant, we calculate whether we need to expose `$ + value`.
55
- export interface UnionVariantLabeled extends UnionVariant {
56
- labelStr: string // value for implicit or explicit `$`: 'A' / 'B' / 'int32' / etc.
57
- hasValueField: boolean // whether we need `$ + value` (a type has no `$` on its own)
58
- }
59
-
60
- // A "label" is the `$` field in TypeScript output, used to differentiate structs and union variants.
61
- // Tolk `int32 | int64` -> TS `{ $: 'int32', value: bigint } | { $: 'int64', value: bigint }`.
62
- // This function creates a string for `$`.
63
- function createLabel(symbols: SymTable, ty: Ty): string {
64
- switch (ty.kind) {
65
- case 'int': return `int`;
66
- case 'intN': return `int${ty.n}`;
67
- case 'uintN': return `uint${ty.n}`;
68
- case 'varintN': return `varint${ty.n}`;
69
- case 'varuintN': return `varuint${ty.n}`;
70
- case 'coins': return `coins`;
71
- case 'bool': return `bool`;
72
- case 'cell': return `cell`;
73
- case 'builder': return `builder`;
74
- case 'slice': return `slice`;
75
- case 'string': return `string`;
76
- case 'remaining': return `RemainingBitsAndRefs`;
77
- case 'address': return `address`;
78
- case 'addressOpt': return `address?`;
79
- case 'addressExt': return `ext_address`;
80
- case 'addressAny': return `any_address`;
81
- case 'bitsN': return `bits${ty.n}`;
82
- case 'nullLiteral': return `null`;
83
- case 'callable': return `callable`;
84
- case 'void': return `void`;
85
- case 'unknown': return `unknown`;
86
- case 'nullable': return `${createLabel(symbols, ty.inner)}?`;
87
- case 'cellOf': return `Cell`;
88
- case 'arrayOf': return `array`;
89
- case 'lispListOf': return `lisp_list`;
90
- case 'tensor': return `tensor`;
91
- case 'shapedTuple': return `shaped`;
92
- case 'mapKV': return `map`;
93
- case 'EnumRef': return ty.enumName;
94
- case 'StructRef': return ty.structName;
95
- case 'AliasRef': return createLabel(symbols, symbols.getAliasTarget(ty.aliasName));
96
- case 'genericT': return ty.nameT;
97
- case 'union': return ty.variants.map(v => createLabel(symbols, v.variantTy)).join('|');
98
- }
99
- }
100
-
101
- // Every Tolk struct is generated as TS `interface` with `$` field.
102
- // Tolk `struct A { ... }` -> TS `interface A { $: 'A', ... }`.
103
- // So, Tolk `A | B` is represented as TS `A | B` (unlike primitives),
104
- // because every struct has its own label.
105
- function isStructWithItsOwnLabel(symbols: SymTable, ty: Ty): boolean {
106
- if (ty.kind === 'StructRef') return true;
107
- if (ty.kind === 'AliasRef') return isStructWithItsOwnLabel(symbols, symbols.getAliasTarget(ty.aliasName));
108
- return false;
109
- }
110
-
111
- // Given a union `T1 | T2 | ...`, calculate a TypeScript representation:
112
- // whether each variant should be `$ + value` or not, and what string does `$` hold.
113
- export function createLabelsForUnion(symbols: SymTable, variants: UnionVariant[]): UnionVariantLabeled[] {
114
- // in all practical cases, `T_i` is a structure or a primitive;
115
- // we try to shorten a label (`createLabel()` is a "simple string of a type"):
116
- // - for a generic struct, use `Wrapper`, not `Wrapper<xxx>`
117
- // - for `Cell<...>`, use a shorthand `Cell`
118
- // - etc.
119
- // but if it results in a duplicate (e.g. `Wrapper<int32> | Wrapper<int64>` => ['Wrapper','Wrapper']),
120
- // then full-string Tolk types are used, and `value` is always required:
121
- // `type U = { $: 'Wrapper<int32>', value: Wrapper<int32> } | ...`
122
- let unique: Set<string> = new Set();
123
- let hasDuplicates = false;
124
- variants.forEach(variant => {
125
- let labelStr = createLabel(symbols, variant.variantTy);
126
- hasDuplicates ||= unique.has(labelStr);
127
- unique.add(labelStr);
128
- });
129
-
130
- return variants.map(variant => {
131
- let variantTy = variant.variantTy;
132
- if (variantTy.kind === 'nullLiteral') {
133
- return { ...variant, labelStr: '', hasValueField: false };
134
- }
135
- return {
136
- ...variant,
137
- labelStr: hasDuplicates ? renderTy(variantTy) : createLabel(symbols, variantTy),
138
- hasValueField: hasDuplicates ? true : !isStructWithItsOwnLabel(symbols, variantTy)
139
- };
140
- });
141
- }
142
-
143
- // Replace all generic Ts (typeParams) with instantiation (typeArgs) recursively.
144
- // Example: `(int, T, Wrapper<T?>)` and T=coins => `(int, coins, Wrapper<coins?>)`
145
- export function instantiateGenerics(ty: Ty, typeParams: string[] | undefined, typeArgs: Ty[]): Ty {
146
- if (ty.kind === 'nullable') return { ...ty, inner: instantiateGenerics(ty.inner, typeParams, typeArgs) };
147
- if (ty.kind === 'cellOf') return { ...ty, inner: instantiateGenerics(ty.inner, typeParams, typeArgs) };
148
- if (ty.kind === 'arrayOf') return { ...ty, inner: instantiateGenerics(ty.inner, typeParams, typeArgs) };
149
- if (ty.kind === 'lispListOf') return { ...ty, inner: instantiateGenerics(ty.inner, typeParams, typeArgs) };
150
- if (ty.kind === 'tensor') return { ...ty, items: ty.items.map(item => instantiateGenerics(item, typeParams, typeArgs)) };
151
- if (ty.kind === 'shapedTuple') return { ...ty, items: ty.items.map(item => instantiateGenerics(item, typeParams, typeArgs)) };
152
- if (ty.kind === 'mapKV') return { ...ty, k: instantiateGenerics(ty.k, typeParams, typeArgs), v: instantiateGenerics(ty.v, typeParams, typeArgs) };
153
- if (ty.kind === 'StructRef') return { ...ty, typeArgs: ty.typeArgs?.map(ta => instantiateGenerics(ta, typeParams, typeArgs)) };
154
- if (ty.kind === 'AliasRef') return { ...ty, typeArgs: ty.typeArgs?.map(ta => instantiateGenerics(ta, typeParams, typeArgs)) };
155
- if (ty.kind === 'union') return { ...ty, variants: ty.variants.map(v => ({ ...v, variantTy: instantiateGenerics(v.variantTy, typeParams, typeArgs) })) };
156
- if (ty.kind === 'genericT') {
157
- const idx = typeParams?.indexOf(ty.nameT);
158
- if (idx === undefined || idx === -1 || idx >= typeArgs.length)
159
- throw new Error(`inconsistent generics: could not find type argument for ${ty.nameT}`)
160
- return typeArgs[idx]
161
- }
162
- return ty;
163
- }
164
-
165
- // Calculate, how many stack slots a type occupies.
166
- export function calcWidthOnStack(symbols: SymTable, ty: Ty): number {
167
- switch (ty.kind) {
168
- case 'void': {
169
- // void is like "unit", equal to an empty tensor
170
- return 0;
171
- }
172
- case 'tensor': {
173
- // a tensor is a sum of its elements
174
- return ty.items.map(item => calcWidthOnStack(symbols, item)).reduce((p, c) => p + c, 0);
175
- }
176
- case 'StructRef': {
177
- // a struct is a named tensor: fields one by one;
178
- // if a struct is generic `Wrapper<T>`, we have typeArgs T=xxx, and replace T in each field
179
- // (it works unless `T` is used in unions)
180
- const structRef = symbols.getStruct(ty.structName);
181
- return structRef.fields.map(f => {
182
- const fTy = ty.typeArgs ? instantiateGenerics(f.ty, structRef.typeParams, ty.typeArgs) : f.ty;
183
- return calcWidthOnStack(symbols, fTy);
184
- }).reduce((p, c) => p + c, 0);
185
- }
186
- case 'AliasRef': {
187
- // an alias is the same as its underlying (target) type;
188
- // if an alias is generic `Maybe<T>`, we have typeArgs T=xxx, and replace T in its target
189
- const aliasRef = symbols.getAlias(ty.aliasName);
190
- const targetTy = ty.typeArgs ? instantiateGenerics(aliasRef.targetTy, aliasRef.typeParams, ty.typeArgs) : aliasRef.targetTy;
191
- return calcWidthOnStack(symbols, targetTy);
192
- }
193
- case 'nullable': {
194
- // for primitive nullables (common case), like `int?` and `address?`, it's 1 (TVM value or NULL);
195
- // for non-primitive nullables, the compiler inserts stackWidth and stackTypeId
196
- return ty.stackWidth ?? 1;
197
- }
198
- case 'union': {
199
- // for union types, the compiler always inserts stackWidth for simplicity (and stackTypeId for each variant)
200
- return ty.stackWidth;
201
- }
202
- case 'genericT': {
203
- // all generics must have been instantiated up to this point
204
- throw new Error(`unexpected genericT=${ty.nameT} in calcWidthOnStack`);
205
- }
206
- default: {
207
- // almost all types are TVM primitives that occupy 1 stack slot:
208
- // - intN is TVM INT
209
- // - array<T> is TVM TUPLE
210
- // - map<K, V> is TVM DICT or NULL
211
- // etc.
212
- return 1;
213
- }
214
- }
215
- }
package/tsconfig.json DELETED
@@ -1,13 +0,0 @@
1
- {
2
- "compilerOptions": {
3
- "target": "ES2020",
4
- "outDir": "dist",
5
- "module": "commonjs",
6
- "declaration": true,
7
- "esModuleInterop": true,
8
- "forceConsistentCasingInFileNames": true,
9
- "strict": true,
10
- "skipLibCheck": true,
11
- "baseUrl": "."
12
- }
13
- }