aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/qml/compiler/qqmlcodegenerator.cpp48
-rw-r--r--src/qml/compiler/qqmlcodegenerator_p.h12
-rw-r--r--src/qml/compiler/qv4compileddata_p.h8
-rw-r--r--src/qml/qml/qqmlobjectcreator.cpp5
-rw-r--r--src/qml/qml/qqmlscript.cpp2
-rw-r--r--src/qml/qml/qqmltypeloader.cpp25
-rw-r--r--src/qml/qml/qqmltypeloader_p.h1
7 files changed, 95 insertions, 6 deletions
diff --git a/src/qml/compiler/qqmlcodegenerator.cpp b/src/qml/compiler/qqmlcodegenerator.cpp
index ed5f4c3772..2aa5aa5a3c 100644
--- a/src/qml/compiler/qqmlcodegenerator.cpp
+++ b/src/qml/compiler/qqmlcodegenerator.cpp
@@ -118,6 +118,7 @@ bool QQmlCodeGenerator::generateFromQml(const QString &code, const QUrl &url, co
output->program = program;
qSwap(_imports, output->imports);
+ qSwap(_pragmas, output->pragmas);
qSwap(_objects, output->objects);
qSwap(_functions, output->functions);
qSwap(_typeReferences, output->typeReferences);
@@ -147,6 +148,7 @@ bool QQmlCodeGenerator::generateFromQml(const QString &code, const QUrl &url, co
collectTypeReferences();
qSwap(_imports, output->imports);
+ qSwap(_pragmas, output->pragmas);
qSwap(_objects, output->objects);
qSwap(_functions, output->functions);
qSwap(_typeReferences, output->typeReferences);
@@ -403,6 +405,11 @@ bool QQmlCodeGenerator::visit(AST::UiImport *node)
error.setColumn(node->importIdToken.startColumn);
errors << error;
return false;
+ } else {
+ // For backward compatibility in how the imports are loaded we
+ // must otherwise initialize the major and minor version to -1.
+ import->majorVersion = -1;
+ import->minorVersion = -1;
}
import->location.line = node->importToken.startLine;
@@ -415,9 +422,38 @@ bool QQmlCodeGenerator::visit(AST::UiImport *node)
return false;
}
-bool QQmlCodeGenerator::visit(AST::UiPragma *ast)
+bool QQmlCodeGenerator::visit(AST::UiPragma *node)
{
- return true;
+ Pragma *pragma = New<Pragma>();
+
+ // For now the only valid pragma is Singleton, so lets validate the input
+ if (!node->pragmaType->name.isNull())
+ {
+ if (QLatin1String("Singleton") == node->pragmaType->name)
+ {
+ pragma->type = Pragma::PragmaSingleton;
+ } else {
+ QQmlError error;
+ error.setDescription(QCoreApplication::translate("QQmlParser","Pragma requires a valid qualifier"));
+ error.setLine(node->pragmaToken.startLine);
+ error.setColumn(node->pragmaToken.startColumn);
+ errors << error;
+ return false;
+ }
+ } else {
+ QQmlError error;
+ error.setDescription(QCoreApplication::translate("QQmlParser","Pragma requires a valid qualifier"));
+ error.setLine(node->pragmaToken.startLine);
+ error.setColumn(node->pragmaToken.startColumn);
+ errors << error;
+ return false;
+ }
+
+ pragma->location.line = node->pragmaToken.startLine;
+ pragma->location.column = node->pragmaToken.startColumn;
+ _pragmas.append(pragma);
+
+ return false;
}
static QStringList astNodeToStringList(QQmlJS::AST::Node *node)
@@ -1146,6 +1182,14 @@ QV4::CompiledData::QmlUnit *QmlUnitGenerator::generate(ParsedQML &output, const
objectPtr += signalTableSize;
}
+ // enable flag if we encountered pragma Singleton
+ foreach (Pragma *p, output.pragmas) {
+ if (p->type == Pragma::PragmaSingleton) {
+ qmlUnit->header.flags |= QV4::CompiledData::Unit::IsSingleton;
+ break;
+ }
+ }
+
return qmlUnit;
}
diff --git a/src/qml/compiler/qqmlcodegenerator_p.h b/src/qml/compiler/qqmlcodegenerator_p.h
index b6749516d3..8de08a81d1 100644
--- a/src/qml/compiler/qqmlcodegenerator_p.h
+++ b/src/qml/compiler/qqmlcodegenerator_p.h
@@ -154,6 +154,16 @@ struct QmlObject
void dump(DebugStream &out);
};
+struct Pragma
+{
+ enum PragmaType {
+ PragmaSingleton = 0x1
+ };
+ quint32 type;
+
+ QV4::CompiledData::Location location;
+};
+
struct ParsedQML
{
ParsedQML()
@@ -163,6 +173,7 @@ struct ParsedQML
QQmlJS::Engine jsParserEngine;
V4IR::Module jsModule;
QList<QV4::CompiledData::Import*> imports;
+ QList<Pragma*> pragmas;
AST::UiProgram *program;
int indexOfRootObject;
QList<QmlObject*> objects;
@@ -253,6 +264,7 @@ public:
QList<QQmlError> errors;
QList<QV4::CompiledData::Import*> _imports;
+ QList<Pragma*> _pragmas;
QList<QmlObject*> _objects;
QList<AST::Node*> _functions;
diff --git a/src/qml/compiler/qv4compileddata_p.h b/src/qml/compiler/qv4compileddata_p.h
index bf6794e182..2c0a46f3c5 100644
--- a/src/qml/compiler/qv4compileddata_p.h
+++ b/src/qml/compiler/qv4compileddata_p.h
@@ -148,7 +148,8 @@ struct Unit
enum {
IsJavascript = 0x1,
IsQml = 0x2,
- StaticData = 0x4 // Unit data persistent in memory?
+ StaticData = 0x4, // Unit data persistent in memory?
+ IsSingleton = 0x8
};
quint32 flags;
uint stringTableSize;
@@ -414,7 +415,6 @@ struct Import
Location location;
};
-
struct QmlUnit
{
Unit header;
@@ -433,6 +433,10 @@ struct QmlUnit
const uint offset = offsetTable[idx];
return reinterpret_cast<const Object*>(reinterpret_cast<const char*>(this) + offset);
}
+
+ bool isSingleton() const {
+ return header.flags & Unit::IsSingleton;
+ }
};
// This is how this hooks into the existing structures:
diff --git a/src/qml/qml/qqmlobjectcreator.cpp b/src/qml/qml/qqmlobjectcreator.cpp
index 4e70e14894..56776dcb82 100644
--- a/src/qml/qml/qqmlobjectcreator.cpp
+++ b/src/qml/qml/qqmlobjectcreator.cpp
@@ -1239,6 +1239,11 @@ QObject *QmlObjectCreator::createInstance(int index, QObject *parent)
}
} else {
Q_ASSERT(typeRef.component);
+ if (typeRef.component->qmlUnit->isSingleton())
+ {
+ recordError(obj->location, tr("Composite Singleton Type %1 is not creatable").arg(stringAt(obj->inheritedTypeNameIndex)));
+ return 0;
+ }
QmlObjectCreator subCreator(context, typeRef.component);
instance = subCreator.create();
if (!instance) {
diff --git a/src/qml/qml/qqmlscript.cpp b/src/qml/qml/qqmlscript.cpp
index cc01307e54..9fd06aa934 100644
--- a/src/qml/qml/qqmlscript.cpp
+++ b/src/qml/qml/qqmlscript.cpp
@@ -895,7 +895,7 @@ bool ProcessAST::visit(AST::UiPragma *node)
// For now the only valid pragma is Singleton, so lets validate the input
if (!node->pragmaType->name.isNull())
{
- if (QLatin1String("Singleton") == node->pragmaType->name.toString())
+ if (QLatin1String("Singleton") == node->pragmaType->name)
{
pragma.type = QQmlScript::Pragma::Singleton;
} else {
diff --git a/src/qml/qml/qqmltypeloader.cpp b/src/qml/qml/qqmltypeloader.cpp
index 932faf4b88..601c1b8bdc 100644
--- a/src/qml/qml/qqmltypeloader.cpp
+++ b/src/qml/qml/qqmltypeloader.cpp
@@ -2218,7 +2218,24 @@ void QQmlTypeData::dataReceived(const Data &data)
}
}
- foreach (const QQmlScript::Pragma &pragma, scriptParser.pragmas()) {
+ // ### convert to use new data structure once old compiler is gone.
+ if (m_useNewCompiler && m_newPragmas.isEmpty()) {
+ m_newPragmas.reserve(parsedQML->pragmas.size());
+ foreach (QtQml::Pragma *p, parsedQML->pragmas) {
+ QQmlScript::Pragma pragma;
+ pragma.location.start.line = p->location.line;
+ pragma.location.start.column = p->location.column;
+
+ switch (p->type) {
+ case QtQml::Pragma::PragmaSingleton: pragma.type = QQmlScript::Pragma::Singleton; break;
+ default: break;
+ }
+
+ m_newPragmas << pragma;
+ }
+ }
+
+ foreach (const QQmlScript::Pragma &pragma, m_useNewCompiler ? m_newPragmas : scriptParser.pragmas()) {
if (!addPragma(pragma, &errors)) {
Q_ASSERT(errors.size());
setError(errors);
@@ -2280,6 +2297,12 @@ void QQmlTypeData::compile()
foreach (const QString &ns, m_namespaces)
m_compiledData->importCache->add(ns);
+ // Add any Composite Singletons that were used to the import cache
+ for (int i = 0; i < compositeSingletons().count(); ++i) {
+ m_compiledData->importCache->add(compositeSingletons().at(i).type->qmlTypeName(),
+ compositeSingletons().at(i).type->sourceUrl(), compositeSingletons().at(i).prefix);
+ }
+
m_imports.populateCache(m_compiledData->importCache);
m_compiledData->importCache->addref();
diff --git a/src/qml/qml/qqmltypeloader_p.h b/src/qml/qml/qqmltypeloader_p.h
index b9bf056cb3..b93cf2942d 100644
--- a/src/qml/qml/qqmltypeloader_p.h
+++ b/src/qml/qml/qqmltypeloader_p.h
@@ -460,6 +460,7 @@ private:
// --- new compiler
QScopedPointer<QtQml::ParsedQML> parsedQML;
QList<QQmlScript::Import> m_newImports;
+ QList<QQmlScript::Pragma> m_newPragmas;
// ---
QList<ScriptReference> m_scripts;