public override IEnumerable <CompletionResult> CompleteArgument(string commandName, string parameterName,
                                                                 string wordToComplete, CommandAst commandAst, IDictionary fakeBoundParameters)
 {
     return(CommenceMetadata.Categories.Where(s => s.ToLower().StartsWith(wordToComplete.ToLower()))
            .Select(s => new CompletionResult(base.MapString(s))));
 }
Пример #2
0
        public ParameterSet(CommandAst commandAst, IAzContext azContext = null)
        {
            Validation.CheckArgument(commandAst, $"{nameof(commandAst)} cannot be null.");

            _commandAst = commandAst;
            _azContext  = azContext;

            var parameters            = new List <Parameter>();
            CommandParameterAst param = null;
            Ast arg = null;

            // positional parameters must be before named parameters.
            // This loop will convert them to named parameters.
            // Loop through all the parameters. The first element of CommandElements is the command name, so skip it.
            bool hasSeenNamedParameter      = false;
            bool hasSeenIncompleteParameter = false;

            for (var i = 1; i < commandAst.CommandElements.Count(); ++i)
            {
                var elem = commandAst.CommandElements[i];

                if (elem is CommandParameterAst p)
                {
                    if (hasSeenIncompleteParameter)
                    {
                        throw new CommandLineException("'-' is in the middle of the parameter list.");
                    }

                    hasSeenNamedParameter = true;
                    AddNamedParameter(param, arg);
                    // In case there is a switch parameter, we store the parameter name/value and add them when we see the next pair.
                    param = p;
                    arg   = null;
                }
                else if (AzPredictorConstants.ParameterIndicator == elem?.ToString().Trim().FirstOrDefault())
                {
                    // We have an incomplete command line such as
                    // `New-AzResourceGroup -Name ResourceGroup01 -Location WestUS -`
                    // We'll ignore the incomplete parameter.
                    AddNamedParameter(param, arg);
                    param = null;
                    arg   = null;
                    hasSeenIncompleteParameter = true;
                }
                else
                {
                    if (hasSeenIncompleteParameter || (hasSeenNamedParameter && param == null))
                    {
                        throw new CommandLineException("Positional parameters must be before named parameters.");
                    }

                    if (param == null)
                    {
                        // This is a positional parameter.
                        var pair = BoundParameters.First((pair) => pair.Value.Value == elem);

                        var parameterName  = pair.Key;
                        var parameterValue = CommandLineUtilities.EscapePredictionText(pair.Value.Value.ToString());
                        parameters.Add(new Parameter(parameterName, parameterValue, true));
                        BoundParameters.Remove(pair); // Remove it so that we can match another parameter with the same value.
                    }
                    else
                    {
                        arg = elem;
                        AddNamedParameter(param, arg);
                        param = null;
                        arg   = null;
                    }
                }
            }

            Validation.CheckInvariant <CommandLineException>((param != null) || (arg == null));
            AddNamedParameter(param, arg);

            Parameters = parameters;

            void AddNamedParameter(CommandParameterAst parameter, Ast parameterValue)
            {
                if (parameter != null)
                {
                    var value = parameterValue?.ToString();
                    if (value == null)
                    {
                        value = parameter.Argument?.ToString();
                    }

                    if (value != null)
                    {
                        value = CommandLineUtilities.UnescapePredictionText(value);
                    }

                    parameters.Add(new Parameter(parameter.ParameterName, value, false));
                }
            }
        }
Пример #3
0
        private static ArmResourceName GetResourceNameFromAst(CommandAst commandAst)
        {
            string @namespace = null;
            string type       = null;
            string apiVersion = null;

            var expectedParameter = ResourceKeywordParameter.None;

            foreach (CommandElementAst commandElement in commandAst.CommandElements)
            {
                if (expectedParameter != ResourceKeywordParameter.None &&
                    commandElement is CommandParameterAst parameterAst)
                {
                    if (parameterAst.ParameterName.Is(nameof(NewPSArmResourceCommand.Namespace)))
                    {
                        if (parameterAst.Argument != null)
                        {
                            @namespace = (parameterAst.Argument as StringConstantExpressionAst)?.Value;
                        }
                        else
                        {
                            expectedParameter = ResourceKeywordParameter.Namespace;
                        }

                        continue;
                    }

                    if (parameterAst.ParameterName.Is(nameof(NewPSArmResourceCommand.Type)))
                    {
                        if (parameterAst.Argument != null)
                        {
                            type = (parameterAst.Argument as StringConstantExpressionAst)?.Value;
                        }
                        else
                        {
                            expectedParameter = ResourceKeywordParameter.Type;
                        }

                        continue;
                    }

                    if (parameterAst.ParameterName.Is(nameof(NewPSArmResourceCommand.ApiVersion)))
                    {
                        if (parameterAst.Argument != null)
                        {
                            apiVersion = (parameterAst.Argument as StringConstantExpressionAst)?.Value;
                        }
                        else
                        {
                            expectedParameter = ResourceKeywordParameter.ApiVersion;
                        }

                        continue;
                    }
                }

                switch (expectedParameter)
                {
                case ResourceKeywordParameter.Namespace:
                    @namespace = (commandElement as StringConstantExpressionAst)?.Value;
                    break;

                case ResourceKeywordParameter.Type:
                    type = (commandElement as StringConstantExpressionAst)?.Value;
                    break;

                case ResourceKeywordParameter.ApiVersion:
                    apiVersion = (commandElement as StringConstantExpressionAst)?.Value;
                    break;
                }

                expectedParameter = ResourceKeywordParameter.None;
            }

            return(new ArmResourceName(@namespace, type, apiVersion));
        }
