示例#1
0
        // Returns true if the call was bound (with success or failure), false if fallback should be performed.
        internal static bool BuildMethodMissingAccess(MetaObjectBuilder /*!*/ metaBuilder, CallArguments /*!*/ args, string /*!*/ methodName,
                                                      RubyMemberInfo methodMissing, RubyMethodVisibility incompatibleVisibility, bool isSuperCall, bool defaultFallback)
        {
            switch (BindToKernelMethodMissing(metaBuilder, args, methodName, methodMissing, incompatibleVisibility, isSuperCall))
            {
            case MethodMissingBinding.Custom:
                // we pretend we found the member and return a method that calls method_missing:
                Debug.Assert(!metaBuilder.Error);
                metaBuilder.Result = Methods.CreateBoundMissingMember.OpCall(
                    AstUtils.Convert(args.TargetExpression, typeof(object)),
                    Ast.Constant(methodMissing, typeof(RubyMemberInfo)),
                    Ast.Constant(methodName)
                    );
                return(true);

            case MethodMissingBinding.Error:
                // method_missing is defined in Kernel, error has been reported:
                return(true);

            case MethodMissingBinding.Fallback:
                // method_missing is defined in Kernel:
                if (defaultFallback)
                {
                    metaBuilder.SetError(Methods.MakeMissingMemberError.OpCall(Ast.Constant(methodName)));
                    return(true);
                }
                return(false);
            }
            throw Assert.Unreachable;
        }
示例#2
0
        // Returns true if the call was bound (with success or failure), false if fallback should be performed.
        internal static bool BuildMethodMissingAccess(MetaObjectBuilder/*!*/ metaBuilder, CallArguments/*!*/ args, string/*!*/ methodName,
            RubyMemberInfo methodMissing, RubyMethodVisibility incompatibleVisibility, bool isSuperCall, bool defaultFallback) {

            switch (BindToKernelMethodMissing(metaBuilder, args, methodName, methodMissing, incompatibleVisibility, isSuperCall)) {
                case MethodMissingBinding.Custom:
                    // we pretend we found the member and return a method that calls method_missing:
                    Debug.Assert(!metaBuilder.Error);
                    metaBuilder.Result = Methods.CreateBoundMissingMember.OpCall(
                        AstUtils.Convert(args.TargetExpression, typeof(object)),
                        Ast.Constant(methodMissing, typeof(RubyMemberInfo)),
                        Ast.Constant(methodName)
                    );
                    return true;

                case MethodMissingBinding.Error:
                    // method_missing is defined in Kernel, error has been reported:
                    return true;

                case MethodMissingBinding.Fallback:
                    // method_missing is defined in Kernel:
                    if (defaultFallback) {
                        metaBuilder.SetError(Methods.MakeMissingMemberError.OpCall(Ast.Constant(methodName)));
                        return true;
                    }
                    return false;
            }
            throw Assert.Unreachable;
        }
示例#3
0
 public bool IsVisible(RubyMethodVisibility visibility)
 {
     return(((int)visibility & (int)Visible) != 0);
 }
示例#4
0
        // Module#module_function/private/protected/public:
        public void SetVisibilityNoEventNoLock(RubyContext/*!*/ callerContext, string/*!*/ name, RubyMemberInfo/*!*/ method, RubyMethodVisibility visibility) {
            Context.RequiresClassHierarchyLock();

            RubyMemberInfo existing;
            bool skipHidden = false;
            if (TryGetMethod(name, ref skipHidden, out existing)) {
                // CLR members: Detaches the member from its underlying type (by creating a copy).
                SetMethodNoEventNoLock(callerContext, name, method.Copy((RubyMemberFlags)visibility, this));
            } else {
                SetMethodNoEventNoLock(callerContext, name, new SuperForwarderInfo((RubyMemberFlags)visibility, method.DeclaringModule, name));
            }
        }
