From 6c72b5d46bf953684c321c7f2018f9e915522b95 Mon Sep 17 00:00:00 2001 From: Sarthak Khattar Date: Fri, 16 Apr 2021 23:56:14 +0530 Subject: [PATCH 01/31] added rough code for model validation for .pysa files --- client/commands/v2/persistent.py | 1 + 1 file changed, 1 insertion(+) diff --git a/client/commands/v2/persistent.py b/client/commands/v2/persistent.py index 0a1fc5f6bdb..1fd2e933a3f 100644 --- a/client/commands/v2/persistent.py +++ b/client/commands/v2/persistent.py @@ -34,6 +34,7 @@ incremental, server_event, ) +from api import query LOG: logging.Logger = logging.getLogger(__name__) From 0ce48d273555d3e9e117c9b73cab2eab1349d076 Mon Sep 17 00:00:00 2001 From: Sarthak Khattar Date: Sat, 17 Apr 2021 00:01:15 +0530 Subject: [PATCH 02/31] untrack documentation files --- .../pysa_tutorial/exercise2/views.py | 32 ------------------- 1 file changed, 32 deletions(-) delete mode 100644 documentation/pysa_tutorial/exercise2/views.py diff --git a/documentation/pysa_tutorial/exercise2/views.py b/documentation/pysa_tutorial/exercise2/views.py deleted file mode 100644 index a722dc273aa..00000000000 --- a/documentation/pysa_tutorial/exercise2/views.py +++ /dev/null @@ -1,32 +0,0 @@ -# Copyright (c) Facebook, Inc. and its affiliates. -# -# This source code is licensed under the MIT license found in the -# LICENSE file in the root directory of this source tree. - -import subprocess - -from django.http import HttpRequest, HttpResponse - - -def operate_on_twos(request: HttpRequest) -> HttpResponse: - operator = request.POST["operator"] - - result = eval(f"2 {operator} 2") # noqa: P204 - - return result - - -def operate_on_threes(request: HttpRequest) -> HttpResponse: - operator = request.GET["operator"] - - exec(f"result = 3 {operator} 3") - - return result # noqa: F821 - - -def operate_on_fours(request: HttpRequest) -> HttpResponse: - operator = request.GET["operator"] - - result = subprocess.getoutput(f"expr 4 {operator} 4") - - return result From ea2b235835772f97c5f5b512db7b221d17e11996 Mon Sep 17 00:00:00 2001 From: Sarthak Khattar Date: Mon, 3 May 2021 19:52:00 +0530 Subject: [PATCH 03/31] hardcoded path value for testing publishing diagnostics --- client/commands/v2/pysa_server.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/client/commands/v2/pysa_server.py b/client/commands/v2/pysa_server.py index f610e0f15fc..3d75ed75095 100644 --- a/client/commands/v2/pysa_server.py +++ b/client/commands/v2/pysa_server.py @@ -101,6 +101,7 @@ async def wait_for_exit(self) -> int: async def process_open_request( self, parameters: lsp.DidOpenTextDocumentParameters ) -> None: + print("A document was just opened!") document_path = parameters.text_document.document_uri().to_file_path() if document_path is None: raise json_rpc.InvalidRequestError( @@ -110,6 +111,7 @@ async def process_open_request( async def process_close_request( self, parameters: lsp.DidCloseTextDocumentParameters ) -> None: + print("A document was just closed!") document_path = parameters.text_document.document_uri().to_file_path() if document_path is None: raise json_rpc.InvalidRequestError( @@ -124,6 +126,7 @@ async def process_close_request( async def process_did_save_request( self, parameters: lsp.DidSaveTextDocumentParameters ) -> None: + print("A document was just saved!") document_path = parameters.text_document.document_uri().to_file_path() if document_path is None: raise json_rpc.InvalidRequestError( From a09ff0bb1134bbf67e7dff26864f71c88e75f019 Mon Sep 17 00:00:00 2001 From: Sarthak Khattar Date: Mon, 17 May 2021 22:09:34 +0530 Subject: [PATCH 04/31] fixed errors highlighted one line below, fixed .pysa files not being tracked by the server --- client/commands/v2/persistent.py | 4 +++ client/commands/v2/pysa_server.py | 11 +++++-- .../pysa_tutorial/exercise2/views.py | 30 +++++++++++++++++++ 3 files changed, 42 insertions(+), 3 deletions(-) create mode 100644 documentation/pysa_tutorial/exercise2/views.py diff --git a/client/commands/v2/persistent.py b/client/commands/v2/persistent.py index 1fd2e933a3f..5914c301570 100644 --- a/client/commands/v2/persistent.py +++ b/client/commands/v2/persistent.py @@ -196,10 +196,14 @@ async def try_initialize( async def _read_lsp_request( input_channel: connection.TextReader, output_channel: connection.TextWriter ) -> AsyncIterator[json_rpc.Request]: + LOG.info("** Inside the read lsp function ** ") try: + LOG.info("** Inside the try and except ** ") message = await lsp.read_json_rpc(input_channel) + LOG.info(f"** {message} **") yield message except json_rpc.JSONRPCException as json_rpc_error: + LOG.info("** Inside the except ** ") await lsp.write_json_rpc( output_channel, json_rpc.ErrorResponse( diff --git a/client/commands/v2/pysa_server.py b/client/commands/v2/pysa_server.py index 3d75ed75095..d42024b6463 100644 --- a/client/commands/v2/pysa_server.py +++ b/client/commands/v2/pysa_server.py @@ -101,7 +101,7 @@ async def wait_for_exit(self) -> int: async def process_open_request( self, parameters: lsp.DidOpenTextDocumentParameters ) -> None: - print("A document was just opened!") + LOG.info("** Inside process_open_request() **") document_path = parameters.text_document.document_uri().to_file_path() if document_path is None: raise json_rpc.InvalidRequestError( @@ -111,7 +111,7 @@ async def process_open_request( async def process_close_request( self, parameters: lsp.DidCloseTextDocumentParameters ) -> None: - print("A document was just closed!") + LOG.info("** Inside process_close_request() **") document_path = parameters.text_document.document_uri().to_file_path() if document_path is None: raise json_rpc.InvalidRequestError( @@ -126,7 +126,7 @@ async def process_close_request( async def process_did_save_request( self, parameters: lsp.DidSaveTextDocumentParameters ) -> None: - print("A document was just saved!") + LOG.info("** Inside process_did_save_request() **") document_path = parameters.text_document.document_uri().to_file_path() if document_path is None: raise json_rpc.InvalidRequestError( @@ -148,6 +148,7 @@ async def run(self) -> int: ) return await self.wait_for_exit() elif request.method == "textDocument/didOpen": + LOG.info("** A Document just opened! **") parameters = request.parameters if parameters is None: raise json_rpc.InvalidRequestError( @@ -159,6 +160,7 @@ async def run(self) -> int: ) ) elif request.method == "textDocument/didClose": + LOG.info("** A Document just closed! **") parameters = request.parameters if parameters is None: raise json_rpc.InvalidRequestError( @@ -170,6 +172,7 @@ async def run(self) -> int: ) ) elif request.method == "textDocument/didSave": + LOG.info("** A Document just saved! **") parameters = request.parameters if parameters is None: raise json_rpc.InvalidRequestError( @@ -182,6 +185,8 @@ async def run(self) -> int: ) elif request.id is not None: raise lsp.RequestCancelledError("Request not supported yet") + else: + LOG.info("** Hmmm I guess nothing seems to be happening **") async def run_persistent( diff --git a/documentation/pysa_tutorial/exercise2/views.py b/documentation/pysa_tutorial/exercise2/views.py new file mode 100644 index 00000000000..0503581725e --- /dev/null +++ b/documentation/pysa_tutorial/exercise2/views.py @@ -0,0 +1,30 @@ +# Copyright (c) Facebook, Inc. and its affiliates. +# +# This source code is licensed under the MIT license found in the +# LICENSE file in the root directory of this source tree. + +import subprocess + +from django.http import HttpRequest, HttpResponse + +def operate_on_twos(request: HttpRequest) -> HttpResponse: + operator = request.POST["operator"] + + result = eval(f"2 {operator} 2") # noqa: P204 + + return result + + +def operate_on_threes(request: HttpRequest) -> HttpResponse: + operator = request.GET["operator"] + + exec(f"result = 3 {operator} 3") + + return result # noqa: F82 1 + +def operate_on_fours(request: HttpRequest) -> HttpResponse: + operator = request.GET["operator"] + + result = subprocess.getoutput(f"expr 4 {operator} 4") + + return result From 6c3b0b59bf998ec563ecca987c37315cfb7b097d Mon Sep 17 00:00:00 2001 From: Sarthak Khattar Date: Tue, 18 May 2021 22:34:55 +0530 Subject: [PATCH 05/31] fixed error validation only working at startup --- client/commands/v2/persistent.py | 8 ++++---- client/commands/v2/pysa_server.py | 17 +++++++++-------- 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/client/commands/v2/persistent.py b/client/commands/v2/persistent.py index 5914c301570..6bceeddc069 100644 --- a/client/commands/v2/persistent.py +++ b/client/commands/v2/persistent.py @@ -196,14 +196,14 @@ async def try_initialize( async def _read_lsp_request( input_channel: connection.TextReader, output_channel: connection.TextWriter ) -> AsyncIterator[json_rpc.Request]: - LOG.info("** Inside the read lsp function ** ") + # LOG.info("** Inside the read lsp function ** ") try: - LOG.info("** Inside the try and except ** ") + # LOG.info("** Inside the try and except ** ") message = await lsp.read_json_rpc(input_channel) - LOG.info(f"** {message} **") + # LOG.info(f"** {message} **") yield message except json_rpc.JSONRPCException as json_rpc_error: - LOG.info("** Inside the except ** ") + # LOG.info("** Inside the except ** ") await lsp.write_json_rpc( output_channel, json_rpc.ErrorResponse( diff --git a/client/commands/v2/pysa_server.py b/client/commands/v2/pysa_server.py index d42024b6463..72533eee370 100644 --- a/client/commands/v2/pysa_server.py +++ b/client/commands/v2/pysa_server.py @@ -35,6 +35,8 @@ LOG: logging.Logger = logging.getLogger(__name__) +PYSA_HANDLER_OBJ = None + class PysaServer: # I/O Channels @@ -101,7 +103,7 @@ async def wait_for_exit(self) -> int: async def process_open_request( self, parameters: lsp.DidOpenTextDocumentParameters ) -> None: - LOG.info("** Inside process_open_request() **") + # LOG.info("** Inside process_open_request() **") document_path = parameters.text_document.document_uri().to_file_path() if document_path is None: raise json_rpc.InvalidRequestError( @@ -111,7 +113,7 @@ async def process_open_request( async def process_close_request( self, parameters: lsp.DidCloseTextDocumentParameters ) -> None: - LOG.info("** Inside process_close_request() **") + # LOG.info("** Inside process_close_request() **") document_path = parameters.text_document.document_uri().to_file_path() if document_path is None: raise json_rpc.InvalidRequestError( @@ -126,7 +128,7 @@ async def process_close_request( async def process_did_save_request( self, parameters: lsp.DidSaveTextDocumentParameters ) -> None: - LOG.info("** Inside process_did_save_request() **") + # LOG.info("** Inside process_did_save_request() **") document_path = parameters.text_document.document_uri().to_file_path() if document_path is None: raise json_rpc.InvalidRequestError( @@ -148,7 +150,7 @@ async def run(self) -> int: ) return await self.wait_for_exit() elif request.method == "textDocument/didOpen": - LOG.info("** A Document just opened! **") + # LOG.info("** A Document just opened! **") parameters = request.parameters if parameters is None: raise json_rpc.InvalidRequestError( @@ -160,7 +162,7 @@ async def run(self) -> int: ) ) elif request.method == "textDocument/didClose": - LOG.info("** A Document just closed! **") + # LOG.info("** A Document just closed! **") parameters = request.parameters if parameters is None: raise json_rpc.InvalidRequestError( @@ -172,7 +174,7 @@ async def run(self) -> int: ) ) elif request.method == "textDocument/didSave": - LOG.info("** A Document just saved! **") + # LOG.info("** A Document just saved! **") parameters = request.parameters if parameters is None: raise json_rpc.InvalidRequestError( @@ -185,13 +187,12 @@ async def run(self) -> int: ) elif request.id is not None: raise lsp.RequestCancelledError("Request not supported yet") - else: - LOG.info("** Hmmm I guess nothing seems to be happening **") async def run_persistent( binary_location: str, server_identifier: str, pysa_arguments: start.Arguments ) -> int: + global PYSA_HANDLER_OBJ stdin, stdout = await connection.create_async_stdin_stdout() while True: initialize_result = await try_initialize(stdin, stdout) From fa008b74f272f77aa8279a160ead66b68ffacd52 Mon Sep 17 00:00:00 2001 From: Sarthak Khattar Date: Tue, 18 May 2021 22:42:27 +0530 Subject: [PATCH 06/31] fixed formatting for example files --- documentation/pysa_tutorial/exercise2/views.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/documentation/pysa_tutorial/exercise2/views.py b/documentation/pysa_tutorial/exercise2/views.py index 0503581725e..9418aab978f 100644 --- a/documentation/pysa_tutorial/exercise2/views.py +++ b/documentation/pysa_tutorial/exercise2/views.py @@ -7,6 +7,7 @@ from django.http import HttpRequest, HttpResponse + def operate_on_twos(request: HttpRequest) -> HttpResponse: operator = request.POST["operator"] @@ -19,9 +20,10 @@ def operate_on_threes(request: HttpRequest) -> HttpResponse: operator = request.GET["operator"] exec(f"result = 3 {operator} 3") - + return result # noqa: F82 1 + def operate_on_fours(request: HttpRequest) -> HttpResponse: operator = request.GET["operator"] From 3d282e8a9b85aa5f24d79b54a7de0ab69abd0d2a Mon Sep 17 00:00:00 2001 From: Sarthak Khattar Date: Tue, 18 May 2021 22:55:05 +0530 Subject: [PATCH 07/31] fixed function arguments not conforming to enforced typing --- client/commands/v2/pysa_server.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/commands/v2/pysa_server.py b/client/commands/v2/pysa_server.py index 72533eee370..0821ef82fa9 100644 --- a/client/commands/v2/pysa_server.py +++ b/client/commands/v2/pysa_server.py @@ -35,7 +35,7 @@ LOG: logging.Logger = logging.getLogger(__name__) -PYSA_HANDLER_OBJ = None +PYSA_HANDLER_OBJ: None class PysaServer: From b5d9268adacef1ddae5d455d3c3729fcf82f3e1f Mon Sep 17 00:00:00 2001 From: Sarthak Khattar Date: Mon, 24 May 2021 16:50:27 +0530 Subject: [PATCH 08/31] removed PysaServerHandler, refactored things into PysaServer class --- client/commands/v2/pysa_server.py | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/client/commands/v2/pysa_server.py b/client/commands/v2/pysa_server.py index 0821ef82fa9..4ac5dfbaab0 100644 --- a/client/commands/v2/pysa_server.py +++ b/client/commands/v2/pysa_server.py @@ -35,8 +35,6 @@ LOG: logging.Logger = logging.getLogger(__name__) -PYSA_HANDLER_OBJ: None - class PysaServer: # I/O Channels @@ -103,7 +101,6 @@ async def wait_for_exit(self) -> int: async def process_open_request( self, parameters: lsp.DidOpenTextDocumentParameters ) -> None: - # LOG.info("** Inside process_open_request() **") document_path = parameters.text_document.document_uri().to_file_path() if document_path is None: raise json_rpc.InvalidRequestError( @@ -113,7 +110,6 @@ async def process_open_request( async def process_close_request( self, parameters: lsp.DidCloseTextDocumentParameters ) -> None: - # LOG.info("** Inside process_close_request() **") document_path = parameters.text_document.document_uri().to_file_path() if document_path is None: raise json_rpc.InvalidRequestError( @@ -128,7 +124,6 @@ async def process_close_request( async def process_did_save_request( self, parameters: lsp.DidSaveTextDocumentParameters ) -> None: - # LOG.info("** Inside process_did_save_request() **") document_path = parameters.text_document.document_uri().to_file_path() if document_path is None: raise json_rpc.InvalidRequestError( @@ -150,7 +145,6 @@ async def run(self) -> int: ) return await self.wait_for_exit() elif request.method == "textDocument/didOpen": - # LOG.info("** A Document just opened! **") parameters = request.parameters if parameters is None: raise json_rpc.InvalidRequestError( @@ -162,7 +156,6 @@ async def run(self) -> int: ) ) elif request.method == "textDocument/didClose": - # LOG.info("** A Document just closed! **") parameters = request.parameters if parameters is None: raise json_rpc.InvalidRequestError( @@ -174,7 +167,6 @@ async def run(self) -> int: ) ) elif request.method == "textDocument/didSave": - # LOG.info("** A Document just saved! **") parameters = request.parameters if parameters is None: raise json_rpc.InvalidRequestError( @@ -192,7 +184,6 @@ async def run(self) -> int: async def run_persistent( binary_location: str, server_identifier: str, pysa_arguments: start.Arguments ) -> int: - global PYSA_HANDLER_OBJ stdin, stdout = await connection.create_async_stdin_stdout() while True: initialize_result = await try_initialize(stdin, stdout) @@ -225,7 +216,7 @@ async def run_persistent( server_identifier=server_identifier, pyre_arguments=pysa_arguments, ) - return await server.run() + return await server._run() elif isinstance(initialize_result, InitializationFailure): exception = initialize_result.exception message = ( From da094da2b3eacf10aa8bcd6d8582b2cfd3a94731 Mon Sep 17 00:00:00 2001 From: Sarthak Khattar Date: Mon, 24 May 2021 17:39:04 +0530 Subject: [PATCH 09/31] removed debug statements, fixed formatting --- client/commands/v2/persistent.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/client/commands/v2/persistent.py b/client/commands/v2/persistent.py index 6bceeddc069..1fd2e933a3f 100644 --- a/client/commands/v2/persistent.py +++ b/client/commands/v2/persistent.py @@ -196,14 +196,10 @@ async def try_initialize( async def _read_lsp_request( input_channel: connection.TextReader, output_channel: connection.TextWriter ) -> AsyncIterator[json_rpc.Request]: - # LOG.info("** Inside the read lsp function ** ") try: - # LOG.info("** Inside the try and except ** ") message = await lsp.read_json_rpc(input_channel) - # LOG.info(f"** {message} **") yield message except json_rpc.JSONRPCException as json_rpc_error: - # LOG.info("** Inside the except ** ") await lsp.write_json_rpc( output_channel, json_rpc.ErrorResponse( From b1e22b50d0073e81e7694168f989c9a3813c2798 Mon Sep 17 00:00:00 2001 From: Sarthak Khattar Date: Sat, 29 May 2021 15:35:41 +0530 Subject: [PATCH 10/31] added try catch for Pyre Parsing errors --- client/commands/v2/pysa_server.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/client/commands/v2/pysa_server.py b/client/commands/v2/pysa_server.py index 4ac5dfbaab0..b6a5d93e682 100644 --- a/client/commands/v2/pysa_server.py +++ b/client/commands/v2/pysa_server.py @@ -32,6 +32,8 @@ InitializationSuccess, InitializationFailure, ) +from api import query, connection as api_connection +from api.connection import PyreQueryError LOG: logging.Logger = logging.getLogger(__name__) @@ -60,6 +62,17 @@ def __init__( self.binary_location = binary_location self.server_identifier = server_identifier + async def update_errors(self) -> None: + pyre_connection = api_connection.PyreConnection( + Path(self.pyre_arguments.global_root) + ) + try: + model_errors = query.get_invalid_taint_models(pyre_connection) + diagnostics = invalid_models_to_diagnostics(model_errors) + await self.show_model_errors_to_client(diagnostics) + except PyreQueryError as e: + await self.log_and_show_message_to_client(f"Error querying Pyre: {e}", lsp.MessageType.WARNING) + async def show_message_to_client( self, message: str, level: lsp.MessageType = lsp.MessageType.INFO ) -> None: From 79dc1302014d4318d20a1e208858564937b45247 Mon Sep 17 00:00:00 2001 From: Sarthak Khattar Date: Sat, 29 May 2021 16:22:00 +0530 Subject: [PATCH 11/31] minor refactoring, minor fixes --- client/commands/v2/pysa_server.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/client/commands/v2/pysa_server.py b/client/commands/v2/pysa_server.py index b6a5d93e682..79934d1a26b 100644 --- a/client/commands/v2/pysa_server.py +++ b/client/commands/v2/pysa_server.py @@ -62,7 +62,8 @@ def __init__( self.binary_location = binary_location self.server_identifier = server_identifier - async def update_errors(self) -> None: + async def update_errors(self, document_path) -> None: + await _publish_diagnostics(self.output_channel, document_path, []) pyre_connection = api_connection.PyreConnection( Path(self.pyre_arguments.global_root) ) @@ -120,6 +121,8 @@ async def process_open_request( f"Document URI is not a file: {parameters.text_document.uri}" ) + await self.update_errors(document_path) + async def process_close_request( self, parameters: lsp.DidCloseTextDocumentParameters ) -> None: @@ -142,6 +145,7 @@ async def process_did_save_request( raise json_rpc.InvalidRequestError( f"Document URI is not a file: {parameters.text_document.uri}" ) + await self.update_errors(document_path) async def run(self) -> int: while True: From d63f8f5944f28f394461d31ddeb45e2605c0ac90 Mon Sep 17 00:00:00 2001 From: Sarthak Khattar Date: Sat, 29 May 2021 16:51:11 +0530 Subject: [PATCH 12/31] undo changes in exercises --- documentation/pysa_tutorial/exercise2/.pyre_configuration | 3 +-- documentation/pysa_tutorial/exercise2/views.py | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/documentation/pysa_tutorial/exercise2/.pyre_configuration b/documentation/pysa_tutorial/exercise2/.pyre_configuration index 16e31f60381..1241b858a1a 100644 --- a/documentation/pysa_tutorial/exercise2/.pyre_configuration +++ b/documentation/pysa_tutorial/exercise2/.pyre_configuration @@ -10,6 +10,5 @@ ], "exclude": [ ".*/integration_test/.*" - ], - "use_command_v2": true + ] } diff --git a/documentation/pysa_tutorial/exercise2/views.py b/documentation/pysa_tutorial/exercise2/views.py index 9418aab978f..a722dc273aa 100644 --- a/documentation/pysa_tutorial/exercise2/views.py +++ b/documentation/pysa_tutorial/exercise2/views.py @@ -21,7 +21,7 @@ def operate_on_threes(request: HttpRequest) -> HttpResponse: exec(f"result = 3 {operator} 3") - return result # noqa: F82 1 + return result # noqa: F821 def operate_on_fours(request: HttpRequest) -> HttpResponse: From c001ebb90edc1eb480cb66acf25dc9bdc2b4143e Mon Sep 17 00:00:00 2001 From: Sarthak Khattar Date: Sat, 29 May 2021 17:13:11 +0530 Subject: [PATCH 13/31] undo pysa specific changes back to refactor only --- client/commands/v2/persistent.py | 1 - client/commands/v2/pysa_server.py | 19 +------------------ 2 files changed, 1 insertion(+), 19 deletions(-) diff --git a/client/commands/v2/persistent.py b/client/commands/v2/persistent.py index 1fd2e933a3f..0a1fc5f6bdb 100644 --- a/client/commands/v2/persistent.py +++ b/client/commands/v2/persistent.py @@ -34,7 +34,6 @@ incremental, server_event, ) -from api import query LOG: logging.Logger = logging.getLogger(__name__) diff --git a/client/commands/v2/pysa_server.py b/client/commands/v2/pysa_server.py index 79934d1a26b..f610e0f15fc 100644 --- a/client/commands/v2/pysa_server.py +++ b/client/commands/v2/pysa_server.py @@ -32,8 +32,6 @@ InitializationSuccess, InitializationFailure, ) -from api import query, connection as api_connection -from api.connection import PyreQueryError LOG: logging.Logger = logging.getLogger(__name__) @@ -62,18 +60,6 @@ def __init__( self.binary_location = binary_location self.server_identifier = server_identifier - async def update_errors(self, document_path) -> None: - await _publish_diagnostics(self.output_channel, document_path, []) - pyre_connection = api_connection.PyreConnection( - Path(self.pyre_arguments.global_root) - ) - try: - model_errors = query.get_invalid_taint_models(pyre_connection) - diagnostics = invalid_models_to_diagnostics(model_errors) - await self.show_model_errors_to_client(diagnostics) - except PyreQueryError as e: - await self.log_and_show_message_to_client(f"Error querying Pyre: {e}", lsp.MessageType.WARNING) - async def show_message_to_client( self, message: str, level: lsp.MessageType = lsp.MessageType.INFO ) -> None: @@ -121,8 +107,6 @@ async def process_open_request( f"Document URI is not a file: {parameters.text_document.uri}" ) - await self.update_errors(document_path) - async def process_close_request( self, parameters: lsp.DidCloseTextDocumentParameters ) -> None: @@ -145,7 +129,6 @@ async def process_did_save_request( raise json_rpc.InvalidRequestError( f"Document URI is not a file: {parameters.text_document.uri}" ) - await self.update_errors(document_path) async def run(self) -> int: while True: @@ -233,7 +216,7 @@ async def run_persistent( server_identifier=server_identifier, pyre_arguments=pysa_arguments, ) - return await server._run() + return await server.run() elif isinstance(initialize_result, InitializationFailure): exception = initialize_result.exception message = ( From 10b76f322675bea9a7426a8ed76be5e8b36c5d8d Mon Sep 17 00:00:00 2001 From: Sarthak Khattar Date: Sat, 29 May 2021 18:58:47 +0530 Subject: [PATCH 14/31] added support for model validation in Pysa VSCode Plugin --- client/commands/v2/pysa_server.py | 51 +++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/client/commands/v2/pysa_server.py b/client/commands/v2/pysa_server.py index f610e0f15fc..8ecf877be8c 100644 --- a/client/commands/v2/pysa_server.py +++ b/client/commands/v2/pysa_server.py @@ -9,6 +9,7 @@ version of persistent.py. """ +from pathlib import Path import asyncio import logging @@ -32,6 +33,9 @@ InitializationSuccess, InitializationFailure, ) +from api import query, connection as api_connection +from api.connection import PyreQueryError +from typing import List, Sequence, Dict LOG: logging.Logger = logging.getLogger(__name__) @@ -60,6 +64,51 @@ def __init__( self.binary_location = binary_location self.server_identifier = server_identifier + def invalid_model_to_diagnostic( + self, + invalid_model: query.InvalidModel, + ) -> lsp.Diagnostic: + return lsp.Diagnostic( + range=lsp.Range( + start=lsp.Position( + line=invalid_model.line - 1, character=invalid_model.column + ), + end=lsp.Position( + line=invalid_model.stop_line - 1, + character=invalid_model.stop_column, + ), + ), + message=invalid_model.full_error_message, + severity=lsp.DiagnosticSeverity.ERROR, + code=None, + source="Pysa", + ) + + def invalid_models_to_diagnostics( + self, + invalid_models: Sequence[query.InvalidModel], + ) -> Dict[Path, List[lsp.Diagnostic]]: + result: Dict[Path, List[lsp.Diagnostic]] = {} + for model in invalid_models: + result.setdefault(Path(model.path), []).append( + self.invalid_model_to_diagnostic(model) + ) + return result + + async def update_errors(self, document_path) -> None: + await _publish_diagnostics(self.output_channel, document_path, []) + pyre_connection = api_connection.PyreConnection( + Path(self.pyre_arguments.global_root) + ) + try: + model_errors = query.get_invalid_taint_models(pyre_connection) + diagnostics = self.invalid_models_to_diagnostics(model_errors) + await self.show_model_errors_to_client(diagnostics) + except PyreQueryError as e: + await self.log_and_show_message_to_client( + f"Error querying Pyre: {e}", lsp.MessageType.WARNING + ) + async def show_message_to_client( self, message: str, level: lsp.MessageType = lsp.MessageType.INFO ) -> None: @@ -106,6 +155,7 @@ async def process_open_request( raise json_rpc.InvalidRequestError( f"Document URI is not a file: {parameters.text_document.uri}" ) + await self.update_errors(document_path) async def process_close_request( self, parameters: lsp.DidCloseTextDocumentParameters @@ -129,6 +179,7 @@ async def process_did_save_request( raise json_rpc.InvalidRequestError( f"Document URI is not a file: {parameters.text_document.uri}" ) + await self.update_errors(document_path) async def run(self) -> int: while True: From 955dd8bd20b8b42cc7e421790f9a1b2e7bbe402c Mon Sep 17 00:00:00 2001 From: Sarthak Khattar Date: Wed, 2 Jun 2021 04:27:41 +0530 Subject: [PATCH 15/31] fixed missing typing for some arguments --- client/commands/v2/pysa_server.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/client/commands/v2/pysa_server.py b/client/commands/v2/pysa_server.py index 8ecf877be8c..6d9e55309f0 100644 --- a/client/commands/v2/pysa_server.py +++ b/client/commands/v2/pysa_server.py @@ -95,7 +95,7 @@ def invalid_models_to_diagnostics( ) return result - async def update_errors(self, document_path) -> None: + async def update_errors(self, document_path: Path) -> None: await _publish_diagnostics(self.output_channel, document_path, []) pyre_connection = api_connection.PyreConnection( Path(self.pyre_arguments.global_root) @@ -135,6 +135,14 @@ async def log_and_show_message_to_client( LOG.debug(message) await self.show_message_to_client(message, level) + async def show_model_errors_to_client( + self, diagnostics: Dict[Path, List[lsp.Diagnostic]] + ) -> None: + for path, diagnostic in diagnostics.items(): + await _publish_diagnostics(self.output_channel, path, []) + if diagnostic is not None: + await _publish_diagnostics(self.output_channel, path, diagnostic) + async def wait_for_exit(self) -> int: while True: async with _read_lsp_request( From 2377ab6466f4331c02db01a8b50f557a7a079737 Mon Sep 17 00:00:00 2001 From: Sarthak Khattar Date: Wed, 9 Jun 2021 22:21:18 +0530 Subject: [PATCH 16/31] rebased with small changes --- client/commands/v2/pysa_server.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/client/commands/v2/pysa_server.py b/client/commands/v2/pysa_server.py index 6d9e55309f0..67e9c6f8d1e 100644 --- a/client/commands/v2/pysa_server.py +++ b/client/commands/v2/pysa_server.py @@ -29,6 +29,7 @@ _read_lsp_request, try_initialize, _log_lsp_event, + _publish_diagnostics, InitializationExit, InitializationSuccess, InitializationFailure, @@ -139,9 +140,7 @@ async def show_model_errors_to_client( self, diagnostics: Dict[Path, List[lsp.Diagnostic]] ) -> None: for path, diagnostic in diagnostics.items(): - await _publish_diagnostics(self.output_channel, path, []) - if diagnostic is not None: - await _publish_diagnostics(self.output_channel, path, diagnostic) + await _publish_diagnostics(self.output_channel, path, diagnostic or []) async def wait_for_exit(self) -> int: while True: From b32d099c4472b715541f4cab8198b584dd95571a Mon Sep 17 00:00:00 2001 From: Sarthak Khattar Date: Wed, 9 Jun 2021 23:23:30 +0530 Subject: [PATCH 17/31] handle path being None --- client/commands/v2/pysa_server.py | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/client/commands/v2/pysa_server.py b/client/commands/v2/pysa_server.py index 67e9c6f8d1e..7f703cbbb4c 100644 --- a/client/commands/v2/pysa_server.py +++ b/client/commands/v2/pysa_server.py @@ -91,9 +91,14 @@ def invalid_models_to_diagnostics( ) -> Dict[Path, List[lsp.Diagnostic]]: result: Dict[Path, List[lsp.Diagnostic]] = {} for model in invalid_models: - result.setdefault(Path(model.path), []).append( - self.invalid_model_to_diagnostic(model) - ) + if model.path is None: + self.log_and_show_message_to_client( + "Path cannot be None", lsp.MessageType.WARNING + ) + else: + result.setdefault(Path(model.path), []).append( + self.invalid_model_to_diagnostic(model) + ) return result async def update_errors(self, document_path: Path) -> None: From 3793e1a5ce6b9e1c055902e8110bc2f32470e718 Mon Sep 17 00:00:00 2001 From: Sarthak Khattar Date: Tue, 13 Jul 2021 21:24:17 +0530 Subject: [PATCH 18/31] changed to relative imports --- client/commands/v2/pysa_server.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/client/commands/v2/pysa_server.py b/client/commands/v2/pysa_server.py index 7f703cbbb4c..82235e98ab2 100644 --- a/client/commands/v2/pysa_server.py +++ b/client/commands/v2/pysa_server.py @@ -9,9 +9,10 @@ version of persistent.py. """ -from pathlib import Path import asyncio import logging +from pathlib import Path +from typing import List, Sequence, Dict from ... import ( json_rpc, @@ -34,9 +35,8 @@ InitializationSuccess, InitializationFailure, ) -from api import query, connection as api_connection -from api.connection import PyreQueryError -from typing import List, Sequence, Dict +from ....api import query, connection as api_connection +from ....api.connection import PyreQueryError LOG: logging.Logger = logging.getLogger(__name__) @@ -102,6 +102,7 @@ def invalid_models_to_diagnostics( return result async def update_errors(self, document_path: Path) -> None: + # Publishing empty diagnostics to clear errors in VSCode await _publish_diagnostics(self.output_channel, document_path, []) pyre_connection = api_connection.PyreConnection( Path(self.pyre_arguments.global_root) From 3f3c5e07b667d7dfaab2072d15083d4b5da37867 Mon Sep 17 00:00:00 2001 From: Sarthak Khattar Date: Mon, 19 Jul 2021 14:00:08 +0530 Subject: [PATCH 19/31] updated error message for None path --- client/commands/v2/pysa_server.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/commands/v2/pysa_server.py b/client/commands/v2/pysa_server.py index 82235e98ab2..9cea5583a50 100644 --- a/client/commands/v2/pysa_server.py +++ b/client/commands/v2/pysa_server.py @@ -93,7 +93,7 @@ def invalid_models_to_diagnostics( for model in invalid_models: if model.path is None: self.log_and_show_message_to_client( - "Path cannot be None", lsp.MessageType.WARNING + f"{model.full_error_message}", lsp.MessageType.WARNING ) else: result.setdefault(Path(model.path), []).append( From 1357024a6ed54d0fa12a4b2e080819b04b88c18b Mon Sep 17 00:00:00 2001 From: Sarthak Khattar Date: Mon, 19 Jul 2021 14:06:55 +0530 Subject: [PATCH 20/31] undo .pyre_configuration changes --- documentation/pysa_tutorial/exercise2/.pyre_configuration | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/documentation/pysa_tutorial/exercise2/.pyre_configuration b/documentation/pysa_tutorial/exercise2/.pyre_configuration index 1241b858a1a..16e31f60381 100644 --- a/documentation/pysa_tutorial/exercise2/.pyre_configuration +++ b/documentation/pysa_tutorial/exercise2/.pyre_configuration @@ -10,5 +10,6 @@ ], "exclude": [ ".*/integration_test/.*" - ] + ], + "use_command_v2": true } From 5114aa2b8d0dc4fdfc5b46ce0c82875e6c702b54 Mon Sep 17 00:00:00 2001 From: Sarthak Khattar Date: Tue, 20 Jul 2021 13:35:00 +0530 Subject: [PATCH 21/31] misc fixes --- client/commands/v2/pysa_server.py | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/client/commands/v2/pysa_server.py b/client/commands/v2/pysa_server.py index 9cea5583a50..58206945c60 100644 --- a/client/commands/v2/pysa_server.py +++ b/client/commands/v2/pysa_server.py @@ -12,6 +12,7 @@ import asyncio import logging from pathlib import Path +from collections import defaultdict from typing import List, Sequence, Dict from ... import ( @@ -64,6 +65,9 @@ def __init__( self.pyre_arguments = pyre_arguments self.binary_location = binary_location self.server_identifier = server_identifier + self.pyre_connection = api_connection.PyreConnection( + Path(self.pyre_arguments.global_root) + ) def invalid_model_to_diagnostic( self, @@ -89,26 +93,22 @@ def invalid_models_to_diagnostics( self, invalid_models: Sequence[query.InvalidModel], ) -> Dict[Path, List[lsp.Diagnostic]]: - result: Dict[Path, List[lsp.Diagnostic]] = {} + result: Dict[Path, List[lsp.Diagnostic]] = defaultdict(list) for model in invalid_models: if model.path is None: self.log_and_show_message_to_client( - f"{model.full_error_message}", lsp.MessageType.WARNING + f"{model.full_error_message}", lsp.MessageType.ERROR ) else: - result.setdefault(Path(model.path), []).append( - self.invalid_model_to_diagnostic(model) - ) + result[Path(model.path)].append(self.invalid_model_to_diagnostic(model)) return result async def update_errors(self, document_path: Path) -> None: # Publishing empty diagnostics to clear errors in VSCode await _publish_diagnostics(self.output_channel, document_path, []) - pyre_connection = api_connection.PyreConnection( - Path(self.pyre_arguments.global_root) - ) + try: - model_errors = query.get_invalid_taint_models(pyre_connection) + model_errors = query.get_invalid_taint_models(self.pyre_connection) diagnostics = self.invalid_models_to_diagnostics(model_errors) await self.show_model_errors_to_client(diagnostics) except PyreQueryError as e: From 5d3fa1977929cbba49409ecbb55894cbad8b0be2 Mon Sep 17 00:00:00 2001 From: Sarthak Khattar Date: Tue, 10 Aug 2021 15:07:43 +0530 Subject: [PATCH 22/31] fixes in import statements --- client/commands/v2/__init__.py | 2 +- client/commands/v2/pysa_server.py | 5 +++-- client/tests/pyre_test.py | 2 +- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/client/commands/v2/__init__.py b/client/commands/v2/__init__.py index 1bd4307ba48..5126239e74f 100644 --- a/client/commands/v2/__init__.py +++ b/client/commands/v2/__init__.py @@ -13,7 +13,6 @@ from . import kill # noqa F401 from . import persistent # noqa F401 from . import profile # noqa F401 -from . import pysa_server # noqa F401 from . import query # noqa F401 from . import rage # noqa F401 from . import restart # noqa F401 @@ -22,3 +21,4 @@ from . import statistics # noqa F401 from . import stop # noqa F401 from . import validate_models # noqa F401 +from ....client.commands.v2 import pysa_server # noqa F401 diff --git a/client/commands/v2/pysa_server.py b/client/commands/v2/pysa_server.py index 58206945c60..d616a313066 100644 --- a/client/commands/v2/pysa_server.py +++ b/client/commands/v2/pysa_server.py @@ -15,6 +15,9 @@ from collections import defaultdict from typing import List, Sequence, Dict +from ....api import query, connection as api_connection +from ....api.connection import PyreQueryError + from ... import ( json_rpc, command_arguments, @@ -36,8 +39,6 @@ InitializationSuccess, InitializationFailure, ) -from ....api import query, connection as api_connection -from ....api.connection import PyreQueryError LOG: logging.Logger = logging.getLogger(__name__) diff --git a/client/tests/pyre_test.py b/client/tests/pyre_test.py index 79c59775015..97932c439c4 100644 --- a/client/tests/pyre_test.py +++ b/client/tests/pyre_test.py @@ -13,9 +13,9 @@ from .. import ( command_arguments, configuration, - pyre, recently_used_configurations, ) +from ...client import pyre from .setup import ( ensure_directories_exists, switch_working_directory, From 84a37d07916fa56ee2cbb0f10886c7a9449e8cd3 Mon Sep 17 00:00:00 2001 From: Sarthak Khattar Date: Tue, 10 Aug 2021 15:20:09 +0530 Subject: [PATCH 23/31] revert import changes --- client/commands/v2/__init__.py | 2 +- client/tests/pyre_test.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/client/commands/v2/__init__.py b/client/commands/v2/__init__.py index 5126239e74f..1bd4307ba48 100644 --- a/client/commands/v2/__init__.py +++ b/client/commands/v2/__init__.py @@ -13,6 +13,7 @@ from . import kill # noqa F401 from . import persistent # noqa F401 from . import profile # noqa F401 +from . import pysa_server # noqa F401 from . import query # noqa F401 from . import rage # noqa F401 from . import restart # noqa F401 @@ -21,4 +22,3 @@ from . import statistics # noqa F401 from . import stop # noqa F401 from . import validate_models # noqa F401 -from ....client.commands.v2 import pysa_server # noqa F401 diff --git a/client/tests/pyre_test.py b/client/tests/pyre_test.py index 97932c439c4..79c59775015 100644 --- a/client/tests/pyre_test.py +++ b/client/tests/pyre_test.py @@ -13,9 +13,9 @@ from .. import ( command_arguments, configuration, + pyre, recently_used_configurations, ) -from ...client import pyre from .setup import ( ensure_directories_exists, switch_working_directory, From f51ee9720d0271f15ef33d367366191096379b7d Mon Sep 17 00:00:00 2001 From: Sarthak Khattar Date: Tue, 10 Aug 2021 15:29:04 +0530 Subject: [PATCH 24/31] sort imports --- client/commands/v2/pysa_server.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/client/commands/v2/pysa_server.py b/client/commands/v2/pysa_server.py index d616a313066..53bed5e56d8 100644 --- a/client/commands/v2/pysa_server.py +++ b/client/commands/v2/pysa_server.py @@ -11,13 +11,12 @@ import asyncio import logging -from pathlib import Path from collections import defaultdict +from pathlib import Path from typing import List, Sequence, Dict from ....api import query, connection as api_connection from ....api.connection import PyreQueryError - from ... import ( json_rpc, command_arguments, From 917f9315b3d9664f41cd443b5b6b804ec799b055 Mon Sep 17 00:00:00 2001 From: Sarthak Khattar Date: Tue, 10 Aug 2021 15:29:18 +0530 Subject: [PATCH 25/31] import changes --- client/commands/v2/__init__.py | 3 +-- client/tests/pyre_test.py | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/client/commands/v2/__init__.py b/client/commands/v2/__init__.py index 1bd4307ba48..c4cca2275d1 100644 --- a/client/commands/v2/__init__.py +++ b/client/commands/v2/__init__.py @@ -3,7 +3,7 @@ # This source code is licensed under the MIT license found in the # LICENSE file in the root directory of this source tree. -from . import analyze # noqa F401 +from ..v2 import pysa_server # noqa F401 from . import backend_arguments # noqa F401 from . import check # noqa F401 from . import coverage # noqa F401 @@ -13,7 +13,6 @@ from . import kill # noqa F401 from . import persistent # noqa F401 from . import profile # noqa F401 -from . import pysa_server # noqa F401 from . import query # noqa F401 from . import rage # noqa F401 from . import restart # noqa F401 diff --git a/client/tests/pyre_test.py b/client/tests/pyre_test.py index 79c59775015..12f126e9a16 100644 --- a/client/tests/pyre_test.py +++ b/client/tests/pyre_test.py @@ -10,10 +10,10 @@ import testslide +from ...client import pyre from .. import ( command_arguments, configuration, - pyre, recently_used_configurations, ) from .setup import ( From 52d5e284f53321dfdf669db1edc5c17e2e6042ea Mon Sep 17 00:00:00 2001 From: Sarthak Khattar Date: Wed, 11 Aug 2021 19:18:47 +0530 Subject: [PATCH 26/31] Revert "import changes" This reverts commit 9b2a4cbc712d17b609dd8967ee28de0432c0f126. --- client/commands/v2/__init__.py | 2 +- client/tests/pyre_test.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/client/commands/v2/__init__.py b/client/commands/v2/__init__.py index c4cca2275d1..6032443237f 100644 --- a/client/commands/v2/__init__.py +++ b/client/commands/v2/__init__.py @@ -3,7 +3,6 @@ # This source code is licensed under the MIT license found in the # LICENSE file in the root directory of this source tree. -from ..v2 import pysa_server # noqa F401 from . import backend_arguments # noqa F401 from . import check # noqa F401 from . import coverage # noqa F401 @@ -13,6 +12,7 @@ from . import kill # noqa F401 from . import persistent # noqa F401 from . import profile # noqa F401 +from . import pysa_server # noqa F401 from . import query # noqa F401 from . import rage # noqa F401 from . import restart # noqa F401 diff --git a/client/tests/pyre_test.py b/client/tests/pyre_test.py index 12f126e9a16..79c59775015 100644 --- a/client/tests/pyre_test.py +++ b/client/tests/pyre_test.py @@ -10,10 +10,10 @@ import testslide -from ...client import pyre from .. import ( command_arguments, configuration, + pyre, recently_used_configurations, ) from .setup import ( From 7b964fe7f8ff11b1e49840547a5389d213f3f4ad Mon Sep 17 00:00:00 2001 From: Sarthak Khattar Date: Tue, 31 Aug 2021 18:59:42 +0530 Subject: [PATCH 27/31] prelim changes to clear out errors in all previous files --- client/commands/v2/pysa_server.py | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/client/commands/v2/pysa_server.py b/client/commands/v2/pysa_server.py index 53bed5e56d8..9401a6947a7 100644 --- a/client/commands/v2/pysa_server.py +++ b/client/commands/v2/pysa_server.py @@ -58,6 +58,7 @@ def __init__( pyre_arguments: start.Arguments, binary_location: str, server_identifier: str, + file_tracker: dict, ) -> None: self.input_channel = input_channel self.output_channel = output_channel @@ -68,6 +69,7 @@ def __init__( self.pyre_connection = api_connection.PyreConnection( Path(self.pyre_arguments.global_root) ) + self.file_tracker = file_tracker def invalid_model_to_diagnostic( self, @@ -103,9 +105,12 @@ def invalid_models_to_diagnostics( result[Path(model.path)].append(self.invalid_model_to_diagnostic(model)) return result - async def update_errors(self, document_path: Path) -> None: - # Publishing empty diagnostics to clear errors in VSCode - await _publish_diagnostics(self.output_channel, document_path, []) + async def update_errors(self) -> None: + # Publishing empty diagnostics to clear errors in VSCode and reset self.file_tracker + for document_path in self.file_tracker.keys(): + await _publish_diagnostics(self.output_channel, Path(document_path), []) + self.file_tracker = {} + # await self.log_and_show_message_to_client(f"All files cleared: {self.file_tracker}") try: model_errors = query.get_invalid_taint_models(self.pyre_connection) @@ -164,16 +169,22 @@ async def process_open_request( self, parameters: lsp.DidOpenTextDocumentParameters ) -> None: document_path = parameters.text_document.document_uri().to_file_path() + self.file_tracker[str(document_path)] = True + # await self.log_and_show_message_to_client(f"Tracking Files: {self.file_tracker}") + if document_path is None: raise json_rpc.InvalidRequestError( f"Document URI is not a file: {parameters.text_document.uri}" ) - await self.update_errors(document_path) + await self.update_errors() async def process_close_request( self, parameters: lsp.DidCloseTextDocumentParameters ) -> None: document_path = parameters.text_document.document_uri().to_file_path() + # self.file_tracker.pop(str(document_path)) + # await self.log_and_show_message_to_client(f"Closed a file. Tracking: {self.file_tracker}") + if document_path is None: raise json_rpc.InvalidRequestError( f"Document URI is not a file: {parameters.text_document.uri}" @@ -192,7 +203,7 @@ async def process_did_save_request( raise json_rpc.InvalidRequestError( f"Document URI is not a file: {parameters.text_document.uri}" ) - await self.update_errors(document_path) + await self.update_errors() async def run(self) -> int: while True: @@ -279,6 +290,7 @@ async def run_persistent( binary_location=binary_location, server_identifier=server_identifier, pyre_arguments=pysa_arguments, + file_tracker={}, ) return await server.run() elif isinstance(initialize_result, InitializationFailure): From 9b0e2a62e72976f70a3ce8f82464d6f10e691c5b Mon Sep 17 00:00:00 2001 From: Sarthak Khattar Date: Tue, 31 Aug 2021 22:18:45 +0530 Subject: [PATCH 28/31] fixes, removed logging comments --- client/commands/v2/pysa_server.py | 20 ++++++-------------- 1 file changed, 6 insertions(+), 14 deletions(-) diff --git a/client/commands/v2/pysa_server.py b/client/commands/v2/pysa_server.py index 9401a6947a7..375ea01663c 100644 --- a/client/commands/v2/pysa_server.py +++ b/client/commands/v2/pysa_server.py @@ -58,7 +58,6 @@ def __init__( pyre_arguments: start.Arguments, binary_location: str, server_identifier: str, - file_tracker: dict, ) -> None: self.input_channel = input_channel self.output_channel = output_channel @@ -69,11 +68,10 @@ def __init__( self.pyre_connection = api_connection.PyreConnection( Path(self.pyre_arguments.global_root) ) - self.file_tracker = file_tracker + self.file_tracker = set() def invalid_model_to_diagnostic( - self, - invalid_model: query.InvalidModel, + self, invalid_model: query.InvalidModel ) -> lsp.Diagnostic: return lsp.Diagnostic( range=lsp.Range( @@ -92,8 +90,7 @@ def invalid_model_to_diagnostic( ) def invalid_models_to_diagnostics( - self, - invalid_models: Sequence[query.InvalidModel], + self, invalid_models: Sequence[query.InvalidModel] ) -> Dict[Path, List[lsp.Diagnostic]]: result: Dict[Path, List[lsp.Diagnostic]] = defaultdict(list) for model in invalid_models: @@ -107,10 +104,9 @@ def invalid_models_to_diagnostics( async def update_errors(self) -> None: # Publishing empty diagnostics to clear errors in VSCode and reset self.file_tracker - for document_path in self.file_tracker.keys(): + for document_path in self.file_tracker(): await _publish_diagnostics(self.output_channel, Path(document_path), []) - self.file_tracker = {} - # await self.log_and_show_message_to_client(f"All files cleared: {self.file_tracker}") + self.file_tracker = set() try: model_errors = query.get_invalid_taint_models(self.pyre_connection) @@ -169,8 +165,7 @@ async def process_open_request( self, parameters: lsp.DidOpenTextDocumentParameters ) -> None: document_path = parameters.text_document.document_uri().to_file_path() - self.file_tracker[str(document_path)] = True - # await self.log_and_show_message_to_client(f"Tracking Files: {self.file_tracker}") + self.file_tracker.add(str(document_path)) if document_path is None: raise json_rpc.InvalidRequestError( @@ -182,8 +177,6 @@ async def process_close_request( self, parameters: lsp.DidCloseTextDocumentParameters ) -> None: document_path = parameters.text_document.document_uri().to_file_path() - # self.file_tracker.pop(str(document_path)) - # await self.log_and_show_message_to_client(f"Closed a file. Tracking: {self.file_tracker}") if document_path is None: raise json_rpc.InvalidRequestError( @@ -290,7 +283,6 @@ async def run_persistent( binary_location=binary_location, server_identifier=server_identifier, pyre_arguments=pysa_arguments, - file_tracker={}, ) return await server.run() elif isinstance(initialize_result, InitializationFailure): From 8f642641e999ac000c8b271218a6ae338475136e Mon Sep 17 00:00:00 2001 From: Sarthak Khattar Date: Tue, 31 Aug 2021 23:53:10 +0530 Subject: [PATCH 29/31] updated tracking published diagnostic files instead of open ones --- client/commands/v2/pysa_server.py | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/client/commands/v2/pysa_server.py b/client/commands/v2/pysa_server.py index 375ea01663c..ca323931f18 100644 --- a/client/commands/v2/pysa_server.py +++ b/client/commands/v2/pysa_server.py @@ -13,7 +13,7 @@ import logging from collections import defaultdict from pathlib import Path -from typing import List, Sequence, Dict +from typing import List, Sequence, Dict, Set from ....api import query, connection as api_connection from ....api.connection import PyreQueryError @@ -68,7 +68,7 @@ def __init__( self.pyre_connection = api_connection.PyreConnection( Path(self.pyre_arguments.global_root) ) - self.file_tracker = set() + self.file_tracker: Set[Path] = set() def invalid_model_to_diagnostic( self, invalid_model: query.InvalidModel @@ -104,13 +104,17 @@ def invalid_models_to_diagnostics( async def update_errors(self) -> None: # Publishing empty diagnostics to clear errors in VSCode and reset self.file_tracker - for document_path in self.file_tracker(): - await _publish_diagnostics(self.output_channel, Path(document_path), []) + for document_path in self.file_tracker: + await _publish_diagnostics(self.output_channel, document_path, []) self.file_tracker = set() try: model_errors = query.get_invalid_taint_models(self.pyre_connection) diagnostics = self.invalid_models_to_diagnostics(model_errors) + # Keep track of files we publish diagnostics for + for path in diagnostics.keys(): + self.file_tracker.add(path) + await self.show_model_errors_to_client(diagnostics) except PyreQueryError as e: await self.log_and_show_message_to_client( @@ -165,7 +169,6 @@ async def process_open_request( self, parameters: lsp.DidOpenTextDocumentParameters ) -> None: document_path = parameters.text_document.document_uri().to_file_path() - self.file_tracker.add(str(document_path)) if document_path is None: raise json_rpc.InvalidRequestError( From 19cf7e59345af5aa6a697f714f5e6338aa17e3ac Mon Sep 17 00:00:00 2001 From: Sarthak Khattar Date: Thu, 2 Sep 2021 15:06:23 +0530 Subject: [PATCH 30/31] misc fixes --- client/commands/v2/pysa_server.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/client/commands/v2/pysa_server.py b/client/commands/v2/pysa_server.py index ca323931f18..d5d2e4dc259 100644 --- a/client/commands/v2/pysa_server.py +++ b/client/commands/v2/pysa_server.py @@ -106,14 +106,13 @@ async def update_errors(self) -> None: # Publishing empty diagnostics to clear errors in VSCode and reset self.file_tracker for document_path in self.file_tracker: await _publish_diagnostics(self.output_channel, document_path, []) - self.file_tracker = set() + self.file_tracker.clear() try: model_errors = query.get_invalid_taint_models(self.pyre_connection) diagnostics = self.invalid_models_to_diagnostics(model_errors) # Keep track of files we publish diagnostics for - for path in diagnostics.keys(): - self.file_tracker.add(path) + self.file_tracker.update(diagnostics.keys()) await self.show_model_errors_to_client(diagnostics) except PyreQueryError as e: From 516a32c8adedb86f23d80b1c441c49310f48ef9b Mon Sep 17 00:00:00 2001 From: Sarthak Khattar Date: Thu, 9 Sep 2021 14:44:30 +0530 Subject: [PATCH 31/31] fix change due to rebase --- client/commands/v2/__init__.py | 1 + 1 file changed, 1 insertion(+) diff --git a/client/commands/v2/__init__.py b/client/commands/v2/__init__.py index 6032443237f..1bd4307ba48 100644 --- a/client/commands/v2/__init__.py +++ b/client/commands/v2/__init__.py @@ -3,6 +3,7 @@ # This source code is licensed under the MIT license found in the # LICENSE file in the root directory of this source tree. +from . import analyze # noqa F401 from . import backend_arguments # noqa F401 from . import check # noqa F401 from . import coverage # noqa F401