Skip to content

Commit

Permalink
fix: getter name collisions in TS wrappers (tact-lang#556)
Browse files Browse the repository at this point in the history
Exports a TS mapping from Tact getter names to their TS analogues
  • Loading branch information
Gusarich authored Jul 12, 2024
1 parent 18a124a commit 540f2d3
Show file tree
Hide file tree
Showing 7 changed files with 375 additions and 1 deletion.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Usage of `initOf` inside of `init()` does not cause error `135` anymore: PR [#521](https://github.com/tact-lang/tact/issues/521)
- Usage of `newAddress` with hash parts shorter than 64 hexadecimal digits does not cause constant evaluation error `Invalid address hash length` anymore: PR [#525](https://github.com/tact-lang/tact/pull/525)
- Introduced a streamlined error logger for compilation pipeline to support third-party tools: PR [#509](https://github.com/tact-lang/tact/pull/509)
- Collisions of PascalCase getter names in generated wrappers are now checked: PR [#556](https://github.com/tact-lang/tact/pull/556)

## [1.4.0] - 2024-06-21

Expand Down
1 change: 1 addition & 0 deletions cspell.json
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@
"src/test/e2e-emulated/contracts/intrinsics.tact",
"src/test/e2e-emulated/contracts/strings.tact",
"src/test/compilation-fail/fail-const-eval.spec.ts",
"src/test/e2e-emulated/getter-names-conflict.spec.ts",
"stdlib/stdlib.fc"
]
}
24 changes: 23 additions & 1 deletion src/bindings/writeTypescript.ts
Original file line number Diff line number Diff line change
Expand Up @@ -214,18 +214,40 @@ export function writeTypescript(
w.append(`]`);
w.append();

const getterNames: Map<string, string> = new Map();

// Getters
w.append(`const ${abi.name}_getters: ABIGetter[] = [`);
w.inIndent(() => {
if (abi.getters) {
for (const t of abi.getters) {
w.append(JSON.stringify(t) + ",");

let getterName = changeCase.pascalCase(t.name);
if (Array.from(getterNames.values()).includes(getterName)) {
getterName = t.name;
}
getterNames.set(t.name, getterName);
}
}
});
w.append(`]`);
w.append();

// Getter mapping
w.append(
`export const ${abi.name}_getterMapping: { [key: string]: string } = {`,
);
w.inIndent(() => {
if (abi.getters) {
for (const t of abi.getters) {
w.append(`'${t.name}': 'get${getterNames.get(t.name)}',`);
}
}
});
w.append(`}`);
w.append();

// Receivers
w.append(`const ${abi.name}_receivers: ABIReceiver[] = [`);
w.inIndent(() => {
Expand Down Expand Up @@ -564,7 +586,7 @@ export function writeTypescript(
if (abi.getters) {
for (const g of abi.getters) {
w.append(
`async get${changeCase.pascalCase(g.name)}(${["provider: ContractProvider", ...writeArguments(g.arguments ? g.arguments : [])].join(", ")}) {`,
`async get${getterNames.get(g.name)}(${["provider: ContractProvider", ...writeArguments(g.arguments ? g.arguments : [])].join(", ")}) {`,
);
w.inIndent(() => {
w.append(`let builder = new TupleBuilder();`);
Expand Down
299 changes: 299 additions & 0 deletions src/test/e2e-emulated/__snapshots__/getter-names-conflict.spec.ts.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,299 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`getter-names-conflict should handle conflicts in getter names correctly 1`] = `
Test {
"abi": {
"errors": {
"10": {
"message": "Dictionary error",
},
"128": {
"message": "Null reference exception",
},
"129": {
"message": "Invalid serialization prefix",
},
"13": {
"message": "Out of gas error",
},
"130": {
"message": "Invalid incoming message",
},
"131": {
"message": "Constraints error",
},
"132": {
"message": "Access denied",
},
"133": {
"message": "Contract stopped",
},
"134": {
"message": "Invalid argument",
},
"135": {
"message": "Code of a contract was not found",
},
"136": {
"message": "Invalid address",
},
"137": {
"message": "Masterchain support is not enabled for this contract",
},
"2": {
"message": "Stack underflow",
},
"3": {
"message": "Stack overflow",
},
"32": {
"message": "Method ID not found",
},
"34": {
"message": "Action is invalid or not supported",
},
"37": {
"message": "Not enough TON",
},
"38": {
"message": "Not enough extra-currencies",
},
"4": {
"message": "Integer overflow",
},
"5": {
"message": "Integer out of expected range",
},
"6": {
"message": "Invalid opcode",
},
"7": {
"message": "Type check error",
},
"8": {
"message": "Cell overflow",
},
"9": {
"message": "Cell underflow",
},
},
"getters": [
{
"arguments": [],
"name": "testGetter",
"returnType": {
"format": 257,
"kind": "simple",
"optional": false,
"type": "int",
},
},
{
"arguments": [],
"name": "test_getter",
"returnType": {
"format": 257,
"kind": "simple",
"optional": false,
"type": "int",
},
},
{
"arguments": [],
"name": "Test_getter",
"returnType": {
"format": 257,
"kind": "simple",
"optional": false,
"type": "int",
},
},
],
"receivers": [
{
"message": {
"kind": "empty",
},
"receiver": "internal",
},
],
"types": [
{
"fields": [
{
"name": "code",
"type": {
"kind": "simple",
"optional": false,
"type": "cell",
},
},
{
"name": "data",
"type": {
"kind": "simple",
"optional": false,
"type": "cell",
},
},
],
"header": null,
"name": "StateInit",
},
{
"fields": [
{
"name": "bounced",
"type": {
"kind": "simple",
"optional": false,
"type": "bool",
},
},
{
"name": "sender",
"type": {
"kind": "simple",
"optional": false,
"type": "address",
},
},
{
"name": "value",
"type": {
"format": 257,
"kind": "simple",
"optional": false,
"type": "int",
},
},
{
"name": "raw",
"type": {
"kind": "simple",
"optional": false,
"type": "slice",
},
},
],
"header": null,
"name": "Context",
},
{
"fields": [
{
"name": "bounce",
"type": {
"kind": "simple",
"optional": false,
"type": "bool",
},
},
{
"name": "to",
"type": {
"kind": "simple",
"optional": false,
"type": "address",
},
},
{
"name": "value",
"type": {
"format": 257,
"kind": "simple",
"optional": false,
"type": "int",
},
},
{
"name": "mode",
"type": {
"format": 257,
"kind": "simple",
"optional": false,
"type": "int",
},
},
{
"name": "body",
"type": {
"kind": "simple",
"optional": true,
"type": "cell",
},
},
{
"name": "code",
"type": {
"kind": "simple",
"optional": true,
"type": "cell",
},
},
{
"name": "data",
"type": {
"kind": "simple",
"optional": true,
"type": "cell",
},
},
],
"header": null,
"name": "SendParameters",
},
],
},
"address": kQD80WcWxBhERIUXYb8hyvNv5hK-iToKR4Q5dEGUZ2NWl9Mx,
"init": {
"code": x{FF00F4A413F4BCF2C80B}
x{62_}
x{D001D0D3030171B0A301FA400120D74981010BBAF2E08820D70B0A208104FFBAF2D0898309BAF2E088545053036F04F86102F862DB3C59DB3CF2E08230C8F84301CC7F01CA00C9ED54}
x{ED44D0D401F863D20030916DE0F828D70B0A8309BAF2E089DB3C}
x{6D}
x{0192307FE07021D749C21F953020D70B1FDEC00001D749C121B0917FE070}
x{2_}
x{2_}
x{B9BDCDB3CDB3C31}
x{ED44D0D401F863D20030916DE0F828D70B0A8309BAF2E089DB3C}
x{6D}
x{73}
x{BBE1FDB3CDB3C31}
x{ED44D0D401F863D20030916DE0F828D70B0A8309BAF2E089DB3C}
x{6D}
x{71}
x{2_}
x{BB1A6DB3CDB3C31}
x{ED44D0D401F863D20030916DE0F828D70B0A8309BAF2E089DB3C}
x{6D}
x{72}
x{B82BEED44D0D20001},
"data": x{4_}
x{C_}
x{A15891_}
x{FF00F4A413F4BCF2C80B}
x{62_}
x{D001D0D3030171B0A301FA400120D74981010BBAF2E08820D70B0A208104FFBAF2D0898309BAF2E088545053036F04F86102F862DB3C59DB3CF2E08230C8F84301CC7F01CA00C9ED54}
x{ED44D0D401F863D20030916DE0F828D70B0A8309BAF2E089DB3C}
x{6D}
x{0192307FE07021D749C21F953020D70B1FDEC00001D749C121B0917FE070}
x{2_}
x{2_}
x{B9BDCDB3CDB3C31}
x{ED44D0D401F863D20030916DE0F828D70B0A8309BAF2E089DB3C}
x{6D}
x{73}
x{BBE1FDB3CDB3C31}
x{ED44D0D401F863D20030916DE0F828D70B0A8309BAF2E089DB3C}
x{6D}
x{71}
x{2_}
x{BB1A6DB3CDB3C31}
x{ED44D0D401F863D20030916DE0F828D70B0A8309BAF2E089DB3C}
x{6D}
x{72}
x{B82BEED44D0D20001},
},
}
`;
16 changes: 16 additions & 0 deletions src/test/e2e-emulated/contracts/getter-names-conflict.tact
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
contract Test {
receive () {}

get fun testGetter(): Int {
return 1;
}

get fun test_getter(): Int {
return 2;
}

get fun Test_getter(): Int {
return 3;
}
}

Loading

0 comments on commit 540f2d3

Please sign in to comment.