void QmlCodeParser::parseSourceFile(const Location& location, const QString& filePath, Tree *tree) { QFile in(filePath); if (!in.open(QIODevice::ReadOnly)) { location.error(tr("Cannot open QML file '%1'").arg(filePath)); return; } QString document = in.readAll(); in.close(); Location fileLocation(filePath); QString newCode = document; extractPragmas(newCode); lexer->setCode(newCode, 1); QSet<QString> topicCommandsAllowed = topicCommands(); QSet<QString> otherMetacommandsAllowed = otherMetaCommands(); QSet<QString> metacommandsAllowed = topicCommandsAllowed + otherMetacommandsAllowed; QDeclarativeJS::NodePool m_nodePool(filePath, &engine); if (parser->parse()) { QDeclarativeJS::AST::UiProgram *ast = parser->ast(); QmlDocVisitor visitor(filePath, newCode, &engine, tree, metacommandsAllowed); QDeclarativeJS::AST::Node::accept(ast, &visitor); } }
/*! This is called by parseSourceFile() to do the actual parsing and tree building. It only processes qdoc comments. It skips everything else. */ bool PureDocParser::processQdocComments() { QSet<QString> topicCommandsAllowed = topicCommands(); QSet<QString> otherMetacommandsAllowed = otherMetaCommands(); QSet<QString> metacommandsAllowed = topicCommandsAllowed + otherMetacommandsAllowed; while (tok != Tok_Eoi) { if (tok == Tok_Doc) { /* lexeme() returns an entire qdoc comment. */ QString comment = lexeme(); Location start_loc(location()); readToken(); Doc::trimCStyleComment(start_loc,comment); Location end_loc(location()); /* Doc parses the comment. */ Doc doc(start_loc,end_loc,comment,metacommandsAllowed); QString topic; ArgList args; QSet<QString> topicCommandsUsed = topicCommandsAllowed & doc.metaCommandsUsed(); /* There should be one topic command in the set, or none. If the set is empty, then the comment should be a function description. */ if (topicCommandsUsed.count() > 0) { topic = *topicCommandsUsed.begin(); args = doc.metaCommandArgs(topic); } NodeList nodes; QList<Doc> docs; if (topic.isEmpty()) { doc.location().warning(tr("This qdoc comment contains no topic command " "(e.g., '\\%1', '\\%2').") .arg(COMMAND_MODULE).arg(COMMAND_PAGE)); } else { /* There is a topic command. Process it. */ if ((topic == COMMAND_QMLPROPERTY) || (topic == COMMAND_QMLATTACHEDPROPERTY)) { Doc nodeDoc = doc; Node* node = processTopicCommandGroup(nodeDoc,topic,args); if (node != 0) { nodes.append(node); docs.append(nodeDoc); } } else { ArgList::ConstIterator a = args.begin(); while (a != args.end()) { Doc nodeDoc = doc; Node* node = processTopicCommand(nodeDoc,topic,*a); if (node != 0) { nodes.append(node); docs.append(nodeDoc); } ++a; } } } Node* treeRoot = QDocDatabase::qdocDB()->treeRoot(); NodeList::Iterator n = nodes.begin(); QList<Doc>::Iterator d = docs.begin(); while (n != nodes.end()) { processOtherMetaCommands(*d, *n); (*n)->setDoc(*d); checkModuleInclusion(*n); if ((*n)->isInnerNode() && ((InnerNode *)*n)->includes().isEmpty()) { InnerNode *m = static_cast<InnerNode *>(*n); while (m->parent() && m->parent() != treeRoot) m = m->parent(); if (m == *n) ((InnerNode *)*n)->addInclude((*n)->name()); else ((InnerNode *)*n)->setIncludes(m->includes()); } ++d; ++n; } } else { readToken(); } } return true; }