Provides binding and overload resolution to .NET methods. MethodBinder's can be used for: generating new AST code for calling a method calling a method via reflection at runtime (not implemented) performing an abstract call MethodBinder's support default arguments, optional arguments, by-ref (in and out), and keyword arguments. Implementation Details: The MethodBinder works by building up a CandidateSet for each number of effective arguments that can be passed to a set of overloads. For example a set of overloads such as: foo(object a, object b, object c) foo(int a, int b) would have 2 target sets - one for 3 parameters and one for 2 parameters. For parameter arrays we fallback and create the appropriately sized CandidateSet on demand. Each CandidateSet consists of a set of MethodCandidate's. Each MethodCandidate knows the flattened parameters that could be received. For example for a function such as: foo(params int[] args) When this method is in a CandidateSet of size 3 the MethodCandidate takes 3 parameters - all of them ints; if it's in a CandidateSet of size 4 it takes 4 parameters. Effectively a MethodCandidate is a simplified view that allows all arguments to be treated as required positional arguments. Each MethodCandidate in turn refers to a MethodTarget. The MethodTarget is composed of a set of ArgBuilder's and a ReturnBuilder which know how to consume the positional arguments and pass them to the appropriate argument of the destination method. This includes routing keyword arguments to the correct position, providing the default values for optional arguments, etc... After binding is finished the MethodCandidates are thrown away and a BindingTarget is returned. The BindingTarget indicates whether the binding was successful and if not any additional information that should be reported to the user about the failed binding. It also exposes the MethodTarget which allows consumers to get the flattened list of required parameters for the call. MethodCandidates are not exposed and are an internal implementation detail of the MethodBinder.
コード例 #1
0
        internal protected override Expression ToExpression(OverloadResolver resolver, RestrictedArguments args, bool[] hasBeenUsed) {
            if (_tmp == null) {
                _tmp = resolver.GetTemporary(_elementType, "outParam");
            }

            Debug.Assert(!hasBeenUsed[Index]);
            hasBeenUsed[Index] = true;
            Expression arg = args.GetObject(Index).Expression;

            return Expression.Condition(
                Expression.TypeIs(arg, Type),
                Expression.Assign(
                    _tmp,
                    Expression.Field(
                        AstUtils.Convert(arg, Type),
                        Type.GetField("Value")
                    )
                ),
                Expression.Throw(
                    Expression.Call(
                        new Func<Type, object, Exception>(RuntimeHelpers.MakeIncorrectBoxTypeError).Method,
                        AstUtils.Constant(_elementType),
                        AstUtils.Convert(arg, typeof(object))
                    ),
                    _elementType
                )
            );
        }
コード例 #2
0
        internal protected override Expression ToExpression(OverloadResolver resolver, RestrictedArguments args, bool[] hasBeenUsed) {
            if (_tmp == null) {
                _tmp = resolver.GetTemporary(Type, "outParam");
            }

            return Ast.Block(Ast.Assign(_tmp, base.ToExpression(resolver, args, hasBeenUsed)), _tmp);
        }
コード例 #3
0
        internal override Expression ToExpression(OverloadResolver resolver, IList<ArgBuilder> builders, RestrictedArguments args, Expression ret) {
            if (_returnArgs.Count == 1) {
                if (_returnArgs[0] == -1) {
                    return ret;
                }
                return Ast.Block(ret, builders[_returnArgs[0]].ToReturnExpression(resolver));
            }

            Expression[] retValues = new Expression[_returnArgs.Count];
            int rIndex = 0;
            bool usesRet = false;
            foreach (int index in _returnArgs) {
                if (index == -1) {
                    usesRet = true;
                    retValues[rIndex++] = ret;
                } else {
                    retValues[rIndex++] = builders[index].ToReturnExpression(resolver);
                }
            }

            Expression retArray = AstUtils.NewArrayHelper(typeof(object), retValues);
            if (!usesRet) {
                retArray = Ast.Block(ret, retArray);
            }

            return resolver.GetByRefArrayExpression(retArray);
        }
コード例 #4
0
ファイル: OutArgBuilder.cs プロジェクト: Hank923/ironruby
        internal override Expression ToReturnExpression(OverloadResolver resolver) {
            if (_isRef) {
                return _tmp;
            }

            return GetDefaultValue();
        }
コード例 #5
0
        internal protected override Expression ToExpression(OverloadResolver resolver, IList<Expression> parameters, bool[] hasBeenUsed) {
            if (_tmp == null) {
                _tmp = resolver.GetTemporary(Type, "outParam");
            }

            return Ast.Block(Ast.Assign(_tmp, base.ToExpression(resolver, parameters, hasBeenUsed)), _tmp);
        }
