Encapsulates the result of an attempt to bind to one or methods using the OverloadResolver. Users should first check the Result property to see if the binding was successful or to determine the specific type of failure that occured. If the binding was successful MakeExpression can then be called to create an expression which calls the method. If the binding was a failure callers can then create a custom error message based upon the reason the call failed.
Exemplo n.º 1
0
 public override Actions.ErrorInfo MakeInvalidParametersError(BindingTarget target) {
     Expression exceptionValue;
     switch (target.Result) {
         case BindingResult.AmbiguousMatch:
             exceptionValue = MakeAmbiguousCallError(target);
             break;
         case BindingResult.IncorrectArgumentCount: 
             exceptionValue = MakeIncorrectArgumentCountError(target);
             break;
         case BindingResult.CallFailure: 
             exceptionValue = MakeCallFailureError(target);
             break;
         default: throw new InvalidOperationException();
     }
     return Actions.ErrorInfo.FromException(exceptionValue);
 }
Exemplo n.º 2
0
        private Expression MakeAmbiguousCallError(BindingTarget target) {
            StringBuilder sb = new StringBuilder(string.Format("Found multiple methods for '{0}': ", target.Name));
            string outerComma = "";
            foreach (MethodTarget mt in target.AmbiguousMatches) {
                Type[] types = mt.GetParameterTypes();
                string innerComma = "";

                sb.Append(outerComma);
                sb.Append(target.Name);
                sb.Append('(');
                foreach (Type t in types) {
                    sb.Append(innerComma);
                    sb.Append(GetTypeName(t));
                    innerComma = ", ";
                }

                sb.Append(')');
                outerComma = ", ";
            }

            return Methods.MakeAmbiguousMatchError.OpCall(AstUtils.Constant(sb.ToString()));
        }
Exemplo n.º 3
0
        private static ErrorInfo MakeIncorrectArgumentCountError(BindingTarget target) {
            int minArgs = Int32.MaxValue;
            int maxArgs = Int32.MinValue;
            foreach (int argCnt in target.ExpectedArgumentCount) {
                minArgs = System.Math.Min(minArgs, argCnt);
                maxArgs = System.Math.Max(maxArgs, argCnt);
            }

            return ErrorInfo.FromException(
                Ast.Call(
                    typeof(BinderOps).GetMethod("TypeErrorForIncorrectArgumentCount", new Type[] {
                                typeof(string), typeof(int), typeof(int) , typeof(int), typeof(int), typeof(bool), typeof(bool)
                            }),
                    Ast.Constant(target.Name, typeof(string)),  // name
                    Ast.Constant(minArgs),                      // min formal normal arg cnt
                    Ast.Constant(maxArgs),                      // max formal normal arg cnt
                    Ast.Constant(0),                            // default cnt
                    Ast.Constant(target.ActualArgumentCount),   // args provided
                    Ast.Constant(false),                        // hasArgList
                    Ast.Constant(false)                         // kwargs provided
                )
            );
        }
Exemplo n.º 4
0
        private ErrorInfo MakeAmbiguousCallError(BindingTarget target) {
            StringBuilder sb = new StringBuilder("Multiple targets could match: ");
            string outerComma = "";
            foreach (MethodTarget mt in target.AmbiguousMatches) {
                Type[] types = mt.GetParameterTypes();
                string innerComma = "";

                sb.Append(outerComma);
                sb.Append(target.Name);
                sb.Append('(');
                foreach (Type t in types) {
                    sb.Append(innerComma);
                    sb.Append(GetTypeName(t));
                    innerComma = ", ";
                }

                sb.Append(')');
                outerComma = ", ";
            }

            return ErrorInfo.FromException(
                Ast.Call(
                    typeof(BinderOps).GetMethod("SimpleTypeError"),
                    Ast.Constant(sb.ToString(), typeof(string))
                )
            );
        }
