aboutsummaryrefslogtreecommitdiff
path: root/aidl_language_y.yy
diff options
context:
space:
mode:
Diffstat (limited to 'aidl_language_y.yy')
-rw-r--r--aidl_language_y.yy118
1 files changed, 77 insertions, 41 deletions
diff --git a/aidl_language_y.yy b/aidl_language_y.yy
index 079bda67..11ab29e9 100644
--- a/aidl_language_y.yy
+++ b/aidl_language_y.yy
@@ -71,10 +71,11 @@ AidlLocation loc(const yy::parser::location_type& l) {
AidlToken* token;
char character;
std::string *str;
+ std::vector<std::unique_ptr<AidlToken>> *token_list;
AidlAnnotation* annotation;
AidlAnnotationParameter* param;
std::map<std::string, std::shared_ptr<AidlConstantValue>>* param_list;
- std::vector<AidlAnnotation>* annotation_list;
+ std::vector<std::unique_ptr<AidlAnnotation>>* annotation_list;
AidlTypeSpecifier* type;
AidlArgument* arg;
AidlArgument::Direction direction;
@@ -90,9 +91,6 @@ AidlLocation loc(const yy::parser::location_type& l) {
AidlDefinedType* declaration;
std::vector<std::unique_ptr<AidlTypeSpecifier>>* type_args;
std::vector<std::string>* type_params;
- std::vector<std::unique_ptr<AidlImport>>* imports;
- AidlImport* import;
- AidlPackage* package;
std::vector<std::unique_ptr<AidlDefinedType>>* declarations;
}
@@ -175,23 +173,25 @@ AidlLocation loc(const yy::parser::location_type& l) {
%type<const_expr> const_expr
%type<constant_value_list> constant_value_list
%type<constant_value_list> constant_value_non_empty_list
-%type<imports> imports
-%type<import> import
-%type<package> package
+%type<token_list> imports
%type<declarations> decls
-%type<token> identifier error qualified_name
+%type<token> import identifier error qualified_name optional_package
%%
document
- : package imports decls {
+ : optional_package imports decls {
Comments comments;
if ($1) {
comments = $1->GetComments();
} else if (!$2->empty()) {
comments = $2->front()->GetComments();
}
- ps->SetDocument(std::make_unique<AidlDocument>(loc(@1), comments, std::move(*$2), std::move(*$3)));
+ std::vector<std::string> imports;
+ for (const auto& import : *$2) {
+ imports.push_back(import->GetText());
+ }
+ ps->MakeDocument(loc(@1), comments, std::move(imports), std::move(*$3));
delete $1;
delete $2;
delete $3;
@@ -208,36 +208,29 @@ identifier
| CPP_HEADER
;
-package
+optional_package
: {
$$ = nullptr;
}
| PACKAGE qualified_name ';' {
- $$ = new AidlPackage(loc(@1, @3), $1->GetComments());
ps->SetPackage($2->GetText());
- delete $1;
+ $$ = $1; // for comments
delete $2;
}
;
imports
- : { $$ = new std::vector<std::unique_ptr<AidlImport>>(); }
+ : { $$ = new std::vector<std::unique_ptr<AidlToken>>(); }
| imports import
{
$$ = $1;
- auto it = std::find_if($$->begin(), $$->end(), [&](const auto& i) {
- return $2->GetNeededClass() == i->GetNeededClass();
- });
- if (it == $$->end()) {
- $$->emplace_back($2);
- } else {
- delete $2;
- }
+ $$->emplace_back($2);
}
import
: IMPORT qualified_name ';' {
- $$ = new AidlImport(loc(@2), $2->GetText(), $1->GetComments());
+ // carry the comments before "import" token
+ $$ = new AidlToken($2->GetText(), $1->GetComments());
delete $1;
delete $2;
};
@@ -274,7 +267,7 @@ decl
if ($1->size() > 0 && $$ != nullptr) {
// copy comments from annotation to decl
- $$->SetComments($1->begin()->GetComments());
+ $$->SetComments($1->begin()->get()->GetComments());
$$->Annotate(std::move(*$1));
}
@@ -309,16 +302,19 @@ type_params
parcelable_decl
: PARCELABLE qualified_name optional_type_params ';' {
+ // No check for type name here. We allow nested types for unstructured parcelables.
$$ = new AidlParcelable(loc(@2), $2->GetText(), ps->Package(), $1->GetComments(), "", $3);
delete $1;
delete $2;
}
| PARCELABLE qualified_name optional_type_params '{' parcelable_members '}' {
+ ps->CheckValidTypeName(*$2, loc(@2));
$$ = new AidlStructuredParcelable(loc(@2), $2->GetText(), ps->Package(), $1->GetComments(), $3, $5);
delete $1;
delete $2;
}
| PARCELABLE qualified_name CPP_HEADER C_STR ';' {
+ // No check for type name here. We allow nested types for unstructured parcelables.
$$ = new AidlParcelable(loc(@2), $2->GetText(), ps->Package(), $1->GetComments(), $4->GetText());
delete $1;
delete $2;
@@ -343,6 +339,10 @@ parcelable_members
$1->emplace_back($2);
$$ = $1;
}
+ | parcelable_members decl {
+ if ($2) $1->emplace_back($2); // decl may be nullptr on error
+ $$ = $1;
+ }
| parcelable_members error ';' {
ps->AddError();
$$ = $1;
@@ -361,13 +361,21 @@ variable_decl
;
interface_decl
- : INTERFACE identifier '{' interface_members '}' {
+ : INTERFACE qualified_name ';' {
+ ps->CheckValidTypeName(*$2, loc(@2));
+ $$ = new AidlInterface(loc(@1), $2->GetText(), $1->GetComments(), false, ps->Package(), nullptr);
+ delete $1;
+ delete $2;
+ }
+ | INTERFACE qualified_name '{' interface_members '}' {
+ ps->CheckValidTypeName(*$2, loc(@2));
$$ = new AidlInterface(loc(@1), $2->GetText(), $1->GetComments(), false, ps->Package(), $4);
delete $1;
delete $2;
}
- | ONEWAY INTERFACE identifier '{' interface_members '}' {
- $$ = new AidlInterface(loc(@2), $3->GetText(), $1->GetComments(), true, ps->Package(), $5);
+ | ONEWAY INTERFACE qualified_name '{' interface_members '}' {
+ ps->CheckValidTypeName(*$3, loc(@3));
+ $$ = new AidlInterface(loc(@2), $3->GetText(), $1->GetComments(), true, ps->Package(), $5);
delete $1;
delete $2;
delete $3;
@@ -386,6 +394,11 @@ interface_members
{ $1->push_back(std::unique_ptr<AidlMember>($2)); $$ = $1; }
| interface_members constant_decl
{ $1->push_back(std::unique_ptr<AidlMember>($2)); $$ = $1; }
+ | interface_members decl
+ {
+ if ($2) $1->emplace_back($2); // decl may be nullptr on error
+ $$ = $1;
+ }
| interface_members error ';' {
ps->AddError();
$$ = $1;
@@ -538,7 +551,7 @@ constant_value_non_empty_list
constant_decl
: annotation_list CONST type identifier '=' const_expr ';' {
if ($1->size() > 0) {
- $3->SetComments($1->begin()->GetComments());
+ $3->SetComments($1->begin()->get()->GetComments());
} else {
$3->SetComments($2->GetComments());
}
@@ -579,7 +592,8 @@ enum_decl_body
;
enum_decl
- : ENUM identifier enum_decl_body {
+ : ENUM qualified_name enum_decl_body {
+ ps->CheckValidTypeName(*$2, loc(@2));
$$ = new AidlEnumDeclaration(loc(@2), $2->GetText(), $3, ps->Package(), $1->GetComments());
delete $1;
delete $2;
@@ -589,6 +603,7 @@ enum_decl
union_decl
: UNION qualified_name optional_type_params '{' parcelable_members '}' {
+ ps->CheckValidTypeName(*$2, loc(@2));
$$ = new AidlUnionDecl(loc(@2), $2->GetText(), ps->Package(), $1->GetComments(), $3, $5);
delete $1;
delete $2;
@@ -601,7 +616,7 @@ method_decl
delete $2;
}
| annotation_list ONEWAY type identifier '(' arg_list ')' ';' {
- const auto& comments = ($1->size() > 0) ? $1->begin()->GetComments() : $2->GetComments();
+ const auto& comments = ($1->size() > 0) ? $1->begin()->get()->GetComments() : $2->GetComments();
$$ = new AidlMethod(loc(@4), true, $3, $4->GetText(), $6, comments);
$3->Annotate(std::move(*$1));
delete $1;
@@ -619,7 +634,7 @@ method_decl
delete $7;
}
| annotation_list ONEWAY type identifier '(' arg_list ')' '=' INTVALUE ';' {
- const auto& comments = ($1->size() > 0) ? $1->begin()->GetComments() : $2->GetComments();
+ const auto& comments = ($1->size() > 0) ? $1->begin()->get()->GetComments() : $2->GetComments();
int32_t serial = 0;
if (!android::base::ParseInt($9->GetText(), &serial)) {
AIDL_ERROR(loc(@9)) << "Could not parse int value: " << $9->GetText();
@@ -661,10 +676,9 @@ arg
non_array_type
: annotation_list qualified_name {
- $$ = new AidlTypeSpecifier(loc(@2), $2->GetText(), false, nullptr, $2->GetComments());
- ps->DeferResolution($$);
+ $$ = new AidlTypeSpecifier(loc(@2), $2->GetText(), /*array=*/std::nullopt, nullptr, $2->GetComments());
if (!$1->empty()) {
- $$->SetComments($1->begin()->GetComments());
+ $$->SetComments($1->begin()->get()->GetComments());
$$->Annotate(std::move(*$1));
}
delete $1;
@@ -695,8 +709,20 @@ type
AIDL_ERROR(loc(@2)) << "Annotations for arrays are not supported.";
ps->AddError();
}
- if (!$1->SetArray()) {
- AIDL_ERROR(loc(@1)) << "Can only have one dimensional arrays.";
+ if (!$1->MakeArray(DynamicArray{})) {
+ AIDL_ERROR(loc(@1)) << "Multi-dimensional arrays must be fixed size.";
+ ps->AddError();
+ }
+ $$ = $1;
+ delete $2;
+ }
+ | type annotation_list '[' const_expr ']' {
+ if (!$2->empty()) {
+ AIDL_ERROR(loc(@2)) << "Annotations for arrays are not supported.";
+ ps->AddError();
+ }
+ if (!$1->MakeArray(FixedSizeArray{std::unique_ptr<AidlConstantValue>($4)})) {
+ AIDL_ERROR(loc(@1)) << "Multi-dimensional arrays must be fixed size.";
ps->AddError();
}
$$ = $1;
@@ -720,12 +746,11 @@ type_args
annotation_list
:
- { $$ = new std::vector<AidlAnnotation>(); }
+ { $$ = new std::vector<std::unique_ptr<AidlAnnotation>>(); }
| annotation_list annotation
{
if ($2 != nullptr) {
- $1->emplace_back(std::move(*$2));
- delete $2;
+ $1->emplace_back(std::unique_ptr<AidlAnnotation>($2));
}
$$ = $1;
};
@@ -762,14 +787,25 @@ parameter_non_empty_list
annotation
: ANNOTATION {
- $$ = AidlAnnotation::Parse(loc(@1), $1->GetText(), nullptr, $1->GetComments());
+ // release() returns nullptr if unique_ptr is empty.
+ $$ = AidlAnnotation::Parse(loc(@1), $1->GetText(), {}, $1->GetComments()).release();
+ if (!$$) {
+ ps->AddError();
+ }
+ delete $1;
+ }
+ | ANNOTATION '(' const_expr ')' {
+ auto value = std::shared_ptr<AidlConstantValue>($3);
+ std::map<std::string, std::shared_ptr<AidlConstantValue>> parameter_list {{"value" , value}};
+ $$ = AidlAnnotation::Parse(loc(@1, @4), $1->GetText(), std::move(parameter_list), $1->GetComments()).release();
if (!$$) {
ps->AddError();
}
delete $1;
}
| ANNOTATION '(' parameter_list ')' {
- $$ = AidlAnnotation::Parse(loc(@1, @4), $1->GetText(), $3, $1->GetComments());
+ // release() returns nullptr if unique_ptr is empty.
+ $$ = AidlAnnotation::Parse(loc(@1, @4), $1->GetText(), std::move(*$3), $1->GetComments()).release();
if (!$$) {
ps->AddError();
}