Skip to content

Commit

Permalink
Support overloaded functions by creating an interface per function
Browse files Browse the repository at this point in the history
  • Loading branch information
vdrg committed Dec 19, 2024
1 parent 15afa74 commit 6d4cbec
Show file tree
Hide file tree
Showing 6 changed files with 120 additions and 27 deletions.
44 changes: 32 additions & 12 deletions packages/world/ts/node/render-solidity/renderSystemLibrary.ts
Original file line number Diff line number Diff line change
Expand Up @@ -87,9 +87,9 @@ export function renderSystemLibrary(options: RenderSystemLibraryOptions) {
${renderList(functions, (contractFunction) => renderUserTypeFunction(contractFunction, userTypeName))}
${renderList(functions, (contractFunction) => renderCallWrapperFunction(contractFunction, systemLabel, callingFromRootSystemErrorName))}
${renderList(functions, (contractFunction) => renderCallWrapperFunction(contractFunction, callingFromRootSystemErrorName))}
${renderList(functions, (contractFunction) => renderRootCallWrapperFunction(contractFunction, systemLabel, namespace))}
${renderList(functions, (contractFunction) => renderRootCallWrapperFunction(contractFunction, namespace))}
function callFrom(${userTypeName} self, address from) internal pure returns (CallWrapper memory) {
return CallWrapper(self.toResourceId(), from);
Expand Down Expand Up @@ -120,6 +120,12 @@ export function renderSystemLibrary(options: RenderSystemLibraryOptions) {
}
}
/**
* These interfaces are used to support overloaded functions
*/
${renderList(functions, (contractFunction) => renderFunctionInterface(contractFunction))}
using ${libraryName} for ${userTypeName} global;
using ${libraryName} for CallWrapper global;
using ${libraryName} for RootCallWrapper global;
Expand Down Expand Up @@ -154,7 +160,6 @@ function renderUserTypeFunction(contractFunction: ContractInterfaceFunction, use

function renderCallWrapperFunction(
contractFunction: ContractInterfaceFunction,
systemLabel: string,
callingFromRootSystemErrorName: string,
) {
const { name, parameters, stateMutability, returnParameters } = contractFunction;
Expand All @@ -174,7 +179,7 @@ function renderCallWrapperFunction(
if (address(_world()) == address(this)) revert ${callingFromRootSystemErrorName}();
`;

const encodedSystemCall = renderEncodeSystemCall(systemLabel, name, parameters);
const encodedSystemCall = renderEncodeSystemCall(contractFunction);

if (stateMutability === "") {
return `
Expand Down Expand Up @@ -203,11 +208,7 @@ function renderCallWrapperFunction(
}
}

function renderRootCallWrapperFunction(
contractFunction: ContractInterfaceFunction,
systemLabel: string,
namespace: string,
) {
function renderRootCallWrapperFunction(contractFunction: ContractInterfaceFunction, namespace: string) {
const { name, parameters, stateMutability, returnParameters } = contractFunction;

// Staticcalls are not supported between root systems yet, due to the additional
Expand All @@ -226,7 +227,7 @@ function renderRootCallWrapperFunction(
${renderReturnParameters(returnParameters)}
`;

const encodedSystemCall = renderEncodeSystemCall(systemLabel, name, parameters);
const encodedSystemCall = renderEncodeSystemCall(contractFunction);

if (stateMutability === "") {
return `
Expand All @@ -248,9 +249,28 @@ function renderRootCallWrapperFunction(
}
}

function renderEncodeSystemCall(interfaceName: string, functionName: string, parameters: string[]) {
function renderFunctionInterface(contractFunction: ContractInterfaceFunction) {
const { name, parameters } = contractFunction;

return `
interface ${functionInterfaceName(contractFunction)} {
function ${name}(
${renderArguments(parameters)}
) external;
}
`;
}

function functionInterfaceName(contractFunction: ContractInterfaceFunction) {
const { name, parameters } = contractFunction;
const paramTypes = parameters.map((param) => param.split(" ")[0]).join("_");
return `_I${name}${paramTypes.length === 0 ? "" : `_${paramTypes}`}`;
}

function renderEncodeSystemCall(contractFunction: ContractInterfaceFunction) {
const { name, parameters } = contractFunction;
const paramNames = parameters.map((param) => param.split(" ").slice(-1)[0]).join(", ");
return `abi.encodeCall(${interfaceName}.${functionName}, (${paramNames}))`;
return `abi.encodeCall(${functionInterfaceName(contractFunction)}.${name}, (${paramNames}))`;
}

function renderAbiDecode(expression: string, returnParameters: string[]) {
Expand Down
2 changes: 2 additions & 0 deletions test/system-libraries/src/codegen/world/IASystem.sol

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions test/system-libraries/src/namespaces/a/ASystem.sol
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@ contract ASystem is System {
Value.set(value.a);
}

function setValue(uint256 value) external {
Value.set(value);
}

function getValue() external view returns (uint256) {
return Value.get();
}
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 6d4cbec

Please sign in to comment.