From ebc31ca3c4a6a49c274f82af52a2e1b6cace30b7 Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Wed, 12 Jun 2013 17:03:01 +0200 Subject: [PATCH] Fix syntax error propagation 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 --- src/qml/qml/qqmljavascriptexpression.cpp | 25 ++++++++++++++++------ src/qml/qml/qqmlvme.cpp | 20 +++++++++++------ .../auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp | 2 +- 3 files changed, 33 insertions(+), 14 deletions(-) diff --git a/src/qml/qml/qqmljavascriptexpression.cpp b/src/qml/qml/qqmljavascriptexpression.cpp index 6670948..820e500 100644 --- a/src/qml/qml/qqmljavascriptexpression.cpp +++ b/src/qml/qml/qqmljavascriptexpression.cpp @@ -46,6 +46,7 @@ #include #include #include +#include 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(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 diff --git a/src/qml/qml/qqmlvme.cpp b/src/qml/qml/qqmlvme.cpp index 2e09cf4..7ca6f4f 100644 --- a/src/qml/qml/qqmlvme.cpp +++ b/src/qml/qml/qqmlvme.cpp @@ -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(); diff --git a/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp b/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp index 3076c7a..cfbd987 100644 --- a/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp +++ b/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp @@ -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(); -- 2.7.4