def _evaluate_response(self, request, result, error_message=""): from robocorp_ls_core.debug_adapter_core.dap.dap_schema import EvaluateResponseBody from robocorp_ls_core.debug_adapter_core.dap.dap_base_schema import build_response body = EvaluateResponseBody(result=result, variablesReference=0) if not error_message: return build_response(request, kwargs={"body": body}) else: response = build_response( request, kwargs={"body": body, "success": False, "message": error_message}, ) return response
def on_launch_request(self, request): """ :param LaunchRequest request: """ from robocorp_ls_core.debug_adapter_core.dap.dap_base_schema import ( build_response, ) from robocorp_ls_core.debug_adapter_core.dap.dap_schema import InitializedEvent from robocorp_code_debug_adapter.launch_process import LaunchProcess # : :type launch_response: LaunchResponse launch_response = build_response(request) launch_process = None try: self._launch_process = launch_process = LaunchProcess( request, launch_response, self, self._rcc_config_location) if launch_process.valid: self.write_to_client_message(InitializedEvent()) except Exception as e: log.exception("Error launching.") launch_response.success = False launch_response.message = str(e) self.write_to_client_message(launch_response) # acknowledge it
def on_initialize_request(self, request): """ :param InitializeRequest request: """ from robocorp_ls_core.debug_adapter_core.dap.dap_base_schema import ( build_response, ) from robocorp_ls_core.debug_adapter_core.dap.dap_schema import InitializedEvent from robocorp_ls_core.debug_adapter_core.dap.dap_schema import ProcessEvent from robocorp_ls_core.debug_adapter_core.dap.dap_schema import ProcessEventBody # : :type initialize_response: InitializeResponse # : :type capabilities: Capabilities self._initialize_request_arguments = request.arguments initialize_response = build_response(request) capabilities = initialize_response.body capabilities.supportsConfigurationDoneRequest = True capabilities.supportsConditionalBreakpoints = True capabilities.supportsHitConditionalBreakpoints = True capabilities.supportsLogPoints = True # capabilities.supportsSetVariable = True self.write_message(initialize_response) self.write_message( ProcessEvent( ProcessEventBody(sys.executable, systemProcessId=os.getpid()))) self.write_message(InitializedEvent())
def on_configurationDone_request(self, request): """ :param ConfigurationDoneRequest request: """ from robocorp_ls_core.debug_adapter_core.dap.dap_base_schema import build_response configuration_done_response = build_response(request) launch_process = self._launch_process if launch_process is None: configuration_done_response.success = False configuration_done_response.message = ( "Launch is not done (configurationDone uncomplete).") self.write_to_client_message(configuration_done_response) return if launch_process.send_and_wait_for_configuration_done_request(): # : :type configuration_done_response: ConfigurationDoneResponse self.write_to_client_message( configuration_done_response) # acknowledge it else: # timed out configuration_done_response.success = False configuration_done_response.message = ( "Timed out waiting for configurationDone event.") self.write_to_client_message(configuration_done_response)
def on_setBreakpoints_request(self, request): """ :param SetBreakpointsRequest request: """ from robocorp_ls_core.debug_adapter_core.dap.dap_schema import SourceBreakpoint from robocorp_ls_core.debug_adapter_core.dap.dap_schema import Breakpoint from robocorp_ls_core.debug_adapter_core.dap.dap_schema import ( SetBreakpointsResponseBody, ) # Just acknowledge that no breakpoints are valid (we don't really debug, # we just run). breakpoints = [] if request.arguments.breakpoints: for bp in request.arguments.breakpoints: source_breakpoint = SourceBreakpoint(**bp) breakpoints.append( Breakpoint( verified=False, line=source_breakpoint.line, source=request.arguments.source, ).to_dict()) self.write_to_client_message( base_schema.build_response( request, kwargs=dict(body=SetBreakpointsResponseBody( breakpoints=breakpoints)), ))
def on_attach_request(self, request): from robocorp_ls_core.debug_adapter_core.dap.dap_base_schema import ( build_response, ) from robocorp_ls_core.debug_adapter_core.dap.dap_schema import AttachResponse attach_response = build_response(request) self.write_message(attach_response)
def on_setBreakpoints_request(self, request: SetBreakpointsRequest): from robocorp_ls_core.debug_adapter_core.dap.dap_schema import ( SetBreakpointsArguments, ) from robocorp_ls_core.debug_adapter_core.dap.dap_schema import Source if self._launch_process is None or not self._run_in_debug_mode: # Just acknowledge that no breakpoints are valid. breakpoints = [] if request.arguments.breakpoints: for bp in request.arguments.breakpoints: source_breakpoint = SourceBreakpoint(**bp) breakpoints.append( Breakpoint( verified=False, line=source_breakpoint.line, source=request.arguments.source, ).to_dict()) self.write_to_client_message( base_schema.build_response( request, kwargs=dict(body=SetBreakpointsResponseBody( breakpoints=breakpoints)), )) return arguments: SetBreakpointsArguments = request.arguments source: Source = arguments.source name = source.name if name and name.lower().endswith((".py", ".pyw")): self._launch_process.resend_request_to_pydevd(request) else: self._launch_process.resend_request_to_robot(request)
def on_launch_request(self, request): """ :param LaunchRequest request: """ from robocorp_ls_core.debug_adapter_core.dap.dap_base_schema import build_response from robotframework_debug_adapter.launch_process import LaunchProcess from robocorp_ls_core.debug_adapter_core.dap.dap_schema import InitializedEvent # : :type launch_response: LaunchResponse launch_response = build_response(request) launch_process = None try: self._launch_process = launch_process = LaunchProcess( request, launch_response, self) if launch_process.valid: # If on debug mode the launch is only considered finished when the connection # from the other side finishes properly. launch_process.launch() # Only write the initialized event after the process has been # launched so that we can forward breakpoints directly to the # target. self.write_to_client_message(InitializedEvent()) except Exception as e: log.exception("Error launching.") launch_response.success = False launch_response.message = str(e) self.write_to_client_message(launch_response) # acknowledge it if launch_process is not None: launch_process.after_launch_response_sent()
def on_pause_request(self, request): """ :param PauseRequest request: """ # : :type pause_response: PauseResponse pause_response = base_schema.build_response(request) self.write_to_client_message(pause_response)
def on_setExceptionBreakpoints_request( self, request: SetExceptionBreakpointsRequest): if self._run_in_debug_mode and self._launch_process is not None: self._launch_process.resend_request_to_pydevd(request) else: response = base_schema.build_response(request) self.write_to_client_message(response)
def on_disconnect_request(self, request: DisconnectRequest): disconnect_response = base_schema.build_response(request) if self._launch_process is not None: self._launch_process.disconnect(request) self.write_to_client_message(disconnect_response)
def on_setBreakpoints_request(self, request): from robocorp_ls_core.debug_adapter_core.dap.dap_schema import SourceBreakpoint from robocorp_ls_core.debug_adapter_core.dap.dap_schema import Breakpoint from robocorp_ls_core.debug_adapter_core.dap.dap_schema import ( SetBreakpointsResponseBody, ) from robocorp_ls_core.debug_adapter_core.dap import dap_base_schema from robotframework_debug_adapter import file_utils from robotframework_debug_adapter.debugger_impl import RobotBreakpoint from robocorp_ls_core.robotframework_log import get_logger log = get_logger("robotframework_debug_adapter.run_robot__main__.py") # Just acknowledge that no breakpoints are valid. breakpoints = [] robot_breakpoints = [] source = request.arguments.source path = source.path filename = file_utils.norm_file_to_server(path) log.info("Normalized %s to %s", path, filename) if request.arguments.breakpoints: for bp in request.arguments.breakpoints: source_breakpoint = SourceBreakpoint(**bp) breakpoints.append( Breakpoint(verified=True, line=source_breakpoint.line, source=source).to_dict()) hit_condition = None try: if source_breakpoint.hitCondition: hit_condition = int(source_breakpoint.hitCondition) except: log.exception( "Unable to evaluate hit condition (%s) to an int. Ignoring it.", source_breakpoint.hitCondition, ) robot_breakpoints.append( RobotBreakpoint( source_breakpoint.line, source_breakpoint.condition, hit_condition, source_breakpoint.logMessage, )) if self._debugger_impl: self._debugger_impl.set_breakpoints(filename, robot_breakpoints) else: if robot_breakpoints: get_log().info("Unable to set breakpoints (no debug mode).") self.write_message( dap_base_schema.build_response( request, kwargs=dict(body=SetBreakpointsResponseBody( breakpoints=breakpoints)), ))
def on_configurationDone_request(self, request): """ :param ConfigurationDoneRequest request: """ from robocorp_ls_core.debug_adapter_core.dap.dap_base_schema import build_response response = build_response(request) self.write_message(response) self.configuration_done.set()
def on_stepIn_request(self, request): from robocorp_ls_core.debug_adapter_core.dap.dap_base_schema import build_response response = build_response(request) if self._debugger_impl: self._debugger_impl.step_in() else: get_log().info("Unable to step in (no debug mode).") self.write_message(response)
def on_threads_request(self, request): from robocorp_ls_core.debug_adapter_core.dap.dap_schema import Thread from robocorp_ls_core.debug_adapter_core.dap.dap_schema import ( ThreadsResponseBody, ) threads = [Thread(0, "Main Thread").to_dict()] kwargs = {"body": ThreadsResponseBody(threads)} # : :type threads_response: ThreadsResponse threads_response = base_schema.build_response(request, kwargs) self.write_to_client_message(threads_response)
def on_launch_request(self, request: LaunchRequest): from robocorp_ls_core.debug_adapter_core.dap.dap_base_schema import ( build_response, ) from robotframework_debug_adapter.launch_process import LaunchProcess from robocorp_ls_core.debug_adapter_core.dap.dap_schema import ( SetDebuggerPropertyRequest, SetDebuggerPropertyArguments, AttachRequest, AttachRequestArguments, ) self._run_in_debug_mode = run_in_debug_mode = not request.arguments.noDebug launch_response: LaunchResponse = build_response(request) launch_process = None try: self._launch_process = launch_process = LaunchProcess( request, launch_response, self) if launch_process.valid: # If on debug mode the launch is only considered finished when the connection # from the other side finishes properly. launch_process.launch() # Only write the initialized event after the process has been # launched so that we can forward breakpoints directly to the # target. self.write_to_client_message(InitializedEvent()) except Exception as e: log.exception("Error launching.") launch_response.success = False launch_response.message = str(e) def on_finish_setup(*args, **kwargs): self.write_to_client_message(launch_response) # acknowledge it if launch_process is not None: launch_process.after_launch_response_sent() if run_in_debug_mode and launch_process: # We must configure/attach to pydevd launch_process.write_to_pydevd( SetDebuggerPropertyRequest( SetDebuggerPropertyArguments( skipSuspendOnBreakpointException=("BaseException", ), skipPrintBreakpointException=("NameError", ), multiThreadsSingleNotification=True, ))) attach_request_arguments = AttachRequestArguments(justMyCode=False) pydevd_attach_request = AttachRequest(attach_request_arguments) launch_process.write_to_pydevd(pydevd_attach_request, on_response=on_finish_setup) else: on_finish_setup()
def on_continue_request(self, request): from robocorp_ls_core.debug_adapter_core.dap.dap_base_schema import build_response from robocorp_ls_core.debug_adapter_core.dap.dap_schema import ContinueResponseBody response = build_response( request, kwargs=dict(body=ContinueResponseBody(allThreadsContinued=True)) ) if self._debugger_impl: self._debugger_impl.step_continue() else: get_log().info("Unable to continue (no debug mode).") self.write_message(response)
def on_threads_request(self, request): """ :param ThreadsRequest request: """ from robocorp_ls_core.debug_adapter_core.dap.dap_schema import Thread from robocorp_ls_core.debug_adapter_core.dap.dap_schema import ThreadsResponseBody from robotframework_debug_adapter.constants import MAIN_THREAD_ID from robocorp_ls_core.debug_adapter_core.dap.dap_base_schema import build_response threads = [Thread(MAIN_THREAD_ID, "Main Thread").to_dict()] kwargs = {"body": ThreadsResponseBody(threads)} # : :type threads_response: ThreadsResponse threads_response = build_response(request, kwargs) self.write_message(threads_response)
def on_initialize_request(self, request): """ :param InitializeRequest request: """ from robocorp_ls_core.debug_adapter_core.dap.dap_base_schema import build_response # : :type initialize_response: InitializeResponse # : :type body: Capabilities self._initialize_request_arguments = request.arguments initialize_response = build_response(request) self._supports_run_in_terminal = request.arguments.supportsRunInTerminalRequest body = initialize_response.body body.supportsConfigurationDoneRequest = True self.write_to_client_message(initialize_response)
def on_initialize_request(self, request: InitializeRequest): from robocorp_ls_core.debug_adapter_core.dap.dap_base_schema import ( build_response, ) from robocorp_ls_core.debug_adapter_core.dap.dap_schema import ( InitializeResponse, ) from robocorp_ls_core.debug_adapter_core.dap.dap_schema import Capabilities self._initialize_request_arguments = request.arguments initialize_response: InitializeResponse = build_response(request) self._supports_run_in_terminal = request.arguments.supportsRunInTerminalRequest capabilities: Capabilities = initialize_response.body capabilities.supportsConfigurationDoneRequest = True capabilities.supportsConditionalBreakpoints = True capabilities.supportsHitConditionalBreakpoints = True capabilities.supportsLogPoints = True # capabilities.supportsSetVariable = True self.write_to_client_message(initialize_response)
def on_threads_request(self, request): """ :param ThreadsRequest request: """ from robocorp_ls_core.debug_adapter_core.dap.dap_schema import Thread from robocorp_ls_core.debug_adapter_core.dap.dap_schema import ( ThreadsResponseBody, ) from robocorp_ls_core.debug_adapter_core.dap.dap_base_schema import ( build_response, ) thread_id = self.get_current_thread_id() threads = [Thread(thread_id, "Main Thread").to_dict()] kwargs = {"body": ThreadsResponseBody(threads)} # : :type threads_response: ThreadsResponse threads_response = build_response(request, kwargs) self.write_message(threads_response)
def on_variables_request(self, request): """ :param VariablesRequest request: """ from robocorp_ls_core.debug_adapter_core.dap.dap_base_schema import build_response from robocorp_ls_core.debug_adapter_core.dap.dap_schema import VariablesResponseBody variables_reference = request.arguments.variablesReference if self._debugger_impl: variables = self._debugger_impl.get_variables(variables_reference) else: variables = [] get_log().info("Unable to step in (no debug mode).") body = VariablesResponseBody(variables if variables else []) response = build_response(request, kwargs=dict(body=body)) self.write_message(response)
def on_scopes_request(self, request): """ :param ScopesRequest request: """ from robocorp_ls_core.debug_adapter_core.dap.dap_base_schema import build_response from robocorp_ls_core.debug_adapter_core.dap.dap_schema import ScopesResponseBody frame_id = request.arguments.frameId if self._debugger_impl: scopes = self._debugger_impl.get_scopes(frame_id) else: scopes = [] get_log().info("Unable to step in (no debug mode).") body = ScopesResponseBody(scopes if scopes else []) response = build_response(request, kwargs=dict(body=body)) self.write_message(response)
def on_stackTrace_request(self, request): """ :param StackTraceRequest request: """ from robocorp_ls_core.debug_adapter_core.dap.dap_base_schema import build_response from robocorp_ls_core.debug_adapter_core.dap.dap_schema import StackTraceResponseBody thread_id = request.arguments.threadId if self._debugger_impl: frames = self._debugger_impl.get_frames(thread_id) else: frames = [] get_log().info("Unable to get stack trace (no debug mode).") body = StackTraceResponseBody(stackFrames=frames if frames else []) response = build_response(request, kwargs=dict(body=body)) self.write_message(response)
def on_initialize_request(self, request): """ :param InitializeRequest request: """ from robocorp_ls_core.debug_adapter_core.dap.dap_base_schema import ( build_response, ) # : :type initialize_response: InitializeResponse # : :type capabilities: Capabilities self._initialize_request_arguments = request.arguments initialize_response = build_response(request) self._supports_run_in_terminal = request.arguments.supportsRunInTerminalRequest self._rcc_config_location = request.arguments.kwargs.get("rccConfigLocation") capabilities = initialize_response.body capabilities.supportsConfigurationDoneRequest = True capabilities.supportsConditionalBreakpoints = True capabilities.supportsHitConditionalBreakpoints = True capabilities.supportsLogPoints = True # capabilities.supportsSetVariable = True self.write_to_client_message(initialize_response)
def on_configurationDone_request(self, request): """ Actually run when the configuration is finished. :param ConfigurationDoneRequest request: """ from robocorp_ls_core.debug_adapter_core.dap.dap_base_schema import ( build_response, ) configuration_done_response = build_response(request) launch_process = self._launch_process if launch_process is None: configuration_done_response.success = False configuration_done_response.message = ( "Launch is not done (configurationDone uncomplete).") self.write_to_client_message(configuration_done_response) return self.write_to_client_message( configuration_done_response) # acknowledge it # Actually launch when the configuration is done. launch_process.launch()
def test_schema(): from robocorp_ls_core.debug_adapter_core.dap import dap_base_schema from robocorp_ls_core.debug_adapter_core.dap.dap_schema import ( InitializeRequest, InitializeRequestArguments, InitializeResponse, Capabilities, InitializedEvent, ) json_msg = """ { "arguments": { "adapterID": "PyDev", "clientID": "vscode", "clientName": "Visual Studio Code", "columnsStartAt1": true, "linesStartAt1": true, "locale": "en-us", "pathFormat": "path", "supportsRunInTerminalRequest": true, "supportsVariablePaging": true, "supportsVariableType": true }, "command": "initialize", "seq": 1, "type": "request" }""" initialize_request = dap_base_schema.from_json(json_msg) assert initialize_request.__class__ == InitializeRequest assert initialize_request.arguments.__class__ == InitializeRequestArguments assert initialize_request.arguments.adapterID == "PyDev" assert initialize_request.command == "initialize" assert initialize_request.type == "request" assert initialize_request.seq == 1 response = dap_base_schema.build_response(initialize_request) assert response.__class__ == InitializeResponse assert response.seq == -1 # Must be set before sending assert response.command == "initialize" assert response.type == "response" assert response.body.__class__ == Capabilities assert response.to_dict() == { "seq": -1, "type": "response", "request_seq": 1, "success": True, "command": "initialize", "body": {}, } capabilities = response.body # : :type capabilities: Capabilities capabilities.supportsCompletionsRequest = True assert response.to_dict() == { "seq": -1, "type": "response", "request_seq": 1, "success": True, "command": "initialize", "body": {"supportsCompletionsRequest": True}, } initialize_event = InitializedEvent() assert initialize_event.to_dict() == { "seq": -1, "type": "event", "event": "initialized", }
def on_pause_request(self, request: PauseRequest): if self._run_in_debug_mode and self._launch_process is not None: self._launch_process.resend_request_to_pydevd(request) else: pause_response = base_schema.build_response(request) self.write_to_client_message(pause_response)
def on_setExceptionBreakpoints_request(self, request): response = base_schema.build_response(request) self.write_to_client_message(response)