slither.utils.source_mapping
1from typing import List, Set 2from crytic_compile import CryticCompile 3from slither.core.declarations import ( 4 Contract, 5 Function, 6 Enum, 7 Event, 8 Import, 9 Pragma, 10 Structure, 11 CustomError, 12 FunctionContract, 13) 14from slither.core.solidity_types import Type, TypeAlias 15from slither.core.source_mapping.source_mapping import Source, SourceMapping 16from slither.core.variables.variable import Variable 17from slither.exceptions import SlitherError 18 19 20def get_definition(target: SourceMapping, crytic_compile: CryticCompile) -> Source: 21 if isinstance(target, (Contract, Function, Enum, Event, Structure, Variable)): 22 # Add " " to look after the first solidity keyword 23 pattern = " " + target.name 24 elif isinstance(target, Import): 25 pattern = "import" 26 elif isinstance(target, Pragma): 27 pattern = "pragma" # todo maybe return with the while pragma statement 28 elif isinstance(target, CustomError): 29 pattern = "error" 30 elif isinstance(target, TypeAlias): 31 pattern = "type" 32 elif isinstance(target, Type): 33 raise SlitherError("get_definition_generic not implemented for types") 34 else: 35 raise SlitherError(f"get_definition_generic not implemented for {type(target)}") 36 37 file_content = crytic_compile.src_content_for_file(target.source_mapping.filename.absolute) 38 txt = file_content[ 39 target.source_mapping.start : target.source_mapping.start + target.source_mapping.length 40 ] 41 42 start_offset = txt.find(pattern) + 1 # remove the space 43 44 starting_line, starting_column = crytic_compile.get_line_from_offset( 45 target.source_mapping.filename, target.source_mapping.start + start_offset 46 ) 47 48 ending_line, ending_column = crytic_compile.get_line_from_offset( 49 target.source_mapping.filename, target.source_mapping.start + start_offset + len(pattern) 50 ) 51 52 s = Source(target.source_mapping.compilation_unit) 53 s.start = target.source_mapping.start + start_offset 54 s.length = len(pattern) 55 s.filename = target.source_mapping.filename 56 s.is_dependency = target.source_mapping.is_dependency 57 s.lines = list(range(starting_line, ending_line + 1)) 58 s.starting_column = starting_column 59 s.ending_column = ending_column 60 s.end = s.start + s.length 61 s.txt = txt 62 return s 63 64 65def get_implementation(target: SourceMapping) -> Source: 66 return target.source_mapping 67 68 69def get_all_implementations(target: SourceMapping, contracts: List[Contract]) -> Set[Source]: 70 """ 71 Get all implementations of a contract or function, accounting for inheritance and overrides 72 """ 73 implementations = set() 74 # Abstract contracts and interfaces are implemented by their children 75 if isinstance(target, Contract): 76 is_interface = target.is_interface 77 is_implicitly_abstract = not target.is_fully_implemented 78 is_explicitly_abstract = target.is_abstract 79 if is_interface or is_implicitly_abstract or is_explicitly_abstract: 80 for contract in contracts: 81 if target in contract.immediate_inheritance: 82 implementations.add(contract.source_mapping) 83 84 # Parent's virtual functions may be overridden by children 85 elif isinstance(target, FunctionContract): 86 for over in target.overridden_by: 87 implementations.add(over.source_mapping) 88 # Only show implemented virtual functions 89 if not target.is_virtual or target.is_implemented: 90 implementations.add(get_implementation(target)) 91 92 else: 93 implementations.add(get_implementation(target)) 94 95 return implementations 96 97 98def get_references(target: SourceMapping) -> List[Source]: 99 return target.references
def
get_definition( target: slither.core.source_mapping.source_mapping.SourceMapping, crytic_compile: crytic_compile.crytic_compile.CryticCompile) -> slither.core.source_mapping.source_mapping.Source:
21def get_definition(target: SourceMapping, crytic_compile: CryticCompile) -> Source: 22 if isinstance(target, (Contract, Function, Enum, Event, Structure, Variable)): 23 # Add " " to look after the first solidity keyword 24 pattern = " " + target.name 25 elif isinstance(target, Import): 26 pattern = "import" 27 elif isinstance(target, Pragma): 28 pattern = "pragma" # todo maybe return with the while pragma statement 29 elif isinstance(target, CustomError): 30 pattern = "error" 31 elif isinstance(target, TypeAlias): 32 pattern = "type" 33 elif isinstance(target, Type): 34 raise SlitherError("get_definition_generic not implemented for types") 35 else: 36 raise SlitherError(f"get_definition_generic not implemented for {type(target)}") 37 38 file_content = crytic_compile.src_content_for_file(target.source_mapping.filename.absolute) 39 txt = file_content[ 40 target.source_mapping.start : target.source_mapping.start + target.source_mapping.length 41 ] 42 43 start_offset = txt.find(pattern) + 1 # remove the space 44 45 starting_line, starting_column = crytic_compile.get_line_from_offset( 46 target.source_mapping.filename, target.source_mapping.start + start_offset 47 ) 48 49 ending_line, ending_column = crytic_compile.get_line_from_offset( 50 target.source_mapping.filename, target.source_mapping.start + start_offset + len(pattern) 51 ) 52 53 s = Source(target.source_mapping.compilation_unit) 54 s.start = target.source_mapping.start + start_offset 55 s.length = len(pattern) 56 s.filename = target.source_mapping.filename 57 s.is_dependency = target.source_mapping.is_dependency 58 s.lines = list(range(starting_line, ending_line + 1)) 59 s.starting_column = starting_column 60 s.ending_column = ending_column 61 s.end = s.start + s.length 62 s.txt = txt 63 return s
def
get_implementation( target: slither.core.source_mapping.source_mapping.SourceMapping) -> slither.core.source_mapping.source_mapping.Source:
def
get_all_implementations( target: slither.core.source_mapping.source_mapping.SourceMapping, contracts: List[slither.core.declarations.contract.Contract]) -> Set[slither.core.source_mapping.source_mapping.Source]:
70def get_all_implementations(target: SourceMapping, contracts: List[Contract]) -> Set[Source]: 71 """ 72 Get all implementations of a contract or function, accounting for inheritance and overrides 73 """ 74 implementations = set() 75 # Abstract contracts and interfaces are implemented by their children 76 if isinstance(target, Contract): 77 is_interface = target.is_interface 78 is_implicitly_abstract = not target.is_fully_implemented 79 is_explicitly_abstract = target.is_abstract 80 if is_interface or is_implicitly_abstract or is_explicitly_abstract: 81 for contract in contracts: 82 if target in contract.immediate_inheritance: 83 implementations.add(contract.source_mapping) 84 85 # Parent's virtual functions may be overridden by children 86 elif isinstance(target, FunctionContract): 87 for over in target.overridden_by: 88 implementations.add(over.source_mapping) 89 # Only show implemented virtual functions 90 if not target.is_virtual or target.is_implemented: 91 implementations.add(get_implementation(target)) 92 93 else: 94 implementations.add(get_implementation(target)) 95 96 return implementations
Get all implementations of a contract or function, accounting for inheritance and overrides
def
get_references( target: slither.core.source_mapping.source_mapping.SourceMapping) -> List[slither.core.source_mapping.source_mapping.Source]: