From 6074ab1c3821e7d040512582756be789844b06c4 Mon Sep 17 00:00:00 2001 From: Alexis Date: Fri, 19 Apr 2024 10:54:37 +0200 Subject: [PATCH] Remove calls to isinstance to improve performances. --- slither/visitors/expression/expression.py | 79 +++++++++-------------- 1 file changed, 29 insertions(+), 50 deletions(-) diff --git a/slither/visitors/expression/expression.py b/slither/visitors/expression/expression.py index 41886a1023..860ca28503 100644 --- a/slither/visitors/expression/expression.py +++ b/slither/visitors/expression/expression.py @@ -1,4 +1,5 @@ import logging +from functools import cache from slither.core.expressions.assignment_operation import AssignmentOperation from slither.core.expressions.binary_operation import BinaryOperation @@ -21,6 +22,28 @@ logger = logging.getLogger("ExpressionVisitor") +@cache +def get_visitor_mapping(): + """Returns a visitor mapping from expression type to visiting functions.""" + return { + AssignmentOperation: '_visit_assignement_operation', + BinaryOperation: '_visit_binary_operation', + CallExpression: '_visit_call_expression', + ConditionalExpression: '_visit_conditional_expression', + ElementaryTypeNameExpression: '_visit_elementary_type_name_expression', + Identifier: '_visit_identifier', + IndexAccess: '_visit_index_access', + Literal: '_visit_literal', + MemberAccess: '_visit_member_access', + NewArray: '_visit_new_array', + NewContract: '_visit_new_contract', + NewElementaryType: '_visit_new_elementary_type', + TupleExpression: '_visit_tuple_expression', + TypeConversion: '_visit_type_conversion', + UnaryOperation: '_visit_unary_operation' + } + + # pylint: disable=too-few-public-methods class ExpressionVisitor: def __init__(self, expression: Expression) -> None: @@ -35,60 +58,16 @@ def expression(self) -> Expression: # visit an expression # call pre_visit, visit_expression_name, post_visit - # pylint: disable=too-many-branches def _visit_expression(self, expression: Expression) -> None: self._pre_visit(expression) - if isinstance(expression, AssignmentOperation): - self._visit_assignement_operation(expression) - - elif isinstance(expression, BinaryOperation): - self._visit_binary_operation(expression) - - elif isinstance(expression, CallExpression): - self._visit_call_expression(expression) - - elif isinstance(expression, ConditionalExpression): - self._visit_conditional_expression(expression) - - elif isinstance(expression, ElementaryTypeNameExpression): - self._visit_elementary_type_name_expression(expression) - - elif isinstance(expression, Identifier): - self._visit_identifier(expression) - - elif isinstance(expression, IndexAccess): - self._visit_index_access(expression) - - elif isinstance(expression, Literal): - self._visit_literal(expression) - - elif isinstance(expression, MemberAccess): - self._visit_member_access(expression) - - elif isinstance(expression, NewArray): - self._visit_new_array(expression) - - elif isinstance(expression, NewContract): - self._visit_new_contract(expression) - - elif isinstance(expression, NewElementaryType): - self._visit_new_elementary_type(expression) - - elif isinstance(expression, TupleExpression): - self._visit_tuple_expression(expression) + if expression is not None: + visitor_method = get_visitor_mapping().get(expression.__class__) + if not visitor_method: + raise SlitherError(f"Expression not handled: {expression}") - elif isinstance(expression, TypeConversion): - self._visit_type_conversion(expression) - - elif isinstance(expression, UnaryOperation): - self._visit_unary_operation(expression) - - elif expression is None: - pass - - else: - raise SlitherError(f"Expression not handled: {expression}") + visitor = getattr(self, visitor_method) + visitor(expression) self._post_visit(expression)