コード例 #6
0
        internal protected override Expression ToExpression(OverloadResolver resolver, RestrictedArguments args, bool[] hasBeenUsed) {
            if (_tmp == null) {
                _tmp = resolver.GetTemporary(_elementType, "outParam");
            }

            Debug.Assert(!hasBeenUsed[Index]);
            hasBeenUsed[Index] = true;
            Type boxType = typeof(StrongBox<>).MakeGenericType(_elementType);
            Expression arg = args.GetObject(Index).Expression;

            return Expression.Condition(
                Expression.TypeIs(arg, Type),
                Expression.Assign(
                    _tmp,
                    Expression.Field(
                        AstUtils.Convert(arg, boxType),
                        boxType.GetField("Value")
                    )
                ),
                Expression.Call(
                    typeof(RuntimeHelpers).GetMethod("IncorrectBoxType").MakeGenericMethod(_elementType),
                    AstUtils.Convert(arg, typeof(object))
                )
            );
        }
コード例 #7
0
        internal protected override Expression ToExpression(OverloadResolver resolver, IList<Expression> parameters, bool[] hasBeenUsed) {
            Debug.Assert(BuilderExpectsSingleParameter(_builder));

            int index = GetKeywordIndex(parameters.Count);
            Debug.Assert(!hasBeenUsed[index]);
            hasBeenUsed[index] = true;
            return _builder.ToExpression(resolver, new Expression[] { parameters[index] }, new bool[1]);
        }
コード例 #8
0
        internal protected override Expression ToExpression(OverloadResolver resolver, RestrictedArguments args, bool[] hasBeenUsed) {
            Debug.Assert(BuilderExpectsSingleParameter(_builder));

            int index = GetKeywordIndex(args.Length);
            Debug.Assert(!hasBeenUsed[index]);
            hasBeenUsed[index] = true;
            return _builder.ToExpression(resolver, MakeRestrictedArg(args, index), new bool[1]);
        }
コード例 #9
0
ファイル: ParameterMapping.cs プロジェクト: BenHall/ironruby
        internal ParameterMapping(OverloadResolver resolver, OverloadInfo method, IList<string> argNames) {
            Assert.NotNull(resolver, method);
            _resolver = resolver;
            _overload = method;
            _argNames = argNames;
            _parameters = new List<ParameterWrapper>();
            _arguments = new List<ArgBuilder>(method.ParameterCount);
            _defaultArguments = new List<ArgBuilder>();
	    }
コード例 #10
0
        internal protected override Expression ToExpression(OverloadResolver resolver, IList<Expression> parameters, bool[] hasBeenUsed) {
            Expression res = Ast.Call(
                typeof(BinderOps).GetMethod("MakeSymbolDictionary"),
                Ast.NewArrayInit(typeof(string), ConstantNames()),
                AstUtils.NewArrayHelper(typeof(object), GetParameters(parameters, hasBeenUsed))
            );

            return res;
        }
コード例 #11
0
        internal protected override Expression ToExpression(OverloadResolver resolver, RestrictedArguments args, bool[] hasBeenUsed) {
            Type dictType = ParameterInfo.ParameterType;

            return Ast.Call(
                GetCreationDelegate(dictType).Method,
                Ast.NewArrayInit(typeof(string), ConstantNames()),
                AstUtils.NewArrayHelper(typeof(object), GetParameters(args, hasBeenUsed))
            );
        }
コード例 #12
0
 internal override Expression UpdateFromReturn(OverloadResolver resolver, IList<Expression> parameters) {
     return Expression.Assign(
         Expression.Field(
             Expression.Convert(parameters[Index], Type),
             Type.GetField("Value")
         ),
         _tmp
     );
 }
コード例 #13
0
 internal override Expression UpdateFromReturn(OverloadResolver resolver, RestrictedArguments args) {
     return Expression.Assign(
         Expression.Field(
             Expression.Convert(args.GetObject(Index).Expression, Type),
             Type.GetField("Value")
         ),
         _tmp
     );
 }
コード例 #14
0
ファイル: OutArgBuilder.cs プロジェクト: Hank923/ironruby
        internal protected override Expression ToExpression(OverloadResolver resolver, RestrictedArguments args, bool[] hasBeenUsed) {
            if (_isRef) {
                if (_tmp == null) {
                    _tmp = resolver.GetTemporary(_parameterType, "outParam");
                }
                return _tmp;
            }

            return GetDefaultValue();
        }
