Improve overall source mapping support

pull/238/head
Josselin 5 years ago
parent c3e111aac4
commit 4c6ee59e42
  1. 9
      slither/slithir/convert.py
  2. 38
      slither/solc_parsing/expressions/expression_parsing.py
  3. 5
      slither/visitors/slithir/expression_to_slithir.py
  4. 29
      utils/slither_format/formatters/naming_convention.py

@ -556,10 +556,10 @@ def extract_tmp_call(ins, contract):
internalcall.call_id = ins.call_id
return internalcall
if str(ins.ori.variable_right) in [f.name for f in contract.events]:
eventcall = EventCall(ins.ori.variable_right)
eventcall.set_expression(ins.expression)
eventcall.call_id = ins.call_id
return eventcall
eventcall = EventCall(ins.ori.variable_right)
eventcall.set_expression(ins.expression)
eventcall.call_id = ins.call_id
return eventcall
if isinstance(ins.ori.variable_left, Contract):
st = ins.ori.variable_left.get_structure_from_name(ins.ori.variable_right)
if st:
@ -624,6 +624,7 @@ def extract_tmp_call(ins, contract):
internalcall = InternalCall(ins.called.constructor, ins.nbr_arguments, ins.lvalue,
ins.type_call)
internalcall.call_id = ins.call_id
internalcall.set_expression(ins.expression)
return internalcall

