Skip to content

Commit 5faf756

Browse files
committed
refactor: establish new codegen model and data model design
Signed-off-by: 0x009922 <43530070+0x009922@users.noreply.github.com>
1 parent 0cb2b1d commit 5faf756

File tree

18 files changed

+9625
-3103
lines changed

18 files changed

+9625
-3103
lines changed
Lines changed: 108 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,120 @@
1-
import { expect, test } from 'vitest'
1+
import { describe, expect, test } from 'vitest'
22
import { SCHEMA } from '@iroha2/data-model-schema'
3-
import { generate, parseRawIdent } from './codegen'
3+
import { enumShortcuts, type EmitCode, generate, renderShortcutsTree } from './codegen'
44
import { QUERY_IMPLS } from '@iroha2/iroha-source'
5+
import { format } from 'prettier'
6+
import PRETTIER_OPTIONS from '../../../.prettierrc.js'
7+
8+
/* TODO
9+
10+
- I manually re-arrange structs (for shortcuts, + maybe to avoid extra lazy stuff)
11+
- II fix core types
12+
- II more object.freeze
13+
- II think about never-enums. Just generate as never? (with a note that these are stubs) Or eliminate entirely from the schema/shortcuts tree?
14+
- III fix Action -> Executable -> Action recursion
15+
- III fix type -> interface
16+
- III codecFromPair()?
17+
- III Codec - differentiate input/output types?
18+
19+
*/
520

621
// convenient for development in watch mode
722
// works almost as if JavaScript supported comptime codegen
823
test('codegen snapshot', async () => {
9-
const code = generate(SCHEMA, QUERY_IMPLS, './generated-prelude')
10-
expect(code).toMatchFileSnapshot('../src/datamodel/generated.ts')
24+
const code = generate(SCHEMA, QUERY_IMPLS, './generated-lib')
25+
const formatted = await format(code, { parser: 'typescript', ...PRETTIER_OPTIONS })
26+
expect(formatted).toMatchFileSnapshot('../src/items/generated.ts')
1127
})
1228

13-
test('parse ident Vec<crate::role::Role>', () => {
14-
expect(parseRawIdent('Vec<crate::role::Role>')).toMatchInlineSnapshot(`
15-
{
16-
"id": "Vec",
17-
"items": [
18-
{
19-
"id": "Role",
20-
"items": [],
21-
"path": [
22-
"crate",
23-
"role",
29+
describe('enum shortcuts', () => {
30+
const SAMPLE = {
31+
A: {
32+
t: 'enum',
33+
variants: [
34+
{ tag: 'Unit', discriminant: 0, type: { t: 'null' } },
35+
{ tag: 'WithType', type: { t: 'local', id: 'Whichever' }, discriminant: 1 },
36+
{ tag: 'Nested', type: { t: 'local', id: 'B' }, discriminant: 2 },
37+
],
38+
},
39+
B: {
40+
t: 'enum',
41+
variants: [
42+
{ tag: 'Bunit', discriminant: 0, type: { t: 'null' } },
43+
{ discriminant: 1, tag: 'Bnested', type: { t: 'local', id: 'C' } },
44+
],
45+
},
46+
C: {
47+
t: 'enum',
48+
variants: [
49+
{ tag: 'CUnit', discriminant: 0, type: { t: 'null' } },
50+
{ discriminant: 1, tag: 'Cfinal', type: { t: 'local', id: 'Whichever' } },
51+
],
52+
},
53+
Whichever: { t: 'alias', to: { t: 'lib', id: 'AccountId' } },
54+
} satisfies Record<string, EmitCode>
55+
56+
const SAMPLE_MAP = new Map(Object.entries(SAMPLE))
57+
58+
test('build shortcuts tree', () => {
59+
const tree = enumShortcuts(SAMPLE.A.variants, SAMPLE_MAP)
60+
61+
expect(tree).toMatchInlineSnapshot(`
62+
[
63+
{
64+
"name": "Unit",
65+
"t": "unit",
66+
},
67+
{
68+
"name": "WithType",
69+
"t": "value",
70+
"value_ty": {
71+
"id": "Whichever",
72+
"t": "local",
73+
},
74+
},
75+
{
76+
"name": "Nested",
77+
"t": "enum",
78+
"tree": {
79+
"id": "B",
80+
"variants": [
81+
{
82+
"name": "Bunit",
83+
"t": "unit",
84+
},
85+
{
86+
"name": "Bnested",
87+
"t": "enum",
88+
"tree": {
89+
"id": "C",
90+
"variants": [
91+
{
92+
"name": "CUnit",
93+
"t": "unit",
94+
},
95+
{
96+
"name": "Cfinal",
97+
"t": "value",
98+
"value_ty": {
99+
"id": "Whichever",
100+
"t": "local",
101+
},
102+
},
103+
],
104+
},
105+
},
24106
],
25107
},
26-
],
27-
"path": undefined,
28-
}
108+
},
109+
]
29110
`)
111+
})
112+
113+
test('generate shortcut tree', () => {
114+
const generated = renderShortcutsTree({ id: 'A', variants: enumShortcuts(SAMPLE.A.variants, SAMPLE_MAP) })
115+
116+
expect(generated).toMatchInlineSnapshot(
117+
`"Unit: Object.freeze<A>({ kind: 'Unit' }), WithType: (value: Whichever): A => ({ kind: 'WithType', value }), Nested: { Bunit: Object.freeze<A>({ kind: 'Nested', value: B.Bunit }), Bnested: { CUnit: Object.freeze<A>({ kind: 'Nested', value: B.Bnested.CUnit }), Cfinal: (value: Whichever): A => ({ kind: 'Nested', value: B.Bnested.Cfinal(value) }) } }"`,
118+
)
119+
})
30120
})

0 commit comments

Comments
 (0)