Exemplo n.º 5
0
        /// <summary>
        /// Performs binding against a set of overloaded methods using the specified arguments.  The arguments are
        /// consumed as specified by the CallSignature object.
        /// </summary>
        /// <param name="minLevel">TODO.</param>
        /// <param name="maxLevel">TODO.</param>
        /// <param name="resolver">Overload resolver.</param>
        /// <param name="targets">The methods to be called</param>
        /// <param name="restrictions">Additional restrictions which should be applied to the resulting MetaObject.</param>
        /// <param name="target">The resulting binding target which can be used for producing error information.</param>
        /// <param name="name">The name of the method or null to use the name from targets.</param>
        /// <returns>A meta object which results from the call.</returns>
        public DynamicMetaObject CallMethod(DefaultOverloadResolver resolver, IList<MethodBase> targets, BindingRestrictions restrictions, string name, 
            NarrowingLevel minLevel, NarrowingLevel maxLevel, out BindingTarget target) {
            ContractUtils.RequiresNotNull(resolver, "resolver");
            ContractUtils.RequiresNotNullItems(targets, "targets");
            ContractUtils.RequiresNotNull(restrictions, "restrictions");

            // attempt to bind to an individual method
            target = resolver.ResolveOverload(name ?? GetTargetName(targets), targets, minLevel, maxLevel);

            if (target.Success) {
                // if we succeed make the target for the rule
                return new DynamicMetaObject(
                    target.MakeExpression(),
                    restrictions.Merge(
                        MakeSplatTests(resolver.CallType, resolver.Signature, resolver.Arguments).
                            Merge(target.RestrictedArguments.GetAllRestrictions())
                    )
                );
            }

            // make an error rule
            return MakeInvalidParametersRule(resolver, restrictions, target);
        }
Exemplo n.º 6
0
        // TODO: revisit
        private DynamicMetaObject MakeInvalidParametersRule(DefaultOverloadResolver binder, BindingRestrictions restrictions, BindingTarget bt) {
            var args = binder.Arguments;
            
            BindingRestrictions restriction = MakeSplatTests(binder.CallType, binder.Signature, true, args);

            // restrict to the exact type of all parameters for errors
            for (int i = 0; i < args.Count; i++) {
                args[i] = args[i].Restrict(args[i].GetLimitType());
            }

            return MakeError(
                binder.MakeInvalidParametersError(bt),
                restrictions.Merge(BindingRestrictions.Combine(args).Merge(restriction)),
                typeof(object)
            );
        }
