Skip to content

Commit 20ad506

Browse files
committed
added support for model validation in Pysa VSCode Plugin
1 parent e5b2b74 commit 20ad506

File tree

1 file changed

+51
-0
lines changed

1 file changed

+51
-0
lines changed

client/commands/v2/pysa_server.py

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
version of persistent.py.
1010
"""
1111

12+
from pathlib import Path
1213
import asyncio
1314
import logging
1415

@@ -32,6 +33,9 @@
3233
InitializationSuccess,
3334
InitializationFailure,
3435
)
36+
from api import query, connection as api_connection
37+
from api.connection import PyreQueryError
38+
from typing import List, Sequence, Dict
3539

3640
LOG: logging.Logger = logging.getLogger(__name__)
3741

@@ -60,6 +64,51 @@ def __init__(
6064
self.binary_location = binary_location
6165
self.server_identifier = server_identifier
6266

67+
def invalid_model_to_diagnostic(
68+
self,
69+
invalid_model: query.InvalidModel,
70+
) -> lsp.Diagnostic:
71+
return lsp.Diagnostic(
72+
range=lsp.Range(
73+
start=lsp.Position(
74+
line=invalid_model.line - 1, character=invalid_model.column
75+
),
76+
end=lsp.Position(
77+
line=invalid_model.stop_line - 1,
78+
character=invalid_model.stop_column,
79+
),
80+
),
81+
message=invalid_model.full_error_message,
82+
severity=lsp.DiagnosticSeverity.ERROR,
83+
code=None,
84+
source="Pysa",
85+
)
86+
87+
def invalid_models_to_diagnostics(
88+
self,
89+
invalid_models: Sequence[query.InvalidModel],
90+
) -> Dict[Path, List[lsp.Diagnostic]]:
91+
result: Dict[Path, List[lsp.Diagnostic]] = {}
92+
for model in invalid_models:
93+
result.setdefault(Path(model.path), []).append(
94+
self.invalid_model_to_diagnostic(model)
95+
)
96+
return result
97+
98+
async def update_errors(self, document_path) -> None:
99+
await _publish_diagnostics(self.output_channel, document_path, [])
100+
pyre_connection = api_connection.PyreConnection(
101+
Path(self.pyre_arguments.global_root)
102+
)
103+
try:
104+
model_errors = query.get_invalid_taint_models(pyre_connection)
105+
diagnostics = self.invalid_models_to_diagnostics(model_errors)
106+
await self.show_model_errors_to_client(diagnostics)
107+
except PyreQueryError as e:
108+
await self.log_and_show_message_to_client(
109+
f"Error querying Pyre: {e}", lsp.MessageType.WARNING
110+
)
111+
63112
async def show_message_to_client(
64113
self, message: str, level: lsp.MessageType = lsp.MessageType.INFO
65114
) -> None:
@@ -106,6 +155,7 @@ async def process_open_request(
106155
raise json_rpc.InvalidRequestError(
107156
f"Document URI is not a file: {parameters.text_document.uri}"
108157
)
158+
await self.update_errors(document_path)
109159

110160
async def process_close_request(
111161
self, parameters: lsp.DidCloseTextDocumentParameters
@@ -129,6 +179,7 @@ async def process_did_save_request(
129179
raise json_rpc.InvalidRequestError(
130180
f"Document URI is not a file: {parameters.text_document.uri}"
131181
)
182+
await self.update_errors(document_path)
132183

133184
async def run(self) -> int:
134185
while True:

0 commit comments

Comments
 (0)