blob: 3ec24fb05338cb4b66ac5021a2d1386652903090 [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 Huber9ed827c2016-08-22 12:31:13 -070021 mRootScope(new Scope("" /* localName */)) {
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 Huber9ed827c2016-08-22 12:31:13 -0700131bool AST::addScopedType(NamedType *type, std::string *errorMsg) {
Andreas Huber39fa7182016-08-19 14:27:33 -0700132 return addScopedTypeInternal(
Andreas Huber9ed827c2016-08-22 12:31:13 -0700133 type->localName().c_str(), type, errorMsg, false /* isTypeDef */);
Andreas Huber39fa7182016-08-19 14:27:33 -0700134}
135
136bool AST::addScopedTypeInternal(
137 const char *localName,
138 Type *type,
139 std::string *errorMsg,
140 bool isTypeDef) {
141 if (!isTypeDef) {
142 // Resolve typeDefs to the target type.
143 while (type->isTypeDef()) {
144 type = static_cast<TypeDef *>(type)->referencedType();
145 }
146 }
147
Andreas Huber31629bc2016-08-03 09:06:40 -0700148 // LOG(INFO) << "adding scoped type '" << localName << "'";
149
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700150 bool success = scope()->addType(localName, type, errorMsg);
Andreas Huber5a545442016-08-03 10:44:56 -0700151 if (!success) {
152 return false;
153 }
154
Andreas Huber31629bc2016-08-03 09:06:40 -0700155 std::string path;
156 for (size_t i = 1; i < mScopePath.size(); ++i) {
Andreas Huber0e00de42016-08-03 09:56:02 -0700157 path.append(mScopePath[i]->localName());
Andreas Huber31629bc2016-08-03 09:06:40 -0700158 path.append(".");
159 }
160 path.append(localName);
161
Andreas Huber31629bc2016-08-03 09:06:40 -0700162 FQName fqName(mPackage.package(), mPackage.version(), path);
Andreas Huber39fa7182016-08-19 14:27:33 -0700163
164 if (!isTypeDef) {
165 CHECK(type->isNamedType());
166
167 NamedType *namedType = static_cast<NamedType *>(type);
Andreas Huber39fa7182016-08-19 14:27:33 -0700168 namedType->setFullName(fqName);
169 }
170
171 mDefinedTypesByFullName.add(fqName, type);
Andreas Huber31629bc2016-08-03 09:06:40 -0700172
Andreas Huber5a545442016-08-03 10:44:56 -0700173 return true;
Andreas Huber31629bc2016-08-03 09:06:40 -0700174}
175
Andreas Huberfd4afab2016-08-03 13:02:57 -0700176Type *AST::lookupType(const char *name) {
Andreas Huber84f89de2016-07-28 15:39:51 -0700177 FQName fqName(name);
178 CHECK(fqName.isValid());
179
Andreas Huberda51b8e2016-07-28 16:00:57 -0700180 if (fqName.name().empty()) {
181 // Given a package and version???
182 return NULL;
183 }
184
Andreas Huber84f89de2016-07-28 15:39:51 -0700185 if (fqName.package().empty() && fqName.version().empty()) {
186 // This is just a plain identifier, resolve locally first if possible.
187
188 for (size_t i = mScopePath.size(); i-- > 0;) {
189 Type *type = mScopePath[i]->lookupType(name);
190
191 if (type != NULL) {
Andreas Huber8d3ac0c2016-08-04 14:49:23 -0700192 // Resolve typeDefs to the target type.
193 while (type->isTypeDef()) {
194 type = static_cast<TypeDef *>(type)->referencedType();
195 }
196
Andreas Huberfd4afab2016-08-03 13:02:57 -0700197 return type->ref();
Andreas Huber84f89de2016-07-28 15:39:51 -0700198 }
Andreas Huberc9410c72016-07-28 12:18:40 -0700199 }
200 }
201
Andreas Huber39fa7182016-08-19 14:27:33 -0700202 Type *resolvedType = nullptr;
203 FQName resolvedName;
Andreas Huber84f89de2016-07-28 15:39:51 -0700204
Andreas Huber39fa7182016-08-19 14:27:33 -0700205 for (const auto &importedAST : mImportedASTs) {
206 FQName matchingName;
207 Type *match = importedAST->findDefinedType(fqName, &matchingName);
Andreas Huber84f89de2016-07-28 15:39:51 -0700208
Andreas Huber39fa7182016-08-19 14:27:33 -0700209 if (match != nullptr) {
210 if (resolvedType != nullptr) {
211 std::cerr << "ERROR: Unable to resolve type name '"
212 << fqName.string()
213 << "', multiple matches found:\n";
Andreas Huber737080b2016-08-02 15:38:04 -0700214
Andreas Huber39fa7182016-08-19 14:27:33 -0700215 std::cerr << " " << resolvedName.string() << "\n";
216 std::cerr << " " << matchingName.string() << "\n";
217
218 return NULL;
219 }
220
221 resolvedType = match;
222 resolvedName = matchingName;
223
224 // Keep going even after finding a match.
225 }
226 }
227
228 if (resolvedType) {
229#if 0
230 LOG(INFO) << "found '"
231 << resolvedName.string()
232 << "' after looking for '"
233 << fqName.string()
234 << "'.";
235#endif
236
237 // Resolve typeDefs to the target type.
238 while (resolvedType->isTypeDef()) {
239 resolvedType =
240 static_cast<TypeDef *>(resolvedType)->referencedType();
241 }
242
243 if (!resolvedType->isInterface()) {
Andreas Huber0e00de42016-08-03 09:56:02 -0700244 // Non-interface types are declared in the associated types header.
Andreas Huber39fa7182016-08-19 14:27:33 -0700245 FQName typesName(
246 resolvedName.package(), resolvedName.version(), "types");
247
Andreas Huber0e00de42016-08-03 09:56:02 -0700248 mImportedNames.insert(typesName);
Andreas Huber85eabdb2016-08-25 11:24:49 -0700249
250 if (resolvedType->isNamedType()) {
251 mImportedNamesForJava.insert(
252 static_cast<NamedType *>(resolvedType)->fqName());
253 }
Andreas Huber0e00de42016-08-03 09:56:02 -0700254 } else {
Andreas Huberbfd76212016-08-09 11:12:16 -0700255 // Do _not_ use fqName, i.e. the name we used to look up the type,
256 // but instead use the name of the interface we found.
257 // This is necessary because if fqName pointed to a typedef which
258 // in turn referenced the found interface we'd mistakenly use the
259 // name of the typedef instead of the proper name of the interface.
260
261 mImportedNames.insert(
Andreas Huber39fa7182016-08-19 14:27:33 -0700262 static_cast<Interface *>(resolvedType)->fqName());
Andreas Huber85eabdb2016-08-25 11:24:49 -0700263
264 mImportedNamesForJava.insert(
265 static_cast<Interface *>(resolvedType)->fqName());
Andreas Huber0e00de42016-08-03 09:56:02 -0700266 }
Andreas Huber737080b2016-08-02 15:38:04 -0700267 }
268
Andreas Huber39fa7182016-08-19 14:27:33 -0700269 return resolvedType->ref();
Andreas Huber5345ec22016-07-29 13:33:27 -0700270}
271
Andreas Huber39fa7182016-08-19 14:27:33 -0700272Type *AST::findDefinedType(const FQName &fqName, FQName *matchingName) const {
273 for (size_t i = 0; i < mDefinedTypesByFullName.size(); ++i) {
274 const FQName &key = mDefinedTypesByFullName.keyAt(i);
Andreas Huber5345ec22016-07-29 13:33:27 -0700275
Andreas Huber39fa7182016-08-19 14:27:33 -0700276 if (key.endsWith(fqName)) {
277 *matchingName = key;
278 return mDefinedTypesByFullName.valueAt(i);
Andreas Huber5345ec22016-07-29 13:33:27 -0700279 }
Andreas Huber5345ec22016-07-29 13:33:27 -0700280 }
Andreas Huber39fa7182016-08-19 14:27:33 -0700281
282 return nullptr;
Andreas Huberc9410c72016-07-28 12:18:40 -0700283}
284
Iliyan Malchev5bb14022016-08-09 15:04:39 -0700285void AST::getImportedPackages(std::set<FQName> *importSet) const {
Andreas Huberd2943e12016-08-05 11:59:31 -0700286 for (const auto &fqName : mImportedNames) {
287 FQName packageName(fqName.package(), fqName.version(), "");
288
289 if (packageName == mPackage) {
290 // We only care about external imports, not our own package.
291 continue;
292 }
293
294 importSet->insert(packageName);
295 }
296}
297
Andreas Huberc9410c72016-07-28 12:18:40 -0700298} // namespace android;