Skip to content
Merged
Original file line number Diff line number Diff line change
Expand Up @@ -84,10 +84,10 @@ public interface IEditorContextService

internal class EditorContextService : IEditorContextService
{
private readonly ILanguageServer _languageServer;
private readonly ILanguageServerFacade _languageServer;

internal EditorContextService(
ILanguageServer languageServer)
ILanguageServerFacade languageServer)
{
_languageServer = languageServer;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,12 +43,12 @@ public class EditorExtensionServiceProvider
internal EditorExtensionServiceProvider(IServiceProvider serviceProvider)
{
_serviceProvider = serviceProvider;
LanguageServer = new LanguageServerService(_serviceProvider.GetService<ILanguageServer>());
LanguageServer = new LanguageServerService(_serviceProvider.GetService<ILanguageServerFacade>());
//DocumentSymbols = new DocumentSymbolService(_serviceProvider.GetService<SymbolsService>());
ExtensionCommands = new ExtensionCommandService(_serviceProvider.GetService<ExtensionService>());
Workspace = new WorkspaceService(_serviceProvider.GetService<Internal.WorkspaceService>());
EditorContext = new EditorContextService(_serviceProvider.GetService<ILanguageServer>());
EditorUI = new EditorUIService(_serviceProvider.GetService<ILanguageServer>());
EditorContext = new EditorContextService(_serviceProvider.GetService<ILanguageServerFacade>());
EditorUI = new EditorUIService(_serviceProvider.GetService<ILanguageServerFacade>());
}

/// <summary>
Expand Down Expand Up @@ -143,7 +143,7 @@ public object GetServiceByAssemblyQualifiedName(string asmQualifiedTypeName)
/// <remarks>
/// This method is intended as a trapdoor and should not be used in the first instance.
/// Consider using the public extension services if possible.
///
///
/// Also note that services in PSES may live in a separate assembly load context,
/// meaning that a type of the seemingly correct name may fail to fetch to a service
/// that is known under a type of the same name but loaded in a different context.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -103,9 +103,9 @@ internal class EditorUIService : IEditorUIService
{
private static string[] s_choiceResponseLabelSeparators = new[] { ", " };

private readonly ILanguageServer _languageServer;
private readonly ILanguageServerFacade _languageServer;

public EditorUIService(ILanguageServer languageServer)
public EditorUIService(ILanguageServerFacade languageServer)
{
_languageServer = languageServer;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,9 +66,9 @@ public interface ILanguageServerService

internal class LanguageServerService : ILanguageServerService
{
private readonly ILanguageServer _languageServer;
private readonly ILanguageServerFacade _languageServer;

internal LanguageServerService(ILanguageServer languageServer)
internal LanguageServerService(ILanguageServerFacade languageServer)
{
_languageServer = languageServer;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -122,11 +122,11 @@ public PsesDebugServer CreateDebugServerForTempSession(Stream inputStream, Strea
.ClearProviders()
.AddSerilog()
.SetMinimumLevel(LogLevel.Trace))
.AddSingleton<ILanguageServer>(provider => null)
.AddSingleton<ILanguageServerFacade>(provider => null)
.AddPsesLanguageServices(hostStartupInfo)
// For a Temp session, there is no LanguageServer so just set it to null
.AddSingleton(
typeof(ILanguageServer),
typeof(ILanguageServerFacade),
_ => null)
.BuildServiceProvider();

Expand Down
4 changes: 2 additions & 2 deletions src/PowerShellEditorServices/PowerShellEditorServices.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,8 @@
<PackageReference Include="Microsoft.CSharp" Version="4.7.0" />
<PackageReference Include="Microsoft.Extensions.FileSystemGlobbing" Version="3.1.9" />
<PackageReference Include="Microsoft.Extensions.Logging" Version="3.1.9" />
<PackageReference Include="OmniSharp.Extensions.LanguageServer" Version="0.17.4" />
<PackageReference Include="OmniSharp.Extensions.DebugAdapter.Server" Version="0.17.4" />
<PackageReference Include="OmniSharp.Extensions.LanguageServer" Version="0.18.2" />
<PackageReference Include="OmniSharp.Extensions.DebugAdapter.Server" Version="0.18.2" />
<PackageReference Include="PowerShellStandard.Library" Version="5.1.1" />
<PackageReference Include="Serilog" Version="2.10.0" />
<PackageReference Include="Serilog.Extensions.Logging" Version="3.0.1" />
Expand Down
65 changes: 35 additions & 30 deletions src/PowerShellEditorServices/Server/PsesDebugServer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@
using Microsoft.PowerShell.EditorServices.Handlers;
using Microsoft.PowerShell.EditorServices.Services;
using Microsoft.PowerShell.EditorServices.Utility;
using OmniSharp.Extensions.DebugAdapter.Protocol;
using OmniSharp.Extensions.DebugAdapter.Protocol.Serialization;
using OmniSharp.Extensions.DebugAdapter.Server;
using OmniSharp.Extensions.JsonRpc;
using OmniSharp.Extensions.LanguageServer.Server;

Expand Down Expand Up @@ -41,7 +43,7 @@ internal class PsesDebugServer : IDisposable
private readonly bool _usePSReadLine;
private readonly TaskCompletionSource<bool> _serverStopped;

private IJsonRpcServer _jsonRpcServer;
private DebugAdapterServer _debugAdapterServer;
private PowerShellContextService _powerShellContextService;

protected readonly ILoggerFactory _loggerFactory;
Expand Down Expand Up @@ -71,13 +73,8 @@ public PsesDebugServer(
/// <returns>A task that completes when the server is ready.</returns>
public async Task StartAsync()
{
_jsonRpcServer = await JsonRpcServer.From(options =>
_debugAdapterServer = await DebugAdapterServer.From(options =>
{
options.Serializer = new DapProtocolSerializer();
options.Receiver = new DapReceiver();
options.LoggerFactory = _loggerFactory;
ILogger logger = options.LoggerFactory.CreateLogger("DebugOptionsStartup");

// We need to let the PowerShell Context Service know that we are in a debug session
// so that it doesn't send the powerShell/startDebugger message.
_powerShellContextService = ServiceProvider.GetService<PowerShellContextService>();
Expand All @@ -97,45 +94,53 @@ public async Task StartAsync()
.GetResult();
}

options.Services = new ServiceCollection()
.AddPsesDebugServices(ServiceProvider, this, _useTempSession);

options
.WithInput(_inputStream)
.WithOutput(_outputStream);

logger.LogInformation("Adding handlers");

options
.WithHandler<InitializeHandler>()
.WithHandler<LaunchHandler>()
.WithHandler<AttachHandler>()
.WithOutput(_outputStream)
.WithServices(serviceCollection => serviceCollection
.AddLogging()
.AddOptions()
.AddPsesDebugServices(ServiceProvider, this, _useTempSession))
.WithHandler<LaunchAndAttachHandler>()
.WithHandler<DisconnectHandler>()
.WithHandler<SetFunctionBreakpointsHandler>()
.WithHandler<SetExceptionBreakpointsHandler>()
.WithHandler<BreakpointHandlers>()
.WithHandler<ConfigurationDoneHandler>()
.WithHandler<ThreadsHandler>()
.WithHandler<SetBreakpointsHandler>()
.WithHandler<StackTraceHandler>()
.WithHandler<ScopesHandler>()
.WithHandler<VariablesHandler>()
.WithHandler<ContinueHandler>()
.WithHandler<NextHandler>()
.WithHandler<PauseHandler>()
.WithHandler<StepInHandler>()
.WithHandler<StepOutHandler>()
.WithHandler<DebuggerActionHandlers>()
.WithHandler<SourceHandler>()
.WithHandler<SetVariableHandler>()
.WithHandler<DebugEvaluateHandler>();

logger.LogInformation("Handlers added");
.WithHandler<DebugEvaluateHandler>()
// The OnInitialize delegate gets run when we first receive the _Initialize_ request:
// https://microsoft.github.io/debug-adapter-protocol/specification#Requests_Initialize
.OnInitialize(async (server, request, cancellationToken) => {
var breakpointService = server.GetService<BreakpointService>();
// Clear any existing breakpoints before proceeding
await breakpointService.RemoveAllBreakpointsAsync().ConfigureAwait(false);
})
// The OnInitialized delegate gets run right before the server responds to the _Initialize_ request:
// https://microsoft.github.io/debug-adapter-protocol/specification#Requests_Initialize

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

.OnInitialized((server, request, response, cancellationToken) => {
response.SupportsConditionalBreakpoints = true;
response.SupportsConfigurationDoneRequest = true;
response.SupportsFunctionBreakpoints = true;
response.SupportsHitConditionalBreakpoints = true;
response.SupportsLogPoints = true;
response.SupportsSetVariable = true;

return Task.CompletedTask;
});
}).ConfigureAwait(false);
}

public void Dispose()
{
_powerShellContextService.IsDebugServerActive = false;
_jsonRpcServer.Dispose();
_debugAdapterServer.Dispose();
_inputStream.Dispose();
_outputStream.Dispose();
_serverStopped.SetResult(true);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ public static IServiceCollection AddPsesLanguageServices(
(provider) =>
PowerShellContextService.Create(
provider.GetService<ILoggerFactory>(),
provider.GetService<OmniSharp.Extensions.LanguageServer.Protocol.Server.ILanguageServer>(),
provider.GetService<OmniSharp.Extensions.LanguageServer.Protocol.Server.ILanguageServerFacade>(),
hostStartupInfo))
.AddSingleton<TemplateService>()
.AddSingleton<EditorOperationsService>()
Expand All @@ -36,7 +36,7 @@ public static IServiceCollection AddPsesLanguageServices(
{
var extensionService = new ExtensionService(
provider.GetService<PowerShellContextService>(),
provider.GetService<OmniSharp.Extensions.LanguageServer.Protocol.Server.ILanguageServer>());
provider.GetService<OmniSharp.Extensions.LanguageServer.Protocol.Server.ILanguageServerFacade>());
extensionService.InitializeAsync(
serviceProvider: provider,
editorOperations: provider.GetService<EditorOperationsService>())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ internal static string GetUniqueIdFromDiagnostic(Diagnostic diagnostic)

private readonly ILogger _logger;

private readonly ILanguageServer _languageServer;
private readonly ILanguageServerFacade _languageServer;

private readonly ConfigurationService _configurationService;

Expand All @@ -109,7 +109,7 @@ internal static string GetUniqueIdFromDiagnostic(Diagnostic diagnostic)
/// <param name="workspaceService">The workspace service for file handling within a workspace.</param>
public AnalysisService(
ILoggerFactory loggerFactory,
ILanguageServer languageServer,
ILanguageServerFacade languageServer,
ConfigurationService configurationService,
WorkspaceService workspaceService)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
using Microsoft.PowerShell.EditorServices.Services.PowerShellContext;
using Microsoft.PowerShell.EditorServices.Utility;
using OmniSharp.Extensions.DebugAdapter.Protocol.Events;
using OmniSharp.Extensions.JsonRpc;
using OmniSharp.Extensions.DebugAdapter.Protocol.Server;

namespace Microsoft.PowerShell.EditorServices.Services
{
Expand All @@ -19,20 +19,20 @@ internal class DebugEventHandlerService
private readonly PowerShellContextService _powerShellContextService;
private readonly DebugService _debugService;
private readonly DebugStateService _debugStateService;
private readonly IJsonRpcServer _jsonRpcServer;
private readonly IDebugAdapterServerFacade _debugAdapterServer;

public DebugEventHandlerService(
ILoggerFactory factory,
PowerShellContextService powerShellContextService,
DebugService debugService,
DebugStateService debugStateService,
IJsonRpcServer jsonRpcServer)
IDebugAdapterServerFacade debugAdapterServer)
{
_logger = factory.CreateLogger<DebugEventHandlerService>();
_powerShellContextService = powerShellContextService;
_debugService = debugService;
_debugStateService = debugStateService;
_jsonRpcServer = jsonRpcServer;
_debugAdapterServer = debugAdapterServer;
}

internal void RegisterEventHandlers()
Expand Down Expand Up @@ -79,7 +79,7 @@ e.OriginalEvent.Breakpoints[0] is CommandBreakpoint
: "breakpoint";
}

_jsonRpcServer.SendNotification(EventNames.Stopped,
_debugAdapterServer.SendNotification(EventNames.Stopped,
new StoppedEvent
{
ThreadId = 1,
Expand All @@ -93,10 +93,10 @@ private void PowerShellContext_RunspaceChanged(object sender, RunspaceChangedEve
e.ChangeAction == RunspaceChangeAction.Enter &&
e.NewRunspace.Context == RunspaceContext.DebuggedRunspace)
{
// Send the InitializedEvent so that the debugger will continue
// Sends the InitializedEvent so that the debugger will continue
// sending configuration requests
_debugStateService.WaitingForAttach = false;
_jsonRpcServer.SendNotification(EventNames.Initialized);
_debugStateService.ServerStarted.SetResult(true);
}
else if (
e.ChangeAction == RunspaceChangeAction.Exit &&
Expand All @@ -105,7 +105,7 @@ private void PowerShellContext_RunspaceChanged(object sender, RunspaceChangedEve
// Exited the session while the debugger is stopped,
// send a ContinuedEvent so that the client changes the
// UI to appear to be running again
_jsonRpcServer.SendNotification(EventNames.Continued,
_debugAdapterServer.SendNotification(EventNames.Continued,
new ContinuedEvent
{
ThreadId = 1,
Expand All @@ -116,7 +116,7 @@ private void PowerShellContext_RunspaceChanged(object sender, RunspaceChangedEve

private void PowerShellContext_DebuggerResumed(object sender, DebuggerResumeAction e)
{
_jsonRpcServer.SendNotification(EventNames.Continued,
_debugAdapterServer.SendNotification(EventNames.Continued,
new ContinuedEvent
{
AllThreadsContinued = true,
Expand Down Expand Up @@ -164,7 +164,7 @@ private void DebugService_BreakpointUpdated(object sender, BreakpointUpdatedEven

breakpoint.Verified = e.UpdateType != BreakpointUpdateType.Disabled;

_jsonRpcServer.SendNotification(EventNames.Breakpoint,
_debugAdapterServer.SendNotification(EventNames.Breakpoint,
new BreakpointEvent
{
Reason = reason,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,9 @@ internal class DebugStateService

internal bool IsUsingTempIntegratedConsole { get; set; }

// This gets set at the end of the Launch/Attach handler which set debug state.
internal TaskCompletionSource<bool> ServerStarted { get; set; }

internal void ReleaseSetBreakpointHandle()
{
_setBreakpointInProgressHandle.Release();
Expand Down
Loading