# Buggy code
def parse_call(expression, caller_context):
    src = expression["src"]
    if caller_context.is_compact_ast:
        attributes = expression
        type_conversion = expression["kind"] == "typeConversion"
        type_return = attributes["typeDescriptions"]["typeString"]

    else:
        attributes = expression["attributes"]
        type_conversion = attributes["type_conversion"]
        type_return = attributes["type"]

    if type_conversion:
        type_call = parse_type(UnknownType(type_return), caller_context)

        if caller_context.is_compact_ast:
            assert len(expression["arguments"]) == 1
            expression_to_parse = expression["arguments"][0]
        else:
            children = expression["children"]
            assert len(children) == 2
            type_info = children[0]
            expression_to_parse = children[1]
            assert type_info["name"] in [
                "ElementaryTypenameExpression",
                "ElementaryTypeNameExpression",
                "Identifier",
                "TupleExpression",
                "IndexAccess",
                "MemberAccess",
            ]

        expression = parse_expression(expression_to_parse, caller_context)
        t = TypeConversion(expression, type_call)
        t.set_offset(src, caller_context.slither)
        return t

    call_gas = None
    call_value = None
    if caller_context.is_compact_ast:
        called = parse_expression(expression["expression"], caller_context)

        # If the next expression is a FunctionCallOptions
        # We can here the gas/value information
        # This is only available if the syntax is {gas: , value: }
        # For the .gas().value(), the member are considered as function call
        # And converted later to the correct info (convert.py)
        if expression["expression"][caller_context.get_key()] == "FunctionCallOptions":
            call_with_options = expression["expression"]
            for idx, name in enumerate(call_with_options.get("names", [])):
                option = parse_expression(
                    call_with_options["options"][idx], caller_context
                )
                if name == "value":
                    call_value = option
                if name == "gas":
                    call_gas = option

        arguments = []
        if expression["arguments"]:
            arguments = [
                parse_expression(a, caller_context) for a in expression["arguments"]
            ]
    else:
        children = expression["children"]
        called = parse_expression(children[0], caller_context)
        arguments = [parse_expression(a, caller_context) for a in children[1::]]

    if isinstance(called, SuperCallExpression):
        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(src, caller_context.slither)

    # Only available if the syntax {gas:, value:} was used
    call_expression.call_gas = call_gas
    call_expression.call_value = call_value
    return call_expression


# Traceback (AssertionError)
ERROR:root:Error in .
ERROR:root:Traceback (most recent call last):
File "/usr/local/lib/python3.7/site-packages/slither/__main__.py", line 606, in main_impl
printer_classes)
File "/usr/local/lib/python3.7/site-packages/slither/__main__.py", line 68, in process_all
compilation, args, detector_classes, printer_classes)
File "/usr/local/lib/python3.7/site-packages/slither/__main__.py", line 55, in process_single
**vars(args))
File "/usr/local/lib/python3.7/site-packages/slither/slither.py", line 86, in __init__
self._analyze_contracts()
File "/usr/local/lib/python3.7/site-packages/slither/solc_parsing/slitherSolc.py", line 254, in _analyze_contracts
self._analyze_third_part(contracts_to_be_analyzed, libraries)
File "/usr/local/lib/python3.7/site-packages/slither/solc_parsing/slitherSolc.py", line 332, in _analyze_third_part
self._analyze_variables_modifiers_functions(contract)
File "/usr/local/lib/python3.7/site-packages/slither/solc_parsing/slitherSolc.py", line 372, in _analyze_variables_modifiers_functions
contract.analyze_content_functions()
File "/usr/local/lib/python3.7/site-packages/slither/solc_parsing/declarations/contract.py", line 291, in analyze_content_functions
function.analyze_content()
File "/usr/local/lib/python3.7/site-packages/slither/solc_parsing/declarations/function.py", line 240, in analyze_content
node.analyze_expressions(self)
File "/usr/local/lib/python3.7/site-packages/slither/solc_parsing/cfg/node.py", line 31, in analyze_expressions
expression = parse_expression(self._unparsed_expression, caller_context)
File "/usr/local/lib/python3.7/site-packages/slither/solc_parsing/expressions/expression_parsing.py", line 417, in parse_expression
return parse_call(expression, caller_context)
File "/usr/local/lib/python3.7/site-packages/slither/solc_parsing/expressions/expression_parsing.py", line 271, in parse_call
called = parse_expression(expression['expression'], caller_context)
File "/usr/local/lib/python3.7/site-packages/slither/solc_parsing/expressions/expression_parsing.py", line 422, in parse_expression
assert isinstance(called, MemberAccess)
AssertionError

# Fixed code
def parse_call(expression, caller_context):
    src = expression["src"]
    if caller_context.is_compact_ast:
        attributes = expression
        type_conversion = expression["kind"] == "typeConversion"
        type_return = attributes["typeDescriptions"]["typeString"]

    else:
        attributes = expression["attributes"]
        type_conversion = attributes["type_conversion"]
        type_return = attributes["type"]

    if type_conversion:
        type_call = parse_type(UnknownType(type_return), caller_context)

        if caller_context.is_compact_ast:
            assert len(expression["arguments"]) == 1
            expression_to_parse = expression["arguments"][0]
        else:
            children = expression["children"]
            assert len(children) == 2
            type_info = children[0]
            expression_to_parse = children[1]
            assert type_info["name"] in [
                "ElementaryTypenameExpression",
                "ElementaryTypeNameExpression",
                "Identifier",
                "TupleExpression",
                "IndexAccess",
                "MemberAccess",
            ]

        expression = parse_expression(expression_to_parse, caller_context)
        t = TypeConversion(expression, type_call)
        t.set_offset(src, caller_context.slither)
        return t

    call_gas = None
    call_value = None
    call_salt = None
    if caller_context.is_compact_ast:
        called = parse_expression(expression["expression"], caller_context)
        # If the next expression is a FunctionCallOptions
        # We can here the gas/value information
        # This is only available if the syntax is {gas: , value: }
        # For the .gas().value(), the member are considered as function call
        # And converted later to the correct info (convert.py)
        if expression["expression"][caller_context.get_key()] == "FunctionCallOptions":
            call_with_options = expression["expression"]
            for idx, name in enumerate(call_with_options.get("names", [])):
                option = parse_expression(
                    call_with_options["options"][idx], caller_context
                )
                if name == "value":
                    call_value = option
                if name == "gas":
                    call_gas = option
                if name == "salt":
                    call_salt = option
        arguments = []
        if expression["arguments"]:
            arguments = [
                parse_expression(a, caller_context) for a in expression["arguments"]
            ]
    else:
        children = expression["children"]
        called = parse_expression(children[0], caller_context)
        arguments = [parse_expression(a, caller_context) for a in children[1::]]

    if isinstance(called, SuperCallExpression):
        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(src, caller_context.slither)

    # Only available if the syntax {gas:, value:} was used
    call_expression.call_gas = call_gas
    call_expression.call_value = call_value
    call_expression.call_salt = call_salt
    return call_expression