blob: 20db9b3c644229344010ca3668855847b4f1d122 [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 Huber5345ec22016-07-29 13:33:27 -070016AST::AST(Coordinator *coordinator)
17 : mCoordinator(coordinator),
18 mScanner(NULL),
Andreas Huber31629bc2016-08-03 09:06:40 -070019 mRootScope(new Scope) {
Andreas Huberc9410c72016-07-28 12:18:40 -070020 enterScope(mRootScope);
21}
22
23AST::~AST() {
Andreas Huberc9410c72016-07-28 12:18:40 -070024 delete mRootScope;
25 mRootScope = NULL;
26
Andreas Hubereb1081f2016-07-28 13:13:24 -070027 CHECK(mScanner == NULL);
Andreas Huberc9410c72016-07-28 12:18:40 -070028
Andreas Huber5345ec22016-07-29 13:33:27 -070029 // Ownership of "coordinator" was NOT transferred.
Andreas Huberc9410c72016-07-28 12:18:40 -070030}
31
32void *AST::scanner() {
33 return mScanner;
34}
35
36void AST::setScanner(void *scanner) {
37 mScanner = scanner;
38}
39
Andreas Huber84f89de2016-07-28 15:39:51 -070040bool AST::setPackage(const char *package) {
Andreas Huberda51b8e2016-07-28 16:00:57 -070041 mPackage.setTo(package);
42 CHECK(mPackage.isValid());
Andreas Huber84f89de2016-07-28 15:39:51 -070043
Andreas Huberda51b8e2016-07-28 16:00:57 -070044 if (mPackage.package().empty()
45 || mPackage.version().empty()
46 || !mPackage.name().empty()) {
Andreas Huber84f89de2016-07-28 15:39:51 -070047 return false;
48 }
49
Andreas Huber84f89de2016-07-28 15:39:51 -070050 return true;
Andreas Hubereb1081f2016-07-28 13:13:24 -070051}
52
Andreas Hubera2723d22016-07-29 15:36:07 -070053FQName AST::package() const {
54 return mPackage;
55}
56
57bool AST::isInterface(std::string *ifaceName) const {
58 return mRootScope->containsSingleInterface(ifaceName);
59}
60
Andreas Huber5345ec22016-07-29 13:33:27 -070061bool AST::addImport(const char *import) {
62 FQName fqName(import);
63 CHECK(fqName.isValid());
Andreas Hubereb1081f2016-07-28 13:13:24 -070064
Andreas Huber5345ec22016-07-29 13:33:27 -070065 fqName.applyDefaults(mPackage.package(), mPackage.version());
66
Andreas Huber68f24592016-07-29 14:53:48 -070067 // LOG(INFO) << "importing " << fqName.string();
Andreas Huber5345ec22016-07-29 13:33:27 -070068
69 if (fqName.name().empty()) {
Andreas Huberd2943e12016-08-05 11:59:31 -070070 std::vector<FQName> packageInterfaces;
Andreas Huber68f24592016-07-29 14:53:48 -070071
Andreas Huberd2943e12016-08-05 11:59:31 -070072 status_t err =
Iliyan Malchev5bb14022016-08-09 15:04:39 -070073 mCoordinator->appendPackageInterfacesToSet(fqName,
74 &packageInterfaces);
Andreas Huberd2943e12016-08-05 11:59:31 -070075
76 if (err != OK) {
Andreas Huber68f24592016-07-29 14:53:48 -070077 return false;
78 }
79
Andreas Huberd2943e12016-08-05 11:59:31 -070080 for (const auto &subFQName : packageInterfaces) {
Andreas Huber68f24592016-07-29 14:53:48 -070081 if (mCoordinator->parse(subFQName) == NULL) {
82 return false;
83 }
84 }
85
86 return true;
Andreas Huber5345ec22016-07-29 13:33:27 -070087 }
88
Andreas Huber68f24592016-07-29 14:53:48 -070089 AST *importAST = mCoordinator->parse(fqName);
Andreas Huber5345ec22016-07-29 13:33:27 -070090
Andreas Huber68f24592016-07-29 14:53:48 -070091 if (importAST == NULL) {
92 return false;
93 }
Andreas Huber84f89de2016-07-28 15:39:51 -070094
95 return true;
Andreas Hubereb1081f2016-07-28 13:13:24 -070096}
97
Andreas Huberc9410c72016-07-28 12:18:40 -070098void AST::enterScope(Scope *container) {
99 mScopePath.push_back(container);
100}
101
102void AST::leaveScope() {
103 mScopePath.pop();
104}
105
106Scope *AST::scope() {
Andreas Hubereb1081f2016-07-28 13:13:24 -0700107 CHECK(!mScopePath.empty());
Andreas Huberc9410c72016-07-28 12:18:40 -0700108 return mScopePath.top();
109}
110
Andreas Huber5a545442016-08-03 10:44:56 -0700111bool AST::addScopedType(const char *localName, NamedType *type) {
Andreas Huber31629bc2016-08-03 09:06:40 -0700112 // LOG(INFO) << "adding scoped type '" << localName << "'";
113
Andreas Huber5a545442016-08-03 10:44:56 -0700114 bool success = scope()->addType(localName, type);
115 if (!success) {
116 return false;
117 }
118
Andreas Huber31629bc2016-08-03 09:06:40 -0700119 std::string path;
120 for (size_t i = 1; i < mScopePath.size(); ++i) {
Andreas Huber0e00de42016-08-03 09:56:02 -0700121 path.append(mScopePath[i]->localName());
Andreas Huber31629bc2016-08-03 09:06:40 -0700122 path.append(".");
123 }
124 path.append(localName);
125
126 type->setLocalName(localName);
127
128 FQName fqName(mPackage.package(), mPackage.version(), path);
129 type->setFullName(fqName);
130
Andreas Huber5a545442016-08-03 10:44:56 -0700131 return true;
Andreas Huber31629bc2016-08-03 09:06:40 -0700132}
133
Andreas Huberfd4afab2016-08-03 13:02:57 -0700134Type *AST::lookupType(const char *name) {
Andreas Huber84f89de2016-07-28 15:39:51 -0700135 FQName fqName(name);
136 CHECK(fqName.isValid());
137
Andreas Huberda51b8e2016-07-28 16:00:57 -0700138 if (fqName.name().empty()) {
139 // Given a package and version???
140 return NULL;
141 }
142
Andreas Huber84f89de2016-07-28 15:39:51 -0700143 if (fqName.package().empty() && fqName.version().empty()) {
144 // This is just a plain identifier, resolve locally first if possible.
145
146 for (size_t i = mScopePath.size(); i-- > 0;) {
147 Type *type = mScopePath[i]->lookupType(name);
148
149 if (type != NULL) {
Andreas Huber8d3ac0c2016-08-04 14:49:23 -0700150 // Resolve typeDefs to the target type.
151 while (type->isTypeDef()) {
152 type = static_cast<TypeDef *>(type)->referencedType();
153 }
154
Andreas Huberfd4afab2016-08-03 13:02:57 -0700155 return type->ref();
Andreas Huber84f89de2016-07-28 15:39:51 -0700156 }
Andreas Huberc9410c72016-07-28 12:18:40 -0700157 }
158 }
159
Andreas Huberda51b8e2016-07-28 16:00:57 -0700160 fqName.applyDefaults(mPackage.package(), mPackage.version());
Andreas Huber84f89de2016-07-28 15:39:51 -0700161
Andreas Huber68f24592016-07-29 14:53:48 -0700162 // LOG(INFO) << "lookupType now looking for " << fqName.string();
Andreas Huber84f89de2016-07-28 15:39:51 -0700163
Andreas Huberfd4afab2016-08-03 13:02:57 -0700164 Type *resultType = mCoordinator->lookupType(fqName);
Andreas Huber737080b2016-08-02 15:38:04 -0700165
166 if (resultType) {
Andreas Huberfd4afab2016-08-03 13:02:57 -0700167 if (!resultType->isInterface()) {
Andreas Huber0e00de42016-08-03 09:56:02 -0700168 // Non-interface types are declared in the associated types header.
169 FQName typesName(fqName.package(), fqName.version(), "types");
170 mImportedNames.insert(typesName);
171 } else {
Andreas Huberbfd76212016-08-09 11:12:16 -0700172 // Do _not_ use fqName, i.e. the name we used to look up the type,
173 // but instead use the name of the interface we found.
174 // This is necessary because if fqName pointed to a typedef which
175 // in turn referenced the found interface we'd mistakenly use the
176 // name of the typedef instead of the proper name of the interface.
177
178 mImportedNames.insert(
179 static_cast<Interface *>(resultType)->fqName());
Andreas Huber0e00de42016-08-03 09:56:02 -0700180 }
Andreas Huber737080b2016-08-02 15:38:04 -0700181 }
182
183 return resultType;
Andreas Huber5345ec22016-07-29 13:33:27 -0700184}
185
186Type *AST::lookupTypeInternal(const std::string &namePath) const {
187 Scope *scope = mRootScope;
188
189 size_t startPos = 0;
190 for (;;) {
191 size_t dotPos = namePath.find('.', startPos);
192
193 std::string component;
194 if (dotPos == std::string::npos) {
195 component = namePath.substr(startPos);
196 } else {
197 component = namePath.substr(startPos, dotPos - startPos);
198 }
199
200 Type *type = scope->lookupType(component.c_str());
201
202 if (type == NULL) {
203 return NULL;
204 }
205
206 if (dotPos == std::string::npos) {
Andreas Huber8d3ac0c2016-08-04 14:49:23 -0700207 // Resolve typeDefs to the target type.
208 while (type->isTypeDef()) {
209 type = static_cast<TypeDef *>(type)->referencedType();
210 }
211
Andreas Huber5345ec22016-07-29 13:33:27 -0700212 return type;
213 }
214
215 if (!type->isScope()) {
216 return NULL;
217 }
218
219 scope = static_cast<Scope *>(type);
220 startPos = dotPos + 1;
221 }
Andreas Huberc9410c72016-07-28 12:18:40 -0700222}
223
Iliyan Malchev5bb14022016-08-09 15:04:39 -0700224void AST::getImportedPackages(std::set<FQName> *importSet) const {
Andreas Huberd2943e12016-08-05 11:59:31 -0700225 for (const auto &fqName : mImportedNames) {
226 FQName packageName(fqName.package(), fqName.version(), "");
227
228 if (packageName == mPackage) {
229 // We only care about external imports, not our own package.
230 continue;
231 }
232
233 importSet->insert(packageName);
234 }
235}
236
Andreas Huberc9410c72016-07-28 12:18:40 -0700237} // namespace android;