~oif-team/ubuntu/natty/qt4-x11/xi2.1

« back to all changes in this revision

Viewing changes to tools/qdoc3/cppcodeparser.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Alessandro Ghersi
  • Date: 2009-11-02 18:30:08 UTC
  • mfrom: (1.2.2 upstream)
  • mto: (15.2.5 experimental)
  • mto: This revision was merged to the branch mainline in revision 88.
  • Revision ID: james.westby@ubuntu.com-20091102183008-b6a4gcs128mvfb3m
Tags: upstream-4.6.0~beta1
ImportĀ upstreamĀ versionĀ 4.6.0~beta1

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/****************************************************************************
2
2
**
3
3
** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
 
4
** All rights reserved.
4
5
** Contact: Nokia Corporation (qt-info@nokia.com)
5
6
**
6
7
** This file is part of the tools applications of the Qt Toolkit.
7
8
**
8
9
** $QT_BEGIN_LICENSE:LGPL$
9
 
** Commercial Usage
10
 
** Licensees holding valid Qt Commercial licenses may use this file in
11
 
** accordance with the Qt Commercial License Agreement provided with the
12
 
** Software or, alternatively, in accordance with the terms contained in
13
 
** a written agreement between you and Nokia.
 
10
** No Commercial Usage
 
11
** This file contains pre-release code and may not be distributed.
 
12
** You may use this file in accordance with the terms and conditions
 
13
** contained in the Technology Preview License Agreement accompanying
 
14
** this package.
14
15
**
15
16
** GNU Lesser General Public License Usage
16
17
** Alternatively, this file may be used under the terms of the GNU Lesser
20
21
** ensure the GNU Lesser General Public License version 2.1 requirements
21
22
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
22
23
**
23
 
** In addition, as a special exception, Nokia gives you certain
24
 
** additional rights. These rights are described in the Nokia Qt LGPL
25
 
** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
26
 
** package.
27
 
**
28
 
** GNU General Public License Usage
29
 
** Alternatively, this file may be used under the terms of the GNU
30
 
** General Public License version 3.0 as published by the Free Software
31
 
** Foundation and appearing in the file LICENSE.GPL included in the
32
 
** packaging of this file.  Please review the following information to
33
 
** ensure the GNU General Public License version 3.0 requirements will be
34
 
** met: http://www.gnu.org/copyleft/gpl.html.
35
 
**
36
 
** If you are unsure which license is appropriate for your use, please
37
 
** contact the sales department at http://www.qtsoftware.com/contact.
 
24
** In addition, as a special exception, Nokia gives you certain additional
 
25
** rights.  These rights are described in the Nokia Qt LGPL Exception
 
26
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
 
27
**
 
28
** If you have questions regarding the use of this file, please contact
 
29
** Nokia at qt-info@nokia.com.
 
30
**
 
31
**
 
32
**
 
33
**
 
34
**
 
35
**
 
36
**
 
37
**
38
38
** $QT_END_LICENSE$
39
39
**
40
40
****************************************************************************/
47
47
#include <qfile.h>
48
48
 
49
49
#include <stdio.h>
 
50
#include <errno.h>
50
51
 
51
52
#include "codechunk.h"
52
53
#include "config.h"
87
88
#ifdef QDOC_QML
88
89
#define COMMAND_QMLCLASS                Doc::alias("qmlclass")
89
90
#define COMMAND_QMLPROPERTY             Doc::alias("qmlproperty")
 
91
#define COMMAND_QMLINHERITS             Doc::alias("inherits")
 
92
#define COMMAND_QMLSIGNAL               Doc::alias("qmlsignal")
 
93
#define COMMAND_QMLMETHOD               Doc::alias("qmlmethod")
 
94
#define COMMAND_QMLDEFAULT              Doc::alias("default")
90
95
#endif
91
96
 
92
97
QStringList CppCodeParser::exampleFiles;
109
114
        if (arg.contains(".html") && spaceAt != -1) {
110
115
            *link = arg.left(spaceAt).trimmed();
111
116
            *desc = arg.mid(spaceAt).trimmed();
112
 
        } else {
 
117
        }
 
