-
Notifications
You must be signed in to change notification settings - Fork 0
/
goto_def_impl_refs.py
105 lines (89 loc) · 3.53 KB
/
goto_def_impl_refs.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
from typing import TYPE_CHECKING, Callable, List, Optional, Set
import lsprotocol.types as lsp
from slither import Slither
from slither.core.source_mapping.source_mapping import Source
from slither_lsp.app.utils.file_paths import uri_to_fs_path
from slither_lsp.app.utils.ranges import source_to_location
if TYPE_CHECKING:
from slither_lsp.app.slither_server import SlitherServer
def _inspect_analyses(
ls: "SlitherServer",
target_filename_str: str,
line: int,
col: int,
func: Callable[[Slither, int], Set[Source]],
) -> List[lsp.Location]:
# Compile a list of definitions
results = []
# Loop through all compilations
for analysis_result in ls.analyses:
if analysis_result.analysis is not None:
# TODO: Remove this temporary try/catch once we refactor crytic-compile to now throw errors in
# these functions.
try:
# Obtain the offset for this line + character position
target_offset = analysis_result.compilation.get_global_offset_from_line(
target_filename_str, line
)
# Obtain sources
sources = func(analysis_result.analysis, target_offset + col)
except Exception:
continue
else:
# Add all definitions from this source.
for source in sources:
source_location: Optional[lsp.Location] = source_to_location(source)
if source_location is not None:
results.append(source_location)
return results
def register_on_goto_definition(ls: "SlitherServer"):
@ls.thread()
@ls.feature(lsp.TEXT_DOCUMENT_DEFINITION)
def on_goto_definition(
ls: "SlitherServer", params: lsp.DefinitionParams
) -> List[lsp.Location]:
# Obtain our filename for this file
target_filename_str: str = uri_to_fs_path(params.text_document.uri)
return _inspect_analyses(
ls,
target_filename_str,
params.position.line + 1,
params.position.character,
lambda analysis, offset: analysis.offset_to_definitions(
target_filename_str, offset
),
)
def register_on_goto_implementation(ls: "SlitherServer"):
@ls.thread()
@ls.feature(lsp.TEXT_DOCUMENT_IMPLEMENTATION)
def on_goto_implementation(
ls: "SlitherServer", params: lsp.ImplementationParams
) -> List[lsp.Location]:
# Obtain our filename for this file
target_filename_str: str = uri_to_fs_path(params.text_document.uri)
return _inspect_analyses(
ls,
target_filename_str,
params.position.line + 1,
params.position.character,
lambda analysis, offset: analysis.offset_to_implementations(
target_filename_str, offset
),
)
def register_on_find_references(ls: "SlitherServer"):
@ls.thread()
@ls.feature(lsp.TEXT_DOCUMENT_REFERENCES)
def on_find_references(
ls: "SlitherServer", params: lsp.ImplementationParams
) -> Optional[List[lsp.Location]]:
# Obtain our filename for this file
target_filename_str: str = uri_to_fs_path(params.text_document.uri)
return _inspect_analyses(
ls,
target_filename_str,
params.position.line + 1,
params.position.character,
lambda analysis, offset: analysis.offset_to_references(
target_filename_str, offset
),
)