예제 #1
0
def test_builtin_interfaces_parse():
    assert len(extract_sigs({
        "type": "vyper",
        "code": ERC20.interface_code
    })) == 6
    assert len(extract_sigs({
        "type": "vyper",
        "code": ERC721.interface_code
    })) == 9
예제 #2
0
def test_extract_sigs_ignores_imports():
    interface_code = """
{}

@external
def foo() -> uint256:
    pass
    """

    base = extract_sigs({"type": "vyper", "code": interface_code.format("")})

    for stmt in ("import x as x", "from x import y"):
        sigs = extract_sigs({
            "type": "vyper",
            "code": interface_code.format(stmt)
        })
        assert [type(i) for i in base] == [type(i) for i in sigs]
예제 #3
0
    def get_global_context(
            cls,
            vyper_module: "vy_ast.Module",
            interface_codes: Optional[InterfaceImports] = None
    ) -> "GlobalContext":
        # TODO is this a cyclic import?
        from vyper.ast.signatures.interface import (
            extract_sigs,
            get_builtin_interfaces,
        )

        interface_codes = {} if interface_codes is None else interface_codes
        global_ctx = cls()

        for item in vyper_module:
            if isinstance(item, vy_ast.StructDef):
                global_ctx._structs[item.name] = global_ctx.make_struct(item)

            elif isinstance(item, vy_ast.InterfaceDef):
                global_ctx._contracts[item.name] = GlobalContext.make_contract(
                    item)

            elif isinstance(item, vy_ast.EventDef):
                continue

            # Statements of the form:
            # variable_name: type
            elif isinstance(item, vy_ast.AnnAssign):
                global_ctx.add_globals_and_events(item)
            # Function definitions
            elif isinstance(item, vy_ast.FunctionDef):
                global_ctx._defs.append(item)
            elif isinstance(item, vy_ast.ImportFrom):
                interface_name = item.name
                assigned_name = item.alias or item.name
                if assigned_name in global_ctx._interfaces:
                    raise StructureException(
                        f"Duplicate import of {interface_name}", item)

                if not item.level and item.module == "vyper.interfaces":
                    built_in_interfaces = get_builtin_interfaces()
                    if interface_name not in built_in_interfaces:
                        raise StructureException(
                            f"Built-In interface {interface_name} does not exist.",
                            item)
                    global_ctx._interfaces[
                        assigned_name] = built_in_interfaces[
                            interface_name].copy()
                else:
                    if interface_name not in interface_codes:
                        raise StructureException(
                            f"Unknown interface {interface_name}", item)
                    global_ctx._interfaces[assigned_name] = extract_sigs(
                        interface_codes[interface_name], interface_name)
            elif isinstance(item, vy_ast.Import):
                interface_name = item.alias
                if interface_name in global_ctx._interfaces:
                    raise StructureException(
                        f"Duplicate import of {interface_name}", item)
                if interface_name not in interface_codes:
                    raise StructureException(
                        f"Unknown interface {interface_name}", item)
                global_ctx._interfaces[interface_name] = extract_sigs(
                    interface_codes[interface_name], interface_name)
            else:
                raise StructureException("Invalid top-level statement", item)

        # Merge intefaces.
        if global_ctx._interfaces:
            for interface_name, sigs in global_ctx._interfaces.items():
                if interface_name in global_ctx._implemented_interfaces:
                    for func_sig in sigs:
                        func_sig.defined_in_interface = interface_name
                        global_ctx._interface[func_sig.sig] = func_sig

        return global_ctx