Implement Class.getDeclared(Constructors|Fields|Methods).
This required making sure that a Method* that represents a constructor
has java.lang.reflect.Constructor as its class.
Change-Id: I25908845a2b8d686d5404ac584693db0edd5853c
diff --git a/src/class_linker.cc b/src/class_linker.cc
index 6daa27a..1c25f61 100644
--- a/src/class_linker.cc
+++ b/src/class_linker.cc
@@ -78,6 +78,7 @@
"[Ljava/lang/Class;",
"[Ljava/lang/Object;",
"Ljava/lang/String;",
+ "Ljava/lang/reflect/Constructor;",
"Ljava/lang/reflect/Field;",
"Ljava/lang/reflect/Method;",
"Ljava/lang/ClassLoader;",
@@ -252,7 +253,14 @@
RegisterDexFile(*dex_file);
}
- // Field and Method are necessary so that FindClass can link members
+ // Constructor, Field, and Method are necessary so that FindClass can link members
+ Class* java_lang_reflect_Constructor = AllocClass(java_lang_Class, sizeof(MethodClass));
+ java_lang_reflect_Constructor->SetDescriptor(intern_table_->InternStrong("Ljava/lang/reflect/Constructor;"));
+ CHECK(java_lang_reflect_Constructor != NULL);
+ java_lang_reflect_Constructor->SetObjectSize(sizeof(Method));
+ SetClassRoot(kJavaLangReflectConstructor, java_lang_reflect_Constructor);
+ java_lang_reflect_Constructor->SetStatus(Class::kStatusResolved);
+
Class* java_lang_reflect_Field = AllocClass(java_lang_Class, sizeof(FieldClass));
CHECK(java_lang_reflect_Field != NULL);
java_lang_reflect_Field->SetDescriptor(intern_table_->InternStrong("Ljava/lang/reflect/Field;"));
@@ -262,13 +270,12 @@
Field::SetClass(java_lang_reflect_Field);
Class* java_lang_reflect_Method = AllocClass(java_lang_Class, sizeof(MethodClass));
- java_lang_reflect_Method->SetDescriptor(
- intern_table_->InternStrong("Ljava/lang/reflect/Method;"));
+ java_lang_reflect_Method->SetDescriptor(intern_table_->InternStrong("Ljava/lang/reflect/Method;"));
CHECK(java_lang_reflect_Method != NULL);
java_lang_reflect_Method->SetObjectSize(sizeof(Method));
SetClassRoot(kJavaLangReflectMethod, java_lang_reflect_Method);
java_lang_reflect_Method->SetStatus(Class::kStatusResolved);
- Method::SetClass(java_lang_reflect_Method);
+ Method::SetClasses(java_lang_reflect_Constructor, java_lang_reflect_Method);
// now we can use FindSystemClass
@@ -337,11 +344,15 @@
CHECK_EQ(java_lang_Cloneable, object_array_class->GetInterface(0));
CHECK_EQ(java_io_Serializable, object_array_class->GetInterface(1));
- // run Class, Field, and Method through FindSystemClass.
+ // run Class, Constructor, Field, and Method through FindSystemClass.
// this initializes their dex_cache_ fields and register them in classes_.
Class* Class_class = FindSystemClass("Ljava/lang/Class;");
CHECK_EQ(java_lang_Class, Class_class);
+ java_lang_reflect_Constructor->SetStatus(Class::kStatusNotReady);
+ Class* Constructor_class = FindSystemClass("Ljava/lang/reflect/Constructor;");
+ CHECK_EQ(java_lang_reflect_Constructor, Constructor_class);
+
java_lang_reflect_Field->SetStatus(Class::kStatusNotReady);
Class* Field_class = FindSystemClass("Ljava/lang/reflect/Field;");
CHECK_EQ(java_lang_reflect_Field, Field_class);
@@ -513,7 +524,7 @@
String::SetClass(GetClassRoot(kJavaLangString));
Field::SetClass(GetClassRoot(kJavaLangReflectField));
- Method::SetClass(GetClassRoot(kJavaLangReflectMethod));
+ Method::SetClasses(GetClassRoot(kJavaLangReflectConstructor), GetClassRoot(kJavaLangReflectMethod));
BooleanArray::SetArrayClass(GetClassRoot(kBooleanArrayClass));
ByteArray::SetArrayClass(GetClassRoot(kByteArrayClass));
CharArray::SetArrayClass(GetClassRoot(kCharArrayClass));
@@ -594,7 +605,7 @@
ClassLinker::~ClassLinker() {
String::ResetClass();
Field::ResetClass();
- Method::ResetClass();
+ Method::ResetClasses();
BooleanArray::ResetArrayClass();
ByteArray::ResetArrayClass();
CharArray::ResetArrayClass();
@@ -699,6 +710,8 @@
klass = GetClassRoot(kJavaLangClass);
} else if (descriptor == "Ljava/lang/String;") {
klass = GetClassRoot(kJavaLangString);
+ } else if (descriptor == "Ljava/lang/reflect/Constructor;") {
+ klass = GetClassRoot(kJavaLangReflectConstructor);
} else if (descriptor == "Ljava/lang/reflect/Field;") {
klass = GetClassRoot(kJavaLangReflectField);
} else if (descriptor == "Ljava/lang/reflect/Method;") {
@@ -957,7 +970,11 @@
Method* dst) {
const DexFile::MethodId& method_id = dex_file.GetMethodId(src.method_idx_);
dst->SetDeclaringClass(klass);
- dst->SetName(ResolveString(dex_file, method_id.name_idx_, klass->GetDexCache()));
+ String* method_name = ResolveString(dex_file, method_id.name_idx_, klass->GetDexCache());
+ dst->SetName(method_name);
+ if (method_name->Equals("<init>")) {
+ dst->SetClass(GetClassRoot(kJavaLangReflectConstructor));
+ }
{
int32_t utf16_length;
std::string utf8(dex_file.CreateMethodDescriptor(method_id.proto_idx_, &utf16_length));