summaryrefslogtreecommitdiffstats
path: root/src/java_lang_Class.cc
diff options
context:
space:
mode:
authorJesse Wilson <jessewilson@google.com>2011-11-21 10:35:06 -0500
committerJesse Wilson <jessewilson@google.com>2011-11-21 10:35:06 -0500
commit8ea36f84a1fff2943127ef21ce371c99a7d191af (patch)
tree1928f6ac2684401f19bc32c49458ecd1e0aa9210 /src/java_lang_Class.cc
parentdbb4079eb1e7d7738c81a97c8dd2550885c1093a (diff)
downloadart-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.cc49
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) {