Skip to content

Commit

Permalink
in case there's an exact parameter match - do not proceed with argume…
Browse files Browse the repository at this point in the history
…nt matching

... towards fixing jruby#2595
  • Loading branch information
kares committed Mar 18, 2015
1 parent 3635300 commit 6521ee4
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 4 deletions.
16 changes: 12 additions & 4 deletions core/src/main/java/org/jruby/java/dispatch/CallableSelector.java
Expand Up @@ -2,6 +2,7 @@

import java.lang.reflect.Member;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import org.jruby.Ruby;
Expand Down Expand Up @@ -169,12 +170,18 @@ private static ParameterTypes findCallable(ParameterTypes[] callables, CallableA

private static List<ParameterTypes> findCallableCandidates(final ParameterTypes[] callables,
final IRubyObject[] args) {
// in case of an exact match prefer to return it early :
for ( int c = 0; c < callables.length; c++ ) {
final ParameterTypes callable = callables[c];
if ( exactMatch(callable, args ) ) return Collections.singletonList(callable);
}

final ArrayList<ParameterTypes> retained = new ArrayList<ParameterTypes>(callables.length);
ParameterTypes[] incoming = callables.clone();

for ( int i = 0; i < args.length; i++ ) {
retained.clear();
for ( final Matcher matcher : MATCH_SEQUENCE ) {
for ( final Matcher matcher : NON_EXACT_MATCH_SEQUENCE ) {
for ( int c = 0; c < incoming.length; c++ ) {
ParameterTypes callable = incoming[c];
if ( callable == null ) continue; // removed (matched)
Expand Down Expand Up @@ -277,7 +284,8 @@ public boolean match(Class type, IRubyObject arg) {
}
};

private static final Matcher[] MATCH_SEQUENCE = new Matcher[] { EXACT, PRIMITIVABLE, ASSIGNABLE, DUCKABLE };
//private static final Matcher[] MATCH_SEQUENCE = new Matcher[] { EXACT, PRIMITIVABLE, ASSIGNABLE, DUCKABLE };
private static final Matcher[] NON_EXACT_MATCH_SEQUENCE = new Matcher[] { PRIMITIVABLE, ASSIGNABLE, DUCKABLE };

private static boolean exactMatch(ParameterTypes paramTypes, IRubyObject... args) {
Class[] types = paramTypes.getParameterTypes();
Expand Down Expand Up @@ -347,7 +355,7 @@ private static boolean assignableAndPrimitivableWithVarargs(ParameterTypes param
return true;
}

private static boolean assignable(Class<?> type, IRubyObject arg) {
private static boolean assignable(Class<?> type, final IRubyObject arg) {
return JavaClass.assignable(type, getJavaClass(arg));
}

Expand All @@ -359,7 +367,7 @@ private static boolean assignable(Class<?> type, IRubyObject arg) {
* @param arg The argument to convert
* @return Whether the argument can be directly converted to the target primitive type
*/
private static boolean primitivable(Class type, IRubyObject arg) {
private static boolean primitivable(final Class<?> type, final IRubyObject arg) {
final Class<?> argClass = getJavaClass(arg);
if (type.isPrimitive()) {
// TODO: This is where we would want to do precision checks to see
Expand Down
21 changes: 21 additions & 0 deletions test/test_higher_javasupport.rb
Expand Up @@ -1040,4 +1040,25 @@ def test_concurrent_proxy_class_initialization_dead_lock
end
end

def test_no_ambiguous_java_constructor_warning_for_exact_match
output = with_stderr_captured do # exact match should not warn :
java.awt.Color.new(1.to_java(:int), 1.to_java(:int), 1.to_java(:int))
end
# warning: ambiguous Java methods found, using java.awt.Color(int,int,int)
assert ! output.index('ambiguous'), output
end

private

def with_stderr_captured
stderr = $stderr; require 'stringio'
begin
$stderr = StringIO.new
yield
$stderr.string
ensure
$stderr = stderr
end
end

end

0 comments on commit 6521ee4

Please sign in to comment.