Beispiel #1
0
        // TODO: BRING THIS BACK
        /// <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>
        public static async Task <CommandCompletion> GetCompletionsAsync(
            Ast scriptAst,
            Token[] currentTokens,
            int fileOffset,
            PowerShellContextService powerShellContext,
            ILogger logger,
            CancellationToken cancellationToken)
        {
            if (!s_completionHandle.Wait(0))
            {
                return(null);
            }

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

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

                if (!powerShellContext.IsAvailable)
                {
                    return(null);
                }

                var stopwatch = new Stopwatch();

                // If the current runspace is out of process we can use
                // CommandCompletion.CompleteInput because PSReadLine won't be taking up the
                // main runspace.
                if (powerShellContext.IsCurrentRunspaceOutOfProcess())
                {
                    using (RunspaceHandle runspaceHandle = await powerShellContext.GetRunspaceHandleAsync(cancellationToken))
                        using (System.Management.Automation.PowerShell powerShell = System.Management.Automation.PowerShell.Create())
                        {
                            powerShell.Runspace = runspaceHandle.Runspace;
                            stopwatch.Start();
                            try
                            {
                                return(CommandCompletion.CompleteInput(
                                           scriptAst,
                                           currentTokens,
                                           cursorPosition,
                                           options: null,
                                           powershell: powerShell));
                            }
                            finally
                            {
                                stopwatch.Stop();
                                logger.LogTrace($"IntelliSense completed in {stopwatch.ElapsedMilliseconds}ms.");
                            }
                        }
                }

                CommandCompletion commandCompletion = null;
                await powerShellContext.InvokeOnPipelineThreadAsync(
                    pwsh =>
                {
                    stopwatch.Start();
                    commandCompletion = CommandCompletion.CompleteInput(
                        scriptAst,
                        currentTokens,
                        cursorPosition,
                        options: null,
                        powershell: pwsh);
                });

                stopwatch.Stop();
                logger.LogTrace($"IntelliSense completed in {stopwatch.ElapsedMilliseconds}ms.");

                return(commandCompletion);
            }
            finally
            {
                s_completionHandle.Release();
            }
        }