118
        else {
113
119
            *link = arg;
114
120
            *desc = arg;
115
121
        }
202
208
    nodeTypeMap.insert(COMMAND_PROPERTY, Node::Property);
203
209
    nodeTypeMap.insert(COMMAND_VARIABLE, Node::Variable);
204
210
 
205
 
#ifdef QDOC_QML
206
 
    //    nodeTypeMap.insert(COMMAND_QMLCLASS, Node::Class);
207
 
    nodeTypeMap.insert(COMMAND_QMLPROPERTY, Node::Property);
208
 
#endif    
209
 
    
210
211
    exampleFiles = config.getStringList(CONFIG_EXAMPLES);
211
212
    exampleDirs = config.getStringList(CONFIG_EXAMPLEDIRS);
212
213
    QStringList exampleFilePatterns = config.getStringList(
281
282
{
282
283
    FILE *in = fopen(QFile::encodeName(filePath), "r");
283
284
    if (!in) {
284
 
        location.error(tr("Cannot open C++ source file '%1'").arg(filePath));
 
285
        location.error(tr("Cannot open C++ source file '%1' (%2)").arg(filePath).arg(strerror(errno)));
285
286
        return;
286
287
    }
287
288
 
477
478
                           << COMMAND_PROPERTY
478
479
                           << COMMAND_SERVICE
479
480
                           << COMMAND_TYPEDEF
480
 
#ifdef QDOC_QML        
 
481
#ifdef QDOC_QML
481
482
                           << COMMAND_VARIABLE
482
483
                           << COMMAND_QMLCLASS
483
 
                           << COMMAND_QMLPROPERTY;
484
 
#else    
 
484
                           << COMMAND_QMLPROPERTY
 
485
                           << COMMAND_QMLSIGNAL
 
486
                           << COMMAND_QMLMETHOD;
 
487
#else
485
488
                           << COMMAND_VARIABLE;
486
 
#endif    
 
489
#endif
487
490
}
488
491
 
489
492
/*!
587
590
          The command was neither "fn" nor "macro" .
588
591
         */
589
592
        // ### split(" ") hack is there to support header file syntax
590
 
        QStringList paths = arg.split(" "); 
 
593
        QStringList paths = arg.split(" ");
591
594
        QStringList path = paths[0].split("::");
592
 
        
593
 
#if QDOC2DOX        
594
 
        // qdoc -> doxygen.
595
 
        if (Doc::isDoxPass(1)) {
596
 
            if (command == COMMAND_PROPERTY) {
597
 
                Doc::insertProperty(path);
598
 
            }
599
 
            else if (command == COMMAND_VARIABLE) {
600
 
                Doc::insertVariable(path);
601
 
            }
602
 
            else if (command == COMMAND_ENUM) {
603
 
                // zzz
604
 
            }
605
 
        }
606
 
#endif
607
 
 
608
595
        Node *node = 0;
609
596
        if (!usedNamespaces.isEmpty()) {
610
597
            foreach (const QString &usedNamespace, usedNamespaces) {
643
630
            }
644
631
        }
645
632
 
 
633
        if (command == COMMAND_CLASS) {
 
634
            if (paths.size() > 1) {
 
635
                if (!paths[1].endsWith(".h")) {
 
636
                    ClassNode*cnode = static_cast<ClassNode*>(node);
 
637
                    cnode->setQmlElement(paths[1]);
 
638
                }
 
639
            }
 
640
        }
646
641
        return node;
647
642
    }
648
643
    else if (command == COMMAND_EXAMPLE) {
649
 
        FakeNode *fake = new FakeNode(tre->root(), arg, FakeNode::Example);
 
644
        FakeNode *fake = new FakeNode(tre->root(), arg, Node::Example);
650
645
        createExampleFileNodes(fake);
651
646
        return fake;
652
647
    }
653
648
    else if (command == COMMAND_EXTERNALPAGE) {
654
 
        return new FakeNode(tre->root(), arg, FakeNode::ExternalPage);
 
649
        return new FakeNode(tre->root(), arg, Node::ExternalPage);
655
650
    }
656
651
    else if (command == COMMAND_FILE) {
657
 
        return new FakeNode(tre->root(), arg, FakeNode::File);
 
652
        return new FakeNode(tre->root(), arg, Node::File);
658
653
    }
