Skip to content

Commit 4644d33

Browse files
committed
Merge remote-tracking branch 'origin/jruby-1_7'
2 parents 057cde9 + 72234f9 commit 4644d33

6 files changed

Lines changed: 201 additions & 41 deletions

File tree

Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
/***** BEGIN LICENSE BLOCK *****
2+
* Version: EPL 1.0/GPL 2.0/LGPL 2.1
3+
*
4+
* The contents of this file are subject to the Eclipse Public
5+
* License Version 1.0 (the "License"); you may not use this file
6+
* except in compliance with the License. You may obtain a copy of
7+
* the License at http://www.eclipse.org/legal/epl-v10.html
8+
*
9+
* Software distributed under the License is distributed on an "AS
10+
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
11+
* implied. See the License for the specific language governing
12+
* rights and limitations under the License.
13+
*
14+
* Copyright (C) 2001 Alan Moore <alan_moore@gmx.net>
15+
* Copyright (C) 2001-2002 Jan Arne Petersen <jpetersen@uni-bonn.de>
16+
* Copyright (C) 2002 Anders Bengtsson <ndrsbngtssn@yahoo.se>
17+
* Copyright (C) 2004 Charles O Nutter <headius@headius.com>
18+
* Copyright (C) 2004 Stefan Matthias Aust <sma@3plus4.de>
19+
*
20+
* Alternatively, the contents of this file may be used under the terms of
21+
* either of the GNU General Public License Version 2 or later (the "GPL"),
22+
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
23+
* in which case the provisions of the GPL or the LGPL are applicable instead
24+
* of those above. If you wish to allow use of your version of this file only
25+
* under the terms of either the GPL or the LGPL, and not to allow others to
26+
* use your version of this file under the terms of the EPL, indicate your
27+
* decision by deleting the provisions above and replace them with the notice
28+
* and other provisions required by the GPL or the LGPL. If you do not delete
29+
* the provisions above, a recipient may use your version of this file under
30+
* the terms of any one of the EPL, the GPL or the LGPL.
31+
***** END LICENSE BLOCK *****/
32+
package org.jruby;
33+
34+
import org.jruby.anno.JRubyClass;
35+
import org.jruby.anno.JRubyMethod;
36+
import org.jruby.ext.jruby.JRubyLibrary;
37+
import org.jruby.internal.runtime.methods.DynamicMethod;
38+
import org.jruby.internal.runtime.methods.ProcMethod;
39+
import org.jruby.runtime.Block;
40+
import org.jruby.runtime.BlockBody;
41+
import org.jruby.runtime.ClassIndex;
42+
import org.jruby.runtime.CompiledBlockCallback19;
43+
import org.jruby.runtime.CompiledBlockLight19;
44+
import org.jruby.runtime.ObjectAllocator;
45+
import org.jruby.runtime.PositionAware;
46+
import org.jruby.runtime.ThreadContext;
47+
import org.jruby.runtime.Visibility;
48+
import org.jruby.runtime.builtin.IRubyObject;
49+
import org.jruby.runtime.marshal.DataType;
50+
51+
/**
52+
* The RubyMethod class represents a RubyMethod object.
53+
*
54+
* You can get such a method by calling the "method" method of an object.
55+
*
56+
* Note: This was renamed from Method.java
57+
*
58+
* @author jpetersen
59+
* @since 0.2.3
60+
*/
61+
public abstract class AbstractRubyMethod extends RubyObject implements DataType {
62+
protected RubyModule implementationModule;
63+
protected String methodName;
64+
protected RubyModule originModule;
65+
protected String originName;
66+
protected DynamicMethod method;
67+
68+
protected AbstractRubyMethod(Ruby runtime, RubyClass rubyClass) {
69+
super(runtime, rubyClass);
70+
}
71+
72+
public DynamicMethod getMethod() {
73+
return method;
74+
}
75+
76+
/** Returns the number of arguments a method accepted.
77+
*
78+
* @return the number of arguments of a method.
79+
*/
80+
@JRubyMethod(name = "arity")
81+
public RubyFixnum arity() {
82+
return getRuntime().newFixnum(method.getArity().getValue());
83+
}
84+
85+
@JRubyMethod(name = "eql?", required = 1, compat = CompatVersion.RUBY1_9)
86+
public IRubyObject op_eql19(ThreadContext context, IRubyObject other) {
87+
return op_equal(context, other);
88+
}
89+
90+
public abstract AbstractRubyMethod rbClone();
91+
92+
@JRubyMethod(name = "name", compat = CompatVersion.RUBY1_8)
93+
public IRubyObject name(ThreadContext context) {
94+
return context.runtime.newString(methodName);
95+
}
96+
97+
@JRubyMethod(name = "name", compat = CompatVersion.RUBY1_9)
98+
public IRubyObject name19(ThreadContext context) {
99+
return context.runtime.newSymbol(methodName);
100+
}
101+
102+
public String getMethodName() {
103+
return methodName;
104+
}
105+
106+
@JRubyMethod(name = "owner")
107+
public IRubyObject owner(ThreadContext context) {
108+
return implementationModule;
109+
}
110+
111+
@JRubyMethod(name = "source_location", compat = CompatVersion.RUBY1_9)
112+
public IRubyObject source_location(ThreadContext context) {
113+
Ruby runtime = context.runtime;
114+
115+
String filename = getFilename();
116+
if (filename != null) {
117+
return runtime.newArray(runtime.newString(filename), runtime.newFixnum(getLine()));
118+
}
119+
120+
return context.runtime.getNil();
121+
}
122+
123+
public String getFilename() {
124+
DynamicMethod realMethod = method.getRealMethod(); // Follow Aliases
125+
if (realMethod instanceof PositionAware) {
126+
PositionAware poser = (PositionAware) realMethod;
127+
return poser.getFile();
128+
}
129+
return null;
130+
}
131+
132+
public int getLine() {
133+
DynamicMethod realMethod = method.getRealMethod(); // Follow Aliases
134+
if (realMethod instanceof PositionAware) {
135+
PositionAware poser = (PositionAware) realMethod;
136+
return poser.getLine() + 1;
137+
}
138+
return -1;
139+
}
140+
141+
@JRubyMethod(name = "parameters", compat = CompatVersion.RUBY1_9)
142+
public IRubyObject parameters(ThreadContext context) {
143+
return JRubyLibrary.MethodExtensions.methodArgs(this);
144+
}
145+
}
146+

