Refactor AidlVisitor so that it no longer responsible for traversing
Visit() methods now return a bool which controls whether or not the
traversal should be continued down to its children or not.
A new trait AidlTraversable is introduced. The type is expected to be
implemented by an AST node which needs to be traversable. The following
three methods need to be implemented:
* TraverseChildren: calls the given traverse function on each of the
traversable children, if there is any.
* DispatchVisit: calls the corresponding Visit method
Traversing the AST is done by any functor that accepts AidlTraversable.
Inside the functor, the various traversing strategies (Top-Down,
Bottom-up, etc.) and stateful options (pushing/popping the diagnostics
options which will be the follow-up change) can be implemented.
Bug: N/A
Test: aidl_unittests
Change-Id: I27e67f53429641b6cdb5727929b1bff77d4d4163
diff --git a/aidl_language.h b/aidl_language.h
index dfc9d1f..55de28b 100644
--- a/aidl_language.h
+++ b/aidl_language.h
@@ -88,38 +88,23 @@
class AidlMethod;
class AidlArgument;
+// Interface for visitors that can traverse AidlTraversable nodes. The contract is that Visit()
+// method returns a bool which controls whether or not the traversal should be continued down to its
+// children.
class AidlVisitor {
public:
virtual ~AidlVisitor() = default;
- virtual void VisitDocument(const AidlDocument& d) = 0;
- virtual void VisitInterface(const AidlInterface& i) = 0;
- virtual void VisitUnstructuredParcelable(const AidlParcelable& p) = 0;
- virtual void VisitStructuredParcelable(const AidlStructuredParcelable& p) = 0;
- virtual void VisitUnion(const AidlUnionDecl& u) = 0;
- virtual void VisitEnum(const AidlEnumDeclaration& e) = 0;
- virtual void VisitEnumerator(const AidlEnumerator& e) = 0;
- virtual void VisitMethod(const AidlMethod& m) = 0;
- virtual void VisitVariable(const AidlVariableDeclaration& v) = 0;
- virtual void VisitConstant(const AidlConstantDeclaration& c) = 0;
- virtual void VisitArgument(const AidlArgument& a) = 0;
-};
-
-// Provides default implementation which visits child nodes.
-// In a derived class, call super method to visit chid nodes.
-// Calling super method first visits nodes in bottom-up way.
-class AidlVisitAll : public AidlVisitor {
- public:
- void VisitDocument(const AidlDocument& d) override;
- void VisitInterface(const AidlInterface& i) override;
- void VisitUnstructuredParcelable(const AidlParcelable& p) override;
- void VisitStructuredParcelable(const AidlStructuredParcelable& p) override;
- void VisitUnion(const AidlUnionDecl& u) override;
- void VisitEnum(const AidlEnumDeclaration& e) override;
- void VisitEnumerator(const AidlEnumerator& e) override;
- void VisitMethod(const AidlMethod& m) override;
- void VisitVariable(const AidlVariableDeclaration& v) override;
- void VisitConstant(const AidlConstantDeclaration& c) override;
- void VisitArgument(const AidlArgument& a) override;
+ virtual bool Visit(const AidlDocument&) { return true; }
+ virtual bool Visit(const AidlInterface&) { return true; }
+ virtual bool Visit(const AidlParcelable&) { return true; }
+ virtual bool Visit(const AidlStructuredParcelable&) { return true; }
+ virtual bool Visit(const AidlUnionDecl&) { return true; }
+ virtual bool Visit(const AidlEnumDeclaration&) { return true; }
+ virtual bool Visit(const AidlEnumerator&) { return true; }
+ virtual bool Visit(const AidlMethod&) { return true; }
+ virtual bool Visit(const AidlVariableDeclaration&) { return true; }
+ virtual bool Visit(const AidlConstantDeclaration&) { return true; }
+ virtual bool Visit(const AidlArgument&) { return true; }
};
// Anything that is locatable in a .aidl file.
@@ -146,6 +131,15 @@
const AidlLocation location_;
};
+// Anything that is traversable by the AidlVisitor
+class AidlTraversable {
+ public:
+ virtual ~AidlTraversable() = default;
+
+ virtual void TraverseChildren(std::function<void(const AidlTraversable&)> traverse) const = 0;
+ virtual bool DispatchVisit(AidlVisitor&) const = 0;
+};
+
// unique_ptr<AidlTypeSpecifier> for type arugment,
// std::string for type parameter(T, U, and so on).
template <typename T>
@@ -396,7 +390,7 @@
class AidlConstantDeclaration;
class AidlVariableDeclaration;
-class AidlMember : public AidlNode {
+class AidlMember : public AidlNode, public AidlTraversable {
public:
AidlMember(const AidlLocation& location);
virtual ~AidlMember() = default;
@@ -423,7 +417,8 @@
const_cast<const AidlMember*>(this)->AsVariableDeclaration());
}
- virtual void Accept(AidlVisitor& vis) const = 0;
+ void TraverseChildren(std::function<void(const AidlTraversable&)> traverse) const = 0;
+ bool DispatchVisit(AidlVisitor& v) const = 0;
};
// TODO: This class is used for method arguments and also parcelable fields,
@@ -457,7 +452,6 @@
AidlTypeSpecifier* GetMutableType() { return type_.get(); }
- void Accept(AidlVisitor& vis) const override { vis.VisitVariable(*this); }
bool CheckValid(const AidlTypenames& typenames) const;
// ToString is for dumping AIDL.
@@ -474,6 +468,11 @@
std::string ValueString(const ConstantValueDecorator& decorator) const;
+ void TraverseChildren(std::function<void(const AidlTraversable&)>) const override {
+ // no children to visit
+ }
+ bool DispatchVisit(AidlVisitor& v) const override { return v.Visit(*this); }
+
private:
std::unique_ptr<AidlTypeSpecifier> type_;
std::string name_;
@@ -507,7 +506,11 @@
// This is "direction annotations type name".
// e.g) "in @utf8InCpp String[] names"
std::string ToString() const;
- void Accept(AidlVisitor& vis) const override { vis.VisitArgument(*this); }
+
+ void TraverseChildren(std::function<void(const AidlTraversable&)>) const override {
+ // no children to visit
+ }
+ bool DispatchVisit(AidlVisitor& v) const override { return v.Visit(*this); }
private:
Direction direction_;
@@ -741,7 +744,6 @@
AidlTypeSpecifier* GetMutableType() { return type_.get(); }
const string& GetName() const { return name_; }
const AidlConstantValue& GetValue() const { return *value_; }
- void Accept(AidlVisitor& vis) const override { vis.VisitConstant(*this); }
bool CheckValid(const AidlTypenames& typenames) const;
// ToString is for dumping AIDL.
@@ -762,6 +764,11 @@
const AidlConstantDeclaration* AsConstantDeclaration() const override { return this; }
+ void TraverseChildren(std::function<void(const AidlTraversable&)>) const override {
+ // no children to traverse
+ }
+ bool DispatchVisit(AidlVisitor& v) const override { return v.Visit(*this); }
+
private:
const unique_ptr<AidlTypeSpecifier> type_;
const string name_;
@@ -824,7 +831,12 @@
// e.g) "foo(int, String)"
std::string Signature() const;
- void Accept(AidlVisitor& vis) const override { vis.VisitMethod(*this); }
+ void TraverseChildren(std::function<void(const AidlTraversable&)> traverse) const override {
+ for (const auto& a : GetArguments()) {
+ traverse(*a);
+ }
+ }
+ bool DispatchVisit(AidlVisitor& v) const override { return v.Visit(*this); }
private:
bool oneway_;
@@ -847,7 +859,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 AidlTraversable {
public:
AidlDefinedType(const AidlLocation& location, const std::string& name,
const std::string& comments, const std::string& package,
@@ -880,7 +892,6 @@
virtual const AidlInterface* AsInterface() const { return nullptr; }
virtual const AidlParameterizable<std::string>* AsParameterizable() const { return nullptr; }
virtual bool CheckValid(const AidlTypenames& typenames) const;
- virtual void Accept(AidlVisitor& vis) const = 0;
virtual bool LanguageSpecificCheckValid(const AidlTypenames& typenames,
Options::Language lang) const = 0;
AidlStructuredParcelable* AsStructuredParcelable() {
@@ -930,6 +941,9 @@
void AddMethod(std::unique_ptr<AidlMethod> method) { methods_.push_back(std::move(method)); }
const std::vector<const AidlMember*>& GetMembers() const { return members_; }
+ void TraverseChildren(std::function<void(const AidlTraversable&)>) const = 0;
+ bool DispatchVisit(AidlVisitor& v) const = 0;
+
protected:
// utility for subclasses with getter names
bool CheckValidForGetterNames() const;
@@ -965,9 +979,6 @@
std::set<AidlAnnotation::Type> GetSupportedAnnotations() const override;
bool CheckValid(const AidlTypenames& typenames) const override;
- void Accept(AidlVisitor& vis) const override {
- if (AsUnstructuredParcelable()) vis.VisitUnstructuredParcelable(*this);
- }
bool LanguageSpecificCheckValid(const AidlTypenames& typenames,
Options::Language lang) const override;
const AidlParcelable* AsParcelable() const override { return this; }
@@ -977,6 +988,13 @@
void Dump(CodeWriter* writer) const override;
+ void TraverseChildren(std::function<void(const AidlTraversable&)> traverse) const override {
+ for (const auto c : GetMembers()) {
+ traverse(*c);
+ }
+ }
+ bool DispatchVisit(AidlVisitor& v) const override { return v.Visit(*this); }
+
private:
std::string cpp_header_;
};
@@ -1001,13 +1019,19 @@
void Dump(CodeWriter* writer) const override;
std::set<AidlAnnotation::Type> GetSupportedAnnotations() const override;
- void Accept(AidlVisitor& vis) const override { vis.VisitStructuredParcelable(*this); }
bool CheckValid(const AidlTypenames& typenames) const override;
bool LanguageSpecificCheckValid(const AidlTypenames& typenames,
Options::Language lang) const override;
+
+ void TraverseChildren(std::function<void(const AidlTraversable&)> traverse) const override {
+ for (const auto c : GetMembers()) {
+ traverse(*c);
+ }
+ }
+ bool DispatchVisit(AidlVisitor& v) const override { return v.Visit(*this); }
};
-class AidlEnumerator : public AidlNode {
+class AidlEnumerator : public AidlNode, public AidlTraversable {
public:
AidlEnumerator(const AidlLocation& location, const std::string& name, AidlConstantValue* value,
const std::string& comments);
@@ -1022,7 +1046,6 @@
const std::string& GetName() const { return name_; }
AidlConstantValue* GetValue() const { return value_.get(); }
const std::string& GetComments() const { return comments_; }
- void Accept(AidlVisitor& vis) const { vis.VisitEnumerator(*this); }
bool CheckValid(const AidlTypeSpecifier& enum_backing_type) const;
string ValueString(const AidlTypeSpecifier& backing_type,
@@ -1031,6 +1054,11 @@
void SetValue(std::unique_ptr<AidlConstantValue> value) { value_ = std::move(value); }
bool IsValueUserSpecified() const { return value_user_specified_; }
+ void TraverseChildren(std::function<void(const AidlTraversable&)>) const override {
+ // no children to traverse
+ }
+ bool DispatchVisit(AidlVisitor& v) const override { return v.Visit(*this); }
+
private:
const std::string name_;
unique_ptr<AidlConstantValue> value_;
@@ -1057,7 +1085,6 @@
return enumerators_;
}
std::set<AidlAnnotation::Type> GetSupportedAnnotations() const override;
- void Accept(AidlVisitor& vis) const override { vis.VisitEnum(*this); }
bool CheckValid(const AidlTypenames& typenames) const override;
bool LanguageSpecificCheckValid(const AidlTypenames& /*typenames*/,
Options::Language) const override {
@@ -1068,6 +1095,13 @@
const AidlEnumDeclaration* AsEnumDeclaration() const override { return this; }
+ void TraverseChildren(std::function<void(const AidlTraversable&)> traverse) const override {
+ for (const auto& c : GetEnumerators()) {
+ traverse(*c);
+ }
+ }
+ bool DispatchVisit(AidlVisitor& v) const override { return v.Visit(*this); }
+
private:
const std::string name_;
@@ -1091,7 +1125,6 @@
std::set<AidlAnnotation::Type> GetSupportedAnnotations() const override;
const AidlNode& AsAidlNode() const override { return *this; }
- void Accept(AidlVisitor& vis) const override { vis.VisitUnion(*this); }
bool CheckValid(const AidlTypenames& typenames) const override;
bool LanguageSpecificCheckValid(const AidlTypenames& typenames,
Options::Language lang) const override;
@@ -1099,6 +1132,13 @@
void Dump(CodeWriter* writer) const override;
const AidlUnionDecl* AsUnionDeclaration() const override { return this; }
+
+ void TraverseChildren(std::function<void(const AidlTraversable&)> traverse) const override {
+ for (const auto c : GetMembers()) {
+ traverse(*c);
+ }
+ }
+ bool DispatchVisit(AidlVisitor& v) const override { return v.Visit(*this); }
};
class AidlInterface final : public AidlDefinedType {
@@ -1120,12 +1160,18 @@
void Dump(CodeWriter* writer) const override;
std::set<AidlAnnotation::Type> GetSupportedAnnotations() const override;
- void Accept(AidlVisitor& vis) const override { vis.VisitInterface(*this); }
bool CheckValid(const AidlTypenames& typenames) const override;
bool LanguageSpecificCheckValid(const AidlTypenames& typenames,
Options::Language lang) const override;
std::string GetDescriptor() const;
+
+ void TraverseChildren(std::function<void(const AidlTraversable&)> traverse) const override {
+ for (const auto c : GetMembers()) {
+ traverse(*c);
+ }
+ }
+ bool DispatchVisit(AidlVisitor& v) const override { return v.Visit(*this); }
};
class AidlImport : public AidlNode {
@@ -1146,7 +1192,7 @@
};
// AidlDocument models an AIDL file
-class AidlDocument : public AidlNode {
+class AidlDocument : public AidlNode, public AidlTraversable {
public:
AidlDocument(const AidlLocation& location, std::vector<std::unique_ptr<AidlImport>>& imports,
std::vector<std::unique_ptr<AidlDefinedType>>&& defined_types)
@@ -1161,13 +1207,19 @@
AidlDocument& operator=(const AidlDocument&) = delete;
AidlDocument& operator=(AidlDocument&&) = delete;
- void Accept(AidlVisitor& vis) const { vis.VisitDocument(*this); }
std::optional<std::string> ResolveName(const std::string& unresolved_type) const;
const std::vector<std::unique_ptr<AidlImport>>& Imports() const { return imports_; }
const std::vector<std::unique_ptr<AidlDefinedType>>& DefinedTypes() const {
return defined_types_;
}
+ void TraverseChildren(std::function<void(const AidlTraversable&)> traverse) const override {
+ for (const auto& t : DefinedTypes()) {
+ traverse(*t);
+ }
+ }
+ bool DispatchVisit(AidlVisitor& v) const override { return v.Visit(*this); }
+
private:
const std::vector<std::unique_ptr<AidlImport>> imports_;
const std::vector<std::unique_ptr<AidlDefinedType>> defined_types_;
@@ -1180,4 +1232,4 @@
return std::nullopt;
}
return it->second->EvaluatedValue<T>();
-}
\ No newline at end of file
+}