diff --git a/e2e/packages/contracts/src/codegen/world/IAddressPayableArraySystem.sol b/e2e/packages/contracts/src/codegen/world/IAddressPayableArraySystem.sol new file mode 100644 index 0000000000..353b5da213 --- /dev/null +++ b/e2e/packages/contracts/src/codegen/world/IAddressPayableArraySystem.sol @@ -0,0 +1,13 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.8.24; + +/* Autogenerated file. Do not edit manually. */ + +/** + * @title IAddressPayableArraySystem + * @author MUD (https://mud.dev) by Lattice (https://lattice.xyz) + * @dev This interface is automatically generated from the corresponding system contract. Do not edit manually. + */ +interface IAddressPayableArraySystem { + function getAddressPayableArray(address payable[] memory array) external pure returns (address payable[] memory); +} diff --git a/e2e/packages/contracts/src/codegen/world/IWorld.sol b/e2e/packages/contracts/src/codegen/world/IWorld.sol index e52b4ae995..05791065bf 100644 --- a/e2e/packages/contracts/src/codegen/world/IWorld.sol +++ b/e2e/packages/contracts/src/codegen/world/IWorld.sol @@ -4,6 +4,7 @@ pragma solidity >=0.8.24; /* Autogenerated file. Do not edit manually. */ import { IBaseWorld } from "@latticexyz/world/src/codegen/interfaces/IBaseWorld.sol"; +import { IAddressPayableArraySystem } from "./IAddressPayableArraySystem.sol"; import { ICustomErrorsSystem } from "./ICustomErrorsSystem.sol"; import { ILibWrapperSystem } from "./ILibWrapperSystem.sol"; import { INumberListSystem } from "./INumberListSystem.sol"; @@ -19,6 +20,7 @@ import { IVectorSystem } from "./IVectorSystem.sol"; */ interface IWorld is IBaseWorld, + IAddressPayableArraySystem, ICustomErrorsSystem, ILibWrapperSystem, INumberListSystem, diff --git a/e2e/packages/contracts/src/systems/AddressPayableArraySystem.sol b/e2e/packages/contracts/src/systems/AddressPayableArraySystem.sol new file mode 100644 index 0000000000..af217912e9 --- /dev/null +++ b/e2e/packages/contracts/src/systems/AddressPayableArraySystem.sol @@ -0,0 +1,10 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.8.24; + +import { System } from "@latticexyz/world/src/System.sol"; + +contract AddressPayableArraySystem is System { + function getAddressPayableArray(address payable[] memory array) public pure returns (address payable[] memory) { + return array; + } +} diff --git a/packages/common/src/codegen/utils/contractToInterface.ts b/packages/common/src/codegen/utils/contractToInterface.ts index 914860b188..2bc64a0421 100644 --- a/packages/common/src/codegen/utils/contractToInterface.ts +++ b/packages/common/src/codegen/utils/contractToInterface.ts @@ -101,13 +101,8 @@ export function contractToInterface( function parseParameter({ name, typeName, storageLocation }: VariableDeclaration): string { let typedNameWithLocation = ""; - const { name: flattenedTypeName, stateMutability } = flattenTypeName(typeName); // type name (e.g. uint256) - typedNameWithLocation += flattenedTypeName; - // optional mutability (e.g. address payable) - if (stateMutability !== null) { - typedNameWithLocation += ` ${stateMutability}`; - } + typedNameWithLocation += flattenTypeName(typeName); // location, when relevant (e.g. string memory) if (storageLocation !== null) { typedNameWithLocation += ` ${storageLocation}`; @@ -120,23 +115,20 @@ function parseParameter({ name, typeName, storageLocation }: VariableDeclaration return typedNameWithLocation; } -function flattenTypeName(typeName: TypeName | null): { name: string; stateMutability: string | null } { +function flattenTypeName(typeName: TypeName | null): string { if (typeName === null) { - return { - name: "", - stateMutability: null, - }; + return ""; } if (typeName.type === "ElementaryTypeName") { - return { - name: typeName.name, - stateMutability: typeName.stateMutability, - }; + if (typeName.stateMutability !== null) { + // for elementary types mutability can only be `payable`, and should be part of the elementary type name + // meaning that `address payable[]` is correct, not `address[] payable` + return `${typeName.name} ${typeName.stateMutability}`; + } else { + return typeName.name; + } } else if (typeName.type === "UserDefinedTypeName") { - return { - name: typeName.namePath, - stateMutability: null, - }; + return typeName.namePath; } else if (typeName.type === "ArrayTypeName") { let length = ""; if (typeName.length?.type === "NumberLiteral") { @@ -145,11 +137,8 @@ function flattenTypeName(typeName: TypeName | null): { name: string; stateMutabi length = typeName.length.name; } - const { name, stateMutability } = flattenTypeName(typeName.baseTypeName); - return { - name: `${name}[${length}]`, - stateMutability, - }; + const name = flattenTypeName(typeName.baseTypeName); + return `${name}[${length}]`; } else { // TODO function types are unsupported but could be useful throw new MUDError(`Invalid typeName.type ${typeName.type}`); diff --git a/test/system-libraries/src/namespaces/a/ASystem.sol b/test/system-libraries/src/namespaces/a/ASystem.sol index 664f501fb1..240da3fb2e 100644 --- a/test/system-libraries/src/namespaces/a/ASystem.sol +++ b/test/system-libraries/src/namespaces/a/ASystem.sol @@ -64,4 +64,11 @@ contract ASystem is System { Value.set(values[3]); } */ + + /* + // TODO: support this case + function getAddressPayableArray(address payable[] memory array) public pure returns (address payable[] memory) { + return array; + } + */ }