summaryrefslogtreecommitdiffstats
path: root/src/script/api/qscriptvalue.cpp
diff options
context:
space:
mode:
authorKent Hansen <khansen@trolltech.com>2009-07-28 12:06:43 (GMT)
committerKent Hansen <khansen@trolltech.com>2009-07-28 12:08:43 (GMT)
commitc11ddcf4c5f47db78a07123a0d534748c0672b0a (patch)
tree90ecfeb49f4232671da581e8d02e14ffc5f00608 /src/script/api/qscriptvalue.cpp
parent09a9014ded34d58177a782b44d385edf86b61f37 (diff)
downloadQt-c11ddcf4c5f47db78a07123a0d534748c0672b0a.zip
Qt-c11ddcf4c5f47db78a07123a0d534748c0672b0a.tar.gz
Qt-c11ddcf4c5f47db78a07123a0d534748c0672b0a.tar.bz2
make more tests pass for QScriptValue::setProperty()
JSC doesn't provide a way of un-defining a getter/setter. If deleting e.g. only the setter, we remember the getter, delete the property, then re-establish the getter.
Diffstat (limited to 'src/script/api/qscriptvalue.cpp')
-rw-r--r--src/script/api/qscriptvalue.cpp76
1 files changed, 53 insertions, 23 deletions
diff --git a/src/script/api/qscriptvalue.cpp b/src/script/api/qscriptvalue.cpp
index 59e6729..d410973 100644
--- a/src/script/api/qscriptvalue.cpp
+++ b/src/script/api/qscriptvalue.cpp
@@ -1857,34 +1857,64 @@ void QScriptValue::setProperty(const QScriptString &name,
JSC::ExecState *exec = eng_p->currentFrame;
JSC::JSValue jscValue = eng_p->scriptValueToJSCValue(value);
JSC::Identifier id = name.d_ptr->identifier;
- if (!jscValue) {
- JSC::asObject(d->jscValue)->deleteProperty(exec, id);
- } else {
- if ((flags & QScriptValue::PropertyGetter) || (flags & QScriptValue::PropertySetter)) {
- if (jscValue.isObject()) {
- if (flags & QScriptValue::PropertyGetter)
- JSC::asObject(d->jscValue)->defineGetter(exec, id, JSC::asObject(jscValue));
- if (flags & QScriptValue::PropertySetter)
- JSC::asObject(d->jscValue)->defineSetter(exec, id, JSC::asObject(jscValue));
+ JSC::JSObject *thisObject = JSC::asObject(d->jscValue);
+ JSC::JSValue setter = thisObject->lookupSetter(exec, id);
+ JSC::JSValue getter = thisObject->lookupGetter(exec, id);
+ if ((flags & QScriptValue::PropertyGetter) || (flags & QScriptValue::PropertySetter)) {
+ if (!jscValue) {
+ // deleting getter/setter
+ if ((flags & QScriptValue::PropertyGetter) && (flags & QScriptValue::PropertySetter)) {
+ // deleting both: just delete the property
+ thisObject->deleteProperty(exec, id);
+ } else if (flags & QScriptValue::PropertyGetter) {
+ // preserve setter, if there is one
+ thisObject->deleteProperty(exec, id);
+ if (setter && setter.isObject())
+ thisObject->defineSetter(exec, id, JSC::asObject(setter));
+ } else { // flags & QScriptValue::PropertySetter
+ // preserve getter, if there is one
+ thisObject->deleteProperty(exec, id);
+ if (getter && getter.isObject())
+ thisObject->defineGetter(exec, id, JSC::asObject(getter));
}
} else {
- if (flags != QScriptValue::KeepExistingFlags) {
- if (JSC::asObject(d->jscValue)->hasOwnProperty(exec, id))
- JSC::asObject(d->jscValue)->deleteProperty(exec, id);
- unsigned attribs = 0;
- if (flags & QScriptValue::ReadOnly)
- attribs |= JSC::ReadOnly;
- if (flags & QScriptValue::SkipInEnumeration)
- attribs |= JSC::DontEnum;
- if (flags & QScriptValue::Undeletable)
- attribs |= JSC::DontDelete;
- attribs |= flags & QScriptValue::UserRange;
- JSC::asObject(d->jscValue)->putWithAttributes(exec, id, jscValue, attribs);
+ if (jscValue.isObject()) { // ### should check if it has callData()
+ // defining getter/setter
+ if (flags & QScriptValue::PropertyGetter)
+ thisObject->defineGetter(exec, id, JSC::asObject(jscValue));
+ if (flags & QScriptValue::PropertySetter)
+ thisObject->defineSetter(exec, id, JSC::asObject(jscValue));
} else {
- JSC::PutPropertySlot slot;
- JSC::asObject(d->jscValue)->put(exec, id, jscValue, slot);
+ qWarning("QScriptValue::setProperty(): getter/setter must be a function");
}
}
+ } else {
+ // setting the value
+ if (getter && getter.isObject() && !(setter && setter.isObject())) {
+ qWarning("QScriptValue::setProperty() failed: "
+ "property '%s' has a getter but no setter",
+ qPrintable(name.toString()));
+ return;
+ }
+ if (!jscValue) {
+ // ### check if it's a getter/setter property
+ thisObject->deleteProperty(exec, id);
+ } else if (flags != QScriptValue::KeepExistingFlags) {
+ if (thisObject->hasOwnProperty(exec, id))
+ thisObject->deleteProperty(exec, id); // ### hmmm - can't we just update the attributes?
+ unsigned attribs = 0;
+ if (flags & QScriptValue::ReadOnly)
+ attribs |= JSC::ReadOnly;
+ if (flags & QScriptValue::SkipInEnumeration)
+ attribs |= JSC::DontEnum;
+ if (flags & QScriptValue::Undeletable)
+ attribs |= JSC::DontDelete;
+ attribs |= flags & QScriptValue::UserRange;
+ thisObject->putWithAttributes(exec, id, jscValue, attribs);
+ } else {
+ JSC::PutPropertySlot slot;
+ thisObject->put(exec, id, jscValue, slot);
+ }
}
}