Fix syntax error propagation
authorSimon Hausmann <simon.hausmann@digia.com>
Wed, 12 Jun 2013 15:03:01 +0000 (17:03 +0200)
committerLars Knoll <lars.knoll@digia.com>
Thu, 13 Jun 2013 06:51:52 +0000 (08:51 +0200)
For syntax errors we use the DiagnosticMessage type in qv4context.cpp,
that contains detailed information about the error. We must catch that
error correctly in QQmlVME::run and report it to the engine.

Change-Id: I8f53c7db8dbdc6afa72396f3c25537690a6f5841
Reviewed-by: Lars Knoll <lars.knoll@digia.com>
src/qml/qml/qqmljavascriptexpression.cpp
src/qml/qml/qqmlvme.cpp
tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp

index 6670948..820e500 100644 (file)
@@ -46,6 +46,7 @@
 #include <private/qv4value_p.h>
 #include <private/qv4functionobject_p.h>
 #include <private/qv4script_p.h>
+#include <private/qv4errorobject_p.h>
 
 QT_BEGIN_NAMESPACE
 
@@ -291,14 +292,24 @@ QQmlDelayedError *QQmlJavaScriptExpression::delayedError()
 
 void QQmlJavaScriptExpression::exceptionToError(const QV4::Exception &e, QQmlError &error)
 {
-    QV4::ExecutionEngine::StackTrace trace = e.stackTrace();
-    if (!trace.isEmpty()) {
-        QV4::ExecutionEngine::StackFrame frame = trace.first();
-        error.setUrl(QUrl(frame.source));
-        error.setLine(frame.line);
-        error.setColumn(-1);
+    QV4::ErrorObject *errorObj = e.value().asErrorObject();
+    if (errorObj && errorObj->subtype == QV4::ErrorObject::SyntaxError) {
+        QV4::DiagnosticMessage *msg = static_cast<QV4::SyntaxErrorObject*>(errorObj)->message();
+        error.setUrl(QUrl(msg->fileName));
+        error.setLine(msg->startLine);
+        error.setColumn(msg->startColumn);
+        error.setDescription(msg->message);
+        // ### FIXME: support msg->next
+    } else {
+        QV4::ExecutionEngine::StackTrace trace = e.stackTrace();
+        if (!trace.isEmpty()) {
+            QV4::ExecutionEngine::StackFrame frame = trace.first();
+            error.setUrl(QUrl(frame.source));
+            error.setLine(frame.line);
+            error.setColumn(-1);
+        }
+        error.setDescription(e.value().toQString());
     }
-    error.setDescription(e.value().toQString());
 }
 
 QV4::PersistentValue
index 2e09cf4..7ca6f4f 100644 (file)
@@ -1071,17 +1071,15 @@ void QQmlScriptData::initialize(QQmlEngine *engine)
     QQmlEnginePrivate *ep = QQmlEnginePrivate::get(engine);
     QV8Engine *v8engine = ep->v8engine();
     QV4::ExecutionEngine *v4 = QV8Engine::getV4(v8engine);
-    QV4::ExecutionContext *ctx = v4->current;
 
     // If compilation throws an error, a surrounding catch will record it.
     // pass 0 as the QML object, we set it later before calling run()
     QV4::Script *program = new QV4::Script(v4, 0, m_programSource, urlString, 1);
     try {
         program->parse();
-    } catch (QV4::Exception &e) {
-        e.accept(ctx);
+    } catch (QV4::Exception &) {
         delete program;
-        return;
+        throw;
     }
 
     m_program = program;
@@ -1148,8 +1146,18 @@ QV4::PersistentValue QQmlVME::run(QQmlContextData *parentCtxt, QQmlScriptData *s
         ctxt->importedScripts << run(ctxt, script->scripts.at(ii)->scriptData());
     }
 
-    if (!script->isInitialized())
-        script->initialize(parentCtxt->engine);
+    if (!script->isInitialized()) {
+        QV4::ExecutionContext *ctx = QV8Engine::getV4(parentCtxt->engine)->current;
+        try {
+            script->initialize(parentCtxt->engine);
+        } catch (QV4::Exception &e) {
+            e.accept(ctx);
+            QQmlError error;
+            QQmlExpressionPrivate::exceptionToError(e, error);
+            if (error.isValid())
+                ep->warning(error);
+        }
+    }
 
     if (!script->m_program)
         return QV4::PersistentValue();
index 3076c7a..cfbd987 100644 (file)
@@ -3928,7 +3928,7 @@ void tst_qqmlecmascript::importScripts_data()
     QTest::newRow("malformed import statement")
             << testFileUrl("jsimportfail/malformedImport.qml")
             << QString()
-            << (QStringList() << testFileUrl("jsimportfail/malformedImport.js").toString() + QLatin1String(":1: SyntaxError: Unexpected token ."))
+            << (QStringList() << testFileUrl("jsimportfail/malformedImport.js").toString() + QLatin1String(":1:1: Syntax error"))
             << QStringList()
             << QVariantList();