blob: 5939e85467b74ccc8a54d8d39b208055062aff9a [file] [log] [blame]
Andreas Huberc9410c72016-07-28 12:18:40 -07001#include "AST.h"
2
Andreas Huber5345ec22016-07-29 13:33:27 -07003#include "Coordinator.h"
Andreas Huberc9410c72016-07-28 12:18:40 -07004#include "Formatter.h"
Andreas Huber84f89de2016-07-28 15:39:51 -07005#include "FQName.h"
Andreas Hubereb1081f2016-07-28 13:13:24 -07006#include "HandleType.h"
Andreas Huberbfd76212016-08-09 11:12:16 -07007#include "Interface.h"
Andreas Huberc9410c72016-07-28 12:18:40 -07008#include "Scope.h"
Andreas Huber8d3ac0c2016-08-04 14:49:23 -07009#include "TypeDef.h"
Andreas Huberc9410c72016-07-28 12:18:40 -070010
Andreas Hubereb1081f2016-07-28 13:13:24 -070011#include <android-base/logging.h>
Andreas Huber39fa7182016-08-19 14:27:33 -070012#include <iostream>
Andreas Huberc9410c72016-07-28 12:18:40 -070013#include <stdlib.h>
14
Andreas Huberc9410c72016-07-28 12:18:40 -070015namespace android {
16
Andreas Huber0d0f9a22016-08-17 10:26:11 -070017AST::AST(Coordinator *coordinator, const std::string &path)
Andreas Huber5345ec22016-07-29 13:33:27 -070018 : mCoordinator(coordinator),
Andreas Huber0d0f9a22016-08-17 10:26:11 -070019 mPath(path),
Andreas Huber5345ec22016-07-29 13:33:27 -070020 mScanner(NULL),
Andreas Huber31629bc2016-08-03 09:06:40 -070021 mRootScope(new Scope) {
Andreas Huberc9410c72016-07-28 12:18:40 -070022 enterScope(mRootScope);
23}
24
25AST::~AST() {
Andreas Huberc9410c72016-07-28 12:18:40 -070026 delete mRootScope;
27 mRootScope = NULL;
28
Andreas Hubereb1081f2016-07-28 13:13:24 -070029 CHECK(mScanner == NULL);
Andreas Huberc9410c72016-07-28 12:18:40 -070030
Andreas Huber5345ec22016-07-29 13:33:27 -070031 // Ownership of "coordinator" was NOT transferred.
Andreas Huberc9410c72016-07-28 12:18:40 -070032}
33
34void *AST::scanner() {
35 return mScanner;
36}
37
38void AST::setScanner(void *scanner) {
39 mScanner = scanner;
40}
41
Andreas Huber0d0f9a22016-08-17 10:26:11 -070042const std::string &AST::getFilename() const {
43 return mPath;
44}
45
Andreas Huber84f89de2016-07-28 15:39:51 -070046bool AST::setPackage(const char *package) {
Andreas Huberda51b8e2016-07-28 16:00:57 -070047 mPackage.setTo(package);
48 CHECK(mPackage.isValid());
Andreas Huber84f89de2016-07-28 15:39:51 -070049
Andreas Huberda51b8e2016-07-28 16:00:57 -070050 if (mPackage.package().empty()
51 || mPackage.version().empty()
52 || !mPackage.name().empty()) {
Andreas Huber84f89de2016-07-28 15:39:51 -070053 return false;
54 }
55
Andreas Huber84f89de2016-07-28 15:39:51 -070056 return true;
Andreas Hubereb1081f2016-07-28 13:13:24 -070057}
58
Andreas Hubera2723d22016-07-29 15:36:07 -070059FQName AST::package() const {
60 return mPackage;
61}
62
63bool AST::isInterface(std::string *ifaceName) const {
64 return mRootScope->containsSingleInterface(ifaceName);
65}
66
Andreas Huber5345ec22016-07-29 13:33:27 -070067bool AST::addImport(const char *import) {
68 FQName fqName(import);
69 CHECK(fqName.isValid());
Andreas Hubereb1081f2016-07-28 13:13:24 -070070
Andreas Huber5345ec22016-07-29 13:33:27 -070071 fqName.applyDefaults(mPackage.package(), mPackage.version());
72
Andreas Huber68f24592016-07-29 14:53:48 -070073 // LOG(INFO) << "importing " << fqName.string();
Andreas Huber5345ec22016-07-29 13:33:27 -070074
75 if (fqName.name().empty()) {
Andreas Huberd2943e12016-08-05 11:59:31 -070076 std::vector<FQName> packageInterfaces;
Andreas Huber68f24592016-07-29 14:53:48 -070077
Andreas Huberd2943e12016-08-05 11:59:31 -070078 status_t err =
Iliyan Malchev5bb14022016-08-09 15:04:39 -070079 mCoordinator->appendPackageInterfacesToSet(fqName,
80 &packageInterfaces);
Andreas Huberd2943e12016-08-05 11:59:31 -070081
82 if (err != OK) {
Andreas Huber68f24592016-07-29 14:53:48 -070083 return false;
84 }
85
Andreas Huberd2943e12016-08-05 11:59:31 -070086 for (const auto &subFQName : packageInterfaces) {
Andreas Huber39fa7182016-08-19 14:27:33 -070087 AST *ast = mCoordinator->parse(subFQName, &mImportedASTs);
88 if (ast == NULL) {
Andreas Huber68f24592016-07-29 14:53:48 -070089 return false;
90 }
91 }
92
93 return true;
Andreas Huber5345ec22016-07-29 13:33:27 -070094 }
95
Andreas Huber39fa7182016-08-19 14:27:33 -070096 AST *importAST = mCoordinator->parse(fqName, &mImportedASTs);
Andreas Huber5345ec22016-07-29 13:33:27 -070097
Andreas Huber68f24592016-07-29 14:53:48 -070098 if (importAST == NULL) {
99 return false;
100 }
Andreas Huber84f89de2016-07-28 15:39:51 -0700101
102 return true;
Andreas Hubereb1081f2016-07-28 13:13:24 -0700103}
104
Andreas Huber39fa7182016-08-19 14:27:33 -0700105void AST::addImportedAST(AST *ast) {
106 mImportedASTs.insert(ast);
107}
108
Andreas Huberc9410c72016-07-28 12:18:40 -0700109void AST::enterScope(Scope *container) {
110 mScopePath.push_back(container);
111}
112
113void AST::leaveScope() {
114 mScopePath.pop();
115}
116
117Scope *AST::scope() {
Andreas Hubereb1081f2016-07-28 13:13:24 -0700118 CHECK(!mScopePath.empty());
Andreas Huberc9410c72016-07-28 12:18:40 -0700119 return mScopePath.top();
120}
121
Andreas Huber39fa7182016-08-19 14:27:33 -0700122bool AST::addTypeDef(
123 const char *localName, Type *type, std::string *errorMsg) {
124 // The reason we wrap the given type in a TypeDef is simply to suppress
125 // emitting any type definitions later on, since this is just an alias
126 // to a type defined elsewhere.
127 return addScopedTypeInternal(
128 localName, new TypeDef(type), errorMsg, true /* isTypeDef */);
129}
130
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700131bool AST::addScopedType(
132 const char *localName, NamedType *type, std::string *errorMsg) {
Andreas Huber39fa7182016-08-19 14:27:33 -0700133 return addScopedTypeInternal(
134 localName, type, errorMsg, false /* isTypeDef */);
135}
136
137bool AST::addScopedTypeInternal(
138 const char *localName,
139 Type *type,
140 std::string *errorMsg,
141 bool isTypeDef) {
142 if (!isTypeDef) {
143 // Resolve typeDefs to the target type.
144 while (type->isTypeDef()) {
145 type = static_cast<TypeDef *>(type)->referencedType();
146 }
147 }
148
Andreas Huberc7dfef32016-08-16 10:57:14 -0700149 std::string anonName;
150
151 if (localName == nullptr) {
152 // Anonymous type declaration.
153 anonName = scope()->pickUniqueAnonymousName();
154 localName = anonName.c_str();
155 }
156
Andreas Huber31629bc2016-08-03 09:06:40 -0700157 // LOG(INFO) << "adding scoped type '" << localName << "'";
158
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700159 bool success = scope()->addType(localName, type, errorMsg);
Andreas Huber5a545442016-08-03 10:44:56 -0700160 if (!success) {
161 return false;
162 }
163
Andreas Huber31629bc2016-08-03 09:06:40 -0700164 std::string path;
165 for (size_t i = 1; i < mScopePath.size(); ++i) {
Andreas Huber0e00de42016-08-03 09:56:02 -0700166 path.append(mScopePath[i]->localName());
Andreas Huber31629bc2016-08-03 09:06:40 -0700167 path.append(".");
168 }
169 path.append(localName);
170
Andreas Huber31629bc2016-08-03 09:06:40 -0700171 FQName fqName(mPackage.package(), mPackage.version(), path);
Andreas Huber39fa7182016-08-19 14:27:33 -0700172
173 if (!isTypeDef) {
174 CHECK(type->isNamedType());
175
176 NamedType *namedType = static_cast<NamedType *>(type);
177 namedType->setLocalName(localName);
178 namedType->setFullName(fqName);
179 }
180
181 mDefinedTypesByFullName.add(fqName, type);
Andreas Huber31629bc2016-08-03 09:06:40 -0700182
Andreas Huber5a545442016-08-03 10:44:56 -0700183 return true;
Andreas Huber31629bc2016-08-03 09:06:40 -0700184}
185
Andreas Huberfd4afab2016-08-03 13:02:57 -0700186Type *AST::lookupType(const char *name) {
Andreas Huber84f89de2016-07-28 15:39:51 -0700187 FQName fqName(name);
188 CHECK(fqName.isValid());
189
Andreas Huberda51b8e2016-07-28 16:00:57 -0700190 if (fqName.name().empty()) {
191 // Given a package and version???
192 return NULL;
193 }
194
Andreas Huber84f89de2016-07-28 15:39:51 -0700195 if (fqName.package().empty() && fqName.version().empty()) {
196 // This is just a plain identifier, resolve locally first if possible.
197
198 for (size_t i = mScopePath.size(); i-- > 0;) {
199 Type *type = mScopePath[i]->lookupType(name);
200
201 if (type != NULL) {
Andreas Huber8d3ac0c2016-08-04 14:49:23 -0700202 // Resolve typeDefs to the target type.
203 while (type->isTypeDef()) {
204 type = static_cast<TypeDef *>(type)->referencedType();
205 }
206
Andreas Huberfd4afab2016-08-03 13:02:57 -0700207 return type->ref();
Andreas Huber84f89de2016-07-28 15:39:51 -0700208 }
Andreas Huberc9410c72016-07-28 12:18:40 -0700209 }
210 }
211
Andreas Huber39fa7182016-08-19 14:27:33 -0700212 Type *resolvedType = nullptr;
213 FQName resolvedName;
Andreas Huber84f89de2016-07-28 15:39:51 -0700214
Andreas Huber39fa7182016-08-19 14:27:33 -0700215 for (const auto &importedAST : mImportedASTs) {
216 FQName matchingName;
217 Type *match = importedAST->findDefinedType(fqName, &matchingName);
Andreas Huber84f89de2016-07-28 15:39:51 -0700218
Andreas Huber39fa7182016-08-19 14:27:33 -0700219 if (match != nullptr) {
220 if (resolvedType != nullptr) {
221 std::cerr << "ERROR: Unable to resolve type name '"
222 << fqName.string()
223 << "', multiple matches found:\n";
Andreas Huber737080b2016-08-02 15:38:04 -0700224
Andreas Huber39fa7182016-08-19 14:27:33 -0700225 std::cerr << " " << resolvedName.string() << "\n";
226 std::cerr << " " << matchingName.string() << "\n";
227
228 return NULL;
229 }
230
231 resolvedType = match;
232 resolvedName = matchingName;
233
234 // Keep going even after finding a match.
235 }
236 }
237
238 if (resolvedType) {
239#if 0
240 LOG(INFO) << "found '"
241 << resolvedName.string()
242 << "' after looking for '"
243 << fqName.string()
244 << "'.";
245#endif
246
247 // Resolve typeDefs to the target type.
248 while (resolvedType->isTypeDef()) {
249 resolvedType =
250 static_cast<TypeDef *>(resolvedType)->referencedType();
251 }
252
253 if (!resolvedType->isInterface()) {
Andreas Huber0e00de42016-08-03 09:56:02 -0700254 // Non-interface types are declared in the associated types header.
Andreas Huber39fa7182016-08-19 14:27:33 -0700255 FQName typesName(
256 resolvedName.package(), resolvedName.version(), "types");
257
Andreas Huber0e00de42016-08-03 09:56:02 -0700258 mImportedNames.insert(typesName);
259 } else {
Andreas Huberbfd76212016-08-09 11:12:16 -0700260 // Do _not_ use fqName, i.e. the name we used to look up the type,
261 // but instead use the name of the interface we found.
262 // This is necessary because if fqName pointed to a typedef which
263 // in turn referenced the found interface we'd mistakenly use the
264 // name of the typedef instead of the proper name of the interface.
265
266 mImportedNames.insert(
Andreas Huber39fa7182016-08-19 14:27:33 -0700267 static_cast<Interface *>(resolvedType)->fqName());
Andreas Huber0e00de42016-08-03 09:56:02 -0700268 }
Andreas Huber737080b2016-08-02 15:38:04 -0700269 }
270
Andreas Huber39fa7182016-08-19 14:27:33 -0700271 return resolvedType->ref();
Andreas Huber5345ec22016-07-29 13:33:27 -0700272}
273
Andreas Huber39fa7182016-08-19 14:27:33 -0700274Type *AST::findDefinedType(const FQName &fqName, FQName *matchingName) const {
275 for (size_t i = 0; i < mDefinedTypesByFullName.size(); ++i) {
276 const FQName &key = mDefinedTypesByFullName.keyAt(i);
Andreas Huber5345ec22016-07-29 13:33:27 -0700277
Andreas Huber39fa7182016-08-19 14:27:33 -0700278 if (key.endsWith(fqName)) {
279 *matchingName = key;
280 return mDefinedTypesByFullName.valueAt(i);
Andreas Huber5345ec22016-07-29 13:33:27 -0700281 }
Andreas Huber5345ec22016-07-29 13:33:27 -0700282 }
Andreas Huber39fa7182016-08-19 14:27:33 -0700283
284 return nullptr;
Andreas Huberc9410c72016-07-28 12:18:40 -0700285}
286
Iliyan Malchev5bb14022016-08-09 15:04:39 -0700287void AST::getImportedPackages(std::set<FQName> *importSet) const {
Andreas Huberd2943e12016-08-05 11:59:31 -0700288 for (const auto &fqName : mImportedNames) {
289 FQName packageName(fqName.package(), fqName.version(), "");
290
291 if (packageName == mPackage) {
292 // We only care about external imports, not our own package.
293 continue;
294 }
295
296 importSet->insert(packageName);
297 }
298}
299
Andreas Huberc9410c72016-07-28 12:18:40 -0700300} // namespace android;