/tools/qdoc3/qmlcodeparser.cpp

https://bitbucket.org/ultra_iter/qt-vtl · C++ · 235 lines · 134 code · 37 blank · 64 comment · 17 complexity · 92baf69d170f2a8a69721021ab2c1afe MD5 · raw file

  1. /****************************************************************************
  2. **
  3. ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
  4. ** All rights reserved.
  5. ** Contact: Nokia Corporation (qt-info@nokia.com)
  6. **
  7. ** This file is part of the tools applications of the Qt Toolkit.
  8. **
  9. ** $QT_BEGIN_LICENSE:LGPL$
  10. ** GNU Lesser General Public License Usage
  11. ** This file may be used under the terms of the GNU Lesser General Public
  12. ** License version 2.1 as published by the Free Software Foundation and
  13. ** appearing in the file LICENSE.LGPL included in the packaging of this
  14. ** file. Please review the following information to ensure the GNU Lesser
  15. ** General Public License version 2.1 requirements will be met:
  16. ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
  17. **
  18. ** In addition, as a special exception, Nokia gives you certain additional
  19. ** rights. These rights are described in the Nokia Qt LGPL Exception
  20. ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
  21. **
  22. ** GNU General Public License Usage
  23. ** Alternatively, this file may be used under the terms of the GNU General
  24. ** Public License version 3.0 as published by the Free Software Foundation
  25. ** and appearing in the file LICENSE.GPL included in the packaging of this
  26. ** file. Please review the following information to ensure the GNU General
  27. ** Public License version 3.0 requirements will be met:
  28. ** http://www.gnu.org/copyleft/gpl.html.
  29. **
  30. ** Other Usage
  31. ** Alternatively, this file may be used in accordance with the terms and
  32. ** conditions contained in a signed written agreement between you and Nokia.
  33. **
  34. **
  35. **
  36. **
  37. **
  38. ** $QT_END_LICENSE$
  39. **
  40. ****************************************************************************/
  41. /*
  42. qmlcodeparser.cpp
  43. */
  44. #include "declarativeparser/qdeclarativejsast_p.h"
  45. #include "declarativeparser/qdeclarativejsastvisitor_p.h"
  46. #include "declarativeparser/qdeclarativejsnodepool_p.h"
  47. #include "qmlcodeparser.h"
  48. #include "node.h"
  49. #include "tree.h"
  50. #include "config.h"
  51. #include "qmlvisitor.h"
  52. QT_BEGIN_NAMESPACE
  53. #define COMMAND_STARTPAGE Doc::alias("startpage")
  54. #define COMMAND_VARIABLE Doc::alias("variable")
  55. #define COMMAND_QMLCLASS Doc::alias("qmlclass")
  56. #define COMMAND_QMLPROPERTY Doc::alias("qmlproperty")
  57. #define COMMAND_QMLATTACHEDPROPERTY Doc::alias("qmlattachedproperty")
  58. #define COMMAND_QMLINHERITS Doc::alias("inherits")
  59. #define COMMAND_QMLSIGNAL Doc::alias("qmlsignal")
  60. #define COMMAND_QMLATTACHEDSIGNAL Doc::alias("qmlattachedsignal")
  61. #define COMMAND_QMLMETHOD Doc::alias("qmlmethod")
  62. #define COMMAND_QMLATTACHEDMETHOD Doc::alias("qmlattachedmethod")
  63. #define COMMAND_QMLDEFAULT Doc::alias("default")
  64. #define COMMAND_QMLBASICTYPE Doc::alias("qmlbasictype")
  65. QmlCodeParser::QmlCodeParser()
  66. {
  67. }
  68. QmlCodeParser::~QmlCodeParser()
  69. {
  70. }
  71. /*!
  72. Initialize the code parser base class.
  73. */
  74. void QmlCodeParser::initializeParser(const Config &config)
  75. {
  76. CodeParser::initializeParser(config);
  77. lexer = new QDeclarativeJS::Lexer(&engine);
  78. parser = new QDeclarativeJS::Parser(&engine);
  79. }
  80. void QmlCodeParser::terminateParser()
  81. {
  82. delete lexer;
  83. delete parser;
  84. }
  85. QString QmlCodeParser::language()
  86. {
  87. return "QML";
  88. }
  89. QStringList QmlCodeParser::sourceFileNameFilter()
  90. {
  91. return QStringList("*.qml");
  92. }
  93. void QmlCodeParser::parseSourceFile(const Location& location,
  94. const QString& filePath,
  95. Tree *tree)
  96. {
  97. QFile in(filePath);
  98. if (!in.open(QIODevice::ReadOnly)) {
  99. location.error(tr("Cannot open QML file '%1'").arg(filePath));
  100. return;
  101. }
  102. QString document = in.readAll();
  103. in.close();
  104. Location fileLocation(filePath);
  105. QString newCode = document;
  106. extractPragmas(newCode);
  107. lexer->setCode(newCode, 1);
  108. QSet<QString> topicCommandsAllowed = topicCommands();
  109. QSet<QString> otherMetacommandsAllowed = otherMetaCommands();
  110. QSet<QString> metacommandsAllowed = topicCommandsAllowed +
  111. otherMetacommandsAllowed;
  112. QDeclarativeJS::NodePool m_nodePool(filePath, &engine);
  113. if (parser->parse()) {
  114. QDeclarativeJS::AST::UiProgram *ast = parser->ast();
  115. QmlDocVisitor visitor(filePath, newCode, &engine, tree, metacommandsAllowed);
  116. QDeclarativeJS::AST::Node::accept(ast, &visitor);
  117. }
  118. }
  119. void QmlCodeParser::doneParsingSourceFiles(Tree *tree)
  120. {
  121. }
  122. /*!
  123. Returns the set of strings representing the topic commands.
  124. */
  125. QSet<QString> QmlCodeParser::topicCommands()
  126. {
  127. return QSet<QString>() << COMMAND_VARIABLE
  128. << COMMAND_QMLCLASS
  129. << COMMAND_QMLPROPERTY
  130. << COMMAND_QMLATTACHEDPROPERTY
  131. << COMMAND_QMLSIGNAL
  132. << COMMAND_QMLATTACHEDSIGNAL
  133. << COMMAND_QMLMETHOD
  134. << COMMAND_QMLATTACHEDMETHOD
  135. << COMMAND_QMLBASICTYPE;
  136. }
  137. /*!
  138. Returns the set of strings representing the common metacommands
  139. plus some other metacommands.
  140. */
  141. QSet<QString> QmlCodeParser::otherMetaCommands()
  142. {
  143. return commonMetaCommands() << COMMAND_STARTPAGE
  144. << COMMAND_QMLINHERITS
  145. << COMMAND_QMLDEFAULT;
  146. }
  147. /*
  148. Copied and pasted from src/declarative/qml/qdeclarativescriptparser.cpp.
  149. */
  150. static void replaceWithSpace(QString &str, int idx, int n)
  151. {
  152. QChar *data = str.data() + idx;
  153. const QChar space(QLatin1Char(' '));
  154. for (int ii = 0; ii < n; ++ii)
  155. *data++ = space;
  156. }
  157. /*
  158. Copied and pasted from src/declarative/qml/qdeclarativescriptparser.cpp then
  159. modified to return no values.
  160. Searches for ".pragma <value>" declarations within \a script. Currently supported pragmas
  161. are:
  162. library
  163. */
  164. void QmlCodeParser::extractPragmas(QString &script)
  165. {
  166. const QString pragma(QLatin1String("pragma"));
  167. const QString library(QLatin1String("library"));
  168. QDeclarativeJS::Lexer l(0);
  169. l.setCode(script, 0);
  170. int token = l.lex();
  171. while (true) {
  172. if (token != QDeclarativeJSGrammar::T_DOT)
  173. return;
  174. int startOffset = l.tokenOffset();
  175. int startLine = l.currentLineNo();
  176. token = l.lex();
  177. if (token != QDeclarativeJSGrammar::T_IDENTIFIER ||
  178. l.currentLineNo() != startLine ||
  179. script.mid(l.tokenOffset(), l.tokenLength()) != pragma)
  180. return;
  181. token = l.lex();
  182. if (token != QDeclarativeJSGrammar::T_IDENTIFIER ||
  183. l.currentLineNo() != startLine)
  184. return;
  185. QString pragmaValue = script.mid(l.tokenOffset(), l.tokenLength());
  186. int endOffset = l.tokenLength() + l.tokenOffset();
  187. token = l.lex();
  188. if (l.currentLineNo() == startLine)
  189. return;
  190. if (pragmaValue == QLatin1String("library"))
  191. replaceWithSpace(script, startOffset, endOffset - startOffset);
  192. else
  193. return;
  194. }
  195. return;
  196. }
  197. QT_END_NAMESPACE