doc: Ensure page name does not change

This fix ensures that the page name is
set only once. Also included are a few
internal documentation changes that
bring qdoc's internal terminology up
to date.

Task-number: QTBUG-31578
Change-Id: Ib52a5a9024533d5a695cee0055bf2bc4d9bc2af9
Reviewed-by: Jerome Pasion <jerome.pasion@digia.com>
This commit is contained in:
Martin Smith 2013-07-18 11:25:48 +02:00 committed by The Qt Project
parent f4a0d6d249
commit eaac7960f8
6 changed files with 50 additions and 79 deletions

View File

@ -612,10 +612,10 @@ Node* CppCodeParser::processTopicCommand(const Doc& doc,
(command == COMMAND_QMLATTACHEDSIGNAL) ||
(command == COMMAND_QMLATTACHEDMETHOD)) {
QString module;
QString element;
QString qmlType;
QString type;
if (splitQmlMethodArg(arg.first,type,module,element)) {
QmlClassNode* qmlClass = qdb_->findQmlType(module,element);
if (splitQmlMethodArg(arg.first,type,module,qmlType)) {
QmlClassNode* qmlClass = qdb_->findQmlType(module,qmlType);
if (qmlClass) {
bool attached = false;
Node::Type nodeType = Node::QmlMethod;
@ -650,24 +650,24 @@ Node* CppCodeParser::processTopicCommand(const Doc& doc,
/*!
A QML property group argument has the form...
<QML-module>::<element>::<name>
<QML-module>::<QML-type>::<name>
This function splits the argument into those parts.
A <QML-module> is the QML equivalent of a C++ namespace.
So this function splits \a arg on "::" and stores the
parts in \a module, \a element, and \a name, and returns
parts in \a module, \a qmlType, and \a name, and returns
true. If any part is not found, a qdoc warning is emitted
and false is returned.
*/
bool CppCodeParser::splitQmlPropertyGroupArg(const QString& arg,
QString& module,
QString& element,
QString& qmlType,
QString& name)
{
QStringList colonSplit = arg.split("::");
if (colonSplit.size() == 3) {
module = colonSplit[0];
element = colonSplit[1];
qmlType = colonSplit[1];
name = colonSplit[2];
return true;
}
@ -679,26 +679,26 @@ bool CppCodeParser::splitQmlPropertyGroupArg(const QString& arg,
/*!
A QML property argument has the form...
<type> <element>::<name>
<type> <QML-module>::<element>::<name>
<type> <QML-type>::<name>
<type> <QML-module>::<QML-type>::<name>
This function splits the argument into one of those
two forms. The three part form is the old form, which
was used before the creation of Qt Quick 2 and Qt
Components. A <QML-module> is the QML equivalent of a
C++ namespace. So this function splits \a arg on "::"
and stores the parts in \a type, \a module, \a element,
and stores the parts in \a type, \a module, \a qmlType,
and \a name, and returns true. If any part other than
\a module is not found, a qdoc warning is emitted and
false is returned.
\note The two elements \e{Component} and \e{QtObject} never
have a module qualifier.
\note The two QML types \e{Component} and \e{QtObject}
never have a module qualifier.
*/
bool CppCodeParser::splitQmlPropertyArg(const QString& arg,
QString& type,
QString& module,
QString& element,
QString& qmlType,
QString& name)
{
QStringList blankSplit = arg.split(QLatin1Char(' '));
@ -707,13 +707,13 @@ bool CppCodeParser::splitQmlPropertyArg(const QString& arg,
QStringList colonSplit(blankSplit[1].split("::"));
if (colonSplit.size() == 3) {
module = colonSplit[0];
element = colonSplit[1];
qmlType = colonSplit[1];
name = colonSplit[2];
return true;
}
if (colonSplit.size() == 2) {
module.clear();
element = colonSplit[0];
qmlType = colonSplit[0];
name = colonSplit[1];
return true;
}
@ -730,21 +730,21 @@ bool CppCodeParser::splitQmlPropertyArg(const QString& arg,
/*!
A QML signal or method argument has the form...
<type> <element>::<name>(<param>, <param>, ...)
<type> <QML-module>::<element>::<name>(<param>, <param>, ...)
<type> <QML-type>::<name>(<param>, <param>, ...)
<type> <QML-module>::<QML-type>::<name>(<param>, <param>, ...)
This function splits the argument into one of those two
forms, sets \a module, \a element, and \a name, and returns
forms, sets \a module, \a qmlType, and \a name, and returns
true. If the argument doesn't match either form, an error
message is emitted and false is returned.
\note The two elements \e{Component} and \e{QtObject} never
\note The two QML types \e{Component} and \e{QtObject} never
have a module qualifier.
*/
bool CppCodeParser::splitQmlMethodArg(const QString& arg,
QString& type,
QString& module,
QString& element)
QString& qmlType)
{
QStringList colonSplit(arg.split("::"));
if (colonSplit.size() > 1) {
@ -753,22 +753,22 @@ bool CppCodeParser::splitQmlMethodArg(const QString& arg,
type = blankSplit[0];
if (colonSplit.size() > 2) {
module = blankSplit[1];
element = colonSplit[1];
qmlType = colonSplit[1];
}
else {
module.clear();
element = blankSplit[1];
qmlType = blankSplit[1];
}
}
else {
type.clear();
if (colonSplit.size() > 2) {
module = colonSplit[0];
element = colonSplit[1];
qmlType = colonSplit[1];
}
else {
module.clear();
element = colonSplit[0];
qmlType = colonSplit[0];
}
}
return true;
@ -790,7 +790,7 @@ void CppCodeParser::processQmlProperties(const Doc& doc, NodeList& nodes, DocLis
QString type;
QString topic;
QString module;
QString element;
QString qmlType;
QString property;
QmlPropertyNode* qpn = 0;
QmlClassNode* qmlClass = 0;
@ -808,11 +808,11 @@ void CppCodeParser::processQmlProperties(const Doc& doc, NodeList& nodes, DocLis
qmlPropertyGroupTopic = topics.at(0);
qmlPropertyGroupTopic.topic = COMMAND_QMLPROPERTYGROUP;
arg = qmlPropertyGroupTopic.args;
if (splitQmlPropertyArg(arg, type, module, element, property)) {
if (splitQmlPropertyArg(arg, type, module, qmlType, property)) {
int i = property.indexOf('.');
if (i != -1) {
property = property.left(i);
qmlPropertyGroupTopic.args = module + "::" + element + "::" + property;
qmlPropertyGroupTopic.args = module + "::" + qmlType + "::" + property;
doc.location().warning(tr("No QML property group command found; using \\%1 %2")
.arg(COMMAND_QMLPROPERTYGROUP).arg(qmlPropertyGroupTopic.args));
}
@ -828,8 +828,8 @@ void CppCodeParser::processQmlProperties(const Doc& doc, NodeList& nodes, DocLis
if (!qmlPropertyGroupTopic.isEmpty()) {
arg = qmlPropertyGroupTopic.args;
if (splitQmlPropertyGroupArg(arg, module, element, property)) {
qmlClass = qdb_->findQmlType(module, element);
if (splitQmlPropertyGroupArg(arg, module, qmlType, property)) {
qmlClass = qdb_->findQmlType(module, qmlType);
if (qmlClass) {
qpgn = new QmlPropertyGroupNode(qmlClass, property);
qpgn->setLocation(doc.startLocation());
@ -848,8 +848,8 @@ void CppCodeParser::processQmlProperties(const Doc& doc, NodeList& nodes, DocLis
arg = topics.at(i).args;
if ((topic == COMMAND_QMLPROPERTY) || (topic == COMMAND_QMLATTACHEDPROPERTY)) {
bool attached = (topic == COMMAND_QMLATTACHEDPROPERTY);
if (splitQmlPropertyArg(arg, type, module, element, property)) {
qmlClass = qdb_->findQmlType(module, element);
if (splitQmlPropertyArg(arg, type, module, qmlType, property)) {
qmlClass = qdb_->findQmlType(module, qmlType);
if (qmlClass) {
if (qmlClass->hasQmlProperty(property) != 0) {
QString msg = tr("QML property documented multiple times: '%1'").arg(arg);
@ -2327,7 +2327,7 @@ bool CppCodeParser::makeFunctionNode(const QString& signature,
the \a type.
\a parent is the QML class node. The QML module and QML
element names have already been consumed to find \a parent.
type names have already been consumed to find \a parent.
What remains in \a sig is the method signature. The method
must be a child of \a parent.
*/

View File

@ -80,7 +80,6 @@ enum {
CMD_ANNOTATEDLIST,
CMD_B,
CMD_BADCODE,
CMD_BASENAME,
CMD_BOLD,
CMD_BR,
CMD_BRIEF,
@ -198,7 +197,6 @@ static struct {
{ "annotatedlist", CMD_ANNOTATEDLIST, 0 },
{ "b", CMD_B, 0 },
{ "badcode", CMD_BADCODE, 0 },
{ "basename", CMD_BASENAME, 0 }, // ### don't document for now
{ "bold", CMD_BOLD, 0 },
{ "br", CMD_BR, 0 },
{ "brief", CMD_BRIEF, 0 },
@ -316,7 +314,6 @@ Q_GLOBAL_STATIC(QHash_QString_Macro, macroHash)
class DocPrivateExtra
{
public:
QString baseName;
Doc::Sections granularity;
Doc::Sections section; // ###
QList<Atom*> tableOfContents;
@ -466,7 +463,6 @@ private:
Location& location();
QString detailsUnknownCommand(const QSet<QString>& metaCommandSet,
const QString& str);
void insertBaseName(const QString &baseName);
void insertTarget(const QString& target, bool keyword);
void include(const QString& fileName, const QString& identifier);
void startFormat(const QString& format, int cmd);
@ -644,10 +640,6 @@ void DocParser::parse(const QString& source,
leavePara();
append(Atom::CodeBad,getCode(CMD_BADCODE, marker));
break;
case CMD_BASENAME:
leavePara();
insertBaseName(getArgument());
break;
case CMD_BR:
leavePara();
append(Atom::BR);
@ -1669,29 +1661,6 @@ QString DocParser::detailsUnknownCommand(const QSet<QString> &metaCommandSet,
return tr("Maybe you meant '\\%1'?").arg(best);
}
void DocParser::insertBaseName(const QString &baseName)
{
priv->constructExtra();
if (currentSection == priv->extra->section) {
priv->extra->baseName = baseName;
}
else {
Atom *atom = priv->text.firstAtom();
Atom *sectionLeft = 0;
int delta = currentSection - priv->extra->section;
while (atom != 0) {
if (atom->type() == Atom::SectionLeft &&
atom->string().toInt() == delta)
sectionLeft = atom;
atom = atom->next();
}
if (sectionLeft != 0)
(void) new Atom(sectionLeft, Atom::BaseName, baseName);
}
}
void DocParser::insertTarget(const QString &target, bool keyword)
{
if (targetMap.contains(target)) {
@ -2980,17 +2949,6 @@ Text Doc::legaleseText() const
return body().subText(Atom::LegaleseLeft, Atom::LegaleseRight);
}
const QString& Doc::baseName() const
{
static QString null;
if (priv == 0 || priv->extra == 0) {
return null;
}
else {
return priv->extra->baseName;
}
}
Doc::Sections Doc::granularity() const
{
if (priv == 0 || priv->extra == 0) {

View File

@ -164,7 +164,6 @@ public:
Text briefText(bool inclusive = false) const;
Text trimmedBriefText(const QString &className) const;
Text legaleseText() const;
const QString& baseName() const;
Sections granularity() const;
const QSet<QString> &parameterNames() const;
const QStringList &enumItemNames() const;

View File

@ -305,10 +305,18 @@ QString Generator::fileBase(const Node *node) const
node = node->parent();
}
QString base = node->doc().baseName();
if (!base.isEmpty())
return base;
if (node->type() == Node::Document && node->subType() == Node::Collision) {
const NameCollisionNode* ncn = static_cast<const NameCollisionNode*>(node);
if (ncn->currentChild())
return fileBase(ncn->currentChild());
}
if (node->hasBaseName()) {
//qDebug() << "RETURNING:" << node->baseName();
return node->baseName();
}
QString base;
const Node *p = node;
forever {
@ -377,6 +385,8 @@ QString Generator::fileBase(const Node *node) const
}
while (res.endsWith(QLatin1Char('-')))
res.chop(1);
Node* n = const_cast<Node*>(node);
n->setBaseName(res);
return res;
}

View File

@ -3779,7 +3779,7 @@ void HtmlGenerator::generateDetailedQmlMember(Node *node,
out() << "<div class=\"qmlproto\">";
out() << "<table class=\"qmlname\">";
QString heading = "Property Group: " + qpgn->name();
QString heading = qpgn->name() + " group";
out() << "<tr valign=\"top\" class=\"even\">";
out() << "<th class=\"centerAlign\"><p>";
out() << "<a name=\"" + refForNode(qpgn) + "\"></a>";

View File

@ -164,7 +164,10 @@ public:
QString plainName() const;
QString plainFullName(const Node* relative = 0) const;
QString fullName(const Node* relative=0) const;
const QString& baseName() const { return baseName_; }
bool hasBaseName() const { return !baseName_.isEmpty(); }
void setBaseName(const QString& bn) { baseName_ = bn; }
void setAccess(Access access) { access_ = access; }
void setLocation(const Location& location) { loc = location; }
void setDoc(const Doc& doc, bool replace = false);
@ -302,6 +305,7 @@ private:
Location loc;
Doc doc_;
QMap<LinkType, QPair<QString, QString> > linkMap_;
QString baseName_;
QString moduleName_;
QString url_;
QString since_;