Allow struct, union and enum type declarations to be annotated.
Change-Id: Idce594b47c324d8420638e2e8853da3c99150672
Bug: 31800672
Test: hidl_test, hidl_test_java
diff --git a/AST.cpp b/AST.cpp
index c2bfc68..555f084 100644
--- a/AST.cpp
+++ b/AST.cpp
@@ -82,6 +82,10 @@
return mRootScope->containsSingleInterface(ifaceName);
}
+bool AST::containsInterfaces() const {
+ return mRootScope->containsInterfaces();
+}
+
bool AST::addImport(const char *import) {
FQName fqName(import);
CHECK(fqName.isValid());
diff --git a/AST.h b/AST.h
index 2d64972..4f1d373 100644
--- a/AST.h
+++ b/AST.h
@@ -48,6 +48,7 @@
// package and version really.
FQName package() const;
bool isInterface(std::string *ifaceName) const;
+ bool containsInterfaces() const;
void enterScope(Scope *container);
void leaveScope();
diff --git a/Coordinator.cpp b/Coordinator.cpp
index a7f0795..2e17b61 100644
--- a/Coordinator.cpp
+++ b/Coordinator.cpp
@@ -127,6 +127,13 @@
fqName.name().c_str());
err = UNKNOWN_ERROR;
+ } else if (ast->containsInterfaces()) {
+ fprintf(stderr,
+ "ERROR: types.hal file at '%s' declares at least one "
+ "interface type.\n",
+ path.c_str());
+
+ err = UNKNOWN_ERROR;
}
}
diff --git a/Interface.cpp b/Interface.cpp
index a5d3c9b..ba5ea8c 100644
--- a/Interface.cpp
+++ b/Interface.cpp
@@ -24,12 +24,9 @@
namespace android {
-Interface::Interface(
- const char *localName, Interface *super,
- std::vector<Annotation *> *annotations)
+Interface::Interface(const char *localName, Interface *super)
: Scope(localName),
mSuperType(super),
- mAnnotations(annotations),
mIsJavaCompatibleInProgress(false) {
}
@@ -53,10 +50,6 @@
return mMethods;
}
-const std::vector<Annotation *> &Interface::annotations() const {
- return *mAnnotations;
-}
-
std::string Interface::getBaseName() const {
return fqName().getInterfaceBaseName();
}
diff --git a/Interface.h b/Interface.h
index 0f12688..1c793e7 100644
--- a/Interface.h
+++ b/Interface.h
@@ -20,18 +20,12 @@
#include "Scope.h"
-#include <vector>
-
namespace android {
-struct Annotation;
struct Method;
struct Interface : public Scope {
- Interface(
- const char *localName,
- Interface *super,
- std::vector<Annotation *> *annotations);
+ Interface(const char *localName, Interface *super);
void addMethod(Method *method);
@@ -42,8 +36,6 @@
const std::vector<Method *> &methods() const;
- const std::vector<Annotation *> &annotations() const;
-
std::string getBaseName() const;
std::string getCppType(
@@ -80,7 +72,6 @@
private:
Interface *mSuperType;
std::vector<Method *> mMethods;
- std::vector<Annotation *> *mAnnotations;
mutable bool mIsJavaCompatibleInProgress;
DISALLOW_COPY_AND_ASSIGN(Interface);
diff --git a/Scope.cpp b/Scope.cpp
index c4cc587..be60c95 100644
--- a/Scope.cpp
+++ b/Scope.cpp
@@ -85,6 +85,16 @@
return false;
}
+bool Scope::containsInterfaces() const {
+ for (const NamedType *type : mTypes) {
+ if (type->isInterface()) {
+ return true;
+ }
+ }
+
+ return false;
+}
+
std::string Scope::pickUniqueAnonymousName() const {
static size_t sNextID = 0;
diff --git a/Scope.h b/Scope.h
index 326ee01..c22392c 100644
--- a/Scope.h
+++ b/Scope.h
@@ -45,6 +45,7 @@
Interface *getInterface() const;
bool containsSingleInterface(std::string *ifaceName) const;
+ bool containsInterfaces() const;
std::string pickUniqueAnonymousName() const;
diff --git a/Type.cpp b/Type.cpp
index e42f072..e54fdc5 100644
--- a/Type.cpp
+++ b/Type.cpp
@@ -16,6 +16,7 @@
#include "Type.h"
+#include "Annotation.h"
#include "ScalarType.h"
#include <hidl-util/Formatter.h>
@@ -23,9 +24,20 @@
namespace android {
-Type::Type() {}
+Type::Type()
+ : mAnnotations(nullptr) {
+}
+
Type::~Type() {}
+void Type::setAnnotations(std::vector<Annotation *> *annotations) {
+ mAnnotations = annotations;
+}
+
+const std::vector<Annotation *> &Type::annotations() const {
+ return *mAnnotations;
+}
+
bool Type::isScope() const {
return false;
}
diff --git a/Type.h b/Type.h
index 6322207..5a82718 100644
--- a/Type.h
+++ b/Type.h
@@ -21,10 +21,12 @@
#include <android-base/macros.h>
#include <string>
#include <utils/Errors.h>
+#include <vector>
#include <set>
namespace android {
+struct Annotation;
struct Formatter;
struct ScalarType;
struct FQName;
@@ -158,6 +160,9 @@
virtual void getAlignmentAndSize(size_t *align, size_t *size) const;
+ void setAnnotations(std::vector<Annotation *> *annotations);
+ const std::vector<Annotation *> &annotations() const;
+
protected:
void handleError(Formatter &out, ErrorMode mode) const;
void handleError2(Formatter &out, ErrorMode mode) const;
@@ -184,6 +189,8 @@
const std::string &extra) const;
private:
+ std::vector<Annotation *> *mAnnotations;
+
DISALLOW_COPY_AND_ASSIGN(Type);
};
diff --git a/hidl-gen_y.yy b/hidl-gen_y.yy
index 08ac6f0..0e7483e 100644
--- a/hidl-gen_y.yy
+++ b/hidl-gen_y.yy
@@ -105,6 +105,9 @@
%type<type> enum_declaration
%type<type> struct_or_union_declaration
%type<type> opt_extends
+%type<type> type_declaration_body interface_declaration typedef_declaration
+%type<type> named_struct_or_union_declaration named_enum_declaration
+%type<type> compound_declaration annotated_compound_declaration
%type<field> field_declaration
%type<fields> field_declarations struct_or_union_body
@@ -329,41 +332,7 @@
| EXTENDS fqtype { $$ = $2; }
body
- : opt_annotations INTERFACE IDENTIFIER opt_extends
- {
- if ($4 != NULL && !$4->isInterface()) {
- std::cerr << "ERROR: You can only extend interfaces. at" << @4
- << "\n";
-
- YYERROR;
- }
-
- if ($3[0] != 'I') {
- std::cerr << "ERROR: All interface names must start with an 'I' "
- << "prefix. at " << @3 << "\n";
-
- YYERROR;
- }
-
- Interface *iface = new Interface($3, static_cast<Interface *>($4), $1);
-
- // Register interface immediately so it can be referenced inside
- // definition.
- std::string errorMsg;
- if (!ast->addScopedType(iface, &errorMsg)) {
- std::cerr << "ERROR: " << errorMsg << " at " << @3 << "\n";
- YYERROR;
- }
-
- ast->enterScope(iface);
- }
- '{' interface_declarations '}' ';'
- {
- Interface *iface = static_cast<Interface *>(ast->scope());
-
- ast->leaveScope();
- }
- | type_declarations
+ : type_declarations
;
interface_declarations
@@ -382,9 +351,66 @@
;
type_declaration
+ : opt_annotations type_declaration_body
+ {
+ if ($2 != nullptr) {
+ $2->setAnnotations($1);
+ } else if (!$1->empty()) {
+ // Since typedefs are always resolved to their target it makes
+ // little sense to annotate them and have their annotations
+ // impose semantics other than their target type.
+ std::cerr << "ERROR: typedefs cannot be annotated. at " << @2
+ << "\n";
+
+ YYERROR;
+ }
+ }
+ ;
+
+type_declaration_body
: named_struct_or_union_declaration ';'
| named_enum_declaration ';'
| typedef_declaration ';'
+ | interface_declaration ';'
+ ;
+
+interface_declaration
+ : INTERFACE IDENTIFIER opt_extends
+ {
+ if ($3 != NULL && !$3->isInterface()) {
+ std::cerr << "ERROR: You can only extend interfaces. at" << @3
+ << "\n";
+
+ YYERROR;
+ }
+
+ if ($2[0] != 'I') {
+ std::cerr << "ERROR: All interface names must start with an 'I' "
+ << "prefix. at " << @2 << "\n";
+
+ YYERROR;
+ }
+
+ Interface *iface = new Interface($2, static_cast<Interface *>($3));
+
+ // Register interface immediately so it can be referenced inside
+ // definition.
+ std::string errorMsg;
+ if (!ast->addScopedType(iface, &errorMsg)) {
+ std::cerr << "ERROR: " << errorMsg << " at " << @2 << "\n";
+ YYERROR;
+ }
+
+ ast->enterScope(iface);
+ }
+ '{' interface_declarations '}'
+ {
+ Interface *iface = static_cast<Interface *>(ast->scope());
+
+ ast->leaveScope();
+
+ $$ = iface;
+ }
;
typedef_declaration
@@ -395,6 +421,8 @@
std::cerr << "ERROR: " << errorMsg << " at " << @3 << "\n";
YYERROR;
}
+
+ $$ = nullptr;
}
;
@@ -525,6 +553,8 @@
std::cerr << "ERROR: " << errorMsg << " at " << @2 << "\n";
YYERROR;
}
+
+ $$ = container;
}
;
@@ -580,8 +610,20 @@
field_declaration
: type IDENTIFIER ';' { $$ = new CompoundField($2, $1); }
- | struct_or_union_declaration ';' { $$ = NULL; }
- | enum_declaration ';' { $$ = NULL; }
+ | annotated_compound_declaration ';' { $$ = NULL; }
+ ;
+
+annotated_compound_declaration
+ : opt_annotations compound_declaration
+ {
+ $2->setAnnotations($1);
+ $$ = $2;
+ }
+ ;
+
+compound_declaration
+ : struct_or_union_declaration { $$ = $1; }
+ | enum_declaration { $$ = $1; }
;
opt_storage_type
@@ -619,6 +661,8 @@
std::cerr << "ERROR: " << errorMsg << " at " << @2 << "\n";
YYERROR;
}
+
+ $$ = enumType;
}
;
@@ -712,8 +756,7 @@
$$ = new VectorType($3);
}
- | struct_or_union_declaration { $$ = $1; }
- | enum_declaration { $$ = $1; }
+ | annotated_compound_declaration { $$ = $1; }
| INTERFACE { $$ = new GenericBinder; }
;