Пример #4
0
        private bool HasRequiredParameters(CommandAst commandAst)
        {
            var bindResult = BindParameters(commandAst);

            return(HasNameParameter(commandAst, bindResult) && HasBodyParameter(commandAst, bindResult));
        }
 /// <inheritdoc/>
 public override void RecordHistory(CommandAst history)
 {
     History = history;
 }
Пример #6
0
        public IEnumerable <CompletionResult> CompleteArgument(string commandName, string parameterName, string wordToComplete, CommandAst commandAst, IDictionary fakeBoundParameters)
        {
            var organizer = new SnippetOrganizer(SnippyOptions.Instance.Value, FileAssociations.Instance.Value);
            var languages = organizer.GetUniqueLanguages();

            return(string.IsNullOrEmpty(wordToComplete)
                ? languages.Select(x => new CompletionResult(x))
                : languages.Where(x => x.StartsWith(wordToComplete)).Select(x => new CompletionResult(x)));
        }
Пример #7
0
        // This method does parameter binding for a very limited set of scenarios, specifically
        // for New-Alias, Set-Alias, Import-Module, and Export-ModuleMember.  It might not even
        // correctly handle these cmdlets if new parameters are added.
        //
        // It also only populates the bound parameters for a limited set of parameters needed
        // for module analysis.
        private static Hashtable DoPsuedoParameterBinding(CommandAst commandAst, string commandName)
        {
            var result = new Hashtable(StringComparer.OrdinalIgnoreCase);

            var parameterBindingInfo = s_parameterBindingInfoTable[commandName].parameterInfo;

            int positionsBound = 0;

            for (int i = 1; i < commandAst.CommandElements.Count; i++)
            {
                var element            = commandAst.CommandElements[i];
                var specifiedParameter = element as CommandParameterAst;
                if (specifiedParameter != null)
                {
                    bool boundParameter     = false;
                    var  specifiedParamName = specifiedParameter.ParameterName;
                    foreach (var parameterInfo in parameterBindingInfo)
                    {
                        if (parameterInfo.name.StartsWith(specifiedParamName, StringComparison.OrdinalIgnoreCase))
                        {
                            if (parameterInfo.position != -1)
                            {
                                positionsBound |= 1 << parameterInfo.position;
                            }

                            var argumentAst = specifiedParameter.Argument;
                            if (argumentAst == null)
                            {
                                argumentAst = commandAst.CommandElements[i] as ExpressionAst;
                                if (argumentAst != null)
                                {
                                    i += 1;
                                }
                            }

                            if (argumentAst != null)
                            {
                                boundParameter             = true;
                                result[parameterInfo.name] =
                                    GetSafeValueVisitor.GetSafeValue(argumentAst, null, GetSafeValueVisitor.SafeValueContext.ModuleAnalysis);
                            }

                            break;
                        }
                    }

                    if (boundParameter || specifiedParameter.Argument != null)
                    {
                        continue;
                    }

                    if (!"PassThru".StartsWith(specifiedParamName, StringComparison.OrdinalIgnoreCase) &&
                        !"Force".StartsWith(specifiedParamName, StringComparison.OrdinalIgnoreCase) &&
                        !"Confirm".StartsWith(specifiedParamName, StringComparison.OrdinalIgnoreCase) &&
                        !"Global".StartsWith(specifiedParamName, StringComparison.OrdinalIgnoreCase) &&
                        !"AsCustomObject".StartsWith(specifiedParamName, StringComparison.OrdinalIgnoreCase) &&
                        !"Verbose".StartsWith(specifiedParamName, StringComparison.OrdinalIgnoreCase) &&
                        !"Debug".StartsWith(specifiedParamName, StringComparison.OrdinalIgnoreCase) &&
                        !"DisableNameChecking".StartsWith(specifiedParamName, StringComparison.OrdinalIgnoreCase) &&
                        !"NoClobber".StartsWith(specifiedParamName, StringComparison.OrdinalIgnoreCase))
                    {
                        // Named parameter, skip the argument (except for specific switch parameters
                        i += 1;
                    }
                }
                else
                {
                    // Positional argument, find which position we want to bind
                    int pos = 0;
                    for (; pos < 10; pos++)
                    {
                        if ((positionsBound & (1 << pos)) == 0)
                        {
                            break;
                        }
                    }

                    positionsBound |= 1 << pos;

                    // Now see if we care (we probably do, but if the user did something odd, like specify too many, then we don't really)
                    foreach (var parameterInfo in parameterBindingInfo)
                    {
                        if (parameterInfo.position == pos)
                        {
                            result[parameterInfo.name] = GetSafeValueVisitor.GetSafeValue(
                                commandAst.CommandElements[i], null,
                                GetSafeValueVisitor.SafeValueContext.ModuleAnalysis);
                        }
                    }
                }
            }

            return(result);
        }
Пример #8
0
 public IEnumerable <CompletionResult> CompleteArgument(string commandName, string parameterName,
                                                        string wordToComplete, CommandAst commandAst, IDictionary fakeBoundParameters)
 {
     return(PrivilegeHelper.ALL_PRIVILEGES
            .Concat(Lsa.ALL_RIGHTS.Keys)
            .Where(p => p.StartsWith(wordToComplete, true, CultureInfo.InvariantCulture))
            .Select(p => ProcessPrivilege(p)));
 }
Пример #9
0
 public override AstVisitAction VisitCommand(CommandAst ast)
 {
     return(Check(ast));
 }
