fix compilation unit missing in source API

pull/1765/head
alpharush 2 years ago
parent 537f11cf88
commit 0b20aca729
  1. 36
      slither/core/source_mapping/source_mapping.py
  2. 28
      slither/printers/summary/declaration.py
  3. 5
      slither/utils/source_mapping.py

@ -18,7 +18,7 @@ if TYPE_CHECKING:
# pylint: disable=too-many-instance-attributes # pylint: disable=too-many-instance-attributes
class Source: class Source:
def __init__(self) -> None: def __init__(self, compilation_unit: "SlitherCompilationUnit") -> None:
self.start: int = 0 self.start: int = 0
self.length: int = 0 self.length: int = 0
self.filename: Filename = Filename("", "", "", "") self.filename: Filename = Filename("", "", "", "")
@ -27,7 +27,7 @@ class Source:
self.starting_column: int = 0 self.starting_column: int = 0
self.ending_column: int = 0 self.ending_column: int = 0
self.end: int = 0 self.end: int = 0
self.compilation_unit: Optional["SlitherCompilationUnit"] = None self.compilation_unit = compilation_unit
def to_json(self) -> Dict: def to_json(self) -> Dict:
return { return {
@ -51,17 +51,16 @@ class Source:
filename_relative: str = self.filename.relative if self.filename.relative else "" filename_relative: str = self.filename.relative if self.filename.relative else ""
return f"{markdown_root}{filename_relative}{lines}" return f"{markdown_root}{filename_relative}{lines}"
def to_detailled_str(self) -> str: def to_detailed_str(self) -> str:
lines = self._get_lines_str() lines = self._get_lines_str()
filename_short: str = self.filename.short if self.filename.short else "" filename_short: str = self.filename.short if self.filename.short else ""
return f"{filename_short}{lines} ({self.starting_column} - {self.ending_column})" return f"{filename_short}{lines} ({self.starting_column} - {self.ending_column})"
def _get_lines_str(self, line_descr=""): def span(self) -> str:
with open (self.filename.absolute, "r") as f:
# If the compilation unit was not initialized, it means that the set_offset was never called return f.readlines()[self.start:self.end]
# on the corresponding object, which should not happen
assert self.compilation_unit is not None
def _get_lines_str(self, line_descr=""):
line_prefix = self.compilation_unit.core.line_prefix line_prefix = self.compilation_unit.core.line_prefix
lines = self.lines lines = self.lines
@ -105,6 +104,7 @@ def _compute_line(
Not done in an efficient way Not done in an efficient way
""" """
start_line, starting_column = compilation_unit.core.crytic_compile.get_line_from_offset( start_line, starting_column = compilation_unit.core.crytic_compile.get_line_from_offset(
filename, start filename, start
) )
@ -127,7 +127,7 @@ def _convert_source_mapping(
position = re.findall("([0-9]*):([0-9]*):([-]?[0-9]*)", offset) position = re.findall("([0-9]*):([0-9]*):([-]?[0-9]*)", offset)
if len(position) != 1: if len(position) != 1:
return Source() return Source(compilation_unit)
s, l, f = position[0] s, l, f = position[0]
s = int(s) s = int(s)
@ -135,7 +135,7 @@ def _convert_source_mapping(
f = int(f) f = int(f)
if f not in sourceUnits: if f not in sourceUnits:
new_source = Source() new_source = Source(compilation_unit)
new_source.start = s new_source.start = s
new_source.length = l new_source.length = l
return new_source return new_source
@ -149,7 +149,7 @@ def _convert_source_mapping(
(lines, starting_column, ending_column) = _compute_line(compilation_unit, filename, s, l) (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.start = s
new_source.length = l new_source.length = l
new_source.filename = filename new_source.filename = filename
@ -158,28 +158,22 @@ def _convert_source_mapping(
new_source.starting_column = starting_column new_source.starting_column = starting_column
new_source.ending_column = ending_column new_source.ending_column = ending_column
new_source.end = new_source.start + l new_source.end = new_source.start + l
return new_source return new_source
class SourceMapping(Context, metaclass=ABCMeta): class SourceMapping(Context, metaclass=ABCMeta):
def __init__(self) -> None: def __init__(self) -> None:
super().__init__() super().__init__()
# self._source_mapping: Optional[Dict] = None self.source_mapping: Optional[Source] = None
self.source_mapping: Source = Source()
self.references: List[Source] = [] self.references: List[Source] = []
def set_offset( def set_offset(
self, offset: Union["Source", str], compilation_unit: "SlitherCompilationUnit" self, offset: Union["Source", str], compilation_unit: "SlitherCompilationUnit"
) -> None: ) -> None:
assert compilation_unit
if isinstance(offset, Source): if isinstance(offset, Source):
self.source_mapping.start = offset.start self.source_mapping = offset
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
else: else:
self.source_mapping = _convert_source_mapping(offset, compilation_unit) self.source_mapping = _convert_source_mapping(offset, compilation_unit)
self.source_mapping.compilation_unit = compilation_unit self.source_mapping.compilation_unit = compilation_unit

@ -20,37 +20,37 @@ class Declaration(AbstractPrinter):
txt += "\n# Contracts\n" txt += "\n# Contracts\n"
for contract in compilation_unit.contracts: for contract in compilation_unit.contracts:
txt += f"# {contract.name}\n" txt += f"# {contract.name}\n"
txt += f"\t- Declaration: {get_definition(contract, compilation_unit.core.crytic_compile).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_detailled_str()}\n" txt += f"\t- Implementation: {get_implementation(contract).to_detailed_str()}\n"
txt += ( 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" txt += "\n\t## Function\n"
for func in contract.functions: for func in contract.functions:
txt += f"\t\t- {func.canonical_name}\n" 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- Declaration: {get_definition(func, compilation_unit.core.crytic_compile).to_detailed_str()}\n"
txt += ( txt += f"\t\t\t- Implementation: {get_implementation(func).to_detailed_str()}\n"
f"\t\t\t- Implementation: {get_implementation(func).to_detailled_str()}\n" txt += f"\t\t\t- References: {[x.to_detailed_str() for x in get_references(func)]}\n"
)
txt += f"\t\t\t- References: {[x.to_detailled_str() for x in get_references(func)]}\n"
txt += "\n\t## State variables\n" txt += "\n\t## State variables\n"
for var in contract.state_variables: for var in contract.state_variables:
txt += f"\t\t- {var.name}\n" 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- Declaration: {get_definition(var, compilation_unit.core.crytic_compile).to_detailed_str()}\n"
txt += f"\t\t\t- Implementation: {get_implementation(var).to_detailled_str()}\n" txt += f"\t\t\t- Implementation: {get_implementation(var).to_detailed_str()}\n"
txt += f"\t\t\t- References: {[x.to_detailled_str() for x in get_references(var)]}\n" txt += f"\t\t\t- References: {[x.to_detailed_str() for x in get_references(var)]}\n"
txt += "\n\t## Structures\n" txt += "\n\t## Structures\n"
for st in contract.structures: for st in contract.structures:
txt += f"\t\t- {st.name}\n" 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- Declaration: {get_definition(st, compilation_unit.core.crytic_compile).txt}\n"
txt += f"\t\t\t- Implementation: {get_implementation(st).to_detailled_str()}\n" txt += f"\t\t\t- Implementation: {get_implementation(st).to_detailed_str()}\n"
txt += f"\t\t\t- References: {[x.to_detailled_str() for x in get_references(st)]}\n" txt += (
f"\t\t\t- References: {[x.to_detailed_str() for x in get_references(st)]}\n"
)
self.info(txt) self.info(txt)
res = self.generate_output(txt) res = self.generate_output(txt)

@ -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) 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.start = target.source_mapping.start + start_offset
s.length = len(pattern) s.length = len(pattern)
s.filename = target.source_mapping.filename 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.starting_column = starting_column
s.ending_column = ending_column s.ending_column = ending_column
s.end = s.start + s.length s.end = s.start + s.length
s.compilation_unit = target.compilation_unit s.txt = txt
return s return s

Loading…
Cancel
Save