diff options
Diffstat (limited to 'src/declarative/qml')
-rw-r--r-- | src/declarative/qml/qdeclarativecompiler.cpp | 33 | ||||
-rw-r--r-- | src/declarative/qml/qdeclarativecompiler_p.h | 1 | ||||
-rw-r--r-- | src/declarative/qml/qdeclarativecomponent.cpp | 4 | ||||
-rw-r--r-- | src/declarative/qml/qdeclarativecustomparser.cpp | 10 | ||||
-rw-r--r-- | src/declarative/qml/qdeclarativecustomparser_p.h | 14 | ||||
-rw-r--r-- | src/declarative/qml/qdeclarativeengine.cpp | 24 | ||||
-rw-r--r-- | src/declarative/qml/qdeclarativeengine_p.h | 1 | ||||
-rw-r--r-- | src/declarative/qml/qdeclarativeglobalscriptclass.cpp | 28 | ||||
-rw-r--r-- | src/declarative/qml/qdeclarativeglobalscriptclass_p.h | 5 | ||||
-rw-r--r-- | src/declarative/qml/qdeclarativeobjectscriptclass.cpp | 24 | ||||
-rw-r--r-- | src/declarative/qml/qdeclarativeobjectscriptclass_p.h | 2 | ||||
-rw-r--r-- | src/declarative/qml/qdeclarativetypenamescriptclass.cpp | 4 |
12 files changed, 118 insertions, 32 deletions
diff --git a/src/declarative/qml/qdeclarativecompiler.cpp b/src/declarative/qml/qdeclarativecompiler.cpp index 80a1093..623e3df 100644 --- a/src/declarative/qml/qdeclarativecompiler.cpp +++ b/src/declarative/qml/qdeclarativecompiler.cpp @@ -815,6 +815,10 @@ bool QDeclarativeCompiler::buildObject(Object *obj, const BindingContext &ctxt) } } + QDeclarativeCustomParser *cp = 0; + if (isCustomParser) + cp = output->types.at(obj->type).type->customParser(); + // Build all explicit properties specified foreach(Property *prop, obj->properties) { @@ -825,7 +829,9 @@ bool QDeclarativeCompiler::buildObject(Object *obj, const BindingContext &ctxt) bool canDefer = false; if (isCustomParser) { - if (doesPropertyExist(prop, obj)) { + if (doesPropertyExist(prop, obj) && + (!(cp->flags() & QDeclarativeCustomParser::AcceptsAttachedProperties) || + !isAttachedPropertyName(prop->name))) { int ids = compileState.ids.count(); COMPILE_CHECK(buildProperty(prop, obj, objCtxt)); canDefer = ids == compileState.ids.count(); @@ -876,8 +882,7 @@ bool QDeclarativeCompiler::buildObject(Object *obj, const BindingContext &ctxt) defaultProperty->release(); // Compile custom parser parts - if (isCustomParser/* && !customProps.isEmpty()*/) { - QDeclarativeCustomParser *cp = output->types.at(obj->type).type->customParser(); + if (isCustomParser && !customProps.isEmpty()) { cp->clearErrors(); cp->compiler = this; cp->object = obj; @@ -1356,7 +1361,7 @@ bool QDeclarativeCompiler::buildSignal(QDeclarativeParser::Property *prop, QDecl Returns true if (value) property \a prop exists on obj, false otherwise. */ bool QDeclarativeCompiler::doesPropertyExist(QDeclarativeParser::Property *prop, - QDeclarativeParser::Object *obj) + QDeclarativeParser::Object *obj) { if(isAttachedPropertyName(prop->name) || prop->name == "id") return true; @@ -2176,6 +2181,18 @@ int QDeclarativeCompiler::evaluateEnum(const QByteArray& script) const return -1; } +const QMetaObject *QDeclarativeCompiler::resolveType(const QByteArray& name) const +{ + QDeclarativeType *qmltype = 0; + if (!enginePrivate->importDatabase.resolveType(unit->imports, name, &qmltype, + 0, 0, 0, 0)) + return 0; + if (!qmltype) + return 0; + return qmltype->metaObject(); +} + + // Ensures that the dynamic meta specification on obj is valid bool QDeclarativeCompiler::checkDynamicMeta(QDeclarativeParser::Object *obj) { @@ -2199,6 +2216,10 @@ bool QDeclarativeCompiler::checkDynamicMeta(QDeclarativeParser::Object *obj) if (QString::fromUtf8(prop.name).at(0).isUpper()) COMPILE_EXCEPTION(&prop, tr("Property names cannot begin with an upper case letter")); + + if (QDeclarativeEnginePrivate::get(engine)->globalClass->illegalNames().contains(prop.name)) + COMPILE_EXCEPTION(&prop, tr("Illegal property name")); + propNames.insert(prop.name); } @@ -2208,6 +2229,8 @@ bool QDeclarativeCompiler::checkDynamicMeta(QDeclarativeParser::Object *obj) COMPILE_EXCEPTION(obj, tr("Duplicate signal name")); if (QString::fromUtf8(name).at(0).isUpper()) COMPILE_EXCEPTION(obj, tr("Signal names cannot begin with an upper case letter")); + if (QDeclarativeEnginePrivate::get(engine)->globalClass->illegalNames().contains(name)) + COMPILE_EXCEPTION(obj, tr("Illegal signal name")); methodNames.insert(name); } for (int ii = 0; ii < obj->dynamicSlots.count(); ++ii) { @@ -2216,6 +2239,8 @@ bool QDeclarativeCompiler::checkDynamicMeta(QDeclarativeParser::Object *obj) COMPILE_EXCEPTION(obj, tr("Duplicate method name")); if (QString::fromUtf8(name).at(0).isUpper()) COMPILE_EXCEPTION(obj, tr("Method names cannot begin with an upper case letter")); + if (QDeclarativeEnginePrivate::get(engine)->globalClass->illegalNames().contains(name)) + COMPILE_EXCEPTION(obj, tr("Illegal method name")); methodNames.insert(name); } diff --git a/src/declarative/qml/qdeclarativecompiler_p.h b/src/declarative/qml/qdeclarativecompiler_p.h index 908c703..caad376 100644 --- a/src/declarative/qml/qdeclarativecompiler_p.h +++ b/src/declarative/qml/qdeclarativecompiler_p.h @@ -161,6 +161,7 @@ public: static bool isSignalPropertyName(const QByteArray &); int evaluateEnum(const QByteArray& script) const; // for QDeclarativeCustomParser::evaluateEnum + const QMetaObject *resolveType(const QByteArray& name) const; // for QDeclarativeCustomParser::resolveType private: static void reset(QDeclarativeCompiledData *); diff --git a/src/declarative/qml/qdeclarativecomponent.cpp b/src/declarative/qml/qdeclarativecomponent.cpp index b4919ff..9d3032c 100644 --- a/src/declarative/qml/qdeclarativecomponent.cpp +++ b/src/declarative/qml/qdeclarativecomponent.cpp @@ -572,7 +572,9 @@ QScriptValue QDeclarativeComponent::createObject(QObject* parent) { Q_D(QDeclarativeComponent); QDeclarativeContext* ctxt = creationContext(); - if(!ctxt) + if(!ctxt && d->engine) + ctxt = d->engine->rootContext(); + if (!ctxt) return QScriptValue(QScriptValue::NullValue); QObject* ret = create(ctxt); if (!ret) diff --git a/src/declarative/qml/qdeclarativecustomparser.cpp b/src/declarative/qml/qdeclarativecustomparser.cpp index 472a883..97a6a00 100644 --- a/src/declarative/qml/qdeclarativecustomparser.cpp +++ b/src/declarative/qml/qdeclarativecustomparser.cpp @@ -295,4 +295,14 @@ int QDeclarativeCustomParser::evaluateEnum(const QByteArray& script) const return compiler->evaluateEnum(script); } +/*! + Resolves \a name to a type, or 0 if it is not a type. This can be used + to type-check object nodes. +*/ +const QMetaObject *QDeclarativeCustomParser::resolveType(const QByteArray& name) const +{ + return compiler->resolveType(name); +} + + QT_END_NAMESPACE diff --git a/src/declarative/qml/qdeclarativecustomparser_p.h b/src/declarative/qml/qdeclarativecustomparser_p.h index 0e397c5..509e30a 100644 --- a/src/declarative/qml/qdeclarativecustomparser_p.h +++ b/src/declarative/qml/qdeclarativecustomparser_p.h @@ -113,10 +113,18 @@ private: class Q_DECLARATIVE_EXPORT QDeclarativeCustomParser { public: - QDeclarativeCustomParser() : compiler(0), object(0) {} + enum Flag { + NoFlag = 0x00000000, + AcceptsAttachedProperties = 0x00000001 + }; + Q_DECLARE_FLAGS(Flags, Flag); + + QDeclarativeCustomParser() : compiler(0), object(0), m_flags(NoFlag) {} + QDeclarativeCustomParser(Flags f) : compiler(0), object(0), m_flags(f) {} virtual ~QDeclarativeCustomParser() {} void clearErrors(); + Flags flags() const { return m_flags; } virtual QByteArray compile(const QList<QDeclarativeCustomParserProperty> &)=0; virtual void setCustomData(QObject *, const QByteArray &)=0; @@ -130,12 +138,16 @@ protected: int evaluateEnum(const QByteArray&) const; + const QMetaObject *resolveType(const QByteArray&) const; + private: QList<QDeclarativeError> exceptions; QDeclarativeCompiler *compiler; QDeclarativeParser::Object *object; + Flags m_flags; friend class QDeclarativeCompiler; }; +Q_DECLARE_OPERATORS_FOR_FLAGS(QDeclarativeCustomParser::Flags); #if 0 #define QML_REGISTER_CUSTOM_TYPE(URI, VERSION_MAJ, VERSION_MIN, NAME, TYPE, CUSTOMTYPE) \ diff --git a/src/declarative/qml/qdeclarativeengine.cpp b/src/declarative/qml/qdeclarativeengine.cpp index 5c4d229..98b4bbf 100644 --- a/src/declarative/qml/qdeclarativeengine.cpp +++ b/src/declarative/qml/qdeclarativeengine.cpp @@ -1033,6 +1033,17 @@ QDeclarativeContextData *QDeclarativeEnginePrivate::getContext(QScriptContext *c return contextClass->contextFromValue(scopeNode); } +/*! + Returns the QUrl associated with the script \a ctxt for the case that there is + no QDeclarativeContext. +*/ +QUrl QDeclarativeEnginePrivate::getUrl(QScriptContext *ctxt) +{ + QScriptValue scopeNode = QScriptDeclarativeClass::scopeChainValue(ctxt, -3); + Q_ASSERT(scopeNode.isValid()); + Q_ASSERT(QScriptDeclarativeClass::scriptClass(scopeNode) == contextClass); + return contextClass->urlFromValue(scopeNode); +} QString QDeclarativeEnginePrivate::urlToLocalFileOrQrc(const QUrl& url) { @@ -1075,16 +1086,19 @@ QScriptValue QDeclarativeEnginePrivate::createComponent(QScriptContext *ctxt, QS static_cast<QDeclarativeScriptEngine*>(engine)->p; QDeclarativeEngine* activeEngine = activeEnginePriv->q_func(); - QDeclarativeContextData* context = activeEnginePriv->getContext(ctxt); - Q_ASSERT(context); - if(ctxt->argumentCount() != 1) { return ctxt->throwError(QLatin1String("Qt.createComponent(): Invalid arguments")); - }else{ + } else { + QString arg = ctxt->argument(0).toString(); if (arg.isEmpty()) return engine->nullValue(); - QUrl url = QUrl(context->resolvedUrl(QUrl(arg))); + QUrl url; + QDeclarativeContextData* context = activeEnginePriv->getContext(ctxt); + if (context) + url = QUrl(context->resolvedUrl(QUrl(arg))); + else + url = activeEnginePriv->getUrl(ctxt).resolved(QUrl(arg)); QDeclarativeComponent *c = new QDeclarativeComponent(activeEngine, url, activeEngine); QDeclarativeComponentPrivate::get(c)->creationContext = context; QDeclarativeData::get(c, true)->setImplicitDestructible(); diff --git a/src/declarative/qml/qdeclarativeengine_p.h b/src/declarative/qml/qdeclarativeengine_p.h index 3269e98..cfa9d73 100644 --- a/src/declarative/qml/qdeclarativeengine_p.h +++ b/src/declarative/qml/qdeclarativeengine_p.h @@ -315,6 +315,7 @@ public: static QDeclarativeEnginePrivate *get(QScriptEngine *e) { return static_cast<QDeclarativeScriptEngine*>(e)->p; } static QDeclarativeEngine *get(QDeclarativeEnginePrivate *p) { return p->q_func(); } QDeclarativeContextData *getContext(QScriptContext *); + QUrl getUrl(QScriptContext *); static QString urlToLocalFileOrQrc(const QUrl& url); diff --git a/src/declarative/qml/qdeclarativeglobalscriptclass.cpp b/src/declarative/qml/qdeclarativeglobalscriptclass.cpp index 39ea101..d43443d 100644 --- a/src/declarative/qml/qdeclarativeglobalscriptclass.cpp +++ b/src/declarative/qml/qdeclarativeglobalscriptclass.cpp @@ -41,6 +41,7 @@ #include "private/qdeclarativeglobalscriptclass_p.h" +#include <QtCore/qstringlist.h> #include <QtCore/qvector.h> #include <QtScript/qscriptstring.h> #include <QtScript/qscriptengine.h> @@ -57,6 +58,7 @@ QDeclarativeGlobalScriptClass::QDeclarativeGlobalScriptClass(QScriptEngine *engi : QScriptClass(engine) { QString eval = QLatin1String("eval"); + QString version = QLatin1String("version"); QScriptValue originalGlobalObject = engine->globalObject(); @@ -72,6 +74,9 @@ QDeclarativeGlobalScriptClass::QDeclarativeGlobalScriptClass(QScriptEngine *engi QString name = iter.name(); + if (name == version) + continue; + if (name != eval) { names.append(name); values.append(iter.value()); @@ -98,18 +103,7 @@ QDeclarativeGlobalScriptClass::queryProperty(const QScriptValue &object, Q_UNUSED(name); Q_UNUSED(flags); Q_UNUSED(id); - return HandlesReadAccess | HandlesWriteAccess; -} - -QScriptValue -QDeclarativeGlobalScriptClass::property(const QScriptValue &object, - const QScriptString &name, - uint id) -{ - Q_UNUSED(object); - Q_UNUSED(name); - Q_UNUSED(id); - return engine()->undefinedValue(); + return HandlesWriteAccess; } void QDeclarativeGlobalScriptClass::setProperty(QScriptValue &object, @@ -125,8 +119,9 @@ void QDeclarativeGlobalScriptClass::setProperty(QScriptValue &object, } /* This method is for the use of tst_qdeclarativeecmascript::callQtInvokables() only */ -void QDeclarativeGlobalScriptClass::explicitSetProperty(const QString &name, const QScriptValue &value) +void QDeclarativeGlobalScriptClass::explicitSetProperty(const QStringList &names, const QList<QScriptValue> &values) { + Q_ASSERT(names.count() == values.count()); QScriptValue globalObject = engine()->globalObject(); QScriptValue v = engine()->newObject(); @@ -137,7 +132,12 @@ void QDeclarativeGlobalScriptClass::explicitSetProperty(const QString &name, con v.setProperty(iter.scriptName(), iter.value()); } - v.setProperty(name, value); + for (int ii = 0; ii < names.count(); ++ii) { + const QString &name = names.at(ii); + const QScriptValue &value = values.at(ii); + v.setProperty(name, value); + } + v.setScriptClass(this); engine()->setGlobalObject(v); diff --git a/src/declarative/qml/qdeclarativeglobalscriptclass_p.h b/src/declarative/qml/qdeclarativeglobalscriptclass_p.h index 414bf02..b42b7bd 100644 --- a/src/declarative/qml/qdeclarativeglobalscriptclass_p.h +++ b/src/declarative/qml/qdeclarativeglobalscriptclass_p.h @@ -67,13 +67,10 @@ public: const QScriptString &name, QueryFlags flags, uint *id); - virtual QScriptValue property(const QScriptValue &object, - const QScriptString &name, uint id); - virtual void setProperty(QScriptValue &object, const QScriptString &name, uint id, const QScriptValue &value); - void explicitSetProperty(const QString &, const QScriptValue &); + void explicitSetProperty(const QStringList &, const QList<QScriptValue> &); const QScriptValue &staticGlobalObject() const { return m_staticGlobalObject; } diff --git a/src/declarative/qml/qdeclarativeobjectscriptclass.cpp b/src/declarative/qml/qdeclarativeobjectscriptclass.cpp index aca01b2..3af892d 100644 --- a/src/declarative/qml/qdeclarativeobjectscriptclass.cpp +++ b/src/declarative/qml/qdeclarativeobjectscriptclass.cpp @@ -797,6 +797,26 @@ QScriptDeclarativeClass::Value MetaCallArgument::toValue(QDeclarativeEngine *e) } } +int QDeclarativeObjectMethodScriptClass::enumType(const QMetaObject *meta, const QString &strname) +{ + QByteArray str = strname.toUtf8(); + QByteArray scope; + QByteArray name; + int scopeIdx = str.lastIndexOf("::"); + if (scopeIdx != -1) { + scope = str.left(scopeIdx); + name = str.mid(scopeIdx + 2); + } else { + name = str; + } + for (int i = meta->enumeratorCount() - 1; i >= 0; --i) { + QMetaEnum m = meta->enumerator(i); + if ((m.name() == name) && (scope.isEmpty() || (m.scope() == scope))) + return QVariant::Int; + } + return QVariant::Invalid; +} + QDeclarativeObjectMethodScriptClass::Value QDeclarativeObjectMethodScriptClass::call(Object *o, QScriptContext *ctxt) { MethodData *method = static_cast<MethodData *>(o); @@ -810,7 +830,9 @@ QDeclarativeObjectMethodScriptClass::Value QDeclarativeObjectMethodScriptClass:: // ### Cache for (int ii = 0; ii < argTypeNames.count(); ++ii) { argTypes[ii] = QMetaType::type(argTypeNames.at(ii)); - if (argTypes[ii] == QVariant::Invalid) + if (argTypes[ii] == QVariant::Invalid) + argTypes[ii] = enumType(method->object->metaObject(), argTypeNames.at(ii)); + if (argTypes[ii] == QVariant::Invalid) return Value(ctxt, ctxt->throwError(QString::fromLatin1("Unknown method parameter type: %1").arg(QLatin1String(argTypeNames.at(ii))))); } diff --git a/src/declarative/qml/qdeclarativeobjectscriptclass_p.h b/src/declarative/qml/qdeclarativeobjectscriptclass_p.h index 4b27e53..75e384c 100644 --- a/src/declarative/qml/qdeclarativeobjectscriptclass_p.h +++ b/src/declarative/qml/qdeclarativeobjectscriptclass_p.h @@ -80,6 +80,8 @@ protected: virtual Value property(Object *, const Identifier &); private: + int enumType(const QMetaObject *, const QString &); + PersistentIdentifier m_connectId; PersistentIdentifier m_disconnectId; QScriptValue m_connect; diff --git a/src/declarative/qml/qdeclarativetypenamescriptclass.cpp b/src/declarative/qml/qdeclarativetypenamescriptclass.cpp index 2a3417a..764a8db 100644 --- a/src/declarative/qml/qdeclarativetypenamescriptclass.cpp +++ b/src/declarative/qml/qdeclarativetypenamescriptclass.cpp @@ -107,8 +107,7 @@ QDeclarativeTypeNameScriptClass::queryProperty(Object *obj, const Identifier &na return 0; } - } else { - Q_ASSERT(data->type); + } else if (data->type) { QString strName = toString(name); @@ -134,6 +133,7 @@ QDeclarativeTypeNameScriptClass::queryProperty(Object *obj, const Identifier &na if (!object) return 0; return ep->objectClass->queryProperty(object, name, flags, 0); } + } return 0; |