cpp: handle generic type-parameters before @nullable
CppNameOf() should handle type-parameters first before applying
@nullable.
Bug: 188237977
Test: aidl_unittests
Change-Id: Ia5e2c7d6f8935646049110559cb46620dad0cd95
diff --git a/aidl_to_cpp.cpp b/aidl_to_cpp.cpp
index 40552c8..e7125f9 100644
--- a/aidl_to_cpp.cpp
+++ b/aidl_to_cpp.cpp
@@ -186,8 +186,15 @@
if (definedType != nullptr && definedType->AsInterface() != nullptr) {
return "::android::sp<" + GetRawCppName(type) + ">";
}
-
- return WrapIfNullable(GetRawCppName(type), raw_type, typenames);
+ auto cpp_name = GetRawCppName(type);
+ if (type.IsGeneric()) {
+ std::vector<std::string> type_params;
+ for (const auto& parameter : type.GetTypeParameters()) {
+ type_params.push_back(CppNameOf(*parameter, typenames));
+ }
+ cpp_name += "<" + base::Join(type_params, ", ") + ">";
+ }
+ return WrapIfNullable(cpp_name, raw_type, typenames);
}
} // namespace
std::string ConstantValueDecorator(const AidlTypeSpecifier& type, const std::string& raw_value) {
@@ -223,13 +230,6 @@
return "::std::optional<::std::vector<" + cpp_name + ">>";
}
return "::std::vector<" + cpp_name + ">";
- } else if (type.IsGeneric()) {
- std::vector<std::string> type_params;
- for (const auto& parameter : type.GetTypeParameters()) {
- type_params.push_back(CppNameOf(*parameter, typenames));
- }
- return StringPrintf("%s<%s>", GetCppName(type, typenames).c_str(),
- base::Join(type_params, ", ").c_str());
}
return GetCppName(type, typenames);
}
diff --git a/aidl_unittest.cpp b/aidl_unittest.cpp
index c3c04df..4113d3a 100644
--- a/aidl_unittest.cpp
+++ b/aidl_unittest.cpp
@@ -1180,6 +1180,62 @@
EXPECT_EQ("::p::Outer::Inner", cpp::CppNameOf(nested_type, typenames_));
}
+TEST_F(AidlTest, CppNameOf_GenericType) {
+ io_delegate_.SetFileContents("p/Wrapper.aidl", "package p; parcelable Wrapper<T> { T wrapped; }");
+ import_paths_.emplace("");
+ // Since we don't support compilation of Wrapper directly (due to "T" reference),
+ // prepare Holder so that Wrapper gets parsed into AidlTypenames
+ const string input_path = "p/Holder.aidl";
+ const string input =
+ "package p; import p.Wrapper; parcelable Holder {\n"
+ " @nullable Wrapper<String> value;\n"
+ "}";
+
+ auto parse_result = Parse(input_path, input, typenames_, Options::Language::CPP);
+ EXPECT_NE(nullptr, parse_result);
+
+ auto type = [](std::string name, auto&&... type_params) -> std::unique_ptr<AidlTypeSpecifier> {
+ auto params = new std::vector<std::unique_ptr<AidlTypeSpecifier>>;
+ (..., params->emplace_back(std::move(type_params)));
+ return std::make_unique<AidlTypeSpecifier>(AIDL_LOCATION_HERE, name, false, params, Comments{});
+ };
+
+ auto set_nullable = [](std::unique_ptr<AidlTypeSpecifier>&& type) {
+ std::vector<AidlAnnotation> annotations;
+ annotations.emplace_back(*AidlAnnotation::Parse(AIDL_LOCATION_HERE, "nullable", nullptr, {}));
+ type->Annotate(std::move(annotations));
+ return std::move(type);
+ };
+
+ auto set_array = [](std::unique_ptr<AidlTypeSpecifier>&& type) {
+ (void)type->SetArray();
+ return std::move(type);
+ };
+
+ auto w = type("p.Wrapper", type("String"));
+ EXPECT_EQ("::p::Wrapper<::android::String16>", cpp::CppNameOf(*w, typenames_));
+
+ auto nullable_w = set_nullable(type("p.Wrapper", type("String")));
+ EXPECT_EQ("::std::optional<::p::Wrapper<::android::String16>>",
+ cpp::CppNameOf(*nullable_w, typenames_));
+
+ auto array_w = set_array(type("p.Wrapper", type("String")));
+ EXPECT_EQ("::std::vector<::p::Wrapper<::android::String16>>",
+ cpp::CppNameOf(*array_w, typenames_));
+
+ auto nullable_array_w = set_nullable(set_array(type("p.Wrapper", type("String"))));
+ EXPECT_EQ("::std::optional<::std::vector<::std::optional<::p::Wrapper<::android::String16>>>>",
+ cpp::CppNameOf(*nullable_array_w, typenames_));
+
+ auto list_w = type("List", type("p.Wrapper", type("String")));
+ EXPECT_EQ("::std::vector<::p::Wrapper<::android::String16>>",
+ cpp::CppNameOf(*list_w, typenames_));
+
+ auto nullable_list_w = set_nullable(type("List", type("p.Wrapper", type("String"))));
+ EXPECT_EQ("::std::optional<::std::vector<::std::optional<::p::Wrapper<::android::String16>>>>",
+ cpp::CppNameOf(*nullable_list_w, typenames_));
+}
+
TEST_P(AidlTest, UnderstandsNativeParcelables) {
io_delegate_.SetFileContents(
"p/Bar.aidl",