move nested logic into functions

pull/1501/head
alpharush 2 years ago
parent ca252f1472
commit baf4143345
  1. 98
      slither/utils/expression_manipulations.py

@ -23,7 +23,8 @@ from slither.all_exceptions import SlitherException
# pylint: disable=protected-access # pylint: disable=protected-access
def f_expressions( def f_expressions(
e: AssignmentOperation, x: Union[Identifier, Literal, MemberAccess, IndexAccess] e: Union[AssignmentOperation, BinaryOperation, TupleExpression],
x: Union[Identifier, Literal, MemberAccess, IndexAccess],
) -> None: ) -> None:
e._expressions.append(x) e._expressions.append(x)
@ -40,7 +41,7 @@ def f_call_gas(e: CallExpression, x):
e._gas = x e._gas = x
def f_expression(e, x): def f_expression(e: Union[TypeConversion, UnaryOperation, MemberAccess], x):
e._expression = x e._expression = x
@ -86,7 +87,6 @@ class SplitTernaryExpression:
f(false_expression, copy.copy(next_expr)) f(false_expression, copy.copy(next_expr))
return True return True
# pylint: disable=too-many-branches
def copy_expression( def copy_expression(
self, expression: Expression, true_expression: Expression, false_expression: Expression self, expression: Expression, true_expression: Expression, false_expression: Expression
) -> None: ) -> None:
@ -102,35 +102,42 @@ class SplitTernaryExpression:
): ):
return return
# case of lib elif isinstance(expression, (AssignmentOperation, BinaryOperation, TupleExpression)):
# (.. ? .. : ..).add true_expression._expressions = []
if isinstance(expression, MemberAccess): false_expression._expressions = []
self.convert_expressions(expression, true_expression, false_expression)
elif isinstance(expression, CallExpression):
next_expr = expression.called
self.convert_call_expression(expression, next_expr, true_expression, false_expression)
elif isinstance(expression, (TypeConversion, UnaryOperation, MemberAccess)):
next_expr = expression.expression next_expr = expression.expression
if self.conditional_not_ahead( if self.conditional_not_ahead(
next_expr, true_expression, false_expression, f_expression next_expr, true_expression, false_expression, f_expression
): ):
self.copy_expression( self.copy_expression(
next_expr, true_expression.expression, false_expression.expression expression.expression,
true_expression.expression,
false_expression.expression,
) )
# pylint: disable=too-many-nested-blocks
elif isinstance(expression, (AssignmentOperation, BinaryOperation, TupleExpression)): else:
true_expression._expressions = [] raise SlitherException(
false_expression._expressions = [] f"Ternary operation not handled {expression}({type(expression)})"
)
def convert_expressions(
self,
expression: Union[AssignmentOperation, BinaryOperation, TupleExpression],
true_expression: Expression,
false_expression: Expression,
) -> None:
for next_expr in expression.expressions: for next_expr in expression.expressions:
# TODO: can we get rid of `NoneType` expressions in `TupleExpression`? # TODO: can we get rid of `NoneType` expressions in `TupleExpression`?
if next_expr: if next_expr:
if isinstance(next_expr, IndexAccess): if isinstance(next_expr, IndexAccess):
# create an index access for each branch self.convert_index_access(next_expr, true_expression, false_expression)
# x[if cond ? 1 : 2] -> if cond { x[1] } else { x[2] }
for expr in next_expr.expressions:
if self.conditional_not_ahead(
expr, true_expression, false_expression, f_expressions
):
self.copy_expression(
expr,
true_expression.expressions[-1],
false_expression.expressions[-1],
)
if self.conditional_not_ahead( if self.conditional_not_ahead(
next_expr, true_expression, false_expression, f_expressions next_expr, true_expression, false_expression, f_expressions
@ -142,9 +149,26 @@ class SplitTernaryExpression:
false_expression.expressions[-1], false_expression.expressions[-1],
) )
elif isinstance(expression, CallExpression): def convert_index_access(
next_expr = expression.called self, next_expr: IndexAccess, true_expression: Expression, false_expression: Expression
) -> None:
# create an index access for each branch
# x[if cond ? 1 : 2] -> if cond { x[1] } else { x[2] }
for expr in next_expr.expressions:
if self.conditional_not_ahead(expr, true_expression, false_expression, f_expressions):
self.copy_expression(
expr,
true_expression.expressions[-1],
false_expression.expressions[-1],
)
def convert_call_expression(
self,
expression: CallExpression,
next_expr: Expression,
true_expression: Expression,
false_expression: Expression,
) -> None:
# case of lib # case of lib
# (.. ? .. : ..).add # (.. ? .. : ..).add
if self.conditional_not_ahead(next_expr, true_expression, false_expression, f_called): if self.conditional_not_ahead(next_expr, true_expression, false_expression, f_called):
@ -155,9 +179,7 @@ class SplitTernaryExpression:
if expression.call_gas: if expression.call_gas:
# case of (..).func{gas: .. ? .. : ..}() # case of (..).func{gas: .. ? .. : ..}()
next_expr = expression.call_gas next_expr = expression.call_gas
if self.conditional_not_ahead( if self.conditional_not_ahead(next_expr, true_expression, false_expression, f_call_gas):
next_expr, true_expression, false_expression, f_call_gas
):
self.copy_expression( self.copy_expression(
next_expr, next_expr,
true_expression.call_gas, true_expression.call_gas,
@ -183,27 +205,11 @@ class SplitTernaryExpression:
true_expression._arguments = [] true_expression._arguments = []
false_expression._arguments = [] false_expression._arguments = []
for next_expr in expression.arguments: for expr in expression.arguments:
if self.conditional_not_ahead(next_expr, true_expression, false_expression, f_call): if self.conditional_not_ahead(expr, true_expression, false_expression, f_call):
# always on last arguments added # always on last arguments added
self.copy_expression( self.copy_expression(
next_expr, expr,
true_expression.arguments[-1], true_expression.arguments[-1],
false_expression.arguments[-1], false_expression.arguments[-1],
) )
elif isinstance(expression, (TypeConversion, UnaryOperation)):
next_expr = expression.expression
if self.conditional_not_ahead(
next_expr, true_expression, false_expression, f_expression
):
self.copy_expression(
expression.expression,
true_expression.expression,
false_expression.expression,
)
else:
raise SlitherException(
f"Ternary operation not handled {expression}({type(expression)})"
)

Loading…
Cancel
Save