Remove AidlImport

AidlImport doesn't need to be an AidlNode.

Fixes: 203135225
Test: atest aidl_unittests aidl_integration_test
Change-Id: I2fad5e5d3e7c5c785ccde1a8279228aba4aabb03
diff --git a/aidl.cpp b/aidl.cpp
index 26c485c..9d43de2 100644
--- a/aidl.cpp
+++ b/aidl.cpp
@@ -423,15 +423,15 @@
   vector<string> import_paths;
   ImportResolver import_resolver{io_delegate, input_file_name, options.ImportDirs()};
   for (const auto& import : document->Imports()) {
-    if (typenames->IsIgnorableImport(import->GetNeededClass())) {
+    if (typenames->IsIgnorableImport(import)) {
       // There are places in the Android tree where an import doesn't resolve,
       // but we'll pick the type up through the preprocessed types.
       // This seems like an error, but legacy support demands we support it...
       continue;
     }
-    string import_path = import_resolver.FindImportFile(import->GetNeededClass());
+    string import_path = import_resolver.FindImportFile(import);
     if (import_path.empty()) {
-      AIDL_ERROR(input_file_name) << "Couldn't find import for class " << import->GetNeededClass();
+      AIDL_ERROR(input_file_name) << "Couldn't find import for class " << import;
       err = AidlError::BAD_IMPORT;
       continue;
     }
@@ -440,8 +440,7 @@
 
     auto imported_doc = Parser::Parse(import_path, io_delegate, *typenames);
     if (imported_doc == nullptr) {
-      AIDL_ERROR(import_path) << "error while importing " << import_path << " for "
-                              << import->GetNeededClass();
+      AIDL_ERROR(import_path) << "error while importing " << import_path << " for " << import;
       err = AidlError::BAD_IMPORT;
       continue;
     }
diff --git a/aidl_language.cpp b/aidl_language.cpp
index 441db23..d924433 100644
--- a/aidl_language.cpp
+++ b/aidl_language.cpp
@@ -1594,12 +1594,8 @@
   return GetCanonicalName();
 }
 
-AidlImport::AidlImport(const AidlLocation& location, const std::string& needed_class,
-                       const Comments& comments)
-    : AidlNode(location, comments), needed_class_(needed_class) {}
-
 AidlDocument::AidlDocument(const AidlLocation& location, const Comments& comments,
-                           std::vector<std::unique_ptr<AidlImport>> imports,
+                           std::set<string> imports,
                            std::vector<std::unique_ptr<AidlDefinedType>> defined_types,
                            bool is_preprocessed)
     : AidlCommentable(location, comments),
@@ -1629,8 +1625,8 @@
   const std::string nested_type = (first_dot == std::string::npos) ? "" : name.substr(first_dot);
 
   for (const auto& import : Imports()) {
-    if (import->SimpleName() == class_name) {
-      return import->GetNeededClass() + nested_type;
+    if (SimpleName(import) == class_name) {
+      return import + nested_type;
     }
   }
 
diff --git a/aidl_language.h b/aidl_language.h
index b6cc448..d790e05 100644
--- a/aidl_language.h
+++ b/aidl_language.h
@@ -81,7 +81,6 @@
 bool ParseFloating(std::string_view sv, float* parsed);
 
 class AidlDocument;
-class AidlImport;
 class AidlInterface;
 class AidlParcelable;
 class AidlStructuredParcelable;
@@ -119,7 +118,6 @@
   virtual void Visit(const AidlUnaryConstExpression&) {}
   virtual void Visit(const AidlBinaryConstExpression&) {}
   virtual void Visit(const AidlAnnotation&) {}
-  virtual void Visit(const AidlImport&) {}
 };
 
 class AidlScope {
@@ -1163,32 +1161,15 @@
   void DispatchVisit(AidlVisitor& v) const override { v.Visit(*this); }
 };
 
-class AidlImport : public AidlNode {
- public:
-  AidlImport(const AidlLocation& location, const std::string& needed_class,
-             const Comments& comments);
-  virtual ~AidlImport() = default;
-
-  // non-copyable, non-movable
-  AidlImport(const AidlImport&) = delete;
-  AidlImport(AidlImport&&) = delete;
-  AidlImport& operator=(const AidlImport&) = delete;
-  AidlImport& operator=(AidlImport&&) = delete;
-
-  const std::string& GetNeededClass() const { return needed_class_; }
-  std::string SimpleName() const { return needed_class_.substr(needed_class_.rfind('.') + 1); }
-  void TraverseChildren(std::function<void(const AidlNode&)>) const {}
-  void DispatchVisit(AidlVisitor& v) const { v.Visit(*this); }
-
- private:
-  std::string needed_class_;
-};
+inline std::string SimpleName(const std::string& qualified_name) {
+  return qualified_name.substr(qualified_name.rfind('.') + 1);
+}
 
 // AidlDocument models an AIDL file
 class AidlDocument : public AidlCommentable, public AidlScope {
  public:
   AidlDocument(const AidlLocation& location, const Comments& comments,
-               std::vector<std::unique_ptr<AidlImport>> imports,
+               std::set<std::string> imports,
                std::vector<std::unique_ptr<AidlDefinedType>> defined_types, bool is_preprocessed);
   ~AidlDocument() = default;
 
@@ -1199,16 +1180,13 @@
   AidlDocument& operator=(AidlDocument&&) = delete;
 
   std::string ResolveName(const std::string& name) const override;
-  const std::vector<std::unique_ptr<AidlImport>>& Imports() const { return imports_; }
+  const std::set<std::string>& Imports() const { return imports_; }
   const std::vector<std::unique_ptr<AidlDefinedType>>& DefinedTypes() const {
     return defined_types_;
   }
   bool IsPreprocessed() const { return is_preprocessed_; }
 
   void TraverseChildren(std::function<void(const AidlNode&)> traverse) const override {
-    for (const auto& i : Imports()) {
-      traverse(*i);
-    }
     for (const auto& t : DefinedTypes()) {
       traverse(*t);
     }
@@ -1216,7 +1194,7 @@
   void DispatchVisit(AidlVisitor& v) const override { v.Visit(*this); }
 
  private:
-  const std::vector<std::unique_ptr<AidlImport>> imports_;
+  const std::set<std::string> imports_;
   const std::vector<std::unique_ptr<AidlDefinedType>> defined_types_;
   bool is_preprocessed_;
 };
diff --git a/aidl_language_y.yy b/aidl_language_y.yy
index 5ed854d..cea569d 100644
--- a/aidl_language_y.yy
+++ b/aidl_language_y.yy
@@ -71,6 +71,7 @@
     AidlToken* token;
     char character;
     std::string *str;
+    std::vector<std::unique_ptr<AidlToken>> *token_list;
     AidlAnnotation* annotation;
     AidlAnnotationParameter* param;
     std::map<std::string, std::shared_ptr<AidlConstantValue>>* param_list;
@@ -90,8 +91,6 @@
     AidlDefinedType* declaration;
     std::vector<std::unique_ptr<AidlTypeSpecifier>>* type_args;
     std::vector<std::string>* type_params;
-    std::vector<std::unique_ptr<AidlImport>>* imports;
-    AidlImport* import;
     std::vector<std::unique_ptr<AidlDefinedType>>* declarations;
 }
 
@@ -175,10 +174,9 @@
 %type<const_expr> const_expr
 %type<constant_value_list> constant_value_list
 %type<constant_value_list> constant_value_non_empty_list
-%type<imports> imports
-%type<import> import
+%type<token_list> imports
 %type<declarations> decls
-%type<token> identifier error qualified_name optional_package
+%type<token> import identifier error qualified_name optional_package
 
 %%
 
@@ -190,7 +188,12 @@
     } else if (!$2->empty()) {
       comments = $2->front()->GetComments();
     }
