Ignore:
Timestamp:
May 5, 2011, 5:36:53 AM (14 years ago)
Author:
Dmitry A. Kuminov
Message:

trunk: Merged in qt 4.7.2 sources from branches/vendor/nokia/qt.

Location:
trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk

  • trunk/tools/qdoc3/node.cpp

    r651 r846  
    11/****************************************************************************
    22**
    3 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
     3** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
    44** All rights reserved.
    55** Contact: Nokia Corporation (qt-info@nokia.com)
     
    4444*/
    4545
    46 #include <QtCore>
    4746#include "node.h"
     47#include "tree.h"
     48#include "codemarker.h"
     49#include <qdebug.h>
    4850
    4951QT_BEGIN_NAMESPACE
     
    8688
    8789/*!
     90  Construct a node with the given \a type and having the
     91  given \a parent and \a name. The new node is added to the
     92  parent's child list.
    8893 */
    8994Node::Node(Type type, InnerNode *parent, const QString& name)
    9095    : typ(type),
    9196      acc(Public),
     97      saf(UnspecifiedSafeness),
     98      pageTyp(NoPageType),
    9299      sta(Commendable),
    93       saf(UnspecifiedSafeness),
    94100      par(parent),
    95101      rel(0),
     
    98104    if (par)
    99105        par->addChild(this);
    100 }
    101 
    102 /*!
     106    //uuid = QUuid::createUuid();
     107}
     108
     109/*!
     110  Returns the node's URL.
    103111 */
    104112QString Node::url() const
     
    108116
    109117/*!
     118  Sets the node's URL to \a url
    110119 */
    111120void Node::setUrl(const QString &url)
     
    114123}
    115124
    116 /*!
     125void Node::setPageType(const QString& t)
     126{
     127    if ((t == "API") || (t == "api"))
     128        pageTyp = ApiPage;
     129    else if (t == "article")
     130        pageTyp = ArticlePage;
     131    else if (t == "example")
     132        pageTyp = ExamplePage;
     133}
     134
     135/*!
     136  Sets the pointer to the node that this node relates to.
    117137 */
    118138void Node::setRelates(InnerNode *pseudoParent)
     
    138158
    139159/*!
     160  Returns a string representing the access specifier.
     161 */
     162QString Node::accessString() const
     163{
     164    switch (acc) {
     165    case Protected:
     166        return "protected";
     167    case Private:
     168        return "private";
     169    case Public:
     170    default:
     171        break;
     172    }
     173    return "public";
     174}
     175
     176/*!
     177  Extract a class name from the type \a string and return it.
     178 */
     179QString Node::extractClassName(const QString &string) const
     180{
     181    QString result;
     182    for (int i=0; i<=string.size(); ++i) {
     183        QChar ch;
     184        if (i != string.size())
     185            ch = string.at(i);
     186
     187        QChar lower = ch.toLower();
     188        if ((lower >= QLatin1Char('a') && lower <= QLatin1Char('z')) ||
     189            ch.digitValue() >= 0 ||
     190            ch == QLatin1Char('_') ||
     191            ch == QLatin1Char(':')) {
     192            result += ch;
     193        }
     194        else if (!result.isEmpty()) {
     195            if (result != QLatin1String("const"))
     196                return result;
     197            result.clear();
     198        }
     199    }
     200    return result;
     201}
     202
     203/*!
     204  Returns a string representing the access specifier.
     205 */
     206QString RelatedClass::accessString() const
     207{
     208    switch (access) {
     209    case Node::Protected:
     210        return "protected";
     211    case Node::Private:
     212        return "private";
     213    case Node::Public:
     214    default:
     215        break;
     216    }
     217    return "public";
     218}
     219
     220/*!
    140221 */
    141222Node::Status Node::inheritedStatus() const
     
    148229
    149230/*!
     231  Returns the thread safeness value for whatever this node
     232  represents. But if this node has a parent and the thread
     233  safeness value of the parent is the same as the thread
     234  safeness value of this node, what is returned is the
     235  value \c{UnspecifiedSafeness}. Why?
    150236 */
    151237Node::ThreadSafeness Node::threadSafeness() const
     
    157243
    158244/*!
     245  If this node has a parent, the parent's thread safeness
     246  value is returned. Otherwise, this node's thread safeness
     247  value is returned. Why?
    159248 */
    160249Node::ThreadSafeness Node::inheritedThreadSafeness() const
     
    166255
    167256/*!
     257  Returns the sanitized file name without the path.
     258  If the the file is an html file, the html suffix
     259  is removed. Why?
    168260 */
    169261QString Node::fileBase() const
     
    179271
    180272/*!
     273  Returns this node's Universally Unique IDentifier.
     274  If its UUID has not yet been created, it is created
     275  first.
     276 */
     277QUuid Node::guid() const
     278{
     279    if (uuid.isNull())
     280        uuid = QUuid::createUuid();
     281    return uuid;
     282}
     283
     284/*!
     285  Composes a string to be used as an href attribute in DITA
     286  XML. It is composed of the file name and the UUID separated
     287  by a '#'. If this node is a class node, the file name is
     288  taken from this node; if this node is a function node, the
     289  file name is taken from the parent node of this node.
     290 */
     291QString Node::ditaXmlHref()
     292{
     293    QString href;
     294    if ((type() == Function) ||
     295        (type() == Property) ||
     296        (type() == Variable)) {
     297        href = parent()->fileBase();
     298    }
     299    else {
     300        href = fileBase();
     301    }
     302    if (!href.endsWith(".xml"))
     303        href += ".xml";
     304    return href + "#" + guid();
     305}
     306
     307/*!
    181308  \class InnerNode
    182309 */
    183310
    184311/*!
     312  The inner node destructor deletes the children and removes
     313  this node from its related nodes.
    185314 */
    186315InnerNode::~InnerNode()
     
    191320
    192321/*!
     322  Find the node in this node's children that has the
     323  given \a name. If this node is a QML class node, be
     324  sure to also look in the children of its property
     325  group nodes. Return the matching node or 0.
    193326 */
    194327Node *InnerNode::findNode(const QString& name)
    195328{
    196329    Node *node = childMap.value(name);
    197     if (node)
     330    if (node && node->subType() != QmlPropertyGroup)
    198331        return node;
     332    if ((type() == Fake) && (subType() == QmlClass)) {
     333        for (int i=0; i<children.size(); ++i) {
     334            Node* n = children.at(i);
     335            if (n->subType() == QmlPropertyGroup) {
     336                node = static_cast<InnerNode*>(n)->findNode(name);
     337                if (node)
     338                    return node;
     339            }
     340        }
     341    }
    199342    return primaryFunctionMap.value(name);
    200343}
    201344
    202345/*!
     346  Same as the other findNode(), but if the node with the
     347  specified \a name is not of the specified \a type, return
     348  0.
    203349 */
    204350Node *InnerNode::findNode(const QString& name, Type type)
     
    309455
    310456/*!
     457  Mark all child nodes that have no documentation as having
     458  private access and internal status. qdoc will then ignore
     459  them for documentation purposes.
    311460 */
    312461void InnerNode::makeUndocumentedChildrenInternal()
     
    382531/*!
    383532 */
    384 void InnerNode::removeFromRelated() 
     533void InnerNode::removeFromRelated()
    385534{
    386535    while (!related.isEmpty()) {
     
    399548
    400549/*!
    401   Returns true.
     550  Returns true because this is an inner node.
    402551 */
    403552bool InnerNode::isInnerNode() const
     
    423572
    424573/*!
    425   Find the function node in this node that has the given \a name. 
     574  Find the function node in this node that has the given \a name.
    426575 */
    427576const FunctionNode *InnerNode::findFunctionNode(const QString& name) const
     
    453602
    454603/*!
     604  Returnds the sequence number of the function node \a func
     605  in the list of overloaded functions for a class, such that
     606  all the functions have the same name as the \a func.
    455607 */
    456608int InnerNode::overloadNumber(const FunctionNode *func) const
     
    466618
    467619/*!
     620  Returns the number of member functions of a class such that
     621  the functions are all named \a funcName.
    468622 */
    469623int InnerNode::numOverloads(const QString& funcName) const
     
    478632
    479633/*!
     634  Returns a node list containing all the member functions of
     635  some class such that the functions overload the name \a funcName.
    480636 */
    481637NodeList InnerNode::overloads(const QString &funcName) const
     
    491647
    492648/*!
     649  Construct an inner node (i.e., not a leaf node) of the
     650  given \a type and having the given \a parent and \a name.
    493651 */
    494652InnerNode::InnerNode(Type type, InnerNode *parent, const QString& name)
    495653    : Node(type, parent, name)
    496654{
    497 }
    498 
    499 /*!
     655    switch (type) {
     656    case Class:
     657    case Namespace:
     658        setPageType(ApiPage);
     659        break;
     660    default:
     661        break;
     662    }
     663}
     664
     665/*!
     666  Appends an \a include file to the list of include files.
    500667 */
    501668void InnerNode::addInclude(const QString& include)
     
    505672
    506673/*!
     674  Sets the list of include files to \a includes.
    507675 */
    508676void InnerNode::setIncludes(const QStringList& includes)
     
    548716
    549717/*!
     718  Adds the \a child to this node's child list.
    550719 */
    551720void InnerNode::addChild(Node *child)
     
    565734        if (child->type() == Enum)
    566735            enumChildren.append(child);
    567         childMap.insert(child->name(), child);
     736        childMap.insert(child->name(), child);
    568737    }
    569738}
     
    579748                primaryFunctionMap.find(child->name());
    580749        NodeList& secs = secondaryFunctionMap[child->name()];
    581         if (*prim == child) {
     750        if (prim != primaryFunctionMap.end() && *prim == child) {
    582751            if (secs.isEmpty()) {
    583752                primaryFunctionMap.remove(child->name());
     
    591760        }
    592761        QMap<QString, Node *>::Iterator ent = childMap.find( child->name() );
    593         if ( *ent == child )
     762        if (ent != childMap.end() && *ent == child)
    594763            childMap.erase( ent );
    595764    }
    596765    else {
    597766        QMap<QString, Node *>::Iterator ent = childMap.find(child->name());
    598         if (*ent == child)
     767        if (ent != childMap.end() && *ent == child)
    599768            childMap.erase(ent);
    600769    }
     
    677846
    678847/*!
     848  Constructs a leaf node named \a name of the specified
     849  \a type. The new leaf node becomes a child of \a parent.
    679850 */
    680851LeafNode::LeafNode(Type type, InnerNode *parent, const QString& name)
    681852    : Node(type, parent, name)
    682853{
     854    switch (type) {
     855    case Enum:
     856    case Function:
     857    case Typedef:
     858    case Variable:
     859    case QmlProperty:
     860    case QmlSignal:
     861    case QmlMethod:
     862        setPageType(ApiPage);
     863        break;
     864    default:
     865        break;
     866    }
    683867}
    684868
     
    688872
    689873/*!
     874  Constructs a namespace node.
    690875 */
    691876NamespaceNode::NamespaceNode(InnerNode *parent, const QString& name)
    692877    : InnerNode(Namespace, parent, name)
    693878{
     879    setPageType(ApiPage);
    694880}
    695881
    696882/*!
    697883  \class ClassNode
    698  */
    699 
    700 /*!
     884  \brief This class represents a C++ class.
     885 */
     886
     887/*!
     888  Constructs a class node. A class node will generate an API page.
    701889 */
    702890ClassNode::ClassNode(InnerNode *parent, const QString& name)
     
    704892{
    705893    hidden = false;
     894    abstract = false;
     895    setPageType(ApiPage);
    706896}
    707897
     
    712902                             const QString &dataTypeWithTemplateArgs)
    713903{
    714     bas.append(RelatedClass(access, node, dataTypeWithTemplateArgs));
    715     node->der.append(RelatedClass(access, this));
     904    bases.append(RelatedClass(access, node, dataTypeWithTemplateArgs));
     905    node->derived.append(RelatedClass(access, this));
    716906}
    717907
     
    721911{
    722912    int i;
    723 
    724913    i = 0;
    725     while (i < bas.size()) {
    726         ClassNode *baseClass = bas.at(i).node;
    727         if (baseClass->access() == Node::Private) {
    728             bas.removeAt(i);
    729 
    730             const QList<RelatedClass> &basesBases = baseClass->baseClasses();
    731             for (int j = basesBases.size() - 1; j >= 0; --j)
    732                 bas.insert(i, basesBases.at(j));
     914    while (i < bases.size()) {
     915        ClassNode* bc = bases.at(i).node;
     916        if (bc->access() == Node::Private) {
     917            RelatedClass rc = bases.at(i);
     918            bases.removeAt(i);
     919            ignoredBases.append(rc);
     920            const QList<RelatedClass> &bb = bc->baseClasses();
     921            for (int j = bb.size() - 1; j >= 0; --j)
     922                bases.insert(i, bb.at(j));
    733923        }
    734924        else {
     
    738928
    739929    i = 0;
    740     while (i < der.size()) {
    741         ClassNode *derivedClass = der.at(i).node;
    742         if (derivedClass->access() == Node::Private) {
    743             der.removeAt(i);
    744 
    745             const QList<RelatedClass> &dersDers =
    746                 derivedClass->derivedClasses();
    747             for (int j = dersDers.size() - 1; j >= 0; --j)
    748                 der.insert(i, dersDers.at(j));
     930    while (i < derived.size()) {
     931        ClassNode* dc = derived.at(i).node;
     932        if (dc->access() == Node::Private) {
     933            derived.removeAt(i);
     934            const QList<RelatedClass> &dd = dc->derivedClasses();
     935            for (int j = dd.size() - 1; j >= 0; --j)
     936                derived.insert(i, dd.at(j));
    749937        }
    750938        else {
     
    755943
    756944/*!
     945  Search the child list to find the property node with the
     946  specified \a name.
     947 */
     948const PropertyNode* ClassNode::findPropertyNode(const QString& name) const
     949{
     950    const Node* n = findNode(name,Node::Property);
     951    return (n ? static_cast<const PropertyNode*>(n) : 0);
     952}
     953
     954/*!
    757955  \class FakeNode
    758956 */
     
    760958/*!
    761959  The type of a FakeNode is Fake, and it has a \a subtype,
    762   which specifies the type of FakeNode.
     960  which specifies the type of FakeNode. The page type for
     961  the page index is set here.
    763962 */
    764963FakeNode::FakeNode(InnerNode *parent, const QString& name, SubType subtype)
    765964    : InnerNode(Fake, parent, name), sub(subtype)
    766965{
     966    switch (subtype) {
     967    case Module:
     968    case Page:
     969    case Group:
     970        setPageType(ArticlePage);
     971        break;
     972    case QmlClass:
     973    case QmlBasicType:
     974        setPageType(ApiPage);
     975        break;
     976    case Example:
     977        setPageType(ExamplePage);
     978        break;
     979    default:
     980        break;
     981    }
     982}
     983
     984/*!
     985  Returns the fake node's title. This is used for the page title.
     986*/
     987QString FakeNode::title() const
     988{
     989    return tle;
    767990}
    768991
     
    8171040
    8181041/*!
     1042  The constructor for the node representing an enum type
     1043  has a \a parent class and an enum type \a name.
    8191044 */
    8201045EnumNode::EnumNode(InnerNode *parent, const QString& name)
     
    8241049
    8251050/*!
     1051  Add \a item to the enum type's item list.
    8261052 */
    8271053void EnumNode::addItem(const EnumItem& item)
     
    8321058
    8331059/*!
     1060  Returns the access level of the enumeration item named \a name.
     1061  Apparently it is private if it has been omitted by qdoc's
     1062  omitvalue command. Otherwise it is public.
    8341063 */
    8351064Node::Access EnumNode::itemAccess(const QString &name) const
    8361065{
    837     if (doc().omitEnumItemNames().contains(name)) {
     1066    if (doc().omitEnumItemNames().contains(name))
    8381067        return Private;
    839     }
    840     else {
    841         return Public;
    842     }
     1068    return Public;
    8431069}
    8441070
     
    9051131/*!
    9061132  Assigning Parameter \a p to this Parameter copies the
    907   strings across. 
     1133  strings across.
    9081134 */
    9091135Parameter& Parameter::operator=(const Parameter& p)
     
    9751201
    9761202/*!
     1203  Sets the \a virtualness of this function. If the \a virtualness
     1204  is PureVirtual, and if the parent() is a ClassNode, set the parent's
     1205  \e abstract flag to true.
     1206 */
     1207void FunctionNode::setVirtualness(Virtualness virtualness)
     1208{
     1209    vir = virtualness;
     1210    if ((virtualness == PureVirtual) && parent() &&
     1211        (parent()->type() == Node::Class))
     1212        parent()->setAbstract(true);
     1213}
     1214
     1215/*!
    9771216 */
    9781217void FunctionNode::setOverload(bool overlode)
     
    10641303    }
    10651304    return names;
     1305}
     1306
     1307/*!
     1308  Returns a raw list of parameters. If \a names is true, the
     1309  names are included. If \a values is true, the default values
     1310  are included, if any are present.
     1311 */
     1312QString FunctionNode::rawParameters(bool names, bool values) const
     1313{
     1314    QString raw;
     1315    foreach (const Parameter &parameter, parameters()) {
     1316        raw += parameter.leftType() + parameter.rightType();
     1317        if (names)
     1318            raw += parameter.name();
     1319        if (values)
     1320            raw += parameter.defaultValue();
     1321    }
     1322    return raw;
    10661323}
    10671324
     
    11101367void FunctionNode::debug() const
    11111368{
    1112     qDebug() << "QML METHOD" << name() << "rt" << rt << "pp" << pp;
     1369    qDebug("QML METHOD %s rt %s pp %s",
     1370            qPrintable(name()), qPrintable(rt), qPrintable(pp.join(" ")));
    11131371}
    11141372
    11151373/*!
    11161374  \class PropertyNode
    1117  */
    1118 
    1119 /*!
     1375
     1376  This class describes one instance of using the Q_PROPERTY macro.
     1377 */
     1378
     1379/*!
     1380  The constructor sets the \a parent and the \a name, but
     1381  everything else is set to default values.
    11201382 */
    11211383PropertyNode::PropertyNode(InnerNode *parent, const QString& name)
     
    11231385      sto(Trool_Default),
    11241386      des(Trool_Default),
     1387      scr(Trool_Default),
     1388      wri(Trool_Default),
     1389      usr(Trool_Default),
     1390      cst(false),
     1391      fnl(false),
    11251392      overrides(0)
    11261393{
    1127 }
    1128 
    1129 /*!
    1130  */
    1131 void PropertyNode::setOverriddenFrom(const PropertyNode *baseProperty)
     1394    // nothing.
     1395}
     1396
     1397/*!
     1398  Sets this property's \e {overridden from} property to
     1399  \a baseProperty, which indicates that this property
     1400  overrides \a baseProperty. To begin with, all the values
     1401  in this property are set to the corresponding values in
     1402  \a baseProperty.
     1403
     1404  We probably should ensure that the constant and final
     1405  attributes are not being overridden improperly.
     1406 */
     1407void PropertyNode::setOverriddenFrom(const PropertyNode* baseProperty)
    11321408{
    11331409    for (int i = 0; i < NumFunctionRoles; ++i) {
     
    11391415    if (des == Trool_Default)
    11401416        des = baseProperty->des;
     1417    if (scr == Trool_Default)
     1418        scr = baseProperty->scr;
     1419    if (wri == Trool_Default)
     1420        wri = baseProperty->wri;
     1421    if (usr == Trool_Default)
     1422        usr = baseProperty->usr;
    11411423    overrides = baseProperty;
    11421424}
     
    11641446}
    11651447
    1166 /*!
     1448/*! Converts the \a boolean value to an enum representation
     1449  of the boolean type, which includes an enum  value for the
     1450  \e {default value} of the item, i.e. true, false, or default.
    11671451 */
    11681452PropertyNode::Trool PropertyNode::toTrool(bool boolean)
     
    11721456
    11731457/*!
     1458  Converts the enum \a troolean back to a boolean value.
     1459  If \a troolean is neither the true enum value nor the
     1460  false enum value, the boolean value returned is
     1461  \a defaultValue.
     1462
     1463  Note that runtimeDesignabilityFunction() should be called
     1464  first. If that function returns the name of a function, it
     1465  means the function must be called at runtime to determine
     1466  whether the property is Designable.
    11741467 */
    11751468bool PropertyNode::fromTrool(Trool troolean, bool defaultValue)
     
    12061499#ifdef QDOC_QML
    12071500bool QmlClassNode::qmlOnly = false;
    1208 
    1209 /*!
    1210   Constructor for the Qml class node.
     1501QMultiMap<QString,Node*> QmlClassNode::inheritedBy;
     1502
     1503/*!
     1504  Constructs a Qml class node (i.e. a Fake node with the
     1505  subtype QmlClass. The new node has the given \a parent
     1506  and \a name and is associated with the C++ class node
     1507  specified by \a cn which may be null if the the Qml
     1508  class node is not associated with a C++ class node.
    12111509 */
    12121510QmlClassNode::QmlClassNode(InnerNode *parent,
     
    12151513    : FakeNode(parent, name, QmlClass), cnode(cn)
    12161514{
    1217     setTitle((qmlOnly ? "" : "QML ") + name + " Element Reference");
     1515    if (name.startsWith(QLatin1String("QML:")))
     1516        setTitle((qmlOnly ? QLatin1String("") : QLatin1String("QML ")) + name.mid(4) + QLatin1String(" Element"));
     1517    else
     1518        setTitle((qmlOnly ? QLatin1String("") : QLatin1String("QML ")) + name + QLatin1String(" Element"));
     1519}
     1520
     1521/*!
     1522  I made this so I could print a debug message here.
     1523 */
     1524QmlClassNode::~QmlClassNode()
     1525{
     1526#ifdef DEBUG_MULTIPLE_QDOCCONF_FILES
     1527    qDebug() << "Deleting QmlClassNode:" << name();
     1528#endif
     1529}
     1530
     1531/*!
     1532  Clear the multimap so that subsequent runs don't try to use
     1533  nodes from a previous run.
     1534 */
     1535void QmlClassNode::clear()
     1536{
     1537    inheritedBy.clear();
    12181538}
    12191539
     
    12261546QString QmlClassNode::fileBase() const
    12271547{
    1228 #if 0   
     1548#if 0
    12291549    if (Node::fileBase() == "item")
    12301550        qDebug() << "FILEBASE: qmlitem" << name();
     
    12351555
    12361556/*!
     1557  Record the fact that QML class \a base is inherited by
     1558  QML class \a sub.
     1559 */
     1560void QmlClassNode::addInheritedBy(const QString& base, Node* sub)
     1561{
     1562    inheritedBy.insert(base,sub);
     1563#ifdef DEBUG_MULTIPLE_QDOCCONF_FILES
     1564    qDebug() << "QmlClassNode::addInheritedBy(): insert" << base << sub->name() << inheritedBy.size();
     1565#endif
     1566}
     1567
     1568/*!
     1569  Loads the list \a subs with the nodes of all the subclasses of \a base.
     1570 */
     1571void QmlClassNode::subclasses(const QString& base, NodeList& subs)
     1572{
     1573    subs.clear();
     1574    if (inheritedBy.count(base) > 0) {
     1575        subs = inheritedBy.values(base);
     1576#ifdef DEBUG_MULTIPLE_QDOCCONF_FILES
     1577        qDebug() << "QmlClassNode::subclasses():" <<  inheritedBy.count(base) << base
     1578                 << "subs:" << subs.size() << "total size:" << inheritedBy.size();
     1579#endif
     1580    }
     1581}
     1582
     1583/*!
     1584  Constructs a Qml basic type node (i.e. a Fake node with
     1585  the subtype QmlBasicType. The new node has the given
     1586  \a parent and \a name.
     1587 */
     1588QmlBasicTypeNode::QmlBasicTypeNode(InnerNode *parent,
     1589                                   const QString& name)
     1590    : FakeNode(parent, name, QmlBasicType)
     1591{
     1592    setTitle(name);
     1593}
     1594
     1595/*!
    12371596  Constructor for the Qml property group node. \a parent is
    1238   always a QmlClassNode. 
     1597  always a QmlClassNode.
    12391598 */
    12401599QmlPropGroupNode::QmlPropGroupNode(QmlClassNode* parent,
     
    12611620      att(attached)
    12621621{
    1263     // nothing.
     1622    setPageType(ApiPage);
    12641623}
    12651624
     
    12861645    }
    12871646}
     1647
     1648static QString valueType(const QString& n)
     1649{
     1650    if (n == "QPoint")
     1651        return "QDeclarativePointValueType";
     1652    if (n == "QPointF")
     1653        return "QDeclarativePointFValueType";
     1654    if (n == "QSize")
     1655        return "QDeclarativeSizeValueType";
     1656    if (n == "QSizeF")
     1657        return "QDeclarativeSizeFValueType";
     1658    if (n == "QRect")
     1659        return "QDeclarativeRectValueType";
     1660    if (n == "QRectF")
     1661        return "QDeclarativeRectFValueType";
     1662    if (n == "QVector2D")
     1663        return "QDeclarativeVector2DValueType";
     1664    if (n == "QVector3D")
     1665        return "QDeclarativeVector3DValueType";
     1666    if (n == "QVector4D")
     1667        return "QDeclarativeVector4DValueType";
     1668    if (n == "QQuaternion")
     1669        return "QDeclarativeQuaternionValueType";
     1670    if (n == "QMatrix4x4")
     1671        return "QDeclarativeMatrix4x4ValueType";
     1672    if (n == "QEasingCurve")
     1673        return "QDeclarativeEasingValueType";
     1674    if (n == "QFont")
     1675        return "QDeclarativeFontValueType";
     1676    return QString();
     1677}
     1678
     1679/*!
     1680  Returns true if a QML property or attached property is
     1681  read-only. The algorithm for figuring this out is long
     1682  amd tedious and almost certainly will break. It currently
     1683  doesn't work for qmlproperty bool PropertyChanges::explicit,
     1684  because the tokenized gets confused on "explicit" .
     1685 */
     1686bool QmlPropertyNode::isWritable(const Tree* tree) const
     1687{
     1688    Node* n = parent();
     1689    while (n && n->subType() != Node::QmlClass)
     1690        n = n->parent();
     1691    if (n) {
     1692        const QmlClassNode* qcn = static_cast<const QmlClassNode*>(n);
     1693        const ClassNode* cn = qcn->classNode();
     1694        if (cn) {
     1695            QStringList dotSplit = name().split(QChar('.'));
     1696            const PropertyNode* pn = cn->findPropertyNode(dotSplit[0]);
     1697            if (pn) {
     1698                if (dotSplit.size() > 1) {
     1699                    QStringList path(extractClassName(pn->qualifiedDataType()));
     1700                    const Node* nn = tree->findNode(path,Class);
     1701                    if (nn) {
     1702                        const ClassNode* cn = static_cast<const ClassNode*>(nn);
     1703                        pn = cn->findPropertyNode(dotSplit[1]);
     1704                        if (pn) {
     1705                            return pn->isWritable();
     1706                        }
     1707                        else {
     1708                            const QList<RelatedClass>& bases = cn->baseClasses();
     1709                            if (!bases.isEmpty()) {
     1710                                for (int i=0; i<bases.size(); ++i) {
     1711                                    const ClassNode* cn = bases[i].node;
     1712                                    pn = cn->findPropertyNode(dotSplit[1]);
     1713                                    if (pn) {
     1714                                        return pn->isWritable();
     1715                                    }
     1716                                }
     1717                            }
     1718                            const QList<RelatedClass>& ignoredBases = cn->ignoredBaseClasses();
     1719                            if (!ignoredBases.isEmpty()) {
     1720                                for (int i=0; i<ignoredBases.size(); ++i) {
     1721                                    const ClassNode* cn = ignoredBases[i].node;
     1722                                    pn = cn->findPropertyNode(dotSplit[1]);
     1723                                    if (pn) {
     1724                                        return pn->isWritable();
     1725                                    }
     1726                                }
     1727                            }
     1728                            QString vt = valueType(cn->name());
     1729                            if (!vt.isEmpty()) {
     1730                                QStringList path(vt);
     1731                                const Node* vtn = tree->findNode(path,Class);
     1732                                if (vtn) {
     1733                                    const ClassNode* cn = static_cast<const ClassNode*>(vtn);
     1734                                    pn = cn->findPropertyNode(dotSplit[1]);
     1735                                    if (pn) {
     1736                                        return pn->isWritable();
     1737                                    }
     1738                                }
     1739                            }
     1740                        }
     1741                    }
     1742                }
     1743                else {
     1744                    return pn->isWritable();
     1745                }
     1746            }
     1747            else {
     1748                const QList<RelatedClass>& bases = cn->baseClasses();
     1749                if (!bases.isEmpty()) {
     1750                    for (int i=0; i<bases.size(); ++i) {
     1751                        const ClassNode* cn = bases[i].node;
     1752                        pn = cn->findPropertyNode(dotSplit[0]);
     1753                        if (pn) {
     1754                            return pn->isWritable();
     1755                        }
     1756                    }
     1757                }
     1758                const QList<RelatedClass>& ignoredBases = cn->ignoredBaseClasses();
     1759                if (!ignoredBases.isEmpty()) {
     1760                    for (int i=0; i<ignoredBases.size(); ++i) {
     1761                        const ClassNode* cn = ignoredBases[i].node;
     1762                        pn = cn->findPropertyNode(dotSplit[0]);
     1763                        if (pn) {
     1764                            return pn->isWritable();
     1765                        }
     1766                    }
     1767                }
     1768                if (isAttached()) {
     1769                    QString classNameAttached = cn->name() + "Attached";
     1770                    QStringList path(classNameAttached);
     1771                    const Node* nn = tree->findNode(path,Class);
     1772                    const ClassNode* acn = static_cast<const ClassNode*>(nn);
     1773                    pn = acn->findPropertyNode(dotSplit[0]);
     1774                    if (pn) {
     1775                        return pn->isWritable();
     1776                    }
     1777                }
     1778            }
     1779        }
     1780    }
     1781    location().warning(tr("Can't determine read-only status of QML property %1; writable assumed.").arg(name()));
     1782    return true;
     1783}
     1784
    12881785#endif
    12891786
Note: See TracChangeset for help on using the changeset viewer.