@@ -21,16 +21,25 @@ namespace Microsoft.PowerShell.EditorServices.Hosting
2121{
2222 /// <summary>
2323 /// Factory class for hiding dependencies of Editor Services.
24- /// In particular, dependency injection and logging are wrapped by factory methods on this class
25- /// so that the host assembly can construct the LSP and debug servers
26- /// without taking logging or dependency injection dependencies directly.
2724 /// </summary>
25+ /// <remarks>
26+ /// Dependency injection and logging are wrapped by factory methods on this class so that the
27+ /// host assembly can construct the LSP and debug servers without directly depending on <see
28+ /// cref="Microsoft.Extensions.Logging"/> and <see
29+ /// cref="Microsoft.Extensions.DependencyInjection"/>.
30+ /// </remarks>
2831 internal class EditorServicesServerFactory : IDisposable
2932 {
3033 /// <summary>
31- /// Create a new Editor Services factory.
32- /// This method will instantiate logging.
34+ /// Create a new Editor Services factory. This method will instantiate logging.
3335 /// </summary>
36+ /// <remarks>
37+ /// This can only be called once because it sets global state (the logger) and that call is
38+ /// in <see cref="EditorServicesRunner"/>.
39+ ///
40+ /// TODO: Why is this a static function wrapping a constructor instead of just a
41+ /// constructor? In the end it returns an instance (albeit a "singleton").
42+ /// </remarks>
3443 /// <param name="logPath">The path of the log file to use.</param>
3544 /// <param name="minimumLogLevel">The minimum log level to use.</param>
3645 /// <returns></returns>
@@ -54,6 +63,9 @@ public static EditorServicesServerFactory Create(string logPath, int minimumLogL
5463 return new EditorServicesServerFactory ( loggerFactory , ( LogLevel ) minimumLogLevel ) ;
5564 }
5665
66+ // TODO: Can we somehow refactor this member so the language and debug servers can be
67+ // instantiated using their constructors instead of tying them to this factory with `Create`
68+ // methods?
5769 private readonly ILoggerFactory _loggerFactory ;
5870
5971 private readonly Microsoft . Extensions . Logging . ILogger _logger ;
@@ -70,9 +82,13 @@ private EditorServicesServerFactory(ILoggerFactory loggerFactory, LogLevel minim
7082 /// <summary>
7183 /// Create the LSP server.
7284 /// </summary>
85+ /// <remarks>
86+ /// This is only called once and that's in <see cref="EditorServicesRunner"/>.
87+ /// </remarks>
7388 /// <param name="inputStream">The protocol transport input stream.</param>
7489 /// <param name="outputStream">The protocol transport output stream.</param>
75- /// <param name="hostStartupInfo">The host details configuration for Editor Services instantation.</param>
90+ /// <param name="hostStartupInfo">The host details configuration for Editor Services
91+ /// instantation.</param>
7692 /// <returns>A new, unstarted language server instance.</returns>
7793 public PsesLanguageServer CreateLanguageServer (
7894 Stream inputStream ,
@@ -85,25 +101,51 @@ public PsesLanguageServer CreateLanguageServer(
85101 /// <summary>
86102 /// Create the debug server given a language server instance.
87103 /// </summary>
104+ /// <remarks>
105+ /// This is only called once and that's in <see cref="EditorServicesRunner"/>.
106+ /// </remarks>
88107 /// <param name="inputStream">The protocol transport input stream.</param>
89108 /// <param name="outputStream">The protocol transport output stream.</param>
90109 /// <param name="languageServer"></param>
91110 /// <returns>A new, unstarted debug server instance.</returns>
92- public PsesDebugServer CreateDebugServerWithLanguageServer ( Stream inputStream , Stream outputStream , PsesLanguageServer languageServer , bool usePSReadLine )
111+ public PsesDebugServer CreateDebugServerWithLanguageServer (
112+ Stream inputStream ,
113+ Stream outputStream ,
114+ PsesLanguageServer languageServer ,
115+ bool usePSReadLine )
93116 {
94- return new PsesDebugServer ( _loggerFactory , inputStream , outputStream , languageServer . LanguageServer . Services , useTempSession : false , usePSReadLine ) ;
117+ return new PsesDebugServer (
118+ _loggerFactory ,
119+ inputStream ,
120+ outputStream ,
121+ languageServer . LanguageServer . Services ,
122+ useTempSession : false ,
123+ usePSReadLine ) ;
95124 }
96125
97126 /// <summary>
98127 /// Create a new debug server based on an old one in an ended session.
99128 /// </summary>
129+ /// <remarks>
130+ /// This is only called once and that's in <see cref="EditorServicesRunner"/>.
131+ /// </remarks>
100132 /// <param name="inputStream">The protocol transport input stream.</param>
101133 /// <param name="outputStream">The protocol transport output stream.</param>
102134 /// <param name="debugServer">The old debug server to recreate.</param>
103135 /// <returns></returns>
104- public PsesDebugServer RecreateDebugServer ( Stream inputStream , Stream outputStream , PsesDebugServer debugServer , bool usePSReadLine )
136+ public PsesDebugServer RecreateDebugServer (
137+ Stream inputStream ,
138+ Stream outputStream ,
139+ PsesDebugServer debugServer ,
140+ bool usePSReadLine )
105141 {
106- return new PsesDebugServer ( _loggerFactory , inputStream , outputStream , debugServer . ServiceProvider , useTempSession : false , usePSReadLine ) ;
142+ return new PsesDebugServer (
143+ _loggerFactory ,
144+ inputStream ,
145+ outputStream ,
146+ debugServer . ServiceProvider ,
147+ useTempSession : false ,
148+ usePSReadLine ) ;
107149 }
108150
109151 /// <summary>
@@ -113,13 +155,16 @@ public PsesDebugServer RecreateDebugServer(Stream inputStream, Stream outputStre
113155 /// <param name="outputStream">The protocol transport output stream.</param>
114156 /// <param name="hostStartupInfo">The host startup configuration to create the server session with.</param>
115157 /// <returns></returns>
116- public PsesDebugServer CreateDebugServerForTempSession ( Stream inputStream , Stream outputStream , HostStartupInfo hostStartupInfo )
158+ public PsesDebugServer CreateDebugServerForTempSession (
159+ Stream inputStream ,
160+ Stream outputStream ,
161+ HostStartupInfo hostStartupInfo )
117162 {
118163 var serviceProvider = new ServiceCollection ( )
119164 . AddLogging ( builder => builder
120165 . ClearProviders ( )
121166 . AddSerilog ( )
122- . SetMinimumLevel ( LogLevel . Trace ) )
167+ . SetMinimumLevel ( LogLevel . Trace ) ) // TODO: Why randomly set to trace?
123168 . AddSingleton < ILanguageServerFacade > ( provider => null )
124169 . AddPsesLanguageServices ( hostStartupInfo )
125170 // For a Temp session, there is no LanguageServer so just set it to null
@@ -143,6 +188,14 @@ public PsesDebugServer CreateDebugServerForTempSession(Stream inputStream, Strea
143188 usePSReadLine : hostStartupInfo . ConsoleReplEnabled && ! hostStartupInfo . UsesLegacyReadLine ) ;
144189 }
145190
191+ /// <remarks>
192+ /// TODO: This class probably should not be <see cref="IDisposable"/> as the primary
193+ /// intention of that interface is to provide cleanup of unmanaged resources, which the
194+ /// logger certainly is not. Nor is this class used with a <see langword="using"/>. Instead,
195+ /// this class should call <see cref="Serilog.Log.CloseAndFlush()"/> in a finalizer. This
196+ /// could potentially even be done with <see
197+ /// cref="SerilogLoggerFactoryExtensions.AddSerilog"</> by passing <c>dispose=true</c>.
198+ /// </remarks>
146199 public void Dispose ( )
147200 {
148201 Log . CloseAndFlush ( ) ;
0 commit comments