Run diagnostics in a separate visitor
CheckValid() is already quite complicated and adding more to the method
seems not to be scalable.
Bug: 168028537
Test: aidl_unittests
Change-Id: I41a11ce028d8b8f018e80e7203b0d6a955d3768b
diff --git a/aidl_language.h b/aidl_language.h
index 112c6dc..d36cec1 100644
--- a/aidl_language.h
+++ b/aidl_language.h
@@ -92,6 +92,52 @@
std::ostream& operator<<(std::ostream& os, const AidlLocation& l);
+class AidlDocument;
+class AidlInterface;
+class AidlParcelable;
+class AidlStructuredParcelable;
+class AidlEnumDeclaration;
+class AidlUnionDecl;
+class AidlVariableDeclaration;
+class AidlConstantDeclaration;
+class AidlEnumerator;
+class AidlMethod;
+class AidlArgument;
+
+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;
+};
+
// Anything that is locatable in a .aidl file.
class AidlNode {
public:
@@ -392,6 +438,8 @@
return const_cast<AidlVariableDeclaration*>(
const_cast<const AidlMember*>(this)->AsVariableDeclaration());
}
+
+ virtual void Accept(AidlVisitor& vis) const = 0;
};
// TODO: This class is used for method arguments and also parcelable fields,
@@ -425,6 +473,7 @@
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 +523,7 @@
// 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); }
private:
Direction direction_;
@@ -677,6 +727,7 @@
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.
@@ -759,6 +810,8 @@
// e.g) "foo(int, String)"
std::string Signature() const;
+ void Accept(AidlVisitor& vis) const override { vis.VisitMethod(*this); }
+
private:
bool oneway_;
std::string comments_;
@@ -812,7 +865,8 @@
virtual const AidlUnionDecl* AsUnionDeclaration() const { return nullptr; }
virtual const AidlInterface* AsInterface() const { return nullptr; }
virtual const AidlParameterizable<std::string>* AsParameterizable() const { return nullptr; }
- virtual bool CheckValid(const AidlTypenames& typenames, DiagnosticsContext& context) const;
+ 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() {
@@ -896,7 +950,10 @@
std::string GetCppHeader() const { return cpp_header_; }
std::set<AidlAnnotation::Type> GetSupportedAnnotations() const override;
- bool CheckValid(const AidlTypenames& typenames, DiagnosticsContext& context) 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; }
@@ -930,7 +987,8 @@
void Dump(CodeWriter* writer) const override;
std::set<AidlAnnotation::Type> GetSupportedAnnotations() const override;
- bool CheckValid(const AidlTypenames& typenames, DiagnosticsContext& context) 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;
};
@@ -950,6 +1008,7 @@
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,
@@ -984,7 +1043,8 @@
return enumerators_;
}
std::set<AidlAnnotation::Type> GetSupportedAnnotations() const override;
- bool CheckValid(const AidlTypenames& typenames, DiagnosticsContext& context) 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 {
return true;
@@ -1017,8 +1077,8 @@
std::set<AidlAnnotation::Type> GetSupportedAnnotations() const override;
const AidlNode& AsAidlNode() const override { return *this; }
-
- bool CheckValid(const AidlTypenames& typenames, DiagnosticsContext& context) const override;
+ 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;
std::string GetPreprocessDeclarationName() const override { return "union"; }
@@ -1046,7 +1106,8 @@
void Dump(CodeWriter* writer) const override;
std::set<AidlAnnotation::Type> GetSupportedAnnotations() const override;
- bool CheckValid(const AidlTypenames& typenames, DiagnosticsContext& context) 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;
@@ -1086,7 +1147,7 @@
AidlDocument& operator=(const AidlDocument&) = delete;
AidlDocument& operator=(AidlDocument&&) = delete;
- bool CheckValid(const AidlTypenames& typenames, DiagnosticsContext& diag) const;
+ 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 {