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