示例#5
0
 // Module#define_method:
 public void SetDefinedMethodNoEventNoLock(RubyContext/*!*/ callerContext, string/*!*/ name, RubyMemberInfo/*!*/ method, RubyMethodVisibility visibility) {
     // CLR members: Detaches the member from its underlying type (by creating a copy).
     // Note: Method#== returns false on defined methods and redefining the original method doesn't affect the new one:
     SetMethodNoEventNoLock(callerContext, name, method.Copy((RubyMemberFlags)visibility, this));
 }
示例#6
0
 public static RubyMethodVisibility GetSpecialMethodVisibility(RubyMethodVisibility/*!*/ visibility, string/*!*/ methodName) {
     return (methodName == Symbols.Initialize || methodName == Symbols.InitializeCopy) ? RubyMethodVisibility.Private : visibility;
 }
示例#7
0
        private static void SetClassMethodsVisibility(RubyContext/*!*/ context, RubyModule/*!*/ module, string[]/*!*/ methodNames, RubyMethodVisibility visibility) {
            var methods = new RubyMemberInfo[methodNames.Length];
            for (int i = 0; i < methods.Length; i++) {
                RubyMemberInfo method = module.SingletonClass.ResolveMethod(methodNames[i], true);
                if (method == null) {
                    throw RubyExceptions.CreateUndefinedMethodError(module, methodNames[i]);
                }
                methods[i] = method;
            }

            for (int i = 0; i < methods.Length; i++) {
                module.SingletonClass.SetMethodVisibility(context, methodNames[i], methods[i], visibility);
            }
        }
示例#8
0
文件: RubyClass.cs 项目: kashano/main
 internal RubyMemberInfo ResolveMethodMissingForSite(string/*!*/ name, RubyMethodVisibility incompatibleVisibility) {
     Context.RequiresClassHierarchyLock();
     var methodMissing = ResolveMethodForSiteNoLock(Symbols.MethodMissing, VisibilityContext.AllVisible);
     if (incompatibleVisibility == RubyMethodVisibility.None) {
         methodMissing.InvalidateSitesOnMissingMethodAddition(name, Context);
     }
     return methodMissing.Info;
 }
示例#9
0
        // Module#module_function/private/protected/public:
        public void SetVisibilityNoEventNoLock(RubyContext/*!*/ callerContext, string/*!*/ name, RubyMemberInfo/*!*/ method, RubyMethodVisibility visibility) {
            Context.RequiresClassHierarchyLock();

            RubyMemberInfo existing;
            bool skipHidden = false;
            if (TryGetMethod(name, ref skipHidden, out existing)) {
                SetMethodNoEventNoLock(callerContext, name, method.Copy((RubyMemberFlags)visibility, this));
            } else {
                SetMethodNoEventNoLock(callerContext, name, new RubyMemberInfo((RubyMemberFlags)visibility | RubyMemberFlags.SuperForwarder, method.DeclaringModule));
            }
        }
示例#10
0
 public RubyLibraryMethodInfo(Delegate/*!*/[]/*!*/ overloads, RubyMethodVisibility visibility, RubyModule/*!*/ declaringModule) 
     : this(overloads, (RubyMemberFlags)visibility & RubyMemberFlags.VisibilityMask, declaringModule) {
     ContractUtils.RequiresNotNull(declaringModule, "declaringModule");
     ContractUtils.RequiresNotNullItems(overloads, "overloads");
 }
示例#11
0
 // Module#define_method:
 public void SetDefinedMethodNoEventNoLock(RubyContext/*!*/ callerContext, string/*!*/ name, RubyMemberInfo/*!*/ method, RubyMethodVisibility visibility) {
     // copy method, Method#== returns false on defined methods and redefining the original method doesn't affect the new one:
     SetMethodNoEventNoLock(callerContext, name, method.Copy((RubyMemberFlags)visibility, this));
 }
