From f8536c7896a839256b2cad74a621e532bb38cd7b Mon Sep 17 00:00:00 2001 From: Daniel Schiavini Date: Fri, 31 May 2024 10:20:16 +0200 Subject: [PATCH] Copy part of compiler_utils from boa --- .github/workflows/release.yaml | 8 +--- boa_zksync/compiler_utils.py | 77 ++++++++++++++++++++++++++++++++++ boa_zksync/contract.py | 2 +- 3 files changed, 80 insertions(+), 7 deletions(-) create mode 100644 boa_zksync/compiler_utils.py diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index 6bbf861..816e489 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -1,17 +1,13 @@ on: release: - types: [published] # releases and pre-releases (release candidates) + types: [published] jobs: publish-pypi: runs-on: ubuntu-latest - # https://docs.pypi.org/trusted-publishers/using-a-publisher/ permissions: - # IMPORTANT: this permission is mandatory for trusted publishing id-token: write - # Specifying a GitHub environment is optional, but strongly encouraged - environment: release steps: - uses: actions/checkout@v4 @@ -19,7 +15,7 @@ jobs: - name: Python uses: actions/setup-python@v5 with: - python-version: "3.11" + cache: "pip" - name: Install dependencies run: | diff --git a/boa_zksync/compiler_utils.py b/boa_zksync/compiler_utils.py new file mode 100644 index 0000000..10d0d94 --- /dev/null +++ b/boa_zksync/compiler_utils.py @@ -0,0 +1,77 @@ +import textwrap + +import vyper.ast as vy_ast +from vyper.ast.utils import parse_to_ast +from vyper.exceptions import InvalidType +from vyper.semantics.analysis.utils import get_exact_type_from_node + + +def generate_source_for_internal_fn(fn): + """Wraps internal fns with an external fn and generate source code""" + + fn_name = fn.func_t.name + fn_args = ", ".join([arg.name for arg in fn.func_t.arguments]) + + return_sig = "" + fn_call = "" + if fn.func_t.return_type: + return_sig = f" -> {fn.func_t.return_type}" + fn_call = "return " + fn_call += f"self.{fn_name}({fn_args})" + + # same but with defaults, signatures, etc.: + _fn_sig = [] + for arg in fn.func_t.arguments: + sig_arg_text = f"{arg.name}: {arg.typ}" + + # check if arg has a default value: + if arg.name in fn.func_t.default_values: + default_value = fn.func_t.default_values[arg.name].value + sig_arg_text += f" = {default_value}" + + _fn_sig.append(sig_arg_text) + fn_sig = ", ".join(_fn_sig) + + return textwrap.dedent( + f""" + @external + @payable + def __boa_private_{fn_name}__({fn_sig}){return_sig}: + {fn_call} + """ + ) + + +def generate_source_for_arbitrary_stmt(source_code, contract): + """Wraps arbitrary stmts with external fn and generates source code""" + + ast_typ = detect_expr_type(source_code, contract) + if ast_typ: + return_sig = f"-> {ast_typ}" + debug_body = f"return {source_code}" + else: + return_sig = "" + debug_body = source_code + + # wrap code in function so that we can easily generate code for it + return textwrap.dedent( + f""" + @external + @payable + def __boa_debug__() {return_sig}: + {debug_body} + """ + ) + + +def detect_expr_type(source_code, contract): + ast = parse_to_ast(source_code) + vy_ast.folding.fold(ast) + ast = ast.body[0] + if isinstance(ast, vy_ast.Expr): + with contract.override_vyper_namespace(): + try: + return get_exact_type_from_node(ast.value) + except InvalidType: + pass + return None diff --git a/boa_zksync/contract.py b/boa_zksync/contract.py index 066529f..f323765 100644 --- a/boa_zksync/contract.py +++ b/boa_zksync/contract.py @@ -2,7 +2,7 @@ from contextlib import contextmanager from boa.contracts.abi.abi_contract import ABIContract, ABIFunction -from boa.contracts.vyper.compiler_utils import ( +from boa_zksync.compiler_utils import ( detect_expr_type, generate_source_for_arbitrary_stmt, generate_source_for_internal_fn,