diff options
author | Jesse Wilson <jessewilson@google.com> | 2011-11-21 10:35:06 -0500 |
---|---|---|
committer | Jesse Wilson <jessewilson@google.com> | 2011-11-21 10:35:06 -0500 |
commit | 8ea36f84a1fff2943127ef21ce371c99a7d191af (patch) | |
tree | 1928f6ac2684401f19bc32c49458ecd1e0aa9210 /src/java_lang_Class.cc | |
parent | dbb4079eb1e7d7738c81a97c8dd2550885c1093a (diff) | |
download | art-8ea36f84a1fff2943127ef21ce371c99a7d191af.zip art-8ea36f84a1fff2943127ef21ce371c99a7d191af.tar.gz art-8ea36f84a1fff2943127ef21ce371c99a7d191af.tar.bz2 |
Prefer non-synthetic methods in Class.getMethod()
This fixes four failing tests in MethodOverridesTest.
Change-Id: I758a7b914554ff2b03d8ecce1b5df8d502f0b827
Diffstat (limited to 'src/java_lang_Class.cc')
-rw-r--r-- | src/java_lang_Class.cc | 49 |
1 files changed, 36 insertions, 13 deletions
diff --git a/src/java_lang_Class.cc b/src/java_lang_Class.cc index 1a625be..f4376ec 100644 --- a/src/java_lang_Class.cc +++ b/src/java_lang_Class.cc @@ -199,10 +199,37 @@ bool MethodMatches(Method* m, String* name, const std::string& signature) { if (!StringPiece(method_signature).starts_with(signature)) { return false; } - m->InitJavaFields(); + if (m->IsMiranda()) { + return false; + } return true; } +Method* FindConstructorOrMethodInArray(ObjectArray<Method>* methods, String* name, + std::string& signature) { + if (methods == NULL) { + return NULL; + } + Method* result = NULL; + for (int32_t i = 0; i < methods->GetLength(); ++i) { + Method* method = methods->Get(i); + if (!MethodMatches(method, name, signature)) { + continue; + } + + result = method; + + // Covariant return types permit the class to define multiple + // methods with the same name and parameter types. Prefer to return + // a non-synthetic method in such situations. We may still return + // a synthetic method to handle situations like escalated visibility. + if (!method->IsSynthetic()) { + break; + } + } + return result; +} + jobject Class_getDeclaredConstructorOrMethod(JNIEnv* env, jclass, jclass javaClass, jstring javaName, jobjectArray javaSignature) { Class* c = Decode<Class*>(env, javaClass); @@ -216,21 +243,17 @@ jobject Class_getDeclaredConstructorOrMethod(JNIEnv* env, jclass, } signature += ")"; - for (size_t i = 0; i < c->NumVirtualMethods(); ++i) { - Method* m = c->GetVirtualMethod(i); - if (MethodMatches(m, name, signature)) { - return AddLocalReference<jobject>(env, m); - } + Method* m = FindConstructorOrMethodInArray(c->GetDirectMethods(), name, signature); + if (m == NULL) { + m = FindConstructorOrMethodInArray(c->GetVirtualMethods(), name, signature); } - for (size_t i = 0; i < c->NumDirectMethods(); ++i) { - Method* m = c->GetDirectMethod(i); - if (MethodMatches(m, name, signature)) { - return AddLocalReference<jobject>(env, m); - } + if (m != NULL) { + m->InitJavaFields(); + return AddLocalReference<jobject>(env, m); + } else { + return NULL; } - - return NULL; } jobject Class_getDeclaredField(JNIEnv* env, jclass, jclass jklass, jobject jname) { |