Exemplo n.º 7
0
        private Expression MakeCallFailureError(BindingTarget target) {
            foreach (CallFailure cf in target.CallFailures) {
                switch (cf.Reason) {
                    case CallFailureReason.ConversionFailure:
                        foreach (ConversionResult cr in cf.ConversionResults) {
                            if (cr.Failed) {
                                if (typeof(Proc).IsAssignableFrom(cr.To)) {
                                    return Methods.CreateArgumentsErrorForProc.OpCall(AstUtils.Constant(cr.GetArgumentTypeName(Binder)));
                                }

                                Debug.Assert(typeof(BlockParam).IsSealed);
                                if (cr.To == typeof(BlockParam)) {
                                    return Methods.CreateArgumentsErrorForMissingBlock.OpCall();
                                }

                                string toType;
                                if (cr.To.IsGenericType && cr.To.GetGenericTypeDefinition() == typeof(Union<,>)) {
                                    var g = cr.To.GetGenericArguments();
                                    toType = Binder.GetTypeName(g[0]) + " or " + Binder.GetTypeName(g[1]);
                                } else {
                                    toType = Binder.GetTypeName(cr.To);
                                }

                                return Methods.CreateTypeConversionError.OpCall(
                                    AstUtils.Constant(cr.GetArgumentTypeName(Binder)),
                                    AstUtils.Constant(toType)
                                );
                            }
                        }
                        break;

                    case CallFailureReason.TypeInference:
                        // TODO: Display generic parameters so it's clear what we couldn't infer.
                        return Methods.CreateArgumentsError.OpCall(
                            AstUtils.Constant(String.Format("generic arguments could not be infered for method '{0}'", target.Name))
                        );

                    case CallFailureReason.DuplicateKeyword:
                    case CallFailureReason.UnassignableKeyword:
                    default: 
                        throw new InvalidOperationException();
                }
            }
            throw new InvalidOperationException();
        }
 /// <summary>
 /// Performs binding against a set of overloaded methods using the specified arguments.  The arguments are
 /// consumed as specified by the CallSignature object.
 /// </summary>
 /// <param name="parameterBinder">ParameterBinder used to map arguments to parameters.</param>
 /// <param name="targets">The methods to be called</param>
 /// <param name="args">The arguments for the call</param>
 /// <param name="signature">The call signature which specified how the arguments will be consumed</param>
 /// <param name="restrictions">Additional restrictions which should be applied to the resulting MetaObject.</param>
 /// <param name="maxLevel">The maximum narrowing level for arguments.  The current narrowing level is flowed thorugh to the DefaultBinder.</param>
 /// <param name="minLevel">The minimum narrowing level for the arguments.  The current narrowing level is flowed thorugh to the DefaultBinder.</param>        
 /// <param name="target">The resulting binding target which can be used for producing error information.</param>
 /// <param name="name">The name of the method or null to use the name from targets.</param>
 /// <returns>A meta object which results from the call.</returns>
 public DynamicMetaObject CallMethod(ParameterBinder parameterBinder, IList<MethodBase> targets, IList<DynamicMetaObject> args, CallSignature signature, BindingRestrictions restrictions, NarrowingLevel minLevel, NarrowingLevel maxLevel, string name, out BindingTarget target) {
     return CallWorker(
         parameterBinder,
         targets,
         args,
         signature,
         CallTypes.None,
         restrictions,
         minLevel,
         maxLevel,
         name,
         out target
     );
 }
Exemplo n.º 9
0
        internal void AddArgumentRestrictions(MetaObjectBuilder/*!*/ metaBuilder, BindingTarget/*!*/ bindingTarget) {
            var args = GetActualArguments();
            var restrictedArgs = bindingTarget.Success ? bindingTarget.RestrictedArguments.GetObjects() : args.Arguments;

            for (int i = _firstRestrictedArg; i < restrictedArgs.Count; i++) {
                var arg = (bindingTarget.Success ? restrictedArgs[i] : restrictedArgs[i].Restrict(restrictedArgs[i].GetLimitType()));

                if (i >= args.FirstSplattedArg && i <= _lastSplattedArg) {
                    metaBuilder.AddCondition(arg.Restrictions.ToExpression());
                } else {
                    metaBuilder.AddRestriction(arg.Restrictions);
                }
            }

            // Adds condition for collapsed arguments - it is the same whether we succeed or not:
            var splatCondition = GetCollapsedArgsCondition();
            if (splatCondition != null) {
                metaBuilder.AddCondition(splatCondition);
            }
        }
Exemplo n.º 10
0
        private Expression MakeAmbiguousCallError(BindingTarget target) {
            StringBuilder sb = new StringBuilder(string.Format("Found multiple methods for '{0}': ", target.Name));
            string outerComma = "";
            foreach (MethodCandidate candidate in target.AmbiguousMatches) {
                IList<ParameterWrapper> parameters = candidate.GetParameters();
                
                string innerComma = "";

                sb.Append(outerComma);
                sb.Append(target.Name);
                sb.Append('(');
                foreach (var param in parameters) {
                    if (!param.IsHidden) {
                        sb.Append(innerComma);
                        sb.Append(Binder.GetTypeName(param.Type));
                        if (param.ProhibitNull) {
                            sb.Append('!');
                        }
                        innerComma = ", ";
                    }
                }

                sb.Append(')');
                outerComma = ", ";
            }

            return Methods.MakeAmbiguousMatchError.OpCall(AstUtils.Constant(sb.ToString()));
        }
