public static IServiceCollection AddPsesLanguageServices( this IServiceCollection collection, HostStartupInfo hostStartupInfo) { return(collection.AddSingleton <WorkspaceService>() .AddSingleton <SymbolsService>() .AddSingleton <ConfigurationService>() .AddSingleton <PowerShellContextService>( (provider) => PowerShellContextService.Create( provider.GetService <ILoggerFactory>(), // NOTE: Giving the context service access to the language server this // early is dangerous because it allows it to start sending // notifications etc. before it has initialized, potentially resulting // in deadlocks. We're working on a solution to this. provider.GetService <OmniSharp.Extensions.LanguageServer.Protocol.Server.ILanguageServerFacade>(), hostStartupInfo)) .AddSingleton <TemplateService>() // TODO: What's the difference between this and the TemplateHandler? .AddSingleton <EditorOperationsService>() .AddSingleton <RemoteFileManagerService>() .AddSingleton <ExtensionService>( (provider) => { var extensionService = new ExtensionService( provider.GetService <PowerShellContextService>(), // NOTE: See above warning. provider.GetService <OmniSharp.Extensions.LanguageServer.Protocol.Server.ILanguageServerFacade>()); extensionService.InitializeAsync( serviceProvider: provider, editorOperations: provider.GetService <EditorOperationsService>()) .Wait(); return extensionService; }) .AddSingleton <AnalysisService>()); }
public DebugServiceTests() { var logger = NullLogger.Instance; this.powerShellContext = PowerShellContextFactory.Create(logger); this.powerShellContext.SessionStateChanged += powerShellContext_SessionStateChanged; this.workspace = new WorkspaceService(NullLoggerFactory.Instance); // Load the test debug files this.debugScriptFile = GetDebugScript("DebugTest.ps1"); this.variableScriptFile = GetDebugScript("VariableTest.ps1"); this.debugService = new DebugService( this.powerShellContext, null, new BreakpointService( NullLoggerFactory.Instance, powerShellContext, new DebugStateService()), NullLoggerFactory.Instance); this.debugService.DebuggerStopped += debugService_DebuggerStopped; this.debugService.BreakpointUpdated += debugService_BreakpointUpdated; }
internal static InvocationEventQueue Create(PowerShellContextService powerShellContext, PromptNest promptNest) { var eventQueue = new InvocationEventQueue(powerShellContext, promptNest); eventQueue.CreateInvocationSubscriber(); return(eventQueue); }
/// <summary> /// Constructs an instance of the SymbolsService class and uses /// the given Runspace to execute language service operations. /// </summary> /// <param name="factory">An ILoggerFactory implementation used for writing log messages.</param> public SymbolsService( ILoggerFactory factory, PowerShellContextService powerShellContextService, WorkspaceService workspaceService) { _logger = factory.CreateLogger <SymbolsService>(); _powerShellContextService = powerShellContextService; _workspaceService = workspaceService; _codeLensProviders = new ConcurrentDictionary <string, ICodeLensProvider>(); var codeLensProviders = new ICodeLensProvider[] { new ReferencesCodeLensProvider(_workspaceService, this), new PesterCodeLensProvider(), }; foreach (ICodeLensProvider codeLensProvider in codeLensProviders) { _codeLensProviders.TryAdd(codeLensProvider.ProviderId, codeLensProvider); } _documentSymbolProviders = new ConcurrentDictionary <string, IDocumentSymbolProvider>(); var documentSymbolProviders = new IDocumentSymbolProvider[] { new ScriptDocumentSymbolProvider(), new PsdDocumentSymbolProvider(), new PesterDocumentSymbolProvider(), }; foreach (IDocumentSymbolProvider documentSymbolProvider in documentSymbolProviders) { _documentSymbolProviders.TryAdd(documentSymbolProvider.ProviderId, documentSymbolProvider); } }
/// <summary> /// Creates a new instance of the TemplateService class. /// </summary> /// <param name="powerShellContext">The PowerShellContext to use for this service.</param> /// <param name="factory">An ILoggerFactory implementation used for writing log messages.</param> public TemplateService(PowerShellContextService powerShellContext, ILoggerFactory factory) { Validate.IsNotNull(nameof(powerShellContext), powerShellContext); this.logger = factory.CreateLogger <TemplateService>(); this.powerShellContext = powerShellContext; }
/// <summary> /// Creates a new instance of the RemoteFileManagerService class. /// </summary> /// <param name="factory">An ILoggerFactory implementation used for writing log messages.</param> /// <param name="powerShellContext"> /// The PowerShellContext to use for file loading operations. /// </param> /// <param name="editorOperations"> /// The IEditorOperations instance to use for opening/closing files in the editor. /// </param> public RemoteFileManagerService( ILoggerFactory factory, PowerShellContextService powerShellContext, EditorOperationsService editorOperations) { Validate.IsNotNull(nameof(powerShellContext), powerShellContext); this.logger = factory.CreateLogger <RemoteFileManagerService>(); this.powerShellContext = powerShellContext; this.powerShellContext.RunspaceChanged += HandleRunspaceChangedAsync; this.editorOperations = editorOperations; this.processTempPath = Path.Combine( Path.GetTempPath(), "PSES-" + Process.GetCurrentProcess().Id); this.remoteFilesPath = Path.Combine(this.processTempPath, "RemoteFiles"); // Delete existing temporary file cache path if it already exists this.TryDeleteTemporaryPath(); // Register the psedit function in the current runspace this.RegisterPSEditFunction(this.powerShellContext.CurrentRunspace); }
/// <summary> /// Creates a new instance of the ConsoleServicePSHostUserInterface /// class with the given IConsoleHost implementation. /// </summary> /// <param name="powerShellContext">The PowerShellContext to use for executing commands.</param> /// <param name="logger">An ILogger implementation to use for this host.</param> /// <param name="internalHost">The InternalHost instance from the origin runspace.</param> public TerminalPSHostUserInterface( PowerShellContextService powerShellContext, ILogger logger, PSHost internalHost) : base( powerShellContext, new TerminalPSHostRawUserInterface(logger, internalHost), logger) { this.internalHostUI = internalHost.UI; this.consoleReadLine = new ConsoleReadLine(powerShellContext); // Set the output encoding to UTF-8 so that special // characters are written to the console correctly System.Console.OutputEncoding = System.Text.Encoding.UTF8; System.Console.CancelKeyPress += (obj, args) => { if (!this.IsNativeApplicationRunning) { // We'll handle Ctrl+C args.Cancel = true; this.SendControlC(); } }; }
/// <summary> /// Gets the CommandInfo instance for a command with a particular name. /// </summary> /// <param name="commandName">The name of the command.</param> /// <param name="powerShellContext">The PowerShellContext to use for running Get-Command.</param> /// <returns>A CommandInfo object with details about the specified command.</returns> public static async Task <CommandInfo> GetCommandInfoAsync( string commandName, PowerShellContextService powerShellContext) { Validate.IsNotNull(nameof(commandName), commandName); Validate.IsNotNull(nameof(powerShellContext), powerShellContext); // Make sure the command's noun isn't blacklisted. This is // currently necessary to make sure that Get-Command doesn't // load PackageManagement or PowerShellGet because they cause // a major slowdown in IntelliSense. var commandParts = commandName.Split('-'); if (commandParts.Length == 2 && NounExclusionList.ContainsKey(commandParts[1])) { return(null); } PSCommand command = new PSCommand(); command.AddCommand(@"Microsoft.PowerShell.Core\Get-Command"); command.AddArgument(commandName); command.AddParameter("ErrorAction", "Ignore"); return((await powerShellContext.ExecuteCommandAsync <PSObject>(command, sendOutputToHost: false, sendErrorToHost: false).ConfigureAwait(false)) .Select(o => o.BaseObject) .OfType <CommandInfo>() .FirstOrDefault()); }
public static PowerShellContextService Create(ILogger logger) { PowerShellContextService powerShellContext = new PowerShellContextService(logger, null, isPSReadLineEnabled: false); HostStartupInfo testHostDetails = new HostStartupInfo( "PowerShell Editor Services Test Host", "Test.PowerShellEditorServices", new Version("1.0.0"), null, TestProfilePaths, new List <string>(), new List <string>(), PSLanguageMode.FullLanguage, null, 0, consoleReplEnabled: false, usesLegacyReadLine: false); powerShellContext.Initialize( TestProfilePaths, PowerShellContextService.CreateRunspace( testHostDetails, powerShellContext, new TestPSHostUserInterface(powerShellContext, logger), logger), true); return(powerShellContext); }
public static IServiceCollection AddPsesLanguageServices( this IServiceCollection collection, HostStartupInfo hostStartupInfo) { return(collection.AddSingleton <WorkspaceService>() .AddSingleton <SymbolsService>() .AddSingleton <ConfigurationService>() .AddSingleton <PowerShellContextService>( (provider) => PowerShellContextService.Create( provider.GetService <ILoggerFactory>(), provider.GetService <OmniSharp.Extensions.LanguageServer.Protocol.Server.ILanguageServerFacade>(), hostStartupInfo)) .AddSingleton <TemplateService>() .AddSingleton <EditorOperationsService>() .AddSingleton <RemoteFileManagerService>() .AddSingleton <ExtensionService>( (provider) => { var extensionService = new ExtensionService( provider.GetService <PowerShellContextService>(), provider.GetService <OmniSharp.Extensions.LanguageServer.Protocol.Server.ILanguageServerFacade>()); extensionService.InitializeAsync( serviceProvider: provider, editorOperations: provider.GetService <EditorOperationsService>()) .Wait(); return extensionService; }) .AddSingleton <AnalysisService>()); }
/// <summary> /// Start the debug server listening. /// </summary> /// <returns>A task that completes when the server is ready.</returns> public async Task StartAsync() { _jsonRpcServer = await JsonRpcServer.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>(); _powerShellContextService.IsDebugServerActive = true; // Needed to make sure PSReadLine's static properties are initialized in the pipeline thread. // This is only needed for Temp sessions who only have a debug server. if (_usePSReadLine && _useTempSession && Interlocked.Exchange(ref s_hasRunPsrlStaticCtor, 1) == 0) { // This must be run synchronously to ensure debugging works _powerShellContextService .ExecuteScriptStringAsync("[System.Runtime.CompilerServices.RuntimeHelpers]::RunClassConstructor([Microsoft.PowerShell.PSConsoleReadLine].TypeHandle)") .GetAwaiter() .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>() .WithHandler <DisconnectHandler>() .WithHandler <SetFunctionBreakpointsHandler>() .WithHandler <SetExceptionBreakpointsHandler>() .WithHandler <ConfigurationDoneHandler>() .WithHandler <ThreadsHandler>() .WithHandler <SetBreakpointsHandler>() .WithHandler <StackTraceHandler>() .WithHandler <ScopesHandler>() .WithHandler <VariablesHandler>() .WithHandler <ContinueHandler>() .WithHandler <NextHandler>() .WithHandler <PauseHandler>() .WithHandler <StepInHandler>() .WithHandler <StepOutHandler>() .WithHandler <SourceHandler>() .WithHandler <SetVariableHandler>() .WithHandler <DebugEvaluateHandler>(); logger.LogInformation("Handlers added"); }).ConfigureAwait(false); }
public void StopCommandInDebugger(PowerShellContextService powerShellContext) { // If the RunspaceAvailability is None, the runspace is dead and we should not try to run anything in it. if (powerShellContext.CurrentRunspace.Runspace.RunspaceAvailability != RunspaceAvailability.None) { powerShellContext.CurrentRunspace.Runspace.Debugger.StopProcessCommand(); } }
/// <summary> /// Creates a new instance of the ConsoleServicePSHostUserInterface /// class with the given IConsoleHost implementation. /// </summary> /// <param name="powerShellContext"></param> public ProtocolPSHostUserInterface( ILanguageServer languageServer, PowerShellContextService powerShellContext, ILogger logger) : base(powerShellContext, new SimplePSHostRawUserInterface(logger), logger) { _languageServer = languageServer; }
public TestPSHostUserInterface( PowerShellContextService powerShellContext, ILogger logger) : base( powerShellContext, new SimplePSHostRawUserInterface(logger), NullLogger.Instance) { }
public DebugEvaluateHandler( ILoggerFactory factory, PowerShellContextService powerShellContextService, DebugService debugService) { _logger = factory.CreateLogger <DebugEvaluateHandler>(); _powerShellContextService = powerShellContextService; _debugService = debugService; }
public LanguageServiceTests() { var logger = NullLogger.Instance; powerShellContext = PowerShellContextFactory.Create(logger); workspace = new WorkspaceService(NullLoggerFactory.Instance); symbolsService = new SymbolsService(NullLoggerFactory.Instance, powerShellContext, workspace, new ConfigurationService()); completionHandler = new PsesCompletionHandler(NullLoggerFactory.Instance, powerShellContext, workspace); }
public BreakpointService( ILoggerFactory factory, PowerShellContextService powerShellContextService, DebugStateService debugStateService) { _logger = factory.CreateLogger <BreakpointService>(); _powerShellContextService = powerShellContextService; _debugStateService = debugStateService; }
public EditorOperationsService( WorkspaceService workspaceService, PowerShellContextService powerShellContextService, ILanguageServer languageServer) { _workspaceService = workspaceService; _powerShellContextService = powerShellContextService; _languageServer = languageServer; }
public PsesCompletionHandler( ILoggerFactory factory, PowerShellContextService powerShellContextService, WorkspaceService workspaceService) { _logger = factory.CreateLogger <PsesCompletionHandler>(); _powerShellContextService = powerShellContextService; _workspaceService = workspaceService; }
/// <summary> /// Gets the command's "Synopsis" documentation section. /// </summary> /// <param name="commandInfo">The CommandInfo instance for the command.</param> /// <param name="powerShellContext">The PowerShellContext to use for getting command documentation.</param> /// <returns></returns> public static async Task <string> GetCommandSynopsisAsync( CommandInfo commandInfo, PowerShellContextService powerShellContext) { Validate.IsNotNull(nameof(commandInfo), commandInfo); Validate.IsNotNull(nameof(powerShellContext), powerShellContext); // A small optimization to not run Get-Help on things like DSC resources. if (commandInfo.CommandType != CommandTypes.Cmdlet && commandInfo.CommandType != CommandTypes.Function && commandInfo.CommandType != CommandTypes.Filter) { return(string.Empty); } // If we have a synopsis cached, return that. // NOTE: If the user runs Update-Help, it's possible that this synopsis will be out of date. // Given the perf increase of doing this, and the simple workaround of restarting the extension, // this seems worth it. if (s_synopsisCache.TryGetValue(commandInfo.Name, out string synopsis)) { return(synopsis); } PSCommand command = new PSCommand() .AddCommand(@"Microsoft.PowerShell.Core\Get-Help") // We use .Name here instead of just passing in commandInfo because // CommandInfo.ToString() duplicates the Prefix if one exists. .AddParameter("Name", commandInfo.Name) .AddParameter("Online", false) .AddParameter("ErrorAction", "Ignore"); var results = await powerShellContext.ExecuteCommandAsync <PSObject>(command, sendOutputToHost : false, sendErrorToHost : false).ConfigureAwait(false); PSObject helpObject = results.FirstOrDefault(); // Extract the synopsis string from the object string synopsisString = (string)helpObject?.Properties["synopsis"].Value ?? string.Empty; // Only cache cmdlet infos because since they're exposed in binaries, the can never change throughout the session. if (commandInfo.CommandType == CommandTypes.Cmdlet) { s_synopsisCache.TryAdd(commandInfo.Name, synopsisString); } // Ignore the placeholder value for this field if (string.Equals(synopsisString, "SHORT DESCRIPTION", System.StringComparison.CurrentCultureIgnoreCase)) { return(string.Empty); } return(synopsisString); }
public SignatureHelpHandler( ILoggerFactory factory, SymbolsService symbolsService, WorkspaceService workspaceService, PowerShellContextService powerShellContextService) { _logger = factory.CreateLogger <HoverHandler>(); _symbolsService = symbolsService; _workspaceService = workspaceService; _powerShellContextService = powerShellContextService; }
public GetVersionHandler( ILoggerFactory factory, PowerShellContextService powerShellContextService, ILanguageServerFacade languageServer, ConfigurationService configurationService) { _logger = factory.CreateLogger <GetVersionHandler>(); _powerShellContextService = powerShellContextService; _languageServer = languageServer; _configurationService = configurationService; }
public async Task StartAsync(IServiceProvider languageServerServiceProvider, bool useTempSession) { _jsonRpcServer = await JsonRpcServer.From(options => { options.Serializer = new DapProtocolSerializer(); options.Reciever = new DapReciever(); 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 = languageServerServiceProvider.GetService <PowerShellContextService>(); _powerShellContextService.IsDebugServerActive = true; // Needed to make sure PSReadLine's static properties are initialized in the pipeline thread. _powerShellContextService .ExecuteScriptStringAsync("[System.Runtime.CompilerServices.RuntimeHelpers]::RunClassConstructor([Microsoft.PowerShell.PSConsoleReadLine].TypeHandle)") .Wait(); options.Services = new ServiceCollection() .AddPsesDebugServices(languageServerServiceProvider, this, useTempSession); options .WithInput(_inputStream) .WithOutput(_outputStream); logger.LogInformation("Adding handlers"); options .WithHandler <InitializeHandler>() .WithHandler <LaunchHandler>() .WithHandler <AttachHandler>() .WithHandler <DisconnectHandler>() .WithHandler <SetFunctionBreakpointsHandler>() .WithHandler <SetExceptionBreakpointsHandler>() .WithHandler <ConfigurationDoneHandler>() .WithHandler <ThreadsHandler>() .WithHandler <SetBreakpointsHandler>() .WithHandler <StackTraceHandler>() .WithHandler <ScopesHandler>() .WithHandler <VariablesHandler>() .WithHandler <ContinueHandler>() .WithHandler <NextHandler>() .WithHandler <PauseHandler>() .WithHandler <StepInHandler>() .WithHandler <StepOutHandler>() .WithHandler <SourceHandler>() .WithHandler <SetVariableHandler>() .WithHandler <DebugEvaluateHandler>(); logger.LogInformation("Handlers added"); }); }
/// <summary> /// Finds the parameter set hints of a specific command (determined by a given file location) /// </summary> /// <param name="file">The details and contents of a open script file</param> /// <param name="lineNumber">The line number of the cursor for the given script</param> /// <param name="columnNumber">The coulumn number of the cursor for the given script</param> /// <returns>ParameterSetSignatures</returns> public async Task <ParameterSetSignatures> FindParameterSetsInFileAsync( ScriptFile file, int lineNumber, int columnNumber, PowerShellContextService powerShellContext) { SymbolReference foundSymbol = AstOperations.FindCommandAtPosition( file.ScriptAst, lineNumber, columnNumber); // If we are not possibly looking at a Function, we don't // need to continue because we won't be able to get the // CommandInfo object. if (foundSymbol?.SymbolType != SymbolType.Function && foundSymbol?.SymbolType != SymbolType.Unknown) { return(null); } CommandInfo commandInfo = await CommandHelpers.GetCommandInfoAsync( foundSymbol.SymbolName, powerShellContext).ConfigureAwait(false); if (commandInfo == null) { return(null); } try { IEnumerable <CommandParameterSetInfo> commandParamSets = commandInfo.ParameterSets; return(new ParameterSetSignatures(commandParamSets, foundSymbol)); } catch (RuntimeException e) { // A RuntimeException will be thrown when an invalid attribute is // on a parameter binding block and then that command/script has // its signatures resolved by typing it into a script. _logger.LogException("RuntimeException encountered while accessing command parameter sets", e); return(null); } catch (InvalidOperationException) { // For some commands there are no paramsets (like applications). Until // the valid command types are better understood, catch this exception // which gets raised when there are no ParameterSets for the command type. return(null); } }
/// <summary> /// Creates a new instance of the ConsoleServicePSHost class /// with the given IConsoleHost implementation. /// </summary> /// <param name="powerShellContext"> /// An implementation of IHostSupportsInteractiveSession for runspace management. /// </param> /// <param name="hostDetails"> /// Provides details about the host application. /// </param> /// <param name="hostUserInterface"> /// The EditorServicesPSHostUserInterface implementation to use for this host. /// </param> /// <param name="logger">An ILogger implementation to use for this host.</param> public EditorServicesPSHost( PowerShellContextService powerShellContext, HostDetails hostDetails, EditorServicesPSHostUserInterface hostUserInterface, ILogger logger) { this.Logger = logger; this.hostDetails = hostDetails; this.hostUserInterface = hostUserInterface; this.hostSupportsInteractiveSession = powerShellContext; this.powerShellContext = powerShellContext; }
public PipelineExecutionRequest( PowerShellContextService powerShellContext, PSCommand psCommand, StringBuilder errorMessages, ExecutionOptions executionOptions) { _powerShellContext = powerShellContext; _psCommand = psCommand; _errorMessages = errorMessages; _executionOptions = executionOptions; _resultsTask = new TaskCompletionSource <IEnumerable <TResult> >(); }
public ConfigurationHandler( ILoggerFactory factory, WorkspaceService workspaceService, AnalysisService analysisService, ConfigurationService configurationService, PowerShellContextService powerShellContextService) { _logger = factory.CreateLogger <ConfigurationHandler>(); _workspaceService = workspaceService; _analysisService = analysisService; _configurationService = configurationService; _powerShellContextService = powerShellContextService; }
/// <summary> /// Creates a new instance of the ConsoleServicePSHostUserInterface /// class with the given IConsoleHost implementation. /// </summary> /// <param name="powerShellContext">The PowerShellContext to use for executing commands.</param> /// <param name="rawUserInterface">The PSHostRawUserInterface implementation to use for this host.</param> /// <param name="logger">An ILogger implementation to use for this host.</param> public EditorServicesPSHostUserInterface( PowerShellContextService powerShellContext, PSHostRawUserInterface rawUserInterface, ILogger logger) { this.Logger = logger; this.powerShellContext = powerShellContext; this.rawUserInterface = rawUserInterface; this.powerShellContext.DebuggerStop += PowerShellContext_DebuggerStop; this.powerShellContext.DebuggerResumed += PowerShellContext_DebuggerResumed; this.powerShellContext.ExecutionStatusChanged += PowerShellContext_ExecutionStatusChanged; }
public void CanDotSourcePath(string rawFileName) { string fullPath = Path.Combine(ScriptAssetPath, rawFileName); string quotedPath = PowerShellContextService.QuoteEscapeString(fullPath); var psCommand = new System.Management.Automation.PSCommand().AddScript($". {quotedPath}"); using (var pwsh = System.Management.Automation.PowerShell.Create()) { pwsh.Commands = psCommand; pwsh.Invoke(); } }
public DebugEventHandlerService( ILoggerFactory factory, PowerShellContextService powerShellContextService, DebugService debugService, DebugStateService debugStateService, IDebugAdapterServerFacade debugAdapterServer) { _logger = factory.CreateLogger <DebugEventHandlerService>(); _powerShellContextService = powerShellContextService; _debugService = debugService; _debugStateService = debugStateService; _debugAdapterServer = debugAdapterServer; }