Пример #1
0
        /// <summary>
        /// Gets all aliases found in the runspace
        /// </summary>
        private async Task GetAliases()
        {
            if (_areAliasesLoaded)
            {
                return;
            }

            try
            {
                RunspaceHandle runspaceHandle =
                    await _powerShellContext.GetRunspaceHandle(
                        new CancellationTokenSource(DefaultWaitTimeoutMilliseconds).Token);

                CommandInvocationIntrinsics invokeCommand = runspaceHandle.Runspace.SessionStateProxy.InvokeCommand;
                IEnumerable <CommandInfo>   aliases       = invokeCommand.GetCommands("*", CommandTypes.Alias, true);

                runspaceHandle.Dispose();

                foreach (AliasInfo aliasInfo in aliases)
                {
                    if (!_cmdletToAliasDictionary.ContainsKey(aliasInfo.Definition))
                    {
                        _cmdletToAliasDictionary.Add(aliasInfo.Definition, new List <String> {
                            aliasInfo.Name
                        });
                    }
                    else
                    {
                        _cmdletToAliasDictionary[aliasInfo.Definition].Add(aliasInfo.Name);
                    }

                    _aliasToCmdletDictionary.Add(aliasInfo.Name, aliasInfo.Definition);
                }

                _areAliasesLoaded = true;
            }
            catch (PSNotSupportedException e)
            {
                _logger.Write(
                    LogLevel.Warning,
                    $"Caught PSNotSupportedException while attempting to get aliases from remote session:\n\n{e.ToString()}");

                // Prevent the aliases from being fetched again - no point if the remote doesn't support InvokeCommand.
                _areAliasesLoaded = true;
            }
            catch (TaskCanceledException)
            {
                // The wait for a RunspaceHandle has timed out, skip aliases for now
            }
        }
Пример #2
0
        /// <summary>
        /// Gets completions for the symbol found in the Ast at
        /// the given file offset.
        /// </summary>
        /// <param name="scriptAst">
        /// The Ast which will be traversed to find a completable symbol.
        /// </param>
        /// <param name="currentTokens">
        /// The array of tokens corresponding to the scriptAst parameter.
        /// </param>
        /// <param name="fileOffset">
        /// The 1-based file offset at which a symbol will be located.
        /// </param>
        /// <param name="powerShellContext">
        /// The PowerShellContext to use for gathering completions.
        /// </param>
        /// <param name="logger">An ILogger implementation used for writing log messages.</param>
        /// <param name="cancellationToken">
        /// A CancellationToken to cancel completion requests.
        /// </param>
        /// <returns>
        /// A CommandCompletion instance that contains completions for the
        /// symbol at the given offset.
        /// </returns>
        static public async Task <CommandCompletion> GetCompletions(
            Ast scriptAst,
            Token[] currentTokens,
            int fileOffset,
            PowerShellContext powerShellContext,
            ILogger logger,
            CancellationToken cancellationToken)
        {
            var type   = scriptAst.Extent.StartScriptPosition.GetType();
            var method =
#if CoreCLR
                type.GetMethod(
                    "CloneWithNewOffset",
                    BindingFlags.Instance | BindingFlags.NonPublic);
#else
                type.GetMethod(
                    "CloneWithNewOffset",
                    BindingFlags.Instance | BindingFlags.NonPublic,
                    null,
                    new[] { typeof(int) }, null);
#endif

            IScriptPosition cursorPosition =
                (IScriptPosition)method.Invoke(
                    scriptAst.Extent.StartScriptPosition,
                    new object[] { fileOffset });

            logger.Write(
                LogLevel.Verbose,
                string.Format(
                    "Getting completions at offset {0} (line: {1}, column: {2})",
                    fileOffset,
                    cursorPosition.LineNumber,
                    cursorPosition.ColumnNumber));

            CommandCompletion commandCompletion = null;
            if (powerShellContext.IsDebuggerStopped)
            {
                PSCommand command = new PSCommand();
                command.AddCommand("TabExpansion2");
                command.AddParameter("Ast", scriptAst);
                command.AddParameter("Tokens", currentTokens);
                command.AddParameter("PositionOfCursor", cursorPosition);
                command.AddParameter("Options", null);

                PSObject outputObject =
                    (await powerShellContext.ExecuteCommand <PSObject>(command, false, false))
                    .FirstOrDefault();

                if (outputObject != null)
                {
                    ErrorRecord errorRecord = outputObject.BaseObject as ErrorRecord;
                    if (errorRecord != null)
                    {
                        logger.WriteException(
                            "Encountered an error while invoking TabExpansion2 in the debugger",
                            errorRecord.Exception);
                    }
                    else
                    {
                        commandCompletion = outputObject.BaseObject as CommandCompletion;
                    }
                }
            }
            else if (powerShellContext.CurrentRunspace.Runspace.RunspaceAvailability ==
                     RunspaceAvailability.Available)
            {
                using (RunspaceHandle runspaceHandle = await powerShellContext.GetRunspaceHandle(cancellationToken))
                    using (PowerShell powerShell = PowerShell.Create())
                    {
                        powerShell.Runspace = runspaceHandle.Runspace;

                        Stopwatch stopwatch = new Stopwatch();
                        stopwatch.Start();

                        commandCompletion =
                            CommandCompletion.CompleteInput(
                                scriptAst,
                                currentTokens,
                                cursorPosition,
                                null,
                                powerShell);

                        stopwatch.Stop();

                        logger.Write(LogLevel.Verbose, $"IntelliSense completed in {stopwatch.ElapsedMilliseconds}ms.");
                    }
            }

            return(commandCompletion);
        }