diff --git a/slither/core/source_mapping/source_mapping.py b/slither/core/source_mapping/source_mapping.py index ee5211c7c..2a1266e22 100644 --- a/slither/core/source_mapping/source_mapping.py +++ b/slither/core/source_mapping/source_mapping.py @@ -18,7 +18,7 @@ if TYPE_CHECKING: # pylint: disable=too-many-instance-attributes class Source: - def __init__(self) -> None: + def __init__(self, compilation_unit: "SlitherCompilationUnit") -> None: self.start: int = 0 self.length: int = 0 self.filename: Filename = Filename("", "", "", "") @@ -27,7 +27,7 @@ class Source: self.starting_column: int = 0 self.ending_column: int = 0 self.end: int = 0 - self.compilation_unit: Optional["SlitherCompilationUnit"] = None + self.compilation_unit = compilation_unit def to_json(self) -> Dict: return { @@ -51,17 +51,16 @@ class Source: filename_relative: str = self.filename.relative if self.filename.relative else "" return f"{markdown_root}{filename_relative}{lines}" - def to_detailled_str(self) -> str: + def to_detailed_str(self) -> str: lines = self._get_lines_str() filename_short: str = self.filename.short if self.filename.short else "" return f"{filename_short}{lines} ({self.starting_column} - {self.ending_column})" - def _get_lines_str(self, line_descr=""): - - # If the compilation unit was not initialized, it means that the set_offset was never called - # on the corresponding object, which should not happen - assert self.compilation_unit is not None + def span(self) -> str: + with open (self.filename.absolute, "r") as f: + return f.readlines()[self.start:self.end] + def _get_lines_str(self, line_descr=""): line_prefix = self.compilation_unit.core.line_prefix lines = self.lines @@ -105,6 +104,7 @@ def _compute_line( Not done in an efficient way """ + start_line, starting_column = compilation_unit.core.crytic_compile.get_line_from_offset( filename, start ) @@ -127,7 +127,7 @@ def _convert_source_mapping( position = re.findall("([0-9]*):([0-9]*):([-]?[0-9]*)", offset) if len(position) != 1: - return Source() + return Source(compilation_unit) s, l, f = position[0] s = int(s) @@ -135,7 +135,7 @@ def _convert_source_mapping( f = int(f) if f not in sourceUnits: - new_source = Source() + new_source = Source(compilation_unit) new_source.start = s new_source.length = l return new_source @@ -149,7 +149,7 @@ def _convert_source_mapping( (lines, starting_column, ending_column) = _compute_line(compilation_unit, filename, s, l) - new_source = Source() + new_source = Source(compilation_unit) new_source.start = s new_source.length = l new_source.filename = filename @@ -158,28 +158,22 @@ def _convert_source_mapping( new_source.starting_column = starting_column new_source.ending_column = ending_column new_source.end = new_source.start + l + return new_source class SourceMapping(Context, metaclass=ABCMeta): def __init__(self) -> None: super().__init__() - # self._source_mapping: Optional[Dict] = None - self.source_mapping: Source = Source() + self.source_mapping: Optional[Source] = None self.references: List[Source] = [] def set_offset( self, offset: Union["Source", str], compilation_unit: "SlitherCompilationUnit" ) -> None: + assert compilation_unit if isinstance(offset, Source): - self.source_mapping.start = offset.start - self.source_mapping.length = offset.length - self.source_mapping.filename = offset.filename - self.source_mapping.is_dependency = offset.is_dependency - self.source_mapping.lines = offset.lines - self.source_mapping.starting_column = offset.starting_column - self.source_mapping.ending_column = offset.ending_column - self.source_mapping.end = offset.end + self.source_mapping = offset else: self.source_mapping = _convert_source_mapping(offset, compilation_unit) self.source_mapping.compilation_unit = compilation_unit diff --git a/slither/printers/summary/declaration.py b/slither/printers/summary/declaration.py index 5888a1f00..529aba5f0 100644 --- a/slither/printers/summary/declaration.py +++ b/slither/printers/summary/declaration.py @@ -20,37 +20,37 @@ class Declaration(AbstractPrinter): txt += "\n# Contracts\n" for contract in compilation_unit.contracts: txt += f"# {contract.name}\n" - txt += f"\t- Declaration: {get_definition(contract, compilation_unit.core.crytic_compile).to_detailled_str()}\n" - txt += f"\t- Implementation: {get_implementation(contract).to_detailled_str()}\n" + txt += f"\t- Declaration: {get_definition(contract, compilation_unit.core.crytic_compile).to_detailed_str()}\n" + txt += f"\t- Implementation: {get_implementation(contract).to_detailed_str()}\n" txt += ( - f"\t- References: {[x.to_detailled_str() for x in get_references(contract)]}\n" + f"\t- References: {[x.to_detailed_str() for x in get_references(contract)]}\n" ) txt += "\n\t## Function\n" for func in contract.functions: txt += f"\t\t- {func.canonical_name}\n" - txt += f"\t\t\t- Declaration: {get_definition(func, compilation_unit.core.crytic_compile).to_detailled_str()}\n" - txt += ( - f"\t\t\t- Implementation: {get_implementation(func).to_detailled_str()}\n" - ) - txt += f"\t\t\t- References: {[x.to_detailled_str() for x in get_references(func)]}\n" + txt += f"\t\t\t- Declaration: {get_definition(func, compilation_unit.core.crytic_compile).to_detailed_str()}\n" + txt += f"\t\t\t- Implementation: {get_implementation(func).to_detailed_str()}\n" + txt += f"\t\t\t- References: {[x.to_detailed_str() for x in get_references(func)]}\n" txt += "\n\t## State variables\n" for var in contract.state_variables: txt += f"\t\t- {var.name}\n" - txt += f"\t\t\t- Declaration: {get_definition(var, compilation_unit.core.crytic_compile).to_detailled_str()}\n" - txt += f"\t\t\t- Implementation: {get_implementation(var).to_detailled_str()}\n" - txt += f"\t\t\t- References: {[x.to_detailled_str() for x in get_references(var)]}\n" + txt += f"\t\t\t- Declaration: {get_definition(var, compilation_unit.core.crytic_compile).to_detailed_str()}\n" + txt += f"\t\t\t- Implementation: {get_implementation(var).to_detailed_str()}\n" + txt += f"\t\t\t- References: {[x.to_detailed_str() for x in get_references(var)]}\n" txt += "\n\t## Structures\n" for st in contract.structures: txt += f"\t\t- {st.name}\n" - txt += f"\t\t\t- Declaration: {get_definition(st, compilation_unit.core.crytic_compile).to_detailled_str()}\n" - txt += f"\t\t\t- Implementation: {get_implementation(st).to_detailled_str()}\n" - txt += f"\t\t\t- References: {[x.to_detailled_str() for x in get_references(st)]}\n" + txt += f"\t\t\t- Declaration: {get_definition(st, compilation_unit.core.crytic_compile).txt}\n" + txt += f"\t\t\t- Implementation: {get_implementation(st).to_detailed_str()}\n" + txt += ( + f"\t\t\t- References: {[x.to_detailed_str() for x in get_references(st)]}\n" + ) self.info(txt) res = self.generate_output(txt) diff --git a/slither/utils/source_mapping.py b/slither/utils/source_mapping.py index 26ad7c0d2..b117cd5f7 100644 --- a/slither/utils/source_mapping.py +++ b/slither/utils/source_mapping.py @@ -35,7 +35,7 @@ def get_definition(target: SourceMapping, crytic_compile: CryticCompile) -> Sour target.source_mapping.filename, target.source_mapping.start + start_offset + len(pattern) ) - s = Source() + s = Source(target.source_mapping.compilation_unit) s.start = target.source_mapping.start + start_offset s.length = len(pattern) s.filename = target.source_mapping.filename @@ -44,8 +44,7 @@ def get_definition(target: SourceMapping, crytic_compile: CryticCompile) -> Sour s.starting_column = starting_column s.ending_column = ending_column s.end = s.start + s.length - s.compilation_unit = target.compilation_unit - + s.txt = txt return s