示例#1
0
文件: IoOps.cs 项目: ltwlf/IronSP
        public static RuleGenerator /*!*/ Open()
        {
            return(new RuleGenerator((metaBuilder, args, name) => {
                var targetClass = (RubyClass)args.Target;
                targetClass.BuildObjectConstructionNoFlow(metaBuilder, args, name);

                // TODO: initialize yields the block?
                if (args.Signature.HasBlock)
                {
                    // ignore flow builder set up so far, we need one that creates a BlockParam for library calls:
                    metaBuilder.ControlFlowBuilder = null;

                    if (metaBuilder.BfcVariable == null)
                    {
                        metaBuilder.BfcVariable = metaBuilder.GetTemporary(typeof(BlockParam), "#bfc");
                    }

                    metaBuilder.Result = Ast.Call(new Func <UnaryOpStorage, BlockParam, object, object>(InvokeOpenBlock).Method,
                                                  Ast.Constant(new UnaryOpStorage(args.RubyContext)),
                                                  metaBuilder.BfcVariable,
                                                  metaBuilder.Result
                                                  );

                    RubyMethodGroupInfo.RuleControlFlowBuilder(metaBuilder, args);
                }
                else
                {
                    metaBuilder.BuildControlFlow(args);
                }
            }));
        }
示例#2
0
        /// <summary>
        /// Implements Class#new feature.
        /// </summary>
        public void BuildObjectConstruction(MetaObjectBuilder /*!*/ metaBuilder, CallArguments /*!*/ args, string /*!*/ methodName)
        {
            Debug.Assert(!IsSingletonClass, "Cannot instantiate singletons");

            Type type = GetUnderlyingSystemType();

            RubyMemberInfo initializer           = ResolveMethod(Symbols.Initialize, true).InvalidateSitesOnOverride();
            RubyMethodInfo overriddenInitializer = initializer as RubyMethodInfo;

            // check the version of this class to ensure the initializer won't be changed without rebuilding the site:
            metaBuilder.AddCondition(
                Ast.Equal(Ast.Property(Ast.Constant(this), RubyModule.VersionProperty), Ast.Constant(this.Version))
                );

            // Initializer is overridden => initializer is invoked on an uninitialized instance.
            // Is user class (defined in Ruby code) => construct it as if it had initializer that calls super immediately
            // (we need to "inherit" factories/constructors from the base class (e.g. class S < String; self; end.new('foo')).
            if (overriddenInitializer != null || (_isRubyClass && _structInfo == null))
            {
                metaBuilder.Result = MakeAllocatorCall(args, () => Ast.Constant(Name));

                if (overriddenInitializer != null || (_isRubyClass && initializer != null && !initializer.IsEmpty))
                {
                    BuildOverriddenInitializerCall(metaBuilder, args, initializer);
                }
            }
            else if (type.IsSubclassOf(typeof(Delegate)))
            {
                metaBuilder.Result = MakeDelegateConstructorCall(type, args);
            }
            else
            {
                MethodBase[] constructionOverloads;

                bool includeSelf;
                if (_structInfo != null)
                {
                    constructionOverloads = new MethodBase[] { Methods.CreateStructInstance };
                    includeSelf           = true;
                }
                else if (_factories != null)
                {
                    constructionOverloads = (MethodBase[])ReflectionUtils.GetMethodInfos(_factories);
                    includeSelf           = true;
                }
                else
                {
                    constructionOverloads = type.GetConstructors();
                    if (constructionOverloads.Length == 0)
                    {
                        throw RubyExceptions.CreateTypeError(String.Format("allocator undefined for {0}", Name));
                    }
                    includeSelf = false;
                }

                RubyMethodGroupInfo.BuildCallNoFlow(metaBuilder, args, methodName, constructionOverloads, includeSelf, false);
                RubyMethodGroupInfo.ApplyBlockFlowHandlingInternal(metaBuilder, args);
            }
        }
示例#3
0
        private static RuleGenerator /*!*/ CreateSetter(int index)
        {
            return(delegate(MetaObjectBuilder /*!*/ metaBuilder, CallArguments /*!*/ args, string /*!*/ name) {
                var actualArgs = RubyMethodGroupInfo.MakeActualArgs(metaBuilder, args, true, false, false, false);

                metaBuilder.Result = Ast.Call(
                    Ast.Convert(actualArgs[0], typeof(RubyStruct)),
                    typeof(RubyStruct).GetMethod("SetValue"),
                    Ast.Constant(index),
                    Ast.Convert(actualArgs[1], typeof(object))
                    );
            });
        }
