/// <summary>
        /// Parse the arguments to process switch parameters and parameters without a value
        /// specified. We always eat the error (such as parameter without value) and continue
        /// to do the binding.
        /// </summary>
        /// 
        /// <param name="paramAstAtCursor">
        /// For parameter completion, if the cursor is pointing at a CommandParameterAst, we
        /// should not try exact matching for that CommandParameterAst. This is to handle the
        /// following case:
        ///     Add-Computer -domain(tab)
        /// Add-Computer has an alias "Domain" that can exactly match this partial input, but
        /// since the user is typing 'tab', the partial input 'domain' should not be considered
        /// as an exact match. In this case, we don't try exact matching when calling 
        /// GetMatchingParameter(..) so as to preserve other possibilities.
        /// </param>
        private bool ParseParameterArguments(CommandParameterAst paramAstAtCursor)
        {
            if (!_bindingEffective)
                return _bindingEffective;

            var result = new Collection<AstParameterArgumentPair>();
            for (int index = 0; index < _arguments.Count; index++)
            {
                AstParameterArgumentPair argument = _arguments[index];
                if (!argument.ParameterSpecified || argument.ArgumentSpecified)
                {
                    // Add the positional/named arguments back
                    result.Add(argument);
                    continue;
                }

                Diagnostics.Assert(argument.ParameterSpecified && !argument.ArgumentSpecified,
                    "At this point, the parameters should have no arguments");

                //Now check the parameter name with the bindable parameters
                string parameterName = argument.ParameterName;
                MergedCompiledCommandParameter matchingParameter = null;

                try
                {
                    bool tryExactMatching = argument.Parameter != paramAstAtCursor;
                    matchingParameter = _bindableParameters.GetMatchingParameter(parameterName, false, tryExactMatching, null);
                }
                catch (ParameterBindingException e)
                {
                    // The parameterName is resolved to multiple parameters. The most possible scenario for this
                    // would be the user typping tab to complete a parameter. In this case, we can ignore this 
                    // parameter safely.

                    // If the next item is a pure argument, we skip it so that it doesn't get bound
                    // positionally.
                    if (index < _arguments.Count - 1)
                    {
                        AstParameterArgumentPair nextArg = _arguments[index + 1];
                        if (!nextArg.ParameterSpecified && nextArg.ArgumentSpecified)
                        {
                            index++;
                        }
                    }

                    _ambiguousParameters.Add(argument.Parameter);
                    _bindingExceptions[argument.Parameter] = e;

                    continue;
                }

                if (matchingParameter == null)
                {
                    // The parameter cannot be found. The reason could be:
                    // 1. It's a bynamic parameter, and we cannot retrieve the ParameterMetadata for it
                    //    at this point, since it's pseudo binding.
                    // 2. The spelling of this parameter is wrong.
                    // We can simply ignore this parameter, but the issue is what to do with the argument
                    // following this parameter (if there is an argument following it). There are two cases:
                    // 1. This parameter is supposed to be a switch parameter. Then the argument following it
                    //    should NOT be ignored.
                    // 2. This parameter is supposed to take an argument. Then the following argument should
                    //    also be ignored
                    // We check the next item. If it's a pure argument, we give up the binding, because we don't
                    // know how to deal with it (ignore it? keep it?), and it will affect the accuracy of our
                    // parameter set resolution.
                    if (index < _arguments.Count - 1)
                    {
                        AstParameterArgumentPair nextArg = _arguments[index + 1];

                        // If the next item is a pure argument, we give up the pseudo binding.
                        if (!nextArg.ParameterSpecified && nextArg.ArgumentSpecified)
                        {
                            // Testing paramsAstAtCursor ensures we only give up during tab completion,
                            // otherwise we know this is a missing parameter.
                            if (paramAstAtCursor != null)
                            {
                                // Do not use the parsed arguments
                                _arguments = null;
                                return false;
                            }
                            else
                            {
                                // Otherwise, skip the next argument
                                index++;
                                _parametersNotFound.Add(argument.Parameter);
                                continue;
                            }
                        }
                    }

                    // If the next item is not a pure argument, or the current parameter is the last item,
                    // ignore this parameter and carry on with the binding
                    _parametersNotFound.Add(argument.Parameter);
                    continue;
                }

                // Check if it's SwitchParameter
                if (matchingParameter.Parameter.Type == typeof(SwitchParameter))
                {
                    SwitchPair newArg = new SwitchPair(argument.Parameter);
                    result.Add(newArg);
                    continue;
                }

                // It's not a switch parameter, we need to check the next argument
                if (index < _arguments.Count - 1)
                {
                    AstParameterArgumentPair nextArg = _arguments[index + 1];
                    if (nextArg.ParameterSpecified)
                    {
                        try
                        {
                            MergedCompiledCommandParameter nextMatchingParameter =
                                _bindableParameters.GetMatchingParameter(nextArg.ParameterName, false, true, null);
                            // The next parameter doesn't exist. We use it as an argument
                            if (nextMatchingParameter == null)
                            {
                                AstPair newArg = new AstPair(argument.Parameter, nextArg.Parameter);
                                result.Add(newArg);
                                index++;
                            }
                            else
                            {
                                // It's possible the user is typing tab for argument completion.
                                // We set a fake argument for the current parameter in this case.
                                FakePair newArg = new FakePair(argument.Parameter);
                                result.Add(newArg);
                            }
                        }
                        catch (ParameterBindingException)
                        {
                            // The next parameter name is ambiguous. We just set
                            // a fake argument for the current paramter.
                            FakePair newArg = new FakePair(argument.Parameter);
                            result.Add(newArg);
                        }
                    }
                    else
                    {
                        // The next item is a pure argument.
                        AstPair nextArgument = nextArg as AstPair;
                        Diagnostics.Assert(nextArgument != null, "the next item should be a pure argument here");
                        Diagnostics.Assert(nextArgument.ArgumentSpecified && !nextArgument.ArgumentIsCommandParameterAst, "the next item should be a pure argument here");

                        AstPair newArg = new AstPair(argument.Parameter, (ExpressionAst)nextArgument.Argument);
                        result.Add(newArg);
                        index++;
                    }
                }
                else
                {
                    // The current parameter is the last item. Set a fake argument for it
                    FakePair newArg = new FakePair(argument.Parameter);
                    result.Add(newArg);
                }
            }

            _arguments = result;
            return true;
        }