コード例 #15
0
        internal ParameterMapping(OverloadResolver resolver, MethodBase method, ParameterInfo[] parameterInfos, IList<string> argNames) {
            Assert.NotNull(resolver, method);
            _resolver = resolver;
            _method = method;
            _argNames = argNames;
            _parameterInfos = parameterInfos ?? method.GetParameters();
            _parameters = new List<ParameterWrapper>();
            _arguments = new List<ArgBuilder>(_parameterInfos.Length);
            _defaultArguments = new List<ArgBuilder>();
	    }
コード例 #16
0
        internal protected override Expression ToExpression(OverloadResolver resolver, RestrictedArguments args, bool[] hasBeenUsed) {
            object value = ParameterInfo.DefaultValue;
            if (value is Missing) {
                value = CompilerHelpers.GetMissingValue(ParameterInfo.ParameterType);
            }

            if (ParameterInfo.ParameterType.IsByRef) {
                return AstUtils.Constant(value, ParameterInfo.ParameterType.GetElementType());
            }

            var metaValue = new DynamicMetaObject(AstUtils.Constant(value), BindingRestrictions.Empty, value);
            return resolver.Convert(metaValue, CompilerHelpers.GetType(value), ParameterInfo, ParameterInfo.ParameterType);
        }
コード例 #17
0
ファイル: InstanceBuilder.cs プロジェクト: Hank923/ironruby
        internal protected virtual Expression ToExpression(ref MethodInfo method, OverloadResolver resolver, RestrictedArguments args, bool[] hasBeenUsed) {
            if (_index == -1) {
                return AstUtils.Constant(null);
            }

            Debug.Assert(hasBeenUsed.Length == args.Length);
            Debug.Assert(_index < args.Length);
            Debug.Assert(!hasBeenUsed[_index]);
            hasBeenUsed[_index] = true;

            GetCallableMethod(args, ref method);
            return resolver.Convert(args.GetObject(_index), args.GetType(_index), null, method.DeclaringType);
        }
コード例 #18
0
ファイル: DefaultArgBuilder.cs プロジェクト: apboyle/ironruby
 protected internal override Func<object[], object> ToDelegate(OverloadResolver resolver, RestrictedArguments args, bool[] hasBeenUsed) {
     if (ParameterInfo.ParameterType.IsByRef) {
         return null;
     } else if (ParameterInfo.DefaultValue is Missing && CompilerHelpers.GetMissingValue(ParameterInfo.ParameterType) is Missing) {
         // reflection throws when we do this
         return null;
     }
     
     object val = ParameterInfo.DefaultValue;
     if (val is Missing) {
         val = CompilerHelpers.GetMissingValue(ParameterInfo.ParameterType);
     }
     Debug.Assert(val != Missing.Value);
     return (_) => val;
 }
コード例 #19
0
ファイル: InstanceBuilder.cs プロジェクト: Hank923/ironruby
        internal protected virtual Func<object[], object> ToDelegate(ref MethodInfo method, OverloadResolver resolver, RestrictedArguments args, bool[] hasBeenUsed) {
            if (_index == -1) {
                return (_) => null;
            }

            GetCallableMethod(args, ref method);

            Func<object[], object> conv = resolver.GetConvertor(_index + 1, args.GetObject(_index), null, method.DeclaringType);
            if (conv != null) {
                return conv;
            }

            return (Func<object[], object>)Delegate.CreateDelegate(
                typeof(Func<object[], object>),
                _index + 1,
                typeof(ArgBuilder).GetMethod("ArgumentRead"));
        }
コード例 #20
0
ファイル: MethodCandidate.cs プロジェクト: jcteague/ironruby
        internal MethodCandidate(OverloadResolver resolver, MethodBase method, List<ParameterWrapper> parameters, ParameterWrapper paramsDict,
            ReturnBuilder returnBuilder, ArgBuilder instanceBuilder, IList<ArgBuilder> argBuilders) {

            Assert.NotNull(resolver, method, instanceBuilder, returnBuilder);
            Assert.NotNullItems(parameters);
            Assert.NotNullItems(argBuilders);

            _resolver = resolver;
            _method = method;
            _instanceBuilder = instanceBuilder;
            _argBuilders = argBuilders;
            _returnBuilder = returnBuilder;
            _parameters = parameters;
            _paramsDict = paramsDict;

            _paramsArrayIndex = ParameterWrapper.IndexOfParamsArray(parameters);

            parameters.TrimExcess();
        }
