internal static MSA.Expression /*!*/ InvokeMethod(RubyContext /*!*/ context, string /*!*/ name, RubyCallSignature signature, MSA.Expression /*!*/ scope, MSA.Expression /*!*/ target, MSA.Expression /*!*/ arg0, MSA.Expression /*!*/ arg1) { Debug.Assert(signature.HasScope); return(AstUtils.LightDynamic(RubyCallAction.Make(context, name, signature), AstUtils.Convert(scope, typeof(RubyScope)), target, arg0, arg1)); }
internal override MSA.Expression /*!*/ TransformRead(AstGenerator /*!*/ gen) { return(Methods.MatchString.OpCall( AstUtils.LightDynamic(ConvertToStrAction.Make(gen.Context), typeof(MutableString), _expression.Transform(gen)), _regex.Transform(gen), gen.CurrentScopeVariable )); }
internal static Expression /*!*/ ConvertExpression(Expression /*!*/ expr, Type /*!*/ toType, RubyContext /*!*/ context, Expression /*!*/ contextExpression, bool implicitProtocolConversions) { return (ImplicitConvert(expr, expr.Type, toType) ?? ExplicitConvert(expr, expr.Type, toType) ?? AstUtils.LightDynamic(ProtocolConversionAction.GetConversionAction(context, toType, implicitProtocolConversions), toType, expr)); }
internal override MSA.Expression /*!*/ TransformDefinedCondition(AstGenerator /*!*/ gen) { // MRI doesn't evaluate the arguments return(AstUtils.LightDynamic( SuperCallAction.Make(gen.Context, RubyCallSignature.IsDefined(true), gen.CurrentFrame.UniqueId), typeof(bool), gen.CurrentScopeVariable, gen.CurrentSelfVariable )); }
// when [<expr>, ...] *<array> private static MSA.Expression /*!*/ MakeArrayTest(AstGenerator /*!*/ gen, MSA.Expression /*!*/ array, MSA.Expression value) { return(Methods.ExistsUnsplat.OpCall( Ast.Constant(CallSite <Func <CallSite, object, object, object> > .Create( RubyCallAction.Make(gen.Context, "===", RubyCallSignature.WithImplicitSelf(2)) )), AstUtils.LightDynamic(ConvertToArraySplatAction.Make(gen.Context), array), AstUtils.Box(value) )); }
internal MSA.Expression /*!*/ MakeCallSite(CallSiteBinder /*!*/ binder) { if (SplattedArgument != null) { Add(SplattedArgument); } if (RhsArgument != null) { Add(RhsArgument); } return(AstUtils.LightDynamic(binder, this)); }
internal static MSA.Expression /*!*/ YieldExpression( RubyContext /*!*/ context, ICollection <MSA.Expression> /*!*/ arguments, MSA.Expression splattedArgument, MSA.Expression rhsArgument, MSA.Expression blockArgument, MSA.Expression /*!*/ bfcVariable, MSA.Expression /*!*/ selfArgument) { Assert.NotNull(arguments, bfcVariable, selfArgument); bool hasArgumentArray; var opMethod = Methods.Yield(arguments.Count, splattedArgument != null, rhsArgument != null, out hasArgumentArray); var args = new AstExpressions(); foreach (var arg in arguments) { args.Add(AstUtils.Box(arg)); } if (hasArgumentArray) { args = new AstExpressions { Ast.NewArrayInit(typeof(object), args) }; } if (splattedArgument != null) { args.Add(AstUtils.LightDynamic(ExplicitSplatAction.Make(context), typeof(IList), splattedArgument)); } if (rhsArgument != null) { args.Add(AstUtils.Box(rhsArgument)); } args.Add(blockArgument != null ? AstUtils.Convert(blockArgument, typeof(Proc)) : AstFactory.NullOfProc); args.Add(AstUtils.Box(selfArgument)); args.Add(bfcVariable); return(Ast.Call(opMethod, args)); }
internal void TransformToCall(AstGenerator /*!*/ gen, CallSiteBuilder /*!*/ siteBuilder) { if (_expressions != null) { foreach (var arg in _expressions) { siteBuilder.Add(arg.TransformRead(gen)); } } if (_maplets != null) { siteBuilder.Add(gen.TransformToHashConstructor(_maplets)); } if (_array != null) { siteBuilder.SplattedArgument = AstUtils.LightDynamic(SplatAction.Make(gen.Context), typeof(IList), _array.TransformRead(gen)); } }
// when <expr> // generates into: // RubyOps.IsTrue(<expr>) if the case has no value, otherise: // RubyOps.IsTrue(Call("===", <expr>, <value>)) private static MSA.Expression /*!*/ MakeTest(AstGenerator /*!*/ gen, Expression /*!*/ expr, MSA.Expression value) { MSA.Expression transformedExpr = expr.TransformRead(gen); if (expr is SplattedArgument) { if (value != null) { return(Methods.ExistsUnsplatCompare.OpCall( Ast.Constant(CallSite <Func <CallSite, object, object, object> > .Create( RubyCallAction.Make(gen.Context, "===", RubyCallSignature.WithImplicitSelf(2)) )), AstUtils.LightDynamic(ExplicitTrySplatAction.Make(gen.Context), transformedExpr), AstUtils.Box(value) )); } else { return(Methods.ExistsUnsplat.OpCall( AstUtils.LightDynamic(ExplicitTrySplatAction.Make(gen.Context), transformedExpr) )); } } else { if (value != null) { return(AstFactory.IsTrue( CallSiteBuilder.InvokeMethod(gen.Context, "===", RubyCallSignature.WithScope(1), gen.CurrentScopeVariable, transformedExpr, value ) )); } else { return(AstFactory.IsTrue(transformedExpr)); } } }
internal static MSA.Expression /*!*/ TransformRead(AstGenerator /*!*/ gen, AstExpressions /*!*/ rightValues, MSA.Expression splattedValue, bool doSplat) { Assert.NotNull(gen, rightValues); MSA.Expression result; // We need to distinguish various special cases here. // For parallel assignment specification, see "Ruby Language.docx/Runtime/Parallel Assignment". // R(0,*)? bool rightNoneSplat = rightValues.Count == 0 && splattedValue != null; // R(1,-)? bool rightOneNone = rightValues.Count == 1 && splattedValue == null; if (rightNoneSplat) { result = AstUtils.LightDynamic(SplatAction.Make(gen.Context), typeof(IList), splattedValue); if (doSplat) { result = Methods.Splat.OpCall(result); } } else if (rightOneNone && doSplat) { result = rightValues[0]; } else { result = Methods.MakeArrayOpCall(rightValues); if (splattedValue != null) { result = Methods.SplatAppend.OpCall(result, AstUtils.LightDynamic(SplatAction.Make(gen.Context), typeof(IList), splattedValue)); } } return(result); }
internal override MSA.Expression /*!*/ TransformRead(AstGenerator /*!*/ gen) { return(AstUtils.LightDynamic(ExplicitSplatAction.Make(gen.Context), typeof(IList), _argument.TransformRead(gen))); }
public override Expression /*!*/ Convert(DynamicMetaObject /*!*/ metaObject, Type restrictedType, ParameterInfo info, Type /*!*/ toType) { Expression expr = metaObject.Expression; Type fromType = restrictedType ?? expr.Type; // block: if (fromType == typeof(MissingBlockParam)) { Debug.Assert(toType == typeof(BlockParam) || toType == typeof(MissingBlockParam)); return(AstUtils.Constant(null)); } if (fromType == typeof(BlockParam) && toType == typeof(MissingBlockParam)) { return(AstUtils.Constant(null)); } // protocol conversions: if (info != null && info.IsDefined(typeof(DefaultProtocolAttribute), false)) { var action = RubyConversionAction.TryGetDefaultConversionAction(Context, toType); if (action != null) { // TODO: inline implicit conversions: return(AstUtils.LightDynamic(action, toType, expr)); } // Do not throw an exception here to allow generic type parameters to be used with D.P. attribute. // The semantics should be to use DP if available for the current instantiation and ignore it otherwise. } if (restrictedType != null) { if (restrictedType == typeof(DynamicNull)) { if (!toType.IsValueType || toType.IsGenericType && toType.GetGenericTypeDefinition() == typeof(Nullable <>)) { return(AstUtils.Constant(null, toType)); } else if (toType == typeof(bool)) { return(AstUtils.Constant(false)); } } if (toType.IsAssignableFrom(restrictedType)) { // expr can be converted to restrictedType, which can be converted toType => we can convert expr to toType: return(AstUtils.Convert(expr, CompilerHelpers.GetVisibleType(toType))); } // if there is a simple conversion from restricted type, convert the expression to the restricted type and use that conversion: Type visibleRestrictedType = CompilerHelpers.GetVisibleType(restrictedType); if (Converter.CanConvertFrom(metaObject, visibleRestrictedType, toType, false, NarrowingLevel.None, false, false).IsConvertible) { expr = AstUtils.Convert(expr, visibleRestrictedType); } } return(Converter.ConvertExpression(expr, toType, _args.RubyContext, _args.MetaContext.Expression, _implicitProtocolConversions)); }
private MSA.Expression /*!*/ TransformSplatType(AstGenerator /*!*/ gen) { return(AstUtils.LightDynamic(SplatAction.Make(gen.Context), typeof(IList), _splatType.TransformRead(gen))); }