示例#12
0
        internal static bool BindToMethodMissing(MetaObjectBuilder/*!*/ metaBuilder, CallArguments/*!*/ args, string/*!*/ methodName,
            RubyMemberInfo methodMissing, RubyMethodVisibility incompatibleVisibility, bool isSuperCall, bool defaultFallback) {
            // Assumption: args already contain method name.
            
            // TODO: better check for builtin method
            if (methodMissing == null ||
                methodMissing.DeclaringModule == methodMissing.Context.KernelModule && methodMissing is RubyLibraryMethodInfo) {

                if (isSuperCall) {
                    metaBuilder.SetError(Methods.MakeMissingSuperException.OpCall(AstUtils.Constant(methodName)));
                } else if (incompatibleVisibility == RubyMethodVisibility.Private) {
                    metaBuilder.SetError(Methods.MakePrivateMethodCalledError.OpCall(
                        AstUtils.Convert(args.MetaContext.Expression, typeof(RubyContext)), args.TargetExpression, AstUtils.Constant(methodName))
                    );
                } else if (incompatibleVisibility == RubyMethodVisibility.Protected) {
                    metaBuilder.SetError(Methods.MakeProtectedMethodCalledError.OpCall(
                        AstUtils.Convert(args.MetaContext.Expression, typeof(RubyContext)), args.TargetExpression, AstUtils.Constant(methodName))
                    );
                } else if (defaultFallback) {
                    args.InsertMethodName(methodName);
                    methodMissing.BuildCall(metaBuilder, args, methodName);
                } else {
                    return false;
                }
            } else {
                args.InsertMethodName(methodName);
                methodMissing.BuildCall(metaBuilder, args, methodName);
            }

            return true;
        }
示例#13
0
 public static RubyMethodVisibility GetSpecialMethodVisibility(RubyMethodVisibility /*!*/ visibility, string /*!*/ methodName)
 {
     return((methodName == Symbols.Initialize || methodName == Symbols.InitializeCopy) ? RubyMethodVisibility.Private : visibility);
 }
示例#14
0
 public void SetMethodVisibility(string/*!*/ name, RubyMemberInfo/*!*/ method, RubyMethodVisibility visibility) {
     if (method.Visibility != visibility) {
         AddMethod(name, method.Copy((RubyMemberFlags)visibility, this));
     }
 }
示例#15
0
        private static MethodMissingBinding BindToKernelMethodMissing(MetaObjectBuilder/*!*/ metaBuilder, CallArguments/*!*/ args, string/*!*/ methodName,
            RubyMemberInfo methodMissing, RubyMethodVisibility incompatibleVisibility, bool isSuperCall) {

            // TODO: better specialization of method_missing methods
            if (methodMissing == null ||
                methodMissing.DeclaringModule == methodMissing.Context.KernelModule && methodMissing is RubyLibraryMethodInfo) {

                if (isSuperCall) {
                    metaBuilder.SetError(Methods.MakeMissingSuperException.OpCall(AstUtils.Constant(methodName)));
                } else if (incompatibleVisibility == RubyMethodVisibility.Private) {
                    metaBuilder.SetError(Methods.MakePrivateMethodCalledError.OpCall(
                        AstUtils.Convert(args.MetaContext.Expression, typeof(RubyContext)), args.TargetExpression, AstUtils.Constant(methodName))
                    );
                } else if (incompatibleVisibility == RubyMethodVisibility.Protected) {
                    metaBuilder.SetError(Methods.MakeProtectedMethodCalledError.OpCall(
                        AstUtils.Convert(args.MetaContext.Expression, typeof(RubyContext)), args.TargetExpression, AstUtils.Constant(methodName))
                    );
                } else {
                    return MethodMissingBinding.Fallback;
                }

                return MethodMissingBinding.Error;
            }

            return MethodMissingBinding.Custom;
        }
