Coordinator.cpp revision 68f24590cda230fb92eac44ed0247f54f9b31ad0
15345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber#include "Coordinator.h" 25345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber 35345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber#include "AST.h" 45345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber#include "RefType.h" 55345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber 65345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber#include <android-base/logging.h> 75345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber 868f24590cda230fb92eac44ed0247f54f9b31ad0Andreas Huberextern android::status_t parseFile(android::AST *ast, const char *path); 95345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber 105345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Hubernamespace android { 115345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber 125345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas HuberCoordinator::Coordinator() {} 135345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas HuberCoordinator::~Coordinator() {} 145345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber 1568f24590cda230fb92eac44ed0247f54f9b31ad0Andreas HuberAST *Coordinator::parse(const FQName &fqName) { 1668f24590cda230fb92eac44ed0247f54f9b31ad0Andreas Huber CHECK(fqName.isFullyQualified()); 1768f24590cda230fb92eac44ed0247f54f9b31ad0Andreas Huber 1868f24590cda230fb92eac44ed0247f54f9b31ad0Andreas Huber ssize_t index = mCache.indexOfKey(fqName); 195345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber if (index >= 0) { 205345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber AST *ast = mCache.valueAt(index); 215345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber 225345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber return ast; 235345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber } 245345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber 2568f24590cda230fb92eac44ed0247f54f9b31ad0Andreas Huber // Add this to the cache immediately, so we can discover circular imports. 2668f24590cda230fb92eac44ed0247f54f9b31ad0Andreas Huber mCache.add(fqName, NULL); 2768f24590cda230fb92eac44ed0247f54f9b31ad0Andreas Huber 2868f24590cda230fb92eac44ed0247f54f9b31ad0Andreas Huber const std::string packagePath = GetPackagePath(fqName); 2968f24590cda230fb92eac44ed0247f54f9b31ad0Andreas Huber 3068f24590cda230fb92eac44ed0247f54f9b31ad0Andreas Huber if (fqName.name() != "types") { 3168f24590cda230fb92eac44ed0247f54f9b31ad0Andreas Huber // Any interface file implicitly imports its package's types.hal. 3268f24590cda230fb92eac44ed0247f54f9b31ad0Andreas Huber FQName typesName(fqName.package(), fqName.version(), "types"); 3368f24590cda230fb92eac44ed0247f54f9b31ad0Andreas Huber (void)parse(typesName); 3468f24590cda230fb92eac44ed0247f54f9b31ad0Andreas Huber 3568f24590cda230fb92eac44ed0247f54f9b31ad0Andreas Huber // fall through. 3668f24590cda230fb92eac44ed0247f54f9b31ad0Andreas Huber } 3768f24590cda230fb92eac44ed0247f54f9b31ad0Andreas Huber 3868f24590cda230fb92eac44ed0247f54f9b31ad0Andreas Huber std::string path = packagePath; 3968f24590cda230fb92eac44ed0247f54f9b31ad0Andreas Huber path.append(fqName.name()); 4068f24590cda230fb92eac44ed0247f54f9b31ad0Andreas Huber path.append(".hal"); 415345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber 425345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber AST *ast = new AST(this); 4368f24590cda230fb92eac44ed0247f54f9b31ad0Andreas Huber status_t err = parseFile(ast, path.c_str()); 4468f24590cda230fb92eac44ed0247f54f9b31ad0Andreas Huber 4568f24590cda230fb92eac44ed0247f54f9b31ad0Andreas Huber if (err != OK) { 4668f24590cda230fb92eac44ed0247f54f9b31ad0Andreas Huber delete ast; 4768f24590cda230fb92eac44ed0247f54f9b31ad0Andreas Huber ast = NULL; 485345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber 4968f24590cda230fb92eac44ed0247f54f9b31ad0Andreas Huber return NULL; 5068f24590cda230fb92eac44ed0247f54f9b31ad0Andreas Huber } 5168f24590cda230fb92eac44ed0247f54f9b31ad0Andreas Huber 5268f24590cda230fb92eac44ed0247f54f9b31ad0Andreas Huber mCache.add(fqName, ast); 535345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber 545345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber return ast; 555345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber} 565345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber 575345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber// static 585345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huberstd::string Coordinator::GetPackagePath(const FQName &fqName) { 595345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber CHECK(!fqName.package().empty()); 605345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber CHECK(!fqName.version().empty()); 615345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber const char *const kPrefix = "android.hardware."; 625345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber CHECK_EQ(fqName.package().find(kPrefix), 0u); 635345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber 645345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber const std::string packageSuffix = fqName.package().substr(strlen(kPrefix)); 655345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber 665345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber std::string packagePath = 675345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber "/Volumes/Source/nyc-mr1-dev-lego/hardware/interfaces/"; 685345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber 695345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber size_t startPos = 0; 705345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber size_t dotPos; 715345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber while ((dotPos = packageSuffix.find('.', startPos)) != std::string::npos) { 725345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber packagePath.append(packageSuffix.substr(startPos, dotPos - startPos)); 735345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber packagePath.append("/"); 745345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber 755345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber startPos = dotPos + 1; 765345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber } 775345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber CHECK_LT(startPos + 1, packageSuffix.length()); 785345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber packagePath.append(packageSuffix.substr(startPos)); 795345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber packagePath.append("/"); 805345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber 815345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber CHECK_EQ(fqName.version().find('@'), 0u); 825345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber packagePath.append(fqName.version().substr(1)); 835345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber packagePath.append("/"); 845345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber 855345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber return packagePath; 865345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber} 875345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber 885345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas HuberType *Coordinator::lookupType(const FQName &fqName) const { 895345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber // Fully qualified. 9068f24590cda230fb92eac44ed0247f54f9b31ad0Andreas Huber CHECK(fqName.isFullyQualified()); 915345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber 925345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber std::string topType; 935345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber size_t dotPos = fqName.name().find('.'); 945345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber if (dotPos == std::string::npos) { 955345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber topType = fqName.name(); 965345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber } else { 975345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber topType = fqName.name().substr(0, dotPos); 985345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber } 995345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber 10068f24590cda230fb92eac44ed0247f54f9b31ad0Andreas Huber // Assuming {topType} is the name of an interface type, let's see if the 10168f24590cda230fb92eac44ed0247f54f9b31ad0Andreas Huber // associated {topType}.hal file was imported. 10268f24590cda230fb92eac44ed0247f54f9b31ad0Andreas Huber FQName ifaceName(fqName.package(), fqName.version(), topType); 10368f24590cda230fb92eac44ed0247f54f9b31ad0Andreas Huber ssize_t index = mCache.indexOfKey(ifaceName); 1045345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber if (index >= 0) { 1055345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber AST *ast = mCache.valueAt(index); 1065345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber Type *type = ast->lookupTypeInternal(fqName.name()); 1075345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber 1085345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber if (type != NULL) { 10968f24590cda230fb92eac44ed0247f54f9b31ad0Andreas Huber return new RefType(fqName.string().c_str(), type); 1105345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber } 1115345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber } 1125345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber 11368f24590cda230fb92eac44ed0247f54f9b31ad0Andreas Huber FQName typesName(fqName.package(), fqName.version(), "types"); 11468f24590cda230fb92eac44ed0247f54f9b31ad0Andreas Huber index = mCache.indexOfKey(typesName); 1155345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber if (index >= 0) { 1165345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber AST *ast = mCache.valueAt(index); 1175345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber Type *type = ast->lookupTypeInternal(fqName.name()); 1185345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber 1195345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber if (type != NULL) { 12068f24590cda230fb92eac44ed0247f54f9b31ad0Andreas Huber return new RefType(fqName.string().c_str(), type); 1215345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber } 1225345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber } 1235345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber 1245345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber return NULL; 1255345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber} 1265345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber 1275345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber} // namespace android 1285345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber 129