-    ps->MakeDocument(loc(@1), comments, std::move(*$2), std::move(*$3));
+    // dedup imports
+    std::set<std::string> imports;
+    for (const auto& import : *$2) {
+      imports.insert(import->GetText());
+    }
+    ps->MakeDocument(loc(@1), comments, std::move(imports), std::move(*$3));
     delete $1;
     delete $2;
     delete $3;
@@ -219,26 +222,17 @@
  ;
 
 imports
- : { $$ = new std::vector<std::unique_ptr<AidlImport>>(); }
+ : { $$ = new std::vector<std::unique_ptr<AidlToken>>(); }
  | imports import
   {
     $$ = $1;
-    // dedup while parsing
-    auto it = std::find_if($$->begin(), $$->end(), [&](const auto& i) {
-      return $2->GetNeededClass() == i->GetNeededClass();
-    });
-    if (it == $$->end()) {
-      $$->emplace_back($2);
-    } else {
-      // remove duplicate node
-      $2->MarkVisited();
-      delete $2;
-    }
+    $$->emplace_back($2);
   }
 
 import
  : IMPORT qualified_name ';' {
-    $$ = new AidlImport(loc(@2), $2->GetText(), $1->GetComments());
+    // carry the comments before "import" token
+    $$ = new AidlToken($2->GetText(), $1->GetComments());
     delete $1;
     delete $2;
   };
