Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New Func backend: First iteration #559

Draft
wants to merge 163 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 115 commits
Commits
Show all changes
163 commits
Select commit Hold shift + click to select a range
3e7c7b4
feat: Initial draft of the new backend.
byakuren-hijiri Jul 12, 2024
60831d1
feat(codegen): Support all `ops`
byakuren-hijiri Jul 13, 2024
a221569
feat(codegen): Support unary expressions + refactor
byakuren-hijiri Jul 13, 2024
d7acbb2
feat(func): Support regular assigns
byakuren-hijiri Jul 13, 2024
29cf7b5
feat(codegen): Support assign statements
byakuren-hijiri Jul 13, 2024
11a1487
chore(codegen): Refactor statements
byakuren-hijiri Jul 13, 2024
c989cb8
feat(codegen): Support field access
byakuren-hijiri Jul 13, 2024
477eb2c
fix(syntax): Remove assignments from available binary operations
byakuren-hijiri Jul 13, 2024
2fd26e7
chore(syntax): Refactor
byakuren-hijiri Jul 13, 2024
b327bb9
feat(codegen): Support all the binary expressions
byakuren-hijiri Jul 13, 2024
811d659
chore(function): Reuse `resolveFuncType`
byakuren-hijiri Jul 13, 2024
5c0af8a
feat(codegen): Constructor functions + relevant changes in AST
byakuren-hijiri Jul 14, 2024
c7bfbc9
chore(codegen): Func example
byakuren-hijiri Jul 14, 2024
2f219f3
feat(codegen): Introduce `CodegenContext`
byakuren-hijiri Jul 14, 2024
7d5e5f3
feat(codegen): Calls to constructor functions + context-related logic
byakuren-hijiri Jul 14, 2024
b0f0dc4
feat(codegen): Support struct values/objects
byakuren-hijiri Jul 14, 2024
a7f85c5
fix(codegen): Minor errors
byakuren-hijiri Jul 14, 2024
e3e0715
feat(ast): Multiline comments
byakuren-hijiri Jul 14, 2024
ee6d514
fix(formatter): Function signatures
byakuren-hijiri Jul 14, 2024
271f3c8
feat(formatter): Indentation
byakuren-hijiri Jul 14, 2024
bd067c1
chore(formatter): Extra newlines
byakuren-hijiri Jul 14, 2024
03f7328
feat(codegen): Comments, pragmas, includes in the generated contract
byakuren-hijiri Jul 14, 2024
583bec2
fix(formatter): VarDef w/ local type inference
byakuren-hijiri Jul 14, 2024
ca0b094
fix(codegen): tuples=>tensors as return values of functions
byakuren-hijiri Jul 14, 2024
515e89e
feat(codegen): contract=>module; draft main contract generation logic
byakuren-hijiri Jul 14, 2024
063e2e3
feat(codegen): Support `init_of` and ternary expressions
byakuren-hijiri Jul 14, 2024
75bcb70
feat(syntax): Function definition/declaration
byakuren-hijiri Jul 15, 2024
cd22057
feat(codegen): Support multi-file generation
byakuren-hijiri Jul 15, 2024
77d7b64
feat(codegen): `lazy_deployment_completed` and `get_abi_ipfs`
byakuren-hijiri Jul 15, 2024
1e3e435
feat(syntax): Support string literal types
byakuren-hijiri Jul 15, 2024
da80237
feat(codegen): Generate `supported_interfaces`
byakuren-hijiri Jul 15, 2024
ad7d2ec
feat(syntax): Introduce `constructors`
byakuren-hijiri Jul 16, 2024
0b0383d
feat(syntax+fmt): Support hex int literals; refactor
byakuren-hijiri Jul 17, 2024
6c86d61
fix(fmt): Missing semicolons
byakuren-hijiri Jul 17, 2024
3f0ed5b
feat(codegen): Routers; handlers for receivers
byakuren-hijiri Jul 17, 2024
9ccdbff
feat(syntax+codegen): Support new AST constructors
byakuren-hijiri Jul 17, 2024
9611476
feat(syntax): Support different comment styles
byakuren-hijiri Jul 18, 2024
c8ce46a
chore(syntax): %s/varDef/vardef/g for consistency
byakuren-hijiri Jul 18, 2024
e9a0166
feat(syntax): Utilize `FuncAstIdExpr` for names instead of raw strings
byakuren-hijiri Jul 18, 2024
571b126
feat(tests): Differential tests based on jest' diff utility
byakuren-hijiri Jul 18, 2024
f557114
fix(fmt): Minor fixes
byakuren-hijiri Jul 18, 2024
29701e6
fix(fmt): Trailing whitespaces in comments
byakuren-hijiri Jul 18, 2024
93932d4
fix(codegen): Typo
byakuren-hijiri Jul 18, 2024
59c5202
feat(formatter): line length limit + multiline tensor expressions
byakuren-hijiri Jul 19, 2024
559b406
feat(syntax+formatter): Support function receivers
byakuren-hijiri Jul 19, 2024
8db5675
fix(codegen): Correct function receivers
byakuren-hijiri Jul 19, 2024
a2ee2b8
chore(compile): Optional debug prints for codegen output
byakuren-hijiri Jul 19, 2024
fad1dc6
fix(codegen): Get rid of extra function attributes
byakuren-hijiri Jul 19, 2024
97216d1
chore(codegen): Replace the rest of ad-hoc initializers w/ constructors
byakuren-hijiri Jul 19, 2024
f666ac0
feat(syntax): Extra check for implicit `Object`->`string` conversion
byakuren-hijiri Jul 19, 2024
e23bbd5
feat(syntax): `asm` functions
byakuren-hijiri Jul 19, 2024
fc69661
feat(codegen): Separate `Literal` generator; string literals support
byakuren-hijiri Jul 19, 2024
245e4c9
feat(codegen): Support `Address`
byakuren-hijiri Jul 19, 2024
7204e74
feat(codegen): Support `Cell` and `Comment` literals
byakuren-hijiri Jul 19, 2024
7b564f1
chore(syntax): More informative error message
byakuren-hijiri Jul 19, 2024
2debb1e
fix(codegen): `[object Object]` in output
byakuren-hijiri Jul 19, 2024
442dcad
fix(codegen): Comment position
byakuren-hijiri Jul 19, 2024
2b3f4f2
feat(syntax): Support extra CR
byakuren-hijiri Jul 20, 2024
5961ff2
feat(codegen): Support receivers
byakuren-hijiri Jul 20, 2024
9065452
feat(syntax): Support value in `method_id` attributes
byakuren-hijiri Jul 20, 2024
9baeac5
fix(codegen): Comment position
byakuren-hijiri Jul 20, 2024
49d246c
feat(codegen): Support getters
byakuren-hijiri Jul 20, 2024
aff835e
feat(codegen): CRs in routers code to look as the old backend
byakuren-hijiri Jul 20, 2024
6cf09e5
feat(codegen): Context management to replicate some `Writer` logic
byakuren-hijiri Jul 21, 2024
39d3127
feat(codegen): Support internal receivers
byakuren-hijiri Jul 22, 2024
1a655d8
fix(codgen): Bug in the old backend
byakuren-hijiri Jul 22, 2024
9cddfa1
feat(codegen): Support external receivers
byakuren-hijiri Jul 22, 2024
cc88488
fix(codegen): Arguments of `throw_unless`
byakuren-hijiri Jul 23, 2024
51defe8
feat(formatter): Set parens around non-trivial unary expressions
byakuren-hijiri Jul 23, 2024
265cf94
feat(codegen): More convinient context API for adding function
byakuren-hijiri Jul 23, 2024
2a058ec
feat(codegen): Support init and initChild functions
byakuren-hijiri Jul 23, 2024
d9a9e59
feat(codegen): Add primitives
byakuren-hijiri Jul 23, 2024
d27e246
chore(codegen): Revisit the structure of `writeProgram`
byakuren-hijiri Jul 23, 2024
6929720
feat(codegen): Support native Func code
byakuren-hijiri Jul 23, 2024
0ecdaba
feat(codegen): Generate the constants file
byakuren-hijiri Jul 23, 2024
34df3be
feat(codegen): Support storage
byakuren-hijiri Jul 24, 2024
089e87c
fix(formatter): Extra space in fun declarations w/o attrs
byakuren-hijiri Jul 24, 2024
8e97c7e
feat(syntax): Func syntax iterator
byakuren-hijiri Jul 24, 2024
a938e04
feat(codegen): Automatic depdendency detection
byakuren-hijiri Jul 24, 2024
e98e2f1
chore(codegen): Skip dependencies check
byakuren-hijiri Jul 24, 2024
e5578ce
feat(codegen): Introduce hacks in dependency management to overcome m…
byakuren-hijiri Jul 25, 2024
8d704c2
chore(codegen): Restructure, to make `writeAll` more explicit
byakuren-hijiri Jul 25, 2024
660bf84
feat(syntax): Support variables unpacking
byakuren-hijiri Jul 25, 2024
1a16faf
feat(codgen): WIP stdlib translation to showcase how it looks like
byakuren-hijiri Jul 25, 2024
75b6952
test: small subset of functions in stdlib for testing FunC grammar
novusnota Jul 25, 2024
33b6b65
WIP: FunC grammar & parser
novusnota Jul 25, 2024
8d32ff8
feat(func-parser): mostly finished the expressions and fixed types
novusnota Jul 26, 2024
8bc2486
feat: tested top-level things, added more tests for identifiers
novusnota Jul 28, 2024
bfab588
feat(func-parser): 1/3 of types and semantics
novusnota Jul 29, 2024
21e5253
test(func-parser): covered everything but expressions in tests
novusnota Jul 31, 2024
c6b4916
fix: statements, expressions and types in different contexts
novusnota Aug 1, 2024
8f781f6
test(func-parser): one more sample of an interesting asm function
novusnota Aug 1, 2024
3c5564c
fix(func-parser): multi-line and single-line strings can be placed af…
novusnota Aug 1, 2024
a8fb799
feat/chore(func-parser): types, loc and formatting
novusnota Aug 1, 2024
cec8c17
fix(func-parser): adjust expressions and identifiers
novusnota Aug 2, 2024
e185cfe
func(func-parser): grammar is finally completed, and most tests pass!
novusnota Aug 4, 2024
7286760
fix(func-parser): fixed most of the bugs, working on identifiers star…
novusnota Aug 5, 2024
f1519d2
refactor(func-parser): types, expressions, and whitespace padding
novusnota Aug 5, 2024
c60104a
feat(func-parser): grammar is finally complete and able to parse stdl…
novusnota Aug 7, 2024
6e86d5e
feat(func-parser): worked through most of the types, got to complete …
novusnota Aug 7, 2024
1482754
feat(func-parser): 2/3 of the AST
novusnota Aug 8, 2024
c64dc47
feat(func-parser): completed! :rocket:
novusnota Aug 10, 2024
93acaef
fix(func-parser): bug squashed and lots of tests added
novusnota Aug 11, 2024
f315834
chore(func-parser): change the note
novusnota Aug 11, 2024
9658c5b
chore(func-parser): simplify `upperId`' regex and reformat `grammar.ts`
novusnota Aug 11, 2024
43e1c4c
chore(func-parser): spelling
novusnota Aug 11, 2024
e69cd14
fix(generator): Fix compilation errors
jubnzv Aug 12, 2024
dd7cf6c
feat(grammar): Add dummy definitions
jubnzv Aug 12, 2024
804ab80
chore(grammar): Extract type
jubnzv Aug 12, 2024
a3eee3a
chore(func-parser): remove redundant snapshots and rename couple thin…
novusnota Aug 12, 2024
79b2ad1
feat(func/grammar): Separate hex literal
jubnzv Aug 13, 2024
56f39ea
fix(grammar): Set correct types for assignment' `lhs` and `rhs`
jubnzv Aug 13, 2024
6ebe769
feat(syntaxConstructors): Support new `grammar.ts`
jubnzv Aug 23, 2024
8d1d508
feat(codegen): Adapted the codegen
jubnzv Aug 26, 2024
ed2c982
feat(iterators): Support new grammar
jubnzv Aug 29, 2024
bb0965b
fix(grammar): Forbid ;-style comments
jubnzv Aug 29, 2024
9142be6
fix(codegen): Update some functionality
jubnzv Aug 29, 2024
8fc6f15
feat(func): Half-backed `pp` for the new AST
jubnzv Aug 29, 2024
d036d3e
feat: Finalize new AST translation
jubnzv Aug 29, 2024
6d3999a
fix(syntaxConstructors): Allow empty `method_id`
jubnzv Sep 4, 2024
299d3f7
fix(pp): Support `unit`
jubnzv Sep 4, 2024
4127b02
fix(package.json): Include func grammar bundle to dist
jubnzv Sep 4, 2024
9f54da1
fix(pp): Global types
jubnzv Sep 4, 2024
ea7928f
feat(codegen): Add stdlib
jubnzv Sep 5, 2024
123f7ae
fix(stdlib): Hack for Func parser
jubnzv Sep 6, 2024
3fc4e79
fix(stdlib): Missing brackets
jubnzv Sep 6, 2024
1344fb7
chore(ctx): Add missing `parse`
jubnzv Sep 6, 2024
ac3111a
chore(stdlib): simplify
jubnzv Sep 6, 2024
4f6e849
chore(pp): ppTy as a public interface
jubnzv Sep 7, 2024
be14b13
feat(codegen): Add accessors
jubnzv Sep 7, 2024
41c3f35
fix(accessors): Syntax errors
jubnzv Sep 8, 2024
f675f27
feat(codegen): Serializers
jubnzv Sep 8, 2024
8da2062
fix(util): `funcInitIdOf`
jubnzv Sep 8, 2024
dc3af50
feat(codegen): Init serializers
jubnzv Sep 8, 2024
5e5a5b8
feat(codegen): Storage functions
jubnzv Sep 8, 2024
10bbf30
feat(codegen): Add static functions
jubnzv Sep 8, 2024
77d12b0
chore(codegen): Add missing file
jubnzv Sep 8, 2024
3bfc322
feat(codegen): Support extensions
jubnzv Sep 8, 2024
dfa9013
feat(grammar): Support `try {} catch (_) {}`
jubnzv Sep 9, 2024
9c46edd
feat(codegen): Support all the statements
jubnzv Sep 9, 2024
9ee58a1
feat(pp): Refine API; more public methods
jubnzv Sep 10, 2024
82272f4
feat(pp): Support type vars
jubnzv Sep 10, 2024
494c240
chore(Writer): Replace `#` annotations
jubnzv Sep 10, 2024
a1b42a0
feat(func): Expose public functions
jubnzv Sep 10, 2024
8b5c98d
chore(codegen): Remove tests; they'll be rewritten
jubnzv Sep 10, 2024
7c3b01f
Merge remote-tracking branch 'origin/main' into 526-func-codegen
jubnzv Sep 10, 2024
bcfef54
feat: New codegen copied from the main version; `writeStdlib` is ported
jubnzv Sep 11, 2024
f792111
fix(codegen): Remove extra attributes
jubnzv Sep 11, 2024
a3b2877
chore(codegen): Roll-back porting `writeStdlib` because of FunC parse…
jubnzv Sep 11, 2024
2419b16
chore(syntaxConstructors): Set `if` instead of `ifnot` by default
jubnzv Sep 11, 2024
a89bd0b
feat(test): Improve readability
jubnzv Sep 11, 2024
6d4b179
feat(test): Don't add extra .tact to paths in the generated config
jubnzv Sep 11, 2024
e140b35
feat(test): Don't consider newlines in differential testing
jubnzv Sep 11, 2024
6909f93
fix(pp): Don't add extra crs
jubnzv Sep 11, 2024
6397c85
feat(codegen): Port `writeRouter`
jubnzv Sep 11, 2024
236a518
feat: support `catch(_)` clauses
novusnota Sep 11, 2024
9cfa662
fix(tests): Hack for FunC parser
novusnota Sep 11, 2024
deaa617
fix(func-parser): Correct recognition of function and method calls
novusnota Sep 11, 2024
59f8936
feat(test): Allow lowercase test names
jubnzv Sep 12, 2024
80cc2cf
fix(pp): Extra dots in new function calls
jubnzv Sep 12, 2024
deb369f
feat(pp): Add pp functions
jubnzv Sep 12, 2024
98c6fb9
fix(writeRouter): Make old `writeReceiver` work with new API functions
jubnzv Sep 12, 2024
dcca629
feat(codegen): Port `writeStdlib`
jubnzv Sep 12, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion .eslintignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,7 @@ src/test/**/output/
src/func/funcfiftlib.js
src/grammar/grammar.ohm*.ts
src/grammar/grammar.ohm*.js
src/func/grammar.ohm*.ts
src/func/grammar.ohm*.js
jest.setup.js
jest.teardown.js
jest.teardown.js
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,8 @@ dist
output/
src/grammar/grammar.ohm-bundle.js
src/grammar/grammar.ohm-bundle.d.ts
src/func/grammar.ohm*.ts
src/func/grammar.ohm*.js
src/func/funcfiftlib.wasm.js
src/codegen/contracts/*.config.json

2 changes: 2 additions & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,7 @@
/src/func/funcfiftlib.wasm.js
/src/grammar/grammar.ohm-bundle.d.ts
/src/grammar/grammar.ohm-bundle.js
/src/func/grammar.ohm*.ts
/src/func/grammar.ohm*.js
/src/imports/stdlib.ts
/grammar
21 changes: 20 additions & 1 deletion cspell.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,20 @@
"jettons",
"jsxdev",
"langle",
"lbrack",
"lparen",
"lquote",
"ltick",
"lvalue",
"masterchain",
"maxint",
"minmax",
"mintable",
"moddiv",
"muldiv",
"muldivc",
"muldivmod",
"muldivr",
"multiformats",
"Korshakov",
"nocheck",
Expand All @@ -50,15 +58,20 @@
"Parens",
"POSIX",
"prando",
"qmark",
"rangle",
"rbrack",
"rparen",
"rquote",
"rtick",
"rugpull",
"rugpulled",
"sctx",
"seqno",
"shiki",
"Stateinit",
"stdlib",
"stdump",
"struct",
"structs",
"subtyping",
Expand All @@ -84,7 +97,13 @@
"node_modules",
"dist",
"examples/__snapshots__/multisig-3.spec.ts.snap",
"func",
"/func",
"scripts/func",
"src/func/__snapshots__/*",
"src/func/grammar.ohm*",
"src/func/funcfiftlib*",
"src/func/grammar-test/*",
"src/func/grammar-test-failed/*",
"grammar/sample.json",
"src/generator/writers/writeStdlib.ts",
"src/generator/writers/__snapshots__/writeSerialization.spec.ts.snap",
Expand Down
5 changes: 4 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,14 @@
"author": "Steve Korshakov <steve@korshakov.com>",
"license": "MIT",
"scripts": {
"gen:grammar": "ohm generateBundles --withTypes src/grammar/*.ohm",
"gen:grammar": "ohm generateBundles --withTypes src/grammar/*.ohm src/func/*.ohm",
"gen:pack": "ts-node ./scripts/pack.ts",
"gen:compiler": "ts-node ./scripts/prepare.ts",
"gen": "yarn gen:grammar && yarn gen:pack && yarn gen:compiler",
"clean": "rm -fr dist",
"build": "tsc && cp ./src/grammar/grammar.ohm* ./dist/grammar/ && cp ./src/func/funcfiftlib.* ./dist/func",
"test": "jest",
"test:func": "yarn gen:grammar && jest -t 'FunC grammar and parser'",
"coverage": "cross-env COVERAGE=true jest",
"release": "yarn clean && yarn build && yarn coverage && yarn release-it --npm.yarn1",
"lint": "yarn eslint .",
Expand All @@ -38,9 +39,11 @@
"@tact-lang/opcode": "^0.0.14",
"@ton/core": "0.56.3",
"@ton/crypto": "^3.2.0",
"@types/json-bigint": "^1.0.4",
"blockstore-core": "1.0.5",
"change-case": "^4.1.2",
"ipfs-unixfs-importer": "9.0.10",
"json-bigint": "^1.0.0",
"meow": "^13.2.0",
"mkdirp": "^2.1.3",
"multiformats": "^13.1.0",
Expand Down
26 changes: 26 additions & 0 deletions src/codegen/abi.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { AstExpression, SrcInfo } from "../grammar/ast";
import { CompilerContext } from "../context";
import { TypeRef } from "../types/types";
import { FuncAstExpression } from "../func/grammar";

/**
* A static map of functions defining Func expressions for Tact ABI functions and methods.
*/
export type AbiFunction = {
name: string;
resolve: (ctx: CompilerContext, args: TypeRef[], loc: SrcInfo) => TypeRef;
generate: (
args: TypeRef[],
resolved: AstExpression[],
loc: SrcInfo,
) => FuncAstExpression;
};

