summaryrefslogtreecommitdiffstats
path: root/src/declarative/qml
diff options
context:
space:
mode:
Diffstat (limited to 'src/declarative/qml')
-rw-r--r--src/declarative/qml/qml.pri2
-rw-r--r--src/declarative/qml/qmlbasicscript.cpp79
-rw-r--r--src/declarative/qml/qmlbasicscript_p.h2
-rw-r--r--src/declarative/qml/qmlcompileddata.cpp5
-rw-r--r--src/declarative/qml/qmlcompiler.cpp287
-rw-r--r--src/declarative/qml/qmlcompiler_p.h24
-rw-r--r--src/declarative/qml/qmlcomponent.cpp10
-rw-r--r--src/declarative/qml/qmlcontext.cpp61
-rw-r--r--src/declarative/qml/qmlcontext.h5
-rw-r--r--src/declarative/qml/qmldom.cpp6
-rw-r--r--src/declarative/qml/qmldom.h2
-rw-r--r--src/declarative/qml/qmlengine.cpp130
-rw-r--r--src/declarative/qml/qmlengine.h3
-rw-r--r--src/declarative/qml/qmlengine_p.h3
-rw-r--r--src/declarative/qml/qmlerror.cpp29
-rw-r--r--src/declarative/qml/qmlerror.h2
-rw-r--r--src/declarative/qml/qmlexpression.cpp98
-rw-r--r--src/declarative/qml/qmlmetaproperty.cpp3
-rw-r--r--src/declarative/qml/qmlparser.cpp7
-rw-r--r--src/declarative/qml/qmlparser_p.h9
-rw-r--r--src/declarative/qml/qmlrewrite.cpp157
-rw-r--r--src/declarative/qml/qmlrewrite_p.h103
-rw-r--r--src/declarative/qml/qmlscriptparser.cpp50
-rw-r--r--src/declarative/qml/qmlvme.cpp22
24 files changed, 508 insertions, 591 deletions
diff --git a/src/declarative/qml/qml.pri b/src/declarative/qml/qml.pri
index 7f1c3f7..0b91ed3 100644
--- a/src/declarative/qml/qml.pri
+++ b/src/declarative/qml/qml.pri
@@ -26,6 +26,7 @@ SOURCES += qml/qmlparser.cpp \
qml/qmlerror.cpp \
qml/qmlscriptparser.cpp \
qml/qmlenginedebug.cpp \
+ qml/qmlrewrite.cpp \
qml/qmlbasicscript.cpp
HEADERS += qml/qmlparser_p.h \
@@ -67,6 +68,7 @@ HEADERS += qml/qmlparser_p.h \
qml/qmlscriptparser_p.h \
qml/qmlbasicscript_p.h \
qml/qmlenginedebug_p.h \
+ qml/qmlrewrite_p.h \
qml/qpodvector_p.h
# for qtscript debugger
diff --git a/src/declarative/qml/qmlbasicscript.cpp b/src/declarative/qml/qmlbasicscript.cpp
index 478491f..40ffffe 100644
--- a/src/declarative/qml/qmlbasicscript.cpp
+++ b/src/declarative/qml/qmlbasicscript.cpp
@@ -64,12 +64,7 @@ struct ScriptInstruction {
FetchD0Constant, // constant
FetchD1Constant, // constant
-
- Add, // NA
- Subtract, // NA
- Multiply, // NA
Equals, // NA
- And, // NA
Int, // integer
Bool, // boolean
@@ -181,6 +176,9 @@ static QVariant toObjectOrVariant(const QVariant &v)
static QVariant fetch_value(QObject *o, int idx, int type)
{
+ if (!o)
+ return QVariant();
+
switch(type) {
case QVariant::String:
{
@@ -291,7 +289,7 @@ struct QmlBasicScriptCompiler
QmlParser::Object *context;
QmlParser::Object *component;
- QHash<QString, QPair<QmlParser::Object *, int> > ids;
+ QHash<QString, QmlParser::Object *> ids;
bool compile(QmlJS::AST::Node *);
@@ -445,15 +443,6 @@ void QmlBasicScript::dump()
qWarning().nospace() << "FETCH\t\t" << instr.fetch.idx << "\t\t"
<< QByteArray(data + instr.fetch.idx);
break;
- case ScriptInstruction::Add:
- qWarning().nospace() << "ADD";
- break;
- case ScriptInstruction::Subtract:
- qWarning().nospace() << "SUBTRACT";
- break;
- case ScriptInstruction::Multiply:
- qWarning().nospace() << "MULTIPLY";
- break;
case ScriptInstruction::Equals:
qWarning().nospace() << "EQUALS";
break;
@@ -588,10 +577,10 @@ bool QmlBasicScriptCompiler::parseName(AST::Node *node,
if (ids.contains(name)) {
instr.type = ScriptInstruction::LoadIdObject;
- instr.fetch.idx = ids.value(name).second;
+ instr.fetch.idx = ids.value(name)->idIndex;
if (type)
- *type = ids.value(name).first;
+ *type = ids.value(name);
} else {
int d0Idx = context->metaObject()->indexOfProperty(name.toUtf8().constData());
@@ -679,11 +668,7 @@ bool QmlBasicScriptCompiler::tryBinaryExpression(AST::Node *node)
AST::BinaryExpression *expr =
static_cast<AST::BinaryExpression *>(node);
- if (expr->op == QSOperator::Add ||
- expr->op == QSOperator::Sub ||
- expr->op == QSOperator::Equal ||
- expr->op == QSOperator::And ||
- expr->op == QSOperator::Mul)
+ if (expr->op == QSOperator::Equal)
return true;
}
return false;
@@ -700,21 +685,9 @@ bool QmlBasicScriptCompiler::compileBinaryExpression(AST::Node *node)
ScriptInstruction instr;
switch (expr->op) {
- case QSOperator::Add:
- instr.type = ScriptInstruction::Add;
- break;
- case QSOperator::Sub:
- instr.type = ScriptInstruction::Subtract;
- break;
case QSOperator::Equal:
instr.type = ScriptInstruction::Equals;
break;
- case QSOperator::And:
- instr.type = ScriptInstruction::And;
- break;
- case QSOperator::Mul:
- instr.type = ScriptInstruction::Multiply;
- break;
default:
return false;
}
@@ -823,7 +796,7 @@ QVariant QmlBasicScript::run(QmlContext *context, void *voidCache, CacheState *c
QObject *obj = contextPrivate->defaultObjects.at(0);
stack.push(fetch_value(obj, instr.constant.idx, instr.constant.type));
- if (instr.constant.notify != 0)
+ if (obj && instr.constant.notify != 0)
enginePrivate->capturedProperties <<
QmlEnginePrivate::CapturedProperty(obj, instr.constant.idx, instr.constant.notify);
state = Reset;
@@ -835,7 +808,7 @@ QVariant QmlBasicScript::run(QmlContext *context, void *voidCache, CacheState *c
QObject *obj = contextPrivate->defaultObjects.at(1);
stack.push(fetch_value(obj, instr.constant.idx, instr.constant.type));
- if (instr.constant.notify != 0)
+ if (obj && instr.constant.notify != 0)
enginePrivate->capturedProperties <<
QmlEnginePrivate::CapturedProperty(obj, instr.constant.idx, instr.constant.notify);
state = Reset;
@@ -848,7 +821,7 @@ QVariant QmlBasicScript::run(QmlContext *context, void *voidCache, CacheState *c
QObject *obj = qvariant_cast<QObject *>(o);
stack.push(fetch_value(obj, instr.constant.idx, instr.constant.type));
- if (instr.constant.notify != 0)
+ if (obj && instr.constant.notify != 0)
enginePrivate->capturedProperties <<
QmlEnginePrivate::CapturedProperty(obj, instr.constant.idx, instr.constant.notify);
state = Reset;
@@ -913,30 +886,6 @@ QVariant QmlBasicScript::run(QmlContext *context, void *voidCache, CacheState *c
case ScriptInstruction::Bool:
stack.push(QVariant(instr.boolean.value));
break;
- case ScriptInstruction::Add:
- {
- QVariant rhs = stack.pop();
- QVariant lhs = stack.pop();
-
- stack.push(rhs.toDouble() + lhs.toDouble());
- }
- break;
- case ScriptInstruction::Subtract:
- {
- QVariant rhs = stack.pop();
- QVariant lhs = stack.pop();
-
- stack.push(lhs.toDouble() - rhs.toDouble());
- }
- break;
- case ScriptInstruction::Multiply:
- {
- QVariant rhs = stack.pop();
- QVariant lhs = stack.pop();
-
- stack.push(rhs.toDouble() * lhs.toDouble());
- }
- break;
case ScriptInstruction::Equals:
{
QVariant rhs = stack.pop();
@@ -945,14 +894,6 @@ QVariant QmlBasicScript::run(QmlContext *context, void *voidCache, CacheState *c
stack.push(rhs == lhs);
}
break;
- case ScriptInstruction::And:
- {
- QVariant rhs = stack.pop();
- QVariant lhs = stack.pop();
-
- stack.push(rhs.toBool() && lhs.toBool());
- }
- break;
default:
break;
}
diff --git a/src/declarative/qml/qmlbasicscript_p.h b/src/declarative/qml/qmlbasicscript_p.h
index 0c69397..77d59eb 100644
--- a/src/declarative/qml/qmlbasicscript_p.h
+++ b/src/declarative/qml/qmlbasicscript_p.h
@@ -85,7 +85,7 @@ public:
QmlParser::Object *context;
QmlParser::Property *property;
QmlParser::Variant expression;
- QHash<QString, QPair<QmlParser::Object *, int> > ids;
+ QHash<QString, QmlParser::Object *> ids;
};
bool compile(const Expression &);
diff --git a/src/declarative/qml/qmlcompileddata.cpp b/src/declarative/qml/qmlcompileddata.cpp
index 0834794..0563891 100644
--- a/src/declarative/qml/qmlcompileddata.cpp
+++ b/src/declarative/qml/qmlcompileddata.cpp
@@ -50,8 +50,6 @@
QT_BEGIN_NAMESPACE
-DEFINE_BOOL_CONFIG_OPTION(compilerDump, QML_COMPILER_DUMP);
-
int QmlCompiledData::pack(const char *data, size_t size)
{
const char *p = packData.constData();
@@ -193,9 +191,6 @@ const QMetaObject *QmlCompiledData::TypeReference::metaObject() const
void QmlCompiledData::dumpInstructions()
{
- if (!compilerDump())
- return;
-
if (!name.isEmpty())
qWarning() << name;
qWarning() << "Index\tLine\tOperation\t\tData1\tData2\t\tComments";
diff --git a/src/declarative/qml/qmlcompiler.cpp b/src/declarative/qml/qmlcompiler.cpp
index ed9df03..b0bc6e8 100644
--- a/src/declarative/qml/qmlcompiler.cpp
+++ b/src/declarative/qml/qmlcompiler.cpp
@@ -68,23 +68,43 @@
QT_BEGIN_NAMESPACE
+DEFINE_BOOL_CONFIG_OPTION(compilerDump, QML_COMPILER_DUMP);
+
using namespace QmlParser;
+/*!
+ Instantiate a new QmlCompiler.
+*/
QmlCompiler::QmlCompiler()
: output(0)
{
}
+/*!
+ Returns true if the last call to compile() caused errors.
+
+ \sa errors()
+*/
bool QmlCompiler::isError() const
{
return !exceptions.isEmpty();
}
+/*!
+ Return the list of errors from the last call to compile(), or an empty list
+ if there were no errors.
+*/
QList<QmlError> QmlCompiler::errors() const
{
return exceptions;
}
+/*!
+ Returns true if \a val is a legal object id, false otherwise.
+
+ Legal ids must start with a letter or underscore, and contain only
+ letters, numbers and underscores.
+*/
bool QmlCompiler::isValidId(const QString &val)
{
if (val.isEmpty())
@@ -122,27 +142,26 @@ bool QmlCompiler::isSignalPropertyName(const QByteArray &name)
'A' <= name.at(2) && 'Z' >= name.at(2);
}
-#define COMPILE_EXCEPTION2(token, desc) \
- { \
- QString exceptionDescription; \
- QmlError error; \
- error.setUrl(output->url); \
- error.setLine(token->location.start.line); \
- error.setColumn(token->location.start.column); \
- QDebug d(&exceptionDescription); \
- d << desc; \
- error.setDescription(exceptionDescription.trimmed()); \
- exceptions << error; \
- return false; \
- }
+/*!
+ Inserts an error into the QmlCompiler error list, and returns false
+ (failure).
-#define COMPILE_EXCEPTION(desc) \
+ \a token is used to source the error line and column, and \a desc is the
+ error itself. \a desc can be an expression that can be piped into QDebug.
+
+ For example:
+
+ \code
+ COMPILE_EXCEPTION(property, "Error for property" << property->name);
+ \endcode
+*/
+#define COMPILE_EXCEPTION(token, desc) \
{ \
QString exceptionDescription; \
QmlError error; \
error.setUrl(output->url); \
- error.setLine(obj->location.start.line); \
- error.setColumn(obj->location.start.column); \
+ error.setLine((token)->location.start.line); \
+ error.setColumn((token)->location.start.column); \
QDebug d(&exceptionDescription); \
d << desc; \
error.setDescription(exceptionDescription.trimmed()); \
@@ -150,19 +169,28 @@ bool QmlCompiler::isSignalPropertyName(const QByteArray &name)
return false; \
}
+/*!
+ Returns false if \a is false, otherwise does nothing.
+*/
#define COMPILE_CHECK(a) \
{ \
if (!a) return false; \
}
-// Compile a simple assignment of v to prop into instr
+/*!
+ Returns true if literal \a v can be assigned to property \a prop, otherwise
+ false.
+
+ This test corresponds to action taken by genLiteralAssignment(). Any change
+ made here, must have a corresponding action in genLiteralAssigment().
+*/
bool QmlCompiler::testLiteralAssignment(const QMetaProperty &prop,
QmlParser::Value *v)
{
QString string = v->value.asScript();
if (!prop.isWritable())
- COMPILE_EXCEPTION2(v, "Invalid property assignment: read-only property");
+ COMPILE_EXCEPTION(v, "Invalid property assignment: read-only property");
if (prop.isEnumType()) {
int value;
@@ -171,7 +199,7 @@ bool QmlCompiler::testLiteralAssignment(const QMetaProperty &prop,
} else
value = prop.enumerator().keyToValue(string.toLatin1().constData());
if (value == -1)
- COMPILE_EXCEPTION2(v, "Invalid property assignment: unknown enumeration");
+ COMPILE_EXCEPTION(v, "Invalid property assignment: unknown enumeration");
return true;
}
int type = prop.userType();
@@ -179,61 +207,61 @@ bool QmlCompiler::testLiteralAssignment(const QMetaProperty &prop,
case -1:
break;
case QVariant::String:
- if (!v->value.isString()) COMPILE_EXCEPTION2(v, "Invalid property assignment: string expected");
+ if (!v->value.isString()) COMPILE_EXCEPTION(v, "Invalid property assignment: string expected");
break;
case QVariant::Url:
- if (!v->value.isString()) COMPILE_EXCEPTION2(v, "Invalid property assignment: url expected");
+ if (!v->value.isString()) COMPILE_EXCEPTION(v, "Invalid property assignment: url expected");
break;
case QVariant::UInt:
{
bool ok;
string.toUInt(&ok);
- if (!v->value.isNumber() || !ok) COMPILE_EXCEPTION2(v, "Invalid property assignment: unsigned int expected");
+ if (!v->value.isNumber() || !ok) COMPILE_EXCEPTION(v, "Invalid property assignment: unsigned int expected");
}
break;
case QVariant::Int:
{
bool ok;
string.toInt(&ok);
- if (!v->value.isNumber() || !ok) COMPILE_EXCEPTION2(v, "Invalid property assignment: int expected");
+ if (!v->value.isNumber() || !ok) COMPILE_EXCEPTION(v, "Invalid property assignment: int expected");
}
break;
case QMetaType::Float:
{
bool ok;
string.toFloat(&ok);
- if (!v->value.isNumber() || !ok) COMPILE_EXCEPTION2(v, "Invalid property assignment: float expected");
+ if (!v->value.isNumber() || !ok) COMPILE_EXCEPTION(v, "Invalid property assignment: float expected");
}
break;
case QVariant::Double:
{
bool ok;
string.toDouble(&ok);
- if (!v->value.isNumber() || !ok) COMPILE_EXCEPTION2(v, "Invalid property assignment: double expected");
+ if (!v->value.isNumber() || !ok) COMPILE_EXCEPTION(v, "Invalid property assignment: double expected");
}
break;
case QVariant::Color:
{
QColor c = QmlStringConverters::colorFromString(string);
- if (!c.isValid()) COMPILE_EXCEPTION2(v, "Invalid property assignment: color expected");
+ if (!c.isValid()) COMPILE_EXCEPTION(v, "Invalid property assignment: color expected");
}
break;
case QVariant::Date:
{
QDate d = QDate::fromString(string, Qt::ISODate);
- if (!d.isValid()) COMPILE_EXCEPTION2(v, "Invalid property assignment: date expected");
+ if (!d.isValid()) COMPILE_EXCEPTION(v, "Invalid property assignment: date expected");
}
break;
case QVariant::Time:
{
QTime time = QTime::fromString(string, Qt::ISODate);
- if (!time.isValid()) COMPILE_EXCEPTION2(v, "Invalid property assignment: time expected");
+ if (!time.isValid()) COMPILE_EXCEPTION(v, "Invalid property assignment: time expected");
}
break;
case QVariant::DateTime:
{
QDateTime dateTime = QDateTime::fromString(string, Qt::ISODate);
- if (!dateTime.isValid()) COMPILE_EXCEPTION2(v, "Invalid property assignment: datetime expected");
+ if (!dateTime.isValid()) COMPILE_EXCEPTION(v, "Invalid property assignment: datetime expected");
}
break;
case QVariant::Point:
@@ -241,7 +269,7 @@ bool QmlCompiler::testLiteralAssignment(const QMetaProperty &prop,
{
bool ok;
QPointF point = QmlStringConverters::pointFFromString(string, &ok);
- if (!ok) COMPILE_EXCEPTION2(v, "Invalid property assignment: point expected");
+ if (!ok) COMPILE_EXCEPTION(v, "Invalid property assignment: point expected");
}
break;
case QVariant::Size:
@@ -249,7 +277,7 @@ bool QmlCompiler::testLiteralAssignment(const QMetaProperty &prop,
{
bool ok;
QSizeF size = QmlStringConverters::sizeFFromString(string, &ok);
- if (!ok) COMPILE_EXCEPTION2(v, "Invalid property assignment: size expected");
+ if (!ok) COMPILE_EXCEPTION(v, "Invalid property assignment: size expected");
}
break;
case QVariant::Rect:
@@ -257,12 +285,12 @@ bool QmlCompiler::testLiteralAssignment(const QMetaProperty &prop,
{
bool ok;
QRectF rect = QmlStringConverters::rectFFromString(string, &ok);
- if (!ok) COMPILE_EXCEPTION2(v, "Invalid property assignment: rect expected");
+ if (!ok) COMPILE_EXCEPTION(v, "Invalid property assignment: rect expected");
}
break;
case QVariant::Bool:
{
- if (!v->value.isBoolean()) COMPILE_EXCEPTION2(v, "Invalid property assignment: boolean expected");
+ if (!v->value.isBoolean()) COMPILE_EXCEPTION(v, "Invalid property assignment: boolean expected");
}
break;
default:
@@ -273,13 +301,19 @@ bool QmlCompiler::testLiteralAssignment(const QMetaProperty &prop,
QmlMetaType::StringConverter converter =
QmlMetaType::customStringConverter(t);
if (!converter)
- COMPILE_EXCEPTION2(v, "Invalid property assignment: unknown type" << prop.type());
+ COMPILE_EXCEPTION(v, "Invalid property assignment: unknown type" << prop.type());
}
break;
}
return true;
}
+/*!
+ Generate a store instruction for assigning literal \a v to property \a prop.
+
+ Any literal assignment that is approved in testLiteralAssignment() must have
+ a corresponding action in this method.
+*/
void QmlCompiler::genLiteralAssignment(const QMetaProperty &prop,
QmlParser::Value *v)
{
@@ -469,17 +503,31 @@ void QmlCompiler::genLiteralAssignment(const QMetaProperty &prop,
output->bytecode << instr;
}
-void QmlCompiler::reset(QmlCompiledData *cc)
+/*!
+ Resets data by clearing the lists that the QmlCompiler modifies.
+*/
+void QmlCompiler::reset(QmlCompiledData *data)
{
- cc->types.clear();
- cc->primitives.clear();
- cc->floatData.clear();
- cc->intData.clear();
- cc->customTypeData.clear();
- cc->datas.clear();
- cc->bytecode.clear();
+ data->types.clear();
+ data->primitives.clear();
+ data->floatData.clear();
+ data->intData.clear();
+ data->customTypeData.clear();
+ data->datas.clear();
+ data->bytecode.clear();
}
+/*!
+ Compile \a unit, and store the output in \a out. \a engine is the QmlEngine
+ with which the QmlCompiledData will be associated.
+
+ Returns true on success, false on failure. On failure, the compile errors
+ are available from errors().
+
+ If the environment variant QML_COMPILER_DUMP is set
+ (eg. QML_COMPILER_DUMP=1) the compiled instructions will be dumped to stderr
+ on a successful compiler.
+*/
bool QmlCompiler::compile(QmlEngine *engine,
QmlCompositeTypeData *unit,
QmlCompiledData *out)
@@ -526,11 +574,14 @@ bool QmlCompiler::compile(QmlEngine *engine,
compileTree(root);
if (!isError()) {
- out->dumpInstructions();
+ if (compilerDump())
+ out->dumpInstructions();
} else {
reset(out);
}
+ compileState = ComponentCompileState();
+ savedCompileStates.clear();
output = 0;
return !isError();
@@ -622,7 +673,7 @@ bool QmlCompiler::buildObject(Object *obj, const BindingContext &ctxt)
bool canDefer = false;
if (isCustomParser) {
- if (testProperty(prop, obj)) {
+ if (doesPropertyExist(prop, obj)) {
int ids = compileState.ids.count();
COMPILE_CHECK(buildProperty(prop, obj, objCtxt));
canDefer = ids == compileState.ids.count();
@@ -651,7 +702,7 @@ bool QmlCompiler::buildObject(Object *obj, const BindingContext &ctxt)
bool canDefer = false;
if (isCustomParser) {
- if (testProperty(prop, obj)) {
+ if (doesPropertyExist(prop, obj)) {
int ids = compileState.ids.count();
COMPILE_CHECK(buildProperty(prop, obj, objCtxt));
canDefer = ids == compileState.ids.count();
@@ -676,7 +727,7 @@ bool QmlCompiler::buildObject(Object *obj, const BindingContext &ctxt)
QmlCustomParser *cp = output->types.at(obj->type).type->customParser();
obj->custom = cp->compile(customProps, &ok);
if(!ok)
- COMPILE_EXCEPTION("Failure compiling custom type");
+ COMPILE_EXCEPTION(obj, "Failure compiling custom type");
}
return true;
@@ -876,36 +927,36 @@ bool QmlCompiler::buildComponent(QmlParser::Object *obj,
Property *idProp = 0;
if (obj->properties.count() > 1 ||
(obj->properties.count() == 1 && obj->properties.begin().key() != "id"))
- COMPILE_EXCEPTION("Invalid component specification");
+ COMPILE_EXCEPTION(obj, "Invalid component specification");
if (obj->properties.count())
idProp = *obj->properties.begin();
if (idProp && (idProp->value || idProp->values.count() > 1 || !isValidId(idProp->values.first()->primitive())))
- COMPILE_EXCEPTION("Invalid component id specification");
+ COMPILE_EXCEPTION(obj, "Invalid component id specification");
if (idProp) {
QString idVal = idProp->values.first()->primitive().toUtf8();
if (compileState.ids.contains(idVal))
- COMPILE_EXCEPTION("id is not unique");
+ COMPILE_EXCEPTION(obj, "id is not unique");
addId(idVal, obj);
- obj->id = idVal.toUtf8();
+ obj->id = idVal;
}
// Check the Component tree is well formed
if (obj->defaultProperty &&
(obj->defaultProperty->value || obj->defaultProperty->values.count() > 1 ||
(obj->defaultProperty->values.count() == 1 && !obj->defaultProperty->values.first()->object)))
- COMPILE_EXCEPTION("Invalid component body specification");
+ COMPILE_EXCEPTION(obj, "Invalid component body specification");
Object *root = 0;
if (obj->defaultProperty && obj->defaultProperty->values.count())
root = obj->defaultProperty->values.first()->object;
if (!root)
- COMPILE_EXCEPTION("Cannot create empty component specification");
+ COMPILE_EXCEPTION(obj, "Cannot create empty component specification");
// Build the component tree
COMPILE_CHECK(buildComponentFromRoot(root, ctxt));
@@ -989,7 +1040,7 @@ bool QmlCompiler::buildSignal(QmlParser::Property *prop, QmlParser::Object *obj,
Q_ASSERT(obj->metaObject());
if (prop->isEmpty())
- COMPILE_EXCEPTION2(prop, "Empty property assignment");
+ COMPILE_EXCEPTION(prop, "Empty property assignment");
QByteArray name = prop->name;
Q_ASSERT(name.startsWith("on"));
@@ -1008,7 +1059,7 @@ bool QmlCompiler::buildSignal(QmlParser::Property *prop, QmlParser::Object *obj,
} else {
if (prop->value || prop->values.count() > 1)
- COMPILE_EXCEPTION("Incorrectly specified signal");
+ COMPILE_EXCEPTION(prop, "Incorrectly specified signal");
prop->index = sigIdx;
obj->addSignalProperty(prop);
@@ -1025,9 +1076,11 @@ bool QmlCompiler::buildSignal(QmlParser::Property *prop, QmlParser::Object *obj,
}
-// Returns true if prop exists on obj, false otherwise
-bool QmlCompiler::testProperty(QmlParser::Property *prop,
- QmlParser::Object *obj)
+/*!
+ Returns true if (value) property \a prop exists on obj, false otherwise.
+*/
+bool QmlCompiler::doesPropertyExist(QmlParser::Property *prop,
+ QmlParser::Object *obj)
{
if(isAttachedPropertyName(prop->name) || prop->name == "id")
return true;
@@ -1051,7 +1104,7 @@ bool QmlCompiler::buildProperty(QmlParser::Property *prop,
const BindingContext &ctxt)
{
if (prop->isEmpty())
- COMPILE_EXCEPTION2(prop, "Empty property assignment");
+ COMPILE_EXCEPTION(prop, "Empty property assignment");
const QMetaObject *metaObject = obj->metaObject();
Q_ASSERT(metaObject);
@@ -1063,16 +1116,16 @@ bool QmlCompiler::buildProperty(QmlParser::Property *prop,
// Attached properties cannot be used on sub-objects. Sub-objects
// always exist in a binding sub-context, which is what we test
// for here.
- COMPILE_EXCEPTION2(prop, "Attached properties cannot be used here");
+ COMPILE_EXCEPTION(prop, "Attached properties cannot be used here");
}
QmlType *type = QmlMetaType::qmlType(prop->name);
if (!type || !type->attachedPropertiesType())
- COMPILE_EXCEPTION2(prop, "Non-existant attached object");
+ COMPILE_EXCEPTION(prop, "Non-existant attached object");
if (!prop->value)
- COMPILE_EXCEPTION2(prop, "Invalid attached object assignment");
+ COMPILE_EXCEPTION(prop, "Invalid attached object assignment");
prop->value->metatype = type->attachedPropertiesType();
} else {
@@ -1125,9 +1178,9 @@ bool QmlCompiler::buildProperty(QmlParser::Property *prop,
} else if (prop->index == -1) {
if (prop->isDefault) {
- COMPILE_EXCEPTION2(prop->values.first(), "Cannot assign to non-existant default property");
+ COMPILE_EXCEPTION(prop->values.first(), "Cannot assign to non-existant default property");
} else {
- COMPILE_EXCEPTION2(prop, "Cannot assign to non-existant property" << prop->name);
+ COMPILE_EXCEPTION(prop, "Cannot assign to non-existant property" << prop->name);
}
} else if (prop->value) {
@@ -1280,17 +1333,17 @@ bool QmlCompiler::buildIdProperty(QmlParser::Property *prop,
if (prop->value ||
prop->values.count() > 1 ||
prop->values.at(0)->object)
- COMPILE_EXCEPTION2(prop, "Invalid use of id property");
+ COMPILE_EXCEPTION(prop, "Invalid use of id property");
QString val = prop->values.at(0)->primitive();
if (!isValidId(val))
- COMPILE_EXCEPTION2(prop, val << "is not a valid object id");
+ COMPILE_EXCEPTION(prop, val << "is not a valid object id");
if (compileState.ids.contains(val))
- COMPILE_EXCEPTION2(prop, "id is not unique");
+ COMPILE_EXCEPTION(prop, "id is not unique");
- obj->id = val.toUtf8();
+ obj->id = val;
prop->values.at(0)->type = Value::Id;
@@ -1301,18 +1354,16 @@ bool QmlCompiler::buildIdProperty(QmlParser::Property *prop,
void QmlCompiler::addId(const QString &id, QmlParser::Object *obj)
{
- IdReference reference;
- reference.id = id;
- reference.object = obj;
- reference.idx = compileState.ids.count();
- compileState.ids.insert(id, reference);
+ Q_ASSERT(!compileState.ids.contains(id));
+ Q_ASSERT(obj->id == id);
+ obj->idIndex = compileState.ids.count();
+ compileState.ids.insert(id, obj);
}
void QmlCompiler::addBindingReference(const BindingReference &ref)
{
- int id = compileState.bindings.count();
- compileState.bindings << ref;
- compileState.bindingMap.insert(ref.value, id);
+ Q_ASSERT(ref.value && !compileState.bindings.contains(ref.value));
+ compileState.bindings.insert(ref.value, ref);
}
void QmlCompiler::saveComponentState()
@@ -1368,7 +1419,7 @@ bool QmlCompiler::buildGroupedProperty(QmlParser::Property *prop,
// Load the nested property's meta type
prop->value->metatype = QmlMetaType::metaObjectForType(prop->type);
if (!prop->value->metatype)
- COMPILE_EXCEPTION2(prop, "Cannot nest non-QObject property" << prop->name);
+ COMPILE_EXCEPTION(prop, "Cannot nest non-QObject property" << prop->name);
obj->addGroupedProperty(prop);
@@ -1408,12 +1459,12 @@ bool QmlCompiler::buildListProperty(QmlParser::Property *prop,
// at runtime.
if (!listTypeIsInterface) {
if (!canCoerce(listType, v->object)) {
- COMPILE_EXCEPTION("Cannot assign object to list");
+ COMPILE_EXCEPTION(v, "Cannot assign object to list");
}
}
} else {
- COMPILE_EXCEPTION("Cannot assign primitives to lists");
+ COMPILE_EXCEPTION(v, "Cannot assign primitives to lists");
}
}
@@ -1432,19 +1483,19 @@ bool QmlCompiler::buildListProperty(QmlParser::Property *prop,
// at runtime.
if (!listTypeIsInterface) {
if (!canCoerce(listType, v->object)) {
- COMPILE_EXCEPTION("Cannot assign object to list");
+ COMPILE_EXCEPTION(v, "Cannot assign object to list");
}
}
} else if (v->value.isScript()) {
if (assignedBinding)
- COMPILE_EXCEPTION("Can only assign one binding to lists");
+ COMPILE_EXCEPTION(v, "Can only assign one binding to lists");
assignedBinding = true;
COMPILE_CHECK(buildBinding(v, prop, ctxt));
v->type = Value::PropertyBinding;
} else {
- COMPILE_EXCEPTION("Cannot assign primitives to lists");
+ COMPILE_EXCEPTION(v, "Cannot assign primitives to lists");
}
}
@@ -1570,7 +1621,7 @@ bool QmlCompiler::buildPropertyObjectAssignment(QmlParser::Property *prop,
v->type = Value::ValueSource;
} else {
- COMPILE_EXCEPTION2(v->object, "Cannot assign object to property");
+ COMPILE_EXCEPTION(v->object, "Cannot assign object to property");
}
}
@@ -1615,12 +1666,12 @@ bool QmlCompiler::checkDynamicMeta(QmlParser::Object *obj)
if (prop.isDefaultProperty) {
if (seenDefaultProperty)
- COMPILE_EXCEPTION("Duplicate default property");
+ COMPILE_EXCEPTION(obj, "Duplicate default property");
seenDefaultProperty = true;
}
if (propNames.contains(prop.name))
- COMPILE_EXCEPTION("Duplicate property name");
+ COMPILE_EXCEPTION(obj, "Duplicate property name");
propNames.insert(prop.name);
}
@@ -1628,13 +1679,13 @@ bool QmlCompiler::checkDynamicMeta(QmlParser::Object *obj)
for (int ii = 0; ii < obj->dynamicSignals.count(); ++ii) {
QByteArray name = obj->dynamicSignals.at(ii).name;
if (methodNames.contains(name))
- COMPILE_EXCEPTION("Duplicate signal name");
+ COMPILE_EXCEPTION(obj, "Duplicate signal name");
methodNames.insert(name);
}
for (int ii = 0; ii < obj->dynamicSlots.count(); ++ii) {
QByteArray name = obj->dynamicSlots.at(ii).name;
if (methodNames.contains(name))
- COMPILE_EXCEPTION("Duplicate method name");
+ COMPILE_EXCEPTION(obj, "Duplicate method name");
methodNames.insert(name);
}
@@ -1656,7 +1707,7 @@ bool QmlCompiler::mergeDynamicMetaProperties(QmlParser::Object *obj)
property = obj->getProperty(p.name);
if (property->value)
- COMPILE_EXCEPTION2(property, "Invalid property nesting");
+ COMPILE_EXCEPTION(property, "Invalid property nesting");
for (int ii = 0; ii < p.defaultValue->values.count(); ++ii) {
Value *v = p.defaultValue->values.at(ii);
@@ -1687,6 +1738,14 @@ bool QmlCompiler::buildDynamicMeta(QmlParser::Object *obj, DynamicMetaMode mode)
for (int ii = 0; ii < obj->dynamicProperties.count(); ++ii) {
const Object::DynamicProperty &p = obj->dynamicProperties.at(ii);
+ int propIdx =
+ obj->metaObject()->indexOfProperty(p.name.constData());
+ if (-1 != propIdx) {
+ QMetaProperty prop = obj->metaObject()->property(propIdx);
+ if (prop.isFinal())
+ COMPILE_EXCEPTION(&p, "Cannot override FINAL property");
+ }
+
if (p.isDefaultProperty &&
(p.type != Object::DynamicProperty::Alias ||
mode == ResolveAliases))
@@ -1797,14 +1856,8 @@ bool QmlCompiler::buildDynamicMeta(QmlParser::Object *obj, DynamicMetaMode mode)
obj->metadata = builder.toRelocatableData();
builder.fromRelocatableData(&obj->extObject, obj->metatype, obj->metadata);
- // ### Remove me
- obj->extObjectData = &obj->extObject;
-
- if (mode == IgnoreAliases && hasAlias) {
- AliasReference alias;
- alias.object = obj;
- compileState.aliases << alias;
- }
+ if (mode == IgnoreAliases && hasAlias)
+ compileState.aliasingObjects << obj;
obj->synthdata = dynamicData;
@@ -1836,34 +1889,34 @@ bool QmlCompiler::compileAlias(QMetaObjectBuilder &builder,
const Object::DynamicProperty &prop)
{
if (!prop.defaultValue)
- COMPILE_EXCEPTION("No property alias location");
+ COMPILE_EXCEPTION(obj, "No property alias location");
if (prop.defaultValue->values.count() != 1 ||
prop.defaultValue->values.at(0)->object ||
!prop.defaultValue->values.at(0)->value.isScript())
- COMPILE_EXCEPTION2(prop.defaultValue, "Invalid alias location");
+ COMPILE_EXCEPTION(prop.defaultValue, "Invalid alias location");
QmlJS::AST::Node *node = prop.defaultValue->values.at(0)->value.asAST();
if (!node)
- COMPILE_EXCEPTION("No property alias location"); // ### Can this happen?
+ COMPILE_EXCEPTION(obj, "No property alias location"); // ### Can this happen?
QStringList alias = astNodeToStringList(node);
if (alias.count() != 2)
- COMPILE_EXCEPTION2(prop.defaultValue, "Invalid alias location");
+ COMPILE_EXCEPTION(prop.defaultValue, "Invalid alias location");
if (!compileState.ids.contains(alias.at(0)))
- COMPILE_EXCEPTION2(prop.defaultValue, "Invalid alias location");
+ COMPILE_EXCEPTION(prop.defaultValue, "Invalid alias location");
- const IdReference &id = compileState.ids[alias.at(0)];
- int propIdx = id.object->metaObject()->indexOfProperty(alias.at(1).toUtf8().constData());
+ Object *idObject = compileState.ids[alias.at(0)];
+ int propIdx = idObject->metaObject()->indexOfProperty(alias.at(1).toUtf8().constData());
if (-1 == propIdx)
- COMPILE_EXCEPTION2(prop.defaultValue, "Invalid alias location");
+ COMPILE_EXCEPTION(prop.defaultValue, "Invalid alias location");
- QMetaProperty aliasProperty = id.object->metaObject()->property(propIdx);
+ QMetaProperty aliasProperty = idObject->metaObject()->property(propIdx);
- data.append((const char *)&id.idx, sizeof(id.idx));
+ data.append((const char *)&idObject->idIndex, sizeof(idObject->idIndex));
data.append((const char *)&propIdx, sizeof(propIdx));
builder.addSignal(prop.name + "Changed()");
@@ -1881,13 +1934,12 @@ bool QmlCompiler::buildBinding(QmlParser::Value *value,
QMetaProperty mp = prop->parent->metaObject()->property(prop->index);
if (!mp.isWritable() && !QmlMetaType::isList(prop->type))
- COMPILE_EXCEPTION2(prop, "Invalid property assignment: read-only property");
+ COMPILE_EXCEPTION(prop, "Invalid property assignment: read-only property");
BindingReference reference;
reference.expression = value->value;
reference.property = prop;
reference.value = value;
- reference.instructionIdx = output->bytecode.count();
reference.bindingContext = ctxt;
addBindingReference(reference);
@@ -1898,10 +1950,9 @@ void QmlCompiler::genBindingAssignment(QmlParser::Value *binding,
QmlParser::Property *prop,
QmlParser::Object *obj)
{
- Q_ASSERT(compileState.bindingMap.contains(binding));
+ Q_ASSERT(compileState.bindings.contains(binding));
- const BindingReference &ref =
- compileState.bindings.at(compileState.bindingMap.value(binding));
+ const BindingReference &ref = compileState.bindings.value(binding);
QMetaProperty mp = obj->metaObject()->property(prop->index);
@@ -1927,21 +1978,17 @@ bool QmlCompiler::completeComponentBuild()
{
saveComponentState();
- for (int ii = 0; ii < compileState.aliases.count(); ++ii) {
- const AliasReference &alias = compileState.aliases.at(ii);
- COMPILE_CHECK(buildDynamicMeta(alias.object, ResolveAliases));
+ for (int ii = 0; ii < compileState.aliasingObjects.count(); ++ii) {
+ Object *aliasObject = compileState.aliasingObjects.at(ii);
+ COMPILE_CHECK(buildDynamicMeta(aliasObject, ResolveAliases));
}
-
QmlBasicScript::Expression expr;
expr.component = compileState.root;
- foreach (const IdReference &id, compileState.ids) {
- expr.ids.insert(id.id, qMakePair(id.object, id.idx));
- }
-
- for (int ii = 0; ii < compileState.bindings.count(); ++ii) {
- BindingReference &binding = compileState.bindings[ii];
+ expr.ids = compileState.ids;
+ for (QHash<QmlParser::Value*,BindingReference>::Iterator iter = compileState.bindings.begin(); iter != compileState.bindings.end(); ++iter) {
+ BindingReference &binding = *iter;
QmlBasicScript bs;
expr.context = binding.bindingContext.object;
diff --git a/src/declarative/qml/qmlcompiler_p.h b/src/declarative/qml/qmlcompiler_p.h
index e09665f..86e6590 100644
--- a/src/declarative/qml/qmlcompiler_p.h
+++ b/src/declarative/qml/qmlcompiler_p.h
@@ -137,7 +137,7 @@ public:
static bool isSignalPropertyName(const QByteArray &);
private:
- void reset(QmlCompiledData *);
+ static void reset(QmlCompiledData *);
struct BindingContext {
BindingContext()
@@ -185,7 +185,7 @@ private:
QmlParser::Object *obj,
QmlParser::Value *value,
const BindingContext &ctxt);
- bool testProperty(QmlParser::Property *prop, QmlParser::Object *obj);
+ bool doesPropertyExist(QmlParser::Property *prop, QmlParser::Object *obj);
bool testLiteralAssignment(const QMetaProperty &prop,
QmlParser::Value *value);
enum DynamicMetaMode { IgnoreAliases, ResolveAliases };
@@ -224,25 +224,13 @@ private:
QStringList deferredProperties(QmlParser::Object *);
- struct IdReference {
- QString id;
- QmlParser::Object *object;
- int instructionIdx;
- int idx;
- };
void addId(const QString &, QmlParser::Object *);
- struct AliasReference {
- QmlParser::Object *object;
- int instructionIdx;
- };
-
struct BindingReference {
QmlParser::Variant expression;
QmlParser::Property *property;
QmlParser::Value *value;
QByteArray compiledData;
- int instructionIdx;
BindingContext bindingContext;
};
void addBindingReference(const BindingReference &);
@@ -252,13 +240,13 @@ private:
ComponentCompileState()
: parserStatusCount(0), savedObjects(0),
pushedProperties(0), root(0) {}
- QHash<QString, IdReference> ids;
+ QHash<QString, QmlParser::Object *> ids;
int parserStatusCount;
int savedObjects;
int pushedProperties;
- QList<BindingReference> bindings;
- QHash<QmlParser::Value *, int> bindingMap;
- QList<AliasReference> aliases;
+
+ QHash<QmlParser::Value *, BindingReference> bindings;
+ QList<QmlParser::Object *> aliasingObjects;
QmlParser::Object *root;
};
ComponentCompileState compileState;
diff --git a/src/declarative/qml/qmlcomponent.cpp b/src/declarative/qml/qmlcomponent.cpp
index 0e68f8a..c7d45fd 100644
--- a/src/declarative/qml/qmlcomponent.cpp
+++ b/src/declarative/qml/qmlcomponent.cpp
@@ -405,9 +405,10 @@ QString QmlComponent::errorsString() const
QString ret;
if(!isError())
return ret;
- foreach(const QmlError &e, d->errors){
- ret += e.url().toString() + ":" + QString::number(e.line()) + " "
- + e.description() + "\n";
+ foreach(const QmlError &e, d->errors) {
+ ret += e.url().toString() + QLatin1String(":") +
+ QString::number(e.line()) + QLatin1String(" ") +
+ e.description() + QLatin1String("\n");
}
return ret;
}
@@ -532,7 +533,6 @@ QObject *QmlComponent::beginCreate(QmlContext *context)
static_cast<QmlContextPrivate*>(ctxt->d_ptr)->startLine = d->cc->bytecode.at(d->start - 1).line;
static_cast<QmlContextPrivate*>(ctxt->d_ptr)->endLine = d->cc->bytecode.at(d->start - 1).createComponent.endLine;
}
- ctxt->activate();
QmlVME vme;
QObject *rv = vme.run(ctxt, d->cc, d->start, d->count);
@@ -540,8 +540,6 @@ QObject *QmlComponent::beginCreate(QmlContext *context)
if (vme.isError())
d->errors = vme.errors();
- ctxt->deactivate();
-
QmlEnginePrivate *ep = d->engine->d_func();
if (ep->rootComponent == this) {
ep->rootComponent = 0;
diff --git a/src/declarative/qml/qmlcontext.cpp b/src/declarative/qml/qmlcontext.cpp
index b605869..5bc70bc 100644
--- a/src/declarative/qml/qmlcontext.cpp
+++ b/src/declarative/qml/qmlcontext.cpp
@@ -86,8 +86,15 @@ void QmlContextPrivate::destroyed(QObject *obj)
}
}
- for (int ii = 0; ii < notifies.count(); ++ii) {
- QMetaObject::activate(q, notifies[ii] + notifyIndex, 0);
+ // There is no need to emit these notifications if our parent is in the
+ // process of being deleted (which is *probably* why obj has been destroyed
+ // anyway), as we're about to get deleted which will invalidate all the
+ // expressions that could depend on us
+ QObject *parent = q->parent();
+ if (!parent || !QObjectPrivate::get(parent)->wasDeleted) {
+ for (int ii = 0; ii < notifies.count(); ++ii) {
+ QMetaObject::activate(q, notifies[ii] + notifyIndex, 0);
+ }
}
}
@@ -398,56 +405,6 @@ void QmlContext::setContextProperty(const QString &name, QObject *value)
}
/*!
- Activate this bind context.
-
- \sa QmlEngine::activeContext() QmlContext::activeContext()
-*/
-void QmlContext::activate()
-{
- QmlEnginePrivate *ep = engine()->d_func();
- ep->activeContexts.push(this);
- ep->setCurrentBindContext(this);
- ep->contextActivated(this);
-}
-
-/*!
- Deactivate this bind context. The previously active bind context will
- become active, or, if there was no previously active bind context, no
- context will be active.
-
- \sa QmlEngine::activeContext() QmlContext::activeContext()
-*/
-void QmlContext::deactivate()
-{
- QmlEnginePrivate *ep = engine()->d_func();
- Q_ASSERT(ep->activeContexts.top() == this);
- ep->activeContexts.pop();
- if (ep->activeContexts.isEmpty())
- ep->setCurrentBindContext(0);
- else
- ep->setCurrentBindContext(ep->activeContexts.top());
- ep->contextDeactivated(this);
-}
-
-/*!
- Returns the currently active context, or 0 if no context is active.
-
- This method is thread-safe. The active context is maintained individually
- for each thread. This method is equivalent to
- \code
- QmlEngine::activeEngine()->activeContext()
- \endcode
-*/
-QmlContext *QmlContext::activeContext()
-{
- QmlEngine *engine = QmlEngine::activeEngine();
- if (engine)
- return engine->activeContext();
- else
- return 0;
-}
-
-/*!
Resolves the URL \a src relative to the URL of the
containing component. If \a src is absolute, it is
simply returned. If there is no containing component,
diff --git a/src/declarative/qml/qmlcontext.h b/src/declarative/qml/qmlcontext.h
index 77f6634..877ff0f 100644
--- a/src/declarative/qml/qmlcontext.h
+++ b/src/declarative/qml/qmlcontext.h
@@ -73,11 +73,6 @@ public:
void setContextProperty(const QString &, QObject *);
void setContextProperty(const QString &, const QVariant &);
- void activate();
- void deactivate();
-
- static QmlContext *activeContext();
-
QUrl resolvedUrl(const QUrl &);
void setBaseUrl(const QUrl &);
diff --git a/src/declarative/qml/qmldom.cpp b/src/declarative/qml/qmldom.cpp
index e3cb563..293ea6a 100644
--- a/src/declarative/qml/qmldom.cpp
+++ b/src/declarative/qml/qmldom.cpp
@@ -587,7 +587,7 @@ QmlDomProperty QmlDomDynamicProperty::defaultValue() const
int QmlDomDynamicProperty::position() const
{
if (isValid()) {
- return d->property.range.offset;
+ return d->property.location.range.offset;
} else
return -1;
}
@@ -599,7 +599,7 @@ int QmlDomDynamicProperty::position() const
int QmlDomDynamicProperty::length() const
{
if (isValid())
- return d->property.range.length;
+ return d->property.location.range.length;
else
return -1;
}
@@ -769,7 +769,7 @@ QByteArray QmlDomObject::objectType() const
Text { id: MyText }
\endqml
*/
-QByteArray QmlDomObject::objectId() const
+QString QmlDomObject::objectId() const
{
if (d->object) return d->object->id;
else return QByteArray();
diff --git a/src/declarative/qml/qmldom.h b/src/declarative/qml/qmldom.h
index 456202a..339570b 100644
--- a/src/declarative/qml/qmldom.h
+++ b/src/declarative/qml/qmldom.h
@@ -150,7 +150,7 @@ public:
bool isValid() const;
QByteArray objectType() const;
- QByteArray objectId() const;
+ QString objectId() const;
void setObjectId(const QByteArray &);
diff --git a/src/declarative/qml/qmlengine.cpp b/src/declarative/qml/qmlengine.cpp
index 5adc2c3..a6f5b28 100644
--- a/src/declarative/qml/qmlengine.cpp
+++ b/src/declarative/qml/qmlengine.cpp
@@ -92,49 +92,6 @@ struct StaticQtMetaObject : public QObject
{ return &static_cast<StaticQtMetaObject*> (0)->staticQtMetaObject; }
};
-
-struct QmlEngineStack {
- QmlEngineStack();
-
- QStack<QmlEngine *> mainThreadEngines;
- QThread *mainThread;
-
- QThreadStorage<QStack<QmlEngine *> *> storage;
-
- QStack<QmlEngine *> *engines();
-};
-
-Q_GLOBAL_STATIC(QmlEngineStack, engineStack);
-
-QmlEngineStack::QmlEngineStack()
-: mainThread(0)
-{
-}
-
-QStack<QmlEngine *> *QmlEngineStack::engines()
-{
- if (mainThread== 0) {
- if (!QCoreApplication::instance())
- return 0;
- mainThread = QCoreApplication::instance()->thread();
- }
-
- // Note: This is very slightly faster than just using the thread storage
- // for everything.
- QStack<QmlEngine *> *engines = 0;
- if (QThread::currentThread() == mainThread) {
- engines = &mainThreadEngines;
- } else {
- engines = storage.localData();
- if (!engines) {
- engines = new QStack<QmlEngine *>;
- storage.setLocalData(engines);
- }
- }
- return engines;
-}
-
-
QmlEnginePrivate::QmlEnginePrivate(QmlEngine *e)
: rootContext(0), currentBindContext(0), currentExpression(0), q(e),
isDebugging(false), rootComponent(0), networkAccessManager(0), typeManager(e),
@@ -297,30 +254,6 @@ QScriptValue QmlEnginePrivate::propertyObject(const QScriptString &propName,
return QScriptValue();
}
-void QmlEnginePrivate::contextActivated(QmlContext *)
-{
- Q_Q(QmlEngine);
- QmlEngineStack *stack = engineStack();
- if (!stack)
- return;
- QStack<QmlEngine *> *engines = stack->engines();
- if (engines)
- engines->push(q);
-}
-
-void QmlEnginePrivate::contextDeactivated(QmlContext *)
-{
- QmlEngineStack *stack = engineStack();
- if (!stack)
- return;
- QStack<QmlEngine *> *engines = stack->engines();
- if (engines) {
- Q_ASSERT(engines->top() == q_func());
- engines->pop();
- }
-}
-
-
////////////////////////////////////////////////////////////////////
bool QmlEnginePrivate::fetchCache(QmlBasicScriptNodeCache &cache, const QString &propName, QObject *obj)
@@ -471,40 +404,12 @@ QmlContext *QmlEngine::rootContext()
}
/*!
- Returns this engine's active context, or 0 if no context is active on this
- engine.
-
- Contexts are activated and deactivated by calling QmlContext::activate() and
- QmlContext::deactivate() respectively.
-
- Context activation holds no special semantic, other than it allows types
- instantiated by QML to access "their" context without having it passed as
- a parameter in their constructor, as shown below.
- \code
- class MyClass : ... {
- ...
- MyClass() {
- qWarning() << "I was instantiated in this context:"
- << QmlContext::activeContext();
- }
- };
- \endcode
-*/
-QmlContext *QmlEngine::activeContext()
-{
- Q_D(QmlEngine);
- if (d->currentBindContext)
- return d->currentBindContext;
- else
- return 0;
-}
-
-/*!
- Sets the common QNetworkAccessManager, \a network, used by all QML elements instantiated
- by this engine.
+ Sets the common QNetworkAccessManager, \a network, used by all QML elements
+ instantiated by this engine.
- Any previously set manager is deleted and \a network is owned by the QmlEngine. This
- method should only be called before any QmlComponents are instantiated.
+ Any previously set manager is deleted and \a network is owned by the
+ QmlEngine. This method should only be called before any QmlComponents are
+ instantiated.
*/
void QmlEngine::setNetworkAccessManager(QNetworkAccessManager *network)
{
@@ -671,30 +576,6 @@ QScriptEngine *QmlEngine::scriptEngine()
}
/*!
- Returns the currently active QmlEngine.
-
- The active engine is the engine associated with the last activated
- QmlContext. This method is thread-safe - the "active" engine is maintained
- independently for each thread.
-*/
-QmlEngine *QmlEngine::activeEngine()
-{
- QmlEngineStack *stack = engineStack();
- if (!stack) return 0;
-
- QStack<QmlEngine *> *engines = stack->engines();
- if (!engines) {
- qWarning("QmlEngine::activeEngine() cannot be called before the construction of QCoreApplication");
- return 0;
- }
-
- if (engines->isEmpty())
- return 0;
- else
- return engines->top();
-}
-
-/*!
Creates a QScriptValue allowing you to use \a object in QML script.
\a engine is the QmlEngine it is to be created in.
@@ -779,7 +660,6 @@ QScriptValue QmlEngine::createComponent(QScriptContext *ctxt, QScriptEngine *eng
QUrl url = QUrl(activeEngine->d_func()->currentExpression->context()
->resolvedUrl(ctxt->argument(0).toString()));
if(!url.isValid()){
- qDebug() << "Error A:" << url << activeEngine->activeContext() << QmlEngine::activeEngine() << activeEngine;
url = QUrl(ctxt->argument(0).toString());
}
c = new QmlComponent(activeEngine, url, activeEngine);
diff --git a/src/declarative/qml/qmlengine.h b/src/declarative/qml/qmlengine.h
index 3e402d8..98deba7 100644
--- a/src/declarative/qml/qmlengine.h
+++ b/src/declarative/qml/qmlengine.h
@@ -70,10 +70,7 @@ public:
QmlEngine(QObject *p = 0);
virtual ~QmlEngine();
- static QmlEngine *activeEngine();
-
QmlContext *rootContext();
- QmlContext *activeContext();
void clearComponentCache();
diff --git a/src/declarative/qml/qmlengine_p.h b/src/declarative/qml/qmlengine_p.h
index e0824cc..f459dc5 100644
--- a/src/declarative/qml/qmlengine_p.h
+++ b/src/declarative/qml/qmlengine_p.h
@@ -93,9 +93,6 @@ public:
void init();
- void contextActivated(QmlContext *);
- void contextDeactivated(QmlContext *);
-
bool fetchCache(QmlBasicScriptNodeCache &cache, const QString &propName, QObject *);
bool loadCache(QmlBasicScriptNodeCache &cache, const QString &propName, QmlContextPrivate *context);
diff --git a/src/declarative/qml/qmlerror.cpp b/src/declarative/qml/qmlerror.cpp
index 149e173..5ee9144 100644
--- a/src/declarative/qml/qmlerror.cpp
+++ b/src/declarative/qml/qmlerror.cpp
@@ -168,6 +168,21 @@ void QmlError::setColumn(int column)
}
/*!
+ Return the error as a human readable string.
+*/
+QString QmlError::toString() const
+{
+ QString rv;
+ rv = url().toString() + QLatin1String(":") + QString::number(line());
+ if(column() != -1)
+ rv += QLatin1String(":") + QString::number(column());
+
+ rv += QLatin1String(": ") + description();
+
+ return rv;
+}
+
+/*!
\relates QmlError
\fn QDebug operator<<(QDebug debug, const QmlError &error)
@@ -176,19 +191,9 @@ void QmlError::setColumn(int column)
QDebug operator<<(QDebug debug, const QmlError &error)
{
- QUrl url = error.url();
-
- QString output;
-
- output = url.toString() + QLatin1String(":") +
- QString::number(error.line());
+ debug << qPrintable(error.toString());
- if(error.column() != -1)
- output += QLatin1String(":") + QString::number(error.column());
-
- output += QLatin1String(": ") + error.description();
-
- debug << qPrintable(output);
+ QUrl url = error.url();
if (error.line() > 0 && url.scheme() == QLatin1String("file")) {
QString file = url.toLocalFile();
diff --git a/src/declarative/qml/qmlerror.h b/src/declarative/qml/qmlerror.h
index 57d2f8f..c1a8720 100644
--- a/src/declarative/qml/qmlerror.h
+++ b/src/declarative/qml/qmlerror.h
@@ -69,6 +69,8 @@ public:
void setLine(int);
int column() const;
void setColumn(int);
+
+ QString toString() const;
private:
QmlErrorPrivate *d;
};
diff --git a/src/declarative/qml/qmlexpression.cpp b/src/declarative/qml/qmlexpression.cpp
index 4fe7d0c..2aa1a8a 100644
--- a/src/declarative/qml/qmlexpression.cpp
+++ b/src/declarative/qml/qmlexpression.cpp
@@ -43,10 +43,7 @@
#include "qmlexpression_p.h"
#include "qmlengine_p.h"
#include "qmlcontext_p.h"
-#include "rewriter/textwriter_p.h"
-#include "parser/qmljslexer_p.h"
-#include "parser/qmljsparser_p.h"
-#include "parser/qmljsnodepool_p.h"
+#include "qmlrewrite_p.h"
#include "QtCore/qdebug.h"
Q_DECLARE_METATYPE(QList<QObject *>);
@@ -55,97 +52,6 @@ QT_BEGIN_NAMESPACE
DEFINE_BOOL_CONFIG_OPTION(qmlDebugger, QML_DEBUGGER)
-namespace {
-
-using namespace QmlJS;
-
-class RewriteBinding: protected AST::Visitor
-{
- unsigned _position;
- TextWriter *_writer;
-
-public:
- QString operator()(const QString &code)
- {
- Engine engine;
- NodePool pool(QString(), &engine);
- Lexer lexer(&engine);
- Parser parser(&engine);
- lexer.setCode(code, 0);
- parser.parseStatement();
- return rewrite(code, 0, parser.statement());
- }
-
-protected:
- using AST::Visitor::visit;
-
- void accept(AST::Node *node)
- {
- AST::Node::acceptChild(node, this);
- }
-
- QString rewrite(QString code, unsigned position, AST::Statement *node)
- {
- TextWriter w;
- _writer = &w;
- _position = position;
-
- accept(node);
-
- unsigned startOfStatement = node->firstSourceLocation().begin() - _position;
- unsigned endOfStatement = node->lastSourceLocation().end() - _position;
-
- _writer->replace(startOfStatement, 0, QLatin1String("function() {\n"));
- _writer->replace(endOfStatement, 0, QLatin1String("\n}"));
-
- w.write(&code);
-
- return code;
- }
-
- virtual bool visit(AST::Block *ast)
- {
- for (AST::StatementList *it = ast->statements; it; it = it->next) {
- if (! it->next) {
- // we need to rewrite only the last statement of a block.
- accept(it->statement);
- }
- }
-
- return false;
- }
-
- virtual bool visit(AST::ExpressionStatement *ast)
- {
- unsigned startOfExpressionStatement = ast->firstSourceLocation().begin() - _position;
- _writer->replace(startOfExpressionStatement, 0, QLatin1String("return "));
-
- return false;
- }
-
- virtual bool visit(AST::NumericLiteral *node)
- {
- if (node->suffix != AST::NumericLiteral::noSuffix) {
- const int suffixLength = AST::NumericLiteral::suffixLength[node->suffix];
- const char *suffixSpell = AST::NumericLiteral::suffixSpell[node->suffix];
- QString pre;
- pre += QLatin1String("qmlNumberFrom");
- pre += QChar(QLatin1Char(suffixSpell[0])).toUpper();
- pre += QLatin1String(&suffixSpell[1]);
- pre += QLatin1Char('(');
- _writer->replace(node->literalToken.begin() - _position, 0, pre);
- _writer->replace(node->literalToken.end() - _position - suffixLength,
- suffixLength,
- QLatin1String(")"));
- }
-
- return false;
- }
-};
-
-} // end of anonymous namespace
-
-
QmlExpressionPrivate::QmlExpressionPrivate(QmlExpression *b)
: q(b), ctxt(0), expressionFunctionValid(false), sseData(0), proxy(0), me(0), trackChange(false), line(-1), id(0), log(0)
{
@@ -332,7 +238,7 @@ QVariant QmlExpressionPrivate::evalQtScript()
scriptEngine->currentContext()->pushScope(ctxtPriv->scopeChain.at(i));
if (!expressionFunctionValid) {
- RewriteBinding rewriteBinding;
+ QmlRewrite::RewriteBinding rewriteBinding;
const QString code = rewriteBinding(expression);
expressionFunction = scriptEngine->evaluate(code, fileName.toString(), line);
diff --git a/src/declarative/qml/qmlmetaproperty.cpp b/src/declarative/qml/qmlmetaproperty.cpp
index 6602021..dea3467 100644
--- a/src/declarative/qml/qmlmetaproperty.cpp
+++ b/src/declarative/qml/qmlmetaproperty.cpp
@@ -643,8 +643,7 @@ void QmlMetaPropertyPrivate::writeSignalProperty(const QVariant &value)
if (!expr.isEmpty()) {
// XXX scope
- (void *)new QmlBoundSignal(QmlContext::activeContext(), expr, object,
- coreIdx, object);
+ (void *)new QmlBoundSignal(qmlContext(object), expr, object, coreIdx, object);
}
}
diff --git a/src/declarative/qml/qmlparser.cpp b/src/declarative/qml/qmlparser.cpp
index 8ee3b4e..8eb58c8 100644
--- a/src/declarative/qml/qmlparser.cpp
+++ b/src/declarative/qml/qmlparser.cpp
@@ -62,8 +62,7 @@ QT_BEGIN_NAMESPACE
using namespace QmlParser;
QmlParser::Object::Object()
-: type(-1), metatype(0), extObjectData(0), defaultProperty(0),
- parserStatusCast(-1)
+: type(-1), idIndex(-1), metatype(0), defaultProperty(0), parserStatusCast(-1)
{
}
@@ -84,7 +83,7 @@ QmlParser::Object::~Object()
const QMetaObject *Object::metaObject() const
{
- if (extObjectData && metatype)
+ if (!metadata.isEmpty() && metatype)
return &extObject;
else
return metatype;
@@ -147,7 +146,7 @@ QmlParser::Object::DynamicProperty::DynamicProperty(const DynamicProperty &o)
type(o.type),
name(o.name),
defaultValue(o.defaultValue),
- range(o.range)
+ location(o.location)
{
}
diff --git a/src/declarative/qml/qmlparser_p.h b/src/declarative/qml/qmlparser_p.h
index d96a43e..d23b4ea 100644
--- a/src/declarative/qml/qmlparser_p.h
+++ b/src/declarative/qml/qmlparser_p.h
@@ -117,8 +117,10 @@ namespace QmlParser
QUrl url;
// The name of this type
QByteArray typeName;
- // The id assigned to the object (if any).
- QByteArray id;
+ // The id assigned to the object (if any). Set by the QmlCompiler
+ QString id;
+ // The id index assigned to the object (if any). Set by the QmlCompiler
+ int idIndex;
// Custom parsed data
QByteArray custom;
// Returns the metaobject for this type, or 0 if not available.
@@ -129,7 +131,6 @@ namespace QmlParser
const QMetaObject *metatype;
// The synthesized metaobject, if QML added signals or properties to
// this type. Otherwise null
- QMetaObject *extObjectData;
QAbstractDynamicMetaObject extObject;
QByteArray metadata; // Generated by compiler
QByteArray synthdata; // Generated by compiler
@@ -168,7 +169,7 @@ namespace QmlParser
Type type;
QByteArray name;
QmlParser::Property *defaultValue;
- LocationRange range;
+ LocationSpan location;
};
struct DynamicSignal {
DynamicSignal();
diff --git a/src/declarative/qml/qmlrewrite.cpp b/src/declarative/qml/qmlrewrite.cpp
new file mode 100644
index 0000000..02bf8fa
--- /dev/null
+++ b/src/declarative/qml/qmlrewrite.cpp
@@ -0,0 +1,157 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtDeclarative module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qmlrewrite_p.h"
+
+QT_BEGIN_NAMESPACE
+
+namespace QmlRewrite {
+
+QString RewriteBinding::operator()(const QString &code)
+{
+ Engine engine;
+ NodePool pool(QString(), &engine);
+ Lexer lexer(&engine);
+ Parser parser(&engine);
+ lexer.setCode(code, 0);
+ parser.parseStatement();
+ return rewrite(code, 0, parser.statement());
+}
+
+void RewriteBinding::accept(AST::Node *node)
+{
+ AST::Node::acceptChild(node, this);
+}
+
+QString RewriteBinding::rewrite(QString code, unsigned position,
+ AST::Statement *node)
+{
+ TextWriter w;
+ _writer = &w;
+ _position = position;
+
+ accept(node);
+
+ unsigned startOfStatement = node->firstSourceLocation().begin() - _position;
+ unsigned endOfStatement = node->lastSourceLocation().end() - _position;
+
+ _writer->replace(startOfStatement, 0, QLatin1String("function() {\n"));
+ _writer->replace(endOfStatement, 0, QLatin1String("\n}"));
+
+ w.write(&code);
+
+ return code;
+}
+
+bool RewriteBinding::visit(AST::Block *ast)
+{
+ for (AST::StatementList *it = ast->statements; it; it = it->next) {
+ if (! it->next) {
+ // we need to rewrite only the last statement of a block.
+ accept(it->statement);
+ }
+ }
+
+ return false;
+}
+
+bool RewriteBinding::visit(AST::ExpressionStatement *ast)
+{
+ unsigned startOfExpressionStatement = ast->firstSourceLocation().begin() - _position;
+ _writer->replace(startOfExpressionStatement, 0, QLatin1String("return "));
+
+ return false;
+}
+
+bool RewriteBinding::visit(AST::NumericLiteral *node)
+{
+ if (node->suffix != AST::NumericLiteral::noSuffix) {
+ const int suffixLength = AST::NumericLiteral::suffixLength[node->suffix];
+ const char *suffixSpell = AST::NumericLiteral::suffixSpell[node->suffix];
+ QString pre;
+ pre += QLatin1String("qmlNumberFrom");
+ pre += QChar(QLatin1Char(suffixSpell[0])).toUpper();
+ pre += QLatin1String(&suffixSpell[1]);
+ pre += QLatin1Char('(');
+ _writer->replace(node->literalToken.begin() - _position, 0, pre);
+ _writer->replace(node->literalToken.end() - _position - suffixLength,
+ suffixLength,
+ QLatin1String(")"));
+ }
+
+ return false;
+}
+
+QString RewriteNumericLiterals::operator()(QString code, unsigned position, AST::Node *node)
+{
+ TextWriter w;
+ _writer = &w;
+ _position = position;
+
+ AST::Node::acceptChild(node, this);
+
+ w.write(&code);
+
+ return code;
+}
+
+bool RewriteNumericLiterals::visit(AST::NumericLiteral *node)
+{
+ if (node->suffix != AST::NumericLiteral::noSuffix) {
+ const int suffixLength = AST::NumericLiteral::suffixLength[node->suffix];
+ const char *suffixSpell = AST::NumericLiteral::suffixSpell[node->suffix];
+ QString pre;
+ pre += QLatin1String("qmlNumberFrom");
+ pre += QChar(QLatin1Char(suffixSpell[0])).toUpper();
+ pre += QLatin1String(&suffixSpell[1]);
+ pre += QLatin1Char('(');
+ _writer->replace(node->literalToken.begin() - _position, 0, pre);
+ _writer->replace(node->literalToken.end() - _position - suffixLength,
+ suffixLength,
+ QLatin1String(")"));
+ }
+
+ return false;
+}
+
+} // namespace QmlRewrite
+
+QT_END_NAMESPACE
diff --git a/src/declarative/qml/qmlrewrite_p.h b/src/declarative/qml/qmlrewrite_p.h
new file mode 100644
index 0000000..51a8015
--- /dev/null
+++ b/src/declarative/qml/qmlrewrite_p.h
@@ -0,0 +1,103 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtDeclarative module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QMLREWRITE_P_H
+#define QMLREWRITE_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "rewriter/textwriter_p.h"
+#include "parser/qmljslexer_p.h"
+#include "parser/qmljsparser_p.h"
+#include "parser/qmljsnodepool_p.h"
+
+QT_BEGIN_NAMESPACE
+
+namespace QmlRewrite {
+using namespace QmlJS;
+
+class RewriteBinding: protected AST::Visitor
+{
+ unsigned _position;
+ TextWriter *_writer;
+
+public:
+ QString operator()(const QString &code);
+
+protected:
+ using AST::Visitor::visit;
+
+ void accept(AST::Node *node);
+ QString rewrite(QString code, unsigned position, AST::Statement *node);
+ virtual bool visit(AST::Block *ast);
+ virtual bool visit(AST::ExpressionStatement *ast);
+ virtual bool visit(AST::NumericLiteral *node);
+};
+
+class RewriteNumericLiterals: protected AST::Visitor
+{
+ unsigned _position;
+ TextWriter *_writer;
+
+public:
+ QString operator()(QString code, unsigned position, AST::Node *node);
+
+protected:
+ using AST::Visitor::visit;
+
+ virtual bool visit(AST::NumericLiteral *node);
+};
+
+} // namespace QmlRewrite
+
+QT_END_NAMESPACE
+
+#endif // QMLREWRITE_P_H
+
diff --git a/src/declarative/qml/qmlscriptparser.cpp b/src/declarative/qml/qmlscriptparser.cpp
index f26266b..c1c11c7 100644
--- a/src/declarative/qml/qmlscriptparser.cpp
+++ b/src/declarative/qml/qmlscriptparser.cpp
@@ -49,7 +49,7 @@
#include "parser/qmljsastvisitor_p.h"
#include "parser/qmljsast_p.h"
-#include "rewriter/textwriter_p.h"
+#include "qmlrewrite_p.h"
#include <QStack>
#include <QCoreApplication>
@@ -64,48 +64,6 @@ using namespace QmlParser;
namespace {
-class RewriteNumericLiterals: protected AST::Visitor
-{
- unsigned _position;
- TextWriter *_writer;
-
-public:
- QString operator()(QString code, unsigned position, AST::Node *node)
- {
- TextWriter w;
- _writer = &w;
- _position = position;
-
- AST::Node::acceptChild(node, this);
-
- w.write(&code);
-
- return code;
- }
-
-protected:
- using AST::Visitor::visit;
-
- virtual bool visit(AST::NumericLiteral *node)
- {
- if (node->suffix != AST::NumericLiteral::noSuffix) {
- const int suffixLength = AST::NumericLiteral::suffixLength[node->suffix];
- const char *suffixSpell = AST::NumericLiteral::suffixSpell[node->suffix];
- QString pre;
- pre += QLatin1String("qmlNumberFrom");
- pre += QChar(QLatin1Char(suffixSpell[0])).toUpper();
- pre += QLatin1String(&suffixSpell[1]);
- pre += QLatin1Char('(');
- _writer->replace(node->literalToken.begin() - _position, 0, pre);
- _writer->replace(node->literalToken.end() - _position - suffixLength,
- suffixLength,
- QLatin1String(")"));
- }
-
- return false;
- }
-};
-
class ProcessAST: protected AST::Visitor
{
struct State {
@@ -196,7 +154,7 @@ protected:
const AST::SourceLocation &last) const
{ return _contents.mid(first.offset, last.offset + last.length - first.offset); }
- RewriteNumericLiterals rewriteNumericLiterals;
+ QmlRewrite::RewriteNumericLiterals rewriteNumericLiterals;
QString asString(AST::ExpressionNode *expr)
{
@@ -572,8 +530,8 @@ bool ProcessAST::visit(AST::UiPublicMember *node)
property.isDefaultProperty = node->isDefaultMember;
property.type = type;
property.name = name.toUtf8();
- property.range.offset = node->firstSourceLocation().offset;
- property.range.length = node->semicolonToken.end() - property.range.offset;
+ property.location = location(node->firstSourceLocation(),
+ node->lastSourceLocation());
if (node->expression) { // default value
property.defaultValue = new Property;
diff --git a/src/declarative/qml/qmlvme.cpp b/src/declarative/qml/qmlvme.cpp
index 3b33686..f468cd0 100644
--- a/src/declarative/qml/qmlvme.cpp
+++ b/src/declarative/qml/qmlvme.cpp
@@ -116,7 +116,6 @@ void QmlVME::runDeferred(QObject *object)
return;
QmlContext *ctxt = data->context;
- ctxt->activate();
QmlCompiledData *comp = data->deferredComponent;
int start = data->deferredIdx + 1;
int count = data->deferredComponent->bytecode.at(data->deferredIdx).defer.deferCount;
@@ -124,17 +123,10 @@ void QmlVME::runDeferred(QObject *object)
stack.push(object);
run(stack, ctxt, comp, start, count);
- ctxt->deactivate();
}
QObject *QmlVME::run(QStack<QObject *> &stack, QmlContext *ctxt, QmlCompiledData *comp, int start, int count)
{
- // XXX - All instances of QmlContext::activeContext() here should be
- // replaced with the use of ctxt. However, this cannot be done until
- // behaviours stop modifying the active context and expecting the
- // instantiation to notice. Instead, QmlParserStatus::beginClass() should
- // be able to return a QmlContext that is used for expressions and
- // sub-instances on that type.
Q_ASSERT(comp);
Q_ASSERT(ctxt);
const QList<QmlCompiledData::TypeReference> &types = comp->types;
@@ -169,7 +161,7 @@ QObject *QmlVME::run(QStack<QObject *> &stack, QmlContext *ctxt, QmlCompiledData
case QmlInstruction::CreateObject:
{
- QObject *o = types.at(instr.create.type).createInstance(QmlContext::activeContext());
+ QObject *o = types.at(instr.create.type).createInstance(ctxt);
if (!o) {
if(types.at(instr.create.type).component)
vmeErrors << types.at(instr.create.type).component->errors();
@@ -203,8 +195,6 @@ QObject *QmlVME::run(QStack<QObject *> &stack, QmlContext *ctxt, QmlCompiledData
case QmlInstruction::SetId:
{
QObject *target = stack.top();
- QmlContext *ctxt =
- QmlContext::activeContext();
ctxt->setContextProperty(primitives.at(instr.setId.value), target);
}
break;
@@ -213,7 +203,7 @@ QObject *QmlVME::run(QStack<QObject *> &stack, QmlContext *ctxt, QmlCompiledData
case QmlInstruction::SetDefault:
{
QObject *target = stack.top();
- QmlContext::activeContext()->addDefaultObject(target);
+ ctxt->addDefaultObject(target);
}
break;
@@ -515,9 +505,9 @@ QObject *QmlVME::run(QStack<QObject *> &stack, QmlContext *ctxt, QmlCompiledData
target->metaObject()->method(instr.storeSignal.signalIndex);
if (signal.parameterTypes().isEmpty()) {
- (void *)new QmlBoundSignal(QmlContext::activeContext(), primitives.at(instr.storeSignal.value), target, instr.storeSignal.signalIndex, target);
+ (void *)new QmlBoundSignal(ctxt, primitives.at(instr.storeSignal.value), target, instr.storeSignal.signalIndex, target);
} else {
- (void *)new QmlBoundSignalProxy(new QmlContext(QmlContext::activeContext(), target, true), primitives.at(instr.storeSignal.value), target, instr.storeSignal.signalIndex, target);
+ (void *)new QmlBoundSignalProxy(new QmlContext(ctxt, target, true), primitives.at(instr.storeSignal.value), target, instr.storeSignal.signalIndex, target);
}
}
break;
@@ -550,7 +540,7 @@ QObject *QmlVME::run(QStack<QObject *> &stack, QmlContext *ctxt, QmlCompiledData
QmlMetaProperty mp(target, instr.assignBinding.property,
(QmlMetaProperty::PropertyCategory)instr.assignBinding.category);
- QmlBindableValue *bind = new QmlBindableValue((void *)datas.at(instr.assignBinding.value).constData(), comp, context, QmlContext::activeContext(), 0);
+ QmlBindableValue *bind = new QmlBindableValue((void *)datas.at(instr.assignBinding.value).constData(), comp, context, ctxt, 0);
bindValues.append(bind);
QmlBindableValuePrivate *p =
static_cast<QmlBindableValuePrivate *>(QObjectPrivate::get(bind));
@@ -570,7 +560,7 @@ QObject *QmlVME::run(QStack<QObject *> &stack, QmlContext *ctxt, QmlCompiledData
QmlMetaProperty mp(target, instr.assignBinding.property,
(QmlMetaProperty::PropertyCategory)instr.assignBinding.category);
- QmlBindableValue *bind = new QmlBindableValue(primitives.at(instr.assignBinding.value), context, QmlContext::activeContext());
+ QmlBindableValue *bind = new QmlBindableValue(primitives.at(instr.assignBinding.value), context, ctxt);
bindValues.append(bind);
QmlBindableValuePrivate *p =
static_cast<QmlBindableValuePrivate *>(QObjectPrivate::get(bind));