diff options
author | Aaron Kennedy <aaron.kennedy@nokia.com> | 2009-11-29 10:46:00 (GMT) |
---|---|---|
committer | Aaron Kennedy <aaron.kennedy@nokia.com> | 2009-11-29 10:46:00 (GMT) |
commit | d406a899943c6d56d921bc290a009415a3c4eba5 (patch) | |
tree | c48f12180910251b4572cb3600a72332ff5f34f5 /src/declarative | |
parent | 696b55195f1ad40a077683dbc533c73baf1536ee (diff) | |
download | Qt-d406a899943c6d56d921bc290a009415a3c4eba5.zip Qt-d406a899943c6d56d921bc290a009415a3c4eba5.tar.gz Qt-d406a899943c6d56d921bc290a009415a3c4eba5.tar.bz2 |
Support array-literal Script::source values
Diffstat (limited to 'src/declarative')
-rw-r--r-- | src/declarative/qml/qmlcompiler.cpp | 54 | ||||
-rw-r--r-- | src/declarative/qml/qmlcompiler_p.h | 1 | ||||
-rw-r--r-- | src/declarative/qml/qmlcontext.cpp | 15 | ||||
-rw-r--r-- | src/declarative/qml/qmlcontext_p.h | 3 | ||||
-rw-r--r-- | src/declarative/qml/qmlinstruction.cpp | 2 | ||||
-rw-r--r-- | src/declarative/qml/qmlinstruction_p.h | 2 | ||||
-rw-r--r-- | src/declarative/qml/qmlparser.cpp | 54 | ||||
-rw-r--r-- | src/declarative/qml/qmlparser_p.h | 11 | ||||
-rw-r--r-- | src/declarative/qml/qmlscriptparser.cpp | 8 | ||||
-rw-r--r-- | src/declarative/qml/qmlvme.cpp | 7 |
10 files changed, 115 insertions, 42 deletions
diff --git a/src/declarative/qml/qmlcompiler.cpp b/src/declarative/qml/qmlcompiler.cpp index 9000339..a4e14b2 100644 --- a/src/declarative/qml/qmlcompiler.cpp +++ b/src/declarative/qml/qmlcompiler.cpp @@ -846,13 +846,13 @@ void QmlCompiler::genObject(QmlParser::Object *obj) } // Set any script blocks - for (int ii = 0; ii < obj->scriptBlocks.count(); ++ii) { + for (int ii = 0; ii < obj->scripts.count(); ++ii) { QmlInstruction script; script.type = QmlInstruction::StoreScript; script.line = 0; // ### - script.storeScript.fileName = output->indexForString(obj->scriptBlocksFile.at(ii)); - script.storeScript.lineNumber = obj->scriptBlocksLineNumber.at(ii); - script.storeScript.value = output->indexForString(obj->scriptBlocks.at(ii)); + int idx = output->scripts.count(); + output->scripts << obj->scripts.at(ii); + script.storeScript.value = idx; output->bytecode << script; } @@ -1086,9 +1086,7 @@ bool QmlCompiler::buildComponent(QmlParser::Object *obj, bool QmlCompiler::buildScript(QmlParser::Object *obj, QmlParser::Object *script) { - QString scriptCode; - QString sourceUrl; - int lineNumber = 1; + Object::ScriptBlock scriptBlock; if (script->properties.count() == 1 && script->properties.begin().key() == QByteArray("source")) { @@ -1098,22 +1096,37 @@ bool QmlCompiler::buildScript(QmlParser::Object *obj, QmlParser::Object *script) COMPILE_EXCEPTION(source, qApp->translate("QmlCompiler","Invalid Script block. Specify either the source property or inline script")); if (source->value || source->values.count() != 1 || - source->values.at(0)->object || !source->values.at(0)->value.isString()) + source->values.at(0)->object || !source->values.at(0)->value.isStringList()) COMPILE_EXCEPTION(source, qApp->translate("QmlCompiler","Invalid Script source value")); - sourceUrl = output->url.resolved(QUrl(source->values.at(0)->value.asString())).toString(); + QStringList sources = source->values.at(0)->value.asStringList(); - for (int ii = 0; ii < unit->resources.count(); ++ii) { - if (unit->resources.at(ii)->url == sourceUrl) { - scriptCode = QString::fromUtf8(unit->resources.at(ii)->data); - break; + for (int jj = 0; jj < sources.count(); ++jj) { + QString sourceUrl = output->url.resolved(QUrl(sources.at(jj))).toString(); + QString scriptCode; + int lineNumber = 1; + + for (int ii = 0; ii < unit->resources.count(); ++ii) { + if (unit->resources.at(ii)->url == sourceUrl) { + scriptCode = QString::fromUtf8(unit->resources.at(ii)->data); + break; + } + } + + if (!scriptCode.isEmpty()) { + scriptBlock.codes.append(scriptCode); + scriptBlock.files.append(sourceUrl); + scriptBlock.lineNumbers.append(lineNumber); } } } else if (!script->properties.isEmpty()) { COMPILE_EXCEPTION(*script->properties.begin(), qApp->translate("QmlCompiler","Properties cannot be set on Script block")); } else if (script->defaultProperty) { - sourceUrl = output->url.toString(); + + QString scriptCode; + int lineNumber = 1; + QString sourceUrl = output->url.toString(); QmlParser::Location currentLocation; @@ -1141,14 +1154,17 @@ bool QmlCompiler::buildScript(QmlParser::Object *obj, QmlParser::Object *script) currentLocation = v->location.end; currentLocation.column++; } - } - if (!scriptCode.isEmpty()) { - obj->scriptBlocks.append(scriptCode); - obj->scriptBlocksFile.append(sourceUrl); - obj->scriptBlocksLineNumber.append(lineNumber); + if (!scriptCode.isEmpty()) { + scriptBlock.codes.append(scriptCode); + scriptBlock.files.append(sourceUrl); + scriptBlock.lineNumbers.append(lineNumber); + } } + if (!scriptBlock.codes.isEmpty()) + obj->scripts << scriptBlock; + return true; } diff --git a/src/declarative/qml/qmlcompiler_p.h b/src/declarative/qml/qmlcompiler_p.h index 9597753..b54a62a 100644 --- a/src/declarative/qml/qmlcompiler_p.h +++ b/src/declarative/qml/qmlcompiler_p.h @@ -116,6 +116,7 @@ public: QList<QScriptProgram *> programs; QList<QmlPropertyCache *> propertyCaches; QList<QmlIntegerCache *> contextCaches; + QList<QmlParser::Object::ScriptBlock> scripts; void dumpInstructions(); private: diff --git a/src/declarative/qml/qmlcontext.cpp b/src/declarative/qml/qmlcontext.cpp index 42f467b..38cbcfa 100644 --- a/src/declarative/qml/qmlcontext.cpp +++ b/src/declarative/qml/qmlcontext.cpp @@ -59,8 +59,7 @@ QmlContextPrivate::QmlContextPrivate() { } -void QmlContextPrivate::addScript(const QString &script, QObject *scopeObject, - const QString &fileName, int lineNumber) +void QmlContextPrivate::addScript(const QmlParser::Object::ScriptBlock &script, QObject *scopeObject) { Q_Q(QmlContext); @@ -76,12 +75,14 @@ void QmlContextPrivate::addScript(const QString &script, QObject *scopeObject, QScriptValue scope = scriptEngine->newObject(); scriptContext->setActivationObject(scope); - QScriptValue val = scriptEngine->evaluate(script, fileName, lineNumber); + for (int ii = 0; ii < script.codes.count(); ++ii) { + scriptEngine->evaluate(script.codes.at(ii), script.files.at(ii), script.lineNumbers.at(ii)); - if (scriptEngine->hasUncaughtException()) { - QmlError error; - QmlExpressionPrivate::exceptionToError(scriptEngine, error); - qWarning().nospace() << qPrintable(error.toString()); + if (scriptEngine->hasUncaughtException()) { + QmlError error; + QmlExpressionPrivate::exceptionToError(scriptEngine, error); + qWarning().nospace() << qPrintable(error.toString()); + } } scriptEngine->popContext(); diff --git a/src/declarative/qml/qmlcontext_p.h b/src/declarative/qml/qmlcontext_p.h index a9c25a3..c8d0b2d 100644 --- a/src/declarative/qml/qmlcontext_p.h +++ b/src/declarative/qml/qmlcontext_p.h @@ -92,8 +92,7 @@ public: int highPriorityCount; QList<QScriptValue> scripts; - void addScript(const QString &script, QObject *scope, - const QString &fileName = QString(), int lineNumber = 1); + void addScript(const QmlParser::Object::ScriptBlock &, QObject *); QUrl url; diff --git a/src/declarative/qml/qmlinstruction.cpp b/src/declarative/qml/qmlinstruction.cpp index 6bab1c4..65d070c 100644 --- a/src/declarative/qml/qmlinstruction.cpp +++ b/src/declarative/qml/qmlinstruction.cpp @@ -140,7 +140,7 @@ void QmlCompiledData::dump(QmlInstruction *instr, int idx) qWarning().nospace() << idx << "\t\t" << line << "\t" << "STORE_SIGNAL\t\t" << instr->storeSignal.signalIndex << "\t" << instr->storeSignal.value << "\t\t" << primitives.at(instr->storeSignal.value); break; case QmlInstruction::StoreScript: - qWarning().nospace() << idx << "\t\t" << line << "\t" << "STORE_SCRIPT\t\t" << instr->storeScript.value << "\t" << instr->storeScript.fileName << "\t" << instr->storeScript.lineNumber; + qWarning().nospace() << idx << "\t\t" << line << "\t" << "STORE_SCRIPT\t\t" << instr->storeScript.value; break; case QmlInstruction::StoreScriptString: qWarning().nospace() << idx << "\t\t" << line << "\t" << "STORE_SCRIPT_STRING\t" << instr->storeScriptString.propertyIndex << "\t" << instr->storeScriptString.value << "\t" << instr->storeScriptString.scope; diff --git a/src/declarative/qml/qmlinstruction_p.h b/src/declarative/qml/qmlinstruction_p.h index 50d4b62..a5fc40c 100644 --- a/src/declarative/qml/qmlinstruction_p.h +++ b/src/declarative/qml/qmlinstruction_p.h @@ -252,8 +252,6 @@ public: } storeScriptString; struct { int value; - int fileName; - int lineNumber; } storeScript; struct { int propertyIndex; diff --git a/src/declarative/qml/qmlparser.cpp b/src/declarative/qml/qmlparser.cpp index ee69b14..402c93e 100644 --- a/src/declarative/qml/qmlparser.cpp +++ b/src/declarative/qml/qmlparser.cpp @@ -54,10 +54,13 @@ #include "private/qmetaobjectbuilder_p.h" #include <private/qmlvmemetaobject_p.h> #include <private/qmlcompiler_p.h> +#include "parser/qmljsast_p.h" +#include "parser/qmljsengine_p.h" #include <QtDebug> QT_BEGIN_NAMESPACE +using namespace QmlJS; using namespace QmlParser; QmlParser::Object::Object() @@ -327,4 +330,55 @@ QmlJS::AST::Node *QmlParser::Variant::asAST() const return 0; } +bool QmlParser::Variant::isStringList() const +{ + if (isString()) + return true; + + if (type() != Script || !n) + return false; + + AST::ArrayLiteral *array = AST::cast<AST::ArrayLiteral *>(n); + if (!array) + return false; + + AST::ElementList *elements = array->elements; + + while (elements) { + + if (!AST::cast<AST::StringLiteral *>(elements->expression)) + return false; + + elements = elements->next; + } + + return true; +} + +QStringList QmlParser::Variant::asStringList() const +{ + QStringList rv; + if (isString()) { + rv << asString(); + return rv; + } + + AST::ArrayLiteral *array = AST::cast<AST::ArrayLiteral *>(n); + if (!array) + return rv; + + AST::ElementList *elements = array->elements; + while (elements) { + + AST::StringLiteral *string = AST::cast<AST::StringLiteral *>(elements->expression); + if (!string) + return QStringList(); + rv.append(string->value->asString()); + + elements = elements->next; + } + + return rv; +} + QT_END_NAMESPACE diff --git a/src/declarative/qml/qmlparser_p.h b/src/declarative/qml/qmlparser_p.h index 2ece51f..73bb498 100644 --- a/src/declarative/qml/qmlparser_p.h +++ b/src/declarative/qml/qmlparser_p.h @@ -169,9 +169,12 @@ namespace QmlParser QList<QPair<Property *, int> > scriptStringProperties; // Script blocks that were nested under this object - QStringList scriptBlocks; - QStringList scriptBlocksFile; - QList<int> scriptBlocksLineNumber; + struct ScriptBlock { + QStringList codes; + QStringList files; + QList<int> lineNumbers; + }; + QList<ScriptBlock> scripts; // The bytes to cast instances by to get to the QmlParserStatus // interface. -1 indicates the type doesn't support this interface. @@ -243,12 +246,14 @@ namespace QmlParser bool isNumber() const { return type() == Number; } bool isString() const { return type() == String; } bool isScript() const { return type() == Script; } + bool isStringList() const; bool asBoolean() const; QString asString() const; double asNumber() const; QString asScript() const; QmlJS::AST::Node *asAST() const; + QStringList asStringList() const; private: Type t; diff --git a/src/declarative/qml/qmlscriptparser.cpp b/src/declarative/qml/qmlscriptparser.cpp index b622c24..23c050c 100644 --- a/src/declarative/qml/qmlscriptparser.cpp +++ b/src/declarative/qml/qmlscriptparser.cpp @@ -383,10 +383,12 @@ Object *ProcessAST::defineObjectBinding(AST::UiQualifiedId *qualifiedId, QString propertyName = asString(scriptBinding->qualifiedId); if (propertyName == QLatin1String("source")) { if (AST::ExpressionStatement *stmt = AST::cast<AST::ExpressionStatement *>(scriptBinding->statement)) { - AST::StringLiteral *string = AST::cast<AST::StringLiteral *>(stmt->expression); - if (string) { + QmlParser::Variant string = getVariant(stmt->expression); + if (string.isStringList()) { + QStringList urls = string.asStringList(); // We need to add this as a resource - _parser->_refUrls << QUrl(string->value->asString()); + for (int ii = 0; ii < urls.count(); ++ii) + _parser->_refUrls << QUrl(urls.at(ii)); } } } diff --git a/src/declarative/qml/qmlvme.cpp b/src/declarative/qml/qmlvme.cpp index da09288..f2fb217 100644 --- a/src/declarative/qml/qmlvme.cpp +++ b/src/declarative/qml/qmlvme.cpp @@ -142,7 +142,7 @@ QObject *QmlVME::run(QStack<QObject *> &stack, QmlContext *ctxt, const QList<int> &intData = comp->intData; const QList<float> &floatData = comp->floatData; const QList<QmlPropertyCache *> &propertyCaches = comp->propertyCaches; - + const QList<QmlParser::Object::ScriptBlock> &scripts = comp->scripts; QmlEnginePrivate::SimpleList<QmlAbstractBinding> bindValues; QmlEnginePrivate::SimpleList<QmlParserStatus> parserStatus; @@ -224,7 +224,6 @@ QObject *QmlVME::run(QStack<QObject *> &stack, QmlContext *ctxt, case QmlInstruction::SetId: { QObject *target = stack.top(); -// ctxt->setContextProperty(primitives.at(instr.setId.value), target); cp->setIdProperty(instr.setId.index, target); } break; @@ -551,9 +550,7 @@ QObject *QmlVME::run(QStack<QObject *> &stack, QmlContext *ctxt, case QmlInstruction::StoreScript: { QObject *target = stack.top(); - cp->addScript(primitives.at(instr.storeScript.value), target, - primitives.at(instr.storeScript.fileName), - instr.storeScript.lineNumber); + cp->addScript(scripts.at(instr.storeScript.value), target); } break; |