Пример #10
0
            public IEnumerable <CompletionResult> CompleteArgument(string commandName, string parameterName, string wordToComplete, CommandAst commandAst, IDictionary fakeBoundParameters)
            {
                var wc = new WildcardPattern(wordToComplete + "*", WildcardOptions.IgnoreCase);

                return(GetPSMembers().Concat(GetTypeMembers() ?? Array.Empty <string>())
                       .Where(i => wc.IsMatch(i))
                       .Select(i => CreateCompletionResult(i)));
            }
        /// <summary>
        /// Convert a CommandAst known to represent a Pester command and a reference to the scriptfile
        /// it is in into symbol representing a Pester call for code lens
        /// </summary>
        /// <param name="scriptFile">the scriptfile the Pester call occurs in</param>
        /// <param name="pesterCommandAst">the CommandAst representing the Pester call</param>
        /// <returns>a symbol representing the Pester call containing metadata for CodeLens to use</returns>
        private static PesterSymbolReference ConvertPesterAstToSymbolReference(ScriptFile scriptFile, CommandAst pesterCommandAst)
        {
            string            testLine    = scriptFile.GetLine(pesterCommandAst.Extent.StartLineNumber);
            PesterCommandType?commandName = PesterSymbolReference.GetCommandType(pesterCommandAst.GetCommandName());

            if (commandName == null)
            {
                return(null);
            }

            // Search for a name for the test
            // If the test has more than one argument for names, we set it to null
            string testName       = null;
            bool   alreadySawName = false;

            for (int i = 1; i < pesterCommandAst.CommandElements.Count; i++)
            {
                CommandElementAst currentCommandElement = pesterCommandAst.CommandElements[i];

                // Check for an explicit "-Name" parameter
                if (currentCommandElement is CommandParameterAst parameterAst)
                {
                    i++;
                    if (parameterAst.ParameterName == "Name" && i < pesterCommandAst.CommandElements.Count)
                    {
                        testName       = alreadySawName ? null : (pesterCommandAst.CommandElements[i] as StringConstantExpressionAst)?.Value;
                        alreadySawName = true;
                    }
                    continue;
                }

                // Otherwise, if an argument is given with no parameter, we assume it's the name
                // If we've already seen a name, we set the name to null
                if (pesterCommandAst.CommandElements[i] is StringConstantExpressionAst testNameStrAst)
                {
                    testName       = alreadySawName ? null : testNameStrAst.Value;
                    alreadySawName = true;
                }
            }

            return(new PesterSymbolReference(
                       scriptFile,
                       commandName.Value,
                       testLine,
                       testName,
                       pesterCommandAst.Extent
                       ));
        }
Пример #12
0
        /// <summary>
        /// Returns completion results for experimental feature names used as arguments to experimental feature cmdlets.
        /// </summary>
        /// <param name="commandName">The command name.</param>
        /// <param name="parameterName">The parameter name.</param>
        /// <param name="wordToComplete">The word to complete.</param>
        /// <param name="commandAst">The command AST.</param>
        /// <param name="fakeBoundParameters">The fake bound parameters.</param>
        /// <returns>List of Completion Results.</returns>
        public IEnumerable <CompletionResult> CompleteArgument(string commandName, string parameterName, string wordToComplete, CommandAst commandAst, IDictionary fakeBoundParameters)
        {
            if (fakeBoundParameters == null)
            {
                throw PSTraceSource.NewArgumentNullException(nameof(fakeBoundParameters));
            }

            var commandInfo = new CmdletInfo("Get-ExperimentalFeature", typeof(GetExperimentalFeatureCommand));
            var ps          = System.Management.Automation.PowerShell.Create(RunspaceMode.CurrentRunspace)
                              .AddCommand(commandInfo)
                              .AddParameter("Name", wordToComplete + "*");

            HashSet <string> names = new HashSet <string>();
            var results            = ps.Invoke <ExperimentalFeature>();

            foreach (var result in results)
            {
                names.Add(result.Name);
            }

            return(names.OrderBy(name => name).Select(name => new CompletionResult(name, name, CompletionResultType.Text, name)));
        }
Пример #13
0
 public object VisitCommand(CommandAst commandAst) => null;
        /// <summary>
        /// Iterate over command elements to extract local parameter values.
        ///
        /// Store these values by a key
        /// consisting of the suffix of the command + the parameter name.  There are some exceptions, e.g.
        /// credential, location, where the parameter name itself is the key.
        ///
        /// For example, New-AzResourceGroup -Name Hello -Location 'EastUS' will store into local parameters:
        ///   ResourceGroupName => Hello
        ///   Location => 'EastUS'
        /// </summary>
        /// <param name="command">The command ast element</param>
        /// <remarks>
        /// This doesn't support positional parameter.
        /// </remarks>
        private void ExtractLocalParameters(CommandAst command)
        {
            // Azure PowerShell command is in the form of {Verb}-Az{Noun}, e.g. New-AzResource.
            // We need to extract the noun to construct the parameter name.

            var commandName = command.GetCommandName();
            var commandNoun = ParameterValuePredictor.GetAzCommandNoun(commandName)?.ToLower();

            if (commandNoun == null)
            {
                return;
            }

            Dictionary <string, string> commandNounMap = null;

            _commandParamToResourceMap?.TryGetValue(commandNoun, out commandNounMap);

            for (int i = 1; i < command.CommandElements.Count;)
            {
                if (command.CommandElements[i] is CommandParameterAst parameterAst)
                {
                    var    parameterName  = parameterAst.ParameterName.ToLower();
                    string parameterValue = null;

                    // In the form of "-Name:Value"
                    if (parameterAst.Argument != null)
                    {
                        parameterValue = parameterAst.Argument.ToString();
                        ++i;
                    }
                    else if (i + 1 < command.CommandElements.Count)
                    {
                        // We don't support positional parameter.
                        // The next element is either
                        // 1. The value of this parameter name.
                        // 2. This parameter is a switch parameter which doesn't have a value. The next element is a parameter.

                        var nextElement = command.CommandElements[i + 1];

                        if (nextElement is CommandParameterAst)
                        {
                            ++i;
                            continue;
                        }

                        parameterValue = command.CommandElements[i + 1].ToString();
                        i += 2;
                    }

                    var parameterKey = parameterName;

                    if (commandNounMap != null)
                    {
                        if (commandNounMap.TryGetValue(parameterName, out var mappedValue))
                        {
                            parameterKey = mappedValue;
                        }
                    }
                    _cancellationTokenSource?.Cancel();
                    _cancellationTokenSource = new CancellationTokenSource();
                    Task.Run(() =>
                    {
                        this._localParameterValues.AddOrUpdate(parameterKey, parameterValue, (k, v) => parameterValue);
                        if (_cancellationTokenSource.IsCancellationRequested)
                        {
                            throw new OperationCanceledException();
                        }
                        String localParameterValuesJson = JsonSerializer.Serialize <ConcurrentDictionary <string, string> >(_localParameterValues, JsonUtilities.DefaultSerializerOptions);
                        _mutex.WaitOne();
                        try
                        {
                            System.IO.File.WriteAllText(_paramValueHistoryFilePath, localParameterValuesJson);
                        }
                        finally
                        {
                            _mutex.ReleaseMutex();
                        }
                    });
                }
            }
        }
