8
8
using Microsoft . PowerShell . EditorServices . Session ;
9
9
using Microsoft . PowerShell . EditorServices . Transport . Stdio . Event ;
10
10
using Microsoft . PowerShell . EditorServices . Transport . Stdio . Message ;
11
+ using Microsoft . PowerShell . EditorServices . Transport . Stdio . Model ;
11
12
using Microsoft . PowerShell . EditorServices . Transport . Stdio . Response ;
12
13
using Nito . AsyncEx ;
13
14
using System ;
15
+ using System . Management . Automation ;
14
16
using System . Reflection ;
15
17
using System . Text ;
16
18
using System . Threading ;
17
19
using System . Threading . Tasks ;
18
20
19
- namespace Microsoft . PowerShell . EditorServices . Transport . Stdio
21
+ namespace Microsoft . PowerShell . EditorServices . Host
20
22
{
21
- public class StdioHost : IHost
23
+ public class MessageLoop : IHost
22
24
{
23
25
#region Private Fields
24
26
25
27
private IConsoleHost consoleHost ;
26
28
private EditorSession editorSession ;
29
+ private MessageReader messageReader ;
30
+ private MessageWriter messageWriter ;
27
31
private SynchronizationContext syncContext ;
28
32
private AsyncContextThread messageLoopThread ;
29
33
@@ -41,12 +45,8 @@ Version IHost.Version
41
45
get { throw new NotImplementedException ( ) ; }
42
46
}
43
47
44
- void IHost . Start ( )
48
+ public void Start ( )
45
49
{
46
- // Start a new EditorSession
47
- // TODO: Allow multiple sessions?
48
- this . editorSession = new EditorSession ( ) ;
49
-
50
50
// Start the main message loop
51
51
AsyncContext . Run ( ( Func < Task > ) this . StartMessageLoop ) ;
52
52
}
@@ -65,69 +65,6 @@ private async Task StartMessageLoop()
65
65
await this . messageLoopThread . Factory . Run ( ( ) => this . ListenForMessages ( ) ) ;
66
66
}
67
67
68
- //private async Task ListenForMessages()
69
- //{
70
- // // Ensure that the console is using UTF-8 encoding
71
- // System.Console.InputEncoding = Encoding.UTF8;
72
- // System.Console.OutputEncoding = Encoding.UTF8;
73
-
74
- // // Set up the reader and writer
75
- // MessageReader messageReader =
76
- // new MessageReader(
77
- // System.Console.In,
78
- // MessageFormat.WithoutContentLength);
79
-
80
- // MessageWriter messageWriter =
81
- // new MessageWriter(
82
- // System.Console.Out,
83
- // MessageFormat.WithContentLength);
84
-
85
- // this.ConsoleHost = new StdioConsoleHost(messageWriter);
86
-
87
- // // Set up the PowerShell session
88
- // // TODO: Do this elsewhere
89
- // EditorSession editorSession = new EditorSession();
90
- // editorSession.StartSession(this.ConsoleHost);
91
-
92
- // // Send a "started" event
93
- // messageWriter.WriteMessage(
94
- // new Event<object>
95
- // {
96
- // EventType = "started"
97
- // });
98
-
99
- // // Run the message loop
100
- // bool isRunning = true;
101
- // while(isRunning)
102
- // {
103
- // // Read a message
104
- // Message newMessage = await messageReader.ReadMessage();
105
-
106
- // // Is the message a request?
107
- // IMessageProcessor messageProcessor = newMessage as IMessageProcessor;
108
- // if (messageProcessor != null)
109
- // {
110
- // // Process the request on the host thread
111
- // messageProcessor.ProcessMessage(
112
- // editorSession,
113
- // messageWriter);
114
- // }
115
- // else
116
- // {
117
- // if (newMessage != null)
118
- // {
119
- // // Return an error response to keep the client moving
120
- // messageWriter.WriteMessage(
121
- // new Response<object>
122
- // {
123
- // Command = request != null ? request.Command : string.Empty,
124
- // RequestSeq = newMessage.Seq,
125
- // Success = false,
126
- // });
127
- // }
128
- // }
129
- // }
130
- //}
131
68
async Task ListenForMessages ( )
132
69
{
133
70
// Ensure that the console is using UTF-8 encoding
@@ -136,16 +73,16 @@ async Task ListenForMessages()
136
73
137
74
// Find all message types in this assembly
138
75
MessageTypeResolver messageTypeResolver = new MessageTypeResolver ( ) ;
139
- messageTypeResolver . ScanForMessageTypes ( Assembly . GetExecutingAssembly ( ) ) ;
76
+ messageTypeResolver . ScanForMessageTypes ( typeof ( StartedEvent ) . Assembly ) ;
140
77
141
78
// Set up the reader and writer
142
- MessageReader messageReader =
79
+ this . messageReader =
143
80
new MessageReader (
144
- System . Console . In ,
81
+ System . Console . In ,
145
82
MessageFormat . WithContentLength ,
146
83
messageTypeResolver ) ;
147
84
148
- MessageWriter messageWriter =
85
+ this . messageWriter =
149
86
new MessageWriter (
150
87
System . Console . Out ,
151
88
MessageFormat . WithContentLength ,
@@ -156,12 +93,16 @@ async Task ListenForMessages()
156
93
this . consoleHost = new StdioConsoleHost ( messageWriter ) ;
157
94
158
95
// Set up the PowerShell session
159
- // TODO: Do this elsewhere
160
- EditorSession editorSession = new EditorSession ( ) ;
161
- editorSession . StartSession ( this . consoleHost ) ;
96
+ this . editorSession = new EditorSession ( ) ;
97
+ this . editorSession . StartSession ( this . consoleHost ) ;
98
+
99
+ // Attach to events from the PowerShell session
100
+ this . editorSession . PowerShellSession . OutputWritten += PowerShellSession_OutputWritten ;
101
+ this . editorSession . PowerShellSession . BreakpointUpdated += PowerShellSession_BreakpointUpdated ;
102
+ this . editorSession . DebugService . DebuggerStopped += DebugService_DebuggerStopped ;
162
103
163
104
// Send a "started" event
164
- messageWriter . WriteMessage (
105
+ this . messageWriter . WriteMessage (
165
106
new StartedEvent ( ) ) ;
166
107
167
108
// Run the message loop
@@ -173,12 +114,12 @@ async Task ListenForMessages()
173
114
try
174
115
{
175
116
// Read a message from stdin
176
- newMessage = await messageReader . ReadMessage ( ) ;
117
+ newMessage = await this . messageReader . ReadMessage ( ) ;
177
118
}
178
119
catch ( MessageParseException e )
179
120
{
180
121
// Write an error response
181
- messageWriter . WriteMessage (
122
+ this . messageWriter . WriteMessage (
182
123
MessageErrorResponse . CreateParseErrorResponse ( e ) ) ;
183
124
184
125
// Continue the loop
@@ -191,16 +132,16 @@ async Task ListenForMessages()
191
132
{
192
133
// Process the message. The processor will take care
193
134
// of writing responses throguh the messageWriter.
194
- messageProcessor . ProcessMessage (
195
- editorSession ,
196
- messageWriter ) ;
135
+ await messageProcessor . ProcessMessage (
136
+ this . editorSession ,
137
+ this . messageWriter ) ;
197
138
}
198
139
else
199
140
{
200
141
if ( newMessage != null )
201
142
{
202
143
// Return an error response to keep the client moving
203
- messageWriter . WriteMessage (
144
+ this . messageWriter . WriteMessage (
204
145
MessageErrorResponse . CreateUnhandledMessageResponse (
205
146
newMessage ) ) ;
206
147
}
@@ -213,6 +154,47 @@ async Task ListenForMessages()
213
154
}
214
155
}
215
156
157
+ void DebugService_DebuggerStopped ( object sender , DebuggerStopEventArgs e )
158
+ {
159
+ this . messageWriter . WriteMessage (
160
+ new StoppedEvent
161
+ {
162
+ Body = new StoppedEventBody
163
+ {
164
+ Source = new Source
165
+ {
166
+ Path = e . InvocationInfo . ScriptName ,
167
+ } ,
168
+ Line = e . InvocationInfo . ScriptLineNumber ,
169
+ Column = e . InvocationInfo . OffsetInLine ,
170
+ ThreadId = 1 , // TODO: Change this based on context
171
+ Reason = "breakpoint" // TODO: Change this based on context
172
+ }
173
+ } ) ;
174
+ }
175
+
176
+ void PowerShellSession_BreakpointUpdated ( object sender , BreakpointUpdatedEventArgs e )
177
+ {
178
+ }
179
+
180
+ void PowerShellSession_OutputWritten ( object sender , OutputWrittenEventArgs e )
181
+ {
182
+ // TODO: change this to use the OutputEvent!
183
+
184
+ this . messageWriter . WriteMessage (
185
+ new ReplWriteOutputEvent
186
+ {
187
+ Body = new ReplWriteOutputEventBody
188
+ {
189
+ LineContents = e . OutputText ,
190
+ LineType = e . OutputType ,
191
+ IncludeNewLine = e . IncludeNewLine ,
192
+ ForegroundColor = e . ForegroundColor ,
193
+ BackgroundColor = e . BackgroundColor
194
+ }
195
+ } ) ;
196
+ }
197
+
216
198
#endregion
217
199
}
218
200
}
0 commit comments