private static ActualArguments/*!*/ CreateActualArguments(List<DynamicMetaObject>/*!*/ normalized, MetaObjectBuilder/*!*/ metaBuilder, CallArguments/*!*/ args, int hidden, int preSplatLimit, int postSplatLimit, out int lastSplattedArg, out IList list, out ParameterExpression listVariable) { int firstSplattedArg, splatIndex, collapsedArgCount; // simple arguments: for (int i = 0; i < args.SimpleArgumentCount; i++) { normalized.Add(args.GetSimpleMetaArgument(i)); } // splat argument: list = null; listVariable = null; if (args.Signature.HasSplattedArgument) { firstSplattedArg = normalized.Count; int listLength; var splatted = args.GetSplattedMetaArgument(); list = (IList)splatted.Value; metaBuilder.AddSplattedArgumentTest(list, splatted.Expression, out listLength, out listVariable); int i = 0; while (i < Math.Min(listLength, preSplatLimit - firstSplattedArg)) { normalized.Add(MakeSplattedItem(list, listVariable, i)); i++; } // skip items that are not needed for overload resolution splatIndex = normalized.Count; i = Math.Max(i, listLength - (postSplatLimit - (args.Signature.HasRhsArgument ? 1 : 0))); while (i < listLength) { normalized.Add(MakeSplattedItem(list, listVariable, i)); i++; } collapsedArgCount = listLength - (normalized.Count - firstSplattedArg); lastSplattedArg = normalized.Count - 1; } else { splatIndex = firstSplattedArg = lastSplattedArg = -1; collapsedArgCount = 0; } Debug.Assert(collapsedArgCount >= 0); // rhs argument: if (args.Signature.HasRhsArgument) { normalized.Add(args.GetRhsMetaArgument()); } return new ActualArguments( normalized.ToArray(), DynamicMetaObject.EmptyMetaObjects, ArrayUtils.EmptyStrings, hidden, collapsedArgCount, firstSplattedArg, splatIndex ); }
private static ActualArguments /*!*/ CreateActualArguments(List <DynamicMetaObject> /*!*/ normalized, MetaObjectBuilder /*!*/ metaBuilder, CallArguments /*!*/ args, int hidden, int preSplatLimit, int postSplatLimit, out int lastSplattedArg, out IList list, out ParameterExpression listVariable) { int firstSplattedArg, splatIndex, collapsedArgCount; // simple arguments: for (int i = 0; i < args.SimpleArgumentCount; i++) { normalized.Add(args.GetSimpleMetaArgument(i)); } // splat argument: list = null; listVariable = null; if (args.Signature.HasSplattedArgument) { firstSplattedArg = normalized.Count; int listLength; var splatted = args.GetSplattedMetaArgument(); list = (IList)splatted.Value; metaBuilder.AddSplattedArgumentTest(list, splatted.Expression, out listLength, out listVariable); int i = 0; while (i < Math.Min(listLength, preSplatLimit - firstSplattedArg)) { normalized.Add(MakeSplattedItem(list, listVariable, i)); i++; } // skip items that are not needed for overload resolution splatIndex = normalized.Count; i = Math.Max(i, listLength - (postSplatLimit - (args.Signature.HasRhsArgument ? 1 : 0))); while (i < listLength) { normalized.Add(MakeSplattedItem(list, listVariable, i)); i++; } collapsedArgCount = listLength - (normalized.Count - firstSplattedArg); lastSplattedArg = normalized.Count - 1; } else { splatIndex = firstSplattedArg = lastSplattedArg = -1; collapsedArgCount = 0; } Debug.Assert(collapsedArgCount >= 0); // rhs argument: if (args.Signature.HasRhsArgument) { normalized.Add(args.GetRhsMetaArgument()); } return(new ActualArguments( normalized.ToArray(), DynamicMetaObject.EmptyMetaObjects, ArrayUtils.EmptyStrings, hidden, collapsedArgCount, firstSplattedArg, splatIndex )); }
// 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(); }