Пример #15
0
 /// <summary>
 /// Condition on the parameter that must be satisfied for the error to be raised.
 /// </summary>
 /// <param name="CmdAst"></param>
 /// <param name="CeAst"></param>
 /// <returns></returns>
 public override bool ParameterCondition(CommandAst CmdAst, CommandElementAst CeAst)
 {
     return(CeAst is CommandParameterAst && String.Equals((CeAst as CommandParameterAst).ParameterName, "AsPlainText", StringComparison.OrdinalIgnoreCase));
 }
Пример #16
0
        /// <summary>
        /// Return true if mandatory parameters are used OR the cmdlet does not exist
        /// </summary>
        /// <param name="cmdAst"></param>
        /// <returns></returns>
        private bool MandatoryParameterExists(CommandAst cmdAst)
        {
            CommandInfo cmdInfo = null;
            List <ParameterMetadata>        mandParams = new List <ParameterMetadata>();
            IEnumerable <CommandElementAst> ceAsts     = null;
            bool returnValue = false;

            #region Predicates

            // Predicate to find ParameterAsts.
            Func <CommandElementAst, bool> foundParamASTs = delegate(CommandElementAst ceAst)
            {
                if (ceAst is CommandParameterAst)
                {
                    return(true);
                }
                return(false);
            };

            #endregion

            #region Compares parameter list and mandatory parameter list.

            cmdInfo = Helper.Instance.GetCommandInfoLegacy(cmdAst.GetCommandName());
            if (cmdInfo == null || (cmdInfo.CommandType != System.Management.Automation.CommandTypes.Cmdlet))
            {
                return(true);
            }

            // ignores if splatted variable is used
            if (Helper.Instance.HasSplattedVariable(cmdAst))
            {
                return(true);
            }

            // Gets parameters from command elements.
            ceAsts = cmdAst.CommandElements.Where <CommandElementAst>(foundParamASTs);

            // Gets mandatory parameters from cmdlet.
            // If cannot find any mandatory parameter, it's not necessary to do a further check for current cmdlet.
            try
            {
                int noOfParamSets = cmdInfo.ParameterSets.Count;
                foreach (ParameterMetadata pm in cmdInfo.Parameters.Values)
                {
                    int count = 0;

                    if (pm.Attributes.Count < noOfParamSets)
                    {
                        continue;
                    }

                    foreach (Attribute attr in pm.Attributes)
                    {
                        if (!(attr is ParameterAttribute))
                        {
                            continue;
                        }
                        if (((ParameterAttribute)attr).Mandatory)
                        {
                            count += 1;
                        }
                    }

                    if (count >= noOfParamSets)
                    {
                        mandParams.Add(pm);
                    }
                }
            }
            catch (Exception)
            {
                // For cases like cmd.exe. Also for runtime exception
                return(true);
            }

            if (mandParams.Count() == 0 || Helper.Instance.PositionalParameterUsed(cmdAst))
            {
                returnValue = true;
            }
            else
            {
                // Compares parameter list and mandatory parameter list.
                foreach (CommandElementAst ceAst in ceAsts)
                {
                    CommandParameterAst cpAst = (CommandParameterAst)ceAst;
                    if (mandParams.Count <ParameterMetadata>(item =>
                                                             item.Name.Equals(cpAst.ParameterName, StringComparison.OrdinalIgnoreCase)) > 0)
                    {
                        returnValue = true;
                        break;
                    }
                }
            }

            #endregion

            return(returnValue);
        }
Пример #17
0
 /// <summary>
 /// Determines if the command is a document definition.
 /// </summary>
 private bool IsDefinition(CommandAst commandAst)
 {
     return(_Comparer.Equals(commandAst.GetCommandName(), DOCUMENT_KEYWORD));
 }
