1 30 package org.jruby.internal.runtime.methods; 31 32 import org.jruby.RubyModule; 33 import org.jruby.runtime.Arity; 34 import org.jruby.runtime.Block; 35 import org.jruby.runtime.CallType; 36 import org.jruby.runtime.ThreadContext; 37 import org.jruby.runtime.Visibility; 38 import org.jruby.runtime.builtin.IRubyObject; 39 40 44 public abstract class DynamicMethod { 45 protected RubyModule implementationClass; 46 protected Visibility visibility; 47 private boolean implIsClass; 48 private boolean implIsKernel; 49 50 protected DynamicMethod(RubyModule implementationClass, Visibility visibility) { 51 this.visibility = visibility; 52 this.implementationClass = implementationClass; 53 if (implementationClass != null) { 54 this.implIsClass = implementationClass.isClass(); 55 this.implIsKernel = implementationClass == implementationClass.getRuntime().getKernel(); 56 } 57 } 58 59 64 public IRubyObject call(ThreadContext context, IRubyObject self, RubyModule clazz, 65 String name, IRubyObject[] args, boolean noSuper, Block block) { 66 preMethod(context, clazz, self, name, args, noSuper, block); 67 68 try { 69 return internalCall(context, clazz, self, name, args, noSuper, block); 70 } finally { 71 postMethod(context); 72 } 73 } 74 75 protected abstract void postMethod(ThreadContext context); 76 protected abstract IRubyObject internalCall(ThreadContext context, RubyModule clazz, IRubyObject self, String name, IRubyObject[] args, boolean noSuper, Block block); 77 protected abstract void preMethod(ThreadContext context, RubyModule clazz, IRubyObject self, String name, IRubyObject[] args, boolean noSuper, Block block); 78 public abstract DynamicMethod dup(); 79 80 public boolean isCallableFrom(IRubyObject caller, CallType callType) { 81 if (getVisibility().isPrivate() && (callType == CallType.NORMAL)) { 82 return false; 83 } else if (getVisibility().isProtected()) { 84 RubyModule defined = getImplementationClass(); 85 while (defined.isIncluded()) { 86 defined = defined.getMetaClass(); 87 } 88 if (!caller.isKindOf(defined)) { 89 return false; 90 } 91 } 92 93 return true; 94 } 95 96 public boolean needsImplementer() { 97 return !(implIsClass || implIsKernel); 98 } 99 100 public String getOriginalName() { 101 return null; 102 } 103 104 public RubyModule getImplementationClass() { 105 return implementationClass; 106 } 107 108 public void setImplementationClass(RubyModule implClass) { 109 implementationClass = implClass; 110 } 111 112 public Visibility getVisibility() { 113 return visibility; 114 } 115 116 public void setVisibility(Visibility visibility) { 117 this.visibility = visibility; 118 } 119 120 public boolean isUndefined() { 121 return false; 122 } 123 124 public Arity getArity() { 125 return Arity.optional(); 126 } 127 } 128 | Popular Tags |