From 516a8f7c40602e9628869a3e05eda134ba142df9 Mon Sep 17 00:00:00 2001 From: Charles Cooper Date: Mon, 18 Jul 2022 14:32:55 -0400 Subject: [PATCH] small cleanup --- vyper/semantics/types/base.py | 69 ++++++++++++++-------------- vyper/semantics/types/bytestrings.py | 7 ++- vyper/semantics/types/user.py | 7 +-- vyper/semantics/types/value_types.py | 26 +++-------- vyper/semantics/validation/utils.py | 2 +- 5 files changed, 50 insertions(+), 61 deletions(-) diff --git a/vyper/semantics/types/base.py b/vyper/semantics/types/base.py index 7e19771c6a..2e24778aa7 100644 --- a/vyper/semantics/types/base.py +++ b/vyper/semantics/types/base.py @@ -17,7 +17,6 @@ UnexpectedValue, UnknownAttribute, ) -from vyper.semantics.types.abstract import AbstractDataType from vyper.semantics.validation.levenshtein_utils import get_levenshtein_error_suggestions @@ -135,36 +134,6 @@ def to_abi_dict(self, name: str = "") -> Dict[str, Any]: return {"name": name, "type": self.canonical_abi_type} - # TODO dead fn - @classmethod - def from_annotation( - cls, - node: Union[vy_ast.Name, vy_ast.Call], - location: DataLocation = DataLocation.UNSET, - is_constant: bool = False, - is_public: bool = False, - is_immutable: bool = False, - ) -> "BaseTypeDefinition": - """ - Generate a `BaseTypeDefinition` instance of this type from `VariableDef.annotation` - or `AnnAssign.annotation` - - Arguments - --------- - node : VyperNode - Vyper ast node from the `annotation` member of a `VariableDef` or `AnnAssign` node. - - Returns - ------- - BaseTypeDefinition - BaseTypeDefinition related to the primitive that the method was called on. - """ - if not isinstance(node, vy_ast.Name): - raise StructureException("Invalid type assignment", node) - if node.id != cls._id: - raise UnexpectedValue("Node id does not match type name") - return cls._type(location, is_constant, is_public, is_immutable) - def validate_literal(self, node: vy_ast.Constant) -> None: """ Validate whether a given literal can be annotated with this type. @@ -180,7 +149,7 @@ def validate_literal(self, node: vy_ast.Constant) -> None: raise InvalidLiteral(f"Invalid literal type for {cls.__name__}", node) @classmethod - def compare_type(cls, other: VyperType) -> bool: + def compare_type(cls, other: "VyperType") -> bool: """ Compare this type object against another type object. @@ -274,6 +243,7 @@ class VarInfo: def __init__( self, typ: VyperType, + decl_node: vy_ast.VyperNode, location: DataLocation = DataLocation.UNSET, is_constant: bool = False, is_public: bool = False, @@ -284,9 +254,10 @@ def __init__( self.is_constant = is_constant self.is_public = is_public self.is_immutable = is_immutable + self.is_local_var = is_local_var - # TODO: probably want to keep around the AST node where this was declared - self.defn_node = pass + # TODO maybe we don't actually need this + self.decl_node = decl_node self._modification_count = 0 @@ -474,6 +445,36 @@ def __init__(self, typ, var_info): if var_info is not None and var_info.typ != self.typ: raise CompilerPanic("Bad analysis: non-matching types {var_info.typ} / {self.typ}") + + @classmethod + def from_annotation( + cls, + node: vy_ast.VyperNode, + location: DataLocation = DataLocation.UNSET, + is_constant: bool = False, + is_public: bool = False, + is_immutable: bool = False, + ) -> "BaseTypeDefinition": + """ + Generate a `BaseTypeDefinition` instance of this type from `VariableDef.annotation` + or `AnnAssign.annotation` + + Arguments + --------- + node : VyperNode + Vyper ast node from the `annotation` member of a `VariableDef` or `AnnAssign` node. + + Returns + ------- + BaseTypeDefinition + BaseTypeDefinition related to the primitive that the method was called on. + """ + if not isinstance(node, vy_ast.Name): + raise StructureException("Invalid type assignment", node) + if node.id != cls._id: + raise UnexpectedValue("Node id does not match type name") + return cls.from_annotation(node) + def validate_modification( self, mutability: Any, # should be StateMutability, import cycle diff --git a/vyper/semantics/types/bytestrings.py b/vyper/semantics/types/bytestrings.py index 847a756eef..17c1703fe5 100644 --- a/vyper/semantics/types/bytestrings.py +++ b/vyper/semantics/types/bytestrings.py @@ -6,8 +6,7 @@ from vyper.semantics import validation from vyper.utils import ceil32 -from ..abstract import ArrayValueAbstractType, BytesAbstractType -from ..bases import BasePrimitive, DataLocation, ValueTypeDefinition +from .base import VyperType, DataLocation class _BytestringT(VyperType): @@ -106,7 +105,7 @@ def compare_type(self, other): @classmethod - def from_annotation( cls, node: vy_ast.VyperNode) -> _BytestringT: + def from_annotation( cls, node: vy_ast.VyperNode) -> "_BytestringT": if not isinstance(node, vy_ast.Subscript): raise StructureException( f"Cannot declare {cls._id} type without a maximum length", node @@ -121,7 +120,7 @@ def from_annotation( cls, node: vy_ast.VyperNode) -> _BytestringT: return cls._type(length, location, is_constant, is_public, is_immutable) @classmethod - def from_literal(cls, node: vy_ast.Constant) -> _BytestringT: + def from_literal(cls, node: vy_ast.Constant) -> "_BytestringT": super().from_literal(node) length = len(node.value) diff --git a/vyper/semantics/types/user.py b/vyper/semantics/types/user.py index 4185104dff..062a62eb27 100644 --- a/vyper/semantics/types/user.py +++ b/vyper/semantics/types/user.py @@ -9,7 +9,8 @@ UnknownAttribute, ) from vyper.semantics.namespace import validate_identifier -from vyper.semantics.types.bases import DataLocation, MemberTypeDefinition, ValueTypeDefinition +from vyper.semantics.types.base import DataLocation, AttributableT +from vyper.semantics.types.value_types import AddressT from vyper.semantics.validation.levenshtein_utils import get_levenshtein_error_suggestions @@ -87,7 +88,7 @@ def to_abi_dict(self) -> List[Dict]: # TODO return [] - def get_member(self, key: str, node: vy_ast.Attribute) -> EnumDefinition: + def get_member(self, key: str, node: vy_ast.Attribute) -> "EnumT": if key in self.members: return self.from_annotation(node.value) suggestions_str = get_levenshtein_error_suggestions(key, self.members, 0.3) @@ -111,7 +112,7 @@ class EventT: Name of the event. """ - def __init__(self, name: str, arguments: OrderedDict, indexed: List) -> None: + def __init__(self, name: str, arguments: dict, indexed: list) -> None: for key in arguments: validate_identifier(key) self.name = name diff --git a/vyper/semantics/types/value_types.py b/vyper/semantics/types/value_types.py index 4089e4479d..aa316e46e1 100644 --- a/vyper/semantics/types/value_types.py +++ b/vyper/semantics/types/value_types.py @@ -3,11 +3,8 @@ from vyper.exceptions import InvalidLiteral from vyper.utils import checksum_encode, is_checksum_encoded -from ..bases import BasePrimitive, MemberTypeDefinition, ValueTypeDefinition -from .array_value import BytesArrayDefinition -from .boolean import BoolDefinition -from .bytes_fixed import Bytes32Definition -from .numeric import Uint256Definition # type: ignore +from .base import AttributableT, VyperType +from .bytestrings import BytesT class AddressT(AttributableT): @@ -15,11 +12,11 @@ class AddressT(AttributableT): _id = "address" _valid_literal = (vy_ast.Hex,) _type_members = { - "balance": Uint256Definition(is_constant=True), - "codehash": Bytes32Definition(is_constant=True), - "codesize": Uint256Definition(is_constant=True), - "is_contract": BoolDefinition(is_constant=True), - "code": BytesArrayDefinition(is_constant=True), + "balance": IntegerT(), + "codehash": Bytes32Definition(), + "codesize": Uint256Definition(), + "is_contract": BoolDefinition(), + "code": BytesArrayDefinition(), } @property @@ -96,15 +93,6 @@ def validate_literal(cls, node: vy_ast.Constant): raise InvalidLiteral(f"Cannot mix uppercase and lowercase for bytes{m} literal", node) -# including so mypy does not complain while we are generating types dynamically -class Bytes32Definition(BytesMDefinition): - - # included for compatibility with bytes array methods - length = 32 - _length = 32 - _min_length = 32 - - class AbstractNumericDefinition(ValueTypeDefinition): """ Private base class for numeric definitions. diff --git a/vyper/semantics/validation/utils.py b/vyper/semantics/validation/utils.py index 32f4fb642b..a1e2037ede 100644 --- a/vyper/semantics/validation/utils.py +++ b/vyper/semantics/validation/utils.py @@ -428,7 +428,7 @@ def validate_expected_type(node, expected_type): if isinstance(node, (vy_ast.List, vy_ast.Tuple)): # special case - for literal arrays or tuples we individually validate each item for expected in expected_type: - if not isinstance(expected, (DynamicArrayDefinition, ArrayDefinition)): + if not isinstance(expected, (DArrayT, SArrayT)): continue if _validate_literal_array(node, expected): return