Snap for 6439596 from e1c27fbb652359e38f38e41ee173366b50e1466c to qt-aml-tzdata-release
Change-Id: If509b9ec0bcfa8c3709ffd86b7d752bb467c960d
diff --git a/Android.bp b/Android.bp
index 9a59d4d..14f2d00 100644
--- a/Android.bp
+++ b/Android.bp
@@ -30,12 +30,6 @@
windows: {
enabled: true,
},
- host: {
- cflags: [
- "-O0",
- "-g",
- ],
- },
},
}
@@ -48,7 +42,6 @@
srcs: [
"aidl.cpp",
"aidl_apicheck.cpp",
- "aidl_const_expressions.cpp",
"aidl_language.cpp",
"aidl_language_l.ll",
"aidl_language_y.yy",
@@ -69,11 +62,10 @@
"line_reader.cpp",
"io_delegate.cpp",
"options.cpp",
+ "type_cpp.cpp",
+ "type_java.cpp",
+ "type_namespace.cpp",
],
- yacc: {
- gen_location_hh: true,
- gen_position_hh: true,
- },
}
// aidl executable
@@ -110,6 +102,7 @@
"-Wextra",
"-Werror",
"-g",
+ "-DUNIT_TEST",
],
srcs: [
@@ -127,63 +120,33 @@
"tests/test_data_ping_responder.cpp",
"tests/test_data_string_constants.cpp",
"tests/test_util.cpp",
+ "type_cpp_unittest.cpp",
+ "type_java_unittest.cpp",
],
static_libs: [
"libaidl-common",
"libbase",
"libcutils",
- "libgmock",
],
target: {
+ host: {
+ static_libs: ["libgmock_host"],
+ },
android: {
static_libs: [
+ "libgmock",
"liblog",
],
},
},
}
-cc_fuzz {
- name: "aidl_parser_fuzzer",
- host_supported: true,
- dictionary: "tests/aidl_parser_fuzzer.dict",
-
- fuzz_config: {
- cc: [
- "smoreland@google.com",
- "jiyong@google.com",
- "jeongik@google.com",
- ],
- },
-
- srcs: [
- "tests/aidl_parser_fuzzer.cpp",
- "tests/fake_io_delegate.cpp",
- "tests/test_util.cpp",
- ],
- static_libs: [
- "libaidl-common",
- "libbase",
- "libcutils",
- ],
- target: {
- android: {
- static_libs: [
- "liblog",
- ],
- },
- },
- // Enable this to show additional information about what is being parsed during fuzzing.
- // cflags: ["-DFUZZ_LOG"],
-}
-
//
// Everything below here is used for integration testing of generated AIDL code.
//
-cc_test {
+cc_binary {
name: "aidl_test_sentinel_searcher",
- gtest: false,
srcs: ["tests/aidl_test_sentinel_searcher.cpp"],
cflags: [
"-Wall",
@@ -207,13 +170,7 @@
],
}
-filegroup {
- name: "libaidl-integration-test-files",
- srcs: ["tests/android/aidl/tests/*.aidl"],
- path: "tests",
-}
-
-cc_library_static {
+cc_library_shared {
name: "libaidl-integration-test",
defaults: ["aidl_test_defaults"],
aidl: {
@@ -222,24 +179,22 @@
include_dirs: ["frameworks/native/aidl/binder"],
},
srcs: [
- ":libaidl-integration-test-files",
+ "tests/android/aidl/tests/*.aidl",
"tests/simple_parcelable.cpp",
],
}
-cc_test {
+cc_binary {
name: "aidl_test_service",
- gtest: false,
defaults: ["aidl_test_defaults"],
- static_libs: ["libaidl-integration-test"],
+ shared_libs: ["libaidl-integration-test"],
srcs: ["tests/aidl_test_service.cpp"],
}
-cc_test {
+cc_binary {
name: "aidl_test_client",
- gtest: false,
defaults: ["aidl_test_defaults"],
- static_libs: ["libaidl-integration-test"],
+ shared_libs: ["libaidl-integration-test"],
srcs: [
"tests/aidl_test_client.cpp",
"tests/aidl_test_client_file_descriptors.cpp",
@@ -266,7 +221,9 @@
manifest: "tests/java_app/AndroidManifest.xml",
resource_dirs: ["tests/java_app/resources"],
srcs: [
- "tests/android/aidl/tests/*.aidl",
+ "tests/android/aidl/tests/ITestService.aidl",
+ "tests/android/aidl/tests/INamedCallback.aidl",
+ "tests/android/aidl/tests/StructuredParcelable.aidl",
"tests/java_app/src/android/aidl/tests/NullableTests.java",
"tests/java_app/src/android/aidl/tests/SimpleParcelable.java",
"tests/java_app/src/android/aidl/tests/TestFailException.java",
diff --git a/aidl.cpp b/aidl.cpp
index b0e2489..25609c0 100644
--- a/aidl.cpp
+++ b/aidl.cpp
@@ -46,6 +46,9 @@
#include "logging.h"
#include "options.h"
#include "os.h"
+#include "type_cpp.h"
+#include "type_java.h"
+#include "type_namespace.h"
#ifndef O_BINARY
# define O_BINARY 0
@@ -149,6 +152,62 @@
return valid;
}
+bool register_types(const AidlStructuredParcelable* parcel, TypeNamespace* types) {
+ for (const auto& v : parcel->GetFields()) {
+ if (!types->MaybeAddContainerType(v->GetType())) {
+ return false;
+ }
+
+ const ValidatableType* type = types->GetReturnType(v->GetType(), *parcel);
+ if (type == nullptr) {
+ return false;
+ }
+ v->GetMutableType()->SetLanguageType(type);
+ }
+ return true;
+}
+
+bool register_types(const AidlInterface* c, TypeNamespace* types) {
+ for (const auto& m : c->GetMethods()) {
+ if (!types->MaybeAddContainerType(m->GetType())) {
+ return false;
+ }
+
+ const ValidatableType* return_type = types->GetReturnType(m->GetType(), *c);
+
+ if (return_type == nullptr) {
+ return false;
+ }
+ m->GetMutableType()->SetLanguageType(return_type);
+
+ set<string> argument_names;
+
+ int index = 1;
+ for (const auto& arg : m->GetArguments()) {
+ if (!types->MaybeAddContainerType(arg->GetType())) {
+ return false;
+ }
+
+ const ValidatableType* arg_type = types->GetArgType(*arg, index, *c);
+ if (arg_type == nullptr) {
+ return false;
+ }
+ arg->GetMutableType()->SetLanguageType(arg_type);
+ }
+ }
+
+ for (const std::unique_ptr<AidlConstantDeclaration>& constant : c->GetConstantDeclarations()) {
+ AidlTypeSpecifier* specifier = constant->GetMutableType();
+ const ValidatableType* return_type = types->GetReturnType(*specifier, *c);
+ if (return_type == nullptr) {
+ return false;
+ }
+ specifier->SetLanguageType(return_type);
+ }
+
+ return true;
+}
+
bool write_dep_file(const Options& options, const AidlDefinedType& defined_type,
const vector<string>& imports, const IoDelegate& io_delegate,
const string& input_file, const string& output_file) {
@@ -253,7 +312,6 @@
set<int> usedIds;
bool hasUnassignedIds = false;
bool hasAssignedIds = false;
- int newId = kMinUserSetMethodId;
for (const auto& item : items) {
// However, meta transactions that are added by the AIDL compiler are
// exceptions. They have fixed IDs but allowed to be with user-defined
@@ -266,34 +324,40 @@
}
if (item->HasId()) {
hasAssignedIds = true;
+ // Ensure that the user set id is not duplicated.
+ if (usedIds.find(item->GetId()) != usedIds.end()) {
+ // We found a duplicate id, so throw an error.
+ AIDL_ERROR(item) << "Found duplicate method id (" << item->GetId() << ") for method "
+ << item->GetName();
+ return false;
+ }
+ // Ensure that the user set id is within the appropriate limits
+ if (item->GetId() < kMinUserSetMethodId || item->GetId() > kMaxUserSetMethodId) {
+ AIDL_ERROR(item) << "Found out of bounds id (" << item->GetId() << ") for method "
+ << item->GetName() << ". Value for id must be between "
+ << kMinUserSetMethodId << " and " << kMaxUserSetMethodId << " inclusive.";
+ return false;
+ }
+ usedIds.insert(item->GetId());
} else {
- item->SetId(newId++);
hasUnassignedIds = true;
}
-
if (hasAssignedIds && hasUnassignedIds) {
AIDL_ERROR(item) << "You must either assign id's to all methods or to none of them.";
return false;
}
-
- // Ensure that the user set id is not duplicated.
- if (usedIds.find(item->GetId()) != usedIds.end()) {
- // We found a duplicate id, so throw an error.
- AIDL_ERROR(item) << "Found duplicate method id (" << item->GetId() << ") for method "
- << item->GetName();
- return false;
- }
- usedIds.insert(item->GetId());
-
- // Ensure that the user set id is within the appropriate limits
- if (item->GetId() < kMinUserSetMethodId || item->GetId() > kMaxUserSetMethodId) {
- AIDL_ERROR(item) << "Found out of bounds id (" << item->GetId() << ") for method "
- << item->GetName() << ". Value for id must be between "
- << kMinUserSetMethodId << " and " << kMaxUserSetMethodId << " inclusive.";
- return false;
- }
}
+ // In the case that all methods have unassigned id's, set a unique id for them.
+ if (hasUnassignedIds) {
+ int newId = kMinUserSetMethodId;
+ for (const auto& item : items) {
+ assert(newId <= kMaxUserSetMethoId);
+ if (item->IsUserDefined()) {
+ item->SetId(newId++);
+ }
+ }
+ }
return true;
}
@@ -347,7 +411,7 @@
namespace internals {
bool parse_preprocessed_file(const IoDelegate& io_delegate, const string& filename,
- AidlTypenames* typenames) {
+ TypeNamespace* types, AidlTypenames& typenames) {
bool success = true;
unique_ptr<LineReader> line_reader = io_delegate.GetLineReader(filename);
if (!line_reader) {
@@ -384,17 +448,20 @@
}
AidlParcelable* doc = new AidlParcelable(
location, new AidlQualifiedName(location, class_name, ""), package, "" /* comments */);
- typenames->AddPreprocessedType(unique_ptr<AidlParcelable>(doc));
+ types->AddParcelableType(*doc, filename);
+ typenames.AddPreprocessedType(unique_ptr<AidlParcelable>(doc));
} else if (decl == "structured_parcelable") {
auto temp = new std::vector<std::unique_ptr<AidlVariableDeclaration>>();
AidlStructuredParcelable* doc =
new AidlStructuredParcelable(location, new AidlQualifiedName(location, class_name, ""),
package, "" /* comments */, temp);
- typenames->AddPreprocessedType(unique_ptr<AidlStructuredParcelable>(doc));
+ types->AddParcelableType(*doc, filename);
+ typenames.AddPreprocessedType(unique_ptr<AidlStructuredParcelable>(doc));
} else if (decl == "interface") {
auto temp = new std::vector<std::unique_ptr<AidlMember>>();
AidlInterface* doc = new AidlInterface(location, class_name, "", false, temp, package);
- typenames->AddPreprocessedType(unique_ptr<AidlInterface>(doc));
+ types->AddBinderType(*doc, filename);
+ typenames.AddPreprocessedType(unique_ptr<AidlInterface>(doc));
} else {
success = false;
break;
@@ -409,7 +476,7 @@
}
AidlError load_and_validate_aidl(const std::string& input_file_name, const Options& options,
- const IoDelegate& io_delegate, AidlTypenames* typenames,
+ const IoDelegate& io_delegate, TypeNamespace* types,
vector<AidlDefinedType*>* defined_types,
vector<string>* imported_files) {
AidlError err = AidlError::OK;
@@ -419,24 +486,18 @@
//////////////////////////////////////////////////////////////////////////
// Parse the main input file
- std::unique_ptr<Parser> main_parser = Parser::Parse(input_file_name, io_delegate, *typenames);
+ std::unique_ptr<Parser> main_parser =
+ Parser::Parse(input_file_name, io_delegate, types->typenames_);
if (main_parser == nullptr) {
return AidlError::PARSE_ERROR;
}
- int num_interfaces_or_structured_parcelables = 0;
- for (AidlDefinedType* type : main_parser->GetDefinedTypes()) {
- if (type->AsInterface() != nullptr || type->AsStructuredParcelable() != nullptr) {
- num_interfaces_or_structured_parcelables++;
- }
- }
- if (num_interfaces_or_structured_parcelables > 1) {
- AIDL_ERROR(input_file_name) << "You must declare only one type per a file.";
+ if (!types->AddDefinedTypes(main_parser->GetDefinedTypes(), input_file_name)) {
return AidlError::BAD_TYPE;
}
// Import the preprocessed file
for (const string& s : options.PreprocessedFiles()) {
- if (!parse_preprocessed_file(io_delegate, s, typenames)) {
+ if (!parse_preprocessed_file(io_delegate, s, types, types->typenames_)) {
err = AidlError::BAD_PRE_PROCESSED_FILE;
}
}
@@ -470,7 +531,7 @@
set<string> import_candidates(type_from_import_statements);
import_candidates.insert(unresolved_types.begin(), unresolved_types.end());
for (const auto& import : import_candidates) {
- if (typenames->IsIgnorableImport(import)) {
+ if (types->HasImportType(import)) {
// There are places in the Android tree where an import doesn't resolve,
// but we'll pick the type up through the preprocessed types.
// This seems like an error, but legacy support demands we support it...
@@ -488,12 +549,16 @@
import_paths.emplace_back(import_path);
- std::unique_ptr<Parser> import_parser = Parser::Parse(import_path, io_delegate, *typenames);
+ std::unique_ptr<Parser> import_parser =
+ Parser::Parse(import_path, io_delegate, types->typenames_);
if (import_parser == nullptr) {
cerr << "error while importing " << import_path << " for " << import << endl;
err = AidlError::BAD_IMPORT;
continue;
}
+ if (!types->AddDefinedTypes(import_parser->GetDefinedTypes(), import_path)) {
+ return AidlError::BAD_TYPE;
+ }
}
if (err != AidlError::OK) {
return err;
@@ -502,12 +567,16 @@
for (const auto& imported_file : options.ImportFiles()) {
import_paths.emplace_back(imported_file);
- std::unique_ptr<Parser> import_parser = Parser::Parse(imported_file, io_delegate, *typenames);
+ std::unique_ptr<Parser> import_parser =
+ Parser::Parse(imported_file, io_delegate, types->typenames_);
if (import_parser == nullptr) {
AIDL_ERROR(imported_file) << "error while importing " << imported_file;
err = AidlError::BAD_IMPORT;
continue;
}
+ if (!types->AddDefinedTypes(import_parser->GetDefinedTypes(), imported_file)) {
+ return AidlError::BAD_TYPE;
+ }
}
if (err != AidlError::OK) {
return err;
@@ -520,32 +589,34 @@
// using fully qualified names.
return AidlError::BAD_TYPE;
}
+ if (!is_check_api) {
+ for (const auto defined_type : main_parser->GetDefinedTypes()) {
+ AidlInterface* interface = defined_type->AsInterface();
+ AidlStructuredParcelable* parcelable = defined_type->AsStructuredParcelable();
- typenames->IterateTypes([&](const AidlDefinedType& type) {
- AidlEnumDeclaration* enum_decl = const_cast<AidlEnumDeclaration*>(type.AsEnumDeclaration());
- if (enum_decl != nullptr) {
- // BackingType is filled in for all known enums, including imported enums,
- // because other types that may use enums, such as Interface or
- // StructuredParcelable, need to know the enum BackingType when
- // generating code.
- if (auto backing_type = enum_decl->BackingType(*typenames); backing_type != nullptr) {
- enum_decl->SetBackingType(std::unique_ptr<const AidlTypeSpecifier>(backing_type));
- } else {
- // Default to byte type for enums.
- auto byte_type =
- std::make_unique<AidlTypeSpecifier>(AIDL_LOCATION_HERE, "byte", false, nullptr, "");
- byte_type->Resolve(*typenames);
- enum_decl->SetBackingType(std::move(byte_type));
+ // Link the AIDL type with the type of the target language. This will
+ // be removed when the migration to AidlTypenames is done.
+ defined_type->SetLanguageType(types->GetDefinedType(*defined_type));
+
+ if (interface != nullptr) {
+ if (!register_types(interface, types)) {
+ return AidlError::BAD_TYPE;
+ }
}
-
- enum_decl->Autofill();
+ if (parcelable != nullptr) {
+ if (!register_types(parcelable, types)) {
+ return AidlError::BAD_TYPE;
+ }
+ }
}
- });
+ }
//////////////////////////////////////////////////////////////////////////
// Validation phase
//////////////////////////////////////////////////////////////////////////
+ AidlTypenames& typenames = types->typenames_;
+
// For legacy reasons, by default, compiling an unstructured parcelable (which contains no output)
// is allowed. This must not be returned as an error until the very end of this procedure since
// this may be considered a success, and we should first check that there are not other, more
@@ -555,15 +626,9 @@
const int num_defined_types = main_parser->GetDefinedTypes().size();
for (const auto defined_type : main_parser->GetDefinedTypes()) {
CHECK(defined_type != nullptr);
-
- // Language specific validation
- if (!defined_type->LanguageSpecificCheckValid(options.TargetLanguage())) {
- return AidlError::BAD_TYPE;
- }
-
AidlParcelable* unstructuredParcelable = defined_type->AsUnstructuredParcelable();
if (unstructuredParcelable != nullptr) {
- if (!unstructuredParcelable->CheckValid(*typenames)) {
+ if (!unstructuredParcelable->CheckValid(typenames)) {
return AidlError::BAD_TYPE;
}
bool isStable = unstructuredParcelable->IsStableParcelable();
@@ -584,19 +649,10 @@
continue;
}
- if (defined_type->IsVintfStability() &&
- (options.GetStability() != Options::Stability::VINTF || !options.IsStructured())) {
- AIDL_ERROR(defined_type)
- << "Must compile @VintfStability type w/ aidl_interface 'stability: \"vintf\"'";
- return AidlError::NOT_STRUCTURED;
- }
-
- // Ensure that a type is either an interface, structured parcelable, or
- // enum.
+ // Ensure that a type is either an interface or a structured parcelable
AidlInterface* interface = defined_type->AsInterface();
AidlStructuredParcelable* parcelable = defined_type->AsStructuredParcelable();
- AidlEnumDeclaration* enum_decl = defined_type->AsEnumDeclaration();
- CHECK(!!interface + !!parcelable + !!enum_decl == 1);
+ CHECK(interface != nullptr || parcelable != nullptr);
// Ensure that foo.bar.IFoo is defined in <some_path>/foo/bar/IFoo.aidl
if (num_defined_types == 1 && !check_filename(input_file_name, *defined_type)) {
@@ -607,7 +663,7 @@
if (!is_check_api) {
// No need to do this for check api because all typespecs are already
// using fully qualified name and we don't import in AIDL files.
- if (!defined_type->CheckValid(*typenames)) {
+ if (!defined_type->CheckValid(typenames)) {
return AidlError::BAD_TYPE;
}
}
@@ -617,7 +673,7 @@
if (options.Version() > 0) {
AidlTypeSpecifier* ret =
new AidlTypeSpecifier(AIDL_LOCATION_HERE, "int", false, nullptr, "");
- ret->Resolve(*typenames);
+ ret->Resolve(typenames);
vector<unique_ptr<AidlArgument>>* args = new vector<unique_ptr<AidlArgument>>();
AidlMethod* method =
new AidlMethod(AIDL_LOCATION_HERE, false, ret, "getInterfaceVersion", args, "",
@@ -627,49 +683,19 @@
if (!check_and_assign_method_ids(interface->GetMethods())) {
return AidlError::BAD_METHOD_ID;
}
-
- // Verify and resolve the constant declarations
- for (const auto& constant : interface->GetConstantDeclarations()) {
- switch (constant->GetValue().GetType()) {
- case AidlConstantValue::Type::STRING: // fall-through
- case AidlConstantValue::Type::INT8: // fall-through
- case AidlConstantValue::Type::INT32: // fall-through
- case AidlConstantValue::Type::INT64: // fall-through
- case AidlConstantValue::Type::FLOATING: // fall-through
- case AidlConstantValue::Type::UNARY: // fall-through
- case AidlConstantValue::Type::BINARY: {
- bool success = constant->CheckValid(*typenames);
- if (!success) {
- return AidlError::BAD_TYPE;
- }
- if (constant->ValueString(cpp::ConstantValueDecorator).empty()) {
- return AidlError::BAD_TYPE;
- }
- break;
- }
- default:
- LOG(FATAL) << "Unrecognized constant type: "
- << static_cast<int>(constant->GetValue().GetType());
- break;
- }
- }
}
}
- typenames->IterateTypes([&](const AidlDefinedType& type) {
- if (options.IsStructured() && type.AsUnstructuredParcelable() != nullptr &&
- !type.AsUnstructuredParcelable()->IsStableParcelable()) {
- err = AidlError::NOT_STRUCTURED;
- LOG(ERROR) << type.GetCanonicalName()
- << " is not structured, but this is a structured interface.";
- }
- if (options.GetStability() == Options::Stability::VINTF && !type.IsVintfStability()) {
- err = AidlError::NOT_STRUCTURED;
- LOG(ERROR) << type.GetCanonicalName()
- << " does not have VINTF level stability, but this interface requires it.";
- }
- });
-
+ if (options.IsStructured()) {
+ typenames.IterateTypes([&](const AidlDefinedType& type) {
+ if (type.AsUnstructuredParcelable() != nullptr &&
+ !type.AsUnstructuredParcelable()->IsStableParcelable()) {
+ err = AidlError::NOT_STRUCTURED;
+ LOG(ERROR) << type.GetCanonicalName()
+ << " is not structured, but this is a structured interface.";
+ }
+ });
+ }
if (err != AidlError::OK) {
return err;
}
@@ -695,13 +721,30 @@
int compile_aidl(const Options& options, const IoDelegate& io_delegate) {
const Options::Language lang = options.TargetLanguage();
for (const string& input_file : options.InputFiles()) {
- AidlTypenames typenames;
+ // Create type namespace that will hold the types identified by the parser.
+ // This two namespaces that are specific to the target language will be
+ // unified to AidlTypenames which is agnostic to the target language.
+ cpp::TypeNamespace cpp_types;
+ cpp_types.Init();
+
+ java::JavaTypeNamespace java_types;
+ java_types.Init();
+
+ TypeNamespace* types;
+ if (options.IsCppOutput()) {
+ types = &cpp_types;
+ } else if (lang == Options::Language::JAVA) {
+ types = &java_types;
+ } else {
+ LOG(FATAL) << "Unsupported target language." << endl;
+ return 1;
+ }
vector<AidlDefinedType*> defined_types;
vector<string> imported_files;
- AidlError aidl_err = internals::load_and_validate_aidl(
- input_file, options, io_delegate, &typenames, &defined_types, &imported_files);
+ AidlError aidl_err = internals::load_and_validate_aidl(input_file, options, io_delegate, types,
+ &defined_types, &imported_files);
bool allowError = aidl_err == AidlError::FOUND_PARCELABLE && !options.FailOnParcelable();
if (aidl_err != AidlError::OK && !allowError) {
return 1;
@@ -727,9 +770,10 @@
bool success = false;
if (lang == Options::Language::CPP) {
success =
- cpp::GenerateCpp(output_file_name, options, typenames, *defined_type, io_delegate);
+ cpp::GenerateCpp(output_file_name, options, cpp_types, *defined_type, io_delegate);
} else if (lang == Options::Language::NDK) {
- ndk::GenerateNdk(output_file_name, options, typenames, *defined_type, io_delegate);
+ ndk::GenerateNdk(output_file_name, options, cpp_types.typenames_, *defined_type,
+ io_delegate);
success = true;
} else if (lang == Options::Language::JAVA) {
if (defined_type->AsUnstructuredParcelable() != nullptr) {
@@ -737,7 +781,7 @@
success = true;
} else {
success =
- java::generate_java(output_file_name, defined_type, typenames, io_delegate, options);
+ java::generate_java(output_file_name, defined_type, &java_types, io_delegate, options);
}
} else {
LOG(FATAL) << "Should not reach here" << endl;
@@ -754,18 +798,19 @@
bool dump_mappings(const Options& options, const IoDelegate& io_delegate) {
android::aidl::mappings::SignatureMap all_mappings;
for (const string& input_file : options.InputFiles()) {
- AidlTypenames typenames;
+ java::JavaTypeNamespace java_types;
+ java_types.Init();
vector<AidlDefinedType*> defined_types;
vector<string> imported_files;
AidlError aidl_err = internals::load_and_validate_aidl(
- input_file, options, io_delegate, &typenames, &defined_types, &imported_files);
+ input_file, options, io_delegate, &java_types, &defined_types, &imported_files);
if (aidl_err != AidlError::OK) {
LOG(WARNING) << "AIDL file is invalid.\n";
continue;
}
for (const auto defined_type : defined_types) {
- auto mappings = mappings::generate_mappings(defined_type, typenames);
+ auto mappings = mappings::generate_mappings(defined_type);
all_mappings.insert(mappings.begin(), mappings.end());
}
}
@@ -806,9 +851,10 @@
bool dump_api(const Options& options, const IoDelegate& io_delegate) {
for (const auto& file : options.InputFiles()) {
- AidlTypenames typenames;
+ java::JavaTypeNamespace ns;
+ ns.Init();
vector<AidlDefinedType*> defined_types;
- if (internals::load_and_validate_aidl(file, options, io_delegate, &typenames, &defined_types,
+ if (internals::load_and_validate_aidl(file, options, io_delegate, &ns, &defined_types,
nullptr) == AidlError::OK) {
for (const auto type : defined_types) {
unique_ptr<CodeWriter> writer =
@@ -825,5 +871,5 @@
return true;
}
-} // namespace aidl
} // namespace android
+} // namespace aidl
diff --git a/aidl.h b/aidl.h
index 955b280..7b5628f 100644
--- a/aidl.h
+++ b/aidl.h
@@ -25,6 +25,7 @@
#include "import_resolver.h"
#include "io_delegate.h"
#include "options.h"
+#include "type_namespace.h"
namespace android {
namespace aidl {
@@ -55,14 +56,14 @@
namespace internals {
AidlError load_and_validate_aidl(const std::string& input_file_name, const Options& options,
- const IoDelegate& io_delegate, AidlTypenames* typenames,
+ const IoDelegate& io_delegate, TypeNamespace* types,
vector<AidlDefinedType*>* defined_types,
vector<string>* imported_files);
bool parse_preprocessed_file(const IoDelegate& io_delegate, const std::string& filename,
- AidlTypenames* typenames);
+ TypeNamespace* types, AidlTypenames& typenames);
} // namespace internals
-} // namespace aidl
} // namespace android
+} // namespace aidl
diff --git a/aidl_apicheck.cpp b/aidl_apicheck.cpp
index 97ab848..4bedd17 100644
--- a/aidl_apicheck.cpp
+++ b/aidl_apicheck.cpp
@@ -1,6 +1,5 @@
/*
- * Copyright (C) 2018, The Android Open Source Project
- *
+ * Copyright (C) 2018, The Android Open Source Project *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
@@ -17,15 +16,13 @@
#include "aidl.h"
#include "aidl_language.h"
#include "import_resolver.h"
-#include "logging.h"
#include "options.h"
+#include "type_java.h"
#include <map>
#include <string>
#include <vector>
-#include <android-base/strings.h>
-
namespace android {
namespace aidl {
@@ -178,47 +175,13 @@
return compatible;
}
-static bool are_compatible_enums(const AidlEnumDeclaration& older,
- const AidlEnumDeclaration& newer) {
- if (!are_compatible_types(older.GetBackingType(), newer.GetBackingType())) {
- AIDL_ERROR(newer) << "Changed backing types.";
- return false;
- }
-
- std::map<std::string, const AidlConstantValue*> old_enum_map;
- for (const auto& enumerator : older.GetEnumerators()) {
- old_enum_map[enumerator->GetName()] = enumerator->GetValue();
- }
- std::map<std::string, const AidlConstantValue*> new_enum_map;
- for (const auto& enumerator : newer.GetEnumerators()) {
- new_enum_map[enumerator->GetName()] = enumerator->GetValue();
- }
-
- bool compatible = true;
- for (const auto& [name, value] : old_enum_map) {
- if (new_enum_map.find(name) == new_enum_map.end()) {
- AIDL_ERROR(newer) << "Removed enumerator from " << older.GetCanonicalName() << ": " << name;
- compatible = false;
- continue;
- }
- const string old_value =
- old_enum_map[name]->ValueString(older.GetBackingType(), AidlConstantValueDecorator);
- const string new_value =
- new_enum_map[name]->ValueString(newer.GetBackingType(), AidlConstantValueDecorator);
- if (old_value != new_value) {
- AIDL_ERROR(newer) << "Changed enumerator value: " << older.GetCanonicalName() << "::" << name
- << " from " << old_value << " to " << new_value << ".";
- compatible = false;
- }
- }
- return compatible;
-}
-
bool check_api(const Options& options, const IoDelegate& io_delegate) {
CHECK(options.IsStructured());
CHECK(options.InputFiles().size() == 2) << "--checkapi requires two inputs "
<< "but got " << options.InputFiles().size();
- AidlTypenames old_tns;
+
+ java::JavaTypeNamespace old_ns;
+ old_ns.Init();
const string old_dir = options.InputFiles().at(0);
vector<AidlDefinedType*> old_types;
vector<string> old_files = io_delegate.ListFiles(old_dir);
@@ -227,10 +190,8 @@
return false;
}
for (const auto& file : old_files) {
- if (!android::base::EndsWith(file, ".aidl")) continue;
-
vector<AidlDefinedType*> types;
- if (internals::load_and_validate_aidl(file, options, io_delegate, &old_tns, &types,
+ if (internals::load_and_validate_aidl(file, options, io_delegate, &old_ns, &types,
nullptr /* imported_files */) != AidlError::OK) {
AIDL_ERROR(file) << "Failed to read.";
return false;
@@ -238,7 +199,8 @@
old_types.insert(old_types.end(), types.begin(), types.end());
}
- AidlTypenames new_tns;
+ java::JavaTypeNamespace new_ns;
+ new_ns.Init();
const string new_dir = options.InputFiles().at(1);
vector<AidlDefinedType*> new_types;
vector<string> new_files = io_delegate.ListFiles(new_dir);
@@ -247,10 +209,8 @@
return false;
}
for (const auto& file : new_files) {
- if (!android::base::EndsWith(file, ".aidl")) continue;
-
vector<AidlDefinedType*> types;
- if (internals::load_and_validate_aidl(file, options, io_delegate, &new_tns, &types,
+ if (internals::load_and_validate_aidl(file, options, io_delegate, &new_ns, &types,
nullptr /* imported_files */) != AidlError::OK) {
AIDL_ERROR(file) << "Failed to read.";
return false;
@@ -273,39 +233,26 @@
}
const auto new_type = found->second;
- if (old_type->AsInterface() != nullptr) {
- if (new_type->AsInterface() == nullptr) {
- AIDL_ERROR(new_type) << "Type mismatch: " << old_type->GetCanonicalName()
- << " is changed from " << old_type->GetPreprocessDeclarationName()
- << " to " << new_type->GetPreprocessDeclarationName();
- compatible = false;
- continue;
- }
+ const bool old_is_iface = old_type->AsInterface() != nullptr;
+ const bool new_is_iface = new_type->AsInterface() != nullptr;
+ if (old_is_iface != new_is_iface) {
+ AIDL_ERROR(new_type) << "Type mismatch: " << old_type->GetCanonicalName()
+ << " is changed from " << old_type->GetPreprocessDeclarationName()
+ << " to " << new_type->GetPreprocessDeclarationName();
+ compatible = false;
+ continue;
+ }
+
+ if (old_is_iface) {
compatible &=
are_compatible_interfaces(*(old_type->AsInterface()), *(new_type->AsInterface()));
- } else if (old_type->AsStructuredParcelable() != nullptr) {
- if (new_type->AsStructuredParcelable() == nullptr) {
- AIDL_ERROR(new_type) << "Parcelable" << new_type->GetCanonicalName()
- << " is not structured. ";
- compatible = false;
- continue;
- }
+ } else {
+ CHECK(old_type->AsStructuredParcelable() != nullptr)
+ << "Parcelable" << old_type->GetCanonicalName() << " is not structured. ";
+ CHECK(new_type->AsStructuredParcelable() != nullptr)
+ << "Parcelable" << new_type->GetCanonicalName() << " is not structured. ";
compatible &= are_compatible_parcelables(*(old_type->AsStructuredParcelable()),
*(new_type->AsStructuredParcelable()));
- } else if (old_type->AsEnumDeclaration() != nullptr) {
- if (new_type->AsEnumDeclaration() == nullptr) {
- AIDL_ERROR(new_type) << "Type mismatch: " << old_type->GetCanonicalName()
- << " is changed from " << old_type->GetPreprocessDeclarationName()
- << " to " << new_type->GetPreprocessDeclarationName();
- compatible = false;
- continue;
- }
- compatible &=
- are_compatible_enums(*(old_type->AsEnumDeclaration()), *(new_type->AsEnumDeclaration()));
- } else {
- AIDL_ERROR(old_type) << "Unsupported type " << old_type->GetPreprocessDeclarationName()
- << " for " << old_type->GetCanonicalName();
- compatible = false;
}
}
diff --git a/aidl_const_expressions.cpp b/aidl_const_expressions.cpp
deleted file mode 100644
index dbd1f8b..0000000
--- a/aidl_const_expressions.cpp
+++ /dev/null
@@ -1,886 +0,0 @@
-/*
- * Copyright (C) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "aidl_language.h"
-#include "logging.h"
-
-#include <stdlib.h>
-#include <algorithm>
-#include <iostream>
-#include <memory>
-
-#include <android-base/parsedouble.h>
-#include <android-base/parseint.h>
-#include <android-base/strings.h>
-
-using android::base::ConsumeSuffix;
-using android::base::Join;
-using std::string;
-using std::unique_ptr;
-using std::vector;
-
-#define SHOULD_NOT_REACH() CHECK(false) << LOG(FATAL) << ": should not reach here: "
-#define OPEQ(__y__) (string(op_) == string(__y__))
-#define COMPUTE_UNARY(__op__) \
- if (op == string(#__op__)) return __op__ val;
-#define COMPUTE_BINARY(__op__) \
- if (op == string(#__op__)) return lval __op__ rval;
-#define OP_IS_BIN_ARITHMETIC (OPEQ("+") || OPEQ("-") || OPEQ("*") || OPEQ("/") || OPEQ("%"))
-#define OP_IS_BIN_BITFLIP (OPEQ("|") || OPEQ("^") || OPEQ("&"))
-#define OP_IS_BIN_COMP \
- (OPEQ("<") || OPEQ(">") || OPEQ("<=") || OPEQ(">=") || OPEQ("==") || OPEQ("!="))
-#define OP_IS_BIN_SHIFT (OPEQ(">>") || OPEQ("<<"))
-#define OP_IS_BIN_LOGICAL (OPEQ("||") || OPEQ("&&"))
-
-// NOLINT to suppress missing parentheses warnings about __def__.
-#define SWITCH_KIND(__cond__, __action__, __def__) \
- switch (__cond__) { \
- case Type::BOOLEAN: \
- __action__(bool); \
- case Type::INT8: \
- __action__(int8_t); \
- case Type::INT32: \
- __action__(int32_t); \
- case Type::INT64: \
- __action__(int64_t); \
- default: \
- __def__; /* NOLINT */ \
- }
-
-template <class T>
-T handleUnary(const string& op, T val) {
- COMPUTE_UNARY(+)
- COMPUTE_UNARY(-)
- COMPUTE_UNARY(!)
- COMPUTE_UNARY(~)
- // Should not reach here.
- SHOULD_NOT_REACH() << "Could not handleUnary for " << op << " " << val;
- return static_cast<T>(0xdeadbeef);
-}
-
-template <class T>
-T handleBinaryCommon(T lval, const string& op, T rval) {
- COMPUTE_BINARY(+)
- COMPUTE_BINARY(-)
- COMPUTE_BINARY(*)
- COMPUTE_BINARY(/)
- COMPUTE_BINARY(%)
- COMPUTE_BINARY(|)
- COMPUTE_BINARY(^)
- COMPUTE_BINARY(&)
- // comparison operators: return 0 or 1 by nature.
- COMPUTE_BINARY(==)
- COMPUTE_BINARY(!=)
- COMPUTE_BINARY(<)
- COMPUTE_BINARY(>)
- COMPUTE_BINARY(<=)
- COMPUTE_BINARY(>=)
- // Should not reach here.
- SHOULD_NOT_REACH() << "Could not handleBinaryCommon for " << lval << " " << op << " " << rval;
- return static_cast<T>(0xdeadbeef);
-}
-
-template <class T>
-T handleShift(T lval, const string& op, int64_t rval) {
- // just cast rval to int64_t and it should fit.
- COMPUTE_BINARY(>>)
- COMPUTE_BINARY(<<)
- // Should not reach here.
- SHOULD_NOT_REACH() << "Could not handleShift for " << lval << " " << op << " " << rval;
- return static_cast<T>(0xdeadbeef);
-}
-
-bool handleLogical(bool lval, const string& op, bool rval) {
- COMPUTE_BINARY(||);
- COMPUTE_BINARY(&&);
- // Should not reach here.
- SHOULD_NOT_REACH() << "Could not handleLogical for " << lval << " " << op << " " << rval;
- return false;
-}
-
-static bool isValidLiteralChar(char c) {
- return !(c <= 0x1f || // control characters are < 0x20
- c >= 0x7f || // DEL is 0x7f
- c == '\\'); // Disallow backslashes for future proofing.
-}
-
-bool AidlUnaryConstExpression::IsCompatibleType(Type type, const string& op) {
- // Verify the unary type here
- switch (type) {
- case Type::BOOLEAN: // fall-through
- case Type::INT8: // fall-through
- case Type::INT32: // fall-through
- case Type::INT64:
- return true;
- case Type::FLOATING:
- return (op == "+" || op == "-");
- default:
- return false;
- }
-}
-
-bool AidlBinaryConstExpression::AreCompatibleTypes(Type t1, Type t2) {
- switch (t1) {
- case Type::STRING:
- if (t2 == Type::STRING) {
- return true;
- }
- break;
- case Type::BOOLEAN: // fall-through
- case Type::INT8: // fall-through
- case Type::INT32: // fall-through
- case Type::INT64:
- switch (t2) {
- case Type::BOOLEAN: // fall-through
- case Type::INT8: // fall-through
- case Type::INT32: // fall-through
- case Type::INT64:
- return true;
- break;
- default:
- break;
- }
- break;
- default:
- break;
- }
-
- return false;
-}
-
-// Returns the promoted kind for both operands
-AidlConstantValue::Type AidlBinaryConstExpression::UsualArithmeticConversion(Type left,
- Type right) {
- // These are handled as special cases
- CHECK(left != Type::STRING && right != Type::STRING);
- CHECK(left != Type::FLOATING && right != Type::FLOATING);
-
- // Kinds in concern: bool, (u)int[8|32|64]
- if (left == right) return left; // easy case
- if (left == Type::BOOLEAN) return right;
- if (right == Type::BOOLEAN) return left;
-
- return left < right ? right : left;
-}
-
-// Returns the promoted integral type where INT32 is the smallest type
-AidlConstantValue::Type AidlBinaryConstExpression::IntegralPromotion(Type in) {
- return (Type::INT32 < in) ? in : Type::INT32;
-}
-
-template <typename T>
-T AidlConstantValue::cast() const {
- CHECK(is_evaluated_ == true);
-
-#define CASE_CAST_T(__type__) return static_cast<T>(static_cast<__type__>(final_value_));
-
- SWITCH_KIND(final_type_, CASE_CAST_T, SHOULD_NOT_REACH(); return 0;);
-}
-
-AidlConstantValue* AidlConstantValue::Boolean(const AidlLocation& location, bool value) {
- return new AidlConstantValue(location, Type::BOOLEAN, value ? "true" : "false");
-}
-
-AidlConstantValue* AidlConstantValue::Character(const AidlLocation& location, char value) {
- if (!isValidLiteralChar(value)) {
- AIDL_ERROR(location) << "Invalid character literal " << value;
- return new AidlConstantValue(location, Type::ERROR, "");
- }
- return new AidlConstantValue(location, Type::CHARACTER, string("'") + value + "'");
-}
-
-AidlConstantValue* AidlConstantValue::Floating(const AidlLocation& location,
- const std::string& value) {
- return new AidlConstantValue(location, Type::FLOATING, value);
-}
-
-bool AidlConstantValue::IsHex(const string& value) {
- if (value.length() > (sizeof("0x") - 1)) {
- if (value[0] == '0' && (value[1] == 'x' || value[1] == 'X')) {
- return true;
- }
- }
- return false;
-}
-
-bool AidlConstantValue::ParseIntegral(const string& value, int64_t* parsed_value,
- Type* parsed_type) {
- bool isLong = false;
-
- if (parsed_value == nullptr || parsed_type == nullptr) {
- return false;
- }
-
- if (IsHex(value)) {
- bool parseOK = false;
- uint32_t rawValue32;
-
- // AIDL considers 'const int foo = 0xffffffff' as -1, but if we want to
- // handle that when computing constant expressions, then we need to
- // represent 0xffffffff as a uint32_t. However, AIDL only has signed types;
- // so we parse as an unsigned int when possible and then cast to a signed
- // int. One example of this is in ICameraService.aidl where a constant int
- // is used for bit manipulations which ideally should be handled with an
- // unsigned int.
- parseOK = android::base::ParseUint<uint32_t>(value, &rawValue32);
- if (parseOK) {
- *parsed_value = static_cast<int32_t>(rawValue32);
- *parsed_type = Type::INT32;
- } else {
- parseOK = android::base::ParseInt<int64_t>(value, parsed_value);
- if (!parseOK) {
- *parsed_type = Type::ERROR;
- return false;
- }
-
- *parsed_type = Type::INT64;
- }
- return true;
- }
-
- if (value[value.size() - 1] == 'l' || value[value.size() - 1] == 'L') {
- isLong = true;
- *parsed_type = Type::INT64;
- }
-
- string value_substr = value.substr(0, isLong ? value.size() - 1 : value.size());
- bool parseOK = android::base::ParseInt<int64_t>(value_substr, parsed_value);
- if (!parseOK) {
- *parsed_type = Type::ERROR;
- return false;
- }
-
- if (!isLong) {
- // guess literal type.
- if (*parsed_value <= INT8_MAX && *parsed_value >= INT8_MIN) {
- *parsed_type = Type::INT8;
- } else if (*parsed_value <= INT32_MAX && *parsed_value >= INT32_MIN) {
- *parsed_type = Type::INT32;
- } else {
- *parsed_type = Type::INT64;
- }
- }
- return true;
-}
-
-AidlConstantValue* AidlConstantValue::Integral(const AidlLocation& location, const string& value) {
- CHECK(!value.empty());
-
- Type parsed_type;
- int64_t parsed_value = 0;
- bool success = ParseIntegral(value, &parsed_value, &parsed_type);
- if (!success) {
- return nullptr;
- }
-
- return new AidlConstantValue(location, parsed_type, parsed_value, value);
-}
-
-AidlConstantValue* AidlConstantValue::Array(
- const AidlLocation& location, std::unique_ptr<vector<unique_ptr<AidlConstantValue>>> values) {
- return new AidlConstantValue(location, Type::ARRAY, std::move(values));
-}
-
-AidlConstantValue* AidlConstantValue::String(const AidlLocation& location, const string& value) {
- for (size_t i = 0; i < value.length(); ++i) {
- if (!isValidLiteralChar(value[i])) {
- AIDL_ERROR(location) << "Found invalid character at index " << i << " in string constant '"
- << value << "'";
- return new AidlConstantValue(location, Type::ERROR, "");
- }
- }
-
- return new AidlConstantValue(location, Type::STRING, value);
-}
-
-AidlConstantValue* AidlConstantValue::ShallowIntegralCopy(const AidlConstantValue& other) {
- // TODO(b/142894901): Perform full proper copy
- AidlTypeSpecifier type = AidlTypeSpecifier(AIDL_LOCATION_HERE, "long", false, nullptr, "");
- // TODO(b/142722772) CheckValid() should be called before ValueString()
- if (!other.CheckValid()) {
- AIDL_FATAL(other) << "Invalid value for ShallowIntegralCopy";
- }
- if (!other.evaluate(type)) {
- AIDL_FATAL(other) << "Unsupported type for ShallowIntegralCopy: " << ToString(other.GetType());
- }
-
- AidlConstantValue* result =
- Integral(AIDL_LOCATION_HERE, other.ValueString(type, AidlConstantValueDecorator));
- if (result == nullptr) {
- AIDL_FATAL(other) << "Unable to perform ShallowIntegralCopy.";
- }
- return result;
-}
-
-string AidlConstantValue::ValueString(const AidlTypeSpecifier& type,
- const ConstantValueDecorator& decorator) const {
- if (type.IsGeneric()) {
- AIDL_ERROR(type) << "Generic type cannot be specified with a constant literal.";
- return "";
- }
- if (!is_evaluated_) {
- // TODO(b/142722772) CheckValid() should be called before ValueString()
- bool success = CheckValid();
- success &= evaluate(type);
- if (!success) {
- // the detailed error message shall be printed in evaluate
- return "";
- }
- }
- if (!is_valid_) {
- AIDL_ERROR(this) << "Invalid constant value: " + value_;
- return "";
- }
- const string& type_string = type.GetName();
- int err = 0;
-
- switch (final_type_) {
- case Type::CHARACTER:
- if (type_string == "char") {
- return decorator(type, final_string_value_);
- }
- err = -1;
- break;
- case Type::STRING:
- if (type_string == "String") {
- return decorator(type, final_string_value_);
- }
- err = -1;
- break;
- case Type::BOOLEAN: // fall-through
- case Type::INT8: // fall-through
- case Type::INT32: // fall-through
- case Type::INT64:
- if (type_string == "byte") {
- if (final_value_ > INT8_MAX || final_value_ < INT8_MIN) {
- err = -1;
- break;
- }
- return decorator(type, std::to_string(static_cast<int8_t>(final_value_)));
- } else if (type_string == "int") {
- if (final_value_ > INT32_MAX || final_value_ < INT32_MIN) {
- err = -1;
- break;
- }
- return decorator(type, std::to_string(static_cast<int32_t>(final_value_)));
- } else if (type_string == "long") {
- return decorator(type, std::to_string(final_value_));
- } else if (type_string == "boolean") {
- return decorator(type, final_value_ ? "true" : "false");
- }
- err = -1;
- break;
- case Type::ARRAY: {
- if (!type.IsArray()) {
- err = -1;
- break;
- }
- vector<string> value_strings;
- value_strings.reserve(values_.size());
- bool success = true;
-
- for (const auto& value : values_) {
- const AidlTypeSpecifier& array_base = type.ArrayBase();
- const string value_string = value->ValueString(array_base, decorator);
- if (value_string.empty()) {
- success = false;
- break;
- }
- value_strings.push_back(value_string);
- }
- if (!success) {
- err = -1;
- break;
- }
-
- return decorator(type, "{" + Join(value_strings, ", ") + "}");
- }
- case Type::FLOATING: {
- std::string_view raw_view(value_.c_str());
- bool is_float_literal = ConsumeSuffix(&raw_view, "f");
- std::string stripped_value = std::string(raw_view);
-
- if (type_string == "double") {
- double parsed_value;
- if (!android::base::ParseDouble(stripped_value, &parsed_value)) {
- AIDL_ERROR(this) << "Could not parse " << value_;
- err = -1;
- break;
- }
- return decorator(type, std::to_string(parsed_value));
- }
- if (is_float_literal && type_string == "float") {
- float parsed_value;
- if (!android::base::ParseFloat(stripped_value, &parsed_value)) {
- AIDL_ERROR(this) << "Could not parse " << value_;
- err = -1;
- break;
- }
- return decorator(type, std::to_string(parsed_value) + "f");
- }
- err = -1;
- break;
- }
- default:
- err = -1;
- break;
- }
-
- CHECK(err != 0);
- AIDL_ERROR(this) << "Invalid type specifier for " << ToString(final_type_) << ": " << type_string;
- return "";
-}
-
-bool AidlConstantValue::CheckValid() const {
- // Nothing needs to be checked here. The constant value will be validated in
- // the constructor or in the evaluate() function.
- if (is_evaluated_) return is_valid_;
-
- switch (type_) {
- case Type::BOOLEAN: // fall-through
- case Type::INT8: // fall-through
- case Type::INT32: // fall-through
- case Type::INT64: // fall-through
- case Type::ARRAY: // fall-through
- case Type::CHARACTER: // fall-through
- case Type::STRING: // fall-through
- case Type::FLOATING: // fall-through
- case Type::UNARY: // fall-through
- case Type::BINARY:
- is_valid_ = true;
- break;
- default:
- AIDL_FATAL(this) << "Unrecognized constant value type: " << ToString(type_);
- return false;
- }
-
- return true;
-}
-
-bool AidlConstantValue::evaluate(const AidlTypeSpecifier& type) const {
- if (is_evaluated_) {
- return is_valid_;
- }
- int err = 0;
- is_evaluated_ = true;
-
- switch (type_) {
- case Type::ARRAY: {
- if (!type.IsArray()) {
- AIDL_ERROR(this) << "Invalid constant array type: " << type.GetName();
- err = -1;
- break;
- }
- Type array_type = Type::ERROR;
- bool success = true;
- for (const auto& value : values_) {
- success = value->CheckValid();
- if (success) {
- success = value->evaluate(type.ArrayBase());
- if (!success) {
- AIDL_ERROR(this) << "Invalid array element: " << value->value_;
- break;
- }
- if (array_type == Type::ERROR) {
- array_type = value->final_type_;
- } else if (!AidlBinaryConstExpression::AreCompatibleTypes(array_type,
- value->final_type_)) {
- AIDL_ERROR(this) << "Incompatible array element type: " << ToString(value->final_type_)
- << ". Expecting type compatible with " << ToString(array_type);
- success = false;
- break;
- }
- } else {
- break;
- }
- }
- if (!success) {
- err = -1;
- break;
- }
- final_type_ = type_;
- break;
- }
- case Type::BOOLEAN:
- if ((value_ != "true") && (value_ != "false")) {
- AIDL_ERROR(this) << "Invalid constant boolean value: " << value_;
- err = -1;
- break;
- }
- final_value_ = (value_ == "true") ? 1 : 0;
- final_type_ = type_;
- break;
- case Type::INT8: // fall-through
- case Type::INT32: // fall-through
- case Type::INT64:
- // Parsing happens in the constructor
- final_type_ = type_;
- break;
- case Type::CHARACTER: // fall-through
- case Type::STRING:
- final_string_value_ = value_;
- final_type_ = type_;
- break;
- case Type::FLOATING:
- // Just parse on the fly in ValueString
- final_type_ = type_;
- break;
- default:
- AIDL_FATAL(this) << "Unrecognized constant value type: " << ToString(type_);
- err = -1;
- }
-
- return (err == 0) ? true : false;
-}
-
-string AidlConstantValue::ToString(Type type) {
- switch (type) {
- case Type::ARRAY:
- return "a literal array";
- case Type::BOOLEAN:
- return "a literal boolean";
- case Type::CHARACTER:
- return "a literal char";
- case Type::INT8:
- return "an int8 literal";
- case Type::INT32:
- return "an int32 literal";
- case Type::INT64:
- return "an int64 literal";
- case Type::STRING:
- return "a literal string";
- case Type::ERROR:
- LOG(FATAL) << "aidl internal error: error type failed to halt program";
- return "";
- case Type::UNARY:
- return "a unary expression";
- case Type::BINARY:
- return "a binary expression";
- default:
- LOG(FATAL) << "aidl internal error: unknown constant type: " << static_cast<int>(type);
- return ""; // not reached
- }
-}
-
-bool AidlUnaryConstExpression::CheckValid() const {
- if (is_evaluated_) return is_valid_;
- CHECK(unary_ != nullptr);
-
- is_valid_ = unary_->CheckValid();
- if (!is_valid_) {
- final_type_ = Type::ERROR;
- return false;
- }
-
- return true;
-}
-
-bool AidlUnaryConstExpression::evaluate(const AidlTypeSpecifier& type) const {
- if (is_evaluated_) {
- return is_valid_;
- }
- is_evaluated_ = true;
-
- // Recursively evaluate the expression tree
- if (!unary_->is_evaluated_) {
- // TODO(b/142722772) CheckValid() should be called before ValueString()
- bool success = CheckValid();
- success &= unary_->evaluate(type);
- if (!success) {
- is_valid_ = false;
- return false;
- }
- }
- if (!unary_->is_valid_ || !IsCompatibleType(unary_->final_type_, op_)) {
- AIDL_ERROR(type) << "Invalid constant unary expression: " + value_;
- is_valid_ = false;
- return false;
- }
- final_type_ = unary_->final_type_;
-
- if (final_type_ == Type::FLOATING) {
- // don't do anything here. ValueString() will handle everything.
- is_valid_ = true;
- return true;
- }
-
-#define CASE_UNARY(__type__) \
- final_value_ = handleUnary(op_, static_cast<__type__>(unary_->final_value_)); \
- return true;
-
- SWITCH_KIND(final_type_, CASE_UNARY, SHOULD_NOT_REACH(); final_type_ = Type::ERROR;
- is_valid_ = false; return false;)
-}
-
-string AidlUnaryConstExpression::ValueString(const AidlTypeSpecifier& type,
- const ConstantValueDecorator& decorator) const {
- if (type.IsGeneric()) {
- AIDL_ERROR(type) << "Generic type cannot be specified with a constant literal.";
- return "";
- }
- if (!is_evaluated_) {
- // TODO(b/142722772) CheckValid() should be called before ValueString()
- bool success = CheckValid();
- success &= evaluate(type);
- if (!success) {
- // A detailed error message shall be printed in evaluate()
- return "";
- }
- }
- if (!is_valid_) {
- AIDL_ERROR(this) << "Invalid constant unary expression";
- return "";
- }
-
- return AidlConstantValue::ValueString(type, decorator);
-}
-
-bool AidlBinaryConstExpression::CheckValid() const {
- bool success = false;
- if (is_evaluated_) return is_valid_;
- CHECK(left_val_ != nullptr);
- CHECK(right_val_ != nullptr);
-
- success = left_val_->CheckValid();
- if (!success) {
- final_type_ = Type::ERROR;
- AIDL_ERROR(this) << "Invalid left operand in binary expression: " + value_;
- }
-
- success = right_val_->CheckValid();
- if (!success) {
- AIDL_ERROR(this) << "Invalid right operand in binary expression: " + value_;
- final_type_ = Type::ERROR;
- }
-
- if (final_type_ == Type::ERROR) {
- is_valid_ = false;
- return false;
- }
-
- is_valid_ = true;
- return true;
-}
-
-bool AidlBinaryConstExpression::evaluate(const AidlTypeSpecifier& type) const {
- if (is_evaluated_) {
- return is_valid_;
- }
- is_evaluated_ = true;
- CHECK(left_val_ != nullptr);
- CHECK(right_val_ != nullptr);
-
- // Recursively evaluate the binary expression tree
- if (!left_val_->is_evaluated_ || !right_val_->is_evaluated_) {
- // TODO(b/142722772) CheckValid() should be called before ValueString()
- bool success = CheckValid();
- success &= left_val_->evaluate(type);
- success &= right_val_->evaluate(type);
- if (!success) {
- is_valid_ = false;
- return false;
- }
- }
- if (!left_val_->is_valid_ || !right_val_->is_valid_) {
- is_valid_ = false;
- return false;
- }
- is_valid_ = AreCompatibleTypes(left_val_->final_type_, right_val_->final_type_);
- if (!is_valid_) {
- return false;
- }
-
- bool isArithmeticOrBitflip = OP_IS_BIN_ARITHMETIC || OP_IS_BIN_BITFLIP;
-
- // Handle String case first
- if (left_val_->final_type_ == Type::STRING) {
- if (!OPEQ("+")) {
- // invalid operation on strings
- final_type_ = Type::ERROR;
- is_valid_ = false;
- return false;
- }
-
- // Remove trailing " from lhs
- const string& lhs = left_val_->final_string_value_;
- if (lhs.back() != '"') {
- AIDL_ERROR(this) << "'" << lhs << "' is missing a trailing quote.";
- final_type_ = Type::ERROR;
- is_valid_ = false;
- return false;
- }
- const string& rhs = right_val_->final_string_value_;
- // Remove starting " from rhs
- if (rhs.front() != '"') {
- AIDL_ERROR(this) << "'" << rhs << "' is missing a leading quote.";
- final_type_ = Type::ERROR;
- is_valid_ = false;
- return false;
- }
-
- final_string_value_ = string(lhs.begin(), lhs.end() - 1).append(rhs.begin() + 1, rhs.end());
- final_type_ = Type::STRING;
- return true;
- }
-
- // TODO(b/139877950) Add support for handling overflows
-
- // CASE: + - * / % | ^ & < > <= >= == !=
- if (isArithmeticOrBitflip || OP_IS_BIN_COMP) {
- if (op_ == "/" && right_val_->final_value_ == 0) {
- final_type_ = Type::ERROR;
- is_valid_ = false;
- AIDL_ERROR(this) << "Divide by 0! const_expr: " + value_;
- return false;
- }
-
- // promoted kind for both operands.
- Type promoted = UsualArithmeticConversion(IntegralPromotion(left_val_->final_type_),
- IntegralPromotion(right_val_->final_type_));
- // result kind.
- final_type_ = isArithmeticOrBitflip
- ? promoted // arithmetic or bitflip operators generates promoted type
- : Type::BOOLEAN; // comparison operators generates bool
-
-#define CASE_BINARY_COMMON(__type__) \
- final_value_ = handleBinaryCommon(static_cast<__type__>(left_val_->final_value_), op_, \
- static_cast<__type__>(right_val_->final_value_)); \
- return true;
-
- SWITCH_KIND(promoted, CASE_BINARY_COMMON, SHOULD_NOT_REACH(); final_type_ = Type::ERROR;
- is_valid_ = false; return false;)
- }
-
- // CASE: << >>
- string newOp = op_;
- if (OP_IS_BIN_SHIFT) {
- final_type_ = IntegralPromotion(left_val_->final_type_);
- // instead of promoting rval, simply casting it to int64 should also be good.
- int64_t numBits = right_val_->cast<int64_t>();
- if (numBits < 0) {
- // shifting with negative number of bits is undefined in C. In HIDL it
- // is defined as shifting into the other direction.
- newOp = OPEQ("<<") ? ">>" : "<<";
- numBits = -numBits;
- }
-
-#define CASE_SHIFT(__type__) \
- final_value_ = handleShift(static_cast<__type__>(left_val_->final_value_), newOp, numBits); \
- return true;
-
- SWITCH_KIND(final_type_, CASE_SHIFT, SHOULD_NOT_REACH(); final_type_ = Type::ERROR;
- is_valid_ = false; return false;)
- }
-
- // CASE: && ||
- if (OP_IS_BIN_LOGICAL) {
- final_type_ = Type::BOOLEAN;
- // easy; everything is bool.
- final_value_ = handleLogical(left_val_->final_value_, op_, right_val_->final_value_);
- return true;
- }
-
- SHOULD_NOT_REACH();
- is_valid_ = false;
- return false;
-}
-
-string AidlBinaryConstExpression::ValueString(const AidlTypeSpecifier& type,
- const ConstantValueDecorator& decorator) const {
- if (type.IsGeneric()) {
- AIDL_ERROR(type) << "Generic type cannot be specified with a constant literal.";
- return "";
- }
- if (!is_evaluated_) {
- // TODO(b/142722772) CheckValid() should be called before ValueString()
- bool success = CheckValid();
- success &= evaluate(type);
- if (!success) {
- AIDL_ERROR(this) << "Invalid constant binary expression";
- return "";
- }
- }
- if (!is_valid_) {
- AIDL_ERROR(this) << "Invalid constant binary expression";
- return "";
- }
-
- return AidlConstantValue::ValueString(type, decorator);
-}
-
-AidlConstantValue::AidlConstantValue(const AidlLocation& location, Type parsed_type,
- int64_t parsed_value, const string& checked_value)
- : AidlNode(location),
- type_(parsed_type),
- value_(checked_value),
- is_valid_(true),
- is_evaluated_(true),
- final_type_(parsed_type),
- final_value_(parsed_value) {
- CHECK(!value_.empty() || type_ == Type::ERROR);
- CHECK(type_ == Type::INT8 || type_ == Type::INT32 || type_ == Type::INT64);
-}
-
-AidlConstantValue::AidlConstantValue(const AidlLocation& location, Type type,
- const string& checked_value)
- : AidlNode(location),
- type_(type),
- value_(checked_value),
- is_valid_(false),
- is_evaluated_(false),
- final_type_(type) {
- CHECK(!value_.empty() || type_ == Type::ERROR);
- switch (type_) {
- case Type::INT8:
- case Type::INT32:
- case Type::INT64:
- case Type::ARRAY:
- AIDL_FATAL(this) << "Invalid type: " << ToString(type_);
- break;
- default:
- break;
- }
-}
-
-AidlConstantValue::AidlConstantValue(const AidlLocation& location, Type type,
- std::unique_ptr<vector<unique_ptr<AidlConstantValue>>> values)
- : AidlNode(location),
- type_(type),
- values_(std::move(*values)),
- is_valid_(false),
- is_evaluated_(false),
- final_type_(type) {
- CHECK(type_ == Type::ARRAY);
-}
-
-AidlUnaryConstExpression::AidlUnaryConstExpression(const AidlLocation& location, const string& op,
- std::unique_ptr<AidlConstantValue> rval)
- : AidlConstantValue(location, Type::UNARY, op + rval->value_),
- unary_(std::move(rval)),
- op_(op) {
- final_type_ = Type::UNARY;
-}
-
-AidlBinaryConstExpression::AidlBinaryConstExpression(const AidlLocation& location,
- std::unique_ptr<AidlConstantValue> lval,
- const string& op,
- std::unique_ptr<AidlConstantValue> rval)
- : AidlConstantValue(location, Type::BINARY, lval->value_ + op + rval->value_),
- left_val_(std::move(lval)),
- right_val_(std::move(rval)),
- op_(op) {
- final_type_ = Type::BINARY;
-}
diff --git a/aidl_language.cpp b/aidl_language.cpp
index e27dbbe..547816a 100644
--- a/aidl_language.cpp
+++ b/aidl_language.cpp
@@ -1,19 +1,3 @@
-/*
- * Copyright (C) 2015, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
#include "aidl_language.h"
#include "aidl_typenames.h"
@@ -21,6 +5,7 @@
#include <stdlib.h>
#include <string.h>
#include <algorithm>
+#include <cassert>
#include <iostream>
#include <set>
#include <sstream>
@@ -33,8 +18,8 @@
#include "aidl_language_y.h"
#include "logging.h"
-
-#include "aidl.h"
+#include "type_java.h"
+#include "type_namespace.h"
#ifdef _WIN32
int isatty(int fd)
@@ -54,22 +39,6 @@
using std::unique_ptr;
using std::vector;
-namespace {
-bool is_java_keyword(const char* str) {
- static const std::vector<std::string> kJavaKeywords{
- "abstract", "assert", "boolean", "break", "byte", "case", "catch",
- "char", "class", "const", "continue", "default", "do", "double",
- "else", "enum", "extends", "final", "finally", "float", "for",
- "goto", "if", "implements", "import", "instanceof", "int", "interface",
- "long", "native", "new", "package", "private", "protected", "public",
- "return", "short", "static", "strictfp", "super", "switch", "synchronized",
- "this", "throw", "throws", "transient", "try", "void", "volatile",
- "while", "true", "false", "null",
- };
- return std::find(kJavaKeywords.begin(), kJavaKeywords.end(), str) != kJavaKeywords.end();
-}
-} // namespace
-
void yylex_init(void **);
void yylex_destroy(void *);
void yyset_in(FILE *f, void *);
@@ -107,125 +76,30 @@
static const string kNullable("nullable");
static const string kUtf8InCpp("utf8InCpp");
-static const string kVintfStability("VintfStability");
static const string kUnsupportedAppUsage("UnsupportedAppUsage");
static const string kSystemApi("SystemApi");
static const string kStableParcelable("JavaOnlyStableParcelable");
-static const string kBacking("Backing");
-static const std::map<string, std::map<std::string, std::string>> kAnnotationParameters{
- {kNullable, {}},
- {kUtf8InCpp, {}},
- {kVintfStability, {}},
- {kUnsupportedAppUsage,
- {{"expectedSignature", "String"},
- {"implicitMember", "String"},
- {"maxTargetSdk", "int"},
- {"publicAlternatives", "String"},
- {"trackingBug", "long"}}},
- {kSystemApi, {}},
- {kStableParcelable, {}},
- {kBacking, {{"type", "String"}}}};
+static const set<string> kAnnotationNames{kNullable, kUtf8InCpp, kUnsupportedAppUsage, kSystemApi,
+ kStableParcelable};
-AidlAnnotation* AidlAnnotation::Parse(
- const AidlLocation& location, const string& name,
- std::map<std::string, std::shared_ptr<AidlConstantValue>>* parameter_list) {
- if (kAnnotationParameters.find(name) == kAnnotationParameters.end()) {
+AidlAnnotation* AidlAnnotation::Parse(const AidlLocation& location, const string& name) {
+ if (kAnnotationNames.find(name) == kAnnotationNames.end()) {
std::ostringstream stream;
stream << "'" << name << "' is not a recognized annotation. ";
stream << "It must be one of:";
- for (const auto& kv : kAnnotationParameters) {
- stream << " " << kv.first;
+ for (const string& kv : kAnnotationNames) {
+ stream << " " << kv;
}
stream << ".";
AIDL_ERROR(location) << stream.str();
return nullptr;
}
- if (parameter_list == nullptr) {
- return new AidlAnnotation(location, name);
- }
-
- return new AidlAnnotation(location, name, std::move(*parameter_list));
+ return new AidlAnnotation(location, name);
}
AidlAnnotation::AidlAnnotation(const AidlLocation& location, const string& name)
- : AidlAnnotation(location, name, {}) {}
-
-AidlAnnotation::AidlAnnotation(
- const AidlLocation& location, const string& name,
- std::map<std::string, std::shared_ptr<AidlConstantValue>>&& parameters)
- : AidlNode(location), name_(name), parameters_(std::move(parameters)) {}
-
-bool AidlAnnotation::CheckValid() const {
- auto supported_params_iterator = kAnnotationParameters.find(GetName());
- if (supported_params_iterator == kAnnotationParameters.end()) {
- AIDL_ERROR(this) << GetName() << " annotation does not have any supported parameters.";
- return false;
- }
- const auto& supported_params = supported_params_iterator->second;
- for (const auto& name_and_param : parameters_) {
- const std::string& param_name = name_and_param.first;
- const std::shared_ptr<AidlConstantValue>& param = name_and_param.second;
- if (!param->CheckValid()) {
- AIDL_ERROR(this) << "Invalid value for parameter " << param_name << " on annotation "
- << GetName() << ".";
- return false;
- }
- auto parameter_mapping_it = supported_params.find(param_name);
- if (parameter_mapping_it == supported_params.end()) {
- std::ostringstream stream;
- stream << "Parameter " << param_name << " not supported ";
- stream << "for annotation " << GetName() << ".";
- stream << "It must be one of:";
- for (const auto& kv : supported_params) {
- stream << " " << kv.first;
- }
- AIDL_ERROR(this) << stream.str();
- return false;
- }
- AidlTypeSpecifier type{AIDL_LOCATION_HERE, parameter_mapping_it->second, false, nullptr, ""};
- const std::string param_value = param->ValueString(type, AidlConstantValueDecorator);
- // Assume error on empty string.
- if (param_value == "") {
- AIDL_ERROR(this) << "Invalid value for parameter " << param_name << " on annotation "
- << GetName() << ".";
- return false;
- }
- }
- return true;
-}
-
-std::map<std::string, std::string> AidlAnnotation::AnnotationParams(
- const ConstantValueDecorator& decorator) const {
- std::map<std::string, std::string> raw_params;
- const auto& supported_params = kAnnotationParameters.at(GetName());
- for (const auto& name_and_param : parameters_) {
- const std::string& param_name = name_and_param.first;
- const std::shared_ptr<AidlConstantValue>& param = name_and_param.second;
- AidlTypeSpecifier type{AIDL_LOCATION_HERE, supported_params.at(param_name), false, nullptr, ""};
- if (!param->CheckValid()) {
- AIDL_ERROR(this) << "Invalid value for parameter " << param_name << " on annotation "
- << GetName() << ".";
- raw_params.clear();
- return raw_params;
- }
-
- raw_params.emplace(param_name, param->ValueString(type, decorator));
- }
- return raw_params;
-}
-
-std::string AidlAnnotation::ToString(const ConstantValueDecorator& decorator) const {
- if (parameters_.empty()) {
- return "@" + GetName();
- } else {
- vector<string> param_strings;
- for (const auto& [name, value] : AnnotationParams(decorator)) {
- param_strings.emplace_back(name + "=" + value);
- }
- return "@" + GetName() + "(" + Join(param_strings, ", ") + ")";
- }
-}
+ : AidlNode(location), name_(name) {}
static bool HasAnnotation(const vector<AidlAnnotation>& annotations, const string& name) {
for (const auto& a : annotations) {
@@ -236,16 +110,6 @@
return false;
}
-static const AidlAnnotation* GetAnnotation(const vector<AidlAnnotation>& annotations,
- const string& name) {
- for (const auto& a : annotations) {
- if (a.GetName() == name) {
- return &a;
- }
- }
- return nullptr;
-}
-
AidlAnnotatable::AidlAnnotatable(const AidlLocation& location) : AidlNode(location) {}
bool AidlAnnotatable::IsNullable() const {
@@ -256,29 +120,8 @@
return HasAnnotation(annotations_, kUtf8InCpp);
}
-bool AidlAnnotatable::IsVintfStability() const {
- return HasAnnotation(annotations_, kVintfStability);
-}
-
-const AidlAnnotation* AidlAnnotatable::UnsupportedAppUsage() const {
- return GetAnnotation(annotations_, kUnsupportedAppUsage);
-}
-
-const AidlTypeSpecifier* AidlAnnotatable::BackingType(const AidlTypenames& typenames) const {
- auto annotation = GetAnnotation(annotations_, kBacking);
- if (annotation != nullptr) {
- auto annotation_params = annotation->AnnotationParams(AidlConstantValueDecorator);
- if (auto it = annotation_params.find("type"); it != annotation_params.end()) {
- const string& type = it->second;
- AidlTypeSpecifier* type_specifier =
- new AidlTypeSpecifier(AIDL_LOCATION_HERE,
- // Strip the quotes off the type String.
- type.substr(1, type.length() - 2), false, nullptr, "");
- type_specifier->Resolve(typenames);
- return type_specifier;
- }
- }
- return nullptr;
+bool AidlAnnotatable::IsUnsupportedAppUsage() const {
+ return HasAnnotation(annotations_, kUnsupportedAppUsage);
}
bool AidlAnnotatable::IsSystemApi() const {
@@ -289,20 +132,10 @@
return HasAnnotation(annotations_, kStableParcelable);
}
-bool AidlAnnotatable::CheckValidAnnotations() const {
- for (const auto& annotation : GetAnnotations()) {
- if (!annotation.CheckValid()) {
- return false;
- }
- }
-
- return true;
-}
-
string AidlAnnotatable::ToString() const {
vector<string> ret;
for (const auto& a : annotations_) {
- ret.emplace_back(a.ToString(AidlConstantValueDecorator));
+ ret.emplace_back(a.ToString());
}
std::sort(ret.begin(), ret.end());
return Join(ret, " ");
@@ -316,8 +149,7 @@
unresolved_name_(unresolved_name),
is_array_(is_array),
type_params_(type_params),
- comments_(comments),
- split_name_(Split(unresolved_name, ".")) {}
+ comments_(comments) {}
AidlTypeSpecifier AidlTypeSpecifier::ArrayBase() const {
AIDL_FATAL_IF(!is_array_, this);
@@ -351,20 +183,16 @@
return ret;
}
-bool AidlTypeSpecifier::Resolve(const AidlTypenames& typenames) {
- CHECK(!IsResolved());
+bool AidlTypeSpecifier::Resolve(android::aidl::AidlTypenames& typenames) {
+ assert(!IsResolved());
pair<string, bool> result = typenames.ResolveTypename(unresolved_name_);
if (result.second) {
fully_qualified_name_ = result.first;
- split_name_ = Split(fully_qualified_name_, ".");
}
return result.second;
}
bool AidlTypeSpecifier::CheckValid(const AidlTypenames& typenames) const {
- if (!CheckValidAnnotations()) {
- return false;
- }
if (IsGeneric()) {
const string& type_name = GetName();
const int num = GetTypeParameters().size();
@@ -403,11 +231,6 @@
AIDL_ERROR(this) << "Primitive type cannot get nullable annotation";
return false;
}
- const auto definedType = typenames.TryGetDefinedType(GetName());
- if (definedType != nullptr && definedType->AsEnumDeclaration() != nullptr && !IsArray()) {
- AIDL_ERROR(this) << "Enum type cannot get nullable annotation";
- return false;
- }
}
return true;
}
@@ -452,7 +275,7 @@
std::string AidlVariableDeclaration::ValueString(const ConstantValueDecorator& decorator) const {
if (default_value_ != nullptr) {
- return default_value_->ValueString(GetType(), decorator);
+ return GetDefaultValue()->As(GetType(), decorator);
} else {
return "";
}
@@ -504,6 +327,207 @@
AidlMember::AidlMember(const AidlLocation& location) : AidlNode(location) {}
+AidlConstantValue::AidlConstantValue(const AidlLocation& location, Type type,
+ const std::string& checked_value)
+ : AidlNode(location), type_(type), value_(checked_value) {
+ CHECK(!value_.empty() || type_ == Type::ERROR);
+ CHECK(type_ != Type::ARRAY);
+}
+
+AidlConstantValue::AidlConstantValue(const AidlLocation& location, Type type,
+ std::vector<std::unique_ptr<AidlConstantValue>>* values)
+ : AidlNode(location), type_(type), values_(std::move(*values)) {}
+
+static bool isValidLiteralChar(char c) {
+ return !(c <= 0x1f || // control characters are < 0x20
+ c >= 0x7f || // DEL is 0x7f
+ c == '\\'); // Disallow backslashes for future proofing.
+}
+
+AidlConstantValue* AidlConstantValue::Boolean(const AidlLocation& location, bool value) {
+ return new AidlConstantValue(location, Type::BOOLEAN, value ? "true" : "false");
+}
+
+AidlConstantValue* AidlConstantValue::Character(const AidlLocation& location, char value) {
+ if (!isValidLiteralChar(value)) {
+ AIDL_ERROR(location) << "Invalid character literal " << value;
+ return new AidlConstantValue(location, Type::ERROR, "");
+ }
+ return new AidlConstantValue(location, Type::CHARACTER, std::string("'") + value + "'");
+}
+
+AidlConstantValue* AidlConstantValue::Floating(const AidlLocation& location,
+ const std::string& value) {
+ return new AidlConstantValue(location, Type::FLOATING, value);
+}
+
+AidlConstantValue* AidlConstantValue::Hex(const AidlLocation& location, const std::string& value) {
+ return new AidlConstantValue(location, Type::HEXIDECIMAL, value);
+}
+
+AidlConstantValue* AidlConstantValue::Integral(const AidlLocation& location,
+ const std::string& value) {
+ return new AidlConstantValue(location, Type::INTEGRAL, value);
+}
+
+AidlConstantValue* AidlConstantValue::Array(
+ const AidlLocation& location, std::vector<std::unique_ptr<AidlConstantValue>>* values) {
+ return new AidlConstantValue(location, Type::ARRAY, values);
+}
+
+AidlConstantValue* AidlConstantValue::String(const AidlLocation& location,
+ const std::string& value) {
+ for (size_t i = 0; i < value.length(); ++i) {
+ if (!isValidLiteralChar(value[i])) {
+ AIDL_ERROR(location) << "Found invalid character at index " << i << " in string constant '"
+ << value << "'";
+ return new AidlConstantValue(location, Type::ERROR, "");
+ }
+ }
+
+ return new AidlConstantValue(location, Type::STRING, value);
+}
+
+bool AidlConstantValue::CheckValid() const {
+ // error always logged during creation
+ return type_ != AidlConstantValue::Type::ERROR;
+}
+
+static string TrimIfSuffix(const string& str, const string& suffix) {
+ if (str.size() > suffix.size() &&
+ 0 == str.compare(str.size() - suffix.size(), suffix.size(), suffix)) {
+ return str.substr(0, str.size() - suffix.size());
+ }
+ return str;
+}
+
+string AidlConstantValue::As(const AidlTypeSpecifier& type,
+ const ConstantValueDecorator& decorator) const {
+ if (type.IsGeneric()) {
+ AIDL_ERROR(type) << "Generic type cannot be specified with a constant literal.";
+ return "";
+ }
+
+ const std::string& type_string = type.GetName();
+
+ if ((type_ == Type::ARRAY) != type.IsArray()) {
+ goto mismatch_error;
+ }
+
+ switch (type_) {
+ case AidlConstantValue::Type::ARRAY: {
+ vector<string> raw_values;
+ raw_values.reserve(values_.size());
+
+ bool success = true;
+ for (const auto& value : values_) {
+ const AidlTypeSpecifier& array_base = type.ArrayBase();
+ const std::string raw_value = value->As(array_base, decorator);
+
+ success &= !raw_value.empty();
+ raw_values.push_back(decorator(array_base, raw_value));
+ }
+ if (!success) {
+ AIDL_ERROR(this) << "Default value must be a literal array of " << type_string << ".";
+ return "";
+ }
+ return decorator(type, "{" + Join(raw_values, ", ") + "}");
+ }
+ case AidlConstantValue::Type::BOOLEAN:
+ if (type_string == "boolean") return decorator(type, value_);
+ goto mismatch_error;
+ case AidlConstantValue::Type::CHARACTER:
+ if (type_string == "char") return decorator(type, value_);
+ goto mismatch_error;
+ case AidlConstantValue::Type::FLOATING: {
+ bool is_float_literal = value_.back() == 'f';
+ const std::string raw_value = TrimIfSuffix(value_, "f");
+
+ if (type_string == "double") {
+ double parsed_value;
+ if (!android::base::ParseDouble(raw_value, &parsed_value)) goto parse_error;
+ return decorator(type, std::to_string(parsed_value));
+ }
+ if (is_float_literal && type_string == "float") {
+ float parsed_value;
+ if (!android::base::ParseFloat(raw_value, &parsed_value)) goto parse_error;
+ return decorator(type, std::to_string(parsed_value) + "f");
+ }
+ goto mismatch_error;
+ }
+ case AidlConstantValue::Type::HEXIDECIMAL:
+ // For historical reasons, a hexidecimal int needs to have the specified bits interpreted
+ // as the signed type, so the other types are made consistent with it.
+ if (type_string == "byte") {
+ uint8_t unsigned_value;
+ if (!android::base::ParseUint<uint8_t>(value_, &unsigned_value)) goto parse_error;
+ return decorator(type, std::to_string((int8_t)unsigned_value));
+ }
+ if (type_string == "int") {
+ uint32_t unsigned_value;
+ if (!android::base::ParseUint<uint32_t>(value_, &unsigned_value)) goto parse_error;
+ return decorator(type, std::to_string((int32_t)unsigned_value));
+ }
+ if (type_string == "long") {
+ uint64_t unsigned_value;
+ if (!android::base::ParseUint<uint64_t>(value_, &unsigned_value)) goto parse_error;
+ return decorator(type, std::to_string((int64_t)unsigned_value));
+ }
+ goto mismatch_error;
+ case AidlConstantValue::Type::INTEGRAL:
+ if (type_string == "byte") {
+ if (!android::base::ParseInt<int8_t>(value_, nullptr)) goto parse_error;
+ return decorator(type, value_);
+ }
+ if (type_string == "int") {
+ if (!android::base::ParseInt<int32_t>(value_, nullptr)) goto parse_error;
+ return decorator(type, value_);
+ }
+ if (type_string == "long") {
+ if (!android::base::ParseInt<int64_t>(value_, nullptr)) goto parse_error;
+ return decorator(type, value_);
+ }
+ goto mismatch_error;
+ case AidlConstantValue::Type::STRING:
+ if (type_string == "String") return decorator(type, value_);
+ goto mismatch_error;
+ default:
+ AIDL_FATAL(this) << "Unrecognized constant value type";
+ }
+
+mismatch_error:
+ AIDL_ERROR(this) << "Expecting type " << type_string << " but constant is " << ToString(type_);
+ return "";
+parse_error:
+ AIDL_ERROR(this) << "Could not parse " << value_ << " as " << type_string;
+ return "";
+}
+
+string AidlConstantValue::ToString(Type type) {
+ switch (type) {
+ case Type::ARRAY:
+ return "a literal array";
+ case Type::BOOLEAN:
+ return "a literal boolean";
+ case Type::CHARACTER:
+ return "a literal char";
+ case Type::FLOATING:
+ return "a floating-point literal";
+ case Type::HEXIDECIMAL:
+ return "a hexidecimal literal";
+ case Type::INTEGRAL:
+ return "an integral literal";
+ case Type::STRING:
+ return "a literal string";
+ case Type::ERROR:
+ LOG(FATAL) << "aidl internal error: error type failed to halt program";
+ return "";
+ default:
+ LOG(FATAL) << "aidl internal error: unknown constant type: " << static_cast<int>(type);
+ return ""; // not reached
+ }
+}
+
AidlConstantDeclaration::AidlConstantDeclaration(const AidlLocation& location,
AidlTypeSpecifier* type, const std::string& name,
AidlConstantValue* value)
@@ -521,7 +545,7 @@
return false;
}
- return true;
+ return !ValueString(AidlConstantValueDecorator).empty();
}
string AidlConstantDeclaration::ToString() const {
@@ -611,9 +635,6 @@
bool AidlParcelable::CheckValid(const AidlTypenames&) const {
static const std::set<string> allowed{kStableParcelable};
- if (!CheckValidAnnotations()) {
- return false;
- }
for (const auto& v : GetAnnotations()) {
if (allowed.find(v.GetName()) == allowed.end()) {
std::ostringstream stream;
@@ -651,170 +672,12 @@
}
bool AidlStructuredParcelable::CheckValid(const AidlTypenames& typenames) const {
- bool success = true;
for (const auto& v : GetFields()) {
- success = success && v->CheckValid(typenames);
- }
- return success;
-}
-
-// TODO: we should treat every backend all the same in future.
-bool AidlTypeSpecifier::LanguageSpecificCheckValid(Options::Language lang) const {
- if (lang == Options::Language::CPP) {
- if (this->GetName() == "List" && !this->IsGeneric()) {
- AIDL_ERROR(this) << "List without type isn't supported in cpp.";
+ if (!(v->CheckValid(typenames))) {
return false;
}
}
- if (this->IsGeneric()) {
- if (this->GetName() == "List") {
- if (this->GetTypeParameters().size() != 1) {
- AIDL_ERROR(this) << "List must have only one type parameter.";
- return false;
- }
- if (lang == Options::Language::CPP) {
- auto& name = this->GetTypeParameters()[0]->GetName();
- if (!(name == "String" || name == "IBinder")) {
- AIDL_ERROR(this) << "List in cpp supports only string and IBinder for now.";
- return false;
- }
- } else if (lang == Options::Language::NDK) {
- AIDL_ERROR(this) << "NDK backend does not support List yet.";
- return false;
- }
- } else if (this->GetName() == "Map") {
- if (lang != Options::Language::JAVA) {
- AIDL_ERROR(this) << "Currently, only Java backend supports Map.";
- return false;
- }
- }
- }
- return true;
-}
-
-// TODO: we should treat every backend all the same in future.
-bool AidlParcelable::LanguageSpecificCheckValid(Options::Language lang) const {
- if (lang != Options::Language::JAVA) {
- if (this->IsStableParcelable()) {
- AIDL_ERROR(this) << "@JavaOnlyStableParcelable supports only Java target.";
- return false;
- }
- const AidlParcelable* unstructuredParcelable = this->AsUnstructuredParcelable();
- if (unstructuredParcelable != nullptr) {
- if (unstructuredParcelable->GetCppHeader().empty()) {
- AIDL_ERROR(unstructuredParcelable)
- << "Unstructured parcelable must have C++ header defined.";
- return false;
- }
- }
- }
- return true;
-}
-
-// TODO: we should treat every backend all the same in future.
-bool AidlStructuredParcelable::LanguageSpecificCheckValid(Options::Language lang) const {
- if (!AidlParcelable::LanguageSpecificCheckValid(lang)) {
- return false;
- }
- for (const auto& v : this->GetFields()) {
- if (!v->GetType().LanguageSpecificCheckValid(lang)) {
- return false;
- }
- }
- return true;
-}
-
-AidlEnumerator::AidlEnumerator(const AidlLocation& location, const std::string& name,
- AidlConstantValue* value, const std::string& comments)
- : AidlNode(location), name_(name), value_(value), comments_(comments) {}
-
-bool AidlEnumerator::CheckValid(const AidlTypeSpecifier& enum_backing_type) const {
- if (GetValue() == nullptr) {
- return false;
- }
- if (!GetValue()->CheckValid()) {
- return false;
- }
- if (GetValue()->ValueString(enum_backing_type, AidlConstantValueDecorator).empty()) {
- AIDL_ERROR(this) << "Enumerator type differs from enum backing type.";
- return false;
- }
- return true;
-}
-
-string AidlEnumerator::ValueString(const AidlTypeSpecifier& backing_type,
- const ConstantValueDecorator& decorator) const {
- return GetValue()->ValueString(backing_type, decorator);
-}
-
-AidlEnumDeclaration::AidlEnumDeclaration(const AidlLocation& location, const std::string& name,
- std::vector<std::unique_ptr<AidlEnumerator>>* enumerators,
- const std::vector<std::string>& package,
- const std::string& comments)
- : AidlDefinedType(location, name, comments, package), enumerators_(std::move(*enumerators)) {}
-
-void AidlEnumDeclaration::SetBackingType(std::unique_ptr<const AidlTypeSpecifier> type) {
- backing_type_ = std::move(type);
-}
-
-void AidlEnumDeclaration::Autofill() {
- const AidlEnumerator* previous = nullptr;
- for (const auto& enumerator : enumerators_) {
- if (enumerator->GetValue() == nullptr) {
- if (previous == nullptr) {
- enumerator->SetValue(std::unique_ptr<AidlConstantValue>(
- AidlConstantValue::Integral(AIDL_LOCATION_HERE, "0")));
- } else {
- enumerator->SetValue(std::make_unique<AidlBinaryConstExpression>(
- AIDL_LOCATION_HERE,
- std::unique_ptr<AidlConstantValue>(
- AidlConstantValue::ShallowIntegralCopy(*previous->GetValue())),
- "+",
- std::unique_ptr<AidlConstantValue>(
- AidlConstantValue::Integral(AIDL_LOCATION_HERE, "1"))));
- }
- }
- previous = enumerator.get();
- }
-}
-
-bool AidlEnumDeclaration::CheckValid(const AidlTypenames&) const {
- if (backing_type_ == nullptr) {
- AIDL_ERROR(this) << "Enum declaration missing backing type.";
- return false;
- }
- bool success = true;
- for (const auto& enumerator : enumerators_) {
- success = success && enumerator->CheckValid(GetBackingType());
- }
- return success;
-}
-
-void AidlEnumDeclaration::Write(CodeWriter* writer) const {
- writer->Write("%s\n", AidlAnnotatable::ToString().c_str());
- writer->Write("enum %s {\n", GetName().c_str());
- writer->Indent();
- for (const auto& enumerator : GetEnumerators()) {
- writer->Write("%s = %s,\n", enumerator->GetName().c_str(),
- enumerator->ValueString(GetBackingType(), AidlConstantValueDecorator).c_str());
- }
- writer->Dedent();
- writer->Write("}\n");
-}
-
-// TODO: we should treat every backend all the same in future.
-bool AidlInterface::LanguageSpecificCheckValid(Options::Language lang) const {
- for (const auto& m : this->GetMethods()) {
- if (!m->GetType().LanguageSpecificCheckValid(lang)) {
- return false;
- }
- for (const auto& arg : m->GetArguments()) {
- if (!arg->GetType().LanguageSpecificCheckValid(lang)) {
- return false;
- }
- }
- }
return true;
}
@@ -857,9 +720,6 @@
}
bool AidlInterface::CheckValid(const AidlTypenames& typenames) const {
- if (!CheckValidAnnotations()) {
- return false;
- }
// Has to be a pointer due to deleting copy constructor. No idea why.
map<string, const AidlMethod*> method_names;
for (const auto& m : GetMethods()) {
@@ -890,29 +750,6 @@
AIDL_ERROR(m) << "oneway method '" << m->GetName() << "' cannot have out parameters";
return false;
}
- const bool can_be_out = typenames.CanBeOutParameter(arg->GetType());
- if (!arg->DirectionWasSpecified() && can_be_out) {
- AIDL_ERROR(arg) << "'" << arg->GetType().ToString()
- << "' can be an out type, so you must declare it as in, out, or inout.";
- return false;
- }
-
- if (arg->GetDirection() != AidlArgument::IN_DIR && !can_be_out) {
- AIDL_ERROR(arg) << "'" << arg->ToString() << "' can only be an in parameter.";
- return false;
- }
-
- // check that the name doesn't match a keyword
- if (is_java_keyword(arg->GetName().c_str())) {
- AIDL_ERROR(arg) << "Argument name is a Java or aidl keyword";
- return false;
- }
-
- // Reserve a namespace for internal use
- if (android::base::StartsWith(arg->GetName(), "_aidl")) {
- AIDL_ERROR(arg) << "Argument name cannot begin with '_aidl'";
- return false;
- }
}
auto it = method_names.find(m->GetName());
diff --git a/aidl_language.h b/aidl_language.h
index ca2e359..49a4606 100644
--- a/aidl_language.h
+++ b/aidl_language.h
@@ -1,26 +1,10 @@
-/*
- * Copyright (C) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
#pragma once
#include "aidl_typenames.h"
#include "code_writer.h"
#include "io_delegate.h"
-#include "options.h"
+#include <cassert>
#include <memory>
#include <string>
#include <vector>
@@ -33,11 +17,11 @@
using android::aidl::AidlTypenames;
using android::aidl::CodeWriter;
-using android::aidl::Options;
using std::shared_ptr;
using std::string;
using std::unique_ptr;
using std::vector;
+
class AidlNode;
namespace android {
@@ -144,44 +128,29 @@
namespace android {
namespace aidl {
+class ValidatableType;
class AidlTypenames;
} // namespace aidl
} // namespace android
-class AidlConstantValue;
-class AidlConstantDeclaration;
-
-// Transforms a value string into a language specific form. Raw value as produced by
-// AidlConstantValue.
-using ConstantValueDecorator =
- std::function<std::string(const AidlTypeSpecifier& type, const std::string& raw_value)>;
-
class AidlAnnotation : public AidlNode {
public:
- static AidlAnnotation* Parse(
- const AidlLocation& location, const string& name,
- std::map<std::string, std::shared_ptr<AidlConstantValue>>* parameter_list);
+ static AidlAnnotation* Parse(const AidlLocation& location, const string& name);
AidlAnnotation(const AidlAnnotation&) = default;
AidlAnnotation(AidlAnnotation&&) = default;
virtual ~AidlAnnotation() = default;
- bool CheckValid() const;
const string& GetName() const { return name_; }
- string ToString(const ConstantValueDecorator& decorator) const;
- std::map<std::string, std::string> AnnotationParams(
- const ConstantValueDecorator& decorator) const;
+ string ToString() const { return "@" + name_; }
const string& GetComments() const { return comments_; }
void SetComments(const string& comments) { comments_ = comments; }
private:
AidlAnnotation(const AidlLocation& location, const string& name);
- AidlAnnotation(const AidlLocation& location, const string& name,
- std::map<std::string, std::shared_ptr<AidlConstantValue>>&& parameters);
const string name_;
string comments_;
- std::map<std::string, std::shared_ptr<AidlConstantValue>> parameters_;
};
static inline bool operator<(const AidlAnnotation& lhs, const AidlAnnotation& rhs) {
@@ -199,23 +168,15 @@
AidlAnnotatable(AidlAnnotatable&&) = default;
virtual ~AidlAnnotatable() = default;
- void Annotate(vector<AidlAnnotation>&& annotations) {
- for (auto& annotation : annotations) {
- annotations_.emplace_back(std::move(annotation));
- }
- }
+ void Annotate(vector<AidlAnnotation>&& annotations) { annotations_ = std::move(annotations); }
bool IsNullable() const;
bool IsUtf8InCpp() const;
- bool IsVintfStability() const;
+ bool IsUnsupportedAppUsage() const;
bool IsSystemApi() const;
bool IsStableParcelable() const;
-
- const AidlAnnotation* UnsupportedAppUsage() const;
- const AidlTypeSpecifier* BackingType(const AidlTypenames& typenames) const;
std::string ToString() const;
const vector<AidlAnnotation>& GetAnnotations() const { return annotations_; }
- bool CheckValidAnnotations() const;
private:
vector<AidlAnnotation> annotations_;
@@ -248,7 +209,7 @@
}
// Returns string representation of this type specifier.
- // This is GetBaseTypeName() + array modifier or generic type parameters
+ // This is GetBaseTypeName() + array modifieir or generic type parameters
string ToString() const;
std::string Signature() const;
@@ -257,8 +218,6 @@
const string& GetComments() const { return comments_; }
- const std::vector<std::string> GetSplitName() const { return split_name_; }
-
void SetComments(const string& comment) { comments_ = comment; }
bool IsResolved() const { return fully_qualified_name_ != ""; }
@@ -271,11 +230,18 @@
// Resolve the base type name to a fully-qualified name. Return false if the
// resolution fails.
- bool Resolve(const AidlTypenames& typenames);
+ bool Resolve(android::aidl::AidlTypenames& typenames);
bool CheckValid(const AidlTypenames& typenames) const;
- bool LanguageSpecificCheckValid(Options::Language lang) const;
+ void SetLanguageType(const android::aidl::ValidatableType* language_type) {
+ language_type_ = language_type;
+ }
+
+ template<typename T>
+ const T* GetLanguageType() const {
+ return reinterpret_cast<const T*>(language_type_);
+ }
private:
AidlTypeSpecifier(const AidlTypeSpecifier&) = default;
@@ -284,9 +250,13 @@
bool is_array_;
const shared_ptr<vector<unique_ptr<AidlTypeSpecifier>>> type_params_;
string comments_;
- vector<string> split_name_;
+ const android::aidl::ValidatableType* language_type_ = nullptr;
};
+// Transforms a value string into a language specific form. Raw value as produced by
+// AidlConstantValue.
+using ConstantValueDecorator =
+ std::function<std::string(const AidlTypeSpecifier& type, const std::string& raw_value)>;
// Returns the universal value unaltered.
std::string AidlConstantValueDecorator(const AidlTypeSpecifier& type, const std::string& raw_value);
@@ -347,7 +317,6 @@
class AidlMethod;
class AidlConstantDeclaration;
-class AidlEnumDeclaration;
class AidlMember : public AidlNode {
public:
AidlMember(const AidlLocation& location);
@@ -360,170 +329,85 @@
DISALLOW_COPY_AND_ASSIGN(AidlMember);
};
-class AidlUnaryConstExpression;
-class AidlBinaryConstExpression;
-
class AidlConstantValue : public AidlNode {
public:
- enum class Type {
- // WARNING: Don't change this order! The order is used to determine type
- // promotion during a binary expression.
- BOOLEAN,
- INT8,
- INT32,
- INT64,
- ARRAY,
- CHARACTER,
- STRING,
- FLOATING,
- UNARY,
- BINARY,
- ERROR,
- };
-
- /*
- * Return the value casted to the given type.
- */
- template <typename T>
- T cast() const;
+ enum class Type { ERROR, ARRAY, BOOLEAN, CHARACTER, FLOATING, HEXIDECIMAL, INTEGRAL, STRING };
virtual ~AidlConstantValue() = default;
static AidlConstantValue* Boolean(const AidlLocation& location, bool value);
static AidlConstantValue* Character(const AidlLocation& location, char value);
- // example: 123, -5498, maybe any size
- static AidlConstantValue* Integral(const AidlLocation& location, const string& value);
+ // example: "0x4f"
static AidlConstantValue* Floating(const AidlLocation& location, const std::string& value);
+ static AidlConstantValue* Hex(const AidlLocation& location, const std::string& value);
+ // example: 123, -5498, maybe any size
+ static AidlConstantValue* Integral(const AidlLocation& location, const std::string& value);
static AidlConstantValue* Array(const AidlLocation& location,
- std::unique_ptr<vector<unique_ptr<AidlConstantValue>>> values);
+ std::vector<std::unique_ptr<AidlConstantValue>>* values);
// example: "\"asdf\""
- static AidlConstantValue* String(const AidlLocation& location, const string& value);
+ static AidlConstantValue* String(const AidlLocation& location, const std::string& value);
- // Construct an AidlConstantValue by evaluating the other integral constant's
- // value string. This does not preserve the structure of the copied constant.
- static AidlConstantValue* ShallowIntegralCopy(const AidlConstantValue& other);
+ Type GetType() const { return type_; }
- Type GetType() const { return final_type_; }
-
- virtual bool CheckValid() const;
+ bool CheckValid() const;
// Raw value of type (currently valid in C++ and Java). Empty string on error.
- virtual string ValueString(const AidlTypeSpecifier& type,
- const ConstantValueDecorator& decorator) const;
+ string As(const AidlTypeSpecifier& type, const ConstantValueDecorator& decorator) const;
private:
- AidlConstantValue(const AidlLocation& location, Type parsed_type, int64_t parsed_value,
- const string& checked_value);
- AidlConstantValue(const AidlLocation& location, Type type, const string& checked_value);
+ AidlConstantValue(const AidlLocation& location, Type type, const std::string& checked_value);
AidlConstantValue(const AidlLocation& location, Type type,
- std::unique_ptr<vector<unique_ptr<AidlConstantValue>>> values);
+ std::vector<std::unique_ptr<AidlConstantValue>>* values);
static string ToString(Type type);
- static bool ParseIntegral(const string& value, int64_t* parsed_value, Type* parsed_type);
- static bool IsHex(const string& value);
- virtual bool evaluate(const AidlTypeSpecifier& type) const;
const Type type_ = Type::ERROR;
- const vector<unique_ptr<AidlConstantValue>> values_; // if type_ == ARRAY
- const string value_; // otherwise
-
- // State for tracking evaluation of expressions
- mutable bool is_valid_;
- mutable bool is_evaluated_;
- mutable Type final_type_;
- mutable int64_t final_value_;
- mutable string final_string_value_ = "";
+ const std::vector<std::unique_ptr<AidlConstantValue>> values_; // if type_ == ARRAY
+ const std::string value_; // otherwise
DISALLOW_COPY_AND_ASSIGN(AidlConstantValue);
-
- friend AidlUnaryConstExpression;
- friend AidlBinaryConstExpression;
-};
-
-class AidlUnaryConstExpression : public AidlConstantValue {
- public:
- AidlUnaryConstExpression(const AidlLocation& location, const string& op,
- std::unique_ptr<AidlConstantValue> rval);
-
- static bool IsCompatibleType(Type type, const string& op);
- bool CheckValid() const override;
- string ValueString(const AidlTypeSpecifier& type,
- const ConstantValueDecorator& decorator) const override;
-
- private:
- bool evaluate(const AidlTypeSpecifier& type) const override;
-
- std::unique_ptr<AidlConstantValue> unary_;
- const string op_;
-};
-
-class AidlBinaryConstExpression : public AidlConstantValue {
- public:
- AidlBinaryConstExpression(const AidlLocation& location, std::unique_ptr<AidlConstantValue> lval,
- const string& op, std::unique_ptr<AidlConstantValue> rval);
-
- bool CheckValid() const override;
- string ValueString(const AidlTypeSpecifier& type,
- const ConstantValueDecorator& decorator) const override;
-
- static bool AreCompatibleTypes(Type t1, Type t2);
- // Returns the promoted kind for both operands
- static Type UsualArithmeticConversion(Type left, Type right);
- // Returns the promoted integral type where INT32 is the smallest type
- static Type IntegralPromotion(Type in);
-
- private:
- bool evaluate(const AidlTypeSpecifier& type) const override;
-
- std::unique_ptr<AidlConstantValue> left_val_;
- std::unique_ptr<AidlConstantValue> right_val_;
- const string op_;
-};
-
-struct AidlAnnotationParameter {
- std::string name;
- std::unique_ptr<AidlConstantValue> value;
};
class AidlConstantDeclaration : public AidlMember {
public:
AidlConstantDeclaration(const AidlLocation& location, AidlTypeSpecifier* specifier,
- const string& name, AidlConstantValue* value);
+ const std::string& name, AidlConstantValue* value);
virtual ~AidlConstantDeclaration() = default;
const AidlTypeSpecifier& GetType() const { return *type_; }
AidlTypeSpecifier* GetMutableType() { return type_.get(); }
- const string& GetName() const { return name_; }
+ const std::string& GetName() const { return name_; }
const AidlConstantValue& GetValue() const { return *value_; }
bool CheckValid(const AidlTypenames& typenames) const;
- string ToString() const;
- string Signature() const;
+ std::string ToString() const;
+ std::string Signature() const;
string ValueString(const ConstantValueDecorator& decorator) const {
- return value_->ValueString(GetType(), decorator);
+ return GetValue().As(GetType(), decorator);
}
AidlConstantDeclaration* AsConstantDeclaration() override { return this; }
private:
const unique_ptr<AidlTypeSpecifier> type_;
- const string name_;
- unique_ptr<AidlConstantValue> value_;
+ const std::string name_;
+ const unique_ptr<AidlConstantValue> value_;
DISALLOW_COPY_AND_ASSIGN(AidlConstantDeclaration);
};
class AidlMethod : public AidlMember {
public:
- AidlMethod(const AidlLocation& location, bool oneway, AidlTypeSpecifier* type, const string& name,
- vector<unique_ptr<AidlArgument>>* args, const string& comments);
- AidlMethod(const AidlLocation& location, bool oneway, AidlTypeSpecifier* type, const string& name,
- vector<unique_ptr<AidlArgument>>* args, const string& comments, int id,
- bool is_user_defined = true);
+ AidlMethod(const AidlLocation& location, bool oneway, AidlTypeSpecifier* type,
+ const std::string& name, std::vector<std::unique_ptr<AidlArgument>>* args,
+ const std::string& comments);
+ AidlMethod(const AidlLocation& location, bool oneway, AidlTypeSpecifier* type,
+ const std::string& name, std::vector<std::unique_ptr<AidlArgument>>* args,
+ const std::string& comments, int id, bool is_user_defined = true);
virtual ~AidlMethod() = default;
AidlMethod* AsMethod() override { return this; }
- const string& GetComments() const { return comments_; }
+ const std::string& GetComments() const { return comments_; }
const AidlTypeSpecifier& GetType() const { return *type_; }
AidlTypeSpecifier* GetMutableType() { return type_.get(); }
@@ -602,7 +486,7 @@
class AidlInterface;
class AidlParcelable;
class AidlStructuredParcelable;
-// AidlDefinedType represents either an interface, parcelable, or enum that is
+// AidlDefinedType represents either an interface or a parcelable that is
// defined in the source file.
class AidlDefinedType : public AidlAnnotatable {
public:
@@ -624,10 +508,9 @@
virtual const AidlStructuredParcelable* AsStructuredParcelable() const { return nullptr; }
virtual const AidlParcelable* AsParcelable() const { return nullptr; }
- virtual const AidlEnumDeclaration* AsEnumDeclaration() const { return nullptr; }
virtual const AidlInterface* AsInterface() const { return nullptr; }
- virtual bool CheckValid(const AidlTypenames&) const { return CheckValidAnnotations(); }
- virtual bool LanguageSpecificCheckValid(Options::Language lang) const = 0;
+ virtual bool CheckValid(const AidlTypenames&) const { return true; }
+
AidlStructuredParcelable* AsStructuredParcelable() {
return const_cast<AidlStructuredParcelable*>(
const_cast<const AidlDefinedType*>(this)->AsStructuredParcelable());
@@ -635,10 +518,6 @@
AidlParcelable* AsParcelable() {
return const_cast<AidlParcelable*>(const_cast<const AidlDefinedType*>(this)->AsParcelable());
}
- AidlEnumDeclaration* AsEnumDeclaration() {
- return const_cast<AidlEnumDeclaration*>(
- const_cast<const AidlDefinedType*>(this)->AsEnumDeclaration());
- }
AidlInterface* AsInterface() {
return const_cast<AidlInterface*>(const_cast<const AidlDefinedType*>(this)->AsInterface());
}
@@ -652,11 +531,21 @@
const_cast<const AidlDefinedType*>(this)->AsUnstructuredParcelable());
}
+ void SetLanguageType(const android::aidl::ValidatableType* language_type) {
+ language_type_ = language_type;
+ }
+
+ template <typename T>
+ const T* GetLanguageType() const {
+ return reinterpret_cast<const T*>(language_type_);
+ }
+
virtual void Write(CodeWriter* writer) const = 0;
private:
std::string name_;
std::string comments_;
+ const android::aidl::ValidatableType* language_type_ = nullptr;
const std::vector<std::string> package_;
DISALLOW_COPY_AND_ASSIGN(AidlDefinedType);
@@ -674,7 +563,7 @@
std::string GetCppHeader() const { return cpp_header_; }
bool CheckValid(const AidlTypenames& typenames) const override;
- bool LanguageSpecificCheckValid(Options::Language lang) const override;
+
const AidlParcelable* AsParcelable() const override { return this; }
std::string GetPreprocessDeclarationName() const override { return "parcelable"; }
@@ -703,7 +592,6 @@
void Write(CodeWriter* writer) const override;
bool CheckValid(const AidlTypenames& typenames) const override;
- bool LanguageSpecificCheckValid(Options::Language lang) const override;
private:
const std::vector<std::unique_ptr<AidlVariableDeclaration>> variables_;
@@ -711,58 +599,6 @@
DISALLOW_COPY_AND_ASSIGN(AidlStructuredParcelable);
};
-class AidlEnumerator : public AidlNode {
- public:
- AidlEnumerator(const AidlLocation& location, const std::string& name, AidlConstantValue* value,
- const std::string& comments);
- virtual ~AidlEnumerator() = default;
-
- const std::string& GetName() const { return name_; }
- AidlConstantValue* GetValue() const { return value_.get(); }
- const std::string& GetComments() const { return comments_; }
- bool CheckValid(const AidlTypeSpecifier& enum_backing_type) const;
-
- string ValueString(const AidlTypeSpecifier& backing_type,
- const ConstantValueDecorator& decorator) const;
-
- void SetValue(std::unique_ptr<AidlConstantValue> value) { value_ = std::move(value); }
-
- private:
- const std::string name_;
- unique_ptr<AidlConstantValue> value_;
- const std::string comments_;
-
- DISALLOW_COPY_AND_ASSIGN(AidlEnumerator);
-};
-
-class AidlEnumDeclaration : public AidlDefinedType {
- public:
- AidlEnumDeclaration(const AidlLocation& location, const string& name,
- std::vector<std::unique_ptr<AidlEnumerator>>* enumerators,
- const std::vector<std::string>& package, const std::string& comments);
- virtual ~AidlEnumDeclaration() = default;
-
- void SetBackingType(std::unique_ptr<const AidlTypeSpecifier> type);
- const AidlTypeSpecifier& GetBackingType() const { return *backing_type_; }
- const std::vector<std::unique_ptr<AidlEnumerator>>& GetEnumerators() const {
- return enumerators_;
- }
- void Autofill();
- bool CheckValid(const AidlTypenames& typenames) const override;
- bool LanguageSpecificCheckValid(Options::Language) const override { return true; }
- std::string GetPreprocessDeclarationName() const override { return "enum"; }
- void Write(CodeWriter*) const override;
-
- const AidlEnumDeclaration* AsEnumDeclaration() const override { return this; }
-
- private:
- const std::string name_;
- const std::vector<std::unique_ptr<AidlEnumerator>> enumerators_;
- std::unique_ptr<const AidlTypeSpecifier> backing_type_;
-
- DISALLOW_COPY_AND_ASSIGN(AidlEnumDeclaration);
-};
-
class AidlInterface final : public AidlDefinedType {
public:
AidlInterface(const AidlLocation& location, const std::string& name, const std::string& comments,
@@ -783,7 +619,6 @@
void Write(CodeWriter* writer) const override;
bool CheckValid(const AidlTypenames& typenames) const override;
- bool LanguageSpecificCheckValid(Options::Language lang) const override;
private:
std::vector<std::unique_ptr<AidlMethod>> methods_;
diff --git a/aidl_language_l.ll b/aidl_language_l.ll
index 8667ab4..862332c 100644
--- a/aidl_language_l.ll
+++ b/aidl_language_l.ll
@@ -1,19 +1,3 @@
-/*
- * Copyright (C) 2016, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
%{
#include <string.h>
#include <stdlib.h>
@@ -36,9 +20,9 @@
identifier [_a-zA-Z][_a-zA-Z0-9]*
whitespace ([ \t\r]+)
-intvalue [0-9]+[lL]?
+intvalue [-+]?(0|[1-9][0-9]*)
hexvalue 0[x|X][0-9a-fA-F]+
-floatvalue [0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?f?
+floatvalue [-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?f?
%%
%{
@@ -62,44 +46,25 @@
\"[^\"]*\" { yylval->token = new AidlToken(yytext, extra_text);
return yy::parser::token::C_STR; }
-\/\/.* { extra_text += yytext; extra_text += "\n"; }
+\/\/.*\n { extra_text += yytext; yylloc->lines(1); yylloc->step(); }
\n+ { yylloc->lines(yyleng); yylloc->step(); }
{whitespace} {}
<<EOF>> { yyterminate(); }
/* symbols */
-"(" { return('('); }
-")" { return(')'); }
-"<" { return('<'); }
-">" { return('>'); }
-"{" { return('{'); }
-"}" { return('}'); }
-"[" { return('['); }
-"]" { return(']'); }
-":" { return(':'); }
-";" { return(';'); }
-"," { return(','); }
-"." { return('.'); }
-"=" { return('='); }
-"+" { return('+'); }
-"-" { return('-'); }
-"*" { return('*'); }
-"/" { return('/'); }
-"%" { return('%'); }
-"&" { return('&'); }
-"|" { return('|'); }
-"^" { return('^'); }
-"<<" { return(yy::parser::token::LSHIFT); }
-">>" { return(yy::parser::token::RSHIFT); }
-"&&" { return(yy::parser::token::LOGICAL_AND); }
-"||" { return(yy::parser::token::LOGICAL_OR); }
-"!" { return('!'); }
-"~" { return('~'); }
-"<=" { return(yy::parser::token::LEQ); }
-">=" { return(yy::parser::token::GEQ); }
-"==" { return(yy::parser::token::EQUALITY); }
-"!=" { return(yy::parser::token::NEQ); }
+; { return ';'; }
+\{ { return '{'; }
+\} { return '}'; }
+= { return '='; }
+, { return ','; }
+\. { return '.'; }
+\( { return '('; }
+\) { return ')'; }
+\[ { return '['; }
+\] { return ']'; }
+\< { return '<'; }
+\> { return '>'; }
/* annotations */
@{identifier} { yylval->token = new AidlToken(yytext + 1, extra_text);
@@ -126,9 +91,6 @@
oneway { yylval->token = new AidlToken("oneway", extra_text);
return yy::parser::token::ONEWAY;
}
-enum { yylval->token = new AidlToken("enum", extra_text);
- return yy::parser::token::ENUM;
- }
/* scalars */
{identifier} { yylval->token = new AidlToken(yytext, extra_text);
diff --git a/aidl_language_y.yy b/aidl_language_y.yy
index c9df5e8..3b2c586 100644
--- a/aidl_language_y.yy
+++ b/aidl_language_y.yy
@@ -1,26 +1,8 @@
-/*
- * Copyright (C) 2016, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
%{
#include "aidl_language.h"
#include "aidl_language_y.h"
#include "logging.h"
-#include <android-base/parseint.h>
#include <set>
-#include <map>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -65,16 +47,11 @@
char character;
std::string *str;
AidlAnnotation* annotation;
- AidlAnnotationParameter* param;
- std::map<std::string, std::shared_ptr<AidlConstantValue>>* param_list;
std::vector<AidlAnnotation>* annotation_list;
AidlTypeSpecifier* type;
AidlArgument* arg;
AidlArgument::Direction direction;
- AidlConstantValue* const_expr;
- AidlEnumerator* enumerator;
- std::vector<std::unique_ptr<AidlEnumerator>>* enumerators;
- AidlEnumDeclaration* enum_decl;
+ AidlConstantValue* constant_value;
std::vector<std::unique_ptr<AidlConstantValue>>* constant_value_list;
std::vector<std::unique_ptr<AidlArgument>>* arg_list;
AidlVariableDeclaration* variable;
@@ -89,24 +66,19 @@
std::vector<std::unique_ptr<AidlTypeSpecifier>>* type_args;
}
-%destructor { } <character>
-%destructor { } <direction>
-%destructor { delete ($$); } <*>
-
%token<token> ANNOTATION "annotation"
%token<token> C_STR "string literal"
%token<token> IDENTIFIER "identifier"
%token<token> INTERFACE "interface"
%token<token> PARCELABLE "parcelable"
%token<token> ONEWAY "oneway"
-%token<token> ENUM "enum"
%token<character> CHARVALUE "char literal"
%token<token> FLOATVALUE "float literal"
%token<token> HEXVALUE "hex literal"
%token<token> INTVALUE "int literal"
-%token '(' ')' ',' '=' '[' ']' '.' '{' '}' ';'
+%token '(' ')' ',' '=' '[' ']' '<' '>' '.' '{' '}' ';'
%token CONST "const"
%token UNKNOWN "unrecognized character"
%token CPP_HEADER "cpp_header"
@@ -118,28 +90,6 @@
%token TRUE_LITERAL "true"
%token FALSE_LITERAL "false"
-/* Operator precedence and associativity, as per
- * http://en.cppreference.com/w/cpp/language/operator_precedence */
-/* Precedence level 13 - 14, LTR, logical operators*/
-%left LOGICAL_OR
-%left LOGICAL_AND
-/* Precedence level 10 - 12, LTR, bitwise operators*/
-%left '|'
-%left '^'
-%left '&'
-/* Precedence level 9, LTR */
-%left EQUALITY NEQ
-/* Precedence level 8, LTR */
-%left '<' '>' LEQ GEQ
-/* Precedence level 7, LTR */
-%left LSHIFT RSHIFT
-/* Precedence level 6, LTR */
-%left '+' '-'
-/* Precedence level 5, LTR */
-%left '*' '/' '%'
-/* Precedence level 3, RTL; but we have to use %left here */
-%right UNARY_PLUS UNARY_MINUS '!' '~'
-
%type<declaration> decl
%type<variable_list> variable_decls
%type<variable> variable_decl
@@ -149,22 +99,16 @@
%type<parcelable> parcelable_decl
%type<method> method_decl
%type<constant> constant_decl
-%type<enumerator> enumerator
-%type<enumerators> enumerators enum_decl_body
-%type<enum_decl> enum_decl
-%type<param> parameter
-%type<param_list> parameter_list
-%type<param_list> parameter_non_empty_list
%type<annotation> annotation
%type<annotation_list>annotation_list
%type<type> type
%type<type> unannotated_type
-%type<arg_list> arg_list arg_non_empty_list
+%type<arg_list> arg_list
%type<arg> arg
%type<direction> direction
%type<type_args> type_args
%type<qname> qualified_name
-%type<const_expr> const_expr
+%type<constant_value> constant_value
%type<constant_value_list> constant_value_list
%type<constant_value_list> constant_value_non_empty_list
@@ -213,14 +157,10 @@
decls
: decl {
- if ($1 != nullptr) {
- ps->AddDefinedType(unique_ptr<AidlDefinedType>($1));
- }
+ ps->AddDefinedType(unique_ptr<AidlDefinedType>($1));
}
| decls decl {
- if ($2 != nullptr) {
- ps->AddDefinedType(unique_ptr<AidlDefinedType>($2));
- }
+ ps->AddDefinedType(unique_ptr<AidlDefinedType>($2));
};
decl
@@ -228,12 +168,12 @@
{
$$ = $2;
- if ($1->size() > 0 && $$ != nullptr) {
+ if ($1->size() > 0) {
// copy comments from annotation to decl
- $$->SetComments($1->begin()->GetComments());
- $$->Annotate(std::move(*$1));
+ $2->SetComments($1->begin()->GetComments());
}
+ $$->Annotate(std::move(*$1));
delete $1;
}
;
@@ -243,31 +183,22 @@
{ $$ = $1; }
| interface_decl
{ $$ = $1; }
- | enum_decl
- { $$ = $1; }
;
parcelable_decl
: PARCELABLE qualified_name ';' {
$$ = new AidlParcelable(loc(@2), $2, ps->Package(), $1->GetComments());
- delete $1;
}
| PARCELABLE qualified_name CPP_HEADER C_STR ';' {
$$ = new AidlParcelable(loc(@2), $2, ps->Package(), $1->GetComments(), $4->GetText());
- delete $1;
- delete $4;
}
| PARCELABLE identifier '{' variable_decls '}' {
AidlQualifiedName* name = new AidlQualifiedName(loc(@2), $2->GetText(), $2->GetComments());
$$ = new AidlStructuredParcelable(loc(@2), name, ps->Package(), $1->GetComments(), $4);
- delete $1;
- delete $2;
- delete $4;
}
| PARCELABLE error ';' {
ps->AddError();
- $$ = nullptr;
- delete $1;
+ $$ = NULL;
};
variable_decls
@@ -284,12 +215,9 @@
variable_decl
: type identifier ';' {
$$ = new AidlVariableDeclaration(loc(@2), $1, $2->GetText());
- delete $2;
}
- | type identifier '=' const_expr ';' {
- // TODO(b/123321528): Support enum type default assignments (TestEnum foo = TestEnum.FOO).
+ | type identifier '=' constant_value ';' {
$$ = new AidlVariableDeclaration(loc(@2), $1, $2->GetText(), $4);
- delete $2;
}
| error ';' {
ps->AddError();
@@ -312,6 +240,7 @@
ps->AddError();
$$ = nullptr;
delete $1;
+ delete $2;
delete $4;
};
@@ -319,26 +248,20 @@
:
{ $$ = new std::vector<std::unique_ptr<AidlMember>>(); }
| interface_members method_decl
- { $1->push_back(std::unique_ptr<AidlMember>($2)); $$ = $1; }
+ { $1->push_back(std::unique_ptr<AidlMember>($2)); }
| interface_members constant_decl
- { $1->push_back(std::unique_ptr<AidlMember>($2)); $$ = $1; }
+ { $1->push_back(std::unique_ptr<AidlMember>($2)); }
| interface_members error ';' {
ps->AddError();
$$ = $1;
};
-const_expr
+constant_value
: TRUE_LITERAL { $$ = AidlConstantValue::Boolean(loc(@1), true); }
| FALSE_LITERAL { $$ = AidlConstantValue::Boolean(loc(@1), false); }
| CHARVALUE { $$ = AidlConstantValue::Character(loc(@1), $1); }
| INTVALUE {
$$ = AidlConstantValue::Integral(loc(@1), $1->GetText());
- if ($$ == nullptr) {
- std::cerr << "ERROR: Could not parse integer: "
- << $1->GetText() << " at " << @1 << ".\n";
- ps->AddError();
- $$ = AidlConstantValue::Integral(loc(@1), "0");
- }
delete $1;
}
| FLOATVALUE {
@@ -346,13 +269,7 @@
delete $1;
}
| HEXVALUE {
- $$ = AidlConstantValue::Integral(loc(@1), $1->GetText());
- if ($$ == nullptr) {
- std::cerr << "ERROR: Could not parse hexvalue: "
- << $1->GetText() << " at " << @1 << ".\n";
- ps->AddError();
- $$ = AidlConstantValue::Integral(loc(@1), "0");
- }
+ $$ = AidlConstantValue::Hex(loc(@1), $1->GetText());
delete $1;
}
| C_STR {
@@ -360,85 +277,9 @@
delete $1;
}
| '{' constant_value_list '}' {
- $$ = AidlConstantValue::Array(loc(@1), std::unique_ptr<vector<unique_ptr<AidlConstantValue>>>($2));
+ $$ = AidlConstantValue::Array(loc(@1), $2);
+ delete $2;
}
- | const_expr LOGICAL_OR const_expr {
- $$ = new AidlBinaryConstExpression(loc(@1), std::unique_ptr<AidlConstantValue>($1), "||", std::unique_ptr<AidlConstantValue>($3));
- }
- | const_expr LOGICAL_AND const_expr {
- $$ = new AidlBinaryConstExpression(loc(@1), std::unique_ptr<AidlConstantValue>($1), "&&", std::unique_ptr<AidlConstantValue>($3));
- }
- | const_expr '|' const_expr {
- $$ = new AidlBinaryConstExpression(loc(@1), std::unique_ptr<AidlConstantValue>($1), "|" , std::unique_ptr<AidlConstantValue>($3));
- }
- | const_expr '^' const_expr {
- $$ = new AidlBinaryConstExpression(loc(@1), std::unique_ptr<AidlConstantValue>($1), "^" , std::unique_ptr<AidlConstantValue>($3));
- }
- | const_expr '&' const_expr {
- $$ = new AidlBinaryConstExpression(loc(@1), std::unique_ptr<AidlConstantValue>($1), "&" , std::unique_ptr<AidlConstantValue>($3));
- }
- | const_expr EQUALITY const_expr {
- $$ = new AidlBinaryConstExpression(loc(@1), std::unique_ptr<AidlConstantValue>($1), "==", std::unique_ptr<AidlConstantValue>($3));
- }
- | const_expr NEQ const_expr {
- $$ = new AidlBinaryConstExpression(loc(@1), std::unique_ptr<AidlConstantValue>($1), "!=", std::unique_ptr<AidlConstantValue>($3));
- }
- | const_expr '<' const_expr {
- $$ = new AidlBinaryConstExpression(loc(@1), std::unique_ptr<AidlConstantValue>($1), "<" , std::unique_ptr<AidlConstantValue>($3));
- }
- | const_expr '>' const_expr {
- $$ = new AidlBinaryConstExpression(loc(@1), std::unique_ptr<AidlConstantValue>($1), ">" , std::unique_ptr<AidlConstantValue>($3));
- }
- | const_expr LEQ const_expr {
- $$ = new AidlBinaryConstExpression(loc(@1), std::unique_ptr<AidlConstantValue>($1), "<=", std::unique_ptr<AidlConstantValue>($3));
- }
- | const_expr GEQ const_expr {
- $$ = new AidlBinaryConstExpression(loc(@1), std::unique_ptr<AidlConstantValue>($1), ">=", std::unique_ptr<AidlConstantValue>($3));
- }
- | const_expr LSHIFT const_expr {
- $$ = new AidlBinaryConstExpression(loc(@1), std::unique_ptr<AidlConstantValue>($1), "<<", std::unique_ptr<AidlConstantValue>($3));
- }
- | const_expr RSHIFT const_expr {
- $$ = new AidlBinaryConstExpression(loc(@1), std::unique_ptr<AidlConstantValue>($1), ">>", std::unique_ptr<AidlConstantValue>($3));
- }
- | const_expr '+' const_expr {
- $$ = new AidlBinaryConstExpression(loc(@1), std::unique_ptr<AidlConstantValue>($1), "+" , std::unique_ptr<AidlConstantValue>($3));
- }
- | const_expr '-' const_expr {
- $$ = new AidlBinaryConstExpression(loc(@1), std::unique_ptr<AidlConstantValue>($1), "-" , std::unique_ptr<AidlConstantValue>($3));
- }
- | const_expr '*' const_expr {
- $$ = new AidlBinaryConstExpression(loc(@1), std::unique_ptr<AidlConstantValue>($1), "*" , std::unique_ptr<AidlConstantValue>($3));
- }
- | const_expr '/' const_expr {
- $$ = new AidlBinaryConstExpression(loc(@1), std::unique_ptr<AidlConstantValue>($1), "/" , std::unique_ptr<AidlConstantValue>($3));
- }
- | const_expr '%' const_expr {
- $$ = new AidlBinaryConstExpression(loc(@1), std::unique_ptr<AidlConstantValue>($1), "%" , std::unique_ptr<AidlConstantValue>($3));
- }
- | '+' const_expr %prec UNARY_PLUS {
- $$ = new AidlUnaryConstExpression(loc(@1), "+", std::unique_ptr<AidlConstantValue>($2));
- }
- | '-' const_expr %prec UNARY_MINUS {
- $$ = new AidlUnaryConstExpression(loc(@1), "-", std::unique_ptr<AidlConstantValue>($2));
- }
- | '!' const_expr {
- $$ = new AidlUnaryConstExpression(loc(@1), "!", std::unique_ptr<AidlConstantValue>($2));
- }
- | '~' const_expr {
- $$ = new AidlUnaryConstExpression(loc(@1), "~", std::unique_ptr<AidlConstantValue>($2));
- }
- | '(' const_expr ')'
- {
- $$ = $2;
- }
- | '(' error ')'
- {
- std::cerr << "ERROR: invalid const expression within parenthesis at " << @1 << ".\n";
- ps->AddError();
- // to avoid segfaults
- $$ = AidlConstantValue::Integral(loc(@1), "0");
- }
;
constant_value_list
@@ -451,112 +292,54 @@
;
constant_value_non_empty_list
- : const_expr {
+ : constant_value {
$$ = new std::vector<std::unique_ptr<AidlConstantValue>>;
$$->push_back(std::unique_ptr<AidlConstantValue>($1));
}
- | constant_value_non_empty_list ',' const_expr {
+ | constant_value_non_empty_list ',' constant_value {
$$ = $1;
$$->push_back(std::unique_ptr<AidlConstantValue>($3));
}
;
constant_decl
- : CONST type identifier '=' const_expr ';' {
+ : CONST type identifier '=' constant_value ';' {
$$ = new AidlConstantDeclaration(loc(@3), $2, $3->GetText(), $5);
delete $3;
}
;
-enumerator
- : identifier '=' const_expr {
- $$ = new AidlEnumerator(loc(@1), $1->GetText(), $3, $1->GetComments());
- delete $1;
- }
- | identifier {
- $$ = new AidlEnumerator(loc(@1), $1->GetText(), nullptr, $1->GetComments());
- delete $1;
- }
- ;
-
-enumerators
- : enumerator {
- $$ = new std::vector<std::unique_ptr<AidlEnumerator>>();
- $$->push_back(std::unique_ptr<AidlEnumerator>($1));
- }
- | enumerators ',' enumerator {
- $1->push_back(std::unique_ptr<AidlEnumerator>($3));
- $$ = $1;
- }
- ;
-
-enum_decl_body
- : '{' enumerators '}' { $$ = $2; }
- | '{' enumerators ',' '}' { $$ = $2; }
- ;
-
-enum_decl
- : ENUM identifier enum_decl_body {
- $$ = new AidlEnumDeclaration(loc(@2), $2->GetText(), $3, ps->Package(), $1->GetComments());
- delete $1;
- delete $2;
- delete $3;
- }
- ;
-
method_decl
: type identifier '(' arg_list ')' ';' {
$$ = new AidlMethod(loc(@2), false, $1, $2->GetText(), $4, $1->GetComments());
delete $2;
}
- | annotation_list ONEWAY type identifier '(' arg_list ')' ';' {
- const std::string& comments = ($1->size() > 0) ? $1->begin()->GetComments() : $2->GetComments();
- $$ = new AidlMethod(loc(@4), true, $3, $4->GetText(), $6, comments);
- $3->Annotate(std::move(*$1));
+ | ONEWAY type identifier '(' arg_list ')' ';' {
+ $$ = new AidlMethod(loc(@3), true, $2, $3->GetText(), $5, $1->GetComments());
delete $1;
- delete $2;
- delete $4;
+ delete $3;
}
| type identifier '(' arg_list ')' '=' INTVALUE ';' {
- int32_t serial;
- if (!android::base::ParseInt($7->GetText(), &serial)) {
- AIDL_ERROR(loc(@7)) << "Could not parse int value: " << $7->GetText();
- ps->AddError();
- }
- $$ = new AidlMethod(loc(@2), false, $1, $2->GetText(), $4, $1->GetComments(), serial);
+ $$ = new AidlMethod(loc(@2), false, $1, $2->GetText(), $4, $1->GetComments(), std::stoi($7->GetText()));
delete $2;
- delete $7;
}
- | annotation_list ONEWAY type identifier '(' arg_list ')' '=' INTVALUE ';' {
- const std::string& comments = ($1->size() > 0) ? $1->begin()->GetComments() : $2->GetComments();
- int32_t serial;
- if (!android::base::ParseInt($9->GetText(), &serial)) {
- AIDL_ERROR(loc(@9)) << "Could not parse int value: " << $9->GetText();
- ps->AddError();
- }
- $$ = new AidlMethod(loc(@4), true, $3, $4->GetText(), $6, comments, serial);
- $3->Annotate(std::move(*$1));
+ | ONEWAY type identifier '(' arg_list ')' '=' INTVALUE ';' {
+ $$ = new AidlMethod(loc(@3), true, $2, $3->GetText(), $5, $1->GetComments(), std::stoi($8->GetText()));
delete $1;
- delete $2;
- delete $4;
- delete $9;
- };
-
-arg_non_empty_list
- : arg {
- $$ = new std::vector<std::unique_ptr<AidlArgument>>();
- $$->push_back(std::unique_ptr<AidlArgument>($1));
- }
- | arg_non_empty_list ',' arg {
- $$ = $1;
- $$->push_back(std::unique_ptr<AidlArgument>($3));
+ delete $3;
};
arg_list
- : /*empty*/
- { $$ = new std::vector<std::unique_ptr<AidlArgument>>(); }
- | arg_non_empty_list { $$ = $1; }
- ;
+ :
+ { $$ = new std::vector<std::unique_ptr<AidlArgument>>(); }
+ | arg {
+ $$ = new std::vector<std::unique_ptr<AidlArgument>>();
+ $$->push_back(std::unique_ptr<AidlArgument>($1));
+ }
+ | arg_list ',' arg {
+ $$ = $1;
+ $$->push_back(std::unique_ptr<AidlArgument>($3));
+ };
arg
: direction type identifier {
@@ -567,7 +350,9 @@
$$ = new AidlArgument(loc(@2), $1, $2->GetText());
delete $2;
}
- ;
+ | error {
+ ps->AddError();
+ };
unannotated_type
: qualified_name {
@@ -604,7 +389,6 @@
}
| type_args ',' unannotated_type {
$1->emplace_back($3);
- $$ = $1;
};
annotation_list
@@ -616,60 +400,17 @@
$1->emplace_back(std::move(*$2));
delete $2;
}
- $$ = $1;
- };
-
-parameter
- : identifier '=' const_expr {
- $$ = new AidlAnnotationParameter{$1->GetText(), std::unique_ptr<AidlConstantValue>($3)};
- delete $1;
- };
-
-parameter_list
- : /*empty*/{
- $$ = new std::map<std::string, std::shared_ptr<AidlConstantValue>>();
- }
- | parameter_non_empty_list {
- $$ = $1;
- };
-
-parameter_non_empty_list
- : parameter {
- $$ = new std::map<std::string, std::shared_ptr<AidlConstantValue>>();
- $$->emplace(std::move($1->name), $1->value.release());
- delete $1;
- }
- | parameter_non_empty_list ',' parameter {
- $$ = $1;
- if ($$->find($3->name) != $$->end()) {
- AIDL_ERROR(loc(@3)) << "Trying to redefine parameter " << $3->name << ".";
- ps->AddError();
- }
- $$->emplace(std::move($3->name), std::move($3->value));
- delete $3;
};
annotation
: ANNOTATION
{
- $$ = AidlAnnotation::Parse(loc(@1), $1->GetText(), nullptr);
- if ($$) {
- $$->SetComments($1->GetComments());
- } else {
+ $$ = AidlAnnotation::Parse(loc(@1), $1->GetText());
+ if ($$ == nullptr) {
ps->AddError();
}
- delete $1;
+ $$->SetComments($1->GetComments());
};
- | ANNOTATION '(' parameter_list ')' {
- $$ = AidlAnnotation::Parse(loc(@1), $1->GetText(), $3);
- if ($$) {
- $$->SetComments($1->GetComments());
- } else {
- ps->AddError();
- }
- delete $1;
- delete $3;
- }
direction
: IN
diff --git a/aidl_to_cpp.cpp b/aidl_to_cpp.cpp
index f5fa3f8..f335475 100644
--- a/aidl_to_cpp.cpp
+++ b/aidl_to_cpp.cpp
@@ -18,182 +18,17 @@
#include "aidl_language.h"
#include "logging.h"
-#include <android-base/stringprintf.h>
-#include <android-base/strings.h>
-
#include <functional>
#include <unordered_map>
-using android::base::Join;
-using android::base::Split;
-using android::base::StringPrintf;
using std::ostringstream;
namespace android {
namespace aidl {
namespace cpp {
-namespace {
-std::string RawParcelMethod(const AidlTypeSpecifier& raw_type, const AidlTypenames& typenames,
- bool readMethod) {
- static map<string, string> kBuiltin = {
- {"byte", "Byte"},
- {"boolean", "Bool"},
- {"char", "Char"},
- {"double", "Double"},
- {"FileDescriptor", "UniqueFileDescriptor"},
- {"float", "Float"},
- {"IBinder", "StrongBinder"},
- {"int", "Int32"},
- {"long", "Int64"},
- {"ParcelFileDescriptor", "Parcelable"},
- {"String", "String16"},
- };
-
- static map<string, string> kBuiltinVector = {
- {"FileDescriptor", "UniqueFileDescriptorVector"},
- {"double", "DoubleVector"},
- {"char", "CharVector"},
- {"boolean", "BoolVector"},
- {"byte", "ByteVector"},
- {"float", "FloatVector"},
- {"IBinder", "StrongBinderVector"},
- {"String", "String16Vector"},
- {"int", "Int32Vector"},
- {"long", "Int64Vector"},
- {"ParcelFileDescriptor", "ParcelableVector"},
- };
-
- const bool nullable = raw_type.IsNullable();
- const bool isVector =
- raw_type.IsArray() || (raw_type.IsGeneric() && raw_type.GetName() == "List");
- const bool utf8 = raw_type.IsUtf8InCpp();
- const auto& type = raw_type.IsGeneric() ? *raw_type.GetTypeParameters().at(0) : raw_type;
- const string& aidl_name = type.GetName();
-
- if (auto enum_decl = typenames.GetEnumDeclaration(raw_type); enum_decl != nullptr) {
- if (isVector) {
- return "EnumVector";
- } else {
- return RawParcelMethod(enum_decl->GetBackingType(), typenames, readMethod);
- }
- }
-
- if (isVector) {
- if (kBuiltinVector.find(aidl_name) != kBuiltinVector.end()) {
- CHECK(AidlTypenames::IsBuiltinTypename(aidl_name));
- if (utf8) {
- CHECK(aidl_name == "String");
- return readMethod ? "Utf8VectorFromUtf16Vector" : "Utf8VectorAsUtf16Vector";
- }
- return kBuiltinVector[aidl_name];
- }
- } else {
- if (kBuiltin.find(aidl_name) != kBuiltin.end()) {
- CHECK(AidlTypenames::IsBuiltinTypename(aidl_name));
- if (aidl_name == "IBinder" && nullable && readMethod) {
- return "NullableStrongBinder";
- }
- if (aidl_name == "ParcelFileDescriptor" && nullable && !readMethod) {
- return "NullableParcelable";
- }
- if (utf8) {
- CHECK(aidl_name == "String");
- return readMethod ? "Utf8FromUtf16" : "Utf8AsUtf16";
- }
- return kBuiltin[aidl_name];
- }
- }
- CHECK(!AidlTypenames::IsBuiltinTypename(aidl_name));
- auto definedType = typenames.TryGetDefinedType(type.GetName());
- if (definedType != nullptr && definedType->AsInterface() != nullptr) {
- if (isVector) {
- return "StrongBinderVector";
- }
- if (nullable && readMethod) {
- return "NullableStrongBinder";
- }
- return "StrongBinder";
- }
-
- // The type must be either primitive or interface or parcelable,
- // so it cannot be nullptr.
- CHECK(definedType != nullptr) << type.GetName() << " is not found.";
-
- // Parcelable
- if (isVector) {
- return "ParcelableVector";
- }
- if (nullable && !readMethod) {
- return "NullableParcelable";
- }
- return "Parcelable";
-}
-
-std::string GetRawCppName(const AidlTypeSpecifier& type) {
- return "::" + Join(type.GetSplitName(), "::");
-}
-
-std::string WrapIfNullable(const std::string type_str, const AidlTypeSpecifier& raw_type,
- const AidlTypenames& typenames) {
- const auto& type = raw_type.IsGeneric() ? (*raw_type.GetTypeParameters().at(0)) : raw_type;
-
- if (raw_type.IsNullable() && !AidlTypenames::IsPrimitiveTypename(type.GetName()) &&
- type.GetName() != "IBinder" && typenames.GetEnumDeclaration(type) == nullptr) {
- return "::std::unique_ptr<" + type_str + ">";
- }
- return type_str;
-}
-
-std::string GetCppName(const AidlTypeSpecifier& raw_type, const AidlTypenames& typenames) {
- // map from AIDL built-in type name to the corresponding Cpp type name
- static map<string, string> m = {
- {"boolean", "bool"},
- {"byte", "int8_t"},
- {"char", "char16_t"},
- {"double", "double"},
- {"FileDescriptor", "::android::base::unique_fd"},
- {"float", "float"},
- {"IBinder", "::android::sp<::android::IBinder>"},
- {"int", "int32_t"},
- {"long", "int64_t"},
- {"ParcelFileDescriptor", "::android::os::ParcelFileDescriptor"},
- {"String", "::android::String16"},
- {"void", "void"},
- };
-
- CHECK(!raw_type.IsGeneric() ||
- (raw_type.GetName() == "List" && raw_type.GetTypeParameters().size() == 1));
- const auto& type = raw_type.IsGeneric() ? (*raw_type.GetTypeParameters().at(0)) : raw_type;
- const string& aidl_name = type.GetName();
- if (m.find(aidl_name) != m.end()) {
- CHECK(AidlTypenames::IsBuiltinTypename(aidl_name));
- if (aidl_name == "byte" && type.IsArray()) {
- return "uint8_t";
- } else if (raw_type.IsUtf8InCpp()) {
- CHECK(aidl_name == "String");
- return WrapIfNullable("::std::string", raw_type, typenames);
- }
- return WrapIfNullable(m[aidl_name], raw_type, typenames);
- }
- auto definedType = typenames.TryGetDefinedType(type.GetName());
- if (definedType != nullptr && definedType->AsInterface() != nullptr) {
- return "::android::sp<" + GetRawCppName(type) + ">";
- }
-
- return WrapIfNullable(GetRawCppName(type), raw_type, typenames);
-}
-} // namespace
std::string ConstantValueDecorator(const AidlTypeSpecifier& type, const std::string& raw_value) {
- if (type.IsArray()) {
- return raw_value;
- }
-
- if (type.GetName() == "long") {
- return raw_value + "L";
- }
-
- if (type.GetName() == "String" && !type.IsUtf8InCpp()) {
+ if (type.GetName() == "String" && !type.IsArray() && !type.IsUtf8InCpp()) {
return "::android::String16(" + raw_value + ")";
}
@@ -207,113 +42,6 @@
output << method.GetId() << " /* " << method.GetName() << " */";
return output.str();
}
-
-std::string CppNameOf(const AidlTypeSpecifier& type, const AidlTypenames& typenames) {
- if (type.IsArray() || type.IsGeneric()) {
- std::string cpp_name = GetCppName(type, typenames);
- if (type.IsNullable()) {
- return "::std::unique_ptr<::std::vector<" + cpp_name + ">>";
- }
- return "::std::vector<" + cpp_name + ">";
- }
- return GetCppName(type, typenames);
-}
-
-std::string ParcelReadMethodOf(const AidlTypeSpecifier& type, const AidlTypenames& typenames) {
- return "read" + RawParcelMethod(type, typenames, true /* readMethod */);
-}
-
-std::string ParcelReadCastOf(const AidlTypeSpecifier& type, const AidlTypenames& typenames,
- const std::string& variable_name) {
- if (auto enum_decl = typenames.GetEnumDeclaration(type);
- enum_decl != nullptr && !type.IsArray()) {
- return StringPrintf("reinterpret_cast<%s *>(%s)",
- CppNameOf(enum_decl->GetBackingType(), typenames).c_str(),
- variable_name.c_str());
- }
-
- return variable_name;
-}
-
-std::string ParcelWriteMethodOf(const AidlTypeSpecifier& type, const AidlTypenames& typenames) {
- return "write" + RawParcelMethod(type, typenames, false /* readMethod */);
-}
-
-std::string ParcelWriteCastOf(const AidlTypeSpecifier& type, const AidlTypenames& typenames,
- const std::string& variable_name) {
- if (auto enum_decl = typenames.GetEnumDeclaration(type);
- enum_decl != nullptr && !type.IsArray()) {
- return StringPrintf("static_cast<%s>(%s)",
- CppNameOf(enum_decl->GetBackingType(), typenames).c_str(),
- variable_name.c_str());
- }
-
- if (typenames.GetInterface(type) != nullptr) {
- return GetRawCppName(type) + "::asBinder(" + variable_name + ")";
- }
-
- return variable_name;
-}
-
-void AddHeaders(const AidlTypeSpecifier& raw_type, const AidlTypenames& typenames,
- std::set<std::string>& headers) {
- bool isVector = raw_type.IsArray() || raw_type.IsGeneric();
- bool isNullable = raw_type.IsNullable();
- bool utf8 = raw_type.IsUtf8InCpp();
-
- CHECK(!raw_type.IsGeneric() ||
- (raw_type.GetName() == "List" && raw_type.GetTypeParameters().size() == 1));
- const auto& type = raw_type.IsGeneric() ? *raw_type.GetTypeParameters().at(0) : raw_type;
- auto definedType = typenames.TryGetDefinedType(type.GetName());
-
- if (isVector) {
- headers.insert("vector");
- }
- if (isNullable) {
- if (type.GetName() != "IBinder") {
- headers.insert("memory");
- }
- }
- if (type.GetName() == "String") {
- headers.insert(utf8 ? "string" : "utils/String16.h");
- }
- if (type.GetName() == "IBinder") {
- headers.insert("binder/IBinder.h");
- }
- if (type.GetName() == "FileDescriptor") {
- headers.insert("android-base/unique_fd.h");
- }
- if (type.GetName() == "ParcelFileDescriptor") {
- headers.insert("binder/ParcelFileDescriptor.h");
- }
-
- static const std::set<string> need_cstdint{"byte", "int", "long"};
- if (need_cstdint.find(type.GetName()) != need_cstdint.end()) {
- headers.insert("cstdint");
- }
-
- if (definedType == nullptr) {
- return;
- }
- if (definedType->AsInterface() != nullptr || definedType->AsStructuredParcelable() != nullptr ||
- definedType->AsEnumDeclaration() != nullptr) {
- AddHeaders(*definedType, headers);
- } else if (definedType->AsParcelable() != nullptr) {
- const std::string cpp_header = definedType->AsParcelable()->GetCppHeader();
- AIDL_FATAL_IF(cpp_header.empty(), definedType->AsParcelable())
- << "Parcelable " << definedType->AsParcelable()->GetCanonicalName()
- << " has no C++ header defined.";
- headers.insert(cpp_header);
- }
-}
-
-void AddHeaders(const AidlDefinedType& definedType, std::set<std::string>& headers) {
- vector<string> name = definedType.GetSplitPackage();
- name.push_back(definedType.GetName());
- const std::string cpp_header = Join(name, '/') + ".h";
- headers.insert(cpp_header);
-}
-
} // namespace cpp
} // namespace aidl
} // namespace android
diff --git a/aidl_to_cpp.h b/aidl_to_cpp.h
index 3bf608c..5c936c9 100644
--- a/aidl_to_cpp.h
+++ b/aidl_to_cpp.h
@@ -36,31 +36,6 @@
};
std::string GetTransactionIdFor(const AidlMethod& method);
-
-std::string CppNameOf(const AidlTypeSpecifier& type, const AidlTypenames& typenames);
-
-// Returns the name of the Parcel method suitable for reading data of the
-// given type.
-std::string ParcelReadMethodOf(const AidlTypeSpecifier& type, const AidlTypenames& typenames);
-
-// Returns the potentially-cast representation of the provided variable name,
-// suitable for being passed to a method from ParcelReadMethodOf.
-std::string ParcelReadCastOf(const AidlTypeSpecifier& type, const AidlTypenames& typenames,
- const std::string& variable_name);
-
-// Returns the name of the Parcel method suitable for writing data of the
-// given type.
-std::string ParcelWriteMethodOf(const AidlTypeSpecifier& type, const AidlTypenames& typenames);
-
-// Returns the potentially-cast representation of the provided variable name,
-// suitable for being passed to a method from ParcelWriteMethodOf.
-std::string ParcelWriteCastOf(const AidlTypeSpecifier& type, const AidlTypenames& typenames,
- const std::string& variable_name);
-
-void AddHeaders(const AidlTypeSpecifier& type, const AidlTypenames& typenames,
- std::set<std::string>& headers);
-
-void AddHeaders(const AidlDefinedType& parcelable, std::set<std::string>& headers);
} // namespace cpp
} // namespace aidl
} // namespace android
diff --git a/aidl_to_java.cpp b/aidl_to_java.cpp
index ec7909d..d8a6368 100644
--- a/aidl_to_java.cpp
+++ b/aidl_to_java.cpp
@@ -21,6 +21,7 @@
#include <android-base/strings.h>
+#include <cassert>
#include <functional>
#include <iostream>
#include <map>
@@ -39,35 +40,15 @@
using std::string;
using std::vector;
-std::string ConstantValueDecorator(const AidlTypeSpecifier& type, const std::string& raw_value) {
- if (type.GetName() == "long" && !type.IsArray()) {
- return raw_value + "L";
- }
-
+std::string ConstantValueDecorator(const AidlTypeSpecifier& /*type*/,
+ const std::string& raw_value) {
+ // no difference
return raw_value;
};
-const string& JavaNameOf(const AidlTypeSpecifier& aidl, const AidlTypenames& typenames,
- bool instantiable = false) {
+const string& JavaNameOf(const AidlTypeSpecifier& aidl) {
CHECK(aidl.IsResolved()) << aidl.ToString();
- if (instantiable) {
- // An instantiable type is used in only out type(not even inout type),
- // And instantiable type has to be either the type in List, Map, ParcelFileDescriptor or
- // user-defined type.
-
- static map<string, string> instantiable_m = {
- {"List", "java.util.ArrayList"},
- {"Map", "java.util.HashMap"},
- {"ParcelFileDescriptor", "android.os.ParcelFileDescriptor"},
- };
- const string& aidl_name = aidl.GetName();
-
- if (instantiable_m.find(aidl_name) != instantiable_m.end()) {
- return instantiable_m[aidl_name];
- }
- }
-
// map from AIDL built-in type name to the corresponding Java type name
static map<string, string> m = {
{"void", "void"},
@@ -86,17 +67,6 @@
{"CharSequence", "java.lang.CharSequence"},
{"ParcelFileDescriptor", "android.os.ParcelFileDescriptor"},
};
-
- // Enums in Java are represented by their backing type when
- // referenced in parcelables, methods, etc.
- if (const AidlEnumDeclaration* enum_decl = typenames.GetEnumDeclaration(aidl);
- enum_decl != nullptr) {
- const string& backing_type_name = enum_decl->GetBackingType().GetName();
- CHECK(m.find(backing_type_name) != m.end());
- CHECK(AidlTypenames::IsBuiltinTypename(backing_type_name));
- return m[backing_type_name];
- }
-
const string& aidl_name = aidl.GetName();
if (m.find(aidl_name) != m.end()) {
CHECK(AidlTypenames::IsBuiltinTypename(aidl_name));
@@ -107,59 +77,28 @@
}
}
-namespace {
-string JavaSignatureOfInternal(const AidlTypeSpecifier& aidl, const AidlTypenames& typenames,
- bool instantiable, bool omit_array) {
- string ret = JavaNameOf(aidl, typenames, instantiable);
+string JavaSignatureOf(const AidlTypeSpecifier& aidl) {
+ string ret = JavaNameOf(aidl);
if (aidl.IsGeneric()) {
vector<string> arg_names;
for (const auto& ta : aidl.GetTypeParameters()) {
- arg_names.emplace_back(JavaSignatureOfInternal(*ta, typenames, false, false));
+ arg_names.emplace_back(JavaSignatureOf(*ta));
}
ret += "<" + Join(arg_names, ",") + ">";
}
- if (aidl.IsArray() && !omit_array) {
+ if (aidl.IsArray()) {
ret += "[]";
}
return ret;
}
-// Returns the name of the backing type for the specified type. Note: this
-// returns type names as used in AIDL, not a Java signature.
-// For enums, this is the enum's backing type.
-// For all other types, this is the type itself.
-string AidlBackingTypeName(const AidlTypeSpecifier& type, const AidlTypenames& typenames) {
- string type_name;
- if (const AidlEnumDeclaration* enum_decl = typenames.GetEnumDeclaration(type);
- enum_decl != nullptr) {
- type_name = enum_decl->GetBackingType().GetName();
- } else {
- type_name = type.GetName();
- }
- if (type.IsArray()) {
- type_name += "[]";
- }
- return type_name;
-}
-
-} // namespace
-
-string JavaSignatureOf(const AidlTypeSpecifier& aidl, const AidlTypenames& typenames) {
- return JavaSignatureOfInternal(aidl, typenames, false, false);
-}
-
-string InstantiableJavaSignatureOf(const AidlTypeSpecifier& aidl, const AidlTypenames& typenames) {
- return JavaSignatureOfInternal(aidl, typenames, true, true);
-}
-
-string DefaultJavaValueOf(const AidlTypeSpecifier& aidl, const AidlTypenames& typenames) {
+string DefaultJavaValueOf(const AidlTypeSpecifier& aidl) {
static map<string, string> m = {
{"boolean", "false"}, {"byte", "0"}, {"char", R"('\u0000')"}, {"int", "0"},
{"long", "0L"}, {"float", "0.0f"}, {"double", "0.0d"},
};
-
- const string name = AidlBackingTypeName(aidl, typenames);
- CHECK(name != "void");
+ const string& name = aidl.GetName();
+ assert(name != "void");
if (!aidl.IsArray() && m.find(name) != m.end()) {
CHECK(AidlTypenames::IsBuiltinTypename(name));
@@ -370,7 +309,7 @@
c.writer << "}\n";
}},
};
- const string type_name = AidlBackingTypeName(c.type, c.typenames);
+ const string type_name = c.type.GetName() + (c.type.IsArray() ? "[]" : "");
const auto found = method_map.find(type_name);
if (found != method_map.end()) {
found->second(c);
@@ -503,8 +442,7 @@
CHECK(t != nullptr) << "Unknown type: " << contained_type << endl;
if (t->AsParcelable() != nullptr) {
c.writer << c.var << " = " << c.parcel << ".createTypedArrayList("
- << JavaNameOf(*(c.type.GetTypeParameters().at(0)), c.typenames)
- << ".CREATOR);\n";
+ << JavaNameOf(*(c.type.GetTypeParameters().at(0))) << ".CREATOR);\n";
}
}
} else {
@@ -570,7 +508,8 @@
c.writer << "}\n";
}},
};
- const auto found = method_map.find(AidlBackingTypeName(c.type, c.typenames));
+ const string type_name = c.type.GetName() + (c.type.IsArray() ? "[]" : "");
+ const auto found = method_map.find(type_name);
if (found != method_map.end()) {
found->second(c);
} else {
@@ -583,8 +522,8 @@
}
} else if (t->AsParcelable() != nullptr || t->AsStructuredParcelable() != nullptr) {
if (c.type.IsArray()) {
- c.writer << c.var << " = " << c.parcel << ".createTypedArray("
- << JavaNameOf(c.type, c.typenames) << ".CREATOR);\n";
+ c.writer << c.var << " = " << c.parcel << ".createTypedArray(" << JavaNameOf(c.type)
+ << ".CREATOR);\n";
} else {
// This is same as readTypedObject.
// Keeping below code just not to break unit tests.
@@ -657,8 +596,7 @@
CHECK(t != nullptr) << "Unknown type: " << contained_type << endl;
if (t->AsParcelable() != nullptr) {
c.writer << c.parcel << ".readTypedList(" << c.var << ", "
- << JavaNameOf(*(c.type.GetTypeParameters().at(0)), c.typenames)
- << ".CREATOR);\n";
+ << JavaNameOf(*(c.type.GetTypeParameters().at(0))) << ".CREATOR);\n";
}
}
} else {
@@ -693,7 +631,8 @@
<< ", android.os.ParcelFileDescriptor.CREATOR);\n";
}},
};
- const auto& found = method_map.find(AidlBackingTypeName(c.type, c.typenames));
+ const string type_name = c.type.GetName() + (c.type.IsArray() ? "[]" : "");
+ const auto& found = method_map.find(type_name);
if (found != method_map.end()) {
found->second(c);
} else {
diff --git a/aidl_to_java.h b/aidl_to_java.h
index d33b25b..060b113 100644
--- a/aidl_to_java.h
+++ b/aidl_to_java.h
@@ -41,16 +41,16 @@
std::string ConstantValueDecorator(const AidlTypeSpecifier& type, const std::string& raw_value);
-// Returns the Java type signature of the AIDL type spec
-// This includes generic type parameters with array modifiers.
-string JavaSignatureOf(const AidlTypeSpecifier& aidl, const AidlTypenames& typenames);
+// Returns the corresponding Java type name for an AIDL type spec
+// This excludes generic type parameters and array modifiers.
+const string& JavaNameOf(const AidlTypeSpecifier& aidl);
-// Returns the instantiable Jva type signature of the AIDL type spec
-// This includes generic type parameters, but excludes array modifiers.
-string InstantiableJavaSignatureOf(const AidlTypeSpecifier& aidl, const AidlTypenames& typenames);
+// Returns the Java type signature of the AIDL type spec
+// This includes generic type parameters and array modifiers.
+string JavaSignatureOf(const AidlTypeSpecifier& aidl);
// Returns the default Java value of the AIDL type spec
-string DefaultJavaValueOf(const AidlTypeSpecifier& aidl, const AidlTypenames& typenames);
+string DefaultJavaValueOf(const AidlTypeSpecifier& aidl);
// This carries information that is required to generate code for
// marshalling and unmarshalling a method argument or a parcelable field
diff --git a/aidl_to_ndk.cpp b/aidl_to_ndk.cpp
index 5379564..26d2465 100644
--- a/aidl_to_ndk.cpp
+++ b/aidl_to_ndk.cpp
@@ -68,14 +68,6 @@
std::shared_ptr<Aspect> nullable_array;
};
-std::string ConstantValueDecorator(const AidlTypeSpecifier& type, const std::string& raw_value) {
- if (type.GetName() == "long" && !type.IsArray()) {
- return raw_value + "L";
- }
-
- return raw_value;
-};
-
static std::function<void(const CodeGeneratorContext& c)> StandardRead(const std::string& name) {
return [name](const CodeGeneratorContext& c) {
c.writer << name << "(" << c.parcel << ", " << c.var << ")";
@@ -163,77 +155,7 @@
};
}
-TypeInfo EnumDeclarationTypeInfo(const AidlEnumDeclaration& enum_decl) {
- const std::string clazz = NdkFullClassName(enum_decl, cpp::ClassNames::BASE);
-
- static map<std::string, std::string> kAParcelTypeNameMap = {
- {"byte", "Byte"},
- {"int", "Int32"},
- {"long", "Int64"},
- };
- auto aparcel_name_it = kAParcelTypeNameMap.find(enum_decl.GetBackingType().GetName());
- CHECK(aparcel_name_it != kAParcelTypeNameMap.end());
- const std::string aparcel_name = aparcel_name_it->second;
-
- const std::string backing_type_name =
- NdkNameOf(AidlTypenames(), enum_decl.GetBackingType(), StorageMode::STACK);
-
- return TypeInfo{
- .raw = TypeInfo::Aspect{
- .cpp_name = clazz,
- .value_is_cheap = true,
- .read_func =
- [aparcel_name, backing_type_name](const CodeGeneratorContext& c) {
- c.writer << "AParcel_read" << aparcel_name << "(" << c.parcel
- << ", reinterpret_cast<" << backing_type_name << "*>(" << c.var << "))";
- },
- .write_func =
- [aparcel_name, backing_type_name](const CodeGeneratorContext& c) {
- c.writer << "AParcel_write" << aparcel_name << "(" << c.parcel << ", static_cast<"
- << backing_type_name << ">(" << c.var << "))";
- },
- },
- .array = std::shared_ptr<TypeInfo::Aspect>(new TypeInfo::Aspect{
- .cpp_name = "std::vector<" + clazz + ">",
- .value_is_cheap = false,
- .read_func =
- [aparcel_name, backing_type_name](const CodeGeneratorContext& c) {
- c.writer << "AParcel_read" << aparcel_name << "Array(" << c.parcel
- << ", static_cast<void*>(" << c.var
- << "), ndk::AParcel_stdVectorAllocator<" << backing_type_name << ">)";
- },
- .write_func =
- [aparcel_name, backing_type_name](const CodeGeneratorContext& c) {
- c.writer << "AParcel_write" << aparcel_name << "Array(" << c.parcel
- << ", reinterpret_cast<const " << backing_type_name << "*>(" << c.var
- << ".data()), " << c.var << ".size())";
- },
- }),
- .nullable = nullptr,
- .nullable_array = std::shared_ptr<TypeInfo::Aspect>(new TypeInfo::Aspect{
- .cpp_name = "std::optional<std::vector<" + clazz + ">>",
- .value_is_cheap = false,
- .read_func =
- [aparcel_name, backing_type_name](const CodeGeneratorContext& c) {
- c.writer << "AParcel_read" << aparcel_name << "Array(" << c.parcel
- << ", static_cast<void*>(" << c.var
- << "), ndk::AParcel_nullableStdVectorAllocator<" << backing_type_name
- << ">)";
- },
- .write_func =
- [aparcel_name, backing_type_name](const CodeGeneratorContext& c) {
- // If the var exists, use writeArray with data() and size().
- // Otherwise, use nullptr and -1.
- c.writer << "AParcel_write" << aparcel_name << "Array(" << c.parcel << ", ("
- << c.var << " ? reinterpret_cast<const " << backing_type_name << "*>("
- << c.var << "->data()) : nullptr)"
- << ", (" << c.var << " ? " << c.var << "->size() : -1))";
- },
- }),
- };
-}
-
-// map from AIDL built-in type name to the corresponding Ndk type info
+// map from AIDL built-in type name to the corresponding Ndk type name
static map<std::string, TypeInfo> kNdkTypeInfoMap = {
{"void", TypeInfo{{"void", true, nullptr, nullptr}, nullptr, nullptr, nullptr}},
{"boolean", PrimitiveType("bool", "Bool")},
@@ -330,13 +252,10 @@
const AidlDefinedType* type = types.TryGetDefinedType(aidl_name);
AIDL_FATAL_IF(type == nullptr, aidl_name) << "Unrecognized type.";
- if (const AidlInterface* intf = type->AsInterface(); intf != nullptr) {
- info = InterfaceTypeInfo(*intf);
- } else if (const AidlParcelable* parcelable = type->AsParcelable(); parcelable != nullptr) {
- info = ParcelableTypeInfo(*parcelable);
- } else if (const AidlEnumDeclaration* enum_decl = type->AsEnumDeclaration();
- enum_decl != nullptr) {
- info = EnumDeclarationTypeInfo(*enum_decl);
+ if (type->AsInterface() != nullptr) {
+ info = InterfaceTypeInfo(*type->AsInterface());
+ } else if (type->AsParcelable() != nullptr) {
+ info = ParcelableTypeInfo(*type->AsParcelable());
} else {
AIDL_FATAL(aidl_name) << "Unrecognized type";
}
diff --git a/aidl_to_ndk.h b/aidl_to_ndk.h
index 1f7f490..50fb880 100644
--- a/aidl_to_ndk.h
+++ b/aidl_to_ndk.h
@@ -31,8 +31,6 @@
std::string NdkHeaderFile(const AidlDefinedType& defined_type, cpp::ClassNames name,
bool use_os_sep = true);
-std::string ConstantValueDecorator(const AidlTypeSpecifier& type, const std::string& raw_value);
-
// Returns ::aidl::some_package::some_sub_package::foo::IFoo/BpFoo/BnFoo
std::string NdkFullClassName(const AidlDefinedType& type, cpp::ClassNames name);
diff --git a/aidl_typenames.cpp b/aidl_typenames.cpp
index 6f9b590..3b79aba 100644
--- a/aidl_typenames.cpp
+++ b/aidl_typenames.cpp
@@ -81,13 +81,6 @@
return true;
}
-bool AidlTypenames::IsIgnorableImport(const string& import) const {
- static set<string> ignore_import = {"android.os.IInterface", "android.os.IBinder",
- "android.os.Parcelable", "android.os.Parcel",
- "android.content.Context", "java.lang.String"};
- return ResolveTypename(import).second || ignore_import.find(import) != ignore_import.end();
-}
-
bool AidlTypenames::AddDefinedType(unique_ptr<AidlDefinedType> type) {
const string name = type->GetCanonicalName();
if (defined_types_.find(name) != defined_types_.end()) {
@@ -169,7 +162,7 @@
// Only T[], List, Map, ParcelFileDescriptor and Parcelable can be an out parameter.
bool AidlTypenames::CanBeOutParameter(const AidlTypeSpecifier& type) const {
const string& name = type.GetName();
- if (IsBuiltinTypename(name) || GetEnumDeclaration(type)) {
+ if (IsBuiltinTypename(name)) {
return type.IsArray() || type.GetName() == "List" || type.GetName() == "Map" ||
type.GetName() == "ParcelFileDescriptor";
}
@@ -178,24 +171,6 @@
return t->AsParcelable() != nullptr;
}
-const AidlEnumDeclaration* AidlTypenames::GetEnumDeclaration(const AidlTypeSpecifier& type) const {
- if (auto defined_type = TryGetDefinedType(type.GetName()); defined_type != nullptr) {
- if (auto enum_decl = defined_type->AsEnumDeclaration(); enum_decl != nullptr) {
- return enum_decl;
- }
- }
- return nullptr;
-}
-
-const AidlInterface* AidlTypenames::GetInterface(const AidlTypeSpecifier& type) const {
- if (auto defined_type = TryGetDefinedType(type.GetName()); defined_type != nullptr) {
- if (auto intf = defined_type->AsInterface(); intf != nullptr) {
- return intf;
- }
- }
- return nullptr;
-}
-
void AidlTypenames::IterateTypes(const std::function<void(const AidlDefinedType&)>& body) const {
for (const auto& kv : defined_types_) {
body(*kv.second);
diff --git a/aidl_typenames.h b/aidl_typenames.h
index c2ea12e..74db49c 100644
--- a/aidl_typenames.h
+++ b/aidl_typenames.h
@@ -31,8 +31,6 @@
using std::vector;
class AidlDefinedType;
-class AidlEnumDeclaration;
-class AidlInterface;
class AidlTypeSpecifier;
namespace android {
@@ -60,13 +58,7 @@
const AidlDefinedType* TryGetDefinedType(const string& type_name) const;
pair<string, bool> ResolveTypename(const string& type_name) const;
bool CanBeOutParameter(const AidlTypeSpecifier& type) const;
- bool IsIgnorableImport(const string& import) const;
- // Returns the AidlEnumDeclaration of the given type, or nullptr if the type
- // is not an AidlEnumDeclaration;
- const AidlEnumDeclaration* GetEnumDeclaration(const AidlTypeSpecifier& type) const;
- // Returns the AidlInterface of the given type, or nullptr if the type
- // is not an AidlInterface;
- const AidlInterface* GetInterface(const AidlTypeSpecifier& type) const;
+
// Iterates over all defined and then preprocessed types
void IterateTypes(const std::function<void(const AidlDefinedType&)>& body) const;
diff --git a/aidl_unittest.cpp b/aidl_unittest.cpp
index 6e56514..7cf8172 100644
--- a/aidl_unittest.cpp
+++ b/aidl_unittest.cpp
@@ -26,19 +26,18 @@
#include "aidl_apicheck.h"
#include "aidl_language.h"
#include "aidl_to_cpp.h"
-#include "aidl_to_java.h"
-#include "options.h"
#include "tests/fake_io_delegate.h"
+#include "type_cpp.h"
+#include "type_java.h"
+#include "type_namespace.h"
-using android::aidl::internals::parse_preprocessed_file;
using android::aidl::test::FakeIoDelegate;
using android::base::StringPrintf;
using std::set;
using std::string;
using std::unique_ptr;
using std::vector;
-using testing::internal::CaptureStderr;
-using testing::internal::GetCapturedStderr;
+using android::aidl::internals::parse_preprocessed_file;
namespace android {
namespace aidl {
@@ -70,7 +69,7 @@
p/Foo.aidl :
)";
-const char kExpectedJavaParcelableOutputContests[] =
+const char kExepectedJavaParcelableOutputContests[] =
R"(/*
* This file is auto-generated. DO NOT MODIFY.
*/
@@ -82,11 +81,9 @@
@android.annotation.SystemApi
public int x = 5;
- @dalvik.annotation.compat.UnsupportedAppUsage(expectedSignature = "dummy", implicitMember = "dummy", maxTargetSdk = 28, publicAlternatives = "dummy", trackingBug = 42L)
+ @android.annotation.UnsupportedAppUsage
@android.annotation.SystemApi
public int y;
-
- public android.os.ParcelFileDescriptor fd;
public static final android.os.Parcelable.Creator<Rect> CREATOR = new android.os.Parcelable.Creator<Rect>() {
@Override
public Rect createFromParcel(android.os.Parcel _aidl_source) {
@@ -105,13 +102,6 @@
_aidl_parcel.writeInt(0);
_aidl_parcel.writeInt(x);
_aidl_parcel.writeInt(y);
- if ((fd!=null)) {
- _aidl_parcel.writeInt(1);
- fd.writeToParcel(_aidl_parcel, 0);
- }
- else {
- _aidl_parcel.writeInt(0);
- }
int _aidl_end_pos = _aidl_parcel.dataPosition();
_aidl_parcel.setDataPosition(_aidl_start_pos);
_aidl_parcel.writeInt(_aidl_end_pos - _aidl_start_pos);
@@ -127,13 +117,6 @@
if (_aidl_parcel.dataPosition() - _aidl_start_pos >= _aidl_parcelable_size) return;
y = _aidl_parcel.readInt();
if (_aidl_parcel.dataPosition() - _aidl_start_pos >= _aidl_parcelable_size) return;
- if ((0!=_aidl_parcel.readInt())) {
- fd = android.os.ParcelFileDescriptor.CREATOR.createFromParcel(_aidl_parcel);
- }
- else {
- fd = null;
- }
- if (_aidl_parcel.dataPosition() - _aidl_start_pos >= _aidl_parcelable_size) return;
} finally {
_aidl_parcel.setDataPosition(_aidl_start_pos + _aidl_parcelable_size);
}
@@ -150,29 +133,19 @@
class AidlTest : public ::testing::Test {
protected:
void SetUp() override {
- CaptureStderr();
+ java_types_.Init();
+ cpp_types_.Init();
}
- void TearDown() override {
- auto actual_stderr = GetCapturedStderr();
- std::cerr << actual_stderr << std::endl;
-
- if (expected_stderr_.size() > 0) {
- EXPECT_EQ(android::base::Join(expected_stderr_, ""), actual_stderr);
- }
- }
-
- void AddExpectedStderr(string expected) { expected_stderr_.push_back(expected); }
-
- AidlDefinedType* Parse(const string& path, const string& contents, AidlTypenames& typenames_,
- Options::Language lang, AidlError* error = nullptr,
+ AidlDefinedType* Parse(const string& path, const string& contents, TypeNamespace* types,
+ AidlError* error = nullptr,
const vector<string> additional_arguments = {}) {
io_delegate_.SetFileContents(path, contents);
vector<string> args;
- if (lang == Options::Language::CPP) {
- args.emplace_back("aidl-cpp");
- } else {
+ if (types == &java_types_) {
args.emplace_back("aidl");
+ } else {
+ args.emplace_back("aidl-cpp");
}
for (const string& s : additional_arguments) {
args.emplace_back(s);
@@ -189,7 +162,7 @@
vector<string> imported_files;
ImportResolver import_resolver{io_delegate_, path, import_paths_, {}};
AidlError actual_error = ::android::aidl::internals::load_and_validate_aidl(
- path, options, io_delegate_, &typenames_, &defined_types, &imported_files);
+ path, options, io_delegate_, types, &defined_types, &imported_files);
if (error != nullptr) {
*error = actual_error;
@@ -207,22 +180,13 @@
FakeIoDelegate io_delegate_;
vector<string> preprocessed_files_;
set<string> import_paths_;
- vector<string> expected_stderr_;
- AidlTypenames typenames_;
+ java::JavaTypeNamespace java_types_;
+ cpp::TypeNamespace cpp_types_;
};
TEST_F(AidlTest, AcceptMissingPackage) {
- EXPECT_NE(nullptr, Parse("IFoo.aidl", "interface IFoo { }", typenames_, Options::Language::JAVA));
- typenames_.Reset();
- EXPECT_NE(nullptr, Parse("IFoo.aidl", "interface IFoo { }", typenames_, Options::Language::CPP));
-}
-
-TEST_F(AidlTest, EndsInSingleLineComment) {
- EXPECT_NE(nullptr,
- Parse("IFoo.aidl", "interface IFoo { } // foo", typenames_, Options::Language::JAVA));
- typenames_.Reset();
- EXPECT_NE(nullptr,
- Parse("IFoo.aidl", "interface IFoo { } // foo", typenames_, Options::Language::CPP));
+ EXPECT_NE(nullptr, Parse("IFoo.aidl", "interface IFoo { }", &java_types_));
+ EXPECT_NE(nullptr, Parse("IFoo.aidl", "interface IFoo { }", &cpp_types_));
}
TEST_F(AidlTest, RejectsArraysOfBinders) {
@@ -233,22 +197,8 @@
string contents = "package foo;\n"
"import bar.IBar;\n"
"interface IFoo { void f(in IBar[] input); }";
- EXPECT_EQ(nullptr, Parse(path, contents, typenames_, Options::Language::JAVA));
- typenames_.Reset();
- EXPECT_EQ(nullptr, Parse(path, contents, typenames_, Options::Language::CPP));
-}
-
-TEST_F(AidlTest, SupportOnlyOutParameters) {
- string interface_list = "package a; interface IBar { void f(out List bar); }";
- string interface_ibinder = "package a; interface IBaz { void f(out IBinder bar); }";
- // List without type isn't supported in cpp.
- EXPECT_EQ(nullptr, Parse("a/IBar.aidl", interface_list, typenames_, Options::Language::CPP));
- typenames_.Reset();
- EXPECT_NE(nullptr, Parse("a/IBar.aidl", interface_list, typenames_, Options::Language::JAVA));
- typenames_.Reset();
- EXPECT_EQ(nullptr, Parse("a/IBaz.aidl", interface_ibinder, typenames_, Options::Language::CPP));
- typenames_.Reset();
- EXPECT_EQ(nullptr, Parse("a/IBaz.aidl", interface_ibinder, typenames_, Options::Language::JAVA));
+ EXPECT_EQ(nullptr, Parse(path, contents, &java_types_));
+ EXPECT_EQ(nullptr, Parse(path, contents, &cpp_types_));
}
TEST_F(AidlTest, RejectsOnewayOutParameters) {
@@ -256,55 +206,43 @@
"package a; oneway interface IFoo { void f(out int bar); }";
string oneway_method =
"package a; interface IBar { oneway void f(out int bar); }";
- EXPECT_EQ(nullptr, Parse("a/IFoo.aidl", oneway_interface, typenames_, Options::Language::CPP));
- typenames_.Reset();
- EXPECT_EQ(nullptr, Parse("a/IFoo.aidl", oneway_interface, typenames_, Options::Language::JAVA));
- typenames_.Reset();
- EXPECT_EQ(nullptr, Parse("a/IBar.aidl", oneway_method, typenames_, Options::Language::CPP));
- typenames_.Reset();
- EXPECT_EQ(nullptr, Parse("a/IBar.aidl", oneway_method, typenames_, Options::Language::JAVA));
+ EXPECT_EQ(nullptr, Parse("a/IFoo.aidl", oneway_interface, &cpp_types_));
+ EXPECT_EQ(nullptr, Parse("a/IFoo.aidl", oneway_interface, &java_types_));
+ EXPECT_EQ(nullptr, Parse("a/IBar.aidl", oneway_method, &cpp_types_));
+ EXPECT_EQ(nullptr, Parse("a/IBar.aidl", oneway_method, &java_types_));
}
TEST_F(AidlTest, RejectsOnewayNonVoidReturn) {
string oneway_method = "package a; interface IFoo { oneway int f(); }";
- EXPECT_EQ(nullptr, Parse("a/IFoo.aidl", oneway_method, typenames_, Options::Language::CPP));
- typenames_.Reset();
- EXPECT_EQ(nullptr, Parse("a/IFoo.aidl", oneway_method, typenames_, Options::Language::JAVA));
+ EXPECT_EQ(nullptr, Parse("a/IFoo.aidl", oneway_method, &cpp_types_));
+ EXPECT_EQ(nullptr, Parse("a/IFoo.aidl", oneway_method, &java_types_));
}
TEST_F(AidlTest, RejectsNullablePrimitive) {
string oneway_method = "package a; interface IFoo { @nullable int f(); }";
- EXPECT_EQ(nullptr, Parse("a/IFoo.aidl", oneway_method, typenames_, Options::Language::CPP));
- typenames_.Reset();
- EXPECT_EQ(nullptr, Parse("a/IFoo.aidl", oneway_method, typenames_, Options::Language::JAVA));
+ EXPECT_EQ(nullptr, Parse("a/IFoo.aidl", oneway_method, &cpp_types_));
+ EXPECT_EQ(nullptr, Parse("a/IFoo.aidl", oneway_method, &java_types_));
}
TEST_F(AidlTest, RejectsDuplicatedArgumentNames) {
string method = "package a; interface IFoo { void f(int a, int a); }";
- EXPECT_EQ(nullptr, Parse("a/IFoo.aidl", method, typenames_, Options::Language::CPP));
- typenames_.Reset();
- EXPECT_EQ(nullptr, Parse("a/IFoo.aidl", method, typenames_, Options::Language::JAVA));
-}
-
-TEST_F(AidlTest, RejectsDuplicatedAnnotationParams) {
- string method = "package a; interface IFoo { @UnsupportedAppUsage(foo=1, foo=2)void f(); }";
- EXPECT_EQ(nullptr, Parse("a/IFoo.aidl", method, typenames_, Options::Language::CPP));
- typenames_.Reset();
- EXPECT_EQ(nullptr, Parse("a/IFoo.aidl", method, typenames_, Options::Language::JAVA));
+ EXPECT_EQ(nullptr, Parse("a/IFoo.aidl", method, &cpp_types_));
+ EXPECT_EQ(nullptr, Parse("a/IFoo.aidl", method, &java_types_));
}
TEST_F(AidlTest, ParsesNullableAnnotation) {
for (auto is_nullable: {true, false}) {
- auto parse_result = Parse("a/IFoo.aidl",
- StringPrintf("package a; interface IFoo {%s String f(); }",
- (is_nullable) ? "@nullable" : ""),
- typenames_, Options::Language::CPP);
+ auto parse_result = Parse(
+ "a/IFoo.aidl",
+ StringPrintf( "package a; interface IFoo {%s String f(); }",
+ (is_nullable) ? "@nullable" : ""),
+ &cpp_types_);
ASSERT_NE(nullptr, parse_result);
const AidlInterface* interface = parse_result->AsInterface();
ASSERT_NE(nullptr, interface);
ASSERT_FALSE(interface->GetMethods().empty());
EXPECT_EQ(interface->GetMethods()[0]->GetType().IsNullable(), is_nullable);
- typenames_.Reset();
+ cpp_types_.typenames_.Reset();
}
}
@@ -312,121 +250,44 @@
for (auto is_utf8: {true, false}) {
auto parse_result = Parse(
"a/IFoo.aidl",
- StringPrintf("package a; interface IFoo {%s String f(); }", (is_utf8) ? "@utf8InCpp" : ""),
- typenames_, Options::Language::CPP);
+ StringPrintf( "package a; interface IFoo {%s String f(); }",
+ (is_utf8) ? "@utf8InCpp" : ""),
+ &cpp_types_);
ASSERT_NE(nullptr, parse_result);
const AidlInterface* interface = parse_result->AsInterface();
ASSERT_NE(nullptr, interface);
ASSERT_FALSE(interface->GetMethods().empty());
EXPECT_EQ(interface->GetMethods()[0]->GetType().IsUtf8InCpp(), is_utf8);
- typenames_.Reset();
+ cpp_types_.typenames_.Reset();
}
}
-TEST_F(AidlTest, VintfRequiresStructuredAndStability) {
- AidlError error;
- auto parse_result = Parse("IFoo.aidl", "@VintfStability interface IFoo {}", typenames_,
- Options::Language::CPP, &error);
- ASSERT_EQ(AidlError::NOT_STRUCTURED, error);
- ASSERT_EQ(nullptr, parse_result);
-}
-
-TEST_F(AidlTest, VintfRequiresStructured) {
- AidlError error;
- auto parse_result = Parse("IFoo.aidl", "@VintfStability interface IFoo {}", typenames_,
- Options::Language::CPP, &error, {"--stability", "vintf"});
- ASSERT_EQ(AidlError::NOT_STRUCTURED, error);
- ASSERT_EQ(nullptr, parse_result);
-}
-
-TEST_F(AidlTest, VintfRequiresSpecifiedStability) {
- AidlError error;
- auto parse_result = Parse("IFoo.aidl", "@VintfStability interface IFoo {}", typenames_,
- Options::Language::CPP, &error, {"--structured"});
- ASSERT_EQ(AidlError::NOT_STRUCTURED, error);
- ASSERT_EQ(nullptr, parse_result);
-}
-
-TEST_F(AidlTest, ParsesStabilityAnnotations) {
- AidlError error;
- auto parse_result =
- Parse("IFoo.aidl", "@VintfStability interface IFoo {}", typenames_, Options::Language::CPP,
- &error, {"--structured", "--stability", "vintf"});
- ASSERT_EQ(AidlError::OK, error);
- ASSERT_NE(nullptr, parse_result);
- const AidlInterface* interface = parse_result->AsInterface();
- ASSERT_NE(nullptr, interface);
- ASSERT_TRUE(interface->IsVintfStability());
- typenames_.Reset();
-}
-
-TEST_F(AidlTest, ParsesJavaOnlyStableParcelable) {
- Options java_options = Options::From("aidl -o out --structured a/Foo.aidl");
- Options cpp_options =
- Options::From("aidl --lang=cpp --structured -o out -h out/include a/Foo.aidl");
- io_delegate_.SetFileContents(
- "a/Foo.aidl", StringPrintf("package a; @JavaOnlyStableParcelable parcelable Foo;"));
-
- EXPECT_EQ(0, ::android::aidl::compile_aidl(java_options, io_delegate_));
- AddExpectedStderr(
- "ERROR: a/Foo.aidl:1.48-52: @JavaOnlyStableParcelable supports only Java target.\n");
- EXPECT_NE(0, ::android::aidl::compile_aidl(cpp_options, io_delegate_));
-}
-
TEST_F(AidlTest, AcceptsOneway) {
string oneway_method = "package a; interface IFoo { oneway void f(int a); }";
string oneway_interface =
"package a; oneway interface IBar { void f(int a); }";
- EXPECT_NE(nullptr, Parse("a/IFoo.aidl", oneway_method, typenames_, Options::Language::CPP));
- typenames_.Reset();
- EXPECT_NE(nullptr, Parse("a/IFoo.aidl", oneway_method, typenames_, Options::Language::JAVA));
- typenames_.Reset();
- EXPECT_NE(nullptr, Parse("a/IBar.aidl", oneway_interface, typenames_, Options::Language::CPP));
- typenames_.Reset();
- EXPECT_NE(nullptr, Parse("a/IBar.aidl", oneway_interface, typenames_, Options::Language::JAVA));
-}
-
-TEST_F(AidlTest, AcceptsAnnotatedOnewayMethod) {
- string oneway_method = "package a; interface IFoo { @UnsupportedAppUsage oneway void f(int a); }";
- EXPECT_NE(nullptr, Parse("a/IFoo.aidl", oneway_method, typenames_, Options::Language::CPP));
- typenames_.Reset();
- EXPECT_NE(nullptr, Parse("a/IFoo.aidl", oneway_method, typenames_, Options::Language::JAVA));
-}
-
-TEST_F(AidlTest, WritesComments) {
- string foo_interface =
- "package a; /* foo */ interface IFoo {"
- " /* i */ int i();"
- " /* j */ @nullable String j();"
- " /* k */ @UnsupportedAppUsage oneway void k(int a); }";
-
- auto parse_result = Parse("a/IFoo.aidl", foo_interface, typenames_, Options::Language::JAVA);
- EXPECT_NE(nullptr, parse_result);
- EXPECT_EQ("/* foo */", parse_result->GetComments());
-
- const AidlInterface* interface = parse_result->AsInterface();
- EXPECT_EQ("/* i */", interface->GetMethods()[0]->GetComments());
- EXPECT_EQ("/* j */", interface->GetMethods()[1]->GetComments());
- EXPECT_EQ("/* k */", interface->GetMethods()[2]->GetComments());
+ EXPECT_NE(nullptr, Parse("a/IFoo.aidl", oneway_method, &cpp_types_));
+ EXPECT_NE(nullptr, Parse("a/IFoo.aidl", oneway_method, &java_types_));
+ EXPECT_NE(nullptr, Parse("a/IBar.aidl", oneway_interface, &cpp_types_));
+ EXPECT_NE(nullptr, Parse("a/IBar.aidl", oneway_interface, &java_types_));
}
TEST_F(AidlTest, ParsesPreprocessedFile) {
string simple_content = "parcelable a.Foo;\ninterface b.IBar;";
io_delegate_.SetFileContents("path", simple_content);
- EXPECT_FALSE(typenames_.ResolveTypename("a.Foo").second);
- EXPECT_TRUE(parse_preprocessed_file(io_delegate_, "path", &typenames_));
- EXPECT_TRUE(typenames_.ResolveTypename("a.Foo").second);
- EXPECT_TRUE(typenames_.ResolveTypename("b.IBar").second);
+ EXPECT_FALSE(java_types_.HasTypeByCanonicalName("a.Foo"));
+ EXPECT_TRUE(parse_preprocessed_file(io_delegate_, "path", &java_types_, java_types_.typenames_));
+ EXPECT_TRUE(java_types_.HasTypeByCanonicalName("a.Foo"));
+ EXPECT_TRUE(java_types_.HasTypeByCanonicalName("b.IBar"));
}
TEST_F(AidlTest, ParsesPreprocessedFileWithWhitespace) {
string simple_content = "parcelable a.Foo;\n interface b.IBar ;\t";
io_delegate_.SetFileContents("path", simple_content);
-
- EXPECT_FALSE(typenames_.ResolveTypename("a.Foo").second);
- EXPECT_TRUE(parse_preprocessed_file(io_delegate_, "path", &typenames_));
- EXPECT_TRUE(typenames_.ResolveTypename("a.Foo").second);
- EXPECT_TRUE(typenames_.ResolveTypename("b.IBar").second);
+ EXPECT_FALSE(java_types_.HasTypeByCanonicalName("a.Foo"));
+ EXPECT_TRUE(parse_preprocessed_file(io_delegate_, "path", &java_types_, java_types_.typenames_));
+ EXPECT_TRUE(java_types_.HasTypeByCanonicalName("a.Foo"));
+ EXPECT_TRUE(java_types_.HasTypeByCanonicalName("b.IBar"));
}
TEST_F(AidlTest, PreferImportToPreprocessed) {
@@ -435,17 +296,18 @@
"interface IBar {}");
preprocessed_files_.push_back("preprocessed");
import_paths_.emplace("");
- auto parse_result = Parse("p/IFoo.aidl", "package p; import one.IBar; interface IFoo {}",
- typenames_, Options::Language::JAVA);
+ auto parse_result = Parse(
+ "p/IFoo.aidl", "package p; import one.IBar; interface IFoo {}",
+ &java_types_);
EXPECT_NE(nullptr, parse_result);
-
// We expect to know about both kinds of IBar
- EXPECT_TRUE(typenames_.ResolveTypename("one.IBar").second);
- EXPECT_TRUE(typenames_.ResolveTypename("another.IBar").second);
+ EXPECT_TRUE(java_types_.HasTypeByCanonicalName("one.IBar"));
+ EXPECT_TRUE(java_types_.HasTypeByCanonicalName("another.IBar"));
// But if we request just "IBar" we should get our imported one.
AidlTypeSpecifier ambiguous_type(AIDL_LOCATION_HERE, "IBar", false, nullptr, "");
- ambiguous_type.Resolve(typenames_);
- EXPECT_EQ("one.IBar", ambiguous_type.GetName());
+ const java::Type* type = java_types_.Find(ambiguous_type);
+ ASSERT_TRUE(type);
+ EXPECT_EQ("one.IBar", type->CanonicalName());
}
TEST_F(AidlTest, WritePreprocessedFile) {
@@ -469,20 +331,16 @@
}
TEST_F(AidlTest, JavaParcelableOutput) {
- io_delegate_.SetFileContents(
- "Rect.aidl",
- "@SystemApi\n"
- "parcelable Rect {\n"
- " // Comment\n"
- " @SystemApi\n"
- " int x=5;\n"
- " @SystemApi\n"
- " @UnsupportedAppUsage(maxTargetSdk = 28, trackingBug = 42, implicitMember = \"dummy\", "
- "expectedSignature = \"dummy\", publicAlternatives = \"d\" \n + \"u\" + \n \"m\" \n + \"m\" "
- "+ \"y\")\n"
- " int y;\n"
- " ParcelFileDescriptor fd;\n"
- "}");
+ io_delegate_.SetFileContents("Rect.aidl",
+ "@SystemApi\n"
+ "parcelable Rect {\n"
+ " // Comment\n"
+ " @SystemApi\n"
+ " int x=5;\n"
+ " @SystemApi\n"
+ " @UnsupportedAppUsage\n"
+ " int y;\n"
+ "}");
vector<string> args{"aidl", "Rect.aidl"};
Options options = Options::From(args);
@@ -490,16 +348,17 @@
string output;
EXPECT_TRUE(io_delegate_.GetWrittenContents("Rect.java", &output));
- EXPECT_EQ(kExpectedJavaParcelableOutputContests, output);
+ EXPECT_EQ(kExepectedJavaParcelableOutputContests, output);
}
TEST_F(AidlTest, RequireOuterClass) {
io_delegate_.SetFileContents("p/Outer.aidl",
"package p; parcelable Outer.Inner;");
import_paths_.emplace("");
- auto parse_result =
- Parse("p/IFoo.aidl", "package p; import p.Outer; interface IFoo { void f(in Inner c); }",
- typenames_, Options::Language::JAVA);
+ auto parse_result = Parse(
+ "p/IFoo.aidl",
+ "package p; import p.Outer; interface IFoo { void f(in Inner c); }",
+ &java_types_);
EXPECT_EQ(nullptr, parse_result);
}
@@ -507,8 +366,10 @@
io_delegate_.SetFileContents("preprocessed",
"parcelable p.Outer.Inner;");
preprocessed_files_.push_back("preprocessed");
- auto parse_result = Parse("p/IFoo.aidl", "package p; interface IFoo { void f(in Inner c); }",
- typenames_, Options::Language::JAVA);
+ auto parse_result = Parse(
+ "p/IFoo.aidl",
+ "package p; interface IFoo { void f(in Inner c); }",
+ &java_types_);
// TODO(wiley): This should actually return nullptr because we require
// the outer class name. However, for legacy reasons,
// this behavior must be maintained. b/17415692
@@ -528,7 +389,7 @@
io_delegate_.SetFileContents("p/IBar.aidl", "package p; parcelable Foo; interface IBar{}");
- // With '-b' option, a parcelable and an interface should fail.
+ // Regardless of '-b', a parcelable and an interface should fail.
Options options3 = Options::From("aidl p/IBar.aidl");
EXPECT_EQ(0, ::android::aidl::compile_aidl(options3, io_delegate_));
Options options4 = Options::From("aidl -b p/IBar.aidl");
@@ -542,35 +403,37 @@
auto parse_result =
Parse("p/IFoo.aidl",
"package p; import o.WhoKnowsWhat; interface IFoo { void f(in WhoKnowsWhat thisIs); }",
- typenames_, Options::Language::JAVA, &reported_error, {"--structured"});
+ &java_types_, &reported_error, {"--structured"});
EXPECT_EQ(nullptr, parse_result);
EXPECT_EQ(AidlError::NOT_STRUCTURED, reported_error);
}
TEST_F(AidlTest, FailOnDuplicateConstantNames) {
AidlError reported_error;
- EXPECT_EQ(nullptr, Parse("p/IFoo.aidl",
- R"(package p;
+ EXPECT_EQ(nullptr,
+ Parse("p/IFoo.aidl",
+ R"(package p;
interface IFoo {
const String DUPLICATED = "d";
const int DUPLICATED = 1;
}
)",
- typenames_, Options::Language::CPP, &reported_error));
+ &cpp_types_,
+ &reported_error));
EXPECT_EQ(AidlError::BAD_TYPE, reported_error);
}
TEST_F(AidlTest, FailOnManyDefinedTypes) {
AidlError reported_error;
- AddExpectedStderr("ERROR: p/IFoo.aidl: You must declare only one type per a file.\n");
EXPECT_EQ(nullptr, Parse("p/IFoo.aidl",
R"(package p;
interface IFoo {}
+ parcelable Bar;
parcelable IBar {}
parcelable StructuredParcelable {}
interface IBaz {}
- )",
- typenames_, Options::Language::CPP, &reported_error));
+ )",
+ &cpp_types_, &reported_error));
// Parse success is important for clear error handling even if the cases aren't
// actually supported in code generation.
EXPECT_EQ(AidlError::BAD_TYPE, reported_error);
@@ -578,58 +441,61 @@
TEST_F(AidlTest, FailOnNoDefinedTypes) {
AidlError reported_error;
- EXPECT_EQ(nullptr, Parse("p/IFoo.aidl", R"(package p;)", typenames_, Options::Language::CPP,
- &reported_error));
+ EXPECT_EQ(nullptr, Parse("p/IFoo.aidl", R"(package p;)", &cpp_types_, &reported_error));
EXPECT_EQ(AidlError::PARSE_ERROR, reported_error);
}
TEST_F(AidlTest, FailOnMalformedConstHexValue) {
AidlError reported_error;
- EXPECT_EQ(nullptr, Parse("p/IFoo.aidl",
- R"(package p;
+ EXPECT_EQ(nullptr,
+ Parse("p/IFoo.aidl",
+ R"(package p;
interface IFoo {
const int BAD_HEX_VALUE = 0xffffffffffffffffff;
}
)",
- typenames_, Options::Language::CPP, &reported_error));
- EXPECT_EQ(AidlError::PARSE_ERROR, reported_error);
+ &cpp_types_,
+ &reported_error));
+ EXPECT_EQ(AidlError::BAD_TYPE, reported_error);
}
TEST_F(AidlTest, ParsePositiveConstHexValue) {
AidlError reported_error;
- auto cpp_parse_result = Parse("p/IFoo.aidl",
- R"(package p;
+ auto cpp_parse_result =
+ Parse("p/IFoo.aidl",
+ R"(package p;
interface IFoo {
const int POSITIVE_HEX_VALUE = 0xf5;
}
)",
- typenames_, Options::Language::CPP, &reported_error);
+ &cpp_types_,
+ &reported_error);
EXPECT_NE(nullptr, cpp_parse_result);
const AidlInterface* interface = cpp_parse_result->AsInterface();
ASSERT_NE(nullptr, interface);
const auto& cpp_constants = interface->GetConstantDeclarations();
EXPECT_EQ((size_t)1, cpp_constants.size());
EXPECT_EQ("POSITIVE_HEX_VALUE", cpp_constants[0]->GetName());
- EXPECT_TRUE(cpp_constants[0]->CheckValid(typenames_));
EXPECT_EQ("245", cpp_constants[0]->ValueString(cpp::ConstantValueDecorator));
}
TEST_F(AidlTest, ParseNegativeConstHexValue) {
AidlError reported_error;
- auto cpp_parse_result = Parse("p/IFoo.aidl",
- R"(package p;
+ auto cpp_parse_result =
+ Parse("p/IFoo.aidl",
+ R"(package p;
interface IFoo {
const int NEGATIVE_HEX_VALUE = 0xffffffff;
}
)",
- typenames_, Options::Language::CPP, &reported_error);
- ASSERT_NE(nullptr, cpp_parse_result);
+ &cpp_types_,
+ &reported_error);
+ EXPECT_NE(nullptr, cpp_parse_result);
const AidlInterface* interface = cpp_parse_result->AsInterface();
ASSERT_NE(nullptr, interface);
const auto& cpp_constants = interface->GetConstantDeclarations();
EXPECT_EQ((size_t)1, cpp_constants.size());
EXPECT_EQ("NEGATIVE_HEX_VALUE", cpp_constants[0]->GetName());
- EXPECT_EQ(true, cpp_constants[0]->CheckValid(typenames_));
EXPECT_EQ("-1", cpp_constants[0]->ValueString(cpp::ConstantValueDecorator));
}
@@ -642,14 +508,12 @@
const string input = "package p; import p.Outer; interface IFoo"
" { Outer.Inner get(); }";
- auto cpp_parse_result = Parse(input_path, input, typenames_, Options::Language::CPP);
+ auto cpp_parse_result = Parse(input_path, input, &cpp_types_);
EXPECT_NE(nullptr, cpp_parse_result);
-
- auto pair = typenames_.ResolveTypename("p.Outer.Inner");
- EXPECT_TRUE(pair.second);
+ auto cpp_type = cpp_types_.FindTypeByCanonicalName("p.Outer.Inner");
+ ASSERT_NE(nullptr, cpp_type);
// C++ uses "::" instead of "." to refer to a inner class.
- AidlTypeSpecifier nested_type(AIDL_LOCATION_HERE, "p.Outer.Inner", false, nullptr, "");
- EXPECT_EQ("::p::Outer::Inner", cpp::CppNameOf(nested_type, typenames_));
+ EXPECT_EQ("::p::Outer::Inner", cpp_type->CppType());
}
TEST_F(AidlTest, UnderstandsNativeParcelables) {
@@ -659,31 +523,24 @@
import_paths_.emplace("");
const string input_path = "p/IFoo.aidl";
const string input = "package p; import p.Bar; interface IFoo { }";
- {
- // C++ understands C++ specific stuff
- auto cpp_parse_result = Parse(input_path, input, typenames_, Options::Language::CPP);
- EXPECT_NE(nullptr, cpp_parse_result);
- auto pair = typenames_.ResolveTypename("p.Bar");
- EXPECT_TRUE(pair.second);
- AidlTypeSpecifier native_type(AIDL_LOCATION_HERE, "p.Bar", false, nullptr, "");
- native_type.Resolve(typenames_);
- EXPECT_EQ("::p::Bar", cpp::CppNameOf(native_type, typenames_));
- set<string> headers;
- cpp::AddHeaders(native_type, typenames_, headers);
- EXPECT_EQ(1u, headers.size());
- EXPECT_EQ(1u, headers.count("baz/header"));
- }
- typenames_.Reset();
- {
- // Java ignores C++ specific stuff
- auto java_parse_result = Parse(input_path, input, typenames_, Options::Language::JAVA);
- EXPECT_NE(nullptr, java_parse_result);
- auto pair = typenames_.ResolveTypename("p.Bar");
- EXPECT_TRUE(pair.second);
- AidlTypeSpecifier native_type(AIDL_LOCATION_HERE, "p.Bar", false, nullptr, "");
- native_type.Resolve(typenames_);
- EXPECT_EQ("p.Bar", java::InstantiableJavaSignatureOf(native_type, typenames_));
- }
+
+ // C++ understands C++ specific stuff
+ auto cpp_parse_result = Parse(input_path, input, &cpp_types_);
+ EXPECT_NE(nullptr, cpp_parse_result);
+ auto cpp_type = cpp_types_.FindTypeByCanonicalName("p.Bar");
+ ASSERT_NE(nullptr, cpp_type);
+ EXPECT_EQ("::p::Bar", cpp_type->CppType());
+ set<string> headers;
+ cpp_type->GetHeaders(&headers);
+ EXPECT_EQ(1u, headers.size());
+ EXPECT_EQ(1u, headers.count("baz/header"));
+
+ // Java ignores C++ specific stuff
+ auto java_parse_result = Parse(input_path, input, &java_types_);
+ EXPECT_NE(nullptr, java_parse_result);
+ auto java_type = java_types_.FindTypeByCanonicalName("p.Bar");
+ ASSERT_NE(nullptr, java_type);
+ EXPECT_EQ("p.Bar", java_type->InstantiableName());
}
TEST_F(AidlTest, WritesCorrectDependencyFile) {
@@ -774,11 +631,10 @@
" List<int, List<String, bool>> foo(); }";
string nested_in_parcelable = "package a; parcelable IData {\n"
" List<int, List<String, bool>> foo;}";
- EXPECT_NE(nullptr, Parse("a/IFoo.aidl", nested_in_iface, typenames_, Options::Language::JAVA));
- EXPECT_NE(nullptr, Parse("a/IFoo.aidl", nested_in_iface, typenames_, Options::Language::CPP));
- EXPECT_NE(nullptr, Parse("a/IFoo.aidl", nested_in_parcelable, typenames_,
-Options::Language::JAVA)); EXPECT_NE(nullptr, Parse("a/IFoo.aidl", nested_in_parcelable, typenames_,
-Options::Language::CPP));
+ EXPECT_NE(nullptr, Parse("a/IFoo.aidl", nested_in_iface, &java_types_));
+ EXPECT_NE(nullptr, Parse("a/IFoo.aidl", nested_in_iface, &cpp_types_));
+ EXPECT_NE(nullptr, Parse("a/IFoo.aidl", nested_in_parcelable, &java_types_));
+ EXPECT_NE(nullptr, Parse("a/IFoo.aidl", nested_in_parcelable, &cpp_types_));
}
*/
@@ -903,33 +759,44 @@
EXPECT_NE(0, ::android::aidl::compile_aidl(options2, io_delegate_));
}
-TEST_F(AidlTest, FailOnMultipleTypesInSingleFile) {
- std::vector<std::string> rawOptions{"aidl --lang=java -o out foo/bar/Foo.aidl",
- "aidl --lang=cpp -o out -h out/include foo/bar/Foo.aidl"};
- for (auto& rawOption : rawOptions) {
- Options options = Options::From(rawOption);
- io_delegate_.SetFileContents(options.InputFiles().front(),
- "package foo.bar;\n"
- "interface IFoo1 { int foo(); }\n"
- "interface IFoo2 { int foo(); }\n"
- "parcelable Data1 { int a; int b;}\n"
- "parcelable Data2 { int a; int b;}\n");
+TEST_F(AidlTest, MultipleTypesInSingleFile) {
+ Options options = Options::From("aidl --lang=java -o out foo/bar/Foo.aidl");
+ io_delegate_.SetFileContents(options.InputFiles().front(),
+ "package foo.bar;\n"
+ "interface IFoo1 { int foo(); }\n"
+ "interface IFoo2 { int foo(); }\n"
+ "parcelable Data { int a; int b;}\n");
- EXPECT_NE(0, ::android::aidl::compile_aidl(options, io_delegate_));
+ EXPECT_EQ(0, ::android::aidl::compile_aidl(options, io_delegate_));
- io_delegate_.SetFileContents(options.InputFiles().front(),
- "package foo.bar;\n"
- "interface IFoo1 { int foo(); }\n"
- "interface IFoo2 { int foo(); }\n");
+ string content;
+ for (const auto file :
+ {"out/foo/bar/IFoo1.java", "out/foo/bar/IFoo2.java", "out/foo/bar/Data.java"}) {
+ content.clear();
+ EXPECT_TRUE(io_delegate_.GetWrittenContents(file, &content));
+ EXPECT_FALSE(content.empty());
+ }
+}
- EXPECT_NE(0, ::android::aidl::compile_aidl(options, io_delegate_));
+TEST_F(AidlTest, MultipleTypesInSingleFileCpp) {
+ Options options = Options::From("aidl --lang=cpp -o out -h out/include foo/bar/Foo.aidl");
+ io_delegate_.SetFileContents(options.InputFiles().front(),
+ "package foo.bar;\n"
+ "interface IFoo1 { int foo(); }\n"
+ "interface IFoo2 { int foo(); }\n"
+ "parcelable Data { int a; int b;}\n");
- io_delegate_.SetFileContents(options.InputFiles().front(),
- "package foo.bar;\n"
- "parcelable Data1 { int a; int b;}\n"
- "parcelable Data2 { int a; int b;}\n");
+ EXPECT_EQ(0, ::android::aidl::compile_aidl(options, io_delegate_));
- EXPECT_NE(0, ::android::aidl::compile_aidl(options, io_delegate_));
+ string content;
+ for (const auto file : {
+ "out/foo/bar/IFoo1.cpp", "out/foo/bar/IFoo2.cpp", "out/foo/bar/Data.cpp",
+ "out/include/foo/bar/IFoo1.h", "out/include/foo/bar/IFoo2.h", "out/include/foo/bar/Data.h",
+ "out/include/foo/bar/BpFoo1.h", "out/include/foo/bar/BpFoo2.h", "out/include/foo/bar/BpData.h",
+ "out/include/foo/bar/BnFoo1.h", "out/include/foo/bar/BnFoo2.h", "out/include/foo/bar/BnData.h"}) {
+ content.clear();
+ EXPECT_TRUE(io_delegate_.GetWrittenContents(file, &content));
+ EXPECT_FALSE(content.empty());
}
}
@@ -1014,7 +881,7 @@
EXPECT_EQ(0, ::android::aidl::compile_aidl(options, io_delegate_));
}
-TEST_F(AidlTest, DifferentOrderAnnotationsInCheckAPI) {
+TEST_F(AidlTest, DiffrentOrderAnnotationsInCheckAPI) {
Options options = Options::From("aidl --checkapi old new");
io_delegate_.SetFileContents("old/p/IFoo.aidl",
"package p; interface IFoo{ @utf8InCpp @nullable String foo();}");
@@ -1032,102 +899,73 @@
EXPECT_TRUE(::android::aidl::check_api(options, io_delegate_));
}
-class AidlTestCompatibleChanges : public AidlTest {
- protected:
- Options options_ = Options::From("aidl --checkapi old new");
-};
-
-TEST_F(AidlTestCompatibleChanges, NewType) {
+TEST_F(AidlTest, SuccessOnCompatibleChanges) {
+ Options options = Options::From("aidl --checkapi old new");
io_delegate_.SetFileContents("old/p/IFoo.aidl",
"package p;"
"interface IFoo {"
" void foo(int a);"
"}");
+ io_delegate_.SetFileContents("old/p/Data.aidl",
+ "package p;"
+ "parcelable Data {"
+ " int foo;"
+ "}");
+
+ // new type
io_delegate_.SetFileContents("new/p/IFoo.aidl",
"package p;"
"interface IFoo {"
" void foo(int a);"
"}");
+ io_delegate_.SetFileContents("new/p/Data.aidl",
+ "package p;"
+ "parcelable Data {"
+ " int foo;"
+ "}");
io_delegate_.SetFileContents("new/p/IBar.aidl",
"package p;"
"interface IBar {"
" void bar();"
"}");
- EXPECT_TRUE(::android::aidl::check_api(options_, io_delegate_));
-}
+ EXPECT_TRUE(::android::aidl::check_api(options, io_delegate_));
+ io_delegate_.SetFileContents("new/p/IFoo.aidl", "");
+ io_delegate_.SetFileContents("new/p/Data.aidl", "");
+ io_delegate_.SetFileContents("new/p/IBar.aidl", "");
-TEST_F(AidlTestCompatibleChanges, NewMethod) {
- io_delegate_.SetFileContents("old/p/IFoo.aidl",
- "package p;"
- "interface IFoo {"
- " void foo(int a);"
- "}");
+ // new method
io_delegate_.SetFileContents("new/p/IFoo.aidl",
"package p;"
"interface IFoo {"
" void foo(int a);"
" void bar();"
"}");
- EXPECT_TRUE(::android::aidl::check_api(options_, io_delegate_));
-}
-
-TEST_F(AidlTestCompatibleChanges, NewField) {
- io_delegate_.SetFileContents("old/p/Data.aidl",
+ io_delegate_.SetFileContents("new/p/Data.aidl",
"package p;"
"parcelable Data {"
" int foo;"
"}");
+ EXPECT_TRUE(::android::aidl::check_api(options, io_delegate_));
+ io_delegate_.SetFileContents("new/p/IFoo.aidl", "");
+ io_delegate_.SetFileContents("new/p/Data.aidl", "");
+
+ // new field
+ io_delegate_.SetFileContents("new/p/IFoo.aidl",
+ "package p;"
+ "interface IFoo {"
+ " void foo(int a);"
+ "}");
io_delegate_.SetFileContents("new/p/Data.aidl",
"package p;"
"parcelable Data {"
" int foo;"
" int bar;"
"}");
- EXPECT_TRUE(::android::aidl::check_api(options_, io_delegate_));
-}
+ EXPECT_TRUE(::android::aidl::check_api(options, io_delegate_));
+ io_delegate_.SetFileContents("new/p/IFoo.aidl", "");
+ io_delegate_.SetFileContents("new/p/Data.aidl", "");
-TEST_F(AidlTestCompatibleChanges, NewEnumerator) {
- io_delegate_.SetFileContents("old/p/Enum.aidl",
- "package p;"
- "enum Enum {"
- " FOO = 1,"
- "}");
- io_delegate_.SetFileContents("new/p/Enum.aidl",
- "package p;"
- "enum Enum {"
- " FOO = 1,"
- " BAR = 2,"
- "}");
- EXPECT_TRUE(::android::aidl::check_api(options_, io_delegate_));
-}
-
-TEST_F(AidlTestCompatibleChanges, ReorderedEnumerator) {
- io_delegate_.SetFileContents("old/p/Enum.aidl",
- "package p;"
- "enum Enum {"
- " FOO = 1,"
- " BAR = 2,"
- "}");
- io_delegate_.SetFileContents("new/p/Enum.aidl",
- "package p;"
- "enum Enum {"
- " BAR = 2,"
- " FOO = 1,"
- "}");
- EXPECT_TRUE(::android::aidl::check_api(options_, io_delegate_));
-}
-
-TEST_F(AidlTestCompatibleChanges, NewPackage) {
- io_delegate_.SetFileContents("old/p/IFoo.aidl",
- "package p;"
- "interface IFoo {"
- " void foo(int a);"
- "}");
- io_delegate_.SetFileContents("old/p/Data.aidl",
- "package p;"
- "parcelable Data {"
- " int foo;"
- "}");
+ // new package
io_delegate_.SetFileContents("new/p/IFoo.aidl",
"package p;"
"interface IFoo {"
@@ -1148,273 +986,277 @@
"parcelable Data {"
" int foo;"
"}");
- EXPECT_TRUE(::android::aidl::check_api(options_, io_delegate_));
-}
+ EXPECT_TRUE(::android::aidl::check_api(options, io_delegate_));
+ io_delegate_.SetFileContents("new/p/IFoo.aidl", "");
+ io_delegate_.SetFileContents("new/p/Data.aidl", "");
+ io_delegate_.SetFileContents("new/q/IFoo.aidl", "");
+ io_delegate_.SetFileContents("new/q/Data.aidl", "");
-TEST_F(AidlTestCompatibleChanges, ArgNameChange) {
- io_delegate_.SetFileContents("old/p/IFoo.aidl",
- "package p;"
- "interface IFoo {"
- " void foo(int a);"
- "}");
+ // arg name change
io_delegate_.SetFileContents("new/p/IFoo.aidl",
"package p;"
"interface IFoo {"
" void foo(int b);"
"}");
- EXPECT_TRUE(::android::aidl::check_api(options_, io_delegate_));
-}
-
-TEST_F(AidlTestCompatibleChanges, AddedConstValue) {
- io_delegate_.SetFileContents("old/p/I.aidl",
- "package p; interface I {"
- "const int A = 1; }");
- io_delegate_.SetFileContents("new/p/I.aidl",
- "package p ; interface I {"
- "const int A = 1; const int B = 2;}");
- EXPECT_TRUE(::android::aidl::check_api(options_, io_delegate_));
-}
-
-TEST_F(AidlTestCompatibleChanges, ChangedConstValueOrder) {
- io_delegate_.SetFileContents("old/p/I.aidl",
- "package p; interface I {"
- "const int A = 1; const int B = 2;}");
- io_delegate_.SetFileContents("new/p/I.aidl",
- "package p ; interface I {"
- "const int B = 2; const int A = 1;}");
- EXPECT_TRUE(::android::aidl::check_api(options_, io_delegate_));
-}
-
-class AidlTestIncompatibleChanges : public AidlTest {
- protected:
- Options options_ = Options::From("aidl --checkapi old new");
-};
-
-TEST_F(AidlTestIncompatibleChanges, RemovedType) {
- io_delegate_.SetFileContents("old/p/IFoo.aidl",
- "package p;"
- "interface IFoo {"
- " void foo(in String[] str);"
- " void bar(@utf8InCpp String str);"
- "}");
- io_delegate_.SetFileContents("new/p/IFoo.aidl", "");
- EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
-}
-
-TEST_F(AidlTestIncompatibleChanges, RemovedMethod) {
- io_delegate_.SetFileContents("old/p/IFoo.aidl",
- "package p;"
- "interface IFoo {"
- " void foo(in String[] str);"
- " void bar(@utf8InCpp String str);"
- "}");
- io_delegate_.SetFileContents("new/p/IFoo.aidl",
- "package p;"
- "interface IFoo {"
- " void foo(in String[] str);"
- "}");
- EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
-}
-
-TEST_F(AidlTestIncompatibleChanges, RemovedField) {
- io_delegate_.SetFileContents("old/p/Data.aidl",
- "package p;"
- "parcelable Data {"
- " int foo;"
- " int bar;"
- "}");
io_delegate_.SetFileContents("new/p/Data.aidl",
"package p;"
"parcelable Data {"
" int foo;"
"}");
- EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
+ EXPECT_TRUE(::android::aidl::check_api(options, io_delegate_));
+ io_delegate_.SetFileContents("new/p/IFoo.aidl", "");
+ io_delegate_.SetFileContents("new/p/Data.aidl", "");
+
+ io_delegate_.SetFileContents("old/p/IFoo.aidl", "");
+ io_delegate_.SetFileContents("old/p/Data.aidl", "");
+
+ // added const value
+ io_delegate_.SetFileContents("old/p/I.aidl",
+ "package p; interface I {"
+ "const int A = 1; }");
+ io_delegate_.SetFileContents("new/p/I.aidl",
+ "package p ; interface I {"
+ "const int A = 1; const int B = 2;}");
+ EXPECT_TRUE(::android::aidl::check_api(options, io_delegate_));
+ io_delegate_.SetFileContents("old/p/I.aidl", "");
+ io_delegate_.SetFileContents("new/p/I.aidl", "");
+
+ // changed const value order
+ io_delegate_.SetFileContents("old/p/I.aidl",
+ "package p; interface I {"
+ "const int A = 1; const int B = 2;}");
+ io_delegate_.SetFileContents("new/p/I.aidl",
+ "package p ; interface I {"
+ "const int B = 2; const int A = 1;}");
+ EXPECT_TRUE(::android::aidl::check_api(options, io_delegate_));
}
-TEST_F(AidlTestIncompatibleChanges, RemovedEnumerator) {
- io_delegate_.SetFileContents("old/p/Enum.aidl",
- "package p;"
- "enum Enum {"
- " FOO = 1,"
- " BAR = 2,"
- "}");
- io_delegate_.SetFileContents("new/p/Enum.aidl",
- "package p;"
- "enum Enum {"
- " BAR = 2,"
- "}");
- EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
-}
-
-TEST_F(AidlTestIncompatibleChanges, RenamedMethod) {
+TEST_F(AidlTest, FailOnIncompatibleChanges) {
+ Options options = Options::From("aidl --checkapi old new");
io_delegate_.SetFileContents("old/p/IFoo.aidl",
"package p;"
"interface IFoo {"
" void foo(in String[] str);"
" void bar(@utf8InCpp String str);"
"}");
+ io_delegate_.SetFileContents("old/p/Data.aidl",
+ "package p;"
+ "parcelable Data {"
+ " int foo;"
+ " int bar;"
+ "}");
+
+ // removed type
+ io_delegate_.SetFileContents("new/p/IFoo.aidl",
+ "package p;"
+ "interface IFoo {"
+ " void foo(in String[] str);"
+ " void bar(@utf8InCpp String str);"
+ "}");
+ EXPECT_FALSE(::android::aidl::check_api(options, io_delegate_));
+ io_delegate_.SetFileContents("new/p/IFoo.aidl", "");
+
+ // removed method
+ io_delegate_.SetFileContents("new/p/IFoo.aidl",
+ "package p;"
+ "interface IFoo {"
+ " void foo(in String[] str);"
+ "}");
+ io_delegate_.SetFileContents("new/p/Data.aidl",
+ "package p;"
+ "parcelable Data {"
+ " int foo;"
+ " int bar;"
+ "}");
+ EXPECT_FALSE(::android::aidl::check_api(options, io_delegate_));
+ io_delegate_.SetFileContents("new/p/IFoo.aidl", "");
+ io_delegate_.SetFileContents("new/p/Data.aidl", "");
+
+ // removed field
+ io_delegate_.SetFileContents("new/p/IFoo.aidl",
+ "package p;"
+ "interface IFoo {"
+ " void foo(in String[] str);"
+ " void bar(@utf8InCpp String str);"
+ "}");
+ io_delegate_.SetFileContents("new/p/Data.aidl",
+ "package p;"
+ "parcelable Data {"
+ " int foo;"
+ "}");
+ EXPECT_FALSE(::android::aidl::check_api(options, io_delegate_));
+ io_delegate_.SetFileContents("new/p/IFoo.aidl", "");
+ io_delegate_.SetFileContents("new/p/Data.aidl", "");
+
+ // renamed method
io_delegate_.SetFileContents("new/p/IFoo.aidl",
"package p;"
"interface IFoo {"
" void foo(in String[] str);"
" void bar2(@utf8InCpp String str);"
"}");
- EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
-}
-
-TEST_F(AidlTestIncompatibleChanges, RenamedField) {
- io_delegate_.SetFileContents("old/p/Data.aidl",
+ io_delegate_.SetFileContents("new/p/Data.aidl",
"package p;"
"parcelable Data {"
" int foo;"
" int bar;"
"}");
+ EXPECT_FALSE(::android::aidl::check_api(options, io_delegate_));
+ io_delegate_.SetFileContents("new/p/IFoo.aidl", "");
+ io_delegate_.SetFileContents("new/p/Data.aidl", "");
+
+ // renamed field
+ io_delegate_.SetFileContents("new/p/IFoo.aidl",
+ "package p;"
+ "interface IFoo {"
+ " void foo(in String[] str);"
+ " void bar(@utf8InCpp String str);"
+ "}");
io_delegate_.SetFileContents("new/p/Data.aidl",
"package p;"
"parcelable Data {"
" int foo;"
" int bar2;"
"}");
- EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
-}
+ EXPECT_FALSE(::android::aidl::check_api(options, io_delegate_));
+ io_delegate_.SetFileContents("new/p/IFoo.aidl", "");
+ io_delegate_.SetFileContents("new/p/Data.aidl", "");
-TEST_F(AidlTestIncompatibleChanges, RenamedType) {
- io_delegate_.SetFileContents("old/p/IFoo.aidl",
- "package p;"
- "interface IFoo {"
- " void foo(in String[] str);"
- " void bar(@utf8InCpp String str);"
- "}");
+ // renamed type
io_delegate_.SetFileContents("new/p/IFoo2.aidl",
"package p;"
"interface IFoo2 {"
" void foo(in String[] str);"
" void bar(@utf8InCpp String str);"
"}");
- EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
-}
+ io_delegate_.SetFileContents("new/p/Data.aidl",
+ "package p;"
+ "parcelable Data {"
+ " int foo;"
+ " int bar;"
+ "}");
+ EXPECT_FALSE(::android::aidl::check_api(options, io_delegate_));
+ io_delegate_.SetFileContents("new/p/IFoo2.aidl", "");
+ io_delegate_.SetFileContents("new/p/Data.aidl", "");
-TEST_F(AidlTestIncompatibleChanges, ChangedEnumerator) {
- io_delegate_.SetFileContents("old/p/Enum.aidl",
- "package p;"
- "enum Enum {"
- " FOO = 1,"
- " BAR = 2,"
- "}");
- io_delegate_.SetFileContents("new/p/Enum.aidl",
- "package p;"
- "enum Enum {"
- " FOO = 3,"
- " BAR = 2,"
- "}");
- EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
-}
-
-TEST_F(AidlTestIncompatibleChanges, ReorderedMethod) {
- io_delegate_.SetFileContents("old/p/IFoo.aidl",
- "package p;"
- "interface IFoo {"
- " void foo(in String[] str);"
- " void bar(@utf8InCpp String str);"
- "}");
+ // reorderd method
io_delegate_.SetFileContents("new/p/IFoo.aidl",
"package p;"
"interface IFoo {"
" void bar(@utf8InCpp String str);"
" void foo(in String[] str);"
"}");
- EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
-}
-
-TEST_F(AidlTestIncompatibleChanges, ReorderedField) {
- io_delegate_.SetFileContents("old/p/Data.aidl",
+ io_delegate_.SetFileContents("new/p/Data.aidl",
"package p;"
"parcelable Data {"
" int foo;"
" int bar;"
"}");
+ EXPECT_FALSE(::android::aidl::check_api(options, io_delegate_));
+ io_delegate_.SetFileContents("new/p/IFoo.aidl", "");
+ io_delegate_.SetFileContents("new/p/Data.aidl", "");
+
+ // reorderd field
+ io_delegate_.SetFileContents("new/p/IFoo.aidl",
+ "package p;"
+ "interface IFoo {"
+ " void foo(in String[] str);"
+ " void bar(@utf8InCpp String str);"
+ "}");
io_delegate_.SetFileContents("new/p/Data.aidl",
"package p;"
"parcelable Data {"
" int bar;"
" int foo;"
"}");
- EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
-}
+ EXPECT_FALSE(::android::aidl::check_api(options, io_delegate_));
+ io_delegate_.SetFileContents("new/p/IFoo.aidl", "");
+ io_delegate_.SetFileContents("new/p/Data.aidl", "");
-TEST_F(AidlTestIncompatibleChanges, ChangedDirectionSpecifier) {
- io_delegate_.SetFileContents("old/p/IFoo.aidl",
- "package p;"
- "interface IFoo {"
- " void foo(in String[] str);"
- " void bar(@utf8InCpp String str);"
- "}");
+ // changed direction specifier
io_delegate_.SetFileContents("new/p/IFoo.aidl",
"package p;"
"interface IFoo {"
" void foo(out String[] str);"
" void bar(@utf8InCpp String str);"
"}");
- EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
-}
-
-TEST_F(AidlTestIncompatibleChanges, AddedAnnotation) {
- io_delegate_.SetFileContents("old/p/IFoo.aidl",
+ io_delegate_.SetFileContents("new/p/Data.aidl",
"package p;"
- "interface IFoo {"
- " void foo(in String[] str);"
- " void bar(@utf8InCpp String str);"
+ "parcelable Data {"
+ " int foo;"
+ " int bar;"
"}");
+ EXPECT_FALSE(::android::aidl::check_api(options, io_delegate_));
+ io_delegate_.SetFileContents("new/p/IFoo.aidl", "");
+ io_delegate_.SetFileContents("new/p/Data.aidl", "");
+
+ // added annotation
io_delegate_.SetFileContents("new/p/IFoo.aidl",
"package p;"
"interface IFoo {"
" void foo(in @utf8InCpp String[] str);"
" void bar(@utf8InCpp String str);"
"}");
- EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
-}
-
-TEST_F(AidlTestIncompatibleChanges, RemovedAnnotation) {
- io_delegate_.SetFileContents("old/p/IFoo.aidl",
+ io_delegate_.SetFileContents("new/p/Data.aidl",
"package p;"
- "interface IFoo {"
- " void foo(in String[] str);"
- " void bar(@utf8InCpp String str);"
+ "parcelable Data {"
+ " int foo;"
+ " int bar;"
"}");
+ EXPECT_FALSE(::android::aidl::check_api(options, io_delegate_));
+ io_delegate_.SetFileContents("new/p/IFoo.aidl", "");
+ io_delegate_.SetFileContents("new/p/Data.aidl", "");
+
+ // removed annotation
io_delegate_.SetFileContents("new/p/IFoo.aidl",
"package p;"
"interface IFoo {"
" void foo(in String[] str);"
" void bar(String str);"
"}");
- EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
-}
+ io_delegate_.SetFileContents("new/p/Data.aidl",
+ "package p;"
+ "parcelable Data {"
+ " int foo;"
+ " int bar;"
+ "}");
+ EXPECT_FALSE(::android::aidl::check_api(options, io_delegate_));
+ io_delegate_.SetFileContents("new/p/IFoo.aidl", "");
+ io_delegate_.SetFileContents("new/p/Data.aidl", "");
-TEST_F(AidlTestIncompatibleChanges, RemovedPackage) {
+ // removed package
+ io_delegate_.SetFileContents("old/p/Data.aidl", "");
io_delegate_.SetFileContents("old/p/IFoo.aidl", "package p; interface IFoo{}");
io_delegate_.SetFileContents("old/q/IFoo.aidl", "package q; interface IFoo{}");
- io_delegate_.SetFileContents("new/p/IFoo.aidl", "package p; interface IFoo{}");
- EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
-}
-TEST_F(AidlTestIncompatibleChanges, ChangedDefaultValue) {
+ io_delegate_.SetFileContents("new/p/IFoo.aidl", "package p; interface IFoo{}");
+ EXPECT_FALSE(::android::aidl::check_api(options, io_delegate_));
+ io_delegate_.SetFileContents("old/p/IFoo.aidl", "");
+ io_delegate_.SetFileContents("old/q/IFoo.aidl", "");
+ io_delegate_.SetFileContents("new/p/IFoo.aidl", "");
+
+ // changed default value
io_delegate_.SetFileContents("old/p/D.aidl", "package p; parcelable D { int a = 1; }");
io_delegate_.SetFileContents("new/p/D.aidl", "package p; parcelable D { int a = 2; }");
- EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
-}
+ EXPECT_FALSE(::android::aidl::check_api(options, io_delegate_));
+ io_delegate_.SetFileContents("old/p/D.aidl", "");
+ io_delegate_.SetFileContents("new/p/D.aidl", "");
-TEST_F(AidlTestIncompatibleChanges, RemovedConstValue) {
+ // removed const value
io_delegate_.SetFileContents("old/p/I.aidl",
"package p; interface I {"
"const int A = 1; const int B = 2;}");
io_delegate_.SetFileContents("new/p/I.aidl", "package p; interface I { const int A = 1; }");
- EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
-}
+ EXPECT_FALSE(::android::aidl::check_api(options, io_delegate_));
+ io_delegate_.SetFileContents("old/p/I.aidl", "");
+ io_delegate_.SetFileContents("new/p/I.aidl", "");
-TEST_F(AidlTestIncompatibleChanges, ChangedConstValue) {
+ // changed const value
io_delegate_.SetFileContents("old/p/I.aidl", "package p; interface I { const int A = 1; }");
io_delegate_.SetFileContents("new/p/I.aidl", "package p; interface I { const int A = 2; }");
- EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
+ EXPECT_FALSE(::android::aidl::check_api(options, io_delegate_));
+ io_delegate_.SetFileContents("old/p/I.aidl", "");
+ io_delegate_.SetFileContents("new/p/I.aidl", "");
}
TEST_F(AidlTest, RejectAmbiguousImports) {
@@ -1516,21 +1358,6 @@
EXPECT_NE(0, ::android::aidl::compile_aidl(options, io_delegate_));
}
-TEST_F(AidlTest, AllowDuplicatedImportPaths) {
- Options options = Options::From("aidl --lang=java -I dir -I dir IFoo.aidl");
- io_delegate_.SetFileContents("dir/IBar.aidl", "interface IBar{}");
- io_delegate_.SetFileContents("IFoo.aidl", "import IBar; interface IFoo{}");
- EXPECT_EQ(0, ::android::aidl::compile_aidl(options, io_delegate_));
-}
-
-TEST_F(AidlTest, FailOnAmbiguousImports) {
- Options options = Options::From("aidl --lang=java -I dir -I dir2 IFoo.aidl");
- io_delegate_.SetFileContents("dir/IBar.aidl", "interface IBar{}");
- io_delegate_.SetFileContents("dir2/IBar.aidl", "interface IBar{}");
- io_delegate_.SetFileContents("IFoo.aidl", "import IBar; interface IFoo{}");
- EXPECT_NE(0, ::android::aidl::compile_aidl(options, io_delegate_));
-}
-
class AidlOutputPathTest : public AidlTest {
protected:
void SetUp() override {
@@ -1565,67 +1392,5 @@
Test(Options::From("aidl sub/dir/foo/bar/IFoo.aidl"), "sub/dir/foo/bar/IFoo.java");
}
-TEST_F(AidlTest, FailOnOutOfBoundsInt32MaxConstInt) {
- AidlError reported_error;
- EXPECT_EQ(nullptr, Parse("p/IFoo.aidl",
- R"(package p;
- interface IFoo {
- const int int32_max_oob = 2147483650;
- }
- )",
- typenames_, Options::Language::CPP, &reported_error));
- EXPECT_EQ(AidlError::BAD_TYPE, reported_error);
-}
-
-TEST_F(AidlTest, FailOnOutOfBoundsInt32MinConstInt) {
- AidlError reported_error;
- EXPECT_EQ(nullptr, Parse("p/IFoo.aidl",
- R"(package p;
- interface IFoo {
- const int int32_min_oob = -2147483650;
- }
- )",
- typenames_, Options::Language::CPP, &reported_error));
- EXPECT_EQ(AidlError::BAD_TYPE, reported_error);
-}
-
-TEST_F(AidlTest, FailOnOutOfBoundsInt64MaxConstInt) {
- AidlError reported_error;
- EXPECT_EQ(nullptr, Parse("p/IFoo.aidl",
- R"(package p;
- interface IFoo {
- const long int64_max_oob = 21474836509999999999999999;
- }
- )",
- typenames_, Options::Language::CPP, &reported_error));
- EXPECT_EQ(AidlError::PARSE_ERROR, reported_error);
-}
-
-TEST_F(AidlTest, FailOnOutOfBoundsInt64MinConstInt) {
- AidlError reported_error;
- EXPECT_EQ(nullptr, Parse("p/IFoo.aidl",
- R"(package p;
- interface IFoo {
- const long int64_min_oob = -21474836509999999999999999;
- }
- )",
- typenames_, Options::Language::CPP, &reported_error));
- EXPECT_EQ(AidlError::PARSE_ERROR, reported_error);
-}
-
-TEST_F(AidlTest, FailOnOutOfBoundsAutofilledEnum) {
- AidlError reported_error;
- EXPECT_EQ(nullptr, Parse("p/TestEnum.aidl",
- R"(package p;
- @Backing(type="byte")
- enum TestEnum {
- FOO = 127,
- BAR,
- }
- )",
- typenames_, Options::Language::CPP, &reported_error));
- EXPECT_EQ(AidlError::BAD_TYPE, reported_error);
-}
-
} // namespace aidl
} // namespace android
diff --git a/ast_cpp.cpp b/ast_cpp.cpp
index 98566fb..e5ed6d8 100644
--- a/ast_cpp.cpp
+++ b/ast_cpp.cpp
@@ -92,18 +92,16 @@
: key(k),
value(v) {}
-Enum::Enum(const string& name, const string& base_type, bool is_class)
- : enum_name_(name), underlying_type_(base_type), is_class_(is_class) {}
+Enum::Enum(const string& name, const string& base_type)
+ : enum_name_(name), underlying_type_(base_type) {}
+
+Enum::Enum(const string& name) : Enum(name, "") {}
void Enum::Write(CodeWriter* to) const {
- to->Write("enum ");
- if (is_class_) {
- to->Write("class ");
- }
if (underlying_type_.empty()) {
- to->Write("%s {\n", enum_name_.c_str());
+ to->Write("enum %s {\n", enum_name_.c_str());
} else {
- to->Write("%s : %s {\n", enum_name_.c_str(), underlying_type_.c_str());
+ to->Write("enum %s : %s {\n", enum_name_.c_str(), underlying_type_.c_str());
}
to->Indent();
for (const auto& field : fields_) {
@@ -263,10 +261,6 @@
arguments_(std::move(arg_list)),
initializer_list_(initializer_list) {}
-StatementBlock* ConstructorImpl::GetStatementBlock() {
- return &body_;
-}
-
void ConstructorImpl::Write(CodeWriter* to) const {
to->Write("%s::%s", class_name_.c_str(), class_name_.c_str());
arguments_.Write(to);
diff --git a/ast_cpp.h b/ast_cpp.h
index 635519d..9f9414a 100644
--- a/ast_cpp.h
+++ b/ast_cpp.h
@@ -87,7 +87,8 @@
class Enum : public Declaration {
public:
- Enum(const std::string& name, const std::string& base_type, bool is_class);
+ Enum(const std::string& name, const std::string& base_type);
+ explicit Enum(const std::string& name);
virtual ~Enum() = default;
bool HasValues() const { return !fields_.empty(); }
@@ -104,7 +105,6 @@
std::string enum_name_;
std::string underlying_type_;
- bool is_class_;
std::vector<EnumField> fields_;
DISALLOW_COPY_AND_ASSIGN(Enum);
@@ -228,9 +228,6 @@
const std::vector<std::string>& initializer_list);
virtual ~ConstructorImpl() = default;
- // ConstructorImpl retains ownership of the statement block.
- StatementBlock* GetStatementBlock();
-
void Write(CodeWriter* to) const override;
private:
diff --git a/ast_cpp_unittest.cpp b/ast_cpp_unittest.cpp
index c8f1937..6c34424 100644
--- a/ast_cpp_unittest.cpp
+++ b/ast_cpp_unittest.cpp
@@ -59,6 +59,13 @@
#endif // HEADER_INCLUDE_GUARD_H_
)";
+const char kExpectedEnumOutput[] =
+R"(enum Foo {
+ BAR = 42,
+ BAZ,
+};
+)";
+
const char kExpectedSwitchOutput[] =
R"(switch (var) {
case 2:
@@ -139,34 +146,11 @@
CompareGeneratedCode(cpp_header, kExpectedHeaderOutput);
}
-TEST_F(AstCppTests, GeneratesUnscopedEnum) {
- Enum e("Foo", "", false);
+TEST_F(AstCppTests, GeneratesEnum) {
+ Enum e("Foo");
e.AddValue("BAR", "42");
e.AddValue("BAZ", "");
-
- string expected =
- R"(enum Foo {
- BAR = 42,
- BAZ,
-};
-)";
-
- CompareGeneratedCode(e, expected);
-}
-
-TEST_F(AstCppTests, GeneratesScopedEnum) {
- Enum e("Foo", "int32_t", true);
- e.AddValue("BAR", "42");
- e.AddValue("BAZ", "");
-
- string expected =
- R"(enum class Foo : int32_t {
- BAR = 42,
- BAZ,
-};
-)";
-
- CompareGeneratedCode(e, expected);
+ CompareGeneratedCode(e, kExpectedEnumOutput);
}
TEST_F(AstCppTests, GeneratesArgList) {
diff --git a/ast_java.cpp b/ast_java.cpp
index f997494..d38319c 100644
--- a/ast_java.cpp
+++ b/ast_java.cpp
@@ -65,7 +65,7 @@
}
}
-void WriteArgumentList(CodeWriter* to, const vector<std::shared_ptr<Expression>>& arguments) {
+void WriteArgumentList(CodeWriter* to, const vector<Expression*>& arguments) {
size_t N = arguments.size();
for (size_t i = 0; i < N; i++) {
arguments[i]->Write(to);
@@ -75,7 +75,7 @@
}
}
-Field::Field(int m, std::shared_ptr<Variable> v) : ClassElement(), modifiers(m), variable(v) {}
+Field::Field(int m, Variable* v) : ClassElement(), modifiers(m), variable(v) {}
void Field::Write(CodeWriter* to) const {
if (this->comment.length() != 0) {
@@ -105,22 +105,27 @@
to->Write("\"%s\"", this->value.c_str());
}
-Variable::Variable(const string& t, const string& n) : type(t), name(n) {}
+Variable::Variable(const string& t, const string& n) : type(t), name(n), dimension(0) {}
+
+Variable::Variable(const string& t, const string& n, int d) : type(t), name(n), dimension(d) {}
void Variable::WriteDeclaration(CodeWriter* to) const {
- to->Write("%s %s", this->type.c_str(), this->name.c_str());
+ string dim;
+ for (int i = 0; i < this->dimension; i++) {
+ dim += "[]";
+ }
+ to->Write("%s%s %s", this->type.c_str(), dim.c_str(), this->name.c_str());
}
void Variable::Write(CodeWriter* to) const { to->Write("%s", name.c_str()); }
-FieldVariable::FieldVariable(std::shared_ptr<Expression> o, const string& n)
- : receiver(o), name(n) {}
+FieldVariable::FieldVariable(Expression* o, const string& n) : receiver(o), name(n) {}
FieldVariable::FieldVariable(const string& c, const string& n) : receiver(c), name(n) {}
void FieldVariable::Write(CodeWriter* to) const {
visit(
- overloaded{[&](std::shared_ptr<Expression> e) { e->Write(to); },
+ overloaded{[&](Expression* e) { e->Write(to); },
[&](const std::string& s) { to->Write("%s", s.c_str()); }, [](std::monostate) {}},
this->receiver);
to->Write(".%s", name.c_str());
@@ -143,26 +148,24 @@
to->Write("}\n");
}
-void StatementBlock::Add(std::shared_ptr<Statement> statement) {
+void StatementBlock::Add(Statement* statement) {
this->statements.push_back(statement);
}
-void StatementBlock::Add(std::shared_ptr<Expression> expression) {
- this->statements.push_back(std::make_shared<ExpressionStatement>(expression));
+void StatementBlock::Add(Expression* expression) {
+ this->statements.push_back(new ExpressionStatement(expression));
}
-ExpressionStatement::ExpressionStatement(std::shared_ptr<Expression> e) : expression(e) {}
+ExpressionStatement::ExpressionStatement(Expression* e) : expression(e) {}
void ExpressionStatement::Write(CodeWriter* to) const {
this->expression->Write(to);
to->Write(";\n");
}
-Assignment::Assignment(std::shared_ptr<Variable> l, std::shared_ptr<Expression> r)
- : lvalue(l), rvalue(r) {}
+Assignment::Assignment(Variable* l, Expression* r) : lvalue(l), rvalue(r) {}
-Assignment::Assignment(std::shared_ptr<Variable> l, std::shared_ptr<Expression> r, string c)
- : lvalue(l), rvalue(r), cast(c) {}
+Assignment::Assignment(Variable* l, Expression* r, string c) : lvalue(l), rvalue(r), cast(c) {}
void Assignment::Write(CodeWriter* to) const {
this->lvalue->Write(to);
@@ -175,24 +178,42 @@
MethodCall::MethodCall(const string& n) : name(n) {}
-MethodCall::MethodCall(const string& n, const std::vector<std::shared_ptr<Expression>>& args)
- : name(n), arguments(args) {}
+MethodCall::MethodCall(const string& n, int argc = 0, ...) : name(n) {
+ va_list args;
+ va_start(args, argc);
+ init(argc, args);
+ va_end(args);
+}
-MethodCall::MethodCall(std::shared_ptr<Expression> o, const string& n) : receiver(o), name(n) {}
+MethodCall::MethodCall(Expression* o, const string& n) : receiver(o), name(n) {}
MethodCall::MethodCall(const std::string& t, const string& n) : receiver(t), name(n) {}
-MethodCall::MethodCall(std::shared_ptr<Expression> o, const string& n,
- const std::vector<std::shared_ptr<Expression>>& args)
- : receiver(o), name(n), arguments(args) {}
+MethodCall::MethodCall(Expression* o, const string& n, int argc = 0, ...) : receiver(o), name(n) {
+ va_list args;
+ va_start(args, argc);
+ init(argc, args);
+ va_end(args);
+}
-MethodCall::MethodCall(const std::string& t, const string& n,
- const std::vector<std::shared_ptr<Expression>>& args)
- : receiver(t), name(n), arguments(args) {}
+MethodCall::MethodCall(const std::string& t, const string& n, int argc = 0, ...)
+ : receiver(t), name(n) {
+ va_list args;
+ va_start(args, argc);
+ init(argc, args);
+ va_end(args);
+}
+
+void MethodCall::init(int n, va_list args) {
+ for (int i = 0; i < n; i++) {
+ Expression* expression = (Expression*)va_arg(args, void*);
+ this->arguments.push_back(expression);
+ }
+}
void MethodCall::Write(CodeWriter* to) const {
visit(
- overloaded{[&](std::shared_ptr<Expression> e) {
+ overloaded{[&](Expression* e) {
e->Write(to);
to->Write(".");
},
@@ -203,8 +224,7 @@
to->Write(")");
}
-Comparison::Comparison(std::shared_ptr<Expression> l, const string& o,
- std::shared_ptr<Expression> r)
+Comparison::Comparison(Expression* l, const string& o, Expression* r)
: lvalue(l), op(o), rvalue(r) {}
void Comparison::Write(CodeWriter* to) const {
@@ -217,9 +237,19 @@
NewExpression::NewExpression(const std::string& n) : instantiableName(n) {}
-NewExpression::NewExpression(const std::string& n,
- const std::vector<std::shared_ptr<Expression>>& args)
- : instantiableName(n), arguments(args) {}
+NewExpression::NewExpression(const std::string& n, int argc = 0, ...) : instantiableName(n) {
+ va_list args;
+ va_start(args, argc);
+ init(argc, args);
+ va_end(args);
+}
+
+void NewExpression::init(int n, va_list args) {
+ for (int i = 0; i < n; i++) {
+ Expression* expression = (Expression*)va_arg(args, void*);
+ this->arguments.push_back(expression);
+ }
+}
void NewExpression::Write(CodeWriter* to) const {
to->Write("new %s(", this->instantiableName.c_str());
@@ -227,8 +257,7 @@
to->Write(")");
}
-NewArrayExpression::NewArrayExpression(const std::string& t, std::shared_ptr<Expression> s)
- : type(t), size(s) {}
+NewArrayExpression::NewArrayExpression(const std::string& t, Expression* s) : type(t), size(s) {}
void NewArrayExpression::Write(CodeWriter* to) const {
to->Write("new %s[", this->type.c_str());
@@ -236,7 +265,7 @@
to->Write("]");
}
-Cast::Cast(const std::string& t, std::shared_ptr<Expression> e) : type(t), expression(e) {}
+Cast::Cast(const std::string& t, Expression* e) : type(t), expression(e) {}
void Cast::Write(CodeWriter* to) const {
to->Write("((%s)", this->type.c_str());
@@ -244,10 +273,9 @@
to->Write(")");
}
-VariableDeclaration::VariableDeclaration(std::shared_ptr<Variable> l, std::shared_ptr<Expression> r)
- : lvalue(l), rvalue(r) {}
+VariableDeclaration::VariableDeclaration(Variable* l, Expression* r) : lvalue(l), rvalue(r) {}
-VariableDeclaration::VariableDeclaration(std::shared_ptr<Variable> l) : lvalue(l) {}
+VariableDeclaration::VariableDeclaration(Variable* l) : lvalue(l) {}
void VariableDeclaration::Write(CodeWriter* to) const {
this->lvalue->WriteDeclaration(to);
@@ -271,7 +299,7 @@
}
}
-ReturnStatement::ReturnStatement(std::shared_ptr<Expression> e) : expression(e) {}
+ReturnStatement::ReturnStatement(Expression* e) : expression(e) {}
void ReturnStatement::Write(CodeWriter* to) const {
to->Write("return ");
@@ -308,7 +336,7 @@
statements->Write(to);
}
-SwitchStatement::SwitchStatement(std::shared_ptr<Expression> e) : expression(e) {}
+SwitchStatement::SwitchStatement(Expression* e) : expression(e) {}
void SwitchStatement::Write(CodeWriter* to) const {
to->Write("switch (");
@@ -338,7 +366,11 @@
SCOPE_MASK | STATIC | ABSTRACT | FINAL | OVERRIDE);
if (this->returnType) {
- to->Write("%s ", this->returnType->c_str());
+ string dim;
+ for (i = 0; i < this->returnTypeDimension; i++) {
+ dim += "[]";
+ }
+ to->Write("%s%s ", this->returnType->c_str(), dim.c_str());
}
to->Write("%s(", this->name.c_str());
@@ -455,11 +487,6 @@
}
}
-std::shared_ptr<Expression> NULL_VALUE = std::make_shared<LiteralExpression>("null");
-std::shared_ptr<Expression> THIS_VALUE = std::make_shared<LiteralExpression>("this");
-std::shared_ptr<Expression> SUPER_VALUE = std::make_shared<LiteralExpression>("super");
-std::shared_ptr<Expression> TRUE_VALUE = std::make_shared<LiteralExpression>("true");
-std::shared_ptr<Expression> FALSE_VALUE = std::make_shared<LiteralExpression>("false");
} // namespace java
} // namespace aidl
} // namespace android
diff --git a/ast_java.h b/ast_java.h
index d037d97..ec0ccfd 100644
--- a/ast_java.h
+++ b/ast_java.h
@@ -89,9 +89,11 @@
struct Variable : public Expression {
const std::string type;
std::string name;
+ int dimension = 0;
Variable() = default;
Variable(const std::string& type, const std::string& name);
+ Variable(const std::string& type, const std::string& name, int dimension);
virtual ~Variable() = default;
void WriteDeclaration(CodeWriter* to) const;
@@ -99,10 +101,10 @@
};
struct FieldVariable : public Expression {
- std::variant<std::shared_ptr<Expression>, std::string> receiver;
+ std::variant<Expression*, std::string> receiver;
std::string name;
- FieldVariable(std::shared_ptr<Expression> object, const std::string& name);
+ FieldVariable(Expression* object, const std::string& name);
FieldVariable(const std::string& clazz, const std::string& name);
virtual ~FieldVariable() = default;
@@ -113,11 +115,11 @@
std::string comment;
std::vector<std::string> annotations;
int modifiers = 0;
- std::shared_ptr<Variable> variable = nullptr;
+ Variable* variable = nullptr;
std::string value;
Field() = default;
- Field(int modifiers, std::shared_ptr<Variable> variable);
+ Field(int modifiers, Variable* variable);
virtual ~Field() = default;
void Write(CodeWriter* to) const override;
@@ -138,108 +140,110 @@
};
struct StatementBlock : public Statement {
- std::vector<std::shared_ptr<Statement>> statements;
+ std::vector<Statement*> statements;
StatementBlock() = default;
virtual ~StatementBlock() = default;
void Write(CodeWriter* to) const override;
- void Add(std::shared_ptr<Statement> statement);
- void Add(std::shared_ptr<Expression> expression);
+ void Add(Statement* statement);
+ void Add(Expression* expression);
};
struct ExpressionStatement : public Statement {
- std::shared_ptr<Expression> expression;
+ Expression* expression;
- explicit ExpressionStatement(std::shared_ptr<Expression> expression);
+ explicit ExpressionStatement(Expression* expression);
virtual ~ExpressionStatement() = default;
void Write(CodeWriter* to) const override;
};
struct Assignment : public Expression {
- std::shared_ptr<Variable> lvalue;
- std::shared_ptr<Expression> rvalue;
+ Variable* lvalue;
+ Expression* rvalue;
std::optional<std::string> cast = std::nullopt;
- Assignment(std::shared_ptr<Variable> lvalue, std::shared_ptr<Expression> rvalue);
- Assignment(std::shared_ptr<Variable> lvalue, std::shared_ptr<Expression> rvalue,
- std::string cast);
+ Assignment(Variable* lvalue, Expression* rvalue);
+ Assignment(Variable* lvalue, Expression* rvalue, std::string cast);
virtual ~Assignment() = default;
void Write(CodeWriter* to) const override;
};
struct MethodCall : public Expression {
- std::variant<std::monostate, std::shared_ptr<Expression>, std::string> receiver;
+ std::variant<std::monostate, Expression*, std::string> receiver;
std::string name;
- std::vector<std::shared_ptr<Expression>> arguments;
+ std::vector<Expression*> arguments;
std::vector<std::string> exceptions;
explicit MethodCall(const std::string& name);
- MethodCall(const std::string& name, const std::vector<std::shared_ptr<Expression>>& args);
- MethodCall(std::shared_ptr<Expression> obj, const std::string& name);
+ MethodCall(const std::string& name, int argc, ...);
+ MethodCall(Expression* obj, const std::string& name);
MethodCall(const std::string& clazz, const std::string& name);
- MethodCall(std::shared_ptr<Expression> obj, const std::string& name,
- const std::vector<std::shared_ptr<Expression>>& args);
- MethodCall(const std::string&, const std::string& name,
- const std::vector<std::shared_ptr<Expression>>& args);
+ MethodCall(Expression* obj, const std::string& name, int argc, ...);
+ MethodCall(const std::string&, const std::string& name, int argc, ...);
virtual ~MethodCall() = default;
void Write(CodeWriter* to) const override;
+
+ private:
+ void init(int n, va_list args);
};
struct Comparison : public Expression {
- std::shared_ptr<Expression> lvalue;
+ Expression* lvalue;
std::string op;
- std::shared_ptr<Expression> rvalue;
+ Expression* rvalue;
- Comparison(std::shared_ptr<Expression> lvalue, const std::string& op,
- std::shared_ptr<Expression> rvalue);
+ Comparison(Expression* lvalue, const std::string& op, Expression* rvalue);
virtual ~Comparison() = default;
void Write(CodeWriter* to) const override;
};
struct NewExpression : public Expression {
const std::string instantiableName;
- std::vector<std::shared_ptr<Expression>> arguments;
+ std::vector<Expression*> arguments;
explicit NewExpression(const std::string& name);
- NewExpression(const std::string& name, const std::vector<std::shared_ptr<Expression>>& args);
+ NewExpression(const std::string& name, int argc, ...);
virtual ~NewExpression() = default;
void Write(CodeWriter* to) const override;
+
+ private:
+ void init(int n, va_list args);
};
struct NewArrayExpression : public Expression {
const std::string type;
- std::shared_ptr<Expression> size;
+ Expression* size;
- NewArrayExpression(const std::string& type, std::shared_ptr<Expression> size);
+ NewArrayExpression(const std::string& type, Expression* size);
virtual ~NewArrayExpression() = default;
void Write(CodeWriter* to) const override;
};
struct Cast : public Expression {
const std::string type;
- std::shared_ptr<Expression> expression = nullptr;
+ Expression* expression = nullptr;
Cast() = default;
- Cast(const std::string& type, std::shared_ptr<Expression> expression);
+ Cast(const std::string& type, Expression* expression);
virtual ~Cast() = default;
void Write(CodeWriter* to) const override;
};
struct VariableDeclaration : public Statement {
- std::shared_ptr<Variable> lvalue = nullptr;
- std::shared_ptr<Expression> rvalue = nullptr;
+ Variable* lvalue = nullptr;
+ Expression* rvalue = nullptr;
- explicit VariableDeclaration(std::shared_ptr<Variable> lvalue);
- VariableDeclaration(std::shared_ptr<Variable> lvalue, std::shared_ptr<Expression> rvalue);
+ explicit VariableDeclaration(Variable* lvalue);
+ VariableDeclaration(Variable* lvalue, Expression* rvalue);
virtual ~VariableDeclaration() = default;
void Write(CodeWriter* to) const override;
};
struct IfStatement : public Statement {
- std::shared_ptr<Expression> expression = nullptr;
- std::shared_ptr<StatementBlock> statements = std::make_shared<StatementBlock>();
- std::shared_ptr<IfStatement> elseif = nullptr;
+ Expression* expression = nullptr;
+ StatementBlock* statements = new StatementBlock;
+ IfStatement* elseif = nullptr;
IfStatement() = default;
virtual ~IfStatement() = default;
@@ -247,15 +251,15 @@
};
struct ReturnStatement : public Statement {
- std::shared_ptr<Expression> expression;
+ Expression* expression;
- explicit ReturnStatement(std::shared_ptr<Expression> expression);
+ explicit ReturnStatement(Expression* expression);
virtual ~ReturnStatement() = default;
void Write(CodeWriter* to) const override;
};
struct TryStatement : public Statement {
- std::shared_ptr<StatementBlock> statements = std::make_shared<StatementBlock>();
+ StatementBlock* statements = new StatementBlock;
TryStatement() = default;
virtual ~TryStatement() = default;
@@ -263,7 +267,7 @@
};
struct FinallyStatement : public Statement {
- std::shared_ptr<StatementBlock> statements = std::make_shared<StatementBlock>();
+ StatementBlock* statements = new StatementBlock;
FinallyStatement() = default;
virtual ~FinallyStatement() = default;
@@ -272,7 +276,7 @@
struct Case : public AstNode {
std::vector<std::string> cases;
- std::shared_ptr<StatementBlock> statements = std::make_shared<StatementBlock>();
+ StatementBlock* statements = new StatementBlock;
Case() = default;
explicit Case(const std::string& c);
@@ -281,10 +285,10 @@
};
struct SwitchStatement : public Statement {
- std::shared_ptr<Expression> expression;
- std::vector<std::shared_ptr<Case>> cases;
+ Expression* expression;
+ std::vector<Case*> cases;
- explicit SwitchStatement(std::shared_ptr<Expression> expression);
+ explicit SwitchStatement(Expression* expression);
virtual ~SwitchStatement() = default;
void Write(CodeWriter* to) const override;
};
@@ -294,10 +298,11 @@
std::vector<std::string> annotations;
int modifiers = 0;
std::optional<std::string> returnType = std::nullopt; // nullopt means constructor
+ size_t returnTypeDimension = 0;
std::string name;
- std::vector<std::shared_ptr<Variable>> parameters;
+ std::vector<Variable*> parameters;
std::vector<std::string> exceptions;
- std::shared_ptr<StatementBlock> statements = nullptr;
+ StatementBlock* statements = nullptr;
Method() = default;
virtual ~Method() = default;
@@ -324,7 +329,7 @@
std::string type;
std::optional<std::string> extends = std::nullopt;
std::vector<std::string> interfaces;
- std::vector<std::shared_ptr<ClassElement>> elements;
+ std::vector<ClassElement*> elements;
Class() = default;
virtual ~Class() = default;
@@ -346,11 +351,6 @@
std::unique_ptr<Class> clazz_;
};
-extern std::shared_ptr<Expression> NULL_VALUE;
-extern std::shared_ptr<Expression> THIS_VALUE;
-extern std::shared_ptr<Expression> SUPER_VALUE;
-extern std::shared_ptr<Expression> TRUE_VALUE;
-extern std::shared_ptr<Expression> FALSE_VALUE;
} // namespace java
} // namespace aidl
} // namespace android
diff --git a/ast_java_unittest.cpp b/ast_java_unittest.cpp
index 0101d42..d287504 100644
--- a/ast_java_unittest.cpp
+++ b/ast_java_unittest.cpp
@@ -20,6 +20,7 @@
#include "ast_java.h"
#include "code_writer.h"
+#include "type_java.h"
using std::string;
@@ -38,12 +39,16 @@
} // namespace
TEST(AstJavaTests, GeneratesClass) {
+ JavaTypeNamespace types;
+ types.Init();
+ Type class_type(&types, "TestClass", ValidatableType::KIND_GENERATED, false);
+ Type extend_type(&types, "SuperClass", ValidatableType::KIND_BUILT_IN, false);
Class a_class;
a_class.comment = "// class comment";
a_class.modifiers = FINAL;
a_class.what = Class::CLASS;
- a_class.type = "TestClass";
- a_class.extends = "SuperClass";
+ a_class.type = class_type.JavaType();
+ a_class.extends = extend_type.JavaType();
string actual_output;
a_class.Write(CodeWriter::ForString(&actual_output).get());
diff --git a/build/Android.bp b/build/Android.bp
index 9cf4125..9b27b32 100644
--- a/build/Android.bp
+++ b/build/Android.bp
@@ -35,8 +35,6 @@
cc_defaults {
name: "aidl-cpp-module-defaults",
- // TODO(b/31559095): remove when host bionic is available
- defaults: ["libbinder_ndk_host_user"],
cflags: [
"-Wall",
"-Werror",
@@ -50,8 +48,12 @@
// Tests
-filegroup {
- name: "aidl-test-filegroup",
+// Copy of test-piece-1 as test only. Creating a separate library because 'vendor_available' is
+// contagious.
+aidl_interface {
+ name: "test-vendor",
+ local_include_dir: "tests_1",
+ vendor_available: true,
srcs: [
"tests_1/some_package/IFoo.aidl",
"tests_1/some_package/Thing.aidl",
@@ -59,25 +61,13 @@
],
}
-// Copy of test-piece-1 as test only. Creating a separate library because 'vendor_available' is
-// contagious.
-aidl_interface {
- name: "test-variants",
- local_include_dir: "tests_1",
- vendor_available: true,
- host_supported: true,
- srcs: [
- ":aidl-test-filegroup",
- ],
-}
-
aidl_interface {
name: "test-piece-1",
local_include_dir: "tests_1",
srcs: [
"tests_1/some_package/IFoo.aidl",
"tests_1/some_package/Thing.aidl",
- "tests_1/some_package/sub_package/*.aidl", // testing glob w/o filegroup
+ "tests_1/some_package/sub_package/*.aidl",
],
api_dir: "api/test-piece-1",
versions: ["1"],
diff --git a/build/Android.mk b/build/Android.mk
deleted file mode 100644
index e50f702..0000000
--- a/build/Android.mk
+++ /dev/null
@@ -1,18 +0,0 @@
-#
-# Copyright (C) 2019 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-.PHONY: aidl-freeze-api
-aidl-freeze-api: $(addsuffix -freeze-api, $(SOONG_ALL_AIDL_INTERFACES))
diff --git a/build/aidl_interface.go b/build/aidl_interface.go
index 56534e7..ba022bf 100644
--- a/build/aidl_interface.go
+++ b/build/aidl_interface.go
@@ -20,7 +20,6 @@
"android/soong/genrule"
"android/soong/java"
"android/soong/phony"
-
"fmt"
"io"
"path/filepath"
@@ -40,6 +39,7 @@
langJava = "java"
langNdk = "ndk"
langNdkPlatform = "ndk_platform"
+ futureVersion = "10000"
pctx = android.NewPackageContext("android/aidl")
@@ -69,11 +69,10 @@
}, "imports", "outDir", "optionalFlags")
aidlDumpApiRule = pctx.StaticRule("aidlDumpApiRule", blueprint.RuleParams{
- Command: `rm -rf "${outDir}" && mkdir -p "${outDir}" && ` +
- `${aidlCmd} --dumpapi --structured ${imports} --out ${outDir} ${in} && ` +
- `(cd ${outDir} && find ./ -name "*.aidl" -exec sha1sum {} ';' && echo ${latestVersion}) | sha1sum > ${hashFile} `,
+ Command: `rm -rf "${out}" && mkdir -p "${out}" && ` +
+ `${aidlCmd} --dumpapi --structured ${imports} --out ${out} ${in}`,
CommandDeps: []string{"${aidlCmd}"},
- }, "imports", "outDir", "hashFile", "latestVersion")
+ }, "imports")
aidlDumpMappingsRule = pctx.StaticRule("aidlDumpMappingsRule", blueprint.RuleParams{
Command: `rm -rf "${outDir}" && mkdir -p "${outDir}" && ` +
@@ -86,12 +85,12 @@
blueprint.RuleParams{
Command: `mkdir -p ${to} && rm -rf ${to}/* && ` +
`${bpmodifyCmd} -w -m ${name} -parameter versions -a ${version} ${bp} && ` +
- `cp -rf ${apiDir}/. ${to} && ` +
+ `cp -rf ${in}/* ${to} && ` +
`find ${to} -type f -exec bash -c ` +
`"cat ${apiPreamble} {} > {}.temp; mv {}.temp {}" \; && ` +
`touch ${out}`,
CommandDeps: []string{"${bpmodifyCmd}"},
- }, "to", "name", "version", "bp", "apiDir", "apiPreamble")
+ }, "to", "name", "version", "bp", "apiPreamble")
aidlCheckApiRule = pctx.StaticRule("aidlCheckApiRule", blueprint.RuleParams{
Command: `(${aidlCmd} --checkapi ${old} ${new} && touch ${out}) || ` +
@@ -101,10 +100,10 @@
}, "old", "new", "messageFile")
aidlDiffApiRule = pctx.StaticRule("aidlDiffApiRule", blueprint.RuleParams{
- Command: `(diff -N --line-format="" ${oldHashFile} ${newHashFile} && diff -r -B -I '//.*' ${old} ${new} && touch ${out}) || ` +
+ Command: `(diff -r -B -I '//.*' ${old} ${new} && touch ${out}) || ` +
`(cat ${messageFile} && exit 1)`,
Description: "Check equality of ${new} and ${old}",
- }, "old", "new", "messageFile", "oldHashFile", "newHashFile")
+ }, "old", "new", "messageFile")
)
func init() {
@@ -113,7 +112,6 @@
pctx.SourcePathVariable("aidlToJniCmd", "system/tools/aidl/build/aidl_to_jni.py")
android.RegisterModuleType("aidl_interface", aidlInterfaceFactory)
android.RegisterModuleType("aidl_mapping", aidlMappingFactory)
- android.RegisterMakeVarsProvider(pctx, allAidlInterfacesMakeVars)
}
// wrap(p, a, s) = [p + v + s for v in a]
@@ -134,24 +132,6 @@
return ret
}
-func checkAndUpdateSources(ctx android.ModuleContext, rawSrcs []string, inDir string) android.Paths {
- srcs := android.PathsForModuleSrc(ctx, rawSrcs)
- srcs = android.PathsWithModuleSrcSubDir(ctx, srcs, inDir)
-
- if len(srcs) == 0 {
- ctx.PropertyErrorf("srcs", "No sources provided.")
- }
-
- for _, source := range srcs {
- if source.Ext() != ".aidl" {
- ctx.PropertyErrorf("srcs", "Source must be a .aidl file: "+source.String())
- continue
- }
- }
-
- return srcs
-}
-
func isRelativePath(path string) bool {
if path == "" {
return true
@@ -161,14 +141,13 @@
}
type aidlGenProperties struct {
- Srcs []string `android:"path"`
- AidlRoot string // base directory for the input aidl file
- Imports []string
- Stability *string
- Lang string // target language [java|cpp|ndk]
- BaseName string
- GenLog bool
- Version string
+ Srcs []string
+ AidlRoot string // base directory for the input aidl file
+ Imports []string
+ Lang string // target language [java|cpp|ndk]
+ BaseName string
+ GenLog bool
+ Version string
}
type aidlGenRule struct {
@@ -179,22 +158,15 @@
implicitInputs android.Paths
importFlags string
- genOutDir android.ModuleGenPath
- genHeaderDir android.ModuleGenPath
- genHeaderDeps android.Paths
- genOutputs android.WritablePaths
+ genOutDir android.ModuleGenPath
+ genHeaderDir android.ModuleGenPath
+ genOutputs android.WritablePaths
}
var _ android.SourceFileProducer = (*aidlGenRule)(nil)
var _ genrule.SourceFileGenerator = (*aidlGenRule)(nil)
func (g *aidlGenRule) GenerateAndroidBuildActions(ctx android.ModuleContext) {
- srcs := checkAndUpdateSources(ctx, g.properties.Srcs, g.properties.AidlRoot)
-
- if ctx.Failed() {
- return
- }
-
genDirTimestamp := android.PathForModuleGen(ctx, "timestamp")
g.implicitInputs = append(g.implicitInputs, genDirTimestamp)
@@ -212,12 +184,12 @@
})
g.importFlags = strings.Join(wrap("-I", importPaths, ""), " ")
+ srcs := android.PathsWithModuleSrcSubDir(ctx, android.PathsForModuleSrc(ctx, g.properties.Srcs), g.properties.AidlRoot)
+
g.genOutDir = android.PathForModuleGen(ctx)
g.genHeaderDir = android.PathForModuleGen(ctx, "include")
for _, src := range srcs {
- outFile, headers := g.generateBuildActionsForSingleAidl(ctx, src)
- g.genOutputs = append(g.genOutputs, outFile)
- g.genHeaderDeps = append(g.genHeaderDeps, headers...)
+ g.genOutputs = append(g.genOutputs, g.generateBuildActionsForSingleAidl(ctx, src))
}
// This is to clean genOutDir before generating any file
@@ -231,7 +203,7 @@
})
}
-func (g *aidlGenRule) generateBuildActionsForSingleAidl(ctx android.ModuleContext, src android.Path) (android.WritablePath, android.Paths) {
+func (g *aidlGenRule) generateBuildActionsForSingleAidl(ctx android.ModuleContext, src android.Path) android.WritablePath {
var outFile android.WritablePath
if g.properties.Lang == langJava {
outFile = android.PathForModuleGen(ctx, pathtools.ReplaceExtension(src.Rel(), "java"))
@@ -244,7 +216,6 @@
optionalFlags = append(optionalFlags, "--version "+g.properties.Version)
}
- var headers android.WritablePaths
if g.properties.Lang == langJava {
ctx.ModuleBuild(pctx, android.ModuleBuildParams{
Rule: aidlJavaRule,
@@ -274,6 +245,7 @@
prefix = "aidl"
}
+ var headers android.WritablePaths
headers = append(headers, g.genHeaderDir.Join(ctx, prefix, packagePath,
typeName+".h"))
headers = append(headers, g.genHeaderDir.Join(ctx, prefix, packagePath,
@@ -285,10 +257,6 @@
optionalFlags = append(optionalFlags, "--log")
}
- if g.properties.Stability != nil {
- optionalFlags = append(optionalFlags, "--stability", *g.properties.Stability)
- }
-
aidlLang := g.properties.Lang
if aidlLang == langNdkPlatform {
aidlLang = "ndk"
@@ -310,7 +278,7 @@
})
}
- return outFile, headers.Paths()
+ return outFile
}
func (g *aidlGenRule) GeneratedSourceFiles() android.Paths {
@@ -322,7 +290,7 @@
}
func (g *aidlGenRule) GeneratedDeps() android.Paths {
- return g.genHeaderDeps
+ return g.genOutputs.Paths()
}
func (g *aidlGenRule) GeneratedHeaderDirs() android.Paths {
@@ -343,7 +311,7 @@
type aidlApiProperties struct {
BaseName string
- Srcs []string `android:"path"`
+ Inputs []string
Imports []string
Api_dir *string
Versions []string
@@ -377,23 +345,17 @@
} else {
latestVersion := m.properties.Versions[len(m.properties.Versions)-1]
- i, err := strconv.Atoi(latestVersion)
+ i, err := strconv.ParseInt(latestVersion, 10, 64)
if err != nil {
ctx.PropertyErrorf("versions", "must be integers")
return ""
}
- return strconv.Itoa(i + 1)
+ return strconv.FormatInt(i+1, 10)
}
}
-func (m *aidlApi) createApiDumpFromSource(ctx android.ModuleContext) (apiDir android.WritablePath, apiFiles android.WritablePaths, hashFile android.WritablePath) {
- srcs := checkAndUpdateSources(ctx, m.properties.Srcs, m.properties.AidlRoot)
-
- if ctx.Failed() {
- return
- }
-
+func (m *aidlApi) createApiDumpFromSource(ctx android.ModuleContext) (apiDir android.WritablePath, apiFiles android.WritablePaths) {
var importPaths []string
ctx.VisitDirectDeps(func(dep android.Module) {
if importedAidl, ok := dep.(*aidlInterface); ok {
@@ -401,28 +363,28 @@
}
})
+ var srcs android.Paths
+ for _, input := range m.properties.Inputs {
+ path := android.PathForModuleSrc(ctx, input)
+ path = android.PathWithModuleSrcSubDir(ctx, path, m.properties.AidlRoot)
+ srcs = append(srcs, path)
+ }
+
apiDir = android.PathForModuleOut(ctx, "dump")
for _, src := range srcs {
apiFiles = append(apiFiles, android.PathForModuleOut(ctx, "dump", src.Rel()))
}
- hashFile = android.PathForModuleOut(ctx, "dump", ".hash")
- latestVersion := "latest-version"
- if len(m.properties.Versions) >= 1 {
- latestVersion = m.properties.Versions[len(m.properties.Versions)-1]
- }
imports := strings.Join(wrap("-I", importPaths, ""), " ")
ctx.ModuleBuild(pctx, android.ModuleBuildParams{
- Rule: aidlDumpApiRule,
- Outputs: append(apiFiles, hashFile),
- Inputs: srcs,
+ Rule: aidlDumpApiRule,
+ Inputs: srcs,
+ Output: apiDir,
+ ImplicitOutputs: apiFiles,
Args: map[string]string{
- "imports": imports,
- "outDir": apiDir.String(),
- "hashFile": hashFile.String(),
- "latestVersion": latestVersion,
+ "imports": imports,
},
})
- return apiDir, apiFiles, hashFile
+ return apiDir, apiFiles
}
func (m *aidlApi) freezeApiDumpAsVersion(ctx android.ModuleContext, apiDumpDir android.Path, apiFiles android.Paths, version string) android.WritablePath {
@@ -443,7 +405,6 @@
Output: timestampFile,
Args: map[string]string{
"to": filepath.Join(modulePath, m.apiDir(), version),
- "apiDir": apiDumpDir.String(),
"name": m.properties.BaseName,
"version": version,
"bp": android.PathForModuleSrc(ctx, "Android.bp").String(),
@@ -474,8 +435,7 @@
return timestampFile
}
-func (m *aidlApi) checkEquality(ctx android.ModuleContext, oldApiDir android.Path, oldApiFiles android.Paths, oldHashFile android.OptionalPath,
- newApiDir android.Path, newApiFiles android.Paths, newHashFile android.Path) android.WritablePath {
+func (m *aidlApi) checkEquality(ctx android.ModuleContext, oldApiDir android.Path, oldApiFiles android.Paths, newApiDir android.Path, newApiFiles android.Paths) android.WritablePath {
newVersion := newApiDir.Base()
timestampFile := android.PathForModuleOut(ctx, "checkapi_"+newVersion+".timestamp")
messageFile := android.PathForSource(ctx, "system/tools/aidl/build/message_check_equality.txt")
@@ -483,10 +443,6 @@
implicits = append(implicits, oldApiFiles...)
implicits = append(implicits, newApiFiles...)
implicits = append(implicits, messageFile)
- if oldHashFile.Valid() {
- implicits = append(implicits, oldHashFile.Path())
- }
- implicits = append(implicits, newHashFile)
ctx.ModuleBuild(pctx, android.ModuleBuildParams{
Rule: aidlDiffApiRule,
Implicits: implicits,
@@ -495,8 +451,6 @@
"old": oldApiDir.String(),
"new": newApiDir.String(),
"messageFile": messageFile.String(),
- "oldHashFile": oldHashFile.String(),
- "newHashFile": newHashFile.String(),
},
})
return timestampFile
@@ -504,12 +458,12 @@
func (m *aidlApi) GenerateAndroidBuildActions(ctx android.ModuleContext) {
currentVersion := m.validateCurrentVersion(ctx)
- currentDumpDir, currentApiFiles, currentHashFile := m.createApiDumpFromSource(ctx)
if ctx.Failed() {
return
}
+ currentDumpDir, currentApiFiles := m.createApiDumpFromSource(ctx)
m.freezeApiTimestamp = m.freezeApiDumpAsVersion(ctx, currentDumpDir, currentApiFiles.Paths(), currentVersion)
apiDirs := make(map[string]android.Path)
@@ -538,9 +492,7 @@
var checkApiTimestamp android.WritablePath
if ctx.Config().DefaultAppTargetSdkInt() != android.FutureApiLevel {
// If API is frozen, don't allow any change to the API
- latestHashFile := android.OptionalPathForModuleSrc(ctx, proptools.StringPtr(filepath.Join(m.apiDir(), latestVersion, ".hash")))
- checkApiTimestamp = m.checkEquality(ctx, apiDirs[latestVersion], apiFiles[latestVersion], latestHashFile,
- apiDirs[currentVersion], apiFiles[currentVersion], currentHashFile)
+ checkApiTimestamp = m.checkEquality(ctx, apiDirs[latestVersion], apiFiles[latestVersion], apiDirs[currentVersion], apiFiles[currentVersion])
} else {
// If not, allow backwards compatible changes to the API
checkApiTimestamp = m.checkCompatibility(ctx, apiDirs[latestVersion], apiFiles[latestVersion], apiDirs[currentVersion], apiFiles[currentVersion])
@@ -577,10 +529,6 @@
// Whether the library can be installed on the vendor image.
Vendor_available *bool
-
- // Whether the library can be used on host
- Host_supported *bool
-
// Top level directories for includes.
// TODO(b/128940869): remove it if aidl_interface can depend on framework.aidl
Include_dirs []string
@@ -588,11 +536,12 @@
// TODO(b/111117220): automatically compute by letting AIDL parse multiple files simultaneously
Local_include_dir string
- // List of .aidl files which compose this interface.
- Srcs []string `android:"path"`
+ // The owner of the module
+ Owner *string
- // List of aidl_interface modules that this uses. If one of your AIDL interfaces uses an
- // interface or parcelable from another aidl_interface, you should put its name here.
+ // List of .aidl files which compose this interface. These may be globbed.
+ Srcs []string
+
Imports []string
// Used by gen dependency to fill out aidl include path
@@ -601,14 +550,6 @@
// Directory where API dumps are. Default is "api".
Api_dir *string
- // Stability promise. Currently only supports "vintf".
- // If this is unset, this corresponds to an interface with stability within
- // this compilation context (so an interface loaded here can only be used
- // with things compiled together, e.g. on the system.img).
- // If this is set to "vintf", this corresponds to a stability promise: the
- // interface must be kept stable as long as it is used.
- Stability *string
-
// Previous API versions that are now frozen. The version that is last in
// the list is considered as the most recent version.
Versions []string
@@ -647,6 +588,9 @@
android.ModuleBase
properties aidlInterfaceProperties
+
+ // Unglobbed sources
+ rawSrcs []string
}
func (i *aidlInterface) shouldGenerateJavaBackend() bool {
@@ -664,6 +608,44 @@
return i.properties.Backend.Ndk.Enabled == nil || *i.properties.Backend.Ndk.Enabled
}
+func (i *aidlInterface) checkAndUpdateSources(mctx android.LoadHookContext) {
+ prefix := mctx.ModuleDir()
+ for _, source := range i.properties.Srcs {
+ if pathtools.IsGlob(source) {
+ globbedSrcFiles, err := mctx.GlobWithDeps(filepath.Join(prefix, source), nil)
+ if err != nil {
+ mctx.ModuleErrorf("glob: %s", err.Error())
+ }
+ for _, globbedSrc := range globbedSrcFiles {
+ relativeGlobbedSrc, err := filepath.Rel(prefix, globbedSrc)
+ if err != nil {
+ panic(err)
+ }
+
+ i.rawSrcs = append(i.rawSrcs, relativeGlobbedSrc)
+ }
+ } else {
+ i.rawSrcs = append(i.rawSrcs, source)
+ }
+ }
+
+ if len(i.rawSrcs) == 0 {
+ mctx.PropertyErrorf("srcs", "No sources provided.")
+ }
+
+ for _, source := range i.rawSrcs {
+ if !strings.HasSuffix(source, ".aidl") {
+ mctx.PropertyErrorf("srcs", "Source must be a .aidl file: "+source)
+ continue
+ }
+
+ relativePath, err := filepath.Rel(i.properties.Local_include_dir, source)
+ if err != nil || !isRelativePath(relativePath) {
+ mctx.PropertyErrorf("srcs", "Source is not in local_include_dir: "+source)
+ }
+ }
+}
+
func (i *aidlInterface) checkImports(mctx android.LoadHookContext) {
for _, anImport := range i.properties.Imports {
other := lookupInterface(anImport)
@@ -672,11 +654,6 @@
mctx.PropertyErrorf("imports", "Import does not exist: "+anImport)
}
- if i.shouldGenerateJavaBackend() && !other.shouldGenerateJavaBackend() {
- mctx.PropertyErrorf("backend.java.enabled",
- "Java backend not enabled in the imported AIDL interface %q", anImport)
- }
-
if i.shouldGenerateCppBackend() && !other.shouldGenerateCppBackend() {
mctx.PropertyErrorf("backend.cpp.enabled",
"C++ backend not enabled in the imported AIDL interface %q", anImport)
@@ -689,93 +666,17 @@
}
}
-func (i *aidlInterface) checkStability(mctx android.LoadHookContext) {
- if i.properties.Stability == nil {
- return
- }
-
- if i.shouldGenerateJavaBackend() {
- mctx.PropertyErrorf("stability", "Java backend does not yet support stability.")
- }
-
- // TODO(b/136027762): should we allow more types of stability (e.g. for APEX) or
- // should we switch this flag to be something like "vintf { enabled: true }"
- if *i.properties.Stability != "vintf" {
- mctx.PropertyErrorf("stability", "must be empty or \"vintf\"")
- }
-
- // TODO(b/136027762): need some global way to understand AOSP interfaces. Also,
- // need the implementation for vendor extensions to be merged. For now, restrict
- // where this can be defined
- if !filepath.HasPrefix(mctx.ModuleDir(), "hardware/interfaces/") {
- mctx.PropertyErrorf("stability", "can only be set in hardware/interfaces")
- }
-}
-
-func (i *aidlInterface) currentVersion(ctx android.BaseModuleContext) string {
- if !i.hasVersion() {
- return ""
- } else {
- i, err := strconv.Atoi(i.latestVersion())
- if err != nil {
- ctx.PropertyErrorf("versions", "must be integers")
- return ""
- }
-
- return strconv.Itoa(i + 1)
- }
-}
-
-func (i *aidlInterface) latestVersion() string {
- return i.properties.Versions[len(i.properties.Versions)-1]
-}
-func (i *aidlInterface) isLatestVersion(version string) bool {
- if !i.hasVersion() {
- return true
- }
- return version == i.latestVersion()
-}
-func (i *aidlInterface) hasVersion() bool {
- return len(i.properties.Versions) > 0
-}
-
-func (i *aidlInterface) isCurrentVersion(ctx android.BaseModuleContext, version string) bool {
- return version == i.currentVersion(ctx)
-}
-
-// This function returns module name with version. Assume that there is foo of which latest version is 2
-// Version -> Module name
-// "1"->foo-V1
-// "2"->foo-V2
-// "3"(unfrozen)->foo-unstable
-// ""-> foo
-func (i *aidlInterface) versionedName(ctx android.BaseModuleContext, version string) string {
+func (i *aidlInterface) versionedName(version string) string {
name := i.ModuleBase.Name()
- if version == "" {
- return name
+ if version != futureVersion && version != "" {
+ name = name + "-V" + version
}
- if i.isCurrentVersion(ctx, version) {
- return name + "-unstable"
- }
- return name + "-V" + version
-}
-
-// The only difference between versionedName and cppOutputName is about unstable version
-// foo-unstable -> foo-V3
-func (i *aidlInterface) cppOutputName(version string) string {
- name := i.ModuleBase.Name()
- if !i.hasVersion() {
- return name
- }
- if version == "" {
- version = i.latestVersion()
- }
- return name + "-V" + version
+ return name
}
func (i *aidlInterface) srcsForVersion(mctx android.LoadHookContext, version string) (srcs []string, base string) {
- if i.isCurrentVersion(mctx, version) {
- return i.properties.Srcs, i.properties.Local_include_dir
+ if version == futureVersion || version == "" {
+ return i.rawSrcs, i.properties.Local_include_dir
} else {
var apiDir string
if i.properties.Api_dir != nil {
@@ -806,8 +707,8 @@
i.properties.Full_import_paths = importPaths
+ i.checkAndUpdateSources(mctx)
i.checkImports(mctx)
- i.checkStability(mctx)
if mctx.Failed() {
return
@@ -815,18 +716,14 @@
var libs []string
- currentVersion := i.currentVersion(mctx)
-
- versionsForCpp := make([]string, len(i.properties.Versions))
- copy(versionsForCpp, i.properties.Versions)
- if i.hasVersion() {
- // In C++ library, AIDL doesn't create the module of which name is with latest version,
- // instead of it, there is a module without version.
- versionsForCpp[len(i.properties.Versions)-1] = ""
+ currentVersion := ""
+ if len(i.properties.Versions) > 0 {
+ currentVersion = futureVersion
}
+
if i.shouldGenerateCppBackend() {
libs = append(libs, addCppLibrary(mctx, i, currentVersion, langCpp))
- for _, version := range versionsForCpp {
+ for _, version := range i.properties.Versions {
addCppLibrary(mctx, i, version, langCpp)
}
}
@@ -835,43 +732,35 @@
// TODO(b/119771576): inherit properties and export 'is vendor' computation from cc.go
if !proptools.Bool(i.properties.Vendor_available) {
libs = append(libs, addCppLibrary(mctx, i, currentVersion, langNdk))
- for _, version := range versionsForCpp {
+ for _, version := range i.properties.Versions {
addCppLibrary(mctx, i, version, langNdk)
}
}
// TODO(b/121157555): combine with '-ndk' variant
libs = append(libs, addCppLibrary(mctx, i, currentVersion, langNdkPlatform))
- for _, version := range versionsForCpp {
+ for _, version := range i.properties.Versions {
addCppLibrary(mctx, i, version, langNdkPlatform)
}
}
- versionsForJava := i.properties.Versions
- if i.hasVersion() {
- versionsForJava = append(i.properties.Versions, "")
- }
- if i.shouldGenerateJavaBackend() {
- libs = append(libs, addJavaLibrary(mctx, i, currentVersion))
- for _, version := range versionsForJava {
- addJavaLibrary(mctx, i, version)
- }
+
+ libs = append(libs, addJavaLibrary(mctx, i, currentVersion))
+ for _, version := range i.properties.Versions {
+ addJavaLibrary(mctx, i, version)
}
addApiModule(mctx, i)
// Reserve this module name for future use
- mctx.CreateModule(phony.PhonyFactory, &phonyProperties{
+ mctx.CreateModule(android.ModuleFactoryAdaptor(phony.PhonyFactory), &phonyProperties{
Name: proptools.StringPtr(i.ModuleBase.Name()),
Required: libs,
})
}
func addCppLibrary(mctx android.LoadHookContext, i *aidlInterface, version string, lang string) string {
- cppSourceGen := i.versionedName(mctx, version) + "-" + lang + "-source"
- cppModuleGen := i.versionedName(mctx, version) + "-" + lang
- cppOutputGen := i.cppOutputName(version) + "-" + lang
- if i.hasVersion() && version == "" {
- version = i.latestVersion()
- }
+ cppSourceGen := i.versionedName(version) + "-" + lang + "-source"
+ cppModuleGen := i.versionedName(version) + "-" + lang
+
srcs, base := i.srcsForVersion(mctx, version)
if len(srcs) == 0 {
// This can happen when the version is about to be frozen; the version
@@ -887,17 +776,16 @@
genLog = proptools.Bool(i.properties.Backend.Ndk.Gen_log)
}
- mctx.CreateModule(aidlGenFactory, &nameProperties{
+ mctx.CreateModule(android.ModuleFactoryAdaptor(aidlGenFactory), &nameProperties{
Name: proptools.StringPtr(cppSourceGen),
}, &aidlGenProperties{
- Srcs: srcs,
- AidlRoot: base,
- Imports: concat(i.properties.Imports, []string{i.ModuleBase.Name()}),
- Stability: i.properties.Stability,
- Lang: lang,
- BaseName: i.ModuleBase.Name(),
- GenLog: genLog,
- Version: version,
+ Srcs: srcs,
+ AidlRoot: base,
+ Imports: concat(i.properties.Imports, []string{i.ModuleBase.Name()}),
+ Lang: lang,
+ BaseName: i.ModuleBase.Name(),
+ GenLog: genLog,
+ Version: version,
})
importExportDependencies := wrap("", i.properties.Imports, "-"+lang)
@@ -906,15 +794,14 @@
var sdkVersion *string
var stl *string
var cpp_std *string
- var host_supported *bool
- var addCflags []string
-
if lang == langCpp {
importExportDependencies = append(importExportDependencies, "libbinder", "libutils")
if genLog {
libJSONCppDependency = []string{"libjsoncpp"}
}
- host_supported = i.properties.Host_supported
+ sdkVersion = nil
+ stl = nil
+ cpp_std = nil
} else if lang == langNdk {
importExportDependencies = append(importExportDependencies, "libbinder_ndk")
if genLog {
@@ -927,16 +814,14 @@
if genLog {
libJSONCppDependency = []string{"libjsoncpp"}
}
- host_supported = i.properties.Host_supported
- addCflags = append(addCflags, "-DBINDER_STABILITY_SUPPORT")
} else {
panic("Unrecognized language: " + lang)
}
- mctx.CreateModule(cc.LibraryFactory, &ccProperties{
+ mctx.CreateModule(android.ModuleFactoryAdaptor(cc.LibraryFactory), &ccProperties{
Name: proptools.StringPtr(cppModuleGen),
+ Owner: i.properties.Owner,
Vendor_available: i.properties.Vendor_available,
- Host_supported: host_supported,
Defaults: []string{"aidl-cpp-module-defaults"},
Generated_sources: []string{cppSourceGen},
Generated_headers: []string{cppSourceGen},
@@ -949,19 +834,16 @@
Sdk_version: sdkVersion,
Stl: stl,
Cpp_std: cpp_std,
- Cflags: append(addCflags, "-Wextra", "-Wall", "-Werror"),
- Stem: proptools.StringPtr(cppOutputGen),
+ Cflags: []string{"-Wextra", "-Wall", "-Werror"},
}, &i.properties.VndkProperties)
return cppModuleGen
}
func addJavaLibrary(mctx android.LoadHookContext, i *aidlInterface, version string) string {
- javaSourceGen := i.versionedName(mctx, version) + "-java-source"
- javaModuleGen := i.versionedName(mctx, version) + "-java"
- if i.hasVersion() && version == "" {
- version = i.latestVersion()
- }
+ javaSourceGen := i.versionedName(version) + "-java-source"
+ javaModuleGen := i.versionedName(version) + "-java"
+
srcs, base := i.srcsForVersion(mctx, version)
if len(srcs) == 0 {
// This can happen when the version is about to be frozen; the version
@@ -972,25 +854,26 @@
sdkVersion := proptools.StringDefault(i.properties.Backend.Java.Sdk_version, "system_current")
- mctx.CreateModule(aidlGenFactory, &nameProperties{
+ mctx.CreateModule(android.ModuleFactoryAdaptor(aidlGenFactory), &nameProperties{
Name: proptools.StringPtr(javaSourceGen),
}, &aidlGenProperties{
- Srcs: srcs,
- AidlRoot: base,
- Imports: concat(i.properties.Imports, []string{i.ModuleBase.Name()}),
- Stability: i.properties.Stability,
- Lang: langJava,
- BaseName: i.ModuleBase.Name(),
- Version: version,
+ Srcs: srcs,
+ AidlRoot: base,
+ Imports: concat(i.properties.Imports, []string{i.ModuleBase.Name()}),
+ Lang: langJava,
+ BaseName: i.ModuleBase.Name(),
+ Version: version,
})
- mctx.CreateModule(java.LibraryFactory, &javaProperties{
- Name: proptools.StringPtr(javaModuleGen),
- Installable: proptools.BoolPtr(true),
- Defaults: []string{"aidl-java-module-defaults"},
- Sdk_version: proptools.StringPtr(sdkVersion),
- Static_libs: wrap("", i.properties.Imports, "-java"),
- Srcs: []string{":" + javaSourceGen},
+ mctx.CreateModule(android.ModuleFactoryAdaptor(java.LibraryFactory), &javaProperties{
+ Name: proptools.StringPtr(javaModuleGen),
+ Owner: i.properties.Owner,
+ Installable: proptools.BoolPtr(true),
+ Defaults: []string{"aidl-java-module-defaults"},
+ No_framework_libs: proptools.BoolPtr(true),
+ Sdk_version: proptools.StringPtr(sdkVersion),
+ Static_libs: wrap("", i.properties.Imports, "-java"),
+ Srcs: []string{":" + javaSourceGen},
})
return javaModuleGen
@@ -998,11 +881,11 @@
func addApiModule(mctx android.LoadHookContext, i *aidlInterface) string {
apiModule := i.ModuleBase.Name() + aidlApiSuffix
- mctx.CreateModule(aidlApiFactory, &nameProperties{
+ mctx.CreateModule(android.ModuleFactoryAdaptor(aidlApiFactory), &nameProperties{
Name: proptools.StringPtr(apiModule),
}, &aidlApiProperties{
BaseName: i.ModuleBase.Name(),
- Srcs: i.properties.Srcs,
+ Inputs: i.rawSrcs,
Imports: concat(i.properties.Imports, []string{i.ModuleBase.Name()}),
Api_dir: i.properties.Api_dir,
AidlRoot: i.properties.Local_include_dir,
@@ -1046,7 +929,7 @@
type aidlMappingProperties struct {
// Source file of this prebuilt.
- Srcs []string `android:"path"`
+ Srcs []string `android:"arch_variant"`
Output string
}
@@ -1057,24 +940,56 @@
}
func (s *aidlMapping) DepsMutator(ctx android.BottomUpMutatorContext) {
+ android.ExtractSourcesDeps(ctx, s.properties.Srcs)
+}
+
+func addItemsToMap(dest map[string]bool, src []string) {
+ for _, item := range src {
+ dest[item] = true
+ }
}
func (s *aidlMapping) GenerateAndroidBuildActions(ctx android.ModuleContext) {
- var aidlSrcs android.Paths
- var importDirs []string
+ var srcs android.Paths
+ var all_import_dirs map[string]bool = make(map[string]bool)
- srcs := android.PathsForModuleSrc(ctx, s.properties.Srcs)
- for _, file := range srcs {
- if file.Ext() == ".aidl" {
- aidlSrcs = append(aidlSrcs, file)
- baseDir := strings.TrimSuffix(file.String(), file.Rel())
- if baseDir != "" && !android.InList(baseDir, importDirs) {
- importDirs = append(importDirs, baseDir)
+ ctx.VisitDirectDeps(func(module android.Module) {
+ for _, property := range module.GetProperties() {
+ if jproperty, ok := property.(*java.CompilerProperties); ok {
+ for _, src := range jproperty.Srcs {
+ if strings.HasSuffix(src, ".aidl") {
+ full_path := android.PathForModuleSrc(ctx, src)
+ srcs = append(srcs, full_path)
+ all_import_dirs[filepath.Dir(full_path.String())] = true
+ } else if pathtools.IsGlob(src) {
+ globbedSrcFiles, err := ctx.GlobWithDeps(src, nil)
+ if err == nil {
+ for _, globbedSrc := range globbedSrcFiles {
+ full_path := android.PathForModuleSrc(ctx, globbedSrc)
+ all_import_dirs[full_path.String()] = true
+ }
+ }
+ }
+ }
+ } else if jproperty, ok := property.(*java.CompilerDeviceProperties); ok {
+ addItemsToMap(all_import_dirs, jproperty.Aidl.Include_dirs)
+ for _, include_dir := range jproperty.Aidl.Export_include_dirs {
+ var full_path = filepath.Join(ctx.ModuleDir(), include_dir)
+ all_import_dirs[full_path] = true
+ }
+ for _, include_dir := range jproperty.Aidl.Local_include_dirs {
+ var full_path = filepath.Join(ctx.ModuleSubDir(), include_dir)
+ all_import_dirs[full_path] = true
+ }
}
}
- }
+ })
- imports := android.JoinWithPrefix(importDirs, " -I")
+ var import_dirs []string
+ for dir := range all_import_dirs {
+ import_dirs = append(import_dirs, dir)
+ }
+ imports := strings.Join(wrap("-I", import_dirs, ""), " ")
s.outputFilePath = android.PathForModuleOut(ctx, s.properties.Output)
outDir := android.PathForModuleGen(ctx)
ctx.Build(pctx, android.BuildParams{
@@ -1109,13 +1024,3 @@
},
}
}
-
-func allAidlInterfacesMakeVars(ctx android.MakeVarsContext) {
- names := []string{}
- ctx.VisitAllModules(func(module android.Module) {
- if ai, ok := module.(*aidlInterface); ok {
- names = append(names, ai.Name())
- }
- })
- ctx.Strict("ALL_AIDL_INTERFACES", strings.Join(names, " "))
-}
diff --git a/build/properties.go b/build/properties.go
index a1b3489..f0256b8 100644
--- a/build/properties.go
+++ b/build/properties.go
@@ -30,7 +30,6 @@
Owner *string
Defaults []string
Vendor_available *bool
- Host_supported *bool
Generated_sources []string
Generated_headers []string
Shared sharedLib
@@ -43,17 +42,17 @@
Stl *string
Cpp_std *string
Cflags []string
- Stem *string
}
type javaProperties struct {
- Name *string
- Owner *string
- Defaults []string
- Installable *bool
- Sdk_version *string
- Srcs []string
- Static_libs []string
+ Name *string
+ Owner *string
+ Defaults []string
+ Installable *bool
+ No_framework_libs *bool
+ Sdk_version *string
+ Srcs []string
+ Static_libs []string
}
type phonyProperties struct {
diff --git a/docs/aidl-cpp.md b/docs/aidl-cpp.md
index aa97aa9..156b697 100644
--- a/docs/aidl-cpp.md
+++ b/docs/aidl-cpp.md
@@ -91,6 +91,7 @@
| String | String16 | in | Supports null references. |
| @utf8InCpp String | std::string | in | @utf8InCpp causes UTF16 to UTF8 conversion in C++. |
| android.os.Parcelable | android::Parcelable | inout | |
+| java.util.Map | android::binder::Map| inout | `std::map<std::string,android::binder::Value>` |
| T extends IBinder | sp<T> | in | |
| Arrays (T[]) | vector<T> | inout | May contain only primitives, Strings and parcelables. |
| List<String> | vector<String16> | inout | |
diff --git a/generate_aidl_mappings.cpp b/generate_aidl_mappings.cpp
index 1624ee6..97958e3 100644
--- a/generate_aidl_mappings.cpp
+++ b/generate_aidl_mappings.cpp
@@ -15,7 +15,7 @@
*/
#include "generate_aidl_mappings.h"
-#include "aidl_to_java.h"
+#include "type_java.h"
#include <sstream>
@@ -27,8 +27,7 @@
return method.PrintLocation();
}
-SignatureMap generate_mappings(const AidlDefinedType* defined_type,
- const AidlTypenames& typenames) {
+SignatureMap generate_mappings(const AidlDefinedType* defined_type) {
const AidlInterface* interface = defined_type->AsInterface();
SignatureMap mappings;
if (interface == nullptr) {
@@ -40,10 +39,10 @@
signature << interface->GetCanonicalName() << "|";
signature << method->GetName() << "|";
for (const auto& arg : method->GetArguments()) {
- signature << java::JavaSignatureOf(arg->GetType(), typenames) << ",";
+ signature << arg->GetType().ToString() << ",";
}
signature << "|";
- signature << java::JavaSignatureOf(method->GetType(), typenames);
+ signature << method->GetType().GetLanguageType<java::Type>()->JavaType();
mappings[signature.str()] = dump_location(*method);
}
}
diff --git a/generate_aidl_mappings.h b/generate_aidl_mappings.h
index d74a17f..09f611e 100644
--- a/generate_aidl_mappings.h
+++ b/generate_aidl_mappings.h
@@ -26,7 +26,7 @@
using SignatureMap = std::unordered_map<std::string, std::string>;
-SignatureMap generate_mappings(const AidlDefinedType* iface, const AidlTypenames& typenames);
+SignatureMap generate_mappings(const AidlDefinedType* iface);
} // namespace mappings
} // namespace aidl
} // namespace android
diff --git a/generate_cpp.cpp b/generate_cpp.cpp
index 70b9acb..9d2a1fb 100644
--- a/generate_cpp.cpp
+++ b/generate_cpp.cpp
@@ -63,7 +63,6 @@
const char kIBinderHeader[] = "binder/IBinder.h";
const char kIInterfaceHeader[] = "binder/IInterface.h";
const char kParcelHeader[] = "binder/Parcel.h";
-const char kStabilityHeader[] = "binder/Stability.h";
const char kStatusHeader[] = "binder/Status.h";
const char kString16Header[] = "utils/String16.h";
const char kTraceHeader[] = "utils/Trace.h";
@@ -93,28 +92,25 @@
return unique_ptr<AstNode>(ret);
}
-ArgList BuildArgList(const AidlTypenames& typenames, const AidlMethod& method, bool for_declaration,
+ArgList BuildArgList(const TypeNamespace& types, const AidlMethod& method, bool for_declaration,
bool type_name_only = false) {
// Build up the argument list for the server method call.
vector<string> method_arguments;
for (const unique_ptr<AidlArgument>& a : method.GetArguments()) {
string literal;
if (for_declaration) {
- // Method declarations need typenames, pointers to out params, and variable
+ // Method declarations need types, pointers to out params, and variable
// names that match the .aidl specification.
- literal = CppNameOf(a->GetType(), typenames);
+ const Type* type = a->GetType().GetLanguageType<Type>();
+
+ literal = type->CppType();
if (a->IsOut()) {
literal = literal + "*";
} else {
- const auto definedType = typenames.TryGetDefinedType(a->GetType().GetName());
-
- const bool isEnum = definedType && definedType->AsEnumDeclaration() != nullptr;
- const bool isPrimitive = AidlTypenames::IsPrimitiveTypename(a->GetType().GetName());
-
// We pass in parameters that are not primitives by const reference.
// Arrays of primitives are not primitives.
- if (!(isPrimitive || isEnum) || a->GetType().IsArray()) {
+ if (!type->IsCppPrimitive() || a->GetType().IsArray()) {
literal = "const " + literal + "&";
}
}
@@ -128,10 +124,12 @@
method_arguments.push_back(literal);
}
- if (method.GetType().GetName() != "void") {
+ const Type* return_type = method.GetType().GetLanguageType<Type>();
+
+ if (return_type != types.VoidType()) {
string literal;
if (for_declaration) {
- literal = StringPrintf("%s* %s", CppNameOf(method.GetType(), typenames).c_str(),
+ literal = StringPrintf("%s* %s", return_type->CppType().c_str(),
type_name_only ? "" : kReturnVarName);
} else {
literal = string{"&"} + kReturnVarName;
@@ -142,7 +140,8 @@
return ArgList(method_arguments);
}
-unique_ptr<Declaration> BuildMethodDecl(const AidlMethod& method, const AidlTypenames& typenames,
+unique_ptr<Declaration> BuildMethodDecl(const AidlMethod& method,
+ const TypeNamespace& types,
bool for_interface) {
uint32_t modifiers = 0;
if (for_interface) {
@@ -153,11 +152,13 @@
}
return unique_ptr<Declaration>{
- new MethodDecl{kBinderStatusLiteral, method.GetName(),
- BuildArgList(typenames, method, true /* for method decl */), modifiers}};
+ new MethodDecl{kBinderStatusLiteral,
+ method.GetName(),
+ BuildArgList(types, method, true /* for method decl */),
+ modifiers}};
}
-unique_ptr<Declaration> BuildMetaMethodDecl(const AidlMethod& method, const AidlTypenames&,
+unique_ptr<Declaration> BuildMetaMethodDecl(const AidlMethod& method, const TypeNamespace&,
const Options& options, bool for_interface) {
CHECK(!method.IsUserDefined());
if (method.GetName() == kGetInterfaceVersion && options.Version()) {
@@ -195,9 +196,11 @@
return NestInNamespaces(std::move(decls), package);
}
-bool DeclareLocalVariable(const AidlArgument& a, StatementBlock* b,
- const AidlTypenames& typenamespaces) {
- string type = CppNameOf(a.GetType(), typenamespaces);
+bool DeclareLocalVariable(const AidlArgument& a, StatementBlock* b) {
+ const Type* cpp_type = a.GetType().GetLanguageType<Type>();
+ if (!cpp_type) { return false; }
+
+ string type = cpp_type->CppType();
b->AddLiteral(type + " " + BuildVarName(a));
return true;
@@ -222,14 +225,14 @@
return ret;
}
-unique_ptr<Declaration> DefineClientTransaction(const AidlTypenames& typenames,
+unique_ptr<Declaration> DefineClientTransaction(const TypeNamespace& types,
const AidlInterface& interface,
const AidlMethod& method, const Options& options) {
const string i_name = ClassName(interface, ClassNames::INTERFACE);
const string bp_name = ClassName(interface, ClassNames::CLIENT);
- unique_ptr<MethodImpl> ret{
- new MethodImpl{kBinderStatusLiteral, bp_name, method.GetName(),
- ArgList{BuildArgList(typenames, method, true /* for method decl */)}}};
+ unique_ptr<MethodImpl> ret{new MethodImpl{
+ kBinderStatusLiteral, bp_name, method.GetName(),
+ ArgList{BuildArgList(types, method, true /* for method decl */)}}};
StatementBlock* b = ret->GetStatementBlock();
// Declare parcels to hold our query and the response.
@@ -264,17 +267,19 @@
b->AddStatement(GotoErrorOnBadStatus());
for (const auto& a: method.GetArguments()) {
- const string var_name = ((a->IsOut()) ? "*" : "") + a->GetName();
+ const Type* type = a->GetType().GetLanguageType<Type>();
+ string var_name = ((a->IsOut()) ? "*" : "") + a->GetName();
+ var_name = type->WriteCast(var_name);
if (a->IsIn()) {
// Serialization looks roughly like:
// _aidl_ret_status = _aidl_data.WriteInt32(in_param_name);
// if (_aidl_ret_status != ::android::OK) { goto error; }
- const string& method = ParcelWriteMethodOf(a->GetType(), typenames);
- b->AddStatement(
- new Assignment(kAndroidStatusVarName,
- new MethodCall(StringPrintf("%s.%s", kDataVarName, method.c_str()),
- ParcelWriteCastOf(a->GetType(), typenames, var_name))));
+ const string& method = type->WriteToParcelMethod();
+ b->AddStatement(new Assignment(
+ kAndroidStatusVarName,
+ new MethodCall(StringPrintf("%s.%s", kDataVarName, method.c_str()),
+ ArgList(var_name))));
b->AddStatement(GotoErrorOnBadStatus());
} else if (a->IsOut() && a->GetType().IsArray()) {
// Special case, the length of the out array is written into the parcel.
@@ -282,7 +287,8 @@
// if (_aidl_ret_status != ::android::OK) { goto error; }
b->AddStatement(new Assignment(
kAndroidStatusVarName,
- new MethodCall(StringPrintf("%s.writeVectorSize", kDataVarName), var_name)));
+ new MethodCall(StringPrintf("%s.writeVectorSize", kDataVarName),
+ ArgList(var_name))));
b->AddStatement(GotoErrorOnBadStatus());
}
}
@@ -308,7 +314,7 @@
for (const auto& a : method.GetArguments()) {
arg_names.emplace_back(a->GetName());
}
- if (method.GetType().GetName() != "void") {
+ if (method.GetType().GetLanguageType<Type>() != types.VoidType()) {
arg_names.emplace_back(kReturnVarName);
}
b->AddLiteral(StringPrintf("if (UNLIKELY(_aidl_ret_status == ::android::UNKNOWN_TRANSACTION && "
@@ -341,12 +347,14 @@
// status" if we are a oneway method, so no more fear of accessing reply.
// If the method is expected to return something, read it first by convention.
- if (method.GetType().GetName() != "void") {
- const string& method_call = ParcelReadMethodOf(method.GetType(), typenames);
+ const Type* return_type = method.GetType().GetLanguageType<Type>();
+ if (return_type != types.VoidType()) {
+ const string& method_call = return_type->ReadFromParcelMethod();
b->AddStatement(new Assignment(
kAndroidStatusVarName,
- new MethodCall(StringPrintf("%s.%s", kReplyVarName, method_call.c_str()),
- ParcelReadCastOf(method.GetType(), typenames, kReturnVarName))));
+ new MethodCall(StringPrintf("%s.%s", kReplyVarName,
+ method_call.c_str()),
+ ArgList(kReturnVarName))));
b->AddStatement(GotoErrorOnBadStatus());
}
@@ -354,12 +362,14 @@
// Deserialization looks roughly like:
// _aidl_ret_status = _aidl_reply.ReadInt32(out_param_name);
// if (_aidl_status != ::android::OK) { goto _aidl_error; }
- string method = ParcelReadMethodOf(a->GetType(), typenames);
+ string method =
+ a->GetType().GetLanguageType<Type>()->ReadFromParcelMethod();
- b->AddStatement(
- new Assignment(kAndroidStatusVarName,
- new MethodCall(StringPrintf("%s.%s", kReplyVarName, method.c_str()),
- ParcelReadCastOf(a->GetType(), typenames, a->GetName()))));
+ b->AddStatement(new Assignment(
+ kAndroidStatusVarName,
+ new MethodCall(StringPrintf("%s.%s", kReplyVarName,
+ method.c_str()),
+ ArgList(a->GetName()))));
b->AddStatement(GotoErrorOnBadStatus());
}
@@ -384,7 +394,7 @@
return unique_ptr<Declaration>(ret.release());
}
-unique_ptr<Declaration> DefineClientMetaTransaction(const AidlTypenames& /* typenames */,
+unique_ptr<Declaration> DefineClientMetaTransaction(const TypeNamespace&,
const AidlInterface& interface,
const AidlMethod& method,
const Options& options) {
@@ -421,8 +431,8 @@
} // namespace
-unique_ptr<Document> BuildClientSource(const AidlTypenames& typenames,
- const AidlInterface& interface, const Options& options) {
+unique_ptr<Document> BuildClientSource(const TypeNamespace& types, const AidlInterface& interface,
+ const Options& options) {
vector<string> include_list = {
HeaderFile(interface, ClassNames::CLIENT, false),
kParcelHeader,
@@ -458,9 +468,9 @@
for (const auto& method : interface.GetMethods()) {
unique_ptr<Declaration> m;
if (method->IsUserDefined()) {
- m = DefineClientTransaction(typenames, interface, *method, options);
+ m = DefineClientTransaction(types, interface, *method, options);
} else {
- m = DefineClientMetaTransaction(typenames, interface, *method, options);
+ m = DefineClientMetaTransaction(types, interface, *method, options);
}
if (!m) { return nullptr; }
file_decls.push_back(std::move(m));
@@ -472,20 +482,22 @@
namespace {
-bool HandleServerTransaction(const AidlTypenames& typenames, const AidlInterface& interface,
+bool HandleServerTransaction(const TypeNamespace& types, const AidlInterface& interface,
const AidlMethod& method, const Options& options, StatementBlock* b) {
// Declare all the parameters now. In the common case, we expect no errors
// in serialization.
for (const unique_ptr<AidlArgument>& a : method.GetArguments()) {
- if (!DeclareLocalVariable(*a, b, typenames)) {
+ if (!DeclareLocalVariable(*a, b)) {
return false;
}
}
// Declare a variable to hold the return value.
- if (method.GetType().GetName() != "void") {
- string type = CppNameOf(method.GetType(), typenames);
- b->AddLiteral(StringPrintf("%s %s", type.c_str(), kReturnVarName));
+ const Type* return_type = method.GetType().GetLanguageType<Type>();
+ if (return_type != types.VoidType()) {
+ b->AddLiteral(StringPrintf(
+ "%s %s", return_type->CppType().c_str(),
+ kReturnVarName));
}
// Check that the client is calling the correct interface.
@@ -503,21 +515,23 @@
// Deserialization looks roughly like:
// _aidl_ret_status = _aidl_data.ReadInt32(&in_param_name);
// if (_aidl_ret_status != ::android::OK) { break; }
- const string& var_name = "&" + BuildVarName(*a);
+ const Type* type = a->GetType().GetLanguageType<Type>();
+ const string& readMethod = type->ReadFromParcelMethod();
+
if (a->IsIn()) {
- const string& readMethod = ParcelReadMethodOf(a->GetType(), typenames);
- b->AddStatement(
- new Assignment{kAndroidStatusVarName,
- new MethodCall{string(kDataVarName) + "." + readMethod,
- ParcelReadCastOf(a->GetType(), typenames, var_name)}});
+ b->AddStatement(new Assignment{
+ kAndroidStatusVarName,
+ new MethodCall{string(kDataVarName) + "." + readMethod,
+ "&" + BuildVarName(*a)}});
b->AddStatement(BreakOnStatusNotOk());
} else if (a->IsOut() && a->GetType().IsArray()) {
// Special case, the length of the out array is written into the parcel.
// _aidl_ret_status = _aidl_data.resizeOutVector(&out_param_name);
// if (_aidl_ret_status != ::android::OK) { break; }
- b->AddStatement(
- new Assignment{kAndroidStatusVarName,
- new MethodCall{string(kDataVarName) + ".resizeOutVector", var_name}});
+ b->AddStatement(new Assignment{
+ kAndroidStatusVarName,
+ new MethodCall{string(kDataVarName) + ".resizeOutVector",
+ "&" + BuildVarName(*a)}});
b->AddStatement(BreakOnStatusNotOk());
}
}
@@ -537,7 +551,8 @@
// Call the actual method. This is implemented by the subclass.
vector<unique_ptr<AstNode>> status_args;
status_args.emplace_back(new MethodCall(
- method.GetName(), BuildArgList(typenames, method, false /* not for method decl */)));
+ method.GetName(),
+ BuildArgList(types, method, false /* not for method decl */)));
b->AddStatement(new Statement(new MethodCall(
StringPrintf("%s %s", kBinderStatusLiteral, kStatusVarName),
ArgList(std::move(status_args)))));
@@ -566,13 +581,13 @@
}
// If we have a return value, write it first.
- if (method.GetType().GetName() != "void") {
+ if (return_type != types.VoidType()) {
string writeMethod =
- string(kReplyVarName) + "->" + ParcelWriteMethodOf(method.GetType(), typenames);
- b->AddStatement(new Assignment(
- kAndroidStatusVarName,
- new MethodCall(writeMethod,
- ParcelWriteCastOf(method.GetType(), typenames, kReturnVarName))));
+ string(kReplyVarName) + "->" +
+ return_type->WriteToParcelMethod();
+ b->AddStatement(new Assignment{
+ kAndroidStatusVarName, new MethodCall{writeMethod,
+ ArgList{return_type->WriteCast(kReturnVarName)}}});
b->AddStatement(BreakOnStatusNotOk());
}
// Write each out parameter to the reply parcel.
@@ -580,18 +595,20 @@
// Serialization looks roughly like:
// _aidl_ret_status = data.WriteInt32(out_param_name);
// if (_aidl_ret_status != ::android::OK) { break; }
- const string& writeMethod = ParcelWriteMethodOf(a->GetType(), typenames);
- b->AddStatement(new Assignment(
+ const Type* type = a->GetType().GetLanguageType<Type>();
+ const string& writeMethod = type->WriteToParcelMethod();
+
+ b->AddStatement(new Assignment{
kAndroidStatusVarName,
- new MethodCall(string(kReplyVarName) + "->" + writeMethod,
- ParcelWriteCastOf(a->GetType(), typenames, BuildVarName(*a)))));
+ new MethodCall{string(kReplyVarName) + "->" + writeMethod,
+ type->WriteCast(BuildVarName(*a))}});
b->AddStatement(BreakOnStatusNotOk());
}
return true;
}
-bool HandleServerMetaTransaction(const AidlTypenames&, const AidlInterface& interface,
+bool HandleServerMetaTransaction(const TypeNamespace&, const AidlInterface& interface,
const AidlMethod& method, const Options& options,
StatementBlock* b) {
CHECK(!method.IsUserDefined());
@@ -610,30 +627,18 @@
} // namespace
-unique_ptr<Document> BuildServerSource(const AidlTypenames& typenames,
- const AidlInterface& interface, const Options& options) {
+unique_ptr<Document> BuildServerSource(const TypeNamespace& types, const AidlInterface& interface,
+ const Options& options) {
const string bn_name = ClassName(interface, ClassNames::SERVER);
vector<string> include_list{
HeaderFile(interface, ClassNames::SERVER, false),
- kParcelHeader,
- kStabilityHeader,
+ kParcelHeader
};
if (options.GenLog()) {
include_list.emplace_back("chrono");
include_list.emplace_back("functional");
include_list.emplace_back("json/value.h");
}
-
- unique_ptr<ConstructorImpl> constructor{
- new ConstructorImpl{ClassName(interface, ClassNames::SERVER), ArgList{}, {}}};
-
- if (interface.IsVintfStability()) {
- constructor->GetStatementBlock()->AddLiteral("::android::internal::Stability::markVintf(this)");
- } else {
- constructor->GetStatementBlock()->AddLiteral(
- "::android::internal::Stability::markCompilationUnit(this)");
- }
-
unique_ptr<MethodImpl> on_transact{new MethodImpl{
kAndroidStatusLiteral, bn_name, "onTransact",
ArgList{{StringPrintf("uint32_t %s", kCodeVarName),
@@ -659,9 +664,9 @@
bool success = false;
if (method->IsUserDefined()) {
- success = HandleServerTransaction(typenames, interface, *method, options, b);
+ success = HandleServerTransaction(types, interface, *method, options, b);
} else {
- success = HandleServerMetaTransaction(typenames, interface, *method, options, b);
+ success = HandleServerMetaTransaction(types, interface, *method, options, b);
}
if (!success) {
return nullptr;
@@ -692,7 +697,6 @@
on_transact->GetStatementBlock()->AddLiteral(
StringPrintf("return %s", kAndroidStatusVarName));
vector<unique_ptr<Declaration>> decls;
- decls.push_back(std::move(constructor));
decls.push_back(std::move(on_transact));
if (options.Version() > 0) {
@@ -716,7 +720,7 @@
new CppSource{include_list, NestInNamespaces(std::move(decls), interface.GetSplitPackage())}};
}
-unique_ptr<Document> BuildInterfaceSource(const AidlTypenames& typenames,
+unique_ptr<Document> BuildInterfaceSource(const TypeNamespace& types,
const AidlInterface& interface, const Options& options) {
vector<string> include_list{
HeaderFile(interface, ClassNames::RAW, false),
@@ -740,7 +744,8 @@
const AidlConstantValue& value = constant->GetValue();
if (value.GetType() != AidlConstantValue::Type::STRING) continue;
- std::string cppType = CppNameOf(constant->GetType(), typenames);
+ std::string cppType = constant->GetType().GetLanguageType<Type>()->CppType();
+
unique_ptr<MethodImpl> getter(new MethodImpl("const " + cppType + "&",
ClassName(interface, ClassNames::INTERFACE),
constant->GetName(), {}));
@@ -769,7 +774,7 @@
if (method->IsUserDefined()) {
std::ostringstream code;
code << "::android::binder::Status " << default_impl << "::" << method->GetName()
- << BuildArgList(typenames, *method, true, true).ToString() << " {\n"
+ << BuildArgList(types, *method, true, true).ToString() << " {\n"
<< " return ::android::binder::Status::fromStatusT(::android::UNKNOWN_TRANSACTION);\n"
<< "}\n";
decls.emplace_back(new LiteralDecl(code.str()));
@@ -789,8 +794,8 @@
NestInNamespaces(std::move(decls), interface.GetSplitPackage())}};
}
-unique_ptr<Document> BuildClientHeader(const AidlTypenames& typenames,
- const AidlInterface& interface, const Options& options) {
+unique_ptr<Document> BuildClientHeader(const TypeNamespace& types, const AidlInterface& interface,
+ const Options& options) {
const string i_name = ClassName(interface, ClassNames::INTERFACE);
const string bp_name = ClassName(interface, ClassNames::CLIENT);
@@ -814,9 +819,9 @@
for (const auto& method: interface.GetMethods()) {
if (method->IsUserDefined()) {
- publics.push_back(BuildMethodDecl(*method, typenames, false));
+ publics.push_back(BuildMethodDecl(*method, types, false));
} else {
- publics.push_back(BuildMetaMethodDecl(*method, typenames, options, false));
+ publics.push_back(BuildMetaMethodDecl(*method, types, options, false));
}
}
@@ -846,14 +851,11 @@
NestInNamespaces(std::move(bp_class), interface.GetSplitPackage())}};
}
-unique_ptr<Document> BuildServerHeader(const AidlTypenames& /* typenames */,
+unique_ptr<Document> BuildServerHeader(const TypeNamespace& /* types */,
const AidlInterface& interface, const Options& options) {
const string i_name = ClassName(interface, ClassNames::INTERFACE);
const string bn_name = ClassName(interface, ClassNames::SERVER);
- unique_ptr<ConstructorDecl> constructor{
- new ConstructorDecl{bn_name, ArgList{}, ConstructorDecl::IS_EXPLICIT}};
-
unique_ptr<Declaration> on_transact{new MethodDecl{
kAndroidStatusLiteral, "onTransact",
ArgList{{StringPrintf("uint32_t %s", kCodeVarName),
@@ -866,7 +868,6 @@
vector<string> includes = {"binder/IInterface.h", HeaderFile(interface, ClassNames::RAW, false)};
vector<unique_ptr<Declaration>> publics;
- publics.push_back(std::move(constructor));
publics.push_back(std::move(on_transact));
if (options.Version() > 0) {
@@ -894,16 +895,20 @@
NestInNamespaces(std::move(bn_class), interface.GetSplitPackage())}};
}
-unique_ptr<Document> BuildInterfaceHeader(const AidlTypenames& typenames,
+unique_ptr<Document> BuildInterfaceHeader(const TypeNamespace& types,
const AidlInterface& interface, const Options& options) {
set<string> includes = {kIBinderHeader, kIInterfaceHeader, kStatusHeader, kStrongPointerHeader};
for (const auto& method : interface.GetMethods()) {
for (const auto& argument : method->GetArguments()) {
- AddHeaders(argument->GetType(), typenames, includes);
+ const Type* type = argument->GetType().GetLanguageType<Type>();
+ type->GetHeaders(&includes);
}
- AddHeaders(method->GetType(), typenames, includes);
+ const Type* return_type = method->GetType().GetLanguageType<Type>();
+ if (return_type != nullptr) {
+ return_type->GetHeaders(&includes);
+ }
}
const string i_name = ClassName(interface, ClassNames::INTERFACE);
@@ -920,21 +925,20 @@
}
std::vector<std::unique_ptr<Declaration>> string_constants;
- unique_ptr<Enum> int_constant_enum{new Enum{"", "int32_t", false}};
+ unique_ptr<Enum> int_constant_enum{new Enum{"", "int32_t"}};
for (const auto& constant : interface.GetConstantDeclarations()) {
const AidlConstantValue& value = constant->GetValue();
switch (value.GetType()) {
case AidlConstantValue::Type::STRING: {
- std::string cppType = CppNameOf(constant->GetType(), typenames);
+ std::string cppType = constant->GetType().GetLanguageType<Type>()->CppType();
unique_ptr<Declaration> getter(new MethodDecl("const " + cppType + "&", constant->GetName(),
{}, MethodDecl::IS_STATIC));
string_constants.push_back(std::move(getter));
break;
}
- case AidlConstantValue::Type::BOOLEAN: // fall-through
- case AidlConstantValue::Type::INT8: // fall-through
- case AidlConstantValue::Type::INT32: {
+ case AidlConstantValue::Type::INTEGRAL:
+ case AidlConstantValue::Type::HEXIDECIMAL: {
int_constant_enum->AddValue(constant->GetName(),
constant->ValueString(ConstantValueDecorator));
break;
@@ -963,9 +967,9 @@
for (const auto& method : interface.GetMethods()) {
if (method->IsUserDefined()) {
// Each method gets an enum entry and pure virtual declaration.
- if_class->AddPublic(BuildMethodDecl(*method, typenames, true));
+ if_class->AddPublic(BuildMethodDecl(*method, types, true));
} else {
- if_class->AddPublic(BuildMetaMethodDecl(*method, typenames, options, true));
+ if_class->AddPublic(BuildMetaMethodDecl(*method, types, options, true));
}
}
}
@@ -977,10 +981,9 @@
vector<string> method_decls;
for (const auto& method : interface.GetMethods()) {
if (method->IsUserDefined()) {
- method_decls.emplace_back(BuildMethodDecl(*method, typenames, false)->ToString());
+ method_decls.emplace_back(BuildMethodDecl(*method, types, false)->ToString());
} else {
- method_decls.emplace_back(
- BuildMetaMethodDecl(*method, typenames, options, false)->ToString());
+ method_decls.emplace_back(BuildMetaMethodDecl(*method, types, options, false)->ToString());
}
}
@@ -999,45 +1002,25 @@
NestInNamespaces(std::move(decls), interface.GetSplitPackage())}};
}
-std::unique_ptr<Document> BuildParcelHeader(const AidlTypenames& typenames,
+std::unique_ptr<Document> BuildParcelHeader(const TypeNamespace& /*types*/,
const AidlStructuredParcelable& parcel,
const Options&) {
unique_ptr<ClassDecl> parcel_class{new ClassDecl{parcel.GetName(), "::android::Parcelable"}};
set<string> includes = {kStatusHeader, kParcelHeader};
- includes.insert("tuple");
for (const auto& variable : parcel.GetFields()) {
- AddHeaders(variable->GetType(), typenames, includes);
+ const Type* type = variable->GetType().GetLanguageType<Type>();
+ type->GetHeaders(&includes);
}
- set<string> operators = {"<", ">", "==", ">=", "<=", "!="};
- for (const auto& op : operators) {
- std::ostringstream operator_code;
- std::vector<std::string> variable_name;
- std::vector<std::string> rhs_variable_name;
- for (const auto& variable : parcel.GetFields()) {
- variable_name.push_back(variable->GetName());
- rhs_variable_name.push_back("rhs." + variable->GetName());
- }
-
- operator_code << "inline bool operator" << op << "(const " << parcel.GetName()
- << "& rhs) const {\n"
- << " return "
- << "std::tie(" << Join(variable_name, ", ") << ")" << op << "std::tie("
- << Join(rhs_variable_name, ", ") << ")"
- << ";\n"
- << "}\n";
-
- parcel_class->AddPublic(std::unique_ptr<LiteralDecl>(new LiteralDecl(operator_code.str())));
- }
for (const auto& variable : parcel.GetFields()) {
+ const Type* type = variable->GetType().GetLanguageType<Type>();
std::ostringstream out;
- std::string cppType = CppNameOf(variable->GetType(), typenames);
- out << cppType.c_str() << " " << variable->GetName().c_str();
+ out << type->CppType().c_str() << " " << variable->GetName().c_str();
if (variable->GetDefaultValue()) {
- out << " = " << cppType.c_str() << "(" << variable->ValueString(ConstantValueDecorator)
- << ")";
+ out << " = " << type->CppType().c_str() << "("
+ << variable->ValueString(ConstantValueDecorator) << ")";
}
out << ";\n";
@@ -1057,7 +1040,7 @@
BuildHeaderGuard(parcel, ClassNames::BASE), vector<string>(includes.begin(), includes.end()),
NestInNamespaces(std::move(parcel_class), parcel.GetSplitPackage())}};
}
-std::unique_ptr<Document> BuildParcelSource(const AidlTypenames& typenames,
+std::unique_ptr<Document> BuildParcelSource(const TypeNamespace& /*types*/,
const AidlStructuredParcelable& parcel,
const Options&) {
unique_ptr<MethodImpl> read{new MethodImpl{kAndroidStatusLiteral, parcel.GetName(),
@@ -1074,12 +1057,11 @@
"size_t _aidl_parcelable_size = static_cast<size_t>(_aidl_parcelable_raw_size);\n");
for (const auto& variable : parcel.GetFields()) {
- string method = ParcelReadMethodOf(variable->GetType(), typenames);
+ string method = variable->GetType().GetLanguageType<Type>()->ReadFromParcelMethod();
read_block->AddStatement(new Assignment(
kAndroidStatusVarName, new MethodCall(StringPrintf("_aidl_parcel->%s", method.c_str()),
- ParcelReadCastOf(variable->GetType(), typenames,
- "&" + variable->GetName()))));
+ ArgList("&" + variable->GetName()))));
read_block->AddStatement(ReturnOnStatusNotOk());
read_block->AddLiteral(StringPrintf(
"if (_aidl_parcel->dataPosition() - _aidl_start_pos >= _aidl_parcelable_size) {\n"
@@ -1102,11 +1084,11 @@
"_aidl_parcel->writeInt32(0);");
for (const auto& variable : parcel.GetFields()) {
- string method = ParcelWriteMethodOf(variable->GetType(), typenames);
+ string method = variable->GetType().GetLanguageType<Type>()->WriteToParcelMethod();
+
write_block->AddStatement(new Assignment(
- kAndroidStatusVarName,
- new MethodCall(StringPrintf("_aidl_parcel->%s", method.c_str()),
- ParcelWriteCastOf(variable->GetType(), typenames, variable->GetName()))));
+ kAndroidStatusVarName, new MethodCall(StringPrintf("_aidl_parcel->%s", method.c_str()),
+ ArgList(variable->GetName()))));
write_block->AddStatement(ReturnOnStatusNotOk());
}
@@ -1122,46 +1104,26 @@
file_decls.push_back(std::move(write));
set<string> includes = {};
- AddHeaders(parcel, includes);
+ parcel.GetLanguageType<Type>()->GetHeaders(&includes);
return unique_ptr<Document>{
new CppSource{vector<string>(includes.begin(), includes.end()),
NestInNamespaces(std::move(file_decls), parcel.GetSplitPackage())}};
}
-std::unique_ptr<Document> BuildEnumHeader(const AidlTypenames& typenames,
- const AidlEnumDeclaration& enum_decl) {
- unique_ptr<Enum> generated_enum{
- new Enum{enum_decl.GetName(), CppNameOf(enum_decl.GetBackingType(), typenames), true}};
- for (const auto& enumerator : enum_decl.GetEnumerators()) {
- generated_enum->AddValue(
- enumerator->GetName(),
- enumerator->ValueString(enum_decl.GetBackingType(), ConstantValueDecorator));
- }
-
- set<string> includes = {};
- AddHeaders(enum_decl.GetBackingType(), typenames, includes);
-
- return unique_ptr<Document>{
- new CppHeader{BuildHeaderGuard(enum_decl, ClassNames::BASE),
- vector<string>(includes.begin(), includes.end()),
- NestInNamespaces(std::move(generated_enum), enum_decl.GetSplitPackage())}};
-}
-
-bool WriteHeader(const Options& options, const AidlTypenames& typenames,
- const AidlInterface& interface, const IoDelegate& io_delegate,
- ClassNames header_type) {
+bool WriteHeader(const Options& options, const TypeNamespace& types, const AidlInterface& interface,
+ const IoDelegate& io_delegate, ClassNames header_type) {
unique_ptr<Document> header;
switch (header_type) {
case ClassNames::INTERFACE:
- header = BuildInterfaceHeader(typenames, interface, options);
+ header = BuildInterfaceHeader(types, interface, options);
header_type = ClassNames::RAW;
break;
case ClassNames::CLIENT:
- header = BuildClientHeader(typenames, interface, options);
+ header = BuildClientHeader(types, interface, options);
break;
case ClassNames::SERVER:
- header = BuildServerHeader(typenames, interface, options);
+ header = BuildServerHeader(types, interface, options);
break;
default:
LOG(FATAL) << "aidl internal error";
@@ -1188,19 +1150,22 @@
using namespace internals;
bool GenerateCppInterface(const string& output_file, const Options& options,
- const AidlTypenames& typenames, const AidlInterface& interface,
+ const TypeNamespace& types, const AidlInterface& interface,
const IoDelegate& io_delegate) {
- auto interface_src = BuildInterfaceSource(typenames, interface, options);
- auto client_src = BuildClientSource(typenames, interface, options);
- auto server_src = BuildServerSource(typenames, interface, options);
+ auto interface_src = BuildInterfaceSource(types, interface, options);
+ auto client_src = BuildClientSource(types, interface, options);
+ auto server_src = BuildServerSource(types, interface, options);
if (!interface_src || !client_src || !server_src) {
return false;
}
- if (!WriteHeader(options, typenames, interface, io_delegate, ClassNames::INTERFACE) ||
- !WriteHeader(options, typenames, interface, io_delegate, ClassNames::CLIENT) ||
- !WriteHeader(options, typenames, interface, io_delegate, ClassNames::SERVER)) {
+ if (!WriteHeader(options, types, interface, io_delegate,
+ ClassNames::INTERFACE) ||
+ !WriteHeader(options, types, interface, io_delegate,
+ ClassNames::CLIENT) ||
+ !WriteHeader(options, types, interface, io_delegate,
+ ClassNames::SERVER)) {
return false;
}
@@ -1218,10 +1183,10 @@
}
bool GenerateCppParcel(const string& output_file, const Options& options,
- const AidlTypenames& typenames, const AidlStructuredParcelable& parcelable,
+ const cpp::TypeNamespace& types, const AidlStructuredParcelable& parcelable,
const IoDelegate& io_delegate) {
- auto header = BuildParcelHeader(typenames, parcelable, options);
- auto source = BuildParcelSource(typenames, parcelable, options);
+ auto header = BuildParcelHeader(types, parcelable, options);
+ auto source = BuildParcelSource(types, parcelable, options);
if (!header || !source) {
return false;
@@ -1249,79 +1214,29 @@
return true;
}
-bool GenerateCppParcelDeclaration(const std::string& filename, const Options& options,
- const AidlParcelable& parcelable, const IoDelegate& io_delegate) {
- CodeWriterPtr source_writer = io_delegate.GetCodeWriter(filename);
- *source_writer
+bool GenerateCppParcelDeclaration(const std::string& filename, const IoDelegate& io_delegate) {
+ CodeWriterPtr code_writer = io_delegate.GetCodeWriter(filename);
+ *code_writer
<< "// This file is intentionally left blank as placeholder for parcel declaration.\n";
- CHECK(source_writer->Close());
-
- // TODO(b/111362593): no unecessary files just to have consistent output with interfaces
- const string header_path = options.OutputHeaderDir() + HeaderFile(parcelable, ClassNames::RAW);
- unique_ptr<CodeWriter> header_writer(io_delegate.GetCodeWriter(header_path));
- header_writer->Write("#error TODO(b/111362593) parcelables do not have headers");
- CHECK(header_writer->Close());
- const string bp_header = options.OutputHeaderDir() + HeaderFile(parcelable, ClassNames::CLIENT);
- unique_ptr<CodeWriter> bp_writer(io_delegate.GetCodeWriter(bp_header));
- bp_writer->Write("#error TODO(b/111362593) parcelables do not have bp classes");
- CHECK(bp_writer->Close());
- const string bn_header = options.OutputHeaderDir() + HeaderFile(parcelable, ClassNames::SERVER);
- unique_ptr<CodeWriter> bn_writer(io_delegate.GetCodeWriter(bn_header));
- bn_writer->Write("#error TODO(b/111362593) parcelables do not have bn classes");
- CHECK(bn_writer->Close());
return true;
}
-bool GenerateCppEnumDeclaration(const std::string& filename, const Options& options,
- const AidlTypenames& typenames,
- const AidlEnumDeclaration& enum_decl,
- const IoDelegate& io_delegate) {
- auto header = BuildEnumHeader(typenames, enum_decl);
- if (!header) return false;
-
- const string header_path = options.OutputHeaderDir() + HeaderFile(enum_decl, ClassNames::RAW);
- unique_ptr<CodeWriter> header_writer(io_delegate.GetCodeWriter(header_path));
- header->Write(header_writer.get());
- CHECK(header_writer->Close());
-
- // TODO(b/111362593): no unnecessary files just to have consistent output with interfaces
- CodeWriterPtr source_writer = io_delegate.GetCodeWriter(filename);
- *source_writer
- << "// This file is intentionally left blank as placeholder for enum declaration.\n";
- CHECK(source_writer->Close());
- const string bp_header = options.OutputHeaderDir() + HeaderFile(enum_decl, ClassNames::CLIENT);
- unique_ptr<CodeWriter> bp_writer(io_delegate.GetCodeWriter(bp_header));
- bp_writer->Write("#error TODO(b/111362593) enums do not have bp classes");
- CHECK(bp_writer->Close());
- const string bn_header = options.OutputHeaderDir() + HeaderFile(enum_decl, ClassNames::SERVER);
- unique_ptr<CodeWriter> bn_writer(io_delegate.GetCodeWriter(bn_header));
- bn_writer->Write("#error TODO(b/111362593) enums do not have bn classes");
- CHECK(bn_writer->Close());
-
- return true;
-}
-
-bool GenerateCpp(const string& output_file, const Options& options, const AidlTypenames& typenames,
+bool GenerateCpp(const string& output_file, const Options& options, const TypeNamespace& types,
const AidlDefinedType& defined_type, const IoDelegate& io_delegate) {
const AidlStructuredParcelable* parcelable = defined_type.AsStructuredParcelable();
if (parcelable != nullptr) {
- return GenerateCppParcel(output_file, options, typenames, *parcelable, io_delegate);
+ return GenerateCppParcel(output_file, options, types, *parcelable, io_delegate);
}
const AidlParcelable* parcelable_decl = defined_type.AsParcelable();
if (parcelable_decl != nullptr) {
- return GenerateCppParcelDeclaration(output_file, options, *parcelable_decl, io_delegate);
- }
-
- const AidlEnumDeclaration* enum_decl = defined_type.AsEnumDeclaration();
- if (enum_decl != nullptr) {
- return GenerateCppEnumDeclaration(output_file, options, typenames, *enum_decl, io_delegate);
+ return GenerateCppParcelDeclaration(output_file, io_delegate);
}
const AidlInterface* interface = defined_type.AsInterface();
if (interface != nullptr) {
- return GenerateCppInterface(output_file, options, typenames, *interface, io_delegate);
+ return GenerateCppInterface(output_file, options, types, *interface, io_delegate);
}
CHECK(false) << "Unrecognized type sent for cpp generation.";
diff --git a/generate_cpp.h b/generate_cpp.h
index 3fd7caf..9b34b96 100644
--- a/generate_cpp.h
+++ b/generate_cpp.h
@@ -24,43 +24,41 @@
#include "aidl_to_cpp_common.h"
#include "ast_cpp.h"
#include "options.h"
+#include "type_cpp.h"
namespace android {
namespace aidl {
namespace cpp {
-bool GenerateCpp(const string& output_file, const Options& options, const AidlTypenames& typenames,
+bool GenerateCpp(const string& output_file, const Options& options, const cpp::TypeNamespace& types,
const AidlDefinedType& parsed_doc, const IoDelegate& io_delegate);
namespace internals {
-std::unique_ptr<Document> BuildClientSource(const AidlTypenames& typenames,
+std::unique_ptr<Document> BuildClientSource(const TypeNamespace& types,
const AidlInterface& parsed_doc,
const Options& options);
-std::unique_ptr<Document> BuildServerSource(const AidlTypenames& typenames,
+std::unique_ptr<Document> BuildServerSource(const TypeNamespace& types,
const AidlInterface& parsed_doc,
const Options& options);
-std::unique_ptr<Document> BuildInterfaceSource(const AidlTypenames& typenames,
+std::unique_ptr<Document> BuildInterfaceSource(const TypeNamespace& types,
const AidlInterface& parsed_doc,
const Options& options);
-std::unique_ptr<Document> BuildClientHeader(const AidlTypenames& typenames,
+std::unique_ptr<Document> BuildClientHeader(const TypeNamespace& types,
const AidlInterface& parsed_doc,
const Options& options);
-std::unique_ptr<Document> BuildServerHeader(const AidlTypenames& typenames,
+std::unique_ptr<Document> BuildServerHeader(const TypeNamespace& types,
const AidlInterface& parsed_doc,
const Options& options);
-std::unique_ptr<Document> BuildInterfaceHeader(const AidlTypenames& typenames,
+std::unique_ptr<Document> BuildInterfaceHeader(const TypeNamespace& types,
const AidlInterface& parsed_doc,
const Options& options);
-std::unique_ptr<Document> BuildParcelHeader(const AidlTypenames& typenames,
+std::unique_ptr<Document> BuildParcelHeader(const TypeNamespace& types,
const AidlStructuredParcelable& parsed_doc,
const Options& options);
-std::unique_ptr<Document> BuildParcelSource(const AidlTypenames& typenames,
+std::unique_ptr<Document> BuildParcelSource(const TypeNamespace& types,
const AidlStructuredParcelable& parsed_doc,
const Options& options);
-
-std::unique_ptr<Document> BuildEnumHeader(const AidlTypenames& typenames,
- const AidlEnumDeclaration& parsed_doc);
}
} // namespace cpp
} // namespace aidl
diff --git a/generate_cpp_unittest.cpp b/generate_cpp_unittest.cpp
index fd6c9f0..a9ba8cd 100644
--- a/generate_cpp_unittest.cpp
+++ b/generate_cpp_unittest.cpp
@@ -27,6 +27,7 @@
#include "os.h"
#include "tests/fake_io_delegate.h"
#include "tests/test_util.h"
+#include "type_cpp.h"
using ::android::aidl::test::FakeIoDelegate;
using ::android::base::StringPrintf;
@@ -726,7 +727,7 @@
)";
const char kExpectedComplexTypeServerHeaderOutput[] =
- R"(#ifndef AIDL_GENERATED_ANDROID_OS_BN_COMPLEX_TYPE_INTERFACE_H_
+R"(#ifndef AIDL_GENERATED_ANDROID_OS_BN_COMPLEX_TYPE_INTERFACE_H_
#define AIDL_GENERATED_ANDROID_OS_BN_COMPLEX_TYPE_INTERFACE_H_
#include <binder/IInterface.h>
@@ -738,7 +739,6 @@
class BnComplexTypeInterface : public ::android::BnInterface<IComplexTypeInterface> {
public:
- explicit BnComplexTypeInterface();
::android::status_t onTransact(uint32_t _aidl_code, const ::android::Parcel& _aidl_data, ::android::Parcel* _aidl_reply, uint32_t _aidl_flags) override;
}; // class BnComplexTypeInterface
@@ -752,17 +752,11 @@
const char kExpectedComplexTypeServerSourceOutput[] =
R"(#include <android/os/BnComplexTypeInterface.h>
#include <binder/Parcel.h>
-#include <binder/Stability.h>
namespace android {
namespace os {
-BnComplexTypeInterface::BnComplexTypeInterface()
-{
- ::android::internal::Stability::markCompilationUnit(this);
-}
-
::android::status_t BnComplexTypeInterface::onTransact(uint32_t _aidl_code, const ::android::Parcel& _aidl_data, ::android::Parcel* _aidl_reply, uint32_t _aidl_flags) {
::android::status_t _aidl_ret_status = ::android::OK;
switch (_aidl_code) {
@@ -1005,17 +999,11 @@
const char kExpectedComplexTypeServerWithTraceSourceOutput[] =
R"(#include <android/os/BnComplexTypeInterface.h>
#include <binder/Parcel.h>
-#include <binder/Stability.h>
namespace android {
namespace os {
-BnComplexTypeInterface::BnComplexTypeInterface()
-{
- ::android::internal::Stability::markCompilationUnit(this);
-}
-
::android::status_t BnComplexTypeInterface::onTransact(uint32_t _aidl_code, const ::android::Parcel& _aidl_data, ::android::Parcel* _aidl_reply, uint32_t _aidl_flags) {
::android::status_t _aidl_ret_status = ::android::OK;
switch (_aidl_code) {
@@ -1378,85 +1366,13 @@
} // namespace android
)";
-const string kEnumAIDL = R"(package android.os;
-enum TestEnum {
- ZERO,
- ONE,
- THREE = 3,
- FOUR = 3 + 1,
- FIVE,
- SIX,
- SEVEN,
- EIGHT = 16 / 2,
- NINE,
- TEN,
-})";
-
-const char kExpectedEnumHeaderOutput[] =
- R"(#ifndef AIDL_GENERATED_ANDROID_OS_TEST_ENUM_H_
-#define AIDL_GENERATED_ANDROID_OS_TEST_ENUM_H_
-
-#include <cstdint>
-
-namespace android {
-
-namespace os {
-
-enum class TestEnum : int8_t {
- ZERO = 0,
- ONE = 1,
- THREE = 3,
- FOUR = 4,
- FIVE = 5,
- SIX = 6,
- SEVEN = 7,
- EIGHT = 8,
- NINE = 9,
- TEN = 10,
-};
-
-} // namespace os
-
-} // namespace android
-
-#endif // AIDL_GENERATED_ANDROID_OS_TEST_ENUM_H_
-)";
-
-const string kEnumWithBackingTypeAIDL = R"(package android.os;
-@Backing(type="long")
-enum TestEnum {
- FOO = 1,
- BAR = 2,
-})";
-
-const char kExpectedEnumWithBackingTypeHeaderOutput[] =
- R"(#ifndef AIDL_GENERATED_ANDROID_OS_TEST_ENUM_H_
-#define AIDL_GENERATED_ANDROID_OS_TEST_ENUM_H_
-
-#include <cstdint>
-
-namespace android {
-
-namespace os {
-
-enum class TestEnum : int64_t {
- FOO = 1L,
- BAR = 2L,
-};
-
-} // namespace os
-
-} // namespace android
-
-#endif // AIDL_GENERATED_ANDROID_OS_TEST_ENUM_H_
-)";
-
} // namespace
class ASTTest : public ::testing::Test {
protected:
ASTTest(const string& cmdline, const string& file_contents)
: options_(Options::From(cmdline)), file_contents_(file_contents) {
+ types_.Init();
}
AidlInterface* ParseSingleInterface() {
@@ -1466,7 +1382,7 @@
vector<string> imported_files;
ImportResolver import_resolver{io_delegate_, options_.InputFiles().at(0), {"."}, {}};
AidlError err = ::android::aidl::internals::load_and_validate_aidl(
- options_.InputFiles().front(), options_, io_delegate_, &typenames_, &defined_types,
+ options_.InputFiles().front(), options_, io_delegate_, &types_, &defined_types,
&imported_files);
if (err != AidlError::OK) {
@@ -1479,25 +1395,6 @@
return defined_types.front()->AsInterface();
}
- AidlEnumDeclaration* ParseSingleEnumDeclaration() {
- io_delegate_.SetFileContents(options_.InputFiles().at(0), file_contents_);
-
- vector<AidlDefinedType*> defined_types;
- vector<string> imported_files;
- AidlError err = ::android::aidl::internals::load_and_validate_aidl(
- options_.InputFiles().front(), options_, io_delegate_, &typenames_, &defined_types,
- &imported_files);
-
- if (err != AidlError::OK) {
- return nullptr;
- }
-
- EXPECT_EQ(1ul, defined_types.size());
- EXPECT_NE(nullptr, defined_types.front()->AsEnumDeclaration());
-
- return defined_types.front()->AsEnumDeclaration();
- }
-
void Compare(Document* doc, const char* expected) {
string output;
doc->Write(CodeWriter::ForString(&output).get());
@@ -1513,7 +1410,7 @@
const Options options_;
const string file_contents_;
FakeIoDelegate io_delegate_;
- AidlTypenames typenames_;
+ TypeNamespace types_;
};
class ComplexTypeInterfaceASTTest : public ASTTest {
@@ -1529,42 +1426,42 @@
TEST_F(ComplexTypeInterfaceASTTest, GeneratesClientHeader) {
AidlInterface* interface = ParseSingleInterface();
ASSERT_NE(interface, nullptr);
- unique_ptr<Document> doc = internals::BuildClientHeader(typenames_, *interface, options_);
+ unique_ptr<Document> doc = internals::BuildClientHeader(types_, *interface, options_);
Compare(doc.get(), kExpectedComplexTypeClientHeaderOutput);
}
TEST_F(ComplexTypeInterfaceASTTest, GeneratesClientSource) {
AidlInterface* interface = ParseSingleInterface();
ASSERT_NE(interface, nullptr);
- unique_ptr<Document> doc = internals::BuildClientSource(typenames_, *interface, options_);
+ unique_ptr<Document> doc = internals::BuildClientSource(types_, *interface, options_);
Compare(doc.get(), kExpectedComplexTypeClientSourceOutput);
}
TEST_F(ComplexTypeInterfaceASTTest, GeneratesServerHeader) {
AidlInterface* interface = ParseSingleInterface();
ASSERT_NE(interface, nullptr);
- unique_ptr<Document> doc = internals::BuildServerHeader(typenames_, *interface, options_);
+ unique_ptr<Document> doc = internals::BuildServerHeader(types_, *interface, options_);
Compare(doc.get(), kExpectedComplexTypeServerHeaderOutput);
}
TEST_F(ComplexTypeInterfaceASTTest, GeneratesServerSource) {
AidlInterface* interface = ParseSingleInterface();
ASSERT_NE(interface, nullptr);
- unique_ptr<Document> doc = internals::BuildServerSource(typenames_, *interface, options_);
+ unique_ptr<Document> doc = internals::BuildServerSource(types_, *interface, options_);
Compare(doc.get(), kExpectedComplexTypeServerSourceOutput);
}
TEST_F(ComplexTypeInterfaceASTTest, GeneratesInterfaceHeader) {
AidlInterface* interface = ParseSingleInterface();
ASSERT_NE(interface, nullptr);
- unique_ptr<Document> doc = internals::BuildInterfaceHeader(typenames_, *interface, options_);
+ unique_ptr<Document> doc = internals::BuildInterfaceHeader(types_, *interface, options_);
Compare(doc.get(), kExpectedComplexTypeInterfaceHeaderOutput);
}
TEST_F(ComplexTypeInterfaceASTTest, GeneratesInterfaceSource) {
AidlInterface* interface = ParseSingleInterface();
ASSERT_NE(interface, nullptr);
- unique_ptr<Document> doc = internals::BuildInterfaceSource(typenames_, *interface, options_);
+ unique_ptr<Document> doc = internals::BuildInterfaceSource(types_, *interface, options_);
Compare(doc.get(), kExpectedComplexTypeInterfaceSourceOutput);
}
@@ -1580,14 +1477,14 @@
TEST_F(ComplexTypeInterfaceASTTestWithTrace, GeneratesClientSource) {
AidlInterface* interface = ParseSingleInterface();
ASSERT_NE(interface, nullptr);
- unique_ptr<Document> doc = internals::BuildClientSource(typenames_, *interface, options_);
+ unique_ptr<Document> doc = internals::BuildClientSource(types_, *interface, options_);
Compare(doc.get(), kExpectedComplexTypeClientWithTraceSourceOutput);
}
TEST_F(ComplexTypeInterfaceASTTestWithTrace, GeneratesServerSource) {
AidlInterface* interface = ParseSingleInterface();
ASSERT_NE(interface, nullptr);
- unique_ptr<Document> doc = internals::BuildServerSource(typenames_, *interface, options_);
+ unique_ptr<Document> doc = internals::BuildServerSource(types_, *interface, options_);
Compare(doc.get(), kExpectedComplexTypeServerWithTraceSourceOutput);
}
@@ -1611,7 +1508,7 @@
// Confirm that this is working correctly without I/O problems.
AidlInterface* interface = ParseSingleInterface();
ASSERT_NE(interface, nullptr);
- ASSERT_TRUE(GenerateCpp(options_.OutputFile(), options_, typenames_, *interface, io_delegate_));
+ ASSERT_TRUE(GenerateCpp(options_.OutputFile(), options_, types_, *interface, io_delegate_));
}
TEST_F(IoErrorHandlingTest, HandlesBadHeaderWrite) {
@@ -1624,7 +1521,7 @@
StringPrintf("%s%c%s", kHeaderDir, OS_PATH_SEPARATOR,
kInterfaceHeaderRelPath);
io_delegate_.AddBrokenFilePath(header_path);
- ASSERT_FALSE(GenerateCpp(options_.OutputFile(), options_, typenames_, *interface, io_delegate_));
+ ASSERT_FALSE(GenerateCpp(options_.OutputFile(), options_, types_, *interface, io_delegate_));
// We should never attempt to write the C++ file if we fail writing headers.
ASSERT_FALSE(io_delegate_.GetWrittenContents(kOutputPath, nullptr));
// We should remove partial results.
@@ -1638,36 +1535,11 @@
// Simulate issues closing the cpp file.
io_delegate_.AddBrokenFilePath(kOutputPath);
- ASSERT_FALSE(GenerateCpp(options_.OutputFile(), options_, typenames_, *interface, io_delegate_));
+ ASSERT_FALSE(GenerateCpp(options_.OutputFile(), options_, types_, *interface, io_delegate_));
// We should remove partial results.
ASSERT_TRUE(io_delegate_.PathWasRemoved(kOutputPath));
}
-class EnumASTTest : public ASTTest {
- public:
- EnumASTTest() : ASTTest("aidl --lang=cpp -I . -o out android/os/TestEnum.aidl", kEnumAIDL) {}
-};
-
-TEST_F(EnumASTTest, GeneratesEnumHeader) {
- AidlEnumDeclaration* enum_decl = ParseSingleEnumDeclaration();
- ASSERT_NE(enum_decl, nullptr);
- unique_ptr<Document> doc = internals::BuildEnumHeader(typenames_, *enum_decl);
- Compare(doc.get(), kExpectedEnumHeaderOutput);
-}
-
-class EnumWithBackingTypeASTTest : public ASTTest {
- public:
- EnumWithBackingTypeASTTest()
- : ASTTest("aidl --lang=cpp -I . -o out android/os/TestEnum.aidl", kEnumWithBackingTypeAIDL) {}
-};
-
-TEST_F(EnumWithBackingTypeASTTest, GeneratesEnumHeader) {
- AidlEnumDeclaration* enum_decl = ParseSingleEnumDeclaration();
- ASSERT_NE(enum_decl, nullptr);
- unique_ptr<Document> doc = internals::BuildEnumHeader(typenames_, *enum_decl);
- Compare(doc.get(), kExpectedEnumWithBackingTypeHeaderOutput);
-}
-
} // namespace cpp
} // namespace aidl
} // namespace android
diff --git a/generate_java.cpp b/generate_java.cpp
index 966ed58..0d96203 100644
--- a/generate_java.cpp
+++ b/generate_java.cpp
@@ -19,7 +19,6 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#include <map>
#include <memory>
#include <sstream>
@@ -27,7 +26,7 @@
#include "aidl_to_java.h"
#include "code_writer.h"
-#include "logging.h"
+#include "type_java.h"
using std::unique_ptr;
using ::android::aidl::java::Variable;
@@ -38,12 +37,12 @@
namespace java {
bool generate_java_interface(const string& filename, const AidlInterface* iface,
- const AidlTypenames& typenames, const IoDelegate& io_delegate,
+ JavaTypeNamespace* types, const IoDelegate& io_delegate,
const Options& options) {
- auto cl = generate_binder_interface_class(iface, typenames, options);
+ Class* cl = generate_binder_interface_class(iface, types, options);
- std::unique_ptr<Document> document =
- std::make_unique<Document>("" /* no comment */, iface->GetPackage(), std::move(cl));
+ Document* document =
+ new Document("" /* no comment */, iface->GetPackage(), unique_ptr<Class>(cl));
CodeWriterPtr code_writer = io_delegate.GetCodeWriter(filename);
document->Write(code_writer.get());
@@ -52,11 +51,11 @@
}
bool generate_java_parcel(const std::string& filename, const AidlStructuredParcelable* parcel,
- const AidlTypenames& typenames, const IoDelegate& io_delegate) {
- auto cl = generate_parcel_class(parcel, typenames);
+ AidlTypenames& typenames, const IoDelegate& io_delegate) {
+ Class* cl = generate_parcel_class(parcel, typenames);
- std::unique_ptr<Document> document =
- std::make_unique<Document>("" /* no comment */, parcel->GetPackage(), std::move(cl));
+ Document* document =
+ new Document("" /* no comment */, parcel->GetPackage(), unique_ptr<Class>(cl));
CodeWriterPtr code_writer = io_delegate.GetCodeWriter(filename);
document->Write(code_writer.get());
@@ -64,38 +63,26 @@
return true;
}
-bool generate_java_enum_declaration(const std::string& filename,
- const AidlEnumDeclaration* enum_decl,
- const AidlTypenames& typenames, const IoDelegate& io_delegate) {
- CodeWriterPtr code_writer = io_delegate.GetCodeWriter(filename);
- generate_enum(code_writer, enum_decl, typenames);
- return true;
-}
-
bool generate_java(const std::string& filename, const AidlDefinedType* defined_type,
- const AidlTypenames& typenames, const IoDelegate& io_delegate,
+ JavaTypeNamespace* types, const IoDelegate& io_delegate,
const Options& options) {
- if (const AidlStructuredParcelable* parcelable = defined_type->AsStructuredParcelable();
- parcelable != nullptr) {
- return generate_java_parcel(filename, parcelable, typenames, io_delegate);
+ const AidlStructuredParcelable* parcelable = defined_type->AsStructuredParcelable();
+ if (parcelable != nullptr) {
+ return generate_java_parcel(filename, parcelable, types->typenames_, io_delegate);
}
- if (const AidlEnumDeclaration* enum_decl = defined_type->AsEnumDeclaration();
- enum_decl != nullptr) {
- return generate_java_enum_declaration(filename, enum_decl, typenames, io_delegate);
+ const AidlInterface* interface = defined_type->AsInterface();
+ if (interface != nullptr) {
+ return generate_java_interface(filename, interface, types, io_delegate, options);
}
- if (const AidlInterface* interface = defined_type->AsInterface(); interface != nullptr) {
- return generate_java_interface(filename, interface, typenames, io_delegate, options);
- }
-
- CHECK(false) << "Unrecognized type sent for java generation.";
+ CHECK(false) << "Unrecognized type sent for cpp generation.";
return false;
}
-std::unique_ptr<android::aidl::java::Class> generate_parcel_class(
- const AidlStructuredParcelable* parcel, const AidlTypenames& typenames) {
- auto parcel_class = std::make_unique<Class>();
+android::aidl::java::Class* generate_parcel_class(const AidlStructuredParcelable* parcel,
+ AidlTypenames& typenames) {
+ Class* parcel_class = new Class;
parcel_class->comment = parcel->GetComments();
parcel_class->modifiers = PUBLIC;
parcel_class->what = Class::CLASS;
@@ -104,18 +91,20 @@
parcel_class->annotations = generate_java_annotations(*parcel);
for (const auto& variable : parcel->GetFields()) {
+ const Type* type = variable->GetType().GetLanguageType<Type>();
+
std::ostringstream out;
out << variable->GetType().GetComments() << "\n";
for (const auto& a : generate_java_annotations(variable->GetType())) {
out << a << "\n";
}
- out << "public " << JavaSignatureOf(variable->GetType(), typenames) << " "
+ out << "public " << type->JavaType() << (variable->GetType().IsArray() ? "[]" : "") << " "
<< variable->GetName();
if (variable->GetDefaultValue()) {
- out << " = " << variable->ValueString(ConstantValueDecorator);
+ out << " = " << variable->ValueString(AidlConstantValueDecorator);
}
out << ";\n";
- parcel_class->elements.push_back(std::make_shared<LiteralClassElement>(out.str()));
+ parcel_class->elements.push_back(new LiteralClassElement(out.str()));
}
std::ostringstream out;
@@ -133,23 +122,23 @@
out << " return new " << parcel->GetName() << "[_aidl_size];\n";
out << " }\n";
out << "};\n";
- parcel_class->elements.push_back(std::make_shared<LiteralClassElement>(out.str()));
+ parcel_class->elements.push_back(new LiteralClassElement(out.str()));
- auto flag_variable = std::make_shared<Variable>("int", "_aidl_flag");
- auto parcel_variable = std::make_shared<Variable>("android.os.Parcel", "_aidl_parcel");
+ Variable* flag_variable = new Variable("int", "_aidl_flag");
+ Variable* parcel_variable = new Variable("android.os.Parcel", "_aidl_parcel");
- auto write_method = std::make_shared<Method>();
+ Method* write_method = new Method;
write_method->modifiers = PUBLIC | OVERRIDE | FINAL;
write_method->returnType = "void";
write_method->name = "writeToParcel";
write_method->parameters.push_back(parcel_variable);
write_method->parameters.push_back(flag_variable);
- write_method->statements = std::make_shared<StatementBlock>();
+ write_method->statements = new StatementBlock();
out.str("");
out << "int _aidl_start_pos = _aidl_parcel.dataPosition();\n"
<< "_aidl_parcel.writeInt(0);\n";
- write_method->statements->Add(std::make_shared<LiteralStatement>(out.str()));
+ write_method->statements->Add(new LiteralStatement(out.str()));
for (const auto& field : parcel->GetFields()) {
string code;
@@ -158,13 +147,13 @@
.writer = *(writer.get()),
.typenames = typenames,
.type = field->GetType(),
- .parcel = parcel_variable->name,
.var = field->GetName(),
+ .parcel = parcel_variable->name,
.is_return_value = false,
};
WriteToParcelFor(context);
writer->Close();
- write_method->statements->Add(std::make_shared<LiteralStatement>(code));
+ write_method->statements->Add(new LiteralStatement(code));
}
out.str("");
@@ -173,16 +162,16 @@
<< "_aidl_parcel.writeInt(_aidl_end_pos - _aidl_start_pos);\n"
<< "_aidl_parcel.setDataPosition(_aidl_end_pos);\n";
- write_method->statements->Add(std::make_shared<LiteralStatement>(out.str()));
+ write_method->statements->Add(new LiteralStatement(out.str()));
parcel_class->elements.push_back(write_method);
- auto read_method = std::make_shared<Method>();
+ Method* read_method = new Method;
read_method->modifiers = PUBLIC | FINAL;
read_method->returnType = "void";
read_method->name = "readFromParcel";
read_method->parameters.push_back(parcel_variable);
- read_method->statements = std::make_shared<StatementBlock>();
+ read_method->statements = new StatementBlock();
out.str("");
out << "int _aidl_start_pos = _aidl_parcel.dataPosition();\n"
@@ -190,12 +179,12 @@
<< "if (_aidl_parcelable_size < 0) return;\n"
<< "try {\n";
- read_method->statements->Add(std::make_shared<LiteralStatement>(out.str()));
+ read_method->statements->Add(new LiteralStatement(out.str()));
out.str("");
out << " if (_aidl_parcel.dataPosition() - _aidl_start_pos >= _aidl_parcelable_size) return;\n";
- std::shared_ptr<LiteralStatement> sizeCheck = nullptr;
+ LiteralStatement* sizeCheck = nullptr;
// keep this across different fields in order to create the classloader
// at most once.
bool is_classloader_created = false;
@@ -206,15 +195,15 @@
.writer = *(writer.get()),
.typenames = typenames,
.type = field->GetType(),
- .parcel = parcel_variable->name,
.var = field->GetName(),
+ .parcel = parcel_variable->name,
.is_classloader_created = &is_classloader_created,
};
context.writer.Indent();
CreateFromParcelFor(context);
writer->Close();
- read_method->statements->Add(std::make_shared<LiteralStatement>(code));
- if (!sizeCheck) sizeCheck = std::make_shared<LiteralStatement>(out.str());
+ read_method->statements->Add(new LiteralStatement(code));
+ if (!sizeCheck) sizeCheck = new LiteralStatement(out.str());
read_method->statements->Add(sizeCheck);
}
@@ -223,67 +212,25 @@
<< " _aidl_parcel.setDataPosition(_aidl_start_pos + _aidl_parcelable_size);\n"
<< "}\n";
- read_method->statements->Add(std::make_shared<LiteralStatement>(out.str()));
+ read_method->statements->Add(new LiteralStatement(out.str()));
parcel_class->elements.push_back(read_method);
- auto describe_contents_method = std::make_shared<Method>();
+ Method* describe_contents_method = new Method;
describe_contents_method->modifiers = PUBLIC | OVERRIDE;
describe_contents_method->returnType = "int";
describe_contents_method->name = "describeContents";
- describe_contents_method->statements = std::make_shared<StatementBlock>();
- describe_contents_method->statements->Add(std::make_shared<LiteralStatement>("return 0;\n"));
+ describe_contents_method->statements = new StatementBlock();
+ describe_contents_method->statements->Add(new LiteralStatement("return 0;\n"));
parcel_class->elements.push_back(describe_contents_method);
return parcel_class;
}
-void generate_enum(const CodeWriterPtr& code_writer, const AidlEnumDeclaration* enum_decl,
- const AidlTypenames& typenames) {
- code_writer->Write(
- "/*\n"
- " * This file is auto-generated. DO NOT MODIFY.\n"
- " */\n");
-
- code_writer->Write("package %s;\n", enum_decl->GetPackage().c_str());
- code_writer->Write("%s\n", enum_decl->GetComments().c_str());
- for (const std::string& annotation : generate_java_annotations(*enum_decl)) {
- code_writer->Write(annotation.c_str());
- }
- code_writer->Write("public @interface %s {\n", enum_decl->GetName().c_str());
- code_writer->Indent();
- for (const auto& enumerator : enum_decl->GetEnumerators()) {
- code_writer->Write(enumerator->GetComments().c_str());
- code_writer->Write(
- "public static final %s %s = %s;\n",
- JavaSignatureOf(enum_decl->GetBackingType(), typenames).c_str(),
- enumerator->GetName().c_str(),
- enumerator->ValueString(enum_decl->GetBackingType(), ConstantValueDecorator).c_str());
- }
- code_writer->Dedent();
- code_writer->Write("}\n");
-}
-
-std::string generate_java_annotation_parameters(const AidlAnnotation& a) {
- const std::map<std::string, std::string> params = a.AnnotationParams(ConstantValueDecorator);
- if (params.empty()) {
- return "";
- }
- std::vector<string> parameters_decl;
- for (const auto& name_and_param : params) {
- const std::string& param_name = name_and_param.first;
- const std::string& param_value = name_and_param.second;
- parameters_decl.push_back(param_name + " = " + param_value);
- }
- return "(" + base::Join(parameters_decl, ", ") + ")";
-}
-
std::vector<std::string> generate_java_annotations(const AidlAnnotatable& a) {
std::vector<std::string> result;
- const AidlAnnotation* unsupported_app_usage = a.UnsupportedAppUsage();
- if (unsupported_app_usage != nullptr) {
- result.emplace_back("@dalvik.annotation.compat.UnsupportedAppUsage" +
- generate_java_annotation_parameters(*unsupported_app_usage));
+ if (a.IsUnsupportedAppUsage()) {
+ result.emplace_back("@android.annotation.UnsupportedAppUsage");
}
if (a.IsSystemApi()) {
result.emplace_back("@android.annotation.SystemApi");
@@ -292,5 +239,5 @@
}
} // namespace java
-} // namespace aidl
} // namespace android
+} // namespace aidl
diff --git a/generate_java.h b/generate_java.h
index d2c8a6d..f2cc7fa 100644
--- a/generate_java.h
+++ b/generate_java.h
@@ -20,6 +20,7 @@
#include "ast_java.h"
#include "io_delegate.h"
#include "options.h"
+#include "type_java.h"
#include <string>
@@ -28,20 +29,18 @@
namespace java {
bool generate_java(const std::string& filename, const AidlDefinedType* iface,
- const AidlTypenames& typenames, const IoDelegate& io_delegate,
+ java::JavaTypeNamespace* types, const IoDelegate& io_delegate,
const Options& options);
-std::unique_ptr<android::aidl::java::Class> generate_binder_interface_class(
- const AidlInterface* iface, const AidlTypenames& typenames, const Options& options);
+android::aidl::java::Class* generate_binder_interface_class(const AidlInterface* iface,
+ java::JavaTypeNamespace* types,
+ const Options& options);
-std::unique_ptr<android::aidl::java::Class> generate_parcel_class(
- const AidlStructuredParcelable* parcel, const AidlTypenames& typenames);
-
-void generate_enum(const CodeWriterPtr& code_writer, const AidlEnumDeclaration* enum_decl,
- const AidlTypenames& typenames);
+android::aidl::java::Class* generate_parcel_class(const AidlStructuredParcelable* parcel,
+ AidlTypenames& typenames);
std::vector<std::string> generate_java_annotations(const AidlAnnotatable& a);
} // namespace java
-} // namespace aidl
} // namespace android
+} // namespace aidl
diff --git a/generate_java_binder.cpp b/generate_java_binder.cpp
index b791241..8ced119 100644
--- a/generate_java_binder.cpp
+++ b/generate_java_binder.cpp
@@ -17,8 +17,8 @@
#include "aidl.h"
#include "aidl_to_java.h"
#include "generate_java.h"
-#include "logging.h"
#include "options.h"
+#include "type_java.h"
#include <stdio.h>
#include <stdlib.h>
@@ -47,20 +47,20 @@
class VariableFactory {
public:
using Variable = ::android::aidl::java::Variable;
+ using Type = ::android::aidl::java::Type;
explicit VariableFactory(const std::string& base) : base_(base), index_(0) {}
- std::shared_ptr<Variable> Get(const AidlTypeSpecifier& type, const AidlTypenames& typenames) {
- auto v = std::make_shared<Variable>(JavaSignatureOf(type, typenames),
- StringPrintf("%s%d", base_.c_str(), index_));
+ Variable* Get(const Type* type) {
+ Variable* v = new Variable(type->JavaType(), StringPrintf("%s%d", base_.c_str(), index_));
vars_.push_back(v);
index_++;
return v;
}
- std::shared_ptr<Variable> Get(int index) { return vars_[index]; }
+ Variable* Get(int index) { return vars_[index]; }
private:
- std::vector<std::shared_ptr<Variable>> vars_;
+ std::vector<Variable*> vars_;
std::string base_;
int index_;
@@ -70,16 +70,17 @@
// =================================================
class StubClass : public Class {
public:
- StubClass(const AidlInterface* interfaceType, const Options& options);
+ StubClass(const Type* type, const InterfaceType* interfaceType, JavaTypeNamespace* types,
+ const Options& options);
~StubClass() override = default;
- std::shared_ptr<Variable> transact_code;
- std::shared_ptr<Variable> transact_data;
- std::shared_ptr<Variable> transact_reply;
- std::shared_ptr<Variable> transact_flags;
- std::shared_ptr<SwitchStatement> transact_switch;
- std::shared_ptr<StatementBlock> transact_statements;
- std::shared_ptr<SwitchStatement> code_to_method_name_switch;
+ Variable* transact_code;
+ Variable* transact_data;
+ Variable* transact_reply;
+ Variable* transact_flags;
+ SwitchStatement* transact_switch;
+ StatementBlock* transact_statements;
+ SwitchStatement* code_to_method_name_switch;
// Where onTransact cases should be generated as separate methods.
bool transact_outline;
@@ -91,18 +92,21 @@
// Finish generation. This will add a default case to the switch.
void finish();
- std::shared_ptr<Expression> get_transact_descriptor(const AidlMethod* method);
+ Expression* get_transact_descriptor(const JavaTypeNamespace* types,
+ const AidlMethod* method);
private:
- void make_as_interface(const AidlInterface* interfaceType);
+ void make_as_interface(const InterfaceType* interfaceType,
+ JavaTypeNamespace* types);
- std::shared_ptr<Variable> transact_descriptor;
+ Variable* transact_descriptor;
const Options& options_;
DISALLOW_COPY_AND_ASSIGN(StubClass);
};
-StubClass::StubClass(const AidlInterface* interfaceType, const Options& options)
+StubClass::StubClass(const Type* type, const InterfaceType* interfaceType, JavaTypeNamespace* types,
+ const Options& options)
: Class(), options_(options) {
transact_descriptor = nullptr;
transact_outline = false;
@@ -111,100 +115,97 @@
this->comment = "/** Local-side IPC implementation stub class. */";
this->modifiers = PUBLIC | ABSTRACT | STATIC;
this->what = Class::CLASS;
- this->type = interfaceType->GetCanonicalName() + ".Stub";
- this->extends = "android.os.Binder";
- this->interfaces.push_back(interfaceType->GetCanonicalName());
+ this->type = type->JavaType();
+ this->extends = types->BinderNativeType()->JavaType();
+ this->interfaces.push_back(interfaceType->JavaType());
// descriptor
- auto descriptor = std::make_shared<Field>(
- STATIC | FINAL | PRIVATE, std::make_shared<Variable>("java.lang.String", "DESCRIPTOR"));
- descriptor->value = "\"" + interfaceType->GetCanonicalName() + "\"";
+ Field* descriptor = new Field(STATIC | FINAL | PRIVATE,
+ new Variable(types->StringType()->JavaType(), "DESCRIPTOR"));
+ descriptor->value = "\"" + interfaceType->JavaType() + "\"";
this->elements.push_back(descriptor);
// ctor
- auto ctor = std::make_shared<Method>();
+ Method* ctor = new Method;
ctor->modifiers = PUBLIC;
ctor->comment =
"/** Construct the stub at attach it to the "
"interface. */";
ctor->name = "Stub";
- ctor->statements = std::make_shared<StatementBlock>();
- auto attach = std::make_shared<MethodCall>(
- THIS_VALUE, "attachInterface",
- std::vector<std::shared_ptr<Expression>>{THIS_VALUE,
- std::make_shared<LiteralExpression>("DESCRIPTOR")});
+ ctor->statements = new StatementBlock;
+ MethodCall* attach =
+ new MethodCall(THIS_VALUE, "attachInterface", 2, THIS_VALUE,
+ new LiteralExpression("DESCRIPTOR"));
ctor->statements->Add(attach);
this->elements.push_back(ctor);
// asInterface
- make_as_interface(interfaceType);
+ make_as_interface(interfaceType, types);
// asBinder
- auto asBinder = std::make_shared<Method>();
+ Method* asBinder = new Method;
asBinder->modifiers = PUBLIC | OVERRIDE;
- asBinder->returnType = "android.os.IBinder";
+ asBinder->returnType = types->IBinderType()->JavaType();
asBinder->name = "asBinder";
- asBinder->statements = std::make_shared<StatementBlock>();
- asBinder->statements->Add(std::make_shared<ReturnStatement>(THIS_VALUE));
+ asBinder->statements = new StatementBlock;
+ asBinder->statements->Add(new ReturnStatement(THIS_VALUE));
this->elements.push_back(asBinder);
if (options_.GenTransactionNames()) {
// getDefaultTransactionName
- auto getDefaultTransactionName = std::make_shared<Method>();
+ Method* getDefaultTransactionName = new Method;
getDefaultTransactionName->comment = "/** @hide */";
getDefaultTransactionName->modifiers = PUBLIC | STATIC;
- getDefaultTransactionName->returnType = "java.lang.String";
+ getDefaultTransactionName->returnType = types->StringType()->JavaType();
getDefaultTransactionName->name = "getDefaultTransactionName";
- auto code = std::make_shared<Variable>("int", "transactionCode");
+ Variable* code = new Variable(types->IntType()->JavaType(), "transactionCode");
getDefaultTransactionName->parameters.push_back(code);
- getDefaultTransactionName->statements = std::make_shared<StatementBlock>();
- this->code_to_method_name_switch = std::make_shared<SwitchStatement>(code);
+ getDefaultTransactionName->statements = new StatementBlock;
+ this->code_to_method_name_switch = new SwitchStatement(code);
getDefaultTransactionName->statements->Add(this->code_to_method_name_switch);
this->elements.push_back(getDefaultTransactionName);
// getTransactionName
- auto getTransactionName = std::make_shared<Method>();
+ Method* getTransactionName = new Method;
getTransactionName->comment = "/** @hide */";
getTransactionName->modifiers = PUBLIC;
- getTransactionName->returnType = "java.lang.String";
+ getTransactionName->returnType = types->StringType()->JavaType();
getTransactionName->name = "getTransactionName";
- auto code2 = std::make_shared<Variable>("int", "transactionCode");
+ Variable* code2 = new Variable(types->IntType()->JavaType(), "transactionCode");
getTransactionName->parameters.push_back(code2);
- getTransactionName->statements = std::make_shared<StatementBlock>();
- getTransactionName->statements->Add(std::make_shared<ReturnStatement>(
- std::make_shared<MethodCall>(THIS_VALUE, "getDefaultTransactionName",
- std::vector<std::shared_ptr<Expression>>{code2})));
+ getTransactionName->statements = new StatementBlock;
+ getTransactionName->statements->Add(
+ new ReturnStatement(new MethodCall(THIS_VALUE, "getDefaultTransactionName", 1, code2)));
this->elements.push_back(getTransactionName);
}
// onTransact
- this->transact_code = std::make_shared<Variable>("int", "code");
- this->transact_data = std::make_shared<Variable>("android.os.Parcel", "data");
- this->transact_reply = std::make_shared<Variable>("android.os.Parcel", "reply");
- this->transact_flags = std::make_shared<Variable>("int", "flags");
- auto onTransact = std::make_shared<Method>();
+ this->transact_code = new Variable(types->IntType()->JavaType(), "code");
+ this->transact_data = new Variable(types->ParcelType()->JavaType(), "data");
+ this->transact_reply = new Variable(types->ParcelType()->JavaType(), "reply");
+ this->transact_flags = new Variable(types->IntType()->JavaType(), "flags");
+ Method* onTransact = new Method;
onTransact->modifiers = PUBLIC | OVERRIDE;
- onTransact->returnType = "boolean";
+ onTransact->returnType = types->BoolType()->JavaType();
onTransact->name = "onTransact";
onTransact->parameters.push_back(this->transact_code);
onTransact->parameters.push_back(this->transact_data);
onTransact->parameters.push_back(this->transact_reply);
onTransact->parameters.push_back(this->transact_flags);
- onTransact->statements = std::make_shared<StatementBlock>();
+ onTransact->statements = new StatementBlock;
transact_statements = onTransact->statements;
- onTransact->exceptions.push_back("android.os.RemoteException");
+ onTransact->exceptions.push_back(types->RemoteExceptionType()->JavaType());
this->elements.push_back(onTransact);
- this->transact_switch = std::make_shared<SwitchStatement>(this->transact_code);
+ this->transact_switch = new SwitchStatement(this->transact_code);
}
void StubClass::finish() {
- auto default_case = std::make_shared<Case>();
+ Case* default_case = new Case;
- auto superCall = std::make_shared<MethodCall>(
- SUPER_VALUE, "onTransact",
- std::vector<std::shared_ptr<Expression>>{this->transact_code, this->transact_data,
- this->transact_reply, this->transact_flags});
- default_case->statements->Add(std::make_shared<ReturnStatement>(superCall));
+ MethodCall* superCall = new MethodCall(
+ SUPER_VALUE, "onTransact", 4, this->transact_code, this->transact_data,
+ this->transact_reply, this->transact_flags);
+ default_case->statements->Add(new ReturnStatement(superCall));
transact_switch->cases.push_back(default_case);
transact_statements->Add(this->transact_switch);
@@ -214,8 +215,8 @@
// Some transaction codes are common, e.g. INTERFACE_TRANSACTION or DUMP_TRANSACTION.
// Common transaction codes will not be resolved to a string by getTransactionName. The method
// will return NULL in this case.
- auto code_switch_default_case = std::make_shared<Case>();
- code_switch_default_case->statements->Add(std::make_shared<ReturnStatement>(NULL_VALUE));
+ Case* code_switch_default_case = new Case;
+ code_switch_default_case->statements->Add(new ReturnStatement(NULL_VALUE));
this->code_to_method_name_switch->cases.push_back(code_switch_default_case);
}
}
@@ -223,18 +224,19 @@
// The the expression for the interface's descriptor to be used when
// generating code for the given method. Null is acceptable for method
// and stands for synthetic cases.
-std::shared_ptr<Expression> StubClass::get_transact_descriptor(const AidlMethod* method) {
+Expression* StubClass::get_transact_descriptor(const JavaTypeNamespace* types,
+ const AidlMethod* method) {
if (transact_outline) {
if (method != nullptr) {
// When outlining, each outlined method needs its own literal.
if (outline_methods.count(method) != 0) {
- return std::make_shared<LiteralExpression>("DESCRIPTOR");
+ return new LiteralExpression("DESCRIPTOR");
}
} else {
// Synthetic case. A small number is assumed. Use its own descriptor
// if there are only synthetic cases.
if (outline_methods.size() == all_method_count) {
- return std::make_shared<LiteralExpression>("DESCRIPTOR");
+ return new LiteralExpression("DESCRIPTOR");
}
}
}
@@ -242,38 +244,41 @@
// When not outlining, store the descriptor literal into a local variable, in
// an effort to save const-string instructions in each switch case.
if (transact_descriptor == nullptr) {
- transact_descriptor = std::make_shared<Variable>("java.lang.String", "descriptor");
- transact_statements->Add(std::make_shared<VariableDeclaration>(
- transact_descriptor, std::make_shared<LiteralExpression>("DESCRIPTOR")));
+ transact_descriptor = new Variable(types->StringType()->JavaType(), "descriptor");
+ transact_statements->Add(
+ new VariableDeclaration(transact_descriptor,
+ new LiteralExpression("DESCRIPTOR")));
}
return transact_descriptor;
}
-void StubClass::make_as_interface(const AidlInterface* interfaceType) {
- auto obj = std::make_shared<Variable>("android.os.IBinder", "obj");
+void StubClass::make_as_interface(const InterfaceType* interfaceType,
+ JavaTypeNamespace* types) {
+ Variable* obj = new Variable(types->IBinderType()->JavaType(), "obj");
- auto m = std::make_shared<Method>();
+ Method* m = new Method;
m->comment = "/**\n * Cast an IBinder object into an ";
- m->comment += interfaceType->GetCanonicalName();
+ m->comment += interfaceType->JavaType();
m->comment += " interface,\n";
m->comment += " * generating a proxy if needed.\n */";
m->modifiers = PUBLIC | STATIC;
- m->returnType = interfaceType->GetCanonicalName();
+ m->returnType = interfaceType->JavaType();
m->name = "asInterface";
m->parameters.push_back(obj);
- m->statements = std::make_shared<StatementBlock>();
+ m->statements = new StatementBlock;
- auto ifstatement = std::make_shared<IfStatement>();
- ifstatement->expression = std::make_shared<Comparison>(obj, "==", NULL_VALUE);
- ifstatement->statements = std::make_shared<StatementBlock>();
- ifstatement->statements->Add(std::make_shared<ReturnStatement>(NULL_VALUE));
+ IfStatement* ifstatement = new IfStatement();
+ ifstatement->expression = new Comparison(obj, "==", NULL_VALUE);
+ ifstatement->statements = new StatementBlock;
+ ifstatement->statements->Add(new ReturnStatement(NULL_VALUE));
m->statements->Add(ifstatement);
// IInterface iin = obj.queryLocalInterface(DESCRIPTOR)
- auto queryLocalInterface = std::make_shared<MethodCall>(obj, "queryLocalInterface");
- queryLocalInterface->arguments.push_back(std::make_shared<LiteralExpression>("DESCRIPTOR"));
- auto iin = std::make_shared<Variable>("android.os.IInterface", "iin");
- auto iinVd = std::make_shared<VariableDeclaration>(iin, queryLocalInterface);
+ MethodCall* queryLocalInterface = new MethodCall(obj, "queryLocalInterface");
+ queryLocalInterface->arguments.push_back(new LiteralExpression("DESCRIPTOR"));
+ IInterfaceType iinType(types);
+ Variable* iin = new Variable(iinType.JavaType(), "iin");
+ VariableDeclaration* iinVd = new VariableDeclaration(iin, queryLocalInterface);
m->statements->Add(iinVd);
// Ensure the instance type of the local object is as expected.
@@ -282,19 +287,19 @@
// if (iin != null && iin instanceof <interfaceType>) return (<interfaceType>)
// iin;
- auto iinNotNull = std::make_shared<Comparison>(iin, "!=", NULL_VALUE);
- auto instOfCheck = std::make_shared<Comparison>(
- iin, " instanceof ", std::make_shared<LiteralExpression>(interfaceType->GetCanonicalName()));
- auto instOfStatement = std::make_shared<IfStatement>();
- instOfStatement->expression = std::make_shared<Comparison>(iinNotNull, "&&", instOfCheck);
- instOfStatement->statements = std::make_shared<StatementBlock>();
- instOfStatement->statements->Add(std::make_shared<ReturnStatement>(
- std::make_shared<Cast>(interfaceType->GetCanonicalName(), iin)));
+ Comparison* iinNotNull = new Comparison(iin, "!=", NULL_VALUE);
+ Comparison* instOfCheck =
+ new Comparison(iin, " instanceof ",
+ new LiteralExpression(interfaceType->JavaType()));
+ IfStatement* instOfStatement = new IfStatement();
+ instOfStatement->expression = new Comparison(iinNotNull, "&&", instOfCheck);
+ instOfStatement->statements = new StatementBlock;
+ instOfStatement->statements->Add(new ReturnStatement(new Cast(interfaceType->JavaType(), iin)));
m->statements->Add(instOfStatement);
- auto ne = std::make_shared<NewExpression>(interfaceType->GetCanonicalName() + ".Stub.Proxy");
+ NewExpression* ne = new NewExpression(interfaceType->GetProxy()->InstantiableName());
ne->arguments.push_back(obj);
- m->statements->Add(std::make_shared<ReturnStatement>(ne));
+ m->statements->Add(new ReturnStatement(ne));
this->elements.push_back(m);
}
@@ -302,130 +307,129 @@
// =================================================
class ProxyClass : public Class {
public:
- ProxyClass(const AidlInterface* interfaceType, const Options& options);
+ ProxyClass(const JavaTypeNamespace* types, const Type* type, const InterfaceType* interfaceType,
+ const Options& options);
~ProxyClass() override;
- std::shared_ptr<Variable> mRemote;
+ Variable* mRemote;
};
-ProxyClass::ProxyClass(const AidlInterface* interfaceType, const Options& options) : Class() {
+ProxyClass::ProxyClass(const JavaTypeNamespace* types, const Type* type,
+ const InterfaceType* interfaceType, const Options& options)
+ : Class() {
this->modifiers = PRIVATE | STATIC;
this->what = Class::CLASS;
- this->type = interfaceType->GetCanonicalName() + ".Stub.Proxy";
- this->interfaces.push_back(interfaceType->GetCanonicalName());
+ this->type = type->JavaType();
+ this->interfaces.push_back(interfaceType->JavaType());
// IBinder mRemote
- mRemote = std::make_shared<Variable>("android.os.IBinder", "mRemote");
- this->elements.push_back(std::make_shared<Field>(PRIVATE, mRemote));
+ mRemote = new Variable(types->IBinderType()->JavaType(), "mRemote");
+ this->elements.push_back(new Field(PRIVATE, mRemote));
// Proxy()
- auto remote = std::make_shared<Variable>("android.os.IBinder", "remote");
- auto ctor = std::make_shared<Method>();
+ Variable* remote = new Variable(types->IBinderType()->JavaType(), "remote");
+ Method* ctor = new Method;
ctor->name = "Proxy";
- ctor->statements = std::make_shared<StatementBlock>();
+ ctor->statements = new StatementBlock;
ctor->parameters.push_back(remote);
- ctor->statements->Add(std::make_shared<Assignment>(mRemote, remote));
+ ctor->statements->Add(new Assignment(mRemote, remote));
this->elements.push_back(ctor);
if (options.Version() > 0) {
std::ostringstream code;
code << "private int mCachedVersion = -1;\n";
- this->elements.emplace_back(std::make_shared<LiteralClassElement>(code.str()));
+ this->elements.emplace_back(new LiteralClassElement(code.str()));
}
// IBinder asBinder()
- auto asBinder = std::make_shared<Method>();
+ Method* asBinder = new Method;
asBinder->modifiers = PUBLIC | OVERRIDE;
- asBinder->returnType = "android.os.IBinder";
+ asBinder->returnType = types->IBinderType()->JavaType();
asBinder->name = "asBinder";
- asBinder->statements = std::make_shared<StatementBlock>();
- asBinder->statements->Add(std::make_shared<ReturnStatement>(mRemote));
+ asBinder->statements = new StatementBlock;
+ asBinder->statements->Add(new ReturnStatement(mRemote));
this->elements.push_back(asBinder);
}
ProxyClass::~ProxyClass() {}
// =================================================
-static void generate_new_array(const AidlTypeSpecifier& type, const AidlTypenames& typenames,
- std::shared_ptr<StatementBlock> addTo, std::shared_ptr<Variable> v,
- std::shared_ptr<Variable> parcel) {
- auto len = std::make_shared<Variable>("int", v->name + "_length");
- addTo->Add(
- std::make_shared<VariableDeclaration>(len, std::make_shared<MethodCall>(parcel, "readInt")));
- auto lencheck = std::make_shared<IfStatement>();
- lencheck->expression =
- std::make_shared<Comparison>(len, "<", std::make_shared<LiteralExpression>("0"));
- lencheck->statements->Add(std::make_shared<Assignment>(v, NULL_VALUE));
- lencheck->elseif = std::make_shared<IfStatement>();
- lencheck->elseif->statements->Add(std::make_shared<Assignment>(
- v, std::make_shared<NewArrayExpression>(InstantiableJavaSignatureOf(type, typenames), len)));
+static void generate_new_array(const Type* t, StatementBlock* addTo,
+ Variable* v, Variable* parcel,
+ JavaTypeNamespace* types) {
+ Variable* len = new Variable(types->IntType()->JavaType(), v->name + "_length");
+ addTo->Add(new VariableDeclaration(len, new MethodCall(parcel, "readInt")));
+ IfStatement* lencheck = new IfStatement();
+ lencheck->expression = new Comparison(len, "<", new LiteralExpression("0"));
+ lencheck->statements->Add(new Assignment(v, NULL_VALUE));
+ lencheck->elseif = new IfStatement();
+ lencheck->elseif->statements->Add(new Assignment(v, new NewArrayExpression(t->JavaType(), len)));
addTo->Add(lencheck);
}
-static void generate_write_to_parcel(const AidlTypeSpecifier& type,
- std::shared_ptr<StatementBlock> addTo,
- std::shared_ptr<Variable> v, std::shared_ptr<Variable> parcel,
- bool is_return_value, const AidlTypenames& typenames) {
+static void generate_write_to_parcel(const AidlTypeSpecifier& type, StatementBlock* addTo,
+ Variable* v, Variable* parcel, bool is_return_value,
+ const AidlTypenames& typenames) {
string code;
CodeWriterPtr writer = CodeWriter::ForString(&code);
CodeGeneratorContext context{
.writer = *(writer.get()),
.typenames = typenames,
.type = type,
- .parcel = parcel->name,
.var = v->name,
+ .parcel = parcel->name,
.is_return_value = is_return_value,
};
WriteToParcelFor(context);
writer->Close();
- addTo->Add(std::make_shared<LiteralStatement>(code));
+ addTo->Add(new LiteralStatement(code));
}
static void generate_int_constant(Class* interface, const std::string& name,
const std::string& value) {
auto code = StringPrintf("public static final int %s = %s;\n", name.c_str(), value.c_str());
- interface->elements.push_back(std::make_shared<LiteralClassElement>(code));
+ interface->elements.push_back(new LiteralClassElement(code));
}
static void generate_string_constant(Class* interface, const std::string& name,
const std::string& value) {
auto code = StringPrintf("public static final String %s = %s;\n", name.c_str(), value.c_str());
- interface->elements.push_back(std::make_shared<LiteralClassElement>(code));
+ interface->elements.push_back(new LiteralClassElement(code));
}
-static std::shared_ptr<Method> generate_interface_method(const AidlMethod& method,
- const AidlTypenames& typenames) {
- auto decl = std::make_shared<Method>();
+static std::unique_ptr<Method> generate_interface_method(
+ const AidlMethod& method, JavaTypeNamespace* types) {
+ std::unique_ptr<Method> decl(new Method);
decl->comment = method.GetComments();
decl->modifiers = PUBLIC;
- decl->returnType = JavaSignatureOf(method.GetType(), typenames);
+ decl->returnType = method.GetType().GetLanguageType<Type>()->JavaType();
+ decl->returnTypeDimension = method.GetType().IsArray() ? 1 : 0;
decl->name = method.GetName();
decl->annotations = generate_java_annotations(method.GetType());
for (const std::unique_ptr<AidlArgument>& arg : method.GetArguments()) {
- decl->parameters.push_back(
- std::make_shared<Variable>(JavaSignatureOf(arg->GetType(), typenames), arg->GetName()));
+ decl->parameters.push_back(new Variable(arg->GetType().GetLanguageType<Type>()->JavaType(),
+ arg->GetName(), arg->GetType().IsArray() ? 1 : 0));
}
- decl->exceptions.push_back("android.os.RemoteException");
+ decl->exceptions.push_back(types->RemoteExceptionType()->JavaType());
return decl;
}
static void generate_stub_code(const AidlInterface& iface, const AidlMethod& method, bool oneway,
- std::shared_ptr<Variable> transact_data,
- std::shared_ptr<Variable> transact_reply,
- const AidlTypenames& typenames,
- std::shared_ptr<StatementBlock> statements,
- std::shared_ptr<StubClass> stubClass, const Options& options) {
- std::shared_ptr<TryStatement> tryStatement;
- std::shared_ptr<FinallyStatement> finallyStatement;
- auto realCall = std::make_shared<MethodCall>(THIS_VALUE, method.GetName());
+ Variable* transact_data, Variable* transact_reply,
+ JavaTypeNamespace* types, StatementBlock* statements,
+ StubClass* stubClass, const Options& options) {
+ TryStatement* tryStatement = nullptr;
+ FinallyStatement* finallyStatement = nullptr;
+ MethodCall* realCall = new MethodCall(THIS_VALUE, method.GetName());
// interface token validation is the very first thing we do
- statements->Add(std::make_shared<MethodCall>(
- transact_data, "enforceInterface",
- std::vector<std::shared_ptr<Expression>>{stubClass->get_transact_descriptor(&method)}));
+ statements->Add(new MethodCall(transact_data,
+ "enforceInterface", 1,
+ stubClass->get_transact_descriptor(types,
+ &method)));
// args
VariableFactory stubArgs("_arg");
@@ -434,29 +438,29 @@
// at most once.
bool is_classloader_created = false;
for (const std::unique_ptr<AidlArgument>& arg : method.GetArguments()) {
- std::shared_ptr<Variable> v = stubArgs.Get(arg->GetType(), typenames);
+ const Type* t = arg->GetType().GetLanguageType<Type>();
+ Variable* v = stubArgs.Get(t);
+ v->dimension = arg->GetType().IsArray() ? 1 : 0;
- statements->Add(std::make_shared<VariableDeclaration>(v));
+ statements->Add(new VariableDeclaration(v));
if (arg->GetDirection() & AidlArgument::IN_DIR) {
string code;
CodeWriterPtr writer = CodeWriter::ForString(&code);
CodeGeneratorContext context{.writer = *(writer.get()),
- .typenames = typenames,
+ .typenames = types->typenames_,
.type = arg->GetType(),
- .parcel = transact_data->name,
.var = v->name,
+ .parcel = transact_data->name,
.is_classloader_created = &is_classloader_created};
CreateFromParcelFor(context);
writer->Close();
- statements->Add(std::make_shared<LiteralStatement>(code));
+ statements->Add(new LiteralStatement(code));
} else {
if (!arg->GetType().IsArray()) {
- statements->Add(std::make_shared<Assignment>(
- v, std::make_shared<NewExpression>(
- InstantiableJavaSignatureOf(arg->GetType(), typenames))));
+ statements->Add(new Assignment(v, new NewExpression(t->InstantiableName())));
} else {
- generate_new_array(arg->GetType(), typenames, statements, v, transact_data);
+ generate_new_array(t, statements, v, transact_data, types);
}
}
@@ -466,20 +470,18 @@
if (options.GenTraces()) {
// try and finally, but only when generating trace code
- tryStatement = std::make_shared<TryStatement>();
- finallyStatement = std::make_shared<FinallyStatement>();
+ tryStatement = new TryStatement();
+ finallyStatement = new FinallyStatement();
- tryStatement->statements->Add(std::make_shared<MethodCall>(
- std::make_shared<LiteralExpression>("android.os.Trace"), "traceBegin",
- std::vector<std::shared_ptr<Expression>>{
- std::make_shared<LiteralExpression>("android.os.Trace.TRACE_TAG_AIDL"),
- std::make_shared<StringLiteralExpression>(iface.GetName() + "::" + method.GetName() +
- "::server")}));
+ tryStatement->statements->Add(new MethodCall(
+ new LiteralExpression("android.os.Trace"), "traceBegin", 2,
+ new LiteralExpression("android.os.Trace.TRACE_TAG_AIDL"),
+ new StringLiteralExpression(iface.GetName() + "::"
+ + method.GetName() + "::server")));
- finallyStatement->statements->Add(std::make_shared<MethodCall>(
- std::make_shared<LiteralExpression>("android.os.Trace"), "traceEnd",
- std::vector<std::shared_ptr<Expression>>{
- std::make_shared<LiteralExpression>("android.os.Trace.TRACE_TAG_AIDL")}));
+ finallyStatement->statements->Add(new MethodCall(
+ new LiteralExpression("android.os.Trace"), "traceEnd", 1,
+ new LiteralExpression("android.os.Trace.TRACE_TAG_AIDL")));
}
// the real call
@@ -494,180 +496,181 @@
if (!oneway) {
// report that there were no exceptions
- auto ex = std::make_shared<MethodCall>(transact_reply, "writeNoException");
+ MethodCall* ex =
+ new MethodCall(transact_reply, "writeNoException", 0);
statements->Add(ex);
}
} else {
- auto _result =
- std::make_shared<Variable>(JavaSignatureOf(method.GetType(), typenames), "_result");
+ Variable* _result = new Variable(method.GetType().GetLanguageType<Type>()->JavaType(),
+ "_result", method.GetType().IsArray() ? 1 : 0);
if (options.GenTraces()) {
- statements->Add(std::make_shared<VariableDeclaration>(_result));
+ statements->Add(new VariableDeclaration(_result));
statements->Add(tryStatement);
- tryStatement->statements->Add(std::make_shared<Assignment>(_result, realCall));
+ tryStatement->statements->Add(new Assignment(_result, realCall));
statements->Add(finallyStatement);
} else {
- statements->Add(std::make_shared<VariableDeclaration>(_result, realCall));
+ statements->Add(new VariableDeclaration(_result, realCall));
}
if (!oneway) {
// report that there were no exceptions
- auto ex = std::make_shared<MethodCall>(transact_reply, "writeNoException");
+ MethodCall* ex =
+ new MethodCall(transact_reply, "writeNoException", 0);
statements->Add(ex);
}
// marshall the return value
generate_write_to_parcel(method.GetType(), statements, _result, transact_reply, true,
- typenames);
+ types->typenames_);
}
// out parameters
int i = 0;
for (const std::unique_ptr<AidlArgument>& arg : method.GetArguments()) {
- std::shared_ptr<Variable> v = stubArgs.Get(i++);
+ Variable* v = stubArgs.Get(i++);
if (arg->GetDirection() & AidlArgument::OUT_DIR) {
- generate_write_to_parcel(arg->GetType(), statements, v, transact_reply, true, typenames);
+ generate_write_to_parcel(arg->GetType(), statements, v, transact_reply, true,
+ types->typenames_);
}
}
// return true
- statements->Add(std::make_shared<ReturnStatement>(TRUE_VALUE));
+ statements->Add(new ReturnStatement(TRUE_VALUE));
}
static void generate_stub_case(const AidlInterface& iface, const AidlMethod& method,
const std::string& transactCodeName, bool oneway,
- std::shared_ptr<StubClass> stubClass, const AidlTypenames& typenames,
+ StubClass* stubClass, JavaTypeNamespace* types,
const Options& options) {
- auto c = std::make_shared<Case>(transactCodeName);
+ Case* c = new Case(transactCodeName);
generate_stub_code(iface, method, oneway, stubClass->transact_data, stubClass->transact_reply,
- typenames, c->statements, stubClass, options);
+ types, c->statements, stubClass, options);
stubClass->transact_switch->cases.push_back(c);
}
static void generate_stub_case_outline(const AidlInterface& iface, const AidlMethod& method,
const std::string& transactCodeName, bool oneway,
- std::shared_ptr<StubClass> stubClass,
- const AidlTypenames& typenames, const Options& options) {
+ StubClass* stubClass, JavaTypeNamespace* types,
+ const Options& options) {
std::string outline_name = "onTransact$" + method.GetName() + "$";
// Generate an "outlined" method with the actual code.
{
- auto transact_data = std::make_shared<Variable>("android.os.Parcel", "data");
- auto transact_reply = std::make_shared<Variable>("android.os.Parcel", "reply");
- auto onTransact_case = std::make_shared<Method>();
+ Variable* transact_data = new Variable(types->ParcelType()->JavaType(), "data");
+ Variable* transact_reply = new Variable(types->ParcelType()->JavaType(), "reply");
+ Method* onTransact_case = new Method;
onTransact_case->modifiers = PRIVATE;
- onTransact_case->returnType = "boolean";
+ onTransact_case->returnType = types->BoolType()->JavaType();
onTransact_case->name = outline_name;
onTransact_case->parameters.push_back(transact_data);
onTransact_case->parameters.push_back(transact_reply);
- onTransact_case->statements = std::make_shared<StatementBlock>();
- onTransact_case->exceptions.push_back("android.os.RemoteException");
+ onTransact_case->statements = new StatementBlock;
+ onTransact_case->exceptions.push_back(types->RemoteExceptionType()->JavaType());
stubClass->elements.push_back(onTransact_case);
- generate_stub_code(iface, method, oneway, transact_data, transact_reply, typenames,
+ generate_stub_code(iface, method, oneway, transact_data, transact_reply, types,
onTransact_case->statements, stubClass, options);
}
// Generate the case dispatch.
{
- auto c = std::make_shared<Case>(transactCodeName);
+ Case* c = new Case(transactCodeName);
- auto helper_call =
- std::make_shared<MethodCall>(THIS_VALUE, outline_name,
- std::vector<std::shared_ptr<Expression>>{
- stubClass->transact_data, stubClass->transact_reply});
- c->statements->Add(std::make_shared<ReturnStatement>(helper_call));
+ MethodCall* helper_call = new MethodCall(THIS_VALUE,
+ outline_name,
+ 2,
+ stubClass->transact_data,
+ stubClass->transact_reply);
+ c->statements->Add(new ReturnStatement(helper_call));
stubClass->transact_switch->cases.push_back(c);
}
}
-static std::shared_ptr<Method> generate_proxy_method(
+static std::unique_ptr<Method> generate_proxy_method(
const AidlInterface& iface, const AidlMethod& method, const std::string& transactCodeName,
- bool oneway, std::shared_ptr<ProxyClass> proxyClass, const AidlTypenames& typenames,
- const Options& options) {
- auto proxy = std::make_shared<Method>();
+ bool oneway, ProxyClass* proxyClass, JavaTypeNamespace* types, const Options& options) {
+ std::unique_ptr<Method> proxy(new Method);
proxy->comment = method.GetComments();
proxy->modifiers = PUBLIC | OVERRIDE;
- proxy->returnType = JavaSignatureOf(method.GetType(), typenames);
+ proxy->returnType = method.GetType().GetLanguageType<Type>()->JavaType();
+ proxy->returnTypeDimension = method.GetType().IsArray() ? 1 : 0;
proxy->name = method.GetName();
- proxy->statements = std::make_shared<StatementBlock>();
+ proxy->statements = new StatementBlock;
for (const std::unique_ptr<AidlArgument>& arg : method.GetArguments()) {
- proxy->parameters.push_back(
- std::make_shared<Variable>(JavaSignatureOf(arg->GetType(), typenames), arg->GetName()));
+ proxy->parameters.push_back(new Variable(arg->GetType().GetLanguageType<Type>()->JavaType(),
+ arg->GetName(), arg->GetType().IsArray() ? 1 : 0));
}
- proxy->exceptions.push_back("android.os.RemoteException");
+ proxy->exceptions.push_back(types->RemoteExceptionType()->JavaType());
// the parcels
- auto _data = std::make_shared<Variable>("android.os.Parcel", "_data");
- proxy->statements->Add(std::make_shared<VariableDeclaration>(
- _data, std::make_shared<MethodCall>("android.os.Parcel", "obtain")));
- std::shared_ptr<Variable> _reply = nullptr;
+ Variable* _data = new Variable(types->ParcelType()->JavaType(), "_data");
+ proxy->statements->Add(
+ new VariableDeclaration(_data, new MethodCall(types->ParcelType()->JavaType(), "obtain")));
+ Variable* _reply = nullptr;
if (!oneway) {
- _reply = std::make_shared<Variable>("android.os.Parcel", "_reply");
- proxy->statements->Add(std::make_shared<VariableDeclaration>(
- _reply, std::make_shared<MethodCall>("android.os.Parcel", "obtain")));
+ _reply = new Variable(types->ParcelType()->JavaType(), "_reply");
+ proxy->statements->Add(
+ new VariableDeclaration(_reply, new MethodCall(types->ParcelType()->JavaType(), "obtain")));
}
// the return value
- std::shared_ptr<Variable> _result = nullptr;
+ Variable* _result = nullptr;
if (method.GetType().GetName() != "void") {
- _result = std::make_shared<Variable>(*proxy->returnType, "_result");
- proxy->statements->Add(std::make_shared<VariableDeclaration>(_result));
+ _result = new Variable(*proxy->returnType, "_result", method.GetType().IsArray() ? 1 : 0);
+ proxy->statements->Add(new VariableDeclaration(_result));
}
// try and finally
- auto tryStatement = std::make_shared<TryStatement>();
+ TryStatement* tryStatement = new TryStatement();
proxy->statements->Add(tryStatement);
- auto finallyStatement = std::make_shared<FinallyStatement>();
+ FinallyStatement* finallyStatement = new FinallyStatement();
proxy->statements->Add(finallyStatement);
if (options.GenTraces()) {
- tryStatement->statements->Add(std::make_shared<MethodCall>(
- std::make_shared<LiteralExpression>("android.os.Trace"), "traceBegin",
- std::vector<std::shared_ptr<Expression>>{
- std::make_shared<LiteralExpression>("android.os.Trace.TRACE_TAG_AIDL"),
- std::make_shared<StringLiteralExpression>(iface.GetName() + "::" + method.GetName() +
- "::client")}));
+ tryStatement->statements->Add(new MethodCall(
+ new LiteralExpression("android.os.Trace"), "traceBegin", 2,
+ new LiteralExpression("android.os.Trace.TRACE_TAG_AIDL"),
+ new StringLiteralExpression(iface.GetName() + "::" +
+ method.GetName() + "::client")));
}
// the interface identifier token: the DESCRIPTOR constant, marshalled as a
// string
- tryStatement->statements->Add(std::make_shared<MethodCall>(
- _data, "writeInterfaceToken",
- std::vector<std::shared_ptr<Expression>>{std::make_shared<LiteralExpression>("DESCRIPTOR")}));
+ tryStatement->statements->Add(new MethodCall(
+ _data, "writeInterfaceToken", 1, new LiteralExpression("DESCRIPTOR")));
// the parameters
for (const std::unique_ptr<AidlArgument>& arg : method.GetArguments()) {
- auto v = std::make_shared<Variable>(JavaSignatureOf(arg->GetType(), typenames), arg->GetName());
+ const Type* t = arg->GetType().GetLanguageType<Type>();
+ Variable* v = new Variable(t->JavaType(), arg->GetName(), arg->GetType().IsArray() ? 1 : 0);
AidlArgument::Direction dir = arg->GetDirection();
if (dir == AidlArgument::OUT_DIR && arg->GetType().IsArray()) {
- auto checklen = std::make_shared<IfStatement>();
- checklen->expression = std::make_shared<Comparison>(v, "==", NULL_VALUE);
- checklen->statements->Add(std::make_shared<MethodCall>(
- _data, "writeInt",
- std::vector<std::shared_ptr<Expression>>{std::make_shared<LiteralExpression>("-1")}));
- checklen->elseif = std::make_shared<IfStatement>();
- checklen->elseif->statements->Add(std::make_shared<MethodCall>(
- _data, "writeInt",
- std::vector<std::shared_ptr<Expression>>{std::make_shared<FieldVariable>(v, "length")}));
+ IfStatement* checklen = new IfStatement();
+ checklen->expression = new Comparison(v, "==", NULL_VALUE);
+ checklen->statements->Add(
+ new MethodCall(_data, "writeInt", 1, new LiteralExpression("-1")));
+ checklen->elseif = new IfStatement();
+ checklen->elseif->statements->Add(
+ new MethodCall(_data, "writeInt", 1, new FieldVariable(v, "length")));
tryStatement->statements->Add(checklen);
} else if (dir & AidlArgument::IN_DIR) {
generate_write_to_parcel(arg->GetType(), tryStatement->statements, v, _data, false,
- typenames);
+ types->typenames_);
+ } else {
+ delete v;
}
}
// the transact call
- auto call = std::make_shared<MethodCall>(
- proxyClass->mRemote, "transact",
- std::vector<std::shared_ptr<Expression>>{
- std::make_shared<LiteralExpression>("Stub." + transactCodeName), _data,
- _reply ? _reply : NULL_VALUE,
- std::make_shared<LiteralExpression>(oneway ? "android.os.IBinder.FLAG_ONEWAY" : "0")});
- auto _status = std::make_shared<Variable>("boolean", "_status");
- tryStatement->statements->Add(std::make_shared<VariableDeclaration>(_status, call));
+ unique_ptr<MethodCall> call(new MethodCall(
+ proxyClass->mRemote, "transact", 4, new LiteralExpression("Stub." + transactCodeName), _data,
+ _reply ? _reply : NULL_VALUE,
+ new LiteralExpression(oneway ? "android.os.IBinder.FLAG_ONEWAY" : "0")));
+ unique_ptr<Variable> _status(new Variable(types->BoolType()->JavaType(), "_status"));
+ tryStatement->statements->Add(new VariableDeclaration(_status.release(), call.release()));
// If the transaction returns false, which means UNKNOWN_TRANSACTION, fall
// back to the local method in the default impl, if set before.
@@ -676,7 +679,7 @@
arg_names.emplace_back(arg->GetName());
}
bool has_return_type = method.GetType().GetName() != "void";
- tryStatement->statements->Add(std::make_shared<LiteralStatement>(
+ tryStatement->statements->Add(new LiteralStatement(
android::base::StringPrintf(has_return_type ? "if (!_status && getDefaultImpl() != null) {\n"
" return getDefaultImpl().%s(%s);\n"
"}\n"
@@ -688,7 +691,7 @@
// throw back exceptions.
if (_reply) {
- auto ex = std::make_shared<MethodCall>(_reply, "readException");
+ MethodCall* ex = new MethodCall(_reply, "readException", 0);
tryStatement->statements->Add(ex);
}
@@ -701,14 +704,14 @@
string code;
CodeWriterPtr writer = CodeWriter::ForString(&code);
CodeGeneratorContext context{.writer = *(writer.get()),
- .typenames = typenames,
+ .typenames = types->typenames_,
.type = method.GetType(),
- .parcel = _reply->name,
.var = _result->name,
+ .parcel = _reply->name,
.is_classloader_created = &is_classloader_created};
CreateFromParcelFor(context);
writer->Close();
- tryStatement->statements->Add(std::make_shared<LiteralStatement>(code));
+ tryStatement->statements->Add(new LiteralStatement(code));
}
// the out/inout parameters
@@ -717,69 +720,66 @@
string code;
CodeWriterPtr writer = CodeWriter::ForString(&code);
CodeGeneratorContext context{.writer = *(writer.get()),
- .typenames = typenames,
+ .typenames = types->typenames_,
.type = arg->GetType(),
- .parcel = _reply->name,
.var = arg->GetName(),
+ .parcel = _reply->name,
.is_classloader_created = &is_classloader_created};
ReadFromParcelFor(context);
writer->Close();
- tryStatement->statements->Add(std::make_shared<LiteralStatement>(code));
+ tryStatement->statements->Add(new LiteralStatement(code));
}
}
- finallyStatement->statements->Add(std::make_shared<MethodCall>(_reply, "recycle"));
+ finallyStatement->statements->Add(new MethodCall(_reply, "recycle"));
}
- finallyStatement->statements->Add(std::make_shared<MethodCall>(_data, "recycle"));
+ finallyStatement->statements->Add(new MethodCall(_data, "recycle"));
if (options.GenTraces()) {
- finallyStatement->statements->Add(std::make_shared<MethodCall>(
- std::make_shared<LiteralExpression>("android.os.Trace"), "traceEnd",
- std::vector<std::shared_ptr<Expression>>{
- std::make_shared<LiteralExpression>("android.os.Trace.TRACE_TAG_AIDL")}));
+ finallyStatement->statements->Add(new MethodCall(
+ new LiteralExpression("android.os.Trace"), "traceEnd", 1,
+ new LiteralExpression("android.os.Trace.TRACE_TAG_AIDL")));
}
if (_result != nullptr) {
- proxy->statements->Add(std::make_shared<ReturnStatement>(_result));
+ proxy->statements->Add(new ReturnStatement(_result));
}
return proxy;
}
static void generate_methods(const AidlInterface& iface, const AidlMethod& method, Class* interface,
- std::shared_ptr<StubClass> stubClass,
- std::shared_ptr<ProxyClass> proxyClass, int index,
- const AidlTypenames& typenames, const Options& options) {
+ StubClass* stubClass, ProxyClass* proxyClass, int index,
+ JavaTypeNamespace* types, const Options& options) {
const bool oneway = method.IsOneway();
// == the TRANSACT_ constant =============================================
string transactCodeName = "TRANSACTION_";
transactCodeName += method.GetName();
- auto transactCode =
- std::make_shared<Field>(STATIC | FINAL, std::make_shared<Variable>("int", transactCodeName));
+ Field* transactCode =
+ new Field(STATIC | FINAL, new Variable(types->IntType()->JavaType(), transactCodeName));
transactCode->value =
StringPrintf("(android.os.IBinder.FIRST_CALL_TRANSACTION + %d)", index);
stubClass->elements.push_back(transactCode);
// getTransactionName
if (options.GenTransactionNames()) {
- auto c = std::make_shared<Case>(transactCodeName);
- c->statements->Add(std::make_shared<ReturnStatement>(
- std::make_shared<StringLiteralExpression>(method.GetName())));
+ Case* c = new Case(transactCodeName);
+ c->statements->Add(new ReturnStatement(new StringLiteralExpression(method.GetName())));
stubClass->code_to_method_name_switch->cases.push_back(c);
}
// == the declaration in the interface ===================================
- std::shared_ptr<ClassElement> decl;
+ ClassElement* decl;
if (method.IsUserDefined()) {
- decl = generate_interface_method(method, typenames);
+ decl = generate_interface_method(method, types).release();
} else {
if (method.GetName() == kGetInterfaceVersion && options.Version() > 0) {
std::ostringstream code;
code << "public int " << kGetInterfaceVersion << "() "
<< "throws android.os.RemoteException;\n";
- decl = std::make_shared<LiteralClassElement>(code.str());
+ decl = new LiteralClassElement(code.str());
}
}
interface->elements.push_back(decl);
@@ -789,29 +789,30 @@
bool outline_stub =
stubClass->transact_outline && stubClass->outline_methods.count(&method) != 0;
if (outline_stub) {
- generate_stub_case_outline(iface, method, transactCodeName, oneway, stubClass, typenames,
+ generate_stub_case_outline(iface, method, transactCodeName, oneway, stubClass, types,
options);
} else {
- generate_stub_case(iface, method, transactCodeName, oneway, stubClass, typenames, options);
+ generate_stub_case(iface, method, transactCodeName, oneway, stubClass, types, options);
}
} else {
if (method.GetName() == kGetInterfaceVersion && options.Version() > 0) {
- auto c = std::make_shared<Case>(transactCodeName);
+ Case* c = new Case(transactCodeName);
std::ostringstream code;
code << "data.enforceInterface(descriptor);\n"
<< "reply.writeNoException();\n"
<< "reply.writeInt(" << kGetInterfaceVersion << "());\n"
<< "return true;\n";
- c->statements->Add(std::make_shared<LiteralStatement>(code.str()));
+ c->statements->Add(new LiteralStatement(code.str()));
stubClass->transact_switch->cases.push_back(c);
}
}
// == the proxy method ===================================================
- std::shared_ptr<ClassElement> proxy = nullptr;
+ ClassElement* proxy = nullptr;
if (method.IsUserDefined()) {
- proxy = generate_proxy_method(iface, method, transactCodeName, oneway, proxyClass, typenames,
- options);
+ proxy =
+ generate_proxy_method(iface, method, transactCodeName, oneway, proxyClass, types, options)
+ .release();
} else {
if (method.GetName() == kGetInterfaceVersion && options.Version() > 0) {
@@ -825,13 +826,8 @@
<< " android.os.Parcel reply = android.os.Parcel.obtain();\n"
<< " try {\n"
<< " data.writeInterfaceToken(DESCRIPTOR);\n"
- << " boolean _status = mRemote.transact(Stub." << transactCodeName << ", "
+ << " mRemote.transact(Stub." << transactCodeName << ", "
<< "data, reply, 0);\n"
- << " if (!_status) {\n"
- << " if (getDefaultImpl() != null) {\n"
- << " return getDefaultImpl().getInterfaceVersion();\n"
- << " }\n"
- << " }\n"
<< " reply.readException();\n"
<< " mCachedVersion = reply.readInt();\n"
<< " } finally {\n"
@@ -841,7 +837,7 @@
<< " }\n"
<< " return mCachedVersion;\n"
<< "}\n";
- proxy = std::make_shared<LiteralClassElement>(code.str());
+ proxy = new LiteralClassElement(code.str());
}
}
if (proxy != nullptr) {
@@ -849,24 +845,25 @@
}
}
-static void generate_interface_descriptors(std::shared_ptr<StubClass> stub,
- std::shared_ptr<ProxyClass> proxy) {
+static void generate_interface_descriptors(StubClass* stub, ProxyClass* proxy,
+ const JavaTypeNamespace* types) {
// the interface descriptor transaction handler
- auto c = std::make_shared<Case>("INTERFACE_TRANSACTION");
- c->statements->Add(std::make_shared<MethodCall>(
- stub->transact_reply, "writeString",
- std::vector<std::shared_ptr<Expression>>{stub->get_transact_descriptor(nullptr)}));
- c->statements->Add(std::make_shared<ReturnStatement>(TRUE_VALUE));
+ Case* c = new Case("INTERFACE_TRANSACTION");
+ c->statements->Add(new MethodCall(stub->transact_reply, "writeString", 1,
+ stub->get_transact_descriptor(types,
+ nullptr)));
+ c->statements->Add(new ReturnStatement(TRUE_VALUE));
stub->transact_switch->cases.push_back(c);
// and the proxy-side method returning the descriptor directly
- auto getDesc = std::make_shared<Method>();
+ Method* getDesc = new Method;
getDesc->modifiers = PUBLIC;
- getDesc->returnType = "java.lang.String";
+ getDesc->returnType = types->StringType()->JavaType();
+ getDesc->returnTypeDimension = 0;
getDesc->name = "getInterfaceDescriptor";
- getDesc->statements = std::make_shared<StatementBlock>();
+ getDesc->statements = new StatementBlock;
getDesc->statements->Add(
- std::make_shared<ReturnStatement>(std::make_shared<LiteralExpression>("DESCRIPTOR")));
+ new ReturnStatement(new LiteralExpression("DESCRIPTOR")));
proxy->elements.push_back(getDesc);
}
@@ -881,7 +878,8 @@
//
// Requirements: non_outline_count <= outline_threshold.
static void compute_outline_methods(const AidlInterface* iface,
- const std::shared_ptr<StubClass> stub, size_t outline_threshold,
+ StubClass* stub,
+ size_t outline_threshold,
size_t non_outline_count) {
CHECK_LE(non_outline_count, outline_threshold);
// We'll outline (create sub methods) if there are more than min_methods
@@ -907,41 +905,45 @@
}
}
-static shared_ptr<ClassElement> generate_default_impl_method(const AidlMethod& method,
- const AidlTypenames& typenames) {
- auto default_method = std::make_shared<Method>();
+static unique_ptr<ClassElement> generate_default_impl_method(const AidlMethod& method) {
+ unique_ptr<Method> default_method(new Method);
default_method->comment = method.GetComments();
default_method->modifiers = PUBLIC | OVERRIDE;
- default_method->returnType = JavaSignatureOf(method.GetType(), typenames);
+ default_method->returnType = method.GetType().GetLanguageType<Type>()->JavaType();
+ default_method->returnTypeDimension = method.GetType().IsArray() ? 1 : 0;
default_method->name = method.GetName();
- default_method->statements = std::make_shared<StatementBlock>();
+ default_method->statements = new StatementBlock;
for (const auto& arg : method.GetArguments()) {
default_method->parameters.push_back(
- std::make_shared<Variable>(JavaSignatureOf(arg->GetType(), typenames), arg->GetName()));
+ new Variable(arg->GetType().GetLanguageType<Type>()->JavaType(), arg->GetName(),
+ arg->GetType().IsArray() ? 1 : 0));
}
- default_method->exceptions.push_back("android.os.RemoteException");
+ default_method->exceptions.push_back(method.GetType()
+ .GetLanguageType<Type>()
+ ->GetTypeNamespace()
+ ->RemoteExceptionType()
+ ->JavaType());
if (method.GetType().GetName() != "void") {
- const string& defaultValue = DefaultJavaValueOf(method.GetType(), typenames);
+ const string& defaultValue = DefaultJavaValueOf(method.GetType());
default_method->statements->Add(
- std::make_shared<LiteralStatement>(StringPrintf("return %s;\n", defaultValue.c_str())));
+ new LiteralStatement(StringPrintf("return %s;\n", defaultValue.c_str())));
}
return default_method;
}
-static shared_ptr<Class> generate_default_impl_class(const AidlInterface& iface,
- const AidlTypenames& typenames,
+static unique_ptr<Class> generate_default_impl_class(const AidlInterface& iface,
const Options& options) {
- auto default_class = std::make_shared<Class>();
+ unique_ptr<Class> default_class(new Class);
default_class->comment = "/** Default implementation for " + iface.GetName() + ". */";
default_class->modifiers = PUBLIC | STATIC;
default_class->what = Class::CLASS;
- default_class->type = iface.GetCanonicalName() + ".Default";
- default_class->interfaces.emplace_back(iface.GetCanonicalName());
+ default_class->type = iface.GetLanguageType<InterfaceType>()->GetDefaultImpl()->JavaType();
+ default_class->interfaces.emplace_back(iface.GetLanguageType<InterfaceType>()->JavaType());
for (const auto& m : iface.GetMethods()) {
if (m->IsUserDefined()) {
- default_class->elements.emplace_back(generate_default_impl_method(*m.get(), typenames));
+ default_class->elements.emplace_back(generate_default_impl_method(*(m.get())).release());
} else {
if (m->GetName() == kGetInterfaceVersion && options.Version() > 0) {
// This is called only when the remote side is not implementing this
@@ -955,30 +957,31 @@
<< "public int " << kGetInterfaceVersion << "() {\n"
<< " return -1;\n"
<< "}\n";
- default_class->elements.emplace_back(std::make_shared<LiteralClassElement>(code.str()));
+ default_class->elements.emplace_back(new LiteralClassElement(code.str()));
}
}
}
default_class->elements.emplace_back(
- std::make_shared<LiteralClassElement>("@Override\n"
- "public android.os.IBinder asBinder() {\n"
- " return null;\n"
- "}\n"));
+ new LiteralClassElement("@Override\n"
+ "public android.os.IBinder asBinder() {\n"
+ " return null;\n"
+ "}\n"));
return default_class;
}
-std::unique_ptr<Class> generate_binder_interface_class(const AidlInterface* iface,
- const AidlTypenames& typenames,
- const Options& options) {
+Class* generate_binder_interface_class(const AidlInterface* iface, JavaTypeNamespace* types,
+ const Options& options) {
+ const InterfaceType* interfaceType = iface->GetLanguageType<InterfaceType>();
+
// the interface class
- auto interface = std::make_unique<Class>();
+ Class* interface = new Class;
interface->comment = iface->GetComments();
interface->modifiers = PUBLIC;
interface->what = Class::INTERFACE;
- interface->type = iface->GetCanonicalName();
- interface->interfaces.push_back("android.os.IInterface");
+ interface->type = interfaceType->JavaType();
+ interface->interfaces.push_back(types->IInterfaceType()->JavaType());
interface->annotations = generate_java_annotations(*iface);
if (options.Version()) {
@@ -990,15 +993,16 @@
<< " * that the remote object is implementing.\n"
<< " */\n"
<< "public static final int VERSION = " << options.Version() << ";\n";
- interface->elements.emplace_back(std::make_shared<LiteralClassElement>(code.str()));
+ interface->elements.emplace_back(new LiteralClassElement(code.str()));
}
// the default impl class
- auto default_impl = generate_default_impl_class(*iface, typenames, options);
+ Class* default_impl = generate_default_impl_class(*iface, options).release();
interface->elements.emplace_back(default_impl);
// the stub inner class
- auto stub = std::make_shared<StubClass>(iface, options);
+ StubClass* stub =
+ new StubClass(interfaceType->GetStub(), interfaceType, types, options);
interface->elements.push_back(stub);
compute_outline_methods(iface,
@@ -1007,11 +1011,11 @@
options.onTransact_non_outline_count_);
// the proxy inner class
- auto proxy = std::make_shared<ProxyClass>(iface, options);
+ ProxyClass* proxy = new ProxyClass(types, interfaceType->GetProxy(), interfaceType, options);
stub->elements.push_back(proxy);
// stub and proxy support for getInterfaceDescriptor()
- generate_interface_descriptors(stub, proxy);
+ generate_interface_descriptors(stub, proxy, types);
// all the declared constants of the interface
for (const auto& constant : iface->GetConstantDeclarations()) {
@@ -1019,14 +1023,13 @@
switch (value.GetType()) {
case AidlConstantValue::Type::STRING: {
- generate_string_constant(interface.get(), constant->GetName(),
+ generate_string_constant(interface, constant->GetName(),
constant->ValueString(ConstantValueDecorator));
break;
}
- case AidlConstantValue::Type::BOOLEAN: // fall-through
- case AidlConstantValue::Type::INT8: // fall-through
- case AidlConstantValue::Type::INT32: {
- generate_int_constant(interface.get(), constant->GetName(),
+ case AidlConstantValue::Type::INTEGRAL:
+ case AidlConstantValue::Type::HEXIDECIMAL: {
+ generate_int_constant(interface, constant->GetName(),
constant->ValueString(ConstantValueDecorator));
break;
}
@@ -1039,7 +1042,13 @@
// all the declared methods of the interface
for (const auto& item : iface->GetMethods()) {
- generate_methods(*iface, *item, interface.get(), stub, proxy, item->GetId(), typenames,
+ generate_methods(*iface,
+ *item,
+ interface,
+ stub,
+ proxy,
+ item->GetId(),
+ types,
options);
}
@@ -1049,8 +1058,8 @@
// supported.
// TODO(b/111417145) make this conditional depending on the Java language
// version requested
- const string i_name = iface->GetCanonicalName();
- stub->elements.emplace_back(std::make_shared<LiteralClassElement>(
+ const string i_name = interfaceType->JavaType();
+ stub->elements.emplace_back(new LiteralClassElement(
StringPrintf("public static boolean setDefaultImpl(%s impl) {\n"
" if (Stub.Proxy.sDefaultImpl == null && impl != null) {\n"
" Stub.Proxy.sDefaultImpl = impl;\n"
@@ -1060,14 +1069,14 @@
"}\n",
i_name.c_str())));
stub->elements.emplace_back(
- std::make_shared<LiteralClassElement>(StringPrintf("public static %s getDefaultImpl() {\n"
- " return Stub.Proxy.sDefaultImpl;\n"
- "}\n",
- i_name.c_str())));
+ new LiteralClassElement(StringPrintf("public static %s getDefaultImpl() {\n"
+ " return Stub.Proxy.sDefaultImpl;\n"
+ "}\n",
+ i_name.c_str())));
// the static field is defined in the proxy class, not in the interface class
// because all fields in an interface class are by default final.
- proxy->elements.emplace_back(std::make_shared<LiteralClassElement>(
+ proxy->elements.emplace_back(new LiteralClassElement(
StringPrintf("public static %s sDefaultImpl;\n", i_name.c_str())));
stub->finish();
@@ -1076,5 +1085,5 @@
}
} // namespace java
-} // namespace aidl
} // namespace android
+} // namespace aidl
diff --git a/generate_ndk.cpp b/generate_ndk.cpp
index fc9cc20..f0445f7 100644
--- a/generate_ndk.cpp
+++ b/generate_ndk.cpp
@@ -93,59 +93,27 @@
CHECK(code_writer->Close());
}
-void GenerateNdkEnumDeclaration(const string& output_file, const Options& options,
- const AidlTypenames& types, const AidlEnumDeclaration& defined_type,
- const IoDelegate& io_delegate) {
- const string header_path =
- options.OutputHeaderDir() + NdkHeaderFile(defined_type, ClassNames::RAW);
- unique_ptr<CodeWriter> header_writer(io_delegate.GetCodeWriter(header_path));
- GenerateEnumHeader(*header_writer, types, defined_type, options);
- CHECK(header_writer->Close());
-
- const string bp_header =
- options.OutputHeaderDir() + NdkHeaderFile(defined_type, ClassNames::CLIENT);
- unique_ptr<CodeWriter> bp_writer(io_delegate.GetCodeWriter(bp_header));
- *bp_writer << "#error TODO(b/111362593) enums do not have bp classes\n";
- CHECK(bp_writer->Close());
-
- const string bn_header =
- options.OutputHeaderDir() + NdkHeaderFile(defined_type, ClassNames::SERVER);
- unique_ptr<CodeWriter> bn_writer(io_delegate.GetCodeWriter(bn_header));
- *bn_writer << "#error TODO(b/111362593) enums do not have bn classes\n";
- CHECK(bn_writer->Close());
-
- unique_ptr<CodeWriter> source_writer = io_delegate.GetCodeWriter(output_file);
- *source_writer
- << "// This file is intentionally left blank as placeholder for enum declaration.\n";
- CHECK(source_writer->Close());
-}
-
void GenerateNdk(const string& output_file, const Options& options, const AidlTypenames& types,
const AidlDefinedType& defined_type, const IoDelegate& io_delegate) {
- if (const AidlStructuredParcelable* parcelable = defined_type.AsStructuredParcelable();
- parcelable != nullptr) {
+ const AidlStructuredParcelable* parcelable = defined_type.AsStructuredParcelable();
+ if (parcelable != nullptr) {
GenerateNdkParcel(output_file, options, types, *parcelable, io_delegate);
return;
}
- if (const AidlParcelable* parcelable_decl = defined_type.AsParcelable();
- parcelable_decl != nullptr) {
+ const AidlParcelable* parcelable_decl = defined_type.AsParcelable();
+ if (parcelable_decl != nullptr) {
GenerateNdkParcelDeclaration(output_file, io_delegate);
return;
}
- if (const AidlEnumDeclaration* enum_decl = defined_type.AsEnumDeclaration();
- enum_decl != nullptr) {
- GenerateNdkEnumDeclaration(output_file, options, types, *enum_decl, io_delegate);
- return;
- }
-
- if (const AidlInterface* interface = defined_type.AsInterface(); interface != nullptr) {
+ const AidlInterface* interface = defined_type.AsInterface();
+ if (interface != nullptr) {
GenerateNdkInterface(output_file, options, types, *interface, io_delegate);
return;
}
- CHECK(false) << "Unrecognized type sent for NDK cpp generation.";
+ CHECK(false) << "Unrecognized type sent for cpp generation.";
}
namespace internals {
@@ -170,14 +138,7 @@
static void GenerateHeaderIncludes(CodeWriter& out, const AidlTypenames& types,
const AidlDefinedType& defined_type) {
- out << "#include <cstdint>\n";
- out << "#include <memory>\n";
- out << "#include <optional>\n";
- out << "#include <string>\n";
- out << "#include <vector>\n";
- out << "#ifdef BINDER_STABILITY_SUPPORT\n";
- out << "#include <android/binder_stability.h>\n";
- out << "#endif // BINDER_STABILITY_SUPPORT\n";
+ out << "#include <android/binder_parcel_utils.h>\n";
types.IterateTypes([&](const AidlDefinedType& other_defined_type) {
if (&other_defined_type == &defined_type) return;
@@ -190,9 +151,6 @@
<< NdkHeaderFile(other_defined_type, ClassNames::BASE, false /*use_os_sep*/) << ">\n";
} else if (other_defined_type.AsParcelable() != nullptr) {
out << "#include \"" << other_defined_type.AsParcelable()->GetCppHeader() << "\"\n";
- } else if (other_defined_type.AsEnumDeclaration() != nullptr) {
- out << "#include <"
- << NdkHeaderFile(other_defined_type, ClassNames::BASE, false /*use_os_sep*/) << ">\n";
} else {
AIDL_FATAL(defined_type) << "Unrecognized type.";
}
@@ -200,8 +158,6 @@
}
static void GenerateSourceIncludes(CodeWriter& out, const AidlTypenames& types,
const AidlDefinedType& /*defined_type*/) {
- out << "#include <android/binder_parcel_utils.h>\n";
-
types.IterateTypes([&](const AidlDefinedType& a_defined_type) {
if (a_defined_type.AsInterface() != nullptr) {
out << "#include <" << NdkHeaderFile(a_defined_type, ClassNames::CLIENT, false /*use_os_sep*/)
@@ -217,8 +173,6 @@
static void GenerateConstantDeclarations(CodeWriter& out, const AidlInterface& interface) {
for (const auto& constant : interface.GetConstantDeclarations()) {
const AidlConstantValue& value = constant->GetValue();
- CHECK(value.GetType() != AidlConstantValue::Type::UNARY &&
- value.GetType() != AidlConstantValue::Type::BINARY);
if (value.GetType() == AidlConstantValue::Type::STRING) {
out << "static const char* " << constant->GetName() << ";\n";
}
@@ -228,11 +182,8 @@
bool hasIntegralConstant = false;
for (const auto& constant : interface.GetConstantDeclarations()) {
const AidlConstantValue& value = constant->GetValue();
- CHECK(value.GetType() != AidlConstantValue::Type::UNARY &&
- value.GetType() != AidlConstantValue::Type::BINARY);
- if (value.GetType() == AidlConstantValue::Type::BOOLEAN ||
- value.GetType() == AidlConstantValue::Type::INT8 ||
- value.GetType() == AidlConstantValue::Type::INT32) {
+ if (value.GetType() == AidlConstantValue::Type::HEXIDECIMAL ||
+ value.GetType() == AidlConstantValue::Type::INTEGRAL) {
hasIntegralConstant = true;
break;
}
@@ -243,10 +194,9 @@
out.Indent();
for (const auto& constant : interface.GetConstantDeclarations()) {
const AidlConstantValue& value = constant->GetValue();
- if (value.GetType() == AidlConstantValue::Type::BOOLEAN ||
- value.GetType() == AidlConstantValue::Type::INT8 ||
- value.GetType() == AidlConstantValue::Type::INT32) {
- out << constant->GetName() << " = " << constant->ValueString(ConstantValueDecorator)
+ if (value.GetType() == AidlConstantValue::Type::HEXIDECIMAL ||
+ value.GetType() == AidlConstantValue::Type::INTEGRAL) {
+ out << constant->GetName() << " = " << constant->ValueString(AidlConstantValueDecorator)
<< ",\n";
}
}
@@ -259,11 +209,9 @@
for (const auto& constant : interface.GetConstantDeclarations()) {
const AidlConstantValue& value = constant->GetValue();
- CHECK(value.GetType() != AidlConstantValue::Type::UNARY &&
- value.GetType() != AidlConstantValue::Type::BINARY);
if (value.GetType() == AidlConstantValue::Type::STRING) {
out << "const char* " << clazz << "::" << constant->GetName() << " = "
- << constant->ValueString(ConstantValueDecorator) << ";\n";
+ << constant->ValueString(AidlConstantValueDecorator) << ";\n";
}
}
}
@@ -338,11 +286,7 @@
out << MethodId(method) << ",\n";
out << "_aidl_in.getR(),\n";
out << "_aidl_out.getR(),\n";
- out << (method.IsOneway() ? "FLAG_ONEWAY" : "0") << "\n";
- out << "#ifdef BINDER_STABILITY_SUPPORT\n";
- out << "| FLAG_PRIVATE_LOCAL\n";
- out << "#endif // BINDER_STABILITY_SUPPORT\n";
- out << ");\n";
+ out << (method.IsOneway() ? "FLAG_ONEWAY" : "0") << ");\n";
out.Dedent();
// If the method is not implmented in the server side but the client has
@@ -490,7 +434,7 @@
}
out << "return _aidl_ret_status;\n";
out.Dedent();
- out << "}\n\n";
+ out << "};\n\n";
out << "static AIBinder_Class* " << kClazz << " = ::ndk::ICInterface::defineClass(" << clazz
<< "::" << kDescriptor << ", _aidl_onTransact);\n\n";
@@ -529,15 +473,6 @@
out << "::ndk::SpAIBinder " << clazz << "::createBinder() {\n";
out.Indent();
out << "AIBinder* binder = AIBinder_new(" << kClazz << ", static_cast<void*>(this));\n";
-
- out << "#ifdef BINDER_STABILITY_SUPPORT\n";
- if (defined_type.IsVintfStability()) {
- out << "AIBinder_markVintfStability(binder);\n";
- } else {
- out << "AIBinder_markCompilationUnitStability(binder);\n";
- }
- out << "#endif // BINDER_STABILITY_SUPPORT\n";
-
out << "return ::ndk::SpAIBinder(binder);\n";
out.Dedent();
out << "}\n";
@@ -838,7 +773,7 @@
for (const auto& variable : defined_type.GetFields()) {
out << NdkNameOf(types, variable->GetType(), StorageMode::STACK) << " " << variable->GetName();
if (variable->GetDefaultValue()) {
- out << " = " << variable->ValueString(ConstantValueDecorator);
+ out << " = " << variable->ValueString(AidlConstantValueDecorator);
}
out << ";\n";
}
@@ -925,27 +860,6 @@
out << "\n";
LeaveNdkNamespace(out, defined_type);
}
-
-void GenerateEnumHeader(CodeWriter& out, const AidlTypenames& types,
- const AidlEnumDeclaration& enum_decl, const Options& /*options*/) {
- out << "#pragma once\n";
- out << "\n";
-
- GenerateHeaderIncludes(out, types, enum_decl);
-
- EnterNdkNamespace(out, enum_decl);
- out << "enum class " << enum_decl.GetName() << " : "
- << NdkNameOf(types, enum_decl.GetBackingType(), StorageMode::STACK) << " {\n";
- out.Indent();
- for (const auto& enumerator : enum_decl.GetEnumerators()) {
- out << enumerator->GetName() << " = "
- << enumerator->ValueString(enum_decl.GetBackingType(), ConstantValueDecorator) << ",\n";
- }
- out.Dedent();
- out << "};\n";
- LeaveNdkNamespace(out, enum_decl);
-}
-
} // namespace internals
} // namespace ndk
} // namespace aidl
diff --git a/generate_ndk.h b/generate_ndk.h
index 94a7669..740883e 100644
--- a/generate_ndk.h
+++ b/generate_ndk.h
@@ -52,9 +52,6 @@
void GenerateParcelSource(CodeWriter& out, const AidlTypenames& types,
const AidlStructuredParcelable& defined_type, const Options& options);
-void GenerateEnumHeader(CodeWriter& out, const AidlTypenames& types,
- const AidlEnumDeclaration& enum_decl, const Options& options);
-
} // namespace internals
} // namespace ndk
} // namespace aidl
diff --git a/import_resolver.cpp b/import_resolver.cpp
index 0500cf8..4e4176f 100644
--- a/import_resolver.cpp
+++ b/import_resolver.cpp
@@ -17,8 +17,6 @@
#include "import_resolver.h"
#include "aidl_language.h"
-#include <algorithm>
-
#include <android-base/file.h>
#include <android-base/strings.h>
#include <unistd.h>
@@ -67,10 +65,6 @@
found_paths.emplace_back(path);
}
}
- // remove duplicates
- std::sort(found_paths.begin(), found_paths.end());
- auto last = std::unique(found_paths.begin(), found_paths.end());
- found_paths.erase(last, found_paths.end());
int num_found = found_paths.size();
if (num_found == 0) {
@@ -92,5 +86,5 @@
}
}
-} // namespace aidl
} // namespace android
+} // namespace aidl
diff --git a/import_resolver.h b/import_resolver.h
index 0a34e05..569c94f 100644
--- a/import_resolver.h
+++ b/import_resolver.h
@@ -47,5 +47,5 @@
DISALLOW_COPY_AND_ASSIGN(ImportResolver);
};
-} // namespace aidl
} // namespace android
+} // namespace aidl
diff --git a/io_delegate.h b/io_delegate.h
index a53bb8f..70556ad 100644
--- a/io_delegate.h
+++ b/io_delegate.h
@@ -65,5 +65,5 @@
DISALLOW_COPY_AND_ASSIGN(IoDelegate);
}; // class IoDelegate
-} // namespace aidl
} // namespace android
+} // namespace aidl
diff --git a/io_delegate_unittest.cpp b/io_delegate_unittest.cpp
index 39982bc..5227d0b 100644
--- a/io_delegate_unittest.cpp
+++ b/io_delegate_unittest.cpp
@@ -42,5 +42,5 @@
EXPECT_EQ(absolute_path[0], '/');
}
-} // namespace aidl
} // namespace android
+} // namespace aidl
diff --git a/line_reader.cpp b/line_reader.cpp
index 66446c0..5e076d8 100644
--- a/line_reader.cpp
+++ b/line_reader.cpp
@@ -87,5 +87,5 @@
return unique_ptr<LineReader>(new MemoryLineReader(contents));
}
-} // namespace aidl
} // namespace android
+} // namespace aidl
diff --git a/line_reader.h b/line_reader.h
index 5883af4..baf9c06 100644
--- a/line_reader.h
+++ b/line_reader.h
@@ -39,5 +39,5 @@
DISALLOW_COPY_AND_ASSIGN(LineReader);
}; // class LineReader
-} // namespace aidl
} // namespace android
+} // namespace aidl
diff --git a/main.cpp b/main.cpp
index 1199579..d21819a 100644
--- a/main.cpp
+++ b/main.cpp
@@ -25,6 +25,11 @@
using android::aidl::Options;
+// aidl is leaky. Turn off LeakSanitizer by default. b/37749857
+extern "C" const char* __asan_default_options() {
+ return "detect_leaks=0";
+}
+
int main(int argc, char* argv[]) {
android::base::InitLogging(argv);
LOG(DEBUG) << "aidl starting";
diff --git a/main_cpp.cpp b/main_cpp.cpp
index 5cb778c..72b3ffb 100644
--- a/main_cpp.cpp
+++ b/main_cpp.cpp
@@ -23,6 +23,11 @@
using android::aidl::Options;
+// aidl is leaky. Turn off LeakSanitizer by default. b/37749857
+extern "C" const char *__asan_default_options() {
+ return "detect_leaks=0";
+}
+
int main(int argc, char* argv[]) {
android::base::InitLogging(argv);
LOG(DEBUG) << "aidl starting";
diff --git a/options.cpp b/options.cpp
index fa34a9d..ff99dad 100644
--- a/options.cpp
+++ b/options.cpp
@@ -39,7 +39,7 @@
string Options::GetUsage() const {
std::ostringstream sstr;
sstr << "usage:" << endl
- << myname_ << " --lang={java|cpp|ndk} [OPTION]... INPUT..." << endl
+ << myname_ << " --lang={java|cpp} [OPTION]... INPUT..." << endl
<< " Generate Java or C++ files for AIDL file(s)." << endl
<< endl
<< myname_ << " --preprocess OUTPUT INPUT..." << endl
@@ -90,8 +90,6 @@
<< " --structured" << endl
<< " Whether this interface is defined exclusively in AIDL." << endl
<< " It is therefore a candidate for stabilization." << endl
- << " --stability=<level>" << endl
- << " The stability requirement of this interface." << endl
<< " -t, --trace" << endl
<< " Include tracing code for systrace. Note that if either" << endl
<< " the client or service code is not auto-generated by this" << endl
@@ -112,9 +110,6 @@
<< " --log" << endl
<< " Information about the transaction, e.g., method name, argument" << endl
<< " values, execution time, etc., is provided via callback." << endl
- << " --parcelable-to-string" << endl
- << " Generates an implementation of toString() for Java parcelables," << endl
- << " and ostream& operator << for C++ parcelables." << endl
<< " --help" << endl
<< " Show this help." << endl
<< endl
@@ -133,14 +128,6 @@
return sstr.str();
}
-bool Options::StabilityFromString(const std::string& stability, Stability* out_stability) {
- if (stability == "vintf") {
- *out_stability = Stability::VINTF;
- return true;
- }
- return false;
-}
-
Options Options::From(const string& cmdline) {
vector<string> args = Split(cmdline, " ");
return From(args);
@@ -181,13 +168,11 @@
{"out", required_argument, 0, 'o'},
{"header_out", required_argument, 0, 'h'},
{"ninja", no_argument, 0, 'n'},
- {"stability", required_argument, 0, 'Y'},
{"structured", no_argument, 0, 'S'},
{"trace", no_argument, 0, 't'},
{"transaction_names", no_argument, 0, 'c'},
{"version", required_argument, 0, 'v'},
{"log", no_argument, 0, 'L'},
- {"parcelable-to-string", no_argument, 0, 'P'},
{"help", no_argument, 0, 'e'},
{0, 0, 0, 0},
};
@@ -273,15 +258,6 @@
case 'S':
structured_ = true;
break;
- case 'Y': {
- const string stability_str = Trim(optarg);
- if (!StabilityFromString(stability_str, &stability_)) {
- error_message_ << "Unrecognized stability level: '" << stability_str
- << "'. Must be vintf." << endl;
- return;
- }
- break;
- }
case 't':
gen_traces_ = true;
break;
@@ -316,9 +292,6 @@
output_file_ = Trim(optarg);
task_ = Task::DUMP_MAPPINGS;
break;
- case 'P':
- gen_parcelable_to_string_ = true;
- break;
default:
std::cerr << GetUsage();
exit(1);
@@ -463,5 +436,5 @@
CHECK(output_header_dir_.empty() || output_header_dir_.back() == OS_PATH_SEPARATOR);
}
-} // namespace aidl
} // namespace android
+} // namespace aidl
diff --git a/options.h b/options.h
index 43334a7..403301d 100644
--- a/options.h
+++ b/options.h
@@ -63,9 +63,6 @@
enum class Task { UNSPECIFIED, COMPILE, PREPROCESS, DUMP_API, CHECK_API, DUMP_MAPPINGS };
- enum class Stability { UNSPECIFIED, VINTF };
- bool StabilityFromString(const std::string& stability, Stability* out_stability);
-
Options(int argc, const char* const argv[], Language default_lang = Language::UNSPECIFIED);
static Options From(const string& cmdline);
@@ -77,8 +74,6 @@
// capacity to be stabilized.
bool IsStructured() const { return structured_; }
- Stability GetStability() const { return stability_; }
-
Language TargetLanguage() const { return language_; }
bool IsCppOutput() const { return language_ == Language::CPP || language_ == Language::NDK; }
@@ -123,8 +118,6 @@
bool GenLog() const { return gen_log_; }
- bool GenParcelableToString() const { return gen_parcelable_to_string_; }
-
bool Ok() const { return error_message_.stream_.str().empty(); }
string GetErrorMessage() const { return error_message_.stream_.str(); }
@@ -143,6 +136,7 @@
Options() = default;
const string myname_;
+ bool structured_ = false;
Language language_ = Language::UNSPECIFIED;
Task task_ = Task::COMPILE;
set<string> import_dirs_;
@@ -152,8 +146,6 @@
bool gen_traces_ = false;
bool gen_transaction_names_ = false;
bool dependency_file_ninja_ = false;
- bool structured_ = false;
- Stability stability_ = Stability::UNSPECIFIED;
string output_dir_;
string output_header_dir_;
bool fail_on_parcelable_ = false;
@@ -162,9 +154,8 @@
string output_file_;
int version_ = 0;
bool gen_log_ = false;
- bool gen_parcelable_to_string_ = false;
ErrorMessage error_message_;
};
-} // namespace aidl
} // namespace android
+} // namespace aidl
diff --git a/options_unittest.cpp b/options_unittest.cpp
index 97b4c0c..27cfb9d 100644
--- a/options_unittest.cpp
+++ b/options_unittest.cpp
@@ -135,23 +135,6 @@
EXPECT_EQ(string{kCompileCommandJavaOutput}, options->OutputFile());
EXPECT_EQ(false, options->AutoDepFile());
EXPECT_EQ(false, options->DependencyFileNinja());
- EXPECT_EQ(false, options->GenParcelableToString());
-
- const char* argv[] = {
- "aidl", "-b", kCompileCommandIncludePath, kCompileCommandInput, "--parcelable-to-string",
- nullptr,
- };
- options = GetOptions(argv);
- EXPECT_EQ(Options::Task::COMPILE, options->GetTask());
- EXPECT_EQ(Options::Language::JAVA, options->TargetLanguage());
- EXPECT_EQ(true, options->FailOnParcelable());
- EXPECT_EQ(1u, options->ImportDirs().size());
- EXPECT_EQ(0u, options->PreprocessedFiles().size());
- EXPECT_EQ(string{kCompileCommandInput}, options->InputFiles().front());
- EXPECT_EQ(string{kCompileCommandJavaOutput}, options->OutputFile());
- EXPECT_EQ(false, options->AutoDepFile());
- EXPECT_EQ(false, options->DependencyFileNinja());
- EXPECT_EQ(true, options->GenParcelableToString());
}
TEST(OptionsTests, ParsesCompileJavaNinja) {
@@ -176,27 +159,6 @@
EXPECT_EQ(kCompileCommandInput, options->InputFiles().front());
EXPECT_EQ(kCompileCommandHeaderDir, options->OutputHeaderDir());
EXPECT_EQ(kCompileCommandCppOutput, options->OutputFile());
- EXPECT_EQ(false, options->GenParcelableToString());
-
- const char* argv[] = {
- "aidl-cpp",
- kCompileCommandIncludePath,
- kCompileDepFile,
- kCompileCommandInput,
- kCompileCommandHeaderDir,
- kCompileCommandCppOutput,
- "--parcelable-to-string",
- nullptr,
- };
- options = GetOptions(argv, Options::Language::CPP);
- ASSERT_EQ(1u, options->ImportDirs().size());
- EXPECT_EQ(string{kCompileCommandIncludePath}.substr(2), *options->ImportDirs().begin());
- EXPECT_EQ(string{kCompileDepFile}.substr(2), options->DependencyFile());
- EXPECT_EQ(false, options->DependencyFileNinja());
- EXPECT_EQ(kCompileCommandInput, options->InputFiles().front());
- EXPECT_EQ(kCompileCommandHeaderDir, options->OutputHeaderDir());
- EXPECT_EQ(kCompileCommandCppOutput, options->OutputFile());
- EXPECT_EQ(true, options->GenParcelableToString());
}
TEST(OptionsTests, ParsesCompileCppNinja) {
@@ -314,5 +276,5 @@
EXPECT_EQ(false, GetOptions(arg_with_no_header_dir)->Ok());
}
-} // namespace aidl
} // namespace android
+} // namespace aidl
diff --git a/runtests.sh b/runtests.sh
index 5f99122..aff108f 100755
--- a/runtests.sh
+++ b/runtests.sh
@@ -20,16 +20,22 @@
fi
echo "Running tests"
-set -ex
+set -e # fail early
+# NOTE We can't actually run these commands, since they rely on functions added
+# by build/envsetup.sh to the bash shell environment.
+echo "+ mmma $ANDROID_BUILD_TOP/system/tools/aidl"
$ANDROID_BUILD_TOP/build/soong/soong_ui.bash --make-mode \
MODULES-IN-system-tools-aidl
+set -x # print commands
${ANDROID_HOST_OUT}/nativetest64/aidl_unittests/aidl_unittests
adb root
-adb sync data
+adb wait-for-device
+adb remount
+adb sync
adb install -r \
${ANDROID_PRODUCT_OUT}/system/app/aidl_test_services/aidl_test_services.apk
${ANDROID_BUILD_TOP}/system/tools/aidl/tests/integration-test.py
diff --git a/runtests_asan.sh b/runtests_asan.sh
deleted file mode 100755
index b796fba..0000000
--- a/runtests_asan.sh
+++ /dev/null
@@ -1,21 +0,0 @@
-#!/usr/bin/env bash
-
-# Copyright (C) 2019 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-export ASAN_OPTIONS=""
-export SANITIZE_HOST=address
-
-./runtests.sh
-
diff --git a/tests/aidl_parser_fuzzer.cpp b/tests/aidl_parser_fuzzer.cpp
deleted file mode 100644
index a3269ce..0000000
--- a/tests/aidl_parser_fuzzer.cpp
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "aidl.h"
-#include "fake_io_delegate.h"
-#include "options.h"
-
-#include <iostream>
-
-#ifdef FUZZ_LOG
-constexpr bool kFuzzLog = true;
-#else
-constexpr bool kFuzzLog = false;
-#endif
-
-using android::aidl::test::FakeIoDelegate;
-
-void fuzz(uint8_t options, const std::string& content) {
- uint8_t lang = options & 0x3;
- std::string langOpt;
- switch (lang) {
- case 1:
- langOpt = "cpp";
- break;
- case 2:
- langOpt = "ndk";
- break;
- case 3:
- langOpt = "java";
- break;
- default:
- return;
- }
-
- // TODO: fuzz multiple files
- // TODO: fuzz arguments
- FakeIoDelegate io;
- io.SetFileContents("a/path/Foo.aidl", content);
-
- std::vector<std::string> args;
- args.emplace_back("aidl");
- args.emplace_back("--lang=" + langOpt);
- args.emplace_back("-b");
- args.emplace_back("-I .");
- args.emplace_back("-o out");
- // corresponding items also in aidl_parser_fuzzer.dict
- args.emplace_back("a/path/Foo.aidl");
-
- if (kFuzzLog) {
- std::cout << "lang: " << langOpt << " content: " << content << std::endl;
- }
-
- int ret = android::aidl::compile_aidl(Options::From(args), io);
- if (ret != 0) return;
-
- if (kFuzzLog) {
- for (const std::string& f : io.ListOutputFiles()) {
- std::string output;
- if (io.GetWrittenContents(f, &output)) {
- std::cout << "OUTPUT " << f << ": " << std::endl;
- std::cout << output << std::endl;
- }
- }
- }
-}
-
-extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
- if (size <= 1) return 0; // no use
-
- uint8_t options = *data;
- data++;
- size--;
-
- std::string content(reinterpret_cast<const char*>(data), size);
- fuzz(options, content);
-
- return 0;
-}
diff --git a/tests/aidl_parser_fuzzer.dict b/tests/aidl_parser_fuzzer.dict
deleted file mode 100644
index 1f882a0..0000000
--- a/tests/aidl_parser_fuzzer.dict
+++ /dev/null
@@ -1,62 +0,0 @@
-# keywords
-" parcelable "
-" import "
-" package "
-" in "
-" out "
-" inout "
-" cpp_header "
-" const "
-" true "
-" false "
-" interface "
-" oneway "
-" enum "
-
-# types
-" void "
-" boolean "
-" byte "
-" char "
-" int "
-" long "
-" float "
-" double "
-" String "
-" List "
-" Map "
-" IBinder "
-" FileDescriptor "
-" CharSequence "
-" ParcelFileDescriptor "
-" java.util.List "
-" java.util.Map "
-" android.os.ParcelFileDescriptor "
-
-# annotations
-" @nullable "
-" @utf8InCpp "
-" @VintfStability "
-" @UnsupportedAppUsage "
-" @SystemApi "
-" @JavaOnlyStableParcelable "
-" @Backing "
-" expectedSignature "
-" implicitMember "
-" maxTargetSdk "
-" publicAlternatives "
-" trackingBug "
-" type "
-
-# ignorable imports
-" android.os.IInterface "
-" android.os.IBinder "
-" android.os.Parcelable "
-" android.os.Parcel "
-" android.content.Context "
-" java.lang.String "
-
-# specific to fuzzer
-" a.path "
-" Foo "
-
diff --git a/tests/aidl_test_client.cpp b/tests/aidl_test_client.cpp
index 678edc5..f4850b0 100644
--- a/tests/aidl_test_client.cpp
+++ b/tests/aidl_test_client.cpp
@@ -90,12 +90,8 @@
if (!client_tests::ConfirmPersistableBundles(service)) return 1;
- if (!client_tests::ConfirmIntfConstantExpressions(service)) return 1;
-
if (!client_tests::ConfirmStructuredParcelables(service)) return 1;
- if (!client_tests::ConfirmStructuredParcelablesEquality(service)) return 1;
-
if (!client_tests::ConfirmFileDescriptors(service)) return 1;
if (!client_tests::ConfirmFileDescriptorArrays(service)) return 1;
diff --git a/tests/aidl_test_client_nullables.cpp b/tests/aidl_test_client_nullables.cpp
index f4eab3a..805827c 100644
--- a/tests/aidl_test_client_nullables.cpp
+++ b/tests/aidl_test_client_nullables.cpp
@@ -31,10 +31,7 @@
using android::binder::Status;
// generated
-using android::aidl::tests::ByteEnum;
-using android::aidl::tests::IntEnum;
using android::aidl::tests::ITestService;
-using android::aidl::tests::LongEnum;
using android::aidl::tests::SimpleParcelable;
using std::string;
@@ -235,27 +232,6 @@
return false;
}
- if (!ConfirmNullableType(
- s, "byte enum array",
- unique_ptr<vector<ByteEnum>>(new vector<ByteEnum>({ByteEnum::FOO, ByteEnum::BAR})),
- &ITestService::RepeatNullableByteEnumArray)) {
- return false;
- }
-
- if (!ConfirmNullableType(
- s, "int enum array",
- unique_ptr<vector<IntEnum>>(new vector<IntEnum>({IntEnum::FOO, IntEnum::BAR})),
- &ITestService::RepeatNullableIntEnumArray)) {
- return false;
- }
-
- if (!ConfirmNullableType(
- s, "long enum array",
- unique_ptr<vector<LongEnum>>(new vector<LongEnum>({LongEnum::FOO, LongEnum::BAR})),
- &ITestService::RepeatNullableLongEnumArray)) {
- return false;
- }
-
if (!ConfirmNullableType(s, "string",
unique_ptr<String16>(new String16("Blooob")),
&ITestService::RepeatNullableString)) {
diff --git a/tests/aidl_test_client_parcelables.cpp b/tests/aidl_test_client_parcelables.cpp
index cc89270..7f52d73 100644
--- a/tests/aidl_test_client_parcelables.cpp
+++ b/tests/aidl_test_client_parcelables.cpp
@@ -26,7 +26,6 @@
using android::binder::Status;
// generated
-using android::aidl::tests::ConstantExpressionEnum;
using android::aidl::tests::ITestService;
using android::aidl::tests::SimpleParcelable;
using android::os::PersistableBundle;
@@ -146,69 +145,7 @@
return true;
}
-bool ConfirmStructuredParcelablesEquality(const sp<ITestService>& s) {
- StructuredParcelable parcelable1;
- StructuredParcelable parcelable2;
-
- parcelable1.f = 11;
- parcelable2.f = 11;
-
- s->FillOutStructuredParcelable(&parcelable1);
- s->FillOutStructuredParcelable(&parcelable2);
-
- sp<INamedCallback> callback1;
- sp<INamedCallback> callback2;
- s->GetOtherTestService(String16("callback1"), &callback1);
- s->GetOtherTestService(String16("callback2"), &callback2);
-
- parcelable1.ibinder = IInterface::asBinder(callback1);
- parcelable2.ibinder = IInterface::asBinder(callback1);
-
- if (parcelable1 != parcelable2) {
- cout << "parcelable1 and parcelable2 should be same." << endl;
- return false;
- }
- parcelable1.f = 0;
- if (parcelable1 >= parcelable2) {
- cout << "parcelable1 and parcelable2 should be different because of shouldContainThreeFs"
- << endl;
- return false;
- }
- parcelable1.f = 11;
-
- parcelable1.shouldBeJerry = "Jarry";
- if (!(parcelable1 < parcelable2)) {
- cout << "parcelable1 and parcelable2 should be different because of shouldContainThreeFs"
- << endl;
- return false;
- }
- parcelable1.shouldBeJerry = "Jerry";
-
- parcelable2.shouldContainThreeFs = {};
- if (parcelable1 <= parcelable2) {
- cout << "parcelable1 and parcelable2 should be different because of shouldContainThreeFs"
- << endl;
- return false;
- }
- parcelable2.shouldContainThreeFs = {parcelable2.f, parcelable2.f, parcelable2.f};
-
- parcelable2.shouldBeIntBar = IntEnum::FOO;
- if (!(parcelable1 > parcelable2)) {
- cout << "parcelable1 and parcelable2 should be different because of shouldBeIntBar" << endl;
- return false;
- }
- parcelable2.shouldBeIntBar = IntEnum::BAR;
-
- parcelable2.ibinder = IInterface::asBinder(callback2);
- if (parcelable1 == parcelable2) {
- cout << "parcelable1 and parcelable2 should be different because of ibinder" << endl;
- return false;
- }
- return true;
-}
-
bool ConfirmStructuredParcelables(const sp<ITestService>& s) {
- bool success = true;
constexpr int kDesiredValue = 23;
StructuredParcelable parcelable;
@@ -284,119 +221,6 @@
return false;
}
- if (parcelable.int32_min != INT32_MIN) {
- cout << "int32_min should be " << INT32_MIN << "but is " << parcelable.int32_min << endl;
- return false;
- }
-
- if (parcelable.int32_max != INT32_MAX) {
- cout << "int32_max should be " << INT32_MAX << "but is " << parcelable.int32_max << endl;
- return false;
- }
-
- if (parcelable.int64_max != INT64_MAX) {
- cout << "int64_max should be " << INT64_MAX << "but is " << parcelable.int64_max << endl;
- return false;
- }
-
- if (parcelable.hexInt32_neg_1 != -1) {
- cout << "hexInt32_neg_1 should be -1 but is " << parcelable.hexInt32_neg_1 << endl;
- return false;
- }
-
- for (size_t ndx = 0; ndx < parcelable.int32_1.size(); ndx++) {
- if (parcelable.int32_1[ndx] != 1) {
- cout << "int32_1[" << ndx << "] should be 1 but is " << parcelable.int32_1[ndx] << endl;
- success = false;
- }
- }
- if (!success) {
- return false;
- }
-
- for (size_t ndx = 0; ndx < parcelable.int64_1.size(); ndx++) {
- if (parcelable.int64_1[ndx] != 1) {
- cout << "int64_1[" << ndx << "] should be 1 but is " << parcelable.int64_1[ndx] << endl;
- success = false;
- }
- }
- if (!success) {
- return false;
- }
-
- if (static_cast<int>(parcelable.hexInt32_pos_1) != 1) {
- cout << "hexInt32_pos_1 should be 1 but is " << parcelable.hexInt32_pos_1 << endl;
- return false;
- }
-
- if (parcelable.hexInt64_pos_1 != 1) {
- cout << "hexInt64_pos_1 should be 1 but is " << parcelable.hexInt64_pos_1 << endl;
- return false;
- }
-
- if (static_cast<int>(parcelable.const_exprs_1) != 1) {
- cout << "parcelable.const_exprs_1 should be 1 but is "
- << static_cast<int>(parcelable.const_exprs_1) << endl;
- return false;
- }
- if (static_cast<int>(parcelable.const_exprs_2) != 1) {
- cout << "parcelable.const_exprs_2 should be 1 but is "
- << static_cast<int>(parcelable.const_exprs_2) << endl;
- return false;
- }
- if (static_cast<int>(parcelable.const_exprs_3) != 1) {
- cout << "parcelable.const_exprs_3 should be 1 but is "
- << static_cast<int>(parcelable.const_exprs_3) << endl;
- return false;
- }
- if (static_cast<int>(parcelable.const_exprs_4) != 1) {
- cout << "parcelable.const_exprs_4 should be 1 but is "
- << static_cast<int>(parcelable.const_exprs_4) << endl;
- return false;
- }
- if (static_cast<int>(parcelable.const_exprs_5) != 1) {
- cout << "parcelable.const_exprs_5 should be 1 but is "
- << static_cast<int>(parcelable.const_exprs_5) << endl;
- return false;
- }
- if (static_cast<int>(parcelable.const_exprs_6) != 1) {
- cout << "parcelable.const_exprs_6 should be 1 but is "
- << static_cast<int>(parcelable.const_exprs_6) << endl;
- return false;
- }
- if (static_cast<int>(parcelable.const_exprs_7) != 1) {
- cout << "parcelable.const_exprs_7 should be 1 but is "
- << static_cast<int>(parcelable.const_exprs_7) << endl;
- return false;
- }
- if (static_cast<int>(parcelable.const_exprs_8) != 1) {
- cout << "parcelable.const_exprs_8 should be 1 but is "
- << static_cast<int>(parcelable.const_exprs_8) << endl;
- return false;
- }
- if (static_cast<int>(parcelable.const_exprs_9) != 1) {
- cout << "parcelable.const_exprs_9 should be 1 but is "
- << static_cast<int>(parcelable.const_exprs_9) << endl;
- return false;
- }
- if (static_cast<int>(parcelable.const_exprs_10) != 1) {
- cout << "parcelable.const_exprs_10 should be 1 but is "
- << static_cast<int>(parcelable.const_exprs_10) << endl;
- return false;
- }
-
- if (parcelable.addString1 != "hello world!") {
- cout << "parcelable.addString1 should be \"hello world!\" but is \"" << parcelable.addString1
- << "\"" << endl;
- return false;
- }
- if (parcelable.addString2 != "The quick brown fox jumps over the lazy dog.") {
- cout << "parcelable.addString2 should be \"The quick brown fox jumps over the lazy dog.\""
- " but is \""
- << parcelable.addString2 << "\"" << endl;
- return false;
- }
-
return true;
}
diff --git a/tests/aidl_test_client_parcelables.h b/tests/aidl_test_client_parcelables.h
index 3031ad4..168f6cd 100644
--- a/tests/aidl_test_client_parcelables.h
+++ b/tests/aidl_test_client_parcelables.h
@@ -30,7 +30,6 @@
bool ConfirmSimpleParcelables(const sp<ITestService>& s);
bool ConfirmPersistableBundles(const sp<ITestService>& s);
bool ConfirmStructuredParcelables(const sp<ITestService>& s);
-bool ConfirmStructuredParcelablesEquality(const sp<ITestService>& s);
} // namespace client
} // namespace tests
diff --git a/tests/aidl_test_client_primitives.cpp b/tests/aidl_test_client_primitives.cpp
index 2733800..98df528 100644
--- a/tests/aidl_test_client_primitives.cpp
+++ b/tests/aidl_test_client_primitives.cpp
@@ -21,11 +21,10 @@
#include <utils/String16.h>
#include <utils/String8.h>
+#include <binder/Value.h>
+#include <binder/Map.h>
-#include "android/aidl/tests/ByteEnum.h"
#include "android/aidl/tests/INamedCallback.h"
-#include "android/aidl/tests/IntEnum.h"
-#include "android/aidl/tests/LongEnum.h"
#include "test_helpers.h"
@@ -36,6 +35,8 @@
// libbinder:
using android::binder::Status;
+using android::binder::Value;
+using android::binder::Map;
// generated
using android::aidl::tests::ITestService;
@@ -54,28 +55,44 @@
bool ConfirmPrimitiveRepeat(const sp<ITestService>& s) {
cout << "Confirming passing and returning primitives works." << endl;
+ Map test_map;
+ test_map["first_val"] = int8_t{-128};
+ test_map["second_val"] = int32_t{1 << 30};
+ test_map["third_val"] = String16("OHAI");
+
if (!RepeatPrimitive(s, &ITestService::RepeatBoolean, true) ||
!RepeatPrimitive(s, &ITestService::RepeatByte, int8_t{-128}) ||
!RepeatPrimitive(s, &ITestService::RepeatChar, char16_t{'A'}) ||
!RepeatPrimitive(s, &ITestService::RepeatInt, int32_t{1 << 30}) ||
!RepeatPrimitive(s, &ITestService::RepeatLong, int64_t{1LL << 60}) ||
- !RepeatPrimitive(s, &ITestService::RepeatFloat, float{1.0f / 3.0f}) ||
- !RepeatPrimitive(s, &ITestService::RepeatDouble, double{1.0 / 3.0}) ||
- !RepeatPrimitive(s, &ITestService::RepeatInt, ITestService::TEST_CONSTANT) ||
- !RepeatPrimitive(s, &ITestService::RepeatInt, ITestService::TEST_CONSTANT2) ||
- !RepeatPrimitive(s, &ITestService::RepeatInt, ITestService::TEST_CONSTANT3) ||
- !RepeatPrimitive(s, &ITestService::RepeatInt, ITestService::TEST_CONSTANT4) ||
- !RepeatPrimitive(s, &ITestService::RepeatInt, ITestService::TEST_CONSTANT5) ||
- !RepeatPrimitive(s, &ITestService::RepeatInt, ITestService::TEST_CONSTANT6) ||
- !RepeatPrimitive(s, &ITestService::RepeatInt, ITestService::TEST_CONSTANT7) ||
- !RepeatPrimitive(s, &ITestService::RepeatInt, ITestService::TEST_CONSTANT8) ||
- !RepeatPrimitive(s, &ITestService::RepeatInt, ITestService::TEST_CONSTANT9) ||
- !RepeatPrimitive(s, &ITestService::RepeatInt, ITestService::TEST_CONSTANT10) ||
- !RepeatPrimitive(s, &ITestService::RepeatInt, ITestService::TEST_CONSTANT11) ||
- !RepeatPrimitive(s, &ITestService::RepeatInt, ITestService::TEST_CONSTANT12) ||
- !RepeatPrimitive(s, &ITestService::RepeatByteEnum, ByteEnum::FOO) ||
- !RepeatPrimitive(s, &ITestService::RepeatIntEnum, IntEnum::BAR) ||
- !RepeatPrimitive(s, &ITestService::RepeatLongEnum, LongEnum::FOO)) {
+ !RepeatPrimitive(s, &ITestService::RepeatFloat, float{1.0f/3.0f}) ||
+ !RepeatPrimitive(s, &ITestService::RepeatDouble, double{1.0/3.0}) ||
+ !RepeatPrimitive(s, &ITestService::RepeatMap, test_map) ||
+ !RepeatPrimitive(
+ s, &ITestService::RepeatInt, ITestService::TEST_CONSTANT) ||
+ !RepeatPrimitive(
+ s, &ITestService::RepeatInt, ITestService::TEST_CONSTANT2) ||
+ !RepeatPrimitive(
+ s, &ITestService::RepeatInt, ITestService::TEST_CONSTANT3) ||
+ !RepeatPrimitive(
+ s, &ITestService::RepeatInt, ITestService::TEST_CONSTANT4) ||
+ !RepeatPrimitive(
+ s, &ITestService::RepeatInt, ITestService::TEST_CONSTANT5) ||
+ !RepeatPrimitive(
+ s, &ITestService::RepeatInt, ITestService::TEST_CONSTANT6) ||
+ !RepeatPrimitive(
+ s, &ITestService::RepeatInt, ITestService::TEST_CONSTANT7) ||
+ !RepeatPrimitive(
+ s, &ITestService::RepeatInt, ITestService::TEST_CONSTANT8) ||
+ !RepeatPrimitive(
+ s, &ITestService::RepeatInt, ITestService::TEST_CONSTANT9) ||
+ !RepeatPrimitive(
+ s, &ITestService::RepeatInt, ITestService::TEST_CONSTANT10) ||
+ !RepeatPrimitive(
+ s, &ITestService::RepeatInt, ITestService::TEST_CONSTANT11) ||
+ !RepeatPrimitive(
+ s, &ITestService::RepeatInt, ITestService::TEST_CONSTANT12)
+ ) {
return false;
}
@@ -106,20 +123,22 @@
bool ConfirmReverseArrays(const sp<ITestService>& s) {
cout << "Confirming passing and returning arrays works." << endl;
- if (!ReverseArray(s, &ITestService::ReverseBoolean, {true, false, false}) ||
- !ReverseArray(s, &ITestService::ReverseByte, {uint8_t{255}, uint8_t{0}, uint8_t{127}}) ||
- !ReverseArray(s, &ITestService::ReverseChar, {char16_t{'A'}, char16_t{'B'}, char16_t{'C'}}) ||
- !ReverseArray(s, &ITestService::ReverseInt, {1, 2, 3}) ||
- !ReverseArray(s, &ITestService::ReverseLong, {-1LL, 0LL, int64_t{1LL << 60}}) ||
- !ReverseArray(s, &ITestService::ReverseFloat, {-0.3f, -0.7f, 8.0f}) ||
- !ReverseArray(s, &ITestService::ReverseDouble, {1.0 / 3.0, 1.0 / 7.0, 42.0}) ||
+ if (!ReverseArray(s, &ITestService::ReverseBoolean,
+ {true, false, false}) ||
+ !ReverseArray(s, &ITestService::ReverseByte,
+ {uint8_t{255}, uint8_t{0}, uint8_t{127}}) ||
+ !ReverseArray(s, &ITestService::ReverseChar,
+ {char16_t{'A'}, char16_t{'B'}, char16_t{'C'}}) ||
+ !ReverseArray(s, &ITestService::ReverseInt,
+ {1, 2, 3}) ||
+ !ReverseArray(s, &ITestService::ReverseLong,
+ {-1LL, 0LL, int64_t{1LL << 60}}) ||
+ !ReverseArray(s, &ITestService::ReverseFloat,
+ {-0.3f, -0.7f, 8.0f}) ||
+ !ReverseArray(s, &ITestService::ReverseDouble,
+ {1.0/3.0, 1.0/7.0, 42.0}) ||
!ReverseArray(s, &ITestService::ReverseString,
- {String16{"f"}, String16{"a"}, String16{"b"}}) ||
- !ReverseArray(s, &ITestService::ReverseByteEnum,
- {ByteEnum::FOO, ByteEnum::BAR, ByteEnum::BAR}) ||
- !ReverseArray(s, &ITestService::ReverseIntEnum, {IntEnum::FOO, IntEnum::BAR, IntEnum::BAR}) ||
- !ReverseArray(s, &ITestService::ReverseLongEnum,
- {LongEnum::FOO, LongEnum::BAR, LongEnum::BAR})) {
+ {String16{"f"}, String16{"a"}, String16{"b"}})) {
return false;
}
@@ -216,242 +235,6 @@
return true;
}
-bool ConfirmIntfConstantExpressions(const sp<ITestService>& s) {
- (void)s;
- bool ret = true;
-
- if (ITestService::A1 != 1) {
- cerr << "ITestService::A1 should be 1 but is " << ITestService::A1 << endl;
- ret = false;
- }
- if (ITestService::A2 != 1) {
- cerr << "ITestService::A2 should be 1 but is " << ITestService::A2 << endl;
- ret = false;
- }
- if (ITestService::A3 != 1) {
- cerr << "ITestService::A3 should be 1 but is " << ITestService::A3 << endl;
- ret = false;
- }
- if (ITestService::A4 != 1) {
- cerr << "ITestService::A4 should be 1 but is " << ITestService::A4 << endl;
- ret = false;
- }
- if (ITestService::A5 != 1) {
- cerr << "ITestService::A5 should be 1 but is " << ITestService::A5 << endl;
- ret = false;
- }
- if (ITestService::A6 != 1) {
- cerr << "ITestService::A6 should be 1 but is " << ITestService::A6 << endl;
- ret = false;
- }
- if (ITestService::A7 != 1) {
- cerr << "ITestService::A7 should be 1 but is " << ITestService::A7 << endl;
- ret = false;
- }
- if (ITestService::A8 != 1) {
- cerr << "ITestService::A8 should be 1 but is " << ITestService::A8 << endl;
- ret = false;
- }
- if (ITestService::A9 != 1) {
- cerr << "ITestService::A9 should be 1 but is " << ITestService::A9 << endl;
- ret = false;
- }
- if (ITestService::A10 != 1) {
- cerr << "ITestService::A10 should be 1 but is " << ITestService::A10 << endl;
- ret = false;
- }
- if (ITestService::A11 != 1) {
- cerr << "ITestService::A11 should be 1 but is " << ITestService::A11 << endl;
- ret = false;
- }
- if (ITestService::A12 != 1) {
- cerr << "ITestService::A12 should be 1 but is " << ITestService::A12 << endl;
- ret = false;
- }
- if (ITestService::A13 != 1) {
- cerr << "ITestService::A13 should be 1 but is " << ITestService::A13 << endl;
- ret = false;
- }
- if (ITestService::A14 != 1) {
- cerr << "ITestService::A14 should be 1 but is " << ITestService::A14 << endl;
- ret = false;
- }
- if (ITestService::A15 != 1) {
- cerr << "ITestService::A15 should be 1 but is " << ITestService::A15 << endl;
- ret = false;
- }
- if (ITestService::A16 != 1) {
- cerr << "ITestService::A16 should be 1 but is " << ITestService::A16 << endl;
- ret = false;
- }
- if (ITestService::A17 != 1) {
- cerr << "ITestService::A17 should be 1 but is " << ITestService::A17 << endl;
- ret = false;
- }
- if (ITestService::A18 != 1) {
- cerr << "ITestService::A18 should be 1 but is " << ITestService::A18 << endl;
- ret = false;
- }
- if (ITestService::A19 != 1) {
- cerr << "ITestService::A19 should be 1 but is " << ITestService::A19 << endl;
- ret = false;
- }
- if (ITestService::A20 != 1) {
- cerr << "ITestService::A20 should be 1 but is " << ITestService::A20 << endl;
- ret = false;
- }
- if (ITestService::A21 != 1) {
- cerr << "ITestService::A21 should be 1 but is " << ITestService::A21 << endl;
- ret = false;
- }
- if (ITestService::A22 != 1) {
- cerr << "ITestService::A22 should be 1 but is " << ITestService::A22 << endl;
- ret = false;
- }
- if (ITestService::A23 != 1) {
- cerr << "ITestService::A23 should be 1 but is " << ITestService::A23 << endl;
- ret = false;
- }
- if (ITestService::A24 != 1) {
- cerr << "ITestService::A24 should be 1 but is " << ITestService::A24 << endl;
- ret = false;
- }
- if (ITestService::A25 != 1) {
- cerr << "ITestService::A25 should be 1 but is " << ITestService::A25 << endl;
- ret = false;
- }
- if (ITestService::A26 != 1) {
- cerr << "ITestService::A26 should be 1 but is " << ITestService::A26 << endl;
- ret = false;
- }
- if (ITestService::A27 != 1) {
- cerr << "ITestService::A27 should be 1 but is " << ITestService::A27 << endl;
- ret = false;
- }
- if (ITestService::A28 != 1) {
- cerr << "ITestService::A28 should be 1 but is " << ITestService::A28 << endl;
- ret = false;
- }
- if (ITestService::A29 != 1) {
- cerr << "ITestService::A29 should be 1 but is " << ITestService::A29 << endl;
- ret = false;
- }
- if (ITestService::A30 != 1) {
- cerr << "ITestService::A30 should be 1 but is " << ITestService::A30 << endl;
- ret = false;
- }
- if (ITestService::A31 != 1) {
- cerr << "ITestService::A31 should be 1 but is " << ITestService::A31 << endl;
- ret = false;
- }
- if (ITestService::A32 != 1) {
- cerr << "ITestService::A32 should be 1 but is " << ITestService::A32 << endl;
- ret = false;
- }
- if (ITestService::A33 != 1) {
- cerr << "ITestService::A33 should be 1 but is " << ITestService::A33 << endl;
- ret = false;
- }
- if (ITestService::A34 != 1) {
- cerr << "ITestService::A34 should be 1 but is " << ITestService::A34 << endl;
- ret = false;
- }
- if (ITestService::A35 != 1) {
- cerr << "ITestService::A35 should be 1 but is " << ITestService::A35 << endl;
- ret = false;
- }
- if (ITestService::A36 != 1) {
- cerr << "ITestService::A36 should be 1 but is " << ITestService::A36 << endl;
- ret = false;
- }
- if (ITestService::A37 != 1) {
- cerr << "ITestService::A37 should be 1 but is " << ITestService::A37 << endl;
- ret = false;
- }
- if (ITestService::A38 != 1) {
- cerr << "ITestService::A38 should be 1 but is " << ITestService::A38 << endl;
- ret = false;
- }
- if (ITestService::A39 != 1) {
- cerr << "ITestService::A39 should be 1 but is " << ITestService::A39 << endl;
- ret = false;
- }
- if (ITestService::A40 != 1) {
- cerr << "ITestService::A40 should be 1 but is " << ITestService::A40 << endl;
- ret = false;
- }
- if (ITestService::A41 != 1) {
- cerr << "ITestService::A41 should be 1 but is " << ITestService::A41 << endl;
- ret = false;
- }
- if (ITestService::A42 != 1) {
- cerr << "ITestService::A42 should be 1 but is " << ITestService::A42 << endl;
- ret = false;
- }
- if (ITestService::A43 != 1) {
- cerr << "ITestService::A43 should be 1 but is " << ITestService::A43 << endl;
- ret = false;
- }
- if (ITestService::A44 != 1) {
- cerr << "ITestService::A44 should be 1 but is " << ITestService::A44 << endl;
- ret = false;
- }
- if (ITestService::A45 != 1) {
- cerr << "ITestService::A45 should be 1 but is " << ITestService::A45 << endl;
- ret = false;
- }
- if (ITestService::A46 != 1) {
- cerr << "ITestService::A46 should be 1 but is " << ITestService::A46 << endl;
- ret = false;
- }
- if (ITestService::A47 != 1) {
- cerr << "ITestService::A47 should be 1 but is " << ITestService::A47 << endl;
- ret = false;
- }
- if (ITestService::A48 != 1) {
- cerr << "ITestService::A48 should be 1 but is " << ITestService::A48 << endl;
- ret = false;
- }
- if (ITestService::A49 != 1) {
- cerr << "ITestService::A49 should be 1 but is " << ITestService::A49 << endl;
- ret = false;
- }
- if (ITestService::A50 != 1) {
- cerr << "ITestService::A50 should be 1 but is " << ITestService::A50 << endl;
- ret = false;
- }
- if (ITestService::A51 != 1) {
- cerr << "ITestService::A51 should be 1 but is " << ITestService::A51 << endl;
- ret = false;
- }
- if (ITestService::A52 != 1) {
- cerr << "ITestService::A52 should be 1 but is " << ITestService::A52 << endl;
- ret = false;
- }
- if (ITestService::A53 != 1) {
- cerr << "ITestService::A53 should be 1 but is " << ITestService::A53 << endl;
- ret = false;
- }
- if (ITestService::A54 != 1) {
- cerr << "ITestService::A54 should be 1 but is " << ITestService::A54 << endl;
- ret = false;
- }
- if (ITestService::A55 != 1) {
- cerr << "ITestService::A55 should be 1 but is " << ITestService::A55 << endl;
- ret = false;
- }
- if (ITestService::A56 != 1) {
- cerr << "ITestService::A56 should be 1 but is " << ITestService::A56 << endl;
- ret = false;
- }
- if (ITestService::A57 != 1) {
- cerr << "ITestService::A57 should be 1 but is " << ITestService::A57 << endl;
- ret = false;
- }
-
- return ret;
-}
-
} // namespace client
} // namespace tests
} // namespace aidl
diff --git a/tests/aidl_test_client_primitives.h b/tests/aidl_test_client_primitives.h
index 0c2fef5..f9b39da 100644
--- a/tests/aidl_test_client_primitives.h
+++ b/tests/aidl_test_client_primitives.h
@@ -31,7 +31,6 @@
bool ConfirmReverseArrays(const android::sp<ITestService>& s);
bool ConfirmReverseLists(const android::sp<ITestService>& s);
bool ConfirmReverseBinderLists(const android::sp<ITestService>& s);
-bool ConfirmIntfConstantExpressions(const sp<ITestService>& s);
} // namespace client
} // namespace tests
diff --git a/tests/aidl_test_service.cpp b/tests/aidl_test_service.cpp
index 3b0deed..6bb8a63 100644
--- a/tests/aidl_test_service.cpp
+++ b/tests/aidl_test_service.cpp
@@ -27,6 +27,7 @@
#include <binder/IServiceManager.h>
#include <binder/ProcessState.h>
#include <binder/Status.h>
+#include <binder/Value.h>
#include <utils/Errors.h>
#include <utils/Log.h>
#include <utils/Looper.h>
@@ -64,12 +65,9 @@
// Generated code:
using android::aidl::tests::BnNamedCallback;
using android::aidl::tests::BnTestService;
-using android::aidl::tests::ByteEnum;
-using android::aidl::tests::ConstantExpressionEnum;
using android::aidl::tests::INamedCallback;
-using android::aidl::tests::IntEnum;
-using android::aidl::tests::LongEnum;
using android::aidl::tests::SimpleParcelable;
+using android::binder::Map;
using android::os::ParcelFileDescriptor;
using android::os::PersistableBundle;
@@ -122,6 +120,10 @@
ALOGI("Repeating token %s", token_str.str().c_str());
}
+ void LogRepeatedMapToken(const Map& token) {
+ ALOGI("Repeating Map with %d elements", (int)token.size());
+ }
+
Status RepeatBoolean(bool token, bool* _aidl_return) override {
LogRepeatedToken(token ? 1 : 0);
*_aidl_return = token;
@@ -162,18 +164,8 @@
*_aidl_return = token;
return Status::ok();
}
- Status RepeatByteEnum(ByteEnum token, ByteEnum* _aidl_return) override {
- ALOGI("Repeating ByteEnum token %d", static_cast<int8_t>(token));
- *_aidl_return = token;
- return Status::ok();
- }
- Status RepeatIntEnum(IntEnum token, IntEnum* _aidl_return) override {
- ALOGI("Repeating IntEnum token %d", static_cast<int8_t>(token));
- *_aidl_return = token;
- return Status::ok();
- }
- Status RepeatLongEnum(LongEnum token, LongEnum* _aidl_return) override {
- ALOGI("Repeating LongEnum token %d", static_cast<int8_t>(token));
+ Status RepeatMap(const Map& token, Map* _aidl_return) override {
+ LogRepeatedMapToken(token);
*_aidl_return = token;
return Status::ok();
}
@@ -257,18 +249,6 @@
vector<String16>* _aidl_return) override {
return ReverseArray(input, repeated, _aidl_return);
}
- Status ReverseByteEnum(const vector<ByteEnum>& input, vector<ByteEnum>* repeated,
- vector<ByteEnum>* _aidl_return) override {
- return ReverseArray(input, repeated, _aidl_return);
- }
- Status ReverseIntEnum(const vector<IntEnum>& input, vector<IntEnum>* repeated,
- vector<IntEnum>* _aidl_return) override {
- return ReverseArray(input, repeated, _aidl_return);
- }
- Status ReverseLongEnum(const vector<LongEnum>& input, vector<LongEnum>* repeated,
- vector<LongEnum>* _aidl_return) override {
- return ReverseArray(input, repeated, _aidl_return);
- }
Status ReverseSimpleParcelables(
const vector<SimpleParcelable>& input,
vector<SimpleParcelable>* repeated,
@@ -366,21 +346,6 @@
return RepeatNullable(input, _aidl_return);
}
- Status RepeatNullableByteEnumArray(const unique_ptr<vector<ByteEnum>>& input,
- unique_ptr<vector<ByteEnum>>* _aidl_return) {
- return RepeatNullable(input, _aidl_return);
- }
-
- Status RepeatNullableIntEnumArray(const unique_ptr<vector<IntEnum>>& input,
- unique_ptr<vector<IntEnum>>* _aidl_return) {
- return RepeatNullable(input, _aidl_return);
- }
-
- Status RepeatNullableLongEnumArray(const unique_ptr<vector<LongEnum>>& input,
- unique_ptr<vector<LongEnum>>* _aidl_return) {
- return RepeatNullable(input, _aidl_return);
- }
-
Status RepeatNullableStringList(
const unique_ptr<vector<unique_ptr<String16>>>& input,
unique_ptr<vector<unique_ptr<String16>>>* _aidl_return) {
@@ -499,24 +464,6 @@
::android::aidl::tests::StructuredParcelable* parcelable) {
parcelable->shouldBeJerry = "Jerry";
parcelable->shouldContainThreeFs = {parcelable->f, parcelable->f, parcelable->f};
- parcelable->shouldBeByteBar = ByteEnum::BAR;
- parcelable->shouldBeIntBar = IntEnum::BAR;
- parcelable->shouldBeLongBar = LongEnum::BAR;
- parcelable->shouldContainTwoByteFoos = {ByteEnum::FOO, ByteEnum::FOO};
- parcelable->shouldContainTwoIntFoos = {IntEnum::FOO, IntEnum::FOO};
- parcelable->shouldContainTwoLongFoos = {LongEnum::FOO, LongEnum::FOO};
-
- parcelable->const_exprs_1 = ConstantExpressionEnum::decInt32_1;
- parcelable->const_exprs_2 = ConstantExpressionEnum::decInt32_2;
- parcelable->const_exprs_3 = ConstantExpressionEnum::decInt64_1;
- parcelable->const_exprs_4 = ConstantExpressionEnum::decInt64_2;
- parcelable->const_exprs_5 = ConstantExpressionEnum::decInt64_3;
- parcelable->const_exprs_6 = ConstantExpressionEnum::decInt64_4;
- parcelable->const_exprs_7 = ConstantExpressionEnum::hexInt32_1;
- parcelable->const_exprs_8 = ConstantExpressionEnum::hexInt32_2;
- parcelable->const_exprs_9 = ConstantExpressionEnum::hexInt32_3;
- parcelable->const_exprs_10 = ConstantExpressionEnum::hexInt64_1;
-
return Status::ok();
}
@@ -526,7 +473,7 @@
android::status_t onTransact(uint32_t code, const Parcel& data, Parcel* reply,
uint32_t flags) override {
- if (code == ::android::IBinder::FIRST_CALL_TRANSACTION + 53 /* UnimplementedMethod */) {
+ if (code == ::android::IBinder::FIRST_CALL_TRANSACTION + 45 /* UnimplementedMethod */) {
// pretend that UnimplementedMethod isn't implemented by this service.
return android::UNKNOWN_TRANSACTION;
} else {
diff --git a/tests/android/aidl/loggable/ILoggableInterface.aidl b/tests/android/aidl/loggable/ILoggableInterface.aidl
index 0b62df3..eee39d6 100644
--- a/tests/android/aidl/loggable/ILoggableInterface.aidl
+++ b/tests/android/aidl/loggable/ILoggableInterface.aidl
@@ -10,6 +10,7 @@
double doubleValue, inout double[] doubleArray,
String stringValue, inout String[] stringArray,
inout List<String> listValue,
+ inout Map mapValue,
IBinder binderValue,
inout ParcelFileDescriptor pfdValue, inout ParcelFileDescriptor[] pfdArray);
}
diff --git a/tests/android/aidl/tests/ByteEnum.aidl b/tests/android/aidl/tests/ByteEnum.aidl
deleted file mode 100644
index 503ae8a..0000000
--- a/tests/android/aidl/tests/ByteEnum.aidl
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.aidl.tests;
-
-/*
- * Hello, world!
- */
-@Backing(type="byte")
-enum ByteEnum {
- // Comment about FOO.
- FOO = 1,
- BAR = 2,
- BAZ,
-}
-
diff --git a/tests/android/aidl/tests/ConstantExpressionEnum.aidl b/tests/android/aidl/tests/ConstantExpressionEnum.aidl
deleted file mode 100644
index 2fe4f61..0000000
--- a/tests/android/aidl/tests/ConstantExpressionEnum.aidl
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.aidl.tests;
-
-@Backing(type="int")
-enum ConstantExpressionEnum {
- // Should be all true / ones.
- // dec literals are either int or long
- decInt32_1 = (~(-1)) == 0,
- decInt32_2 = -(1 << 31) == (1 << 31),
- decInt64_1 = (~(-1L)) == 0,
- decInt64_2 = (~4294967295L) != 0,
- decInt64_3 = (~4294967295) != 0,
- decInt64_4 = -(1L << 63) == (1L << 63),
-
- // hex literals could be int or long
- // 0x7fffffff is int, hence can be negated
- hexInt32_1 = -0x7fffffff < 0,
-
- // 0x80000000 is int32_t max + 1
- hexInt32_2 = -0x80000000 < 0,
-
- // 0xFFFFFFFF is int32_t, not long; if it were long then ~(long)0xFFFFFFFF != 0
- hexInt32_3 = ~0xFFFFFFFF == 0,
-
- // 0x7FFFFFFFFFFFFFFF is long, hence can be negated
- hexInt64_1 = -0x7FFFFFFFFFFFFFFF < 0
-}
-
diff --git a/tests/android/aidl/tests/ITestService.aidl b/tests/android/aidl/tests/ITestService.aidl
index 9b7f08c..4143ba7 100644
--- a/tests/android/aidl/tests/ITestService.aidl
+++ b/tests/android/aidl/tests/ITestService.aidl
@@ -16,10 +16,7 @@
package android.aidl.tests;
-import android.aidl.tests.ByteEnum;
import android.aidl.tests.INamedCallback;
-import android.aidl.tests.IntEnum;
-import android.aidl.tests.LongEnum;
import android.aidl.tests.SimpleParcelable;
import android.aidl.tests.StructuredParcelable;
import android.os.PersistableBundle;
@@ -53,26 +50,21 @@
float RepeatFloat(float token);
double RepeatDouble(double token);
String RepeatString(String token);
- ByteEnum RepeatByteEnum(ByteEnum token);
- IntEnum RepeatIntEnum(IntEnum token);
- LongEnum RepeatLongEnum(LongEnum token);
+ Map RepeatMap(in Map token);
SimpleParcelable RepeatSimpleParcelable(in SimpleParcelable input,
out SimpleParcelable repeat);
PersistableBundle RepeatPersistableBundle(in PersistableBundle input);
// Test that arrays work as parameters and return types.
- boolean[] ReverseBoolean (in boolean[] input, out boolean[] repeated);
- byte[] ReverseByte (in byte[] input, out byte[] repeated);
- char[] ReverseChar (in char[] input, out char[] repeated);
- int[] ReverseInt (in int[] input, out int[] repeated);
- long[] ReverseLong (in long[] input, out long[] repeated);
- float[] ReverseFloat (in float[] input, out float[] repeated);
- double[] ReverseDouble (in double[] input, out double[] repeated);
- String[] ReverseString (in String[] input, out String[] repeated);
- ByteEnum[] ReverseByteEnum (in ByteEnum[] input, out ByteEnum[] repeated);
- IntEnum[] ReverseIntEnum (in IntEnum[] input, out IntEnum[] repeated);
- LongEnum[] ReverseLongEnum (in LongEnum[] input, out LongEnum[] repeated);
+ boolean[] ReverseBoolean(in boolean[] input, out boolean[] repeated);
+ byte[] ReverseByte (in byte[] input, out byte[] repeated);
+ char[] ReverseChar (in char[] input, out char[] repeated);
+ int[] ReverseInt (in int[] input, out int[] repeated);
+ long[] ReverseLong (in long[] input, out long[] repeated);
+ float[] ReverseFloat (in float[] input, out float[] repeated);
+ double[] ReverseDouble (in double[] input, out double[] repeated);
+ String[] ReverseString (in String[] input, out String[] repeated);
SimpleParcelable[] ReverseSimpleParcelables(in SimpleParcelable[] input,
out SimpleParcelable[] repeated);
@@ -102,9 +94,6 @@
// Test nullability
@nullable int[] RepeatNullableIntArray(in @nullable int[] input);
- @nullable ByteEnum[] RepeatNullableByteEnumArray(in @nullable ByteEnum[] input);
- @nullable IntEnum[] RepeatNullableIntEnumArray(in @nullable IntEnum[] input);
- @nullable LongEnum[] RepeatNullableLongEnumArray(in @nullable LongEnum[] input);
@nullable String RepeatNullableString(in @nullable String input);
@nullable List<String> RepeatNullableStringList(in @nullable List<String> input);
@nullable SimpleParcelable RepeatNullableParcelable(in @nullable SimpleParcelable input);
@@ -143,63 +132,4 @@
// to actually implement this, but intercept the dispatch to the method
// inside onTransact().
int UnimplementedMethod(int arg);
-
- // All these constant expressions should be equal to 1
- const int A1 = (~(-1)) == 0;
- const int A2 = -(1 << 31) == (1 << 31);
- const int A3 = -0x7fffffff < 0;
- const int A4 = -0x80000000 < 0;
- const int A5 = (1 + 0x7fffffff) == -2147483648;
- const int A6 = (1 << 31) == 0x80000000;
- const int A7 = (1 + 2) == 3;
- const int A8 = (8 - 9) == -1;
- const int A9 = (9 * 9) == 81;
- const int A10 = (29 / 3) == 9;
- const int A11 = (29 % 3) == 2;
- const int A12 = (0xC0010000 | 0xF00D) == (0xC001F00D);
- const int A13 = (10 | 6) == 14;
- const int A14 = (10 & 6) == 2;
- const int A15 = (10 ^ 6) == 12;
- const int A16 = 6 < 10;
- const int A17 = (10 < 10) == 0;
- const int A18 = (6 > 10) == 0;
- const int A19 = (10 > 10) == 0;
- const int A20 = 19 >= 10;
- const int A21 = 10 >= 10;
- const int A22 = 5 <= 10;
- const int A23 = (19 <= 10) == 0;
- const int A24 = 19 != 10;
- const int A25 = (10 != 10) == 0;
- const int A26 = (22 << 1) == 44;
- const int A27 = (11 >> 1) == 5;
- const int A28 = (1 || 0) == 1;
- const int A29 = (1 || 1) == 1;
- const int A30 = (0 || 0) == 0;
- const int A31 = (0 || 1) == 1;
- const int A32 = (1 && 0) == 0;
- const int A33 = (1 && 1) == 1;
- const int A34 = (0 && 0) == 0;
- const int A35 = (0 && 1) == 0;
- const int A36 = 4 == 4;
- const int A37 = -4 < 0;
- const int A38 = 0xffffffff == -1;
- const int A39 = 4 + 1 == 5;
- const int A40 = 2 + 3 - 4;
- const int A41 = 2 - 3 + 4 == 3;
- const int A42 = 1 == 4 == 0;
- const int A43 = 1 && 1;
- const int A44 = 1 || 1 && 0; // && higher than ||
- const int A45 = 1 < 2;
- const int A46 = !!((3 != 4 || (2 < 3 <= 3 > 4)) >= 0);
- const int A47 = !(1 == 7) && ((3 != 4 || (2 < 3 <= 3 > 4)) >= 0);
- const int A48 = (1 << 2) >= 0;
- const int A49 = (4 >> 1) == 2;
- const int A50 = (8 << -1) == 4;
- const int A51 = (1 << 31 >> 31) == -1;
- const int A52 = (1 | 16 >> 2) == 5;
- const int A53 = (0x0f ^ 0x33 & 0x99) == 0x1e; // & higher than ^
- const int A54 = (~42 & (1 << 3 | 16 >> 2) ^ 7) == 3;
- const int A55 = (2 + 3 - 4 * -7 / (10 % 3)) - 33 == 0;
- const int A56 = (2 + (-3&4 / 7)) == 2;
- const int A57 = (((((1 + 0)))));
}
diff --git a/tests/android/aidl/tests/IntEnum.aidl b/tests/android/aidl/tests/IntEnum.aidl
deleted file mode 100644
index d3769ef..0000000
--- a/tests/android/aidl/tests/IntEnum.aidl
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.aidl.tests;
-
-@Backing(type="int")
-enum IntEnum {
- FOO = 1000,
- BAR = 2000,
- BAZ,
-}
-
diff --git a/tests/android/aidl/tests/LongEnum.aidl b/tests/android/aidl/tests/LongEnum.aidl
deleted file mode 100644
index 9d7610b..0000000
--- a/tests/android/aidl/tests/LongEnum.aidl
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.aidl.tests;
-
-@Backing(type="long")
-enum LongEnum {
- FOO = 100000000000,
- BAR = 200000000000,
- BAZ,
-}
-
diff --git a/tests/android/aidl/tests/StructuredParcelable.aidl b/tests/android/aidl/tests/StructuredParcelable.aidl
index 28046e2..2ced1e8 100644
--- a/tests/android/aidl/tests/StructuredParcelable.aidl
+++ b/tests/android/aidl/tests/StructuredParcelable.aidl
@@ -16,21 +16,10 @@
package android.aidl.tests;
-import android.aidl.tests.ByteEnum;
-import android.aidl.tests.IntEnum;
-import android.aidl.tests.LongEnum;
-import android.aidl.tests.ConstantExpressionEnum;
-
parcelable StructuredParcelable {
int[] shouldContainThreeFs;
int f;
@utf8InCpp String shouldBeJerry;
- ByteEnum shouldBeByteBar;
- IntEnum shouldBeIntBar;
- LongEnum shouldBeLongBar;
- ByteEnum[] shouldContainTwoByteFoos;
- IntEnum[] shouldContainTwoIntFoos;
- LongEnum[] shouldContainTwoLongFoos;
String stringDefaultsToFoo = "foo";
byte byteDefaultsToFour = 4;
@@ -47,116 +36,4 @@
double checkDoubleFromFloat = 3.14f;
String[] checkStringArray1 = { "a", "b" };
@utf8InCpp String[] checkStringArray2 = { "a", "b" };
-
- // Add test to verify corner cases
- int int32_min = -2147483648;
- int int32_max = 2147483647;
- long int64_max = 9223372036854775807;
- int hexInt32_neg_1 = 0xffffffff;
-
- @nullable IBinder ibinder;
-
- // Constant expressions that evaluate to 1
- int[] int32_1 = {
- (~(-1)) == 0,
- -(1 << 31) == (1 << 31),
- -0x7fffffff < 0,
- -0x80000000 < 0,
-
- // both treated int32_t, sum = (int32_t)0x80000000 = -2147483648
- (1 + 0x7fffffff) == -2147483648,
-
- // Shifting for more than 31 bits are undefined. Not tested.
- (1 << 31) == 0x80000000,
-
- // Should be all true / ones.
- (1 + 2) == 3,
- (8 - 9) == -1,
- (9 * 9) == 81,
- (29 / 3) == 9,
- (29 % 3) == 2,
- (0xC0010000 | 0xF00D) == (0xC001F00D),
- (10 | 6) == 14,
- (10 & 6) == 2,
- (10 ^ 6) == 12,
- 6 < 10,
- (10 < 10) == 0,
- (6 > 10) == 0,
- (10 > 10) == 0,
- 19 >= 10,
- 10 >= 10,
- 5 <= 10,
- (19 <= 10) == 0,
- 19 != 10,
- (10 != 10) == 0,
- (22 << 1) == 44,
- (11 >> 1) == 5,
- (1 || 0) == 1,
- (1 || 1) == 1,
- (0 || 0) == 0,
- (0 || 1) == 1,
- (1 && 0) == 0,
- (1 && 1) == 1,
- (0 && 0) == 0,
- (0 && 1) == 0,
-
- // precedence tests -- all 1s
- 4 == 4,
- -4 < 0,
- 0xffffffff == -1,
- 4 + 1 == 5,
- 2 + 3 - 4,
- 2 - 3 + 4 == 3,
- 1 == 4 == 0,
- 1 && 1,
- 1 || 1 && 0, // && higher than ||
- 1 < 2,
- !!((3 != 4 || (2 < 3 <= 3 > 4)) >= 0),
- !(1 == 7) && ((3 != 4 || (2 < 3 <= 3 > 4)) >= 0),
- (1 << 2) >= 0,
- (4 >> 1) == 2,
- (8 << -1) == 4,
- (1 << 31 >> 31) == -1,
- (1 | 16 >> 2) == 5,
- (0x0f ^ 0x33 & 0x99) == 0x1e, // & higher than ^
- (~42 & (1 << 3 | 16 >> 2) ^ 7) == 3,
- (2 + 3 - 4 * -7 / (10 % 3)) - 33 == 0,
- (2 + (-3&4 / 7)) == 2,
- (((((1 + 0)))))
- };
-
- long[] int64_1 = {
- (~(-1)) == 0,
- (~4294967295) != 0,
- (~4294967295) != 0,
- -(1 << 63) == (1 << 63),
- -0x7FFFFFFFFFFFFFFF < 0,
-
- // both treated int32_t, sum = (int64_t)(int32_t)0x80000000 = (int64_t)(-2147483648)
- (1 + 0x7fffffff) == -2147483648,
-
- // 0x80000000 is uint32_t, sum = (int64_t)(uint32_t)0x7fffffff = (int64_t)(2147483647)
- (0x80000000 - 1) == 2147483647,
- (0x80000000 + 1) == -2147483647,
- (1L << 63)+1 == -9223372036854775807,
- 0xfffffffff == 68719476735
- };
- int hexInt32_pos_1 = -0xffffffff;
- int hexInt64_pos_1 = -0xfffffffffff < 0;
-
- ConstantExpressionEnum const_exprs_1;
- ConstantExpressionEnum const_exprs_2;
- ConstantExpressionEnum const_exprs_3;
- ConstantExpressionEnum const_exprs_4;
- ConstantExpressionEnum const_exprs_5;
- ConstantExpressionEnum const_exprs_6;
- ConstantExpressionEnum const_exprs_7;
- ConstantExpressionEnum const_exprs_8;
- ConstantExpressionEnum const_exprs_9;
- ConstantExpressionEnum const_exprs_10;
-
- // String expressions
- @utf8InCpp String addString1 = "hello" + " world!";
- @utf8InCpp String addString2 = "The quick brown fox jumps " + "over the lazy dog.";
}
-
diff --git a/tests/end_to_end_tests.cpp b/tests/end_to_end_tests.cpp
index 601c76f..7602a86 100644
--- a/tests/end_to_end_tests.cpp
+++ b/tests/end_to_end_tests.cpp
@@ -325,5 +325,5 @@
CheckFileContents(kJavaOutputPath, kExpectedJavaOutputWithVersion);
}
-} // namespace aidl
} // namespace android
+} // namespace aidl
diff --git a/tests/fake_io_delegate.cpp b/tests/fake_io_delegate.cpp
index dc35c4d..b63e1e3 100644
--- a/tests/fake_io_delegate.cpp
+++ b/tests/fake_io_delegate.cpp
@@ -151,14 +151,6 @@
return true;
}
-std::vector<std::string> FakeIoDelegate::ListOutputFiles() {
- std::vector<std::string> out;
- for (const auto& [file, contents] : written_file_contents_) {
- out.push_back(file);
- }
- return out;
-}
-
bool FakeIoDelegate::PathWasRemoved(const std::string& path) {
if (removed_files_.count(path) > 0) {
return true;
@@ -177,5 +169,5 @@
}
} // namespace test
-} // namespace aidl
} // namespace android
+} // namespace aidl
diff --git a/tests/fake_io_delegate.h b/tests/fake_io_delegate.h
index f077c0f..32ef2ed 100644
--- a/tests/fake_io_delegate.h
+++ b/tests/fake_io_delegate.h
@@ -60,7 +60,6 @@
// Returns true iff we've previously written to |path|.
// When we return true, we'll set *contents to the written string.
bool GetWrittenContents(const std::string& path, std::string* content);
- std::vector<std::string> ListOutputFiles();
bool PathWasRemoved(const std::string& path);
@@ -83,7 +82,7 @@
}; // class FakeIoDelegate
} // namespace test
-} // namespace aidl
} // namespace android
+} // namespace aidl
#endif // AIDL_TESTS_FAKE_IO_DELEGATE_H_
diff --git a/tests/integration-test.py b/tests/integration-test.py
index 32d1a8f..0079ba9 100755
--- a/tests/integration-test.py
+++ b/tests/integration-test.py
@@ -9,9 +9,9 @@
import subprocess
import shlex
-JAVA_OUTPUT_READER_FOR_BITNESS = '/data/nativetest%s/aidl_test_sentinel_searcher/aidl_test_sentinel_searcher'
-NATIVE_TEST_CLIENT_FOR_BITNESS = ' /data/nativetest%s/aidl_test_client/aidl_test_client'
-NATIVE_TEST_SERVICE_FOR_BITNESS = ' /data/nativetest%s/aidl_test_service/aidl_test_service'
+JAVA_OUTPUT_READER = 'aidl_test_sentinel_searcher'
+NATIVE_TEST_CLIENT = 'aidl_test_client'
+NATIVE_TEST_SERVICE = 'aidl_test_service'
TEST_FILTER_ALL = 'all'
TEST_FILTER_JAVA = 'java'
@@ -123,36 +123,28 @@
raise subprocess.CalledProcessError(p.returncode, command)
return ShellResult(p.returncode, stdout, stderr)
+
def run_test(host, test_native, test_java):
"""Body of the test.
Args:
host: AdbHost object to run tests on
test_native: True iff we should test native Binder clients.
- test_java: True iff we should test Java Binder clients.
+ test_java: True iff we shoudl test Java Binder clients.
"""
print('Starting aidl integration testing...')
- if host.run('ls /data/nativetest64', ignore_status=True).exit_status:
- bitness = ""
- else:
- bitness = "64"
-
- JAVA_OUTPUT_READER = JAVA_OUTPUT_READER_FOR_BITNESS % bitness
- NATIVE_TEST_CLIENT = NATIVE_TEST_CLIENT_FOR_BITNESS % bitness
- NATIVE_TEST_SERVICE = NATIVE_TEST_SERVICE_FOR_BITNESS % bitness
-
# Kill any previous test context
host.run('rm -f %s' % JAVA_LOG_FILE, ignore_status=True)
- host.run('killall %s' % NATIVE_TEST_SERVICE, ignore_status=True)
+ host.run('pkill %s' % NATIVE_TEST_SERVICE, ignore_status=True)
# Start up a native server
host.run(NATIVE_TEST_SERVICE, background=True)
# Start up clients
if test_native:
- host.run('killall %s' % NATIVE_TEST_CLIENT, ignore_status=True)
+ host.run('pkill %s' % NATIVE_TEST_CLIENT, ignore_status=True)
result = host.run(NATIVE_TEST_CLIENT, ignore_status=True)
if result.exit_status:
print(result.printable_string())
@@ -174,9 +166,6 @@
print(result.printable_string())
raise TestFail('Java client did not complete successfully.')
- host.run('killall %s' % NATIVE_TEST_SERVICE, ignore_status=True)
- host.run('killall android.aidl.tests', ignore_status=True)
-
print('Success!')
diff --git a/tests/java_app/src/android/aidl/tests/TestServiceClient.java b/tests/java_app/src/android/aidl/tests/TestServiceClient.java
index ef5c651..697a3da 100644
--- a/tests/java_app/src/android/aidl/tests/TestServiceClient.java
+++ b/tests/java_app/src/android/aidl/tests/TestServiceClient.java
@@ -16,11 +16,6 @@
package android.aidl.tests;
-import android.aidl.tests.ByteEnum;
-import android.aidl.tests.INamedCallback;
-import android.aidl.tests.ITestService;
-import android.aidl.tests.IntEnum;
-import android.aidl.tests.LongEnum;
import android.aidl.tests.SimpleParcelable;
import android.aidl.tests.StructuredParcelable;
import android.aidl.tests.TestFailException;
@@ -28,13 +23,13 @@
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
+import android.os.ServiceSpecificException;
import android.os.Bundle;
import android.os.IBinder;
import android.os.ParcelFileDescriptor;
import android.os.PersistableBundle;
import android.os.RemoteException;
import android.os.ServiceManager;
-import android.os.ServiceSpecificException;
import android.util.Log;
import java.io.File;
import java.io.FileDescriptor;
@@ -44,9 +39,13 @@
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
-import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import java.util.HashMap;
+
+// Generated
+import android.aidl.tests.INamedCallback;
+import android.aidl.tests.ITestService;
public class TestServiceClient extends Activity {
private static final String TAG = "TestServiceClient";
@@ -160,25 +159,15 @@
}
}
{
- byte query = ByteEnum.FOO;
- byte response = service.RepeatByteEnum(query);
- if (query != response) {
- mLog.logAndThrow("Repeat ByteEnum with " + query + " responded " + response);
- }
- }
- {
- int query = IntEnum.FOO;
- int response = service.RepeatIntEnum(query);
- if (query != response) {
- mLog.logAndThrow("Repeat IntEnum with " + query + " responded " + response);
- }
- }
- {
- long query = LongEnum.FOO;
- long response = service.RepeatLongEnum(query);
- if (query != response) {
- mLog.logAndThrow("Repeat LongEnum with " + query + " responded " + response);
- }
+ Map<String, Object> query = new HashMap<String, Object>();
+ query.put("first_val", new Byte((byte)-128));
+ query.put("second_val", new Integer(1<<30));
+ query.put("third_val", "OHAI");
+ Object response = service.RepeatMap(query);
+ if (!query.equals(response)) {
+ mLog.logAndThrow("Repeat with " + query +
+ " responded " + response);
+ }
}
List<String> queries = Arrays.asList(
@@ -754,9 +743,6 @@
parcelable.shouldContainThreeFs = new int[0];
parcelable.f = kDesiredFValue;
parcelable.shouldBeJerry = "";
- parcelable.shouldContainTwoByteFoos = new byte[2];
- parcelable.shouldContainTwoIntFoos = new int[2];
- parcelable.shouldContainTwoLongFoos = new long[2];
if (!parcelable.stringDefaultsToFoo.equals("foo")) {
mLog.logAndThrow(
@@ -810,117 +796,6 @@
if (!parcelable.shouldBeJerry.equals("Jerry")) {
mLog.logAndThrow("shouldBeJerry should be 'Jerry' but is " + parcelable.shouldBeJerry);
}
-
- if (parcelable.shouldBeByteBar != ByteEnum.BAR) {
- mLog.logAndThrow(
- "shouldBeByteBar should be ByteEnum.BAR but is " + parcelable.shouldBeByteBar);
- }
- if (parcelable.shouldBeIntBar != IntEnum.BAR) {
- mLog.logAndThrow(
- "shouldBeIntBar should be IntEnum.BAR but is " + parcelable.shouldBeIntBar);
- }
- if (parcelable.shouldBeLongBar != LongEnum.BAR) {
- mLog.logAndThrow(
- "shouldBeLongBar should be LongEnum.BAR but is " + parcelable.shouldBeLongBar);
- }
-
- if (!Arrays.equals(
- parcelable.shouldContainTwoByteFoos, new byte[] {ByteEnum.FOO, ByteEnum.FOO})) {
- mLog.logAndThrow(
- "shouldContainTwoByteFoos is " + Arrays.toString(parcelable.shouldContainTwoByteFoos));
- }
- if (!Arrays.equals(
- parcelable.shouldContainTwoIntFoos, new int[] {IntEnum.FOO, IntEnum.FOO})) {
- mLog.logAndThrow(
- "shouldContainTwoIntFoos is " + Arrays.toString(parcelable.shouldContainTwoIntFoos));
- }
- if (!Arrays.equals(
- parcelable.shouldContainTwoLongFoos, new long[] {LongEnum.FOO, LongEnum.FOO})) {
- mLog.logAndThrow(
- "shouldContainTwoLongFoos is " + Arrays.toString(parcelable.shouldContainTwoLongFoos));
- }
-
- if (parcelable.int32_min != Integer.MIN_VALUE) {
- mLog.logAndThrow(
- "int32_min should be " + Integer.MIN_VALUE + "but is " + parcelable.int32_min);
- }
-
- if (parcelable.int32_max != Integer.MAX_VALUE) {
- mLog.logAndThrow(
- "int32_max should be " + Integer.MAX_VALUE + "but is " + parcelable.int32_max);
- }
-
- if (parcelable.int64_max != Long.MAX_VALUE) {
- mLog.logAndThrow(
- "int64_max should be " + Long.MAX_VALUE + "but is " + parcelable.int64_max);
- }
-
- if (parcelable.hexInt32_neg_1 != -1) {
- mLog.logAndThrow("hexInt32_neg_1 should be -1 but is " + parcelable.hexInt32_neg_1);
- }
-
- boolean success = true;
- for (int ndx = 0; ndx < parcelable.int32_1.length; ndx++) {
- if (parcelable.int32_1[ndx] != 1) {
- mLog.log("int32_1[" + ndx + "] should be 1 but is " + parcelable.int32_1[ndx]);
- success = false;
- }
- }
- if (!success) {
- mLog.logAndThrow("Failed to parse int32_1 array");
- }
-
- for (int ndx = 0; ndx < parcelable.int64_1.length; ndx++) {
- if (parcelable.int64_1[ndx] != 1) {
- mLog.log("int64_1[" + ndx + "] should be 1 but is " + parcelable.int64_1[ndx]);
- success = false;
- }
- }
- if (!success) {
- mLog.logAndThrow("Failed to parse int64_1 array");
- }
-
- if (parcelable.hexInt32_pos_1 != 1) {
- mLog.logAndThrow("hexInt32_pos_1 should be 1 but is " + parcelable.hexInt32_pos_1);
- }
-
- if (parcelable.hexInt64_pos_1 != 1) {
- mLog.logAndThrow("hexInt64_pos_1 should be 1 but is " + parcelable.hexInt64_pos_1);
- }
-
- if (parcelable.const_exprs_1 != 1) {
- mLog.logAndThrow("parcelable.const_exprs_1 should be 1 but is " + parcelable.const_exprs_1);
- }
- if (parcelable.const_exprs_2 != 1) {
- mLog.logAndThrow("parcelable.const_exprs_2 should be 1 but is " + parcelable.const_exprs_2);
- }
- if (parcelable.const_exprs_3 != 1) {
- mLog.logAndThrow("parcelable.const_exprs_3 should be 1 but is " + parcelable.const_exprs_3);
- }
- if (parcelable.const_exprs_4 != 1) {
- mLog.logAndThrow("parcelable.const_exprs_4 should be 1 but is " + parcelable.const_exprs_4);
- }
- if (parcelable.const_exprs_5 != 1) {
- mLog.logAndThrow("parcelable.const_exprs_5 should be 1 but is " + parcelable.const_exprs_5);
- }
- if (parcelable.const_exprs_6 != 1) {
- mLog.logAndThrow("parcelable.const_exprs_6 should be 1 but is " + parcelable.const_exprs_6);
- }
- if (parcelable.const_exprs_7 != 1) {
- mLog.logAndThrow("parcelable.const_exprs_7 should be 1 but is " + parcelable.const_exprs_7);
- }
- if (parcelable.const_exprs_8 != 1) {
- mLog.logAndThrow("parcelable.const_exprs_8 should be 1 but is " + parcelable.const_exprs_8);
- }
- if (parcelable.const_exprs_9 != 1) {
- mLog.logAndThrow("parcelable.const_exprs_9 should be 1 but is " + parcelable.const_exprs_9);
- }
- if (parcelable.const_exprs_10 != 1) {
- mLog.logAndThrow(
- "parcelable.const_exprs_10 should be 1 but is " + parcelable.const_exprs_10);
- }
-
- mLog.log("Successfully verified the StructuredParcelable");
}
private void checkDefaultImpl(ITestService service) throws TestFailException {
diff --git a/tests/test_data_example_interface.cpp b/tests/test_data_example_interface.cpp
index 58a0426..24fee69 100644
--- a/tests/test_data_example_interface.cpp
+++ b/tests/test_data_example_interface.cpp
@@ -122,7 +122,7 @@
* This file is auto-generated. DO NOT MODIFY.
*/
package android.test;
-@dalvik.annotation.compat.UnsupportedAppUsage
+@android.annotation.UnsupportedAppUsage
@android.annotation.SystemApi
public interface IExampleInterface extends android.os.IInterface
{
@@ -564,7 +564,7 @@
public int getState() throws android.os.RemoteException;
public java.lang.String getAddress() throws android.os.RemoteException;
/* Test long comment */
- @dalvik.annotation.compat.UnsupportedAppUsage
+ @android.annotation.UnsupportedAppUsage
@android.annotation.SystemApi
public android.foo.ExampleParcelable[] getParcelables() throws android.os.RemoteException;
// Test short comment
@@ -584,7 +584,7 @@
* This file is auto-generated. DO NOT MODIFY.
*/
package android.test;
-@dalvik.annotation.compat.UnsupportedAppUsage
+@android.annotation.UnsupportedAppUsage
@android.annotation.SystemApi
public interface IExampleInterface extends android.os.IInterface
{
@@ -1078,7 +1078,7 @@
public int getState() throws android.os.RemoteException;
public java.lang.String getAddress() throws android.os.RemoteException;
/* Test long comment */
- @dalvik.annotation.compat.UnsupportedAppUsage
+ @android.annotation.UnsupportedAppUsage
@android.annotation.SystemApi
public android.foo.ExampleParcelable[] getParcelables() throws android.os.RemoteException;
// Test short comment
@@ -1098,7 +1098,7 @@
* This file is auto-generated. DO NOT MODIFY.
*/
package android.test;
-@dalvik.annotation.compat.UnsupportedAppUsage
+@android.annotation.UnsupportedAppUsage
@android.annotation.SystemApi
public interface IExampleInterface extends android.os.IInterface
{
@@ -1620,7 +1620,7 @@
public int getState() throws android.os.RemoteException;
public java.lang.String getAddress() throws android.os.RemoteException;
/* Test long comment */
- @dalvik.annotation.compat.UnsupportedAppUsage
+ @android.annotation.UnsupportedAppUsage
@android.annotation.SystemApi
public android.foo.ExampleParcelable[] getParcelables() throws android.os.RemoteException;
// Test short comment
@@ -2517,12 +2517,7 @@
android.os.Parcel reply = android.os.Parcel.obtain();
try {
data.writeInterfaceToken(DESCRIPTOR);
- boolean _status = mRemote.transact(Stub.TRANSACTION_getInterfaceVersion, data, reply, 0);
- if (!_status) {
- if (getDefaultImpl() != null) {
- return getDefaultImpl().getInterfaceVersion();
- }
- }
+ mRemote.transact(Stub.TRANSACTION_getInterfaceVersion, data, reply, 0);
reply.readException();
mCachedVersion = reply.readInt();
} finally {
diff --git a/tests/test_data_ping_responder.cpp b/tests/test_data_ping_responder.cpp
index 130a225..9699d26 100644
--- a/tests/test_data_ping_responder.cpp
+++ b/tests/test_data_ping_responder.cpp
@@ -268,17 +268,11 @@
} // namespace android
#include <android/os/BnPingResponder.h>
#include <binder/Parcel.h>
-#include <binder/Stability.h>
namespace android {
namespace os {
-BnPingResponder::BnPingResponder()
-{
- ::android::internal::Stability::markCompilationUnit(this);
-}
-
::android::status_t BnPingResponder::onTransact(uint32_t _aidl_code, const ::android::Parcel& _aidl_data, ::android::Parcel* _aidl_reply, uint32_t _aidl_flags) {
::android::status_t _aidl_ret_status = ::android::OK;
switch (_aidl_code) {
@@ -476,7 +470,7 @@
)";
const char kExpectedBnHeaderOutput[] =
- R"(#ifndef AIDL_GENERATED_ANDROID_OS_BN_PING_RESPONDER_H_
+R"(#ifndef AIDL_GENERATED_ANDROID_OS_BN_PING_RESPONDER_H_
#define AIDL_GENERATED_ANDROID_OS_BN_PING_RESPONDER_H_
#include <binder/IInterface.h>
@@ -488,7 +482,6 @@
class BnPingResponder : public ::android::BnInterface<IPingResponder> {
public:
- explicit BnPingResponder();
::android::status_t onTransact(uint32_t _aidl_code, const ::android::Parcel& _aidl_data, ::android::Parcel* _aidl_reply, uint32_t _aidl_flags) override;
}; // class BnPingResponder
@@ -714,17 +707,11 @@
} // namespace android
#include <android/os/BnPingResponder.h>
#include <binder/Parcel.h>
-#include <binder/Stability.h>
namespace android {
namespace os {
-BnPingResponder::BnPingResponder()
-{
- ::android::internal::Stability::markCompilationUnit(this);
-}
-
::android::status_t BnPingResponder::onTransact(uint32_t _aidl_code, const ::android::Parcel& _aidl_data, ::android::Parcel* _aidl_reply, uint32_t _aidl_flags) {
::android::status_t _aidl_ret_status = ::android::OK;
switch (_aidl_code) {
@@ -867,7 +854,6 @@
#include <binder/IBinder.h>
#include <binder/IInterface.h>
#include <binder/Status.h>
-#include <cstdint>
#include <memory>
#include <string>
#include <utils/String16.h>
@@ -940,7 +926,7 @@
)";
const char kExpectedBnHeaderOutputWithVersion[] =
- R"(#ifndef AIDL_GENERATED_ANDROID_OS_BN_PING_RESPONDER_H_
+R"(#ifndef AIDL_GENERATED_ANDROID_OS_BN_PING_RESPONDER_H_
#define AIDL_GENERATED_ANDROID_OS_BN_PING_RESPONDER_H_
#include <binder/IInterface.h>
@@ -952,7 +938,6 @@
class BnPingResponder : public ::android::BnInterface<IPingResponder> {
public:
- explicit BnPingResponder();
::android::status_t onTransact(uint32_t _aidl_code, const ::android::Parcel& _aidl_data, ::android::Parcel* _aidl_reply, uint32_t _aidl_flags) override;
int32_t getInterfaceVersion() final override;
}; // class BnPingResponder
diff --git a/tests/test_data_string_constants.cpp b/tests/test_data_string_constants.cpp
index d7b4bb5..2077880 100644
--- a/tests/test_data_string_constants.cpp
+++ b/tests/test_data_string_constants.cpp
@@ -197,17 +197,11 @@
} // namespace android
#include <android/os/BnStringConstants.h>
#include <binder/Parcel.h>
-#include <binder/Stability.h>
namespace android {
namespace os {
-BnStringConstants::BnStringConstants()
-{
- ::android::internal::Stability::markCompilationUnit(this);
-}
-
::android::status_t BnStringConstants::onTransact(uint32_t _aidl_code, const ::android::Parcel& _aidl_data, ::android::Parcel* _aidl_reply, uint32_t _aidl_flags) {
::android::status_t _aidl_ret_status = ::android::OK;
switch (_aidl_code) {
@@ -328,12 +322,7 @@
android.os.Parcel reply = android.os.Parcel.obtain();
try {
data.writeInterfaceToken(DESCRIPTOR);
- boolean _status = mRemote.transact(Stub.TRANSACTION_getInterfaceVersion, data, reply, 0);
- if (!_status) {
- if (getDefaultImpl() != null) {
- return getDefaultImpl().getInterfaceVersion();
- }
- }
+ mRemote.transact(Stub.TRANSACTION_getInterfaceVersion, data, reply, 0);
reply.readException();
mCachedVersion = reply.readInt();
} finally {
@@ -369,7 +358,6 @@
#include <binder/IBinder.h>
#include <binder/IInterface.h>
#include <binder/Status.h>
-#include <cstdint>
#include <utils/String16.h>
#include <utils/StrongPointer.h>
@@ -459,17 +447,11 @@
} // namespace android
#include <android/os/BnStringConstants.h>
#include <binder/Parcel.h>
-#include <binder/Stability.h>
namespace android {
namespace os {
-BnStringConstants::BnStringConstants()
-{
- ::android::internal::Stability::markCompilationUnit(this);
-}
-
::android::status_t BnStringConstants::onTransact(uint32_t _aidl_code, const ::android::Parcel& _aidl_data, ::android::Parcel* _aidl_reply, uint32_t _aidl_flags) {
::android::status_t _aidl_ret_status = ::android::OK;
switch (_aidl_code) {
diff --git a/tests/test_util.cpp b/tests/test_util.cpp
index 6d4750a..9cb52f3 100644
--- a/tests/test_util.cpp
+++ b/tests/test_util.cpp
@@ -164,5 +164,5 @@
}
} // namespace test
-} // namespace aidl
} // namespace android
+} // namespace aidl
diff --git a/tests/test_util.h b/tests/test_util.h
index 6c4389c..34b9e5d 100644
--- a/tests/test_util.h
+++ b/tests/test_util.h
@@ -34,7 +34,7 @@
void PrintDiff(const std::string& a, const std::string& b);
} // namespace test
-} // namespace aidl
} // namespace android
+} // namespace aidl
#endif // AIDL_TESTS_TEST_UTIL_H_
diff --git a/type_cpp.cpp b/type_cpp.cpp
new file mode 100644
index 0000000..c3cab98
--- /dev/null
+++ b/type_cpp.cpp
@@ -0,0 +1,527 @@
+/*
+ * Copyright (C) 2015, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "type_cpp.h"
+
+#include <algorithm>
+#include <iostream>
+#include <memory>
+#include <vector>
+
+#include <android-base/stringprintf.h>
+#include <android-base/strings.h>
+
+#include "logging.h"
+
+using std::string;
+using std::vector;
+
+using android::base::Join;
+using android::base::StringPrintf;
+
+namespace android {
+namespace aidl {
+namespace cpp {
+namespace {
+
+const char kNoPackage[] = "";
+const char kNoHeader[] = "";
+const char kNoValidMethod[] = "";
+Type* const kNoArrayType = nullptr;
+Type* const kNoNullableType = nullptr;
+
+class VoidType : public Type {
+ public:
+ VoidType() : Type(ValidatableType::KIND_BUILT_IN, kNoPackage, "void",
+ {}, "void", kNoValidMethod, kNoValidMethod) {}
+ ~VoidType() override = default;
+ bool CanWriteToParcel() const override { return false; }
+}; // class VoidType
+
+class CppArrayType : public Type {
+ public:
+ CppArrayType(int kind, // from ValidatableType
+ const std::string& package,
+ const string& underlying_aidl_type,
+ const string& cpp_header,
+ const string& underlying_cpp_type,
+ const string& underlying_cpp_type_nulllable,
+ const string& read_method,
+ const string& write_method,
+ bool is_nullable,
+ const string& src_file_name = "")
+ : Type(kind, package,
+ underlying_aidl_type + "[]",
+ GetHeaders(is_nullable, cpp_header),
+ GetCppType(is_nullable, underlying_cpp_type),
+ read_method, write_method, kNoArrayType,
+ (is_nullable)
+ ? kNoNullableType
+ // All arrays are nullable.
+ : new CppArrayType(kind, package, underlying_aidl_type,
+ cpp_header, underlying_cpp_type_nulllable,
+ underlying_cpp_type_nulllable,
+ read_method, write_method, true),
+ src_file_name) {}
+
+ private:
+ static vector<string> GetHeaders(bool is_nullable, const string& cpp_header) {
+ vector<string> result = {"vector"};
+ if (is_nullable) {
+ result.push_back("memory");
+ }
+ if (!cpp_header.empty()) {
+ result.push_back(cpp_header);
+ }
+ return result;
+ }
+
+ static string GetCppType(bool is_nullable,
+ const string& underlying_cpp_type) {
+ if (is_nullable)
+ return StringPrintf("::std::unique_ptr<::std::vector<%s>>",
+ underlying_cpp_type.c_str());
+ return StringPrintf("::std::vector<%s>",
+ underlying_cpp_type.c_str());
+ }
+
+ DISALLOW_COPY_AND_ASSIGN(CppArrayType);
+}; // class CppArrayType
+
+class PrimitiveType : public Type {
+ public:
+ PrimitiveType(const std::string& aidl_type,
+ const std::string& header,
+ const std::string& cpp_type,
+ const std::string& read_method,
+ const std::string& write_method,
+ const std::string& read_array_method,
+ const std::string& write_array_method)
+ : Type(ValidatableType::KIND_BUILT_IN, kNoPackage, aidl_type, {header},
+ cpp_type, read_method, write_method,
+ new CppArrayType(ValidatableType::KIND_BUILT_IN, kNoPackage,
+ aidl_type, header, cpp_type, cpp_type,
+ read_array_method, write_array_method,
+ false)) {}
+
+ ~PrimitiveType() override = default;
+ bool IsCppPrimitive() const override { return true; }
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(PrimitiveType);
+}; // class PrimitiveType
+
+// Unfortunately, bytes in Java are signed. However, most C authors would
+// say that a byte is not in fact signed. Compromise: customize this otherwise
+// normal primitive to use signed single bytes, but unsigned byte arrays.
+class ByteType : public Type {
+ public:
+ ByteType()
+ : Type(ValidatableType::KIND_BUILT_IN, kNoPackage, "byte",
+ {"cstdint"}, "int8_t", "readByte", "writeByte",
+ new CppArrayType(ValidatableType::KIND_BUILT_IN, kNoPackage,
+ "byte", "cstdint", "uint8_t", "uint8_t",
+ "readByteVector", "writeByteVector",
+ false)) {}
+
+ ~ByteType() override = default;
+ bool IsCppPrimitive() const override { return true; }
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(ByteType);
+}; // class PrimitiveType
+
+static string GetCppHeader(const AidlDefinedType& defined_type) {
+ vector<string> name = defined_type.GetSplitPackage();
+ name.push_back(defined_type.GetName());
+ return Join(name, '/') + ".h";
+}
+
+class BinderType : public Type {
+ public:
+ BinderType(const AidlInterface& interface, const std::string& src_file_name)
+ : BinderType(interface, src_file_name,
+ new BinderType(interface, src_file_name, kNoNullableType,
+ "readNullableStrongBinder"),
+ "readStrongBinder") {}
+ ~BinderType() override = default;
+
+ string WriteCast(const string& val) const override {
+ return write_cast_ + "(" + val + ")";
+ }
+
+ private:
+ BinderType(const AidlInterface& interface, const std::string& src_file_name, Type* nullable_type,
+ const std::string& read)
+ : Type(ValidatableType::KIND_GENERATED, interface.GetPackage(), interface.GetName(),
+ {GetCppHeader(interface)}, GetCppName(interface), read, "writeStrongBinder",
+ kNoArrayType, nullable_type, src_file_name),
+ write_cast_(GetRawCppName(interface) + "::asBinder") {}
+
+ static string GetCppName(const AidlInterface& interface) {
+ return "::android::sp<" + GetRawCppName(interface) + ">";
+ }
+
+ static string GetRawCppName(const AidlInterface& interface) {
+ vector<string> name = interface.GetSplitPackage();
+ string ret;
+
+ name.push_back(interface.GetName());
+
+ for (const auto& term : name) {
+ ret += "::" + term;
+ }
+
+ return ret;
+ }
+
+ std::string write_cast_;
+};
+
+class NullableParcelableType : public Type {
+ public:
+ NullableParcelableType(const AidlParcelable& parcelable, const std::string& cpp_header,
+ const std::string& src_file_name)
+ : Type(ValidatableType::KIND_PARCELABLE, parcelable.GetPackage(), parcelable.GetName(),
+ {cpp_header}, GetCppName(parcelable), "readParcelable", "writeNullableParcelable",
+ kNoArrayType, kNoNullableType, src_file_name) {}
+ ~NullableParcelableType() override = default;
+
+ private:
+ static string GetCppName(const AidlParcelable& parcelable) {
+ return "::std::unique_ptr<::" + Join(parcelable.GetSplitPackage(), "::") +
+ "::" + parcelable.GetCppName() + ">";
+ }
+};
+
+class ParcelableType : public Type {
+ public:
+ ParcelableType(const AidlParcelable& parcelable, const std::string& cpp_header,
+ const std::string& src_file_name)
+ : Type(ValidatableType::KIND_PARCELABLE, parcelable.GetPackage(), parcelable.GetName(),
+ {cpp_header}, GetCppName(parcelable), "readParcelable", "writeParcelable",
+ new CppArrayType(ValidatableType::KIND_PARCELABLE, parcelable.GetPackage(),
+ parcelable.GetName(), cpp_header, GetCppName(parcelable),
+ GetCppName(parcelable), "readParcelableVector",
+ "writeParcelableVector", false, src_file_name),
+ new NullableParcelableType(parcelable, cpp_header, src_file_name), src_file_name) {}
+ ~ParcelableType() override = default;
+
+ private:
+ static string GetCppName(const AidlParcelable& parcelable) {
+ return "::" + Join(parcelable.GetSplitPackage(), "::") +
+ "::" + parcelable.GetCppName();
+ }
+};
+
+class NullableMap : public Type {
+ public:
+ NullableMap()
+ : Type(ValidatableType::KIND_BUILT_IN,
+ "java.util", "Map",
+ {"binder/Map.h", "binder/Value.h"},
+ "::std::unique_ptr<::android::binder::Map>",
+ "readNullableMap", "writeNullableMap") {}
+ ~NullableMap() override = default;
+};
+
+
+class MapType : public Type {
+ public:
+ MapType()
+ : Type(ValidatableType::KIND_BUILT_IN,
+ "java.util", "Map",
+ {"binder/Map.h","binder/Value.h"},
+ "::android::binder::Map",
+ "readMap", "writeMap",
+ kNoArrayType,
+ new NullableMap() ) {}
+ ~MapType() override = default;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(MapType);
+}; // class MapType
+
+class NullableStringListType : public Type {
+ public:
+ NullableStringListType()
+ : Type(ValidatableType::KIND_BUILT_IN,
+ "java.util", "List<" + string(kStringCanonicalName) + ">",
+ {"utils/String16.h", "memory", "vector"},
+ "::std::unique_ptr<::std::vector<std::unique_ptr<::android::String16>>>",
+ "readString16Vector", "writeString16Vector") {}
+ ~NullableStringListType() override = default;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(NullableStringListType);
+}; // class NullableStringListType
+
+class StringListType : public Type {
+ public:
+ StringListType()
+ : Type(ValidatableType::KIND_BUILT_IN,
+ "java.util", "List<" + string(kStringCanonicalName) + ">",
+ {"utils/String16.h", "vector"},
+ "::std::vector<::android::String16>",
+ "readString16Vector", "writeString16Vector",
+ kNoArrayType, new NullableStringListType()) {}
+ ~StringListType() override = default;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(StringListType);
+}; // class StringListType
+
+class NullableUtf8InCppStringListType : public Type {
+ public:
+ NullableUtf8InCppStringListType()
+ : Type(ValidatableType::KIND_BUILT_IN,
+ "java.util", "List<" + string(kUtf8InCppStringCanonicalName) + ">",
+ {"memory", "string", "vector"},
+ "::std::unique_ptr<::std::vector<std::unique_ptr<::std::string>>>",
+ "readUtf8VectorFromUtf16Vector", "writeUtf8VectorAsUtf16Vector") {}
+ ~NullableUtf8InCppStringListType() override = default;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(NullableUtf8InCppStringListType);
+}; // class NullableUtf8InCppStringListType
+
+class Utf8InCppStringListType : public Type {
+ public:
+ Utf8InCppStringListType()
+ : Type(ValidatableType::KIND_BUILT_IN,
+ "java.util", "List<" + string(kUtf8InCppStringCanonicalName) + ">",
+ {"string", "vector"},
+ "::std::vector<::std::string>",
+ "readUtf8VectorFromUtf16Vector", "writeUtf8VectorAsUtf16Vector",
+ kNoArrayType, new NullableUtf8InCppStringListType()) {}
+ ~Utf8InCppStringListType() override = default;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(Utf8InCppStringListType);
+}; // class Utf8InCppStringListType
+
+class NullableBinderListType : public Type {
+ public:
+ NullableBinderListType()
+ : Type(ValidatableType::KIND_BUILT_IN, "java.util",
+ "List<android.os.IBinder>", {"binder/IBinder.h", "vector"},
+ "::std::unique_ptr<::std::vector<::android::sp<::android::IBinder>>>",
+ "readStrongBinderVector", "writeStrongBinderVector") {}
+ ~NullableBinderListType() override = default;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(NullableBinderListType);
+}; // class NullableBinderListType
+
+class BinderListType : public Type {
+ public:
+ BinderListType()
+ : Type(ValidatableType::KIND_BUILT_IN, "java.util",
+ "List<android.os.IBinder>", {"binder/IBinder.h", "vector"},
+ "::std::vector<::android::sp<::android::IBinder>>",
+ "readStrongBinderVector", "writeStrongBinderVector",
+ kNoArrayType, new NullableBinderListType()) {}
+ ~BinderListType() override = default;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(BinderListType);
+}; // class BinderListType
+
+} // namespace
+
+Type::Type(int kind,
+ const std::string& package,
+ const std::string& aidl_type,
+ const vector<string>& headers,
+ const string& cpp_type,
+ const string& read_method,
+ const string& write_method,
+ Type* array_type,
+ Type* nullable_type,
+ const string& src_file_name,
+ int line)
+ : ValidatableType(kind, package, aidl_type, src_file_name, line),
+ headers_(headers),
+ aidl_type_(aidl_type),
+ cpp_type_(cpp_type),
+ parcel_read_method_(read_method),
+ parcel_write_method_(write_method),
+ array_type_(array_type),
+ nullable_type_(nullable_type) {}
+
+bool Type::CanWriteToParcel() const { return true; }
+
+void TypeNamespace::Init() {
+ Add(std::make_unique<ByteType>());
+ Add(std::make_unique<PrimitiveType>("int", "cstdint", "int32_t", "readInt32", "writeInt32",
+ "readInt32Vector", "writeInt32Vector"));
+ Add(std::make_unique<PrimitiveType>("long", "cstdint", "int64_t", "readInt64", "writeInt64",
+ "readInt64Vector", "writeInt64Vector"));
+ Add(std::make_unique<PrimitiveType>("float", kNoHeader, "float", "readFloat", "writeFloat",
+ "readFloatVector", "writeFloatVector"));
+ Add(std::make_unique<PrimitiveType>("double", kNoHeader, "double", "readDouble", "writeDouble",
+ "readDoubleVector", "writeDoubleVector"));
+ Add(std::make_unique<PrimitiveType>("boolean", kNoHeader, "bool", "readBool", "writeBool",
+ "readBoolVector", "writeBoolVector"));
+ // C++11 defines the char16_t type as a built in for Unicode characters.
+ Add(std::make_unique<PrimitiveType>("char", kNoHeader, "char16_t", "readChar", "writeChar",
+ "readCharVector", "writeCharVector"));
+
+ Type* string_array_type = new CppArrayType(
+ ValidatableType::KIND_BUILT_IN, "java.lang", "String",
+ "utils/String16.h", "::android::String16",
+ "::std::unique_ptr<::android::String16>", "readString16Vector",
+ "writeString16Vector", false);
+
+ Type* nullable_string_type =
+ new Type(ValidatableType::KIND_BUILT_IN, "java.lang", "String",
+ {"memory", "utils/String16.h"}, "::std::unique_ptr<::android::String16>",
+ "readString16", "writeString16");
+
+ AddAndSetMember(&string_type_,
+ std::make_unique<Type>(ValidatableType::KIND_BUILT_IN, "java.lang", "String",
+ std::vector<std::string>{"utils/String16.h"},
+ "::android::String16", "readString16", "writeString16",
+ string_array_type, nullable_string_type));
+
+ using ::android::aidl::kAidlReservedTypePackage;
+ using ::android::aidl::kUtf8InCppStringClass;
+
+ // This type is a Utf16 string in the parcel, but deserializes to
+ // a std::string in Utf8 format when we use it in C++.
+ Type* cpp_utf8_string_array = new CppArrayType(
+ ValidatableType::KIND_BUILT_IN,
+ kAidlReservedTypePackage, kUtf8InCppStringClass,
+ "string", "::std::string", "::std::unique_ptr<::std::string>",
+ "readUtf8VectorFromUtf16Vector", "writeUtf8VectorAsUtf16Vector",
+ false);
+ Type* nullable_cpp_utf8_string_type =
+ new Type(ValidatableType::KIND_BUILT_IN, kAidlReservedTypePackage, kUtf8InCppStringClass,
+ std::vector<std::string>{"string", "memory"}, "::std::unique_ptr<::std::string>",
+ "readUtf8FromUtf16", "writeUtf8AsUtf16");
+ Add(std::make_unique<Type>(ValidatableType::KIND_BUILT_IN, kAidlReservedTypePackage,
+ kUtf8InCppStringClass, std::vector<std::string>{"string"},
+ "::std::string", "readUtf8FromUtf16", "writeUtf8AsUtf16",
+ cpp_utf8_string_array, nullable_cpp_utf8_string_type));
+
+ Type* nullable_ibinder = new Type(
+ ValidatableType::KIND_BUILT_IN, "android.os", "IBinder",
+ {"binder/IBinder.h"}, "::android::sp<::android::IBinder>",
+ "readNullableStrongBinder", "writeStrongBinder");
+
+ AddAndSetMember(&ibinder_type_,
+ std::make_unique<Type>(ValidatableType::KIND_BUILT_IN, "android.os", "IBinder",
+ std::vector<std::string>{"binder/IBinder.h"},
+ "::android::sp<::android::IBinder>", "readStrongBinder",
+ "writeStrongBinder", kNoArrayType, nullable_ibinder));
+
+ Add(std::make_unique<MapType>());
+
+ Add(std::make_unique<BinderListType>());
+ Add(std::make_unique<StringListType>());
+ Add(std::make_unique<Utf8InCppStringListType>());
+
+ Type* fd_vector_type = new CppArrayType(
+ ValidatableType::KIND_BUILT_IN, kNoPackage, "FileDescriptor",
+ "android-base/unique_fd.h",
+ "::android::base::unique_fd", "::android::base::unique_fd",
+ "readUniqueFileDescriptorVector", "writeUniqueFileDescriptorVector",
+ false);
+
+ Add(std::make_unique<Type>(ValidatableType::KIND_BUILT_IN, kNoPackage, "FileDescriptor",
+ std::vector<std::string>{"android-base/unique_fd.h"},
+ "::android::base::unique_fd", "readUniqueFileDescriptor",
+ "writeUniqueFileDescriptor", fd_vector_type));
+
+ Type* pfd_vector_type =
+ new CppArrayType(ValidatableType::KIND_BUILT_IN, "android.os", "ParcelFileDescriptor",
+ "binder/ParcelFileDescriptor.h", "::android::os::ParcelFileDescriptor",
+ "::android::os::ParcelFileDescriptor", "readParcelableVector",
+ "writeParcelableVector", false);
+
+ Type* nullable_pfd_type =
+ new Type(ValidatableType::KIND_BUILT_IN, "android.os", "ParcelFileDescriptor",
+ std::vector<std::string>{"memory", "binder/ParcelFileDescriptor.h"},
+ "::std::unique_ptr<::android::os::ParcelFileDescriptor>", "readParcelable",
+ "writeNullableParcelable");
+
+ Add(std::make_unique<Type>(ValidatableType::KIND_BUILT_IN, "android.os", "ParcelFileDescriptor",
+ std::vector<std::string>{"binder/ParcelFileDescriptor.h"},
+ "::android::os::ParcelFileDescriptor", "readParcelable",
+ "writeParcelable", pfd_vector_type, nullable_pfd_type));
+
+ // Qualify VoidType so we don't get collisions with the VoidType method
+ AddAndSetMember(&void_type_, std::make_unique<class VoidType>());
+}
+
+bool TypeNamespace::AddParcelableType(const AidlParcelable& p, const std::string& filename) {
+ const std::string cpp_header = p.AsStructuredParcelable() ? GetCppHeader(p) : p.GetCppHeader();
+
+ if (cpp_header.empty()) {
+ AIDL_ERROR(p) << "Parcelable " << p.GetCanonicalName() << " has no C++ header defined.";
+ return false;
+ }
+
+ Add(std::make_unique<ParcelableType>(p, cpp_header, filename));
+ return true;
+}
+
+bool TypeNamespace::AddBinderType(const AidlInterface& b, const std::string& filename) {
+ Add(std::make_unique<BinderType>(b, filename));
+ return true;
+}
+
+bool TypeNamespace::AddListType(const std::string& type_name) {
+ const Type* contained_type = FindTypeByCanonicalName(type_name);
+ if (!contained_type) {
+ LOG(ERROR) << "Cannot create List<" << type_name << "> because contained "
+ "type cannot be found or is invalid.";
+ return false;
+ }
+ if (contained_type->IsCppPrimitive()) {
+ LOG(ERROR) << "Cannot create List<" << type_name << "> because contained "
+ "type is a primitive in Java and Java List cannot hold "
+ "primitives.";
+ return false;
+ }
+
+ if (contained_type->CanonicalName() == kStringCanonicalName ||
+ contained_type->CanonicalName() == kUtf8InCppStringCanonicalName ||
+ contained_type == IBinderType()) {
+ return true;
+ }
+
+ // TODO Support lists of parcelables b/23600712
+
+ LOG(ERROR) << "aidl-cpp does not yet support List<" << type_name << ">";
+ return false;
+}
+
+bool TypeNamespace::AddMapType(const std::string& /* key_type_name */,
+ const std::string& /* value_type_name */) {
+ // TODO Support list types b/25242025
+ LOG(ERROR) << "aidl does not implement support for typed maps!";
+ return false;
+}
+
+const ValidatableType* TypeNamespace::GetArgType(const AidlArgument& a, int arg_index,
+ const AidlDefinedType& context) const {
+ return ::android::aidl::TypeNamespace::GetArgType(a, arg_index, context);
+}
+
+} // namespace cpp
+} // namespace aidl
+} // namespace android
diff --git a/type_cpp.h b/type_cpp.h
new file mode 100644
index 0000000..a27132b
--- /dev/null
+++ b/type_cpp.h
@@ -0,0 +1,118 @@
+/*
+ * Copyright (C) 2015, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <memory>
+#include <string>
+#include <set>
+#include <vector>
+
+#include <android-base/macros.h>
+
+#include "type_namespace.h"
+
+namespace android {
+namespace aidl {
+namespace cpp {
+
+class Type : public ValidatableType {
+ public:
+ Type(int kind, // from ValidatableType
+ const std::string& package,
+ const std::string& aidl_type,
+ const std::vector<std::string>& header,
+ const std::string& cpp_type,
+ const std::string& read_method,
+ const std::string& write_method,
+ Type* array_type = nullptr,
+ Type* nullable_type = nullptr,
+ const std::string& src_file_name = "",
+ int line = -1);
+ virtual ~Type() = default;
+
+ // overrides of ValidatableType
+ bool CanWriteToParcel() const override;
+
+ const Type* ArrayType() const override { return array_type_.get(); }
+ const Type* NullableType() const override { return nullable_type_.get(); }
+ std::string CppType() const { return cpp_type_; }
+ const std::string& ReadFromParcelMethod() const {
+ return parcel_read_method_;
+ }
+ const std::string& WriteToParcelMethod() const {
+ return parcel_write_method_;
+ }
+
+ void GetHeaders(std::set<std::string>* headers) const {
+ for (const std::string& header : headers_) {
+ if (!header.empty()) {
+ headers->insert(header);
+ }
+ }
+ }
+ virtual bool IsCppPrimitive() const { return false; }
+ virtual std::string WriteCast(const std::string& value) const {
+ return value;
+ }
+
+ private:
+ // |headers| are the headers we must include to use this type
+ const std::vector<std::string> headers_;
+ // |aidl_type| is what we find in the yacc generated AST (e.g. "int").
+ const std::string aidl_type_;
+ // |cpp_type| is what we use in the generated C++ code (e.g. "int32_t").
+ const std::string cpp_type_;
+ const std::string parcel_read_method_;
+ const std::string parcel_write_method_;
+
+ const std::unique_ptr<Type> array_type_;
+ const std::unique_ptr<Type> nullable_type_;
+
+ DISALLOW_COPY_AND_ASSIGN(Type);
+}; // class Type
+
+class TypeNamespace : public ::android::aidl::LanguageTypeNamespace<Type> {
+ public:
+ TypeNamespace() = default;
+ virtual ~TypeNamespace() = default;
+
+ void Init() override;
+ bool AddParcelableType(const AidlParcelable& p,
+ const std::string& filename) override;
+ bool AddBinderType(const AidlInterface& b,
+ const std::string& filename) override;
+ bool AddListType(const std::string& type_name) override;
+ bool AddMapType(const std::string& key_type_name,
+ const std::string& value_type_name) override;
+
+ const ValidatableType* GetArgType(const AidlArgument& a, int arg_index,
+ const AidlDefinedType& context) const override;
+
+ const Type* VoidType() const { return void_type_; }
+ const Type* IBinderType() const { return ibinder_type_; }
+
+ private:
+ const Type* void_type_ = nullptr;
+ const Type* string_type_ = nullptr;
+ const Type* ibinder_type_ = nullptr;
+
+ DISALLOW_COPY_AND_ASSIGN(TypeNamespace);
+}; // class TypeNamespace
+
+} // namespace cpp
+} // namespace aidl
+} // namespace android
diff --git a/type_cpp_unittest.cpp b/type_cpp_unittest.cpp
new file mode 100644
index 0000000..79b47a9
--- /dev/null
+++ b/type_cpp_unittest.cpp
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2015, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <memory>
+#include <string>
+
+#include <gtest/gtest.h>
+
+#include "type_cpp.h"
+
+using std::string;
+using std::unique_ptr;
+
+namespace android {
+namespace aidl {
+namespace cpp {
+
+namespace {
+
+string kParcelableDotName = "Outer.Inner";
+string kParcelableColonName = "Outer::Inner";
+
+} // namespace
+
+class CppTypeNamespaceTest : public ::testing::Test {
+ protected:
+ void SetUp() override {
+ types_.Init();
+ }
+ TypeNamespace types_;
+};
+
+TEST_F(CppTypeNamespaceTest, HasSomeBasicTypes) {
+ EXPECT_TRUE(types_.HasTypeByCanonicalName("byte"));
+ EXPECT_TRUE(types_.HasTypeByCanonicalName("int"));
+ EXPECT_TRUE(types_.HasTypeByCanonicalName("long"));
+ EXPECT_TRUE(types_.HasTypeByCanonicalName("float"));
+ EXPECT_TRUE(types_.HasTypeByCanonicalName("double"));
+ EXPECT_TRUE(types_.HasTypeByCanonicalName("boolean"));
+ EXPECT_TRUE(types_.HasTypeByCanonicalName("char"));
+ EXPECT_TRUE(types_.HasTypeByCanonicalName("String"));
+}
+
+TEST_F(CppTypeNamespaceTest, SupportsListString) {
+ EXPECT_TRUE(
+ types_.HasTypeByCanonicalName("java.util.List<java.lang.String>"));
+}
+
+TEST_F(CppTypeNamespaceTest, SupportsNestedParcelableClass) {
+ unique_ptr<AidlParcelable> parcelable(new AidlParcelable(
+ AIDL_LOCATION_HERE, new AidlQualifiedName(AIDL_LOCATION_HERE, kParcelableDotName, ""),
+ {"a", "goog"}, ""));
+ EXPECT_EQ(parcelable->GetCppName(), kParcelableColonName);
+}
+
+} // namespace cpp
+} // namespace android
+} // namespace aidl
diff --git a/type_java.cpp b/type_java.cpp
new file mode 100644
index 0000000..1298eac
--- /dev/null
+++ b/type_java.cpp
@@ -0,0 +1,363 @@
+/*
+ * Copyright (C) 2015, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "type_java.h"
+
+#include <sys/types.h>
+#include <memory>
+
+#include <android-base/strings.h>
+
+#include "aidl_language.h"
+#include "logging.h"
+
+using std::string;
+
+namespace android {
+namespace aidl {
+namespace java {
+
+Expression* NULL_VALUE;
+Expression* THIS_VALUE;
+Expression* SUPER_VALUE;
+Expression* TRUE_VALUE;
+Expression* FALSE_VALUE;
+
+// ================================================================
+
+Type::Type(const JavaTypeNamespace* types, const string& name, int kind, bool canWriteToParcel)
+ : Type(types, "", name, kind, canWriteToParcel, "", -1) {}
+
+Type::Type(const JavaTypeNamespace* types, const string& package, const string& name, int kind,
+ bool canWriteToParcel, const string& declFile, int declLine)
+ : ValidatableType(kind, package, name, declFile, declLine),
+ m_types(types),
+ m_javaType((package.empty()) ? name : package + "." + name),
+ m_canWriteToParcel(canWriteToParcel) {}
+
+string Type::InstantiableName() const { return JavaType(); }
+
+Expression* Type::BuildWriteToParcelFlags(int flags) const {
+ if (flags == 0) {
+ return new LiteralExpression("0");
+ }
+ if ((flags & PARCELABLE_WRITE_RETURN_VALUE) != 0) {
+ return new FieldVariable(m_types->ParcelableInterfaceType()->JavaType(),
+ "PARCELABLE_WRITE_RETURN_VALUE");
+ }
+ return new LiteralExpression("0");
+}
+
+// ================================================================
+
+BasicType::BasicType(const JavaTypeNamespace* types, const string& name,
+ const string& marshallParcel, const string& unmarshallParcel,
+ const string& writeArrayParcel, const string& createArrayParcel,
+ const string& readArrayParcel)
+ : Type(types, name, ValidatableType::KIND_BUILT_IN, true),
+ m_marshallParcel(marshallParcel),
+ m_unmarshallParcel(unmarshallParcel) {
+ m_array_type.reset(new BasicArrayType(types, name, writeArrayParcel,
+ createArrayParcel, readArrayParcel));
+}
+
+BasicArrayType::BasicArrayType(const JavaTypeNamespace* types, const string& name,
+ const string& writeArrayParcel, const string& createArrayParcel,
+ const string& readArrayParcel)
+ : Type(types, name, ValidatableType::KIND_BUILT_IN, true),
+ m_writeArrayParcel(writeArrayParcel),
+ m_createArrayParcel(createArrayParcel),
+ m_readArrayParcel(readArrayParcel) {}
+
+// ================================================================
+
+FileDescriptorType::FileDescriptorType(const JavaTypeNamespace* types)
+ : Type(types, "java.io", "FileDescriptor", ValidatableType::KIND_BUILT_IN, true) {
+ m_array_type.reset(new FileDescriptorArrayType(types));
+}
+
+FileDescriptorArrayType::FileDescriptorArrayType(const JavaTypeNamespace* types)
+ : Type(types, "java.io", "FileDescriptor", ValidatableType::KIND_BUILT_IN, true) {}
+
+// ================================================================
+
+ParcelFileDescriptorType::ParcelFileDescriptorType(const JavaTypeNamespace* types)
+ : Type(types, "android.os", "ParcelFileDescriptor", ValidatableType::KIND_BUILT_IN, true) {
+ m_array_type.reset(new ParcelFileDescriptorArrayType(types));
+}
+
+ParcelFileDescriptorArrayType::ParcelFileDescriptorArrayType(const JavaTypeNamespace* types)
+ : Type(types, "android.os", "ParcelFileDescriptor", ValidatableType::KIND_BUILT_IN, true) {}
+
+// ================================================================
+
+BooleanType::BooleanType(const JavaTypeNamespace* types)
+ : Type(types, "boolean", ValidatableType::KIND_BUILT_IN, true) {
+ m_array_type.reset(new BooleanArrayType(types));
+}
+
+BooleanArrayType::BooleanArrayType(const JavaTypeNamespace* types)
+ : Type(types, "boolean", ValidatableType::KIND_BUILT_IN, true) {}
+
+// ================================================================
+
+CharType::CharType(const JavaTypeNamespace* types)
+ : Type(types, "char", ValidatableType::KIND_BUILT_IN, true) {
+ m_array_type.reset(new CharArrayType(types));
+}
+
+CharArrayType::CharArrayType(const JavaTypeNamespace* types)
+ : Type(types, "char", ValidatableType::KIND_BUILT_IN, true) {}
+
+// ================================================================
+
+StringType::StringType(const JavaTypeNamespace* types, const std::string& package,
+ const std::string& class_name)
+ : Type(types, package, class_name, ValidatableType::KIND_BUILT_IN, true) {
+ m_array_type.reset(new StringArrayType(types));
+}
+
+StringArrayType::StringArrayType(const JavaTypeNamespace* types)
+ : Type(types, "java.lang", "String", ValidatableType::KIND_BUILT_IN, true) {}
+
+// ================================================================
+
+CharSequenceType::CharSequenceType(const JavaTypeNamespace* types)
+ : Type(types, "java.lang", "CharSequence", ValidatableType::KIND_BUILT_IN, true) {}
+
+// ================================================================
+
+RemoteExceptionType::RemoteExceptionType(const JavaTypeNamespace* types)
+ : Type(types, "android.os", "RemoteException", ValidatableType::KIND_BUILT_IN, false) {}
+
+// ================================================================
+
+RuntimeExceptionType::RuntimeExceptionType(const JavaTypeNamespace* types)
+ : Type(types, "java.lang", "RuntimeException", ValidatableType::KIND_BUILT_IN, false) {}
+
+// ================================================================
+
+IBinderType::IBinderType(const JavaTypeNamespace* types)
+ : Type(types, "android.os", "IBinder", ValidatableType::KIND_BUILT_IN, true) {
+ m_array_type.reset(new IBinderArrayType(types));
+}
+
+IBinderArrayType::IBinderArrayType(const JavaTypeNamespace* types)
+ : Type(types, "android.os", "IBinder", ValidatableType::KIND_BUILT_IN, true) {}
+
+// ================================================================
+
+IInterfaceType::IInterfaceType(const JavaTypeNamespace* types)
+ : Type(types, "android.os", "IInterface", ValidatableType::KIND_BUILT_IN, false) {}
+
+// ================================================================
+
+BinderType::BinderType(const JavaTypeNamespace* types)
+ : Type(types, "android.os", "Binder", ValidatableType::KIND_BUILT_IN, false) {}
+
+// ================================================================
+
+BinderProxyType::BinderProxyType(const JavaTypeNamespace* types)
+ : Type(types, "android.os", "BinderProxy", ValidatableType::KIND_BUILT_IN, false) {}
+
+// ================================================================
+
+ParcelType::ParcelType(const JavaTypeNamespace* types)
+ : Type(types, "android.os", "Parcel", ValidatableType::KIND_BUILT_IN, false) {}
+
+// ================================================================
+
+ParcelableInterfaceType::ParcelableInterfaceType(const JavaTypeNamespace* types)
+ : Type(types, "android.os", "Parcelable", ValidatableType::KIND_BUILT_IN, false) {}
+
+// ================================================================
+
+MapType::MapType(const JavaTypeNamespace* types)
+ : Type(types, "java.util", "Map", ValidatableType::KIND_BUILT_IN, true) {}
+
+// ================================================================
+
+ListType::ListType(const JavaTypeNamespace* types)
+ : Type(types, "java.util", "List", ValidatableType::KIND_BUILT_IN, true) {}
+
+string ListType::InstantiableName() const { return "java.util.ArrayList"; }
+
+// ================================================================
+
+UserDataType::UserDataType(const JavaTypeNamespace* types, const string& package,
+ const string& name, bool builtIn, bool canWriteToParcel,
+ const string& declFile, int declLine)
+ : Type(types, package, name,
+ builtIn ? ValidatableType::KIND_BUILT_IN : ValidatableType::KIND_PARCELABLE,
+ canWriteToParcel, declFile, declLine) {
+ m_array_type.reset(new UserDataArrayType(types, package, name, builtIn,
+ canWriteToParcel, declFile,
+ declLine));
+}
+
+UserDataArrayType::UserDataArrayType(const JavaTypeNamespace* types, const string& package,
+ const string& name, bool builtIn, bool canWriteToParcel,
+ const string& declFile, int declLine)
+ : Type(types, package, name,
+ builtIn ? ValidatableType::KIND_BUILT_IN : ValidatableType::KIND_PARCELABLE,
+ canWriteToParcel, declFile, declLine) {}
+
+// ================================================================
+
+InterfaceType::InterfaceType(const JavaTypeNamespace* types, const string& package,
+ const string& name, bool builtIn, const string& declFile, int declLine,
+ const Type* stub, const Type* proxy, const Type* defaultImpl)
+ : Type(types, package, name,
+ builtIn ? ValidatableType::KIND_BUILT_IN : ValidatableType::KIND_INTERFACE, true,
+ declFile, declLine),
+ stub_(stub),
+ proxy_(proxy),
+ defaultImpl_(defaultImpl) {}
+
+// ================================================================
+
+GenericListType::GenericListType(const JavaTypeNamespace* types, const Type* contained_type)
+ : Type(types, "java.util", "List<" + contained_type->CanonicalName() + ">",
+ ValidatableType::KIND_BUILT_IN, true),
+ m_contained_type(contained_type) {}
+
+string GenericListType::InstantiableName() const {
+ return "java.util.ArrayList<" + m_contained_type->JavaType() + ">";
+}
+
+// ================================================================
+
+ClassLoaderType::ClassLoaderType(const JavaTypeNamespace* types)
+ : Type(types, "java.lang", "ClassLoader", ValidatableType::KIND_BUILT_IN, false) {}
+
+// ================================================================
+
+void JavaTypeNamespace::Init() {
+ Add(std::make_unique<BasicType>(this, "void", "XXX", "XXX", "XXX", "XXX", "XXX"));
+
+ AddAndSetMember(&m_bool_type, std::make_unique<BooleanType>(this));
+
+ Add(std::make_unique<BasicType>(this, "byte", "writeByte", "readByte", "writeByteArray",
+ "createByteArray", "readByteArray"));
+
+ Add(std::make_unique<CharType>(this));
+
+ AddAndSetMember(&m_int_type,
+ std::make_unique<BasicType>(this, "int", "writeInt", "readInt", "writeIntArray",
+ "createIntArray", "readIntArray"));
+
+ Add(std::make_unique<BasicType>(this, "long", "writeLong", "readLong", "writeLongArray",
+ "createLongArray", "readLongArray"));
+
+ Add(std::make_unique<BasicType>(this, "float", "writeFloat", "readFloat", "writeFloatArray",
+ "createFloatArray", "readFloatArray"));
+
+ Add(std::make_unique<BasicType>(this, "double", "writeDouble", "readDouble", "writeDoubleArray",
+ "createDoubleArray", "readDoubleArray"));
+
+ AddAndSetMember(&m_string_type, std::make_unique<class StringType>(this, "java.lang", "String"));
+ Add(std::make_unique<class StringType>(this, ::android::aidl::kAidlReservedTypePackage,
+ ::android::aidl::kUtf8InCppStringClass));
+
+ Add(std::make_unique<Type>(this, "java.lang", "Object", ValidatableType::KIND_BUILT_IN, false));
+
+ Add(std::make_unique<FileDescriptorType>(this));
+
+ Add(std::make_unique<ParcelFileDescriptorType>(this));
+
+ Add(std::make_unique<CharSequenceType>(this));
+
+ Add(std::make_unique<MapType>(this));
+
+ Add(std::make_unique<ListType>(this));
+
+ AddAndSetMember(&m_text_utils_type,
+ std::make_unique<Type>(this, "android.text", "TextUtils",
+ ValidatableType::KIND_BUILT_IN, false));
+
+ AddAndSetMember(&m_remote_exception_type, std::make_unique<class RemoteExceptionType>(this));
+
+ AddAndSetMember(&m_runtime_exception_type, std::make_unique<class RuntimeExceptionType>(this));
+
+ AddAndSetMember(&m_ibinder_type, std::make_unique<class IBinderType>(this));
+
+ AddAndSetMember(&m_iinterface_type, std::make_unique<class IInterfaceType>(this));
+
+ AddAndSetMember(&m_binder_native_type, std::make_unique<BinderType>(this));
+
+ AddAndSetMember(&m_binder_proxy_type, std::make_unique<class BinderProxyType>(this));
+
+ AddAndSetMember(&m_parcel_type, std::make_unique<class ParcelType>(this));
+
+ AddAndSetMember(&m_parcelable_interface_type,
+ std::make_unique<class ParcelableInterfaceType>(this));
+
+ AddAndSetMember(&m_context_type, std::make_unique<Type>(this, "android.content", "Context",
+ ValidatableType::KIND_BUILT_IN, false));
+
+ AddAndSetMember(&m_classloader_type, std::make_unique<class ClassLoaderType>(this));
+
+ NULL_VALUE = new LiteralExpression("null");
+ THIS_VALUE = new LiteralExpression("this");
+ SUPER_VALUE = new LiteralExpression("super");
+ TRUE_VALUE = new LiteralExpression("true");
+ FALSE_VALUE = new LiteralExpression("false");
+}
+
+bool JavaTypeNamespace::AddParcelableType(const AidlParcelable& p,
+ const std::string& filename) {
+ return Add(
+ std::make_unique<UserDataType>(this, p.GetPackage(), p.GetName(), false, true, filename));
+}
+
+bool JavaTypeNamespace::AddBinderType(const AidlInterface& b,
+ const std::string& filename) {
+ // for interfaces, add the stub, proxy, and interface types.
+ auto stub = std::make_unique<Type>(this, b.GetPackage(), b.GetName() + ".Stub",
+ ValidatableType::KIND_GENERATED, false, filename);
+ auto proxy = std::make_unique<Type>(this, b.GetPackage(), b.GetName() + ".Stub.Proxy",
+ ValidatableType::KIND_GENERATED, false, filename);
+ auto defaultImpl = std::make_unique<Type>(this, b.GetPackage(), b.GetName() + ".Default",
+ ValidatableType::KIND_GENERATED, false, filename);
+ auto type = std::make_unique<InterfaceType>(this, b.GetPackage(), b.GetName(), false, filename,
+ -1, stub.get(), proxy.get(), defaultImpl.get());
+
+ bool success = true;
+ success &= Add(std::move(type));
+ success &= Add(std::move(stub));
+ success &= Add(std::move(proxy));
+ success &= Add(std::move(defaultImpl));
+ return success;
+}
+
+bool JavaTypeNamespace::AddListType(const std::string& contained_type_name) {
+ const Type* contained_type = FindTypeByCanonicalName(contained_type_name);
+ if (!contained_type) {
+ return false;
+ }
+ Add(std::make_unique<GenericListType>(this, contained_type));
+ return true;
+}
+
+bool JavaTypeNamespace::AddMapType(const string& /*key_type_name*/,
+ const string& /*value_type_name*/) {
+ LOG(ERROR) << "Don't know how to create a Map<K,V> container.";
+ return false;
+}
+
+} // namespace java
+} // namespace aidl
+} // namespace android
diff --git a/type_java.h b/type_java.h
new file mode 100644
index 0000000..a5c1ff8
--- /dev/null
+++ b/type_java.h
@@ -0,0 +1,343 @@
+/*
+ * Copyright (C) 2015, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <string>
+#include <vector>
+
+#include "ast_java.h"
+#include "type_namespace.h"
+
+namespace android {
+namespace aidl {
+namespace java {
+
+class JavaTypeNamespace;
+
+class Type : public ValidatableType {
+ public:
+ // WriteToParcel flags
+ enum { PARCELABLE_WRITE_RETURN_VALUE = 0x0001 };
+
+ // defaultValue is by default set to "null" because that is the default value
+ // for most of the types like class and array. default values for built-in
+ // types like int, double, boolean, etc. are explicitly set via BasicType
+ Type(const JavaTypeNamespace* types, const std::string& name, int kind, bool canWriteToParcel);
+ Type(const JavaTypeNamespace* types, const std::string& package, const std::string& name,
+ int kind, bool canWriteToParcel, const std::string& declFile = "", int declLine = -1);
+ virtual ~Type() = default;
+
+ bool CanWriteToParcel() const override { return m_canWriteToParcel; }
+
+ const ValidatableType* ArrayType() const override { return m_array_type.get(); }
+ const ValidatableType* NullableType() const override { return nullptr; }
+
+ virtual std::string JavaType() const { return m_javaType; }
+ virtual std::string InstantiableName() const;
+
+ // The namespace where this type is defined in
+ const JavaTypeNamespace* GetTypeNamespace() const { return m_types; }
+
+ protected:
+ Expression* BuildWriteToParcelFlags(int flags) const;
+
+ const JavaTypeNamespace* m_types;
+
+ std::unique_ptr<Type> m_array_type;
+
+ private:
+ Type();
+ Type(const Type&);
+
+ std::string m_javaType;
+ std::string m_declFile;
+ bool m_canWriteToParcel;
+};
+
+class BasicArrayType : public Type {
+ public:
+ BasicArrayType(const JavaTypeNamespace* types, const std::string& name,
+ const std::string& writeArrayParcel,
+ const std::string& createArrayParcel,
+ const std::string& readArrayParcel);
+
+ const ValidatableType* NullableType() const override { return this; }
+
+ private:
+ std::string m_writeArrayParcel;
+ std::string m_createArrayParcel;
+ std::string m_readArrayParcel;
+};
+
+class BasicType : public Type {
+ public:
+ BasicType(const JavaTypeNamespace* types, const std::string& name,
+ const std::string& marshallParcel, const std::string& unmarshallParcel,
+ const std::string& writeArrayParcel, const std::string& createArrayParcel,
+ const std::string& readArrayParcel);
+
+ private:
+ std::string m_marshallParcel;
+ std::string m_unmarshallParcel;
+};
+
+class FileDescriptorArrayType : public Type {
+ public:
+ explicit FileDescriptorArrayType(const JavaTypeNamespace* types);
+
+ const ValidatableType* NullableType() const override { return this; }
+};
+
+class FileDescriptorType : public Type {
+ public:
+ explicit FileDescriptorType(const JavaTypeNamespace* types);
+};
+
+class ParcelFileDescriptorArrayType : public Type {
+ public:
+ explicit ParcelFileDescriptorArrayType(const JavaTypeNamespace* types);
+
+ const ValidatableType* NullableType() const override { return this; }
+};
+
+class ParcelFileDescriptorType : public Type {
+ public:
+ explicit ParcelFileDescriptorType(const JavaTypeNamespace* types);
+
+ const ValidatableType* NullableType() const override { return this; }
+};
+
+class BooleanArrayType : public Type {
+ public:
+ explicit BooleanArrayType(const JavaTypeNamespace* types);
+ const ValidatableType* NullableType() const override { return this; }
+};
+
+class BooleanType : public Type {
+ public:
+ explicit BooleanType(const JavaTypeNamespace* types);
+};
+
+class CharArrayType : public Type {
+ public:
+ explicit CharArrayType(const JavaTypeNamespace* types);
+ const ValidatableType* NullableType() const override { return this; }
+};
+
+class CharType : public Type {
+ public:
+ explicit CharType(const JavaTypeNamespace* types);
+};
+
+class StringArrayType : public Type {
+ public:
+ explicit StringArrayType(const JavaTypeNamespace* types);
+
+ const ValidatableType* NullableType() const override { return this; }
+};
+
+class StringType : public Type {
+ public:
+ StringType(const JavaTypeNamespace* types, const std::string& package,
+ const std::string& class_name);
+
+ std::string JavaType() const override { return "java.lang.String"; }
+ const ValidatableType* NullableType() const override { return this; }
+};
+
+class CharSequenceType : public Type {
+ public:
+ explicit CharSequenceType(const JavaTypeNamespace* types);
+};
+
+class RemoteExceptionType : public Type {
+ public:
+ explicit RemoteExceptionType(const JavaTypeNamespace* types);
+};
+
+class RuntimeExceptionType : public Type {
+ public:
+ explicit RuntimeExceptionType(const JavaTypeNamespace* types);
+};
+
+class IBinderArrayType : public Type {
+ public:
+ explicit IBinderArrayType(const JavaTypeNamespace* types);
+ const ValidatableType* NullableType() const override { return this; }
+};
+
+class IBinderType : public Type {
+ public:
+ explicit IBinderType(const JavaTypeNamespace* types);
+ const ValidatableType* NullableType() const override { return this; }
+};
+
+class IInterfaceType : public Type {
+ public:
+ explicit IInterfaceType(const JavaTypeNamespace* types);
+};
+
+class BinderType : public Type {
+ public:
+ explicit BinderType(const JavaTypeNamespace* types);
+};
+
+class BinderProxyType : public Type {
+ public:
+ explicit BinderProxyType(const JavaTypeNamespace* types);
+};
+
+class ParcelType : public Type {
+ public:
+ explicit ParcelType(const JavaTypeNamespace* types);
+ const ValidatableType* NullableType() const override { return this; }
+};
+
+class ParcelableInterfaceType : public Type {
+ public:
+ explicit ParcelableInterfaceType(const JavaTypeNamespace* types);
+};
+
+class MapType : public Type {
+ public:
+ explicit MapType(const JavaTypeNamespace* types);
+ const ValidatableType* NullableType() const override { return this; }
+};
+
+class ListType : public Type {
+ public:
+ explicit ListType(const JavaTypeNamespace* types);
+
+ std::string InstantiableName() const override;
+ const ValidatableType* NullableType() const override { return this; }
+};
+
+class UserDataArrayType : public Type {
+ public:
+ UserDataArrayType(const JavaTypeNamespace* types, const std::string& package,
+ const std::string& name, bool builtIn,
+ bool canWriteToParcel, const std::string& declFile = "",
+ int declLine = -1);
+
+ const ValidatableType* NullableType() const override { return this; }
+};
+
+class UserDataType : public Type {
+ public:
+ UserDataType(const JavaTypeNamespace* types, const std::string& package,
+ const std::string& name, bool builtIn, bool canWriteToParcel,
+ const std::string& declFile = "", int declLine = -1);
+
+ const ValidatableType* NullableType() const override { return this; }
+};
+
+class InterfaceType : public Type {
+ public:
+ InterfaceType(const JavaTypeNamespace* types, const std::string& package, const std::string& name,
+ bool builtIn, const std::string& declFile, int declLine, const Type* stub,
+ const Type* proxy, const Type* defaultImpl);
+
+ const ValidatableType* NullableType() const override { return this; }
+ const Type* GetStub() const { return stub_; }
+ const Type* GetProxy() const { return proxy_; }
+ const Type* GetDefaultImpl() const { return defaultImpl_; }
+
+ private:
+ const Type* stub_;
+ const Type* proxy_;
+ const Type* defaultImpl_;
+};
+
+class ClassLoaderType : public Type {
+ public:
+ explicit ClassLoaderType(const JavaTypeNamespace* types);
+};
+
+class GenericListType : public Type {
+ public:
+ GenericListType(const JavaTypeNamespace* types, const Type* arg);
+
+ std::string InstantiableName() const override;
+ std::string JavaType() const override {
+ return "java.util.List<" + m_contained_type->JavaType() + ">";
+ }
+
+ const ValidatableType* NullableType() const override { return this; }
+
+ private:
+ const Type* m_contained_type;
+};
+
+class JavaTypeNamespace : public LanguageTypeNamespace<Type> {
+ public:
+ JavaTypeNamespace() = default;
+ virtual ~JavaTypeNamespace() = default;
+
+ void Init() override;
+ bool AddParcelableType(const AidlParcelable& p,
+ const std::string& filename) override;
+ bool AddBinderType(const AidlInterface& b,
+ const std::string& filename) override;
+ bool AddListType(const std::string& contained_type_name) override;
+ bool AddMapType(const std::string& key_type_name,
+ const std::string& value_type_name) override;
+
+ const Type* BoolType() const { return m_bool_type; }
+ const Type* IntType() const { return m_int_type; }
+ const Type* StringType() const { return m_string_type; }
+ const Type* TextUtilsType() const { return m_text_utils_type; }
+ const Type* RemoteExceptionType() const { return m_remote_exception_type; }
+ const Type* RuntimeExceptionType() const { return m_runtime_exception_type; }
+ const Type* IBinderType() const { return m_ibinder_type; }
+ const Type* IInterfaceType() const { return m_iinterface_type; }
+ const Type* BinderNativeType() const { return m_binder_native_type; }
+ const Type* BinderProxyType() const { return m_binder_proxy_type; }
+ const Type* ParcelType() const { return m_parcel_type; }
+ const Type* ParcelableInterfaceType() const {
+ return m_parcelable_interface_type;
+ }
+ const Type* ContextType() const { return m_context_type; }
+ const Type* ClassLoaderType() const { return m_classloader_type; }
+
+ private:
+ const Type* m_bool_type{nullptr};
+ const Type* m_int_type{nullptr};
+ const Type* m_string_type{nullptr};
+ const Type* m_text_utils_type{nullptr};
+ const Type* m_remote_exception_type{nullptr};
+ const Type* m_runtime_exception_type{nullptr};
+ const Type* m_ibinder_type{nullptr};
+ const Type* m_iinterface_type{nullptr};
+ const Type* m_binder_native_type{nullptr};
+ const Type* m_binder_proxy_type{nullptr};
+ const Type* m_parcel_type{nullptr};
+ const Type* m_parcelable_interface_type{nullptr};
+ const Type* m_context_type{nullptr};
+ const Type* m_classloader_type{nullptr};
+
+ DISALLOW_COPY_AND_ASSIGN(JavaTypeNamespace);
+};
+
+extern Expression* NULL_VALUE;
+extern Expression* THIS_VALUE;
+extern Expression* SUPER_VALUE;
+extern Expression* TRUE_VALUE;
+extern Expression* FALSE_VALUE;
+
+} // namespace java
+} // namespace aidl
+} // namespace android
diff --git a/type_java_unittest.cpp b/type_java_unittest.cpp
new file mode 100644
index 0000000..098a7a5
--- /dev/null
+++ b/type_java_unittest.cpp
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2015, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <memory>
+
+#include <gtest/gtest.h>
+
+#include "aidl_language.h"
+#include "type_java.h"
+
+using std::unique_ptr;
+
+namespace android {
+namespace aidl {
+namespace java {
+
+class JavaTypeNamespaceTest : public ::testing::Test {
+ protected:
+ void SetUp() override {
+ types_.Init();
+ }
+ JavaTypeNamespace types_;
+};
+
+TEST_F(JavaTypeNamespaceTest, HasSomeBasicTypes) {
+ EXPECT_TRUE(types_.HasTypeByCanonicalName("void"));
+ EXPECT_TRUE(types_.HasTypeByCanonicalName("int"));
+ EXPECT_TRUE(types_.HasTypeByCanonicalName("java.lang.String"));
+}
+
+TEST_F(JavaTypeNamespaceTest, ContainerTypeCreation) {
+ // We start with no knowledge of parcelables or lists of them.
+ EXPECT_FALSE(types_.HasTypeByCanonicalName("Foo"));
+ EXPECT_FALSE(types_.HasTypeByCanonicalName("java.util.List<a.goog.Foo>"));
+ unique_ptr<AidlParcelable> parcelable(new AidlParcelable(
+ AIDL_LOCATION_HERE, new AidlQualifiedName(AIDL_LOCATION_HERE, "Foo", ""), {"a", "goog"}, ""));
+ // Add the parcelable type we care about.
+ EXPECT_TRUE(types_.AddParcelableType(*parcelable.get(), __FILE__));
+ // Now we can find the parcelable type, but not the List of them.
+ EXPECT_TRUE(types_.HasTypeByCanonicalName("a.goog.Foo"));
+ EXPECT_FALSE(types_.HasTypeByCanonicalName("java.util.List<a.goog.Foo>"));
+ // But after we add the list explicitly...
+ std::vector<std::unique_ptr<AidlTypeSpecifier>>* type_args =
+ new std::vector<std::unique_ptr<AidlTypeSpecifier>>();
+ type_args->emplace_back(new AidlTypeSpecifier(AIDL_LOCATION_HERE, "Foo", false, nullptr, ""));
+ AidlTypeSpecifier container_type(AIDL_LOCATION_HERE, "List", false, type_args, "");
+ EXPECT_TRUE(types_.MaybeAddContainerType(container_type));
+ // This should work.
+ EXPECT_TRUE(types_.HasTypeByCanonicalName("java.util.List<a.goog.Foo>"));
+}
+
+} // namespace java
+} // namespace android
+} // namespace aidl
diff --git a/type_namespace.cpp b/type_namespace.cpp
new file mode 100644
index 0000000..e8e5a29
--- /dev/null
+++ b/type_namespace.cpp
@@ -0,0 +1,164 @@
+/*
+ * Copyright (C) 2015, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "type_namespace.h"
+
+#include <algorithm>
+#include <string>
+#include <vector>
+
+#include "aidl_language.h"
+#include "logging.h"
+
+using android::base::StringPrintf;
+using std::string;
+using std::vector;
+
+namespace android {
+namespace aidl {
+
+// Since packages cannot contain '-' normally, we cannot be asked
+// to create a type that conflicts with these strings.
+const char kAidlReservedTypePackage[] = "aidl-internal";
+const char kUtf8InCppStringClass[] = "Utf8InCppString";
+
+// These *must* match the package and class names above.
+const char kUtf8InCppStringCanonicalName[] = "aidl-internal.Utf8InCppString";
+
+const char kStringCanonicalName[] = "java.lang.String";
+
+const char kUtf8InCppAnnotation[] = "@utfInCpp";
+
+namespace {
+
+bool is_java_keyword(const char* str) {
+ static const std::vector<std::string> kJavaKeywords{
+ "abstract", "assert", "boolean", "break", "byte",
+ "case", "catch", "char", "class", "const",
+ "continue", "default", "do", "double", "else",
+ "enum", "extends", "final", "finally", "float",
+ "for", "goto", "if", "implements", "import",
+ "instanceof", "int", "interface", "long", "native",
+ "new", "package", "private", "protected", "public",
+ "return", "short", "static", "strictfp", "super",
+ "switch", "synchronized", "this", "throw", "throws",
+ "transient", "try", "void", "volatile", "while",
+ "true", "false", "null",
+ };
+ return std::find(kJavaKeywords.begin(), kJavaKeywords.end(), str) !=
+ kJavaKeywords.end();
+}
+
+} // namespace
+
+ValidatableType::ValidatableType(
+ int kind, const string& package, const string& type_name,
+ const string& decl_file, int decl_line)
+ : kind_(kind),
+ type_name_(type_name),
+ canonical_name_((package.empty()) ? type_name
+ : package + "." + type_name),
+ origin_file_(decl_file),
+ origin_line_(decl_line) {}
+
+string ValidatableType::HumanReadableKind() const {
+ switch (Kind()) {
+ case ValidatableType::KIND_BUILT_IN:
+ return "a built in";
+ case ValidatableType::KIND_PARCELABLE:
+ return "a parcelable";
+ case ValidatableType::KIND_INTERFACE:
+ return "an interface";
+ case ValidatableType::KIND_GENERATED:
+ return "a generated";
+ }
+ return "unknown";
+}
+
+const ValidatableType* TypeNamespace::GetReturnType(const AidlTypeSpecifier& raw_type,
+ const AidlDefinedType& context) const {
+ string error_msg;
+ const ValidatableType* return_type = GetValidatableType(raw_type, &error_msg, context);
+ if (return_type == nullptr) {
+ AIDL_ERROR(raw_type) << "Return type " << raw_type.ToString() << ": " << error_msg;
+ return nullptr;
+ }
+
+ return return_type;
+}
+
+bool TypeNamespace::AddDefinedTypes(vector<AidlDefinedType*>& types, const string& filename) {
+ bool success = true;
+ for (const auto type : types) {
+ const AidlInterface* interface = type->AsInterface();
+ if (interface != nullptr) {
+ success &= AddBinderType(*interface, filename);
+ continue;
+ }
+
+ const AidlParcelable* parcelable = type->AsParcelable();
+ if (parcelable != nullptr) {
+ success &= AddParcelableType(*parcelable, filename);
+ continue;
+ }
+
+ CHECK(false) << "aidl internal error: unrecognized type";
+ }
+ return success;
+}
+
+const ValidatableType* TypeNamespace::GetArgType(const AidlArgument& a, int arg_index,
+ const AidlDefinedType& context) const {
+ string error_prefix =
+ StringPrintf("parameter %s (argument %d): ", a.GetName().c_str(), arg_index);
+
+ // check the arg type
+ string error_msg;
+ const ValidatableType* t = GetValidatableType(a.GetType(), &error_msg, context);
+ if (t == nullptr) {
+ AIDL_ERROR(a) << error_prefix << error_msg;
+ return nullptr;
+ }
+
+ const bool can_be_out = typenames_.CanBeOutParameter(a.GetType());
+ if (!a.DirectionWasSpecified() && can_be_out) {
+ AIDL_ERROR(a) << error_prefix << "'" << a.GetType().ToString()
+ << "' can be an out type, so you must declare it as in, out, or inout.";
+ return nullptr;
+ }
+
+ if (a.GetDirection() != AidlArgument::IN_DIR && !can_be_out) {
+ AIDL_ERROR(a) << error_prefix << "'" << a.ToString() << "' can only be an in parameter.";
+ return nullptr;
+ }
+
+ // check that the name doesn't match a keyword
+ if (is_java_keyword(a.GetName().c_str())) {
+ AIDL_ERROR(a) << error_prefix << "Argument name is a Java or aidl keyword";
+ return nullptr;
+ }
+
+ // Reserve a namespace for internal use
+ if (a.GetName().substr(0, 5) == "_aidl") {
+ AIDL_ERROR(a) << error_prefix << "Argument name cannot begin with '_aidl'";
+ return nullptr;
+ }
+
+ return t;
+}
+
+} // namespace aidl
+} // namespace android
diff --git a/type_namespace.h b/type_namespace.h
new file mode 100644
index 0000000..a7952fb
--- /dev/null
+++ b/type_namespace.h
@@ -0,0 +1,450 @@
+/*
+ * Copyright (C) 2015, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <memory>
+#include <string>
+
+#include <android-base/macros.h>
+#include <android-base/stringprintf.h>
+#include <android-base/strings.h>
+
+#include "aidl_language.h"
+#include "logging.h"
+
+namespace android {
+namespace aidl {
+
+// Special reserved type names.
+extern const char kAidlReservedTypePackage[];
+extern const char kUtf8InCppStringClass[]; // UTF16 wire format, UTF8 in C++
+
+// Helpful aliases defined to be <kAidlReservedTypePackage>.<class name>
+extern const char kUtf8InCppStringCanonicalName[];
+
+// We sometimes special case this class.
+extern const char kStringCanonicalName[];
+
+// Note that these aren't the strings recognized by the parser, we just keep
+// here for the sake of logging a common string constant.
+extern const char kUtf8InCppAnnotation[];
+
+class ValidatableType {
+ public:
+ enum {
+ KIND_BUILT_IN,
+ KIND_PARCELABLE,
+ KIND_INTERFACE,
+ KIND_GENERATED,
+ };
+
+ ValidatableType(int kind,
+ const std::string& package, const std::string& type_name,
+ const std::string& decl_file, int decl_line);
+ virtual ~ValidatableType() = default;
+
+ virtual bool CanBeArray() const { return ArrayType() != nullptr; }
+ virtual bool CanWriteToParcel() const = 0;
+
+ virtual const ValidatableType* ArrayType() const = 0;
+ virtual const ValidatableType* NullableType() const = 0;
+
+ // ShortName() is the class name without a package.
+ std::string ShortName() const { return type_name_; }
+ // CanonicalName() returns the canonical AIDL type, with packages.
+ std::string CanonicalName() const { return canonical_name_; }
+
+ int Kind() const { return kind_; }
+ std::string HumanReadableKind() const;
+ std::string DeclFile() const { return origin_file_; }
+ int DeclLine() const { return origin_line_; }
+
+ private:
+ const int kind_;
+ const std::string type_name_;
+ const std::string canonical_name_;
+ const std::string origin_file_;
+ const int origin_line_;
+
+ DISALLOW_COPY_AND_ASSIGN(ValidatableType);
+};
+
+class TypeNamespace {
+ public:
+ // Load the TypeNamespace with built in types. Don't do work in the
+ // constructor because many of the useful methods are virtual.
+ virtual void Init() = 0;
+
+ bool AddDefinedTypes(vector<AidlDefinedType*>& types, const string& filename);
+
+ // Load this TypeNamespace with user defined types.
+ virtual bool AddParcelableType(const AidlParcelable& p,
+ const std::string& filename) = 0;
+
+ virtual bool AddBinderType(const AidlInterface& b,
+ const std::string& filename) = 0;
+ // Add a container type to this namespace. Returns false only
+ // on error. Silently discards requests to add non-container types.
+ virtual bool MaybeAddContainerType(const AidlTypeSpecifier& aidl_type) = 0;
+
+ // Returns true iff this has a type for |import|.
+ virtual bool HasImportType(const std::string& import) const = 0;
+
+ // Returns a pointer to a type corresponding to |raw_type| or nullptr
+ // if this is an invalid return type.
+ virtual const ValidatableType* GetReturnType(const AidlTypeSpecifier& raw_type,
+ const AidlDefinedType& context) const;
+
+ // Returns a pointer to a type corresponding to |a| or nullptr if |a|
+ // has an invalid argument type.
+ virtual const ValidatableType* GetArgType(const AidlArgument& a, int arg_index,
+ const AidlDefinedType& context) const;
+
+ // Returns a pointer to a type corresponding to |defined_type|.
+ virtual const ValidatableType* GetDefinedType(const AidlDefinedType& defined_type) const = 0;
+
+ AidlTypenames typenames_;
+
+ protected:
+ TypeNamespace() = default;
+ virtual ~TypeNamespace() = default;
+
+ virtual const ValidatableType* GetValidatableType(const AidlTypeSpecifier& type,
+ std::string* error_msg,
+ const AidlDefinedType& context) const = 0;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(TypeNamespace);
+};
+
+template<typename T>
+class LanguageTypeNamespace : public TypeNamespace {
+ public:
+ LanguageTypeNamespace() = default;
+ virtual ~LanguageTypeNamespace() = default;
+
+ // Get a pointer to an existing type. Searches first by fully-qualified
+ // name, and then class name (dropping package qualifiers).
+ const T* Find(const AidlTypeSpecifier& aidl_type) const;
+
+ // Find a type by its |name|. If |name| refers to a container type (e.g.
+ // List<String>) you must turn it into a canonical name first (e.g.
+ // java.util.List<java.lang.String>).
+ const T* FindTypeByCanonicalName(const std::string& name) const;
+ bool HasTypeByCanonicalName(const std::string& type_name) const {
+ return FindTypeByCanonicalName(type_name) != nullptr;
+ }
+ bool HasImportType(const std::string& import) const override {
+ return HasTypeByCanonicalName(import);
+ }
+ const ValidatableType* GetDefinedType(const AidlDefinedType& defined_type) const override {
+ return FindTypeByCanonicalName(defined_type.GetCanonicalName());
+ }
+
+ bool MaybeAddContainerType(const AidlTypeSpecifier& aidl_type) override;
+ // We dynamically create container types as we discover them in the parse
+ // tree. Returns false if the contained types cannot be canonicalized.
+ virtual bool AddListType(const std::string& contained_type_name) = 0;
+ virtual bool AddMapType(const std::string& key_type_name,
+ const std::string& value_type_name) = 0;
+
+ protected:
+ bool Add(std::unique_ptr<const T> type);
+ void AddAndSetMember(const T** member, std::unique_ptr<const T> type) {
+ const T* ptr_value = type.get();
+ CHECK(Add(std::move(type)));
+ *member = ptr_value;
+ }
+
+ private:
+ // Returns true iff the name can be canonicalized to a container type.
+ virtual bool CanonicalizeContainerType(const AidlTypeSpecifier& aidl_type,
+ std::vector<std::string>* container_class,
+ std::vector<std::string>* contained_type_names) const;
+
+ // Returns true if this is a container type, rather than a normal type.
+ bool IsContainerType(const std::string& type_name) const;
+
+ const ValidatableType* GetValidatableType(const AidlTypeSpecifier& type, std::string* error_msg,
+ const AidlDefinedType& context) const override;
+
+ std::vector<std::unique_ptr<const T>> types_;
+
+ DISALLOW_COPY_AND_ASSIGN(LanguageTypeNamespace);
+}; // class LanguageTypeNamespace
+
+template <typename T>
+bool LanguageTypeNamespace<T>::Add(std::unique_ptr<const T> type) {
+ const T* existing = FindTypeByCanonicalName(type->CanonicalName());
+ if (!existing) {
+ types_.push_back(std::move(type));
+ return true;
+ }
+
+ if (existing->Kind() == ValidatableType::KIND_BUILT_IN) {
+ LOG(ERROR) << type->DeclFile() << ":" << type->DeclLine()
+ << " attempt to redefine built in class "
+ << type->CanonicalName();
+ return false;
+ }
+
+ if (type->Kind() != existing->Kind()) {
+ LOG(ERROR) << type->DeclFile() << ":" << type->DeclLine()
+ << " attempt to redefine " << type->CanonicalName()
+ << " as " << type->HumanReadableKind();
+ LOG(ERROR) << existing->DeclFile() << ":" << existing->DeclLine()
+ << " previously defined here as "
+ << existing->HumanReadableKind();
+ return false;
+ }
+
+ return true;
+}
+
+template <typename T>
+const T* LanguageTypeNamespace<T>::Find(const AidlTypeSpecifier& aidl_type) const {
+ using std::string;
+ using std::vector;
+ using android::base::Join;
+ using android::base::Trim;
+
+ string name = Trim(aidl_type.IsArray() ? aidl_type.GetName() : aidl_type.ToString());
+ if (IsContainerType(name)) {
+ vector<string> container_class;
+ vector<string> contained_type_names;
+ if (!CanonicalizeContainerType(aidl_type, &container_class,
+ &contained_type_names)) {
+ return nullptr;
+ }
+ name = Join(container_class, '.') +
+ "<" + Join(contained_type_names, ',') + ">";
+ }
+ // Here, we know that we have the canonical name for this container.
+ return FindTypeByCanonicalName(name);
+}
+
+template<typename T>
+const T* LanguageTypeNamespace<T>::FindTypeByCanonicalName(
+ const std::string& raw_name) const {
+ using android::base::Trim;
+
+ std::string name = Trim(raw_name);
+ const T* ret = nullptr;
+ for (const auto& type : types_) {
+ // Always prefer a exact match if possible.
+ // This works for primitives and class names qualified with a package.
+ if (type->CanonicalName() == name) {
+ ret = type.get();
+ break;
+ }
+ // We allow authors to drop packages when refering to a class name.
+ if (type->ShortName() == name) {
+ ret = type.get();
+ }
+ }
+
+ return ret;
+}
+
+template <typename T>
+bool LanguageTypeNamespace<T>::MaybeAddContainerType(const AidlTypeSpecifier& aidl_type) {
+ using android::base::Join;
+
+ const std::string& type_name = aidl_type.ToString();
+ if (!IsContainerType(type_name)) {
+ return true;
+ }
+
+ std::vector<std::string> container_class;
+ std::vector<std::string> contained_type_names;
+ if (!CanonicalizeContainerType(aidl_type, &container_class,
+ &contained_type_names)) {
+ return false;
+ }
+
+ const std::string canonical_name = Join(container_class, ".") +
+ "<" + Join(contained_type_names, ",") + ">";
+ if (HasTypeByCanonicalName(canonical_name)) {
+ return true;
+ }
+
+
+ // We only support two types right now and this type is one of them.
+ switch (contained_type_names.size()) {
+ case 1:
+ return AddListType(contained_type_names[0]);
+ case 2:
+ return AddMapType(contained_type_names[0], contained_type_names[1]);
+ default:
+ break; // Should never get here, will FATAL below.
+ }
+
+ LOG(FATAL) << "aidl internal error";
+ return false;
+}
+
+template<typename T>
+bool LanguageTypeNamespace<T>::IsContainerType(
+ const std::string& type_name) const {
+ const size_t opening_brace = type_name.find('<');
+ const size_t closing_brace = type_name.find('>');
+ if (opening_brace != std::string::npos ||
+ closing_brace != std::string::npos) {
+ return true; // Neither < nor > appear in normal AIDL types.
+ }
+ return false;
+}
+
+template <typename T>
+bool LanguageTypeNamespace<T>::CanonicalizeContainerType(
+ const AidlTypeSpecifier& aidl_type, std::vector<std::string>* container_class,
+ std::vector<std::string>* contained_type_names) const {
+ std::string container = aidl_type.GetName();
+ std::vector<std::string> args;
+ for (auto& type_arg : aidl_type.GetTypeParameters()) {
+ if (type_arg->IsGeneric()) {
+ // nesting is not allowed yet.
+ LOG(ERROR) << "Nested template type '" << aidl_type.ToString() << "'";
+ }
+
+ std::string type_name = type_arg->ToString();
+ // Here, we are relying on FindTypeByCanonicalName to do its best when
+ // given a non-canonical name for non-compound type (i.e. not another
+ // container).
+ const T* arg_type = FindTypeByCanonicalName(type_name);
+ if (!arg_type) {
+ return false;
+ }
+
+ // Now get the canonical names for these contained types, remapping them if
+ // necessary.
+ type_name = arg_type->CanonicalName();
+ if (aidl_type.IsUtf8InCpp() && type_name == "java.lang.String") {
+ type_name = kUtf8InCppStringCanonicalName;
+ }
+ args.emplace_back(type_name);
+ }
+
+ // Map the container name to its canonical form for supported containers.
+ if ((container == "List" || container == "java.util.List") &&
+ args.size() == 1) {
+ *container_class = {"java", "util", "List"};
+ *contained_type_names = args;
+ return true;
+ }
+ if ((container == "Map" || container == "java.util.Map") &&
+ args.size() == 2) {
+ *container_class = {"java", "util", "Map"};
+ *contained_type_names = args;
+ return true;
+ }
+
+ LOG(ERROR) << "Unknown find container with name " << container << " and " << args.size()
+ << " contained types.";
+ return false;
+}
+
+template <typename T>
+const ValidatableType* LanguageTypeNamespace<T>::GetValidatableType(
+ const AidlTypeSpecifier& aidl_type, std::string* error_msg,
+ const AidlDefinedType& context) const {
+ using android::base::StringPrintf;
+
+ const ValidatableType* type = Find(aidl_type);
+ if (type == nullptr) {
+ *error_msg = "unknown type";
+ return nullptr;
+ }
+
+ if (aidl_type.GetName() == "void") {
+ if (aidl_type.IsArray()) {
+ *error_msg = "void type cannot be an array";
+ return nullptr;
+ }
+ if (aidl_type.IsNullable() || aidl_type.IsUtf8InCpp()) {
+ *error_msg = "void type cannot be annotated";
+ return nullptr;
+ }
+ // We have no more special handling for void.
+ return type;
+ }
+
+ bool utf8InCpp = aidl_type.IsUtf8InCpp();
+
+ // Strings inside containers get remapped to appropriate utf8 versions when
+ // we convert the container name to its canonical form and the look up the
+ // type. However, for non-compound types (i.e. those not in a container) we
+ // must patch them up here.
+ if (IsContainerType(type->CanonicalName())) {
+ utf8InCpp = false;
+ } else if (aidl_type.GetName() == "String" ||
+ aidl_type.GetName() == "java.lang.String") {
+ utf8InCpp = utf8InCpp || context.IsUtf8InCpp();
+ } else if (utf8InCpp) {
+ *error_msg = StringPrintf("type '%s' may not be annotated as %s.", aidl_type.GetName().c_str(),
+ kUtf8InCppAnnotation);
+ return nullptr;
+ }
+
+ if (utf8InCpp) {
+ type = FindTypeByCanonicalName(kUtf8InCppStringCanonicalName);
+ }
+
+ // One of our UTF8 transforms made type null
+ if (type == nullptr) {
+ *error_msg = StringPrintf("%s is unsupported when generating code for this language.",
+ kUtf8InCppAnnotation);
+ return nullptr;
+ }
+
+ if (!type->CanWriteToParcel()) {
+ *error_msg = "type cannot be marshalled";
+ return nullptr;
+ }
+
+ if (aidl_type.IsArray()) {
+ type = type->ArrayType();
+ if (!type) {
+ *error_msg = StringPrintf("type '%s' cannot be an array",
+ aidl_type.GetName().c_str());
+ return nullptr;
+ }
+ }
+
+ if (context.IsNullable()) {
+ const ValidatableType* nullableType = type->NullableType();
+
+ if (nullableType) {
+ return nullableType;
+ }
+ }
+
+ if (aidl_type.IsNullable()) {
+ type = type->NullableType();
+ if (!type) {
+ *error_msg = StringPrintf("type '%s%s' cannot be marked as possibly null",
+ aidl_type.GetName().c_str(),
+ (aidl_type.IsArray()) ? "[]" : "");
+ return nullptr;
+ }
+ }
+
+ return type;
+}
+
+} // namespace aidl
+} // namespace android