Don't call virtual methods in TypeNamespace constructors

While probably safe in this particular context because of this specific
class structure, it is bad practice to call virtual methods in constructors.

Bug: None
Test: unittests continue to pass

Change-Id: I3c9a435efd89a2c2bd7ce576aed585b8ab766bda
diff --git a/aidl.cpp b/aidl.cpp
index 3cff7e0..a9b2d6e 100644
--- a/aidl.cpp
+++ b/aidl.cpp
@@ -561,6 +561,7 @@
   unique_ptr<AidlInterface> interface;
   std::vector<std::unique_ptr<AidlImport>> imports;
   unique_ptr<cpp::TypeNamespace> types(new cpp::TypeNamespace());
+  types->Init();
   int err = internals::load_and_validate_aidl(
       std::vector<std::string>{},  // no preprocessed files
       options.ImportPaths(),
@@ -583,6 +584,7 @@
   unique_ptr<AidlInterface> interface;
   std::vector<std::unique_ptr<AidlImport>> imports;
   unique_ptr<java::JavaTypeNamespace> types(new java::JavaTypeNamespace());
+  types->Init();
   int err = internals::load_and_validate_aidl(
       options.preprocessed_files_,
       options.import_paths_,
diff --git a/aidl_unittest.cpp b/aidl_unittest.cpp
index 7515f6f..05ca02c 100644
--- a/aidl_unittest.cpp
+++ b/aidl_unittest.cpp
@@ -36,6 +36,11 @@
 
 class AidlTest : public ::testing::Test {
  protected:
+  void SetUp() override {
+    java_types_.Init();
+    cpp_types_.Init();
+  }
+
   unique_ptr<AidlInterface> Parse(const string& path,
                                   const string& contents,
                                   TypeNamespace* types) {
@@ -55,11 +60,12 @@
 
   FakeIoDelegate io_delegate_;
   vector<string> import_paths_;
+  java::JavaTypeNamespace java_types_;
+  cpp::TypeNamespace cpp_types_;
 };
 
 TEST_F(AidlTest, JavaAcceptsMissingPackage) {
-  java::JavaTypeNamespace types;
-  EXPECT_NE(nullptr, Parse("IFoo.aidl", "interface IFoo { }", &types));
+  EXPECT_NE(nullptr, Parse("IFoo.aidl", "interface IFoo { }", &java_types_));
 }
 
 TEST_F(AidlTest, RejectsArraysOfBinders) {
@@ -70,50 +76,41 @@
   string contents = "package foo;\n"
                     "import bar.IBar;\n"
                     "interface IFoo { void f(in IBar[] input); }";
-  java::JavaTypeNamespace java_types;
-  EXPECT_EQ(nullptr, Parse(path, contents, &java_types));
-  cpp::TypeNamespace cpp_types;
-  EXPECT_EQ(nullptr, Parse(path, contents, &cpp_types));
+  EXPECT_EQ(nullptr, Parse(path, contents, &java_types_));
+  EXPECT_EQ(nullptr, Parse(path, contents, &cpp_types_));
 }
 
 TEST_F(AidlTest, CppRejectsMissingPackage) {
-  cpp::TypeNamespace types;
-  EXPECT_EQ(nullptr, Parse("IFoo.aidl", "interface IFoo { }", &types));
+  EXPECT_EQ(nullptr, Parse("IFoo.aidl", "interface IFoo { }", &cpp_types_));
   EXPECT_NE(nullptr,
-            Parse("a/IFoo.aidl", "package a; interface IFoo { }", &types));
+            Parse("a/IFoo.aidl", "package a; interface IFoo { }", &cpp_types_));
 }
 
 TEST_F(AidlTest, RejectsOnewayOutParameters) {
-  cpp::TypeNamespace cpp_types;
-  java::JavaTypeNamespace java_types;
   string oneway_interface =
       "package a; oneway interface IFoo { void f(out int bar); }";
   string oneway_method =
       "package a; interface IBar { oneway void f(out int bar); }";
-  EXPECT_EQ(nullptr, Parse("a/IFoo.aidl", oneway_interface, &cpp_types));
-  EXPECT_EQ(nullptr, Parse("a/IFoo.aidl", oneway_interface, &java_types));
-  EXPECT_EQ(nullptr, Parse("a/IBar.aidl", oneway_method, &cpp_types));
-  EXPECT_EQ(nullptr, Parse("a/IBar.aidl", oneway_method, &java_types));
+  EXPECT_EQ(nullptr, Parse("a/IFoo.aidl", oneway_interface, &cpp_types_));
+  EXPECT_EQ(nullptr, Parse("a/IFoo.aidl", oneway_interface, &java_types_));
+  EXPECT_EQ(nullptr, Parse("a/IBar.aidl", oneway_method, &cpp_types_));
+  EXPECT_EQ(nullptr, Parse("a/IBar.aidl", oneway_method, &java_types_));
 }
 
 TEST_F(AidlTest, RejectsOnewayNonVoidReturn) {
-  cpp::TypeNamespace cpp_types;
-  java::JavaTypeNamespace java_types;
   string oneway_method = "package a; interface IFoo { oneway int f(); }";
-  EXPECT_EQ(nullptr, Parse("a/IFoo.aidl", oneway_method, &cpp_types));
-  EXPECT_EQ(nullptr, Parse("a/IFoo.aidl", oneway_method, &java_types));
+  EXPECT_EQ(nullptr, Parse("a/IFoo.aidl", oneway_method, &cpp_types_));
+  EXPECT_EQ(nullptr, Parse("a/IFoo.aidl", oneway_method, &java_types_));
 }
 
 TEST_F(AidlTest, AcceptsOneway) {
-  cpp::TypeNamespace cpp_types;
-  java::JavaTypeNamespace java_types;
   string oneway_method = "package a; interface IFoo { oneway void f(int a); }";
   string oneway_interface =
       "package a; oneway interface IBar { void f(int a); }";
-  EXPECT_NE(nullptr, Parse("a/IFoo.aidl", oneway_method, &cpp_types));
-  EXPECT_NE(nullptr, Parse("a/IFoo.aidl", oneway_method, &java_types));
-  EXPECT_NE(nullptr, Parse("a/IBar.aidl", oneway_interface, &cpp_types));
-  EXPECT_NE(nullptr, Parse("a/IBar.aidl", oneway_interface, &java_types));
+  EXPECT_NE(nullptr, Parse("a/IFoo.aidl", oneway_method, &cpp_types_));
+  EXPECT_NE(nullptr, Parse("a/IFoo.aidl", oneway_method, &java_types_));
+  EXPECT_NE(nullptr, Parse("a/IBar.aidl", oneway_interface, &cpp_types_));
+  EXPECT_NE(nullptr, Parse("a/IBar.aidl", oneway_interface, &java_types_));
 }
 }  // namespace aidl
 }  // namespace android
