const-ref: support recursive references
Referenced constant expression can also refer another constant
expressions.
parcelable P {
const int A = B + 1;
const int B = C + 1;
const int C = 1;
}
This works with imported types.
parcelable P { const int A = Q.A + 1; }
parcelable Q { const int A = 1; }
Using this, "auto-fill" of enums got simplified.
enum E { A, B } == enum E { A = 0, B = A + 1 }
Note that circular references are not supported.
parcelable P { const int A = A + 1; } // error
Bug: 142893595
Bug: 174877216
Test: aidl_unittests
Change-Id: Ib187ec47c0184effd64568a9a3d57a2adf5aa4f4
diff --git a/aidl_language.cpp b/aidl_language.cpp
index 38af0bc..4ab9fad 100644
--- a/aidl_language.cpp
+++ b/aidl_language.cpp
@@ -1145,7 +1145,11 @@
AidlEnumerator::AidlEnumerator(const AidlLocation& location, const std::string& name,
AidlConstantValue* value, const std::string& comments)
- : AidlNode(location), name_(name), value_(value), comments_(comments) {}
+ : AidlNode(location),
+ name_(name),
+ value_(value),
+ comments_(comments),
+ value_user_specified_(value != nullptr) {}
bool AidlEnumerator::CheckValid(const AidlTypeSpecifier& enum_backing_type) const {
if (GetValue() == nullptr) {
@@ -1170,33 +1174,31 @@
std::vector<std::unique_ptr<AidlEnumerator>>* enumerators,
const std::string& package, const std::string& comments)
: AidlDefinedType(location, name, comments, package, nullptr),
- enumerators_(std::move(*enumerators)) {}
+ enumerators_(std::move(*enumerators)) {
+ Autofill();
+}
void AidlEnumDeclaration::SetBackingType(std::unique_ptr<const AidlTypeSpecifier> type) {
backing_type_ = std::move(type);
}
-bool AidlEnumDeclaration::Autofill() {
+void AidlEnumDeclaration::Autofill() {
const AidlEnumerator* previous = nullptr;
for (const auto& enumerator : enumerators_) {
if (enumerator->GetValue() == nullptr) {
+ auto loc = enumerator->GetLocation();
if (previous == nullptr) {
enumerator->SetValue(
- std::unique_ptr<AidlConstantValue>(AidlConstantValue::Integral(GetLocation(), "0")));
+ std::unique_ptr<AidlConstantValue>(AidlConstantValue::Integral(loc, "0")));
} else {
- auto prev_value = std::unique_ptr<AidlConstantValue>(
- AidlConstantValue::ShallowIntegralCopy(*previous->GetValue()));
- if (prev_value == nullptr) {
- return false;
- }
+ auto prev_value = std::make_unique<AidlConstantReference>(loc, previous->GetName(), "");
enumerator->SetValue(std::make_unique<AidlBinaryConstExpression>(
- GetLocation(), std::move(prev_value), "+",
- std::unique_ptr<AidlConstantValue>(AidlConstantValue::Integral(GetLocation(), "1"))));
+ loc, std::move(prev_value), "+",
+ std::unique_ptr<AidlConstantValue>(AidlConstantValue::Integral(loc, "1"))));
}
}
previous = enumerator.get();
}
- return true;
}
std::set<AidlAnnotation::Type> AidlEnumDeclaration::GetSupportedAnnotations() const {
@@ -1477,3 +1479,32 @@
AidlImport::AidlImport(const AidlLocation& location, const std::string& needed_class)
: AidlNode(location), needed_class_(needed_class) {}
+
+// Resolves unresolved type name to fully qualified typename to import
+// case #1: SimpleName --> import p.SimpleName
+// case #2: Outer.Inner --> import p.Outer
+// case #3: p.SimpleName --> (as is)
+std::optional<std::string> AidlDocument::ResolveName(const std::string& unresolved_name) const {
+ std::string canonical_name;
+ const auto first_dot = unresolved_name.find_first_of('.');
+ const std::string class_name =
+ (first_dot == std::string::npos) ? unresolved_name : unresolved_name.substr(0, first_dot);
+ for (const auto& import : Imports()) {
+ const auto& fq_name = import->GetNeededClass();
+ const auto last_dot = fq_name.find_last_of('.');
+ const std::string imported_type_name =
+ (last_dot == std::string::npos) ? fq_name : fq_name.substr(last_dot + 1);
+ if (imported_type_name == class_name) {
+ if (canonical_name != "" && canonical_name != fq_name) {
+ AIDL_ERROR(import) << "Ambiguous type: " << canonical_name << " vs. " << fq_name;
+ return {};
+ }
+ canonical_name = fq_name;
+ }
+ }
+ // if not found, use unresolved_name as it is
+ if (canonical_name == "") {
+ return unresolved_name;
+ }
+ return canonical_name;
+}
\ No newline at end of file