// 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; }
// 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; }
public bool IsVisible(RubyMethodVisibility visibility) { return(((int)visibility & (int)Visible) != 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)); } }
// 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)); }
public static RubyMethodVisibility GetSpecialMethodVisibility(RubyMethodVisibility/*!*/ visibility, string/*!*/ methodName) { return (methodName == Symbols.Initialize || methodName == Symbols.InitializeCopy) ? RubyMethodVisibility.Private : visibility; }
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); } }
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; }
// 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)); } }
public RubyLibraryMethodInfo(Delegate/*!*/[]/*!*/ overloads, RubyMethodVisibility visibility, RubyModule/*!*/ declaringModule) : this(overloads, (RubyMemberFlags)visibility & RubyMemberFlags.VisibilityMask, declaringModule) { ContractUtils.RequiresNotNull(declaringModule, "declaringModule"); ContractUtils.RequiresNotNullItems(overloads, "overloads"); }
// 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)); }
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; }
public static RubyMethodVisibility GetSpecialMethodVisibility(RubyMethodVisibility /*!*/ visibility, string /*!*/ methodName) { return((methodName == Symbols.Initialize || methodName == Symbols.InitializeCopy) ? RubyMethodVisibility.Private : visibility); }
public void SetMethodVisibility(string/*!*/ name, RubyMemberInfo/*!*/ method, RubyMethodVisibility visibility) { if (method.Visibility != visibility) { AddMethod(name, method.Copy((RubyMemberFlags)visibility, this)); } }
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; }
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); }
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); } }
public bool IsVisible(RubyMethodVisibility visibility) { return ((int)visibility & (int)Visible) != 0; }
public static RubyLambdaMethodInfo/*!*/ ToLambdaMethodInfo(Proc/*!*/ block, string/*!*/ definitionName, RubyMethodVisibility visibility, RubyModule/*!*/ owner) { return new RubyLambdaMethodInfo(block, definitionName, (RubyMemberFlags)visibility, owner); }
public static RubyLambdaMethodInfo /*!*/ ToLambdaMethodInfo(Proc /*!*/ block, string /*!*/ definitionName, RubyMethodVisibility visibility, RubyModule /*!*/ owner) { return(new RubyLambdaMethodInfo(block, definitionName, (RubyMemberFlags)visibility, owner)); }
public RubyLibraryMethodInfo(LibraryOverload /*!*/[] /*!*/ overloads, RubyMethodVisibility visibility, RubyModule /*!*/ declaringModule) : this(overloads, (RubyMemberFlags)visibility & RubyMemberFlags.VisibilityMask, declaringModule) { ContractUtils.RequiresNotNull(declaringModule, "declaringModule"); ContractUtils.RequiresNotNullItems(overloads, "overloads"); }
public void SetMethodVisibility(RubyContext/*!*/ callerContext, string/*!*/ name, RubyMemberInfo/*!*/ method, RubyMethodVisibility visibility) { if (method.Visibility != visibility) { AddMethod(callerContext, name, method.Copy((RubyMemberFlags)visibility, this)); } }