// TODO
export const MapFunctions: Map<string, AbiFunction> = new Map([]);

// TODO
export const StructFunctions: Map<string, AbiFunction> = new Map([]);

// TODO
export const GlobalFunctions: Map<string, AbiFunction> = new Map([]);
178 changes: 178 additions & 0 deletions src/codegen/codegen.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,178 @@
import * as fs from "fs";
import * as path from "path";

import { __DANGER_resetNodeId } from "../grammar/ast";
import { compile } from "../pipeline/compile";
import { precompile } from "../pipeline/precompile";
import { getContracts } from "../types/resolveDescriptors";
import { CompilationOutput, CompilationResults } from "../pipeline/compile";
import { createNodeFileSystem } from "../vfs/createNodeFileSystem";
import { CompilerContext } from "../context";

const CONTRACTS_DIR = path.join(__dirname, "./contracts/");

function capitalize(str: string): string {
if (str.length === 0) return str;
return str.charAt(0).toUpperCase() + str.slice(1).toLowerCase();
}

/**
* Generates a Tact configuration file for the given contract (imported from Misti).
*/
export function generateConfig(contractName: string): string {
const config = {
projects: [
{
name: `${contractName}`,
path: `./${contractName}.tact`,
output: `./output`,
options: {},
},
],
};
const configPath = path.join(CONTRACTS_DIR, `${contractName}.config.json`);
fs.writeFileSync(configPath, JSON.stringify(config), {
encoding: "utf8",
flag: "w",
});
return configPath;
}

