Example #1
0
QScriptValueImpl Object::method_propertyIsEnumerable(QScriptContextPrivate *context, QScriptEnginePrivate *eng, QScriptClassInfo *)
{
    bool result = false;

    if (context->thisObject().isObject() && (context->argumentCount() > 0)) {
        QScriptValueImpl arg = context->argument(0);

        QScriptNameIdImpl *id = 0;
        if (arg.isString())
            id = arg.stringValue();

        if (! id || ! id->unique) {
            QString str = arg.toString();
            id = eng->nameId(str);
        }

        QScript::Member member;
        QScriptValueImpl base;
        QScriptValueImpl self = context->thisObject();
        if (self.resolve(id, &member, &base, QScriptValue::ResolveLocal, QScript::Read)) {
            result = ! member.dontEnum();
            if (result) {
                QScriptValueImpl tmp;
                base.get(member, &tmp);
                result = tmp.isValid();
            }
        }
    }

    return (QScriptValueImpl(result));
}
/*!
  Returns the flags of the last property that was jumped over using
  next() or previous().

  \sa value()
*/
QScriptValue::PropertyFlags QScriptValueIterator::flags() const
{
    Q_D(const QScriptValueIterator);
    if (d->index == -1)
        return 0;

    QScript::Member member;
    QScriptValuePrivate::valueOf(d->object).member(d->index, &member);
    if (!member.isValid())
        return 0;

    return QScriptValue::PropertyFlags(member.flags());
}
/*!
  Removes the last property that was jumped over using next()
  or previous().

  \sa setValue()
*/
void QScriptValueIterator::remove()
{
    Q_D(const QScriptValueIterator);
    if (d->index == -1)
        return;

    QScript::Member member;
    QScriptValuePrivate::valueOf(d->object).member(d->index, &member);
    if (!member.isValid())
        return;

    QScriptValuePrivate::valueOf(d->object).removeMember(member);
}
/*!
  Sets the \a value of the last property that was jumped over using
  next() or previous().

  \sa value(), name()
*/
void QScriptValueIterator::setValue(const QScriptValue &value)
{
    Q_D(const QScriptValueIterator);
    if (d->index == -1)
        return;

    QScript::Member member;
    QScriptValuePrivate::valueOf(d->object).member(d->index, &member);
    if (!member.isValid())
        return;

    QScriptValuePrivate::valueOf(d->object).put(member, QScriptValuePrivate::valueOf(value));
}
/*!
  Returns the value of the last property that was jumped over using
  next() or previous().

  \sa setValue(), name()
*/
QScriptValue QScriptValueIterator::value() const
{
    Q_D(const QScriptValueIterator);
    if (d->index == -1)
        return QScriptValue();

    QScript::Member member;
    QScriptValuePrivate::valueOf(d->object).member(d->index, &member);
    if (!member.isValid())
        return QScriptValue();

    QScriptValueImpl result;
    QScriptValuePrivate::valueOf(d->object).get(member, &result);
    return result;
}
void QScriptValueIteratorImpl::setValue(const QScriptValueImpl &value)
{
    if (!m_member.isValid())
        return;
    if (m_member.isGetterOrSetter()) {
        // find and call the setter
        QScriptValueImpl setter;
        if (m_member.isObjectProperty() && !m_member.isSetter()) {
            QScript::Member mb;
            QScriptObject *obj = m_object.m_object_value;
            mb.object(m_member.nameId(), obj->memberCount(), 0);
            if (!obj->findSetter(&mb))
                return;
            m_object.get(mb, &setter);
        } else {
            m_object.get(m_member, &setter);
        }
        setter.call(m_object, QScriptValueImplList() << value);
    } else {
        m_object.put(m_member, value);
    }
}
/*!
  Returns true if there is at least one item behind the iterator
  (i.e. the iterator is \e not at the front of the property sequence);
  otherwise returns false.

  \sa previous(), hasNext()
*/
bool QScriptValueIterator::hasPrevious() const
{
    Q_D(const QScriptValueIterator);
    if ((d->nextIndex != -1) && !d->forward)
        return true;

    if (!d->object.isObject())
        return false;

    QScriptValueImpl v = QScriptValuePrivate::valueOf(d->object);
    int i = d->index;
    if ((i != -1) && d->forward)
        ++i;

    bool found = false;
    while (! found && --i >= 0) {
        QScript::Member member;
        v.member(i, &member);
        found = member.isValid();
        if (found) {
            QScriptValueImpl vv;
            v.get(member, &vv);
            found = vv.isValid();
        }
    }

    QScriptValueIteratorPrivate *that;
    that = const_cast<QScriptValueIteratorPrivate*>(d);
    if (found) {
        that->forward = false;
        that->nextIndex = i;
        return true;
    } else {
        that->nextIndex = -1;
        return false;
    }

}
/*!
  Returns true if there is at least one item ahead of the iterator
  (i.e. the iterator is \e not at the back of the property sequence);
  otherwise returns false.

  \sa next(), hasPrevious()
*/
bool QScriptValueIterator::hasNext() const
{
    Q_D(const QScriptValueIterator);
    if ((d->nextIndex != -1) && d->forward)
        return true;

    if (!d->object.isObject())
        return false;

    QScriptValueImpl v = QScriptValuePrivate::valueOf(d->object);
    int i = d->index;
    if ((i != -1) && !d->forward)
        --i;

    int count = v.memberCount();
    bool found = false;
    while (! found && ++i < count) {
        QScript::Member member;
        v.member(i, &member);
        found = member.isValid();
        if (found && (member.isObjectProperty() || v.isArray())) {
            QScriptValueImpl vv;
            v.get(member, &vv);
            found = vv.isValid();
        }
    }

    QScriptValueIteratorPrivate *that;
    that = const_cast<QScriptValueIteratorPrivate*>(d);
    if (found) {
        that->forward = true;
        that->nextIndex = i;
        return true;
    } else {
        that->nextIndex = -1;
        return false;
    }
}
QScriptValueImpl QScriptValueIteratorImpl::value() const
{
    if (!m_member.isValid())
        return QScriptValueImpl();
    QScriptValueImpl result;
    m_object.get(m_member, &result);
    if (m_member.isGetterOrSetter()) {
        // find and call the getter
        QScriptValueImpl getter;
        if (m_member.isObjectProperty() && !m_member.isGetter()) {
            QScript::Member mb;
            QScriptObject *obj = m_object.m_object_value;
            mb.object(m_member.nameId(), obj->memberCount(), 0);
            if (!obj->findGetter(&mb))
                return QScriptValueImpl();
            m_object.get(mb, &getter);
        } else {
            getter = result;
        }
        result = getter.call(m_object);
    }
    return result;
}
void Enumeration::Instance::next(QScriptContextPrivate *context, QScriptValueImpl *result)
{
    QScriptEnginePrivate *eng = context->engine();
    Q_ASSERT(it != 0);
    it->next();
    QScript::Member *member = it->member();
    if (member->isObjectProperty() || member->nameId())
        eng->newNameId(result, member->nameId());

    else if (member->isNativeProperty() && !member->nameId())
        *result = QScriptValueImpl(uint(member->id()));

    else
        *result = eng->undefinedValue();
}
/*!
  Returns the name of the last property that was jumped over using
  next() or previous().

  \sa value(), flags()
*/
QString QScriptValueIterator::name() const
{
    Q_D(const QScriptValueIterator);
    if (d->index == -1)
        return QString();

    QScript::Member member;
    QScriptValuePrivate::valueOf(d->object).member(d->index, &member);

    if (member.isObjectProperty() || member.nameId())
        return member.nameId()->s;

    else if (member.isNativeProperty())
        return QScriptEnginePrivate::toString(member.id());

    return QString();
}
bool QScriptValueIteratorImpl::acceptsMember(const QScriptValueImpl &o,
                                             const QScript::Member &m) const
{
    if (!m.isValid() || (!m_ignoresDontEnum && m.dontEnum())
        || (m.isSetter() && !m.isGetter())) {
        return false;
    }

    if (!m_enumerateProto || QScriptEnginePrivate::strictlyEquals(o, m_frontObject))
        return true;

    // make sure it's not a shadowed property
    QScript::Member dummy;
    QScriptValueImpl base;
    QScriptNameIdImpl *id;
    if (m.nameId()) {
        id = m.nameId();
    } else {
        QScriptEnginePrivate *eng_p = m_frontObject.engine();
        id = eng_p->nameId(QScript::numberToString(m.id()));
    }
    m_frontObject.resolve(id, &dummy, &base, QScriptValue::ResolvePrototype, QScript::Read);
    return QScriptEnginePrivate::strictlyEquals(base, o);
}
Example #13
0
QDebug &operator<<(QDebug &d, const QScriptValueImpl &object)
{
    d.nospace() << "QScriptValue(";

    switch (object.type()) {
    case QScript::InvalidType:
        d.nospace() << "Invalid)";
        return d;

    case QScript::BooleanType:
        d.nospace() << "bool=" << object.toBoolean();
        break;

    case QScript::IntegerType:
        d.nospace() << "int=" << object.toInt32();
        break;

    case QScript::NumberType:
        d.nospace() << "qsreal=" << object.toNumber();
        break;

    case QScript::LazyStringType:
    case QScript::StringType:
        d.nospace() << "string=" << object.toString();
        break;

    case QScript::ReferenceType:
        d.nospace() << "reference";
        break;

    case QScript::NullType:
        d.nospace() << "null";
        break;

    case QScript::UndefinedType:
        d.nospace() << "undefined";
        break;

    case QScript::PointerType:
        d.nospace() << "pointer";
        break;

    case QScript::ObjectType:
        d.nospace() << object.classInfo()->name() << ",{";
        QScriptObject *od = object.objectValue();
        for (int i=0; i<od->memberCount(); ++i) {
            if (i != 0)
                d << ",";

            QScript::Member m;
            od->member(i, &m);

            if (m.isValid() && m.isObjectProperty()) {
                d << object.engine()->toString(m.nameId());
                QScriptValueImpl o;
                od->get(m, &o);
                d.nospace() << QLatin1String(":")
                            << (o.classInfo()
                                ? o.classInfo()->name()
                                : QLatin1String("?"));
            }
        }

        d.nospace() << "} scope={";
        QScriptValueImpl scope = object.scope();
        while (scope.isValid()) {
            Q_ASSERT(scope.isObject());
            d.nospace() << " " << scope.objectValue();
            scope = scope.scope();
        }
        d.nospace() << "}";
        break;
    }

    d << ")";
    return d;
}
Example #14
0
void QScriptValueImpl::setProperty(QScriptNameIdImpl *nameId,
                                   const QScriptValueImpl &value,
                                   const QScriptValue::PropertyFlags &flags)
{
    if (!isObject())
        return;

    QScriptValueImpl base;
    QScript::Member member;

    QScriptValue::ResolveFlags mode = QScriptValue::ResolveLocal;
    // if we are not setting a setter or getter, look in prototype too
    if (!(flags & (QScriptValue::PropertyGetter | QScriptValue::PropertySetter)))
        mode |= QScriptValue::ResolvePrototype;

    if (resolve(nameId, &member, &base, mode, QScript::ReadWrite)) {
        // we resolved an existing property with that name
        if (flags & (QScriptValue::PropertyGetter | QScriptValue::PropertySetter)) {
            // setting the getter or setter of a property in this object
            if (member.isNativeProperty()) {
                if (value.isValid()) {
                    qWarning("QScriptValue::setProperty() failed: "
                             "cannot set getter or setter of native property `%s'",
                             qPrintable(nameId->s));
                }
                return;
            }
            if (member.isSetter()) {
                // the property we resolved is a setter
                if (!(flags & QScriptValue::PropertySetter) && !member.isGetter()) {
                    // find the getter, if not, create one
                    if (!m_object_value->findGetter(&member)) {
                        if (!value.isValid())
                            return; // don't create property for invalid value
                        createMember(nameId, &member, flags);
                    }
                }
            } else if (member.isGetter()) {
                // the property we resolved is a getter
                if (!(flags & QScriptValue::PropertyGetter)) {
                    // find the setter, if not, create one
                    if (!m_object_value->findSetter(&member)) {
                        if (!value.isValid())
                            return; // don't create property for invalid value
                        createMember(nameId, &member, flags);
                    }
                }
            } else {
                // the property is a normal property -- change the flags
                uint newFlags = flags & ~QScript::Member::InternalRange;
                newFlags |= QScript::Member::ObjectProperty;
                member.resetFlags(newFlags);
                base.m_object_value->m_members[member.id()].resetFlags(newFlags);
            }
            Q_ASSERT(member.isValid());
            if (!value.isValid()) {
                // remove the property
                removeMember(member);
                return;
            }
        } else {
            // setting the value
            if (member.isGetterOrSetter()) {
                // call the setter
                QScriptValueImpl setter;
                if (member.isObjectProperty() && !member.isSetter()) {
                    if (!base.m_object_value->findSetter(&member)) {
                        qWarning("QScriptValue::setProperty() failed: "
                                 "property '%s' has a getter but no setter",
                                 qPrintable(nameId->s));
                        return;
                    }
                }
                base.get(member, &setter);
                setter.call(*this, QScriptValueImplList() << value);
                return;
            } else {
                if (base.m_object_value != m_object_value) {
                    if (!value.isValid())
                        return; // don't create property for invalid value
                    createMember(nameId, &member, flags);
                    base = *this;
                } else {
                    if (!value.isValid()) {
                        // remove the property
                        removeMember(member);
                        return;
                    }
                }
                if (flags != QScriptValue::KeepExistingFlags) {
                    // change flags
                    if (member.isNativeProperty()) {
                        qWarning("QScriptValue::setProperty(%s): "
                                 "cannot change flags of a native property",
                                 qPrintable(nameId->s));
                    } else {
                        uint newFlags = member.flags() & QScript::Member::InternalRange;
                        newFlags |= flags & ~QScript::Member::InternalRange;
                        base.m_object_value->m_members[member.id()].resetFlags(newFlags);
                    }
                }
            }
        }
    } else {
        // property does not exist
        if (!value.isValid())
            return; // don't create property for invalid value
        createMember(nameId, &member, flags & ~QScript::Member::InternalRange);
        base = *this;
    }

    base.put(member, value);
}