diff --git a/slither/core/declarations/function.py b/slither/core/declarations/function.py index 11d39dc92..66594216f 100644 --- a/slither/core/declarations/function.py +++ b/slither/core/declarations/function.py @@ -1028,19 +1028,21 @@ class Function(ChildContract, ChildInheritance, SourceMapping): filename (str) """ from slither.core.cfg.node import NodeType + content = '' with open(filename, 'w', encoding='utf8') as f: - f.write('digraph{\n') + content += 'digraph{\n' for node in self.nodes: label = 'Node Type: {} {}\n'.format(NodeType.str(node.type), node.node_id) if node.expression: label += '\nEXPRESSION:\n{}\n'.format(node.expression) if node.irs: label += '\nIRs:\n' + '\n'.join([str(ir) for ir in node.irs]) - f.write('{}[label="{}"];\n'.format(node.node_id, label)) + content += '{}[label="{}"];\n'.format(node.node_id, label) for son in node.sons: - f.write('{}->{};\n'.format(node.node_id, son.node_id)) + content += '{}->{};\n'.format(node.node_id, son.node_id) - f.write("}\n") + content += "}\n" + return content def dominator_tree_to_dot(self, filename): """ diff --git a/slither/printers/call/call_graph.py b/slither/printers/call/call_graph.py index 8710e82ed..4c3058ad6 100644 --- a/slither/printers/call/call_graph.py +++ b/slither/printers/call/call_graph.py @@ -163,15 +163,15 @@ class PrinterCallGraph(AbstractPrinter): info = '' results = [] with open(filename, 'w', encoding='utf8') as f: - info += f'Call Graph: {filename}' - content = '\n'.join(['strict digraph {'] + [self._process_functions(self.slither.functions)] + ['}']) + info += f'Call Graph: {filename}\n' + content = '\n'.join(['strict digraph {'] + [self._process_functions(self.slither.functions)] + ['}']) f.write(content) results.append((filename, content)) for derived_contract in self.slither.contracts_derived: with open(f'{derived_contract.name}.dot', 'w', encoding='utf8') as f: - info += f'Call Graph: {derived_contract.name}.dot' - content = '\n'.join(['strict digraph {'] + [self._process_functions(derived_contract.functions)] + ['}']) + info += f'Call Graph: {derived_contract.name}.dot\n' + content = '\n'.join(['strict digraph {'] + [self._process_functions(derived_contract.functions)] + ['}']) f.write(content) results.append((filename, content)) diff --git a/slither/printers/functions/cfg.py b/slither/printers/functions/cfg.py index a8b53a3be..0bec28369 100644 --- a/slither/printers/functions/cfg.py +++ b/slither/printers/functions/cfg.py @@ -22,8 +22,11 @@ class CFG(AbstractPrinter): all_files = [] for contract in self.contracts: for function in contract.functions + contract.modifiers: - filename = "{}-{}-{}.dot".format(original_filename, contract.name, function.full_name) - info += 'Export {}'.format(filename) + if original_filename: + filename = "{}-{}-{}.dot".format(original_filename, contract.name, function.full_name) + else: + filename = "{}-{}.dot".format(contract.name, function.full_name) + info += 'Export {}\n'.format(filename) content = function.slithir_cfg_to_dot(filename) with open(filename, 'w', encoding='utf8') as f: f.write(content) diff --git a/slither/printers/inheritance/inheritance.py b/slither/printers/inheritance/inheritance.py index e6b2972fb..62d816f18 100644 --- a/slither/printers/inheritance/inheritance.py +++ b/slither/printers/inheritance/inheritance.py @@ -36,11 +36,10 @@ class PrinterInheritance(AbstractPrinter): info += blue('Child_Contract -> ') + green('Immediate_Base_Contracts') info += green(' [Not_Immediate_Base_Contracts]') - result = {} - result['child_to_base'] = {} + result = {'child_to_base': {}} for child in self.contracts: - info += blue(f'\n+ {child.name}') + info += blue(f'\n+ {child.name}\n') result['child_to_base'][child.name] = {'immediate': [], 'not_immediate': []} if child.inheritance: @@ -48,18 +47,18 @@ class PrinterInheritance(AbstractPrinter): immediate = child.immediate_inheritance not_immediate = [i for i in child.inheritance if i not in immediate] - info += ' -> ' + green(", ".join(map(str, immediate))) + info += ' -> ' + green(", ".join(map(str, immediate))) + '\n' result['child_to_base'][child.name]['immediate'] = list(map(str, immediate)) if not_immediate: - info += ", ["+ green(", ".join(map(str, not_immediate))) + "]" + info += ", ["+ green(", ".join(map(str, not_immediate))) + "]\n" result['child_to_base'][child.name]['not_immediate'] = list(map(str, not_immediate)) - info += green('\n\nBase_Contract -> ') + blue('Immediate_Child_Contracts') - info += blue(' [Not_Immediate_Child_Contracts]') + info += green('\n\nBase_Contract -> ') + blue('Immediate_Child_Contracts') + '\n' + info += blue(' [Not_Immediate_Child_Contracts]') + '\n' result['base_to_child'] = {} for base in self.contracts: - info += green(f'\n+ {base.name}') + info += green(f'\n+ {base.name}') + '\n' children = list(self._get_child_contracts(base)) result['base_to_child'][base.name] = {'immediate': [], @@ -68,10 +67,10 @@ class PrinterInheritance(AbstractPrinter): immediate = [child for child in children if base in child.immediate_inheritance] not_immediate = [child for child in children if not child in immediate] - info += ' -> ' + blue(", ".join(map(str, immediate))) + info += ' -> ' + blue(", ".join(map(str, immediate))) + '\n' result['base_to_child'][base.name]['immediate'] = list(map(str, immediate)) if not_immediate: - info += ', [' + blue(", ".join(map(str, not_immediate))) + ']' + info += ', [' + blue(", ".join(map(str, not_immediate))) + ']' + '\n' result['base_to_child'][base.name]['not_immediate'] = list(map(str, immediate)) self.info(info) diff --git a/slither/printers/inheritance/inheritance_graph.py b/slither/printers/inheritance/inheritance_graph.py index de527809a..4fb3bf877 100644 --- a/slither/printers/inheritance/inheritance_graph.py +++ b/slither/printers/inheritance/inheritance_graph.py @@ -161,7 +161,7 @@ class PrinterInheritanceGraph(AbstractPrinter): filename = 'contracts.dot' if not filename.endswith('.dot'): filename += ".dot" - info = 'Inheritance Graph: ' + filename + info = 'Inheritance Graph: ' + filename + '\n' self.info(info) content = 'digraph "" {\n' diff --git a/slither/printers/summary/constructor_calls.py b/slither/printers/summary/constructor_calls.py index aae307827..fd9d17226 100644 --- a/slither/printers/summary/constructor_calls.py +++ b/slither/printers/summary/constructor_calls.py @@ -23,8 +23,8 @@ class ConstructorPrinter(AbstractPrinter): for contract in self.contracts: stack_name = [] stack_definition = [] - info += "\n\nContact Name: " + contract.name - info += " Constructor Call Sequence: " + info += "\n\nContact Name: " + contract.name + '\n' + info += " Constructor Call Sequence: " + '\n' cst = contract.constructors_declared if cst: stack_name.append(contract.name) @@ -35,16 +35,16 @@ class ConstructorPrinter(AbstractPrinter): stack_name.append(inherited_contract.name) stack_definition.append(self._get_soruce_code(cst)) if len(stack_name) > 0: - info += " " + ' '.join(stack_name[len(stack_name) - 1]) + info += " " + ' '.join(stack_name[len(stack_name) - 1]) + '\n' count = len(stack_name) - 2 while count >= 0: - info += "-->" + ' '.join(stack_name[count]) + info += "-->" + ' '.join(stack_name[count]) + '\n' count = count - 1 - info += "\n Constructor Definitions:" + info += "\n Constructor Definitions:" + '\n' count = len(stack_definition) - 1 while count >= 0: - info += "\n Contract name:" + str(stack_name[count]) - info += "\n" + str(stack_definition[count]) + info += "\n Contract name:" + str(stack_name[count]) + '\n' + info += "\n" + str(stack_definition[count]) + '\n' count = count - 1 self.info(info) diff --git a/slither/printers/summary/slithir.py b/slither/printers/summary/slithir.py index f75c8b062..30b62239b 100644 --- a/slither/printers/summary/slithir.py +++ b/slither/printers/summary/slithir.py @@ -22,30 +22,30 @@ class PrinterSlithIR(AbstractPrinter): for contract in self.contracts: txt += 'Contract {}'.format(contract.name) for function in contract.functions: - txt += f'\tFunction {function.canonical_name} {"" if function.is_shadowed else "(*)"}' + txt += f'\tFunction {function.canonical_name} {"" if function.is_shadowed else "(*)"}\n' for node in function.nodes: if node.expression: - txt += '\t\tExpression: {}'.format(node.expression) - txt += '\t\tIRs:' + txt += '\t\tExpression: {}\n'.format(node.expression) + txt += '\t\tIRs:\n' for ir in node.irs: - txt += '\t\t\t{}'.format(ir) + txt += '\t\t\t{}\n'.format(ir) elif node.irs: - txt += '\t\tIRs:' + txt += '\t\tIRs:\n' for ir in node.irs: - txt += '\t\t\t{}'.format(ir) + txt += '\t\t\t{}\n'.format(ir) for modifier_statement in function.modifiers_statements: - txt += f'\t\tModifier Call {modifier_statement.entry_point.expression}' + txt += f'\t\tModifier Call {modifier_statement.entry_point.expression}\n' for modifier_statement in function.explicit_base_constructor_calls_statements: - txt += f'\t\tConstructor Call {modifier_statement.entry_point.expression}' + txt += f'\t\tConstructor Call {modifier_statement.entry_point.expression}\n' for modifier in contract.modifiers: - txt += '\tModifier {}'.format(modifier.canonical_name) + txt += '\tModifier {}\n'.format(modifier.canonical_name) for node in modifier.nodes: txt += str(node) if node.expression: - txt += '\t\tExpression: {}'.format(node.expression) - txt += '\t\tIRs:' + txt += '\t\tExpression: {}\n'.format(node.expression) + txt += '\t\tIRs:\n' for ir in node.irs: - txt += '\t\t\t{}'.format(ir) + txt += '\t\t\t{}\n'.format(ir) self.info(txt) res = self.generate_output(txt) return res diff --git a/slither/printers/summary/slithir_ssa.py b/slither/printers/summary/slithir_ssa.py index 26d962401..53ac73997 100644 --- a/slither/printers/summary/slithir_ssa.py +++ b/slither/printers/summary/slithir_ssa.py @@ -21,26 +21,26 @@ class PrinterSlithIRSSA(AbstractPrinter): txt = "" for contract in self.contracts: - txt += 'Contract {}'.format(contract.name) + txt += 'Contract {}'.format(contract.name) + '\n' for function in contract.functions: - txt += '\tFunction {}'.format(function.canonical_name) + txt += '\tFunction {}'.format(function.canonical_name) + '\n' for node in function.nodes: if node.expression: - txt += '\t\tExpression: {}'.format(node.expression) + txt += '\t\tExpression: {}'.format(node.expression) + '\n' if node.irs_ssa: - txt += '\t\tIRs:' + txt += '\t\tIRs:' + '\n' for ir in node.irs_ssa: - txt += '\t\t\t{}'.format(ir) + txt += '\t\t\t{}'.format(ir) + '\n' for modifier in contract.modifiers: - txt += '\tModifier {}'.format(modifier.canonical_name) + txt += '\tModifier {}'.format(modifier.canonical_name) + '\n' for node in modifier.nodes: - txt += str(node) + txt += str(node) + '\n' if node.expression: - txt += '\t\tExpression: {}'.format(node.expression) + txt += '\t\tExpression: {}'.format(node.expression) + '\n' if node.irs_ssa: - txt += '\t\tIRs:' + txt += '\t\tIRs:' + '\n' for ir in node.irs_ssa: - txt += '\t\t\t{}'.format(ir) + txt += '\t\t\t{}'.format(ir) + '\n' self.info(txt) res = self.generate_output(txt) return res