diff --git a/vyper/builtins/_signatures.py b/vyper/builtins/_signatures.py index f4f808f84e..270176ce08 100644 --- a/vyper/builtins/_signatures.py +++ b/vyper/builtins/_signatures.py @@ -4,7 +4,7 @@ from vyper.ast.validation import validate_call_args from vyper.codegen.expr import Expr from vyper.codegen.ir_node import IRnode -from vyper.exceptions import CompilerPanic, TypeMismatch +from vyper.exceptions import CompilerPanic, TypeMismatch, UnfoldableNode, VyperException from vyper.semantics.analysis.utils import ( check_kwargable, get_exact_type_from_node, @@ -121,6 +121,15 @@ def _validate_arg_types(self, node): # ensures the type can be inferred exactly. get_exact_type_from_node(arg) + def prefold(self, node): + if not hasattr(self, "evaluate"): + return None + + try: + return self.evaluate(node) + except (UnfoldableNode, VyperException): + return None + def fetch_call_return(self, node): self._validate_arg_types(node) diff --git a/vyper/builtins/functions.py b/vyper/builtins/functions.py index cf2c47711f..223830fd59 100644 --- a/vyper/builtins/functions.py +++ b/vyper/builtins/functions.py @@ -141,12 +141,6 @@ class Floor(BuiltinFunction): # TODO: maybe use int136? _return_type = INT256_T - def prefold(self, node): - try: - return self.evaluate(node) - except (UnfoldableNode, VyperException): - return None - def evaluate(self, node): validate_call_args(node, 1) value = node.args[0]._metadata.get("folded_value") @@ -178,12 +172,6 @@ class Ceil(BuiltinFunction): # TODO: maybe use int136? _return_type = INT256_T - def prefold(self, node): - try: - return self.evaluate(node) - except (UnfoldableNode, VyperException): - return None - def evaluate(self, node): validate_call_args(node, 1) value = node.args[0]._metadata.get("folded_value") @@ -479,12 +467,6 @@ class Len(BuiltinFunction): _inputs = [("b", (StringT.any(), BytesT.any(), DArrayT.any()))] _return_type = UINT256_T - def prefold(self, node): - try: - return self.evaluate(node) - except (UnfoldableNode, VyperException): - return None - def evaluate(self, node): validate_call_args(node, 1) arg = node.args[0] @@ -622,12 +604,6 @@ class Keccak256(BuiltinFunction): _inputs = [("value", (BytesT.any(), BYTES32_T, StringT.any()))] _return_type = BYTES32_T - def prefold(self, node): - try: - return self.evaluate(node) - except (UnfoldableNode, VyperException): - return None - def evaluate(self, node): validate_call_args(node, 1) value = node.args[0]._metadata.get("folded_value") @@ -677,12 +653,6 @@ class Sha256(BuiltinFunction): _inputs = [("value", (BYTES32_T, BytesT.any(), StringT.any()))] _return_type = BYTES32_T - def prefold(self, node): - try: - return self.evaluate(node) - except (UnfoldableNode, VyperException): - return None - def evaluate(self, node): validate_call_args(node, 1) if isinstance(node.args[0], vy_ast.Bytes): @@ -753,12 +723,6 @@ def build_IR(self, expr, args, kwargs, context): class MethodID(FoldedFunction): _id = "method_id" - def prefold(self, node): - try: - return self.evaluate(node) - except (UnfoldableNode, VyperException): - return None - def evaluate(self, node): validate_call_args(node, 1, ["output_type"]) @@ -1033,12 +997,6 @@ def get_denomination(self, node): return denom - def prefold(self, node): - try: - return self.evaluate(node) - except (UnfoldableNode, VyperException): - return None - def evaluate(self, node): validate_call_args(node, 2) denom = self.get_denomination(node) @@ -1398,12 +1356,6 @@ class BitwiseAnd(BuiltinFunction): _return_type = UINT256_T _warned = False - def prefold(self, node): - try: - return self.evaluate(node) - except (UnfoldableNode, VyperException): - return None - def evaluate(self, node): if not self.__class__._warned: vyper_warn("`bitwise_and()` is deprecated! Please use the & operator instead.") @@ -1430,12 +1382,6 @@ class BitwiseOr(BuiltinFunction): _return_type = UINT256_T _warned = False - def prefold(self, node): - try: - return self.evaluate(node) - except (UnfoldableNode, VyperException): - return None - def evaluate(self, node): if not self.__class__._warned: vyper_warn("`bitwise_or()` is deprecated! Please use the | operator instead.") @@ -1462,12 +1408,6 @@ class BitwiseXor(BuiltinFunction): _return_type = UINT256_T _warned = False - def prefold(self, node): - try: - return self.evaluate(node) - except (UnfoldableNode, VyperException): - return None - def evaluate(self, node): if not self.__class__._warned: vyper_warn("`bitwise_xor()` is deprecated! Please use the ^ operator instead.") @@ -1494,12 +1434,6 @@ class BitwiseNot(BuiltinFunction): _return_type = UINT256_T _warned = False - def prefold(self, node): - try: - return self.evaluate(node) - except (UnfoldableNode, VyperException): - return None - def evaluate(self, node): if not self.__class__._warned: vyper_warn("`bitwise_not()` is deprecated! Please use the ~ operator instead.") @@ -1527,12 +1461,6 @@ class Shift(BuiltinFunction): _return_type = UINT256_T _warned = False - def prefold(self, node): - try: - return self.evaluate(node) - except (UnfoldableNode, VyperException): - return None - def evaluate(self, node): if not self.__class__._warned: vyper_warn("`shift()` is deprecated! Please use the << or >> operator instead.") @@ -1586,12 +1514,6 @@ class _AddMulMod(BuiltinFunction): _inputs = [("a", UINT256_T), ("b", UINT256_T), ("c", UINT256_T)] _return_type = UINT256_T - def prefold(self, node): - try: - return self.evaluate(node) - except (UnfoldableNode, VyperException): - return None - def evaluate(self, node): validate_call_args(node, 3) args = [i._metadata.get("folded_value") for i in node.args] @@ -2102,12 +2024,6 @@ class UnsafeDiv(_UnsafeMath): class _MinMax(BuiltinFunction): _inputs = [("a", (DecimalT(), IntegerT.any())), ("b", (DecimalT(), IntegerT.any()))] - def prefold(self, node): - try: - return self.evaluate(node) - except (UnfoldableNode, VyperException): - return None - def evaluate(self, node): validate_call_args(node, 2) @@ -2199,12 +2115,6 @@ def fetch_call_return(self, node): len_needed = math.ceil(bits * math.log(2) / math.log(10)) return StringT(len_needed) - def prefold(self, node): - try: - return self.evaluate(node) - except (UnfoldableNode, VyperException): - return None - def evaluate(self, node): validate_call_args(node, 1) if not isinstance(node.args[0], vy_ast.Int): @@ -2692,12 +2602,6 @@ def build_IR(self, expr, args, kwargs, context): class _MinMaxValue(TypenameFoldedFunction): - def prefold(self, node): - try: - return self.evaluate(node) - except (UnfoldableNode, VyperException): - return None - def evaluate(self, node): self._validate_arg_types(node) input_type = type_from_annotation(node.args[0]) @@ -2734,12 +2638,6 @@ def _eval(self, type_): class Epsilon(TypenameFoldedFunction): _id = "epsilon" - def prefold(self, node): - try: - return self.evaluate(node) - except (UnfoldableNode, VyperException): - return None - def evaluate(self, node): self._validate_arg_types(node) input_type = type_from_annotation(node.args[0]) diff --git a/vyper/semantics/analysis/pre_typecheck.py b/vyper/semantics/analysis/pre_typecheck.py index f6bb6389a0..3c3cc96501 100644 --- a/vyper/semantics/analysis/pre_typecheck.py +++ b/vyper/semantics/analysis/pre_typecheck.py @@ -76,5 +76,5 @@ def prefold(node: vy_ast.VyperNode, constants: dict) -> None: func_name = node.func.id call_type = DISPATCH_TABLE.get(func_name) - if call_type and hasattr(call_type, "prefold"): + if call_type: node._metadata["folded_value"] = call_type.prefold(node) # type: ignore