Пример #18
0
        /// <inheritdoc/>
        /// <remarks>
        /// Tries to get the suggestions for the user input from the command history. If that doesn't find
        /// <paramref name="suggestionCount"/> suggestions, it'll fallback to find the suggestion regardless of command history.
        /// </remarks>
        public virtual CommandLineSuggestion GetSuggestion(PredictionContext context, int suggestionCount, int maxAllowedCommandDuplicate, CancellationToken cancellationToken)
        {
            Validation.CheckArgument(context, $"{nameof(context)} cannot be null");
            Validation.CheckArgument <ArgumentOutOfRangeException>(suggestionCount > 0, $"{nameof(suggestionCount)} must be larger than 0.");
            Validation.CheckArgument <ArgumentOutOfRangeException>(maxAllowedCommandDuplicate > 0, $"{nameof(maxAllowedCommandDuplicate)} must be larger than 0.");

            var        relatedAsts = context.RelatedAsts;
            CommandAst commandAst  = null;

            for (var i = relatedAsts.Count - 1; i >= 0; --i)
            {
                if (relatedAsts[i] is CommandAst c)
                {
                    commandAst = c;
                    break;
                }
            }

            if (commandAst == null)
            {
                return(null);
            }

            var commandName = commandAst.GetCommandName();

            if (string.IsNullOrWhiteSpace(commandName))
            {
                return(null);
            }

            ParameterSet inputParameterSet = null;

            try
            {
                inputParameterSet = new ParameterSet(commandAst, _azContext);
            }
            catch when(!IsRecognizedCommand(commandName))
            {
                // We only ignore the exception when the command name is not supported.
                // We want to collect the telemetry about the exception how common it is for the format we don't support.
                return(null);
            }

            cancellationToken.ThrowIfCancellationRequested();

            // We want to show a survey/feedback cmdlet at the end of the suggestion list. We try to find one less
            // suggestions to make room for that cmdlet and avoid too much computation.
            // But if only one suggestion is requested, we don't replace it with the survey cmdlets.
            var suggestionFromPredictorCount = (suggestionCount == 1) ? 1 : (suggestionCount - 1);

            var rawUserInput               = context.InputAst.ToString();
            var presentCommands            = new Dictionary <string, int>();
            var commandBasedPredictor      = _commandBasedPredictor;
            var commandToRequestPrediction = _commandToRequestPrediction;

            var result = commandBasedPredictor?.Item2?.GetSuggestion(commandName,
                                                                     inputParameterSet,
                                                                     rawUserInput,
                                                                     presentCommands,
                                                                     suggestionFromPredictorCount,
                                                                     maxAllowedCommandDuplicate,
                                                                     cancellationToken);

            if ((result != null) && (result.Count > 0))
            {
                var suggestionSource = SuggestionSource.PreviousCommand;

                if (string.Equals(commandToRequestPrediction, commandBasedPredictor?.Item1, StringComparison.Ordinal))
                {
                    suggestionSource = SuggestionSource.CurrentCommand;
                }

                for (var i = 0; i < result.Count; ++i)
                {
                    result.UpdateSuggestionSource(i, suggestionSource);
                }
            }

            if ((result == null) || (result.Count < suggestionFromPredictorCount))
            {
                var fallbackPredictor        = _fallbackPredictor;
                var suggestionCountToRequest = (result == null) ? suggestionFromPredictorCount : suggestionFromPredictorCount - result.Count;
                var resultsFromFallback      = fallbackPredictor?.GetSuggestion(commandName,
                                                                                inputParameterSet,
                                                                                rawUserInput,
                                                                                presentCommands,
                                                                                suggestionCountToRequest,
                                                                                maxAllowedCommandDuplicate,
                                                                                cancellationToken);

                if ((result == null) && (resultsFromFallback != null))
                {
                    result = resultsFromFallback;

                    for (var i = 0; i < result.Count; ++i)
                    {
                        result.UpdateSuggestionSource(i, SuggestionSource.StaticCommands);
                    }
                }
                else if ((resultsFromFallback != null) && (resultsFromFallback.Count > 0))
                {
                    for (var i = 0; i < resultsFromFallback.Count; ++i)
                    {
                        result.AddSuggestion(resultsFromFallback.PredictiveSuggestions[i], resultsFromFallback.SourceTexts[i], SuggestionSource.StaticCommands);
                    }
                }
            }

            if (suggestionCount > 1)
            {
                // Add the survey/feedback cmdlet at the end if the user isn't typing it.
                bool isSurveyCmdletFound = false;

                if (result != null)
                {
                    foreach (var predictiveCommand in result.SourceTexts)
                    {
                        if (string.Equals(predictiveCommand, _surveyCmdlets[_azContext.Cohort].Command, StringComparison.Ordinal))
                        {
                            isSurveyCmdletFound = true;
                            break;
                        }
                    }
                }
                else
                {
                    result = new CommandLineSuggestion();
                }

                if (!isSurveyCmdletFound)
                {
                    var toAddCmdlet      = _surveyCmdlets[_azContext.Cohort].Command;
                    var toAddDescription = _surveyCmdlets[_azContext.Cohort].Description;
                    result.AddSuggestion(new PredictiveSuggestion($"{toAddCmdlet} # {toAddDescription}", toAddCmdlet), toAddCmdlet, SuggestionSource.StaticCommands);
                }
            }

            return(result);
        }
