From 66bbbfdf856395fc626872dc7573239edf3b02da Mon Sep 17 00:00:00 2001 From: homura Date: Mon, 5 Aug 2024 22:24:06 +0900 Subject: [PATCH] fix(molecule): incorrect fallback Bytes codec in codegen (#737) --- .changeset/shaggy-beans-grab.md | 5 + .../generated/common/basic_types.ts | 7 +- .../molecule-codegen-dir/generated/skills.ts | 7 +- examples/molecule-codegen/blockchain.ts | 9 +- packages/molecule/package.json | 4 +- packages/molecule/src/cli.ts | 2 +- packages/molecule/src/codegen.ts | 7 +- .../molecule/tests/codegen/customization.ts | 5 + packages/molecule/tests/codegen/generated.ts | 336 +++++++++++ .../tests/codegen/lumos-molecule-codegen.json | 4 + .../molecule/tests/codegen/simple.test.ts | 69 +++ packages/molecule/tests/codegen/simple.yaml | 529 ++++++++++++++++++ packages/molecule/tests/codegen/types.mol | 263 +++++++++ pnpm-lock.yaml | 10 + 14 files changed, 1234 insertions(+), 23 deletions(-) create mode 100644 .changeset/shaggy-beans-grab.md create mode 100644 packages/molecule/tests/codegen/customization.ts create mode 100644 packages/molecule/tests/codegen/generated.ts create mode 100644 packages/molecule/tests/codegen/lumos-molecule-codegen.json create mode 100644 packages/molecule/tests/codegen/simple.test.ts create mode 100644 packages/molecule/tests/codegen/simple.yaml create mode 100644 packages/molecule/tests/codegen/types.mol diff --git a/.changeset/shaggy-beans-grab.md b/.changeset/shaggy-beans-grab.md new file mode 100644 index 000000000..207880954 --- /dev/null +++ b/.changeset/shaggy-beans-grab.md @@ -0,0 +1,5 @@ +--- +"@ckb-lumos/molecule": minor +--- + +fix: incorrect fallback `Bytes` codec from codegen diff --git a/examples/molecule-codegen-dir/generated/common/basic_types.ts b/examples/molecule-codegen-dir/generated/common/basic_types.ts index 19269563c..6ad145edc 100644 --- a/examples/molecule-codegen-dir/generated/common/basic_types.ts +++ b/examples/molecule-codegen-dir/generated/common/basic_types.ts @@ -3,12 +3,9 @@ import { bytes, createBytesCodec, createFixedBytesCodec, molecule } from "@ckb-lumos/codec"; import { Uint32, Uint64, Uint128, DepType, HashType } from '../../customized' -const { array, vector, union, option, struct, table } = molecule; +const { array, vector, union, option, struct, table, byteVecOf } = molecule; -const fallbackBytesCodec = createBytesCodec({ - pack: bytes.bytify, - unpack: bytes.hexify, -}); +const fallbackBytesCodec = byteVecOf({ pack: bytes.bytify, unpack: bytes.hexify }); function createFallbackFixedBytesCodec(byteLength: number) { return createFixedBytesCodec({ diff --git a/examples/molecule-codegen-dir/generated/skills.ts b/examples/molecule-codegen-dir/generated/skills.ts index 60c92b0c7..5797ad904 100644 --- a/examples/molecule-codegen-dir/generated/skills.ts +++ b/examples/molecule-codegen-dir/generated/skills.ts @@ -4,12 +4,9 @@ import { bytes, createBytesCodec, createFixedBytesCodec, molecule } from "@ckb-l import { Uint32, Uint64, Uint128, DepType, HashType } from '../customized' import { AttrValue, SkillLevel, Uint8, Uint16 } from './common/basic_types' -const { array, vector, union, option, struct, table } = molecule; +const { array, vector, union, option, struct, table, byteVecOf } = molecule; -const fallbackBytesCodec = createBytesCodec({ - pack: bytes.bytify, - unpack: bytes.hexify, -}); +const fallbackBytesCodec = byteVecOf({ pack: bytes.bytify, unpack: bytes.hexify }); function createFallbackFixedBytesCodec(byteLength: number) { return createFixedBytesCodec({ diff --git a/examples/molecule-codegen/blockchain.ts b/examples/molecule-codegen/blockchain.ts index cffb4fd3d..a539c8660 100644 --- a/examples/molecule-codegen/blockchain.ts +++ b/examples/molecule-codegen/blockchain.ts @@ -1,15 +1,11 @@ // This file is generated by @ckb-lumos/molecule, please do not modify it manually. /* eslint-disable */ - import { bytes, createBytesCodec, createFixedBytesCodec, molecule } from "@ckb-lumos/codec"; import { Uint32, Uint64, Uint128, DepType, HashType } from './customized' -const { array, vector, union, option, struct, table } = molecule; +const { array, vector, union, option, struct, table, byteVecOf } = molecule; -const fallbackBytesCodec = createBytesCodec({ - pack: bytes.bytify, - unpack: bytes.hexify, -}); +const fallbackBytesCodec = byteVecOf({ pack: bytes.bytify, unpack: bytes.hexify }); function createFallbackFixedBytesCodec(byteLength: number) { return createFixedBytesCodec({ @@ -140,3 +136,4 @@ export const BlockV1 = table({ proposals: ProposalShortIdVec, extension: Bytes }, ['header', 'uncles', 'transactions', 'proposals', 'extension']); + diff --git a/packages/molecule/package.json b/packages/molecule/package.json index 0917917d1..e2303aac1 100644 --- a/packages/molecule/package.json +++ b/packages/molecule/package.json @@ -60,6 +60,8 @@ }, "devDependencies": { "@ckb-lumos/base": "0.24.0-next.1", - "jsbi": "^4.1.0" + "jsbi": "^4.1.0", + "js-yaml": "^4.1.0", + "@types/js-yaml": "^4.0.9" } } diff --git a/packages/molecule/src/cli.ts b/packages/molecule/src/cli.ts index 9062659b0..492e0dd9f 100644 --- a/packages/molecule/src/cli.ts +++ b/packages/molecule/src/cli.ts @@ -119,5 +119,5 @@ function outputSingleToConsole(schemaFile: string) { codegenOption ); - console.log(generated); + console.log(generated.code); } diff --git a/packages/molecule/src/codegen.ts b/packages/molecule/src/codegen.ts index c6f440b31..a23a5882e 100644 --- a/packages/molecule/src/codegen.ts +++ b/packages/molecule/src/codegen.ts @@ -198,12 +198,9 @@ export function codegen(schema: string, options: Options = {}): CodegenResult { import { bytes, createBytesCodec, createFixedBytesCodec, molecule } from "@ckb-lumos/codec"; ${options.prepend || ""} -const { array, vector, union, option, struct, table } = molecule; +const { array, vector, union, option, struct, table, byteVecOf } = molecule; -const fallbackBytesCodec = createBytesCodec({ - pack: bytes.bytify, - unpack: bytes.hexify, -}); +const fallbackBytesCodec = byteVecOf({ pack: bytes.bytify, unpack: bytes.hexify }); function createFallbackFixedBytesCodec(byteLength: number) { return createFixedBytesCodec({ diff --git a/packages/molecule/tests/codegen/customization.ts b/packages/molecule/tests/codegen/customization.ts new file mode 100644 index 000000000..31c30666c --- /dev/null +++ b/packages/molecule/tests/codegen/customization.ts @@ -0,0 +1,5 @@ +import { molecule } from "@ckb-lumos/codec"; + +// the compiler does not support empty block declaration +// so the Table0 is manually declared +export const Table0 = molecule.table({}, []); diff --git a/packages/molecule/tests/codegen/generated.ts b/packages/molecule/tests/codegen/generated.ts new file mode 100644 index 000000000..45a2d354a --- /dev/null +++ b/packages/molecule/tests/codegen/generated.ts @@ -0,0 +1,336 @@ +// This file is generated by @ckb-lumos/molecule, please do not modify it manually. +/* eslint-disable */ +import { bytes, createBytesCodec, createFixedBytesCodec, molecule } from "@ckb-lumos/codec"; +import { Table0 } from './customization' + +const { array, vector, union, option, struct, table, byteVecOf } = molecule; + +const fallbackBytesCodec = byteVecOf({ pack: bytes.bytify, unpack: bytes.hexify }); + +function createFallbackFixedBytesCodec(byteLength: number) { + return createFixedBytesCodec({ + pack: bytes.bytify, + unpack: bytes.hexify, + byteLength, + }); +} + +const byte = createFallbackFixedBytesCodec(1); + +export const Byte2 = createFallbackFixedBytesCodec(2); + +export const Byte3 = createFallbackFixedBytesCodec(3); + +export const Byte4 = createFallbackFixedBytesCodec(4); + +export const Byte5 = createFallbackFixedBytesCodec(5); + +export const Byte6 = createFallbackFixedBytesCodec(6); + +export const Byte7 = createFallbackFixedBytesCodec(7); + +export const Byte8 = createFallbackFixedBytesCodec(8); + +export const Byte9 = createFallbackFixedBytesCodec(9); + +export const Byte10 = createFallbackFixedBytesCodec(10); + +export const Byte11 = createFallbackFixedBytesCodec(11); + +export const Byte12 = createFallbackFixedBytesCodec(12); + +export const Byte13 = createFallbackFixedBytesCodec(13); + +export const Byte14 = createFallbackFixedBytesCodec(14); + +export const Byte15 = createFallbackFixedBytesCodec(15); + +export const Byte16 = createFallbackFixedBytesCodec(16); + +export const Word = createFallbackFixedBytesCodec(2); + +export const Word2 = array(Word, 2); + +export const Word3 = array(Word, 3); + +export const Word4 = array(Word, 4); + +export const Word5 = array(Word, 5); + +export const Word6 = array(Word, 6); + +export const Word7 = array(Word, 7); + +export const Word8 = array(Word, 8); + +export const Byte3x3 = array(Byte3, 3); + +export const Byte5x3 = array(Byte5, 3); + +export const Byte7x3 = array(Byte7, 3); + +export const Byte9x3 = array(Byte9, 3); + +export const StructA = struct({ + f1: byte, + f2: byte, + f3: Byte2, + f4: Byte2 +}, ['f1', 'f2', 'f3', 'f4']); + +export const StructB = struct({ + f1: byte, + f2: byte, + f3: Byte2, + f4: Byte3 +}, ['f1', 'f2', 'f3', 'f4']); + +export const StructC = struct({ + f1: byte, + f2: byte, + f3: Byte2, + f4: Byte4 +}, ['f1', 'f2', 'f3', 'f4']); + +export const StructD = struct({ + f1: byte, + f2: byte, + f3: Byte2, + f4: Byte5 +}, ['f1', 'f2', 'f3', 'f4']); + +export const StructE = struct({ + f1: byte, + f2: Byte2, + f3: byte, + f4: Byte2 +}, ['f1', 'f2', 'f3', 'f4']); + +export const StructF = struct({ + f1: byte, + f2: Byte3, + f3: byte +}, ['f1', 'f2', 'f3']); + +export const StructG = struct({ + f1: Byte3, + f2: byte, + f3: Byte2, + f4: Word2 +}, ['f1', 'f2', 'f3', 'f4']); + +export const StructH = struct({ + f1: Byte3, + f2: byte, + f3: Byte2, + f4: Byte4 +}, ['f1', 'f2', 'f3', 'f4']); + +export const StructI = struct({ + f1: Byte3, + f2: byte +}, ['f1', 'f2']); + +export const StructJ = struct({ + f1: Byte6, + f2: byte +}, ['f1', 'f2']); + +export const StructIx3 = array(StructI, 3); + +export const StructO = struct({ + f1: StructIx3, + f2: byte +}, ['f1', 'f2']); + +export const StructP = struct({ + f1: StructJ, + f2: byte +}, ['f1', 'f2']); + +export const Bytes = fallbackBytesCodec; + +export const Words = vector(Word); + +export const Byte3Vec = vector(Byte3); + +export const Byte7Vec = vector(Byte7); + +export const StructIVec = vector(StructI); + +export const StructJVec = vector(StructJ); + +export const StructPVec = vector(StructP); + +export const BytesVec = vector(Bytes); + +export const WordsVec = vector(Words); + +export const Table1 = table({ + f1: byte +}, ['f1']); + +export const Table2 = table({ + f1: byte, + f2: Word2 +}, ['f1', 'f2']); + +export const Table3 = table({ + f1: byte, + f2: Word2, + f3: StructA +}, ['f1', 'f2', 'f3']); + +export const Table4 = table({ + f1: byte, + f2: Word2, + f3: StructA, + f4: Bytes +}, ['f1', 'f2', 'f3', 'f4']); + +export const Table5 = table({ + f1: byte, + f2: Word2, + f3: StructA, + f4: Bytes, + f5: BytesVec +}, ['f1', 'f2', 'f3', 'f4', 'f5']); + +export const Table6 = table({ + f1: byte, + f2: Word2, + f3: StructA, + f4: Bytes, + f5: BytesVec, + f6: Table5 +}, ['f1', 'f2', 'f3', 'f4', 'f5', 'f6']); + +export const ByteOpt = option(byte); + +export const WordOpt = option(Word); + +export const StructAOpt = option(StructA); + +export const StructPOpt = option(StructP); + +export const BytesOpt = option(Bytes); + +export const WordsOpt = option(Words); + +export const BytesVecOpt = option(BytesVec); + +export const WordsVecOpt = option(WordsVec); + +export const Table0Opt = option(Table0); + +export const Table6Opt = option(Table6); + +export const Table6OptOpt = option(Table6Opt); + +export const ByteOptVec = vector(ByteOpt); + +export const WordOptVec = vector(WordOpt); + +export const WordsOptVec = vector(WordsOpt); + +export const BytesOptVec = vector(BytesOpt); + +export const UnionA = union({ + byte, + Word, + StructA, + Bytes, + Words, + Table0, + Table6, + Table6Opt +}, ['byte', 'Word', 'StructA', 'Bytes', 'Words', 'Table0', 'Table6', 'Table6Opt']); + +export const TableA = table({ + f1: Word2, + f2: StructA, + f3: Bytes, + f4: BytesVec, + f5: Table1, + f6: BytesOpt, + f7: UnionA, + f8: byte +}, ['f1', 'f2', 'f3', 'f4', 'f5', 'f6', 'f7', 'f8']); + +export const AllInOne = table({ + f0: byte, + f1: Byte2, + f2: Byte3, + f3: Byte4, + f4: Byte5, + f5: Byte6, + f6: Byte7, + f7: Byte8, + f8: Byte9, + f9: Byte10, + f10: Byte11, + f11: Byte12, + f12: Byte13, + f13: Byte14, + f14: Byte15, + f15: Byte16, + f16: Word, + f17: Word2, + f18: Word3, + f19: Word4, + f20: Word5, + f21: Word6, + f22: Word7, + f23: Word8, + f24: Byte3x3, + f25: Byte5x3, + f26: Byte7x3, + f27: Byte9x3, + f28: StructA, + f29: StructB, + f30: StructC, + f31: StructD, + f32: StructE, + f33: StructF, + f34: StructG, + f35: StructH, + f36: StructI, + f37: StructJ, + f38: StructIx3, + f39: StructO, + f40: StructP, + f41: Bytes, + f42: Words, + f43: Byte3Vec, + f44: Byte7Vec, + f45: StructIVec, + f46: StructJVec, + f47: StructPVec, + f48: BytesVec, + f49: WordsVec, + f50: Table0, + f51: Table1, + f52: Table2, + f53: Table3, + f54: Table4, + f55: Table5, + f56: Table6, + f57: ByteOpt, + f58: WordOpt, + f59: StructAOpt, + f60: StructPOpt, + f61: BytesOpt, + f62: WordsOpt, + f63: BytesVecOpt, + f64: WordsVecOpt, + f65: Table0Opt, + f66: Table6Opt, + f67: Table6OptOpt, + f68: ByteOptVec, + f69: WordOptVec, + f70: WordsOptVec, + f71: BytesOptVec, + f72: UnionA, + f73: TableA +}, ['f0', 'f1', 'f2', 'f3', 'f4', 'f5', 'f6', 'f7', 'f8', 'f9', 'f10', 'f11', 'f12', 'f13', 'f14', 'f15', 'f16', 'f17', 'f18', 'f19', 'f20', 'f21', 'f22', 'f23', 'f24', 'f25', 'f26', 'f27', 'f28', 'f29', 'f30', 'f31', 'f32', 'f33', 'f34', 'f35', 'f36', 'f37', 'f38', 'f39', 'f40', 'f41', 'f42', 'f43', 'f44', 'f45', 'f46', 'f47', 'f48', 'f49', 'f50', 'f51', 'f52', 'f53', 'f54', 'f55', 'f56', 'f57', 'f58', 'f59', 'f60', 'f61', 'f62', 'f63', 'f64', 'f65', 'f66', 'f67', 'f68', 'f69', 'f70', 'f71', 'f72', 'f73']); + diff --git a/packages/molecule/tests/codegen/lumos-molecule-codegen.json b/packages/molecule/tests/codegen/lumos-molecule-codegen.json new file mode 100644 index 000000000..7d7a01b54 --- /dev/null +++ b/packages/molecule/tests/codegen/lumos-molecule-codegen.json @@ -0,0 +1,4 @@ +{ + "schemaFile": "types.mol", + "prepend": "import { Table0 } from './customization'" +} diff --git a/packages/molecule/tests/codegen/simple.test.ts b/packages/molecule/tests/codegen/simple.test.ts new file mode 100644 index 000000000..06f7f477a --- /dev/null +++ b/packages/molecule/tests/codegen/simple.test.ts @@ -0,0 +1,69 @@ +/* +The test +using the Molecule schema from [types.mol](https://github.com/nervosnetwork/molecule/blob/4988418dd65c398b5eab2bc22bc125b72ceeb4b9/test/schemas/types.mol) and corresponding vector from [simple.yaml](https://github.com/nervosnetwork/molecule/blob/4988418dd65c398b5eab2bc22bc125b72ceeb4b9/test/vectors/simple.yaml). +This test checks if the generated code works as expected by running `pack(unpack(item)) == expected`. + +To run the test from scratch, please make sure the pwd is `/path/to/lumos/packages/molecule/tests/codegen` + +```sh +node ../../lib/cli > generated.ts +``` +*/ + +import test from "ava"; +import path from "node:path"; +import * as fs from "node:fs"; +import { load } from "js-yaml"; +import * as generated from "./generated"; +import { AnyCodec, bytes } from "@ckb-lumos/codec"; + +test("Test codegen examples", () => { + const yamlItems = load( + fs.readFileSync(path.join(__dirname, "tests/simple.yaml")).toString() + ) as any[]; + + const x = yamlItems.map((testCase) => { + let data: object | string[] | undefined = undefined; + if (Array.isArray(testCase.data)) { + data = testCase.data.map((dataItem: any) => + dataItem.replace(/[_/]/gi, "") + ); + } else if (typeof testCase.data === "object") { + data = {}; + Object.entries(testCase.data).forEach((testCaseDataEntry) => { + Object.assign(data as object, { + [testCaseDataEntry[0]]: (testCaseDataEntry[1] as string).replace( + /[_/]/gi, + "" + ), + }); + }); + } + let caseItem: object | string | undefined = undefined; + if (typeof testCase.item === "string") { + caseItem = testCase.item.replace(/[_/]/gi, ""); + } else if (typeof testCase.item === "object") { + caseItem = {}; + Object.entries(testCase.item).forEach((testCaseItemEntry) => { + Object.assign(caseItem as object, { + [testCaseItemEntry[0]]: (testCaseItemEntry[1] as string).replace( + /[_/]/gi, + "" + ), + }); + }); + } + return { + name: testCase.name as keyof typeof generated, + data, + item: caseItem, + expected: testCase.expected.replace(/[_/]/gi, ""), + }; + }); + + x.forEach(({ name, expected }) => { + // eslint-disable-next-line import/namespace + const c = generated[name] as AnyCodec; + console.log(bytes.equal(c.pack(c.unpack(expected)), expected)); + }); +}); diff --git a/packages/molecule/tests/codegen/simple.yaml b/packages/molecule/tests/codegen/simple.yaml new file mode 100644 index 000000000..9ff25c12f --- /dev/null +++ b/packages/molecule/tests/codegen/simple.yaml @@ -0,0 +1,529 @@ +# +# Array +# +- + name: Byte7 + data: + 0: "0x01" + expected: "0x01000000_000000" +- + name: Byte7 + data: + 0: "0x01" + 3: "0x03" + expected: "0x01000003_000000" +- + name: Byte7 + data: + 0: "0x01" + 3: "0x03" + 6: "0x06" + expected: "0x01000003_000006" +# +# Struct +# +- + name: StructH + data: + f1: "0x001122" + expected: "0x001122/00/0000/00000000" +- + name: StructH + data: + f2: "0x33" + expected: "0x000000/33/0000/00000000" +- + name: StructH + data: + f3: "0x4455" + expected: "0x000000/00/4455/00000000" +- + name: StructH + data: + f4: "0x66778899" + expected: "0x000000/00/0000/66778899" +- + name: StructH + data: + f1: "0x001122" + f2: "0x33" + expected: "0x001122/33/0000/00000000" +- + name: StructH + data: + f1: "0x001122" + f2: "0x33" + f3: "0x4455" + expected: "0x001122/33/4455/00000000" +- + name: StructH + data: + f1: "0x001122" + f2: "0x33" + f3: "0x4455" + f4: "0x66778899" + expected: "0x001122/33/4455/66778899" +# +# Vector +# +- + name: Bytes + data: + - "0x01" + expected: "0x01000000//01" +- + name: Bytes + data: + - "0x01" + - "0x02" + expected: "0x02000000//01/02" +- + name: Bytes + data: + - "0x01" + - "0x02" + - "0x03" + expected: "0x03000000//01/02/03" +- + name: Words + data: + - "0x0123" + expected: "0x01000000//0123" +- + name: Words + data: + - "0x0123" + - "0x4567" + expected: "0x02000000//0123/4567" +- + name: Words + data: + - "0x0123" + - "0x4567" + - "0x89ab" + expected: "0x03000000//0123/4567/89ab" +- + name: Byte3Vec + data: + - "0x000000" + expected: "0x01000000//000000" +- + name: Byte3Vec + data: + - "0x000000" + - "0x111111" + expected: "0x02000000//000000/111111" +- + name: Byte3Vec + data: + - "0x000000" + - "0x111111" + - "0x222222" + expected: "0x03000000//000000/111111/222222" +- + name: Byte7Vec + data: + - "0x00000000_000000" + expected: "0x01000000//\ + 00000000_000000" +- + name: Byte7Vec + data: + - "0x00000000_000000" + - "0x11111111_111111" + expected: "0x02000000//\ + 00000000_000000/\ + 11111111_111111" +- + name: Byte7Vec + data: + - "0x00000000_000000" + - "0x11111111_111111" + - "0x22222222_222222" + expected: "0x03000000//\ + 00000000_000000/\ + 11111111_111111/\ + 22222222_222222" +- + name: StructIVec + data: + - "0x00000000" + expected: "0x01000000//00000000" +- + name: StructIVec + data: + - "0x00000000" + - "0x11111111" + expected: "0x02000000//00000000/11111111" +- + name: StructIVec + data: + - "0x00000000" + - "0x11111111" + - "0x22222222" + expected: "0x03000000//00000000/11111111/22222222" +- + name: StructJVec + data: + - "0x00000000_000000" + expected: "0x01000000//\ + 00000000_000000" +- + name: StructJVec + data: + - "0x00000000_000000" + - "0x11111111_111111" + expected: "0x02000000//\ + 00000000_000000/\ + 11111111_111111" +- + name: StructJVec + data: + - "0x00000000_000000" + - "0x11111111_111111" + - "0x22222222_222222" + expected: "0x03000000//\ + 00000000_000000/\ + 11111111_111111/\ + 22222222_222222" +- + name: StructPVec + data: + - "0x00000000_00000000" + expected: "0x01000000//\ + 00000000_00000000" +- + name: StructPVec + data: + - "0x00000000_00000000" + - "0x11111111_11111111" + expected: "0x02000000//\ + 00000000_00000000/\ + 11111111_11111111" +- + name: StructPVec + data: + - "0x00000000_00000000" + - "0x11111111_11111111" + - "0x22222222_22222222" + expected: "0x03000000//\ + 00000000_00000000/\ + 11111111_11111111/\ + 22222222_22222222" +- + name: BytesVec + data: + - "0x00000000" + expected: "0x0c000000//08000000//00000000" +- + name: BytesVec + data: + - "0x00000000" + - "0x01000000//00" + expected: "0x15000000//\ + 0c000000_10000000//\ + 00000000\ + 01000000//00" +- + name: BytesVec + data: + - "0x00000000" + - "0x01000000//00" + - "0x02000000//00/11" + expected: "0x1f000000//\ + 10000000_14000000_19000000//\ + 00000000\ + 01000000//00\ + 02000000//00/11" +- + name: WordsVec + data: + - "0x00000000" + expected: "0x0c000000//08000000//00000000" +- + name: WordsVec + data: + - "0x00000000" + - "0x01000000//0000" + expected: "0x16000000//\ + 0c000000_10000000//\ + 00000000\ + 01000000//0000" +- + name: WordsVec + data: + - "0x00000000" + - "0x01000000//0000" + - "0x02000000//0000/1111" + expected: "0x22000000//\ + 10000000_14000000_1a000000//\ + 00000000\ + 01000000//0000\ + 02000000//0000/1111" +- + name: ByteOptVec + data: + - "0x" + expected: "0x08000000//08000000//" +- + name: ByteOptVec + data: + - "0x" + - "0x" + expected: "0x0c000000//0c000000_0c000000//" +- + name: ByteOptVec + data: + - "0x" + - "0x" + - "0x" + expected: "0x10000000//10000000_10000000_10000000//" +# +# Table +- + name: Table5 + data: + f4: "0x02000000_1234" + expected: "0x2d000000//\ + 18000000_19000000_1d000000_23000000_29000000//\ + 00/00000000/00000000_0000/02000000_1234/04000000" +- + name: Table5 + data: + f4: "0x02000000_1234" + f5: "0x1f000000//\ + 10000000_14000000_19000000//\ + 00000000\ + 01000000//00\ + 02000000//00/11" + expected: "0x48000000//\ + 18000000_19000000_1d000000_23000000_29000000//\ + 00/00000000/00000000_0000/02000000_1234/\ + \ + 1f000000//\ + 10000000_14000000_19000000//\ + 00000000\ + 01000000//00\ + 02000000//00/11" +- + name: TableA + data: + f1: "0x12345678" + f2: "0xaabbccdd_eeff" + f4: "0x1f000000//\ + 10000000_14000000_19000000//\ + 00000000\ + 01000000//00\ + 02000000//00/11" + f6: "0x00000000" + f7: "0x03000000//00000000" + f8: "0x99" + expected: "0x67000000//\ + 24000000_28000000_2e000000_32000000_\ + 51000000_5a000000_5e000000_66000000//\ + \ + 12345678/aabbccdd_eeff/00000000/\ + \ + 1f000000//\ + 10000000_14000000_19000000//\ + 00000000\ + 01000000//00\ + 02000000//00/11\ + \ + 09000000\ + 08000000\ + 00\ + \ + 00000000\ + \ + 03000000\ + 00000000\ + \ + 99" +# +# +# Option +# +- + name: ByteOpt + item: "0x00" + expected: "0x00" +- + name: WordOpt + item: "0x0000" + expected: "0x0000" +- + name: StructAOpt + item: "0x00/00/0000/0000" + expected: "0x00/00/0000/0000" +- + name: StructPOpt + item: "0x00000000_000000/00" + expected: "0x00000000_000000/00" +- + name: BytesOpt + item: "0x00000000" + expected: "0x00000000" +- + name: WordsOpt + item: "0x00000000" + expected: "0x00000000" +- + name: BytesVecOpt + item: "0x04000000" + expected: "0x04000000" +- + name: WordsVecOpt + item: "0x04000000" + expected: "0x04000000" +- + name: Table0Opt + item: "0x04000000" + expected: "0x04000000" +- + name: Table6Opt + item: "0x5a000000//\ + 1c000000_1d000000_21000000_27000000_2b000000_2f000000//\ + 00/00000000/00000000_0000/00000000/04000000/\ + \ + 2b000000\ + 18000000_19000000_1d000000_23000000_27000000\ + 00\ + 00000000\ + 00000000_0000\ + 00000000\ + 04000000" + expected: "0x5a000000//\ + 1c000000_1d000000_21000000_27000000_2b000000_2f000000//\ + 00/00000000/00000000_0000/00000000/04000000/\ + \ + 2b000000\ + 18000000_19000000_1d000000_23000000_27000000\ + 00\ + 00000000\ + 00000000_0000\ + 00000000\ + 04000000" +- + name: Table6OptOpt + item: "0x5a000000//\ + 1c000000_1d000000_21000000_27000000_2b000000_2f000000//\ + 00/00000000/00000000_0000/00000000/04000000/\ + \ + 2b000000\ + 18000000_19000000_1d000000_23000000_27000000\ + 00\ + 00000000\ + 00000000_0000\ + 00000000\ + 04000000" + expected: "0x5a000000//\ + 1c000000_1d000000_21000000_27000000_2b000000_2f000000//\ + 00/00000000/00000000_0000/00000000/04000000/\ + \ + 2b000000\ + 18000000_19000000_1d000000_23000000_27000000\ + 00\ + 00000000\ + 00000000_0000\ + 00000000\ + 04000000" +# +# Union +# +- + name: UnionA + item: + type: byte + data: "0x00" + expected: "0x00000000//00" +- + name: UnionA + item: + type: Word + data: "0x0000" + expected: "0x01000000//0000" +- + name: UnionA + item: + type: StructA + data: "0x00/00/0000/0000" + expected: "0x02000000//00/00/0000/0000" +- + name: UnionA + item: + type: Bytes + data: "0x00000000" + expected: "0x03000000//00000000" +- + name: UnionA + item: + type: Words + data: "0x00000000" + expected: "0x04000000//00000000" +- + name: UnionA + item: + type: Table0 + data: "0x04000000" + expected: "0x05000000//04000000" +- + name: UnionA + item: + type: Table6 + data: "0x5a000000//\ + 1c000000_1d000000_21000000_27000000_2b000000_2f000000//\ + 00/00000000/00000000_0000/00000000/04000000/\ + \ + 2b000000\ + 18000000_19000000_1d000000_23000000_27000000\ + 00\ + 00000000\ + 00000000_0000\ + 00000000\ + 04000000" + expected: "0x06000000//\ + 5a000000//\ + 1c000000_1d000000_21000000_27000000_2b000000_2f000000//\ + 00/00000000/00000000_0000/00000000/04000000/\ + \ + 2b000000\ + 18000000_19000000_1d000000_23000000_27000000\ + 00\ + 00000000\ + 00000000_0000\ + 00000000\ + 04000000" +- + name: UnionA + item: + type: Table6Opt + data: "0x" + expected: "0x07000000" +- + name: UnionA + item: + type: Table6Opt + data: "0x5a000000//\ + 1c000000_1d000000_21000000_27000000_2b000000_2f000000//\ + 00/00000000/00000000_0000/00000000/04000000/\ + \ + 2b000000\ + 18000000_19000000_1d000000_23000000_27000000\ + 00\ + 00000000\ + 00000000_0000\ + 00000000\ + 04000000" + expected: "0x07000000//\ + 5a000000//\ + 1c000000_1d000000_21000000_27000000_2b000000_2f000000//\ + 00/00000000/00000000_0000/00000000/04000000/\ + \ + 2b000000\ + 18000000_19000000_1d000000_23000000_27000000\ + 00\ + 00000000\ + 00000000_0000\ + 00000000\ + 04000000" diff --git a/packages/molecule/tests/codegen/types.mol b/packages/molecule/tests/codegen/types.mol new file mode 100644 index 000000000..9bd3cb587 --- /dev/null +++ b/packages/molecule/tests/codegen/types.mol @@ -0,0 +1,263 @@ +array Byte2 [byte; 2]; +array Byte3 [byte; 3]; +array Byte4 [byte; 4]; +array Byte5 [byte; 5]; +array Byte6 [byte; 6]; +array Byte7 [byte; 7]; +array Byte8 [byte; 8]; +array Byte9 [byte; 9]; +array Byte10 [byte; 10]; +array Byte11 [byte; 11]; +array Byte12 [byte; 12]; +array Byte13 [byte; 13]; +array Byte14 [byte; 14]; +array Byte15 [byte; 15]; +array Byte16 [byte; 16]; + +array Word [byte; 2]; +array Word2 [Word; 2]; +array Word3 [Word; 3]; +array Word4 [Word; 4]; +array Word5 [Word; 5]; +array Word6 [Word; 6]; +array Word7 [Word; 7]; +array Word8 [Word; 8]; + +array Byte3x3 [Byte3; 3]; +array Byte5x3 [Byte5; 3]; +array Byte7x3 [Byte7; 3]; +array Byte9x3 [Byte9; 3]; + +struct StructA { + f1: byte, + f2: byte, + f3: Byte2, + f4: Byte2, +} +struct StructB { + f1: byte, + f2: byte, + f3: Byte2, + f4: Byte3, +} +struct StructC { + f1: byte, + f2: byte, + f3: Byte2, + f4: Byte4, +} +struct StructD { + f1: byte, + f2: byte, + f3: Byte2, + f4: Byte5, +} +struct StructE { + f1: byte, + f2: Byte2, + f3: byte, + f4: Byte2, +} +struct StructF { + f1: byte, + f2: Byte3, + f3: byte, +} +struct StructG { + f1: Byte3, + f2: byte, + f3: Byte2, + f4: Word2, +} +struct StructH { + f1: Byte3, + f2: byte, + f3: Byte2, + f4: Byte4, +} +struct StructI { + f1: Byte3, + f2: byte, +} +struct StructJ { + f1: Byte6, + f2: byte, +} + +array StructIx3 [StructI; 3]; + +struct StructO { + f1: StructIx3, + f2: byte, +} +struct StructP { + f1: StructJ, + f2: byte, +} + +vector Bytes ; +vector Words ; + +vector Byte3Vec ; +vector Byte7Vec ; +vector StructIVec ; +vector StructJVec ; +vector StructPVec ; + +vector BytesVec ; +vector WordsVec ; + +table Table1 { + f1: byte, +} + +table Table2 { + f1: byte, + f2: Word2, +} + +table Table3 { + f1: byte, + f2: Word2, + f3: StructA, +} + +table Table4 { + f1: byte, + f2: Word2, + f3: StructA, + f4: Bytes, +} + +table Table5 { + f1: byte, + f2: Word2, + f3: StructA, + f4: Bytes, + f5: BytesVec, +} + +table Table6 { + f1: byte, + f2: Word2, + f3: StructA, + f4: Bytes, + f5: BytesVec, + f6: Table5, +} + +option ByteOpt (byte); +option WordOpt (Word); +option StructAOpt (StructA); +option StructPOpt (StructP); +option BytesOpt (Bytes); +option WordsOpt (Words); +option BytesVecOpt (BytesVec); +option WordsVecOpt (WordsVec); +option Table0Opt (Table0); +option Table6Opt (Table6); +option Table6OptOpt (Table6Opt); + +vector ByteOptVec ; +vector WordOptVec ; +vector WordsOptVec ; +vector BytesOptVec ; + +union UnionA { + byte, + Word, + StructA, + Bytes, + Words, + Table0, + Table6, + Table6Opt, +} + +table TableA { + f1: Word2, + f2: StructA, + f3: Bytes, + f4: BytesVec, + f5: Table1, + f6: BytesOpt, + f7: UnionA, + f8: byte, +} + +table AllInOne { + f0: byte, + f1: Byte2, + f2: Byte3, + f3: Byte4, + f4: Byte5, + f5: Byte6, + f6: Byte7, + f7: Byte8, + f8: Byte9, + f9: Byte10, + f10: Byte11, + f11: Byte12, + f12: Byte13, + f13: Byte14, + f14: Byte15, + f15: Byte16, + f16: Word, + f17: Word2, + f18: Word3, + f19: Word4, + f20: Word5, + f21: Word6, + f22: Word7, + f23: Word8, + f24: Byte3x3, + f25: Byte5x3, + f26: Byte7x3, + f27: Byte9x3, + f28: StructA, + f29: StructB, + f30: StructC, + f31: StructD, + f32: StructE, + f33: StructF, + f34: StructG, + f35: StructH, + f36: StructI, + f37: StructJ, + f38: StructIx3, + f39: StructO, + f40: StructP, + f41: Bytes, + f42: Words, + f43: Byte3Vec, + f44: Byte7Vec, + f45: StructIVec, + f46: StructJVec, + f47: StructPVec, + f48: BytesVec, + f49: WordsVec, + f50: Table0, + f51: Table1, + f52: Table2, + f53: Table3, + f54: Table4, + f55: Table5, + f56: Table6, + f57: ByteOpt, + f58: WordOpt, + f59: StructAOpt, + f60: StructPOpt, + f61: BytesOpt, + f62: WordsOpt, + f63: BytesVecOpt, + f64: WordsVecOpt, + f65: Table0Opt, + f66: Table6Opt, + f67: Table6OptOpt, + f68: ByteOptVec, + f69: WordOptVec, + f70: WordsOptVec, + f71: BytesOptVec, + f72: UnionA, + f73: TableA, +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 67d221578..7214c40ed 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -690,6 +690,12 @@ importers: '@ckb-lumos/base': specifier: 0.24.0-next.1 version: link:../base + '@types/js-yaml': + specifier: ^4.0.9 + version: 4.0.9 + js-yaml: + specifier: ^4.1.0 + version: 4.1.0 jsbi: specifier: ^4.1.0 version: 4.3.0 @@ -4959,6 +4965,10 @@ packages: pretty-format: 29.7.0 dev: true + /@types/js-yaml@4.0.9: + resolution: {integrity: sha512-k4MGaQl5TGo/iipqb2UDG2UwjXziSWkh0uysQelTlJpX1qGlpUZYm8PnO4DxG1qBomtJUdYJ6qR6xdIah10JLg==} + dev: true + /@types/json-schema@7.0.15: resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==}