Saner determination of a declared type's name (now short + full name)

at the time the type is introduced to a scope.
diff --git a/AST.cpp b/AST.cpp
index e0d4dbd..f23c37d 100644
--- a/AST.cpp
+++ b/AST.cpp
@@ -16,7 +16,7 @@
 AST::AST(Coordinator *coordinator)
     : mCoordinator(coordinator),
       mScanner(NULL),
-      mRootScope(new Scope("root")) {
+      mRootScope(new Scope) {
     enterScope(mRootScope);
 }
 
@@ -141,6 +141,24 @@
     return mScopePath.top();
 }
 
+void AST::addScopedType(const char *localName, NamedType *type) {
+    // LOG(INFO) << "adding scoped type '" << localName << "'";
+
+    std::string path;
+    for (size_t i = 1; i < mScopePath.size(); ++i) {
+        path.append(mScopePath[i]->name());
+        path.append(".");
+    }
+    path.append(localName);
+
+    type->setLocalName(localName);
+
+    FQName fqName(mPackage.package(), mPackage.version(), path);
+    type->setFullName(fqName);
+
+    scope()->addType(localName, type);
+}
+
 Type *AST::lookupType(const char *name) {
     FQName fqName(name);
     CHECK(fqName.isValid());
diff --git a/AST.h b/AST.h
index c775e76..7bb07c1 100644
--- a/AST.h
+++ b/AST.h
@@ -15,6 +15,7 @@
 struct Coordinator;
 struct Formatter;
 struct Method;
+struct NamedType;
 struct TypedVar;
 struct Scope;
 
@@ -32,6 +33,7 @@
     void enterScope(Scope *container);
     void leaveScope();
     Scope *scope();
+    void addScopedType(const char *localName, NamedType *type);
 
     void *scanner();
     void setScanner(void *scanner);
diff --git a/CompoundType.cpp b/CompoundType.cpp
index fba3a86..4da8e23 100644
--- a/CompoundType.cpp
+++ b/CompoundType.cpp
@@ -4,22 +4,8 @@
 
 namespace android {
 
-CompoundField::CompoundField(const char *name, Type *type)
-    : mName(name),
-      mType(type) {
-}
-
-std::string CompoundField::name() const {
-    return mName;
-}
-
-const Type &CompoundField::type() const {
-    return *mType;
-}
-
-CompoundType::CompoundType(Style style, const char *name)
-    : Scope(name),
-      mStyle(style),
+CompoundType::CompoundType(Style style)
+    : mStyle(style),
       mFields(NULL) {
 }
 
@@ -280,5 +266,20 @@
     return true;
 }
 
+////////////////////////////////////////////////////////////////////////////////
+
+CompoundField::CompoundField(const char *name, Type *type)
+    : mName(name),
+      mType(type) {
+}
+
+std::string CompoundField::name() const {
+    return mName;
+}
+
+const Type &CompoundField::type() const {
+    return *mType;
+}
+
 }  // namespace android
 
diff --git a/CompoundType.h b/CompoundType.h
index e61a05e..cfb995b 100644
--- a/CompoundType.h
+++ b/CompoundType.h
@@ -8,18 +8,7 @@
 
 namespace android {
 
-struct CompoundField {
-    CompoundField(const char *name, Type *type);
-
-    std::string name() const;
-    const Type &type() const;
-
-private:
-    std::string mName;
-    Type *mType;
-
-    DISALLOW_COPY_AND_ASSIGN(CompoundField);
-};
+struct CompoundField;
 
 struct CompoundType : public Scope {
     enum Style {
@@ -27,7 +16,7 @@
         STYLE_UNION,
     };
 
-    CompoundType(Style style, const char *name);
+    CompoundType(Style style);
 
     void setFields(std::vector<CompoundField *> *fields);
 
@@ -70,6 +59,19 @@
     DISALLOW_COPY_AND_ASSIGN(CompoundType);
 };
 
+struct CompoundField {
+    CompoundField(const char *name, Type *type);
+
+    std::string name() const;
+    const Type &type() const;
+
+private:
+    std::string mName;
+    Type *mType;
+
+    DISALLOW_COPY_AND_ASSIGN(CompoundField);
+};
+
 }  // namespace android
 
 #endif  // COMPOUND_TYPE_H_
