summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon Hausmann <simon.hausmann@theqtcompany.com>2016-04-06 12:42:27 +0200
committerSimon Hausmann <simon.hausmann@theqtcompany.com>2016-04-06 12:42:51 +0200
commit887f86794c24c6e80cf49a2687b669d7530a1944 (patch)
tree9d08458d66b9621faf2d877879b5e3aa8faa30af
parent790f59646d80e3b05d03aa8d3e2d9cc52eef68b9 (diff)
parentcf9129f19fb180d24f217897cc660ea7c6861e87 (diff)
downloadqttools-887f86794c24c6e80cf49a2687b669d7530a1944.tar.gz
Merge remote-tracking branch 'origin/5.6' into 5.7
Change-Id: I06a1d65d1bcb0cdb0ae6e00e57283333aafbb673
-rw-r--r--src/assistant/assistant/images/darkclosebutton.pngbin319 -> 170 bytes
-rw-r--r--src/assistant/assistant/stdinlistener.cpp2
-rw-r--r--src/assistant/help/qhelpprojectdata.cpp8
-rw-r--r--src/assistant/help/qhelpsearchindexreader_clucene.cpp4
-rw-r--r--src/assistant/help/qhelpsearchquerywidget.cpp4
-rw-r--r--src/designer/src/components/formeditor/formwindowmanager.cpp29
-rw-r--r--src/designer/src/components/formeditor/images/cleartext.pngbin760 -> 474 bytes
-rw-r--r--src/designer/src/components/formeditor/images/mac/simplifyrichtext.pngbin1988 -> 1917 bytes
-rw-r--r--src/designer/src/components/formeditor/images/righttoleft.pngbin197 -> 131 bytes
-rw-r--r--src/linguist/lupdate/cpp.cpp3
-rw-r--r--src/qdoc/cppcodemarker.cpp18
-rw-r--r--src/qdoc/cppcodeparser.cpp42
-rw-r--r--src/qdoc/cppcodeparser.h3
-rw-r--r--src/qdoc/doc/qdoc-manual-markupcmds.qdoc2
-rw-r--r--src/qdoc/generator.cpp246
-rw-r--r--src/qdoc/generator.h2
-rw-r--r--src/qdoc/htmlgenerator.cpp12
-rw-r--r--src/qdoc/jscodemarker.cpp11
-rw-r--r--src/qdoc/node.h2
-rw-r--r--src/qdoc/qdoc.pro7
-rw-r--r--src/qdoc/qmlcodemarker.cpp13
-rw-r--r--src/qdoc/qmlcodemarker.h4
-rw-r--r--src/qdoc/qmlcodeparser.cpp14
-rw-r--r--src/qdoc/qmlcodeparser.h6
-rw-r--r--src/qdoc/qmlmarkupvisitor.cpp4
-rw-r--r--src/qdoc/qmlmarkupvisitor.h4
-rw-r--r--src/qdoc/qmlvisitor.cpp4
-rw-r--r--src/qdoc/qmlvisitor.h4
-rw-r--r--src/windeployqt/utils.cpp2
-rw-r--r--src/windeployqt/windeployqt.pro2
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/parsecpp/main.cpp19
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/parsecpp/project.ts.result27
32 files changed, 346 insertions, 152 deletions
diff --git a/src/assistant/assistant/images/darkclosebutton.png b/src/assistant/assistant/images/darkclosebutton.png
index 1077663b2..147a954be 100644
--- a/src/assistant/assistant/images/darkclosebutton.png
+++ b/src/assistant/assistant/images/darkclosebutton.png
Binary files differ
diff --git a/src/assistant/assistant/stdinlistener.cpp b/src/assistant/assistant/stdinlistener.cpp
index 13059c207..0a4241bce 100644
--- a/src/assistant/assistant/stdinlistener.cpp
+++ b/src/assistant/assistant/stdinlistener.cpp
@@ -35,6 +35,8 @@
#include "tracer.h"
+#include <stdio.h>
+
QT_BEGIN_NAMESPACE
StdInListener::StdInListener(QObject *parent)
diff --git a/src/assistant/help/qhelpprojectdata.cpp b/src/assistant/help/qhelpprojectdata.cpp
index f48fdea9b..fa084ff3c 100644
--- a/src/assistant/help/qhelpprojectdata.cpp
+++ b/src/assistant/help/qhelpprojectdata.cpp
@@ -275,13 +275,13 @@ void QHelpProjectDataPrivate::addMatchingFiles(const QString &pattern)
{
// The pattern matching is expensive, so we skip it if no
// wildcard symbols occur in the string.
- if (!pattern.contains('?') && !pattern.contains('*')
- && !pattern.contains('[') && !pattern.contains(']')) {
+ if (!pattern.contains(QLatin1Char('?')) && !pattern.contains(QLatin1Char('*'))
+ && !pattern.contains(QLatin1Char('[')) && !pattern.contains(QLatin1Char(']'))) {
filterSectionList.last().addFile(pattern);
return;
}
- QFileInfo fileInfo(rootPath + '/' + pattern);
+ QFileInfo fileInfo(rootPath + QLatin1Char('/') + pattern);
const QDir &dir = fileInfo.dir();
const QString &path = dir.canonicalPath();
@@ -303,7 +303,7 @@ void QHelpProjectDataPrivate::addMatchingFiles(const QString &pattern)
if (regExp.exactMatch(file)) {
matchFound = true;
filterSectionList.last().
- addFile(QFileInfo(pattern).dir().path() + '/' + file);
+ addFile(QFileInfo(pattern).dir().path() + QLatin1Char('/') + file);
}
}
if (!matchFound)
diff --git a/src/assistant/help/qhelpsearchindexreader_clucene.cpp b/src/assistant/help/qhelpsearchindexreader_clucene.cpp
index 18b128b01..a63128a88 100644
--- a/src/assistant/help/qhelpsearchindexreader_clucene.cpp
+++ b/src/assistant/help/qhelpsearchindexreader_clucene.cpp
@@ -270,8 +270,8 @@ bool QHelpSearchIndexReaderClucene::buildTryHarderQuery(
bool QHelpSearchIndexReaderClucene::isNegativeQuery(const QHelpSearchQuery &query) const
{
- const QString &search = query.wordList.join(" ");
- return search.contains('!') || search.contains('-')
+ const QString &search = query.wordList.join(QLatin1Char(' '));
+ return search.contains(QLatin1Char('!')) || search.contains(QLatin1Char('-'))
|| search.contains(QLatin1String(" NOT "));
}
diff --git a/src/assistant/help/qhelpsearchquerywidget.cpp b/src/assistant/help/qhelpsearchquerywidget.cpp
index 46f6fdfbd..e0b481e58 100644
--- a/src/assistant/help/qhelpsearchquerywidget.cpp
+++ b/src/assistant/help/qhelpsearchquerywidget.cpp
@@ -212,7 +212,7 @@ private:
queryHist.queries.append(query);
foreach (const QHelpSearchQuery &queryPart, query) {
static_cast<CompleterModel *>(searchCompleter.model())->
- addTerm(queryPart.wordList.join(" "));
+ addTerm(queryPart.wordList.join(QLatin1Char(' ')));
}
}
}
@@ -241,7 +241,7 @@ private:
queryHist->queries.at(queryHist->curQuery);
foreach (const QHelpSearchQuery &queryPart, query) {
if (QLineEdit *lineEdit = lineEditFor(queryPart.fieldName))
- lineEdit->setText(queryPart.wordList.join(" "));
+ lineEdit->setText(queryPart.wordList.join(QLatin1Char(' ')));
}
if (queryHist->curQuery == maxOrMinIndex)
diff --git a/src/designer/src/components/formeditor/formwindowmanager.cpp b/src/designer/src/components/formeditor/formwindowmanager.cpp
index 386d09f8e..000c9d52f 100644
--- a/src/designer/src/components/formeditor/formwindowmanager.cpp
+++ b/src/designer/src/components/formeditor/formwindowmanager.cpp
@@ -363,7 +363,8 @@ QWidget *FormWindowManager::findManagedWidget(FormWindow *fw, QWidget *w)
void FormWindowManager::setupActions()
{
#ifndef QT_NO_CLIPBOARD
- m_actionCut = new QAction(createIconSet(QStringLiteral("editcut.png")), tr("Cu&t"), this);
+ const QIcon cutIcon = QIcon::fromTheme(QStringLiteral("edit-cut"), createIconSet(QStringLiteral("editcut.png")));
+ m_actionCut = new QAction(cutIcon, tr("Cu&t"), this);
m_actionCut->setObjectName(QStringLiteral("__qt_cut_action"));
m_actionCut->setShortcut(QKeySequence::Cut);
m_actionCut->setStatusTip(tr("Cuts the selected widgets and puts them on the clipboard"));
@@ -371,7 +372,8 @@ void FormWindowManager::setupActions()
connect(m_actionCut, &QAction::triggered, this, &FormWindowManager::slotActionCutActivated);
m_actionCut->setEnabled(false);
- m_actionCopy = new QAction(createIconSet(QStringLiteral("editcopy.png")), tr("&Copy"), this);
+ const QIcon copyIcon = QIcon::fromTheme(QStringLiteral("edit-copy"), createIconSet(QStringLiteral("editcopy.png")));
+ m_actionCopy = new QAction(copyIcon, tr("&Copy"), this);
m_actionCopy->setObjectName(QStringLiteral("__qt_copy_action"));
m_actionCopy->setShortcut(QKeySequence::Copy);
m_actionCopy->setStatusTip(tr("Copies the selected widgets to the clipboard"));
@@ -379,7 +381,8 @@ void FormWindowManager::setupActions()
connect(m_actionCopy, &QAction::triggered, this, &FormWindowManager::slotActionCopyActivated);
m_actionCopy->setEnabled(false);
- m_actionPaste = new QAction(createIconSet(QStringLiteral("editpaste.png")), tr("&Paste"), this);
+ const QIcon pasteIcon = QIcon::fromTheme(QStringLiteral("edit-paste"), createIconSet(QStringLiteral("editpaste.png")));
+ m_actionPaste = new QAction(pasteIcon, tr("&Paste"), this);
m_actionPaste->setObjectName(QStringLiteral("__qt_paste_action"));
m_actionPaste->setShortcut(QKeySequence::Paste);
m_actionPaste->setStatusTip(tr("Pastes the clipboard's contents"));
@@ -388,7 +391,7 @@ void FormWindowManager::setupActions()
m_actionPaste->setEnabled(false);
#endif
- m_actionDelete = new QAction(tr("&Delete"), this);
+ m_actionDelete = new QAction(QIcon::fromTheme(QStringLiteral("edit-delete")), tr("&Delete"), this);
m_actionDelete->setObjectName(QStringLiteral("__qt_delete_action"));
m_actionDelete->setStatusTip(tr("Deletes the selected widgets"));
m_actionDelete->setWhatsThis(whatsThisFrom(QStringLiteral("Edit|Delete")));
@@ -523,24 +526,6 @@ void FormWindowManager::setupActions()
connect(m_actionShowFormWindowSettingsDialog, &QAction::triggered,
this, &FormWindowManager::slotActionShowFormWindowSettingsDialog);
m_actionShowFormWindowSettingsDialog->setEnabled(false);
-
-#if defined (Q_OS_UNIX) && !defined(Q_OS_MAC)
-#ifndef QT_NO_CLIPBOARD
- m_actionCopy->setIcon(QIcon::fromTheme(QStringLiteral("edit-copy"), m_actionCopy->icon()));
- m_actionCut->setIcon(QIcon::fromTheme(QStringLiteral("edit-cut"), m_actionCut->icon()));
- m_actionPaste->setIcon(QIcon::fromTheme(QStringLiteral("edit-paste"), m_actionPaste->icon()));
-#endif
- m_actionDelete->setIcon(QIcon::fromTheme(QStringLiteral("edit-delete"), m_actionDelete->icon()));
-
- // These do not currently exist, but will allow theme authors to fill in the gaps
- m_actionBreakLayout->setIcon(QIcon::fromTheme(QStringLiteral("designer-break-layout"), m_actionBreakLayout->icon()));
- m_actionGridLayout->setIcon(QIcon::fromTheme(QStringLiteral("designer-grid-layout"), m_actionGridLayout->icon()));
- m_actionHorizontalLayout->setIcon(QIcon::fromTheme(QStringLiteral("designer-horizontal-layout"), m_actionHorizontalLayout->icon()));
- m_actionVerticalLayout->setIcon(QIcon::fromTheme(QStringLiteral("designer-vertical-layout"), m_actionVerticalLayout->icon()));
- m_actionSplitHorizontal->setIcon(QIcon::fromTheme(QStringLiteral("designer-split-horizontal"), m_actionSplitHorizontal->icon()));
- m_actionSplitVertical->setIcon(QIcon::fromTheme(QStringLiteral("designer-split-vertical"), m_actionSplitVertical->icon()));
- m_actionAdjustSize->setIcon(QIcon::fromTheme(QStringLiteral("designer-adjust-size"), m_actionAdjustSize->icon()));
-#endif
}
#ifndef QT_NO_CLIPBOARD
diff --git a/src/designer/src/components/formeditor/images/cleartext.png b/src/designer/src/components/formeditor/images/cleartext.png
index 74133baff..4c7bb13f3 100644
--- a/src/designer/src/components/formeditor/images/cleartext.png
+++ b/src/designer/src/components/formeditor/images/cleartext.png
Binary files differ
diff --git a/src/designer/src/components/formeditor/images/mac/simplifyrichtext.png b/src/designer/src/components/formeditor/images/mac/simplifyrichtext.png
index a48e974bf..cdfc086bb 100644
--- a/src/designer/src/components/formeditor/images/mac/simplifyrichtext.png
+++ b/src/designer/src/components/formeditor/images/mac/simplifyrichtext.png
Binary files differ
diff --git a/src/designer/src/components/formeditor/images/righttoleft.png b/src/designer/src/components/formeditor/images/righttoleft.png
index 26a69d5ba..759066479 100644
--- a/src/designer/src/components/formeditor/images/righttoleft.png
+++ b/src/designer/src/components/formeditor/images/righttoleft.png
Binary files differ
diff --git a/src/linguist/lupdate/cpp.cpp b/src/linguist/lupdate/cpp.cpp
index 0d5a7a8d9..37927c447 100644
--- a/src/linguist/lupdate/cpp.cpp
+++ b/src/linguist/lupdate/cpp.cpp
@@ -459,6 +459,7 @@ STRING(class);
STRING(final);
STRING(friend);
STRING(namespace);
+STRING(nullptr);
STRING(operator);
STRING(return);
STRING(struct);
@@ -698,6 +699,8 @@ CppParser::TokenType CppParser::getToken()
case 'n':
if (yyWord == strnamespace)
return Tok_namespace;
+ if (yyWord == strnullptr)
+ return Tok_Null;
break;
case 'o':
if (yyWord == stroperator) {
diff --git a/src/qdoc/cppcodemarker.cpp b/src/qdoc/cppcodemarker.cpp
index eb88346dc..c68012d2f 100644
--- a/src/qdoc/cppcodemarker.cpp
+++ b/src/qdoc/cppcodemarker.cpp
@@ -161,10 +161,12 @@ QString CppCodeMarker::markedUpSynopsis(const Node *node,
while (p != func->parameters().constEnd()) {
if (p != func->parameters().constBegin())
synopsis += ", ";
- synopsis += typified((*p).dataType(), true);
- if (style != Subpage && !(*p).name().isEmpty())
- synopsis +=
- "<@param>" + protect((*p).name()) + "</@param>";
+ bool hasName = !(*p).name().isEmpty();
+ if (hasName)
+ synopsis += typified((*p).dataType(), true);
+ const QString &paramName = hasName ? (*p).name() : (*p).dataType();
+ if (style != Subpage || !hasName)
+ synopsis += "<@param>" + protect(paramName) + "</@param>";
synopsis += protect((*p).rightType());
if (style != Subpage && !(*p).defaultValue().isEmpty())
synopsis += " = " + protect((*p).defaultValue());
@@ -342,9 +344,11 @@ QString CppCodeMarker::markedUpQmlItem(const Node* node, bool summary)
while (p != func->parameters().constEnd()) {
if (p != func->parameters().constBegin())
synopsis += ", ";
- synopsis += typified((*p).dataType(), true);
- if (!(*p).name().isEmpty())
- synopsis += "<@param>" + protect((*p).name()) + "</@param>";
+ bool hasName = !(*p).name().isEmpty();
+ if (hasName)
+ synopsis += typified((*p).dataType(), true);
+ const QString &paramName = hasName ? (*p).name() : (*p).dataType();
+ synopsis += "<@param>" + protect(paramName) + "</@param>";
synopsis += protect((*p).rightType());
++p;
}
diff --git a/src/qdoc/cppcodeparser.cpp b/src/qdoc/cppcodeparser.cpp
index 0ea135cce..c1295c3a7 100644
--- a/src/qdoc/cppcodeparser.cpp
+++ b/src/qdoc/cppcodeparser.cpp
@@ -813,9 +813,11 @@ void CppCodeParser::processQmlProperties(const Doc& doc,
bool attached = ((topic == COMMAND_QMLATTACHEDPROPERTY) ||
(topic == COMMAND_JSATTACHEDPROPERTY));
if (splitQmlPropertyArg(arg, type, module, qmlTypeName, property)) {
- qmlType = qdb_->findQmlType(module, qmlTypeName);
- if (qmlType) {
- if (qmlType->hasQmlProperty(property, attached) != 0) {
+ Aggregate* aggregate = qdb_->findQmlType(module, qmlTypeName);
+ if (!aggregate)
+ aggregate = qdb_->findQmlBasicType(module, qmlTypeName);
+ if (aggregate) {
+ if (aggregate->hasQmlProperty(property, attached) != 0) {
QString msg = tr("QML property documented multiple times: '%1'").arg(arg);
doc.startLocation().warning(msg);
}
@@ -826,7 +828,7 @@ void CppCodeParser::processQmlProperties(const Doc& doc,
qpn->setGenus(Node::JS);
}
else {
- qpn = new QmlPropertyNode(qmlType, property, type, attached);
+ qpn = new QmlPropertyNode(aggregate, property, type, attached);
qpn->setLocation(doc.startLocation());
if (jsProps)
qpn->setGenus(Node::JS);
@@ -1548,7 +1550,10 @@ bool CppCodeParser::matchFunctionDecl(Aggregate *parent,
VariableNode *var = new VariableNode(parent, name);
var->setAccess(access);
- var->setLocation(location());
+ if (parsingHeaderFile_)
+ var->setLocation(declLoc());
+ else
+ var->setLocation(location());
var->setLeftType(returnType.left());
var->setRightType(returnType.right());
if (matched_compat)
@@ -1638,7 +1643,10 @@ bool CppCodeParser::matchFunctionDecl(Aggregate *parent,
if (matched_friend)
access = Node::Public;
func->setAccess(access);
- func->setLocation(location());
+ if (parsingHeaderFile_)
+ func->setLocation(declLoc());
+ else
+ func->setLocation(location());
func->setReturnType(returnType.toString());
func->setParentPath(parentPath);
func->setTemplateStuff(templateStuff);
@@ -1790,7 +1798,7 @@ bool CppCodeParser::matchClassDecl(Aggregate *parent,
*/
ClassNode *classe = new ClassNode(parent, className);
classe->setAccess(access);
- classe->setLocation(location());
+ classe->setLocation(declLoc());
if (compat)
classe->setStatus(Node::Compat);
if (!physicalModuleName.isEmpty())
@@ -1834,7 +1842,7 @@ bool CppCodeParser::matchNamespaceDecl(Aggregate *parent)
if (!ns) {
ns = new NamespaceNode(parent, namespaceName);
ns->setAccess(access);
- ns->setLocation(location());
+ ns->setLocation(declLoc());
}
readToken(); // skip '{'
@@ -1997,7 +2005,7 @@ bool CppCodeParser::matchEnumDecl(Aggregate *parent)
if (!name.isEmpty()) {
enume = new EnumNode(parent, name);
enume->setAccess(access);
- enume->setLocation(location());
+ enume->setLocation(declLoc());
}
readToken();
@@ -2027,7 +2035,7 @@ bool CppCodeParser::matchTypedefDecl(Aggregate *parent)
if (parent && !parent->findChildNode(name, Node::Typedef)) {
TypedefNode* td = new TypedefNode(parent, name);
td->setAccess(access);
- td->setLocation(location());
+ td->setLocation(declLoc());
}
return true;
}
@@ -2056,7 +2064,7 @@ bool CppCodeParser::matchProperty(Aggregate *parent)
PropertyNode *property = new PropertyNode(parent, name);
property->setAccess(Node::Public);
- property->setLocation(location());
+ property->setLocation(declLoc());
property->setDataType(dataType.toString());
while (tok != Tok_RightParen && tok != Tok_Eoi) {
@@ -2161,12 +2169,15 @@ bool CppCodeParser::matchDeclList(Aggregate *parent)
case Tok_class:
case Tok_struct:
case Tok_union:
+ setDeclLoc();
matchClassDecl(parent, templateStuff);
break;
case Tok_namespace:
+ setDeclLoc();
matchNamespaceDecl(parent);
break;
case Tok_using:
+ setDeclLoc();
matchUsingDecl(parent);
break;
case Tok_template:
@@ -2178,9 +2189,11 @@ bool CppCodeParser::matchDeclList(Aggregate *parent)
}
continue;
case Tok_enum:
+ setDeclLoc();
matchEnumDecl(parent);
break;
case Tok_typedef:
+ setDeclLoc();
matchTypedefDecl(parent);
break;
case Tok_private:
@@ -2216,6 +2229,7 @@ bool CppCodeParser::matchDeclList(Aggregate *parent)
case Tok_Q_PROPERTY:
case Tok_Q_PRIVATE_PROPERTY:
case Tok_QDOC_PROPERTY:
+ setDeclLoc();
if (!matchProperty(parent)) {
location().warning(tr("Failed to parse token %1 in property declaration").arg(lexeme()));
skipTo(Tok_RightParen);
@@ -2248,13 +2262,14 @@ bool CppCodeParser::matchDeclList(Aggregate *parent)
break;
case Tok_Q_DECLARE_FLAGS:
readToken();
+ setDeclLoc();
if (match(Tok_LeftParen) && match(Tok_Ident)) {
QString flagsType = previousLexeme();
if (match(Tok_Comma) && match(Tok_Ident)) {
QString name = previousLexeme();
TypedefNode *flagsNode = new TypedefNode(parent, flagsType);
flagsNode->setAccess(access);
- flagsNode->setLocation(location());
+ flagsNode->setLocation(declLoc());
EnumNode* en = static_cast<EnumNode*>(parent->findChildNode(name, Node::Enum));
if (en)
en->setFlagsType(flagsNode);
@@ -2264,6 +2279,7 @@ bool CppCodeParser::matchDeclList(Aggregate *parent)
break;
case Tok_QT_MODULE:
readToken();
+ setDeclLoc();
if (match(Tok_LeftParen) && match(Tok_Ident))
physicalModuleName = previousLexeme();
if (!physicalModuleName.startsWith("Qt"))
@@ -2271,6 +2287,8 @@ bool CppCodeParser::matchDeclList(Aggregate *parent)
match(Tok_RightParen);
break;
default:
+ if (parsingHeaderFile_)
+ setDeclLoc();
if (!matchFunctionDecl(parent, 0, 0, templateStuff, extra)) {
while (tok != Tok_Eoi &&
(tokenizer->braceDepth() > braceDepth0 ||
diff --git a/src/qdoc/cppcodeparser.h b/src/qdoc/cppcodeparser.h
index 7c110d2bb..d3a5829e3 100644
--- a/src/qdoc/cppcodeparser.h
+++ b/src/qdoc/cppcodeparser.h
@@ -76,6 +76,8 @@ public:
virtual void doneParsingHeaderFiles() Q_DECL_OVERRIDE;
virtual void doneParsingSourceFiles() Q_DECL_OVERRIDE;
bool parseParameters(const QString& parameters, QVector<Parameter>& pvect, bool& isQPrivateSignal);
+ const Location& declLoc() const { return declLoc_; }
+ void setDeclLoc() { declLoc_ = location(); }
protected:
const QSet<QString>& topicCommands();
@@ -163,6 +165,7 @@ protected:
QStringList lastPath_;
QRegExp varComment;
QRegExp sep;
+ Location declLoc_;
private:
QString sequentialIteratorDefinition;
diff --git a/src/qdoc/doc/qdoc-manual-markupcmds.qdoc b/src/qdoc/doc/qdoc-manual-markupcmds.qdoc
index a8d5e6830..5c997e5b4 100644
--- a/src/qdoc/doc/qdoc-manual-markupcmds.qdoc
+++ b/src/qdoc/doc/qdoc-manual-markupcmds.qdoc
@@ -1934,7 +1934,7 @@
\c {\l [QML|CPP|DOC|QtModuleName] {link target} {link text}}
\endlist
- The \e {square bracket} argument is only allowed in the \c {\\l
+ The \e {square bracket} argument is only allowed in the \c {\l
(link)} command. The example above shows how \c QML is used as the
\e {square brackets} argument to force qdoc to match a QML target.
Most often, this will be a QML type, but it can also be a QML
diff --git a/src/qdoc/generator.cpp b/src/qdoc/generator.cpp
index 0765e8ab7..4286aa692 100644
--- a/src/qdoc/generator.cpp
+++ b/src/qdoc/generator.cpp
@@ -190,6 +190,41 @@ void Generator::appendFullNames(Text& text, const NodeList& nodes, const Node* r
}
}
+/*!
+ Append the signature for the function named in \a node to
+ \a text, so that is is a link to the documentation for that
+ function.
+ */
+void Generator::appendSignature(Text& text, const Node* node)
+{
+ text << Atom(Atom::LinkNode, CodeMarker::stringForNode(node))
+ << Atom(Atom::FormattingLeft, ATOM_FORMATTING_LINK)
+ << Atom(Atom::String, node->signature(false, true))
+ << Atom(Atom::FormattingRight, ATOM_FORMATTING_LINK);
+}
+
+/*!
+ Generate a bullet list of function signatures. The function
+ nodes are in \a nodes. It uses the \a relative node and the
+ \a marker for the generation.
+ */
+void Generator::signatureList(const NodeList& nodes, const Node* relative, CodeMarker* marker)
+{
+ Text text;
+ int count = 0;
+ text << Atom(Atom::ListLeft, QString("bullet"));
+ NodeList::ConstIterator n = nodes.constBegin();
+ while (n != nodes.constEnd()) {
+ text << Atom(Atom::ListItemNumber, QString::number(++count));
+ text << Atom(Atom::ListItemLeft, QString("bullet"));
+ appendSignature(text, *n);
+ text << Atom(Atom::ListItemRight, QString("bullet"));
+ ++n;
+ }
+ text << Atom(Atom::ListRight, QString("bullet"));
+ generateText(text, relative, marker);
+}
+
int Generator::appendSortedNames(Text& text, const ClassNode* cn, const QList<RelatedClass>& rc)
{
QList<RelatedClass>::ConstIterator r;
@@ -1392,24 +1427,83 @@ bool Generator::generateText(const Text& text,
return result;
}
+/*
+ The node is an aggregate, typically a class node, which has
+ a threadsafeness level. This function checks all the children
+ of the node to see if they are exceptions to the node's
+ threadsafeness. If there are any exceptions, the exceptions
+ are added to the appropriate set (reentrant, threadsafe, and
+ nonreentrant, and true is returned. If there are no exceptions,
+ the three node lists remain empty and false is returned.
+ */
+static bool hasExceptions(const Node* node,
+ NodeList& reentrant,
+ NodeList& threadsafe,
+ NodeList& nonreentrant)
+{
+ bool result = false;
+ Node::ThreadSafeness ts = node->threadSafeness();
+ const Aggregate* a = static_cast<const Aggregate*>(node);
+ NodeList::ConstIterator c = a->childNodes().constBegin();
+ while (c != a->childNodes().constEnd()) {
+ if (!(*c)->isObsolete()){
+ switch ((*c)->threadSafeness()) {
+ case Node::Reentrant:
+ reentrant.append(*c);
+ if (ts == Node::ThreadSafe)
+ result = true;
+ break;
+ case Node::ThreadSafe:
+ threadsafe.append(*c);
+ if (ts == Node::Reentrant)
+ result = true;
+ break;
+ case Node::NonReentrant:
+ nonreentrant.append(*c);
+ result = true;
+ break;
+ default:
+ break;
+ }
+ }
+ ++c;
+ }
+ return result;
+}
+
+static void startNote(Text& text)
+{
+ text << Atom::ParaLeft
+ << Atom(Atom::FormattingLeft, ATOM_FORMATTING_BOLD)
+ << "Note:"
+ << Atom(Atom::FormattingRight, ATOM_FORMATTING_BOLD)
+ << " ";
+}
+
+/*!
+ Generates text that explains how threadsafe and/or reentrant
+ \a node is.
+ */
void Generator::generateThreadSafeness(const Node *node, CodeMarker *marker)
{
- Text text;
- Node::ThreadSafeness threadSafeness = node->threadSafeness();
+ Text text, rlink, tlink;
+ NodeList reentrant;
+ NodeList threadsafe;
+ NodeList nonreentrant;
+ Node::ThreadSafeness ts = node->threadSafeness();
+ bool exceptions = false;
- Text rlink;
rlink << Atom(Atom::Link,"reentrant")
<< Atom(Atom::FormattingLeft, ATOM_FORMATTING_LINK)
<< "reentrant"
<< Atom(Atom::FormattingRight, ATOM_FORMATTING_LINK);
- Text tlink;
tlink << Atom(Atom::Link,"thread-safe")
<< Atom(Atom::FormattingLeft, ATOM_FORMATTING_LINK)
<< "thread-safe"
<< Atom(Atom::FormattingRight, ATOM_FORMATTING_LINK);
- switch (threadSafeness) {
+ switch (ts) {
case Node::UnspecifiedSafeness:
break;
case Node::NonReentrant:
@@ -1426,110 +1520,76 @@ void Generator::generateThreadSafeness(const Node *node, CodeMarker *marker)
break;
case Node::Reentrant:
case Node::ThreadSafe:
- text << Atom::ParaLeft
- << Atom(Atom::FormattingLeft,ATOM_FORMATTING_BOLD)
- << "Note:"
- << Atom(Atom::FormattingRight,ATOM_FORMATTING_BOLD)
- << " ";
-
+ startNote(text);
if (node->isAggregate()) {
- const Aggregate* innerNode = static_cast<const Aggregate*>(node);
- text << "All functions in this "
- << typeString(node)
- << " are ";
- if (threadSafeness == Node::ThreadSafe)
+ exceptions = hasExceptions(node, reentrant, threadsafe, nonreentrant);
+ text << "All functions in this " << typeString(node) << " are ";
+ if (ts == Node::ThreadSafe)
text << tlink;
else
text << rlink;
- bool exceptions = false;
- NodeList reentrant;
- NodeList threadsafe;
- NodeList nonreentrant;
- NodeList::ConstIterator c = innerNode->childNodes().constBegin();
- while (c != innerNode->childNodes().constEnd()) {
-
- if ((*c)->status() != Node::Obsolete){
- switch ((*c)->threadSafeness()) {
- case Node::Reentrant:
- reentrant.append(*c);
- if (threadSafeness == Node::ThreadSafe)
- exceptions = true;
- break;
- case Node::ThreadSafe:
- threadsafe.append(*c);
- if (threadSafeness == Node::Reentrant)
- exceptions = true;
- break;
- case Node::NonReentrant:
- nonreentrant.append(*c);
- exceptions = true;
- break;
- default:
- break;
- }
- }
- ++c;
- }
- if (!exceptions)
+ if (!exceptions || (ts == Node::Reentrant && !threadsafe.isEmpty()))
text << ".";
- else if (threadSafeness == Node::Reentrant) {
- if (nonreentrant.isEmpty()) {
- if (!threadsafe.isEmpty()) {
- text << ", but ";
- appendFullNames(text,threadsafe,innerNode);
- singularPlural(text,threadsafe);
- text << " also " << tlink << ".";
- }
- else
- text << ".";
- }
- else {
- text << ", except for ";
- appendFullNames(text,nonreentrant,innerNode);
- text << ", which";
- singularPlural(text,nonreentrant);
- text << " nonreentrant.";
- if (!threadsafe.isEmpty()) {
- text << " ";
- appendFullNames(text,threadsafe,innerNode);
- singularPlural(text,threadsafe);
- text << " " << tlink << ".";
- }
- }
- }
- else { // thread-safe
- if (!nonreentrant.isEmpty() || !reentrant.isEmpty()) {
- text << ", except for ";
- if (!reentrant.isEmpty()) {
- appendFullNames(text,reentrant,innerNode);
- text << ", which";
- singularPlural(text,reentrant);
- text << " only " << rlink;
- if (!nonreentrant.isEmpty())
- text << ", and ";
- }
- if (!nonreentrant.isEmpty()) {
- appendFullNames(text,nonreentrant,innerNode);
- text << ", which";
- singularPlural(text,nonreentrant);
- text << " nonreentrant.";
- }
- text << ".";
- }
- }
+ else
+ text << " with the following exceptions:";
}
else {
text << "This " << typeString(node) << " is ";
- if (threadSafeness == Node::ThreadSafe)
+ if (ts == Node::ThreadSafe)
text << tlink;
else
text << rlink;
- text << ".";
}
text << Atom::ParaRight;
+ break;
+ default:
+ break;
}
generateText(text,node,marker);
+
+ if (exceptions) {
+ text.clear();
+ if (ts == Node::Reentrant) {
+ if (!nonreentrant.isEmpty()) {
+ startNote(text);
+ text << "These functions are not "
+ << rlink
+ << ":"
+ << Atom::ParaRight;
+ signatureList(nonreentrant, node, marker);
+ }
+ if (!threadsafe.isEmpty()) {
+ text.clear();
+ startNote(text);
+ text << "These functions are also "
+ << tlink
+ << ":"
+ << Atom::ParaRight;
+ generateText(text, node, marker);
+ signatureList(threadsafe, node, marker);
+ }
+ }
+ else { // thread-safe
+ if (!reentrant.isEmpty()) {
+ startNote(text);
+ text << "These functions are only "
+ << rlink
+ << ":"
+ << Atom::ParaRight;
+ signatureList(reentrant, node, marker);
+ }
+ if (!nonreentrant.isEmpty()) {
+ text.clear();
+ startNote(text);
+ text << "These functions are not "
+ << rlink
+ << ":"
+ << Atom::ParaRight;
+ signatureList(nonreentrant, node, marker);
+ }
+ }
+ }
}
/*!
diff --git a/src/qdoc/generator.h b/src/qdoc/generator.h
index c0adc1468..5b301f9f1 100644
--- a/src/qdoc/generator.h
+++ b/src/qdoc/generator.h
@@ -200,6 +200,8 @@ protected:
const Node *actualNode);
void appendFullNames(Text& text, const NodeList& nodes, const Node* relative);
int appendSortedNames(Text& text, const ClassNode *classe, const QList<RelatedClass> &classes);
+ void appendSignature(Text& text, const Node* node);
+ void signatureList(const NodeList& nodes, const Node* relative, CodeMarker* marker);
private:
static Generator* currentGenerator_;
diff --git a/src/qdoc/htmlgenerator.cpp b/src/qdoc/htmlgenerator.cpp
index 0702f0a9b..02384c962 100644
--- a/src/qdoc/htmlgenerator.cpp
+++ b/src/qdoc/htmlgenerator.cpp
@@ -1383,7 +1383,6 @@ void HtmlGenerator::generateClassLikeNode(Aggregate* inner, CodeMarker* marker)
generateBrief(inner, marker);
generateRequisites(inner, marker);
generateStatus(inner, marker);
- generateThreadSafeness(inner, marker);
out() << "<ul>\n";
@@ -1408,6 +1407,7 @@ void HtmlGenerator::generateClassLikeNode(Aggregate* inner, CodeMarker* marker)
<< "Compatibility members</a></li>\n";
out() << "</ul>\n";
+ generateThreadSafeness(inner, marker);
bool needOtherSection = false;
@@ -2016,10 +2016,12 @@ void HtmlGenerator::generateHeader(const QString& title,
out() << " <title>"
<< protectEnc(title)
<< divider
- << titleSuffix
- << QLatin1Char(' ')
- << shortVersion
- << "</title>\n";
+ << titleSuffix;
+
+ if (!shortVersion.isEmpty())
+ out() << QLatin1Char(' ') << shortVersion;
+
+ out() << "</title>\n";
// Include style sheet and script links.
out() << headerStyles;
diff --git a/src/qdoc/jscodemarker.cpp b/src/qdoc/jscodemarker.cpp
index 669040da0..496eb8c30 100644
--- a/src/qdoc/jscodemarker.cpp
+++ b/src/qdoc/jscodemarker.cpp
@@ -44,10 +44,12 @@
#include "tree.h"
#include "generator.h"
+#ifndef QT_NO_DECLARATIVE
#include <private/qqmljsast_p.h>
#include <private/qqmljsengine_p.h>
#include <private/qqmljslexer_p.h>
#include <private/qqmljsparser_p.h>
+#endif
QT_BEGIN_NAMESPACE
@@ -64,6 +66,7 @@ JsCodeMarker::~JsCodeMarker()
*/
bool JsCodeMarker::recognizeCode(const QString &code)
{
+#ifndef QT_NO_DECLARATIVE
QQmlJS::Engine engine;
QQmlJS::Lexer lexer(&engine);
QQmlJS::Parser parser(&engine);
@@ -73,6 +76,9 @@ bool JsCodeMarker::recognizeCode(const QString &code)
lexer.setCode(newCode, 1);
return parser.parseProgram();
+#else
+ return false;
+#endif
}
/*!
@@ -112,6 +118,7 @@ QString JsCodeMarker::addMarkUp(const QString &code,
const Node * /* relative */,
const Location &location)
{
+#ifndef QT_NO_DECLARATIVE
QQmlJS::Engine engine;
QQmlJS::Lexer lexer(&engine);
@@ -137,6 +144,10 @@ QString JsCodeMarker::addMarkUp(const QString &code,
output = protect(code);
}
return output;
+#else
+ location.warning("QtDeclarative not installed; cannot parse QML or JS.");
+ return QString();
+#endif
}
QT_END_NAMESPACE
diff --git a/src/qdoc/node.h b/src/qdoc/node.h
index e76d940f9..870a55cdf 100644
--- a/src/qdoc/node.h
+++ b/src/qdoc/node.h
@@ -952,7 +952,7 @@ public:
bool hasActiveAssociatedProperty() const;
QStringList reconstructParameters(bool values = false) const;
- virtual QString signature(bool values, bool noReturnType = false) const;
+ virtual QString signature(bool values, bool noReturnType = false) const Q_DECL_OVERRIDE;
virtual QString element() const Q_DECL_OVERRIDE { return parent()->name(); }
virtual bool isAttached() const Q_DECL_OVERRIDE { return attached_; }
virtual bool isQtQuickNode() const Q_DECL_OVERRIDE { return parent()->isQtQuickNode(); }
diff --git a/src/qdoc/qdoc.pro b/src/qdoc/qdoc.pro
index 6333a046e..52b40bccb 100644
--- a/src/qdoc/qdoc.pro
+++ b/src/qdoc/qdoc.pro
@@ -4,7 +4,12 @@
}
option(host_build)
-QT = core qmldevtools-private
+QT = core
+qtHaveModule(qmldevtools-private) {
+ QT += qmldevtools-private
+} else {
+ DEFINES += QT_NO_DECLARATIVE
+}
DEFINES += \
QDOC2_COMPAT
diff --git a/src/qdoc/qmlcodemarker.cpp b/src/qdoc/qmlcodemarker.cpp
index 089e1d1c8..3b76f87da 100644
--- a/src/qdoc/qmlcodemarker.cpp
+++ b/src/qdoc/qmlcodemarker.cpp
@@ -44,11 +44,13 @@
#include "tree.h"
#include "generator.h"
+#ifndef QT_NO_DECLARATIVE
#include <private/qqmljsast_p.h>
#include <private/qqmljsastfwd_p.h>
#include <private/qqmljsengine_p.h>
#include <private/qqmljslexer_p.h>
#include <private/qqmljsparser_p.h>
+#endif
QT_BEGIN_NAMESPACE
@@ -65,6 +67,7 @@ QmlCodeMarker::~QmlCodeMarker()
*/
bool QmlCodeMarker::recognizeCode(const QString &code)
{
+#ifndef QT_NO_DECLARATIVE
QQmlJS::Engine engine;
QQmlJS::Lexer lexer(&engine);
QQmlJS::Parser parser(&engine);
@@ -74,6 +77,9 @@ bool QmlCodeMarker::recognizeCode(const QString &code)
lexer.setCode(newCode, 1);
return parser.parse();
+#else
+ return false;
+#endif
}
/*!
@@ -163,6 +169,7 @@ QString QmlCodeMarker::addMarkUp(const QString &code,
const Node * /* relative */,
const Location &location)
{
+#ifndef QT_NO_DECLARATIVE
QQmlJS::Engine engine;
QQmlJS::Lexer lexer(&engine);
@@ -188,8 +195,13 @@ QString QmlCodeMarker::addMarkUp(const QString &code,
}
return output;
+#else
+ location.warning("QtDeclarative not installed; cannot parse QML or JS.");
+ return QString();
+#endif
}
+#ifndef QT_NO_DECLARATIVE
/*
Copied and pasted from
src/declarative/qml/qqmlscriptparser.cpp.
@@ -270,5 +282,6 @@ QList<QQmlJS::AST::SourceLocation> QmlCodeMarker::extractPragmas(QString &script
}
return removed;
}
+#endif
QT_END_NAMESPACE
diff --git a/src/qdoc/qmlcodemarker.h b/src/qdoc/qmlcodemarker.h
index 96353ebe5..0090350e7 100644
--- a/src/qdoc/qmlcodemarker.h
+++ b/src/qdoc/qmlcodemarker.h
@@ -40,7 +40,9 @@
#include "cppcodemarker.h"
+#ifndef QT_NO_DECLARATIVE
#include <private/qqmljsastfwd_p.h>
+#endif
QT_BEGIN_NAMESPACE
@@ -67,7 +69,9 @@ public:
virtual QString functionEndRegExp(const QString &funcName) Q_DECL_OVERRIDE;
/* Copied from src/declarative/qml/qdeclarativescriptparser.cpp */
+#ifndef QT_NO_DECLARATIVE
QList<QQmlJS::AST::SourceLocation> extractPragmas(QString &script);
+#endif
private:
QString addMarkUp(const QString &code, const Node *relative,
diff --git a/src/qdoc/qmlcodeparser.cpp b/src/qdoc/qmlcodeparser.cpp
index e94df4753..58be80d01 100644
--- a/src/qdoc/qmlcodeparser.cpp
+++ b/src/qdoc/qmlcodeparser.cpp
@@ -41,8 +41,10 @@
#include "config.h"
#include "qmlvisitor.h"
+#ifndef QT_NO_DECLARATIVE
#include <private/qqmljsast_p.h>
#include <private/qqmljsastvisitor_p.h>
+#endif
#include <qdebug.h>
QT_BEGIN_NAMESPACE
@@ -97,8 +99,10 @@ QT_BEGIN_NAMESPACE
Constructs the QML code parser.
*/
QmlCodeParser::QmlCodeParser()
+#ifndef QT_NO_DECLARATIVE
: lexer( 0 ),
parser( 0 )
+#endif
{
}
@@ -119,8 +123,10 @@ void QmlCodeParser::initializeParser(const Config &config)
{
CodeParser::initializeParser(config);
+#ifndef QT_NO_DECLARATIVE
lexer = new QQmlJS::Lexer(&engine);
parser = new QQmlJS::Parser(&engine);
+#endif
}
/*!
@@ -129,8 +135,10 @@ void QmlCodeParser::initializeParser(const Config &config)
*/
void QmlCodeParser::terminateParser()
{
+#ifndef QT_NO_DECLARATIVE
delete lexer;
delete parser;
+#endif
}
/*!
@@ -167,6 +175,7 @@ void QmlCodeParser::parseSourceFile(const Location& location, const QString& fil
return;
}
+#ifndef QT_NO_DECLARATIVE
QString document = in.readAll();
in.close();
@@ -195,6 +204,9 @@ void QmlCodeParser::parseSourceFile(const Location& location, const QString& fil
<< ": " << qPrintable(msg.message);
}
currentFile_.clear();
+#else
+ location.warning("QtDeclarative not installed; cannot parse QML or JS.");
+#endif
}
/*!
@@ -265,6 +277,7 @@ const QSet<QString>& QmlCodeParser::otherMetaCommands()
return otherMetaCommands_;
}
+#ifndef QT_NO_DECLARATIVE
/*!
Copy and paste from src/declarative/qml/qdeclarativescriptparser.cpp.
This function blanks out the section of the \a str beginning at \a idx
@@ -329,5 +342,6 @@ void QmlCodeParser::extractPragmas(QString &script)
}
return;
}
+#endif
QT_END_NAMESPACE
diff --git a/src/qdoc/qmlcodeparser.h b/src/qdoc/qmlcodeparser.h
index 8b5667532..f483b7382 100644
--- a/src/qdoc/qmlcodeparser.h
+++ b/src/qdoc/qmlcodeparser.h
@@ -41,9 +41,11 @@
#include "codeparser.h"
#include <qset.h>
+#ifndef QT_NO_DECLARATIVE
#include <private/qqmljsengine_p.h>
#include <private/qqmljslexer_p.h>
#include <private/qqmljsparser_p.h>
+#endif
QT_BEGIN_NAMESPACE
@@ -66,17 +68,21 @@ public:
virtual void parseSourceFile(const Location& location, const QString& filePath) Q_DECL_OVERRIDE;
virtual void doneParsingSourceFiles() Q_DECL_OVERRIDE;
+#ifndef QT_NO_DECLARATIVE
/* Copied from src/declarative/qml/qdeclarativescriptparser.cpp */
void extractPragmas(QString &script);
+#endif
protected:
const QSet<QString>& topicCommands();
const QSet<QString>& otherMetaCommands();
private:
+#ifndef QT_NO_DECLARATIVE
QQmlJS::Engine engine;
QQmlJS::Lexer *lexer;
QQmlJS::Parser *parser;
+#endif
};
QT_END_NAMESPACE
diff --git a/src/qdoc/qmlmarkupvisitor.cpp b/src/qdoc/qmlmarkupvisitor.cpp
index 17dd99325..122c23040 100644
--- a/src/qdoc/qmlmarkupvisitor.cpp
+++ b/src/qdoc/qmlmarkupvisitor.cpp
@@ -35,12 +35,15 @@
#include <qstringlist.h>
#include <qglobal.h>
+#ifndef QT_NO_DECLARATIVE
#include <private/qqmljsast_p.h>
#include <private/qqmljsastfwd_p.h>
#include <private/qqmljsengine_p.h>
+#endif
QT_BEGIN_NAMESPACE
+#ifndef QT_NO_DECLARATIVE
QmlMarkupVisitor::QmlMarkupVisitor(const QString &source,
const QList<QQmlJS::AST::SourceLocation> &pragmas,
QQmlJS::Engine *engine)
@@ -840,5 +843,6 @@ bool QmlMarkupVisitor::visit(QQmlJS::AST::UiObjectDefinition *definition)
QQmlJS::AST::Node::accept(definition->initializer, this);
return false;
}
+#endif
QT_END_NAMESPACE
diff --git a/src/qdoc/qmlmarkupvisitor.h b/src/qdoc/qmlmarkupvisitor.h
index ab1180fd4..63d6f1bf4 100644
--- a/src/qdoc/qmlmarkupvisitor.h
+++ b/src/qdoc/qmlmarkupvisitor.h
@@ -38,11 +38,14 @@
#include "tree.h"
#include <qstring.h>
+#ifndef QT_NO_DECLARATIVE
#include <private/qqmljsastvisitor_p.h>
#include <private/qqmljsengine_p.h>
+#endif
QT_BEGIN_NAMESPACE
+#ifndef QT_NO_DECLARATIVE
class QmlMarkupVisitor : public QQmlJS::AST::Visitor
{
public:
@@ -167,6 +170,7 @@ private:
int extraIndex;
};
Q_DECLARE_TYPEINFO(QmlMarkupVisitor::ExtraType, Q_PRIMITIVE_TYPE);
+#endif
QT_END_NAMESPACE
diff --git a/src/qdoc/qmlvisitor.cpp b/src/qdoc/qmlvisitor.cpp
index 654922929..3fee46932 100644
--- a/src/qdoc/qmlvisitor.cpp
+++ b/src/qdoc/qmlvisitor.cpp
@@ -42,9 +42,11 @@
#include <qstringlist.h>
#include <qglobal.h>
#include <qdebug.h>
+#ifndef QT_NO_DECLARATIVE
#include <private/qqmljsast_p.h>
#include <private/qqmljsastfwd_p.h>
#include <private/qqmljsengine_p.h>
+#endif
QT_BEGIN_NAMESPACE
@@ -89,6 +91,7 @@ QT_BEGIN_NAMESPACE
#define COMMAND_JSATTACHEDMETHOD Doc::alias(QLatin1String("jsattachedmethod"))
#define COMMAND_JSBASICTYPE Doc::alias(QLatin1String("jsbasictype"))
+#ifndef QT_NO_DECLARATIVE
/*!
The constructor stores all the parameters in local data members.
*/
@@ -823,5 +826,6 @@ void QmlDocVisitor::endVisit(QQmlJS::AST::UiQualifiedId* )
{
// nothing.
}
+#endif
QT_END_NAMESPACE
diff --git a/src/qdoc/qmlvisitor.h b/src/qdoc/qmlvisitor.h
index 8a23eef75..bc7a3c003 100644
--- a/src/qdoc/qmlvisitor.h
+++ b/src/qdoc/qmlvisitor.h
@@ -37,8 +37,10 @@
#include "node.h"
#include <qstring.h>
+#ifndef QT_NO_DECLARATIVE
#include <private/qqmljsastvisitor_p.h>
#include <private/qqmljsengine_p.h>
+#endif
QT_BEGIN_NAMESPACE
@@ -57,6 +59,7 @@ struct QmlPropArgs
}
};
+#ifndef QT_NO_DECLARATIVE
class QmlDocVisitor : public QQmlJS::AST::Visitor
{
Q_DECLARE_TR_FUNCTIONS(QDoc::QmlDocVisitor)
@@ -115,6 +118,7 @@ private:
QSet<quint32> usedComments;
Aggregate *current;
};
+#endif
QT_END_NAMESPACE
diff --git a/src/windeployqt/utils.cpp b/src/windeployqt/utils.cpp
index 64f39619d..a29b38bbd 100644
--- a/src/windeployqt/utils.cpp
+++ b/src/windeployqt/utils.cpp
@@ -45,7 +45,7 @@
#include <QtCore/QStandardPaths>
#if defined(Q_OS_WIN)
# include <QtCore/qt_windows.h>
-# include <Shlwapi.h>
+# include <shlwapi.h>
# include <delayimp.h>
#else // Q_OS_WIN
# include <sys/wait.h>
diff --git a/src/windeployqt/windeployqt.pro b/src/windeployqt/windeployqt.pro
index ef5534a67..4ea703948 100644
--- a/src/windeployqt/windeployqt.pro
+++ b/src/windeployqt/windeployqt.pro
@@ -7,6 +7,6 @@ HEADERS += utils.h qmlutils.h elfreader.h
CONFIG += force_bootstrap
-win32: LIBS += -lShlwapi
+win32: LIBS += -lshlwapi
load(qt_tool)
diff --git a/tests/auto/linguist/lupdate/testdata/good/parsecpp/main.cpp b/tests/auto/linguist/lupdate/testdata/good/parsecpp/main.cpp
index f4ac1e214..d58ddf9fb 100644
--- a/tests/auto/linguist/lupdate/testdata/good/parsecpp/main.cpp
+++ b/tests/auto/linguist/lupdate/testdata/good/parsecpp/main.cpp
@@ -488,3 +488,22 @@ class TernaryClass : public QObject
tr("ternary, ddd, false");
}
};
+
+
+
+// QTBUG-47467: lupdate confused by nullptr in case of plural forms
+void nullptrInPlural()
+{
+ QObject::tr("%n nullptr(s)", nullptr, 3);
+ QCoreApplication::translate("Plurals, nullptr", "%n car(s)", nullptr, QCoreApplication::UnicodeUTF8, 1);
+}
+
+class nullptrClass : public QObject
+{
+ Q_OBJECT
+
+ void f()
+ {
+ tr("%n car(s)", nullptr, 2);
+ }
+};
diff --git a/tests/auto/linguist/lupdate/testdata/good/parsecpp/project.ts.result b/tests/auto/linguist/lupdate/testdata/good/parsecpp/project.ts.result
index b847f8f89..be9df15ca 100644
--- a/tests/auto/linguist/lupdate/testdata/good/parsecpp/project.ts.result
+++ b/tests/auto/linguist/lupdate/testdata/good/parsecpp/project.ts.result
@@ -235,6 +235,16 @@ backslashed \ stuff.</source>
</message>
</context>
<context>
+ <name>Plurals, nullptr</name>
+ <message numerus="yes">
+ <location filename="main.cpp" line="498"/>
+ <source>%n car(s)</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ </translation>
+ </message>
+</context>
+<context>
<name>QApplication</name>
<message>
<location filename="main.cpp" line="43"/>
@@ -302,6 +312,13 @@ backslashed \ stuff.</source>
<extracomment>comment, bbb, false</extracomment>
<translation type="unfinished"></translation>
</message>
+ <message numerus="yes">
+ <location filename="main.cpp" line="497"/>
+ <source>%n nullptr(s)</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ </translation>
+ </message>
<message>
<location filename="included.cpp" line="34"/>
<source>message from #included .cpp file</source>
@@ -456,6 +473,16 @@ backslashed \ stuff.</source>
</message>
</context>
<context>
+ <name>nullptrClass</name>
+ <message numerus="yes">
+ <location filename="main.cpp" line="507"/>
+ <source>%n car(s)</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ </translation>
+ </message>
+</context>
+<context>
<name>scope</name>
<message numerus="yes">
<location filename="main.cpp" line="179"/>