Пример #19
0
        // Visit one the other variations:
        //  - Dotting scripts
        //  - Setting aliases
        //  - Importing modules
        //  - Exporting module members
        public override AstVisitAction VisitCommand(CommandAst commandAst)
        {
            string commandName =
                commandAst.GetCommandName() ??
                GetSafeValueVisitor.GetSafeValue(commandAst.CommandElements[0], null, GetSafeValueVisitor.SafeValueContext.ModuleAnalysis) as string;

            if (commandName == null)
            {
                return(AstVisitAction.SkipChildren);
            }

            // They are trying to dot a script
            if (commandAst.InvocationOperator == TokenKind.Dot)
            {
                // . Foo-Bar4.ps1
                // . $psScriptRoot\Foo-Bar.ps1 -Bing Baz
                // . ""$psScriptRoot\Support Files\Foo-Bar2.ps1"" -Bing Baz
                // . '$psScriptRoot\Support Files\Foo-Bar3.ps1' -Bing Baz

                DiscoveredModules.Add(
                    new RequiredModuleInfo {
                    Name = commandName, CommandsToPostFilter = new List <string>()
                });
                ModuleIntrinsics.Tracer.WriteLine("Module dots {0}", commandName);
            }

            // They are setting an alias.
            if (string.Equals(commandName, "New-Alias", StringComparison.OrdinalIgnoreCase) ||
                string.Equals(commandName, "Microsoft.PowerShell.Utility\\New-Alias", StringComparison.OrdinalIgnoreCase) ||
                string.Equals(commandName, "Set-Alias", StringComparison.OrdinalIgnoreCase) ||
                string.Equals(commandName, "Microsoft.PowerShell.Utility\\Set-Alias", StringComparison.OrdinalIgnoreCase) ||
                string.Equals(commandName, "nal", StringComparison.OrdinalIgnoreCase) ||
                string.Equals(commandName, "sal", StringComparison.OrdinalIgnoreCase))
            {
                // Set-Alias Foo-Bar5 Foo-Bar
                // Set-Alias -Name Foo-Bar6 -Value Foo-Bar
                // sal Foo-Bar7 Foo-Bar
                // sal -Value Foo-Bar -Name Foo-Bar8

                var boundParameters = DoPsuedoParameterBinding(commandAst, commandName);

                var name = boundParameters["Name"] as string;
                if (!string.IsNullOrEmpty(name))
                {
                    var value = boundParameters["Value"] as string;
                    if (!string.IsNullOrEmpty(value))
                    {
                        // These aren't stored in DiscoveredExports, as they are only
                        // exported after the user calls Export-ModuleMember.
                        DiscoveredAliases[name] = value;
                        ModuleIntrinsics.Tracer.WriteLine("Module defines alias: {0} = {1}", name, value);
                    }
                }

                return(AstVisitAction.SkipChildren);
            }

            // They are importing a module
            if (string.Equals(commandName, "Import-Module", StringComparison.OrdinalIgnoreCase) ||
                string.Equals(commandName, "ipmo", StringComparison.OrdinalIgnoreCase))
            {
                // Import-Module Module1
                // Import-Module Module2 -Function Foo-Module2*, Foo-Module2Second* -Cmdlet Foo-Module2Cmdlet,Foo-Module2Cmdlet*
                // Import-Module Module3 -Function Foo-Module3Command1, Foo-Module3Command2
                // Import-Module Module4,
                //    Module5
                // Import-Module -Name Module6,
                //    Module7 -Global

                var boundParameters = DoPsuedoParameterBinding(commandAst, commandName);

                List <string> commandsToPostFilter = new List <string>();

                Action <string> onEachCommand = importedCommandName => commandsToPostFilter.Add(importedCommandName);

                // Process any exports from the module that we determine from
                // the -Function, -Cmdlet, or -Alias parameters
                ProcessCmdletArguments(boundParameters["Function"], onEachCommand);
                ProcessCmdletArguments(boundParameters["Cmdlet"], onEachCommand);
                ProcessCmdletArguments(boundParameters["Alias"], onEachCommand);

                // Now, go through all of the discovered modules on Import-Module
                // and register them for deeper investigation.
                Action <string> onEachModule = moduleName =>
                {
                    ModuleIntrinsics.Tracer.WriteLine("Discovered module import: {0}", moduleName);
                    DiscoveredModules.Add(
                        new RequiredModuleInfo
                    {
                        Name = moduleName,
                        CommandsToPostFilter = commandsToPostFilter
                    });
                };
                ProcessCmdletArguments(boundParameters["Name"], onEachModule);

                return(AstVisitAction.SkipChildren);
            }

            // They are exporting a module member
            if (string.Equals(commandName, "Export-ModuleMember", StringComparison.OrdinalIgnoreCase) ||
                string.Equals(commandName, "Microsoft.PowerShell.Core\\Export-ModuleMember", StringComparison.OrdinalIgnoreCase) ||
                string.Equals(commandName, "$script:ExportModuleMember", StringComparison.OrdinalIgnoreCase))
            {
                // Export-ModuleMember *
                // Export-ModuleMember Exported-UnNamedModuleMember
                // Export-ModuleMember -Function Exported-FunctionModuleMember1, Exported-FunctionModuleMember2 -Cmdlet Exported-CmdletModuleMember `
                //    -Alias Exported-AliasModuleMember
                // & $script:ExportModuleMember -Function (...)

                var boundParameters = DoPsuedoParameterBinding(commandAst, commandName);

                Action <string> onEachFunction = exportedCommandName =>
                {
                    DiscoveredCommandFilters.Add(exportedCommandName);
                    ModuleIntrinsics.Tracer.WriteLine("Discovered explicit export: {0}", exportedCommandName);

                    // If the export doesn't contain wildcards, then add it to the
                    // discovered commands as well. It is likely that they created
                    // the command dynamically
                    if ((!WildcardPattern.ContainsWildcardCharacters(exportedCommandName)) &&
                        (!DiscoveredExports.Contains(exportedCommandName)))
                    {
                        DiscoveredExports.Add(exportedCommandName);
                    }
                };
                ProcessCmdletArguments(boundParameters["Function"], onEachFunction);
                ProcessCmdletArguments(boundParameters["Cmdlet"], onEachFunction);

                Action <string> onEachAlias = exportedAlias =>
                {
                    DiscoveredCommandFilters.Add(exportedAlias);

                    // If the export doesn't contain wildcards, then add it to the
                    // discovered commands as well. It is likely that they created
                    // the command dynamically
                    if (!WildcardPattern.ContainsWildcardCharacters(exportedAlias))
                    {
                        DiscoveredAliases[exportedAlias] = null;
                    }
                };
                ProcessCmdletArguments(boundParameters["Alias"], onEachAlias);

                return(AstVisitAction.SkipChildren);
            }

            // They are exporting a module member using our advanced 'public' function
            // that we've presented in many demos
            if ((string.Equals(commandName, "public", StringComparison.OrdinalIgnoreCase)) &&
                (commandAst.CommandElements.Count > 2))
            {
                // public function Publicly-ExportedFunction
                // public alias Publicly-ExportedAlias
                string publicCommandName = commandAst.CommandElements[2].ToString().Trim();
                DiscoveredExports.Add(publicCommandName);
                DiscoveredCommandFilters.Add(publicCommandName);
            }

            return(AstVisitAction.SkipChildren);
        }
