void cb(const NodePtr& node) { if (!_cb) return; if (_parents.size()) _cb(_parents.back(), node); else _cb(NodePtr(), node); }
/** parse all dependents packages */ void PackageManager::resolvePackage(const std::string& packageName) { PackagePtr pkg = package(packageName); DiagnosticVector mv; ASTMap::iterator it; for (it = pkg->_imports.begin(); it != pkg->_imports.end(); ++it) { try { //throw on error? should.. parsePackage(it->first); } catch (const std::exception& e) { mv.push_back(Diagnostic(DiagnosticType_Error, "Can't find package '" + it->first + "'"));//, it->second->loc())); } } //for each imports verify each symbol are correct //for (it = pkg->_imports.begin(); it != pkg->_imports.end(); ++it) { //} //for each customtype expr resolve name //for each files in the package ParseResultMap::iterator it2; for (it2 = pkg->_contents.begin(); it2 != pkg->_contents.end(); ++it2) { NodePtrVector customs = findNode(it2->second->ast, NodeType_CustomTypeExpr); for (unsigned j = 0; j < customs.size(); ++j) { CustomTypeExprNode* tnode = static_cast<CustomTypeExprNode*>(customs.at(j).get()); ResolutionResult sp; try { sp = resolveImport(it2->second, pkg, tnode); } catch(const std::exception& e) { it2->second->addDiag(Diagnostic(DiagnosticType_Error, "Can't find id '" + tnode->value + "'", tnode->loc())); continue; } qiLogVerbose() << "resolved value '" << tnode->value << " to '" << sp.pkg << "." << sp.type << "'"; tnode->resolved_package = sp.pkg; tnode->resolved_value = sp.type; tnode->resolved_kind = sp.kind; } } }
/** 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; }
void popParent() { _parents.pop_back(); }
void pushParent(const NodePtr& p) { _parents.push_back(p); }
inline void findNodeKindVisitor(const NodePtr& parent, const NodePtr& node, NodeKind wanted, NodePtrVector& result) { if (node->kind() == wanted) result.push_back(node); }
inline void findNodeTypeVisitor(const NodePtr& parent, const NodePtr& node, NodeType wanted, NodePtrVector& result) { if (node->type() == wanted) result.push_back(node); }