Skip to content

Commit

Permalink
JRUBY-1613: Tweak Java method aliasing in JavaClass to apply ? suffix…
Browse files Browse the repository at this point in the history
… to any method with boolean return type, loosen restriction on non-void setters

git-svn-id: http://svn.codehaus.org/jruby/trunk/jruby@7221 961051c9-f516-0410-bf72-c9f7e237a7b7
  • Loading branch information
enebo committed Jul 18, 2008
1 parent 7f57fe7 commit cba0800
Show file tree
Hide file tree
Showing 3 changed files with 73 additions and 49 deletions.
3 changes: 3 additions & 0 deletions spec/java_integration/fixtures/MethodNames.java
Expand Up @@ -28,6 +28,9 @@ public void CAMELWithUpper2() {}
public void setValue2(Object value) {} public void setValue2(Object value) {}
public void setValues2(Object value, Object otherValue) {} public void setValues2(Object value, Object otherValue) {}


public Object getJConsecutiveCaps() {return null;}
public void setJConsecutiveCaps(Object value) {}

public boolean isFirst2() {return false;} public boolean isFirst2() {return false;}
public boolean isSecond2(Object something) {return false;} public boolean isSecond2(Object something) {return false;}
public boolean hasThird2() {return false;} public boolean hasThird2() {return false;}
Expand Down
51 changes: 37 additions & 14 deletions spec/java_integration/methods/naming_spec.rb
Expand Up @@ -39,23 +39,30 @@
methods.should include("set_values1") methods.should include("set_values1")
methods.should_not include("values1=") methods.should_not include("values1=")
end end

it "should present boolean javabean property accessors as '?' method" do it "should present boolean javabean property accessors as '?' method" do
methods = MethodNames.methods methods = MethodNames.methods


pending("missing") do methods.should include("isFirst1")
methods.should include("isFirst2") methods.should include("first1")
end methods.should include("first1?")
methods.should include("isSecond2")
methods.should include("first2?") methods.should include("isSecond1")
methods.should_not include("second2?") methods.should include("second1")
methods.should include("second1?")


methods.should include("hasThird2") methods.should include("hasThird1")
methods.should include("hasFourth2") methods.should include("has_third1")
methods.should include("has_third1?")

methods.should include("hasFourth1")
methods.should include("has_fourth1");
methods.should include("has_fourth1?");

pending("not implemented") do pending("not implemented") do
methods.should include("third2?") methods.should include("third1?")
end end
methods.should_not include("fourth2?") methods.should_not include("fourth1?")
end end


it "should not overwrite critical core Ruby methods" do it "should not overwrite critical core Ruby methods" do
Expand Down Expand Up @@ -101,16 +108,32 @@
methods.should_not include("values2=") methods.should_not include("values2=")
end end


it "should treat consecutive caps as part of one property name" do
methods = MethodNames.instance_methods

methods.should include("jconsecutive_caps")
methods.should include("jconsecutive_caps=")
end

it "should present boolean javabean property accessors as '?' method" do it "should present boolean javabean property accessors as '?' method" do
methods = MethodNames.instance_methods methods = MethodNames.instance_methods


methods.should include("isFirst2") methods.should include("isFirst2")
methods.should include("isSecond2") methods.should include("first2")
methods.should include("first2?") methods.should include("first2?")
methods.should_not include("second2?")
methods.should include("isSecond2")
methods.should include("second2")
methods.should include("second2?")


methods.should include("hasThird2") methods.should include("hasThird2")
methods.should include("has_third2")
methods.should include("has_third2?")

methods.should include("hasFourth2") methods.should include("hasFourth2")
methods.should include("has_fourth2")
methods.should include("has_fourth2?")

