/// <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; }
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; }