/**
* Compiles the contract on the given filepath to CompilationResults replicating the Tact compiler pipeline.
*/
async function compileContract(
backend: "new" | "old",
contractName: string,
): Promise<CompilationResults[]> {
const _ = generateConfig(contractName);

// see: pipeline/build.ts
const project = createNodeFileSystem(CONTRACTS_DIR, false);
const stdlib = createNodeFileSystem(
path.resolve(__dirname, "..", "..", "stdlib"),
false,
);
let ctx: CompilerContext = new CompilerContext({ shared: {} });
ctx = precompile(ctx, project, stdlib, contractName);

return await Promise.all(
getContracts(ctx).map(async (contract) => {
const res = await compile(
ctx,
contract,
`${contractName}_${contract}`,
backend,
);
return res;
}),
);
}

function compareCompilationOutputs(
newOut: CompilationOutput,
oldOut: CompilationOutput,
): void {
const errors: string[] = [];

if (newOut === undefined || oldOut === undefined) {
errors.push("One of the outputs is undefined.");
} else {
try {
expect(newOut.entrypoint).toBe(oldOut.entrypoint);
} catch (error) {
if (error instanceof Error) {
errors.push(`Entrypoint mismatch: ${error.message}`);
} else {
errors.push(`Entrypoint mismatch: ${String(error)}`);
}
}

try {
expect(newOut.abi).toBe(oldOut.abi);
} catch (error) {
if (error instanceof Error) {
errors.push(`ABI mismatch: ${error.message}`);
} else {
errors.push(`ABI mismatch: ${String(error)}`);
}
}

const unmatchedFiles = new Set(oldOut.files.map((file) => file.name));

for (const newFile of newOut.files) {
const oldFile = oldOut.files.find(
(file) => file.name === newFile.name,
);
if (oldFile) {
unmatchedFiles.delete(oldFile.name);
try {
expect(newFile.code).toBe(oldFile.code);
} catch (error) {
if (error instanceof Error) {
errors.push(
`Code mismatch in file ${newFile.name}: ${error.message}`,
);
} else {
errors.push(
`Code mismatch in file ${newFile.name}: ${String(error)}`,
);
}
}
} else {
errors.push(
`File ${newFile.name} is missing in the old output.`,
);
}
}

for (const missingFile of unmatchedFiles) {
errors.push(`File ${missingFile} is missing in the new output.`);
}
}

if (errors.length > 0) {
throw new Error(errors.join("\n"));
}
}

describe("codegen", () => {
beforeEach(async () => {
__DANGER_resetNodeId();
});

fs.readdirSync(CONTRACTS_DIR).forEach((file) => {
if (!file.endsWith(".tact")) {
return;
}
const contractName = capitalize(file);
// Differential tests with the old backend
it(`Should compile the ${file} contract`, async () => {
Promise.all([
compileContract("new", contractName),
compileContract("old", contractName),
])
.then(([resultsNew, resultsOld]) => {
if (resultsNew.length !== resultsOld.length) {
throw new Error("Not all contracts have been compiled");
}
const zipped = resultsNew.map((value, idx) => [
value,
resultsOld[idx],
]);
zipped.forEach(([newRes, oldRes]) => {
compareCompilationOutputs(
newRes!.output,
oldRes!.output,
);
});
})
.catch((error) => {
console.error(
"An error occurred during compilation:",
error,
);
});
});
});
});
Loading