From 9529188304b47d3fdb39cec52ad233f37a477f2f Mon Sep 17 00:00:00 2001 From: David Boddie Date: Wed, 24 Nov 2010 19:33:21 +0100 Subject: Refactored use of parsers to parse files based on their types. The full range of file types is specified in the configuration file. Each parser is asked if it handles each file. The pure documentation parser conceptually handles qdoc files, but it uses the same code as the C++ parser. --- tools/qdoc3/codeparser.cpp | 38 ++++++++- tools/qdoc3/codeparser.h | 6 +- tools/qdoc3/config.cpp | 6 +- tools/qdoc3/config.h | 1 - tools/qdoc3/cppcodeparser.cpp | 9 +- tools/qdoc3/cppcodeparser.h | 4 +- tools/qdoc3/main.cpp | 74 +++++++++------- tools/qdoc3/puredocparser.cpp | 63 ++++++++++++++ tools/qdoc3/puredocparser.h | 72 ++++++++++++++++ tools/qdoc3/qdoc3.pro | 11 +++ tools/qdoc3/qmlcodeparser.cpp | 168 +++++++++++++++++++++++++++++++++++++ tools/qdoc3/qmlcodeparser.h | 90 ++++++++++++++++++++ tools/qdoc3/qmlvisitor.cpp | 191 ++++++++++++++++++++++++++++++++++++++++++ tools/qdoc3/qmlvisitor.h | 83 ++++++++++++++++++ 14 files changed, 769 insertions(+), 47 deletions(-) create mode 100644 tools/qdoc3/puredocparser.cpp create mode 100644 tools/qdoc3/puredocparser.h create mode 100644 tools/qdoc3/qmlcodeparser.cpp create mode 100644 tools/qdoc3/qmlcodeparser.h create mode 100644 tools/qdoc3/qmlvisitor.cpp create mode 100644 tools/qdoc3/qmlvisitor.h diff --git a/tools/qdoc3/codeparser.cpp b/tools/qdoc3/codeparser.cpp index ed8b54e..3652758 100644 --- a/tools/qdoc3/codeparser.cpp +++ b/tools/qdoc3/codeparser.cpp @@ -105,7 +105,7 @@ void CodeParser::terminateParser() // nothing. } -QString CodeParser::headerFileNameFilter() +QStringList CodeParser::headerFileNameFilter() { return sourceFileNameFilter(); } @@ -158,6 +158,42 @@ CodeParser *CodeParser::parserForLanguage(const QString& language) return 0; } +CodeParser *CodeParser::parserForHeaderFile(const QString &filePath) +{ + QString fileName = QFileInfo(filePath).fileName(); + + QList::ConstIterator p = parsers.begin(); + while (p != parsers.end()) { + + QStringList headerPatterns = (*p)->headerFileNameFilter(); + foreach (QString pattern, headerPatterns) { + QRegExp re(pattern, Qt::CaseInsensitive, QRegExp::Wildcard); + if (re.exactMatch(fileName)) + return *p; + } + ++p; + } + return 0; +} + +CodeParser *CodeParser::parserForSourceFile(const QString &filePath) +{ + QString fileName = QFileInfo(filePath).fileName(); + + QList::ConstIterator p = parsers.begin(); + while (p != parsers.end()) { + + QStringList sourcePatterns = (*p)->sourceFileNameFilter(); + foreach (QString pattern, sourcePatterns) { + QRegExp re(pattern, Qt::CaseInsensitive, QRegExp::Wildcard); + if (re.exactMatch(fileName)) + return *p; + } + ++p; + } + return 0; +} + /*! Returns the set of strings representing the common metacommands. */ diff --git a/tools/qdoc3/codeparser.h b/tools/qdoc3/codeparser.h index ebba601..2d11ee0 100644 --- a/tools/qdoc3/codeparser.h +++ b/tools/qdoc3/codeparser.h @@ -66,8 +66,8 @@ class CodeParser virtual void initializeParser(const Config& config); virtual void terminateParser(); virtual QString language() = 0; - virtual QString headerFileNameFilter(); - virtual QString sourceFileNameFilter() = 0; + virtual QStringList headerFileNameFilter(); + virtual QStringList sourceFileNameFilter() = 0; virtual void parseHeaderFile(const Location& location, const QString& filePath, Tree *tree); virtual void parseSourceFile(const Location& location, @@ -78,6 +78,8 @@ class CodeParser static void initialize(const Config& config); static void terminate(); static CodeParser *parserForLanguage(const QString& language); + static CodeParser *parserForHeaderFile(const QString &filePath); + static CodeParser *parserForSourceFile(const QString &filePath); static const QString titleFromName(const QString& name); protected: diff --git a/tools/qdoc3/config.cpp b/tools/qdoc3/config.cpp index 0146a26..c2ab559 100644 --- a/tools/qdoc3/config.cpp +++ b/tools/qdoc3/config.cpp @@ -359,16 +359,12 @@ QSet Config::subVars(const QString& var) const */ QStringList Config::getAllFiles(const QString &filesVar, const QString &dirsVar, - const QString &defaultNameFilter, const QSet &excludedDirs) { QStringList result = getStringList(filesVar); QStringList dirs = getStringList(dirsVar); - QString nameFilter = getString(filesVar + dot + - QLatin1String(CONFIG_FILEEXTENSIONS)); - if (nameFilter.isEmpty()) - nameFilter = defaultNameFilter; + QString nameFilter = getString(filesVar + dot + QLatin1String(CONFIG_FILEEXTENSIONS)); QStringList::ConstIterator d = dirs.begin(); while (d != dirs.end()) { diff --git a/tools/qdoc3/config.h b/tools/qdoc3/config.h index f089a70..bc36f3d 100644 --- a/tools/qdoc3/config.h +++ b/tools/qdoc3/config.h @@ -76,7 +76,6 @@ class Config QSet subVars(const QString& var) const; QStringList getAllFiles(const QString& filesVar, const QString& dirsVar, - const QString& defaultNameFilter, const QSet &excludedDirs = QSet()); static QStringList getFilesHere(const QString& dir, diff --git a/tools/qdoc3/cppcodeparser.cpp b/tools/qdoc3/cppcodeparser.cpp index 8e891b8..fce2553 100644 --- a/tools/qdoc3/cppcodeparser.cpp +++ b/tools/qdoc3/cppcodeparser.cpp @@ -47,7 +47,6 @@ #include #include -#include #include "codechunk.h" #include "config.h" @@ -258,18 +257,18 @@ QString CppCodeParser::language() /*! Returns a list of extensions for header files. */ -QString CppCodeParser::headerFileNameFilter() +QStringList CppCodeParser::headerFileNameFilter() { - return "*.ch *.h *.h++ *.hh *.hpp *.hxx"; + return QStringList() << "*.ch" << "*.h" << "*.h++" << "*.hh" << "*.hpp" << "*.hxx"; } /*! Returns a list of extensions for source files, i.e. not header files. */ -QString CppCodeParser::sourceFileNameFilter() +QStringList CppCodeParser::sourceFileNameFilter() { - return "*.c++ *.cc *.cpp *.cxx"; + return QStringList() << "*.c++" << "*.cc" << "*.cpp" << "*.cxx" << "*.mm"; } /*! diff --git a/tools/qdoc3/cppcodeparser.h b/tools/qdoc3/cppcodeparser.h index 55d9ddf..64e9119 100644 --- a/tools/qdoc3/cppcodeparser.h +++ b/tools/qdoc3/cppcodeparser.h @@ -69,8 +69,8 @@ class CppCodeParser : public CodeParser virtual void initializeParser(const Config& config); virtual void terminateParser(); virtual QString language(); - virtual QString headerFileNameFilter(); - virtual QString sourceFileNameFilter(); + virtual QStringList headerFileNameFilter(); + virtual QStringList sourceFileNameFilter(); virtual void parseHeaderFile(const Location& location, const QString& filePath, Tree *tree); diff --git a/tools/qdoc3/main.cpp b/tools/qdoc3/main.cpp index 768c5eb..2d3f034 100644 --- a/tools/qdoc3/main.cpp +++ b/tools/qdoc3/main.cpp @@ -50,10 +50,12 @@ #include "config.h" #include "cppcodemarker.h" #include "cppcodeparser.h" +#include "ditaxmlgenerator.h" #include "doc.h" #include "htmlgenerator.h" #include "plaincodemarker.h" -#include "ditaxmlgenerator.h" +#include "puredocparser.h" +#include "qmlcodeparser.h" #include "tokenizer.h" #include "tree.h" #include @@ -235,14 +237,6 @@ static void processQdocconfFile(const QString &fileName) tree->setVersion(config.getString(CONFIG_VERSION)); /* - There must be a code parser for the source code language, e.g. C++. - If there isn't one, give up. - */ - CodeParser *codeParser = CodeParser::parserForLanguage(lang); - if (codeParser == 0) - config.lastLocation().fatal(tr("Cannot parse programming language '%1'").arg(lang)); - - /* By default, the only output format is HTML. */ QSet outputFormats = config.getStringSet(CONFIG_OUTPUTFORMATS); @@ -257,52 +251,69 @@ static void processQdocconfFile(const QString &fileName) langLocation.fatal(tr("Cannot output documentation for programming language '%1'").arg(lang)); /* - Read some XML indexes. What are they??? + Read some XML indexes containing definitions from other documentation sets. */ QStringList indexFiles = config.getStringList(CONFIG_INDEXES); tree->readIndexes(indexFiles); - + /* - Get all the header files: "*.ch *.h *.h++ *.hh *.hpp *.hxx" - Put them in a set. + Read the list of excluded directories. */ QSet excludedDirs; QStringList excludedDirsList = config.getStringList(CONFIG_EXCLUDEDIRS); foreach (const QString &excludeDir, excludedDirsList) excludedDirs.insert(QDir::fromNativeSeparators(excludeDir)); - QSet headers = QSet::fromList( - config.getAllFiles(CONFIG_HEADERS, CONFIG_HEADERDIRS, - codeParser->headerFileNameFilter(), - excludedDirs)); /* - Parse each header file in the set and add it to the big tree. + Get all the header files: "*.ch *.h *.h++ *.hh *.hpp *.hxx" + Put them in a set. */ - QSet::ConstIterator h = headers.begin(); - while (h != headers.end()) { - codeParser->parseHeaderFile(config.location(), *h, tree); - ++h; - } - codeParser->doneParsingHeaderFiles(tree); + QSet headers = QSet::fromList( + config.getAllFiles(CONFIG_HEADERS, CONFIG_HEADERDIRS, excludedDirs)); /* Get all the source text files: "*.cpp *.qdoc *.mm" Put them in a set. */ QSet sources = QSet::fromList( - config.getAllFiles(CONFIG_SOURCES, CONFIG_SOURCEDIRS, - codeParser->sourceFileNameFilter(), - excludedDirs)); + config.getAllFiles(CONFIG_SOURCES, CONFIG_SOURCEDIRS, excludedDirs)); + + /* + Parse each header file in the set using the appropriate parser and add it + to the big tree. + */ + QSet usedParsers; + + QSet::ConstIterator h = headers.begin(); + while (h != headers.end()) { + CodeParser *codeParser = CodeParser::parserForHeaderFile(*h); + if (codeParser) { + codeParser->parseHeaderFile(config.location(), *h, tree); + usedParsers.insert(codeParser); + } + ++h; + } + foreach (CodeParser *codeParser, usedParsers) + codeParser->doneParsingHeaderFiles(tree); + + usedParsers.clear(); /* - Parse each source text file in the set and add it to the big tree. + Parse each source text file in the set using the appropriate parser and + add it to the big tree. */ QSet::ConstIterator s = sources.begin(); while (s != sources.end()) { - codeParser->parseSourceFile(config.location(), *s, tree); + CodeParser *codeParser = CodeParser::parserForSourceFile(*s); + if (codeParser) { + codeParser->parseSourceFile(config.location(), *s, tree); + usedParsers.insert(codeParser); + } ++s; } - codeParser->doneParsingSourceFiles(tree); + + foreach (CodeParser *codeParser, usedParsers) + codeParser->doneParsingSourceFiles(tree); /* Now the big tree has been built from all the header and @@ -371,7 +382,8 @@ int main(int argc, char **argv) and create a tree for C++. */ CppCodeParser cppParser; - Tree *cppTree = treeForLanguage(cppParser.language()); + QmlCodeParser qmlParser; + PureDocParser docParser; /* Create code markers for plain text and C++. diff --git a/tools/qdoc3/puredocparser.cpp b/tools/qdoc3/puredocparser.cpp new file mode 100644 index 0000000..de7d668 --- /dev/null +++ b/tools/qdoc3/puredocparser.cpp @@ -0,0 +1,63 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the tools applications of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/* + puredocparser.cpp +*/ + +#include "puredocparser.h" + +QT_BEGIN_NAMESPACE + +PureDocParser::PureDocParser() +{ +} + +PureDocParser::~PureDocParser() +{ +} + +QStringList PureDocParser::sourceFileNameFilter() +{ + return QStringList("*.qdoc"); +} + +QT_END_NAMESPACE diff --git a/tools/qdoc3/puredocparser.h b/tools/qdoc3/puredocparser.h new file mode 100644 index 0000000..6e37dbd --- /dev/null +++ b/tools/qdoc3/puredocparser.h @@ -0,0 +1,72 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the tools applications of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/* + puredocparser.h +*/ + +#ifndef PUREDOCPARSER_H +#define PUREDOCPARSER_H + +#include + +#include "cppcodeparser.h" +#include "location.h" + +QT_BEGIN_NAMESPACE + +class Config; +class Node; +class QString; +class Tree; + +class PureDocParser : public CppCodeParser +{ +public: + PureDocParser(); + virtual ~PureDocParser(); + + virtual QStringList sourceFileNameFilter(); +}; + +QT_END_NAMESPACE + +#endif diff --git a/tools/qdoc3/qdoc3.pro b/tools/qdoc3/qdoc3.pro index c9b05d2..2c91a9c 100644 --- a/tools/qdoc3/qdoc3.pro +++ b/tools/qdoc3/qdoc3.pro @@ -42,6 +42,9 @@ HEADERS += atom.h \ openedlist.h \ pagegenerator.h \ plaincodemarker.h \ + puredocparser.h \ + qmlcodeparser.h \ + qmlvisitor.h \ quoter.h \ separator.h \ text.h \ @@ -67,6 +70,9 @@ SOURCES += atom.cpp \ openedlist.cpp \ pagegenerator.cpp \ plaincodemarker.cpp \ + puredocparser.cpp \ + qmlcodeparser.cpp \ + qmlvisitor.cpp \ quoter.cpp \ separator.cpp \ text.cpp \ @@ -74,6 +80,11 @@ SOURCES += atom.cpp \ tree.cpp \ yyindent.cpp +# Include the QML parsing library from Qt Creator. + +LIBS += -L$$(QTCREATOR_LIBPATH) -lQmlJS -lUtils +INCLUDEPATH += $$(QTCREATOR_INCPATH) + ### Documentation for qdoc3 ### qtPrepareTool(QDOC, qdoc3) diff --git a/tools/qdoc3/qmlcodeparser.cpp b/tools/qdoc3/qmlcodeparser.cpp new file mode 100644 index 0000000..c6ace7d --- /dev/null +++ b/tools/qdoc3/qmlcodeparser.cpp @@ -0,0 +1,168 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the tools applications of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/* + qmlcodeparser.cpp +*/ + +#include "parser/qmljsast_p.h" +#include "parser/qmljsastvisitor_p.h" +#include "parser/qmljsnodepool_p.h" + +#include "qmlcodeparser.h" +#include "node.h" +#include "tree.h" +#include "config.h" +#include "qmlvisitor.h" + +QT_BEGIN_NAMESPACE + +#define COMMAND_STARTPAGE Doc::alias("startpage") +#define COMMAND_VARIABLE Doc::alias("variable") + +#define COMMAND_QMLCLASS Doc::alias("qmlclass") +#define COMMAND_QMLPROPERTY Doc::alias("qmlproperty") +#define COMMAND_QMLATTACHEDPROPERTY Doc::alias("qmlattachedproperty") +#define COMMAND_QMLINHERITS Doc::alias("inherits") +#define COMMAND_QMLSIGNAL Doc::alias("qmlsignal") +#define COMMAND_QMLATTACHEDSIGNAL Doc::alias("qmlattachedsignal") +#define COMMAND_QMLMETHOD Doc::alias("qmlmethod") +#define COMMAND_QMLATTACHEDMETHOD Doc::alias("qmlattachedmethod") +#define COMMAND_QMLDEFAULT Doc::alias("default") +#define COMMAND_QMLBASICTYPE Doc::alias("qmlbasictype") + +QmlCodeParser::QmlCodeParser() +{ +} + +QmlCodeParser::~QmlCodeParser() +{ +} + +/*! + Initialize the code parser base class. + */ +void QmlCodeParser::initializeParser(const Config &config) +{ + CodeParser::initializeParser(config); + + lexer = new QmlJS::Lexer(&engine); + parser = new QmlJS::Parser(&engine); +} + +void QmlCodeParser::terminateParser() +{ + delete lexer; + delete parser; +} + +QString QmlCodeParser::language() +{ + return "QML"; +} + +QStringList QmlCodeParser::sourceFileNameFilter() +{ + return QStringList("*.qml"); +} + +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); + lexer->setCode(document, 1); + + QSet topicCommandsAllowed = topicCommands(); + QSet otherMetacommandsAllowed = otherMetaCommands(); + QSet metacommandsAllowed = topicCommandsAllowed + + otherMetacommandsAllowed; + + QmlJS::NodePool m_nodePool(filePath, &engine); + + if (parser->parse()) { + QmlJS::AST::UiProgram *ast = parser->ast(); + DocVisitor visitor(filePath, document, &engine, tree, metacommandsAllowed); + QmlJS::AST::Node::accept(ast, &visitor); + } +} + +void QmlCodeParser::doneParsingSourceFiles(Tree *tree) +{ +} + +/*! + Returns the set of strings reopresenting the topic commands. + */ +QSet QmlCodeParser::topicCommands() +{ + return QSet() << COMMAND_VARIABLE + << COMMAND_QMLCLASS + << COMMAND_QMLPROPERTY + << COMMAND_QMLATTACHEDPROPERTY + << COMMAND_QMLSIGNAL + << COMMAND_QMLATTACHEDSIGNAL + << COMMAND_QMLMETHOD + << COMMAND_QMLATTACHEDMETHOD + << COMMAND_QMLBASICTYPE; +} + +/*! + Returns the set of strings representing the common metacommands + plus some other metacommands. + */ +QSet QmlCodeParser::otherMetaCommands() +{ + return commonMetaCommands() << COMMAND_STARTPAGE + << COMMAND_QMLINHERITS + << COMMAND_QMLDEFAULT; +} + +QT_END_NAMESPACE diff --git a/tools/qdoc3/qmlcodeparser.h b/tools/qdoc3/qmlcodeparser.h new file mode 100644 index 0000000..f6d6684 --- /dev/null +++ b/tools/qdoc3/qmlcodeparser.h @@ -0,0 +1,90 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the tools applications of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/* + qmlcodeparser.h +*/ + +#ifndef QMLCODEPARSER_H +#define QMLCODEPARSER_H + +#include +#include "parser/qmljsengine_p.h" +#include "parser/qmljslexer_p.h" +#include "parser/qmljsparser_p.h" + +#include "codeparser.h" +#include "location.h" + +QT_BEGIN_NAMESPACE + +class Config; +class Node; +class QString; +class Tree; + +class QmlCodeParser : public CodeParser +{ +public: + QmlCodeParser(); + virtual ~QmlCodeParser(); + + virtual void initializeParser(const Config& config); + virtual void terminateParser(); + virtual QString language(); + virtual QStringList sourceFileNameFilter(); + virtual void parseSourceFile(const Location& location, + const QString& filePath, Tree *tree); + virtual void doneParsingSourceFiles(Tree *tree); + +protected: + virtual QSet topicCommands(); + virtual QSet otherMetaCommands(); + +private: + QmlJS::Engine engine; + QmlJS::Lexer *lexer; + QmlJS::Parser *parser; +}; + +QT_END_NAMESPACE + +#endif diff --git a/tools/qdoc3/qmlvisitor.cpp b/tools/qdoc3/qmlvisitor.cpp new file mode 100644 index 0000000..83bf96f --- /dev/null +++ b/tools/qdoc3/qmlvisitor.cpp @@ -0,0 +1,191 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the tools applications of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#include +#include +#include "parser/qmljsast_p.h" +#include "parser/qmljsastfwd_p.h" +#include "parser/qmljsengine_p.h" + +#include "node.h" +#include "qmlvisitor.h" + +DocVisitor::DocVisitor(const QString &filePath, const QString &code, + QmlJS::Engine *engine, Tree *tree, QSet &commands) +{ + this->filePath = filePath; + this->name = QFileInfo(filePath).baseName(); + document = code; + this->engine = engine; + this->tree = tree; + this->commands = commands; + current = tree->root(); +} + +DocVisitor::~DocVisitor() +{ +} + +QmlJS::AST::SourceLocation DocVisitor::precedingComment(unsigned offset) const +{ + QmlJS::AST::SourceLocation currentLoc; + + foreach (const QmlJS::AST::SourceLocation &loc, engine->comments()) { + if (loc.begin() > lastEndOffset && loc.end() < offset) + currentLoc = loc; + else + break; + } + if (currentLoc.isValid()) { + QString comment = document.mid(currentLoc.offset, currentLoc.length); + if (comment.startsWith("!") || comment.startsWith("*")) + return currentLoc; + } + + return QmlJS::AST::SourceLocation(); +} + +void DocVisitor::applyDocumentation(QmlJS::AST::SourceLocation location, + InnerNode *node) +{ + QmlJS::AST::SourceLocation loc = precedingComment(location.begin()); + + if (loc.isValid()) { + QString source = document.mid(loc.offset, loc.length); + if (source.startsWith(QLatin1String("!")) || + source.startsWith(QLatin1String("*"))) { + + Location start(filePath); + start.setLineNo(loc.startLine); + start.setColumnNo(loc.startColumn); + Location finish(filePath); + finish.setLineNo(loc.startLine); + finish.setColumnNo(loc.startColumn); + + Doc doc(start, finish, source.mid(1), commands); + node->setDoc(doc); + } + } +} + +/*! + Visits element definitions, recording them in a tree structure. +*/ +bool DocVisitor::visit(QmlJS::AST::UiObjectDefinition *definition) +{ + QString type = definition->qualifiedTypeNameId->name->asString(); + + if (current->type() == Node::Namespace) { + QmlClassNode *component = new QmlClassNode(current, name, 0); + applyDocumentation(definition->firstSourceLocation(), component); + current = component; + } + + return true; +} + +void DocVisitor::endVisit(QmlJS::AST::UiObjectDefinition *definition) +{ + lastEndOffset = definition->lastSourceLocation().end(); +} + +bool DocVisitor::visit(QmlJS::AST::UiImportList *imports) +{ + // Note that the imports list can be traversed by iteration to obtain + // all the imports in the document at once, having found just one: + // *it = imports; it; it = it->next + + QString module = document.mid(imports->import->fileNameToken.offset, + imports->import->fileNameToken.length); + QString version = document.mid(imports->import->versionToken.offset, + imports->import->versionToken.length); + importList.append(QPair(module, version)); + + return true; +} + +/*! + Visits public member declarations, such as signals and properties. + These only include custom signals and properties. +*/ +bool DocVisitor::visit(QmlJS::AST::UiPublicMember *member) +{ + switch (member->type) { + case QmlJS::AST::UiPublicMember::Signal: + { + QString name = member->name->asString(); + + QList > parameters; + for (QmlJS::AST::UiParameterList *it = member->parameters; it; it = it->next) { + if (it->type && it->name) + parameters.append(QPair(it->type->asString(), + it->name->asString())); + } + + //current->addSignal(new Signal(name, parameters)); + break; + } + case QmlJS::AST::UiPublicMember::Property: + { + QString type = member->memberType->asString(); + QString name = member->name->asString(); + + //current->addProperty(new Property(type, name)); + break; + } + default: + return false; + } + + //current->doc = precedingComment(member->firstSourceLocation().begin()); + return true; +} + +void DocVisitor::endVisit(QmlJS::AST::UiPublicMember *definition) +{ + lastEndOffset = definition->lastSourceLocation().end(); +} + +bool DocVisitor::visit(QmlJS::AST::IdentifierPropertyName *idproperty) +{ + return true; +} diff --git a/tools/qdoc3/qmlvisitor.h b/tools/qdoc3/qmlvisitor.h new file mode 100644 index 0000000..01da98e --- /dev/null +++ b/tools/qdoc3/qmlvisitor.h @@ -0,0 +1,83 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the tools applications of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef DOCVISITOR_H +#define DOCVISITOR_H + +#include +#include "parser/qmljsastvisitor_p.h" +#include "node.h" +#include "tree.h" + +class DocVisitor : public QmlJS::AST::Visitor +{ +public: + DocVisitor(const QString &filePath, const QString &code, + QmlJS::Engine *engine, Tree *tree, QSet &commands); + virtual ~DocVisitor(); + + bool visit(QmlJS::AST::UiImportList *imports); + + bool visit(QmlJS::AST::UiObjectDefinition *definition); + void endVisit(QmlJS::AST::UiObjectDefinition *definition); + + bool visit(QmlJS::AST::UiPublicMember *member); + void endVisit(QmlJS::AST::UiPublicMember *definition); + + bool visit(QmlJS::AST::IdentifierPropertyName *idproperty); + +private: + QmlJS::AST::SourceLocation precedingComment(unsigned offset) const; + void applyDocumentation(QmlJS::AST::SourceLocation location, + InnerNode *node); + + QmlJS::Engine *engine; + quint32 lastEndOffset; + QString filePath; + QString name; + QString document; + QList > importList; + QSet commands; + Tree *tree; + InnerNode *current; +}; + +#endif -- cgit v0.12