示例#4
0
        private bool TryGetClrMethod(Type /*!*/ type, BindingFlags bindingFlags, string /*!*/ name, out RubyMemberInfo method)
        {
            Assert.NotNull(type, name);

            MemberInfo[] members = type.GetMember(name, MemberTypes.Method, bindingFlags | BindingFlags.InvokeMethod);
            if (members.Length > 0)
            {
                method = new RubyMethodGroupInfo(SelectNonPrivateMethods(members), this, _isSingletonClass);
                return(true);
            }
            else
            {
                method = null;
                return(false);
            }
        }
        public void OverloadResolution_Block()
        {
            var t = GetType();

            var gse   = new GlobalScopeExtension(Context, new Scope(), new object(), true);
            var scope = new RubyTopLevelScope(gse, null, new SymbolDictionary());
            var proc  = new Proc(ProcKind.Proc, null, scope, new BlockDispatcher0((x, y) => null, BlockSignatureAttributes.None));

            var scopeArg    = new MetaObject(Ast.Constant(proc.LocalScope), Restrictions.Empty, proc.LocalScope);
            var contextArg  = new MetaObject(Ast.Constant(Context), Restrictions.Empty, Context);
            var instanceInt = new MetaObject(Ast.Constant(1), Restrictions.Empty, 1);
            var str         = "foo";
            var instanceStr = new MetaObject(Ast.Constant(str), Restrictions.Empty, str);
            var procArg     = new MetaObject(Ast.Constant(proc), Restrictions.Empty, proc);
            var nullArg     = new MetaObject(Ast.Constant(Ast.Constant(null)), Restrictions.Empty, null);

            var arguments = new[] {
                // 1.times
                new CallArguments(scopeArg, instanceInt, new MetaObject[0], RubyCallSignature.WithScope(0)),
                // 1.times &nil
                new CallArguments(scopeArg, instanceInt, new[] { nullArg }, RubyCallSignature.WithScopeAndBlock(0)),
                // 1.times &p
                new CallArguments(contextArg, instanceInt, new[] { procArg }, RubyCallSignature.WithBlock(0)),
                // obj.times &p
                new CallArguments(contextArg, instanceStr, new[] { procArg }, RubyCallSignature.WithBlock(0)),
            };

            var results = new[] {
                "Times2",
                "Times1",
                "Times3",
                "Times4",
            };

            for (int i = 0; i < arguments.Length; i++)
            {
                var bindingTarget = RubyMethodGroupInfo.ResolveOverload("times", new[] {
                    t.GetMethod("Times1"),
                    t.GetMethod("Times2"),
                    t.GetMethod("Times3"),
                    t.GetMethod("Times4"),
                }, arguments[i], true, false);

                Assert(bindingTarget.Success);
                Assert(bindingTarget.Method.Name == results[i]);
            }
        }
        public void OverloadResolution_Block1()
        {
            var scope = Context.EmptyScope;
            var proc  = new Proc(ProcKind.Proc, null, scope, new BlockDispatcher0(BlockSignatureAttributes.None, null, 0).
                                 SetMethod(new BlockCallTarget0((x, y) => null)));

            var arguments = new[] {
                // 1.times
                new CallArguments(Context, MO(scope), new[] { MO(1) }, RubyCallSignature.WithScope(0)),
                // 1.times &nil
                new CallArguments(Context, MO(scope), new[] { MO(1), MO(null) }, RubyCallSignature.WithScopeAndBlock(0)),
                // 1.times &p
                new CallArguments(Context, MO(1), new[] { MO(proc) }, RubyCallSignature.WithBlock(0)),
                // obj.times &p
                new CallArguments(Context, MO("foo"), new[] { MO(proc) }, RubyCallSignature.WithBlock(0)),
            };

            var results = new[] {
                "Times2",
                "Times1",
                "Times3",
                "Times4",
            };

            var metaBuilder = new MetaObjectBuilder(null);

            for (int i = 0; i < arguments.Length; i++)
            {
                RubyOverloadResolver resolver;

                var methods = GetStaticMethodsStartingWith(typeof(OverloadsWithBlock), "Times");

                var bindingTarget = RubyMethodGroupInfo.ResolveOverload(
                    metaBuilder, arguments[i], "times", methods, SelfCallConvention.SelfIsParameter,
                    false, out resolver
                    );

                Assert(bindingTarget.Success);
                Assert(bindingTarget.Overload.Name == results[i]);
            }
        }