Skip to content

Commit 8bc0af8

Browse files
committed
Move signature code to dedicated handler
1 parent 57dbcfe commit 8bc0af8

File tree

4 files changed

+98
-79
lines changed

4 files changed

+98
-79
lines changed

tests/test_info.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
from pygls.workspace import Document
33
from vyper_lsp.ast import AST
44
from vyper_lsp.analyzer.AstAnalyzer import AstAnalyzer
5+
from vyper_lsp.handlers.signatures import SignatureHandler
56

67

78
def test_signature_help(ast: AST):
@@ -23,7 +24,7 @@ def foobar():
2324
self.foo(self.baz(1), 2)
2425
"""
2526
ast.build_ast(src)
26-
analyzer = AstAnalyzer(ast)
27+
analyzer = SignatureHandler(ast)
2728

2829
doc = Document(uri="<inline source code>", source=src)
2930

vyper_lsp/analyzer/AstAnalyzer.py

Lines changed: 0 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -57,83 +57,6 @@ def __init__(self, ast: AST) -> None:
5757
else:
5858
self.diagnostics_enabled = True
5959

60-
def _handle_internal_fn_signature(
61-
self, current_line: str, fn_name: str
62-
) -> Optional[SignatureHelp]:
63-
node = self.ast.find_function_declaration_node_for_name(fn_name)
64-
if not node:
65-
return None
66-
67-
fn_name = node.name
68-
parameters = []
69-
70-
fn_label = node.node_source_code.split(":\n")[0].removeprefix("def ")
71-
72-
for arg in node.args.args:
73-
start_index = fn_label.find(arg.arg)
74-
end_index = start_index + len(arg.arg)
75-
parameters.append(
76-
ParameterInformation(label=(start_index, end_index), documentation=None)
77-
)
78-
active_parameter = current_line.split("(")[-1].count(",")
79-
return SignatureHelp(
80-
signatures=[
81-
SignatureInformation(
82-
label=fn_label,
83-
parameters=parameters,
84-
documentation=None,
85-
active_parameter=active_parameter or 0,
86-
)
87-
],
88-
active_signature=0,
89-
)
90-
91-
def _handle_imported_fn_signature(
92-
self, current_line: str, module: str, fn_name: str
93-
) -> Optional[SignatureHelp]:
94-
if module in self.ast.imports:
95-
if fn := self.ast.imports[module].functions[fn_name]:
96-
logger.info(f"getting signature for {fn_name}")
97-
logger.info(fn.decl_node)
98-
node: FunctionDef = fn.decl_node
99-
label = node.node_source_code.split("def ")[1].split(":\n")[0]
100-
parameters = []
101-
for arg in node.args.args:
102-
parameters.append(
103-
ParameterInformation(label=arg.arg, documentation=None)
104-
)
105-
active_parameter = current_line.split("(")[-1].count(",")
106-
return SignatureHelp(
107-
signatures=[
108-
SignatureInformation(
109-
label=label,
110-
parameters=parameters,
111-
documentation=None,
112-
active_parameter=active_parameter or 0,
113-
)
114-
],
115-
active_signature=0,
116-
)
117-
118-
def signature_help(
119-
self, doc: Document, params: SignatureHelpParams
120-
) -> Optional[SignatureHelp]:
121-
# TODO: Implement checking external functions, module functions, and interfaces
122-
current_line = doc.lines[params.position.line]
123-
expression = get_expression_at_cursor(
124-
current_line, params.position.character - 1
125-
)
126-
parsed = utils.parse_fncall_expression(expression)
127-
if parsed is None:
128-
return None
129-
module, fn_name = parsed
130-
131-
# this returns for all external functions
132-
if module == "self":
133-
return self._handle_internal_fn_signature(current_line, fn_name)
134-
else:
135-
return self._handle_imported_fn_signature(current_line, module, fn_name)
136-
13760
def _dot_completions_for_module(
13861
self, element: str, top_level_node=None, line: str = ""
13962
) -> List[CompletionItem]:

vyper_lsp/handlers/signatures.py

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
import logging
2+
3+
from pygls.workspace import Document
4+
from vyper.ast import FunctionDef
5+
from typing import Optional
6+
7+
from lsprotocol.types import ParameterInformation, SignatureHelp, SignatureHelpParams, SignatureInformation
8+
from vyper_lsp import utils
9+
from vyper_lsp.ast import AST
10+
from vyper_lsp.utils import get_expression_at_cursor
11+
12+
logger = logging.getLogger("vyper-lsp")
13+
14+
class SignatureHandler:
15+
def __init__(self, ast: AST):
16+
self.ast = ast
17+
18+
def _handle_internal_fn_signature(
19+
self, current_line: str, fn_name: str
20+
) -> Optional[SignatureHelp]:
21+
node = self.ast.find_function_declaration_node_for_name(fn_name)
22+
if not node:
23+
return None
24+
25+
fn_name = node.name
26+
parameters = []
27+
28+
fn_label = node.node_source_code.split(":\n")[0].removeprefix("def ")
29+
30+
for arg in node.args.args:
31+
start_index = fn_label.find(arg.arg)
32+
end_index = start_index + len(arg.arg)
33+
parameters.append(
34+
ParameterInformation(label=(start_index, end_index), documentation=None)
35+
)
36+
active_parameter = current_line.split("(")[-1].count(",")
37+
return SignatureHelp(
38+
signatures=[
39+
SignatureInformation(
40+
label=fn_label,
41+
parameters=parameters,
42+
documentation=None,
43+
active_parameter=active_parameter or 0,
44+
)
45+
],
46+
active_signature=0,
47+
)
48+
49+
def _handle_imported_fn_signature(
50+
self, current_line: str, module: str, fn_name: str
51+
) -> Optional[SignatureHelp]:
52+
if module in self.ast.imports:
53+
if fn := self.ast.imports[module].functions[fn_name]:
54+
logger.info(f"getting signature for {fn_name}")
55+
logger.info(fn.decl_node)
56+
node: FunctionDef = fn.decl_node
57+
label = node.node_source_code.split("def ")[1].split(":\n")[0]
58+
parameters = []
59+
for arg in node.args.args:
60+
parameters.append(
61+
ParameterInformation(label=arg.arg, documentation=None)
62+
)
63+
active_parameter = current_line.split("(")[-1].count(",")
64+
return SignatureHelp(
65+
signatures=[
66+
SignatureInformation(
67+
label=label,
68+
parameters=parameters,
69+
documentation=None,
70+
active_parameter=active_parameter or 0,
71+
)
72+
],
73+
active_signature=0,
74+
)
75+
76+
def signature_help(
77+
self, doc: Document, params: SignatureHelpParams
78+
) -> Optional[SignatureHelp]:
79+
# TODO: Implement checking external functions, module functions, and interfaces
80+
current_line = doc.lines[params.position.line]
81+
expression = get_expression_at_cursor(
82+
current_line, params.position.character - 1
83+
)
84+
parsed = utils.parse_fncall_expression(expression)
85+
if parsed is None:
86+
return None
87+
module, fn_name = parsed
88+
89+
# this returns for all external functions
90+
if module == "self":
91+
return self._handle_internal_fn_signature(current_line, fn_name)
92+
else:
93+
return self._handle_imported_fn_signature(current_line, module, fn_name)

vyper_lsp/main.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
from packaging.version import Version
3232
from pygls.server import LanguageServer
3333
from vyper_lsp.analyzer.AstAnalyzer import AstAnalyzer
34+
from vyper_lsp.handlers.signatures import SignatureHandler
3435
from vyper_lsp.analyzer.SourceAnalyzer import SourceAnalyzer
3536
from vyper_lsp.debounce import Debouncer
3637

@@ -53,6 +54,7 @@
5354
completer = ast_analyzer
5455
source_analyzer = SourceAnalyzer()
5556

57+
signature_handler = SignatureHandler(ast)
5658

5759
debouncer = Debouncer(wait=0.5)
5860

@@ -152,7 +154,7 @@ def hover(ls: LanguageServer, params: HoverParams):
152154
)
153155
def signature_help(ls: LanguageServer, params: SignatureHelpParams):
154156
document = ls.workspace.get_text_document(params.text_document.uri)
155-
signature_info = ast_analyzer.signature_help(document, params)
157+
signature_info = signature_handler.signature_help(document, params)
156158
if signature_info:
157159
return signature_info
158160

0 commit comments

Comments
 (0)