blob: 7e90ed0271afbb517eb057c45f408681316f748a [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 Huberc9410c72016-07-28 12:18:40 -070012#include <stdlib.h>
13
Andreas Huberc9410c72016-07-28 12:18:40 -070014namespace android {
15
Andreas Huber0d0f9a22016-08-17 10:26:11 -070016AST::AST(Coordinator *coordinator, const std::string &path)
Andreas Huber5345ec22016-07-29 13:33:27 -070017 : mCoordinator(coordinator),
Andreas Huber0d0f9a22016-08-17 10:26:11 -070018 mPath(path),
Andreas Huber5345ec22016-07-29 13:33:27 -070019 mScanner(NULL),
Andreas Huber31629bc2016-08-03 09:06:40 -070020 mRootScope(new Scope) {
Andreas Huberc9410c72016-07-28 12:18:40 -070021 enterScope(mRootScope);
22}
23
24AST::~AST() {
Andreas Huberc9410c72016-07-28 12:18:40 -070025 delete mRootScope;
26 mRootScope = NULL;
27
Andreas Hubereb1081f2016-07-28 13:13:24 -070028 CHECK(mScanner == NULL);
Andreas Huberc9410c72016-07-28 12:18:40 -070029
Andreas Huber5345ec22016-07-29 13:33:27 -070030 // Ownership of "coordinator" was NOT transferred.
Andreas Huberc9410c72016-07-28 12:18:40 -070031}
32
33void *AST::scanner() {
34 return mScanner;
35}
36
37void AST::setScanner(void *scanner) {
38 mScanner = scanner;
39}
40
Andreas Huber0d0f9a22016-08-17 10:26:11 -070041const std::string &AST::getFilename() const {
42 return mPath;
43}
44
Andreas Huber84f89de2016-07-28 15:39:51 -070045bool AST::setPackage(const char *package) {
Andreas Huberda51b8e2016-07-28 16:00:57 -070046 mPackage.setTo(package);
47 CHECK(mPackage.isValid());
Andreas Huber84f89de2016-07-28 15:39:51 -070048
Andreas Huberda51b8e2016-07-28 16:00:57 -070049 if (mPackage.package().empty()
50 || mPackage.version().empty()
51 || !mPackage.name().empty()) {
Andreas Huber84f89de2016-07-28 15:39:51 -070052 return false;
53 }
54
Andreas Huber84f89de2016-07-28 15:39:51 -070055 return true;
Andreas Hubereb1081f2016-07-28 13:13:24 -070056}
57
Andreas Hubera2723d22016-07-29 15:36:07 -070058FQName AST::package() const {
59 return mPackage;
60}
61
62bool AST::isInterface(std::string *ifaceName) const {
63 return mRootScope->containsSingleInterface(ifaceName);
64}
65
Andreas Huber5345ec22016-07-29 13:33:27 -070066bool AST::addImport(const char *import) {
67 FQName fqName(import);
68 CHECK(fqName.isValid());
Andreas Hubereb1081f2016-07-28 13:13:24 -070069
Andreas Huber5345ec22016-07-29 13:33:27 -070070 fqName.applyDefaults(mPackage.package(), mPackage.version());
71
Andreas Huber68f24592016-07-29 14:53:48 -070072 // LOG(INFO) << "importing " << fqName.string();
Andreas Huber5345ec22016-07-29 13:33:27 -070073
74 if (fqName.name().empty()) {
Andreas Huberd2943e12016-08-05 11:59:31 -070075 std::vector<FQName> packageInterfaces;
Andreas Huber68f24592016-07-29 14:53:48 -070076
Andreas Huberd2943e12016-08-05 11:59:31 -070077 status_t err =
Iliyan Malchev5bb14022016-08-09 15:04:39 -070078 mCoordinator->appendPackageInterfacesToSet(fqName,
79 &packageInterfaces);
Andreas Huberd2943e12016-08-05 11:59:31 -070080
81 if (err != OK) {
Andreas Huber68f24592016-07-29 14:53:48 -070082 return false;
83 }
84
Andreas Huberd2943e12016-08-05 11:59:31 -070085 for (const auto &subFQName : packageInterfaces) {
Andreas Huber68f24592016-07-29 14:53:48 -070086 if (mCoordinator->parse(subFQName) == NULL) {
87 return false;
88 }
89 }
90
91 return true;
Andreas Huber5345ec22016-07-29 13:33:27 -070092 }
93
Andreas Huber68f24592016-07-29 14:53:48 -070094 AST *importAST = mCoordinator->parse(fqName);
Andreas Huber5345ec22016-07-29 13:33:27 -070095
Andreas Huber68f24592016-07-29 14:53:48 -070096 if (importAST == NULL) {
97 return false;
98 }
Andreas Huber84f89de2016-07-28 15:39:51 -070099
100 return true;
Andreas Hubereb1081f2016-07-28 13:13:24 -0700101}
102
Andreas Huberc9410c72016-07-28 12:18:40 -0700103void AST::enterScope(Scope *container) {
104 mScopePath.push_back(container);
105}
106
107void AST::leaveScope() {
108 mScopePath.pop();
109}
110
111Scope *AST::scope() {
Andreas Hubereb1081f2016-07-28 13:13:24 -0700112 CHECK(!mScopePath.empty());
Andreas Huberc9410c72016-07-28 12:18:40 -0700113 return mScopePath.top();
114}
115
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700116bool AST::addScopedType(
117 const char *localName, NamedType *type, std::string *errorMsg) {
Andreas Huberc7dfef32016-08-16 10:57:14 -0700118 std::string anonName;
119
120 if (localName == nullptr) {
121 // Anonymous type declaration.
122 anonName = scope()->pickUniqueAnonymousName();
123 localName = anonName.c_str();
124 }
125
Andreas Huber31629bc2016-08-03 09:06:40 -0700126 // LOG(INFO) << "adding scoped type '" << localName << "'";
127
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700128 bool success = scope()->addType(localName, type, errorMsg);
Andreas Huber5a545442016-08-03 10:44:56 -0700129 if (!success) {
130 return false;
131 }
132
Andreas Huber31629bc2016-08-03 09:06:40 -0700133 std::string path;
134 for (size_t i = 1; i < mScopePath.size(); ++i) {
Andreas Huber0e00de42016-08-03 09:56:02 -0700135 path.append(mScopePath[i]->localName());
Andreas Huber31629bc2016-08-03 09:06:40 -0700136 path.append(".");
137 }
138 path.append(localName);
139
140 type->setLocalName(localName);
141
142 FQName fqName(mPackage.package(), mPackage.version(), path);
143 type->setFullName(fqName);
144
Andreas Huber5a545442016-08-03 10:44:56 -0700145 return true;
Andreas Huber31629bc2016-08-03 09:06:40 -0700146}
147
Andreas Huberfd4afab2016-08-03 13:02:57 -0700148Type *AST::lookupType(const char *name) {
Andreas Huber84f89de2016-07-28 15:39:51 -0700149 FQName fqName(name);
150 CHECK(fqName.isValid());
151
Andreas Huberda51b8e2016-07-28 16:00:57 -0700152 if (fqName.name().empty()) {
153 // Given a package and version???
154 return NULL;
155 }
156
Andreas Huber84f89de2016-07-28 15:39:51 -0700157 if (fqName.package().empty() && fqName.version().empty()) {
158 // This is just a plain identifier, resolve locally first if possible.
159
160 for (size_t i = mScopePath.size(); i-- > 0;) {
161 Type *type = mScopePath[i]->lookupType(name);
162
163 if (type != NULL) {
Andreas Huber8d3ac0c2016-08-04 14:49:23 -0700164 // Resolve typeDefs to the target type.
165 while (type->isTypeDef()) {
166 type = static_cast<TypeDef *>(type)->referencedType();
167 }
168
Andreas Huberfd4afab2016-08-03 13:02:57 -0700169 return type->ref();
Andreas Huber84f89de2016-07-28 15:39:51 -0700170 }
Andreas Huberc9410c72016-07-28 12:18:40 -0700171 }
172 }
173
Andreas Huberda51b8e2016-07-28 16:00:57 -0700174 fqName.applyDefaults(mPackage.package(), mPackage.version());
Andreas Huber84f89de2016-07-28 15:39:51 -0700175
Andreas Huber68f24592016-07-29 14:53:48 -0700176 // LOG(INFO) << "lookupType now looking for " << fqName.string();
Andreas Huber84f89de2016-07-28 15:39:51 -0700177
Andreas Huberfd4afab2016-08-03 13:02:57 -0700178 Type *resultType = mCoordinator->lookupType(fqName);
Andreas Huber737080b2016-08-02 15:38:04 -0700179
180 if (resultType) {
Andreas Huberfd4afab2016-08-03 13:02:57 -0700181 if (!resultType->isInterface()) {
Andreas Huber0e00de42016-08-03 09:56:02 -0700182 // Non-interface types are declared in the associated types header.
183 FQName typesName(fqName.package(), fqName.version(), "types");
184 mImportedNames.insert(typesName);
185 } else {
Andreas Huberbfd76212016-08-09 11:12:16 -0700186 // Do _not_ use fqName, i.e. the name we used to look up the type,
187 // but instead use the name of the interface we found.
188 // This is necessary because if fqName pointed to a typedef which
189 // in turn referenced the found interface we'd mistakenly use the
190 // name of the typedef instead of the proper name of the interface.
191
192 mImportedNames.insert(
193 static_cast<Interface *>(resultType)->fqName());
Andreas Huber0e00de42016-08-03 09:56:02 -0700194 }
Andreas Huber737080b2016-08-02 15:38:04 -0700195 }
196
197 return resultType;
Andreas Huber5345ec22016-07-29 13:33:27 -0700198}
199
200Type *AST::lookupTypeInternal(const std::string &namePath) const {
201 Scope *scope = mRootScope;
202
203 size_t startPos = 0;
204 for (;;) {
205 size_t dotPos = namePath.find('.', startPos);
206
207 std::string component;
208 if (dotPos == std::string::npos) {
209 component = namePath.substr(startPos);
210 } else {
211 component = namePath.substr(startPos, dotPos - startPos);
212 }
213
214 Type *type = scope->lookupType(component.c_str());
215
216 if (type == NULL) {
217 return NULL;
218 }
219
220 if (dotPos == std::string::npos) {
Andreas Huber8d3ac0c2016-08-04 14:49:23 -0700221 // Resolve typeDefs to the target type.
222 while (type->isTypeDef()) {
223 type = static_cast<TypeDef *>(type)->referencedType();
224 }
225
Andreas Huber5345ec22016-07-29 13:33:27 -0700226 return type;
227 }
228
229 if (!type->isScope()) {
230 return NULL;
231 }
232
233 scope = static_cast<Scope *>(type);
234 startPos = dotPos + 1;
235 }
Andreas Huberc9410c72016-07-28 12:18:40 -0700236}
237
Iliyan Malchev5bb14022016-08-09 15:04:39 -0700238void AST::getImportedPackages(std::set<FQName> *importSet) const {
Andreas Huberd2943e12016-08-05 11:59:31 -0700239 for (const auto &fqName : mImportedNames) {
240 FQName packageName(fqName.package(), fqName.version(), "");
241
242 if (packageName == mPackage) {
243 // We only care about external imports, not our own package.
244 continue;
245 }
246
247 importSet->insert(packageName);
248 }
249}
250
Andreas Huberc9410c72016-07-28 12:18:40 -0700251} // namespace android;