659
654
    else if (command == COMMAND_GROUP) {
660
 
        return new FakeNode(tre->root(), arg, FakeNode::Group);
 
655
        return new FakeNode(tre->root(), arg, Node::Group);
661
656
    }
662
657
    else if (command == COMMAND_HEADERFILE) {
663
 
        return new FakeNode(tre->root(), arg, FakeNode::HeaderFile);
 
658
        return new FakeNode(tre->root(), arg, Node::HeaderFile);
664
659
    }
665
660
    else if (command == COMMAND_MODULE) {
666
 
        return new FakeNode(tre->root(), arg, FakeNode::Module);
 
661
        return new FakeNode(tre->root(), arg, Node::Module);
667
662
    }
668
663
    else if (command == COMMAND_PAGE) {
669
 
        return new FakeNode(tre->root(), arg, FakeNode::Page);
 
664
        return new FakeNode(tre->root(), arg, Node::Page);
670
665
    }
671
 
#ifdef QDOC_QML    
 
666
#ifdef QDOC_QML
672
667
    else if (command == COMMAND_QMLCLASS) {
673
668
        const ClassNode* classNode = 0;
674
 
        QStringList names = arg.split(" "); 
675
 
        //qDebug() << "QMLCLASS" << names;
 
669
        QStringList names = arg.split(" ");
676
670
        if (names.size() > 1) {
677
671
            Node* n = tre->findNode(names[1].split("::"),Node::Class);
678
 
            if (n) {
 
672
            if (n)
679
673
                classNode = static_cast<const ClassNode*>(n);
680
 
                //qDebug() << "FOUND IT!" << classNode->name();
 
674
        }
 
675
        return new QmlClassNode(tre->root(), names[0], classNode);
 
676
    }
 
677
    else if ((command == COMMAND_QMLSIGNAL) ||
 
678
             (command == COMMAND_QMLMETHOD)) {
 
679
        QString element;
 
680
        QString name;
 
681
        QmlClassNode* qmlClass = 0;
 
682
        if (splitQmlArg(doc,arg,element,name)) {
 
683
            Node* n = tre->findNode(QStringList(element),Node::Fake);
 
684
            if (n && n->subType() == Node::QmlClass) {
 
685
                qmlClass = static_cast<QmlClassNode*>(n);
 
686
                if (command == COMMAND_QMLSIGNAL)
 
687
                    return new QmlSignalNode(qmlClass,name);
 
688
                else
 
689
                    return new QmlMethodNode(qmlClass,name);
681
690
            }
682
691
        }
683
 
        return new QmlNode(tre->root(), names[0], classNode);
684
692
    }
685
 
#endif    
 
693
#endif
686
694
    return 0;
687
695
}
688
696
 
 
697
#ifdef QDOC_QML
 
698
 
 
699
/*!
 
700
  A QML property argument has the form...
 
701
 
 
702
  <type> <element>::<name>
 
703
 
 
704
  This function splits the argument into those three
 
705
  parts, sets \a type, \a element, and \a property,
 
706
  and returns true. If any of the parts isn't found,
 
707
  a debug message is output and false is returned.
 
708
 */
 
709
bool CppCodeParser::splitQmlPropertyArg(const Doc& doc,
 
710
                                        const QString& arg,
 
711
                                        QString& type,
 
712
                                        QString& element,
 
713
                                        QString& property)
 
714
{
 
715
    QStringList blankSplit = arg.split(" ");
 
716
    if (blankSplit.size() > 1) {
 
717
        type = blankSplit[0];
 
718
        QStringList colonSplit(blankSplit[1].split("::"));
 
719
        if (colonSplit.size() > 1) {
 
720
            element = colonSplit[0];
 
721
            property = colonSplit[1];
 
722
            return true;
 
723
        }
 
724
        else
 
725
            doc.location().warning(tr("Missing QML element name or property name"));
 
726
    }
 
727
    else
 
728
        doc.location().warning(tr("Missing QML property type or property path"));
 
729
    return false;
 
730
}
 
731
 
 
732
/*!
 
733
  A QML signal or method argument has the form...
 
734
 
 
735
  <element>::<name>
 
736
 
 
737
  This function splits the argument into those two
 
738
  parts, sets \a element, and \a name, and returns
 
739
  true. If either of the parts isn't found, a debug
 
740
  message is output and false is returned.
 
741
 */
 
742
bool CppCodeParser::splitQmlArg(const Doc& doc,
 
743
                                const QString& arg,
 
744
                                QString& element,
 
745
                                QString& name)
 
746
{
 
747
    QStringList colonSplit(arg.split("::"));
 
748
    if (colonSplit.size() > 1) {
 
749
        element = colonSplit[0];
 
750
        name = colonSplit[1];
 
751
        return true;
 
752
    }
 
753
    else
 
754
        doc.location().warning(tr("Missing QML element name or signal/method name"));
 
755
    return false;
 
756
}
 
757
 
 
758
/*!
 
759
  Process the topic \a command group with arguments \a args.
 
760
 
 
761
  Currently, this function is called only for \e{qmlproperty}.
 
762
 */
 
763
Node *CppCodeParser::processTopicCommandGroup(const Doc& doc,
 
764
                                              const QString& command,
 
765
                                              const QStringList& args)
 
766
{
 
767
    QmlPropGroupNode* qmlPropGroup = 0;
 
768
    if (command == COMMAND_QMLPROPERTY) {
 
769
        QString type;
 
770
        QString element;
 
771
        QString property;
 
772
        QStringList::ConstIterator arg = args.begin();
 
773
        if (splitQmlPropertyArg(doc,(*arg),type,element,property)) {
 
774
            Node* n = tre->findNode(QStringList(element),Node::Fake);
 
775
            if (n && n->subType() == Node::QmlClass) {
 
776
                QmlClassNode* qmlClass = static_cast<QmlClassNode*>(n);
 
777
                if (qmlClass)
 
778
                    qmlPropGroup = new QmlPropGroupNode(qmlClass,property);
 
779
            }
 
780
        }
 
781
        if (qmlPropGroup) {
 
782
            new QmlPropertyNode(qmlPropGroup,property,type);
 
783
            ++arg;
 
784
            while (arg != args.end()) {
 
785
                if (splitQmlPropertyArg(doc,(*arg),type,element,property)) {
 
786
                    new QmlPropertyNode(qmlPropGroup,property,type);
 
787
                }
 
788
                ++arg;
 
789
            }
 
790
        }
 
791
    }
 
792
    return qmlPropGroup;
 
793
}
 
794
#endif
 
795
 
689
796
/*!
690
797
  Returns the set of strings representing the common metacommands
691
798
  plus some other metacommands.
700
807
                                << COMMAND_NEXTPAGE
701
808
                                << COMMAND_PREVIOUSPAGE
702
809
                                << COMMAND_INDEXPAGE
 
810
#ifdef QDOC_QML        
 
811
                                << COMMAND_STARTPAGE
 
812
                                << COMMAND_QMLINHERITS
 
813
                                << COMMAND_QMLDEFAULT;
 
814
#else    
703
815
                                << COMMAND_STARTPAGE;
 
816
#endif    
704
817
}
705
818
 
706
819
/*!
742
855
                    tr("The function either doesn't exist in any base class "
743
856
                       "with the same signature or it exists but isn't virtual."));
744
857
            }
745
 
#if 0 // Ideally, we would enable this check to warn whenever \reimp is used
746
 
      // incorrectly, and only make the node internal if the function is a
747
 
      // reimplementation of another function in a base class.
 
858
            /*
 
859
              Ideally, we would enable this check to warn whenever
 
860
              \reimp is used incorrectly, and only make the node
 
861
              internal if the function is a reimplementation of
 
862
              another function in a base class.
 
863
            */
748
864
            else if (from->access() == Node::Private
749
865
                     || from->parent()->access() == Node::Private) {
750
 
                doc.location().warning(
751
 
                    tr("Base function for '\\%1' in %2() is private or internal")
 
866
                doc.location().warning(tr("'\\%1' in %2() should be '\\internal' because its base function is private or internal")
752
867
                    .arg(COMMAND_REIMP).arg(node->name()));
753
868
            }
754
 
#endif
755
 
            // Note: Setting the access to Private hides the documentation,
756
 
            // but setting the status to Internal makes the node available
757
 
            // in the XML output when the WebXMLGenerator is used.
 
869
 
 
870
#if 0
 
871
            // Reimplemented functions now reported in separate sections.
 
872
            /*
 
873
              Note: Setting the access to Private hides the documentation,
 
874
              but setting the status to Internal makes the node available
 
875
              in the XML output when the WebXMLGenerator is used.
 
876
            */
758
877
            func->setAccess(Node::Private);
759
878
            func->setStatus(Node::Internal);
 
879
#endif
 
880
            func->setReimp(true);
760
881
        }
761
882
        else {
762
883
            doc.location().warning(tr("Ignored '\\%1' in %2")
767
888
    else if (command == COMMAND_RELATES) {
768
889
        InnerNode *pseudoParent;
769
890
        if (arg.startsWith("<") || arg.startsWith("\"")) {
770
 
            pseudoParent = static_cast<InnerNode *>(tre->findNode(QStringList(arg), Node::Fake));
 
891
            pseudoParent =
 
892
                static_cast<InnerNode *>(tre->findNode(QStringList(arg),
 
893
                                                       Node::Fake));
771
894
        }
772
895
        else {
773
896
            QStringList newPath = arg.split("::");
774
 
            pseudoParent = static_cast<InnerNode *>(tre->findNode(QStringList(newPath), Node::Class));
 
897
            pseudoParent =
 
898
                static_cast<InnerNode*>(tre->findNode(QStringList(newPath),
 
899
                                                      Node::Class));
775
900
            if (!pseudoParent)
776
 
                pseudoParent = static_cast<InnerNode *>(tre->findNode(QStringList(newPath),
777
 
                                                        Node::Namespace));
 
901
                pseudoParent =
 
902
                    static_cast<InnerNode*>(tre->findNode(QStringList(newPath),
 
903
                                                          Node::Namespace));
778
904
        }
779
905
        if (!pseudoParent) {
780
906
            doc.location().warning(tr("Cannot find '%1' in '\\%2'")
799
925
    else if (command == COMMAND_STARTPAGE) {
800
926
        setLink(node, Node::StartLink, arg);
801
927
    }
 
928
#ifdef QDOC_QML
 
929
    else if (command == COMMAND_QMLINHERITS) {
 
930
        setLink(node, Node::InheritsLink, arg);
 
931
    }
 
932
    else if (command == COMMAND_QMLDEFAULT) {
 
933
        QmlPropGroupNode* qpgn = static_cast<QmlPropGroupNode*>(node);
 
934
        qpgn->setDefault();
 
935
    }
 
936
#endif
802
937
    else {
803
938
        processCommonMetaCommand(doc.location(),command,arg,node,tre);
804
939
    }
878
1013
        readToken();
879
1014
        return true;
880
1015
    }
881
 
    else {
 
1016
    else
882
1017
        return false;
883
 
    }
884
1018
}
885
1019
 
886
1020
/*!
915
1049
        do {
916
1050
            if (tok == Tok_LeftAngle) {
917
1051
                leftAngleDepth++;
918
 
            } else if (tok == Tok_RightAngle) {
 
1052
            }
 
1053
            else if (tok == Tok_RightAngle) {
919
1054
                leftAngleDepth--;
920
 
            } else if (tok == Tok_LeftParen || tok == Tok_LeftBrace) {
 
1055
            }
 
1056
            else if (tok == Tok_LeftParen || tok == Tok_LeftBrace) {
921
1057
                ++parenAndBraceDepth;
922
 
            } else if (tok == Tok_RightParen || tok == Tok_RightBrace) {
 
1058
            }
 
1059
            else if (tok == Tok_RightParen || tok == Tok_RightBrace) {
923
1060
                if (--parenAndBraceDepth < 0)
924
1061
                    return false;
925
1062
            }
982
1119
                dataType->append(previousLexeme());
983
1120
            else
984
1121
                return false;
985
 
        } else if (match(Tok_int) || match(Tok_char) || match(Tok_double)) {
 
1122
        }
 
1123
        else if (match(Tok_int) || match(Tok_char) || match(Tok_double)) {
986
1124
            dataType->append(previousLexeme());
987
1125
        }
988
1126
 
1082
1220
            readToken();
1083
1221
        }
1084
1222
    }
1085
 
    func->addParameter(Parameter(dataType.toString(), "", name,
1086
 
                                  defaultValue.toString())); // ###
 
1223
    func->addParameter(Parameter(dataType.toString(),
 
1224
                                 "",
 
1225
                                 name,
 
1226
                                 defaultValue.toString())); // ###
1087
1227
    return true;
1088
1228
}
1089
1229
 
1131
1271
        compat = true;
1132
1272
 
1133
1273
    if (tok == Tok_operator &&
1134
 
         (returnType.toString().isEmpty() || returnType.toString().endsWith("::"))) {
 
1274
         (returnType.toString().isEmpty() ||
 
1275
          returnType.toString().endsWith("::"))) {
1135
1276
        // 'QString::operator const char *()'
1136
1277
        parentPath = returnType.toString().split(sep);
1137
1278
        parentPath.removeAll(QString());
1167
1308
            name = previousLexeme();
1168
1309
            matchTemplateAngles();
1169
1310
 
1170
 
            if (match(Tok_Gulbrandsen)) {
 
1311
            if (match(Tok_Gulbrandsen))
1171
1312
                parentPath.append(name);
1172
 
            } else {
 
1313
            else
1173
1314
                break;
1174
 
            }
1175
1315
        }
1176
1316
 
1177
1317
        if (tok == Tok_operator) {
1184
1324
                    break;
1185
1325
            }
1186
1326
        }
1187
 
        if (parent && (tok == Tok_Semicolon || tok == Tok_LeftBracket || tok == Tok_Colon)
 
1327
        if (parent && (tok == Tok_Semicolon ||
 
1328
                       tok == Tok_LeftBracket ||
 
1329
                       tok == Tok_Colon)
1188
1330
                && access != Node::Private) {
1189
1331
            if (tok == Tok_LeftBracket) {
1190
1332
                returnType.appendHotspot();
1198
1340
                }
1199
1341
                if (tok != Tok_Semicolon)
1200
1342
                    return false;
1201
 
            } else if (tok == Tok_Colon) {
 
1343
            }
 
1344
            else if (tok == Tok_Colon) {
1202
1345
                returnType.appendHotspot();
1203
1346
 
1204
1347
                while (tok != Tok_Semicolon && tok != Tok_Eoi) {
1390
1533
    QString namespaceName = previousLexeme();
1391
1534
    NamespaceNode *namespasse = 0;
1392
1535
    if (parent)
1393
 
        namespasse = static_cast<NamespaceNode *>(parent->findNode(namespaceName, Node::Namespace));
 
1536
        namespasse = static_cast<NamespaceNode*>(parent->findNode(namespaceName, Node::Namespace));
1394
1537
    if (!namespasse) {
1395
1538
        namespasse = new NamespaceNode(parent, namespaceName);
1396
1539
        namespasse->setAccess(access);
1456
1599
        if (strVal.isEmpty()) {
1457
1600
            if (enume->items().isEmpty()) {
1458
1601
                strVal = "0";
1459
 
            } else {
 
1602
            }
 
1603
            else {
1460
1604
                QString last = enume->items().last().value();
1461
1605
                bool ok;
1462
1606
                int n = last.toInt(&ok);
1466
1610
                            strVal = last.left(2) + QString::number(n + 1, 16);
1467
1611
                        else
1468
1612
                            strVal = "0" + QString::number(n + 1, 8);
1469
 
                    } else {
 
1613
                    }
 
1614
                    else
1470
1615
                        strVal = QString::number(n + 1);
1471
 
                    }
1472
1616
                }
1473
1617
            }
1474
1618
        }
1475
1619
 
1476
1620
        enume->addItem(EnumItem(name, strVal));
1477
 
    } else {
 
1621
    }
 
1622
    else {
1478
1623
        VariableNode *var = new VariableNode(parent, name);
1479
1624
        var->setAccess(access);
1480
1625
        var->setLocation(location());
1562
1707
 
1563
1708
        if (match(Tok_Ident)) {
1564
1709
            value = previousLexeme();
1565
 
        } else if (match(Tok_LeftParen)) {
 
1710
        }
 
1711
        else if (match(Tok_LeftParen)) {
1566
1712
            int depth = 1;
1567
1713
            while (tok != Tok_Eoi) {
1568
1714
                if (tok == Tok_LeftParen) {
1589
1735
            property->setDesignable(value.toLower() == "true");
1590
1736
        else if (key == "RESET")
1591
1737
            tre->addPropertyFunction(property, value, PropertyNode::Resetter);
 
1738
 
 
1739
        else if (key == "NOTIFY") {
 
1740
            tre->addPropertyFunction(property, value, PropertyNode::Notifier);
 
1741
        }
 
1742
 
1592
1743
    }
1593
1744
    match(Tok_RightParen);
1594
1745
    return true;
1753
1904
            readToken();
1754
1905
 
1755
1906
            Doc::trimCStyleComment(start_loc,comment);
1756
 
            /*
1757
 
              qdoc --> doxygen
1758
 
              We must also remember the location of the end
1759
 
              of the comment, so we can construct a diff for
1760
 
              it.
1761
 
            */
1762
1907
            Location end_loc(location());
1763
1908
 
1764
1909
            /*
1821
1966
                /*
1822
1967
                  There is a topic command. Process it.
1823
1968
                 */
 
1969
#ifdef QDOC_QML
 
1970
                if (topic == COMMAND_QMLPROPERTY) {
 
1971
                    Doc nodeDoc = doc;
 
1972
                    Node *node = processTopicCommandGroup(nodeDoc,topic,args);
 
1973
                    if (node != 0) {
 
1974
                        nodes.append(node);
 
1975
                        docs.append(nodeDoc);
 
1976
                    }
 
1977
                }
 
1978
                else {
 
1979
                    QStringList::ConstIterator a = args.begin();
 
1980
                    while (a != args.end()) {
 
1981
                        Doc nodeDoc = doc;
 
1982
                        Node *node = processTopicCommand(nodeDoc,topic,*a);
 
1983
                        if (node != 0) {
 
1984
                            nodes.append(node);
 
1985
                            docs.append(nodeDoc);
 
1986
                        }
 
1987
                        ++a;
 
1988
                    }
 
1989
                }
 
1990
#else
1824
1991
                QStringList::ConstIterator a = args.begin();
1825
1992
                while (a != args.end()) {
1826
1993
                    Doc nodeDoc = doc;
1831
1998
                    }
1832
1999
                    ++a;
1833
2000
                }
 
2001
#endif                
1834
2002
            }
1835
2003
 
1836
2004
            NodeList::Iterator n = nodes.begin();
1838
2006
            while (n != nodes.end()) {
1839
2007
                processOtherMetaCommands(*d, *n);
1840
2008
                (*n)->setDoc(*d);
1841
 
                if ((*n)->isInnerNode() && ((InnerNode *)*n)->includes().isEmpty()) {
 
2009
                if ((*n)->isInnerNode() &&
 
2010
                    ((InnerNode *)*n)->includes().isEmpty()) {
1842
2011
                    InnerNode *m = static_cast<InnerNode *>(*n);
1843
2012
                    while (m->parent() != tre->root())
1844
2013
                        m = m->parent();
1926
2095
        mutableSequentialIteratorDefinition = lines[1];
1927
2096
        associativeIteratorDefinition = lines[2];
1928
2097
        mutableAssociativeIteratorDefinition = lines[3];
1929
 
    } else {
 
2098
    }
 
2099
    else {
1930
2100
        location.warning(tr("The qiterator.h hack failed"));
1931
2101
    }
1932
2102
}
2008
2178
    foreach (const QString &exampleFile, exampleFiles)
2009
2179
        (void) new FakeNode(fake,
2010
2180
                            exampleFile.mid(sizeOfBoringPartOfName),
2011
 
                            FakeNode::File);
 
2181
                            Node::File);
2012
2182
}
2013
2183
 
2014
2184
QT_END_NAMESPACE