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); } }
void QsCodeParser::setQuickDoc(Node *quickNode, const Doc& doc, const QStringList& qtParams, const QStringList& quickParams) { QRegExp quickifyCommand("\\\\" + COMMAND_QUICKIFY + "([^\n]*)(?:\n|$)"); if (quickNode->type() == Node::Function) { FunctionNode *quickFunc = (FunctionNode *) quickNode; quickFunc->setOverload(false); } if (doc.metaCommandsUsed().contains(COMMAND_QUICKIFY)) { QString source = doc.source(); int pos = source.indexOf(quickifyCommand); if (pos != -1) { QString quickifiedSource = quickNode->doc().source(); if (!qtParams.isEmpty() && qtParams != quickParams) renameParameters(quickifiedSource, doc, qtParams, quickParams); applyReplacementList(quickifiedSource, doc); do { QString extract = quickifiedSource; QString arg = quickifyCommand.cap(1).simplified(); if (!arg.isEmpty()) { if (arg.startsWith("/") && arg.endsWith("/") && arg.length() > 2) { QString pattern = arg.mid(1, arg.length() - 2); extractRegExp(QRegExp(pattern), extract, doc); } else { extractTarget(arg, extract, doc); } } source.replace(pos, quickifyCommand.matchedLength(), extract); pos += extract.length(); } while ((pos = source.indexOf(quickifyCommand, pos)) != -1); QRegExp quickcodeRegExp( "\\\\" + COMMAND_QUICKCODE + "(.*)\\\\" + COMMAND_ENDQUICKCODE); quickcodeRegExp.setMinimal(true); source.replace(quickcodeRegExp, ""); } Doc quickDoc(doc.location(), doc.location(), source, (CppCodeParser::topicCommands() + topicCommands() + CppCodeParser::otherMetaCommands()) << COMMAND_REPLACE); quickNode->setDoc(quickDoc, true); processOtherMetaCommands(quickDoc, quickNode); } else { quickNode->setDoc(doc, true); processOtherMetaCommands(doc, quickNode); } }
/*! 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; }