diff --git a/ast_java_unittest.cpp b/ast_java_unittest.cpp
index 7c09684..3981363 100644
--- a/ast_java_unittest.cpp
+++ b/ast_java_unittest.cpp
@@ -38,6 +38,7 @@
 
 TEST(AstJavaTests, GeneratesClass) {
   JavaTypeNamespace types;
+  types.Init();
   Type class_type(&types, "TestClass", ValidatableType::KIND_GENERATED,
                   false, false);
   Type extend_type(&types, "SuperClass", ValidatableType::KIND_BUILT_IN,
diff --git a/generate_cpp_unittest.cpp b/generate_cpp_unittest.cpp
index 93336ef..f5518f5 100644
--- a/generate_cpp_unittest.cpp
+++ b/generate_cpp_unittest.cpp
@@ -364,7 +364,9 @@
  protected:
   ASTTest(string file_path, string file_contents)
       : file_path_(file_path),
-        file_contents_(file_contents) {}
+        file_contents_(file_contents) {
+    types_.Init();
+  }
 
   unique_ptr<AidlInterface> Parse() {
     io_delegate_.SetFileContents(file_path_, file_contents_);
diff --git a/type_cpp.cpp b/type_cpp.cpp
index 85e15e4..0cf4767 100644
--- a/type_cpp.cpp
+++ b/type_cpp.cpp
@@ -168,7 +168,7 @@
   }
 }
 
-TypeNamespace::TypeNamespace() {
+void TypeNamespace::Init() {
   Add(new PrimitiveType(
       ValidatableType::KIND_BUILT_IN, kNoPackage, "byte",
       "cstdint", "int8_t", "readByte", "writeByte",
diff --git a/type_cpp.h b/type_cpp.h
index 214252b..98eb211 100644
--- a/type_cpp.h
+++ b/type_cpp.h
@@ -87,9 +87,10 @@
 
 class TypeNamespace : public ::android::aidl::LanguageTypeNamespace<Type> {
  public:
-  TypeNamespace();
+  TypeNamespace() = default;
   virtual ~TypeNamespace() = default;
 
+  void Init() override;
   bool AddParcelableType(const AidlParcelable* p,
                          const std::string& filename) override;
   bool AddBinderType(const AidlInterface* b,
diff --git a/type_cpp_unittest.cpp b/type_cpp_unittest.cpp
index a2e8f74..d4232a0 100644
--- a/type_cpp_unittest.cpp
+++ b/type_cpp_unittest.cpp
@@ -26,6 +26,9 @@
 
 class CppTypeNamespaceTest : public ::testing::Test {
  protected:
+  void SetUp() override {
+    types_.Init();
+  }
   TypeNamespace types_;
 };
 
diff --git a/type_java.cpp b/type_java.cpp
index e922f9f..ff05440 100644
--- a/type_java.cpp
+++ b/type_java.cpp
@@ -705,7 +705,7 @@
 
 // ================================================================
 
-JavaTypeNamespace::JavaTypeNamespace() {
+void JavaTypeNamespace::Init() {
   Add(new BasicType(this, "void", "XXX", "XXX", "XXX", "XXX", "XXX"));
 
   m_bool_type = new BooleanType(this);
diff --git a/type_java.h b/type_java.h
index bf348c4..a5e0e0a 100644
--- a/type_java.h
+++ b/type_java.h
@@ -365,9 +365,10 @@
 
 class JavaTypeNamespace : public LanguageTypeNamespace<Type> {
  public:
-  JavaTypeNamespace();
+  JavaTypeNamespace() = default;
   virtual ~JavaTypeNamespace() = default;
 
+  void Init() override;
   bool AddParcelableType(const AidlParcelable* p,
                          const string& filename) override;
   bool AddBinderType(const AidlInterface* b,
diff --git a/type_java_unittest.cpp b/type_java_unittest.cpp
index 6be2b1a..e435480 100644
--- a/type_java_unittest.cpp
+++ b/type_java_unittest.cpp
@@ -29,6 +29,9 @@
 
 class JavaTypeNamespaceTest : public ::testing::Test {
  protected:
+  void SetUp() override {
+    types_.Init();
+  }
   JavaTypeNamespace types_;
 };
 
diff --git a/type_namespace.h b/type_namespace.h
index b5719b0..7aaba7b 100644
--- a/type_namespace.h
+++ b/type_namespace.h
@@ -67,6 +67,10 @@
 
 class TypeNamespace {
  public:
+  // Load the TypeNamespace with built in types.  Don't do work in the
+  // constructor because many of the useful methods are virtual.
+  virtual void Init() = 0;
+
   // Load this TypeNamespace with user defined types.
   virtual bool AddParcelableType(const AidlParcelable* p,
                                  const std::string& filename) = 0;