diff options
Diffstat (limited to 'aidl_language_y.yy')
-rw-r--r-- | aidl_language_y.yy | 118 |
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(); } |