Пример #20
0
        /// <inheritdoc/>
        public virtual void RecordHistory(CommandAst history)
        {
            Validation.CheckArgument(history, $"{nameof(history)} cannot be null.");

            _parameterValuePredictor.ProcessHistoryCommand(history);
        }
Пример #21
0
 /// <summary>
 /// Determines if the command is a rule definition.
 /// </summary>
 private bool IsRule(CommandAst commandAst)
 {
     return(_Comparer.Equals(commandAst.GetCommandName(), RULE_KEYWORD));
 }
Пример #22
0
 /// <summary>
 /// GetError: Retrieves the error message.
 /// </summary>
 /// <returns></returns>
 public abstract string GetError(string FileName, CommandAst CmdAst);
Пример #23
0
        private void ConvertCommand(CommandAst commandAst, bool isTrustedInput)
        {
            // First need command name.
            var commandName = GetCommandName(commandAst.CommandElements[0], isTrustedInput);

            var command = new Command(commandName, isScript: false, useLocalScope: _createLocalScope);

            // Handle redirections, if any (there can really be just 0 or 1).
            if (commandAst.Redirections.Count > 0)
            {
                Diagnostics.Assert(commandAst.Redirections.Count == 1, "only 1 kind of redirection is supported");
                Diagnostics.Assert(commandAst.Redirections[0] is MergingRedirectionAst, "unexpected redirection type");

                PipelineResultTypes toType = PipelineResultTypes.Output;
                PipelineResultTypes fromType;
                switch (commandAst.Redirections[0].FromStream)
                {
                case RedirectionStream.Error:
                    fromType = PipelineResultTypes.Error;
                    break;

                case RedirectionStream.Warning:
                    fromType = PipelineResultTypes.Warning;
                    break;

                case RedirectionStream.Verbose:
                    fromType = PipelineResultTypes.Verbose;
                    break;

                case RedirectionStream.Debug:
                    fromType = PipelineResultTypes.Debug;
                    break;

                case RedirectionStream.Information:
                    fromType = PipelineResultTypes.Information;
                    break;

                case RedirectionStream.All:
                    fromType = PipelineResultTypes.All;
                    break;

                default:
                    // Default to Error->Output to be compatible with V2.
                    fromType = PipelineResultTypes.Error;
                    break;
                }

                command.MergeMyResults(fromType, toType);
            }

            _powershell.AddCommand(command);

            // Now the parameters and arguments.
            foreach (var ast in commandAst.CommandElements.Skip(1))
            {
                var exprAst = ast as ExpressionAst;
                if (exprAst != null)
                {
                    VariableExpressionAst variableAst = null;

                    var usingExprAst = ast as UsingExpressionAst;
                    if (usingExprAst != null)
                    {
                        string usingAstKey = PsUtils.GetUsingExpressionKey(usingExprAst);
                        object usingValue  = _usingValueMap[usingAstKey];
                        variableAst = usingExprAst.SubExpression as VariableExpressionAst;
                        if (variableAst != null && variableAst.Splatted)
                        {
                            // Support the splatting of a dictionary
                            var parameters = usingValue as System.Collections.IDictionary;
                            if (parameters != null)
                            {
                                _powershell.AddParameters(parameters);
                            }
                            else
                            {
                                // Support the splatting of an array
                                var arguments = usingValue as System.Collections.IEnumerable;
                                if (arguments != null)
                                {
                                    foreach (Object argument in arguments)
                                    {
                                        _powershell.AddArgument(argument);
                                    }
                                }
                                else
                                {
                                    // Splat the object directly.
                                    _powershell.AddArgument(usingValue);
                                }
                            }
                        }
                        else
                        {
                            _powershell.AddArgument(usingValue);
                        }
                        continue;
                    }

                    variableAst = ast as VariableExpressionAst;
                    if (variableAst != null && variableAst.Splatted)
                    {
                        GetSplattedVariable(variableAst);
                    }
                    else
                    {
                        var    constantExprAst = ast as ConstantExpressionAst;
                        object argument;
                        if (constantExprAst != null && LanguagePrimitives.IsNumeric(LanguagePrimitives.GetTypeCode(constantExprAst.StaticType)))
                        {
                            var commandArgumentText = constantExprAst.Extent.Text;
                            argument = constantExprAst.Value;
                            if (!commandArgumentText.Equals(constantExprAst.Value.ToString(), StringComparison.Ordinal))
                            {
                                // The wrapped number will actually return a PSObject which could end holding a reference to
                                // a typetable, making the object runspace specific.  We should find a better way to avoid
                                // any possibility of sharing problems, though this is unlikely to cause problems.
                                argument = ParserOps.WrappedNumber(argument, commandArgumentText);
                            }
                        }
                        else
                        {
                            if (!isTrustedInput)
                            {
                                try
                                {
                                    argument = GetSafeValueVisitor.GetSafeValue(exprAst, _context, GetSafeValueVisitor.SafeValueContext.GetPowerShell);
                                }
                                catch (System.Exception)
                                {
                                    throw new ScriptBlockToPowerShellNotSupportedException(
                                              "CantConvertWithDynamicExpression",
                                              null,
                                              AutomationExceptions.CantConvertWithDynamicExpression,
                                              exprAst.Extent.Text);
                                }
                            }
                            else
                            {
                                argument = GetExpressionValue(exprAst, isTrustedInput);
                            }
                        }
                        _powershell.AddArgument(argument);
                    }
                }
                else
                {
                    AddParameter((CommandParameterAst)ast, isTrustedInput);
                }
            }
        }