diff --git a/diagnostics.cpp b/diagnostics.cpp
index bc7973a..13f918f 100644
--- a/diagnostics.cpp
+++ b/diagnostics.cpp
@@ -262,8 +262,7 @@
   void Visit(const AidlDocument& doc) override {
     auto collide_with_decls = [&](const auto& import) {
       for (const auto& type : doc.DefinedTypes()) {
-        if (type->GetCanonicalName() != import->GetNeededClass() &&
-            type->GetName() == import->SimpleName()) {
+        if (type->GetCanonicalName() != import && type->GetName() == SimpleName(import)) {
           return true;
         }
       }
@@ -273,13 +272,13 @@
     std::set<std::string> imported_names;
     for (const auto& import : doc.Imports()) {
       if (collide_with_decls(import)) {
-        diag.Report(import->GetLocation(), DiagnosticID::unique_import)
-            << import->SimpleName() << " is already defined in this file.";
+        diag.Report(doc.GetLocation(), DiagnosticID::unique_import)
+            << SimpleName(import) << " is already defined in this file.";
       }
-      auto [_, inserted] = imported_names.insert(import->SimpleName());
+      auto [_, inserted] = imported_names.insert(SimpleName(import));
       if (!inserted) {
-        diag.Report(import->GetLocation(), DiagnosticID::unique_import)
-            << import->SimpleName() << " is already imported.";
+        diag.Report(doc.GetLocation(), DiagnosticID::unique_import)
+            << SimpleName(import) << " is already imported.";
       }
     }
   }
diff --git a/parser.cpp b/parser.cpp
index a34a52d..0c2677a 100644
--- a/parser.cpp
+++ b/parser.cpp
@@ -310,7 +310,7 @@
 }
 
 void Parser::MakeDocument(const AidlLocation& location, const Comments& comments,
-                          std::vector<std::unique_ptr<AidlImport>> imports,
+                          std::set<std::string> imports,
                           std::vector<std::unique_ptr<AidlDefinedType>> defined_types) {
   AIDL_FATAL_IF(document_.get(), location);
   document_ = std::make_unique<AidlDocument>(location, comments, std::move(imports),
diff --git a/parser.h b/parser.h
index be4b7c6..e497912 100644
--- a/parser.h
+++ b/parser.h
@@ -92,7 +92,7 @@
   const std::string& Package() const { return package_; }
 
   void MakeDocument(const AidlLocation& location, const Comments& comments,
-                    std::vector<std::unique_ptr<AidlImport>> imports,
+                    std::set<std::string> imports,
                     std::vector<std::unique_ptr<AidlDefinedType>> defined_types);
 
  private: