qdoc: Implement better handling of QML property groups
The \qmlpropertygroup command is added, and qdoc is taught to generate better output for it. The format is, e.g.: \qmlpropertygroup QtQuick2::Item::anchors \qmlproperty AnchorLine QtQuick2::Item::anchors.top \qmlproperty AnchorLine QtQuick2::Item::anchors.bottom \qmlproperty AnchorLine QtQuick2::Item::anchors.left \qmlproperty AnchorLine QtQuick2::Item::anchors.right \qmlproperty AnchorLine QtQuick2::Item::anchors.horizontalCenter \qmlproperty AnchorLine QtQuick2::Item::anchors.verticalCenter \qmlproperty AnchorLine QtQuick2::Item::anchors.baseline \qmlproperty Item QtQuick2::Item::anchors.fill \qmlproperty Item QtQuick2::Item::anchors.centerIn \qmlproperty real QtQuick2::Item::anchors.margins \qmlproperty real QtQuick2::Item::anchors.topMargin \qmlproperty real QtQuick2::Item::anchors.bottomMargin \qmlproperty real QtQuick2::Item::anchors.leftMargin \qmlproperty real QtQuick2::Item::anchors.rightMargin \qmlproperty real QtQuick2::Item::anchors.horizontalCenterOffset \qmlproperty real QtQuick2::Item::anchors.verticalCenterOffset \qmlproperty real QtQuick2::Item::anchors.baselineOffset \qmlproperty bool QtQuick2::Item::anchors.alignWhenCentered Task-number: QTBUG-32341 Change-Id: I4b06a3a061b23680e663e8d4e82ac9863ffd4ecb Reviewed-by: Jerome Pasion <jerome.pasion@digia.com>
This commit is contained in:
parent
b06304e164
commit
2eb28f51ce
@ -398,7 +398,7 @@ void CodeMarker::insert(FastSection &fastSection,
|
||||
bool inheritedMember = false;
|
||||
if (!node->relates()) {
|
||||
InnerNode* p = node->parent();
|
||||
if (p->subType() == Node::QmlPropertyGroup)
|
||||
if (p->type() == Node::QmlPropertyGroup)
|
||||
p = p->parent();
|
||||
if (p != fastSection.parent_) { // && !node->parent()->isAbstract()) {
|
||||
if (p->subType() != Node::QmlClass || !p->isAbstract()) {
|
||||
|
@ -199,29 +199,33 @@ CodeParser *CodeParser::parserForSourceFile(const QString &filePath)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static QSet<QString> commonMetaCommands_;
|
||||
/*!
|
||||
Returns the set of strings representing the common metacommands.
|
||||
*/
|
||||
QSet<QString> CodeParser::commonMetaCommands()
|
||||
const QSet<QString>& CodeParser::commonMetaCommands()
|
||||
{
|
||||
return QSet<QString>() << COMMAND_COMPAT
|
||||
<< COMMAND_DEPRECATED
|
||||
<< COMMAND_INGROUP
|
||||
<< COMMAND_INMODULE
|
||||
<< COMMAND_INQMLMODULE
|
||||
<< COMMAND_INTERNAL
|
||||
<< COMMAND_MAINCLASS
|
||||
<< COMMAND_NONREENTRANT
|
||||
<< COMMAND_OBSOLETE
|
||||
<< COMMAND_PAGEKEYWORDS
|
||||
<< COMMAND_PRELIMINARY
|
||||
<< COMMAND_INPUBLICGROUP
|
||||
<< COMMAND_REENTRANT
|
||||
<< COMMAND_SINCE
|
||||
<< COMMAND_SUBTITLE
|
||||
<< COMMAND_THREADSAFE
|
||||
<< COMMAND_TITLE
|
||||
<< COMMAND_WRAPPER;
|
||||
if (commonMetaCommands_.isEmpty()) {
|
||||
commonMetaCommands_ << COMMAND_COMPAT
|
||||
<< COMMAND_DEPRECATED
|
||||
<< COMMAND_INGROUP
|
||||
<< COMMAND_INMODULE
|
||||
<< COMMAND_INQMLMODULE
|
||||
<< COMMAND_INTERNAL
|
||||
<< COMMAND_MAINCLASS
|
||||
<< COMMAND_NONREENTRANT
|
||||
<< COMMAND_OBSOLETE
|
||||
<< COMMAND_PAGEKEYWORDS
|
||||
<< COMMAND_PRELIMINARY
|
||||
<< COMMAND_INPUBLICGROUP
|
||||
<< COMMAND_REENTRANT
|
||||
<< COMMAND_SINCE
|
||||
<< COMMAND_SUBTITLE
|
||||
<< COMMAND_THREADSAFE
|
||||
<< COMMAND_TITLE
|
||||
<< COMMAND_WRAPPER;
|
||||
}
|
||||
return commonMetaCommands_;
|
||||
}
|
||||
|
||||
/*!
|
||||
@ -269,8 +273,8 @@ void CodeParser::processCommonMetaCommand(const Location& location,
|
||||
if (!showInternal) {
|
||||
node->setAccess(Node::Private);
|
||||
node->setStatus(Node::Internal);
|
||||
if (node->subType() == Node::QmlPropertyGroup) {
|
||||
const QmlPropGroupNode* qpgn = static_cast<const QmlPropGroupNode*>(node);
|
||||
if (node->type() == Node::QmlPropertyGroup) {
|
||||
const QmlPropertyGroupNode* qpgn = static_cast<const QmlPropertyGroupNode*>(node);
|
||||
NodeList::ConstIterator p = qpgn->childNodes().constBegin();
|
||||
while (p != qpgn->childNodes().constEnd()) {
|
||||
if ((*p)->type() == Node::QmlProperty) {
|
||||
|
@ -86,7 +86,7 @@ public:
|
||||
static const QString& currentOutputSubdirectory() { return currentSubDir_; }
|
||||
|
||||
protected:
|
||||
QSet<QString> commonMetaCommands();
|
||||
const QSet<QString>& commonMetaCommands();
|
||||
void processCommonMetaCommand(const Location& location,
|
||||
const QString& command,
|
||||
const ArgLocPair& arg,
|
||||
|
@ -1110,40 +1110,15 @@ QList<Section> CppCodeMarker::qmlSections(const QmlClassNode* qmlClassNode, Syno
|
||||
while (qcn != 0) {
|
||||
NodeList::ConstIterator c = qcn->childNodes().constBegin();
|
||||
while (c != qcn->childNodes().constEnd()) {
|
||||
if ((*c)->subType() == Node::QmlPropertyGroup) {
|
||||
const QmlPropGroupNode* qpgn = static_cast<const QmlPropGroupNode*>(*c);
|
||||
NodeList::ConstIterator p = qpgn->childNodes().constBegin();
|
||||
while (p != qpgn->childNodes().constEnd()) {
|
||||
if ((*p)->type() == Node::QmlProperty) {
|
||||
const QmlPropertyNode* pn = static_cast<const QmlPropertyNode*>(*p);
|
||||
if (pn->isAttached())
|
||||
insert(qmlattachedproperties,*p,style,Okay);
|
||||
else
|
||||
insert(qmlproperties,*p,style,Okay);
|
||||
}
|
||||
++p;
|
||||
}
|
||||
if ((*c)->type() == Node::QmlPropertyGroup) {
|
||||
insert(qmlproperties, *c, style, Okay);
|
||||
}
|
||||
else if ((*c)->type() == Node::QmlProperty) {
|
||||
const QmlPropertyNode* pn = static_cast<const QmlPropertyNode*>(*c);
|
||||
if (pn->qmlPropNodes().isEmpty()) {
|
||||
if (pn->isAttached())
|
||||
insert(qmlattachedproperties,*c,style,Okay);
|
||||
else
|
||||
insert(qmlproperties,*c,style,Okay);
|
||||
}
|
||||
if (pn->isAttached())
|
||||
insert(qmlattachedproperties,*c,style,Okay);
|
||||
else {
|
||||
NodeList::ConstIterator p = pn->qmlPropNodes().constBegin();
|
||||
while (p != pn->qmlPropNodes().constEnd()) {
|
||||
if ((*p)->type() == Node::QmlProperty) {
|
||||
const QmlPropertyNode* pn = static_cast<const QmlPropertyNode*>(*p);
|
||||
if (pn->isAttached())
|
||||
insert(qmlattachedproperties,*p,style,Okay);
|
||||
else
|
||||
insert(qmlproperties,*p,style,Okay);
|
||||
}
|
||||
++p;
|
||||
}
|
||||
insert(qmlproperties,*c,style,Okay);
|
||||
}
|
||||
}
|
||||
else if ((*c)->type() == Node::QmlSignal) {
|
||||
@ -1196,24 +1171,8 @@ QList<Section> CppCodeMarker::qmlSections(const QmlClassNode* qmlClassNode, Syno
|
||||
while (qcn != 0) {
|
||||
NodeList::ConstIterator c = qcn->childNodes().constBegin();
|
||||
while (c != qcn->childNodes().constEnd()) {
|
||||
if ((*c)->subType() == Node::QmlPropertyGroup) {
|
||||
bool attached = false;
|
||||
const QmlPropGroupNode* pgn = static_cast<const QmlPropGroupNode*>(*c);
|
||||
NodeList::ConstIterator C = pgn->childNodes().constBegin();
|
||||
while (C != pgn->childNodes().constEnd()) {
|
||||
if ((*C)->type() == Node::QmlProperty) {
|
||||
const QmlPropertyNode* pn = static_cast<const QmlPropertyNode*>(*C);
|
||||
if (pn->isAttached()) {
|
||||
attached = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
++C;
|
||||
}
|
||||
if (attached)
|
||||
insert(qmlattachedproperties,*c,style,Okay);
|
||||
else
|
||||
insert(qmlproperties,*c,style,Okay);
|
||||
if ((*c)->type() == Node::QmlPropertyGroup) {
|
||||
insert(qmlproperties,*c,style,Okay);
|
||||
}
|
||||
else if ((*c)->type() == Node::QmlProperty) {
|
||||
const QmlPropertyNode* pn = static_cast<const QmlPropertyNode*>(*c);
|
||||
@ -1278,8 +1237,8 @@ QList<Section> CppCodeMarker::qmlSections(const QmlClassNode* qmlClassNode, Syno
|
||||
}
|
||||
NodeList::ConstIterator c = current->childNodes().constBegin();
|
||||
while (c != current->childNodes().constEnd()) {
|
||||
if ((*c)->subType() == Node::QmlPropertyGroup) {
|
||||
const QmlPropGroupNode* qpgn = static_cast<const QmlPropGroupNode*>(*c);
|
||||
if ((*c)->type() == Node::QmlPropertyGroup) {
|
||||
const QmlPropertyGroupNode* qpgn = static_cast<const QmlPropertyGroupNode*>(*c);
|
||||
NodeList::ConstIterator p = qpgn->childNodes().constBegin();
|
||||
while (p != qpgn->childNodes().constEnd()) {
|
||||
if ((*p)->type() == Node::QmlProperty) {
|
||||
|
@ -272,37 +272,42 @@ void CppCodeParser::doneParsingSourceFiles()
|
||||
qdb_->treeRoot()->makeUndocumentedChildrenInternal();
|
||||
}
|
||||
|
||||
static QSet<QString> topicCommands_;
|
||||
/*!
|
||||
Returns the set of strings reopresenting the topic commands.
|
||||
*/
|
||||
QSet<QString> CppCodeParser::topicCommands()
|
||||
const QSet<QString>& CppCodeParser::topicCommands()
|
||||
{
|
||||
return QSet<QString>() << COMMAND_CLASS
|
||||
<< COMMAND_DITAMAP
|
||||
<< COMMAND_ENUM
|
||||
<< COMMAND_EXAMPLE
|
||||
<< COMMAND_EXTERNALPAGE
|
||||
<< COMMAND_FILE
|
||||
<< COMMAND_FN
|
||||
<< COMMAND_GROUP
|
||||
<< COMMAND_HEADERFILE
|
||||
<< COMMAND_MACRO
|
||||
<< COMMAND_MODULE
|
||||
<< COMMAND_NAMESPACE
|
||||
<< COMMAND_PAGE
|
||||
<< COMMAND_PROPERTY
|
||||
<< COMMAND_TYPEDEF
|
||||
<< COMMAND_VARIABLE
|
||||
<< COMMAND_QMLCLASS
|
||||
<< COMMAND_QMLTYPE
|
||||
<< COMMAND_QMLPROPERTY
|
||||
<< COMMAND_QMLATTACHEDPROPERTY
|
||||
<< COMMAND_QMLSIGNAL
|
||||
<< COMMAND_QMLATTACHEDSIGNAL
|
||||
<< COMMAND_QMLMETHOD
|
||||
<< COMMAND_QMLATTACHEDMETHOD
|
||||
<< COMMAND_QMLBASICTYPE
|
||||
<< COMMAND_QMLMODULE;
|
||||
if (topicCommands_.isEmpty()) {
|
||||
topicCommands_ << COMMAND_CLASS
|
||||
<< COMMAND_DITAMAP
|
||||
<< COMMAND_ENUM
|
||||
<< COMMAND_EXAMPLE
|
||||
<< COMMAND_EXTERNALPAGE
|
||||
<< COMMAND_FILE
|
||||
<< COMMAND_FN
|
||||
<< COMMAND_GROUP
|
||||
<< COMMAND_HEADERFILE
|
||||
<< COMMAND_MACRO
|
||||
<< COMMAND_MODULE
|
||||
<< COMMAND_NAMESPACE
|
||||
<< COMMAND_PAGE
|
||||
<< COMMAND_PROPERTY
|
||||
<< COMMAND_TYPEDEF
|
||||
<< COMMAND_VARIABLE
|
||||
<< COMMAND_QMLCLASS
|
||||
<< COMMAND_QMLTYPE
|
||||
<< COMMAND_QMLPROPERTY
|
||||
<< COMMAND_QMLPROPERTYGROUP
|
||||
<< COMMAND_QMLATTACHEDPROPERTY
|
||||
<< COMMAND_QMLSIGNAL
|
||||
<< COMMAND_QMLATTACHEDSIGNAL
|
||||
<< COMMAND_QMLMETHOD
|
||||
<< COMMAND_QMLATTACHEDMETHOD
|
||||
<< COMMAND_QMLBASICTYPE
|
||||
<< COMMAND_QMLMODULE;
|
||||
}
|
||||
return topicCommands_;
|
||||
}
|
||||
|
||||
/*!
|
||||
@ -642,6 +647,35 @@ Node* CppCodeParser::processTopicCommand(const Doc& doc,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*!
|
||||
A QML property group argument has the form...
|
||||
|
||||
<QML-module>::<element>::<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
|
||||
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& name)
|
||||
{
|
||||
QStringList colonSplit = arg.split("::");
|
||||
if (colonSplit.size() == 3) {
|
||||
module = colonSplit[0];
|
||||
element = colonSplit[1];
|
||||
name = colonSplit[2];
|
||||
return true;
|
||||
}
|
||||
QString msg = "Unrecognizable QML module/component qualifier for " + arg;
|
||||
location().warning(tr(msg.toLatin1().data()));
|
||||
return false;
|
||||
}
|
||||
|
||||
/*!
|
||||
A QML property argument has the form...
|
||||
|
||||
@ -750,79 +784,118 @@ bool CppCodeParser::splitQmlMethodArg(const QString& arg,
|
||||
Currently, this function is called only for \e{qmlproperty}
|
||||
and \e{qmlattachedproperty}.
|
||||
*/
|
||||
Node* CppCodeParser::processTopicCommandGroup(const Doc& doc,
|
||||
const QString& command,
|
||||
const ArgList& args)
|
||||
void CppCodeParser::processQmlProperties(const Doc& doc, NodeList& nodes, DocList& docs)
|
||||
{
|
||||
QmlPropGroupNode* qmlPropGroup = 0;
|
||||
if ((command == COMMAND_QMLPROPERTY) ||
|
||||
(command == COMMAND_QMLATTACHEDPROPERTY)) {
|
||||
QString arg;
|
||||
QString type;
|
||||
QString module;
|
||||
QString element;
|
||||
QString property;
|
||||
QmlClassNode* qmlClass = 0;
|
||||
bool attached = (command == COMMAND_QMLATTACHEDPROPERTY);
|
||||
ArgList::ConstIterator argsIter = args.constBegin();
|
||||
arg = argsIter->first;
|
||||
if (splitQmlPropertyArg(arg,type,module,element,property)) {
|
||||
qmlClass = qdb_->findQmlType(module,element);
|
||||
if (qmlClass) {
|
||||
qmlPropGroup = new QmlPropGroupNode(qmlClass,property); //,attached);
|
||||
qmlPropGroup->setLocation(doc.startLocation());
|
||||
}
|
||||
QString arg;
|
||||
QString type;
|
||||
QString topic;
|
||||
QString module;
|
||||
QString element;
|
||||
QString property;
|
||||
QmlPropertyNode* qpn = 0;
|
||||
QmlClassNode* qmlClass = 0;
|
||||
QmlPropertyGroupNode* qpgn = 0;
|
||||
|
||||
Topic qmlPropertyGroupTopic;
|
||||
const TopicList& topics = doc.topicsUsed();
|
||||
for (int i=0; i<topics.size(); ++i) {
|
||||
if (topics.at(i).topic == COMMAND_QMLPROPERTYGROUP) {
|
||||
qmlPropertyGroupTopic = topics.at(i);
|
||||
break;
|
||||
}
|
||||
if (qmlPropGroup) {
|
||||
if (qmlClass->hasProperty(property)) {
|
||||
doc.startLocation().warning(tr("QML property documented multiple times: '%1'").arg(arg));
|
||||
}
|
||||
if (qmlPropertyGroupTopic.isEmpty() && topics.size() > 1) {
|
||||
qmlPropertyGroupTopic = topics.at(0);
|
||||
qmlPropertyGroupTopic.topic = COMMAND_QMLPROPERTYGROUP;
|
||||
arg = qmlPropertyGroupTopic.args;
|
||||
if (splitQmlPropertyArg(arg, type, module, element, property)) {
|
||||
int i = property.indexOf('.');
|
||||
if (i != -1) {
|
||||
property = property.left(i);
|
||||
qmlPropertyGroupTopic.args = module + "::" + element + "::" + property;
|
||||
doc.location().warning(tr("No QML property group command found; using \\%1 %2")
|
||||
.arg(COMMAND_QMLPROPERTYGROUP).arg(qmlPropertyGroupTopic.args));
|
||||
}
|
||||
else {
|
||||
QmlPropertyNode *qmlPropNode = new QmlPropertyNode(qmlPropGroup,property,type,attached);
|
||||
qmlPropNode->setLocation(doc.startLocation());
|
||||
}
|
||||
++argsIter;
|
||||
while (argsIter != args.constEnd()) {
|
||||
arg = argsIter->first;
|
||||
if (splitQmlPropertyArg(arg,type,module,element,property)) {
|
||||
if (qmlClass->hasProperty(property)) {
|
||||
doc.startLocation().warning(tr("QML property documented multiple times: '%1'").arg(arg));
|
||||
}
|
||||
else {
|
||||
QmlPropertyNode* qmlPropNode = new QmlPropertyNode(qmlPropGroup,
|
||||
property,
|
||||
type,
|
||||
attached);
|
||||
qmlPropNode->setLocation(doc.startLocation());
|
||||
}
|
||||
}
|
||||
++argsIter;
|
||||
/*
|
||||
Assumption: No '.' in the property name
|
||||
means there is no property group.
|
||||
*/
|
||||
qmlPropertyGroupTopic.clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!qmlPropertyGroupTopic.isEmpty()) {
|
||||
arg = qmlPropertyGroupTopic.args;
|
||||
if (splitQmlPropertyGroupArg(arg, module, element, property)) {
|
||||
qmlClass = qdb_->findQmlType(module, element);
|
||||
if (qmlClass) {
|
||||
qpgn = new QmlPropertyGroupNode(qmlClass, property);
|
||||
qpgn->setLocation(doc.startLocation());
|
||||
}
|
||||
}
|
||||
if (topics.size() == 1) {
|
||||
nodes.append(qpgn);
|
||||
docs.append(doc);
|
||||
return;
|
||||
}
|
||||
}
|
||||
for (int i=0; i<topics.size(); ++i) {
|
||||
if (topics.at(i).topic == COMMAND_QMLPROPERTYGROUP)
|
||||
continue;
|
||||
topic = topics.at(i).topic;
|
||||
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 (qmlClass) {
|
||||
if (qmlClass->hasQmlProperty(property) != 0) {
|
||||
QString msg = tr("QML property documented multiple times: '%1'").arg(arg);
|
||||
doc.startLocation().warning(msg);
|
||||
}
|
||||
else if (qpgn) {
|
||||
qpn = new QmlPropertyNode(qpgn, property, type, attached);
|
||||
qpn->setLocation(doc.startLocation());
|
||||
}
|
||||
else {
|
||||
qpn = new QmlPropertyNode(qmlClass, property, type, attached);
|
||||
qpn->setLocation(doc.startLocation());
|
||||
nodes.append(qpn);
|
||||
docs.append(doc);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return qmlPropGroup;
|
||||
}
|
||||
|
||||
static QSet<QString> otherMetaCommands_;
|
||||
/*!
|
||||
Returns the set of strings representing the common metacommands
|
||||
plus some other metacommands.
|
||||
*/
|
||||
QSet<QString> CppCodeParser::otherMetaCommands()
|
||||
const QSet<QString>& CppCodeParser::otherMetaCommands()
|
||||
{
|
||||
return commonMetaCommands() << COMMAND_INHEADERFILE
|
||||
<< COMMAND_OVERLOAD
|
||||
<< COMMAND_REIMP
|
||||
<< COMMAND_RELATES
|
||||
<< COMMAND_CONTENTSPAGE
|
||||
<< COMMAND_NEXTPAGE
|
||||
<< COMMAND_PREVIOUSPAGE
|
||||
<< COMMAND_INDEXPAGE
|
||||
<< COMMAND_STARTPAGE
|
||||
<< COMMAND_QMLINHERITS
|
||||
<< COMMAND_QMLINSTANTIATES
|
||||
<< COMMAND_QMLDEFAULT
|
||||
<< COMMAND_QMLREADONLY
|
||||
<< COMMAND_QMLABSTRACT;
|
||||
if (otherMetaCommands_.isEmpty()) {
|
||||
otherMetaCommands_ = commonMetaCommands();
|
||||
otherMetaCommands_ << COMMAND_INHEADERFILE
|
||||
<< COMMAND_OVERLOAD
|
||||
<< COMMAND_REIMP
|
||||
<< COMMAND_RELATES
|
||||
<< COMMAND_CONTENTSPAGE
|
||||
<< COMMAND_NEXTPAGE
|
||||
<< COMMAND_PREVIOUSPAGE
|
||||
<< COMMAND_INDEXPAGE
|
||||
<< COMMAND_STARTPAGE
|
||||
<< COMMAND_QMLINHERITS
|
||||
<< COMMAND_QMLINSTANTIATES
|
||||
<< COMMAND_QMLDEFAULT
|
||||
<< COMMAND_QMLREADONLY
|
||||
<< COMMAND_QMLABSTRACT;
|
||||
}
|
||||
return otherMetaCommands_;
|
||||
}
|
||||
|
||||
/*!
|
||||
@ -961,8 +1034,8 @@ void CppCodeParser::processOtherMetaCommand(const Doc& doc,
|
||||
QmlPropertyNode* qpn = static_cast<QmlPropertyNode*>(node);
|
||||
qpn->setDefault();
|
||||
}
|
||||
else if (node->type() == Node::Document && node->subType() == Node::QmlPropertyGroup) {
|
||||
QmlPropGroupNode* qpgn = static_cast<QmlPropGroupNode*>(node);
|
||||
else if (node->type() == Node::QmlPropertyGroup) {
|
||||
QmlPropertyGroupNode* qpgn = static_cast<QmlPropertyGroupNode*>(node);
|
||||
NodeList::ConstIterator p = qpgn->childNodes().constBegin();
|
||||
while (p != qpgn->childNodes().constEnd()) {
|
||||
if ((*p)->type() == Node::QmlProperty) {
|
||||
@ -978,8 +1051,8 @@ void CppCodeParser::processOtherMetaCommand(const Doc& doc,
|
||||
QmlPropertyNode* qpn = static_cast<QmlPropertyNode*>(node);
|
||||
qpn->setReadOnly(1);
|
||||
}
|
||||
else if (node->type() == Node::Document && node->subType() == Node::QmlPropertyGroup) {
|
||||
QmlPropGroupNode* qpgn = static_cast<QmlPropGroupNode*>(node);
|
||||
else if (node->type() == Node::QmlPropertyGroup) {
|
||||
QmlPropertyGroupNode* qpgn = static_cast<QmlPropertyGroupNode*>(node);
|
||||
NodeList::ConstIterator p = qpgn->childNodes().constBegin();
|
||||
while (p != qpgn->childNodes().constEnd()) {
|
||||
if ((*p)->type() == Node::QmlProperty) {
|
||||
@ -2067,10 +2140,9 @@ bool CppCodeParser::matchDeclList(InnerNode *parent)
|
||||
bool CppCodeParser::matchDocsAndStuff()
|
||||
{
|
||||
ExtraFuncData extra;
|
||||
QSet<QString> topicCommandsAllowed = topicCommands();
|
||||
QSet<QString> otherMetacommandsAllowed = otherMetaCommands();
|
||||
QSet<QString> metacommandsAllowed = topicCommandsAllowed +
|
||||
otherMetacommandsAllowed;
|
||||
const QSet<QString>& topicCommandsAllowed = topicCommands();
|
||||
const QSet<QString>& otherMetacommandsAllowed = otherMetaCommands();
|
||||
const QSet<QString>& metacommandsAllowed = topicCommandsAllowed + otherMetacommandsAllowed;
|
||||
|
||||
while (tok != Tok_Eoi) {
|
||||
if (tok == Tok_Doc) {
|
||||
@ -2087,25 +2159,22 @@ bool CppCodeParser::matchDocsAndStuff()
|
||||
/*
|
||||
Doc parses the comment.
|
||||
*/
|
||||
Doc doc(start_loc,end_loc,comment,metacommandsAllowed);
|
||||
|
||||
Doc doc(start_loc,end_loc,comment,metacommandsAllowed, topicCommandsAllowed);
|
||||
QString topic;
|
||||
ArgList args;
|
||||
bool isQmlPropertyTopic = false;
|
||||
|
||||
QSet<QString> topicCommandsUsed = topicCommandsAllowed & doc.metaCommandsUsed();
|
||||
|
||||
/*
|
||||
There should be one topic command in the set,
|
||||
or none. If the set is empty, then the comment
|
||||
should be a function description.
|
||||
*/
|
||||
if (topicCommandsUsed.count() > 0) {
|
||||
topic = *topicCommandsUsed.constBegin();
|
||||
args = doc.metaCommandArgs(topic);
|
||||
const TopicList& topics = doc.topicsUsed();
|
||||
if (!topics.isEmpty()) {
|
||||
topic = topics[0].topic;
|
||||
if ((topic == COMMAND_QMLPROPERTY) ||
|
||||
(topic == COMMAND_QMLPROPERTYGROUP) ||
|
||||
(topic == COMMAND_QMLATTACHEDPROPERTY)) {
|
||||
isQmlPropertyTopic = true;
|
||||
}
|
||||
}
|
||||
|
||||
// if (isQmlPropertyTopic && doc.location().fileName().endsWith("qquickitem.cpp")) {
|
||||
NodeList nodes;
|
||||
QList<Doc> docs;
|
||||
DocList docs;
|
||||
|
||||
if (topic.isEmpty()) {
|
||||
QStringList parentPath;
|
||||
@ -2133,43 +2202,39 @@ bool CppCodeParser::matchDocsAndStuff()
|
||||
.arg(COMMAND_FN).arg(COMMAND_PAGE));
|
||||
}
|
||||
}
|
||||
else if (isQmlPropertyTopic) {
|
||||
Doc nodeDoc = doc;
|
||||
processQmlProperties(nodeDoc, nodes, docs);
|
||||
}
|
||||
else {
|
||||
/*
|
||||
There is a topic command. Process it.
|
||||
*/
|
||||
if ((topic == COMMAND_QMLPROPERTY) ||
|
||||
(topic == COMMAND_QMLATTACHEDPROPERTY)) {
|
||||
ArgList args;
|
||||
const QSet<QString>& topicCommandsUsed = topicCommandsAllowed & doc.metaCommandsUsed();
|
||||
if (topicCommandsUsed.count() > 0) {
|
||||
topic = *topicCommandsUsed.constBegin();
|
||||
args = doc.metaCommandArgs(topic);
|
||||
}
|
||||
if (topicCommandsUsed.count() > 1) {
|
||||
QString topics;
|
||||
QSet<QString>::ConstIterator t = topicCommandsUsed.constBegin();
|
||||
while (t != topicCommandsUsed.constEnd()) {
|
||||
topics += " \\" + *t + ",";
|
||||
++t;
|
||||
}
|
||||
topics[topics.lastIndexOf(',')] = '.';
|
||||
int i = topics.lastIndexOf(',');
|
||||
topics[i] = ' ';
|
||||
topics.insert(i+1,"and");
|
||||
doc.location().warning(tr("Multiple topic commands found in comment: %1").arg(topics));
|
||||
}
|
||||
ArgList::ConstIterator a = args.constBegin();
|
||||
while (a != args.constEnd()) {
|
||||
Doc nodeDoc = doc;
|
||||
Node *node = processTopicCommandGroup(nodeDoc, topic,args);
|
||||
Node *node = processTopicCommand(nodeDoc,topic,*a);
|
||||
if (node != 0) {
|
||||
nodes.append(node);
|
||||
docs.append(nodeDoc);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (topicCommandsUsed.count() > 1) {
|
||||
QString topics;
|
||||
QSet<QString>::ConstIterator t = topicCommandsUsed.constBegin();
|
||||
while (t != topicCommandsUsed.constEnd()) {
|
||||
topics += " \\" + *t + ",";
|
||||
++t;
|
||||
}
|
||||
topics[topics.lastIndexOf(',')] = '.';
|
||||
int i = topics.lastIndexOf(',');
|
||||
topics[i] = ' ';
|
||||
topics.insert(i+1,"and");
|
||||
doc.location().warning(tr("Multiple topic commands found in comment: %1").arg(topics));
|
||||
}
|
||||
ArgList::ConstIterator a = args.constBegin();
|
||||
while (a != args.constEnd()) {
|
||||
Doc nodeDoc = doc;
|
||||
Node *node = processTopicCommand(nodeDoc,topic,*a);
|
||||
if (node != 0) {
|
||||
nodes.append(node);
|
||||
docs.append(nodeDoc);
|
||||
}
|
||||
++a;
|
||||
}
|
||||
++a;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -84,13 +84,16 @@ public:
|
||||
virtual void doneParsingSourceFiles();
|
||||
|
||||
protected:
|
||||
virtual QSet<QString> topicCommands();
|
||||
const QSet<QString>& topicCommands();
|
||||
const QSet<QString>& otherMetaCommands();
|
||||
virtual Node* processTopicCommand(const Doc& doc,
|
||||
const QString& command,
|
||||
const ArgLocPair& arg);
|
||||
virtual Node *processTopicCommandGroup(const Doc& doc,
|
||||
const QString& command,
|
||||
const ArgList& args);
|
||||
void processQmlProperties(const Doc& doc, NodeList& nodes, DocList& docs);
|
||||
bool splitQmlPropertyGroupArg(const QString& arg,
|
||||
QString& module,
|
||||
QString& element,
|
||||
QString& name);
|
||||
bool splitQmlPropertyArg(const QString& arg,
|
||||
QString& type,
|
||||
QString& module,
|
||||
@ -100,7 +103,6 @@ protected:
|
||||
QString& type,
|
||||
QString& module,
|
||||
QString& element);
|
||||
virtual QSet<QString> otherMetaCommands();
|
||||
virtual void processOtherMetaCommand(const Doc& doc,
|
||||
const QString& command,
|
||||
const ArgLocPair& argLocPair,
|
||||
@ -212,6 +214,7 @@ protected:
|
||||
#define COMMAND_QMLCLASS Doc::alias("qmlclass")
|
||||
#define COMMAND_QMLTYPE Doc::alias("qmltype")
|
||||
#define COMMAND_QMLPROPERTY Doc::alias("qmlproperty")
|
||||
#define COMMAND_QMLPROPERTYGROUP Doc::alias("qmlpropertygroup")
|
||||
#define COMMAND_QMLATTACHEDPROPERTY Doc::alias("qmlattachedproperty")
|
||||
#define COMMAND_QMLINHERITS Doc::alias("inherits")
|
||||
#define COMMAND_QMLINSTANTIATES Doc::alias("instantiates")
|
||||
|
@ -3677,8 +3677,8 @@ QString DitaXmlGenerator::guidForNode(const Node* node)
|
||||
return fn->guid();
|
||||
}
|
||||
case Node::Document:
|
||||
if (node->subType() != Node::QmlPropertyGroup)
|
||||
break;
|
||||
break;
|
||||
case Node::QmlPropertyGroup:
|
||||
case Node::QmlProperty:
|
||||
case Node::Property:
|
||||
return node->guid();
|
||||
@ -3743,7 +3743,7 @@ QString DitaXmlGenerator::linkForNode(const Node* node, const Node* relative)
|
||||
}
|
||||
QString link = fn;
|
||||
|
||||
if (!node->isInnerNode() || node->subType() == Node::QmlPropertyGroup) {
|
||||
if (!node->isInnerNode() || node->type() == Node::QmlPropertyGroup) {
|
||||
QString guid = guidForNode(node);
|
||||
if (relative && fn == fileName(relative) && guid == guidForNode(relative)) {
|
||||
return QString();
|
||||
@ -4079,8 +4079,8 @@ void DitaXmlGenerator::generateDetailedQmlMember(Node* node,
|
||||
QString marked;
|
||||
QmlPropertyNode* qpn = 0;
|
||||
|
||||
if (node->subType() == Node::QmlPropertyGroup) {
|
||||
const QmlPropGroupNode* qpgn = static_cast<const QmlPropGroupNode*>(node);
|
||||
if (node->type() == Node::QmlPropertyGroup) {
|
||||
const QmlPropertyGroupNode* qpgn = static_cast<const QmlPropertyGroupNode*>(node);
|
||||
NodeList::ConstIterator p = qpgn->childNodes().constBegin();
|
||||
if (qpgn->childNodes().size() == 1) {
|
||||
qpn = static_cast<QmlPropertyNode*>(*p);
|
||||
@ -4114,50 +4114,10 @@ void DitaXmlGenerator::generateDetailedQmlMember(Node* node,
|
||||
}
|
||||
else if (node->type() == Node::QmlProperty) {
|
||||
qpn = static_cast<QmlPropertyNode*>(node);
|
||||
if (qpn->qmlPropNodes().isEmpty()) {
|
||||
startQmlProperty(qpn,relative,marker);
|
||||
writeApiDesc(node, marker, node->title());
|
||||
writeEndTag(); // </qmlPropertyDetail>
|
||||
writeEndTag(); // </qmlProperty>
|
||||
}
|
||||
else if (qpn->qmlPropNodes().size() == 1) {
|
||||
Node* n = qpn->qmlPropNodes().at(0);
|
||||
if (n->type() == Node::QmlProperty) {
|
||||
qpn = static_cast<QmlPropertyNode*>(n);
|
||||
startQmlProperty(qpn,relative,marker);
|
||||
writeApiDesc(node, marker, node->title());
|
||||
writeEndTag(); // </qmlPropertyDetail>
|
||||
writeEndTag(); // </qmlProperty>
|
||||
}
|
||||
}
|
||||
else {
|
||||
/*
|
||||
The QML property node has multiple override nodes.
|
||||
Process the whole list as we would for a QML property
|
||||
group.
|
||||
*/
|
||||
writeStartTag(DT_qmlPropertyGroup);
|
||||
QString id = "id-qml-propertygroup-" + node->name();
|
||||
id.replace('.','-');
|
||||
xmlWriter().writeAttribute("id",id);
|
||||
writeStartTag(DT_apiName);
|
||||
//writeCharacters("...");
|
||||
writeEndTag(); // </apiName>
|
||||
writeStartTag(DT_qmlPropertyGroupDetail);
|
||||
writeApiDesc(node, marker, node->title());
|
||||
writeEndTag(); // </qmlPropertyGroupDetail>
|
||||
NodeList::ConstIterator p = qpn->qmlPropNodes().constBegin();
|
||||
while (p != qpn->qmlPropNodes().constEnd()) {
|
||||
if ((*p)->type() == Node::QmlProperty) {
|
||||
QmlPropertyNode* q = static_cast<QmlPropertyNode*>(*p);
|
||||
startQmlProperty(q,relative,marker);
|
||||
writeEndTag(); // </qmlPropertyDetail>
|
||||
writeEndTag(); // </qmlProperty>
|
||||
}
|
||||
++p;
|
||||
}
|
||||
writeEndTag(); // </qmlPropertyGroup
|
||||
}
|
||||
startQmlProperty(qpn,relative,marker);
|
||||
writeApiDesc(node, marker, node->title());
|
||||
writeEndTag(); // </qmlPropertyDetail>
|
||||
writeEndTag(); // </qmlProperty>
|
||||
}
|
||||
else if (node->type() == Node::QmlSignal)
|
||||
writeQmlRef(DT_qmlSignal,node,relative,marker);
|
||||
@ -5326,13 +5286,13 @@ DitaXmlGenerator::generateInnerNode(InnerNode* node)
|
||||
return;
|
||||
if (docNode->subType() == Node::Image)
|
||||
return;
|
||||
if (docNode->subType() == Node::QmlPropertyGroup)
|
||||
return;
|
||||
if (docNode->subType() == Node::Page) {
|
||||
if (node->count() > 0)
|
||||
qDebug("PAGE %s HAS CHILDREN", qPrintable(docNode->title()));
|
||||
}
|
||||
}
|
||||
else if (node->type() == Node::QmlPropertyGroup)
|
||||
return;
|
||||
|
||||
/*
|
||||
Obtain a code marker for the source file.
|
||||
@ -5487,8 +5447,6 @@ Node* DitaXmlGenerator::collectNodesByTypeAndSubtype(const InnerNode* parent)
|
||||
if (!isDuplicate(nodeSubtypeMaps[Node::QmlClass],child->title(),child))
|
||||
nodeSubtypeMaps[Node::QmlClass]->insert(child->title(),child);
|
||||
break;
|
||||
case Node::QmlPropertyGroup:
|
||||
break;
|
||||
case Node::QmlBasicType:
|
||||
if (!isDuplicate(nodeSubtypeMaps[Node::QmlBasicType],child->title(),child))
|
||||
nodeSubtypeMaps[Node::QmlBasicType]->insert(child->title(),child);
|
||||
@ -5517,6 +5475,8 @@ Node* DitaXmlGenerator::collectNodesByTypeAndSubtype(const InnerNode* parent)
|
||||
break;
|
||||
case Node::QmlProperty:
|
||||
break;
|
||||
case Node::QmlPropertyGroup:
|
||||
break;
|
||||
case Node::QmlSignal:
|
||||
break;
|
||||
case Node::QmlSignalHandler:
|
||||
|
@ -376,7 +376,7 @@ public:
|
||||
bool hasLegalese : 1;
|
||||
bool hasSectioningUnits : 1;
|
||||
DocPrivateExtra *extra;
|
||||
TopicList topics;
|
||||
TopicList topics_;
|
||||
DitaRefList ditamap_;
|
||||
};
|
||||
|
||||
@ -571,7 +571,7 @@ void DocParser::parse(const QString& source,
|
||||
cachedPos = 0;
|
||||
priv = docPrivate;
|
||||
priv->text << Atom::Nop;
|
||||
priv->topics.clear();
|
||||
priv->topics_.clear();
|
||||
|
||||
paraState = OutsideParagraph;
|
||||
inTableHeader = false;
|
||||
@ -1404,7 +1404,7 @@ void DocParser::parse(const QString& source,
|
||||
QString arg = getMetaCommandArgument(cmdStr);
|
||||
priv->metaCommandMap[cmdStr].append(ArgLocPair(arg,location()));
|
||||
if (possibleTopics.contains(cmdStr)) {
|
||||
priv->topics.append(Topic(cmdStr,arg));
|
||||
priv->topics_.append(Topic(cmdStr,arg));
|
||||
}
|
||||
}
|
||||
else if (macroHash()->contains(cmdStr)) {
|
||||
@ -2751,6 +2751,7 @@ QString DocParser::slashed(const QString& str)
|
||||
#define COMMAND_BRIEF Doc::alias("brief")
|
||||
#define COMMAND_QMLBRIEF Doc::alias("qmlbrief")
|
||||
|
||||
#if 0
|
||||
Doc::Doc(const Location& start_loc,
|
||||
const Location& end_loc,
|
||||
const QString& source,
|
||||
@ -2760,6 +2761,7 @@ Doc::Doc(const Location& start_loc,
|
||||
DocParser parser;
|
||||
parser.parse(source,priv,metaCommandSet,QSet<QString>());
|
||||
}
|
||||
#endif
|
||||
|
||||
/*!
|
||||
Parse the qdoc comment \a source. Build up a list of all the topic
|
||||
@ -3026,7 +3028,7 @@ const QSet<QString> &Doc::metaCommandsUsed() const
|
||||
*/
|
||||
const TopicList& Doc::topicsUsed() const
|
||||
{
|
||||
return priv == 0 ? *nullTopicList() : priv->topics;
|
||||
return priv == 0 ? *nullTopicList() : priv->topics_;
|
||||
}
|
||||
|
||||
ArgList Doc::metaCommandArgs(const QString& metacommand) const
|
||||
|
@ -71,7 +71,10 @@ struct Topic
|
||||
{
|
||||
QString topic;
|
||||
QString args;
|
||||
Topic() { }
|
||||
Topic(QString& t, QString a) : topic(t), args(a) { }
|
||||
bool isEmpty() const { return topic.isEmpty(); }
|
||||
void clear() { topic.clear(); args.clear(); }
|
||||
};
|
||||
typedef QList<Topic> TopicList;
|
||||
|
||||
@ -136,10 +139,6 @@ public:
|
||||
};
|
||||
|
||||
Doc() : priv(0) {}
|
||||
Doc(const Location &start_loc,
|
||||
const Location &end_loc,
|
||||
const QString &source,
|
||||
const QSet<QString> &metaCommandSet);
|
||||
Doc(const Location& start_loc,
|
||||
const Location& end_loc,
|
||||
const QString& source,
|
||||
@ -196,6 +195,7 @@ private:
|
||||
void detach();
|
||||
DocPrivate *priv;
|
||||
};
|
||||
typedef QList<Doc> DocList;
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
|
@ -301,7 +301,7 @@ QString Generator::fileBase(const Node *node) const
|
||||
node = node->relates();
|
||||
else if (!node->isInnerNode())
|
||||
node = node->parent();
|
||||
if (node->subType() == Node::QmlPropertyGroup) {
|
||||
if (node->type() == Node::QmlPropertyGroup) {
|
||||
node = node->parent();
|
||||
}
|
||||
|
||||
@ -469,7 +469,7 @@ QString Generator::fullDocumentLocation(const Node *node, bool subdir)
|
||||
parentName = fullDocumentLocation(node->relates());
|
||||
}
|
||||
else if ((parentNode = node->parent())) {
|
||||
if (parentNode->subType() == Node::QmlPropertyGroup) {
|
||||
if (parentNode->type() == Node::QmlPropertyGroup) {
|
||||
parentNode = parentNode->parent();
|
||||
parentName = fullDocumentLocation(parentNode);
|
||||
}
|
||||
@ -942,13 +942,13 @@ void Generator::generateInnerNode(InnerNode* node)
|
||||
return;
|
||||
if (docNode->subType() == Node::Image)
|
||||
return;
|
||||
if (docNode->subType() == Node::QmlPropertyGroup)
|
||||
return;
|
||||
if (docNode->subType() == Node::Page) {
|
||||
if (node->count() > 0)
|
||||
qDebug("PAGE %s HAS CHILDREN", qPrintable(docNode->title()));
|
||||
}
|
||||
}
|
||||
else if (node->type() == Node::QmlPropertyGroup)
|
||||
return;
|
||||
|
||||
/*
|
||||
Obtain a code marker for the source file.
|
||||
@ -1910,8 +1910,6 @@ QString Generator::typeString(const Node *node)
|
||||
switch (node->subType()) {
|
||||
case Node::QmlClass:
|
||||
return "type";
|
||||
case Node::QmlPropertyGroup:
|
||||
return "property group";
|
||||
case Node::QmlBasicType:
|
||||
return "type";
|
||||
default:
|
||||
@ -1926,6 +1924,16 @@ QString Generator::typeString(const Node *node)
|
||||
return "function";
|
||||
case Node::Property:
|
||||
return "property";
|
||||
case Node::QmlPropertyGroup:
|
||||
return "property group";
|
||||
case Node::QmlProperty:
|
||||
return "QML property";
|
||||
case Node::QmlSignal:
|
||||
return "QML signal";
|
||||
case Node::QmlSignalHandler:
|
||||
return "QML signal handler";
|
||||
case Node::QmlMethod:
|
||||
return "QML method";
|
||||
default:
|
||||
return "documentation";
|
||||
}
|
||||
|
@ -135,6 +135,7 @@ void HelpProjectWriter::readSelectors(SubProject &subproject, const QStringList
|
||||
typeHash["qmlsignal"] = Node::QmlSignal;
|
||||
typeHash["qmlsignalhandler"] = Node::QmlSignalHandler;
|
||||
typeHash["qmlmethod"] = Node::QmlMethod;
|
||||
typeHash["qmlpropertygroup"] = Node::QmlPropertyGroup;
|
||||
|
||||
QHash<QString, Node::SubType> subTypeHash;
|
||||
subTypeHash["example"] = Node::Example;
|
||||
@ -145,7 +146,6 @@ void HelpProjectWriter::readSelectors(SubProject &subproject, const QStringList
|
||||
subTypeHash["page"] = Node::Page;
|
||||
subTypeHash["externalpage"] = Node::ExternalPage;
|
||||
subTypeHash["qmlclass"] = Node::QmlClass;
|
||||
subTypeHash["qmlpropertygroup"] = Node::QmlPropertyGroup;
|
||||
subTypeHash["qmlbasictype"] = Node::QmlBasicType;
|
||||
|
||||
QSet<Node::SubType> allSubTypes = QSet<Node::SubType>::fromList(subTypeHash.values());
|
||||
@ -435,21 +435,24 @@ void HelpProjectWriter::generateSections(HelpProject &project,
|
||||
continue;
|
||||
|
||||
if (childNode->type() == Node::Document) {
|
||||
childMap[static_cast<const DocNode *>(childNode)->fullTitle()] = childNode;
|
||||
}
|
||||
else if (childNode->type() == Node::QmlPropertyGroup) {
|
||||
/*
|
||||
Don't visit QML property group nodes,
|
||||
but visit their children, which are all
|
||||
QML property nodes.
|
||||
|
||||
This is probably not correct anymore,
|
||||
because The Qml Property Group is an
|
||||
actual documented thing.
|
||||
*/
|
||||
if (childNode->subType() == Node::QmlPropertyGroup) {
|
||||
const InnerNode* inner = static_cast<const InnerNode*>(childNode);
|
||||
foreach (const Node* n, inner->childNodes()) {
|
||||
if (n->access() == Node::Private)
|
||||
continue;
|
||||
childMap[n->fullDocumentName()] = n;
|
||||
}
|
||||
const InnerNode* inner = static_cast<const InnerNode*>(childNode);
|
||||
foreach (const Node* n, inner->childNodes()) {
|
||||
if (n->access() == Node::Private)
|
||||
continue;
|
||||
childMap[n->fullDocumentName()] = n;
|
||||
}
|
||||
else
|
||||
childMap[static_cast<const DocNode *>(childNode)->fullTitle()] = childNode;
|
||||
}
|
||||
else {
|
||||
// Store member status of children
|
||||
|
@ -3266,8 +3266,8 @@ QString HtmlGenerator::refForNode(const Node *node)
|
||||
}
|
||||
break;
|
||||
case Node::Document:
|
||||
if (node->subType() != Node::QmlPropertyGroup)
|
||||
break;
|
||||
break;
|
||||
case Node::QmlPropertyGroup:
|
||||
case Node::QmlProperty:
|
||||
case Node::Property:
|
||||
ref = node->name() + "-prop";
|
||||
@ -3330,7 +3330,7 @@ QString HtmlGenerator::linkForNode(const Node *node, const Node *relative)
|
||||
}
|
||||
QString link = fn;
|
||||
|
||||
if (!node->isInnerNode() || node->subType() == Node::QmlPropertyGroup) {
|
||||
if (!node->isInnerNode() || node->type() == Node::QmlPropertyGroup) {
|
||||
QString ref = refForNode(node);
|
||||
if (relative && fn == fileName(relative) && ref == refForNode(relative))
|
||||
return QString();
|
||||
@ -3736,6 +3736,22 @@ void HtmlGenerator::generateQmlSummary(const Section& section,
|
||||
while (m != section.members.constEnd()) {
|
||||
out() << "<li class=\"fn\">";
|
||||
generateQmlItem(*m,relative,marker,true);
|
||||
if ((*m)->type() == Node::QmlPropertyGroup) {
|
||||
const QmlPropertyGroupNode* qpgn = static_cast<const QmlPropertyGroupNode*>(*m);
|
||||
if (!qpgn->childNodes().isEmpty()) {
|
||||
NodeList::ConstIterator p = qpgn->childNodes().constBegin();
|
||||
out() << "<ul>\n";
|
||||
while (p != qpgn->childNodes().constEnd()) {
|
||||
if ((*p)->type() == Node::QmlProperty) {
|
||||
out() << "<li class=\"fn\">";
|
||||
generateQmlItem(*p, relative, marker, true);
|
||||
out() << "</li>\n";
|
||||
}
|
||||
++p;
|
||||
}
|
||||
out() << "</ul>\n";
|
||||
}
|
||||
}
|
||||
out() << "</li>\n";
|
||||
++m;
|
||||
}
|
||||
@ -3757,11 +3773,18 @@ void HtmlGenerator::generateDetailedQmlMember(Node *node,
|
||||
#endif
|
||||
generateExtractionMark(node, MemberMark);
|
||||
out() << "<div class=\"qmlitem\">";
|
||||
if (node->subType() == Node::QmlPropertyGroup) {
|
||||
const QmlPropGroupNode* qpgn = static_cast<const QmlPropGroupNode*>(node);
|
||||
if (node->type() == Node::QmlPropertyGroup) {
|
||||
const QmlPropertyGroupNode* qpgn = static_cast<const QmlPropertyGroupNode*>(node);
|
||||
NodeList::ConstIterator p = qpgn->childNodes().constBegin();
|
||||
out() << "<div class=\"qmlproto\">";
|
||||
out() << "<table class=\"qmlname\">";
|
||||
|
||||
QString heading = "Property Group: " + qpgn->name();
|
||||
out() << "<tr valign=\"top\" class=\"even\">";
|
||||
out() << "<th class=\"centerAlign\"><p>";
|
||||
out() << "<a name=\"" + refForNode(qpgn) + "\"></a>";
|
||||
out() << "<b>" << heading << "</b>";
|
||||
out() << "</p></th></tr>";
|
||||
while (p != qpgn->childNodes().constEnd()) {
|
||||
if ((*p)->type() == Node::QmlProperty) {
|
||||
qpn = static_cast<QmlPropertyNode*>(*p);
|
||||
@ -3783,68 +3806,23 @@ void HtmlGenerator::generateDetailedQmlMember(Node *node,
|
||||
}
|
||||
else if (node->type() == Node::QmlProperty) {
|
||||
qpn = static_cast<QmlPropertyNode*>(node);
|
||||
/*
|
||||
If the QML property node has a single subproperty,
|
||||
override, replace qpn with that override node and
|
||||
proceed as normal.
|
||||
*/
|
||||
if (qpn->qmlPropNodes().size() == 1) {
|
||||
Node* n = qpn->qmlPropNodes().at(0);
|
||||
if (n->type() == Node::QmlProperty)
|
||||
qpn = static_cast<QmlPropertyNode*>(n);
|
||||
}
|
||||
/*
|
||||
Now qpn either has no overrides, or it has more
|
||||
than 1. If it has none, proceed to output as nortmal.
|
||||
*/
|
||||
if (qpn->qmlPropNodes().isEmpty()) {
|
||||
out() << "<div class=\"qmlproto\">";
|
||||
out() << "<table class=\"qmlname\">";
|
||||
out() << "<tr valign=\"top\" class=\"odd\">";
|
||||
out() << "<td class=\"tblQmlPropNode\"><p>";
|
||||
out() << "<a name=\"" + refForNode(qpn) + "\"></a>";
|
||||
if (!qpn->isReadOnlySet()) {
|
||||
if (qpn->declarativeCppNode())
|
||||
qpn->setReadOnly(!qpn->isWritable(qdb_));
|
||||
}
|
||||
if (qpn->isReadOnly())
|
||||
out() << "<span class=\"qmlreadonly\">read-only</span>";
|
||||
if (qpn->isDefault())
|
||||
out() << "<span class=\"qmldefault\">default</span>";
|
||||
generateQmlItem(qpn, relative, marker, false);
|
||||
out() << "</p></td></tr>";
|
||||
out() << "</table>";
|
||||
out() << "</div>";
|
||||
}
|
||||
else {
|
||||
/*
|
||||
The QML property node has multiple override nodes.
|
||||
Process the whole list as we would for a QML property
|
||||
group.
|
||||
*/
|
||||
NodeList::ConstIterator p = qpn->qmlPropNodes().constBegin();
|
||||
out() << "<div class=\"qmlproto\">";
|
||||
out() << "<table class=\"qmlname\">";
|
||||
while (p != qpn->qmlPropNodes().constEnd()) {
|
||||
if ((*p)->type() == Node::QmlProperty) {
|
||||
QmlPropertyNode* q = static_cast<QmlPropertyNode*>(*p);
|
||||
out() << "<tr valign=\"top\" class=\"odd\">";
|
||||
out() << "<td class=\"tblQmlPropNode\"><p>";
|
||||
out() << "<a name=\"" + refForNode(q) + "\"></a>";
|
||||
if (!qpn->isReadOnlySet())
|
||||
qpn->setReadOnly(!qpn->isWritable(qdb_));
|
||||
if (qpn->isReadOnly())
|
||||
out() << "<span class=\"qmlreadonly\">read-only</span>";
|
||||
if (qpn->isDefault())
|
||||
out() << "<span class=\"qmldefault\">default</span>";
|
||||
generateQmlItem(q, relative, marker, false);
|
||||
out() << "</p></td></tr>";
|
||||
}
|
||||
++p;
|
||||
}
|
||||
out() << "</table>";
|
||||
out() << "</div>";
|
||||
out() << "<div class=\"qmlproto\">";
|
||||
out() << "<table class=\"qmlname\">";
|
||||
out() << "<tr valign=\"top\" class=\"odd\">";
|
||||
out() << "<td class=\"tblQmlPropNode\"><p>";
|
||||
out() << "<a name=\"" + refForNode(qpn) + "\"></a>";
|
||||
if (!qpn->isReadOnlySet()) {
|
||||
if (qpn->declarativeCppNode())
|
||||
qpn->setReadOnly(!qpn->isWritable(qdb_));
|
||||
}
|
||||
if (qpn->isReadOnly())
|
||||
out() << "<span class=\"qmlreadonly\">read-only</span>";
|
||||
if (qpn->isDefault())
|
||||
out() << "<span class=\"qmldefault\">default</span>";
|
||||
generateQmlItem(qpn, relative, marker, false);
|
||||
out() << "</p></td></tr>";
|
||||
out() << "</table>";
|
||||
out() << "</div>";
|
||||
}
|
||||
else if (node->type() == Node::QmlSignal) {
|
||||
const FunctionNode* qsn = static_cast<const FunctionNode*>(node);
|
||||
@ -4317,8 +4295,6 @@ void HtmlGenerator::reportOrphans(const InnerNode* parent)
|
||||
break;
|
||||
case Node::QmlClass:
|
||||
break;
|
||||
case Node::QmlPropertyGroup:
|
||||
break;
|
||||
case Node::QmlBasicType:
|
||||
break;
|
||||
case Node::QmlModule:
|
||||
@ -4352,6 +4328,8 @@ void HtmlGenerator::reportOrphans(const InnerNode* parent)
|
||||
if (!related)
|
||||
child->location().warning(tr("Global variable, %1, %2").arg(child->name()).arg(message));
|
||||
break;
|
||||
case Node::QmlPropertyGroup:
|
||||
break;
|
||||
case Node::QmlProperty:
|
||||
if (!related)
|
||||
child->location().warning(tr("Global QML property, %1, %2").arg(child->name()).arg(message));
|
||||
|
@ -151,11 +151,11 @@ QString Node::fullName(const Node* relative) const
|
||||
*/
|
||||
void Node::setDoc(const Doc& doc, bool replace)
|
||||
{
|
||||
if (!d.isEmpty() && !replace) {
|
||||
if (!doc_.isEmpty() && !replace) {
|
||||
doc.location().warning(tr("Overrides a previous doc"));
|
||||
d.location().warning(tr("(The previous doc is here)"));
|
||||
doc_.location().warning(tr("(The previous doc is here)"));
|
||||
}
|
||||
d = doc;
|
||||
doc_ = doc;
|
||||
}
|
||||
|
||||
/*!
|
||||
@ -311,6 +311,8 @@ QString Node::nodeTypeString(unsigned t)
|
||||
return "variable";
|
||||
case QmlProperty:
|
||||
return "QML property";
|
||||
case QmlPropertyGroup:
|
||||
return "QML property group";
|
||||
case QmlSignal:
|
||||
return "QML signal";
|
||||
case QmlSignalHandler:
|
||||
@ -359,8 +361,6 @@ QString Node::nodeSubtypeString(unsigned t)
|
||||
return "external page";
|
||||
case QmlClass:
|
||||
return "QML type";
|
||||
case QmlPropertyGroup:
|
||||
return "QML property group";
|
||||
case QmlBasicType:
|
||||
return "QML basic type";
|
||||
case QmlModule:
|
||||
@ -742,12 +742,12 @@ void InnerNode::getMemberClasses(NodeMap& out)
|
||||
Node *InnerNode::findChildNodeByName(const QString& name)
|
||||
{
|
||||
Node *node = childMap.value(name);
|
||||
if (node && node->subType() != QmlPropertyGroup)
|
||||
if (node && node->type() != QmlPropertyGroup)
|
||||
return node;
|
||||
if ((type() == Document) && (subType() == QmlClass)) {
|
||||
for (int i=0; i<children_.size(); ++i) {
|
||||
Node* n = children_.at(i);
|
||||
if (n->subType() == QmlPropertyGroup) {
|
||||
if (n->type() == QmlPropertyGroup) {
|
||||
node = static_cast<InnerNode*>(n)->findChildNodeByName(name);
|
||||
if (node)
|
||||
return node;
|
||||
@ -771,7 +771,7 @@ void InnerNode::findNodes(const QString& name, QList<Node*>& n)
|
||||
if ((type() == Document) && (subType() == QmlClass)) {
|
||||
for (int i=0; i<children_.size(); ++i) {
|
||||
node = children_.at(i);
|
||||
if (node->subType() == QmlPropertyGroup) {
|
||||
if (node->type() == QmlPropertyGroup) {
|
||||
node = static_cast<InnerNode*>(node)->findChildNodeByName(name);
|
||||
if (node) {
|
||||
n.append(node);
|
||||
@ -793,7 +793,7 @@ void InnerNode::findNodes(const QString& name, QList<Node*>& n)
|
||||
*/
|
||||
for (int i=0; i<nodes.size(); ++i) {
|
||||
node = nodes.at(i);
|
||||
if (node->subType() != QmlPropertyGroup)
|
||||
if (node->type() != QmlPropertyGroup)
|
||||
n.append(node);
|
||||
else {
|
||||
node = static_cast<InnerNode*>(node)->findChildNodeByName(name);
|
||||
@ -829,14 +829,14 @@ Node* InnerNode::findChildNodeByName(const QString& name, bool qml)
|
||||
if (!node->isQmlNode())
|
||||
return node;
|
||||
}
|
||||
else if (node->isQmlNode() && (node->subType() != QmlPropertyGroup))
|
||||
else if (node->isQmlNode() && (node->type() != QmlPropertyGroup))
|
||||
return node;
|
||||
}
|
||||
}
|
||||
if (qml && (type() == Document) && (subType() == QmlClass)) {
|
||||
for (int i=0; i<children_.size(); ++i) {
|
||||
Node* node = children_.at(i);
|
||||
if (node->subType() == QmlPropertyGroup) {
|
||||
if (node->type() == QmlPropertyGroup) {
|
||||
node = static_cast<InnerNode*>(node)->findChildNodeByName(name);
|
||||
if (node)
|
||||
return node;
|
||||
@ -1370,6 +1370,26 @@ void InnerNode::removeRelated(Node *pseudoChild)
|
||||
related_.removeAll(pseudoChild);
|
||||
}
|
||||
|
||||
/*!
|
||||
If this node has a child that is a QML property named \a n,
|
||||
return the pointer to that child.
|
||||
*/
|
||||
QmlPropertyNode* InnerNode::hasQmlProperty(const QString& n) const
|
||||
{
|
||||
foreach (Node* child, childNodes()) {
|
||||
if (child->type() == Node::QmlProperty) {
|
||||
if (child->name() == n)
|
||||
return static_cast<QmlPropertyNode*>(child);
|
||||
}
|
||||
else if (child->type() == Node::QmlPropertyGroup) {
|
||||
QmlPropertyNode* t = child->hasQmlProperty(n);
|
||||
if (t)
|
||||
return t;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*!
|
||||
\class LeafNode
|
||||
*/
|
||||
@ -1672,25 +1692,6 @@ QString DocNode::subTitle() const
|
||||
return QString();
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns true if this QML type or property group contains a
|
||||
property named \a name.
|
||||
*/
|
||||
bool DocNode::hasProperty(const QString& name) const
|
||||
{
|
||||
foreach (Node* child, childNodes()) {
|
||||
if (child->type() == Node::Document && child->subType() == Node::QmlPropertyGroup) {
|
||||
if (child->hasProperty(name))
|
||||
return true;
|
||||
}
|
||||
else if (child->type() == Node::QmlProperty) {
|
||||
if (child->hasProperty(name))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/*!
|
||||
The constructor calls the DocNode constructor with
|
||||
\a parent, \a name, and Node::Example.
|
||||
@ -2273,8 +2274,8 @@ QmlBasicTypeNode::QmlBasicTypeNode(InnerNode *parent,
|
||||
Constructor for the Qml property group node. \a parent is
|
||||
always a QmlClassNode.
|
||||
*/
|
||||
QmlPropGroupNode::QmlPropGroupNode(QmlClassNode* parent, const QString& name)
|
||||
: DocNode(parent, name, QmlPropertyGroup, Node::ApiPage)
|
||||
QmlPropertyGroupNode::QmlPropertyGroupNode(QmlClassNode* parent, const QString& name)
|
||||
: InnerNode(QmlPropertyGroup, parent, name)
|
||||
{
|
||||
idNumber_ = -1;
|
||||
}
|
||||
@ -2286,24 +2287,17 @@ QmlPropGroupNode::QmlPropGroupNode(QmlClassNode* parent, const QString& name)
|
||||
property group count and set the id number to the new
|
||||
value.
|
||||
*/
|
||||
QString QmlPropGroupNode::idNumber()
|
||||
QString QmlPropertyGroupNode::idNumber()
|
||||
{
|
||||
if (idNumber_ == -1)
|
||||
idNumber_ = incPropertyGroupCount();
|
||||
return QString().setNum(idNumber_);
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
Constructor for the QML property node, when the \a parent
|
||||
is QML property group node. This constructor is only used
|
||||
for creating QML property nodes for QML elements, i.e.
|
||||
not for creating QML property nodes for QML components.
|
||||
Hopefully, this constructor will become obsolete, so don't
|
||||
use it unless one of the other two constructors can't be
|
||||
used.
|
||||
Constructor for the QML property node.
|
||||
*/
|
||||
QmlPropertyNode::QmlPropertyNode(QmlPropGroupNode *parent,
|
||||
QmlPropertyNode::QmlPropertyNode(InnerNode* parent,
|
||||
const QString& name,
|
||||
const QString& type,
|
||||
bool attached)
|
||||
@ -2311,56 +2305,14 @@ QmlPropertyNode::QmlPropertyNode(QmlPropGroupNode *parent,
|
||||
type_(type),
|
||||
stored_(FlagValueDefault),
|
||||
designable_(FlagValueDefault),
|
||||
isAlias_(false),
|
||||
isdefault_(false),
|
||||
attached_(attached),
|
||||
readOnly_(FlagValueDefault)
|
||||
{
|
||||
setPageType(ApiPage);
|
||||
}
|
||||
|
||||
/*!
|
||||
Constructor for the QML property node, when the \a parent
|
||||
is a QML class node.
|
||||
*/
|
||||
QmlPropertyNode::QmlPropertyNode(QmlClassNode *parent,
|
||||
const QString& name,
|
||||
const QString& type,
|
||||
bool attached)
|
||||
: LeafNode(QmlProperty, parent, name),
|
||||
type_(type),
|
||||
stored_(FlagValueDefault),
|
||||
designable_(FlagValueDefault),
|
||||
isdefault_(false),
|
||||
attached_(attached),
|
||||
readOnly_(FlagValueDefault)
|
||||
{
|
||||
setPageType(ApiPage);
|
||||
}
|
||||
|
||||
/*!
|
||||
Constructor for the QML property node, when the \a parent
|
||||
is a QML property node. Strictly speaking, this is not the
|
||||
way QML property nodes were originally meant to be built,
|
||||
because this constructor has another QML property node as
|
||||
its parent. But this constructor is useful for documenting
|
||||
QML properties in QML components, i.e., when you override
|
||||
the definition of a property with the \e{qmlproperty}
|
||||
command. It actually uses the parent of \a parent as the
|
||||
parent.
|
||||
*/
|
||||
QmlPropertyNode::QmlPropertyNode(QmlPropertyNode* parent,
|
||||
const QString& name,
|
||||
const QString& type,
|
||||
bool attached)
|
||||
: LeafNode(parent->parent(), QmlProperty, name),
|
||||
type_(type),
|
||||
stored_(FlagValueDefault),
|
||||
designable_(FlagValueDefault),
|
||||
isdefault_(false),
|
||||
attached_(attached),
|
||||
readOnly_(FlagValueDefault)
|
||||
{
|
||||
setPageType(ApiPage);
|
||||
if (type_ == QString("alias"))
|
||||
isAlias_ = true;
|
||||
}
|
||||
|
||||
/*!
|
||||
@ -2450,23 +2402,6 @@ PropertyNode* QmlPropertyNode::correspondingProperty(QDocDatabase* qdb)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns true if this QML type or property group contains a
|
||||
property named \a name.
|
||||
*/
|
||||
bool QmlPropertyNode::hasProperty(const QString& n) const
|
||||
{
|
||||
if (name() == n)
|
||||
return true;
|
||||
foreach (Node* child, qmlPropNodes()) {
|
||||
if (child->type() == Node::QmlProperty) {
|
||||
if (child->name() == n)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/*! \class NameCollisionNode
|
||||
|
||||
An instance of this node is inserted in the tree
|
||||
@ -2586,11 +2521,10 @@ QString Node::fullDocumentName() const
|
||||
const Node* n = this;
|
||||
|
||||
do {
|
||||
if (!n->name().isEmpty() &&
|
||||
((n->type() != Node::Document) || (n->subType() != Node::QmlPropertyGroup)))
|
||||
if (!n->name().isEmpty() && n->type() != Node::QmlPropertyGroup)
|
||||
pieces.insert(0, n->name());
|
||||
|
||||
if ((n->type() == Node::Document) && (n->subType() != Node::QmlPropertyGroup)) {
|
||||
if (n->type() == Node::Document) {
|
||||
if ((n->subType() == Node::QmlClass) && !n->qmlModuleName().isEmpty())
|
||||
pieces.insert(0, n->qmlModuleIdentifier());
|
||||
break;
|
||||
@ -2806,12 +2740,6 @@ QString Node::idForNode() const
|
||||
case Node::QmlClass:
|
||||
str = "qml-class-" + name();
|
||||
break;
|
||||
case Node::QmlPropertyGroup:
|
||||
{
|
||||
Node* n = const_cast<Node*>(this);
|
||||
str = "qml-propertygroup-" + n->name();
|
||||
}
|
||||
break;
|
||||
case Node::Page:
|
||||
case Node::Group:
|
||||
case Node::Module:
|
||||
@ -2852,6 +2780,12 @@ QString Node::idForNode() const
|
||||
case Node::QmlProperty:
|
||||
str = "qml-property-" + name();
|
||||
break;
|
||||
case Node::QmlPropertyGroup:
|
||||
{
|
||||
Node* n = const_cast<Node*>(this);
|
||||
str = "qml-propertygroup-" + n->name();
|
||||
}
|
||||
break;
|
||||
case Node::Property:
|
||||
str = "property-" + name();
|
||||
break;
|
||||
|
@ -60,6 +60,7 @@ class InnerNode;
|
||||
class ExampleNode;
|
||||
class QmlClassNode;
|
||||
class QDocDatabase;
|
||||
class QmlPropertyNode;
|
||||
|
||||
typedef QList<Node*> NodeList;
|
||||
typedef QMap<QString, Node*> NodeMap;
|
||||
@ -80,6 +81,7 @@ public:
|
||||
Function,
|
||||
Property,
|
||||
Variable,
|
||||
QmlPropertyGroup,
|
||||
QmlProperty,
|
||||
QmlSignal,
|
||||
QmlSignalHandler,
|
||||
@ -98,7 +100,6 @@ public:
|
||||
Page,
|
||||
ExternalPage,
|
||||
QmlClass,
|
||||
QmlPropertyGroup,
|
||||
QmlBasicType,
|
||||
QmlModule,
|
||||
DitaMap,
|
||||
@ -200,8 +201,11 @@ public:
|
||||
virtual bool isQmlPropertyGroup() const { return false; }
|
||||
virtual bool isCollisionNode() const { return false; }
|
||||
virtual bool isAttached() const { return false; }
|
||||
virtual bool isAlias() const { return false; }
|
||||
virtual bool isGroup() const { return false; }
|
||||
virtual bool isWrapper() const;
|
||||
virtual bool isReadOnly() const { return false; }
|
||||
virtual bool isDefault() const { return false; }
|
||||
virtual void addMember(Node* ) { }
|
||||
virtual bool hasMembers() const { return false; }
|
||||
virtual bool hasNamespaces() const { return false; }
|
||||
@ -209,10 +213,12 @@ public:
|
||||
virtual void setAbstract(bool ) { }
|
||||
virtual void setWrapper() { }
|
||||
virtual QString title() const { return QString(); }
|
||||
virtual bool hasProperty(const QString& ) const { return false; }
|
||||
virtual QmlPropertyNode* hasQmlProperty(const QString& ) const { return 0; }
|
||||
virtual void getMemberNamespaces(NodeMap& ) { }
|
||||
virtual void getMemberClasses(NodeMap& ) { }
|
||||
virtual bool isInternal() const;
|
||||
virtual void setDataType(const QString& ) { }
|
||||
virtual void setReadOnly(bool ) { }
|
||||
bool isIndexNode() const { return indexNodeFlag_; }
|
||||
bool wasSeen() const { return seen_; }
|
||||
Type type() const { return nodeType_; }
|
||||
@ -231,7 +237,7 @@ public:
|
||||
Access access() const { return access_; }
|
||||
QString accessString() const;
|
||||
const Location& location() const { return loc; }
|
||||
const Doc& doc() const { return d; }
|
||||
const Doc& doc() const { return doc_; }
|
||||
Status status() const { return status_; }
|
||||
Status inheritedStatus() const;
|
||||
ThreadSafeness threadSafeness() const;
|
||||
@ -294,7 +300,7 @@ private:
|
||||
InnerNode* relatesTo_;
|
||||
QString name_;
|
||||
Location loc;
|
||||
Doc d;
|
||||
Doc doc_;
|
||||
QMap<LinkType, QPair<QString, QString> > linkMap_;
|
||||
QString moduleName_;
|
||||
QString url_;
|
||||
@ -366,6 +372,7 @@ public:
|
||||
virtual void setCurrentChild(InnerNode* ) { }
|
||||
virtual void setOutputFileName(const QString& f) { outputFileName_ = f; }
|
||||
virtual QString outputFileName() const { return outputFileName_; }
|
||||
virtual QmlPropertyNode* hasQmlProperty(const QString& ) const;
|
||||
|
||||
void printChildren(const QString& title);
|
||||
void printMembers(const QString& title);
|
||||
@ -497,8 +504,6 @@ public:
|
||||
virtual QString nameForLists() const { return title(); }
|
||||
virtual void setImageFileName(const QString& ) { }
|
||||
virtual bool isGroup() const { return (subType() == Node::Group); }
|
||||
virtual bool isQmlPropertyGroup() const { return (nodeSubtype_ == QmlPropertyGroup); }
|
||||
virtual bool hasProperty(const QString& ) const;
|
||||
|
||||
protected:
|
||||
SubType nodeSubtype_;
|
||||
@ -619,11 +624,11 @@ public:
|
||||
virtual bool isQmlNode() const { return true; }
|
||||
};
|
||||
|
||||
class QmlPropGroupNode : public DocNode
|
||||
class QmlPropertyGroupNode : public InnerNode
|
||||
{
|
||||
public:
|
||||
QmlPropGroupNode(QmlClassNode* parent, const QString& name);
|
||||
virtual ~QmlPropGroupNode() { }
|
||||
QmlPropertyGroupNode(QmlClassNode* parent, const QString& name);
|
||||
virtual ~QmlPropertyGroupNode() { }
|
||||
virtual bool isQmlNode() const { return true; }
|
||||
virtual bool isQtQuickNode() const { return parent()->isQtQuickNode(); }
|
||||
virtual QString qmlTypeName() const { return parent()->qmlTypeName(); }
|
||||
@ -631,6 +636,7 @@ public:
|
||||
virtual QString qmlModuleVersion() const { return parent()->qmlModuleVersion(); }
|
||||
virtual QString qmlModuleIdentifier() const { return parent()->qmlModuleIdentifier(); }
|
||||
virtual QString idNumber();
|
||||
virtual bool isQmlPropertyGroup() const { return true; }
|
||||
|
||||
const QString& element() const { return parent()->name(); }
|
||||
|
||||
@ -645,34 +651,27 @@ class QmlPropertyNode : public LeafNode
|
||||
Q_DECLARE_TR_FUNCTIONS(QDoc::QmlPropertyNode)
|
||||
|
||||
public:
|
||||
QmlPropertyNode(QmlClassNode *parent,
|
||||
const QString& name,
|
||||
const QString& type,
|
||||
bool attached);
|
||||
QmlPropertyNode(QmlPropGroupNode* parent,
|
||||
const QString& name,
|
||||
const QString& type,
|
||||
bool attached);
|
||||
QmlPropertyNode(QmlPropertyNode* parent,
|
||||
QmlPropertyNode(InnerNode *parent,
|
||||
const QString& name,
|
||||
const QString& type,
|
||||
bool attached);
|
||||
virtual ~QmlPropertyNode() { }
|
||||
|
||||
void setDataType(const QString& dataType) { type_ = dataType; }
|
||||
virtual void setDataType(const QString& dataType) { type_ = dataType; }
|
||||
void setStored(bool stored) { stored_ = toFlagValue(stored); }
|
||||
void setDesignable(bool designable) { designable_ = toFlagValue(designable); }
|
||||
void setReadOnly(bool ro) { readOnly_ = toFlagValue(ro); }
|
||||
virtual void setReadOnly(bool ro) { readOnly_ = toFlagValue(ro); }
|
||||
void setDefault() { isdefault_ = true; }
|
||||
|
||||
const QString &dataType() const { return type_; }
|
||||
QString qualifiedDataType() const { return type_; }
|
||||
bool isReadOnlySet() const { return (readOnly_ != FlagValueDefault); }
|
||||
bool isDefault() const { return isdefault_; }
|
||||
bool isStored() const { return fromFlagValue(stored_,true); }
|
||||
bool isDesignable() const { return fromFlagValue(designable_,false); }
|
||||
bool isWritable(QDocDatabase* qdb);
|
||||
bool isReadOnly() const { return fromFlagValue(readOnly_,false); }
|
||||
virtual bool isDefault() const { return isdefault_; }
|
||||
virtual bool isReadOnly() const { return fromFlagValue(readOnly_,false); }
|
||||
virtual bool isAlias() const { return isAlias_; }
|
||||
virtual bool isAttached() const { return attached_; }
|
||||
virtual bool isQmlNode() const { return true; }
|
||||
virtual bool isQtQuickNode() const { return parent()->isQtQuickNode(); }
|
||||
@ -680,22 +679,19 @@ public:
|
||||
virtual QString qmlModuleName() const { return parent()->qmlModuleName(); }
|
||||
virtual QString qmlModuleVersion() const { return parent()->qmlModuleVersion(); }
|
||||
virtual QString qmlModuleIdentifier() const { return parent()->qmlModuleIdentifier(); }
|
||||
virtual bool hasProperty(const QString& name) const;
|
||||
|
||||
PropertyNode* correspondingProperty(QDocDatabase* qdb);
|
||||
|
||||
const QString& element() const { return static_cast<QmlPropGroupNode*>(parent())->element(); }
|
||||
void appendQmlPropNode(QmlPropertyNode* p) { qmlPropNodes_.append(p); }
|
||||
const NodeList& qmlPropNodes() const { return qmlPropNodes_; }
|
||||
const QString& element() const { return static_cast<QmlPropertyGroupNode*>(parent())->element(); }
|
||||
|
||||
private:
|
||||
QString type_;
|
||||
FlagValue stored_;
|
||||
FlagValue designable_;
|
||||
bool isAlias_;
|
||||
bool isdefault_;
|
||||
bool attached_;
|
||||
FlagValue readOnly_;
|
||||
NodeList qmlPropNodes_;
|
||||
};
|
||||
|
||||
class EnumItem
|
||||
@ -892,7 +888,7 @@ public:
|
||||
PropertyNode(InnerNode* parent, const QString& name);
|
||||
virtual ~PropertyNode() { }
|
||||
|
||||
void setDataType(const QString& dataType) { type_ = dataType; }
|
||||
virtual void setDataType(const QString& dataType) { type_ = dataType; }
|
||||
void addFunction(FunctionNode* function, FunctionRole role);
|
||||
void addSignal(FunctionNode* function, FunctionRole role);
|
||||
void setStored(bool stored) { stored_ = toFlagValue(stored); }
|
||||
|
@ -118,9 +118,9 @@ void PureDocParser::parseSourceFile(const Location& location, const QString& fil
|
||||
*/
|
||||
bool PureDocParser::processQdocComments()
|
||||
{
|
||||
QSet<QString> topicCommandsAllowed = topicCommands();
|
||||
QSet<QString> otherMetacommandsAllowed = otherMetaCommands();
|
||||
QSet<QString> metacommandsAllowed = topicCommandsAllowed + otherMetacommandsAllowed;
|
||||
const QSet<QString>& topicCommandsAllowed = topicCommands();
|
||||
const QSet<QString>& otherMetacommandsAllowed = otherMetaCommands();
|
||||
const QSet<QString>& metacommandsAllowed = topicCommandsAllowed + otherMetacommandsAllowed;
|
||||
|
||||
while (tok != Tok_Eoi) {
|
||||
if (tok == Tok_Doc) {
|
||||
@ -137,55 +137,68 @@ bool PureDocParser::processQdocComments()
|
||||
/*
|
||||
Doc parses the comment.
|
||||
*/
|
||||
Doc doc(start_loc,end_loc,comment,metacommandsAllowed);
|
||||
Doc doc(start_loc, end_loc, comment, metacommandsAllowed, topicCommandsAllowed);
|
||||
|
||||
QString topic;
|
||||
ArgList args;
|
||||
bool isQmlPropertyTopic = false;
|
||||
|
||||
QSet<QString> topicCommandsUsed = topicCommandsAllowed & doc.metaCommandsUsed();
|
||||
|
||||
/*
|
||||
There should be one topic command in the set,
|
||||
or none. If the set is empty, then the comment
|
||||
should be a function description.
|
||||
*/
|
||||
if (topicCommandsUsed.count() > 0) {
|
||||
topic = *topicCommandsUsed.begin();
|
||||
args = doc.metaCommandArgs(topic);
|
||||
const TopicList& topics = doc.topicsUsed();
|
||||
if (!topics.isEmpty()) {
|
||||
topic = topics[0].topic;
|
||||
if ((topic == COMMAND_QMLPROPERTY) ||
|
||||
(topic == COMMAND_QMLPROPERTYGROUP) ||
|
||||
(topic == COMMAND_QMLATTACHEDPROPERTY)) {
|
||||
isQmlPropertyTopic = true;
|
||||
}
|
||||
}
|
||||
if (isQmlPropertyTopic && topics.size() > 1) {
|
||||
qDebug() << "MULTIPLE TOPICS:" << doc.location().fileName() << doc.location().lineNo();
|
||||
for (int i=0; i<topics.size(); ++i) {
|
||||
qDebug() << " " << topics[i].topic << topics[i].args;
|
||||
}
|
||||
}
|
||||
|
||||
NodeList nodes;
|
||||
QList<Doc> docs;
|
||||
DocList docs;
|
||||
|
||||
if (topic.isEmpty()) {
|
||||
doc.location().warning(tr("This qdoc comment contains no topic command "
|
||||
"(e.g., '\\%1', '\\%2').")
|
||||
.arg(COMMAND_MODULE).arg(COMMAND_PAGE));
|
||||
}
|
||||
else if (isQmlPropertyTopic) {
|
||||
Doc nodeDoc = doc;
|
||||
processQmlProperties(nodeDoc, nodes, docs);
|
||||
}
|
||||
else {
|
||||
/*
|
||||
There is a topic command. Process it.
|
||||
*/
|
||||
if ((topic == COMMAND_QMLPROPERTY) ||
|
||||
(topic == COMMAND_QMLATTACHEDPROPERTY)) {
|
||||
ArgList args;
|
||||
QSet<QString> topicCommandsUsed = topicCommandsAllowed & doc.metaCommandsUsed();
|
||||
if (topicCommandsUsed.count() > 0) {
|
||||
topic = *topicCommandsUsed.begin();
|
||||
args = doc.metaCommandArgs(topic);
|
||||
}
|
||||
if (topicCommandsUsed.count() > 1) {
|
||||
QString topics;
|
||||
QSet<QString>::ConstIterator t = topicCommandsUsed.constBegin();
|
||||
while (t != topicCommandsUsed.constEnd()) {
|
||||
topics += " \\" + *t + ",";
|
||||
++t;
|
||||
}
|
||||
topics[topics.lastIndexOf(',')] = '.';
|
||||
int i = topics.lastIndexOf(',');
|
||||
topics[i] = ' ';
|
||||
topics.insert(i+1,"and");
|
||||
doc.location().warning(tr("Multiple topic commands found in comment: %1").arg(topics));
|
||||
}
|
||||
ArgList::ConstIterator a = args.begin();
|
||||
while (a != args.end()) {
|
||||
Doc nodeDoc = doc;
|
||||
Node* node = processTopicCommandGroup(nodeDoc,topic,args);
|
||||
Node* node = processTopicCommand(nodeDoc,topic,*a);
|
||||
if (node != 0) {
|
||||
nodes.append(node);
|
||||
docs.append(nodeDoc);
|
||||
}
|
||||
}
|
||||
else {
|
||||
ArgList::ConstIterator a = args.begin();
|
||||
while (a != args.end()) {
|
||||
Doc nodeDoc = doc;
|
||||
Node* node = processTopicCommand(nodeDoc,topic,*a);
|
||||
if (node != 0) {
|
||||
nodes.append(node);
|
||||
docs.append(nodeDoc);
|
||||
}
|
||||
++a;
|
||||
}
|
||||
++a;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -612,7 +612,7 @@ void QDocDatabase::findAllObsoleteThings(const InnerNode* node)
|
||||
case Node::QmlMethod:
|
||||
if ((*c)->parent()) {
|
||||
Node* parent = (*c)->parent();
|
||||
if (parent->subType() == Node::QmlPropertyGroup && parent->parent())
|
||||
if (parent->type() == Node::QmlPropertyGroup && parent->parent())
|
||||
parent = parent->parent();
|
||||
if (parent && parent->subType() == Node::QmlClass && !parent->name().isEmpty())
|
||||
name = parent->name() + "::" + name;
|
||||
|
@ -217,8 +217,18 @@ void QDocIndexFiles::readIndexSection(const QDomElement& element,
|
||||
location = Location(name);
|
||||
node = qbtn;
|
||||
}
|
||||
else if (element.nodeName() == "qmlproperty") {
|
||||
else if (element.nodeName() == "qmlpropertygroup") {
|
||||
QmlClassNode* qcn = static_cast<QmlClassNode*>(parent);
|
||||
QmlPropertyGroupNode* qpgn = new QmlPropertyGroupNode(qcn, name);
|
||||
if (element.hasAttribute("location"))
|
||||
name = element.attribute("location", QString());
|
||||
if (!indexUrl.isEmpty())
|
||||
location = Location(indexUrl + QLatin1Char('/') + name);
|
||||
else if (!indexUrl.isNull())
|
||||
location = Location(name);
|
||||
node = qpgn;
|
||||
}
|
||||
else if (element.nodeName() == "qmlproperty") {
|
||||
QString type = element.attribute("type");
|
||||
bool attached = false;
|
||||
if (element.attribute("attached") == "true")
|
||||
@ -226,7 +236,15 @@ void QDocIndexFiles::readIndexSection(const QDomElement& element,
|
||||
bool readonly = false;
|
||||
if (element.attribute("writable") == "false")
|
||||
readonly = true;
|
||||
QmlPropertyNode* qpn = new QmlPropertyNode(qcn, name, type, attached);
|
||||
QmlPropertyNode* qpn = 0;
|
||||
if (parent->type() == Node::Document) {
|
||||
QmlClassNode* qcn = static_cast<QmlClassNode*>(parent);
|
||||
qpn = new QmlPropertyNode(qcn, name, type, attached);
|
||||
}
|
||||
else if (parent->type() == Node::QmlPropertyGroup) {
|
||||
QmlPropertyGroupNode* qpgn = static_cast<QmlPropertyGroupNode*>(parent);
|
||||
qpn = new QmlPropertyNode(qpgn, name, type, attached);
|
||||
}
|
||||
qpn->setReadOnly(readonly);
|
||||
node = qpn;
|
||||
}
|
||||
@ -281,10 +299,6 @@ void QDocIndexFiles::readIndexSection(const QDomElement& element,
|
||||
subtype = Node::QmlClass;
|
||||
ptype = Node::ApiPage;
|
||||
}
|
||||
else if (element.attribute("subtype") == "qmlpropertygroup") {
|
||||
subtype = Node::QmlPropertyGroup;
|
||||
ptype = Node::ApiPage;
|
||||
}
|
||||
else if (element.attribute("subtype") == "qmlbasictype") {
|
||||
subtype = Node::QmlBasicType;
|
||||
ptype = Node::ApiPage;
|
||||
@ -501,7 +515,7 @@ void QDocIndexFiles::readIndexSection(const QDomElement& element,
|
||||
|
||||
// Create some content for the node.
|
||||
QSet<QString> emptySet;
|
||||
Doc doc(location, location, " ", emptySet); // placeholder
|
||||
Doc doc(location, location, " ", emptySet, emptySet); // placeholder
|
||||
node->setDoc(doc);
|
||||
node->setIndexNodeFlag();
|
||||
node->setOutputSubdirectory(project_.toLower());
|
||||
@ -644,6 +658,9 @@ bool QDocIndexFiles::generateIndexSection(QXmlStreamWriter& writer,
|
||||
case Node::QmlProperty:
|
||||
nodeName = "qmlproperty";
|
||||
break;
|
||||
case Node::QmlPropertyGroup:
|
||||
nodeName = "qmlpropertygroup";
|
||||
break;
|
||||
case Node::QmlSignal:
|
||||
nodeName = "qmlsignal";
|
||||
break;
|
||||
@ -927,6 +944,12 @@ bool QDocIndexFiles::generateIndexSection(QXmlStreamWriter& writer,
|
||||
writer.writeAttribute("brief", brief);
|
||||
}
|
||||
break;
|
||||
case Node::QmlPropertyGroup:
|
||||
{
|
||||
if (!brief.isEmpty())
|
||||
writer.writeAttribute("brief", brief);
|
||||
}
|
||||
break;
|
||||
case Node::Property:
|
||||
{
|
||||
const PropertyNode* propertyNode = static_cast<const PropertyNode*>(node);
|
||||
@ -1179,17 +1202,12 @@ void QDocIndexFiles::generateIndexSections(QXmlStreamWriter& writer,
|
||||
|
||||
foreach (Node* child, cnodes) {
|
||||
/*
|
||||
Don't generate anything for a QML property group node.
|
||||
It is just a place holder for a collection of QML property
|
||||
nodes. Recurse to its children, which are the QML property
|
||||
nodes.
|
||||
|
||||
Do the same thing for collision nodes - we want children
|
||||
of collision nodes in the index, but leaving out the
|
||||
parent collision page will make searching for nodes easier.
|
||||
Don't generate anything for a collision node. We want
|
||||
children of collision nodes in the index, but leaving
|
||||
out the parent collision page will make searching for
|
||||
nodes easier.
|
||||
*/
|
||||
if (child->subType() == Node::QmlPropertyGroup ||
|
||||
child->subType() == Node::Collision) {
|
||||
if (child->subType() == Node::Collision) {
|
||||
const InnerNode* pgn = static_cast<const InnerNode*>(child);
|
||||
foreach (Node* c, pgn->childNodes()) {
|
||||
generateIndexSections(writer, c, generateInternalNodes);
|
||||
|
@ -70,6 +70,7 @@ QT_BEGIN_NAMESPACE
|
||||
#define COMMAND_QMLTYPE Doc::alias("qmltype")
|
||||
#define COMMAND_QMLMODULE Doc::alias("qmlmodule")
|
||||
#define COMMAND_QMLPROPERTY Doc::alias("qmlproperty")
|
||||
#define COMMAND_QMLPROPERTYGROUP Doc::alias("qmlpropertygroup")
|
||||
#define COMMAND_QMLATTACHEDPROPERTY Doc::alias("qmlattachedproperty")
|
||||
#define COMMAND_QMLINHERITS Doc::alias("inherits")
|
||||
#define COMMAND_QMLINSTANTIATES Doc::alias("instantiates")
|
||||
@ -166,9 +167,9 @@ void QmlCodeParser::parseSourceFile(const Location& location, const QString& fil
|
||||
extractPragmas(newCode);
|
||||
lexer->setCode(newCode, 1);
|
||||
|
||||
QSet<QString> topicCommandsAllowed = topicCommands();
|
||||
QSet<QString> otherMetacommandsAllowed = otherMetaCommands();
|
||||
QSet<QString> metacommandsAllowed = topicCommandsAllowed + otherMetacommandsAllowed;
|
||||
const QSet<QString>& topicCommandsAllowed = topicCommands();
|
||||
const QSet<QString>& otherMetacommandsAllowed = otherMetaCommands();
|
||||
const QSet<QString>& metacommandsAllowed = topicCommandsAllowed + otherMetacommandsAllowed;
|
||||
|
||||
if (parser->parse()) {
|
||||
QQmlJS::AST::UiProgram *ast = parser->ast();
|
||||
@ -195,42 +196,52 @@ void QmlCodeParser::doneParsingSourceFiles()
|
||||
{
|
||||
}
|
||||
|
||||
static QSet<QString> topicCommands_;
|
||||
/*!
|
||||
Returns the set of strings representing the topic commands.
|
||||
*/
|
||||
QSet<QString> QmlCodeParser::topicCommands()
|
||||
const QSet<QString>& QmlCodeParser::topicCommands()
|
||||
{
|
||||
return QSet<QString>() << COMMAND_VARIABLE
|
||||
<< COMMAND_QMLCLASS
|
||||
<< COMMAND_QMLTYPE
|
||||
<< COMMAND_QMLPROPERTY
|
||||
<< COMMAND_QMLATTACHEDPROPERTY
|
||||
<< COMMAND_QMLSIGNAL
|
||||
<< COMMAND_QMLATTACHEDSIGNAL
|
||||
<< COMMAND_QMLMETHOD
|
||||
<< COMMAND_QMLATTACHEDMETHOD
|
||||
<< COMMAND_QMLBASICTYPE;
|
||||
if (topicCommands_.isEmpty()) {
|
||||
topicCommands_ << COMMAND_VARIABLE
|
||||
<< COMMAND_QMLCLASS
|
||||
<< COMMAND_QMLTYPE
|
||||
<< COMMAND_QMLPROPERTY
|
||||
<< COMMAND_QMLPROPERTYGROUP
|
||||
<< COMMAND_QMLATTACHEDPROPERTY
|
||||
<< COMMAND_QMLSIGNAL
|
||||
<< COMMAND_QMLATTACHEDSIGNAL
|
||||
<< COMMAND_QMLMETHOD
|
||||
<< COMMAND_QMLATTACHEDMETHOD
|
||||
<< COMMAND_QMLBASICTYPE;
|
||||
}
|
||||
return topicCommands_;
|
||||
}
|
||||
|
||||
static QSet<QString> otherMetaCommands_;
|
||||
/*!
|
||||
Returns the set of strings representing the common metacommands
|
||||
plus some other metacommands.
|
||||
*/
|
||||
QSet<QString> QmlCodeParser::otherMetaCommands()
|
||||
const QSet<QString>& QmlCodeParser::otherMetaCommands()
|
||||
{
|
||||
return commonMetaCommands() << COMMAND_STARTPAGE
|
||||
<< COMMAND_QMLINHERITS
|
||||
<< COMMAND_QMLDEFAULT
|
||||
<< COMMAND_QMLREADONLY
|
||||
<< COMMAND_DEPRECATED
|
||||
<< COMMAND_INGROUP
|
||||
<< COMMAND_INTERNAL
|
||||
<< COMMAND_OBSOLETE
|
||||
<< COMMAND_PRELIMINARY
|
||||
<< COMMAND_SINCE
|
||||
<< COMMAND_QMLABSTRACT
|
||||
<< COMMAND_INQMLMODULE
|
||||
<< COMMAND_WRAPPER;
|
||||
if (otherMetaCommands_.isEmpty()) {
|
||||
otherMetaCommands_ = commonMetaCommands();
|
||||
otherMetaCommands_ << COMMAND_STARTPAGE
|
||||
<< COMMAND_QMLINHERITS
|
||||
<< COMMAND_QMLDEFAULT
|
||||
<< COMMAND_QMLREADONLY
|
||||
<< COMMAND_DEPRECATED
|
||||
<< COMMAND_INGROUP
|
||||
<< COMMAND_INTERNAL
|
||||
<< COMMAND_OBSOLETE
|
||||
<< COMMAND_PRELIMINARY
|
||||
<< COMMAND_SINCE
|
||||
<< COMMAND_QMLABSTRACT
|
||||
<< COMMAND_INQMLMODULE
|
||||
<< COMMAND_WRAPPER;
|
||||
}
|
||||
return otherMetaCommands_;
|
||||
}
|
||||
|
||||
/*!
|
||||
|
@ -79,8 +79,8 @@ public:
|
||||
void extractPragmas(QString &script);
|
||||
|
||||
protected:
|
||||
virtual QSet<QString> topicCommands();
|
||||
virtual QSet<QString> otherMetaCommands();
|
||||
const QSet<QString>& topicCommands();
|
||||
const QSet<QString>& otherMetaCommands();
|
||||
|
||||
private:
|
||||
QQmlJS::Engine engine;
|
||||
|
@ -67,6 +67,7 @@ QT_BEGIN_NAMESPACE
|
||||
#define COMMAND_QMLTYPE Doc::alias(QLatin1String("qmltype"))
|
||||
#define COMMAND_QMLMODULE Doc::alias(QLatin1String("qmlmodule"))
|
||||
#define COMMAND_QMLPROPERTY Doc::alias(QLatin1String("qmlproperty"))
|
||||
#define COMMAND_QMLPROPERTYGROUP Doc::alias(QLatin1String("qmlpropertygroup"))
|
||||
#define COMMAND_QMLATTACHEDPROPERTY Doc::alias(QLatin1String("qmlattachedproperty"))
|
||||
#define COMMAND_QMLINHERITS Doc::alias(QLatin1String("inherits"))
|
||||
#define COMMAND_QMLINSTANTIATES Doc::alias(QLatin1String("instantiates"))
|
||||
@ -85,17 +86,17 @@ QT_BEGIN_NAMESPACE
|
||||
QmlDocVisitor::QmlDocVisitor(const QString &filePath,
|
||||
const QString &code,
|
||||
QQmlJS::Engine *engine,
|
||||
QSet<QString> &commands,
|
||||
QSet<QString> &topics)
|
||||
const QSet<QString> &commands,
|
||||
const QSet<QString> &topics)
|
||||
: nestingLevel(0)
|
||||
{
|
||||
lastEndOffset = 0;
|
||||
this->filePath = filePath;
|
||||
this->filePath_ = filePath;
|
||||
this->name = QFileInfo(filePath).baseName();
|
||||
document = code;
|
||||
this->engine = engine;
|
||||
this->commands = commands;
|
||||
this->topics = topics;
|
||||
this->commands_ = commands;
|
||||
this->topics_ = topics;
|
||||
current = QDocDatabase::qdocDB()->treeRoot();
|
||||
}
|
||||
|
||||
@ -141,13 +142,89 @@ QQmlJS::AST::SourceLocation QmlDocVisitor::precedingComment(quint32 offset) cons
|
||||
return QQmlJS::AST::SourceLocation();
|
||||
}
|
||||
|
||||
#if 0
|
||||
ArgList args;
|
||||
QSet<QString>::iterator i = metacommands.begin();
|
||||
while (i != metacommands.end()) {
|
||||
if (topics_.contains(*i)) {
|
||||
topic = *i;
|
||||
break;
|
||||
}
|
||||
++i;
|
||||
}
|
||||
if (!topic.isEmpty()) {
|
||||
args = doc.metaCommandArgs(topic);
|
||||
if ((topic == COMMAND_QMLCLASS) || (topic == COMMAND_QMLTYPE)) {
|
||||
// do nothing.
|
||||
}
|
||||
else if (topic == COMMAND_QMLPROPERTY) {
|
||||
if (node->type() == Node::QmlProperty) {
|
||||
QmlPropertyNode* qpn = static_cast<QmlPropertyNode*>(node);
|
||||
qpn->setReadOnly(0);
|
||||
if (qpn->dataType() == "alias") {
|
||||
QStringList part = args[0].first.split(QLatin1Char(' '));
|
||||
qpn->setDataType(part[0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (topic == COMMAND_QMLPROPERTYGROUP) {
|
||||
// zzz ?
|
||||
}
|
||||
else if (topic == COMMAND_QMLMODULE) {
|
||||
}
|
||||
else if (topic == COMMAND_QMLATTACHEDPROPERTY) {
|
||||
if (node->type() == Node::QmlProperty) {
|
||||
QmlPropertyNode* qpn = static_cast<QmlPropertyNode*>(node);
|
||||
qpn->setReadOnly(0);
|
||||
}
|
||||
}
|
||||
else if (topic == COMMAND_QMLSIGNAL) {
|
||||
}
|
||||
else if (topic == COMMAND_QMLATTACHEDSIGNAL) {
|
||||
}
|
||||
else if (topic == COMMAND_QMLMETHOD) {
|
||||
}
|
||||
else if (topic == COMMAND_QMLATTACHEDMETHOD) {
|
||||
}
|
||||
else if (topic == COMMAND_QMLBASICTYPE) {
|
||||
}
|
||||
}
|
||||
|
||||
if (node->type() == Node::QmlProperty) {
|
||||
QmlPropertyNode* qpn = static_cast<QmlPropertyNode*>(node);
|
||||
for (int i=0; i<topicsUsed.size(); ++i) {
|
||||
if (topicsUsed.at(i).topic == "qmlproperty") {
|
||||
/*
|
||||
A \qmlproperty command would be used in a QML file
|
||||
to document the underlying property for a property
|
||||
alias.
|
||||
*/
|
||||
QmlPropArgs qpa;
|
||||
if (splitQmlPropertyArg(doc, topicsUsed.at(i).args, qpa)) {
|
||||
QmlPropertyNode* n = parent->hasQmlPropertyNode(qpa.name_);
|
||||
if (n == 0)
|
||||
n = new QmlPropertyNode(qpn, qpa.name_, qpa.type_, false);
|
||||
n->setLocation(doc.location());
|
||||
n->setReadOnly(qpn->isReadOnly());
|
||||
if (qpn->isDefault())
|
||||
n->setDefault();
|
||||
}
|
||||
else
|
||||
qDebug() << " FAILED TO PARSE QML PROPERTY:"
|
||||
<< topicsUsed.at(i).topic << topicsUsed.at(i).args;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/*!
|
||||
Finds the nearest unused qdoc comment above the QML entity
|
||||
represented by the \a node and processes the qdoc commands
|
||||
in that comment. The proceesed documentation is stored in
|
||||
in that comment. The processed documentation is stored in
|
||||
the \a node.
|
||||
|
||||
If a qdoc comment is found about \a location, true is returned.
|
||||
If a qdoc comment is found for \a location, true is returned.
|
||||
If a comment is not found there, false is returned.
|
||||
*/
|
||||
bool QmlDocVisitor::applyDocumentation(QQmlJS::AST::SourceLocation location, Node* node)
|
||||
@ -156,23 +233,68 @@ bool QmlDocVisitor::applyDocumentation(QQmlJS::AST::SourceLocation location, Nod
|
||||
|
||||
if (loc.isValid()) {
|
||||
QString source = document.mid(loc.offset, loc.length);
|
||||
Location start(filePath);
|
||||
Location start(filePath_);
|
||||
start.setLineNo(loc.startLine);
|
||||
start.setColumnNo(loc.startColumn);
|
||||
Location finish(filePath);
|
||||
Location finish(filePath_);
|
||||
finish.setLineNo(loc.startLine);
|
||||
finish.setColumnNo(loc.startColumn);
|
||||
|
||||
Doc doc(start, finish, source.mid(1), commands, topics);
|
||||
Doc doc(start, finish, source.mid(1), commands_, topics_);
|
||||
const TopicList& topicsUsed = doc.topicsUsed();
|
||||
NodeList nodes;
|
||||
Node* nodePassedIn = node;
|
||||
InnerNode* parent = nodePassedIn->parent();
|
||||
int pgc_idx = -1;
|
||||
node->setDoc(doc);
|
||||
applyMetacommands(loc, node, doc);
|
||||
nodes.append(node);
|
||||
if (topicsUsed.size() > 0) {
|
||||
for (int i=0; i<topicsUsed.size(); ++i) {
|
||||
if (topicsUsed.at(i).topic == QString("qmlpropertygroup")) {
|
||||
pgc_idx = i;
|
||||
qDebug() << "PROPERTY GROUP COMMAND SEEN:" << topicsUsed.at(i).args << filePath_;
|
||||
break;
|
||||
}
|
||||
}
|
||||
for (int i=0; i<topicsUsed.size(); ++i) {
|
||||
QString topic = topicsUsed.at(i).topic;
|
||||
QString args = topicsUsed.at(i).args;
|
||||
if ((topic == COMMAND_QMLPROPERTY) || (topic == COMMAND_QMLATTACHEDPROPERTY)) {
|
||||
QmlPropArgs qpa;
|
||||
if (splitQmlPropertyArg(doc, args, qpa)) {
|
||||
if (qpa.name_ == nodePassedIn->name()) {
|
||||
if (nodePassedIn->isAlias())
|
||||
nodePassedIn->setDataType(qpa.type_);
|
||||
}
|
||||
else {
|
||||
bool isAttached = (topic == COMMAND_QMLATTACHEDPROPERTY);
|
||||
QmlPropertyNode* n = parent->hasQmlProperty(qpa.name_);
|
||||
if (n == 0)
|
||||
n = new QmlPropertyNode(parent, qpa.name_, qpa.type_, isAttached);
|
||||
n->setLocation(doc.location());
|
||||
n->setDoc(doc);
|
||||
n->setReadOnly(nodePassedIn->isReadOnly());
|
||||
if (nodePassedIn->isDefault())
|
||||
n->setDefault();
|
||||
if (isAttached)
|
||||
n->setReadOnly(0);
|
||||
nodes.append(n);
|
||||
}
|
||||
}
|
||||
else
|
||||
qDebug() << " FAILED TO PARSE QML PROPERTY:" << topic << args;
|
||||
}
|
||||
}
|
||||
}
|
||||
for (int i=0; i<nodes.size(); ++i)
|
||||
applyMetacommands(loc, nodes.at(i), doc);
|
||||
usedComments.insert(loc.offset);
|
||||
if (doc.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
Location codeLoc(filePath);
|
||||
Location codeLoc(filePath_);
|
||||
codeLoc.setLineNo(location.startLine);
|
||||
node->setLocation(codeLoc);
|
||||
return false;
|
||||
@ -237,80 +359,13 @@ void QmlDocVisitor::applyMetacommands(QQmlJS::AST::SourceLocation,
|
||||
Doc& doc)
|
||||
{
|
||||
QDocDatabase* qdb = QDocDatabase::qdocDB();
|
||||
|
||||
const TopicList& topicsUsed = doc.topicsUsed();
|
||||
if (topicsUsed.size() > 0) {
|
||||
if (node->type() == Node::QmlProperty) {
|
||||
QmlPropertyNode* qpn = static_cast<QmlPropertyNode*>(node);
|
||||
for (int i=0; i<topicsUsed.size(); ++i) {
|
||||
if (topicsUsed.at(i).topic == "qmlproperty") {
|
||||
QmlPropArgs qpa;
|
||||
if (splitQmlPropertyArg(doc, topicsUsed.at(i).args, qpa)) {
|
||||
QmlPropertyNode* n = new QmlPropertyNode(qpn, qpa.name_, qpa.type_, false);
|
||||
n->setLocation(doc.location());
|
||||
qpn->appendQmlPropNode(n);
|
||||
n->setReadOnly(qpn->isReadOnly());
|
||||
if (qpn->isDefault())
|
||||
n->setDefault();
|
||||
}
|
||||
else
|
||||
qDebug() << " FAILED TO PARSE QML PROPERTY:"
|
||||
<< topicsUsed.at(i).topic << topicsUsed.at(i).args;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
QSet<QString> metacommands = doc.metaCommandsUsed();
|
||||
if (metacommands.count() > 0) {
|
||||
QString topic;
|
||||
ArgList args;
|
||||
metacommands.subtract(topics_);
|
||||
QSet<QString>::iterator i = metacommands.begin();
|
||||
while (i != metacommands.end()) {
|
||||
if (topics.contains(*i)) {
|
||||
topic = *i;
|
||||
break;
|
||||
}
|
||||
++i;
|
||||
}
|
||||
if (!topic.isEmpty()) {
|
||||
args = doc.metaCommandArgs(topic);
|
||||
if ((topic == COMMAND_QMLCLASS) || (topic == COMMAND_QMLTYPE)) {
|
||||
// do nothing.
|
||||
}
|
||||
else if (topic == COMMAND_QMLPROPERTY) {
|
||||
if (node->type() == Node::QmlProperty) {
|
||||
QmlPropertyNode* qpn = static_cast<QmlPropertyNode*>(node);
|
||||
qpn->setReadOnly(0);
|
||||
if (qpn->dataType() == "alias") {
|
||||
QStringList part = args[0].first.split(QLatin1Char(' '));
|
||||
qpn->setDataType(part[0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (topic == COMMAND_QMLMODULE) {
|
||||
}
|
||||
else if (topic == COMMAND_QMLATTACHEDPROPERTY) {
|
||||
if (node->type() == Node::QmlProperty) {
|
||||
QmlPropertyNode* qpn = static_cast<QmlPropertyNode*>(node);
|
||||
qpn->setReadOnly(0);
|
||||
}
|
||||
}
|
||||
else if (topic == COMMAND_QMLSIGNAL) {
|
||||
}
|
||||
else if (topic == COMMAND_QMLATTACHEDSIGNAL) {
|
||||
}
|
||||
else if (topic == COMMAND_QMLMETHOD) {
|
||||
}
|
||||
else if (topic == COMMAND_QMLATTACHEDMETHOD) {
|
||||
}
|
||||
else if (topic == COMMAND_QMLBASICTYPE) {
|
||||
}
|
||||
}
|
||||
metacommands.subtract(topics);
|
||||
i = metacommands.begin();
|
||||
while (i != metacommands.end()) {
|
||||
QString command = *i;
|
||||
args = doc.metaCommandArgs(command);
|
||||
ArgList args = doc.metaCommandArgs(command);
|
||||
if (command == COMMAND_QMLABSTRACT) {
|
||||
if ((node->type() == Node::Document) && (node->subType() == Node::QmlClass)) {
|
||||
node->setAbstract(true);
|
||||
@ -528,7 +583,9 @@ bool QmlDocVisitor::visit(QQmlJS::AST::UiPublicMember *member)
|
||||
QmlClassNode *qmlClass = static_cast<QmlClassNode *>(current);
|
||||
if (qmlClass) {
|
||||
QString name = member->name.toString();
|
||||
QmlPropertyNode *qmlPropNode = new QmlPropertyNode(qmlClass, name, type, false);
|
||||
QmlPropertyNode* qmlPropNode = qmlClass->hasQmlProperty(name);
|
||||
if (qmlPropNode == 0)
|
||||
qmlPropNode = new QmlPropertyNode(qmlClass, name, type, false);
|
||||
qmlPropNode->setReadOnly(member->isReadonlyMember);
|
||||
if (member->isDefaultMember)
|
||||
qmlPropNode->setDefault();
|
||||
|
@ -71,8 +71,8 @@ public:
|
||||
QmlDocVisitor(const QString &filePath,
|
||||
const QString &code,
|
||||
QQmlJS::Engine *engine,
|
||||
QSet<QString> &commands,
|
||||
QSet<QString> &topics);
|
||||
const QSet<QString> &commands,
|
||||
const QSet<QString> &topics);
|
||||
virtual ~QmlDocVisitor();
|
||||
|
||||
bool visit(QQmlJS::AST::UiImportList *imports);
|
||||
@ -112,12 +112,12 @@ private:
|
||||
QQmlJS::Engine *engine;
|
||||
quint32 lastEndOffset;
|
||||
quint32 nestingLevel;
|
||||
QString filePath;
|
||||
QString filePath_;
|
||||
QString name;
|
||||
QString document;
|
||||
ImportList importList;
|
||||
QSet<QString> commands;
|
||||
QSet<QString> topics;
|
||||
QSet<QString> commands_;
|
||||
QSet<QString> topics_;
|
||||
QSet<quint32> usedComments;
|
||||
InnerNode *current;
|
||||
};
|
||||
|
@ -169,7 +169,7 @@ const Node* Tree::findNode(const QStringList& path,
|
||||
if (node && i == path.size()
|
||||
&& (!(findFlags & NonFunction) || node->type() != Node::Function
|
||||
|| ((FunctionNode*)node)->metaness() == FunctionNode::MacroWithoutParams)) {
|
||||
if ((node != self) && (node->subType() != Node::QmlPropertyGroup)) {
|
||||
if ((node != self) && (node->type() != Node::QmlPropertyGroup)) {
|
||||
if (node->subType() == Node::Collision) {
|
||||
node = node->applyModuleIdentifier(start);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user