Give an example of walking TypeIds in a DexFile
Also prevent accidentally copying of DexFile structures

Change-Id: I293bdfe073ce1e1a54f6de2e0abadac312503016
diff --git a/src/class_linker_test.cc b/src/class_linker_test.cc
index ce08b1b..e2b9a2b 100644
--- a/src/class_linker_test.cc
+++ b/src/class_linker_test.cc
@@ -23,7 +23,10 @@
   }
 
   void AssertPrimitiveClass(const StringPiece& descriptor) {
-    Class* primitive = class_linker_->FindSystemClass(descriptor);
+    AssertPrimitiveClass(descriptor, class_linker_->FindSystemClass(descriptor));
+  }
+
+  void AssertPrimitiveClass(const StringPiece& descriptor, const Class* primitive) {
     ASSERT_TRUE(primitive != NULL);
     ASSERT_TRUE(primitive->GetClass() != NULL);
     ASSERT_EQ(primitive->GetClass(), primitive->GetClass()->GetClass());
@@ -56,6 +59,13 @@
                         const StringPiece& component_type,
                         ClassLoader* class_loader) {
     Class* array = class_linker_->FindClass(array_descriptor, class_loader);
+    EXPECT_EQ(array_rank, array->array_rank_);
+    EXPECT_TRUE(array->GetComponentType()->GetDescriptor()->Equals(component_type));
+    EXPECT_EQ(class_loader, array->GetClassLoader());
+    AssertArrayClass(array_descriptor, array);
+  }
+
+  void AssertArrayClass(const StringPiece& array_descriptor, Class* array) {
     ASSERT_TRUE(array != NULL);
     ASSERT_TRUE(array->GetClass() != NULL);
     ASSERT_EQ(array->GetClass(), array->GetClass()->GetClass());
@@ -64,16 +74,14 @@
     EXPECT_TRUE(array->GetSuperClass() != NULL);
     EXPECT_EQ(class_linker_->FindSystemClass("Ljava/lang/Object;"), array->GetSuperClass());
     EXPECT_TRUE(array->HasSuperClass());
-    EXPECT_EQ(class_loader, array->GetClassLoader());
     ASSERT_TRUE(array->GetComponentType() != NULL);
     ASSERT_TRUE(array->GetComponentType()->GetDescriptor() != NULL);
-    EXPECT_TRUE(array->GetComponentType()->GetDescriptor()->Equals(component_type));
     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_LE(1, array->array_rank_);
     EXPECT_FALSE(array->IsInterface());
     EXPECT_EQ(array->GetComponentType()->IsPublic(), array->IsPublic());
     EXPECT_TRUE(array->IsFinal());
@@ -86,7 +94,7 @@
     EXPECT_EQ(2U, array->NumInterfaces());
   }
 