Exemplo n.º 11
0
        private Expression MakeIncorrectArgumentCountError(BindingTarget target) {
            int minArgs = Int32.MaxValue;
            int maxArgs = Int32.MinValue;
            foreach (int argCnt in target.ExpectedArgumentCount) {
                minArgs = System.Math.Min(minArgs, argCnt);
                maxArgs = System.Math.Max(maxArgs, argCnt);
            }

            return Methods.MakeWrongNumberOfArgumentsError.OpCall(
                AstUtils.Constant(target.ActualArgumentCount),
                AstUtils.Constant(minArgs));
        }
Exemplo n.º 12
0
 private ErrorInfo MakeCallFailureError(BindingTarget target) {
     foreach (CallFailure cf in target.CallFailures) {
         switch (cf.Reason) {
             case CallFailureReason.ConversionFailure:
                 foreach (ConversionResult cr in cf.ConversionResults) {
                     if (cr.Failed) {
                         return ErrorInfo.FromException(
                             Ast.Call(
                                 typeof(BinderOps).GetMethod("SimpleTypeError"),
                                 Ast.Constant(String.Format("expected {0}, got {1}", GetTypeName(cr.To), GetTypeName(cr.From)))
                             )
                         );
                     }
                 }
                 break;
             case CallFailureReason.DuplicateKeyword:
                 return ErrorInfo.FromException(
                         Ast.Call(
                             typeof(BinderOps).GetMethod("TypeErrorForDuplicateKeywordArgument"),
                             Ast.Constant(target.Name, typeof(string)),
                             Ast.Constant(SymbolTable.IdToString(cf.KeywordArguments[0]), typeof(string))    // TODO: Report all bad arguments?
                     )
                 );
             case CallFailureReason.UnassignableKeyword:
                 return ErrorInfo.FromException(
                         Ast.Call(
                             typeof(BinderOps).GetMethod("TypeErrorForExtraKeywordArgument"),
                             Ast.Constant(target.Name, typeof(string)),
                             Ast.Constant(SymbolTable.IdToString(cf.KeywordArguments[0]), typeof(string))    // TODO: Report all bad arguments?
                     )
                 );
             default: throw new InvalidOperationException();
         }
     }
     throw new InvalidOperationException();
 }
Exemplo n.º 13
0
 private ErrorInfo MakeInvalidSplatteeError(BindingTarget target) {
     return ErrorInfo.FromException(
         Ast.Call(typeof(BinderOps).GetMethod("InvalidSplatteeError"), 
             AstUtils.Constant(target.Name),
             AstUtils.Constant(Binder.GetTypeName(_invalidSplattee.GetLimitType()))
         )
     );
 }
Exemplo n.º 14
0
 public override ErrorInfo MakeInvalidParametersError(BindingTarget target) {
     if (target.Result == BindingResult.InvalidArguments && _invalidSplattee != null) {
         return MakeInvalidSplatteeError(target);
     }
     return base.MakeInvalidParametersError(target);
 }
Exemplo n.º 15
0
        private static DynamicMetaObject MakeInvalidParametersRule(CallTypes callType, CallSignature signature, DefaultBinder binder, IList<DynamicMetaObject> args, BindingRestrictions restrictions, BindingTarget bt) {
            BindingRestrictions restriction = MakeSplatTests(callType, signature, true, args);

            // restrict to the exact type of all parameters for errors
            for (int i = 0; i < args.Count; i++) {
                args[i] = args[i].Restrict(args[i].GetLimitType());
            }

            return MakeError(
                binder.MakeInvalidParametersError(bt),
                restrictions.Merge(BindingRestrictions.Combine(args).Merge(restriction))
            );
        }
