blob: 026a7ac5c4fb0aa0f429801670a445dc00fda0a1 [file] [log] [blame]
Andreas Huber1aec3972016-08-26 09:26:32 -07001/*
2 * Copyright (C) 2016 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Andreas Huberc9410c72016-07-28 12:18:40 -070017#include "Scope.h"
18
Timur Iskhakove9ccfa22017-08-14 15:07:03 -070019#include "Annotation.h"
Timur Iskhakov891a8662017-08-25 21:53:48 -070020#include "ConstantExpression.h"
Andreas Hubera2723d22016-07-29 15:36:07 -070021#include "Interface.h"
Andreas Huberc9410c72016-07-28 12:18:40 -070022
Andreas Huber2831d512016-08-15 09:33:47 -070023#include <android-base/logging.h>
Yifan Hong327cfe12016-10-03 10:29:42 -070024#include <hidl-util/Formatter.h>
Steven Moreland169a2d22018-01-25 10:05:31 -080025#include <hidl-util/StringHelper.h>
Timur Iskhakov458ca362017-09-12 23:16:03 -070026#include <algorithm>
Timur Iskhakov565b0132017-09-06 18:07:11 -070027#include <iostream>
Neel Mehta69920a62019-07-22 16:22:13 -070028#include <string>
Yifan Hong327cfe12016-10-03 10:29:42 -070029#include <vector>
Andreas Huber2831d512016-08-15 09:33:47 -070030
Andreas Huberc9410c72016-07-28 12:18:40 -070031namespace android {
32
Neel Mehta69920a62019-07-22 16:22:13 -070033Scope::Scope(const std::string& localName, const FQName& fullName, const Location& location,
34 Scope* parent)
Timur Iskhakov565b0132017-09-06 18:07:11 -070035 : NamedType(localName, fullName, location, parent) {}
Yifan Hongf24fa852016-09-23 11:03:15 -070036Scope::~Scope(){}
Andreas Huberc9410c72016-07-28 12:18:40 -070037
Timur Iskhakov565b0132017-09-06 18:07:11 -070038void Scope::addType(NamedType* type) {
Andreas Huberc9410c72016-07-28 12:18:40 -070039 size_t index = mTypes.size();
40 mTypes.push_back(type);
Neel Mehta9200af02019-07-19 13:24:57 -070041 mTypeIndexByName[type->definedName()] = index;
Timur Iskhakov565b0132017-09-06 18:07:11 -070042}
Andreas Huberc9410c72016-07-28 12:18:40 -070043
Steven Morelanda5361da2020-12-05 02:02:46 +000044status_t Scope::validate() const {
45 status_t status = validateAnnotations();
46 if (status != OK) return status;
47
48 return NamedType::validate();
49}
50
Timur Iskhakov565b0132017-09-06 18:07:11 -070051status_t Scope::validateUniqueNames() const {
52 for (const auto* type : mTypes) {
Neel Mehta9200af02019-07-19 13:24:57 -070053 if (mTypes[mTypeIndexByName.at(type->definedName())] != type) {
54 std::cerr << "ERROR: A type named '" << type->definedName()
Steven Morelandcbff5612017-10-11 17:01:54 -070055 << "' is already declared in the scope at " << type->location() << std::endl;
Timur Iskhakov565b0132017-09-06 18:07:11 -070056 return UNKNOWN_ERROR;
57 }
58 }
59 return OK;
Andreas Huberc9410c72016-07-28 12:18:40 -070060}
61
Steven Morelanda5361da2020-12-05 02:02:46 +000062status_t Scope::validateAnnotations() const {
63 for (const Annotation* annotation : annotations()) {
64 std::cerr << "WARNING: Unrecognized annotation '" << annotation->name() << "' at "
65 << location() << ". No annotations are supported here." << std::endl;
66 // This is a warning to avoid breaking downstream unnecessarily.
67 }
68 return OK;
69}
70
Yifan Hongae16eed2016-09-23 13:25:25 -070071NamedType *Scope::lookupType(const FQName &fqName) const {
Yifan Hong327cfe12016-10-03 10:29:42 -070072 CHECK(fqName.package().empty() && fqName.version().empty());
73 if (!fqName.valueName().empty()) {
Steven Morelandcbff5612017-10-11 17:01:54 -070074 std::cerr << "ERROR: " << fqName.string() << " does not refer to a type." << std::endl;
Yifan Hong327cfe12016-10-03 10:29:42 -070075 return nullptr;
76 }
77 std::vector<std::string> names = fqName.names();
78 CHECK_GT(names.size(), 0u);
79 auto it = mTypeIndexByName.find(names[0]);
Andreas Huberc9410c72016-07-28 12:18:40 -070080
Yifan Hong327cfe12016-10-03 10:29:42 -070081 if (it == mTypeIndexByName.end()) {
82 return nullptr;
Andreas Huberc9410c72016-07-28 12:18:40 -070083 }
84
Yifan Hong327cfe12016-10-03 10:29:42 -070085 NamedType *outerType = mTypes[it->second];
86 if (names.size() == 1) {
87 return outerType;
88 }
89 if (!outerType->isScope()) {
90 // more than one names, but the first name is not a scope
91 return nullptr;
92 }
93 Scope *outerScope = static_cast<Scope *>(outerType);
94 // *slowly* pop first element
95 names.erase(names.begin());
Steven Morelande1b157e2018-03-06 14:18:32 -080096 FQName innerName;
97 CHECK(FQName::parse(StringHelper::JoinStrings(names, "."), &innerName));
Yifan Hong327cfe12016-10-03 10:29:42 -070098 return outerScope->lookupType(innerName);
Andreas Huberc9410c72016-07-28 12:18:40 -070099}
100
Yifan Hongf24fa852016-09-23 11:03:15 -0700101LocalIdentifier *Scope::lookupIdentifier(const std::string & /*name*/) const {
Yi Kongd7f8ab32018-07-24 11:27:02 -0700102 return nullptr;
Yifan Hongf24fa852016-09-23 11:03:15 -0700103}
104
Andreas Huber5345ec22016-07-29 13:33:27 -0700105bool Scope::isScope() const {
106 return true;
107}
108
Andreas Huber881227d2016-08-02 14:20:21 -0700109Interface *Scope::getInterface() const {
Andreas Hubera2723d22016-07-29 15:36:07 -0700110 if (mTypes.size() == 1 && mTypes[0]->isInterface()) {
Andreas Huber881227d2016-08-02 14:20:21 -0700111 return static_cast<Interface *>(mTypes[0]);
112 }
113
Yi Kongd7f8ab32018-07-24 11:27:02 -0700114 return nullptr;
Andreas Huber881227d2016-08-02 14:20:21 -0700115}
116
Steven Morelandb47a2622018-07-11 09:04:25 -0700117bool Scope::definesInterfaces() const {
Andreas Huber7c5ddfb2016-09-29 13:45:22 -0700118 for (const NamedType *type : mTypes) {
119 if (type->isInterface()) {
120 return true;
121 }
122 }
123
124 return false;
125}
126
Timur Iskhakove9ccfa22017-08-14 15:07:03 -0700127const std::vector<Annotation*>& Scope::annotations() const {
128 return mAnnotations;
129}
130
131void Scope::setAnnotations(std::vector<Annotation*>* annotations) {
132 CHECK(mAnnotations.empty());
133 CHECK(annotations != nullptr);
134 mAnnotations = *annotations;
135}
136
Timur Iskhakovb58f4182017-08-29 15:19:24 -0700137std::vector<const Type*> Scope::getDefinedTypes() const {
138 std::vector<const Type*> ret;
139 ret.insert(ret.end(), mTypes.begin(), mTypes.end());
Timur Iskhakov33431e62017-08-21 17:31:23 -0700140 return ret;
141}
142
Neel Mehta3b414a82019-07-02 15:47:48 -0700143std::vector<const NamedType*> Scope::getSortedDefinedTypes() const {
144 std::vector<const NamedType*> ret;
145 ret.insert(ret.end(), mTypes.begin(), mTypes.end());
146
147 std::sort(ret.begin(), ret.end(), [](const NamedType* lhs, const NamedType* rhs) -> bool {
148 return lhs->location() < rhs->location();
149 });
150 return ret;
151}
152
Timur Iskhakov458ca362017-09-12 23:16:03 -0700153void Scope::topologicalReorder(const std::unordered_map<const Type*, size_t>& reversedOrder) {
154 auto less = [&](const Type* lhs, const Type* rhs) {
155 return reversedOrder.at(lhs) < reversedOrder.at(rhs);
156 };
157
158 if (std::is_sorted(mTypes.begin(), mTypes.end(), less)) return;
159
160 mTypeOrderChanged = true;
161 std::sort(mTypes.begin(), mTypes.end(), less);
162
163 for (size_t i = 0; i != mTypes.size(); ++i) {
Neel Mehta9200af02019-07-19 13:24:57 -0700164 mTypeIndexByName.at(mTypes[i]->definedName()) = i;
Timur Iskhakov458ca362017-09-12 23:16:03 -0700165 }
166}
167
Neel Mehta3b414a82019-07-02 15:47:48 -0700168void Scope::emitHidlDefinition(Formatter& out) const {
169 const std::vector<const NamedType*>& definedTypes = getSortedDefinedTypes();
170 out.join(definedTypes.begin(), definedTypes.end(), "\n",
171 [&](auto t) { t->emitHidlDefinition(out); });
172}
173
Steven Moreland6ec9eb92018-02-16 14:21:49 -0800174void Scope::emitTypeDeclarations(Formatter& out) const {
175 if (mTypes.empty()) return;
Timur Iskhakov99072c32017-09-13 16:34:21 -0700176
177 out << "// Forward declaration for forward reference support:\n";
Steven Moreland6ec9eb92018-02-16 14:21:49 -0800178 for (const Type* type : mTypes) {
Timur Iskhakovfd3f2502017-09-05 16:25:02 -0700179 type->emitTypeForwardDeclaration(out);
Steven Moreland6ec9eb92018-02-16 14:21:49 -0800180 }
Timur Iskhakov99072c32017-09-13 16:34:21 -0700181 out << "\n";
Timur Iskhakovfd3f2502017-09-05 16:25:02 -0700182
Timur Iskhakov458ca362017-09-12 23:16:03 -0700183 if (mTypeOrderChanged) {
184 out << "// Order of inner types was changed for forward reference support.\n\n";
185 }
Steven Moreland6ec9eb92018-02-16 14:21:49 -0800186
187 for (const Type* type : mTypes) {
Steven Moreland073269e2018-05-17 15:45:26 -0700188 type->emitDocComment(out);
Steven Moreland6ec9eb92018-02-16 14:21:49 -0800189 type->emitTypeDeclarations(out);
190 }
Yifan Hong244e82d2016-11-11 11:13:57 -0800191}
192
Steven Moreland8e61c5a2017-11-17 15:55:28 -0800193void Scope::emitGlobalTypeDeclarations(Formatter& out) const {
Steven Moreland6ec9eb92018-02-16 14:21:49 -0800194 for (const Type* type : mTypes) {
Steven Moreland8e61c5a2017-11-17 15:55:28 -0800195 type->emitGlobalTypeDeclarations(out);
Steven Moreland6ec9eb92018-02-16 14:21:49 -0800196 }
Steven Moreland8e61c5a2017-11-17 15:55:28 -0800197}
198
Steven Moreland6ec9eb92018-02-16 14:21:49 -0800199void Scope::emitPackageTypeDeclarations(Formatter& out) const {
200 for (const Type* type : mTypes) {
201 type->emitPackageTypeDeclarations(out);
202 }
Yifan Hong244e82d2016-11-11 11:13:57 -0800203}
Andreas Hubere3f769a2016-10-10 10:54:44 -0700204
Steven Moreland09c6ebe2018-10-09 10:15:48 -0700205void Scope::emitPackageTypeHeaderDefinitions(Formatter& out) const {
206 for (const Type* type : mTypes) {
207 type->emitPackageTypeHeaderDefinitions(out);
208 }
209}
210
Steven Moreland6ec9eb92018-02-16 14:21:49 -0800211void Scope::emitPackageHwDeclarations(Formatter& out) const {
212 for (const Type* type : mTypes) {
213 type->emitPackageHwDeclarations(out);
214 }
Andreas Hubere3f769a2016-10-10 10:54:44 -0700215}
216
Steven Moreland6ec9eb92018-02-16 14:21:49 -0800217void Scope::emitJavaTypeDeclarations(Formatter& out, bool atTopLevel) const {
Timur Iskhakov458ca362017-09-12 23:16:03 -0700218 if (mTypeOrderChanged) {
219 out << "// Order of inner types was changed for forward reference support.\n\n";
220 }
Steven Moreland6ec9eb92018-02-16 14:21:49 -0800221
222 for (const Type* type : mTypes) {
Steven Moreland073269e2018-05-17 15:45:26 -0700223 type->emitDocComment(out);
Steven Moreland6ec9eb92018-02-16 14:21:49 -0800224 type->emitJavaTypeDeclarations(out, atTopLevel);
225 }
Andreas Huber2831d512016-08-15 09:33:47 -0700226}
227
Steven Moreland6ec9eb92018-02-16 14:21:49 -0800228void Scope::emitTypeDefinitions(Formatter& out, const std::string& prefix) const {
229 for (const Type* type : mTypes) {
230 type->emitTypeDefinitions(out, prefix);
231 }
Andreas Huber881227d2016-08-02 14:20:21 -0700232}
233
Steven Morelandd537ab02016-09-12 10:32:01 -0700234const std::vector<NamedType *> &Scope::getSubTypes() const {
Zhuoyao Zhang5158db42016-08-10 10:25:20 -0700235 return mTypes;
236}
237
Steven Moreland6ec9eb92018-02-16 14:21:49 -0800238void Scope::emitVtsTypeDeclarations(Formatter& out) const {
239 for (const Type* type : mTypes) {
240 type->emitVtsTypeDeclarations(out);
241 }
Zhuoyao Zhang5158db42016-08-10 10:25:20 -0700242}
243
Timur Iskhakov5dc72fe2017-09-07 23:13:44 -0700244bool Scope::deepIsJavaCompatible(std::unordered_set<const Type*>* visited) const {
Steven Moreland6ec9eb92018-02-16 14:21:49 -0800245 for (const Type* type : mTypes) {
Steven Moreland8f8e8622019-11-04 12:38:38 -0800246 // Java compatibility focuses on types that are actually used by interfaces.
247 // Declarations of java-incompatible types are simply omitted from
248 // corresponding Java libraries.
249 if (type->isInterface() && !type->isJavaCompatible(visited)) {
Andreas Huber70a59e12016-08-16 12:57:01 -0700250 return false;
251 }
252 }
Steven Moreland8f8e8622019-11-04 12:38:38 -0800253
Timur Iskhakov5dc72fe2017-09-07 23:13:44 -0700254 return Type::deepIsJavaCompatible(visited);
Andreas Huber60d3b222017-03-30 09:10:56 -0700255}
256
Andreas Huber019d21d2016-10-03 12:59:47 -0700257void Scope::appendToExportedTypesVector(
258 std::vector<const Type *> *exportedTypes) const {
Steven Moreland6ec9eb92018-02-16 14:21:49 -0800259 for (const Type* type : mTypes) {
Andreas Huber019d21d2016-10-03 12:59:47 -0700260 type->appendToExportedTypesVector(exportedTypes);
Steven Moreland6ec9eb92018-02-16 14:21:49 -0800261 }
Andreas Huber019d21d2016-10-03 12:59:47 -0700262}
263
Timur Iskhakovcec46c42017-08-09 00:22:02 -0700264////////////////////////////////////////
265
Timur Iskhakov565b0132017-09-06 18:07:11 -0700266RootScope::RootScope(const char* localName, const FQName& fullName, const Location& location,
267 Scope* parent)
268 : Scope(localName, fullName, location, parent) {}
Steven Moreland0ecc7b82017-07-19 12:59:23 -0700269RootScope::~RootScope() {}
270
271std::string RootScope::typeName() const {
272 return "(root scope)";
273}
274
Timur Iskhakovcec46c42017-08-09 00:22:02 -0700275status_t RootScope::validate() const {
276 CHECK(annotations().empty());
277 return Scope::validate();
278}
279
280////////////////////////////////////////
281
Yifan Hongf24fa852016-09-23 11:03:15 -0700282LocalIdentifier::LocalIdentifier(){}
283LocalIdentifier::~LocalIdentifier(){}
284
285bool LocalIdentifier::isEnumValue() const {
286 return false;
287}
288
Timur Iskhakovdbaed332017-08-31 16:33:41 -0700289const LocalIdentifier* LocalIdentifier::resolve() const {
290 return this;
291}
292
293LocalIdentifier* LocalIdentifier::resolve() {
294 return this;
295}
296
Timur Iskhakov7296af12017-08-09 21:52:48 +0000297ConstantExpression* LocalIdentifier::constExpr() const {
298 return nullptr;
299}
300
Andreas Huberc9410c72016-07-28 12:18:40 -0700301} // namespace android
302