core/src/main/java/org/jruby/RubyMethod.java

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -61,12 +61,7 @@
6161
* @since 0.2.3
6262
*/
6363
@JRubyClass(name="Method")
64-
public class RubyMethod extends RubyObject implements DataType {
65-
protected RubyModule implementationModule;
66-
protected String methodName;
67-
protected RubyModule originModule;
68-
protected String originName;
69-
protected DynamicMethod method;
64+
public class RubyMethod extends AbstractRubyMethod {
7065
protected IRubyObject receiver;
7166

7267
protected RubyMethod(Ruby runtime, RubyClass rubyClass) {
@@ -83,7 +78,8 @@ public static RubyClass createMethodClass(Ruby runtime) {
8378

8479
methodClass.setClassIndex(ClassIndex.METHOD);
8580
methodClass.setReifiedClass(RubyMethod.class);
86-
81+
82+
methodClass.defineAnnotatedMethods(AbstractRubyMethod.class);
8783
methodClass.defineAnnotatedMethods(RubyMethod.class);
8884

8985
return methodClass;
@@ -109,10 +105,6 @@ public static RubyMethod newMethod(
109105
return newMethod;
110106
}
111107

112-
public DynamicMethod getMethod() {
113-
return method;
114-
}
115-
116108
/** Call the method.
117109
*
118110
*/

core/src/main/java/org/jruby/RubyModule.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1556,7 +1556,7 @@ public IRubyObject newMethod(IRubyObject receiver, final String methodName, bool
15561556
originModule = ((MetaClass)originModule).getRealClass();
15571557
}
15581558

1559-
RubyMethod newMethod;
1559+
AbstractRubyMethod newMethod;
15601560
if (bound) {
15611561
newMethod = RubyMethod.newMethod(implementationModule, methodName, originModule, methodName, method, receiver);
15621562
} else {
@@ -1617,13 +1617,13 @@ public IRubyObject define_method(ThreadContext context, IRubyObject arg0, IRubyO
16171617
body = proc;
16181618

16191619
newMethod = createProcMethod(name, visibility, proc);
1620-
} else if (runtime.getMethod().isInstance(arg1)) {
1621-
RubyMethod method = (RubyMethod)arg1;
1620+
} else if (arg1 instanceof AbstractRubyMethod) {
1621+
AbstractRubyMethod method = (AbstractRubyMethod)arg1;
16221622
body = method;
16231623

16241624
checkValidBindTargetFrom(context, (RubyModule)method.owner(context));
16251625

1626-
newMethod = method.unbind().getMethod().dup();
1626+
newMethod = method.getMethod().dup();
16271627
newMethod.setImplementationClass(this);
16281628
} else {
16291629
throw runtime.newTypeError("wrong argument type " + arg1.getType().getName() + " (expected Proc/Method)");

core/src/main/java/org/jruby/RubyUnboundMethod.java

Lines changed: 41 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
import org.jruby.anno.JRubyMethod;
3232
import org.jruby.anno.JRubyClass;
3333
import org.jruby.internal.runtime.methods.DynamicMethod;
34+
import org.jruby.internal.runtime.methods.ProcMethod;
3435
import org.jruby.runtime.Block;
3536
import org.jruby.runtime.ClassIndex;
3637
import org.jruby.runtime.ObjectAllocator;
@@ -44,7 +45,7 @@
4445
* @author jpetersen
4546
*/
4647
@JRubyClass(name="UnboundMethod", parent="Method")
47-
public class RubyUnboundMethod extends RubyMethod {
48+
public class RubyUnboundMethod extends AbstractRubyMethod {
4849
protected RubyUnboundMethod(Ruby runtime) {
4950
super(runtime, runtime.getUnboundMethod());
5051
}
@@ -67,35 +68,34 @@ public static RubyUnboundMethod newUnboundMethod(
6768
}
6869

6970
public static RubyClass defineUnboundMethodClass(Ruby runtime) {
70-
// TODO: NOT_ALLOCATABLE_ALLOCATOR is probably ok here. Confirm. JRUBY-415
7171
RubyClass newClass =
72-
runtime.defineClass("UnboundMethod", runtime.getMethod(), ObjectAllocator.NOT_ALLOCATABLE_ALLOCATOR);
72+
runtime.defineClass("UnboundMethod", runtime.getObject(), ObjectAllocator.NOT_ALLOCATABLE_ALLOCATOR);
7373
runtime.setUnboundMethod(newClass);
7474

7575
newClass.setClassIndex(ClassIndex.UNBOUNDMETHOD);
7676
newClass.setReifiedClass(RubyUnboundMethod.class);
7777

78+
newClass.defineAnnotatedMethods(AbstractRubyMethod.class);
7879
newClass.defineAnnotatedMethods(RubyUnboundMethod.class);
7980

80-
return newClass;
81-
}
81+
newClass.getSingletonClass().undefineMethod("new");
8282

83-
/**
84-
* @see org.jruby.RubyMethod#call(IRubyObject[])
85-
*/
86-
@JRubyMethod(name = {"call", "[]"}, rest = true)
87-
@Override
88-
public IRubyObject call(ThreadContext context, IRubyObject[] args, Block block) {
89-
throw context.runtime.newTypeError("you cannot call unbound method; bind first");
83+
return newClass;
9084
}
9185

92-
/**
93-
* @see org.jruby.RubyMethod#unbind()
94-
*/
95-
@JRubyMethod
86+
@JRubyMethod(name = "==", required = 1)
9687
@Override
97-
public RubyUnboundMethod unbind() {
98-
return this;
88+
public RubyBoolean op_equal(ThreadContext context, IRubyObject other) {
89+
if (!(other instanceof AbstractRubyMethod)) {
90+
return context.runtime.getFalse();
91+
}
92+
if (method instanceof ProcMethod) {
93+
return context.runtime.newBoolean(((ProcMethod) method).isSame(((AbstractRubyMethod) other).getMethod()));
94+
}
95+
AbstractRubyMethod otherMethod = (AbstractRubyMethod)other;
96+
return context.runtime.newBoolean(
97+
originModule == otherMethod.originModule &&
98+
method.getRealMethod().getSerialNumber() == otherMethod.method.getRealMethod().getSerialNumber());
9999
}
100100

101101
@JRubyMethod
@@ -109,14 +109,33 @@ public RubyMethod bind(ThreadContext context, IRubyObject aReceiver) {
109109

110110
@JRubyMethod(name = "clone")
111111
@Override
112-
public RubyMethod rbClone() {
112+
public RubyUnboundMethod rbClone() {
113113
return newUnboundMethod(implementationModule, methodName, originModule, originName, method);
114114
}
115115

116-
@JRubyMethod
116+
@JRubyMethod(name = {"inspect", "to_s"})
117117
@Override
118-
public IRubyObject to_proc(ThreadContext context, Block unusedBlock) {
119-
return super.to_proc(context, unusedBlock);
118+
public IRubyObject inspect() {
119+
StringBuilder buf = new StringBuilder("#<");
120+
char delimeter = '#';
121+
122+
buf.append(getMetaClass().getRealClass().getName()).append(": ");
123+
124+
if (implementationModule.isSingleton()) {
125+
buf.append(implementationModule.inspect().toString());
126+
} else {
127+
buf.append(originModule.getName());
128+
129+
if (implementationModule != originModule) {
130+
buf.append('(').append(implementationModule.getName()).append(')');
131+
}
132+
}
133+
134+
buf.append(delimeter).append(methodName).append('>');
135+
136+
RubyString str = getRuntime().newString(buf.toString());
137+
str.setTaint(isTaint());
138+
return str;
120139
}
121140

122141
@Override

core/src/main/java/org/jruby/ext/jruby/JRubyLibrary.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@
3131
package org.jruby.ext.jruby;
3232

3333
import java.util.ArrayList;
34+
35+
import org.jruby.AbstractRubyMethod;
3436
import org.jruby.CompatVersion;
3537
import org.jruby.ast.RestArgNode;
3638
import org.jruby.anno.JRubyMethod;
@@ -165,7 +167,7 @@ public static class MethodExtensions {
165167
@JRubyMethod(name = "args")
166168
public static IRubyObject methodArgs(IRubyObject recv) {
167169
Ruby runtime = recv.getRuntime();
168-
RubyMethod rubyMethod = (RubyMethod)recv;
170+
AbstractRubyMethod rubyMethod = (AbstractRubyMethod)recv;
169171
RubyArray argsArray = RubyArray.newArray(runtime);
170172
DynamicMethod method = rubyMethod.getMethod().getRealMethod();
171173
RubySymbol req = runtime.newSymbol("req");

core/src/main/java/org/jruby/runtime/Helpers.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -883,12 +883,13 @@ public static Block getBlockFromBlockPassBody(Ruby runtime, IRubyObject proc, Bl
883883
return getBlockFromProc(currentBlock, proc);
884884
}
885885

886-
private static IRubyObject coerceProc(IRubyObject proc, Ruby runtime) throws RaiseException {
887-
proc = TypeConverter.convertToType(proc, runtime.getProc(), "to_proc", false);
886+
private static IRubyObject coerceProc(IRubyObject maybeProc, Ruby runtime) throws RaiseException {
887+
IRubyObject proc = TypeConverter.convertToType(maybeProc, runtime.getProc(), "to_proc", false);
888888

889889
if (!(proc instanceof RubyProc)) {
890-
throw runtime.newTypeError("wrong argument type " + proc.getMetaClass().getName() + " (expected Proc)");
890+
throw runtime.newTypeError("wrong argument type " + maybeProc.getMetaClass().getName() + " (expected Proc)");
891891
}
892+
892893
return proc;
893894
}
894895

0 commit comments

Comments
 (0)