internal static void GetParameterCount(OverloadInfo /*!*/ method, SelfCallConvention callConvention, out int mandatory, out int optional) { mandatory = 0; optional = 0; for (int i = GetHiddenParameterCount(method, callConvention); i < method.ParameterCount; i++) { var info = method.Parameters[i]; if (method.IsParamArray(i)) { // TODO: indicate splat args separately? optional++; } else if (info.IsOutParameter()) { // Python allows passing of optional "clr.Reference" to capture out parameters // Ruby should allow similar optional++; } else if (info.IsMandatory()) { mandatory++; } else { optional++; } } }
internal RubyOverloadResolver(MetaObjectBuilder/*!*/ metaBuilder, CallArguments/*!*/ args, SelfCallConvention callConvention, bool implicitProtocolConversions) : base(args.RubyContext.Binder) { _args = args; _metaBuilder = metaBuilder; _callConvention = callConvention; _implicitProtocolConversions = implicitProtocolConversions; }
internal RubyOverloadResolver(MetaObjectBuilder /*!*/ metaBuilder, CallArguments /*!*/ args, SelfCallConvention callConvention, bool implicitProtocolConversions) : base(args.RubyContext.Binder) { _args = args; _metaBuilder = metaBuilder; _callConvention = callConvention; _implicitProtocolConversions = implicitProtocolConversions; }
internal static int GetHiddenParameterCount(OverloadInfo /*!*/ method, SelfCallConvention callConvention) { int i = 0; var infos = method.Parameters; if (callConvention == SelfCallConvention.SelfIsInstance) { if (method.IsStatic) { Debug.Assert(RubyUtils.IsOperator(method) || method.IsExtension); i++; } } while (i < infos.Count && infos[i].ParameterType.IsSubclassOf(typeof(RubyCallSiteStorage))) { i++; } if (i < infos.Count) { var info = infos[i]; if (info.ParameterType == typeof(RubyScope)) { i++; } else if (info.ParameterType == typeof(RubyContext)) { i++; } else if (method.IsConstructor && info.ParameterType == typeof(RubyClass)) { i++; } } if (i < infos.Count && infos[i].ParameterType == typeof(BlockParam)) { i++; } if (callConvention == SelfCallConvention.SelfIsParameter) { Debug.Assert(i < infos.Count); Debug.Assert(method.IsStatic); i++; } return(i); }
/// <summary> /// Resolves an library method overload and builds call expression. /// The resulting expression on meta-builder doesn't handle block control flow yet. /// </summary> internal static void BuildCallNoFlow(MetaObjectBuilder /*!*/ metaBuilder, CallArguments /*!*/ args, string /*!*/ name, IList <OverloadInfo> /*!*/ overloads, SelfCallConvention callConvention, bool implicitProtocolConversions) { RubyOverloadResolver resolver; var bindingTarget = ResolveOverload(metaBuilder, args, name, overloads, callConvention, implicitProtocolConversions, out resolver); if (bindingTarget.Success) { // TODO: create a custom overload info: if (ReferenceEquals(bindingTarget.Overload.ReflectionInfo, Methods.CreateDefaultInstance)) { Debug.Assert(args.TargetClass.TypeTracker.Type.IsValueType); metaBuilder.Result = Ast.New(args.TargetClass.TypeTracker.Type); } else if (args.Signature.IsVirtualCall && bindingTarget.Overload.IsVirtual) { // Virtual methods that have been detached from the CLR type and // defined on the corresponding Ruby class or its subclass are not // directly invoked from a dynamic virtual call to prevent recursion. // Instead the base call is performed. // // Example: // class C < ArrayList // define_method(:Add, instance_method(:Add)) // end // // C.new.Add(1) // // C.new.Add dispatches to the virtual ArrayList::Add, which in turn dispatches to the auto-generated override C$1::Add. // That gets here since the defined method is a Ruby method (a detached CLR method group). If we called it directly // it would invoke the C$1::Add override again leading to a stack overflow. So we need to use a base call instead. metaBuilder.Result = Ast.Field(null, Fields.ForwardToBase); } else { metaBuilder.Result = bindingTarget.MakeExpression(); } } else { metaBuilder.SetError(resolver.MakeInvalidParametersError(bindingTarget).Expression); } }
// TODO: OBSOLETE private static Expression[]/*!*/ MakeActualArgs(MetaObjectBuilder/*!*/ metaBuilder, CallArguments/*!*/ args, SelfCallConvention callConvention, bool calleeHasBlockParam, bool injectMissingBlockParam) { var actualArgs = new List<Expression>(); // self (instance): if (callConvention == SelfCallConvention.SelfIsInstance) { // test already added by method resolver Debug.Assert(args.TargetExpression != null); AddArgument(actualArgs, args.Target, args.TargetExpression); } // block: if (calleeHasBlockParam) { if (args.Signature.HasBlock) { if (args.GetBlock() == null) { // the user explicitly passed nil as a block arg: actualArgs.Add(AstUtils.Constant(null)); } else { // pass BlockParam: Debug.Assert(metaBuilder.BfcVariable != null); actualArgs.Add(metaBuilder.BfcVariable); } } else { // no block passed into a method with a BlockParam: actualArgs.Add(AstUtils.Constant(null)); } } else if (injectMissingBlockParam) { // no block passed into a method w/o a BlockParam (we still need to fill the missing block argument): actualArgs.Add(AstUtils.Constant(null)); } // self (non-instance): if (callConvention == SelfCallConvention.SelfIsParameter) { // test already added by method resolver AddArgument(actualArgs, args.Target, args.TargetExpression); } // simple arguments: for (int i = 0; i < args.SimpleArgumentCount; i++) { var value = args.GetSimpleArgument(i); var expr = args.GetSimpleArgumentExpression(i); // TODO: overload-resolution restrictions metaBuilder.AddObjectTypeRestriction(value, expr); AddArgument(actualArgs, value, expr); } // splat argument: int listLength; ParameterExpression listVariable; if (args.Signature.HasSplattedArgument) { object splattedArg = args.GetSplattedArgument(); Expression splattedArgExpression = args.GetSplattedArgumentExpression(); if (metaBuilder.AddSplattedArgumentTest(splattedArg, splattedArgExpression, out listLength, out listVariable)) { // AddTestForListArg only returns 'true' if the argument is a List<object> var list = (List<object>)splattedArg; // get arguments, add tests for (int j = 0; j < listLength; j++) { var value = list[j]; var expr = Ast.Call(listVariable, typeof(List<object>).GetMethod("get_Item"), AstUtils.Constant(j)); // TODO: overload-resolution restrictions metaBuilder.AddObjectTypeCondition(value, expr); AddArgument(actualArgs, value, expr); } } else { // argument is not an array => add the argument itself: AddArgument(actualArgs, splattedArg, splattedArgExpression); } } // rhs argument: if (args.Signature.HasRhsArgument) { var value = args.GetRhsArgument(); var expr = args.GetRhsArgumentExpression(); // TODO: overload-resolution restrictions metaBuilder.AddObjectTypeRestriction(value, expr); AddArgument(actualArgs, value, expr); } return actualArgs.ToArray(); }
/// <summary> /// Resolves an library method overload and builds call expression. /// The resulting expression on meta-builder doesn't handle block control flow yet. /// </summary> internal static void BuildCallNoFlow(MetaObjectBuilder/*!*/ metaBuilder, CallArguments/*!*/ args, string/*!*/ name, IList<MethodBase>/*!*/ overloads, SelfCallConvention callConvention) { RubyOverloadResolver resolver; var bindingTarget = ResolveOverload(metaBuilder, args, name, overloads, callConvention, out resolver); if (bindingTarget.Success) { metaBuilder.Result = bindingTarget.MakeExpression(); } else { metaBuilder.SetError(resolver.MakeInvalidParametersError(bindingTarget).Expression); } }
internal static void GetParameterCount(MethodBase/*!*/ method, ParameterInfo/*!*/[]/*!*/ parameterInfos, SelfCallConvention callConvention, out int mandatory, out int optional) { mandatory = 0; optional = 0; for (int i = GetHiddenParameterCount(method, parameterInfos, callConvention); i < parameterInfos.Length; i++) { var info = parameterInfos[i]; if (CompilerHelpers.IsParamArray(info)) { // TODO: indicate splat args separately? optional++; } else if (CompilerHelpers.IsOutParameter(info)) { // Python allows passing of optional "clr.Reference" to capture out parameters // Ruby should allow similar optional++; } else if (CompilerHelpers.IsMandatoryParameter(info)) { mandatory++; } else { optional++; } } }
internal static int GetHiddenParameterCount(MethodBase/*!*/ method, ParameterInfo/*!*/[]/*!*/ infos, SelfCallConvention callConvention) { int i = 0; if (callConvention == SelfCallConvention.SelfIsInstance) { if (CompilerHelpers.IsStatic(method)) { Debug.Assert(RubyUtils.IsOperator(method) || CompilerHelpers.IsExtension(method)); i++; } } while (i < infos.Length && infos[i].ParameterType.IsSubclassOf(typeof(RubyCallSiteStorage))) { i++; } if (i < infos.Length) { var info = infos[i]; if (info.ParameterType == typeof(RubyScope)) { i++; } else if (info.ParameterType == typeof(RubyContext)) { i++; } else if (method.IsConstructor && info.ParameterType == typeof(RubyClass)) { i++; } } if (i < infos.Length && infos[i].ParameterType == typeof(BlockParam)) { i++; } if (callConvention == SelfCallConvention.SelfIsParameter) { Debug.Assert(i < infos.Length); Debug.Assert(CompilerHelpers.IsStatic(method)); i++; } return i; }
internal static void GetParameterCount(OverloadInfo/*!*/ method, SelfCallConvention callConvention, out int mandatory, out int optional) { mandatory = 0; optional = 0; for (int i = GetHiddenParameterCount(method, callConvention); i < method.ParameterCount; i++) { var info = method.Parameters[i]; if (method.IsParamArray(i)) { // TODO: indicate splat args separately? optional++; } else if (info.IsOutParameter()) { // Python allows passing of optional "clr.Reference" to capture out parameters // Ruby should allow similar optional++; } else if (info.IsMandatory()) { mandatory++; } else { optional++; } } }
internal static int GetHiddenParameterCount(OverloadInfo/*!*/ method, SelfCallConvention callConvention) { int i = 0; var infos = method.Parameters; if (callConvention == SelfCallConvention.SelfIsInstance) { if (method.IsStatic) { Debug.Assert(RubyUtils.IsOperator(method) || method.IsExtension); i++; } } while (i < infos.Count && infos[i].ParameterType.IsSubclassOf(typeof(RubyCallSiteStorage))) { i++; } if (i < infos.Count) { var info = infos[i]; if (info.ParameterType == typeof(RubyScope)) { i++; } else if (info.ParameterType == typeof(RubyContext)) { i++; } else if (method.IsConstructor && info.ParameterType == typeof(RubyClass)) { i++; } } if (i < infos.Count && infos[i].ParameterType == typeof(BlockParam)) { i++; } if (callConvention == SelfCallConvention.SelfIsParameter) { Debug.Assert(i < infos.Count); Debug.Assert(method.IsStatic); i++; } return i; }
/// <summary> /// Resolves an library method overload and builds call expression. /// The resulting expression on meta-builder doesn't handle block control flow yet. /// </summary> internal static void BuildCallNoFlow(MetaObjectBuilder/*!*/ metaBuilder, CallArguments/*!*/ args, string/*!*/ name, IList<OverloadInfo>/*!*/ overloads, SelfCallConvention callConvention, bool implicitProtocolConversions) { RubyOverloadResolver resolver; var bindingTarget = ResolveOverload(metaBuilder, args, name, overloads, callConvention, implicitProtocolConversions, out resolver); if (bindingTarget.Success) { // TODO: create a custom overload info: if (ReferenceEquals(bindingTarget.Overload.ReflectionInfo, Methods.CreateDefaultInstance)) { Debug.Assert(args.TargetClass.TypeTracker.Type.IsValueType); metaBuilder.Result = Ast.New(args.TargetClass.TypeTracker.Type); } else if (args.Signature.IsVirtualCall && bindingTarget.Overload.IsVirtual) { // Virtual methods that have been detached from the CLR type and // defined on the corresponding Ruby class or its subclass are not // directly invoked from a dynamic virtual call to prevent recursion. // Instead the base call is performed. // // Example: // class C < ArrayList // define_method(:Add, instance_method(:Add)) // end // // C.new.Add(1) // // C.new.Add dispatches to the virtual ArrayList::Add, which in turn dispatches to the auto-generated override C$1::Add. // That gets here since the defined method is a Ruby method (a detached CLR method group). If we called it directly // it would invoke the C$1::Add override again leading to a stack overflow. So we need to use a base call instead. metaBuilder.Result = Ast.Field(null, Fields.ForwardToBase); } else { metaBuilder.Result = bindingTarget.MakeExpression(); } } else { metaBuilder.SetError(resolver.MakeInvalidParametersError(bindingTarget).Expression); } }
internal static BindingTarget/*!*/ ResolveOverload(MetaObjectBuilder/*!*/ metaBuilder, CallArguments/*!*/ args, string/*!*/ name, IList<OverloadInfo>/*!*/ overloads, SelfCallConvention callConvention, bool implicitProtocolConversions, out RubyOverloadResolver/*!*/ resolver) { resolver = new RubyOverloadResolver(metaBuilder, args, callConvention, implicitProtocolConversions); var bindingTarget = resolver.ResolveOverload(name, overloads, NarrowingLevel.None, NarrowingLevel.All); bool calleeHasBlockParam = bindingTarget.Success && HasBlockParameter(bindingTarget.Overload); // At runtime the BlockParam is created with a new RFC instance that identifies the library method frame as // a proc-converter target of a method unwinder triggered by break from a block. if (args.Signature.HasBlock && calleeHasBlockParam) { metaBuilder.ControlFlowBuilder = RuleControlFlowBuilder; } // add restrictions used for overload resolution: resolver.AddArgumentRestrictions(metaBuilder, bindingTarget); return bindingTarget; }
internal static BindingTarget/*!*/ ResolveOverload(MetaObjectBuilder/*!*/ metaBuilder, CallArguments/*!*/ args, string/*!*/ name, IList<MethodBase>/*!*/ overloads, SelfCallConvention callConvention, out RubyOverloadResolver/*!*/ resolver) { resolver = new RubyOverloadResolver(metaBuilder, args, callConvention); var bindingTarget = resolver.ResolveOverload(name, overloads, NarrowingLevel.None, NarrowingLevel.All); bool calleeHasBlockParam = bindingTarget.Success && HasBlockParameter(bindingTarget.Method); // At runtime the BlockParam is created with a new RFC instance that identifies the library method frame as // a proc-converter target of a method unwinder triggered by break from a block. if (args.Signature.HasBlock) { var metaBlock = args.GetMetaBlock(); if (metaBlock.Value != null && calleeHasBlockParam) { Debug.Assert(metaBuilder.BfcVariable != null); metaBuilder.ControlFlowBuilder = RuleControlFlowBuilder; } // Overload resolution might not need to distinguish between nil and non-nil block. // However, we still do since we construct CF only for non-nil blocks. if (metaBlock.Value == null) { metaBuilder.AddRestriction(Ast.Equal(metaBlock.Expression, AstUtils.Constant(null))); } else { // don't need to test the exact type of the Proc since the code is subclass agnostic: metaBuilder.AddRestriction(Ast.NotEqual(metaBlock.Expression, AstUtils.Constant(null))); } } // add restrictions used for overload resolution: resolver.AddArgumentRestrictions(metaBuilder, bindingTarget); return bindingTarget; }
internal static BindingTarget /*!*/ ResolveOverload(MetaObjectBuilder /*!*/ metaBuilder, CallArguments /*!*/ args, string /*!*/ name, IList <OverloadInfo> /*!*/ overloads, SelfCallConvention callConvention, bool implicitProtocolConversions, out RubyOverloadResolver /*!*/ resolver) { resolver = new RubyOverloadResolver(metaBuilder, args, callConvention, implicitProtocolConversions); var bindingTarget = resolver.ResolveOverload(name, overloads, NarrowingLevel.None, NarrowingLevel.All); bool calleeHasBlockParam = bindingTarget.Success && HasBlockParameter(bindingTarget.Overload); // At runtime the BlockParam is created with a new RFC instance that identifies the library method frame as // a proc-converter target of a method unwinder triggered by break from a block. if (args.Signature.HasBlock && calleeHasBlockParam) { metaBuilder.ControlFlowBuilder = RuleControlFlowBuilder; } // add restrictions used for overload resolution: resolver.AddArgumentRestrictions(metaBuilder, bindingTarget); return(bindingTarget); }
// Normalizes arguments: inserts self, expands splats, and inserts rhs arg. // Adds any restrictions/conditions applied to the arguments to the given meta-builder. internal static DynamicMetaObject[]/*!*/ NormalizeArguments(MetaObjectBuilder/*!*/ metaBuilder, CallArguments/*!*/ args, SelfCallConvention callConvention, bool calleeHasBlockParam, bool injectMissingBlockParam) { var result = new List<DynamicMetaObject>(); // self (instance): if (callConvention == SelfCallConvention.SelfIsInstance) { result.Add(args.MetaTarget); } // block: if (calleeHasBlockParam) { if (args.Signature.HasBlock) { if (args.GetMetaBlock() == null) { // the user explicitly passed nil as a block arg: result.Add(RubyBinder.NullMetaObject); } else { // pass BlockParam: Debug.Assert(metaBuilder.BfcVariable != null); result.Add(new DynamicMetaObject(metaBuilder.BfcVariable, BindingRestrictions.Empty)); } } else { // no block passed into a method with a BlockParam: result.Add(RubyBinder.NullMetaObject); } } else if (injectMissingBlockParam) { // no block passed into a method w/o a BlockParam (we still need to fill the missing block argument): result.Add(RubyBinder.NullMetaObject); } // self (parameter): if (callConvention == SelfCallConvention.SelfIsParameter) { result.Add(args.MetaTarget); } // simple arguments: for (int i = 0; i < args.SimpleArgumentCount; i++) { result.Add(args.GetSimpleMetaArgument(i)); } // splat argument: int listLength; ParameterExpression listVariable; if (args.Signature.HasSplattedArgument) { var splatted = args.GetSplattedMetaArgument(); if (metaBuilder.AddSplattedArgumentTest(splatted.Value, splatted.Expression, out listLength, out listVariable)) { // AddTestForListArg only returns 'true' if the argument is a List<object> var list = (List<object>)splatted.Value; // get arguments, add tests for (int j = 0; j < listLength; j++) { result.Add(DynamicMetaObject.Create( list[j], Ast.Call(listVariable, typeof(List<object>).GetMethod("get_Item"), AstUtils.Constant(j)) )); } } else { // argument is not an array => add the argument itself: result.Add(splatted); } } // rhs argument: if (args.Signature.HasRhsArgument) { result.Add(args.GetRhsMetaArgument()); } return result.ToArray(); }
/// <summary> /// Resolves an library method overload and builds call expression. /// The resulting expression on meta-builder doesn't handle block control flow yet. /// </summary> internal static void BuildCallNoFlow(MetaObjectBuilder/*!*/ metaBuilder, CallArguments/*!*/ args, string/*!*/ name, IList<MethodBase>/*!*/ overloads, SelfCallConvention callConvention) { var bindingTarget = ResolveOverload(name, overloads, args, callConvention); bool calleeHasBlockParam = bindingTarget.Success && HasBlockParameter(bindingTarget.Method); // Allocates a variable holding BlockParam. At runtime the BlockParam is created with a new RFC instance that // identifies the library method frame as a proc-converter target of a method unwinder triggered by break from a block. if (args.Signature.HasBlock) { var metaBlock = args.GetMetaBlock(); if (metaBlock.Value != null && calleeHasBlockParam) { if (metaBuilder.BfcVariable == null) { metaBuilder.BfcVariable = metaBuilder.GetTemporary(typeof(BlockParam), "#bfc"); } metaBuilder.ControlFlowBuilder = RuleControlFlowBuilder; } // Block test - we need to test for a block regardless of whether it is actually passed to the method or not // since the information that the block is not null is used for overload resolution. if (metaBlock.Value == null) { metaBuilder.AddRestriction(Ast.Equal(metaBlock.Expression, AstUtils.Constant(null))); } else { // don't need to test the exact type of the Proc since the code is subclass agnostic: metaBuilder.AddRestriction(Ast.NotEqual(metaBlock.Expression, AstUtils.Constant(null))); } } var actualArgs = MakeActualArgs(metaBuilder, args, callConvention, calleeHasBlockParam, true); if (bindingTarget.Success) { var parameterBinder = new RubyParameterBinder(args.RubyContext.Binder, args.MetaContext.Expression, args.Signature.HasScope); metaBuilder.Result = bindingTarget.MakeExpression(parameterBinder, actualArgs); } else { metaBuilder.SetError(args.RubyContext.RubyBinder.MakeInvalidParametersError(bindingTarget).Expression); } }
internal static BindingTarget/*!*/ ResolveOverload(string/*!*/ name, IList<MethodBase>/*!*/ overloads, CallArguments/*!*/ args, SelfCallConvention callConvention) { var methodBinder = MethodBinder.MakeBinder(args.RubyContext.Binder, name, overloads, ArrayUtils.EmptyStrings, NarrowingLevel.None, NarrowingLevel.All); var argTypes = GetSignatureToMatch(args, callConvention); return methodBinder.MakeBindingTarget(CallTypes.None, argTypes); }
public RubyOverloadResolver(MetaObjectBuilder/*!*/ metaBuilder, CallArguments/*!*/ args, SelfCallConvention callConvention) : base(args.RubyContext.Binder) { _args = args; _metaBuilder = metaBuilder; _callConvention = callConvention; }
/// <summary> /// Resolves an library method overload and builds call expression. /// The resulting expression on meta-builder doesn't handle block control flow yet. /// </summary> internal static void BuildCallNoFlow(MetaObjectBuilder/*!*/ metaBuilder, CallArguments/*!*/ args, string/*!*/ name, IList<MethodBase>/*!*/ overloads, SelfCallConvention callConvention) { var bindingTarget = ResolveOverload(name, overloads, args, callConvention); if (bindingTarget.Success) { bool calleeHasBlockParam = HasBlockParameter(bindingTarget.Method); // Allocates a variable holding BlockParam. At runtime the BlockParam is created with a new RFC instance that // identifies the library method frame as a proc-converter target of a method unwinder triggered by break from a block. // // NOTE: We check for null block here -> test for that fact is added in MakeActualArgs if (args.Signature.HasBlock && args.GetBlock() != null && calleeHasBlockParam) { if (metaBuilder.BfcVariable == null) { metaBuilder.BfcVariable = metaBuilder.GetTemporary(typeof(BlockParam), "#bfc"); } metaBuilder.ControlFlowBuilder = RuleControlFlowBuilder; } var actualArgs = MakeActualArgs(metaBuilder, args, callConvention, calleeHasBlockParam, true); var parameterBinder = new RubyParameterBinder(args.RubyContext.Binder, args.MetaContext.Expression, args.Signature.HasScope); var targetExpression = bindingTarget.MakeExpression(parameterBinder, actualArgs); metaBuilder.Result = targetExpression; } else { metaBuilder.SetError(args.RubyContext.RubyBinder.MakeInvalidParametersError(bindingTarget).Expression); } }
// TODO: OBSOLETE private static Type[]/*!*/ GetSignatureToMatch(CallArguments/*!*/ args, SelfCallConvention callConvention) { var result = new List<Type>(args.ExplicitArgumentCount); // self (instance): if (callConvention == SelfCallConvention.SelfIsInstance) { result.Add(CompilerHelpers.GetType(args.Target)); } // block: if (args.Signature.HasBlock) { // use None to let binder know that [NotNull]BlockParam is not applicable result.Add(args.GetBlock() != null ? typeof(BlockParam) : typeof(DynamicNull)); } else { result.Add(typeof(MissingBlockParam)); } // self (non-instance): if (callConvention == SelfCallConvention.SelfIsParameter) { result.Add(CompilerHelpers.GetType(args.Target)); } // simple args: for (int i = 0; i < args.SimpleArgumentCount; i++) { result.Add(CompilerHelpers.GetType(args.GetSimpleArgument(i))); } // splat arg: if (args.Signature.HasSplattedArgument) { object splattedArg = args.GetSplattedArgument(); var list = splattedArg as List<object>; if (list != null) { foreach (object obj in list) { result.Add(CompilerHelpers.GetType(obj)); } } else { result.Add(CompilerHelpers.GetType(splattedArg)); } } // rhs arg: if (args.Signature.HasRhsArgument) { result.Add(CompilerHelpers.GetType(args.GetRhsArgument())); } return result.ToArray(); }
/// <summary> /// Resolves an library method overload and builds call expression. /// The resulting expression on meta-builder doesn't handle block control flow yet. /// </summary> internal static void BuildCallNoFlow(MetaObjectBuilder/*!*/ metaBuilder, CallArguments/*!*/ args, string/*!*/ name, IList<MethodBase>/*!*/ overloads, SelfCallConvention callConvention, bool implicitProtocolConversions) { RubyOverloadResolver resolver; var bindingTarget = ResolveOverload(metaBuilder, args, name, overloads, callConvention, implicitProtocolConversions, out resolver); if (bindingTarget.Success) { if (ReferenceEquals(bindingTarget.Method, Methods.CreateDefaultInstance)) { Debug.Assert(args.TargetClass.TypeTracker.Type.IsValueType); metaBuilder.Result = Ast.New(args.TargetClass.TypeTracker.Type); } else { metaBuilder.Result = bindingTarget.MakeExpression(); } } else { metaBuilder.SetError(resolver.MakeInvalidParametersError(bindingTarget).Expression); } }