private void CreateBindingResultForSuccessfulBind(CommandAst commandAst, PseudoBindingInfo bindingInfo) { _bindingInfo = bindingInfo; // Check if there is exactly one parameter set valid. In that case, // ValidParameterSetFlags is exactly a power of two. Otherwise, // add to the binding exceptions. bool parameterSetSpecified = bindingInfo.ValidParameterSetsFlags != UInt32.MaxValue; bool remainingParameterSetIncludesDefault = (bindingInfo.DefaultParameterSetFlag != 0) && ((bindingInfo.ValidParameterSetsFlags & bindingInfo.DefaultParameterSetFlag) == bindingInfo.DefaultParameterSetFlag); // (x & (x -1 ) == 0) is a bit hack to determine if something is // exactly a power of two. bool onlyOneRemainingParameterSet = (bindingInfo.ValidParameterSetsFlags != 0) && (bindingInfo.ValidParameterSetsFlags & (bindingInfo.ValidParameterSetsFlags - 1)) == 0; if (parameterSetSpecified && (!remainingParameterSetIncludesDefault) && (!onlyOneRemainingParameterSet)) { ParameterBindingException bindingException = new ParameterBindingException( ErrorCategory.InvalidArgument, null, null, null, null, null, ParameterBinderStrings.AmbiguousParameterSet, "AmbiguousParameterSet"); BindingExceptions.Add(commandAst.CommandElements[0].Extent.Text, new StaticBindingError(commandAst.CommandElements[0], bindingException)); } // Add error for duplicate parameters if (bindingInfo.DuplicateParameters != null) { foreach (AstParameterArgumentPair duplicateParameter in bindingInfo.DuplicateParameters) { AddDuplicateParameterBindingException(duplicateParameter.Parameter); } } // Add error for parameters not found if (bindingInfo.ParametersNotFound != null) { foreach (CommandParameterAst parameterNotFound in bindingInfo.ParametersNotFound) { ParameterBindingException bindingException = new ParameterBindingException( ErrorCategory.InvalidArgument, null, parameterNotFound.ErrorPosition, parameterNotFound.ParameterName, null, null, ParameterBinderStrings.NamedParameterNotFound, "NamedParameterNotFound"); BindingExceptions.Add(parameterNotFound.ParameterName, new StaticBindingError(parameterNotFound, bindingException)); } } // Add error for ambiguous parameters if (bindingInfo.AmbiguousParameters != null) { foreach (CommandParameterAst ambiguousParameter in bindingInfo.AmbiguousParameters) { ParameterBindingException bindingException = bindingInfo.BindingExceptions[ambiguousParameter]; BindingExceptions.Add(ambiguousParameter.ParameterName, new StaticBindingError(ambiguousParameter, bindingException)); } } // Add error for unbound positional parameters if (bindingInfo.UnboundArguments != null) { foreach (AstParameterArgumentPair unboundArgument in bindingInfo.UnboundArguments) { AstPair argument = unboundArgument as AstPair; ParameterBindingException bindingException = new ParameterBindingException( ErrorCategory.InvalidArgument, null, argument.Argument.Extent, argument.Argument.Extent.Text, null, null, ParameterBinderStrings.PositionalParameterNotFound, "PositionalParameterNotFound"); BindingExceptions.Add(argument.Argument.Extent.Text, new StaticBindingError(argument.Argument, bindingException)); } } // Process the bound parameters if (bindingInfo.BoundParameters != null) { foreach (KeyValuePair<string, MergedCompiledCommandParameter> item in bindingInfo.BoundParameters) { CompiledCommandParameter parameter = item.Value.Parameter; CommandElementAst value = null; Object constantValue = null; // This is a single argument AstPair argumentAstPair = bindingInfo.BoundArguments[item.Key] as AstPair; if (argumentAstPair != null) { value = argumentAstPair.Argument; } // This is a parameter that took an argument, as well as ValueFromRemainingArguments. // Merge the arguments into a single fake argument. AstArrayPair argumentAstArrayPair = bindingInfo.BoundArguments[item.Key] as AstArrayPair; if (argumentAstArrayPair != null) { List<ExpressionAst> arguments = new List<ExpressionAst>(); foreach (ExpressionAst expression in argumentAstArrayPair.Argument) { ArrayLiteralAst expressionArray = expression as ArrayLiteralAst; if (expressionArray != null) { foreach (ExpressionAst newExpression in expressionArray.Elements) { arguments.Add((ExpressionAst)newExpression.Copy()); } } else { arguments.Add((ExpressionAst)expression.Copy()); } } // Define the virtual extent and virtual ArrayLiteral. IScriptExtent fakeExtent = arguments[0].Extent; ArrayLiteralAst fakeArguments = new ArrayLiteralAst(fakeExtent, arguments); value = fakeArguments; } // Special handling of switch parameters if (parameter.Type == typeof(SwitchParameter)) { if ((value != null) && (String.Equals("$false", value.Extent.Text, StringComparison.OrdinalIgnoreCase))) { continue; } constantValue = true; } // We got a parameter and a value if ((value != null) || (constantValue != null)) { BoundParameters.Add(item.Key, new ParameterBindingResult(parameter, value, constantValue)); } else { bool takesValueFromPipeline = false; foreach (ParameterSetSpecificMetadata parameterSet in parameter.GetMatchingParameterSetData(bindingInfo.ValidParameterSetsFlags)) { if (parameterSet.ValueFromPipeline) { takesValueFromPipeline = true; break; } } if (!takesValueFromPipeline) { // We have a parameter with no value that isn't a switch parameter, or input parameter ParameterBindingException bindingException = new ParameterBindingException( ErrorCategory.InvalidArgument, null, commandAst.CommandElements[0].Extent, parameter.Name, parameter.Type, null, ParameterBinderStrings.MissingArgument, "MissingArgument"); BindingExceptions.Add(commandAst.CommandElements[0].Extent.Text, new StaticBindingError(commandAst.CommandElements[0], bindingException)); } } } } }
internal StaticBindingResult(CommandAst commandAst, PseudoBindingInfo bindingInfo) { BoundParameters = new Dictionary<string, ParameterBindingResult>(StringComparer.OrdinalIgnoreCase); BindingExceptions = new Dictionary<string, StaticBindingError>(StringComparer.OrdinalIgnoreCase); if (bindingInfo == null) { CreateBindingResultForSyntacticBind(commandAst); } else { CreateBindingResultForSuccessfulBind(commandAst, bindingInfo); } }