Exemplo n.º 16
0
        private DynamicMetaObject CallWorker(ParameterBinder parameterBinder, IList<MethodBase> targets, IList<DynamicMetaObject> args, CallSignature signature, CallTypes callType, BindingRestrictions restrictions, NarrowingLevel minLevel, NarrowingLevel maxLevel, string name, out BindingTarget target) {
            ContractUtils.RequiresNotNull(parameterBinder, "parameterBinder");
            ContractUtils.RequiresNotNullItems(args, "args");
            ContractUtils.RequiresNotNullItems(targets, "targets");
            ContractUtils.RequiresNotNull(restrictions, "restrictions");

            DynamicMetaObject[] finalArgs;
            SymbolId[] argNames;

            if (callType == CallTypes.ImplicitInstance) {
                GetArgumentNamesAndTypes(signature, ArrayUtils.RemoveFirst(args), out argNames, out finalArgs);
                finalArgs = ArrayUtils.Insert(args[0], finalArgs);
            } else {
                GetArgumentNamesAndTypes(signature, args, out argNames, out finalArgs);
            }

            // attempt to bind to an individual method
            MethodBinder binder = MethodBinder.MakeBinder(
                this,
                name ?? GetTargetName(targets),
                targets,
                argNames,
                minLevel,
                maxLevel);
            target = binder.MakeBindingTarget(callType, finalArgs);

            if (target.Success) {
                // if we succeed make the target for the rule
                return new DynamicMetaObject(
                    target.MakeExpression(parameterBinder),
                    restrictions.Merge(MakeSplatTests(callType, signature, args).Merge(BindingRestrictions.Combine(target.RestrictedArguments)))
                );
            }
            // make an error rule
            return MakeInvalidParametersRule(callType, signature, this, args, restrictions, target);
        }
Exemplo n.º 17
0
 /// <summary>
 /// Performs binding against a set of overloaded methods using the specified arguments and the specified
 /// instance argument.  The arguments are consumed as specified by the CallSignature object.
 /// </summary>
 /// <param name="parameterBinder">ParameterBinder used to map arguments to parameters.</param>
 /// <param name="targets">The methods to be called</param>
 /// <param name="args">The arguments for the call</param>
 /// <param name="signature">The call signature which specified how the arguments will be consumed</param>
 /// <param name="restrictions">Additional restrictions which should be applied to the resulting MetaObject.</param>
 /// <param name="instance">The instance which will be provided for dispatching to an instance method.</param>
 /// <param name="maxLevel">The maximum narrowing level for arguments.  The current narrowing level is flowed thorugh to the DefaultBinder.</param>
 /// <param name="minLevel">The minimum narrowing level for the arguments.  The current narrowing level is flowed thorugh to the DefaultBinder.</param>        
 /// <param name="target">The resulting binding target which can be used for producing error information.</param>
 /// <param name="name">The name of the method or null to use the name from targets.</param>
 /// <returns>A meta object which results from the call.</returns>
 public DynamicMetaObject CallInstanceMethod(ParameterBinder parameterBinder, IList<MethodBase> targets, DynamicMetaObject instance, IList<DynamicMetaObject> args, CallSignature signature, BindingRestrictions restrictions, NarrowingLevel minLevel, NarrowingLevel maxLevel, string name, out BindingTarget target) {
     return CallWorker(
         parameterBinder,
         targets,
         ArrayUtils.Insert(instance, args),
         signature,
         CallTypes.ImplicitInstance,
         restrictions,
         minLevel,
         maxLevel,
         name,
         out target
     );
 }
Exemplo n.º 18
0
 public virtual ErrorInfo MakeInvalidParametersError(BindingTarget target) {
     switch (target.Result) {
         case BindingResult.CallFailure: return MakeCallFailureError(target);
         case BindingResult.AmbiguousMatch: return MakeAmbiguousCallError(target);
         case BindingResult.IncorrectArgumentCount: return MakeIncorrectArgumentCountError(target);
         default: throw new InvalidOperationException();
     }
 }
