Replace method_type with AidlMethod
As usual, we're leaving most of the same members in place and public. However,
we have removed the linked list pointer and switched to std::vector for lists
of methods.
Change-Id: Id0aa55340e2c56bfa1001c6c8a8343bb4815d38e
Test: unit tests
Bug: 24410295
Signed-off-by: Casey Dahlin <sadmac@google.com>
diff --git a/aidl.cpp b/aidl.cpp
index c88c9de..11a4fea 100644
--- a/aidl.cpp
+++ b/aidl.cpp
@@ -204,8 +204,8 @@
interface_type* c,
TypeNamespace* types) {
int err = 0;
- map<string,method_type*> method_names;
- for (method_type* m = c->interface_items; m; m = m->next) {
+ set<string> method_names;
+ for (const auto& m : *c->methods) {
if (!types->AddContainerType(m->type->type.data) ||
!types->IsValidReturnType(*m->type, filename)) {
err = 1; // return type is invalid
@@ -221,7 +221,7 @@
// prevent duplicate methods
if (method_names.find(m->name.data) == method_names.end()) {
- method_names[m->name.data] = m;
+ method_names.insert(m->name.data);
} else {
cerr << filename << ":" << m->name.lineno
<< " attempt to redefine method " << m->name.data << "," << endl
@@ -449,15 +449,14 @@
}
int check_and_assign_method_ids(const char * filename,
- method_type* first_item) {
+ const std::vector<std::unique_ptr<AidlMethod>>& items) {
// Check whether there are any methods with manually assigned id's and any that are not.
// Either all method id's must be manually assigned or all of them must not.
// Also, check for duplicates of user set id's and that the id's are within the proper bounds.
set<int> usedIds;
- method_type* item = first_item;
bool hasUnassignedIds = false;
bool hasAssignedIds = false;
- while (item != NULL) {
+ for (const auto& item : items) {
if (item->hasId) {
hasAssignedIds = true;
item->assigned_id = atoi(item->id.data);
@@ -490,16 +489,13 @@
filename);
return 1;
}
- item = item->next;
}
// In the case that all methods have unassigned id's, set a unique id for them.
if (hasUnassignedIds) {
int newId = 0;
- item = first_item;
- while (item != NULL) {
+ for (const auto& item : items) {
item->assigned_id = newId++;
- item = item->next;
}
}
@@ -593,7 +589,7 @@
// assign method ids and validate.
err |= check_and_assign_method_ids(input_file_name.c_str(),
- interface->interface_items);
+ *interface->methods);
// after this, there shouldn't be any more errors because of the
// input.
diff --git a/aidl_language.h b/aidl_language.h
index 9e7d25d..3de29ec 100644
--- a/aidl_language.h
+++ b/aidl_language.h
@@ -87,22 +87,24 @@
DISALLOW_COPY_AND_ASSIGN(AidlArgument);
};
-struct method_type {
- struct method_type *next;
- AidlType* type;
- bool oneway;
- buffer_type oneway_token;
- buffer_type name;
- buffer_type open_paren_token;
- std::vector<std::unique_ptr<AidlArgument>>* args;
- buffer_type close_paren_token;
- bool hasId;
- buffer_type equals_token;
- buffer_type id;
- // XXX missing comments/copy text here
- buffer_type semicolon_token;
- buffer_type* comments_token; // points into this structure, DO NOT DELETE
- int assigned_id;
+class AidlMethod {
+ public:
+ AidlMethod() = default;
+ virtual ~AidlMethod() = default;
+
+ AidlType* type;
+ bool oneway;
+ buffer_type oneway_token;
+ buffer_type name;
+ std::vector<std::unique_ptr<AidlArgument>>* args;
+ bool hasId;
+ buffer_type id;
+ buffer_type semicolon_token;
+ buffer_type* comments_token; // points into this structure, DO NOT DELETE
+ int assigned_id;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(AidlMethod);
};
enum {
@@ -133,7 +135,7 @@
char* package;
buffer_type name;
buffer_type open_brace_token;
- method_type* interface_items;
+ std::vector<std::unique_ptr<AidlMethod>>* methods;
buffer_type close_brace_token;
buffer_type* comments_token; // points into this structure, DO NOT DELETE
};
diff --git a/aidl_language_l.l b/aidl_language_l.l
index a067bf7..d6508db 100644
--- a/aidl_language_l.l
+++ b/aidl_language_l.l
@@ -87,11 +87,12 @@
; { SET_BUFFER(';'); return ';'; }
\{ { SET_BUFFER('{'); return '{'; }
\} { SET_BUFFER('}'); return '}'; }
-\( { SET_BUFFER('('); return '('; }
-\) { SET_BUFFER(')'); return ')'; }
, { SET_BUFFER(','); return ','; }
= { SET_BUFFER('='); return '='; }
+\( { return '('; }
+\) { return ')'; }
+
/* keywords */
parcelable { SET_BUFFER(yy::parser::token::PARCELABLE); return yy::parser::token::PARCELABLE; }
interface { SET_BUFFER(yy::parser::token::INTERFACE); return yy::parser::token::INTERFACE; }
diff --git a/aidl_language_y.y b/aidl_language_y.y
index a6d4cbb..aee02db 100644
--- a/aidl_language_y.y
+++ b/aidl_language_y.y
@@ -28,19 +28,20 @@
AidlArgument* arg;
AidlArgument::Direction direction;
std::vector<std::unique_ptr<AidlArgument>>* arg_list;
- method_type* method;
+ AidlMethod* method;
+ std::vector<std::unique_ptr<AidlMethod>>* methods;
interface_type* interface_obj;
user_data_type* user_data;
document_item_type* document_item;
}
%token<buffer> IMPORT PACKAGE IDENTIFIER IDVALUE GENERIC ARRAY PARCELABLE
-%token<buffer> ONEWAY INTERFACE ';' '{' '}' '(' ')' ',' '='
-%token IN OUT INOUT
+%token<buffer> ONEWAY INTERFACE ';' '{' '}' ',' '='
+%token IN OUT INOUT '(' ')'
%type<document_item> document_items declaration
%type<user_data> parcelable_decl
-%type<method> interface_items
+%type<methods> methods
%type<interface_obj> interface_decl interface_header
%type<method> method_decl
%type<type> type
@@ -151,17 +152,17 @@
;
interface_decl:
- interface_header IDENTIFIER '{' interface_items '}' {
+ interface_header IDENTIFIER '{' methods '}' {
interface_type* c = $1;
c->name = $2;
c->package =
cpp_strdup(ps->Package().c_str());
c->open_brace_token = $3;
- c->interface_items = $4;
+ c->methods = $4;
c->close_brace_token = $5;
$$ = c;
}
- | INTERFACE error '{' interface_items '}' {
+ | INTERFACE error '{' methods '}' {
fprintf(stderr, "%s:%d: syntax error in interface declaration. Expected type name, saw \"%s\"\n",
ps->FileName().c_str(), $2.lineno, $2.data);
$$ = NULL;
@@ -174,87 +175,66 @@
;
-interface_items:
- { $$ = NULL; }
- | interface_items method_decl {
- method_type* p=$1;
- while (p && p->next) {
- p=p->next;
- }
- if (p) {
- p->next = $2;
- $$ = $1;
- } else {
- $$ = $2;
- }
- }
- | interface_items error ';' {
- fprintf(stderr, "%s:%d: syntax error before ';' (expected method declaration)\n",
- ps->FileName().c_str(), $3.lineno);
- $$ = $1;
- }
- ;
+methods
+ :
+ { $$ = new std::vector<std::unique_ptr<AidlMethod>>(); }
+ | methods method_decl
+ { $1->push_back(std::unique_ptr<AidlMethod>($2)); }
+ | methods error ';' {
+ fprintf(stderr, "%s:%d: syntax error before ';' "
+ "(expected method declaration)\n",
+ ps->FileName().c_str(), $3.lineno);
+ $$ = $1;
+ };
method_decl:
type IDENTIFIER '(' arg_list ')' ';' {
- method_type *method = new method_type();
+ AidlMethod *method = new AidlMethod();
method->oneway = false;
method->type = $1;
memset(&method->oneway_token, 0, sizeof(buffer_type));
method->name = $2;
- method->open_paren_token = $3;
method->args = $4;
- method->close_paren_token = $5;
method->hasId = false;
- memset(&method->equals_token, 0, sizeof(buffer_type));
memset(&method->id, 0, sizeof(buffer_type));
method->semicolon_token = $6;
method->comments_token = &method->type->type;
$$ = method;
}
| ONEWAY type IDENTIFIER '(' arg_list ')' ';' {
- method_type *method = new method_type();
+ AidlMethod *method = new AidlMethod();
method->oneway = true;
method->oneway_token = $1;
method->type = $2;
method->name = $3;
- method->open_paren_token = $4;
method->args = $5;
- method->close_paren_token = $6;
method->hasId = false;
- memset(&method->equals_token, 0, sizeof(buffer_type));
memset(&method->id, 0, sizeof(buffer_type));
method->semicolon_token = $7;
method->comments_token = &method->oneway_token;
$$ = method;
}
| type IDENTIFIER '(' arg_list ')' '=' IDVALUE ';' {
- method_type *method = new method_type();
+ AidlMethod *method = new AidlMethod();
method->oneway = false;
memset(&method->oneway_token, 0, sizeof(buffer_type));
method->type = $1;
method->name = $2;
- method->open_paren_token = $3;
method->args = $4;
- method->close_paren_token = $5;
method->hasId = true;
- method->equals_token = $6;
method->id = $7;
method->semicolon_token = $8;
method->comments_token = &method->type->type;
$$ = method;
}
| ONEWAY type IDENTIFIER '(' arg_list ')' '=' IDVALUE ';' {
- method_type *method = new method_type();
+ AidlMethod *method = new AidlMethod();
method->oneway = true;
method->oneway_token = $1;
method->type = $2;
method->name = $3;
- method->open_paren_token = $4;
method->args = $5;
- method->close_paren_token = $6;
method->hasId = true;
- method->equals_token = $7;
method->id = $8;
method->semicolon_token = $9;
method->comments_token = &method->oneway_token;
@@ -262,7 +242,8 @@
}
;
-arg_list:
+arg_list
+ :
{ $$ = new std::vector<std::unique_ptr<AidlArgument>>(); }
| arg {
$$ = new std::vector<std::unique_ptr<AidlArgument>>();
@@ -278,7 +259,8 @@
$$ = new std::vector<std::unique_ptr<AidlArgument>>();
};
-arg: direction type IDENTIFIER
+arg
+ : direction type IDENTIFIER
{ $$ = new AidlArgument($1, $2, $3); };
| type IDENTIFIER
{ $$ = new AidlArgument($1, $2); };
@@ -301,7 +283,8 @@
}
;
-direction: IN
+direction
+ : IN
{ $$ = AidlArgument::IN_DIR; }
| OUT
{ $$ = AidlArgument::OUT_DIR; }
diff --git a/generate_cpp.cpp b/generate_cpp.cpp
index 50dd392..5f14a61 100644
--- a/generate_cpp.cpp
+++ b/generate_cpp.cpp
@@ -65,17 +65,17 @@
type.Brackets().c_str());
}
-unique_ptr<Declaration> BuildMethodDecl(const method_type* method,
+unique_ptr<Declaration> BuildMethodDecl(const AidlMethod& method,
const TypeNamespace& types,
bool for_interface) {
vector<string> args;
- for (const unique_ptr<AidlArgument>& arg : *method->args) {
+ for (const unique_ptr<AidlArgument>& arg : *method.args) {
args.push_back(GetCPPVarDec(
types, arg->GetType(), arg->GetName(),
AidlArgument::OUT_DIR & arg->GetDirection()));
}
- string return_arg = GetCPPVarDec(types, *method->type, "_aidl_return", true);
+ string return_arg = GetCPPVarDec(types, *method.type, "_aidl_return", true);
args.push_back(return_arg);
uint32_t modifiers = 0;
@@ -88,7 +88,7 @@
return unique_ptr<Declaration>{
new MethodDecl{kAndroidStatusLiteral,
- method->name.Literal(),
+ method.name.Literal(),
args,
modifiers}};
}
@@ -171,10 +171,8 @@
publics.push_back(std::move(constructor));
publics.push_back(std::move(destructor));
- for (method_type *item = parsed_doc.interface_items;
- item;
- item = item->next) {
- publics.push_back(BuildMethodDecl(item, types, false));
+ for (const auto& item : *parsed_doc.methods) {
+ publics.push_back(BuildMethodDecl(*item, types, false));
}
unique_ptr<ClassDecl> bp_class{
@@ -234,10 +232,8 @@
{ClassName(parsed_doc, ClassNames::BASE)}}});
unique_ptr<Enum> call_enum{new Enum{"Call"}};
- for (const method_type* method = parsed_doc.interface_items;
- method;
- method = method->next) {
- if_class->AddPublic(BuildMethodDecl(method, types, true));
+ for (const auto& method : *parsed_doc.methods) {
+ if_class->AddPublic(BuildMethodDecl(*method, types, true));
call_enum->AddValue(
UpperCase(method->name.data),
StringPrintf("android::IBinder::FIRST_CALL_TRANSACTION + %d",
diff --git a/generate_java_binder.cpp b/generate_java_binder.cpp
index 42b0a2e..b8fded0 100644
--- a/generate_java_binder.cpp
+++ b/generate_java_binder.cpp
@@ -263,18 +263,18 @@
static void
-generate_method(const method_type* method, Class* interface,
+generate_method(const AidlMethod& method, Class* interface,
StubClass* stubClass, ProxyClass* proxyClass, int index,
JavaTypeNamespace* types)
{
int i;
bool hasOutParams = false;
- const bool oneway = proxyClass->mOneWay || method->oneway;
+ const bool oneway = proxyClass->mOneWay || method.oneway;
// == the TRANSACT_ constant =============================================
string transactCodeName = "TRANSACTION_";
- transactCodeName += method->name.data;
+ transactCodeName += method.name.data;
char transactCodeValue[60];
sprintf(transactCodeValue, "(android.os.IBinder.FIRST_CALL_TRANSACTION + %d)", index);
@@ -286,13 +286,13 @@
// == the declaration in the interface ===================================
Method* decl = new Method;
- decl->comment = gather_comments(method->comments_token->extra);
+ decl->comment = gather_comments(method.comments_token->extra);
decl->modifiers = PUBLIC;
- decl->returnType = types->Find(method->type->type.data);
- decl->returnTypeDimension = method->type->dimension;
- decl->name = method->name.data;
+ decl->returnType = types->Find(method.type->type.data);
+ decl->returnTypeDimension = method.type->dimension;
+ decl->name = method.name.data;
- for (const std::unique_ptr<AidlArgument>& arg : *method->args) {
+ for (const std::unique_ptr<AidlArgument>& arg : *method.args) {
decl->parameters.push_back(new Variable(
types->Find(arg->GetType().type.data), arg->GetName(),
arg->GetType().dimension));
@@ -306,7 +306,7 @@
Case* c = new Case(transactCodeName);
- MethodCall* realCall = new MethodCall(THIS_VALUE, method->name.data);
+ MethodCall* realCall = new MethodCall(THIS_VALUE, method.name.data);
// interface token validation is the very first thing we do
c->statements->Add(new MethodCall(stubClass->transact_data,
@@ -315,7 +315,7 @@
// args
Variable* cl = NULL;
VariableFactory stubArgs("_arg");
- for (const std::unique_ptr<AidlArgument>& arg : *method->args) {
+ for (const std::unique_ptr<AidlArgument>& arg : *method.args) {
const Type* t = types->Find(arg->GetType().type.data);
Variable* v = stubArgs.Get(t);
v->dimension = arg->GetType().dimension;
@@ -344,7 +344,7 @@
// the real call
Variable* _result = NULL;
- if (0 == strcmp(method->type->type.data, "void")) {
+ if (0 == strcmp(method.type->type.data, "void")) {
c->statements->Add(realCall);
if (!oneway) {
@@ -373,7 +373,7 @@
// out parameters
i = 0;
- for (const std::unique_ptr<AidlArgument>& arg : *method->args) {
+ for (const std::unique_ptr<AidlArgument>& arg : *method.args) {
const Type* t = types->Find(arg->GetType().type.data);
Variable* v = stubArgs.Get(i++);
@@ -391,13 +391,13 @@
// == the proxy method ===================================================
Method* proxy = new Method;
- proxy->comment = gather_comments(method->comments_token->extra);
+ proxy->comment = gather_comments(method.comments_token->extra);
proxy->modifiers = PUBLIC | OVERRIDE;
- proxy->returnType = types->Find(method->type->type.data);
- proxy->returnTypeDimension = method->type->dimension;
- proxy->name = method->name.data;
+ proxy->returnType = types->Find(method.type->type.data);
+ proxy->returnTypeDimension = method.type->dimension;
+ proxy->name = method.name.data;
proxy->statements = new StatementBlock;
- for (const std::unique_ptr<AidlArgument>& arg : *method->args) {
+ for (const std::unique_ptr<AidlArgument>& arg : *method.args) {
proxy->parameters.push_back(new Variable(
types->Find(arg->GetType().type.data), arg->GetName(),
arg->GetType().dimension));
@@ -420,9 +420,9 @@
// the return value
_result = NULL;
- if (0 != strcmp(method->type->type.data, "void")) {
+ if (0 != strcmp(method.type->type.data, "void")) {
_result = new Variable(proxy->returnType, "_result",
- method->type->dimension);
+ method.type->dimension);
proxy->statements->Add(new VariableDeclaration(_result));
}
@@ -437,7 +437,7 @@
1, new LiteralExpression("DESCRIPTOR")));
// the parameters
- for (const std::unique_ptr<AidlArgument>& arg : *method->args) {
+ for (const std::unique_ptr<AidlArgument>& arg : *method.args) {
const Type* t = types->Find(arg->GetType().type.data);
Variable* v = new Variable(t, arg->GetName(), arg->GetType().dimension);
AidlArgument::Direction dir = arg->GetDirection();
@@ -478,7 +478,7 @@
}
// the out/inout parameters
- for (const std::unique_ptr<AidlArgument>& arg : *method->args) {
+ for (const std::unique_ptr<AidlArgument>& arg : *method.args) {
const Type* t = types->Find(arg->GetType().type.data);
Variable* v = new Variable(t, arg->GetName(), arg->GetType().dimension);
if (arg->GetDirection() & AidlArgument::OUT_DIR) {
@@ -552,11 +552,9 @@
// all the declared methods of the interface
int index = 0;
- method_type* item = iface->interface_items;
- while (item != NULL) {
- generate_method(item, interface, stub, proxy,
+ for (const auto& item : *iface->methods) {
+ generate_method(*item, interface, stub, proxy,
item->assigned_id, types);
- item = item->next;
index++;
}