-  void AssertDexFileMethod(Class* klass, Method* method) {
+  void AssertMethod(Class* klass, Method* method) {
     EXPECT_TRUE(method != NULL);
     EXPECT_TRUE(method->GetName() != NULL);
     EXPECT_TRUE(method->GetSignature() != NULL);
@@ -101,17 +109,14 @@
     EXPECT_EQ(method->declaring_class_->dex_cache_->GetFields(), method->dex_cache_fields_);
   }
 
-  void AssertDexFileField(Class* klass, Field* field) {
+  void AssertField(Class* klass, Field* field) {
     EXPECT_TRUE(field != NULL);
     EXPECT_EQ(klass, field->GetDeclaringClass());
     EXPECT_TRUE(field->GetName() != NULL);
     EXPECT_TRUE(field->GetDescriptor() != NULL);
   }
 
-  void AssertDexFileClass(ClassLoader* class_loader, const char* descriptor) {
-    ASSERT_TRUE(descriptor != NULL);
-    Class* klass = class_linker_->FindSystemClass(descriptor);
-    ASSERT_TRUE(klass != NULL);
+  void AssertClass(const StringPiece& descriptor, Class* klass) {
     EXPECT_TRUE(klass->GetDescriptor()->Equals(descriptor));
     if (klass->descriptor_->Equals(String::AllocFromModifiedUtf8("Ljava/lang/Object;"))) {
       EXPECT_FALSE(klass->HasSuperClass());
@@ -119,7 +124,6 @@
       EXPECT_TRUE(klass->HasSuperClass());
       EXPECT_TRUE(klass->GetSuperClass() != NULL);
     }
-    EXPECT_EQ(class_loader, klass->GetClassLoader());
     EXPECT_TRUE(klass->GetDexCache() != NULL);
     EXPECT_TRUE(klass->GetComponentType() == NULL);
     EXPECT_TRUE(klass->GetComponentType() == NULL);
@@ -161,25 +165,25 @@
 
     for (size_t i = 0; i < klass->NumDirectMethods(); i++) {
       Method* method = klass->GetDirectMethod(i);
-      AssertDexFileMethod(klass, method);
+      AssertMethod(klass, method);
       EXPECT_EQ(klass, method->GetDeclaringClass());
     }
 
     for (size_t i = 0; i < klass->NumVirtualMethods(); i++) {
       Method* method = klass->GetVirtualMethod(i);
-      AssertDexFileMethod(klass, method);
+      AssertMethod(klass, method);
       EXPECT_TRUE(method->GetDeclaringClass()->IsAssignableFrom(klass));
     }
 
     for (size_t i = 0; i < klass->NumInstanceFields(); i++) {
       Field* field = klass->GetInstanceField(i);
-      AssertDexFileField(klass, field);
+      AssertField(klass, field);
       EXPECT_FALSE(field->IsStatic());
     }
 
     for (size_t i = 0; i < klass->NumStaticFields(); i++) {
       Field* field = klass->GetStaticField(i);
-      AssertDexFileField(klass, field);
+      AssertField(klass, field);
       EXPECT_TRUE(field->IsStatic());
    }
 
@@ -187,13 +191,15 @@
     EXPECT_GE(klass->NumInstanceFields(), klass->NumReferenceInstanceFields());
     for (size_t i = 0; i < klass->NumReferenceInstanceFields(); i++) {
       Field* field = klass->GetInstanceField(i);
-      Class* field_type = class_linker_->FindClass(field->GetDescriptor(), class_loader);
+      Class* field_type = class_linker_->FindClass(field->GetDescriptor(),
+                                                   klass->GetClassLoader());
       ASSERT_TRUE(field_type != NULL);
       EXPECT_FALSE(field_type->IsPrimitive());
     }
     for (size_t i = klass->NumReferenceInstanceFields(); i < klass->NumInstanceFields(); i++) {
       Field* field = klass->GetInstanceField(i);
-      Class* field_type = class_linker_->FindClass(field->GetDescriptor(), class_loader);
+      Class* field_type = class_linker_->FindClass(field->GetDescriptor(),
+                                                   klass->GetClassLoader());
       ASSERT_TRUE(field_type != NULL);
       EXPECT_TRUE(field_type->IsPrimitive());
     }
@@ -208,19 +214,41 @@
               total_num_reference_instance_fields == 0);
   }
 
-  static void TestRootVisitor(Object* root, void* arg) {
-    EXPECT_TRUE(root != NULL);
+  void AssertDexFileClass(ClassLoader* class_loader, const StringPiece& descriptor) {
+    ASSERT_TRUE(descriptor != NULL);
+    Class* klass = class_linker_->FindSystemClass(descriptor);
+    ASSERT_TRUE(klass != NULL);
+    EXPECT_TRUE(klass->GetDescriptor()->Equals(descriptor));
+    EXPECT_EQ(class_loader, klass->GetClassLoader());
+    if (klass->IsPrimitive()) {
+      AssertPrimitiveClass(descriptor, klass);
+    } else if (klass->IsArray()) {
+      AssertArrayClass(descriptor, klass);
+    } else {
+      AssertClass(descriptor, klass);
+    }
   }
 
   void AssertDexFile(const DexFile* dex, ClassLoader* class_loader) {
     ASSERT_TRUE(dex != NULL);
+    // Verify all the classes defined in this file
     for (size_t i = 0; i < dex->NumClassDefs(); i++) {
-      const DexFile::ClassDef class_def = dex->GetClassDef(i);
+      const DexFile::ClassDef& class_def = dex->GetClassDef(i);
       const char* descriptor = dex->GetClassDescriptor(class_def);
       AssertDexFileClass(class_loader, descriptor);
     }
+    // Verify all the types referened by this file
+    for (size_t i = 0; i < dex->NumTypeIds(); i++) {
+      const DexFile::TypeId& type_id = dex->GetTypeId(i);
+      const char* descriptor = dex->GetTypeDescriptor(type_id);
+      AssertDexFileClass(class_loader, descriptor);
+    }
     class_linker_->VisitRoots(TestRootVisitor, NULL);
   }
+
+  static void TestRootVisitor(Object* root, void* arg) {
+    EXPECT_TRUE(root != NULL);
+  }
 };
 
 TEST_F(ClassLinkerTest, FindClassNonexistent) {