Exemplo n.º 19
0
        private Expression MakeCallFailureError(BindingTarget target) {
            foreach (CallFailure cf in target.CallFailures) {
                switch (cf.Reason) {
                    case CallFailureReason.ConversionFailure:
                        foreach (ConversionResult cr in cf.ConversionResults) {
                            if (cr.Failed) {
                                if (typeof(Proc).IsAssignableFrom(cr.To)) {
                                    return Methods.CreateArgumentsErrorForProc.OpCall(AstUtils.Constant(cr.GetArgumentTypeName(Binder)));
                                }

                                Debug.Assert(typeof(BlockParam).IsSealed);
                                if (cr.To == typeof(BlockParam)) {
                                    return Methods.CreateArgumentsErrorForMissingBlock.OpCall();
                                }

                                return Methods.CreateTypeConversionError.OpCall(
                                        AstUtils.Constant(cr.GetArgumentTypeName(Binder)),
                                        AstUtils.Constant(Binder.GetTypeName(cr.To)));
                            }
                        }
                        break;

                    case CallFailureReason.DuplicateKeyword:
                    case CallFailureReason.UnassignableKeyword:
                    default: throw new InvalidOperationException();
                }
            }
            throw new InvalidOperationException();
        }
Exemplo n.º 20
0
        public override Microsoft.Scripting.Actions.ErrorInfo MakeInvalidParametersError(BindingTarget target) {
            Expression exceptionValue;
            switch (target.Result) {
                case BindingResult.AmbiguousMatch:
                    exceptionValue = MakeAmbiguousCallError(target);
                    break;

                case BindingResult.IncorrectArgumentCount:
                    exceptionValue = MakeIncorrectArgumentCountError(target);
                    break;

                case BindingResult.CallFailure:
                    exceptionValue = MakeCallFailureError(target);
                    break;

                case BindingResult.NoCallableMethod:
                    exceptionValue = Methods.CreateArgumentsError.OpCall(
                        AstUtils.Constant(String.Format("Method '{0}' is not callable", target.Name))
                    );
                    break;

                default: 
                    throw new InvalidOperationException();
            }
            return Microsoft.Scripting.Actions.ErrorInfo.FromException(exceptionValue);
        }
Exemplo n.º 21
0
 internal static BuiltinFunction.BindingResult CheckLightThrow(DynamicMetaObjectBinder call, DynamicMetaObject res, BindingTarget target) {
     return new BuiltinFunction.BindingResult(target, CheckLightThrowMO(call, res, target));
 }
Exemplo n.º 22
0
        private Expression MakeIncorrectArgumentCountError(BindingTarget target) {
            IList<int> available = target.ExpectedArgumentCount;
            int expected;

            if (available.Count > 0) {
                int minGreater = Int32.MaxValue;
                int maxLesser = Int32.MinValue;
                int max = Int32.MinValue;
                foreach (int arity in available) {
                    if (arity > target.ActualArgumentCount) {
                        minGreater = Math.Min(minGreater, arity);
                    } else {
                        maxLesser = Math.Max(maxLesser, arity);
                    }

                    max = Math.Max(max, arity);
                }

                expected = (target.ActualArgumentCount < maxLesser ? maxLesser : Math.Min(minGreater, max));
            } else {
                // no overload is callable:
                expected = 0;
            }

            return Methods.MakeWrongNumberOfArgumentsError.OpCall(AstUtils.Constant(target.ActualArgumentCount), AstUtils.Constant(expected));
        }
Exemplo n.º 23
0
 internal static DynamicMetaObject CheckLightThrowMO(DynamicMetaObjectBinder call, DynamicMetaObject res, BindingTarget target) {
     if (target.Success && target.Overload.ReflectionInfo.IsDefined(typeof(LightThrowingAttribute), false)) {
         if (!call.SupportsLightThrow()) {
             res = new DynamicMetaObject(
                 LightExceptions.CheckAndThrow(res.Expression),
                 res.Restrictions
             );
         }
     }
     return res;
 }
Exemplo n.º 24
0
 public SlotOrFunction(BindingTarget/*!*/ function, DynamicMetaObject/*!*/ target) {
     _target = target;
     _function = function;
 }
Exemplo n.º 25
0
 public BindingResult(BindingTarget target, DynamicMetaObject meta) {
     Target = target;
     MetaObject = meta;
 }