1
1
// Copyright (c) Microsoft Corporation.
2
2
// Licensed under the MIT License.
3
3
4
+ using System . Management . Automation ;
5
+ using System . Management . Automation . Language ;
6
+ using System . Threading ;
7
+ using System . Threading . Tasks ;
4
8
using Microsoft . Extensions . Logging ;
5
9
using Microsoft . PowerShell . EditorServices . Services ;
6
10
using Microsoft . PowerShell . EditorServices . Services . DebugAdapter ;
13
17
using OmniSharp . Extensions . DebugAdapter . Protocol . Events ;
14
18
using OmniSharp . Extensions . DebugAdapter . Protocol . Requests ;
15
19
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
20
21
21
namespace Microsoft . PowerShell . EditorServices . Handlers
22
22
{
@@ -77,7 +77,10 @@ public Task<ConfigurationDoneResponse> Handle(ConfigurationDoneArguments request
77
77
78
78
if ( ! string . IsNullOrEmpty ( _debugStateService . ScriptToLaunch ) )
79
79
{
80
- LaunchScriptAsync ( _debugStateService . ScriptToLaunch ) . HandleErrorsAsync ( _logger ) ;
80
+ // NOTE: This is an unawaited task because responding to "configuration done" means
81
+ // setting up the debugger, and in our case that means starting the script but not
82
+ // waiting for it to finish.
83
+ Task _ = LaunchScriptAsync ( _debugStateService . ScriptToLaunch ) . HandleErrorsAsync ( _logger ) ;
81
84
}
82
85
83
86
if ( _debugStateService . IsInteractiveDebugSession && _debugService . IsDebuggerStopped )
@@ -102,48 +105,18 @@ public Task<ConfigurationDoneResponse> Handle(ConfigurationDoneArguments request
102
105
103
106
private async Task LaunchScriptAsync ( string scriptToLaunch )
104
107
{
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
- }
108
+ // TODO: Theoretically we can make PowerShell respect line breakpoints in untitled
109
+ // files, but the previous method was a hack that conflicted with correct passing of
110
+ // arguments to the debugged script. We are prioritizing the latter over the former, as
111
+ // command breakpoints and `Wait-Debugger` work fine.
112
+ string command = ScriptFile . IsUntitledPath ( scriptToLaunch )
113
+ ? string . Concat ( "{ " , _workspaceService . GetFile ( scriptToLaunch ) . Contents , " }" )
114
+ : string . Concat ( '"' , scriptToLaunch , '"' ) ;
146
115
116
+ await _executionService . ExecutePSCommandAsync (
117
+ PSCommandHelpers . BuildCommandFromArguments ( command , _debugStateService . Arguments ) ,
118
+ CancellationToken . None ,
119
+ s_debuggerExecutionOptions ) . ConfigureAwait ( false ) ;
147
120
_debugAdapterServer . SendNotification ( EventNames . Terminated ) ;
148
121
}
149
122
}
0 commit comments