diff --git a/src/PowerShellEditorServices.Protocol/DebugAdapter/StackFrame.cs b/src/PowerShellEditorServices.Protocol/DebugAdapter/StackFrame.cs
index 910472c86..d9ba5e8c4 100644
--- a/src/PowerShellEditorServices.Protocol/DebugAdapter/StackFrame.cs
+++ b/src/PowerShellEditorServices.Protocol/DebugAdapter/StackFrame.cs
@@ -15,8 +15,12 @@ public class StackFrame
public int Line { get; set; }
+ public int? EndLine { get; set; }
+
public int Column { get; set; }
+ public int? EndColumn { get; set; }
+
// /** An identifier for the stack frame. */
//id: number;
///** The name of the stack frame, typically a method name */
@@ -38,8 +42,10 @@ public static StackFrame Create(
{
Id = id,
Name = stackFrame.FunctionName,
- Line = stackFrame.LineNumber,
- Column = stackFrame.ColumnNumber,
+ Line = stackFrame.StartLineNumber,
+ EndLine = stackFrame.EndLineNumber > 0 ? (int?)stackFrame.EndLineNumber : null,
+ Column = stackFrame.StartColumnNumber,
+ EndColumn = stackFrame.EndColumnNumber > 0 ? (int?)stackFrame.EndColumnNumber : null,
Source = new Source
{
Path = stackFrame.ScriptPath
diff --git a/src/PowerShellEditorServices.Protocol/DebugAdapter/StoppedEvent.cs b/src/PowerShellEditorServices.Protocol/DebugAdapter/StoppedEvent.cs
index b0850ddb6..8d88a1e5a 100644
--- a/src/PowerShellEditorServices.Protocol/DebugAdapter/StoppedEvent.cs
+++ b/src/PowerShellEditorServices.Protocol/DebugAdapter/StoppedEvent.cs
@@ -28,10 +28,6 @@ public class StoppedEventBody
public Source Source { get; set; }
- public int Line { get; set; }
-
- public int Column { get; set; }
-
///
/// Gets or sets additional information such as an error message.
///
diff --git a/src/PowerShellEditorServices.Protocol/Server/DebugAdapter.cs b/src/PowerShellEditorServices.Protocol/Server/DebugAdapter.cs
index 29142a83f..909ea977c 100644
--- a/src/PowerShellEditorServices.Protocol/Server/DebugAdapter.cs
+++ b/src/PowerShellEditorServices.Protocol/Server/DebugAdapter.cs
@@ -857,8 +857,6 @@ await this.SendEvent(
{
Path = e.ScriptPath,
},
- Line = e.LineNumber,
- Column = e.ColumnNumber,
ThreadId = 1,
Reason = debuggerStoppedReason
});
diff --git a/src/PowerShellEditorServices/Debugging/DebugService.cs b/src/PowerShellEditorServices/Debugging/DebugService.cs
index 20ac0f04c..81d042eea 100644
--- a/src/PowerShellEditorServices/Debugging/DebugService.cs
+++ b/src/PowerShellEditorServices/Debugging/DebugService.cs
@@ -8,6 +8,7 @@
using System.Linq;
using System.Management.Automation;
using System.Management.Automation.Language;
+using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using Microsoft.PowerShell.EditorServices.Debugging;
@@ -41,6 +42,7 @@ public class DebugService
private VariableContainerDetails globalScopeVariables;
private VariableContainerDetails scriptScopeVariables;
private StackFrameDetails[] stackFrameDetails;
+ private PropertyInfo invocationTypeScriptPositionProperty;
private static int breakpointHitCounter = 0;
@@ -81,6 +83,12 @@ public DebugService(
this.powerShellContext.BreakpointUpdated += this.OnBreakpointUpdated;
this.remoteFileManager = remoteFileManager;
+
+ this.invocationTypeScriptPositionProperty =
+ typeof(InvocationInfo)
+ .GetProperty(
+ "ScriptPosition",
+ BindingFlags.NonPublic | BindingFlags.Instance);
}
#endregion
@@ -1100,6 +1108,22 @@ await this.remoteFileManager.FetchRemoteFile(
this.powerShellContext.CurrentRunspace);
}
+ if (this.stackFrameDetails.Length > 0)
+ {
+ // Augment the top stack frame with details from the stop event
+ IScriptExtent scriptExtent =
+ this.invocationTypeScriptPositionProperty
+ .GetValue(e.InvocationInfo) as IScriptExtent;
+
+ if (scriptExtent != null)
+ {
+ this.stackFrameDetails[0].StartLineNumber = scriptExtent.StartLineNumber;
+ this.stackFrameDetails[0].EndLineNumber = scriptExtent.EndLineNumber;
+ this.stackFrameDetails[0].StartColumnNumber = scriptExtent.StartColumnNumber;
+ this.stackFrameDetails[0].EndColumnNumber = scriptExtent.EndColumnNumber;
+ }
+ }
+
// Notify the host that the debugger is stopped
this.DebuggerStopped?.Invoke(
sender,
diff --git a/src/PowerShellEditorServices/Debugging/StackFrameDetails.cs b/src/PowerShellEditorServices/Debugging/StackFrameDetails.cs
index 8b8a07eed..df8ffecd4 100644
--- a/src/PowerShellEditorServices/Debugging/StackFrameDetails.cs
+++ b/src/PowerShellEditorServices/Debugging/StackFrameDetails.cs
@@ -35,15 +35,25 @@ public class StackFrameDetails
///
public string FunctionName { get; private set; }
+ ///
+ /// Gets the start line number of the script where the stack frame occurred.
+ ///
+ public int StartLineNumber { get; internal set; }
+
///
/// Gets the line number of the script where the stack frame occurred.
///
- public int LineNumber { get; private set; }
+ public int EndLineNumber { get; internal set; }
+
+ ///
+ /// Gets the start column number of the line where the stack frame occurred.
+ ///
+ public int StartColumnNumber { get; internal set; }
///
- /// Gets the column number of the line where the stack frame occurred.
+ /// Gets the end column number of the line where the stack frame occurred.
///
- public int ColumnNumber { get; private set; }
+ public int EndColumnNumber { get; internal set; }
///
/// Gets or sets the VariableContainerDetails that contains the auto variables.
@@ -82,8 +92,8 @@ static internal StackFrameDetails Create(
{
ScriptPath = (callStackFrameObject.Properties["ScriptName"].Value as string) ?? NoFileScriptPath,
FunctionName = callStackFrameObject.Properties["FunctionName"].Value as string,
- LineNumber = (int)(callStackFrameObject.Properties["ScriptLineNumber"].Value ?? 0),
- ColumnNumber = 0, // Column number isn't given in PowerShell stack frames
+ StartLineNumber = (int)(callStackFrameObject.Properties["ScriptLineNumber"].Value ?? 0),
+ StartColumnNumber = 0, // Column number isn't given in PowerShell stack frames
AutoVariables = autoVariables,
LocalVariables = localVariables
};
diff --git a/test/PowerShellEditorServices.Test.Host/DebugAdapterTests.cs b/test/PowerShellEditorServices.Test.Host/DebugAdapterTests.cs
index bc2f45504..2d5fc905a 100644
--- a/test/PowerShellEditorServices.Test.Host/DebugAdapterTests.cs
+++ b/test/PowerShellEditorServices.Test.Host/DebugAdapterTests.cs
@@ -85,13 +85,25 @@ await this.SendRequest(
// Wait for a couple breakpoints
StoppedEventBody stoppedDetails = await breakEventTask;
Assert.Equal(DebugScriptPath, stoppedDetails.Source.Path);
- Assert.Equal(5, stoppedDetails.Line);
+
+ var stackTraceResponse =
+ await this.SendRequest(
+ StackTraceRequest.Type,
+ new StackTraceRequestArguments());
+
+ Assert.Equal(5, stackTraceResponse.StackFrames[0].Line);
breakEventTask = this.WaitForEvent(StoppedEvent.Type);
await this.SendRequest(ContinueRequest.Type, new object());
stoppedDetails = await breakEventTask;
Assert.Equal(DebugScriptPath, stoppedDetails.Source.Path);
- Assert.Equal(7, stoppedDetails.Line);
+
+ stackTraceResponse =
+ await this.SendRequest(
+ StackTraceRequest.Type,
+ new StackTraceRequestArguments());
+
+ Assert.Equal(7, stackTraceResponse.StackFrames[0].Line);
// Abort script execution
await this.SendRequest(DisconnectRequest.Type, new object());