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
            }));
        }
Esempio n. 3
0
        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))
            });
        }
Esempio n. 5
0
        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))
            });
        }