Пример #24
0
 /// <summary>
 /// Condition on the cmdlet that must be satisfied for the error to be raised
 /// </summary>
 /// <param name="CmdAst"></param>
 /// <returns></returns>
 public abstract bool CommandCondition(CommandAst CmdAst);
        /// <summary>
        /// Implementations CompleteArgument function of the <see cref="IArgumentCompleter"/>.
        /// </summary>
        public IEnumerable <CompletionResult> CompleteArgument(string commandName, string parameterName, string wordToComplete, CommandAst commandAst, IDictionary fakeBoundParameters)
        {
            IEnumerable <string> names = GetEnvironments().Where(env => env.ToLower().StartsWith(wordToComplete.ToLower()));

            foreach (string name in names)
            {
                yield return(new CompletionResult(name, name, CompletionResultType.ParameterValue, name));
            }
        }
Пример #26
0
 /// <summary>
 /// Condition on the parameter that must be satisfied for the error to be raised.
 /// </summary>
 /// <param name="CmdAst"></param>
 /// <param name="CeAst"></param>
 /// <returns></returns>
 public abstract bool ParameterCondition(CommandAst CmdAst, CommandElementAst CeAst);
Пример #27
0
        /// <summary>
        /// CompleteArgument.
        /// </summary>
        public IEnumerable <CompletionResult> CompleteArgument(string commandName, string parameterName, string wordToComplete, CommandAst commandAst, IDictionary fakeBoundParameters)
        {
            var wordToCompletePattern = WildcardPattern.Get(string.IsNullOrWhiteSpace(wordToComplete) ? "*" : wordToComplete + "*", WildcardOptions.IgnoreCase);

            foreach (var edition in Utils.AllowedEditionValues)
            {
                if (wordToCompletePattern.IsMatch(edition))
                {
                    yield return(new CompletionResult(edition, edition, CompletionResultType.Text, edition));
                }
            }
        }
Пример #28
0
 /// <summary>
 /// Condition on the cmdlet that must be satisfied for the error to be raised
 /// </summary>
 /// <param name="CmdAst"></param>
 /// <returns></returns>
 public override bool CommandCondition(CommandAst CmdAst)
 {
     return(true);
 }
        /// <summary>
        /// Offers the names of types loaded into the session for argument completion.
        /// </summary>
        public IEnumerable <CompletionResult> CompleteArgument(string commandName, string parameterName, string wordToComplete, CommandAst commandAst, IDictionary fakeBoundParameters)
        {
            var wc    = new WildcardPattern(wordToComplete?.Trim("\"'()[]".ToCharArray()) + "*", WildcardOptions.IgnoreCase);
            var types = AppDomain.CurrentDomain.GetAssemblies()
                        .SelectMany(a => a.GetTypes())
                        .Where(t => t.IsPublic)
                        .Select(t => (t.FullName, t.Name))
                        .Where(n => wc.IsMatch(n.Name) || wc.IsMatch(n.FullName));

            foreach (var(FullName, Name) in types)
            {
                string safeOutput = FullName.Contains(" ") ? "'" + CodeGeneration.EscapeSingleQuotedStringContent(FullName) + "'" : FullName;
                yield return(new CompletionResult(safeOutput, FullName, CompletionResultType.Type, FullName));
            }
        }
Пример #30
0
        /// <summary>
        /// Offers argument completion for IPv4 address values.
        /// </summary>
        /// <param name="commandName">Unused</param>
        /// <param name="parameterName">Unused</param>
        /// <param name="wordToComplete">IP addresses will be matched against any value in this string.
        /// The closer to the intended IP address, the more accurate the argument completion results will be.</param>
        /// <param name="commandAst">Unused</param>
        /// <param name="fakeBoundParameters">Unused</param>
        /// <returns></returns>
        public IEnumerable <CompletionResult> CompleteArgument(string commandName, string parameterName, string wordToComplete, CommandAst commandAst, IDictionary fakeBoundParameters)
        {
            wordToComplete        += "*";
            string[]? octetStrings = wordToComplete?.Split('.');
            if (octetStrings?.Length > 4)
            {
                yield break;
            }
            IEnumerable <byte>[] ranges = new IEnumerable <byte> [4];
            for (int i = 0; i < 4; i++)
            {
                string?octetString = octetStrings?.Length > i ? octetStrings[i] : null;
                ranges[i] = CompleteOctet(octetString);
            }


            decimal returned = 0;

            foreach (byte firstOctet in ranges[0])
            {
                foreach (byte secondOctet in ranges[1])
                {
                    foreach (byte thirdOctet in ranges[2])
                    {
                        foreach (byte fourthOctet in ranges[3])
                        {
                            var ip = new IPAddress(new[] { firstOctet, secondOctet, thirdOctet, fourthOctet }).ToString();
                            yield return(new CompletionResult(ip, ip, CompletionResultType.ParameterValue, ip));

                            if (returned++ > MaximumReturnCount)
                            {
                                yield break;
                            }
                        }
                    }
                }
            }
        }