示例#16
0
        private static MethodMissingBinding BindToKernelMethodMissing(MetaObjectBuilder /*!*/ metaBuilder, CallArguments /*!*/ args, string /*!*/ methodName,
                                                                      RubyMemberInfo methodMissing, RubyMethodVisibility incompatibleVisibility, bool isSuperCall)
        {
            // TODO: better specialization of method_missing methods
            if (methodMissing == null ||
                methodMissing.DeclaringModule == methodMissing.Context.KernelModule && methodMissing is RubyLibraryMethodInfo)
            {
                if (isSuperCall)
                {
                    metaBuilder.SetError(Methods.MakeMissingSuperException.OpCall(AstUtils.Constant(methodName)));
                }
                else if (incompatibleVisibility == RubyMethodVisibility.Private)
                {
                    metaBuilder.SetError(Methods.MakePrivateMethodCalledError.OpCall(
                                             AstUtils.Convert(args.MetaContext.Expression, typeof(RubyContext)), args.TargetExpression, AstUtils.Constant(methodName))
                                         );
                }
                else if (incompatibleVisibility == RubyMethodVisibility.Protected)
                {
                    metaBuilder.SetError(Methods.MakeProtectedMethodCalledError.OpCall(
                                             AstUtils.Convert(args.MetaContext.Expression, typeof(RubyContext)), args.TargetExpression, AstUtils.Constant(methodName))
                                         );
                }
                else
                {
                    return(MethodMissingBinding.Fallback);
                }

                return(MethodMissingBinding.Error);
            }

            return(MethodMissingBinding.Custom);
        }
示例#17
0
        private static void SetClassMethodsVisibility(RubyModule /*!*/ module, string[] /*!*/ methodNames, RubyMethodVisibility visibility)
        {
            var methods = new RubyMemberInfo[methodNames.Length];

            for (int i = 0; i < methods.Length; i++)
            {
                RubyMemberInfo method = module.SingletonClass.ResolveMethod(methodNames[i], true);
                if (method == null)
                {
                    throw RubyExceptions.CreateUndefinedMethodError(module, methodNames[i]);
                }
                methods[i] = method;
            }

            for (int i = 0; i < methods.Length; i++)
            {
                module.SingletonClass.SetMethodVisibility(methodNames[i], methods[i], visibility);
            }
        }
示例#18
0
 public bool IsVisible(RubyMethodVisibility visibility)
 {
     return ((int)visibility & (int)Visible) != 0;
 }
示例#19
0
 public static RubyLambdaMethodInfo/*!*/ ToLambdaMethodInfo(Proc/*!*/ block, string/*!*/ definitionName, RubyMethodVisibility visibility,
     RubyModule/*!*/ owner) {
     return new RubyLambdaMethodInfo(block, definitionName, (RubyMemberFlags)visibility, owner);
 }
示例#20
0
文件: Proc.cs 项目: yyyyj/ironruby
 public static RubyLambdaMethodInfo /*!*/ ToLambdaMethodInfo(Proc /*!*/ block, string /*!*/ definitionName, RubyMethodVisibility visibility,
                                                             RubyModule /*!*/ owner)
 {
     return(new RubyLambdaMethodInfo(block, definitionName, (RubyMemberFlags)visibility, owner));
 }
示例#21
0
 public RubyLibraryMethodInfo(LibraryOverload /*!*/[] /*!*/ overloads, RubyMethodVisibility visibility, RubyModule /*!*/ declaringModule)
     : this(overloads, (RubyMemberFlags)visibility & RubyMemberFlags.VisibilityMask, declaringModule)
 {
     ContractUtils.RequiresNotNull(declaringModule, "declaringModule");
     ContractUtils.RequiresNotNullItems(overloads, "overloads");
 }
示例#22
0
 public void SetMethodVisibility(RubyContext/*!*/ callerContext, string/*!*/ name, RubyMemberInfo/*!*/ method, RubyMethodVisibility visibility) {
     if (method.Visibility != visibility) {
         AddMethod(callerContext, name, method.Copy((RubyMemberFlags)visibility, this));
     }
 }