Refactor: type resolution done in Scope
Type resolution should be based on "scope". Previously, the compiler
didn't consider its scope and just look it up in the known types. This
caused unnessary complication regarding "preprocessed types" such as
"prefer import over preprocssed".
Now "name resolution" is done in its scope and AidlTypenames don't have
to guess what type it is. (It just looks up fully-qualified names.)
For legacy reasons, preprocessed unstructured parcelable types can still
be resolved with unqualified names.
Bug: 182508839
Test: aidl_unittests
Change-Id: I65b6e2e01bd354b3f0a4027d039a8ef3679ebe6f
diff --git a/aidl_language.h b/aidl_language.h
index 77c8d0a..28f94ee 100644
--- a/aidl_language.h
+++ b/aidl_language.h
@@ -121,6 +121,20 @@
virtual void Visit(const AidlPackage&) {}
};
+class AidlScope {
+ public:
+ virtual ~AidlScope() = default;
+ virtual std::string ResolveName(const std::string& name) const = 0;
+ void SetEnclosingScope(const AidlScope* enclosing) {
+ AIDL_FATAL_IF(enclosing_, AIDL_LOCATION_HERE) << "SetEnclosingScope can be set only once.";
+ enclosing_ = enclosing;
+ }
+ const AidlScope* GetEnclosingScope() const { return enclosing_; }
+
+ private:
+ const AidlScope* enclosing_ = nullptr;
+};
+
// Anything that is locatable in a .aidl file.
class AidlNode {
public:
@@ -402,7 +416,7 @@
// Resolve the base type name to a fully-qualified name. Return false if the
// resolution fails.
- bool Resolve(const AidlTypenames& typenames);
+ bool Resolve(const AidlTypenames& typenames, const AidlScope* scope);
bool CheckValid(const AidlTypenames& typenames) const;
bool LanguageSpecificCheckValid(const AidlTypenames& typenames, Options::Language lang) const;
@@ -890,7 +904,7 @@
// AidlDefinedType represents either an interface, parcelable, or enum that is
// defined in the source file.
-class AidlDefinedType : public AidlAnnotatable {
+class AidlDefinedType : public AidlAnnotatable, public AidlScope {
public:
AidlDefinedType(const AidlLocation& location, const std::string& name, const Comments& comments,
const std::string& package, std::vector<std::unique_ptr<AidlMember>>* members);
@@ -904,6 +918,8 @@
const std::string& GetName() const { return name_; };
+ std::string ResolveName(const std::string& name) const override;
+
/* dot joined package, example: "android.package.foo" */
std::string GetPackage() const { return package_; }
/* dot joined package and name, example: "android.package.foo.IBar" */
@@ -1202,14 +1218,11 @@
};
// AidlDocument models an AIDL file
-class AidlDocument : public AidlCommentable {
+class AidlDocument : public AidlCommentable, public AidlScope {
public:
AidlDocument(const AidlLocation& location, const Comments& comments,
std::vector<std::unique_ptr<AidlImport>> imports,
- std::vector<std::unique_ptr<AidlDefinedType>> defined_types)
- : AidlCommentable(location, comments),
- imports_(std::move(imports)),
- defined_types_(std::move(defined_types)) {}
+ std::vector<std::unique_ptr<AidlDefinedType>> defined_types);
~AidlDocument() = default;
// non-copyable, non-movable
@@ -1218,7 +1231,7 @@
AidlDocument& operator=(const AidlDocument&) = delete;
AidlDocument& operator=(AidlDocument&&) = delete;
- std::optional<std::string> ResolveName(const std::string& unresolved_type) const;
+ std::string ResolveName(const std::string& name) const override;
const std::vector<std::unique_ptr<AidlImport>>& Imports() const { return imports_; }
const std::vector<std::unique_ptr<AidlDefinedType>>& DefinedTypes() const {
return defined_types_;