Improve overall source mapping support

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

@ -624,6 +624,7 @@ def extract_tmp_call(ins, contract):
internalcall = InternalCall(ins.called.constructor, ins.nbr_arguments, ins.lvalue, internalcall = InternalCall(ins.called.constructor, ins.nbr_arguments, ins.lvalue,
ins.type_call) ins.type_call)
internalcall.call_id = ins.call_id internalcall.call_id = ins.call_id
internalcall.set_expression(ins.expression)
return internalcall return internalcall

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

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

@ -410,13 +410,20 @@ def _explore_irs(slither, irs, result, target, convert):
if not str(target) in full_txt: if not str(target) in full_txt:
raise FormatError(f'{target} not found in {full_txt} ({source_mapping}') 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) old_str = str(target)
new_str = convert(old_str) new_str = convert(old_str)
loc_start = full_txt_start + full_txt.find(str(target)) counter = 0
# Can be found multiple time on the same IR
# We patch one by one
while old_str in full_txt:
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) loc_end = loc_start + len(old_str)
create_patch(result, create_patch(result,

Loading…
Cancel
Save