Changeset 62921 in webkit


Ignore:
Timestamp:
Jul 9, 2010 2:19:34 AM (14 years ago)
Author:
Simon Hausmann
Message:

Implementation of the QScriptValue::propertyFlags function.

Patch by Jedrzej Nowacki <jedrzej.nowacki@nokia.com> on 2010-07-09
Reviewed by Simon Hausmann.

The function returns the flags of a property with the given name,
using a given mode to resolve the property. This is a simple
implementation that is sufficient to test the QScriptValueIterator.

[Qt] QScriptValue API should have a property flag accessor.
https://bugs.webkit.org/show_bug.cgi?id=41769

  • api/qscriptvalue.cpp:

(QScriptValue::propertyFlags):

  • api/qscriptvalue.h:
  • api/qscriptvalue_p.h:

(QScriptValuePrivate::propertyFlags):

  • tests/qscriptvalue/tst_qscriptvalue.cpp:

(tst_QScriptValue::propertyFlag_data):
(tst_QScriptValue::propertyFlag):

  • tests/qscriptvalue/tst_qscriptvalue.h:
Location:
trunk/JavaScriptCore/qt
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/JavaScriptCore/qt/ChangeLog

    r62661 r62921  
     12010-07-09  Jedrzej Nowacki  <jedrzej.nowacki@nokia.com>
     2
     3        Reviewed by Simon Hausmann.
     4
     5        Implementation of the QScriptValue::propertyFlags function.
     6
     7        The function returns the flags of a property with the given name,
     8        using a given mode to resolve the property. This is a simple
     9        implementation that is sufficient to test the QScriptValueIterator.
     10
     11        [Qt] QScriptValue API should have a property flag accessor.
     12        https://bugs.webkit.org/show_bug.cgi?id=41769
     13
     14        * api/qscriptvalue.cpp:
     15        (QScriptValue::propertyFlags):
     16        * api/qscriptvalue.h:
     17        * api/qscriptvalue_p.h:
     18        (QScriptValuePrivate::propertyFlags):
     19        * tests/qscriptvalue/tst_qscriptvalue.cpp:
     20        (tst_QScriptValue::propertyFlag_data):
     21        (tst_QScriptValue::propertyFlag):
     22        * tests/qscriptvalue/tst_qscriptvalue.h:
     23
    1242010-07-07  Caio Marcelo de Oliveira Filho  <caio.oliveira@openbossa.org>
    225
  • trunk/JavaScriptCore/qt/api/qscriptvalue.cpp

    r62661 r62921  
    756756    d_ptr->setProperty(QScriptStringPrivate::get(name).constData(), QScriptValuePrivate::get(value), flags);
    757757}
     758
     759/*!
     760  Returns the flags of the property with the given \a name, using the
     761  given \a mode to resolve the property.
     762
     763  \sa property()
     764*/
     765QScriptValue::PropertyFlags QScriptValue::propertyFlags(const QString& name, const ResolveFlags& mode) const
     766{
     767    return d_ptr->propertyFlags(name, mode);
     768}
     769
     770/*!
     771  Returns the flags of the property with the given \a name, using the
     772  given \a mode to resolve the property.
     773
     774  \sa property()
     775*/
     776QScriptValue::PropertyFlags QScriptValue::propertyFlags(const QScriptString& name, const ResolveFlags& mode) const
     777{
     778    return d_ptr->propertyFlags(QScriptStringPrivate::get(name).constData(), mode);
     779}
  • trunk/JavaScriptCore/qt/api/qscriptvalue.h

    r62661 r62921  
    9797    void setProperty(const QScriptString& name, const QScriptValue& value, const PropertyFlags& flags = KeepExistingFlags);
    9898
     99    PropertyFlags propertyFlags(const QString& name, const ResolveFlags& mode = ResolvePrototype) const;
     100    PropertyFlags propertyFlags(const QScriptString& name, const ResolveFlags& mode = ResolvePrototype) const;
     101
    99102    QScriptEngine* engine() const;
    100103
  • trunk/JavaScriptCore/qt/api/qscriptvalue_p.h

    r62661 r62921  
    141141    template<typename T>
    142142    inline void setProperty(T name, QScriptValuePrivate* value, const QScriptValue::PropertyFlags& flags);
     143
     144    QScriptValue::PropertyFlags propertyFlags(const QString& name, const QScriptValue::ResolveFlags& mode);
     145    QScriptValue::PropertyFlags propertyFlags(const QScriptStringPrivate* name, const QScriptValue::ResolveFlags& mode);
     146    QScriptValue::PropertyFlags propertyFlags(const JSStringRef name, const QScriptValue::ResolveFlags& mode);
    143147
    144148    inline QScriptValuePrivate* call(const QScriptValuePrivate* , const QScriptValueList& args);
     
    990994}
    991995
     996inline QScriptValue::PropertyFlags QScriptValuePrivate::propertyFlags(const QString& name, const QScriptValue::ResolveFlags& mode)
     997{
     998    JSRetainPtr<JSStringRef> propertyName(Adopt, QScriptConverter::toString(name));
     999    return propertyFlags(propertyName.get(), mode);
     1000}
     1001
     1002inline QScriptValue::PropertyFlags QScriptValuePrivate::propertyFlags(const QScriptStringPrivate* name, const QScriptValue::ResolveFlags& mode)
     1003{
     1004    return propertyFlags(*name, mode);
     1005}
     1006
     1007inline QScriptValue::PropertyFlags QScriptValuePrivate::propertyFlags(JSStringRef name, const QScriptValue::ResolveFlags& mode)
     1008{
     1009    unsigned flags = 0;
     1010    if (!isObject())
     1011        return QScriptValue::PropertyFlags(flags);
     1012
     1013    // FIXME It could be faster and nicer, but new JSC C API should be created.
     1014    static JSStringRef objectName = QScriptConverter::toString("Object");
     1015    static JSStringRef propertyDescriptorName = QScriptConverter::toString("getOwnPropertyDescriptor");
     1016
     1017    // FIXME This is dangerous if global object was modified (bug 41839).
     1018    JSValueRef exception = 0;
     1019    JSObjectRef globalObject = JSContextGetGlobalObject(*m_engine);
     1020    JSValueRef objectConstructor = JSObjectGetProperty(*m_engine, globalObject, objectName, &exception);
     1021    Q_ASSERT(JSValueIsObject(*m_engine, objectConstructor));
     1022    JSValueRef propertyDescriptorGetter = JSObjectGetProperty(*m_engine, const_cast<JSObjectRef>(objectConstructor), propertyDescriptorName, &exception);
     1023    Q_ASSERT(JSValueIsObject(*m_engine, propertyDescriptorGetter));
     1024
     1025    JSValueRef arguments[] = { *this, JSValueMakeString(*m_engine, name) };
     1026    JSObjectRef propertyDescriptor
     1027            = const_cast<JSObjectRef>(JSObjectCallAsFunction(*m_engine,
     1028                                                            const_cast<JSObjectRef>(propertyDescriptorGetter),
     1029                                                            /* thisObject */ 0,
     1030                                                            /* argumentCount */ 2,
     1031                                                            arguments,
     1032                                                            &exception));
     1033    if (exception) {
     1034        // Invalid property.
     1035        return QScriptValue::PropertyFlags(flags);
     1036    }
     1037
     1038    if (!JSValueIsObject(*m_engine, propertyDescriptor)) {
     1039        // Property isn't owned by this object.
     1040        JSObjectRef proto;
     1041        if (mode == QScriptValue::ResolveLocal
     1042                || ((proto = const_cast<JSObjectRef>(JSObjectGetPrototype(*m_engine, *this))) && JSValueIsNull(*m_engine, proto))) {
     1043            return QScriptValue::PropertyFlags(flags);
     1044        }
     1045        QScriptValuePrivate p(engine(), proto);
     1046        return p.propertyFlags(name, QScriptValue::ResolvePrototype);
     1047    }
     1048
     1049    static JSStringRef writableName = QScriptConverter::toString("writable");
     1050    static JSStringRef configurableName = QScriptConverter::toString("configurable");
     1051    static JSStringRef enumerableName = QScriptConverter::toString("enumerable");
     1052
     1053    bool readOnly = !JSValueToBoolean(*m_engine, JSObjectGetProperty(*m_engine, propertyDescriptor, writableName, &exception));
     1054    if (!exception && readOnly)
     1055        flags |= QScriptValue::ReadOnly;
     1056    bool undeletable = !JSValueToBoolean(*m_engine, JSObjectGetProperty(*m_engine, propertyDescriptor, configurableName, &exception));
     1057    if (!exception && undeletable)
     1058        flags |= QScriptValue::Undeletable;
     1059    bool skipInEnum = !JSValueToBoolean(*m_engine, JSObjectGetProperty(*m_engine, propertyDescriptor, enumerableName, &exception));
     1060    if (!exception && skipInEnum)
     1061        flags |= QScriptValue::SkipInEnumeration;
     1062
     1063    return QScriptValue::PropertyFlags(flags);
     1064}
    9921065
    9931066QScriptValuePrivate* QScriptValuePrivate::call(const QScriptValuePrivate*, const QScriptValueList& args)
  • trunk/JavaScriptCore/qt/tests/qscriptvalue/tst_qscriptvalue.cpp

    r62547 r62921  
    12201220}
    12211221
     1222void tst_QScriptValue::propertyFlag_data()
     1223{
     1224    QTest::addColumn<QString>("name");
     1225    QTest::addColumn<int>("flag");
     1226
     1227    QTest::newRow("?Cr@jzi!%$") << "?Cr@jzi!%$" << static_cast<int>(0);
     1228    QTest::newRow("ReadOnly") << "ReadOnly" << static_cast<int>(QScriptValue::ReadOnly);
     1229    QTest::newRow("Undeletable") << "Undeletable" << static_cast<int>(QScriptValue::Undeletable);
     1230    QTest::newRow("SkipInEnumeration") << "SkipInEnumeration" << static_cast<int>(QScriptValue::SkipInEnumeration);
     1231    QTest::newRow("ReadOnly | Undeletable") << "ReadOnly_Undeletable" << static_cast<int>(QScriptValue::ReadOnly | QScriptValue::Undeletable);
     1232    QTest::newRow("ReadOnly | SkipInEnumeration") << "ReadOnly_SkipInEnumeration" << static_cast<int>(QScriptValue::ReadOnly | QScriptValue::SkipInEnumeration);
     1233    QTest::newRow("Undeletable | SkipInEnumeration") << "Undeletable_SkipInEnumeration" << static_cast<int>(QScriptValue::Undeletable | QScriptValue::SkipInEnumeration);
     1234    QTest::newRow("ReadOnly | Undeletable | SkipInEnumeration") << "ReadOnly_Undeletable_SkipInEnumeration" << static_cast<int>(QScriptValue::ReadOnly | QScriptValue::Undeletable | QScriptValue::SkipInEnumeration);
     1235}
     1236
     1237void tst_QScriptValue::propertyFlag()
     1238{
     1239    QScriptEngine engine;
     1240    QFETCH(QString, name);
     1241    QFETCH(int, flag);
     1242    const QScriptString nameHandle = engine.toStringHandle(name);
     1243    const QString protoName = "proto" + name;
     1244    const QScriptString protoNameHandle = engine.toStringHandle(protoName);
     1245
     1246    QScriptValue proto = engine.newObject();
     1247    QScriptValue object = engine.newObject();
     1248    object.setPrototype(proto);
     1249
     1250    proto.setProperty(protoName, QScriptValue(124816), QScriptValue::PropertyFlag(flag));
     1251    object.setProperty(name, QScriptValue(124816), QScriptValue::PropertyFlag(flag));
     1252
     1253    // Check using QString name
     1254    QCOMPARE(object.propertyFlags(name), QScriptValue::PropertyFlag(flag));
     1255    QCOMPARE(object.propertyFlags(protoName, QScriptValue::ResolvePrototype), QScriptValue::PropertyFlag(flag));
     1256    QVERIFY(!object.propertyFlags(protoName, QScriptValue::ResolveLocal));
     1257
     1258    // Check using QScriptString name
     1259    QCOMPARE(object.propertyFlags(nameHandle), QScriptValue::PropertyFlag(flag));
     1260    QCOMPARE(object.propertyFlags(protoNameHandle, QScriptValue::ResolvePrototype), QScriptValue::PropertyFlag(flag));
     1261    QVERIFY(!object.propertyFlags(protoNameHandle, QScriptValue::ResolveLocal));
     1262}
     1263
    12221264QTEST_MAIN(tst_QScriptValue)
  • trunk/JavaScriptCore/qt/tests/qscriptvalue/tst_qscriptvalue.h

    r62547 r62921  
    5959    void getSetProperty();
    6060    void getPropertyResolveFlag();
     61    void propertyFlag_data();
     62    void propertyFlag();
    6163
    6264    // Generated test functions.
Note: See TracChangeset for help on using the changeset viewer.