Esempio n. 1
0
//throw on error
static ResolutionResult checkImport(const PackageManager& pm, const ParseResultPtr& pr, const std::string& pkgName, const CustomTypeExprNode* tnode, const std::string& type)
{
    PackagePtr pkg = pm.package(pkgName);
    NodePtr node = pkg->getExport(type);
    TypeKind kind;
    if (node) {
        switch (node->type()) {
        case NodeType_InterfaceDecl:
            kind = TypeKind_Interface;
            break;
        case NodeType_EnumDecl:
            kind = TypeKind_Enum;
            break;
        case NodeType_StructDecl:
            kind = TypeKind_Struct;
            break;
        default:
            pr->addDiag(Diagnostic(DiagnosticType_Error, "'" + type + "' in package '" + pkgName + "' is not a type", tnode->loc()));
            throw std::runtime_error("Not a type");
            break;
        }
        return ResolutionResult(pkgName, type, kind);
    }
    pr->addDiag(Diagnostic(DiagnosticType_Error, "Can't find '" + type + "' in package '" + pkgName + "'", tnode->loc()));
    throw std::runtime_error("Can't find import");
}
Esempio n. 2
0
 //public interface
 ParseResultPtr parse(const FileReaderPtr& file) {
   ParseResultPtr ret = newParseResult();
   ret->filename = file->filename();
   if (!file->isOpen()) {
     ret->addDiag(Diagnostic(DiagnosticType_Error, "Can't open file '" + file->filename() + "'"));
     return ret;
   }
   Parser p(file);
   return p.result();
 }
Esempio n. 3
0
/** 1 / Check for missing or multiple package declaration
 *  2 / Check that the directory path and package name match
 *  3 / register the content of the file to the package
 */
bool PackageManager::addFileToPackage(const std::string& absfile, const FileReaderPtr& file, ParseResultPtr& pr) {

    // 1
    NodePtrVector result;
    result = findNode(pr->ast, NodeType_Package);
    if (result.size() == 0) {
        pr->addDiag(Diagnostic(DiagnosticType_Error, "missing package declaration", Location(file->filename())));
        return false;
    }
    if (result.size() > 1) {
        for (unsigned i = 1; i < result.size(); ++i) {
            pr->addDiag(Diagnostic(DiagnosticType_Error, "extra package declaration", result.at(i)->loc()));

        }
        pr->addDiag(Diagnostic(DiagnosticType_Info, "previous declared here", result.at(0)->loc()));
        return false;
    }
    std::string pkgname = extractPackageName(result.at(0));
    // 2
    qi::Path pf(file->filename());
    StringVector leafs = splitPkgName(pkgname);


    qi::Path dirname;
    qi::Path cur = pf.parent().absolute();
    for (unsigned i = 0; i < leafs.size(); ++i)
    {
        dirname = qi::Path(cur.filename()) / dirname;
        cur = cur.parent();
        if (cur.isEmpty())
            break;
    }

    qi::Path p = pf.parent().absolute();
    for (int i = leafs.size() - 1; i >= 0; --i) {
        std::string par = p.filename();
        if (par != leafs.at(i)) {
            pr->addDiag(Diagnostic(DiagnosticType_Error,
                                   "package name '" + pkgname + "' do not match parent directory name '" + (std::string)dirname + "'",
                                   result.at(0)->loc()));
            return false;
        }
        p = p.parent();
    }

    std::string pkgpath = p.absolute().str();

    addInclude(pkgpath);
    addPackage(pkgname);
    pr->package = pkgname;
    package(pkgname)->setContent(absfile, pr);
    return true;
}
Esempio n. 4
0
//throw on error
ResolutionResult PackageManager::resolveImport(const ParseResultPtr& pr, const PackagePtr& pkg, const CustomTypeExprNode* tnode)
{
    const std::string type = tnode->value;
    qiLogVerbose() << "Resolving: " << type << " from package: " << pkg->_name;
    const auto lastDot = type.find_last_of('.');
    const std::string pkgName = (lastDot == std::string::npos) ? "" : type.substr(0, lastDot);
    const auto valueBegins = pkgName.empty() ? 0 : (pkgName.size() + 1);
    std::string value = type.substr(valueBegins);

    //package name provided
    if (!pkgName.empty() && pkgName != type)
        return checkImport(*this, pr, pkgName, tnode, value);
    value = type;

    //no package name. find the package name
    NodePtr exportnode = pkg->getExport(type);
    if (exportnode)
        return checkImport(*this, pr, pkg->_name, tnode, type);

    ASTMap::const_iterator it;
    for (it = pkg->_imports.begin(); it != pkg->_imports.end(); ++it) {
        const NodePtrVector& v = it->second;
        for (unsigned i = 0; i < v.size(); ++i) {
            ImportNode* inode = static_cast<ImportNode*>(v.at(i).get());
            switch (inode->importType) {
            case ImportType_All: {
                return checkImport(*this, pr, inode->name, tnode, type);
            }
            case ImportType_List: {
                StringVector::iterator it = std::find(inode->imports.begin(), inode->imports.end(), type);
                if (it != inode->imports.end()) {
                    return checkImport(*this, pr, inode->name, tnode, type);
                }
                break;
            }
            case ImportType_Package:
                break;
            }
        }
    }
    pr->addDiag(Diagnostic(DiagnosticType_Error, "cant resolve id '" + type + "' from package '" + pkg->_name + "'", tnode->loc()));
    throw std::runtime_error("cant resolve id");
}