From 58e80bd5a2db7d2f6d0d53f4ff955573ce2d2766 Mon Sep 17 00:00:00 2001 From: tserg <8017125+tserg@users.noreply.github.com> Date: Sun, 5 Mar 2023 12:27:42 +0800 Subject: [PATCH 01/21] validate internal function names --- vyper/semantics/analysis/module.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/vyper/semantics/analysis/module.py b/vyper/semantics/analysis/module.py index 21ee13a566..df420baa3b 100644 --- a/vyper/semantics/analysis/module.py +++ b/vyper/semantics/analysis/module.py @@ -265,8 +265,7 @@ def visit_FunctionDef(self, node): func = ContractFunctionT.from_FunctionDef(node) try: - # TODO sketchy elision of namespace validation - self.namespace["self"].typ.add_member(func.name, func, skip_namespace_validation=True) + self.namespace["self"].typ.add_member(func.name, func) node._metadata["type"] = func except VyperException as exc: raise exc.with_annotation(node) from None From 8647e9d33112734bd2a37886fac352b8b5229035 Mon Sep 17 00:00:00 2001 From: tserg <8017125+tserg@users.noreply.github.com> Date: Sun, 5 Mar 2023 12:27:57 +0800 Subject: [PATCH 02/21] add test case --- tests/parser/syntax/utils/test_function_names.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tests/parser/syntax/utils/test_function_names.py b/tests/parser/syntax/utils/test_function_names.py index ca7158a9b3..8d56224528 100644 --- a/tests/parser/syntax/utils/test_function_names.py +++ b/tests/parser/syntax/utils/test_function_names.py @@ -35,6 +35,11 @@ def false(i: int128) -> int128: temp_var : int128 = i return temp_var """, + """ +@external +def floor(): + pass + """ ] From 8a3122b3aff0a065556f17e99aa004cc96b35774 Mon Sep 17 00:00:00 2001 From: tserg <8017125+tserg@users.noreply.github.com> Date: Sun, 5 Mar 2023 12:34:00 +0800 Subject: [PATCH 03/21] fix lint --- tests/parser/syntax/utils/test_function_names.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/parser/syntax/utils/test_function_names.py b/tests/parser/syntax/utils/test_function_names.py index 8d56224528..daa2d64308 100644 --- a/tests/parser/syntax/utils/test_function_names.py +++ b/tests/parser/syntax/utils/test_function_names.py @@ -39,7 +39,7 @@ def false(i: int128) -> int128: @external def floor(): pass - """ + """, ] From 6cbf0e77800e25e1f6e39025d7e218829e4f4445 Mon Sep 17 00:00:00 2001 From: tserg <8017125+tserg@users.noreply.github.com> Date: Sun, 5 Mar 2023 13:56:30 +0800 Subject: [PATCH 04/21] remove invalid syntax test --- tests/parser/syntax/test_send.py | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/tests/parser/syntax/test_send.py b/tests/parser/syntax/test_send.py index 15ec19f770..d966df29c6 100644 --- a/tests/parser/syntax/test_send.py +++ b/tests/parser/syntax/test_send.py @@ -137,17 +137,6 @@ def foo(): send(0xde0B295669a9FD93d5F28D9Ec85E40f4cb697BAe, 5) """, """ -# Test custom send method -@internal -def send(a: address, w: uint256): - send(0xde0B295669a9FD93d5F28D9Ec85E40f4cb697BAe, 1) - -@external -@payable -def foo(): - self.send(msg.sender, msg.value) - """, - """ #Test send gas stipend @external def foo(): From a0c32cb957a6cc6f0e8ddb7c05c479809afaeaab Mon Sep 17 00:00:00 2001 From: tserg <8017125+tserg@users.noreply.github.com> Date: Fri, 7 Apr 2023 13:40:16 +0800 Subject: [PATCH 05/21] split validate_identifier to namespace and name --- vyper/semantics/analysis/module.py | 2 +- vyper/semantics/namespace.py | 8 ++++++-- vyper/semantics/types/base.py | 11 +++++++---- vyper/semantics/types/user.py | 2 +- 4 files changed, 15 insertions(+), 8 deletions(-) diff --git a/vyper/semantics/analysis/module.py b/vyper/semantics/analysis/module.py index 28591e366d..709b65e294 100644 --- a/vyper/semantics/analysis/module.py +++ b/vyper/semantics/analysis/module.py @@ -269,7 +269,7 @@ def visit_FunctionDef(self, node): func = ContractFunctionT.from_FunctionDef(node) try: - self.namespace["self"].typ.add_member(func.name, func) + self.namespace["self"].typ.add_member(func.name, func, skip_namespace_validation=True) node._metadata["type"] = func except VyperException as exc: raise exc.with_annotation(node) from None diff --git a/vyper/semantics/namespace.py b/vyper/semantics/namespace.py index 752ef7ad96..713a28f6a9 100644 --- a/vyper/semantics/namespace.py +++ b/vyper/semantics/namespace.py @@ -88,7 +88,8 @@ def clear(self): self.__init__() def validate_assignment(self, attr): - validate_identifier(attr) + validate_identifier_name(attr) + validate_identifier_with_namespace(attr) if attr in self: obj = super().__getitem__(attr) raise NamespaceCollision(f"'{attr}' has already been declared as a {obj}") @@ -119,12 +120,15 @@ def override_global_namespace(ns): _namespace = tmp -def validate_identifier(attr): +def validate_identifier_with_namespace(attr): namespace = get_namespace() if attr in namespace and attr not in [x for i in namespace._scopes for x in i]: raise NamespaceCollision(f"Cannot assign to '{attr}', it is a builtin") if attr.lower() in RESERVED_KEYWORDS or attr.upper() in OPCODES: raise StructureException(f"'{attr}' is a reserved keyword") + + +def validate_identifier_name(attr): if not re.match("^[_a-zA-Z][a-zA-Z0-9_]*$", attr): raise StructureException(f"'{attr}' contains invalid character(s)") diff --git a/vyper/semantics/types/base.py b/vyper/semantics/types/base.py index 4216b5e23e..552acd76e9 100644 --- a/vyper/semantics/types/base.py +++ b/vyper/semantics/types/base.py @@ -12,7 +12,7 @@ UnknownAttribute, ) from vyper.semantics.analysis.levenshtein_utils import get_levenshtein_error_suggestions -from vyper.semantics.namespace import validate_identifier +from vyper.semantics.namespace import validate_identifier_with_namespace, validate_identifier_name # Some fake type with an overridden `compare_type` which accepts any RHS @@ -57,7 +57,9 @@ class VyperType: size_in_bytes = 32 # default; override for larger types - def __init__(self, members: Optional[Dict] = None) -> None: + def __init__( + self, members: Optional[Dict] = None, skip_namespace_validation: bool = False + ) -> None: self.members: Dict = {} # add members that are on the class instance. @@ -69,7 +71,7 @@ def __init__(self, members: Optional[Dict] = None) -> None: members = members or {} for k, v in members.items(): - self.add_member(k, v) + self.add_member(k, v, skip_namespace_validation=skip_namespace_validation) def _get_equality_attrs(self): return tuple(getattr(self, attr) for attr in self._equality_attrs) @@ -283,7 +285,8 @@ def add_member( # skip_namespace_validation provides a way of bypassing validate_identifier, which # introduces a dependency cycle with the builtin_functions module if not skip_namespace_validation: - validate_identifier(name) + validate_identifier_with_namespace(name) + validate_identifier_name(name) if name in self.members: raise NamespaceCollision(f"Member '{name}' already exists in {self}") self.members[name] = type_ diff --git a/vyper/semantics/types/user.py b/vyper/semantics/types/user.py index 536d482e75..f25cc79894 100644 --- a/vyper/semantics/types/user.py +++ b/vyper/semantics/types/user.py @@ -268,7 +268,7 @@ class InterfaceT(_UserType): def __init__(self, _id: str, members: dict, events: dict) -> None: validate_unique_method_ids(list(members.values())) # explicit list cast for mypy - super().__init__(members) + super().__init__(members, skip_namespace_validation=True) self._id = _id self.events = events From c42ecd1273dac5b714bd83e1d9934b1b52f8cf3a Mon Sep 17 00:00:00 2001 From: tserg <8017125+tserg@users.noreply.github.com> Date: Fri, 7 Apr 2023 13:40:25 +0800 Subject: [PATCH 06/21] update tests --- .../syntax/utils/test_function_names.py | 60 +++++++++---------- 1 file changed, 30 insertions(+), 30 deletions(-) diff --git a/tests/parser/syntax/utils/test_function_names.py b/tests/parser/syntax/utils/test_function_names.py index daa2d64308..e06c5aae50 100644 --- a/tests/parser/syntax/utils/test_function_names.py +++ b/tests/parser/syntax/utils/test_function_names.py @@ -4,42 +4,13 @@ from vyper import compiler from vyper.exceptions import NamespaceCollision, StructureException -fail_list = [ # noqa: E122 +fail_list = [ """ @external def ő1qwerty(i: int128) -> int128: temp_var : int128 = i return temp_var - """, - """ -@external -def int128(i: int128) -> int128: - temp_var : int128 = i - return temp_var - """, """ -@external -def decimal(i: int128) -> int128: - temp_var : int128 = i - return temp_var - """, - """ -@external -def wei(i: int128) -> int128: - temp_var : int128 = i - return temp_var - """, - """ -@external -def false(i: int128) -> int128: - temp_var : int128 = i - return temp_var - """, - """ -@external -def floor(): - pass - """, ] @@ -68,6 +39,35 @@ def first1(i: int128) -> int128: _var123 : int128 = i return _var123 """, + """ +@external +def int128(i: int128) -> int128: + temp_var : int128 = i + return temp_var + """, + """ +@external +def decimal(i: int128) -> int128: + temp_var : int128 = i + return temp_var + """, + """ +@external +def false(i: int128) -> int128: + temp_var : int128 = i + return temp_var + """, + """ +@external +def wei(i: int128) -> int128: + temp_var : int128 = i + return temp_var + """, + """ +@external +def floor(): + pass + """, ] From 71188d8482b51475e75390dacb7513c69313ef40 Mon Sep 17 00:00:00 2001 From: tserg <8017125+tserg@users.noreply.github.com> Date: Fri, 7 Apr 2023 13:43:01 +0800 Subject: [PATCH 07/21] fix lint --- vyper/semantics/types/base.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vyper/semantics/types/base.py b/vyper/semantics/types/base.py index 552acd76e9..768e83de54 100644 --- a/vyper/semantics/types/base.py +++ b/vyper/semantics/types/base.py @@ -12,7 +12,7 @@ UnknownAttribute, ) from vyper.semantics.analysis.levenshtein_utils import get_levenshtein_error_suggestions -from vyper.semantics.namespace import validate_identifier_with_namespace, validate_identifier_name +from vyper.semantics.namespace import validate_identifier_name, validate_identifier_with_namespace # Some fake type with an overridden `compare_type` which accepts any RHS From 7fc982d1a06c7e5bf8043e501b8c5810c2ae1eb7 Mon Sep 17 00:00:00 2001 From: tserg <8017125+tserg@users.noreply.github.com> Date: Fri, 7 Apr 2023 16:26:48 +0800 Subject: [PATCH 08/21] separate python keywords --- tests/parser/types/test_identifier_naming.py | 26 ++- vyper/semantics/namespace.py | 171 +++++++++---------- vyper/utils.py | 3 - 3 files changed, 103 insertions(+), 97 deletions(-) diff --git a/tests/parser/types/test_identifier_naming.py b/tests/parser/types/test_identifier_naming.py index 8e4e2a2d66..519799018e 100755 --- a/tests/parser/types/test_identifier_naming.py +++ b/tests/parser/types/test_identifier_naming.py @@ -4,8 +4,8 @@ from vyper.builtins.functions import BUILTIN_FUNCTIONS from vyper.codegen.expr import ENVIRONMENT_VARIABLES from vyper.exceptions import NamespaceCollision, StructureException, SyntaxException -from vyper.semantics.namespace import RESERVED_KEYWORDS -from vyper.utils import FUNCTION_WHITELIST +from vyper.semantics.namespace import PYTHON_KEYWORDS, RESERVED_KEYWORDS +from vyper.semantics.types.primitives import AddressT ALL_RESERVED_KEYWORDS = ( set(BUILTIN_CONSTANTS.keys()) @@ -47,16 +47,26 @@ def test({constant}: int128): ) -RESERVED_KEYWORDS_NOT_WHITELISTED = sorted(ALL_RESERVED_KEYWORDS.difference(FUNCTION_WHITELIST)) +SELF_NAMESPACE_MEMBERS = set(AddressT._type_members.keys()) +DISALLOWED_FN_NAMES = SELF_NAMESPACE_MEMBERS.union(PYTHON_KEYWORDS) +ALLOWED_FN_NAMES = ALL_RESERVED_KEYWORDS - DISALLOWED_FN_NAMES -@pytest.mark.parametrize("constant", sorted(RESERVED_KEYWORDS_NOT_WHITELISTED)) -def test_reserved_keywords_fns(constant, get_contract, assert_compile_failed): +@pytest.mark.parametrize("constant", sorted(ALLOWED_FN_NAMES)) +def test_reserved_keywords_fns_pass(constant, get_contract, assert_compile_failed): code = f""" @external def {constant}(var: int128): pass """ - assert_compile_failed( - lambda: get_contract(code), (SyntaxException, StructureException, NamespaceCollision) - ) + assert get_contract(code) is not None + + +@pytest.mark.parametrize("constant", sorted(DISALLOWED_FN_NAMES)) +def test_reserved_keywords_fns_fail(constant, get_contract, assert_compile_failed): + code = f""" +@external +def {constant}(var: int128): + pass + """ + assert_compile_failed(lambda: get_contract(code), (SyntaxException, NamespaceCollision)) diff --git a/vyper/semantics/namespace.py b/vyper/semantics/namespace.py index 713a28f6a9..66a3bf813c 100644 --- a/vyper/semantics/namespace.py +++ b/vyper/semantics/namespace.py @@ -133,90 +133,89 @@ def validate_identifier_name(attr): raise StructureException(f"'{attr}' contains invalid character(s)") +# Reserved python keywords +PYTHON_KEYWORDS = set({"if", "for", "while", "pass", "def", "assert", "continue", "raise"}) + + # Cannot be used for variable or member naming -RESERVED_KEYWORDS = { - # decorators - "public", - "external", - "nonpayable", - "constant", - "immutable", - "internal", - "payable", - "nonreentrant", - # "class" keywords - "interface", - "struct", - "event", - "enum", - # control flow - "if", - "for", - "while", - "until", - "pass", - "def", - # EVM operations - "send", - "selfdestruct", - "assert", - "raise", - "throw", - "unreachable", - # special functions (no name mangling) - "init", - "_init_", - "___init___", - "____init____", - "default", - "_default_", - "___default___", - "____default____", - # environment variables - "chainid", - "blockhash", - "timestamp", - "timedelta", - # boolean literals - "true", - "false", - # more control flow and special operations - "this", - "continue", - "range", - # None sentinal value - "none", - # more special operations - "indexed", - # denominations - "ether", - "wei", - "finney", - "szabo", - "shannon", - "lovelace", - "ada", - "babbage", - "gwei", - "kwei", - "mwei", - "twei", - "pwei", - # `address` members - "balance", - "codesize", - "codehash", - "code", - "is_contract", - # units - "units", - # sentinal constant values - "zero_address", - "empty_bytes32", - "max_int128", - "min_int128", - "max_decimal", - "min_decimal", - "max_uint256", - "zero_wei", -} +RESERVED_KEYWORDS = set( + { + # decorators + "public", + "external", + "nonpayable", + "constant", + "immutable", + "internal", + "payable", + "nonreentrant", + # "class" keywords + "interface", + "struct", + "event", + "enum", + # EVM operations + "send", + "selfdestruct", + "assert", + "raise", + "throw", + "unreachable", + # special functions (no name mangling) + "init", + "_init_", + "___init___", + "____init____", + "default", + "_default_", + "___default___", + "____default____", + # environment variables + "chainid", + "blockhash", + "timestamp", + "timedelta", + # boolean literals + "true", + "false", + # more control flow and special operations + "this", + "continue", + "range", + # None sentinal value + "none", + # more special operations + "indexed", + # denominations + "ether", + "wei", + "finney", + "szabo", + "shannon", + "lovelace", + "ada", + "babbage", + "gwei", + "kwei", + "mwei", + "twei", + "pwei", + # `address` members + "balance", + "codesize", + "codehash", + "code", + "is_contract", + # units + "units", + # sentinal constant values + "zero_address", + "empty_bytes32", + "max_int128", + "min_int128", + "max_decimal", + "min_decimal", + "max_uint256", + "zero_wei", + } +).union(PYTHON_KEYWORDS) diff --git a/vyper/utils.py b/vyper/utils.py index 2df78f1c2d..37a3f13b3d 100644 --- a/vyper/utils.py +++ b/vyper/utils.py @@ -257,9 +257,6 @@ class SizeLimits: MAX_UINT256 = 2**256 - 1 -# Otherwise reserved words that are whitelisted for function declarations -FUNCTION_WHITELIST = {"send"} - # List of valid IR macros. # TODO move this somewhere else, like ir_node.py VALID_IR_MACROS = { From 6436bf2578d4c067114ae4261ae3c0c3947111a1 Mon Sep 17 00:00:00 2001 From: tserg <8017125+tserg@users.noreply.github.com> Date: Fri, 7 Apr 2023 16:28:32 +0800 Subject: [PATCH 09/21] add deleted test --- tests/parser/syntax/test_send.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/tests/parser/syntax/test_send.py b/tests/parser/syntax/test_send.py index d966df29c6..aef283ec50 100644 --- a/tests/parser/syntax/test_send.py +++ b/tests/parser/syntax/test_send.py @@ -143,6 +143,16 @@ def foo(): send(0xde0B295669a9FD93d5F28D9Ec85E40f4cb697BAe, 5, gas=5000) """, """ + # Test custom send method +@internal +def send(a: address, w: uint256): + send(0xde0B295669a9FD93d5F28D9Ec85E40f4cb697BAe, 1) +@external +@payable +def foo(): + self.send(msg.sender, msg.value) + """, + """ x: uint256 #Test send gas stipend From 6920e743d308f285c68d92f4eff2affdb11698d9 Mon Sep 17 00:00:00 2001 From: tserg <8017125+tserg@users.noreply.github.com> Date: Fri, 7 Apr 2023 16:29:56 +0800 Subject: [PATCH 10/21] fix order --- tests/parser/syntax/test_send.py | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/tests/parser/syntax/test_send.py b/tests/parser/syntax/test_send.py index aef283ec50..a1efc02131 100644 --- a/tests/parser/syntax/test_send.py +++ b/tests/parser/syntax/test_send.py @@ -132,25 +132,25 @@ def foo(): send(0x1234567890123456789012345678901234567890, self.x) """, """ + # Test custom send method +@internal +def send(a: address, w: uint256): + send(0xde0B295669a9FD93d5F28D9Ec85E40f4cb697BAe, 1) @external +@payable def foo(): - send(0xde0B295669a9FD93d5F28D9Ec85E40f4cb697BAe, 5) + self.send(msg.sender, msg.value) """, """ -#Test send gas stipend @external def foo(): - send(0xde0B295669a9FD93d5F28D9Ec85E40f4cb697BAe, 5, gas=5000) + send(0xde0B295669a9FD93d5F28D9Ec85E40f4cb697BAe, 5) """, """ - # Test custom send method -@internal -def send(a: address, w: uint256): - send(0xde0B295669a9FD93d5F28D9Ec85E40f4cb697BAe, 1) +#Test send gas stipend @external -@payable def foo(): - self.send(msg.sender, msg.value) + send(0xde0B295669a9FD93d5F28D9Ec85E40f4cb697BAe, 5, gas=5000) """, """ x: uint256 From 4a07973f6d05e1d2b5d6319a5685183e3de088e1 Mon Sep 17 00:00:00 2001 From: tserg <8017125+tserg@users.noreply.github.com> Date: Fri, 7 Apr 2023 16:30:22 +0800 Subject: [PATCH 11/21] fix formatting --- tests/parser/syntax/test_send.py | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/tests/parser/syntax/test_send.py b/tests/parser/syntax/test_send.py index a1efc02131..15ec19f770 100644 --- a/tests/parser/syntax/test_send.py +++ b/tests/parser/syntax/test_send.py @@ -132,21 +132,22 @@ def foo(): send(0x1234567890123456789012345678901234567890, self.x) """, """ - # Test custom send method +@external +def foo(): + send(0xde0B295669a9FD93d5F28D9Ec85E40f4cb697BAe, 5) + """, + """ +# Test custom send method @internal def send(a: address, w: uint256): send(0xde0B295669a9FD93d5F28D9Ec85E40f4cb697BAe, 1) + @external @payable def foo(): self.send(msg.sender, msg.value) """, """ -@external -def foo(): - send(0xde0B295669a9FD93d5F28D9Ec85E40f4cb697BAe, 5) - """, - """ #Test send gas stipend @external def foo(): From 37771560907bce1881c315aa3e4198af8492fa00 Mon Sep 17 00:00:00 2001 From: tserg <8017125+tserg@users.noreply.github.com> Date: Fri, 7 Apr 2023 21:41:56 +0800 Subject: [PATCH 12/21] handle pop and append --- tests/parser/syntax/test_interfaces.py | 18 +++++++++ .../syntax/utils/test_function_names.py | 9 +++++ vyper/codegen/stmt.py | 39 ++++++++++--------- vyper/semantics/types/__init__.py | 1 + 4 files changed, 48 insertions(+), 19 deletions(-) diff --git a/tests/parser/syntax/test_interfaces.py b/tests/parser/syntax/test_interfaces.py index 962c25ae88..602a081756 100644 --- a/tests/parser/syntax/test_interfaces.py +++ b/tests/parser/syntax/test_interfaces.py @@ -210,6 +210,24 @@ def kick(): payable kickers: HashMap[address, MyInterface] """, + """ +interface Foo: + def append(a: uint256): payable + +@external +def bar(x: address): + a: Foo = Foo(x) + a.append(1) + """, + """ +interface Foo: + def pop(): payable + +@external +def foo(x: address): + a: Foo = Foo(x) + a.pop() + """, ] diff --git a/tests/parser/syntax/utils/test_function_names.py b/tests/parser/syntax/utils/test_function_names.py index e06c5aae50..729e925443 100644 --- a/tests/parser/syntax/utils/test_function_names.py +++ b/tests/parser/syntax/utils/test_function_names.py @@ -68,6 +68,15 @@ def wei(i: int128) -> int128: def floor(): pass """, + """ +@internal +def append(): + pass + +@external +def foo(): + self.append() + """, ] diff --git a/vyper/codegen/stmt.py b/vyper/codegen/stmt.py index 6bd63eddec..de9801a740 100644 --- a/vyper/codegen/stmt.py +++ b/vyper/codegen/stmt.py @@ -24,7 +24,7 @@ from vyper.codegen.expr import Expr from vyper.codegen.return_ import make_return_stmt from vyper.exceptions import CompilerPanic, StructureException, TypeCheckFailure -from vyper.semantics.types import DArrayT +from vyper.semantics.types import DArrayT, MemberFunctionT from vyper.semantics.types.shortcuts import INT256_T, UINT256_T @@ -123,24 +123,25 @@ def parse_Call(self): "append", "pop", ): - # TODO: consider moving this to builtins - darray = Expr(self.stmt.func.value, self.context).ir_node - args = [Expr(x, self.context).ir_node for x in self.stmt.args] - if self.stmt.func.attr == "append": - # sanity checks - assert len(args) == 1 - arg = args[0] - assert isinstance(darray.typ, DArrayT) - check_assign( - dummy_node_for_type(darray.typ.value_type), dummy_node_for_type(arg.typ) - ) - - return append_dyn_array(darray, arg) - else: - assert len(args) == 0 - return pop_dyn_array(darray, return_popped_item=False) - - elif is_self_function: + func_type = self.stmt.func._metadata["type"] + if isinstance(func_type, MemberFunctionT): + darray = Expr(self.stmt.func.value, self.context).ir_node + args = [Expr(x, self.context).ir_node for x in self.stmt.args] + if self.stmt.func.attr == "append": + # sanity checks + assert len(args) == 1 + arg = args[0] + assert isinstance(darray.typ, DArrayT) + check_assign( + dummy_node_for_type(darray.typ.value_type), dummy_node_for_type(arg.typ) + ) + + return append_dyn_array(darray, arg) + else: + assert len(args) == 0 + return pop_dyn_array(darray, return_popped_item=False) + + if is_self_function: return self_call.ir_for_self_call(self.stmt, self.context) else: return external_call.ir_for_external_call(self.stmt, self.context) diff --git a/vyper/semantics/types/__init__.py b/vyper/semantics/types/__init__.py index 222c34ee99..246dcfdf34 100644 --- a/vyper/semantics/types/__init__.py +++ b/vyper/semantics/types/__init__.py @@ -1,6 +1,7 @@ from . import primitives, subscriptable, user from .base import TYPE_T, KwargSettings, VyperType, is_type_t from .bytestrings import BytesT, StringT, _BytestringT +from .function import MemberFunctionT from .primitives import AddressT, BoolT, BytesM_T, DecimalT, IntegerT from .subscriptable import DArrayT, HashMapT, SArrayT, TupleT from .user import EnumT, EventT, InterfaceT, StructT From a959818bb6d46f4f67155ca5cc6afcf3f478ce5c Mon Sep 17 00:00:00 2001 From: tserg <8017125+tserg@users.noreply.github.com> Date: Fri, 7 Apr 2023 22:49:25 +0800 Subject: [PATCH 13/21] fix merge conflict --- tests/parser/syntax/test_interfaces.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/parser/syntax/test_interfaces.py b/tests/parser/syntax/test_interfaces.py index ff5174d177..c0afec5504 100644 --- a/tests/parser/syntax/test_interfaces.py +++ b/tests/parser/syntax/test_interfaces.py @@ -227,6 +227,8 @@ def pop(): payable def foo(x: address): a: Foo = Foo(x) a.pop() + """, + """ interface ITestInterface: def foo() -> uint256: view From 43b4f7940733d5699308704845572abd9b886852 Mon Sep 17 00:00:00 2001 From: tserg <8017125+tserg@users.noreply.github.com> Date: Sat, 8 Apr 2023 09:22:38 +0800 Subject: [PATCH 14/21] apply bts suggestions --- vyper/semantics/namespace.py | 164 +++++++++++++++++----------------- vyper/semantics/types/base.py | 4 +- 2 files changed, 83 insertions(+), 85 deletions(-) diff --git a/vyper/semantics/namespace.py b/vyper/semantics/namespace.py index 66a3bf813c..0b752783d9 100644 --- a/vyper/semantics/namespace.py +++ b/vyper/semantics/namespace.py @@ -89,7 +89,7 @@ def clear(self): def validate_assignment(self, attr): validate_identifier_name(attr) - validate_identifier_with_namespace(attr) + validate_namespace_availability(attr) if attr in self: obj = super().__getitem__(attr) raise NamespaceCollision(f"'{attr}' has already been declared as a {obj}") @@ -120,7 +120,7 @@ def override_global_namespace(ns): _namespace = tmp -def validate_identifier_with_namespace(attr): +def validate_namespace_availability(attr): namespace = get_namespace() if attr in namespace and attr not in [x for i in namespace._scopes for x in i]: raise NamespaceCollision(f"Cannot assign to '{attr}', it is a builtin") @@ -138,84 +138,82 @@ def validate_identifier_name(attr): # Cannot be used for variable or member naming -RESERVED_KEYWORDS = set( - { - # decorators - "public", - "external", - "nonpayable", - "constant", - "immutable", - "internal", - "payable", - "nonreentrant", - # "class" keywords - "interface", - "struct", - "event", - "enum", - # EVM operations - "send", - "selfdestruct", - "assert", - "raise", - "throw", - "unreachable", - # special functions (no name mangling) - "init", - "_init_", - "___init___", - "____init____", - "default", - "_default_", - "___default___", - "____default____", - # environment variables - "chainid", - "blockhash", - "timestamp", - "timedelta", - # boolean literals - "true", - "false", - # more control flow and special operations - "this", - "continue", - "range", - # None sentinal value - "none", - # more special operations - "indexed", - # denominations - "ether", - "wei", - "finney", - "szabo", - "shannon", - "lovelace", - "ada", - "babbage", - "gwei", - "kwei", - "mwei", - "twei", - "pwei", - # `address` members - "balance", - "codesize", - "codehash", - "code", - "is_contract", - # units - "units", - # sentinal constant values - "zero_address", - "empty_bytes32", - "max_int128", - "min_int128", - "max_decimal", - "min_decimal", - "max_uint256", - "zero_wei", - } -).union(PYTHON_KEYWORDS) +RESERVED_KEYWORDS = { + # decorators + "public", + "external", + "nonpayable", + "constant", + "immutable", + "internal", + "payable", + "nonreentrant", + # "class" keywords + "interface", + "struct", + "event", + "enum", + # EVM operations + "send", + "selfdestruct", + "assert", + "raise", + "throw", + "unreachable", + # special functions (no name mangling) + "init", + "_init_", + "___init___", + "____init____", + "default", + "_default_", + "___default___", + "____default____", + # environment variables + "chainid", + "blockhash", + "timestamp", + "timedelta", + # boolean literals + "true", + "false", + # more control flow and special operations + "this", + "continue", + "range", + # None sentinal value + "none", + # more special operations + "indexed", + # denominations + "ether", + "wei", + "finney", + "szabo", + "shannon", + "lovelace", + "ada", + "babbage", + "gwei", + "kwei", + "mwei", + "twei", + "pwei", + # `address` members + "balance", + "codesize", + "codehash", + "code", + "is_contract", + # units + "units", + # sentinal constant values + "zero_address", + "empty_bytes32", + "max_int128", + "min_int128", + "max_decimal", + "min_decimal", + "max_uint256", + "zero_wei", +}.union(PYTHON_KEYWORDS) diff --git a/vyper/semantics/types/base.py b/vyper/semantics/types/base.py index 768e83de54..67f92b1a18 100644 --- a/vyper/semantics/types/base.py +++ b/vyper/semantics/types/base.py @@ -12,7 +12,7 @@ UnknownAttribute, ) from vyper.semantics.analysis.levenshtein_utils import get_levenshtein_error_suggestions -from vyper.semantics.namespace import validate_identifier_name, validate_identifier_with_namespace +from vyper.semantics.namespace import validate_identifier_name, validate_namespace_availability # Some fake type with an overridden `compare_type` which accepts any RHS @@ -285,7 +285,7 @@ def add_member( # skip_namespace_validation provides a way of bypassing validate_identifier, which # introduces a dependency cycle with the builtin_functions module if not skip_namespace_validation: - validate_identifier_with_namespace(name) + validate_namespace_availability(name) validate_identifier_name(name) if name in self.members: raise NamespaceCollision(f"Member '{name}' already exists in {self}") From 481304ee10e9db29bd10f7317f93d1ace06a5d0d Mon Sep 17 00:00:00 2001 From: tserg <8017125+tserg@users.noreply.github.com> Date: Sat, 8 Apr 2023 11:50:32 +0800 Subject: [PATCH 15/21] apply bts suggestions --- vyper/semantics/namespace.py | 18 +++++++++--------- vyper/semantics/types/base.py | 4 ++-- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/vyper/semantics/namespace.py b/vyper/semantics/namespace.py index 0b752783d9..f9a1febde0 100644 --- a/vyper/semantics/namespace.py +++ b/vyper/semantics/namespace.py @@ -88,7 +88,7 @@ def clear(self): self.__init__() def validate_assignment(self, attr): - validate_identifier_name(attr) + validate_identifier(attr) validate_namespace_availability(attr) if attr in self: obj = super().__getitem__(attr) @@ -120,21 +120,21 @@ def override_global_namespace(ns): _namespace = tmp -def validate_namespace_availability(attr): +def validate_namespace_availability(ident): namespace = get_namespace() - if attr in namespace and attr not in [x for i in namespace._scopes for x in i]: - raise NamespaceCollision(f"Cannot assign to '{attr}', it is a builtin") - if attr.lower() in RESERVED_KEYWORDS or attr.upper() in OPCODES: - raise StructureException(f"'{attr}' is a reserved keyword") + if ident in namespace and ident not in [x for i in namespace._scopes for x in i]: + raise NamespaceCollision(f"Cannot assign to '{ident}', it is a builtin") + if ident.lower() in RESERVED_KEYWORDS or ident.upper() in OPCODES: + raise StructureException(f"'{ident}' is a reserved keyword") -def validate_identifier_name(attr): +def validate_identifier(attr): if not re.match("^[_a-zA-Z][a-zA-Z0-9_]*$", attr): raise StructureException(f"'{attr}' contains invalid character(s)") # Reserved python keywords -PYTHON_KEYWORDS = set({"if", "for", "while", "pass", "def", "assert", "continue", "raise"}) +PYTHON_KEYWORDS = {"if", "for", "while", "pass", "def", "assert", "continue", "raise"} # Cannot be used for variable or member naming @@ -216,4 +216,4 @@ def validate_identifier_name(attr): "min_decimal", "max_uint256", "zero_wei", -}.union(PYTHON_KEYWORDS) +} | PYTHON_KEYWORDS diff --git a/vyper/semantics/types/base.py b/vyper/semantics/types/base.py index 67f92b1a18..43d84ae71a 100644 --- a/vyper/semantics/types/base.py +++ b/vyper/semantics/types/base.py @@ -12,7 +12,7 @@ UnknownAttribute, ) from vyper.semantics.analysis.levenshtein_utils import get_levenshtein_error_suggestions -from vyper.semantics.namespace import validate_identifier_name, validate_namespace_availability +from vyper.semantics.namespace import validate_identifier, validate_namespace_availability # Some fake type with an overridden `compare_type` which accepts any RHS @@ -286,7 +286,7 @@ def add_member( # introduces a dependency cycle with the builtin_functions module if not skip_namespace_validation: validate_namespace_availability(name) - validate_identifier_name(name) + validate_identifier(name) if name in self.members: raise NamespaceCollision(f"Member '{name}' already exists in {self}") self.members[name] = type_ From 1095a7df71f87c58cc5180d473e1cbf1bc08ed7f Mon Sep 17 00:00:00 2001 From: tserg <8017125+tserg@users.noreply.github.com> Date: Sat, 8 Apr 2023 11:52:59 +0800 Subject: [PATCH 16/21] remove duplicate keywords --- vyper/semantics/namespace.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/vyper/semantics/namespace.py b/vyper/semantics/namespace.py index f9a1febde0..e34edba1d1 100644 --- a/vyper/semantics/namespace.py +++ b/vyper/semantics/namespace.py @@ -156,8 +156,6 @@ def validate_identifier(attr): # EVM operations "send", "selfdestruct", - "assert", - "raise", "throw", "unreachable", # special functions (no name mangling) @@ -179,7 +177,6 @@ def validate_identifier(attr): "false", # more control flow and special operations "this", - "continue", "range", # None sentinal value "none", From 7975b3ca43564fa54df110ce3008070406ca9255 Mon Sep 17 00:00:00 2001 From: Charles Cooper Date: Fri, 7 Apr 2023 21:16:47 -0700 Subject: [PATCH 17/21] simplify identifier validation --- vyper/semantics/analysis/module.py | 2 +- vyper/semantics/namespace.py | 37 +++----------------------- vyper/semantics/types/base.py | 18 ++++--------- vyper/semantics/types/subscriptable.py | 12 ++------- vyper/semantics/types/user.py | 2 +- 5 files changed, 12 insertions(+), 59 deletions(-) diff --git a/vyper/semantics/analysis/module.py b/vyper/semantics/analysis/module.py index 60b3564b69..db9b9d7c91 100644 --- a/vyper/semantics/analysis/module.py +++ b/vyper/semantics/analysis/module.py @@ -283,7 +283,7 @@ def visit_FunctionDef(self, node): func = ContractFunctionT.from_FunctionDef(node) try: - self.namespace["self"].typ.add_member(func.name, func, skip_namespace_validation=True) + self.namespace["self"].typ.add_member(func.name, func) node._metadata["type"] = func except VyperException as exc: raise exc.with_annotation(node) from None diff --git a/vyper/semantics/namespace.py b/vyper/semantics/namespace.py index e34edba1d1..2204dce3d3 100644 --- a/vyper/semantics/namespace.py +++ b/vyper/semantics/namespace.py @@ -89,7 +89,7 @@ def clear(self): def validate_assignment(self, attr): validate_identifier(attr) - validate_namespace_availability(attr) + if attr in self: obj = super().__getitem__(attr) raise NamespaceCollision(f"'{attr}' has already been declared as a {obj}") @@ -120,17 +120,11 @@ def override_global_namespace(ns): _namespace = tmp -def validate_namespace_availability(ident): - namespace = get_namespace() - if ident in namespace and ident not in [x for i in namespace._scopes for x in i]: - raise NamespaceCollision(f"Cannot assign to '{ident}', it is a builtin") - if ident.lower() in RESERVED_KEYWORDS or ident.upper() in OPCODES: - raise StructureException(f"'{ident}' is a reserved keyword") - - def validate_identifier(attr): if not re.match("^[_a-zA-Z][a-zA-Z0-9_]*$", attr): raise StructureException(f"'{attr}' contains invalid character(s)") + if attr.lower() in RESERVED_KEYWORDS: + raise StructureException(f"'{attr}' is a reserved keyword") # Reserved python keywords @@ -154,9 +148,6 @@ def validate_identifier(attr): "event", "enum", # EVM operations - "send", - "selfdestruct", - "throw", "unreachable", # special functions (no name mangling) "init", @@ -167,11 +158,6 @@ def validate_identifier(attr): "_default_", "___default___", "____default____", - # environment variables - "chainid", - "blockhash", - "timestamp", - "timedelta", # boolean literals "true", "false", @@ -196,21 +182,4 @@ def validate_identifier(attr): "mwei", "twei", "pwei", - # `address` members - "balance", - "codesize", - "codehash", - "code", - "is_contract", - # units - "units", - # sentinal constant values - "zero_address", - "empty_bytes32", - "max_int128", - "min_int128", - "max_decimal", - "min_decimal", - "max_uint256", - "zero_wei", } | PYTHON_KEYWORDS diff --git a/vyper/semantics/types/base.py b/vyper/semantics/types/base.py index 43d84ae71a..0ac4f7b06d 100644 --- a/vyper/semantics/types/base.py +++ b/vyper/semantics/types/base.py @@ -12,7 +12,7 @@ UnknownAttribute, ) from vyper.semantics.analysis.levenshtein_utils import get_levenshtein_error_suggestions -from vyper.semantics.namespace import validate_identifier, validate_namespace_availability +from vyper.semantics.namespace import validate_identifier # Some fake type with an overridden `compare_type` which accepts any RHS @@ -57,9 +57,7 @@ class VyperType: size_in_bytes = 32 # default; override for larger types - def __init__( - self, members: Optional[Dict] = None, skip_namespace_validation: bool = False - ) -> None: + def __init__(self, members: Optional[Dict] = None) -> None: self.members: Dict = {} # add members that are on the class instance. @@ -67,11 +65,11 @@ def __init__( for k, v in self._type_members.items(): # for builtin members like `contract.address` -- skip namespace # validation, as it introduces a dependency cycle - self.add_member(k, v, skip_namespace_validation=True) + self.add_member(k, v) members = members or {} for k, v in members.items(): - self.add_member(k, v, skip_namespace_validation=skip_namespace_validation) + self.add_member(k, v) def _get_equality_attrs(self): return tuple(getattr(self, attr) for attr in self._equality_attrs) @@ -279,13 +277,7 @@ def get_subscripted_type(self, node: vy_ast.Index) -> None: """ raise StructureException(f"'{self}' cannot be indexed into", node) - def add_member( - self, name: str, type_: "VyperType", skip_namespace_validation: bool = False - ) -> None: - # skip_namespace_validation provides a way of bypassing validate_identifier, which - # introduces a dependency cycle with the builtin_functions module - if not skip_namespace_validation: - validate_namespace_availability(name) + def add_member(self, name: str, type_: "VyperType") -> None: validate_identifier(name) if name in self.members: raise NamespaceCollision(f"Member '{name}' already exists in {self}") diff --git a/vyper/semantics/types/subscriptable.py b/vyper/semantics/types/subscriptable.py index fb4505fb20..a5ae075b73 100644 --- a/vyper/semantics/types/subscriptable.py +++ b/vyper/semantics/types/subscriptable.py @@ -216,16 +216,8 @@ def __init__(self, value_type: VyperType, length: int) -> None: from vyper.semantics.types.function import MemberFunctionT - self.add_member( - "append", - MemberFunctionT(self, "append", [self.value_type], None, True), - skip_namespace_validation=True, - ) - self.add_member( - "pop", - MemberFunctionT(self, "pop", [], self.value_type, True), - skip_namespace_validation=True, - ) + self.add_member("append", MemberFunctionT(self, "append", [self.value_type], None, True)) + self.add_member("pop", MemberFunctionT(self, "pop", [], self.value_type, True)) def __repr__(self): return f"DynArray[{self.value_type}, {self.length}]" diff --git a/vyper/semantics/types/user.py b/vyper/semantics/types/user.py index f25cc79894..536d482e75 100644 --- a/vyper/semantics/types/user.py +++ b/vyper/semantics/types/user.py @@ -268,7 +268,7 @@ class InterfaceT(_UserType): def __init__(self, _id: str, members: dict, events: dict) -> None: validate_unique_method_ids(list(members.values())) # explicit list cast for mypy - super().__init__(members, skip_namespace_validation=True) + super().__init__(members) self._id = _id self.events = events From dcae97e9a9ad48524df0c7da268c8d12e8ac7bf3 Mon Sep 17 00:00:00 2001 From: Charles Cooper Date: Fri, 7 Apr 2023 21:34:57 -0700 Subject: [PATCH 18/21] wip - identifiers --- tests/parser/types/test_identifier_naming.py | 11 +++++------ vyper/semantics/namespace.py | 17 +++++++++++------ 2 files changed, 16 insertions(+), 12 deletions(-) diff --git a/tests/parser/types/test_identifier_naming.py b/tests/parser/types/test_identifier_naming.py index 519799018e..33e79a13ec 100755 --- a/tests/parser/types/test_identifier_naming.py +++ b/tests/parser/types/test_identifier_naming.py @@ -4,14 +4,11 @@ from vyper.builtins.functions import BUILTIN_FUNCTIONS from vyper.codegen.expr import ENVIRONMENT_VARIABLES from vyper.exceptions import NamespaceCollision, StructureException, SyntaxException -from vyper.semantics.namespace import PYTHON_KEYWORDS, RESERVED_KEYWORDS +from vyper.semantics.namespace import RESERVED_KEYWORDS from vyper.semantics.types.primitives import AddressT ALL_RESERVED_KEYWORDS = ( - set(BUILTIN_CONSTANTS.keys()) - .union(BUILTIN_FUNCTIONS) - .union(RESERVED_KEYWORDS) - .union(ENVIRONMENT_VARIABLES) + set(BUILTIN_CONSTANTS.keys()) | BUILTIN_FUNCTIONS | RESERVED_KEYWORDS | ENVIRONMENT_VARIABLES ) @@ -47,8 +44,10 @@ def test({constant}: int128): ) +PYTHON_KEYWORDS = {"if", "for", "while", "pass", "def", "assert", "continue", "raise"} + SELF_NAMESPACE_MEMBERS = set(AddressT._type_members.keys()) -DISALLOWED_FN_NAMES = SELF_NAMESPACE_MEMBERS.union(PYTHON_KEYWORDS) +DISALLOWED_FN_NAMES = SELF_NAMESPACE_MEMBERS | PYTHON_KEYWORDS | RESERVED_KEYWORDS ALLOWED_FN_NAMES = ALL_RESERVED_KEYWORDS - DISALLOWED_FN_NAMES diff --git a/vyper/semantics/namespace.py b/vyper/semantics/namespace.py index 2204dce3d3..9fd4e1f307 100644 --- a/vyper/semantics/namespace.py +++ b/vyper/semantics/namespace.py @@ -1,7 +1,6 @@ import contextlib import re -from vyper.evm.opcodes import OPCODES from vyper.exceptions import ( CompilerPanic, NamespaceCollision, @@ -127,10 +126,6 @@ def validate_identifier(attr): raise StructureException(f"'{attr}' is a reserved keyword") -# Reserved python keywords -PYTHON_KEYWORDS = {"if", "for", "while", "pass", "def", "assert", "continue", "raise"} - - # Cannot be used for variable or member naming RESERVED_KEYWORDS = { # decorators @@ -182,4 +177,14 @@ def validate_identifier(attr): "mwei", "twei", "pwei", -} | PYTHON_KEYWORDS + # sentinal constant values + # TODO remove when these are removed from the language + "zero_address", + "empty_bytes32", + "max_int128", + "min_int128", + "max_decimal", + "min_decimal", + "max_uint256", + "zero_wei", +} From f62c7d714d99ed192ba55d66b2980a07ebc2a545 Mon Sep 17 00:00:00 2001 From: tserg <8017125+tserg@users.noreply.github.com> Date: Sat, 8 Apr 2023 14:03:26 +0800 Subject: [PATCH 19/21] fix test --- tests/parser/types/test_identifier_naming.py | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/tests/parser/types/test_identifier_naming.py b/tests/parser/types/test_identifier_naming.py index 33e79a13ec..d0daa6dc05 100755 --- a/tests/parser/types/test_identifier_naming.py +++ b/tests/parser/types/test_identifier_naming.py @@ -7,8 +7,9 @@ from vyper.semantics.namespace import RESERVED_KEYWORDS from vyper.semantics.types.primitives import AddressT +BUILTIN_CONSTANTS = set(BUILTIN_CONSTANTS.keys()) ALL_RESERVED_KEYWORDS = ( - set(BUILTIN_CONSTANTS.keys()) | BUILTIN_FUNCTIONS | RESERVED_KEYWORDS | ENVIRONMENT_VARIABLES + BUILTIN_CONSTANTS | BUILTIN_FUNCTIONS | RESERVED_KEYWORDS | ENVIRONMENT_VARIABLES ) @@ -47,7 +48,9 @@ def test({constant}: int128): PYTHON_KEYWORDS = {"if", "for", "while", "pass", "def", "assert", "continue", "raise"} SELF_NAMESPACE_MEMBERS = set(AddressT._type_members.keys()) -DISALLOWED_FN_NAMES = SELF_NAMESPACE_MEMBERS | PYTHON_KEYWORDS | RESERVED_KEYWORDS +DISALLOWED_FN_NAMES = ( + SELF_NAMESPACE_MEMBERS | PYTHON_KEYWORDS | RESERVED_KEYWORDS | BUILTIN_CONSTANTS +) ALLOWED_FN_NAMES = ALL_RESERVED_KEYWORDS - DISALLOWED_FN_NAMES @@ -68,4 +71,6 @@ def test_reserved_keywords_fns_fail(constant, get_contract, assert_compile_faile def {constant}(var: int128): pass """ - assert_compile_failed(lambda: get_contract(code), (SyntaxException, NamespaceCollision)) + assert_compile_failed( + lambda: get_contract(code), (SyntaxException, StructureException, NamespaceCollision) + ) From df786eb7bc2fc030544dc2936c8e87596a6d6438 Mon Sep 17 00:00:00 2001 From: tserg <8017125+tserg@users.noreply.github.com> Date: Sat, 8 Apr 2023 14:36:15 +0800 Subject: [PATCH 20/21] fix tests --- .../syntax/utils/test_function_names.py | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/tests/parser/syntax/utils/test_function_names.py b/tests/parser/syntax/utils/test_function_names.py index 729e925443..90e185558c 100644 --- a/tests/parser/syntax/utils/test_function_names.py +++ b/tests/parser/syntax/utils/test_function_names.py @@ -10,7 +10,19 @@ def ő1qwerty(i: int128) -> int128: temp_var : int128 = i return temp_var + """, + """ +@external +def false(i: int128) -> int128: + temp_var : int128 = i + return temp_var + """, """ +@external +def wei(i: int128) -> int128: + temp_var : int128 = i + return temp_var1 + """, ] @@ -53,18 +65,6 @@ def decimal(i: int128) -> int128: """, """ @external -def false(i: int128) -> int128: - temp_var : int128 = i - return temp_var - """, - """ -@external -def wei(i: int128) -> int128: - temp_var : int128 = i - return temp_var - """, - """ -@external def floor(): pass """, From 7ae2aaf674896a5af63f8b13aab23757a112bc50 Mon Sep 17 00:00:00 2001 From: tserg <8017125+tserg@users.noreply.github.com> Date: Sat, 8 Apr 2023 14:48:41 +0800 Subject: [PATCH 21/21] fix more tests --- .../exceptions/test_structure_exception.py | 8 -------- tests/parser/syntax/test_address_code.py | 15 +++------------ tests/parser/syntax/test_structs.py | 17 ----------------- 3 files changed, 3 insertions(+), 37 deletions(-) diff --git a/tests/parser/exceptions/test_structure_exception.py b/tests/parser/exceptions/test_structure_exception.py index f99eac45e1..08794b75f2 100644 --- a/tests/parser/exceptions/test_structure_exception.py +++ b/tests/parser/exceptions/test_structure_exception.py @@ -62,14 +62,6 @@ def double_nonreentrant(): pass """, """ -CALLDATACOPY: int128 - """, - """ -@external -def foo(): - BALANCE: int128 = 45 - """, - """ @external def foo(): true: int128 = 3 diff --git a/tests/parser/syntax/test_address_code.py b/tests/parser/syntax/test_address_code.py index c8a153a855..25fe1be0b4 100644 --- a/tests/parser/syntax/test_address_code.py +++ b/tests/parser/syntax/test_address_code.py @@ -5,7 +5,7 @@ from web3 import Web3 from vyper import compiler -from vyper.exceptions import StructureException, VyperException +from vyper.exceptions import NamespaceCollision, StructureException, VyperException # For reproducibility, use precompiled data of `hello: public(uint256)` using vyper 0.3.1 PRECOMPILED_ABI = """[{"stateMutability": "view", "type": "function", "name": "hello", "inputs": [], "outputs": [{"name": "", "type": "uint256"}], "gas": 2460}]""" # noqa: E501 @@ -114,17 +114,8 @@ def code_slice(x: address, y: uint256) -> Bytes[4]: """ code: public(Bytes[4]) """, - StructureException, - "'code' is a reserved keyword", - ), - ( - # User defined struct with `code` attribute - """ -struct S: - code: Bytes[4] -""", - StructureException, - "'code' is a reserved keyword", + NamespaceCollision, + "Value 'code' has already been declared", ), ], ) diff --git a/tests/parser/syntax/test_structs.py b/tests/parser/syntax/test_structs.py index b89446e450..757c46c4b3 100644 --- a/tests/parser/syntax/test_structs.py +++ b/tests/parser/syntax/test_structs.py @@ -3,7 +3,6 @@ from vyper import compiler from vyper.exceptions import ( InvalidType, - NamespaceCollision, StructureException, TypeMismatch, UnknownAttribute, @@ -421,22 +420,6 @@ def foo(): ), ( """ -struct X: - bar: int128 - decimal: int128 - """, - NamespaceCollision, - ), - ( - """ -struct B: - num: int128 - address: address - """, - NamespaceCollision, - ), - ( - """ struct Foo: a: uint256