Skip to content
Permalink
Browse files
2010-01-27 Kent Hansen <kent.hansen@nokia.com>
        Reviewed by Simon Hausmann.

        [Qt] Meta-methods can't be introspected using ES5 API
        https://bugs.webkit.org/show_bug.cgi?id=34087

        Add getOwnPropertyDescriptor() and getOwnPropertyNames() reimplementations.

        Tests are in WebKit/qt/tests/qwebframe

        * bridge/qt/qt_runtime.cpp:
        (JSC::Bindings::QtRuntimeMetaMethod::getOwnPropertyDescriptor):
        (JSC::Bindings::QtRuntimeMetaMethod::getOwnPropertyNames):
        (JSC::Bindings::QtRuntimeConnectionMethod::getOwnPropertyDescriptor):
        (JSC::Bindings::QtRuntimeConnectionMethod::getOwnPropertyNames):
        * bridge/qt/qt_runtime.h:
2010-01-27  Kent Hansen  <kent.hansen@nokia.com>

        Reviewed by Simon Hausmann.

        [Qt] Meta-methods can't be introspected using ES5 API
        https://bugs.webkit.org/show_bug.cgi?id=34087

        Test that Object.getOwnPropertyDescriptor and
        Object.getOwnPropertyNames work with meta-methods.

        * tests/qwebframe/tst_qwebframe.cpp:

Canonical link: https://commits.webkit.org/45313@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@53930 268f45cc-cd09-0410-ab3c-d52691b4dbfc
  • Loading branch information
eseidel committed Jan 27, 2010
1 parent fb7233e commit 49f32e3e8eb13343b34e9072cae50139a5e1745f
Showing with 136 additions and 1 deletion.
  1. +18 −0 WebCore/ChangeLog
  2. +57 −0 WebCore/bridge/qt/qt_runtime.cpp
  3. +5 −1 WebCore/bridge/qt/qt_runtime.h
  4. +12 −0 WebKit/qt/ChangeLog
  5. +44 −0 WebKit/qt/tests/qwebframe/tst_qwebframe.cpp
@@ -1,3 +1,21 @@
2010-01-27 Kent Hansen <kent.hansen@nokia.com>

Reviewed by Simon Hausmann.

[Qt] Meta-methods can't be introspected using ES5 API
https://bugs.webkit.org/show_bug.cgi?id=34087

Add getOwnPropertyDescriptor() and getOwnPropertyNames() reimplementations.

Tests are in WebKit/qt/tests/qwebframe

* bridge/qt/qt_runtime.cpp:
(JSC::Bindings::QtRuntimeMetaMethod::getOwnPropertyDescriptor):
(JSC::Bindings::QtRuntimeMetaMethod::getOwnPropertyNames):
(JSC::Bindings::QtRuntimeConnectionMethod::getOwnPropertyDescriptor):
(JSC::Bindings::QtRuntimeConnectionMethod::getOwnPropertyNames):
* bridge/qt/qt_runtime.h:

2010-01-27 Tony Chang <tony@chromium.org>

Reviewed by Eric Seidel.
@@ -1400,6 +1400,43 @@ bool QtRuntimeMetaMethod::getOwnPropertySlot(ExecState* exec, const Identifier&
return QtRuntimeMethod::getOwnPropertySlot(exec, propertyName, slot);
}

bool QtRuntimeMetaMethod::getOwnPropertyDescriptor(ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor)
{
if (propertyName == "connect") {
PropertySlot slot;
slot.setCustom(this, connectGetter);
descriptor.setDescriptor(slot.getValue(exec, propertyName), DontDelete | ReadOnly | DontEnum);
return true;
}

if (propertyName == "disconnect") {
PropertySlot slot;
slot.setCustom(this, disconnectGetter);
descriptor.setDescriptor(slot.getValue(exec, propertyName), DontDelete | ReadOnly | DontEnum);
return true;
}

if (propertyName == exec->propertyNames().length) {
PropertySlot slot;
slot.setCustom(this, lengthGetter);
descriptor.setDescriptor(slot.getValue(exec, propertyName), DontDelete | ReadOnly | DontEnum);
return true;
}

return QtRuntimeMethod::getOwnPropertyDescriptor(exec, propertyName, descriptor);
}

