Skip to content

Commit

Permalink
feat: Trailing commas for with ... lists and init() parameters (#246
Browse files Browse the repository at this point in the history
)

* fix: Prohibited empty inherited trait lists
* chore: 7-10s speedup of tests with just 1 change
* chore: `yarn all` for running everything besides installing dependencies

See: #247
  • Loading branch information
novusnota authored Apr 13, 2024
1 parent 0a0ca08 commit 9c741b2
Show file tree
Hide file tree
Showing 15 changed files with 162 additions and 32 deletions.
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Changed

- Update the `dump` function to handle addresses: PR [#175](https://github.com/tact-lang/tact/pull/175)
- Support trailing commas for struct fields and function arguments: PR [#179](https://github.com/tact-lang/tact/pull/179)
- Support trailing commas in all comma-separated lists (struct instantiations, `initOf` arguments, `init()` parameters, inherited traits via `with`, function arguments and parameters): PR [#179](https://github.com/tact-lang/tact/pull/179) and PR [#246](https://github.com/tact-lang/tact/pull/246)
- The implicit empty `init` function is now present by default in the contract if not declared: PR [#167](https://github.com/tact-lang/tact/pull/167)
- `@stdlib/stoppable` now imports `@stdlib/ownable` so the programmer does not have to do it separately: PR [#193](https://github.com/tact-lang/tact/pull/193)
- Support escape sequences for strings (`\\`, `\"`, `\n`, `\r`, `\t`, `\v`, `\b`, `\f`, `\u{0}` through `\u{FFFFFF}`, `\u0000` through `\uFFFF`, `\x00` through `\xFF`): PR [#192](https://github.com/tact-lang/tact/pull/192)
Expand All @@ -28,6 +28,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

- Incorrect "already exists" errors when using names such as `toString` or `valueOf`: PR [#208](https://github.com/tact-lang/tact/pull/208)
- Escape backticks in error messages for generated TypeScript code: PR [#192](https://github.com/tact-lang/tact/pull/192)
- Empty inherited trait lists after `with` keyword are now disallowed: PR [#246](https://github.com/tact-lang/tact/pull/246)

## [1.2.0] - 2024-02-29

Expand Down
2 changes: 1 addition & 1 deletion jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ module.exports = {
preset: "ts-jest",
testEnvironment: "node",
testPathIgnorePatterns: ["/node_modules/", "/dist/"],
maxWorkers: 1,
maxWorkers: "50%",
globalSetup: "./jest.setup.js",
globalTeardown: "./jest.teardown.js",
snapshotSerializers: ["@tact-lang/ton-jest/serializers"],
Expand Down
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@
"release": "yarn clean && yarn build && yarn coverage && yarn release-it --npm.yarn1",
"lint": "yarn eslint .",
"lint:schema": "ajv validate -s grammar/configSchema.json -d tact.config.json",
"fmt:check": "yarn prettier --check ."
"fmt:check": "yarn prettier --check .",
"all": "yarn clean && yarn gen && yarn build && yarn coverage && yarn lint && yarn fmt:check"
},
"files": [
"dist/**/*",
Expand Down
111 changes: 99 additions & 12 deletions src/grammar/__snapshots__/grammar.spec.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,52 @@ Line 2, col 31:
"
`;
exports[`grammar should fail case-27 1`] = `
"<unknown>:1:19: Syntax error: expected "_", "A".."Z", or "a".."z"
Line 1, col 19:
> 1 | contract Name with, {}
^
2 |
"
`;
exports[`grammar should fail case-28 1`] = `
"<unknown>:1:16: Syntax error: expected "_", "A".."Z", or "a".."z"
Line 1, col 16:
> 1 | trait Name with, {}
^
2 |
"
`;
exports[`grammar should fail case-29 1`] = `
"<unknown>:2:10: Empty parameter list should not have a dangling comma.
Line 2, col 10:
1 | contract Name {
> 2 | init(,) {}
^
3 | }
"
`;
exports[`grammar should fail case-30 1`] = `
"<unknown>:1:20: Syntax error: expected "_", "A".."Z", or "a".."z"
Line 1, col 20:
> 1 | contract Name with {}
^
2 |
"
`;
exports[`grammar should fail case-31 1`] = `
"<unknown>:1:17: Syntax error: expected "_", "A".."Z", or "a".."z"
Line 1, col 17:
> 1 | trait Name with {}
^
2 |
"
`;
exports[`grammar should parse case-0 1`] = `
{
"entries": [
Expand Down Expand Up @@ -2727,8 +2773,8 @@ exports[`grammar should parse case-22 1`] = `
"id": 3,
"init": null,
"kind": "def_field",
"name": "a",
"ref": a: Int;,
"name": "c",
"ref": c: Int;,
"type": {
"id": 2,
"kind": "type_ref_simple",
Expand All @@ -2740,10 +2786,10 @@ exports[`grammar should parse case-22 1`] = `
],
"id": 4,
"kind": "def_trait",
"name": "SomeTrait",
"name": "OtherTrait",
"origin": "user",
"ref": trait SomeTrait {
a: Int;
"ref": trait OtherTrait {
c: Int;
},
"traits": [],
},
Expand All @@ -2755,8 +2801,8 @@ exports[`grammar should parse case-22 1`] = `
"id": 6,
"init": null,
"kind": "def_field",
"name": "b",
"ref": b: Int;,
"name": "a",
"ref": a: Int;,
"type": {
"id": 5,
"kind": "type_ref_simple",
Expand All @@ -2767,23 +2813,58 @@ exports[`grammar should parse case-22 1`] = `
},
],
"id": 8,
"kind": "def_trait",
"name": "SomeTrait",
"origin": "user",
"ref": trait SomeTrait with OtherTrait, {
a: Int;
},
"traits": [
{
"id": 7,
"kind": "id",
"ref": OtherTrait,
"value": "OtherTrait",
},
],
},
{
"attributes": [],
"declarations": [
{
"as": null,
"id": 10,
"init": null,
"kind": "def_field",
"name": "b",
"ref": b: Int;,
"type": {
"id": 9,
"kind": "type_ref_simple",
"name": "Int",
"optional": false,
"ref": Int,
},
},
],
"id": 12,
"kind": "def_contract",
"name": "Main",
"origin": "user",
"ref": contract Main with SomeTrait {
"ref": contract Main with SomeTrait, {
b: Int;
},
"traits": [
{
"id": 7,
"id": 11,
"kind": "id",
"ref": SomeTrait,
"value": "SomeTrait",
},
],
},
],
"id": 9,
"id": 13,
"kind": "program",
}
`;
Expand Down Expand Up @@ -3669,7 +3750,10 @@ exports[`grammar should parse case-25 1`] = `
],
"id": 76,
"kind": "def_init_function",
"ref": init(arg1: Int, arg2: Int) {},
"ref": init(
arg1: Int,
arg2: Int,
) {},
"statements": [],
},
],
Expand All @@ -3678,7 +3762,10 @@ exports[`grammar should parse case-25 1`] = `
"name": "TestContract",
"origin": "user",
"ref": contract TestContract {
init(arg1: Int, arg2: Int) {}
init(
arg1: Int,
arg2: Int,
) {}
},
"traits": [],
},
Expand Down
6 changes: 3 additions & 3 deletions src/grammar/grammar.ohm
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,8 @@ Tact {

// Contract
Contract = ContractAttribute* contract id "{" ContractBody* "}" --simple
| ContractAttribute* contract id with ListOf<id,","> "{" ContractBody* "}" --withTraits
ContractInit = "init" "(" ListOf<FunctionArg,","> ")" "{" Statement* "}"
| ContractAttribute* contract id with NonemptyListOf<id,","> ","? "{" ContractBody* "}" --withTraits
ContractInit = "init" "(" ListOf<FunctionArg,","> ","? ")" "{" Statement* "}"
ContractBody = Field
| ContractInit
| ReceiveFunction
Expand All @@ -55,7 +55,7 @@ Tact {

// Trait
Trait = ContractAttribute* trait id "{" TraitBody* "}" --originary
| ContractAttribute* trait id with ListOf<id,","> "{" TraitBody* "}" --withTraits
| ContractAttribute* trait id with NonemptyListOf<id,","> ","? "{" TraitBody* "}" --withTraits
TraitBody = Field
| ReceiveFunction
| Function
Expand Down
6 changes: 3 additions & 3 deletions src/grammar/grammar.ohm-bundle.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,12 +43,12 @@ export interface TactActionDict<T> extends ActionDict<T> {
Struct?: (this: NonterminalNode, arg0: NonterminalNode) => T;
StructBody?: (this: NonterminalNode, arg0: NonterminalNode) => T;
Contract_simple?: (this: NonterminalNode, arg0: IterationNode, arg1: NonterminalNode, arg2: NonterminalNode, arg3: TerminalNode, arg4: IterationNode, arg5: TerminalNode) => T;
Contract_withTraits?: (this: NonterminalNode, arg0: IterationNode, arg1: NonterminalNode, arg2: NonterminalNode, arg3: NonterminalNode, arg4: NonterminalNode, arg5: TerminalNode, arg6: IterationNode, arg7: TerminalNode) => T;
Contract_withTraits?: (this: NonterminalNode, arg0: IterationNode, arg1: NonterminalNode, arg2: NonterminalNode, arg3: NonterminalNode, arg4: NonterminalNode, arg5: IterationNode, arg6: TerminalNode, arg7: IterationNode, arg8: TerminalNode) => T;
Contract?: (this: NonterminalNode, arg0: NonterminalNode) => T;
ContractInit?: (this: NonterminalNode, arg0: TerminalNode, arg1: TerminalNode, arg2: NonterminalNode, arg3: TerminalNode, arg4: TerminalNode, arg5: IterationNode, arg6: TerminalNode) => T;
ContractInit?: (this: NonterminalNode, arg0: TerminalNode, arg1: TerminalNode, arg2: NonterminalNode, arg3: IterationNode, arg4: TerminalNode, arg5: TerminalNode, arg6: IterationNode, arg7: TerminalNode) => T;
ContractBody?: (this: NonterminalNode, arg0: NonterminalNode) => T;
Trait_originary?: (this: NonterminalNode, arg0: IterationNode, arg1: NonterminalNode, arg2: NonterminalNode, arg3: TerminalNode, arg4: IterationNode, arg5: TerminalNode) => T;
Trait_withTraits?: (this: NonterminalNode, arg0: IterationNode, arg1: NonterminalNode, arg2: NonterminalNode, arg3: NonterminalNode, arg4: NonterminalNode, arg5: TerminalNode, arg6: IterationNode, arg7: TerminalNode) => T;
Trait_withTraits?: (this: NonterminalNode, arg0: IterationNode, arg1: NonterminalNode, arg2: NonterminalNode, arg3: NonterminalNode, arg4: NonterminalNode, arg5: IterationNode, arg6: TerminalNode, arg7: IterationNode, arg8: TerminalNode) => T;
Trait?: (this: NonterminalNode, arg0: NonterminalNode) => T;
TraitBody?: (this: NonterminalNode, arg0: NonterminalNode) => T;
ContractAttribute_interface?: (this: NonterminalNode, arg0: TerminalNode, arg1: TerminalNode, arg2: NonterminalNode, arg3: TerminalNode) => T;
Expand Down
2 changes: 1 addition & 1 deletion src/grammar/grammar.ohm-bundle.js

Large diffs are not rendered by default.

39 changes: 33 additions & 6 deletions src/grammar/grammar.ts
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,17 @@ semantics.addOperation<ASTNode>("resolve_program_item", {
ref: createRef(this),
});
},
Contract_withTraits(arg0, _arg1, arg2, _arg3, arg4, _arg5, arg6, _arg7) {
Contract_withTraits(
arg0,
_arg1,
arg2,
_arg3,
arg4,
_arg5,
_arg6,
arg7,
_arg8,
) {
checkVariableName(arg2.sourceString, createRef(arg2));
return createNode({
kind: "def_contract",
Expand All @@ -116,7 +126,7 @@ semantics.addOperation<ASTNode>("resolve_program_item", {
attributes: arg0.children.map((v) =>
v.resolve_contract_attributes(),
),
declarations: arg6.children.map((v) => v.resolve_declaration()),
declarations: arg7.children.map((v) => v.resolve_declaration()),
traits: arg4
.asIteration()
.children.map((v) => v.resolve_expression()),
Expand All @@ -137,7 +147,17 @@ semantics.addOperation<ASTNode>("resolve_program_item", {
ref: createRef(this),
});
},
Trait_withTraits(arg0, _arg1, arg2, _arg3, arg4, _arg5, arg6, _arg7) {
Trait_withTraits(
arg0,
_arg1,
arg2,
_arg3,
arg4,
_arg5,
_arg6,
arg7,
_arg8,
) {
checkVariableName(arg2.sourceString, createRef(arg2));
return createNode({
kind: "def_trait",
Expand All @@ -146,7 +166,7 @@ semantics.addOperation<ASTNode>("resolve_program_item", {
attributes: arg0.children.map((v) =>
v.resolve_contract_attributes(),
),
declarations: arg6.children.map((v) => v.resolve_declaration()),
declarations: arg7.children.map((v) => v.resolve_declaration()),
traits: arg4
.asIteration()
.children.map((v) => v.resolve_expression()),
Expand Down Expand Up @@ -539,13 +559,20 @@ semantics.addOperation<ASTNode>("resolve_declaration", {
ref: createRef(this),
});
},
ContractInit(_arg0, _arg1, arg2, _arg3, _arg4, arg5, _arg6) {
ContractInit(_arg0, _arg1, arg2, arg3, _arg4, _arg5, arg6, _arg7) {
if (arg2.source.contents === "" && arg3.sourceString === ",") {
throwError(
"Empty parameter list should not have a dangling comma.",
createRef(arg3),
);
}

return createNode({
kind: "def_init_function",
args: arg2
.asIteration()
.children.map((v) => v.resolve_declaration()),
statements: arg5.children.map((v) => v.resolve_statement()),
statements: arg6.children.map((v) => v.resolve_statement()),
ref: createRef(this),
});
},
Expand Down
1 change: 1 addition & 0 deletions src/grammar/test-failed/case-27.tact
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
contract Name with, {}
1 change: 1 addition & 0 deletions src/grammar/test-failed/case-28.tact
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
trait Name with, {}
3 changes: 3 additions & 0 deletions src/grammar/test-failed/case-29.tact
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
contract Name {
init(,) {}
}
1 change: 1 addition & 0 deletions src/grammar/test-failed/case-30.tact
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
contract Name with {}
1 change: 1 addition & 0 deletions src/grammar/test-failed/case-31.tact
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
trait Name with {}
10 changes: 7 additions & 3 deletions src/grammar/test/case-22.tact
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
primitive Int;

trait SomeTrait {
trait OtherTrait {
c: Int;
}

trait SomeTrait with OtherTrait, {
a: Int;
}

contract Main with SomeTrait {
contract Main with SomeTrait, {
b: Int;
}
}
5 changes: 4 additions & 1 deletion src/grammar/test/case-25.tact
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,10 @@ fun oneMoreFunction(
}

contract TestContract {
init(arg1: Int, arg2: Int) {}
init(
arg1: Int,
arg2: Int,
) {}
}

fun test() {
Expand Down

0 comments on commit 9c741b2

Please sign in to comment.