New ClassLinker::CreateArrayClass

- Added ClassLinker::CreateArrayClass for use by ClassLinker::FindClass
- Replaced hand crafted ClassLinker::char_array_class_ initialization with call to FindClass
- Removed ClassLinker::LoadClass public interfaces, kept only one internally
- Removed JType
- Cleanedup gtest naming convention
- Added RuntimeTest for common test initialization such as Thread::Init
- Switched from assert to DCHECK which found some bit rotted code
- Expanded class_linker_test to array classes and also also array rank
  and interface count in existing cases

Change-Id: Ie3d71c8b434c8521f4ea8d2f07b1c4c905ee1d90
diff --git a/src/class_linker_test.cc b/src/class_linker_test.cc
index 251b6cb..00fb75c 100644
--- a/src/class_linker_test.cc
+++ b/src/class_linker_test.cc
@@ -8,53 +8,129 @@
 
 namespace art {
 
-TEST(ClassLinker, LoadNonexistent) {
+class ClassLinkerTest : public RuntimeTest {};
+
+TEST_F(ClassLinkerTest, FindClassNonexistent) {
   scoped_ptr<DexFile> dex(DexFile::OpenBase64(kMyClassDex));
   ASSERT_TRUE(dex != NULL);
 
   scoped_ptr<ClassLinker> linker(ClassLinker::Create());
   linker->AppendToClassPath(dex.get());
 
-  scoped_ptr<Class> klass(linker.get()->AllocClass(dex.get()));
-  bool result1 = linker->LoadClass("NoSuchClass", klass.get());
-  EXPECT_FALSE(result1);
-  bool result2 = linker->LoadClass("LNoSuchClass;", klass.get());
-  EXPECT_FALSE(result2);
+  Class* result1 = linker.get()->FindClass("NoSuchClass;", NULL);
+  EXPECT_TRUE(result1 == NULL);
+  Class* result2 = linker.get()->FindClass("LNoSuchClass;", NULL);
+  EXPECT_TRUE(result2 == NULL);
 }
 
-TEST(ClassLinker, Load) {
-  scoped_ptr<DexFile> dex(DexFile::OpenBase64(kNestedDex));
-  ASSERT_TRUE(dex != NULL);
+TEST_F(ClassLinkerTest, FindClassNested) {
+  scoped_ptr<DexFile> objectDex(DexFile::OpenBase64(kJavaLangDex));
+  ASSERT_TRUE(objectDex != NULL);
+  scoped_ptr<DexFile> nestedDex(DexFile::OpenBase64(kNestedDex));
+  ASSERT_TRUE(nestedDex != NULL);
 
   scoped_ptr<ClassLinker> linker(ClassLinker::Create());
-  linker->AppendToClassPath(dex.get());
+  linker->AppendToClassPath(objectDex.get());
+  linker->AppendToClassPath(nestedDex.get());
 
-  scoped_ptr<Class> klass(linker.get()->AllocClass(dex.get()));
-  bool result = linker->LoadClass("LNested;", klass.get());
-  ASSERT_TRUE(result);
+  Class* outer = linker.get()->FindClass("LNested;", NULL);
+  ASSERT_TRUE(outer != NULL);
+  EXPECT_EQ(0U, outer->NumVirtualMethods());
+  EXPECT_EQ(1U, outer->NumDirectMethods());
 
-  uint32_t vmeth = klass->NumVirtualMethods();
-  EXPECT_EQ(vmeth, 0U);
-
-  uint32_t dmeth = klass->NumDirectMethods();
-  EXPECT_EQ(dmeth, 1U);
+  Class* inner = linker.get()->FindClass("LNested$Inner;", NULL);
+  ASSERT_TRUE(inner != NULL);
+  EXPECT_EQ(0U, inner->NumVirtualMethods());
+  EXPECT_EQ(1U, inner->NumDirectMethods());
 }
 
-TEST(ClassLinker, FindClass) {
-  ASSERT_TRUE(Thread::Init());
-  ASSERT_TRUE(Thread::Attach() != NULL);
+static void AssertNonExistantClass(ClassLinker* linker, const StringPiece& descriptor) {
+  EXPECT_TRUE(linker->FindClass(descriptor, NULL) == NULL);
+}
+
+static void AssertPrimitiveClass(ClassLinker* linker, const StringPiece& descriptor) {
+  Class* primitive = linker->FindClass(descriptor, NULL);
+  ASSERT_TRUE(primitive != NULL);
+  ASSERT_TRUE(primitive->GetClass() != NULL);
+  ASSERT_EQ(primitive->GetClass(), primitive->GetClass()->GetClass());
+  EXPECT_TRUE(primitive->GetClass()->GetSuperClass() != NULL);
+  ASSERT_EQ(descriptor, primitive->GetDescriptor());
+  EXPECT_TRUE(primitive->GetSuperClass() == NULL);
+  EXPECT_FALSE(primitive->HasSuperClass());
+  EXPECT_TRUE(primitive->GetComponentType() == NULL);
+  EXPECT_TRUE(primitive->GetStatus() == Class::kStatusInitialized);
+  EXPECT_FALSE(primitive->IsErroneous());
+  EXPECT_TRUE(primitive->IsVerified());
+  EXPECT_TRUE(primitive->IsLinked());
+  EXPECT_FALSE(primitive->IsArray());
+  EXPECT_EQ(0, primitive->array_rank_);
+  EXPECT_FALSE(primitive->IsInterface());
+  EXPECT_TRUE(primitive->IsPublic());
+  EXPECT_TRUE(primitive->IsFinal());
+  EXPECT_TRUE(primitive->IsPrimitive());
+  EXPECT_EQ(0U, primitive->NumDirectMethods());
+  EXPECT_EQ(0U, primitive->NumVirtualMethods());
+  EXPECT_EQ(0U, primitive->NumInstanceFields());
+  EXPECT_EQ(0U, primitive->NumStaticFields());
+  EXPECT_EQ(0U, primitive->interface_count_);
+}
+
+static void AssertArrayClass(ClassLinker* linker,
+                             const StringPiece& array_descriptor,
+                             int32_t array_rank,
+                             const StringPiece& component_type) {
+  Class* array = linker->FindClass(array_descriptor, NULL);
+  ASSERT_TRUE(array != NULL);
+  ASSERT_TRUE(array->GetClass() != NULL);
+  ASSERT_EQ(array->GetClass(), array->GetClass()->GetClass());
+  EXPECT_TRUE(array->GetClass()->GetSuperClass() != NULL);
+  ASSERT_EQ(array_descriptor, array->GetDescriptor());
+  EXPECT_TRUE(array->GetSuperClass() != NULL);
+  EXPECT_EQ(linker->FindSystemClass("Ljava/lang/Object;"), array->GetSuperClass());
+  EXPECT_TRUE(array->HasSuperClass());
+  ASSERT_TRUE(array->GetComponentType() != NULL);
+  ASSERT_TRUE(array->GetComponentType()->GetDescriptor() != NULL);
+  EXPECT_EQ(component_type, array->GetComponentType()->GetDescriptor());
+  EXPECT_TRUE(array->GetStatus() == Class::kStatusInitialized);
+  EXPECT_FALSE(array->IsErroneous());
+  EXPECT_TRUE(array->IsVerified());
+  EXPECT_TRUE(array->IsLinked());
+  EXPECT_TRUE(array->IsArray());
+  EXPECT_EQ(array_rank, array->array_rank_);
+  EXPECT_FALSE(array->IsInterface());
+  EXPECT_EQ(array->GetComponentType()->IsPublic(), array->IsPublic());
+  EXPECT_TRUE(array->IsFinal());
+  EXPECT_FALSE(array->IsPrimitive());
+  EXPECT_EQ(0U, array->NumDirectMethods());
+  EXPECT_EQ(0U, array->NumVirtualMethods());
+  EXPECT_EQ(0U, array->NumInstanceFields());
+  EXPECT_EQ(0U, array->NumStaticFields());
+  EXPECT_EQ(2U, array->interface_count_);
+}
+
+TEST_F(ClassLinkerTest, FindClass) {
+  scoped_ptr<ClassLinker> linker(ClassLinker::Create());
+
+  StringPiece expected = "BCDFIJSZV";
+  for (int ch = 0; ch < 255; ch++) {
+    char* s = reinterpret_cast<char*>(&ch);
+    StringPiece descriptor(s, 1);
+    if (expected.find(ch) == StringPiece::npos) {
+      AssertNonExistantClass(linker.get(), descriptor);
+    } else {
+      AssertPrimitiveClass(linker.get(), descriptor);
+    }
+  }
 
   scoped_ptr<DexFile> dex(DexFile::OpenBase64(kMyClassDex));
   ASSERT_TRUE(dex != NULL);
-
-  scoped_ptr<ClassLinker> linker(ClassLinker::Create());
   linker->AppendToClassPath(dex.get());
 
   Class* JavaLangObject = linker->FindClass("Ljava/lang/Object;", NULL);
   ASSERT_TRUE(JavaLangObject != NULL);
   ASSERT_TRUE(JavaLangObject->GetClass() != NULL);
   ASSERT_EQ(JavaLangObject->GetClass(), JavaLangObject->GetClass()->GetClass());
-  EXPECT_EQ(JavaLangObject->GetClass()->GetSuperClass(), JavaLangObject);
+  EXPECT_EQ(JavaLangObject, JavaLangObject->GetClass()->GetSuperClass());
   ASSERT_TRUE(JavaLangObject->GetDescriptor() == "Ljava/lang/Object;");
   EXPECT_TRUE(JavaLangObject->GetSuperClass() == NULL);
   EXPECT_FALSE(JavaLangObject->HasSuperClass());
@@ -63,6 +139,7 @@
   EXPECT_FALSE(JavaLangObject->IsVerified());
   EXPECT_TRUE(JavaLangObject->IsLinked());
   EXPECT_FALSE(JavaLangObject->IsArray());
+  EXPECT_EQ(0, JavaLangObject->array_rank_);
   EXPECT_FALSE(JavaLangObject->IsInterface());
   EXPECT_TRUE(JavaLangObject->IsPublic());
   EXPECT_FALSE(JavaLangObject->IsFinal());
@@ -71,12 +148,14 @@
   EXPECT_EQ(0U, JavaLangObject->NumVirtualMethods());
   EXPECT_EQ(0U, JavaLangObject->NumInstanceFields());
   EXPECT_EQ(0U, JavaLangObject->NumStaticFields());
+  EXPECT_EQ(0U, JavaLangObject->interface_count_);
+
 
   Class* MyClass = linker->FindClass("LMyClass;", NULL);
   ASSERT_TRUE(MyClass != NULL);
   ASSERT_TRUE(MyClass->GetClass() != NULL);
   ASSERT_EQ(MyClass->GetClass(), MyClass->GetClass()->GetClass());
-  EXPECT_EQ(MyClass->GetClass()->GetSuperClass(), JavaLangObject);
+  EXPECT_EQ(JavaLangObject, MyClass->GetClass()->GetSuperClass());
   ASSERT_TRUE(MyClass->GetDescriptor() == "LMyClass;");
   EXPECT_TRUE(MyClass->GetSuperClass() == JavaLangObject);
   EXPECT_TRUE(MyClass->HasSuperClass());
@@ -86,6 +165,7 @@
   EXPECT_FALSE(MyClass->IsVerified());
   EXPECT_TRUE(MyClass->IsLinked());
   EXPECT_FALSE(MyClass->IsArray());
+  EXPECT_EQ(0, JavaLangObject->array_rank_);
   EXPECT_FALSE(MyClass->IsInterface());
   EXPECT_FALSE(MyClass->IsPublic());
   EXPECT_FALSE(MyClass->IsFinal());
@@ -94,9 +174,17 @@
   EXPECT_EQ(0U, MyClass->NumVirtualMethods());
   EXPECT_EQ(0U, MyClass->NumInstanceFields());
   EXPECT_EQ(0U, MyClass->NumStaticFields());
+  EXPECT_EQ(0U, MyClass->interface_count_);
 
   EXPECT_EQ(JavaLangObject->GetClass()->GetClass(), MyClass->GetClass()->GetClass());
 
+  // created by class_linker
+  AssertArrayClass(linker.get(), "[C", 1, "C");
+  // synthesized on the fly
+  AssertArrayClass(linker.get(), "[[C", 2, "C");
+  AssertArrayClass(linker.get(), "[[[LMyClass;", 3, "LMyClass;");
+  // or not available at all
+  AssertNonExistantClass(linker.get(), "[[[[LNonExistantClass;");
 }
 
 }  // namespace art