Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Report column number in stack frame when debugger stops #405

Merged
merged 1 commit into from Mar 25, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
10 changes: 8 additions & 2 deletions src/PowerShellEditorServices.Protocol/DebugAdapter/StackFrame.cs
Expand Up @@ -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 */
Expand All @@ -38,8 +42,10 @@ public class StackFrame
{
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
Expand Down
Expand Up @@ -28,10 +28,6 @@ public class StoppedEventBody

public Source Source { get; set; }

public int Line { get; set; }

public int Column { get; set; }

/// <summary>
/// Gets or sets additional information such as an error message.
/// </summary>
Expand Down
2 changes: 0 additions & 2 deletions src/PowerShellEditorServices.Protocol/Server/DebugAdapter.cs
Expand Up @@ -857,8 +857,6 @@ async void DebugService_DebuggerStopped(object sender, DebuggerStoppedEventArgs
{
Path = e.ScriptPath,
},
Line = e.LineNumber,
Column = e.ColumnNumber,
ThreadId = 1,
Reason = debuggerStoppedReason
});
Expand Down
24 changes: 24 additions & 0 deletions src/PowerShellEditorServices/Debugging/DebugService.cs
Expand Up @@ -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;
Expand Down Expand Up @@ -41,6 +42,7 @@ public class DebugService
private VariableContainerDetails globalScopeVariables;
private VariableContainerDetails scriptScopeVariables;
private StackFrameDetails[] stackFrameDetails;
private PropertyInfo invocationTypeScriptPositionProperty;

private static int breakpointHitCounter = 0;

Expand Down Expand Up @@ -81,6 +83,12 @@ public DebugService(PowerShellContext powerShellContext)
this.powerShellContext.BreakpointUpdated += this.OnBreakpointUpdated;

this.remoteFileManager = remoteFileManager;

this.invocationTypeScriptPositionProperty =
typeof(InvocationInfo)
.GetProperty(
"ScriptPosition",
BindingFlags.NonPublic | BindingFlags.Instance);
}

#endregion
Expand Down Expand Up @@ -1100,6 +1108,22 @@ private async void OnDebuggerStop(object sender, DebuggerStopEventArgs e)
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,
Expand Down
20 changes: 15 additions & 5 deletions src/PowerShellEditorServices/Debugging/StackFrameDetails.cs
Expand Up @@ -35,15 +35,25 @@ public class StackFrameDetails
/// </summary>
public string FunctionName { get; private set; }

/// <summary>
/// Gets the start line number of the script where the stack frame occurred.
/// </summary>
public int StartLineNumber { get; internal set; }

/// <summary>
/// Gets the line number of the script where the stack frame occurred.
/// </summary>
public int LineNumber { get; private set; }
public int EndLineNumber { get; internal set; }

/// <summary>
/// Gets the start column number of the line where the stack frame occurred.
/// </summary>
public int StartColumnNumber { get; internal set; }

/// <summary>
/// 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.
/// </summary>
public int ColumnNumber { get; private set; }
public int EndColumnNumber { get; internal set; }

/// <summary>
/// Gets or sets the VariableContainerDetails that contains the auto variables.
Expand Down Expand Up @@ -82,8 +92,8 @@ public class StackFrameDetails
{
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
};
Expand Down
16 changes: 14 additions & 2 deletions test/PowerShellEditorServices.Test.Host/DebugAdapterTests.cs
Expand Up @@ -85,13 +85,25 @@ public async Task DebugAdapterStopsOnLineBreakpoints()
// 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());
Expand Down