def get_global_context(cls, code, interface_codes=None): from vyper.signatures.interface import ( extract_sigs, get_builtin_interfaces, ) interface_codes = {} if interface_codes is None else interface_codes global_ctx = cls() for item in code: # Contract references if isinstance(item, ast.ClassDef): if global_ctx._events or global_ctx._globals or global_ctx._defs: raise StructureException( ("External contract and struct declarations must come " "before event declarations, global declarations, and " "function definitions"), item) if item.class_type == 'struct': if global_ctx._contracts: raise StructureException( "Structs must come before external contract definitions", item) global_ctx._structs[item.name] = global_ctx.make_struct( item.name, item.body) elif item.class_type == 'contract': if item.name in global_ctx._contracts or item.name in global_ctx._interfaces: raise StructureException( f"Contract '{item.name}' is already defined", item, ) global_ctx._contracts[ item.name] = GlobalContext.make_contract(item.body) else: raise StructureException( "Unknown class_type. This is likely a compiler bug, please report", item) # Statements of the form: # variable_name: type elif isinstance(item, ast.AnnAssign): is_implements_statement = (isinstance(item.target, ast.Name) and item.target.id == 'implements') and item.annotation # implements statement. if is_implements_statement: interface_name = item.annotation.id if interface_name not in global_ctx._interfaces: raise StructureException( f'Unknown interface specified: {interface_name}', item) global_ctx._implemented_interfaces.add(interface_name) else: global_ctx.add_globals_and_events(item) # Function definitions elif isinstance(item, ast.FunctionDef): if item.name in global_ctx._globals: raise FunctionDeclarationException( f"Function name shadowing a variable name: {item.name}" ) global_ctx._defs.append(item) elif isinstance(item, ast.ImportFrom): if not item.level and item.module == 'vyper.interfaces': built_in_interfaces = get_builtin_interfaces() for item_alias in item.names: interface_name = item_alias.name if interface_name in global_ctx._interfaces: raise StructureException( f'Duplicate import of {interface_name}', item) if interface_name not in built_in_interfaces: raise StructureException( f'Built-In interface {interface_name} does not exist.', item) global_ctx._interfaces[ interface_name] = built_in_interfaces[ interface_name].copy() # noqa: E501 else: for item_alias in item.names: interface_name = item_alias.name 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]) # noqa: E501 elif isinstance(item, ast.Import): for item_alias in item.names: if not item_alias.asname: raise StructureException( 'External interface import expects an alias using `as` statement', item) interface_name = item_alias.asname 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]) # noqa: E501 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 # Add getters to _defs global_ctx._defs += global_ctx._getters return global_ctx
def get_global_context(cls, code, interface_codes=None): interface_codes = {} if interface_codes is None else interface_codes global_ctx = cls() for item in code: # Contract references if isinstance(item, ast.ClassDef): if global_ctx._events or global_ctx._globals or global_ctx._defs: raise StructureException( "External contract and struct declarations must come before event declarations, global declarations, and function definitions", item) if item.class_type == 'struct': if global_ctx._contracts: raise StructureException( "Structs must come before external contract definitions", item) global_ctx._structs[item.name] = global_ctx.make_struct( item.name, item.body) elif item.class_type == 'contract': global_ctx._contracts[ item.name] = GlobalContext.make_contract(item.body) else: raise StructureException( "Unknown class_type. This is likely a compiler bug, please report", item) # Statements of the form: # variable_name: type elif isinstance(item, ast.AnnAssign): # implements statement. if isinstance( item.target, ast.Name ) and item.target.id == 'implements' and item.annotation: interface_name = item.annotation.id if interface_name not in global_ctx._interfaces: raise StructureException( 'Unknown interface specified: {}'.format( interface_name), item) global_ctx._implemented_interfaces.add(interface_name) else: global_ctx.add_globals_and_events(item) # Function definitions elif isinstance(item, ast.FunctionDef): if item.name in global_ctx._globals: raise FunctionDeclarationException( "Function name shadowing a variable name: %s" % item.name) global_ctx._defs.append(item) elif isinstance(item, ast.ImportFrom): if item.module == 'vyper.interfaces': built_in_interfaces = get_builtin_interfaces() for item_alias in item.names: interface_name = item_alias.name if interface_name in global_ctx._interfaces: raise StructureException( 'Duplicate import of {}'.format( interface_name), item) if interface_name not in built_in_interfaces: raise StructureException( 'Built-In interface {} does not exist.'.format( interface_name), item) global_ctx._interfaces[ interface_name] = built_in_interfaces[ interface_name].copy() else: raise StructureException( 'Only built-in vyper.interfaces package supported for `from` statement.', item) elif isinstance(item, ast.Import): for item_alias in item.names: if not item_alias.asname: raise StructureException( 'External interface import expects and alias using `as` statement', item) interface_name = item_alias.asname if interface_name in global_ctx._interfaces: raise StructureException( 'Duplicate import of {}'.format(interface_name), item) if interface_name not in interface_codes: raise StructureException( 'Unknown interface {}'.format(interface_name), item) global_ctx._interfaces[interface_name] = extract_sigs( interface_codes[interface_name]) else: raise StructureException("Invalid top-level statement", item) if set(global_ctx._interfaces.keys() ) != global_ctx._implemented_interfaces: raise StructureException( 'All interfaces that are imported have to be implemented using the "implements" statement.' ) # Merge intefaces. if global_ctx._interfaces: for interface_name, sigs in global_ctx._interfaces.items(): for func_sig in sigs: setattr(func_sig, 'defined_in_interface', interface_name) global_ctx._interface[func_sig.sig] = func_sig # Add getters to _defs global_ctx._defs += global_ctx._getters return global_ctx
def get_global_context( cls, vyper_module: "vy_ast.Module", interface_codes: Optional[InterfaceImports] = None ) -> "GlobalContext": from vyper.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): global_ctx._events.append(item) # Statements of the form: # variable_name: type elif isinstance(item, vy_ast.AnnAssign): is_implements_statement = (isinstance(item.target, vy_ast.Name) and item.target.id == "implements") and item.annotation # implements statement. if is_implements_statement: interface_name = item.annotation.id # type: ignore if interface_name not in global_ctx._interfaces: raise StructureException( f"Unknown interface specified: {interface_name}", item) global_ctx._implemented_interfaces.add(interface_name) else: 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]) 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]) 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 # Add getters to _defs global_ctx._defs += global_ctx._getters return global_ctx