blob: d5f8cc73592e8c81f116c33e9b589bcb39e54c3d [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 Huberc7dfef32016-08-16 10:57:14 -0700112 std::string anonName;
113
114 if (localName == nullptr) {
115 // Anonymous type declaration.
116 anonName = scope()->pickUniqueAnonymousName();
117 localName = anonName.c_str();
118 }
119
Andreas Huber31629bc2016-08-03 09:06:40 -0700120 // LOG(INFO) << "adding scoped type '" << localName << "'";
121
Andreas Huber5a545442016-08-03 10:44:56 -0700122 bool success = scope()->addType(localName, type);
123 if (!success) {
124 return false;
125 }
126
Andreas Huber31629bc2016-08-03 09:06:40 -0700127 std::string path;
128 for (size_t i = 1; i < mScopePath.size(); ++i) {
Andreas Huber0e00de42016-08-03 09:56:02 -0700129 path.append(mScopePath[i]->localName());
Andreas Huber31629bc2016-08-03 09:06:40 -0700130 path.append(".");
131 }
132 path.append(localName);
133
134 type->setLocalName(localName);
135
136 FQName fqName(mPackage.package(), mPackage.version(), path);
137 type->setFullName(fqName);
138
Andreas Huber5a545442016-08-03 10:44:56 -0700139 return true;
Andreas Huber31629bc2016-08-03 09:06:40 -0700140}
141
Andreas Huberfd4afab2016-08-03 13:02:57 -0700142Type *AST::lookupType(const char *name) {
Andreas Huber84f89de2016-07-28 15:39:51 -0700143 FQName fqName(name);
144 CHECK(fqName.isValid());
145
Andreas Huberda51b8e2016-07-28 16:00:57 -0700146 if (fqName.name().empty()) {
147 // Given a package and version???
148 return NULL;
149 }
150
Andreas Huber84f89de2016-07-28 15:39:51 -0700151 if (fqName.package().empty() && fqName.version().empty()) {
152 // This is just a plain identifier, resolve locally first if possible.
153
154 for (size_t i = mScopePath.size(); i-- > 0;) {
155 Type *type = mScopePath[i]->lookupType(name);
156
157 if (type != NULL) {
Andreas Huber8d3ac0c2016-08-04 14:49:23 -0700158 // Resolve typeDefs to the target type.
159 while (type->isTypeDef()) {
160 type = static_cast<TypeDef *>(type)->referencedType();
161 }
162
Andreas Huberfd4afab2016-08-03 13:02:57 -0700163 return type->ref();
Andreas Huber84f89de2016-07-28 15:39:51 -0700164 }
Andreas Huberc9410c72016-07-28 12:18:40 -0700165 }
166 }
167
Andreas Huberda51b8e2016-07-28 16:00:57 -0700168 fqName.applyDefaults(mPackage.package(), mPackage.version());
Andreas Huber84f89de2016-07-28 15:39:51 -0700169
Andreas Huber68f24592016-07-29 14:53:48 -0700170 // LOG(INFO) << "lookupType now looking for " << fqName.string();
Andreas Huber84f89de2016-07-28 15:39:51 -0700171
Andreas Huberfd4afab2016-08-03 13:02:57 -0700172 Type *resultType = mCoordinator->lookupType(fqName);
Andreas Huber737080b2016-08-02 15:38:04 -0700173
174 if (resultType) {
Andreas Huberfd4afab2016-08-03 13:02:57 -0700175 if (!resultType->isInterface()) {
Andreas Huber0e00de42016-08-03 09:56:02 -0700176 // Non-interface types are declared in the associated types header.
177 FQName typesName(fqName.package(), fqName.version(), "types");
178 mImportedNames.insert(typesName);
179 } else {
Andreas Huberbfd76212016-08-09 11:12:16 -0700180 // Do _not_ use fqName, i.e. the name we used to look up the type,
181 // but instead use the name of the interface we found.
182 // This is necessary because if fqName pointed to a typedef which
183 // in turn referenced the found interface we'd mistakenly use the
184 // name of the typedef instead of the proper name of the interface.
185
186 mImportedNames.insert(
187 static_cast<Interface *>(resultType)->fqName());
Andreas Huber0e00de42016-08-03 09:56:02 -0700188 }
Andreas Huber737080b2016-08-02 15:38:04 -0700189 }
190
191 return resultType;
Andreas Huber5345ec22016-07-29 13:33:27 -0700192}
193
194Type *AST::lookupTypeInternal(const std::string &namePath) const {
195 Scope *scope = mRootScope;
196
197 size_t startPos = 0;
198 for (;;) {
199 size_t dotPos = namePath.find('.', startPos);
200
201 std::string component;
202 if (dotPos == std::string::npos) {
203 component = namePath.substr(startPos);
204 } else {
205 component = namePath.substr(startPos, dotPos - startPos);
206 }
207
208 Type *type = scope->lookupType(component.c_str());
209
210 if (type == NULL) {
211 return NULL;
212 }
213
214 if (dotPos == std::string::npos) {
Andreas Huber8d3ac0c2016-08-04 14:49:23 -0700215 // Resolve typeDefs to the target type.
216 while (type->isTypeDef()) {
217 type = static_cast<TypeDef *>(type)->referencedType();
218 }
219
Andreas Huber5345ec22016-07-29 13:33:27 -0700220 return type;
221 }
222
223 if (!type->isScope()) {
224 return NULL;
225 }
226
227 scope = static_cast<Scope *>(type);
228 startPos = dotPos + 1;
229 }
Andreas Huberc9410c72016-07-28 12:18:40 -0700230}
231
Iliyan Malchev5bb14022016-08-09 15:04:39 -0700232void AST::getImportedPackages(std::set<FQName> *importSet) const {
Andreas Huberd2943e12016-08-05 11:59:31 -0700233 for (const auto &fqName : mImportedNames) {
234 FQName packageName(fqName.package(), fqName.version(), "");
235
236 if (packageName == mPackage) {
237 // We only care about external imports, not our own package.
238 continue;
239 }
240
241 importSet->insert(packageName);
242 }
243}
244
Andreas Huberc9410c72016-07-28 12:18:40 -0700245} // namespace android;