コード例 #21
0
ファイル: MethodCandidate.cs プロジェクト: hansdude/Phalanger
        internal MethodCandidate(OverloadResolver resolver, OverloadInfo method, List<ParameterWrapper> parameters, ParameterWrapper paramsDict,
            ReturnBuilder returnBuilder, InstanceBuilder instanceBuilder, IList<ArgBuilder> argBuilders, Dictionary<DynamicMetaObject, BindingRestrictions> restrictions) {

            Assert.NotNull(resolver, method, instanceBuilder, returnBuilder);
            Assert.NotNullItems(parameters);
            Assert.NotNullItems(argBuilders);

            _resolver = resolver;
            _overload = method;
            _instanceBuilder = instanceBuilder;
            _argBuilders = argBuilders;
            _returnBuilder = returnBuilder;
            _parameters = parameters;
            _paramsDict = paramsDict;
            _restrictions = restrictions;

            _paramsArrayIndex = ParameterWrapper.IndexOfParamsArray(parameters);

            parameters.TrimExcess();
        }
コード例 #22
0
 internal protected override Expression ToExpression(OverloadResolver resolver, RestrictedArguments args, bool[] hasBeenUsed) {
     Debug.Assert(hasBeenUsed.Length == args.Length);
     Debug.Assert(_index < args.Length);
     Debug.Assert(!hasBeenUsed[Index]);
     
     hasBeenUsed[_index] = true;
     return resolver.Convert(args.GetObject(_index), args.GetType(_index), ParameterInfo, _parameterType);
 }
コード例 #23
0
        protected internal override Func<object[], object> ToDelegate(OverloadResolver resolver, RestrictedArguments args, bool[] hasBeenUsed) {
            Func<object[], object> conv = resolver.GetConvertor(_index + 1, args.GetObject(_index), ParameterInfo, _parameterType);
            if (conv != null) {
                return conv;
            }

            return (Func<object[], object>)Delegate.CreateDelegate(
                typeof(Func<object[], object>), 
                _index + 1, 
                typeof(ArgBuilder).GetMethod("ArgumentRead"));
        }
コード例 #24
0
ファイル: KeywordArgBuilder.cs プロジェクト: TerabyteX/main
 internal override Expression ToReturnExpression(OverloadResolver resolver)
 {
     return _builder.ToReturnExpression(resolver);
 }
コード例 #25
0
 protected override Expression ToExpression(OverloadResolver/*!*/ resolver, RestrictedArguments/*!*/ args, bool[]/*!*/ hasBeenUsed) {
     Debug.Assert(Index < args.Length);
     Debug.Assert(Index < hasBeenUsed.Length);
     hasBeenUsed[Index] = true;
     return null;
 }
コード例 #26
0
        protected internal override Func<object[], object> ToDelegate(OverloadResolver resolver, RestrictedArguments args, bool[] hasBeenUsed) {
            string[] names = _names;
            int[] indexes = GetParameters(hasBeenUsed);

            Type dictType = ParameterInfo.ParameterType;

            Func<string[], object[], object> func = GetCreationDelegate(dictType);

            return (actualArgs) => {
                object[] values = new object[indexes.Length];
                for (int i = 0; i < indexes.Length; i++) {
                    values[i] = actualArgs[indexes[i] + 1];
                }
                return func(names, values);
            };
        }
コード例 #27
0
 protected override Expression ToExpression(OverloadResolver resolver, RestrictedArguments args, bool[] hasBeenUsed) {
     return AstUtils.Constant(Activator.CreateInstance(ParameterInfo.ParameterType));
 }
コード例 #28
0
 protected override Func<object[], object> ToDelegate(OverloadResolver resolver, RestrictedArguments args, bool[] hasBeenUsed) {
     object value = Activator.CreateInstance(ParameterInfo.ParameterType);
     return (_) => value;
 }
コード例 #29
0
ファイル: KeywordArgBuilder.cs プロジェクト: TerabyteX/main
 internal override Expression UpdateFromReturn(OverloadResolver resolver, RestrictedArguments args)
 {
     int index = GetKeywordIndex(args.Length);
     return _builder.UpdateFromReturn(resolver, MakeRestrictedArg(args, index));
 }
コード例 #30
0
 protected override Func<object[], object> ToDelegate(ref MethodInfo/*!*/ method, OverloadResolver/*!*/ resolver, RestrictedArguments/*!*/ args, bool[]/*!*/ hasBeenUsed) {
     return null;
 }