pending("not implemented") do pending("not implemented") do
methods.should include("third2?") methods.should include("third2?")
end end
Expand All @@ -125,4 +148,4 @@
obj.__id__.should_not == "foo" obj.__id__.should_not == "foo"
lambda {obj.__send__}.should raise_error(ArgumentError) lambda {obj.__send__}.should raise_error(ArgumentError)
end end
end end
68 changes: 33 additions & 35 deletions src/org/jruby/javasupport/JavaClass.java
Expand Up @@ -736,49 +736,51 @@ public void setupProxy(final RubyClass proxy) {


private static void assignAliases(MethodCallback callback, Map<String, AssignedName> assignedNames) { private static void assignAliases(MethodCallback callback, Map<String, AssignedName> assignedNames) {
String name = callback.name; String name = callback.name;
addUnassignedAlias(getRubyCasedName(name),assignedNames,callback); String rubyCasedName = getRubyCasedName(name);
// logic adapted from java.beans.Introspector addUnassignedAlias(rubyCasedName,assignedNames,callback);
if (!(name.length() > 3 || name.startsWith("is")))
return;


String javaPropertyName = getJavaPropertyName(name); String javaPropertyName = getJavaPropertyName(name);
if (javaPropertyName == null) String rubyPropertyName = null;
return; // not a Java property name, done with this method


for (Method method: callback.methods) { for (Method method: callback.methods) {
Class<?>[] argTypes = method.getParameterTypes(); Class<?>[] argTypes = method.getParameterTypes();
Class<?> resultType = method.getReturnType(); Class<?> resultType = method.getReturnType();
int argCount = argTypes.length; int argCount = argTypes.length;
if (argCount == 0) {
if (name.startsWith("get")) { // Add property name aliases
addUnassignedAlias(getRubyCasedName(name).substring(4),assignedNames,callback); if (javaPropertyName != null) {
addUnassignedAlias(javaPropertyName,assignedNames,callback); if (rubyCasedName.startsWith("get_")) {
} else if (resultType == boolean.class && name.startsWith("is")) { rubyPropertyName = rubyCasedName.substring(4);
String rubyName = getRubyCasedName(name).substring(3); if (argCount == 0 || // getFoo => foo
if (rubyName != null) { argCount == 1 && argTypes[0] == int.class) { // getFoo(int) => foo(int)
addUnassignedAlias(rubyName,assignedNames,callback);
addUnassignedAlias(rubyName+'?',assignedNames,callback);
}
if (!javaPropertyName.equals(rubyName)) {
addUnassignedAlias(javaPropertyName,assignedNames,callback); addUnassignedAlias(javaPropertyName,assignedNames,callback);
addUnassignedAlias(javaPropertyName+'?',assignedNames,callback); addUnassignedAlias(rubyPropertyName,assignedNames,callback);
} }
} } else if (rubyCasedName.startsWith("set_")) {
} else if (argCount == 1) { rubyPropertyName = rubyCasedName.substring(4);
// indexed get if (argCount == 1 && resultType == void.class) { // setFoo(Foo) => foo=(Foo)
if (argTypes[0] == int.class && name.startsWith("get")) { addUnassignedAlias(javaPropertyName+'=',assignedNames,callback);
addUnassignedAlias(getRubyCasedName(name).substring(4),assignedNames,callback); addUnassignedAlias(rubyPropertyName+'=',assignedNames,callback);
addUnassignedAlias(javaPropertyName,assignedNames,callback);
} else if (resultType == void.class && name.startsWith("set")) {
String rubyName = getRubyCasedName(name).substring(4);
if (rubyName != null) {
addUnassignedAlias(rubyName + '=',assignedNames,callback);
} }
if (!javaPropertyName.equals(rubyName)) { } else if (rubyCasedName.startsWith("is_")) {
addUnassignedAlias(javaPropertyName + '=',assignedNames,callback); rubyPropertyName = rubyCasedName.substring(3);
if (resultType == boolean.class) { // isFoo() => foo, isFoo(*) => foo(*)
addUnassignedAlias(javaPropertyName,assignedNames,callback);
addUnassignedAlias(rubyPropertyName,assignedNames,callback);
} }
} }
} }

// Additionally add ?-postfixed aliases to any boolean methods and properties.
if (resultType == boolean.class) {
// is_something?, contains_thing?
addUnassignedAlias(rubyCasedName+'?',assignedNames,callback);
if (rubyPropertyName != null) {
// something?
addUnassignedAlias(rubyPropertyName+'?',assignedNames,callback);
}
}
} }
} }


Expand Down Expand Up @@ -812,11 +814,7 @@ public static String getJavaPropertyName(String beanMethodName) {
private static final Pattern CAMEL_CASE_SPLITTER = Pattern.compile("([a-z][0-9]*)([A-Z])"); private static final Pattern CAMEL_CASE_SPLITTER = Pattern.compile("([a-z][0-9]*)([A-Z])");
public static String getRubyCasedName(String javaCasedName) { public static String getRubyCasedName(String javaCasedName) {
Matcher m = CAMEL_CASE_SPLITTER.matcher(javaCasedName); Matcher m = CAMEL_CASE_SPLITTER.matcher(javaCasedName);
String rubyCasedName = m.replaceAll("$1_$2").toLowerCase(); return m.replaceAll("$1_$2").toLowerCase();
if (rubyCasedName.equals(javaCasedName)) {
return null;
}
return rubyCasedName;
} }




Expand Down

0 comments on commit cba0800

Please sign in to comment.