1
1
// Copyright (c) Microsoft Corporation.
2
2
// Licensed under the MIT License.
3
3
4
+ using System . Threading ;
5
+ using System . Threading . Tasks ;
4
6
using Microsoft . Extensions . Logging ;
5
7
using Microsoft . PowerShell . EditorServices . Services ;
6
- using Microsoft . PowerShell . EditorServices . Services . DebugAdapter ;
7
8
using Microsoft . PowerShell . EditorServices . Services . PowerShell ;
8
9
using Microsoft . PowerShell . EditorServices . Services . PowerShell . Debugging ;
9
10
using Microsoft . PowerShell . EditorServices . Services . PowerShell . Execution ;
10
- using Microsoft . PowerShell . EditorServices . Services . PowerShell . Runspace ;
11
11
using Microsoft . PowerShell . EditorServices . Services . TextDocument ;
12
12
using Microsoft . PowerShell . EditorServices . Utility ;
13
13
using OmniSharp . Extensions . DebugAdapter . Protocol . Events ;
14
14
using OmniSharp . Extensions . DebugAdapter . Protocol . Requests ;
15
15
using OmniSharp . Extensions . DebugAdapter . Protocol . Server ;
16
- using System . Management . Automation ;
17
- using System . Management . Automation . Language ;
18
- using System . Threading ;
19
- using System . Threading . Tasks ;
20
16
21
17
namespace Microsoft . PowerShell . EditorServices . Handlers
22
18
{
@@ -38,9 +34,7 @@ internal class ConfigurationDoneHandler : IConfigurationDoneHandler
38
34
private readonly DebugEventHandlerService _debugEventHandlerService ;
39
35
private readonly IInternalPowerShellExecutionService _executionService ;
40
36
private readonly WorkspaceService _workspaceService ;
41
-
42
37
private readonly IPowerShellDebugContext _debugContext ;
43
- private readonly IRunspaceContext _runspaceContext ;
44
38
45
39
public ConfigurationDoneHandler (
46
40
ILoggerFactory loggerFactory ,
@@ -50,8 +44,7 @@ public ConfigurationDoneHandler(
50
44
DebugEventHandlerService debugEventHandlerService ,
51
45
IInternalPowerShellExecutionService executionService ,
52
46
WorkspaceService workspaceService ,
53
- IPowerShellDebugContext debugContext ,
54
- IRunspaceContext runspaceContext )
47
+ IPowerShellDebugContext debugContext )
55
48
{
56
49
_logger = loggerFactory . CreateLogger < ConfigurationDoneHandler > ( ) ;
57
50
_debugAdapterServer = debugAdapterServer ;
@@ -61,23 +54,18 @@ public ConfigurationDoneHandler(
61
54
_executionService = executionService ;
62
55
_workspaceService = workspaceService ;
63
56
_debugContext = debugContext ;
64
- _runspaceContext = runspaceContext ;
65
57
}
66
58
67
59
public Task < ConfigurationDoneResponse > Handle ( ConfigurationDoneArguments request , CancellationToken cancellationToken )
68
60
{
69
61
_debugService . IsClientAttached = true ;
70
62
71
- if ( _debugStateService . OwnsEditorSession )
72
- {
73
- // TODO: If this is a debug-only session, we need to start the command loop manually
74
- //
75
- //_powerShellContextService.ConsoleReader.StartCommandLoop();
76
- }
77
-
78
63
if ( ! string . IsNullOrEmpty ( _debugStateService . ScriptToLaunch ) )
79
64
{
80
- LaunchScriptAsync ( _debugStateService . ScriptToLaunch ) . HandleErrorsAsync ( _logger ) ;
65
+ // NOTE: This is an unawaited task because responding to "configuration done" means
66
+ // setting up the debugger, and in our case that means starting the script but not
67
+ // waiting for it to finish.
68
+ Task _ = LaunchScriptAsync ( _debugStateService . ScriptToLaunch ) . HandleErrorsAsync ( _logger ) ;
81
69
}
82
70
83
71
if ( _debugStateService . IsInteractiveDebugSession && _debugService . IsDebuggerStopped )
@@ -102,48 +90,18 @@ public Task<ConfigurationDoneResponse> Handle(ConfigurationDoneArguments request
102
90
103
91
private async Task LaunchScriptAsync ( string scriptToLaunch )
104
92
{
105
- // Is this an untitled script?
106
- if ( ScriptFile . IsUntitledPath ( scriptToLaunch ) )
107
- {
108
- ScriptFile untitledScript = _workspaceService . GetFile ( scriptToLaunch ) ;
109
-
110
- if ( BreakpointApiUtils . SupportsBreakpointApis ( _runspaceContext . CurrentRunspace ) )
111
- {
112
- // Parse untitled files with their `Untitled:` URI as the file name which will cache the URI & contents within the PowerShell parser.
113
- // By doing this, we light up the ability to debug Untitled files with breakpoints.
114
- // This is only possible via the direct usage of the breakpoint APIs in PowerShell because
115
- // Set-PSBreakpoint validates that paths are actually on the filesystem.
116
- ScriptBlockAst ast = Parser . ParseInput ( untitledScript . Contents , untitledScript . DocumentUri . ToString ( ) , out Token [ ] tokens , out ParseError [ ] errors ) ;
117
-
118
- // This seems to be the simplest way to invoke a script block (which contains breakpoint information) via the PowerShell API.
119
- //
120
- // TODO: Fix this so the added script doesn't show up.
121
- var cmd = new PSCommand ( ) . AddScript ( ". $args[0]" ) . AddArgument ( ast . GetScriptBlock ( ) ) ;
122
- await _executionService
123
- . ExecutePSCommandAsync < object > ( cmd , CancellationToken . None , s_debuggerExecutionOptions )
124
- . ConfigureAwait ( false ) ;
125
- }
126
- else
127
- {
128
- await _executionService
129
- . ExecutePSCommandAsync (
130
- new PSCommand ( ) . AddScript ( untitledScript . Contents ) ,
131
- CancellationToken . None ,
132
- s_debuggerExecutionOptions )
133
- . ConfigureAwait ( false ) ;
134
- }
135
- }
136
- else
137
- {
138
- // TODO: Fix this so the added script doesn't show up.
139
- await _executionService
140
- . ExecutePSCommandAsync (
141
- PSCommandHelpers . BuildCommandFromArguments ( scriptToLaunch , _debugStateService . Arguments ) ,
142
- CancellationToken . None ,
143
- s_debuggerExecutionOptions )
144
- . ConfigureAwait ( false ) ;
145
- }
93
+ // TODO: Theoretically we can make PowerShell respect line breakpoints in untitled
94
+ // files, but the previous method was a hack that conflicted with correct passing of
95
+ // arguments to the debugged script. We are prioritizing the latter over the former, as
96
+ // command breakpoints and `Wait-Debugger` work fine.
97
+ string command = ScriptFile . IsUntitledPath ( scriptToLaunch )
98
+ ? string . Concat ( "{ " , _workspaceService . GetFile ( scriptToLaunch ) . Contents , " }" )
99
+ : string . Concat ( '"' , scriptToLaunch , '"' ) ;
146
100
101
+ await _executionService . ExecutePSCommandAsync (
102
+ PSCommandHelpers . BuildCommandFromArguments ( command , _debugStateService . Arguments ) ,
103
+ CancellationToken . None ,
104
+ s_debuggerExecutionOptions ) . ConfigureAwait ( false ) ;
147
105
_debugAdapterServer . SendNotification ( EventNames . Terminated ) ;
148
106
}
149
107
}
0 commit comments