refactor: type resolution using visitor

Type references and constant references are done in a same visitor.

Visitor provides "scope" which can be used to (not implemented in this
change)

- resolve "type parameter"(AidlTypeSpecifier) bound to the scope
- resolve nested types
- ...

Bug: n/a
Test: aidl_unittests
Change-Id: I44aef519545ca377b208dbe98ef5a57b9cec1878
diff --git a/parser.cpp b/parser.cpp
index 721979f..c8cf476 100644
--- a/parser.cpp
+++ b/parser.cpp
@@ -61,24 +61,26 @@
   }
 }
 
-class ConstantReferenceResolver : public AidlVisitor {
+class ReferenceResolver : public AidlVisitor {
  public:
-  ConstantReferenceResolver(const AidlDefinedType* scope, const AidlTypenames& typenames,
-                            TypeResolver& resolver, bool* success)
+  ReferenceResolver(const AidlDefinedType* scope, const AidlTypenames& typenames,
+                    TypeResolver& resolver, bool* success)
       : scope_(scope), typenames_(typenames), resolver_(resolver), success_(success) {}
+
+  void Visit(const AidlTypeSpecifier& t) override {
+    AidlTypeSpecifier& type = const_cast<AidlTypeSpecifier&>(t);
+    if (!resolver_(typenames_.GetDocumentFor(scope_), &type)) {
+      AIDL_ERROR(type) << "Failed to resolve '" << type.GetUnresolvedName() << "'";
+      *success_ = false;
+    }
+  }
+
   void Visit(const AidlConstantReference& v) override {
     if (IsCircularReference(&v)) {
       *success_ = false;
       return;
     }
 
-    if (v.GetRefType() && !v.GetRefType()->IsResolved()) {
-      if (!resolver_(typenames_.GetDocumentFor(scope_), v.GetRefType().get())) {
-        AIDL_ERROR(v.GetRefType()) << "Unknown type '" << v.GetRefType()->GetName() << "'";
-        *success_ = false;
-        return;
-      }
-    }
     const AidlConstantValue* resolved = v.Resolve(scope_);
     if (!resolved) {
       AIDL_ERROR(v) << "Unknown reference '" << v.Literal() << "'";
@@ -88,7 +90,7 @@
 
     // resolve recursive references
     Push(&v);
-    VisitTopDown(*this, *resolved);
+    VisitBottomUp(*this, *resolved);
     Pop();
   }
 
@@ -133,20 +135,13 @@
   std::vector<StackElem> stack_ = {};
 };
 
+// Resolve "unresolved" types in the "main" document.
 bool Parser::Resolve(TypeResolver& type_resolver) {
   bool success = true;
-  for (AidlTypeSpecifier* typespec : unresolved_typespecs_) {
-    if (!type_resolver(document_, typespec)) {
-      AIDL_ERROR(typespec) << "Failed to resolve '" << typespec->GetUnresolvedName() << "'";
-      success = false;
-      // don't stop to show more errors if any
-    }
-  }
 
-  // resolve "field references" as well.
   for (const auto& type : document_->DefinedTypes()) {
-    ConstantReferenceResolver ref_resolver{type.get(), typenames_, type_resolver, &success};
-    VisitTopDown(ref_resolver, *type);
+    ReferenceResolver ref_resolver{type.get(), typenames_, type_resolver, &success};
+    VisitBottomUp(ref_resolver, *type);
   }
 
   return success;