diff options
author | Aaron Kennedy <aaron.kennedy@nokia.com> | 2010-03-22 05:34:41 (GMT) |
---|---|---|
committer | Aaron Kennedy <aaron.kennedy@nokia.com> | 2010-03-22 05:36:35 (GMT) |
commit | 888d29c9c138ca3d698985f090ceb3db912ade0f (patch) | |
tree | aa991f683dd8e7ea4b05d029dd75b32321fde3c0 /src/declarative/qml | |
parent | 42de973ff156383beed62a6b1bce70b56b360078 (diff) | |
download | Qt-888d29c9c138ca3d698985f090ceb3db912ade0f.zip Qt-888d29c9c138ca3d698985f090ceb3db912ade0f.tar.gz Qt-888d29c9c138ca3d698985f090ceb3db912ade0f.tar.bz2 |
Deprecate inline Script {} blocks
Inline blocks/includes have been replaced with an import syntax:
import "foo.js" as Foo
this gives better separation between QML and code. Imported script blocks
also have a mandatory qualifier, which leads to better optimization
potential.
Diffstat (limited to 'src/declarative/qml')
18 files changed, 349 insertions, 23 deletions
diff --git a/src/declarative/qml/qdeclarativecompiler.cpp b/src/declarative/qml/qdeclarativecompiler.cpp index 103e918..28c2210 100644 --- a/src/declarative/qml/qdeclarativecompiler.cpp +++ b/src/declarative/qml/qdeclarativecompiler.cpp @@ -542,8 +542,8 @@ void QDeclarativeCompiler::reset(QDeclarativeCompiledData *data) on a successful compiler. */ bool QDeclarativeCompiler::compile(QDeclarativeEngine *engine, - QDeclarativeCompositeTypeData *unit, - QDeclarativeCompiledData *out) + QDeclarativeCompositeTypeData *unit, + QDeclarativeCompiledData *out) { exceptions.clear(); @@ -633,6 +633,37 @@ void QDeclarativeCompiler::compileTree(Object *tree) init.init.compiledBinding = output->indexForByteArray(compileState.compiledBindingData); output->bytecode << init; + // Build global import scripts + QHash<QString, Object::ScriptBlock> importedScripts; + QStringList importedScriptIndexes; + + for (int ii = 0; ii < unit->scripts.count(); ++ii) { + QString scriptCode = QString::fromUtf8(unit->scripts.at(ii).resource->data); + Object::ScriptBlock::Pragmas pragmas = QDeclarativeScriptParser::extractPragmas(scriptCode); + + if (!scriptCode.isEmpty()) { + Object::ScriptBlock &scriptBlock = importedScripts[unit->scripts.at(ii).qualifier]; + + scriptBlock.codes.append(scriptCode); + scriptBlock.lineNumbers.append(1); + scriptBlock.files.append(unit->scripts.at(ii).resource->url); + scriptBlock.pragmas.append(pragmas); + } + } + + for (QHash<QString, Object::ScriptBlock>::Iterator iter = importedScripts.begin(); + iter != importedScripts.end(); ++iter) { + + importedScriptIndexes.append(iter.key()); + + QDeclarativeInstruction import; + import.type = QDeclarativeInstruction::StoreImportedScript; + import.line = 0; + import.storeScript.value = output->scripts.count(); + output->scripts << *iter; + output->bytecode << import; + } + genObject(tree); QDeclarativeInstruction def; @@ -641,7 +672,13 @@ void QDeclarativeCompiler::compileTree(Object *tree) output->bytecode << def; output->imports = unit->imports; - output->importCache = output->imports.cache(engine); + + output->importCache = new QDeclarativeTypeNameCache(engine); + + for (int ii = 0; ii < importedScriptIndexes.count(); ++ii) + output->importCache->add(importedScriptIndexes.at(ii), ii); + + output->imports.cache(output->importCache, engine); Q_ASSERT(tree->metatype); @@ -1153,6 +1190,8 @@ bool QDeclarativeCompiler::buildComponent(QDeclarativeParser::Object *obj, bool QDeclarativeCompiler::buildScript(QDeclarativeParser::Object *obj, QDeclarativeParser::Object *script) { + qWarning().nospace() << qPrintable(output->url.toString()) << ":" << obj->location.start.line << ":" << obj->location.start.column << ": Script blocks have been deprecated. Support will be removed entirely shortly."; + Object::ScriptBlock scriptBlock; if (script->properties.count() == 1 && @@ -1184,6 +1223,7 @@ bool QDeclarativeCompiler::buildScript(QDeclarativeParser::Object *obj, QDeclara scriptBlock.codes.append(scriptCode); scriptBlock.files.append(sourceUrl); scriptBlock.lineNumbers.append(lineNumber); + scriptBlock.pragmas.append(Object::ScriptBlock::None); } } @@ -1226,6 +1266,7 @@ bool QDeclarativeCompiler::buildScript(QDeclarativeParser::Object *obj, QDeclara scriptBlock.codes.append(scriptCode); scriptBlock.files.append(sourceUrl); scriptBlock.lineNumbers.append(lineNumber); + scriptBlock.pragmas.append(Object::ScriptBlock::None); } } diff --git a/src/declarative/qml/qdeclarativecomponent.cpp b/src/declarative/qml/qdeclarativecomponent.cpp index ec595e3..ec23458 100644 --- a/src/declarative/qml/qdeclarativecomponent.cpp +++ b/src/declarative/qml/qdeclarativecomponent.cpp @@ -612,6 +612,11 @@ QDeclarativeComponentPrivate::beginCreate(QDeclarativeContextData *context, cons ctxt->isInternal = true; ctxt->url = cc->url; ctxt->imports = cc->importCache; + + // Nested global imports + if (creationContext && start != -1) + ctxt->importedScripts = creationContext->importedScripts; + cc->importCache->addref(); ctxt->setParent(context); diff --git a/src/declarative/qml/qdeclarativecomponent_p.h b/src/declarative/qml/qdeclarativecomponent_p.h index 649fce5..b44aeef 100644 --- a/src/declarative/qml/qdeclarativecomponent_p.h +++ b/src/declarative/qml/qdeclarativecomponent_p.h @@ -116,7 +116,7 @@ public: static void complete(QDeclarativeEnginePrivate *enginePriv, ConstructionState *state); QDeclarativeEngine *engine; - QDeclarativeContextData *creationContext; + QDeclarativeGuardedContextData creationContext; void clear(); diff --git a/src/declarative/qml/qdeclarativecompositetypedata_p.h b/src/declarative/qml/qdeclarativecompositetypedata_p.h index fb26af9..04d0c63 100644 --- a/src/declarative/qml/qdeclarativecompositetypedata_p.h +++ b/src/declarative/qml/qdeclarativecompositetypedata_p.h @@ -103,7 +103,16 @@ public: QDeclarativeCompositeTypeData *unit; }; + struct ScriptReference + { + ScriptReference(); + + QString qualifier; + QDeclarativeCompositeTypeResource *resource; + }; + QList<TypeReference> types; + QList<ScriptReference> scripts; QList<QDeclarativeCompositeTypeResource *> resources; // Add or remove p as a waiter. When the QDeclarativeCompositeTypeData becomes diff --git a/src/declarative/qml/qdeclarativecompositetypemanager.cpp b/src/declarative/qml/qdeclarativecompositetypemanager.cpp index ebf1f40..c883805 100644 --- a/src/declarative/qml/qdeclarativecompositetypemanager.cpp +++ b/src/declarative/qml/qdeclarativecompositetypemanager.cpp @@ -126,6 +126,27 @@ QDeclarativeCompositeTypeData::toCompiledComponent(QDeclarativeEngine *engine) { if (status == Complete && !compiledComponent) { + // Build script imports + foreach (const QDeclarativeScriptParser::Import &import, data.imports()) { + if (import.type == QDeclarativeScriptParser::Import::Script) { + QString url = imports.baseUrl().resolved(QUrl(import.uri)).toString(); + + ScriptReference ref; + ref.qualifier = import.qualifier; + + for (int ii = 0; ii < resources.count(); ++ii) { + if (resources.at(ii)->url == url) { + ref.resource = resources.at(ii); + break; + } + } + + Q_ASSERT(ref.resource); + + scripts << ref; + } + } + compiledComponent = new QDeclarativeCompiledData(engine); compiledComponent->url = imports.baseUrl(); compiledComponent->name = compiledComponent->url.toString(); @@ -153,6 +174,11 @@ QDeclarativeCompositeTypeData::TypeReference::TypeReference() { } +QDeclarativeCompositeTypeData::ScriptReference::ScriptReference() +: resource(0) +{ +} + QDeclarativeCompositeTypeManager::QDeclarativeCompositeTypeManager(QDeclarativeEngine *e) : engine(e), redirectCount(0) { @@ -514,6 +540,9 @@ int QDeclarativeCompositeTypeManager::resolveTypes(QDeclarativeCompositeTypeData foreach (QDeclarativeScriptParser::Import imp, unit->data.imports()) { QDeclarativeDirComponents qmldircomponentsnetwork; + if (imp.type == QDeclarativeScriptParser::Import::Script) + continue; + if (imp.type == QDeclarativeScriptParser::Import::File && imp.qualifier.isEmpty()) { QString importUrl = unit->imports.baseUrl().resolved(QUrl(imp.uri + QLatin1String("/qmldir"))).toString(); for (int ii = 0; ii < unit->resources.count(); ++ii) { diff --git a/src/declarative/qml/qdeclarativecontext.cpp b/src/declarative/qml/qdeclarativecontext.cpp index 782c0d7..85896c4 100644 --- a/src/declarative/qml/qdeclarativecontext.cpp +++ b/src/declarative/qml/qdeclarativecontext.cpp @@ -606,6 +606,75 @@ void QDeclarativeContextData::addObject(QObject *o) contextObjects = data; } +void QDeclarativeContextData::addImportedScript(const QDeclarativeParser::Object::ScriptBlock &script) +{ + if (!engine) + return; + + Q_ASSERT(script.codes.count() == 1); + + QDeclarativeEnginePrivate *enginePriv = QDeclarativeEnginePrivate::get(engine); + QScriptEngine *scriptEngine = QDeclarativeEnginePrivate::getScriptEngine(engine); + + const QString &code = script.codes.at(0); + const QString &url = script.files.at(0); + const QDeclarativeParser::Object::ScriptBlock::Pragmas &pragmas = script.pragmas.at(0); + + Q_ASSERT(!url.isEmpty()); + + if (pragmas & QDeclarativeParser::Object::ScriptBlock::Shared) { + + QHash<QString, QScriptValue>::Iterator iter = enginePriv->m_sharedScriptImports.find(url); + if (iter == enginePriv->m_sharedScriptImports.end()) { + QScriptContext *scriptContext = QScriptDeclarativeClass::pushCleanContext(scriptEngine); + + scriptContext->pushScope(enginePriv->globalClass->globalObject()); + + QScriptValue scope = scriptEngine->newObject(); + scriptContext->setActivationObject(scope); + scriptContext->pushScope(scope); + + scriptEngine->evaluate(code, url, 1); + + if (scriptEngine->hasUncaughtException()) { + QDeclarativeError error; + QDeclarativeExpressionPrivate::exceptionToError(scriptEngine, error); + qWarning().nospace() << qPrintable(error.toString()); + } + + scriptEngine->popContext(); + + iter = enginePriv->m_sharedScriptImports.insert(url, scope); + } + + importedScripts.append(*iter); + + } else { + + QScriptContext *scriptContext = QScriptDeclarativeClass::pushCleanContext(scriptEngine); + + scriptContext->pushScope(enginePriv->contextClass->newContext(this, 0)); + scriptContext->pushScope(enginePriv->globalClass->globalObject()); + + QScriptValue scope = scriptEngine->newObject(); + scriptContext->setActivationObject(scope); + scriptContext->pushScope(scope); + + scriptEngine->evaluate(code, url, 1); + + if (scriptEngine->hasUncaughtException()) { + QDeclarativeError error; + QDeclarativeExpressionPrivate::exceptionToError(scriptEngine, error); + qWarning().nospace() << qPrintable(error.toString()); + } + + scriptEngine->popContext(); + + importedScripts.append(scope); + + } +} + void QDeclarativeContextData::addScript(const QDeclarativeParser::Object::ScriptBlock &script, QObject *scopeObject) { diff --git a/src/declarative/qml/qdeclarativecontext_p.h b/src/declarative/qml/qdeclarativecontext_p.h index d74aa33..ecf3ec8 100644 --- a/src/declarative/qml/qdeclarativecontext_p.h +++ b/src/declarative/qml/qdeclarativecontext_p.h @@ -141,6 +141,8 @@ public: // Any script blocks that exist on this context QList<QScriptValue> scripts; + QList<QScriptValue> importedScripts; + void addImportedScript(const QDeclarativeParser::Object::ScriptBlock &script); void addScript(const QDeclarativeParser::Object::ScriptBlock &script, QObject *scopeObject); // Context base url diff --git a/src/declarative/qml/qdeclarativecontextscriptclass.cpp b/src/declarative/qml/qdeclarativecontextscriptclass.cpp index 847d632..2559224 100644 --- a/src/declarative/qml/qdeclarativecontextscriptclass.cpp +++ b/src/declarative/qml/qdeclarativecontextscriptclass.cpp @@ -240,10 +240,19 @@ QDeclarativeContextScriptClass::property(Object *object, const Identifier &name) } else if (lastData) { - if (lastData->type) + if (lastData->type) { return Value(scriptEngine, ep->typeNameClass->newObject(bindContext->contextObject, lastData->type)); - else - return Value(scriptEngine, ep->typeNameClass->newObject(bindContext->contextObject, lastData->typeNamespace)); + } else if (lastData->typeNamespace) { + return Value(scriptEngine, ep->typeNameClass->newObject(bindContext->contextObject, + lastData->typeNamespace)); + } else { + int index = lastData->importedScriptIndex; + if (index < bindContext->importedScripts.count()) { + return Value(scriptEngine, bindContext->importedScripts.at(index)); + } else { + return Value(); + } + } } else if (lastPropertyIndex != -1) { @@ -266,7 +275,6 @@ QDeclarativeContextScriptClass::property(Object *object, const Identifier &name) ep->capturedProperties << QDeclarativeEnginePrivate::CapturedProperty(bindContext->asQDeclarativeContext(), -1, lastPropertyIndex + cp->notifyIndex); } - return Value(scriptEngine, rv); } else { diff --git a/src/declarative/qml/qdeclarativeengine.cpp b/src/declarative/qml/qdeclarativeengine.cpp index 5820961..0bedbeb 100644 --- a/src/declarative/qml/qdeclarativeengine.cpp +++ b/src/declarative/qml/qdeclarativeengine.cpp @@ -1695,12 +1695,10 @@ static QDeclarativeTypeNameCache *cacheForNamespace(QDeclarativeEngine *engine, return cache; } -QDeclarativeTypeNameCache *QDeclarativeEnginePrivate::Imports::cache(QDeclarativeEngine *engine) const +void QDeclarativeEnginePrivate::Imports::cache(QDeclarativeTypeNameCache *cache, QDeclarativeEngine *engine) const { const QDeclarativeEnginePrivate::ImportedNamespace &set = d->unqualifiedset; - QDeclarativeTypeNameCache *cache = new QDeclarativeTypeNameCache(engine); - for (QHash<QString,QDeclarativeEnginePrivate::ImportedNamespace* >::ConstIterator iter = d->set.begin(); iter != d->set.end(); ++iter) { @@ -1716,8 +1714,6 @@ QDeclarativeTypeNameCache *QDeclarativeEnginePrivate::Imports::cache(QDeclarativ } cacheForNamespace(engine, set, cache); - - return cache; } /* diff --git a/src/declarative/qml/qdeclarativeengine_p.h b/src/declarative/qml/qdeclarativeengine_p.h index 4ab619e..6532d30 100644 --- a/src/declarative/qml/qdeclarativeengine_p.h +++ b/src/declarative/qml/qdeclarativeengine_p.h @@ -264,7 +264,7 @@ public: void setBaseUrl(const QUrl& url); QUrl baseUrl() const; - QDeclarativeTypeNameCache *cache(QDeclarativeEngine *) const; + void cache(QDeclarativeTypeNameCache *cache, QDeclarativeEngine *) const; private: friend class QDeclarativeEnginePrivate; @@ -281,7 +281,9 @@ public: QString resolvePlugin(const QDir &dir, const QString &baseName); - bool addToImport(Imports*, const QDeclarativeDirComponents &qmldircomponentsnetwork, const QString& uri, const QString& prefix, int vmaj, int vmin, QDeclarativeScriptParser::Import::Type importType) const; + bool addToImport(Imports*, const QDeclarativeDirComponents &qmldircomponentsnetwork, + const QString& uri, const QString& prefix, int vmaj, int vmin, + QDeclarativeScriptParser::Import::Type importType) const; bool resolveType(const Imports&, const QByteArray& type, QDeclarativeType** type_return, QUrl* url_return, int *version_major, int *version_minor, @@ -303,6 +305,8 @@ public: QHash<int, int> m_qmlLists; QHash<int, QDeclarativeCompiledData *> m_compositeTypes; + QHash<QString, QScriptValue> m_sharedScriptImports; + QScriptValue scriptValueFromVariant(const QVariant &); QVariant scriptValueToVariant(const QScriptValue &); diff --git a/src/declarative/qml/qdeclarativeinstruction.cpp b/src/declarative/qml/qdeclarativeinstruction.cpp index a23ff75..9083ab3 100644 --- a/src/declarative/qml/qdeclarativeinstruction.cpp +++ b/src/declarative/qml/qdeclarativeinstruction.cpp @@ -144,6 +144,9 @@ void QDeclarativeCompiledData::dump(QDeclarativeInstruction *instr, int idx) case QDeclarativeInstruction::StoreScript: qWarning().nospace() << idx << "\t\t" << line << "\t" << "STORE_SCRIPT\t\t" << instr->storeScript.value; break; + case QDeclarativeInstruction::StoreImportedScript: + qWarning().nospace() << idx << "\t\t" << line << "\t" << "STORE_IMPORTED_SCRIPT\t" << instr->storeScript.value; + break; case QDeclarativeInstruction::StoreScriptString: qWarning().nospace() << idx << "\t\t" << line << "\t" << "STORE_SCRIPT_STRING\t" << instr->storeScriptString.propertyIndex << "\t" << instr->storeScriptString.value << "\t" << instr->storeScriptString.scope; break; diff --git a/src/declarative/qml/qdeclarativeinstruction_p.h b/src/declarative/qml/qdeclarativeinstruction_p.h index ec32b35..877179d 100644 --- a/src/declarative/qml/qdeclarativeinstruction_p.h +++ b/src/declarative/qml/qdeclarativeinstruction_p.h @@ -119,6 +119,7 @@ public: StoreSignal, /* storeSignal */ StoreScript, /* storeScript */ + StoreImportedScript, /* storeScript */ StoreScriptString, /* storeScriptString */ // diff --git a/src/declarative/qml/qdeclarativeparser_p.h b/src/declarative/qml/qdeclarativeparser_p.h index 9dfb86b..476b027 100644 --- a/src/declarative/qml/qdeclarativeparser_p.h +++ b/src/declarative/qml/qdeclarativeparser_p.h @@ -179,9 +179,16 @@ namespace QDeclarativeParser // Script blocks that were nested under this object struct ScriptBlock { + enum Pragma { + None = 0x00000000, + Shared = 0x00000001 + }; + Q_DECLARE_FLAGS(Pragmas, Pragma) + QStringList codes; QStringList files; QList<int> lineNumbers; + QList<Pragmas> pragmas; }; QList<ScriptBlock> scripts; @@ -360,6 +367,8 @@ namespace QDeclarativeParser }; } +Q_DECLARE_OPERATORS_FOR_FLAGS(QDeclarativeParser::Object::ScriptBlock::Pragmas); + QT_END_NAMESPACE Q_DECLARE_METATYPE(QDeclarativeParser::Variant) diff --git a/src/declarative/qml/qdeclarativescriptparser.cpp b/src/declarative/qml/qdeclarativescriptparser.cpp index 2578ff4..49bd3b7 100644 --- a/src/declarative/qml/qdeclarativescriptparser.cpp +++ b/src/declarative/qml/qdeclarativescriptparser.cpp @@ -441,8 +441,14 @@ bool ProcessAST::visit(AST::UiImport *node) QDeclarativeScriptParser::Import import; if (node->fileName) { - import.type = QDeclarativeScriptParser::Import::File; uri = node->fileName->asString(); + + if (uri.endsWith(QLatin1String(".js"))) { + import.type = QDeclarativeScriptParser::Import::Script; + _parser->_refUrls << QUrl(uri); + } else { + import.type = QDeclarativeScriptParser::Import::File; + } } else { import.type = QDeclarativeScriptParser::Import::Library; uri = asString(node->importUri); @@ -451,6 +457,7 @@ bool ProcessAST::visit(AST::UiImport *node) AST::SourceLocation startLoc = node->importToken; AST::SourceLocation endLoc = node->semicolonToken; + // Qualifier if (node->importId) { import.qualifier = node->importId->asString(); if (!import.qualifier.at(0).isUpper()) { @@ -461,17 +468,43 @@ bool ProcessAST::visit(AST::UiImport *node) _parser->_errors << error; return false; } + + // Check for script qualifier clashes + bool isScript = import.type == QDeclarativeScriptParser::Import::Script; + for (int ii = 0; ii < _parser->_imports.count(); ++ii) { + const QDeclarativeScriptParser::Import &other = _parser->_imports.at(ii); + bool otherIsScript = other.type == QDeclarativeScriptParser::Import::Script; + + if ((isScript || otherIsScript) && import.qualifier == other.qualifier) { + QDeclarativeError error; + error.setDescription(QCoreApplication::translate("QDeclarativeParser","Script import qualifiers must be unique.")); + error.setLine(node->importIdToken.startLine); + error.setColumn(node->importIdToken.startColumn); + _parser->_errors << error; + return false; + } + } + + } else if (import.type == QDeclarativeScriptParser::Import::Script) { + QDeclarativeError error; + error.setDescription(QCoreApplication::translate("QDeclarativeParser","Script import requires a qualifier")); + error.setLine(node->importIdToken.startLine); + error.setColumn(node->importIdToken.startColumn); + _parser->_errors << error; + return false; } - if (node->versionToken.isValid()) + + if (node->versionToken.isValid()) { import.version = textAt(node->versionToken); - else if (import.type == QDeclarativeScriptParser::Import::Library) { + } else if (import.type == QDeclarativeScriptParser::Import::Library) { QDeclarativeError error; error.setDescription(QCoreApplication::translate("QDeclarativeParser","Library import requires a version")); error.setLine(node->importIdToken.startLine); error.setColumn(node->importIdToken.startColumn); _parser->_errors << error; return false; - } + } + import.location = location(startLoc, endLoc); import.uri = uri; @@ -934,6 +967,95 @@ QList<QDeclarativeError> QDeclarativeScriptParser::errors() const return _errors; } +/* +Searches for ".pragma <value>" declarations within \a script. Currently supported pragmas +are: + library +*/ +QDeclarativeParser::Object::ScriptBlock::Pragmas QDeclarativeScriptParser::extractPragmas(QString &script) +{ + QDeclarativeParser::Object::ScriptBlock::Pragmas rv = QDeclarativeParser::Object::ScriptBlock::None; + + const QChar forwardSlash(QLatin1Char('/')); + const QChar star(QLatin1Char('*')); + const QChar newline(QLatin1Char('\n')); + const QChar dot(QLatin1Char('.')); + const QChar semicolon(QLatin1Char(';')); + const QChar space(QLatin1Char(' ')); + const QString pragma(QLatin1String(".pragma ")); + + const QChar *pragmaData = pragma.constData(); + + const QChar *data = script.constData(); + const int length = script.count(); + for (int ii = 0; ii < length; ++ii) { + const QChar &c = data[ii]; + + if (c.isSpace()) + continue; + + if (c == forwardSlash) { + ++ii; + if (ii >= length) + return rv; + + const QChar &c = data[ii]; + if (c == forwardSlash) { + // Find next newline + while (ii < length && data[++ii] != newline) {}; + } else if (c == star) { + // Find next star + while (true) { + while (ii < length && data[++ii] != star) {}; + if (ii + 1 >= length) + return rv; + + if (data[ii + 1] == forwardSlash) { + ++ii; + break; + } + } + } else { + return rv; + } + } else if (c == dot) { + // Could be a pragma! + if (ii + pragma.length() >= length || + 0 != ::memcmp(data + ii, pragmaData, sizeof(QChar) * pragma.length())) + return rv; + + int pragmaStatementIdx = ii; + + ii += pragma.length(); + + while (ii < length && data[ii].isSpace()) { ++ii; } + + int startIdx = ii; + + while (ii < length && data[ii].isLetter()) { ++ii; } + + int endIdx = ii; + + if (ii != length && data[ii] != forwardSlash && !data[ii].isSpace() && data[ii] != semicolon) + return rv; + + QString p(data + startIdx, endIdx - startIdx); + + if (p == QLatin1String("library")) + rv |= QDeclarativeParser::Object::ScriptBlock::Shared; + else + return rv; + + for (int jj = pragmaStatementIdx; jj < endIdx; ++jj) script[jj] = space; + + } else { + return rv; + } + } + + return rv; +} + void QDeclarativeScriptParser::clear() { if (root) { diff --git a/src/declarative/qml/qdeclarativescriptparser_p.h b/src/declarative/qml/qdeclarativescriptparser_p.h index b8f77d1..68f1840 100644 --- a/src/declarative/qml/qdeclarativescriptparser_p.h +++ b/src/declarative/qml/qdeclarativescriptparser_p.h @@ -75,7 +75,7 @@ public: public: Import() : type(Library) {} - enum Type { Library, File }; + enum Type { Library, File, Script }; Type type; QString uri; @@ -112,6 +112,8 @@ public: QList<QDeclarativeError> errors() const; + static QDeclarativeParser::Object::ScriptBlock::Pragmas extractPragmas(QString &); + // ### private: TypeReference *findOrCreateType(const QString &name); void setTree(QDeclarativeParser::Object *tree); diff --git a/src/declarative/qml/qdeclarativetypenamecache.cpp b/src/declarative/qml/qdeclarativetypenamecache.cpp index f94f944..c4a8707 100644 --- a/src/declarative/qml/qdeclarativetypenamecache.cpp +++ b/src/declarative/qml/qdeclarativetypenamecache.cpp @@ -63,6 +63,21 @@ void QDeclarativeTypeNameCache::clear() engine = 0; } +void QDeclarativeTypeNameCache::add(const QString &name, int importedScriptIndex) +{ + if (stringCache.contains(name)) + return; + + QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(engine); + + RData *data = new RData; + // ### Use typename class + data->identifier = ep->objectClass->createPersistentIdentifier(name); + data->importedScriptIndex = importedScriptIndex; + stringCache.insert(name, data); + identifierCache.insert(data->identifier.identifier, data); +} + void QDeclarativeTypeNameCache::add(const QString &name, QDeclarativeType *type) { if (stringCache.contains(name)) diff --git a/src/declarative/qml/qdeclarativetypenamecache_p.h b/src/declarative/qml/qdeclarativetypenamecache_p.h index eee5b77..3e24f5c 100644 --- a/src/declarative/qml/qdeclarativetypenamecache_p.h +++ b/src/declarative/qml/qdeclarativetypenamecache_p.h @@ -73,8 +73,10 @@ public: inline ~Data(); QDeclarativeType *type; QDeclarativeTypeNameCache *typeNamespace; + int importedScriptIndex; }; + void add(const QString &, int); void add(const QString &, QDeclarativeType *); void add(const QString &, QDeclarativeTypeNameCache *); @@ -97,7 +99,7 @@ private: }; QDeclarativeTypeNameCache::Data::Data() -: type(0), typeNamespace(0) +: type(0), typeNamespace(0), importedScriptIndex(-1) { } diff --git a/src/declarative/qml/qdeclarativevme.cpp b/src/declarative/qml/qdeclarativevme.cpp index b3144a8..2338bc3 100644 --- a/src/declarative/qml/qdeclarativevme.cpp +++ b/src/declarative/qml/qdeclarativevme.cpp @@ -259,8 +259,9 @@ QObject *QDeclarativeVME::run(QDeclarativeVMEStack<QObject *> &stack, case QDeclarativeInstruction::CreateComponent: { - QObject *qcomp = new QDeclarativeComponent(ctxt->engine, comp, ii + 1, instr.createComponent.count, - stack.isEmpty() ? 0 : stack.top()); + QDeclarativeComponent *qcomp = + new QDeclarativeComponent(ctxt->engine, comp, ii + 1, instr.createComponent.count, + stack.isEmpty() ? 0 : stack.top()); QDeclarativeDeclarativeData *ddata = QDeclarativeDeclarativeData::get(qcomp, true); Q_ASSERT(ddata); @@ -275,6 +276,8 @@ QObject *QDeclarativeVME::run(QDeclarativeVMEStack<QObject *> &stack, ddata->lineNumber = instr.line; ddata->columnNumber = instr.create.column; + QDeclarativeComponentPrivate::get(qcomp)->creationContext = ctxt; + stack.push(qcomp); ii += instr.createComponent.count; } @@ -581,6 +584,12 @@ QObject *QDeclarativeVME::run(QDeclarativeVMEStack<QObject *> &stack, } break; + case QDeclarativeInstruction::StoreImportedScript: + { + ctxt->addImportedScript(scripts.at(instr.storeScript.value)); + } + break; + case QDeclarativeInstruction::StoreScriptString: { QObject *target = stack.top(); |