diff --git a/EnumType.cpp b/EnumType.cpp
index b107d70..6d922a0 100644
--- a/EnumType.cpp
+++ b/EnumType.cpp
@@ -7,23 +7,9 @@
 
 namespace android {
 
-EnumValue::EnumValue(const char *name, const char *value)
-    : mName(name),
-      mValue(value) {
-}
-
-std::string EnumValue::name() const {
-    return mName;
-}
-
-const char *EnumValue::value() const {
-    return mValue;
-}
-
 EnumType::EnumType(
-        const char *name, std::vector<EnumValue *> *values, Type *storageType)
-    : NamedType(name),
-      mValues(values),
+        std::vector<EnumValue *> *values, Type *storageType)
+    : mValues(values),
       mStorageType(
               storageType != NULL
                 ? storageType
@@ -91,5 +77,20 @@
     return OK;
 }
 
+////////////////////////////////////////////////////////////////////////////////
+
+EnumValue::EnumValue(const char *name, const char *value)
+    : mName(name),
+      mValue(value) {
+}
+
+std::string EnumValue::name() const {
+    return mName;
+}
+
+const char *EnumValue::value() const {
+    return mValue;
+}
+
 }  // namespace android
 
diff --git a/EnumType.h b/EnumType.h
index 7a174cb..2bb258c 100644
--- a/EnumType.h
+++ b/EnumType.h
@@ -8,22 +8,10 @@
 
 namespace android {
 
-struct EnumValue {
-    EnumValue(const char *name, const char *value = NULL);
-
-    std::string name() const;
-    const char *value() const;
-
-private:
-    std::string mName;
-    const char *mValue;
-
-    DISALLOW_COPY_AND_ASSIGN(EnumValue);
-};
+struct EnumValue;
 
 struct EnumType : public NamedType {
-    EnumType(const char *name,
-             std::vector<EnumValue *> *values,
+    EnumType(std::vector<EnumValue *> *values,
              Type *storageType = NULL);
 
     const ScalarType *resolveToScalarType() const override;
@@ -47,6 +35,19 @@
     DISALLOW_COPY_AND_ASSIGN(EnumType);
 };
 
+struct EnumValue {
+    EnumValue(const char *name, const char *value = NULL);
+
+    std::string name() const;
+    const char *value() const;
+
+private:
+    std::string mName;
+    const char *mValue;
+
+    DISALLOW_COPY_AND_ASSIGN(EnumValue);
+};
+
 }  // namespace android
 
 #endif  // ENUM_TYPE_H_
diff --git a/Interface.cpp b/Interface.cpp
index 9056e72..89bd10e 100644
--- a/Interface.cpp
+++ b/Interface.cpp
@@ -5,9 +5,8 @@
 
 namespace android {
 
-Interface::Interface(const char *name, Type *super)
-    : Scope(name),
-      mSuperType(super) {
+Interface::Interface(Type *super)
+    : mSuperType(super) {
 }
 
 void Interface::addMethod(Method *method) {
@@ -28,7 +27,7 @@
 
 std::string Interface::getCppType(StorageMode mode, std::string *extra) const {
     extra->clear();
-    const std::string base = "::android::sp<" + name() + ">";
+    const std::string base = "::android::sp<" + fullName() + ">";
 
     switch (mode) {
         case StorageMode_Stack:
diff --git a/Interface.h b/Interface.h
index c7f1841..b3e16c7 100644
--- a/Interface.h
+++ b/Interface.h
@@ -11,7 +11,7 @@
 struct Method;
 
 struct Interface : public Scope {
-    Interface(const char *name, Type *super);
+    Interface(Type *super);
 
     void addMethod(Method *method);
 
diff --git a/Method.cpp b/Method.cpp
index b20797b..7e0058f 100644
--- a/Method.cpp
+++ b/Method.cpp
@@ -5,20 +5,6 @@
 
 namespace android {
 
-TypedVar::TypedVar(const char *name, Type *type)
-    : mName(name),
-      mType(type) {
-}
-
-std::string TypedVar::name() const {
-    return mName;
-}
-
-const Type &TypedVar::type() const {
-    return *mType;
-}
-
-
 Method::Method(
         const char *name,
         std::vector<TypedVar *> *args,
@@ -61,5 +47,20 @@
     return out;
 }
 
+////////////////////////////////////////////////////////////////////////////////
+
+TypedVar::TypedVar(const char *name, Type *type)
+    : mName(name),
+      mType(type) {
+}
+
+std::string TypedVar::name() const {
+    return mName;
+}
+
+const Type &TypedVar::type() const {
+    return *mType;
+}
+
 }  // namespace android
 
diff --git a/Method.h b/Method.h
index a13526e..a4e13d4 100644
--- a/Method.h
+++ b/Method.h
@@ -10,19 +10,7 @@
 
 struct Formatter;
 struct Type;
-
-struct TypedVar {
-    TypedVar(const char *name, Type *type);
-
-    std::string name() const;
-    const Type &type() const;
-
-private:
-    std::string mName;
-    Type *mType;
-
-    DISALLOW_COPY_AND_ASSIGN(TypedVar);
-};
+struct TypedVar;
 
 struct Method {
     Method(const char *name,
@@ -43,6 +31,19 @@
     DISALLOW_COPY_AND_ASSIGN(Method);
 };
 
+struct TypedVar {
+    TypedVar(const char *name, Type *type);
+
+    std::string name() const;
+    const Type &type() const;
+
+private:
+    std::string mName;
+    Type *mType;
+
+    DISALLOW_COPY_AND_ASSIGN(TypedVar);
+};
+
 }  // namespace android
 
 #endif  // METHOD_H_
diff --git a/NamedType.cpp b/NamedType.cpp
index 53c8c86..006bd61 100644
--- a/NamedType.cpp
+++ b/NamedType.cpp
@@ -2,12 +2,22 @@
 
 namespace android {
 
-NamedType::NamedType(const char *name)
-    : mName(name) {
+NamedType::NamedType() {}
+
+void NamedType::setLocalName(const std::string &localName) {
+    mLocalName = localName;
+}
+
+void NamedType::setFullName(const FQName &fullName) {
+    mFullName = fullName;
 }
 
 std::string NamedType::name() const {
-    return mName;
+    return mLocalName;
+}
+
+std::string NamedType::fullName() const {
+    return mLocalName; // XXX mFullName.string();
 }
 
 }  // namespace android
diff --git a/NamedType.h b/NamedType.h
index 8992609..78854b5 100644
--- a/NamedType.h
+++ b/NamedType.h
@@ -4,17 +4,24 @@
 
 #include "Type.h"
 
+#include "FQName.h"
+
 #include <string>
 
 namespace android {
 
 struct NamedType : public Type {
-    NamedType(const char *name);
+    NamedType();
+
+    void setLocalName(const std::string &localName);
+    void setFullName(const FQName &fullName);
 
     std::string name() const;
+    std::string fullName() const;
 
 private:
-    std::string mName;
+    std::string mLocalName;
+    FQName mFullName;
 
     DISALLOW_COPY_AND_ASSIGN(NamedType);
 };
diff --git a/Scope.cpp b/Scope.cpp
index 406c816..ee2b51c 100644
--- a/Scope.cpp
+++ b/Scope.cpp
@@ -6,20 +6,16 @@
 
 namespace android {
 
-Scope::Scope(const char *name)
-    : NamedType(name) {
-}
+Scope::Scope() {}
 
-bool Scope::addType(NamedType *type) {
-    std::string name = type->name();
-
-    if (mTypeIndexByName.indexOfKey(name) >= 0) {
+bool Scope::addType(const char *localName, NamedType *type) {
+    if (mTypeIndexByName.indexOfKey(localName) >= 0) {
         return false;
     }
 
     size_t index = mTypes.size();
     mTypes.push_back(type);
-    mTypeIndexByName.add(name, index);
+    mTypeIndexByName.add(localName, index);
 
     return true;
 }
diff --git a/Scope.h b/Scope.h
index cefcd48..d9a2a7b 100644
--- a/Scope.h
+++ b/Scope.h
@@ -14,9 +14,9 @@
 struct Interface;
 
 struct Scope : public NamedType {
-    Scope(const char *name);
+    Scope();
 
-    bool addType(NamedType *type);
+    bool addType(const char *localName, NamedType *type);
     Type *lookupType(const char *name) const;
 
     bool addConstant(Constant *constant);
diff --git a/TypeDef.cpp b/TypeDef.cpp
index 9d2a799..b4aff0c 100644
--- a/TypeDef.cpp
+++ b/TypeDef.cpp
@@ -4,8 +4,8 @@
 
 namespace android {
 
-TypeDef::TypeDef(const char *name, Type *type)
-    : NamedType(name),
+TypeDef::TypeDef(Type *type)
+    : NamedType(),
       mReferencedType(type) {
 }
 
diff --git a/TypeDef.h b/TypeDef.h
index 845b27c..00bc6a3 100644
--- a/TypeDef.h
+++ b/TypeDef.h
@@ -7,7 +7,7 @@
 namespace android {
 
 struct TypeDef : public NamedType {
-    TypeDef(const char *name, Type *type);
+    TypeDef(Type *type);
 
     const ScalarType *resolveToScalarType() const override;
 
diff --git a/hidl-gen_y.yy b/hidl-gen_y.yy
index b396edc..75a79fd 100644
--- a/hidl-gen_y.yy
+++ b/hidl-gen_y.yy
@@ -158,11 +158,11 @@
 body
     : INTERFACE IDENTIFIER opt_extends
       {
-          Interface *iface = new Interface($2, $3);
+          Interface *iface = new Interface($3);
 
           // Register interface immediately so it can be referenced inside
           // definition.
-          ast->scope()->addType(iface);
+          ast->addScopedType($2, iface);
 
           ast->enterScope(iface);
       }
@@ -200,8 +200,8 @@
 typedef_declaration
     : TYPEDEF type IDENTIFIER
       {
-          TypeDef *def = new TypeDef($3, $2);
-          ast->scope()->addType(def);
+          TypeDef *def = new TypeDef($2);
+          ast->addScopedType($3, def);
       }
     ;
 
@@ -257,7 +257,7 @@
 named_struct_or_union_declaration
     : struct_or_union_keyword IDENTIFIER
       {
-          CompoundType *container = new CompoundType($1, $2);
+          CompoundType *container = new CompoundType($1);
           ast->enterScope(container);
       }
       struct_or_union_body
@@ -266,14 +266,14 @@
 
           container->setFields($4);
           ast->leaveScope();
-          ast->scope()->addType(container);
+          ast->addScopedType($2, container);
       }
     ;
 
 struct_or_union_declaration
     : struct_or_union_keyword optIdentifier
       {
-          CompoundType *container = new CompoundType($1, $2);
+          CompoundType *container = new CompoundType($1);
           ast->enterScope(container);
       }
       struct_or_union_body
@@ -282,7 +282,7 @@
 
           container->setFields($4);
           ast->leaveScope();
-          ast->scope()->addType(container);
+          ast->addScopedType($2, container);
 
           $$ = new RefType(container);
       }
@@ -323,23 +323,23 @@
 named_enum_declaration
     : ENUM IDENTIFIER opt_storage_type '{' enum_values opt_comma '}'
       {
-          EnumType *enumType = new EnumType($2, $5, $3);
-          ast->scope()->addType(enumType);
+          EnumType *enumType = new EnumType($5, $3);
+          ast->addScopedType($2, enumType);
       }
     ;
 
 enum_declaration
     : ENUM '{' enum_values opt_comma '}'
       {
-          EnumType *enumType = new EnumType(NULL /* name */, $3);
-          ast->scope()->addType(enumType);
+          EnumType *enumType = new EnumType($3);
+          ast->addScopedType(NULL /* localName */, enumType);
 
           $$ = new RefType(enumType);
       }
     | ENUM IDENTIFIER opt_storage_type '{' enum_values opt_comma '}'
       {
-          EnumType *enumType = new EnumType($2, $5, $3);
-          ast->scope()->addType(enumType);
+          EnumType *enumType = new EnumType($5, $3);
+          ast->addScopedType($2, enumType);
 
           $$ = new RefType(enumType);
       }