slither.utils.source_mapping

 1from typing import List, Set
 2from crytic_compile import CryticCompile
 3from slither.core.declarations import (
 4    Contract,
 5    FunctionContract,
 6)
 7from slither.core.source_mapping.source_mapping import Source, SourceMapping
 8from slither.exceptions import SlitherError
 9
10
11def get_definition(target: SourceMapping, crytic_compile: CryticCompile) -> Source:
12    try:
13        pattern = target.pattern
14    except AttributeError as exc:
15        raise SlitherError(f"get_definition_generic not implemented for {type(target)}") from exc
16
17    file_content = crytic_compile.src_content_for_file(target.source_mapping.filename.absolute)
18    txt = file_content[
19        target.source_mapping.start : target.source_mapping.start + target.source_mapping.length
20    ]
21
22    start_offset = txt.find(pattern) + 1  # remove the space
23
24    starting_line, starting_column = crytic_compile.get_line_from_offset(
25        target.source_mapping.filename, target.source_mapping.start + start_offset
26    )
27
28    ending_line, ending_column = crytic_compile.get_line_from_offset(
29        target.source_mapping.filename, target.source_mapping.start + start_offset + len(pattern)
30    )
31
32    s = Source(target.source_mapping.compilation_unit)
33    s.start = target.source_mapping.start + start_offset
34    s.length = len(pattern)
35    s.filename = target.source_mapping.filename
36    s.is_dependency = target.source_mapping.is_dependency
37    s.lines = list(range(starting_line, ending_line + 1))
38    s.starting_column = starting_column
39    s.ending_column = ending_column
40    s.end = s.start + s.length
41    s.txt = txt
42    return s
43
44
45def get_implementation(target: SourceMapping) -> Source:
46    return target.source_mapping
47
48
49def get_all_implementations(target: SourceMapping, contracts: List[Contract]) -> Set[Source]:
50    """
51    Get all implementations of a contract or function, accounting for inheritance and overrides
52    """
53    implementations = set()
54    # Abstract contracts and interfaces are implemented by their children
55    if isinstance(target, Contract):
56        is_interface = target.is_interface
57        is_implicitly_abstract = not target.is_fully_implemented
58        is_explicitly_abstract = target.is_abstract
59        if is_interface or is_implicitly_abstract or is_explicitly_abstract:
60            for contract in contracts:
61                if target in contract.immediate_inheritance:
62                    implementations.add(contract.source_mapping)
63
64    # Parent's virtual functions may be overridden by children
65    elif isinstance(target, FunctionContract):
66        for over in target.overridden_by:
67            implementations.add(over.source_mapping)
68        # Only show implemented virtual functions
69        if not target.is_virtual or target.is_implemented:
70            implementations.add(get_implementation(target))
71
72    else:
73        implementations.add(get_implementation(target))
74
75    return implementations
76
77
78def get_references(target: SourceMapping) -> List[Source]:
79    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:
12def get_definition(target: SourceMapping, crytic_compile: CryticCompile) -> Source:
13    try:
14        pattern = target.pattern
15    except AttributeError as exc:
16        raise SlitherError(f"get_definition_generic not implemented for {type(target)}") from exc
17
18    file_content = crytic_compile.src_content_for_file(target.source_mapping.filename.absolute)
19    txt = file_content[
20        target.source_mapping.start : target.source_mapping.start + target.source_mapping.length
21    ]
22
23    start_offset = txt.find(pattern) + 1  # remove the space
24
25    starting_line, starting_column = crytic_compile.get_line_from_offset(
26        target.source_mapping.filename, target.source_mapping.start + start_offset
27    )
28
29    ending_line, ending_column = crytic_compile.get_line_from_offset(
30        target.source_mapping.filename, target.source_mapping.start + start_offset + len(pattern)
31    )
32
33    s = Source(target.source_mapping.compilation_unit)
34    s.start = target.source_mapping.start + start_offset
35    s.length = len(pattern)
36    s.filename = target.source_mapping.filename
37    s.is_dependency = target.source_mapping.is_dependency
38    s.lines = list(range(starting_line, ending_line + 1))
39    s.starting_column = starting_column
40    s.ending_column = ending_column
41    s.end = s.start + s.length
42    s.txt = txt
43    return s
46def get_implementation(target: SourceMapping) -> Source:
47    return target.source_mapping
50def get_all_implementations(target: SourceMapping, contracts: List[Contract]) -> Set[Source]:
51    """
52    Get all implementations of a contract or function, accounting for inheritance and overrides
53    """
54    implementations = set()
55    # Abstract contracts and interfaces are implemented by their children
56    if isinstance(target, Contract):
57        is_interface = target.is_interface
58        is_implicitly_abstract = not target.is_fully_implemented
59        is_explicitly_abstract = target.is_abstract
60        if is_interface or is_implicitly_abstract or is_explicitly_abstract:
61            for contract in contracts:
62                if target in contract.immediate_inheritance:
63                    implementations.add(contract.source_mapping)
64
65    # Parent's virtual functions may be overridden by children
66    elif isinstance(target, FunctionContract):
67        for over in target.overridden_by:
68            implementations.add(over.source_mapping)
69        # Only show implemented virtual functions
70        if not target.is_virtual or target.is_implemented:
71            implementations.add(get_implementation(target))
72
73    else:
74        implementations.add(get_implementation(target))
75
76    return implementations

Get all implementations of a contract or function, accounting for inheritance and overrides

79def get_references(target: SourceMapping) -> List[Source]:
80    return target.references