aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/qml/compiler/qqmlcodegenerator.cpp1
-rw-r--r--src/qml/compiler/qv4codegen.cpp7
-rw-r--r--src/qml/compiler/qv4codegen_p.h1
-rw-r--r--src/qml/compiler/qv4jsir_p.h2
-rw-r--r--src/qml/qml/qqmlcompiler.cpp5
-rw-r--r--tests/auto/qml/qqmlecmascript/data/idAsLValue.qml7
-rw-r--r--tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp11
7 files changed, 30 insertions, 4 deletions
diff --git a/src/qml/compiler/qqmlcodegenerator.cpp b/src/qml/compiler/qqmlcodegenerator.cpp
index 2b3cb80acb..c16dd5daea 100644
--- a/src/qml/compiler/qqmlcodegenerator.cpp
+++ b/src/qml/compiler/qqmlcodegenerator.cpp
@@ -1211,6 +1211,7 @@ JSCodeGen::JSCodeGen(QQmlEnginePrivate *enginePrivate, const QString &fileName,
{
_module = jsModule;
_module->setFileName(fileName);
+ _fileNameIsUrl = true;
}
void JSCodeGen::beginContextScope(const JSCodeGen::ObjectIdMapping &objectIds, QQmlPropertyCache *contextObject)
diff --git a/src/qml/compiler/qv4codegen.cpp b/src/qml/compiler/qv4codegen.cpp
index 68c46f5677..893abc9659 100644
--- a/src/qml/compiler/qv4codegen.cpp
+++ b/src/qml/compiler/qv4codegen.cpp
@@ -418,6 +418,7 @@ Codegen::Codegen(bool strict)
, _labelledStatement(0)
, _scopeAndFinally(0)
, _strictMode(strict)
+ , _fileNameIsUrl(false)
, hasError(false)
{
}
@@ -1182,7 +1183,7 @@ bool Codegen::visit(BinaryExpression *ast)
if (throwSyntaxErrorOnEvalOrArgumentsInStrictMode(left, ast->left->lastSourceLocation()))
return false;
V4IR::Expr* right = *expression(ast->right);
- if (! (left->asTemp() || left->asName() || left->asSubscript() || left->asMember())) {
+ if (!left->isLValue()) {
throwReferenceError(ast->operatorToken, QStringLiteral("left-hand side of assignment operator is not an lvalue"));
return false;
}
@@ -2850,7 +2851,7 @@ void Codegen::throwSyntaxError(const SourceLocation &loc, const QString &detail)
hasError = true;
QQmlError error;
- error.setUrl(QUrl::fromLocalFile(_module->fileName));
+ error.setUrl(_fileNameIsUrl ? QUrl(_module->fileName) : QUrl::fromLocalFile(_module->fileName));
error.setDescription(detail);
error.setLine(loc.startLine);
error.setColumn(loc.startColumn);
@@ -2864,7 +2865,7 @@ void Codegen::throwReferenceError(const SourceLocation &loc, const QString &deta
hasError = true;
QQmlError error;
- error.setUrl(QUrl::fromLocalFile(_module->fileName));
+ error.setUrl(_fileNameIsUrl ? QUrl(_module->fileName) : QUrl::fromLocalFile(_module->fileName));
error.setDescription(detail);
error.setLine(loc.startLine);
error.setColumn(loc.startColumn);
diff --git a/src/qml/compiler/qv4codegen_p.h b/src/qml/compiler/qv4codegen_p.h
index 0bac996349..de22e8904b 100644
--- a/src/qml/compiler/qv4codegen_p.h
+++ b/src/qml/compiler/qv4codegen_p.h
@@ -460,6 +460,7 @@ protected:
QStack<V4IR::BasicBlock *> _exceptionHandlers;
bool _strictMode;
+ bool _fileNameIsUrl;
bool hasError;
QList<QQmlError> _errors;
diff --git a/src/qml/compiler/qv4jsir_p.h b/src/qml/compiler/qv4jsir_p.h
index f4b8b15984..9a1bd87a1d 100644
--- a/src/qml/compiler/qv4jsir_p.h
+++ b/src/qml/compiler/qv4jsir_p.h
@@ -558,7 +558,7 @@ struct Member: Expr {
}
virtual void accept(ExprVisitor *v) { v->visitMember(this); }
- virtual bool isLValue() { return true; }
+ virtual bool isLValue() { return type != MemberOfQmlContext; }
virtual Member *asMember() { return this; }
virtual void dump(QTextStream &out) const;
diff --git a/src/qml/qml/qqmlcompiler.cpp b/src/qml/qml/qqmlcompiler.cpp
index f9dd0b65a3..7b33849e67 100644
--- a/src/qml/qml/qqmlcompiler.cpp
+++ b/src/qml/qml/qqmlcompiler.cpp
@@ -3682,6 +3682,11 @@ bool QQmlCompiler::completeComponentBuild()
jsCodeGen.beginObjectScope(scopeObject->metatype);
cd->runtimeFunctionIndices = jsCodeGen.generateJSCodeForFunctionsAndBindings(cd->functionsToCompile, expressionNames);
+ QList<QQmlError> errors = jsCodeGen.errors();
+ if (!errors.isEmpty()) {
+ exceptions << errors;
+ return false;
+ }
foreach (const QQmlCompilerTypes::ComponentCompileState::CompiledMetaMethod &cmm, cd->compiledMetaMethods) {
typedef QQmlVMEMetaData VMD;
diff --git a/tests/auto/qml/qqmlecmascript/data/idAsLValue.qml b/tests/auto/qml/qqmlecmascript/data/idAsLValue.qml
new file mode 100644
index 0000000000..1035f844b4
--- /dev/null
+++ b/tests/auto/qml/qqmlecmascript/data/idAsLValue.qml
@@ -0,0 +1,7 @@
+import QtQml 2.0
+QtObject {
+ id: root
+ Component.onCompleted: {
+ root = "hello"
+ }
+}
diff --git a/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp b/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp
index 6af8863de7..6e1e606fb8 100644
--- a/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp
+++ b/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp
@@ -317,6 +317,7 @@ private slots:
void setPropertyOnInvalid();
void miscTypeTest();
void stackLimits();
+ void idsAsLValues();
private:
// static void propertyVarWeakRefCallback(v8::Persistent<v8::Value> object, void* parameter);
@@ -7466,6 +7467,16 @@ void tst_qqmlecmascript::stackLimits()
engine.evaluate(QStringLiteral("function foo() {foo();} try {foo()} catch(e) { }"));
}
+void tst_qqmlecmascript::idsAsLValues()
+{
+ QString err = QString(QLatin1String("%1:5 left-hand side of assignment operator is not an lvalue\n")).arg(testFileUrl("idAsLValue.qml").toString());
+ QQmlComponent component(&engine, testFileUrl("idAsLValue.qml"));
+ QTest::ignoreMessage(QtWarningMsg, "QQmlComponent: Component is not ready");
+ MyQmlObject *object = qobject_cast<MyQmlObject*>(component.create());
+ QVERIFY(!object);
+ QCOMPARE(component.errorString(), err);
+}
+
QTEST_MAIN(tst_qqmlecmascript)
#include "tst_qqmlecmascript.moc"