private void DebugService_BreakpointUpdated(object sender, BreakpointUpdatedEventArgs e) { string reason = "changed"; if (_debugStateService.IsSetBreakpointInProgress) { // Don't send breakpoint update notifications when setting // breakpoints on behalf of the client. return; } switch (e.UpdateType) { case BreakpointUpdateType.Set: reason = "new"; break; case BreakpointUpdateType.Removed: reason = "removed"; break; } var breakpoint = new OmniSharp.Extensions.DebugAdapter.Protocol.Models.Breakpoint { Verified = e.UpdateType != BreakpointUpdateType.Disabled }; if (e.Breakpoint is LineBreakpoint) { breakpoint = LspDebugUtils.CreateBreakpoint(BreakpointDetails.Create(e.Breakpoint)); } else if (e.Breakpoint is CommandBreakpoint) { _logger.LogTrace("Function breakpoint updated event is not supported yet"); return; } else { _logger.LogError($"Unrecognized breakpoint type {e.Breakpoint.GetType().FullName}"); return; } _debugAdapterServer.SendNotification(EventNames.Breakpoint, new BreakpointEvent { Reason = reason, Breakpoint = breakpoint }); }
public Task <StackTraceResponse> Handle(StackTraceArguments request, CancellationToken cancellationToken) { StackFrameDetails[] stackFrameDetails = _debugService.GetStackFrames(); // Handle a rare race condition where the adapter requests stack frames before they've // begun building. if (stackFrameDetails == null) { return(Task.FromResult(new StackTraceResponse { StackFrames = Array.Empty <StackFrame>(), TotalFrames = 0 })); } List <StackFrame> newStackFrames = new List <StackFrame>(); long startFrameIndex = request.StartFrame ?? 0; long maxFrameCount = stackFrameDetails.Length; // If the number of requested levels == 0 (or null), that means get all stack frames // after the specified startFrame index. Otherwise get all the stack frames. long requestedFrameCount = (request.Levels ?? 0); if (requestedFrameCount > 0) { maxFrameCount = Math.Min(maxFrameCount, startFrameIndex + requestedFrameCount); } for (long i = startFrameIndex; i < maxFrameCount; i++) { // Create the new StackFrame object with an ID that can // be referenced back to the current list of stack frames //newStackFrames.Add( // StackFrame.Create( // stackFrameDetails[i], // i)); newStackFrames.Add( LspDebugUtils.CreateStackFrame(stackFrameDetails[i], id: i)); } return(Task.FromResult(new StackTraceResponse { StackFrames = newStackFrames, TotalFrames = newStackFrames.Count })); }
private void DebugService_BreakpointUpdated(object sender, BreakpointUpdatedEventArgs e) { // Don't send breakpoint update notifications when setting // breakpoints on behalf of the client. if (_debugStateService.IsSetBreakpointInProgress) { return; } if (e.Breakpoint is LineBreakpoint) { var breakpoint = LspDebugUtils.CreateBreakpoint( BreakpointDetails.Create(e.Breakpoint, e.UpdateType) ); string reason = (e.UpdateType) switch { BreakpointUpdateType.Set => BreakpointEventReason.New, BreakpointUpdateType.Removed => BreakpointEventReason.Removed, BreakpointUpdateType.Enabled => BreakpointEventReason.Changed, BreakpointUpdateType.Disabled => BreakpointEventReason.Changed, _ => "InvalidBreakpointUpdateTypeEnum" }; _debugAdapterServer.SendNotification( EventNames.Breakpoint, new BreakpointEvent { Breakpoint = breakpoint, Reason = reason } ); } else if (e.Breakpoint is CommandBreakpoint) { _logger.LogTrace("Function breakpoint updated event is not supported yet"); } else { _logger.LogError($"Unrecognized breakpoint type {e.Breakpoint.GetType().FullName}"); } }
public async Task <SetBreakpointsResponse> Handle(SetBreakpointsArguments request, CancellationToken cancellationToken) { ScriptFile scriptFile = null; // When you set a breakpoint in the right pane of a Git diff window on a PS1 file, // the Source.Path comes through as Untitled-X. That's why we check for IsUntitledPath. if (!ScriptFile.IsUntitledPath(request.Source.Path) && !_workspaceService.TryGetFile( request.Source.Path, out scriptFile)) { string message = _debugStateService.NoDebug ? string.Empty : "Source file could not be accessed, breakpoint not set."; var srcBreakpoints = request.Breakpoints .Select(srcBkpt => LspDebugUtils.CreateBreakpoint( srcBkpt, request.Source.Path, message, verified: _debugStateService.NoDebug)); // Return non-verified breakpoint message. return(new SetBreakpointsResponse { Breakpoints = new Container <Breakpoint>(srcBreakpoints) }); } // Verify source file is a PowerShell script file. string fileExtension = Path.GetExtension(scriptFile?.FilePath ?? "")?.ToLower(); if (string.IsNullOrEmpty(fileExtension) || ((fileExtension != ".ps1") && (fileExtension != ".psm1"))) { _logger.LogWarning( $"Attempted to set breakpoints on a non-PowerShell file: {request.Source.Path}"); string message = _debugStateService.NoDebug ? string.Empty : "Source is not a PowerShell script, breakpoint not set."; var srcBreakpoints = request.Breakpoints .Select(srcBkpt => LspDebugUtils.CreateBreakpoint( srcBkpt, request.Source.Path, message, verified: _debugStateService.NoDebug)); // Return non-verified breakpoint message. return(new SetBreakpointsResponse { Breakpoints = new Container <Breakpoint>(srcBreakpoints) }); } // At this point, the source file has been verified as a PowerShell script. BreakpointDetails[] breakpointDetails = request.Breakpoints .Select((srcBreakpoint) => BreakpointDetails.Create( scriptFile.FilePath, (int)srcBreakpoint.Line, (int?)srcBreakpoint.Column, srcBreakpoint.Condition, srcBreakpoint.HitCondition)) .ToArray(); // If this is a "run without debugging (Ctrl+F5)" session ignore requests to set breakpoints. BreakpointDetails[] updatedBreakpointDetails = breakpointDetails; if (!_debugStateService.NoDebug) { _debugStateService.SetBreakpointInProgress = true; try { updatedBreakpointDetails = await _debugService.SetLineBreakpointsAsync( scriptFile, breakpointDetails); } catch (Exception e) { // Log whatever the error is _logger.LogException($"Caught error while setting breakpoints in SetBreakpoints handler for file {scriptFile?.FilePath}", e); } finally { _debugStateService.SetBreakpointInProgress = false; } } return(new SetBreakpointsResponse { Breakpoints = new Container <Breakpoint>(updatedBreakpointDetails .Select(LspDebugUtils.CreateBreakpoint)) }); }
public async Task <SetBreakpointsResponse> Handle(SetBreakpointsArguments request, CancellationToken cancellationToken) { if (!_workspaceService.TryGetFile(request.Source.Path, out ScriptFile scriptFile)) { string message = _debugStateService.NoDebug ? string.Empty : "Source file could not be accessed, breakpoint not set."; var srcBreakpoints = request.Breakpoints .Select(srcBkpt => LspDebugUtils.CreateBreakpoint( srcBkpt, request.Source.Path, message, verified: _debugStateService.NoDebug)); // Return non-verified breakpoint message. return(new SetBreakpointsResponse { Breakpoints = new Container <Breakpoint>(srcBreakpoints) }); } // Verify source file is a PowerShell script file. string fileExtension = Path.GetExtension(scriptFile?.FilePath ?? "")?.ToLower(); bool isUntitledPath = ScriptFile.IsUntitledPath(request.Source.Path); if ((!isUntitledPath && fileExtension != ".ps1" && fileExtension != ".psm1") || (!BreakpointApiUtils.SupportsBreakpointApis && isUntitledPath)) { _logger.LogWarning( $"Attempted to set breakpoints on a non-PowerShell file: {request.Source.Path}"); string message = _debugStateService.NoDebug ? string.Empty : "Source is not a PowerShell script, breakpoint not set."; var srcBreakpoints = request.Breakpoints .Select(srcBkpt => LspDebugUtils.CreateBreakpoint( srcBkpt, request.Source.Path, message, verified: _debugStateService.NoDebug)); // Return non-verified breakpoint message. return(new SetBreakpointsResponse { Breakpoints = new Container <Breakpoint>(srcBreakpoints) }); } // At this point, the source file has been verified as a PowerShell script. BreakpointDetails[] breakpointDetails = request.Breakpoints .Select((srcBreakpoint) => BreakpointDetails.Create( scriptFile.FilePath, srcBreakpoint.Line, srcBreakpoint.Column, srcBreakpoint.Condition, srcBreakpoint.HitCondition, srcBreakpoint.LogMessage)) .ToArray(); // If this is a "run without debugging (Ctrl+F5)" session ignore requests to set breakpoints. BreakpointDetails[] updatedBreakpointDetails = breakpointDetails; if (!_debugStateService.NoDebug) { await _debugStateService.WaitForSetBreakpointHandleAsync().ConfigureAwait(false); try { updatedBreakpointDetails = await _debugService.SetLineBreakpointsAsync( scriptFile, breakpointDetails).ConfigureAwait(false); } catch (Exception e) { // Log whatever the error is _logger.LogException($"Caught error while setting breakpoints in SetBreakpoints handler for file {scriptFile?.FilePath}", e); } finally { _debugStateService.ReleaseSetBreakpointHandle(); } } return(new SetBreakpointsResponse { Breakpoints = new Container <Breakpoint>(updatedBreakpointDetails .Select(LspDebugUtils.CreateBreakpoint)) }); }