def add_globals_and_events(self, item): item_attributes = {"public": False} if self._nonrentrant_counter: raise CompilerPanic("Re-entrancy lock was set before all storage slots were defined") # 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": return item_name, item_attributes = self.get_item_name_and_attributes(item, item_attributes) 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, ) 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,) self._globals[item.target.id] = VariableRecord( item.target.id, len(self._globals), typ, True, ) 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,), True, ) else: raise InvalidType("Invalid global type specified", item)
def add_globals_and_events(self, item): item_attributes = {"public": False} # Make sure we have a valid variable name. if not isinstance(item.target, 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( 'Invalid global keyword used: %s' % 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, 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, 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, ast.Str): raise VariableDeclarationException( "Custom unit description must be a valid string", value) if not isinstance(key, 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) # If the type declaration is of the form public(<type here>), then proceed with # the underlying type but also add getters elif self.get_call_func_name(item) == "address": if item.annotation.args[0].id not in premade_contracts: raise VariableDeclarationException( "Unsupported premade contract declaration", item.annotation.args[0]) premade_contract = premade_contracts[item.annotation.args[0].id] self._contracts[item.target.id] = self.make_contract( premade_contract.body) self._globals[item.target.id] = VariableRecord( item.target.id, len(self._globals), BaseType('address'), True) elif item_name in self._contracts: 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) elif self.get_call_func_name(item) == "public": if isinstance(item.annotation.args[0], 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) elif isinstance(item.annotation, (ast.Name, ast.Call, 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 InvalidTypeException('Invalid global type specified', item)
def add_globals_and_events(self, item): item_attributes = {"public": False} if len(self._globals) > NONRENTRANT_STORAGE_OFFSET: raise ParserException( 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, 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, 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, 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, ast.Str): raise VariableDeclarationException( "Custom unit description must be a valid string", value) if not isinstance(key, 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) elif self.get_call_func_name(item) == "public": if isinstance(item.annotation.args[0], 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) elif isinstance(item.annotation, (ast.Name, ast.Call, 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 InvalidTypeException('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 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(_custom_units, _contracts, _defs, _events, _getters, _globals, item): item_attributes = {"public": False} if not (isinstance(item.annotation, ast.Call) and item.annotation.func.id == "event"): item_name, item_attributes = get_item_name_and_attributes(item, item_attributes) if not all([attr in valid_global_keywords for attr in item_attributes.keys()]): raise StructureException('Invalid global keyword used: %s' % item_attributes, item) if item.value is not None: raise StructureException('May not assign value whilst defining type', item) elif isinstance(item.annotation, ast.Call) and item.annotation.func.id == "event": if _globals or len(_defs): raise EventDeclarationException("Events must all come before global declarations and function definitions", item) _events.append(item) elif not isinstance(item.target, 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 _custom_units: if not isinstance(item.annotation, 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, ast.Str): raise VariableDeclarationException("Custom unit description must be a valid string.", value) if not isinstance(key, ast.Name): raise VariableDeclarationException("Custom unit name must be a valid string unquoted string.", key) if key.id in _custom_units: raise VariableDeclarationException("Custom unit may only be defined once", key) if not is_varname_valid(key.id, custom_units=_custom_units): raise VariableDeclarationException("Custom unit may not be a reserved keyword", key) _custom_units.append(key.id) else: raise VariableDeclarationException("Can units can only defined once.", item.target) # Check if variable name is reserved or invalid elif not is_varname_valid(item.target.id, custom_units=_custom_units): raise VariableDeclarationException("Variable name invalid or reserved: ", item.target) # Check if global already exists, if so error elif item.target.id in _globals: raise VariableDeclarationException("Cannot declare a persistent variable twice!", item.target) elif len(_defs): raise StructureException("Global variables must all come before function definitions", item) # If the type declaration is of the form public(<type here>), then proceed with # the underlying type but also add getters elif isinstance(item.annotation, ast.Call) and item.annotation.func.id == "address": if item.annotation.args[0].id not in premade_contracts: raise VariableDeclarationException("Unsupported premade contract declaration", item.annotation.args[0]) premade_contract = premade_contracts[item.annotation.args[0].id] _contracts[item.target.id] = add_contract(premade_contract.body) _globals[item.target.id] = VariableRecord(item.target.id, len(_globals), BaseType('address'), True) elif item_name in _contracts: _globals[item.target.id] = ContractRecord(item.target.id, len(_globals), ContractType(item_name), True) if item_attributes["public"]: typ = ContractType(item_name) for getter in mk_getter(item.target.id, typ): _getters.append(parse_line('\n' * (item.lineno - 1) + getter)) _getters[-1].pos = getpos(item) elif isinstance(item.annotation, ast.Call) and item.annotation.func.id == "public": if isinstance(item.annotation.args[0], ast.Name) and item_name in _contracts: typ = ContractType(item_name) else: typ = parse_type(item.annotation.args[0], 'storage', custom_units=_custom_units) _globals[item.target.id] = VariableRecord(item.target.id, len(_globals), typ, True) # Adding getters here for getter in mk_getter(item.target.id, typ): _getters.append(parse_line('\n' * (item.lineno - 1) + getter)) _getters[-1].pos = getpos(item) else: _globals[item.target.id] = VariableRecord( item.target.id, len(_globals), parse_type(item.annotation, 'storage', custom_units=_custom_units), True ) return _custom_units, _contracts, _events, _globals, _getters