Пример #1
0
        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));
        }
Пример #2
0
 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
                ));
 }
Пример #3
0
 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));
 }
Пример #4
0
 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
                ));
 }
Пример #5
0
 // 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)
                ));
 }
Пример #6
0
        internal MSA.Expression /*!*/ MakeCallSite(CallSiteBinder /*!*/ binder)
        {
            if (SplattedArgument != null)
            {
                Add(SplattedArgument);
            }

            if (RhsArgument != null)
            {
                Add(RhsArgument);
            }

            return(AstUtils.LightDynamic(binder, this));
        }
Пример #7
0
        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));
        }
Пример #8
0
        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));
            }
        }
Пример #9
0
 // 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));
         }
     }
 }
Пример #10
0
        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);
        }
Пример #11
0
 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));
        }
Пример #13
0
 private MSA.Expression /*!*/ TransformSplatType(AstGenerator /*!*/ gen)
 {
     return(AstUtils.LightDynamic(SplatAction.Make(gen.Context), typeof(IList), _splatType.TransformRead(gen)));
 }