diff options
-rw-r--r-- | src/plugins/qmltooling/qmldbg_debugger/qv4debugger.cpp | 4 | ||||
-rw-r--r-- | src/plugins/qmltooling/qmldbg_nativedebugger/qqmlnativedebugservice.cpp | 3 | ||||
-rw-r--r-- | src/qml/jsapi/qjsengine.cpp | 28 | ||||
-rw-r--r-- | tests/auto/qml/qjsengine/tst_qjsengine.cpp | 69 |
4 files changed, 85 insertions, 19 deletions
diff --git a/src/plugins/qmltooling/qmldbg_debugger/qv4debugger.cpp b/src/plugins/qmltooling/qmldbg_debugger/qv4debugger.cpp index 3170ee0c1b..5521e7628b 100644 --- a/src/plugins/qmltooling/qmldbg_debugger/qv4debugger.cpp +++ b/src/plugins/qmltooling/qmldbg_debugger/qv4debugger.cpp @@ -157,7 +157,7 @@ void QV4Debugger::clearPauseRequest() QV4Debugger::ExecutionState QV4Debugger::currentExecutionState() const { ExecutionState state; - state.fileName = getFunction()->sourceFile(); + state.fileName = QUrl(getFunction()->sourceFile()).fileName(); state.lineNumber = engine()->currentStackFrame->lineNumber(); return state; @@ -288,7 +288,7 @@ void QV4Debugger::pauseAndWait(PauseReason reason) bool QV4Debugger::reallyHitTheBreakPoint(const QString &filename, int linenr) { QHash<BreakPoint, QString>::iterator it = m_breakPoints.find( - BreakPoint(filename.mid(filename.lastIndexOf('/') + 1), linenr)); + BreakPoint(QUrl(filename).fileName(), linenr)); if (it == m_breakPoints.end()) return false; QString condition = it.value(); diff --git a/src/plugins/qmltooling/qmldbg_nativedebugger/qqmlnativedebugservice.cpp b/src/plugins/qmltooling/qmldbg_nativedebugger/qqmlnativedebugservice.cpp index ceaa8a8de1..a5c2f40420 100644 --- a/src/plugins/qmltooling/qmldbg_nativedebugger/qqmlnativedebugservice.cpp +++ b/src/plugins/qmltooling/qmldbg_nativedebugger/qqmlnativedebugservice.cpp @@ -689,8 +689,7 @@ bool NativeDebugger::reallyHitTheBreakPoint(const QV4::Function *function, int l for (int i = 0, n = m_service->m_breakHandler->m_breakPoints.size(); i != n; ++i) { const BreakPoint &bp = m_service->m_breakHandler->m_breakPoints.at(i); if (bp.lineNumber == lineNumber) { - const QString fileName = function->sourceFile(); - const QStringRef base = fileName.midRef(fileName.lastIndexOf('/') + 1); + const QString base = QUrl(function->sourceFile()).fileName(); if (bp.fileName.endsWith(base)) { if (bp.condition.isEmpty() || checkCondition(bp.condition)) { BreakPoint &mbp = m_service->m_breakHandler->m_breakPoints[i]; diff --git a/src/qml/jsapi/qjsengine.cpp b/src/qml/jsapi/qjsengine.cpp index b5eadf483a..69e1436c0a 100644 --- a/src/qml/jsapi/qjsengine.cpp +++ b/src/qml/jsapi/qjsengine.cpp @@ -469,6 +469,17 @@ void QJSEngine::installExtensions(QJSEngine::Extensions extensions, const QJSVal QV4::GlobalExtensions::init(obj, extensions); } +static QUrl urlForFileName(const QString &fileName) +{ + if (!fileName.startsWith(QLatin1Char(':'))) + return QUrl::fromLocalFile(fileName); + + QUrl url; + url.setPath(fileName.mid(1)); + url.setScheme(QLatin1String("qrc")); + return url; +} + /*! Evaluates \a program, using \a lineNumber as the base line number, and returns the result of the evaluation. @@ -503,7 +514,7 @@ QJSValue QJSEngine::evaluate(const QString& program, const QString& fileName, in QV4::Scope scope(v4); QV4::ScopedValue result(scope); - QV4::Script script(v4->rootContext(), QV4::Compiler::ContextType::Global, program, fileName, lineNumber); + QV4::Script script(v4->rootContext(), QV4::Compiler::ContextType::Global, program, urlForFileName(fileName).toString(), lineNumber); script.strictMode = false; if (v4->currentStackFrame) script.strictMode = v4->currentStackFrame->v4Function->isStrict(); @@ -521,19 +532,6 @@ QJSValue QJSEngine::evaluate(const QString& program, const QString& fileName, in return retval; } -static QUrl moduleUrlForFileName(const QString &fileName) -{ - QString absolutePath = QFileInfo(fileName).canonicalFilePath(); - if (!absolutePath.startsWith(QLatin1Char(':'))) - return QUrl::fromLocalFile(absolutePath); - - absolutePath.remove(0, 1); - QUrl url; - url.setPath(absolutePath); - url.setScheme(QLatin1String("qrc")); - return url; -} - /*! Imports the module located at \a fileName and returns a module namespace object that contains all exported variables, constants and functions as properties. @@ -556,7 +554,7 @@ static QUrl moduleUrlForFileName(const QString &fileName) */ QJSValue QJSEngine::importModule(const QString &fileName) { - const QUrl url = moduleUrlForFileName(fileName); + const QUrl url = urlForFileName(QFileInfo(fileName).canonicalFilePath()); auto moduleUnit = m_v4Engine->loadModule(url); if (m_v4Engine->hasException) return QJSValue(m_v4Engine, m_v4Engine->catchException()); diff --git a/tests/auto/qml/qjsengine/tst_qjsengine.cpp b/tests/auto/qml/qjsengine/tst_qjsengine.cpp index 6bc0359483..a38224ef81 100644 --- a/tests/auto/qml/qjsengine/tst_qjsengine.cpp +++ b/tests/auto/qml/qjsengine/tst_qjsengine.cpp @@ -177,6 +177,8 @@ private slots: void translateScriptUnicodeIdBased_data(); void translateScriptUnicodeIdBased(); void translateFromBuiltinCallback(); + void translationFilePath_data(); + void translationFilePath(); void installConsoleFunctions(); void logging(); @@ -3915,6 +3917,73 @@ void tst_QJSEngine::translateFromBuiltinCallback() eng.evaluate("[10,20].forEach(foo)", "script.js"); } +void tst_QJSEngine::translationFilePath_data() +{ + QTest::addColumn<QString>("filename"); + + QTest::newRow("relative") << QStringLiteral("script.js"); + QTest::newRow("absolute unix") << QStringLiteral("/script.js"); + QTest::newRow("absolute /windows/") << QStringLiteral("c:/script.js"); +#ifdef Q_OS_WIN + QTest::newRow("absolute \\windows\\") << QStringLiteral("c:\\script.js"); +#endif + QTest::newRow("relative url") << QStringLiteral("file://script.js"); + QTest::newRow("absolute url unix") << QStringLiteral("file:///script.js"); + QTest::newRow("absolute url windows") << QStringLiteral("file://c:/script.js"); +} + +class DummyTranslator : public QTranslator +{ + Q_OBJECT + +public: + DummyTranslator(const char *sourceText) + : srcTxt(sourceText) + {} + + QString translate(const char *context, const char *sourceText, const char *disambiguation, int n) const override + { + Q_UNUSED(disambiguation); + Q_UNUSED(n); + + if (srcTxt == sourceText) + ctxt = QByteArray(context); + + return QString(sourceText); + } + + bool isEmpty() const override + { + return false; + } + + const char *sourceText() const + { return srcTxt.constData(); } + + QByteArray context() const + { return ctxt; } + +private: + QByteArray srcTxt; + mutable QByteArray ctxt; +}; + +void tst_QJSEngine::translationFilePath() +{ + QFETCH(QString, filename); + + DummyTranslator translator("some text"); + QCoreApplication::installTranslator(&translator); + QByteArray scriptContent = QByteArray("qsTr('%1')").replace("%1", translator.sourceText()); + + QJSEngine engine; + engine.installExtensions(QJSEngine::TranslationExtension); + QJSValue result = engine.evaluate(scriptContent, filename); + QCOMPARE(translator.context(), QByteArray("script")); + + QCoreApplication::removeTranslator(&translator); +} + void tst_QJSEngine::installConsoleFunctions() { QJSEngine engine; |