public void AddSplatted(MetaObjectBuilder /*!*/ metaBuilder, CallArguments /*!*/ args) { var arg = args.GetSplattedMetaArgument(); int listLength; ParameterExpression listVariable; metaBuilder.AddSplattedArgumentTest((IList)arg.Value, arg.Expression, out listLength, out listVariable); if (listLength > 0) { for (int i = 0; i < listLength; i++) { Add( Ast.Call( listVariable, typeof(IList).GetMethod("get_Item"), AstUtils.Constant(i) ) ); } } }
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 )); }
public void AddSplatted(MetaObjectBuilder/*!*/ metaBuilder, CallArguments/*!*/ args) { var arg = args.GetSplattedMetaArgument(); int listLength; ParameterExpression listVariable; metaBuilder.AddSplattedArgumentTest((IList)arg.Value, arg.Expression, out listLength, out listVariable); if (listLength > 0) { for (int i = 0; i < listLength; i++) { Add( Ast.Call( listVariable, typeof(IList).GetMethod("get_Item"), AstUtils.Constant(i) ) ); } } }
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(); }
public void AddSplatted(MetaObjectBuilder/*!*/ metaBuilder, CallArguments/*!*/ args) { var arg = args.GetSplattedMetaArgument(); int listLength; ParameterExpression listVariable; if (metaBuilder.AddSplattedArgumentTest(arg.Value, arg.Expression, out listLength, out listVariable)) { if (listLength > 0) { for (int i = 0; i < listLength; i++) { Add( Ast.Call( listVariable, typeof(List<object>).GetMethod("get_Item"), AstUtils.Constant(i) ) ); } } } else { // argument is not an array => add the argument itself: Add(arg.Expression); } }
public void AddCallArguments(MetaObjectBuilder /*!*/ metaBuilder, CallArguments /*!*/ args) { _callArguments = args; // calculate actual argument count: _actualArgumentCount = args.SimpleArgumentCount; if (args.Signature.HasSplattedArgument) { var splattedArg = args.GetSplattedMetaArgument(); metaBuilder.AddSplattedArgumentTest((IList)splattedArg.Value, splattedArg.Expression, out _listLength, out _listVariable); _actualArgumentCount += _listLength; } if (args.Signature.HasRhsArgument) { _actualArgumentCount++; } // check: if (HasTooFewArguments) { metaBuilder.SetWrongNumberOfArgumentsError(_actualArgumentCount, _mandatoryParamCount); return; } if (HasTooManyArguments) { metaBuilder.SetWrongNumberOfArgumentsError(_actualArgumentCount, _mandatoryParamCount); return; } bool isSplatted; // leading mandatory: for (int i = 0; i < _leadingMandatoryParamCount; i++) { _arguments[LeadingMandatoryIndex + i] = GetArgument(i, out isSplatted); } // trailing mandatory: for (int i = 0; i < TrailingMandatoryCount; i++) { _arguments[TrailingMandatoryIndex + i] = GetArgument(_actualArgumentCount - TrailingMandatoryCount + i, out isSplatted); } int start = _leadingMandatoryParamCount; int end = _actualArgumentCount - TrailingMandatoryCount; // optional: for (int i = 0; i < _optionalParamCount; i++) { _arguments[OptionalParameterIndex + i] = (start < end) ? GetArgument(start++, out isSplatted) : Ast.Field(null, Fields.DefaultArgument); } // unsplat: if (_hasUnsplatParameter) { Expression array; if (args.Signature.HasSplattedArgument) { // simple: var argsToUnsplat = new List <Expression>(); while (start < end) { var arg = GetArgument(start, out isSplatted); if (isSplatted) { break; } argsToUnsplat.Add(AstUtils.Box(arg)); start++; } array = Methods.MakeArrayOpCall(argsToUnsplat); int rangeStart = start - args.SimpleArgumentCount; int rangeLength = Math.Min(end - start, _listLength - rangeStart); // splatted: if (rangeLength > 0) { array = Methods.AddSubRange.OpCall(array, _listVariable, Ast.Constant(rangeStart), Ast.Constant(rangeLength)); start += rangeLength; } // rhs: while (start < end) { array = Methods.AddItem.OpCall(array, AstUtils.Box(GetArgument(start, out isSplatted))); start++; } } else { var argsToUnsplat = new List <Expression>(end - start); while (start < end) { argsToUnsplat.Add(AstUtils.Box(GetArgument(start++, out isSplatted))); } array = Methods.MakeArrayOpCall(argsToUnsplat); } _arguments[UnsplatParameterIndex] = array; } _callArguments = null; _listVariable = null; Debug.Assert(CollectionUtils.TrueForAll(_arguments, (e) => e != null)); }
public void AddCallArguments(MetaObjectBuilder/*!*/ metaBuilder, CallArguments/*!*/ args) { _callArguments = args; // calculate actual argument count: _actualArgumentCount = args.SimpleArgumentCount; if (args.Signature.HasSplattedArgument) { var splattedArg = args.GetSplattedMetaArgument(); metaBuilder.AddSplattedArgumentTest((IList)splattedArg.Value, splattedArg.Expression, out _listLength, out _listVariable); _actualArgumentCount += _listLength; } if (args.Signature.HasRhsArgument) { _actualArgumentCount++; } // check: if (HasTooFewArguments) { metaBuilder.SetWrongNumberOfArgumentsError(_actualArgumentCount, _mandatoryParamCount); return; } if (HasTooManyArguments) { metaBuilder.SetWrongNumberOfArgumentsError(_actualArgumentCount, _mandatoryParamCount); return; } bool isSplatted; // leading mandatory: for (int i = 0; i < _leadingMandatoryParamCount; i++) { _arguments[LeadingMandatoryIndex + i] = GetArgument(i, out isSplatted); } // trailing mandatory: for (int i = 0; i < TrailingMandatoryCount; i++) { _arguments[TrailingMandatoryIndex + i] = GetArgument(_actualArgumentCount - TrailingMandatoryCount + i, out isSplatted); } int start = _leadingMandatoryParamCount; int end = _actualArgumentCount - TrailingMandatoryCount; // optional: for (int i = 0; i < _optionalParamCount; i++) { _arguments[OptionalParameterIndex + i] = (start < end) ? GetArgument(start++, out isSplatted) : Ast.Field(null, Fields.DefaultArgument); } // unsplat: if (_hasUnsplatParameter) { Expression array; if (args.Signature.HasSplattedArgument) { // simple: var argsToUnsplat = new List<Expression>(); while (start < end) { var arg = GetArgument(start, out isSplatted); if (isSplatted) { break; } argsToUnsplat.Add(AstUtils.Box(arg)); start++; } array = Methods.MakeArrayOpCall(argsToUnsplat); int rangeStart = start - args.SimpleArgumentCount; int rangeLength = Math.Min(end - start, _listLength - rangeStart); // splatted: if (rangeLength > 0) { array = Methods.AddSubRange.OpCall(array, _listVariable, Ast.Constant(rangeStart), Ast.Constant(rangeLength)); start += rangeLength; } // rhs: while (start < end) { array = Methods.AddItem.OpCall(array, AstUtils.Box(GetArgument(start, out isSplatted))); start++; } } else { var argsToUnsplat = new List<Expression>(end - start); while (start < end) { argsToUnsplat.Add(AstUtils.Box(GetArgument(start++, out isSplatted))); } array = Methods.MakeArrayOpCall(argsToUnsplat); } _arguments[UnsplatParameterIndex] = array; } _callArguments = null; _listVariable = null; Debug.Assert(CollectionUtils.TrueForAll(_arguments, (e) => e != null)); }