Structured Parcelables: int/string default values.
Initial two types for defaults.
Syntax is:
parcelable MyParcelable {
String name = "wicked";
int rest = 0;
}
Bug: 110758329
Test: runtests.sh
Change-Id: Ieadf503ccb9acedf6782c15964c2d4957549542d
diff --git a/aidl.cpp b/aidl.cpp
index f859b1d..d8cc4b8 100644
--- a/aidl.cpp
+++ b/aidl.cpp
@@ -171,6 +171,10 @@
TypeNamespace* types) {
int err = 0;
for (const auto& v : parcel->GetFields()) {
+ if (!v->CheckValid()) {
+ err = 1;
+ }
+
if (!types->MaybeAddContainerType(v->GetType())) {
err = 1; // return type is invalid
}
diff --git a/aidl_language.cpp b/aidl_language.cpp
index 4cb3aa7..5ca18d1 100644
--- a/aidl_language.cpp
+++ b/aidl_language.cpp
@@ -142,10 +142,32 @@
AidlVariableDeclaration::AidlVariableDeclaration(AidlTypeSpecifier* type, std::string name,
unsigned line)
- : type_(type), name_(name), line_(line) {}
+ : AidlVariableDeclaration(type, name, line, nullptr /*default_value*/) {}
+
+AidlVariableDeclaration::AidlVariableDeclaration(AidlTypeSpecifier* type, std::string name,
+ unsigned line, AidlConstantValue* default_value)
+ : type_(type), name_(name), line_(line), default_value_(default_value) {}
+
+bool AidlVariableDeclaration::CheckValid() const {
+ if (default_value_ == nullptr) return true;
+
+ const string given_type = type_->GetName();
+ const string value_type = AidlConstantValue::ToString(default_value_->GetType());
+
+ if (given_type != value_type) {
+ cerr << "Declaration " << name_ << " is of type " << given_type << " but value is of type "
+ << value_type << " on line " << line_ << endl;
+ return false;
+ }
+ return true;
+}
string AidlVariableDeclaration::ToString() const {
- return type_->ToString() + " " + name_;
+ string ret = type_->ToString() + " " + name_;
+ if (default_value_ != nullptr) {
+ ret += " = " + default_value_->ToString();
+ }
+ return ret;
}
string AidlVariableDeclaration::Signature() const {
diff --git a/aidl_language.h b/aidl_language.h
index 19679e3..374ff6f 100644
--- a/aidl_language.h
+++ b/aidl_language.h
@@ -151,16 +151,22 @@
DISALLOW_COPY_AND_ASSIGN(AidlTypeSpecifier);
};
+class AidlConstantValue;
class AidlVariableDeclaration : public AidlNode {
public:
AidlVariableDeclaration(AidlTypeSpecifier* type, std::string name, unsigned line);
+ AidlVariableDeclaration(AidlTypeSpecifier* type, std::string name, unsigned line,
+ AidlConstantValue* default_value);
virtual ~AidlVariableDeclaration() = default;
std::string GetName() const { return name_; }
int GetLine() const { return line_; }
const AidlTypeSpecifier& GetType() const { return *type_; }
+ const AidlConstantValue* GetDefaultValue() const { return default_value_.get(); }
+
AidlTypeSpecifier* GetMutableType() { return type_.get(); }
+ bool CheckValid() const;
std::string ToString() const;
std::string Signature() const;
@@ -168,6 +174,7 @@
std::unique_ptr<AidlTypeSpecifier> type_;
std::string name_;
unsigned line_;
+ std::unique_ptr<AidlConstantValue> default_value_;
DISALLOW_COPY_AND_ASSIGN(AidlVariableDeclaration);
};
diff --git a/aidl_language_y.yy b/aidl_language_y.yy
index f0d34a0..21c174e 100644
--- a/aidl_language_y.yy
+++ b/aidl_language_y.yy
@@ -199,6 +199,9 @@
: type identifier ';' {
$$ = new AidlVariableDeclaration($1, $2->GetText(), @2.begin.line);
}
+ | type identifier '=' constant_value ';' {
+ $$ = new AidlVariableDeclaration($1, $2->GetText(), @2.begin.line, $4);
+ }
| error ';' {
ps->AddError();
$$ = nullptr;
diff --git a/generate_cpp.cpp b/generate_cpp.cpp
index 0fa4291..e74ec40 100644
--- a/generate_cpp.cpp
+++ b/generate_cpp.cpp
@@ -865,9 +865,16 @@
for (const auto& variable : parcel.GetFields()) {
const Type* type = variable->GetType().GetLanguageType<Type>();
+ const AidlConstantValue* default_value = variable->GetDefaultValue();
- parcel_class->AddPublic(std::unique_ptr<LiteralDecl>(new LiteralDecl(
- StringPrintf("%s %s;\n", type->CppType().c_str(), variable->GetName().c_str()))));
+ std::ostringstream out;
+ out << type->CppType().c_str() << " " << variable->GetName().c_str();
+ if (default_value) {
+ out << " = " << type->CppType().c_str() << "(" << default_value->ToString() << ")";
+ }
+ out << ";\n";
+
+ parcel_class->AddPublic(std::unique_ptr<LiteralDecl>(new LiteralDecl(out.str())));
}
unique_ptr<MethodDecl> read(new MethodDecl(kAndroidStatusLiteral, "readFromParcel",
diff --git a/generate_java.cpp b/generate_java.cpp
index 5f5472e..30951a8 100644
--- a/generate_java.cpp
+++ b/generate_java.cpp
@@ -113,9 +113,16 @@
for (const auto& variable : parcel->GetFields()) {
const Type* type = variable->GetType().GetLanguageType<Type>();
- Variable* variable_element =
- new Variable(type, variable->GetName(), variable->GetType().IsArray() ? 1 : 0);
- parcel_class->elements.push_back(new Field(PUBLIC, variable_element));
+ const AidlConstantValue* default_value = variable->GetDefaultValue();
+
+ std::ostringstream out;
+ out << "public " << type->JavaType() << (variable->GetType().IsArray() ? "[]" : "") << " "
+ << variable->GetName();
+ if (default_value) {
+ out << " = " << default_value->ToString();
+ }
+ out << ";\n";
+ parcel_class->elements.push_back(new LiteralClassElement(out.str()));
}
std::ostringstream out;
diff --git a/tests/aidl_test_client_parcelables.cpp b/tests/aidl_test_client_parcelables.cpp
index 66b66c0..75d5fb0 100644
--- a/tests/aidl_test_client_parcelables.cpp
+++ b/tests/aidl_test_client_parcelables.cpp
@@ -151,6 +151,15 @@
StructuredParcelable parcelable;
parcelable.f = kDesiredValue;
+ if (parcelable.stringDefaultsToFoo != String16("foo")) {
+ cout << "stringDefaultsToFoo should be 'foo' but is " << parcelable.stringDefaultsToFoo;
+ return false;
+ }
+ if (parcelable.intDefaultsToFive != 5) {
+ cout << "intDefaultsToFive should be 5 but is " << parcelable.intDefaultsToFive;
+ return false;
+ }
+
s->FillOutStructuredParcelable(&parcelable);
if (parcelable.shouldContainThreeFs.size() != 3) {
@@ -167,7 +176,7 @@
}
if (parcelable.shouldBeJerry != "Jerry") {
- cout << "shouldBeJerry is not Jerry and is instead " << parcelable.shouldBeJerry << endl;
+ cout << "shouldBeJerry should be 'Jerry' but is " << parcelable.shouldBeJerry << endl;
return false;
}
diff --git a/tests/android/aidl/tests/StructuredParcelable.aidl b/tests/android/aidl/tests/StructuredParcelable.aidl
index bc23eb6..60bb579 100644
--- a/tests/android/aidl/tests/StructuredParcelable.aidl
+++ b/tests/android/aidl/tests/StructuredParcelable.aidl
@@ -20,4 +20,7 @@
int[] shouldContainThreeFs;
int f;
@utf8InCpp String shouldBeJerry;
+
+ String stringDefaultsToFoo = "foo";
+ int intDefaultsToFive = 5;
}
diff --git a/tests/java_app/src/android/aidl/tests/TestServiceClient.java b/tests/java_app/src/android/aidl/tests/TestServiceClient.java
index 4795c1d..4826354 100644
--- a/tests/java_app/src/android/aidl/tests/TestServiceClient.java
+++ b/tests/java_app/src/android/aidl/tests/TestServiceClient.java
@@ -708,6 +708,14 @@
parcelable.f = kDesiredFValue;
parcelable.shouldBeJerry = "";
+ if (!parcelable.stringDefaultsToFoo.equals("foo")) {
+ mLog.logAndThrow(
+ "stringDefaultsToFoo should be 'foo' but is " + parcelable.stringDefaultsToFoo);
+ }
+ if (parcelable.intDefaultsToFive != 5) {
+ mLog.logAndThrow("intDefaultsToFive should be 5 but is " + parcelable.intDefaultsToFive);
+ }
+
try {
service.FillOutStructuredParcelable(parcelable);
} catch (RemoteException ex) {