void QtRuntimeMetaMethod::getOwnPropertyNames(ExecState* exec, PropertyNameArray& propertyNames, EnumerationMode mode)
{
if (mode == IncludeDontEnumProperties) {
propertyNames.add(Identifier(exec, "connect"));
propertyNames.add(Identifier(exec, "disconnect"));
propertyNames.add(exec->propertyNames().length);
}

QtRuntimeMethod::getOwnPropertyNames(exec, propertyNames, mode);
}

JSValue QtRuntimeMetaMethod::lengthGetter(ExecState* exec, const Identifier&, const PropertySlot&)
{
// QtScript always returns 0
@@ -1586,6 +1623,26 @@ bool QtRuntimeConnectionMethod::getOwnPropertySlot(ExecState* exec, const Identi
return QtRuntimeMethod::getOwnPropertySlot(exec, propertyName, slot);
}

bool QtRuntimeConnectionMethod::getOwnPropertyDescriptor(ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor)
{
if (propertyName == exec->propertyNames().length) {
PropertySlot slot;
slot.setCustom(this, lengthGetter);
descriptor.setDescriptor(slot.getValue(exec, propertyName), DontDelete | ReadOnly | DontEnum);
return true;
}

return QtRuntimeMethod::getOwnPropertyDescriptor(exec, propertyName, descriptor);
}

void QtRuntimeConnectionMethod::getOwnPropertyNames(ExecState* exec, PropertyNameArray& propertyNames, EnumerationMode mode)
{
if (mode == IncludeDontEnumProperties)
propertyNames.add(exec->propertyNames().length);

QtRuntimeMethod::getOwnPropertyNames(exec, propertyNames, mode);
}

JSValue QtRuntimeConnectionMethod::lengthGetter(ExecState* exec, const Identifier&, const PropertySlot&)
{
// we have one formal argument, and one optional
@@ -155,7 +155,7 @@ class QtRuntimeMethod : public InternalFunction {
}

protected:
static const unsigned StructureFlags = OverridesGetOwnPropertySlot | InternalFunction::StructureFlags | OverridesMarkChildren;
static const unsigned StructureFlags = OverridesGetOwnPropertySlot | OverridesGetPropertyNames | InternalFunction::StructureFlags | OverridesMarkChildren;

QtRuntimeMethodData *d_func() const {return d_ptr;}
QtRuntimeMethod(QtRuntimeMethodData *dd, ExecState *exec, const Identifier &n, PassRefPtr<QtInstance> inst);
@@ -168,6 +168,8 @@ class QtRuntimeMetaMethod : public QtRuntimeMethod
QtRuntimeMetaMethod(ExecState *exec, const Identifier &n, PassRefPtr<QtInstance> inst, int index, const QByteArray& signature, bool allowPrivate);

virtual bool getOwnPropertySlot(ExecState *, const Identifier&, PropertySlot&);
virtual bool getOwnPropertyDescriptor(ExecState*, const Identifier&, PropertyDescriptor&);
virtual void getOwnPropertyNames(ExecState*, PropertyNameArray&, EnumerationMode mode = ExcludeDontEnumProperties);

virtual void markChildren(MarkStack& markStack);

@@ -189,6 +191,8 @@ class QtRuntimeConnectionMethod : public QtRuntimeMethod
QtRuntimeConnectionMethod(ExecState *exec, const Identifier &n, bool isConnect, PassRefPtr<QtInstance> inst, int index, const QByteArray& signature );

virtual bool getOwnPropertySlot(ExecState *, const Identifier&, PropertySlot&);
virtual bool getOwnPropertyDescriptor(ExecState*, const Identifier&, PropertyDescriptor&);
virtual void getOwnPropertyNames(ExecState*, PropertyNameArray&, EnumerationMode mode = ExcludeDontEnumProperties);

protected:
QtRuntimeConnectionMethodData* d_func() const {return reinterpret_cast<QtRuntimeConnectionMethodData*>(d_ptr);}
@@ -1,3 +1,15 @@
2010-01-27 Kent Hansen <kent.hansen@nokia.com>

Reviewed by Simon Hausmann.

[Qt] Meta-methods can't be introspected using ES5 API
https://bugs.webkit.org/show_bug.cgi?id=34087

Test that Object.getOwnPropertyDescriptor and
Object.getOwnPropertyNames work with meta-methods.

* tests/qwebframe/tst_qwebframe.cpp:

2010-01-26 Simon Hausmann <simon.hausmann@nokia.com>

Reviewed by Kenneth Rohde Christiansen.
@@ -573,6 +573,8 @@ private slots:
void evaluateWillCauseRepaint();
void qObjectWrapperWithSameIdentity();
void scrollRecursively();
void introspectQtMethods_data();
void introspectQtMethods();

private:
QString evalJS(const QString&s) {
@@ -2861,5 +2863,47 @@ void tst_QWebFrame::scrollRecursively()

}

void tst_QWebFrame::introspectQtMethods_data()
{
QTest::addColumn<QString>("objectExpression");
QTest::addColumn<QString>("methodName");
QTest::addColumn<QStringList>("expectedPropertyNames");

QTest::newRow("myObject.mySignal")
<< "myObject" << "mySignal" << (QStringList() << "connect" << "disconnect" << "length" << "name");
QTest::newRow("myObject.mySlot")
<< "myObject" << "mySlot" << (QStringList() << "connect" << "disconnect" << "length" << "name");
QTest::newRow("myObject.myInvokable")
<< "myObject" << "myInvokable" << (QStringList() << "connect" << "disconnect" << "length" << "name");
QTest::newRow("myObject.mySignal.connect")
<< "myObject.mySignal" << "connect" << (QStringList() << "length" << "name");
QTest::newRow("myObject.mySignal.disconnect")
<< "myObject.mySignal" << "disconnect" << (QStringList() << "length" << "name");
}

void tst_QWebFrame::introspectQtMethods()
{
QFETCH(QString, objectExpression);
QFETCH(QString, methodName);
QFETCH(QStringList, expectedPropertyNames);

QString methodLookup = QString::fromLatin1("%0['%1']").arg(objectExpression).arg(methodName);
QCOMPARE(evalJSV(QString::fromLatin1("Object.getOwnPropertyNames(%0).sort()").arg(methodLookup)).toStringList(), expectedPropertyNames);

for (int i = 0; i < expectedPropertyNames.size(); ++i) {
QString name = expectedPropertyNames.at(i);
QCOMPARE(evalJS(QString::fromLatin1("%0.hasOwnProperty('%1')").arg(methodLookup).arg(name)), sTrue);
evalJS(QString::fromLatin1("var descriptor = Object.getOwnPropertyDescriptor(%0, '%1')").arg(methodLookup).arg(name));
QCOMPARE(evalJS("typeof descriptor"), QString::fromLatin1("object"));
QCOMPARE(evalJS("descriptor.get"), sUndefined);
QCOMPARE(evalJS("descriptor.set"), sUndefined);
QCOMPARE(evalJS(QString::fromLatin1("descriptor.value === %0['%1']").arg(methodLookup).arg(name)), sTrue);
QCOMPARE(evalJS(QString::fromLatin1("descriptor.enumerable")), sFalse);
QCOMPARE(evalJS(QString::fromLatin1("descriptor.configurable")), sFalse);
}

QVERIFY(evalJSV("var props=[]; for (var p in myObject.deleteLater) {props.push(p);}; props.sort()").toStringList().isEmpty());
}

QTEST_MAIN(tst_QWebFrame)
#include "tst_qwebframe.moc"

0 comments on commit 49f32e3

Please sign in to comment.