//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"); }
//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"); }