def add_globals_and_events(self, item): item_attributes = {"public": False} if len(self._globals) > NONRENTRANT_STORAGE_OFFSET: raise StructureException( f"Too many globals defined, only {NONRENTRANT_STORAGE_OFFSET} globals are allowed", item, ) # Make sure we have a valid variable name. if not isinstance(item.target, vy_ast.Name): raise StructureException("Invalid global variable name", item.target) # Handle constants. if self.get_call_func_name(item) == "constant": self._constants.add_constant(item, global_ctx=self) return item_name, item_attributes = self.get_item_name_and_attributes( item, item_attributes) if not all( [attr in VALID_GLOBAL_KEYWORDS for attr in item_attributes.keys()]): raise StructureException( f"Invalid global keyword used: {item_attributes}", item) self.is_valid_varname(item.target.id, item) if item_name in self._contracts or item_name in self._interfaces: if self.get_call_func_name(item) == "address": raise StructureException( f"Persistent address({item_name}) style contract declarations " "are not support anymore." f" Use {item.target.id}: {item_name} instead") self._globals[item.target.id] = ContractRecord( item.target.id, len(self._globals), InterfaceType(item_name), True, ) if item_attributes["public"]: typ = InterfaceType(item_name) for getter in self.mk_getter(item.target.id, typ): self._getters.append( self.parse_line("\n" * (item.lineno - 1) + getter)) self._getters[-1].pos = getpos(item) set_offsets(self._getters[-1], self._getters[-1].pos) elif self.get_call_func_name(item) == "public": if isinstance(item.annotation.args[0], vy_ast.Name) and item_name in self._contracts: typ = InterfaceType(item_name) else: typ = parse_type( item.annotation.args[0], "storage", custom_structs=self._structs, constants=self._constants, ) self._globals[item.target.id] = VariableRecord( item.target.id, len(self._globals), typ, True, ) # Adding getters here for getter in self.mk_getter(item.target.id, typ): self._getters.append( self.parse_line("\n" * (item.lineno - 1) + getter)) self._getters[-1].pos = getpos(item) set_offsets(self._getters[-1], self._getters[-1].pos) elif isinstance(item.annotation, (vy_ast.Name, vy_ast.Call, vy_ast.Subscript)): self._globals[item.target.id] = VariableRecord( item.target.id, len(self._globals), parse_type( item.annotation, "storage", custom_structs=self._structs, constants=self._constants, ), True, ) else: raise InvalidType("Invalid global type specified", item)
def add_globals_and_events(self, item): item_attributes = {"public": False} if len(self._globals) > NONRENTRANT_STORAGE_OFFSET: raise StructureException( f"Too many globals defined, only {NONRENTRANT_STORAGE_OFFSET} globals are allowed", item, ) # Make sure we have a valid variable name. if not isinstance(item.target, vy_ast.Name): raise StructureException('Invalid global variable name', item.target) # Handle constants. if self.get_call_func_name(item) == "constant": self._constants.add_constant(item, global_ctx=self) return # Handle events. if not (self.get_call_func_name(item) == "event"): item_name, item_attributes = self.get_item_name_and_attributes( item, item_attributes) if not all([ attr in VALID_GLOBAL_KEYWORDS for attr in item_attributes.keys() ]): raise StructureException( f'Invalid global keyword used: {item_attributes}', item) if item.value is not None: raise StructureException( 'May not assign value whilst defining type', item) elif self.get_call_func_name(item) == "event": if self._globals or len(self._defs): raise EventDeclarationException( "Events must all come before global declarations and function definitions", item) self._events.append(item) elif not isinstance(item.target, vy_ast.Name): raise StructureException( "Can only assign type to variable in top-level statement", item) # Is this a custom unit definition. elif item.target.id == 'units': if not self._custom_units: if not isinstance(item.annotation, vy_ast.Dict): raise VariableDeclarationException( "Define custom units using units: { }.", item.target) for key, value in zip(item.annotation.keys, item.annotation.values): if not isinstance(value, vy_ast.Str): raise VariableDeclarationException( "Custom unit description must be a valid string", value) if not isinstance(key, vy_ast.Name): raise VariableDeclarationException( "Custom unit name must be a valid string", key) check_valid_varname(key.id, self._custom_units, self._structs, self._constants, key, "Custom unit invalid.") self._custom_units.add(key.id) self._custom_units_descriptions[key.id] = value.s else: raise VariableDeclarationException( "Custom units can only be defined once", item.target) # Check if variable name is valid. # Don't move this check higher, as unit parsing has to happen first. elif not self.is_valid_varname(item.target.id, item): pass elif len(self._defs): raise StructureException( "Global variables must all come before function definitions", item, ) elif item_name in self._contracts or item_name in self._interfaces: if self.get_call_func_name(item) == "address": raise StructureException( f"Persistent address({item_name}) style contract declarations " "are not support anymore." f" Use {item.target.id}: {item_name} instead") self._globals[item.target.id] = ContractRecord( item.target.id, len(self._globals), ContractType(item_name), True, ) if item_attributes["public"]: typ = ContractType(item_name) for getter in self.mk_getter(item.target.id, typ): self._getters.append( self.parse_line('\n' * (item.lineno - 1) + getter)) self._getters[-1].pos = getpos(item) set_offsets(self._getters[-1], self._getters[-1].pos) elif self.get_call_func_name(item) == "public": if isinstance(item.annotation.args[0], vy_ast.Name) and item_name in self._contracts: typ = ContractType(item_name) else: typ = parse_type( item.annotation.args[0], 'storage', custom_units=self._custom_units, custom_structs=self._structs, constants=self._constants, ) self._globals[item.target.id] = VariableRecord( item.target.id, len(self._globals), typ, True, ) # Adding getters here for getter in self.mk_getter(item.target.id, typ): self._getters.append( self.parse_line('\n' * (item.lineno - 1) + getter)) self._getters[-1].pos = getpos(item) set_offsets(self._getters[-1], self._getters[-1].pos) elif isinstance(item.annotation, (vy_ast.Name, vy_ast.Call, vy_ast.Subscript)): self._globals[item.target.id] = VariableRecord( item.target.id, len(self._globals), parse_type(item.annotation, 'storage', custom_units=self._custom_units, custom_structs=self._structs, constants=self._constants), True) else: raise InvalidType('Invalid global type specified', item)