@ -297,8 +297,9 @@ def parse_call(expression, caller_context):
'IndexAccess',
'MemberAccess']
expression = parse_expression(expression_to_parse, caller_context)
t = TypeConversion(expression, type_call)
expression_parsed = parse_expression(expression_to_parse, caller_context)
t = TypeConversion(expression_parsed, type_call)
t.set_offset(expression['src'], caller_context.slither)
return t
if caller_context.is_compact_ast:
@ -312,7 +313,9 @@ def parse_call(expression, caller_context):
arguments = [parse_expression(a, caller_context) for a in children[1::]]
if isinstance(called, SuperCallExpression):
return SuperCallExpression(called, arguments, type_return)
sp = SuperCallExpression(called, arguments, type_return)
sp.set_offset(expression['src'], caller_context.slither)
return sp
call_expression = CallExpression(called, arguments, type_return)
call_expression.set_offset(expression['src'], caller_context.slither)
return call_expression
@ -349,7 +352,9 @@ def _parse_elementary_type_name_expression(expression, is_compact_ast, caller_co
value = expression['attributes']['value']
t = parse_type(UnknownType(value), caller_context)
return ElementaryTypeNameExpression(t)
e = ElementaryTypeNameExpression(t)
e.set_offset(expression['src'], caller_context.slither)
return e
def parse_expression(expression, caller_context):
"""
@ -393,11 +398,12 @@ def parse_expression(expression, caller_context):
operation_type = UnaryOperationType.get_type(attributes['operator'], attributes['prefix'])
if is_compact_ast:
expression = parse_expression(expression['subExpression'], caller_context)
expression_parsed = parse_expression(expression['subExpression'], caller_context)
else:
assert len(expression['children']) == 1
expression = parse_expression(expression['children'][0], caller_context)
unary_op = UnaryOperation(expression, operation_type)
expression_parsed = parse_expression(expression['children'][0], caller_context)
unary_op = UnaryOperation(expression_parsed, operation_type)
unary_op.set_offset(expression['src'], caller_context.slither)
return unary_op
elif name == 'BinaryOperation':
@ -415,10 +421,11 @@ def parse_expression(expression, caller_context):
left_expression = parse_expression(expression['children'][0], caller_context)
right_expression = parse_expression(expression['children'][1], caller_context)
binary_op = BinaryOperation(left_expression, right_expression, operation_type)
binary_op.set_offset(expression['src'], caller_context.slither)
return binary_op
elif name == 'FunctionCall':
return parse_call(expression, caller_context)
return parse_call(expression, caller_context)
elif name == 'TupleExpression':
"""
@ -433,7 +440,7 @@ def parse_expression(expression, caller_context):
Note: this is only possible with Solidity >= 0.4.12
"""
if is_compact_ast:
expressions = [parse_expression(e, caller_context) if e else None for e in expression['components']]
expressions = [parse_expression(e, caller_context) if e else None for e in expression['components']]
else:
if 'children' not in expression :
attributes = expression['attributes']
@ -452,6 +459,7 @@ def parse_expression(expression, caller_context):
if elems[idx] == '':
expressions.insert(idx, None)
t = TupleExpression(expressions)
t.set_offset(expression['src'], caller_context.slither)
return t
elif name == 'Conditional':
@ -466,6 +474,7 @@ def parse_expression(expression, caller_context):
then_expression = parse_expression(children[1], caller_context)
else_expression = parse_expression(children[2], caller_context)
conditional = ConditionalExpression(if_expression, then_expression, else_expression)
conditional.set_offset(expression['src'], caller_context.slither)
return conditional
elif name == 'Assignment':
@ -487,6 +496,7 @@ def parse_expression(expression, caller_context):
operation_return_type = attributes['type']
assignement = AssignmentOperation(left_expression, right_expression, operation_type, operation_return_type)
assignement.set_offset(expression['src'], caller_context.slither)
return assignement
elif name == 'Literal':
@ -531,6 +541,7 @@ def parse_expression(expression, caller_context):
else:
type = ElementaryType('string')
literal = Literal(value, type)
literal.set_offset(expression['src'], caller_context.slither)
return literal
elif name == 'Identifier':
@ -584,6 +595,7 @@ def parse_expression(expression, caller_context):
left_expression = parse_expression(left, caller_context)
right_expression = parse_expression(right, caller_context)
index = IndexAccess(left_expression, right_expression, index_type)
index.set_offset(expression['src'], caller_context.slither)
return index
elif name == 'MemberAccess':
@ -604,8 +616,11 @@ def parse_expression(expression, caller_context):
raise VariableNotFound('Variable not found: {}'.format(super_name))
return SuperIdentifier(var)
member_access = MemberAccess(member_name, member_type, member_expression)
member_access.set_offset(expression['src'], caller_context.slither)
if str(member_access) in SOLIDITY_VARIABLES_COMPOSED:
return Identifier(SolidityVariableComposed(str(member_access)))
identifier = Identifier(SolidityVariableComposed(str(member_access)))
identifier.set_offset(expression['src'], caller_context.slither)
return identifier
return member_access
elif name == 'ElementaryTypeNameExpression':
@ -647,6 +662,7 @@ def parse_expression(expression, caller_context):
else:
raise ParsingError('Incorrect type array {}'.format(type_name))
array = NewArray(depth, array_type)
array.set_offset(expression['src'], caller_context.slither)
return array
if type_name[caller_context.get_key()] == 'ElementaryTypeName':
@ -655,6 +671,7 @@ def parse_expression(expression, caller_context):
else:
elem_type = ElementaryType(type_name['attributes']['name'])
new_elem = NewElementaryType(elem_type)
new_elem.set_offset(expression['src'], caller_context.slither)
return new_elem
assert type_name[caller_context.get_key()] == 'UserDefinedTypeName'
@ -664,6 +681,7 @@ def parse_expression(expression, caller_context):
else:
contract_name = type_name['attributes']['name']
new = NewContract(contract_name)
new.set_offset(expression['src'], caller_context.slither)
return new
elif name == 'ModifierInvocation':

@ -67,7 +67,9 @@ class ExpressionToSlithIR(ExpressionVisitor):
self._result = []
self._visit_expression(self.expression)
if node.type == NodeType.RETURN:
self._result.append(Return(get(self.expression)))
r = Return(get(self.expression))
r.set_expression(expression)
self._result.append(r)
for ir in self._result:
ir.set_node(node)
@ -125,6 +127,7 @@ class ExpressionToSlithIR(ExpressionVisitor):
args = [get(a) for a in expression.arguments if a]
for arg in args:
arg_ = Argument(arg)
arg_.set_expression(expression)
self._result.append(arg_)
if isinstance(called, Function):
# internal call

@ -410,21 +410,28 @@ def _explore_irs(slither, irs, result, target, convert):
if not str(target) in full_txt:
raise FormatError(f'{target} not found in {full_txt} ({source_mapping}')
if full_txt.count(str(target)) > 1:
raise FormatError(f'{target} found multiple times in {full_txt} ({source_mapping}')
old_str = str(target)
new_str = convert(old_str)
loc_start = full_txt_start + full_txt.find(str(target))
loc_end = loc_start + len(old_str)
counter = 0
# Can be found multiple time on the same IR
# We patch one by one
while old_str in full_txt:
create_patch(result,
filename_source_code,
loc_start,
loc_end,
old_str,
new_str)
target_found_at = full_txt.find((old_str))
full_txt = full_txt[target_found_at+1:]
counter += target_found_at
loc_start = full_txt_start + counter
loc_end = loc_start + len(old_str)
create_patch(result,
filename_source_code,
loc_start,
loc_end,
old_str,
new_str)
def _explore_functions(slither, functions, result, target, convert):

Loading…
Cancel
Save