Generate client-side headers
Test: Ran aidl-cpp
Bug: 23599760
Change-Id: I31ca5be9dd1274ba81ea6a7110e9f2005f86855d
Signed-off-by: Casey Dahlin <sadmac@google.com>
diff --git a/generate_cpp.cpp b/generate_cpp.cpp
index d0bd7ba..503e557 100644
--- a/generate_cpp.cpp
+++ b/generate_cpp.cpp
@@ -15,35 +15,56 @@
*/
#include "generate_cpp.h"
+#include "parse_helpers.h"
#include <cctype>
#include <memory>
#include <random>
#include <string>
+#include "aidl_language.h"
#include "ast_cpp.h"
#include "code_writer.h"
#include "logging.h"
using std::string;
using std::unique_ptr;
+using std::vector;
namespace android {
namespace aidl {
-namespace {
+namespace internals {
-const int kGuardSize = 32;
+string StrippedLiteral(const buffer_type& buffer) {
+ std::string i_name = buffer.Literal();
-string RandomGuardString() {
- std::default_random_engine generator;
- std::uniform_int_distribution<int> distribution(0,25);
+ string c_name;
- string ret{kGuardSize, '-'};
+ if (i_name.length() >= 2 && i_name[0] == 'I' && isupper(i_name[1]))
+ c_name = i_name.substr(1);
+ else
+ c_name = i_name;
- for (char& c : ret)
- c = 'A' + distribution(generator);
+ return c_name;
+}
- return ret;
+string GetCPPType(type_type *type) {
+ string lit = type->type.Literal();
+
+ if (lit == "int")
+ return "int32_t";
+ else if (lit == "long")
+ return "int64_t";
+ else
+ LOG(FATAL) << "Type not yet supported";
+
+ return "int";
+}
+
+string GetCPPVarDec(type_type* type, string name,
+ int direction) {
+ return GetCPPType(type) + ((OUT_PARAMETER & direction) ? "* " : " ") +
+ name + type->Brackets();
}
unique_ptr<CppDocument> BuildClientSource(interface_type* parsed_doc) {
@@ -62,19 +83,75 @@
}
unique_ptr<CppDocument> BuildClientHeader(interface_type* parsed_doc) {
- unique_ptr<CppNamespace> ns{new CppNamespace{"android", {}}};
- return unique_ptr<CppDocument>{new CppSource{ {}, std::move(ns)}};
+ string i_name = parsed_doc->name.Literal();
+ string c_name = StrippedLiteral(parsed_doc->name);
+ string bp_name = "Bp" + c_name;
+
+ unique_ptr<CppMacroOrConstructorDeclaration> constructor{
+ new CppMacroOrConstructorDeclaration(bp_name, {}, false, false)};
+
+ unique_ptr<CppMacroOrConstructorDeclaration> destructor{
+ new CppMacroOrConstructorDeclaration("~" + bp_name, {}, false, false)};
+
+ vector<unique_ptr<CppDeclaration>> publics;
+ publics.push_back(std::move(constructor));
+ publics.push_back(std::move(destructor));
+
+ for (interface_item_type *item = parsed_doc->interface_items;
+ item;
+ item = item->next) {
+ if (item->item_type != METHOD_TYPE) {
+ LOG(FATAL) << "Unknown interface item type";
+ return nullptr;
+ }
+
+ method_type *m_item = (method_type *)item;
+
+ string method_name = m_item->name.Literal();
+ string return_arg = GetCPPVarDec(&m_item->type, "_aidl_return",
+ OUT_PARAMETER);
+
+ vector<string> args;
+
+ for (arg_type *arg = m_item->args; arg; arg = arg->next)
+ args.push_back(GetCPPVarDec(&arg->type, arg->name.Literal(),
+ convert_direction(arg->direction.data)));
+
+ args.push_back(return_arg);
+
+ unique_ptr<CppDeclaration> meth {
+ new CppMethodDeclaration("android::status_t", method_name,
+ args, false, true)
+ };
+
+ publics.push_back(std::move(meth));
+ }
+
+ unique_ptr<CppClassDeclaration> bp_class{
+ new CppClassDeclaration{bp_name,
+ "public android::BpInterface<" + i_name + ">",
+ std::move(publics),
+ {}
+ }};
+
+ vector<unique_ptr<CppDeclaration>> bp_class_vec;
+ bp_class_vec.push_back(std::move(bp_class));
+
+ unique_ptr<CppNamespace> ns {new CppNamespace{"android", std::move(bp_class_vec)}};
+
+ unique_ptr<CppDocument> bp_header{new CppHeader{bp_name + "_H",
+ {"binder/IBinder.h",
+ "binder/IInterface.h",
+ "utils/Errors.h",
+ i_name + ".h"},
+ std::move(ns) }};
+
+ return bp_header;
}
unique_ptr<CppDocument> BuildServerHeader(interface_type* parsed_doc) {
- string i_name = parsed_doc->name.Literal();
- string c_name;
-
- if (i_name.length() >= 2 && i_name[0] == 'I' && isupper(i_name[1]))
- c_name = i_name.substr(1);
- else
- c_name = i_name;
-
+ string i_name = parsed_doc->name.Literal();;
+ string c_name = StrippedLiteral(parsed_doc->name);
string bn_name = "Bn" + c_name;
unique_ptr<CppDeclaration> on_transact{
@@ -100,7 +177,7 @@
unique_ptr<CppNamespace> ns{new CppNamespace{"android", std::move(declarations)}};
- unique_ptr<CppDocument> bn_header{new CppHeader{RandomGuardString(),
+ unique_ptr<CppDocument> bn_header{new CppHeader{bn_name + "_H",
{"binder/IInterface.h",
i_name + ".h"},
std::move(ns) }};
@@ -122,7 +199,9 @@
return true;
}
-} // namespace
+} // namespace internals
+
+using namespace internals;
bool GenerateCpp(const CppOptions& options, interface_type* parsed_doc) {
bool success = true;