Exemple #2
0
        private bool ParseParameterArguments(CommandParameterAst paramAstAtCursor)
        {
            if (!this._bindingEffective)
            {
                return(this._bindingEffective);
            }
            Collection <AstParameterArgumentPair> collection = new Collection <AstParameterArgumentPair>();

            for (int i = 0; i < this._arguments.Count; i++)
            {
                AstParameterArgumentPair item = this._arguments[i];
                if (!item.ParameterSpecified || item.ArgumentSpecified)
                {
                    collection.Add(item);
                }
                else
                {
                    string parameterName = item.ParameterName;
                    MergedCompiledCommandParameter parameter = null;
                    try
                    {
                        bool tryExactMatching = item.Parameter != paramAstAtCursor;
                        parameter = this._bindableParameters.GetMatchingParameter(parameterName, false, tryExactMatching, null);
                    }
                    catch (ParameterBindingException)
                    {
                        this._ambiguousParameters.Add(item.Parameter);
                        goto Label_01F1;
                    }
                    if (parameter == null)
                    {
                        if (i < (this._arguments.Count - 1))
                        {
                            AstParameterArgumentPair pair2 = this._arguments[i + 1];
                            if (!pair2.ParameterSpecified && pair2.ArgumentSpecified)
                            {
                                this._arguments = null;
                                return(false);
                            }
                        }
                        this._parametersNotFound.Add(item.Parameter);
                    }
                    else if (parameter.Parameter.Type == typeof(SwitchParameter))
                    {
                        SwitchPair pair3 = new SwitchPair(item.Parameter);
                        collection.Add(pair3);
                    }
                    else if (i < (this._arguments.Count - 1))
                    {
                        AstParameterArgumentPair pair4 = this._arguments[i + 1];
                        if (pair4.ParameterSpecified)
                        {
                            try
                            {
                                if (this._bindableParameters.GetMatchingParameter(pair4.ParameterName, false, true, null) == null)
                                {
                                    AstPair pair5 = new AstPair(item.Parameter, pair4.Parameter);
                                    collection.Add(pair5);
                                    i++;
                                }
                                else
                                {
                                    FakePair pair6 = new FakePair(item.Parameter);
                                    collection.Add(pair6);
                                }
                                goto Label_01F1;
                            }
                            catch (ParameterBindingException)
                            {
                                FakePair pair7 = new FakePair(item.Parameter);
                                collection.Add(pair7);
                                goto Label_01F1;
                            }
                        }
                        AstPair pair8 = pair4 as AstPair;
                        AstPair pair9 = new AstPair(item.Parameter, (ExpressionAst)pair8.Argument);
                        collection.Add(pair9);
                        i++;
                    }
                    else
                    {
                        FakePair pair10 = new FakePair(item.Parameter);
                        collection.Add(pair10);
                    }
                    Label_01F1 :;
                }
            }
            this._arguments = collection;
            return(true);
        }
 private bool ParseParameterArguments(CommandParameterAst paramAstAtCursor)
 {
     if (!this._bindingEffective)
     {
         return this._bindingEffective;
     }
     Collection<AstParameterArgumentPair> collection = new Collection<AstParameterArgumentPair>();
     for (int i = 0; i < this._arguments.Count; i++)
     {
         AstParameterArgumentPair item = this._arguments[i];
         if (!item.ParameterSpecified || item.ArgumentSpecified)
         {
             collection.Add(item);
         }
         else
         {
             string parameterName = item.ParameterName;
             MergedCompiledCommandParameter parameter = null;
             try
             {
                 bool tryExactMatching = item.Parameter != paramAstAtCursor;
                 parameter = this._bindableParameters.GetMatchingParameter(parameterName, false, tryExactMatching, null);
             }
             catch (ParameterBindingException)
             {
                 this._ambiguousParameters.Add(item.Parameter);
                 goto Label_01F1;
             }
             if (parameter == null)
             {
                 if (i < (this._arguments.Count - 1))
                 {
                     AstParameterArgumentPair pair2 = this._arguments[i + 1];
                     if (!pair2.ParameterSpecified && pair2.ArgumentSpecified)
                     {
                         this._arguments = null;
                         return false;
                     }
                 }
                 this._parametersNotFound.Add(item.Parameter);
             }
             else if (parameter.Parameter.Type == typeof(SwitchParameter))
             {
                 SwitchPair pair3 = new SwitchPair(item.Parameter);
                 collection.Add(pair3);
             }
             else if (i < (this._arguments.Count - 1))
             {
                 AstParameterArgumentPair pair4 = this._arguments[i + 1];
                 if (pair4.ParameterSpecified)
                 {
                     try
                     {
                         if (this._bindableParameters.GetMatchingParameter(pair4.ParameterName, false, true, null) == null)
                         {
                             AstPair pair5 = new AstPair(item.Parameter, pair4.Parameter);
                             collection.Add(pair5);
                             i++;
                         }
                         else
                         {
                             FakePair pair6 = new FakePair(item.Parameter);
                             collection.Add(pair6);
                         }
                         goto Label_01F1;
                     }
                     catch (ParameterBindingException)
                     {
                         FakePair pair7 = new FakePair(item.Parameter);
                         collection.Add(pair7);
                         goto Label_01F1;
                     }
                 }
                 AstPair pair8 = pair4 as AstPair;
                 AstPair pair9 = new AstPair(item.Parameter, (ExpressionAst) pair8.Argument);
                 collection.Add(pair9);
                 i++;
             }
             else
             {
                 FakePair pair10 = new FakePair(item.Parameter);
                 collection.Add(pair10);
             }
         Label_01F1:;
         }
     }
     this._arguments = collection;
     return true;
 }