blob: d13167a3126b67224e219493cc0b3ecfb41e128f [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 "AST.h"
18
Andreas Huber5345ec22016-07-29 13:33:27 -070019#include "Coordinator.h"
Andreas Huberc9410c72016-07-28 12:18:40 -070020#include "Formatter.h"
Andreas Huber84f89de2016-07-28 15:39:51 -070021#include "FQName.h"
Andreas Hubereb1081f2016-07-28 13:13:24 -070022#include "HandleType.h"
Andreas Huberbfd76212016-08-09 11:12:16 -070023#include "Interface.h"
Andreas Huberc9410c72016-07-28 12:18:40 -070024#include "Scope.h"
Andreas Huber8d3ac0c2016-08-04 14:49:23 -070025#include "TypeDef.h"
Andreas Huberc9410c72016-07-28 12:18:40 -070026
Andreas Hubereb1081f2016-07-28 13:13:24 -070027#include <android-base/logging.h>
Andreas Huber39fa7182016-08-19 14:27:33 -070028#include <iostream>
Andreas Huberc9410c72016-07-28 12:18:40 -070029#include <stdlib.h>
30
Andreas Huberc9410c72016-07-28 12:18:40 -070031namespace android {
32
Andreas Huber0d0f9a22016-08-17 10:26:11 -070033AST::AST(Coordinator *coordinator, const std::string &path)
Andreas Huber5345ec22016-07-29 13:33:27 -070034 : mCoordinator(coordinator),
Andreas Huber0d0f9a22016-08-17 10:26:11 -070035 mPath(path),
Andreas Huber5345ec22016-07-29 13:33:27 -070036 mScanner(NULL),
Andreas Huber9ed827c2016-08-22 12:31:13 -070037 mRootScope(new Scope("" /* localName */)) {
Andreas Huberc9410c72016-07-28 12:18:40 -070038 enterScope(mRootScope);
39}
40
41AST::~AST() {
Andreas Huberc9410c72016-07-28 12:18:40 -070042 delete mRootScope;
43 mRootScope = NULL;
44
Andreas Hubereb1081f2016-07-28 13:13:24 -070045 CHECK(mScanner == NULL);
Andreas Huberc9410c72016-07-28 12:18:40 -070046
Andreas Huber5345ec22016-07-29 13:33:27 -070047 // Ownership of "coordinator" was NOT transferred.
Andreas Huberc9410c72016-07-28 12:18:40 -070048}
49
50void *AST::scanner() {
51 return mScanner;
52}
53
54void AST::setScanner(void *scanner) {
55 mScanner = scanner;
56}
57
Andreas Huber0d0f9a22016-08-17 10:26:11 -070058const std::string &AST::getFilename() const {
59 return mPath;
60}
61
Andreas Huber84f89de2016-07-28 15:39:51 -070062bool AST::setPackage(const char *package) {
Andreas Huberda51b8e2016-07-28 16:00:57 -070063 mPackage.setTo(package);
64 CHECK(mPackage.isValid());
Andreas Huber84f89de2016-07-28 15:39:51 -070065
Andreas Huberda51b8e2016-07-28 16:00:57 -070066 if (mPackage.package().empty()
67 || mPackage.version().empty()
68 || !mPackage.name().empty()) {
Andreas Huber84f89de2016-07-28 15:39:51 -070069 return false;
70 }
71
Andreas Huber84f89de2016-07-28 15:39:51 -070072 return true;
Andreas Hubereb1081f2016-07-28 13:13:24 -070073}
74
Andreas Hubera2723d22016-07-29 15:36:07 -070075FQName AST::package() const {
76 return mPackage;
77}
78
79bool AST::isInterface(std::string *ifaceName) const {
80 return mRootScope->containsSingleInterface(ifaceName);
81}
82
Andreas Huber5345ec22016-07-29 13:33:27 -070083bool AST::addImport(const char *import) {
84 FQName fqName(import);
85 CHECK(fqName.isValid());
Andreas Hubereb1081f2016-07-28 13:13:24 -070086
Andreas Huber5345ec22016-07-29 13:33:27 -070087 fqName.applyDefaults(mPackage.package(), mPackage.version());
88
Andreas Huber68f24592016-07-29 14:53:48 -070089 // LOG(INFO) << "importing " << fqName.string();
Andreas Huber5345ec22016-07-29 13:33:27 -070090
91 if (fqName.name().empty()) {
Andreas Huberd2943e12016-08-05 11:59:31 -070092 std::vector<FQName> packageInterfaces;
Andreas Huber68f24592016-07-29 14:53:48 -070093
Andreas Huberd2943e12016-08-05 11:59:31 -070094 status_t err =
Iliyan Malchev5bb14022016-08-09 15:04:39 -070095 mCoordinator->appendPackageInterfacesToSet(fqName,
96 &packageInterfaces);
Andreas Huberd2943e12016-08-05 11:59:31 -070097
98 if (err != OK) {
Andreas Huber68f24592016-07-29 14:53:48 -070099 return false;
100 }
101
Andreas Huberd2943e12016-08-05 11:59:31 -0700102 for (const auto &subFQName : packageInterfaces) {
Andreas Huber39fa7182016-08-19 14:27:33 -0700103 AST *ast = mCoordinator->parse(subFQName, &mImportedASTs);
104 if (ast == NULL) {
Andreas Huber68f24592016-07-29 14:53:48 -0700105 return false;
106 }
107 }
108
109 return true;
Andreas Huber5345ec22016-07-29 13:33:27 -0700110 }
111
Andreas Huber39fa7182016-08-19 14:27:33 -0700112 AST *importAST = mCoordinator->parse(fqName, &mImportedASTs);
Andreas Huber5345ec22016-07-29 13:33:27 -0700113
Andreas Huber68f24592016-07-29 14:53:48 -0700114 if (importAST == NULL) {
115 return false;
116 }
Andreas Huber84f89de2016-07-28 15:39:51 -0700117
118 return true;
Andreas Hubereb1081f2016-07-28 13:13:24 -0700119}
120
Andreas Huber39fa7182016-08-19 14:27:33 -0700121void AST::addImportedAST(AST *ast) {
122 mImportedASTs.insert(ast);
123}
124
Andreas Huberc9410c72016-07-28 12:18:40 -0700125void AST::enterScope(Scope *container) {
126 mScopePath.push_back(container);
127}
128
129void AST::leaveScope() {
130 mScopePath.pop();
131}
132
133Scope *AST::scope() {
Andreas Hubereb1081f2016-07-28 13:13:24 -0700134 CHECK(!mScopePath.empty());
Andreas Huberc9410c72016-07-28 12:18:40 -0700135 return mScopePath.top();
136}
137
Andreas Huber39fa7182016-08-19 14:27:33 -0700138bool AST::addTypeDef(
139 const char *localName, Type *type, std::string *errorMsg) {
140 // The reason we wrap the given type in a TypeDef is simply to suppress
141 // emitting any type definitions later on, since this is just an alias
142 // to a type defined elsewhere.
143 return addScopedTypeInternal(
144 localName, new TypeDef(type), errorMsg, true /* isTypeDef */);
145}
146
Andreas Huber9ed827c2016-08-22 12:31:13 -0700147bool AST::addScopedType(NamedType *type, std::string *errorMsg) {
Andreas Huber39fa7182016-08-19 14:27:33 -0700148 return addScopedTypeInternal(
Andreas Huber9ed827c2016-08-22 12:31:13 -0700149 type->localName().c_str(), type, errorMsg, false /* isTypeDef */);
Andreas Huber39fa7182016-08-19 14:27:33 -0700150}
151
152bool AST::addScopedTypeInternal(
153 const char *localName,
154 Type *type,
155 std::string *errorMsg,
156 bool isTypeDef) {
157 if (!isTypeDef) {
158 // Resolve typeDefs to the target type.
159 while (type->isTypeDef()) {
160 type = static_cast<TypeDef *>(type)->referencedType();
161 }
162 }
163
Andreas Huber31629bc2016-08-03 09:06:40 -0700164 // LOG(INFO) << "adding scoped type '" << localName << "'";
165
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700166 bool success = scope()->addType(localName, type, errorMsg);
Andreas Huber5a545442016-08-03 10:44:56 -0700167 if (!success) {
168 return false;
169 }
170
Andreas Huber31629bc2016-08-03 09:06:40 -0700171 std::string path;
172 for (size_t i = 1; i < mScopePath.size(); ++i) {
Andreas Huber0e00de42016-08-03 09:56:02 -0700173 path.append(mScopePath[i]->localName());
Andreas Huber31629bc2016-08-03 09:06:40 -0700174 path.append(".");
175 }
176 path.append(localName);
177
Andreas Huber31629bc2016-08-03 09:06:40 -0700178 FQName fqName(mPackage.package(), mPackage.version(), path);
Andreas Huber39fa7182016-08-19 14:27:33 -0700179
180 if (!isTypeDef) {
181 CHECK(type->isNamedType());
182
183 NamedType *namedType = static_cast<NamedType *>(type);
Andreas Huber39fa7182016-08-19 14:27:33 -0700184 namedType->setFullName(fqName);
185 }
186
187 mDefinedTypesByFullName.add(fqName, type);
Andreas Huber31629bc2016-08-03 09:06:40 -0700188
Andreas Huber5a545442016-08-03 10:44:56 -0700189 return true;
Andreas Huber31629bc2016-08-03 09:06:40 -0700190}
191
Andreas Huberfd4afab2016-08-03 13:02:57 -0700192Type *AST::lookupType(const char *name) {
Andreas Huber84f89de2016-07-28 15:39:51 -0700193 FQName fqName(name);
194 CHECK(fqName.isValid());
195
Andreas Huberda51b8e2016-07-28 16:00:57 -0700196 if (fqName.name().empty()) {
197 // Given a package and version???
198 return NULL;
199 }
200
Andreas Huber84f89de2016-07-28 15:39:51 -0700201 if (fqName.package().empty() && fqName.version().empty()) {
202 // This is just a plain identifier, resolve locally first if possible.
203
204 for (size_t i = mScopePath.size(); i-- > 0;) {
205 Type *type = mScopePath[i]->lookupType(name);
206
207 if (type != NULL) {
Andreas Huber8d3ac0c2016-08-04 14:49:23 -0700208 // Resolve typeDefs to the target type.
209 while (type->isTypeDef()) {
210 type = static_cast<TypeDef *>(type)->referencedType();
211 }
212
Andreas Huberfd4afab2016-08-03 13:02:57 -0700213 return type->ref();
Andreas Huber84f89de2016-07-28 15:39:51 -0700214 }
Andreas Huberc9410c72016-07-28 12:18:40 -0700215 }
216 }
217
Andreas Huber39fa7182016-08-19 14:27:33 -0700218 Type *resolvedType = nullptr;
219 FQName resolvedName;
Andreas Huber84f89de2016-07-28 15:39:51 -0700220
Andreas Huber39fa7182016-08-19 14:27:33 -0700221 for (const auto &importedAST : mImportedASTs) {
222 FQName matchingName;
223 Type *match = importedAST->findDefinedType(fqName, &matchingName);
Andreas Huber84f89de2016-07-28 15:39:51 -0700224
Andreas Huber39fa7182016-08-19 14:27:33 -0700225 if (match != nullptr) {
226 if (resolvedType != nullptr) {
227 std::cerr << "ERROR: Unable to resolve type name '"
228 << fqName.string()
229 << "', multiple matches found:\n";
Andreas Huber737080b2016-08-02 15:38:04 -0700230
Andreas Huber39fa7182016-08-19 14:27:33 -0700231 std::cerr << " " << resolvedName.string() << "\n";
232 std::cerr << " " << matchingName.string() << "\n";
233
234 return NULL;
235 }
236
237 resolvedType = match;
238 resolvedName = matchingName;
239
240 // Keep going even after finding a match.
241 }
242 }
243
244 if (resolvedType) {
245#if 0
246 LOG(INFO) << "found '"
247 << resolvedName.string()
248 << "' after looking for '"
249 << fqName.string()
250 << "'.";
251#endif
252
253 // Resolve typeDefs to the target type.
254 while (resolvedType->isTypeDef()) {
255 resolvedType =
256 static_cast<TypeDef *>(resolvedType)->referencedType();
257 }
258
259 if (!resolvedType->isInterface()) {
Andreas Huber0e00de42016-08-03 09:56:02 -0700260 // Non-interface types are declared in the associated types header.
Andreas Huber39fa7182016-08-19 14:27:33 -0700261 FQName typesName(
262 resolvedName.package(), resolvedName.version(), "types");
263
Andreas Huber0e00de42016-08-03 09:56:02 -0700264 mImportedNames.insert(typesName);
Andreas Huber85eabdb2016-08-25 11:24:49 -0700265
266 if (resolvedType->isNamedType()) {
267 mImportedNamesForJava.insert(
268 static_cast<NamedType *>(resolvedType)->fqName());
269 }
Andreas Huber0e00de42016-08-03 09:56:02 -0700270 } else {
Andreas Huberbfd76212016-08-09 11:12:16 -0700271 // Do _not_ use fqName, i.e. the name we used to look up the type,
272 // but instead use the name of the interface we found.
273 // This is necessary because if fqName pointed to a typedef which
274 // in turn referenced the found interface we'd mistakenly use the
275 // name of the typedef instead of the proper name of the interface.
276
277 mImportedNames.insert(
Andreas Huber39fa7182016-08-19 14:27:33 -0700278 static_cast<Interface *>(resolvedType)->fqName());
Andreas Huber85eabdb2016-08-25 11:24:49 -0700279
280 mImportedNamesForJava.insert(
281 static_cast<Interface *>(resolvedType)->fqName());
Andreas Huber0e00de42016-08-03 09:56:02 -0700282 }
Andreas Huber737080b2016-08-02 15:38:04 -0700283 }
284
Andreas Huber39fa7182016-08-19 14:27:33 -0700285 return resolvedType->ref();
Andreas Huber5345ec22016-07-29 13:33:27 -0700286}
287
Andreas Huber39fa7182016-08-19 14:27:33 -0700288Type *AST::findDefinedType(const FQName &fqName, FQName *matchingName) const {
289 for (size_t i = 0; i < mDefinedTypesByFullName.size(); ++i) {
290 const FQName &key = mDefinedTypesByFullName.keyAt(i);
Andreas Huber5345ec22016-07-29 13:33:27 -0700291
Andreas Huber39fa7182016-08-19 14:27:33 -0700292 if (key.endsWith(fqName)) {
293 *matchingName = key;
294 return mDefinedTypesByFullName.valueAt(i);
Andreas Huber5345ec22016-07-29 13:33:27 -0700295 }
Andreas Huber5345ec22016-07-29 13:33:27 -0700296 }
Andreas Huber39fa7182016-08-19 14:27:33 -0700297
298 return nullptr;
Andreas Huberc9410c72016-07-28 12:18:40 -0700299}
300
Iliyan Malchev5bb14022016-08-09 15:04:39 -0700301void AST::getImportedPackages(std::set<FQName> *importSet) const {
Andreas Huberd2943e12016-08-05 11:59:31 -0700302 for (const auto &fqName : mImportedNames) {
303 FQName packageName(fqName.package(), fqName.version(), "");
304
305 if (packageName == mPackage) {
306 // We only care about external imports, not our own package.
307 continue;
308 }
309
310 importSet->insert(packageName);
311 }
312}
313
Andreas Huberc9410c72016-07-28 12:18:40 -0700314} // namespace android;