summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--doc/src/frameworks-technologies/threads.qdoc9
-rw-r--r--mkspecs/features/no_debug_info.prf17
-rw-r--r--src/corelib/thread/qthread_unix.cpp1
-rw-r--r--src/script/api/qscriptvalue.cpp15
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/parsejscontexts/main.js29
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/parsejscontexts/project.pro3
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/parsejscontexts/project.ts.result81
-rw-r--r--tests/auto/qscriptengine/translatable.js3
-rw-r--r--tests/auto/qscriptengine/translations/translatable_la.qmbin678 -> 975 bytes
-rw-r--r--tests/auto/qscriptengine/translations/translatable_la.ts16
-rw-r--r--tests/auto/qscriptengine/tst_qscriptengine.cpp214
-rw-r--r--tests/auto/qscriptvalue/tst_qscriptvalue.cpp344
-rw-r--r--tests/auto/qscriptvalue/tst_qscriptvalue.h13
-rw-r--r--tools/linguist/lupdate/qscript.cpp52
-rw-r--r--tools/linguist/lupdate/qscript.g52
15 files changed, 600 insertions, 249 deletions
diff --git a/doc/src/frameworks-technologies/threads.qdoc b/doc/src/frameworks-technologies/threads.qdoc
index 3ef617c..001b29d 100644
--- a/doc/src/frameworks-technologies/threads.qdoc
+++ b/doc/src/frameworks-technologies/threads.qdoc
@@ -459,11 +459,10 @@
\list
- \o \l{Qt::AutoConnection}{Auto Connection} (default) The behavior
- is the same as the Direct Connection, if the emitter and
- receiver are in the same thread. The behavior is the same as
- the Queued Connection, if the emitter and receiver are in
- different threads.
+ \o \l{Qt::AutoConnection}{Auto Connection} (default) If the signal is
+ emitted in the thread which the receiving object has affinity then
+ the behavior is the same as the Direct Connection. Otherwise,
+ the behavior is the same as the Queued Connection."
\o \l{Qt::DirectConnection}{Direct Connection} The slot is invoked
immediately, when the signal is emitted. The slot is executed
diff --git a/mkspecs/features/no_debug_info.prf b/mkspecs/features/no_debug_info.prf
index 3acf6c8..e05410d 100644
--- a/mkspecs/features/no_debug_info.prf
+++ b/mkspecs/features/no_debug_info.prf
@@ -1,5 +1,14 @@
-QMAKE_CFLAGS -= -g -ggdb3
-QMAKE_CXXFLAGS -= -g -ggdb3
-QMAKE_LFLAGS -= -g -ggdb3
-QMAKE_LIBFLAGS -= -g -ggdb3
+win32-msvc2*|wince*msvc* {
+ QMAKE_CFLAGS -= -Zi
+ QMAKE_CFLAGS_DEBUG -= -Zi
+ QMAKE_CFLAGS_RELEASE_WITH_DEBUGINFO -= -Zi
+ QMAKE_CXXFLAGS -= -Zi
+ QMAKE_CXXFLAGS_DEBUG -= -Zi
+ QMAKE_CXXFLAGS_RELEASE_WITH_DEBUGINFO -= -Zi
+} else {
+ QMAKE_CFLAGS -= -g -ggdb3
+ QMAKE_CXXFLAGS -= -g -ggdb3
+ QMAKE_LFLAGS -= -g -ggdb3
+ QMAKE_LIBFLAGS -= -g -ggdb3
+}
diff --git a/src/corelib/thread/qthread_unix.cpp b/src/corelib/thread/qthread_unix.cpp
index f409256..3a3c2bb 100644
--- a/src/corelib/thread/qthread_unix.cpp
+++ b/src/corelib/thread/qthread_unix.cpp
@@ -140,6 +140,7 @@ static void create_current_thread_data_key()
static void destroy_current_thread_data_key()
{
+ pthread_once(&current_thread_data_once, create_current_thread_data_key);
pthread_key_delete(current_thread_data_key);
}
Q_DESTRUCTOR_FUNCTION(destroy_current_thread_data_key)
diff --git a/src/script/api/qscriptvalue.cpp b/src/script/api/qscriptvalue.cpp
index 8cd4057..6ce54f5 100644
--- a/src/script/api/qscriptvalue.cpp
+++ b/src/script/api/qscriptvalue.cpp
@@ -1716,7 +1716,14 @@ QScriptValue QScriptValue::construct(const QScriptValueList &args)
QVarLengthArray<JSC::JSValue, 8> argsVector(args.size());
for (int i = 0; i < args.size(); ++i) {
- if (!args.at(i).isValid())
+ QScriptValue arg = args.at(i);
+ if (QScriptValuePrivate::getEngine(arg) != d->engine && QScriptValuePrivate::getEngine(arg)) {
+ qWarning("QScriptValue::construct() failed: "
+ "cannot construct function with argument created in "
+ "a different engine");
+ return QScriptValue();
+ }
+ if (!arg.isValid())
argsVector[i] = JSC::jsUndefined();
else
argsVector[i] = d->engine->scriptValueToJSCValue(args.at(i));
@@ -1766,6 +1773,12 @@ QScriptValue QScriptValue::construct(const QScriptValue &arguments)
JSC::ExecState *exec = d->engine->currentFrame;
+ if (QScriptValuePrivate::getEngine(arguments) != d->engine && QScriptValuePrivate::getEngine(arguments)) {
+ qWarning("QScriptValue::construct() failed: "
+ "cannot construct function with argument created in "
+ "a different engine");
+ return QScriptValue();
+ }
JSC::JSValue array = d->engine->scriptValueToJSCValue(arguments);
// copied from runtime/FunctionPrototype.cpp, functionProtoFuncApply()
JSC::MarkedArgumentBuffer applyArgs;
diff --git a/tests/auto/linguist/lupdate/testdata/good/parsejscontexts/main.js b/tests/auto/linguist/lupdate/testdata/good/parsejscontexts/main.js
new file mode 100644
index 0000000..aa510c1
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/parsejscontexts/main.js
@@ -0,0 +1,29 @@
+// No context specified, default should be used.
+qsTr("One");
+QT_TR_NOOP("Two");
+
+// TRANSLATOR Foo
+qsTr("Three");
+QT_TR_NOOP("Four");
+
+// TRANSLATOR Bar
+qsTr("Five");
+
+/*
+ TRANSLATOR Baz
+ This is a comment to the translator.
+*/
+QT_TR_NOOP("Six");
+
+// TRANSLATOR Foo.Bar
+qsTr("Seven");
+
+/* TRANSLATOR Bar::Baz */
+QT_TR_NOOP("Eight");
+
+// qsTranslate() context is not affected.
+qsTranslate("Foo", "Nine");
+
+// Empty context.
+// TRANSLATOR
+qsTr("Ten");
diff --git a/tests/auto/linguist/lupdate/testdata/good/parsejscontexts/project.pro b/tests/auto/linguist/lupdate/testdata/good/parsejscontexts/project.pro
new file mode 100644
index 0000000..d549039
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/parsejscontexts/project.pro
@@ -0,0 +1,3 @@
+SOURCES += main.js
+
+TRANSLATIONS = project.ts
diff --git a/tests/auto/linguist/lupdate/testdata/good/parsejscontexts/project.ts.result b/tests/auto/linguist/lupdate/testdata/good/parsejscontexts/project.ts.result
new file mode 100644
index 0000000..18407b2
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/parsejscontexts/project.ts.result
@@ -0,0 +1,81 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.0">
+<context>
+ <name></name>
+ <message>
+ <location filename="main.js" line="29"/>
+ <source>Ten</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>Bar</name>
+ <message>
+ <location filename="main.js" line="10"/>
+ <source>Five</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>Bar::Baz</name>
+ <message>
+ <location filename="main.js" line="22"/>
+ <source>Eight</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>Baz</name>
+ <message>
+ <location filename="main.js" line="12"/>
+ <source></source>
+ <comment>This is a comment to the translator.</comment>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="main.js" line="16"/>
+ <source>Six</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>Foo</name>
+ <message>
+ <location filename="main.js" line="6"/>
+ <source>Three</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="main.js" line="7"/>
+ <source>Four</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="main.js" line="25"/>
+ <source>Nine</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>Foo.Bar</name>
+ <message>
+ <location filename="main.js" line="19"/>
+ <source>Seven</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>main</name>
+ <message>
+ <location filename="main.js" line="2"/>
+ <source>One</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="main.js" line="3"/>
+ <source>Two</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+</TS>
diff --git a/tests/auto/qscriptengine/translatable.js b/tests/auto/qscriptengine/translatable.js
index 30e139a..c0d7ed0 100644
--- a/tests/auto/qscriptengine/translatable.js
+++ b/tests/auto/qscriptengine/translatable.js
@@ -7,3 +7,6 @@ var greeting_strings = [
];
qsTr("One", "not the same one");
+
+qsTr("%n message(s) saved", "", 10);
+qsTranslate("FooContext", "%n fooish bar(s) found", "", "UnicodeUTF8", 10);
diff --git a/tests/auto/qscriptengine/translations/translatable_la.qm b/tests/auto/qscriptengine/translations/translatable_la.qm
index 703d0f1..d76b1ca 100644
--- a/tests/auto/qscriptengine/translations/translatable_la.qm
+++ b/tests/auto/qscriptengine/translations/translatable_la.qm
Binary files differ
diff --git a/tests/auto/qscriptengine/translations/translatable_la.ts b/tests/auto/qscriptengine/translations/translatable_la.ts
index 1598f39..36271c9 100644
--- a/tests/auto/qscriptengine/translations/translatable_la.ts
+++ b/tests/auto/qscriptengine/translations/translatable_la.ts
@@ -26,6 +26,14 @@
<source>Goodbye</source>
<translation>Farvel</translation>
</message>
+ <message numerus="yes">
+ <location filename="translatable.js" line="12"/>
+ <source>%n fooish bar(s) found</source>
+ <translation>
+ <numerusform>%n fooaktig bar funnet</numerusform>
+ <numerusform>%n fooaktige barer funnet</numerusform>
+ </translation>
+ </message>
</context>
<context>
<name>translatable</name>
@@ -45,6 +53,14 @@
<comment>not the same one</comment>
<translation>Enda en</translation>
</message>
+ <message numerus="yes">
+ <location filename="translatable.js" line="11"/>
+ <source>%n message(s) saved</source>
+ <translation>
+ <numerusform>%n melding lagret</numerusform>
+ <numerusform>%n meldinger lagret</numerusform>
+ </translation>
+ </message>
<message>
<source>Goodbye</source>
<translation type="obsolete">Farvel</translation>
diff --git a/tests/auto/qscriptengine/tst_qscriptengine.cpp b/tests/auto/qscriptengine/tst_qscriptengine.cpp
index d529b8b..2fe7a2d 100644
--- a/tests/auto/qscriptengine/tst_qscriptengine.cpp
+++ b/tests/auto/qscriptengine/tst_qscriptengine.cpp
@@ -180,7 +180,12 @@ private slots:
void incDecNonObjectProperty();
void installTranslatorFunctions_data();
void installTranslatorFunctions();
+ void translateScript_data();
void translateScript();
+ void translateScript_crossScript();
+ void translateScript_callQsTrFromNative();
+ void translateScript_trNoOp();
+ void translateScript_callQsTrFromCpp();
void translateWithInvalidArgs_data();
void translateWithInvalidArgs();
void translationContext_data();
@@ -4728,78 +4733,134 @@ void tst_QScriptEngine::installTranslatorFunctions()
QVERIFY(eng.evaluate("QT_TRID_NOOP()").isUndefined());
}
-static QScriptValue callQsTr(QScriptContext *ctx, QScriptEngine *eng)
-{
- return eng->globalObject().property("qsTr").call(ctx->thisObject(), ctx->argumentsObject());
-}
-
-void tst_QScriptEngine::translateScript()
+class TranslationScope
{
- QScriptEngine engine;
+public:
+ TranslationScope(const QString &fileName)
+ {
+ translator.load(fileName);
+ QCoreApplication::instance()->installTranslator(&translator);
+ }
+ ~TranslationScope()
+ {
+ QCoreApplication::instance()->removeTranslator(&translator);
+ }
+private:
QTranslator translator;
- translator.load(":/translations/translatable_la");
- QCoreApplication::instance()->installTranslator(&translator);
- engine.installTranslatorFunctions();
+};
+
+void tst_QScriptEngine::translateScript_data()
+{
+ QTest::addColumn<QString>("expression");
+ QTest::addColumn<QString>("fileName");
+ QTest::addColumn<QString>("expectedTranslation");
QString fileName = QString::fromLatin1("translatable.js");
// Top-level
- QCOMPARE(engine.evaluate("qsTr('One')", fileName).toString(), QString::fromLatin1("En"));
- QCOMPARE(engine.evaluate("qsTr('Hello')", fileName).toString(), QString::fromLatin1("Hallo"));
+ QTest::newRow("qsTr('One')@translatable.js")
+ << QString::fromLatin1("qsTr('One')") << fileName << QString::fromLatin1("En");
+ QTest::newRow("qsTr('Hello')@translatable.js")
+ << QString::fromLatin1("qsTr('Hello')") << fileName << QString::fromLatin1("Hallo");
// From function
- QCOMPARE(engine.evaluate("(function() { return qsTr('One'); })()", fileName).toString(), QString::fromLatin1("En"));
- QCOMPARE(engine.evaluate("(function() { return qsTr('Hello'); })()", fileName).toString(), QString::fromLatin1("Hallo"));
+ QTest::newRow("(function() { return qsTr('One'); })()@translatable.js")
+ << QString::fromLatin1("(function() { return qsTr('One'); })()") << fileName << QString::fromLatin1("En");
+ QTest::newRow("(function() { return qsTr('Hello'); })()@translatable.js")
+ << QString::fromLatin1("(function() { return qsTr('Hello'); })()") << fileName << QString::fromLatin1("Hallo");
// From eval
- QCOMPARE(engine.evaluate("eval('qsTr(\\'One\\')')", fileName).toString(), QString::fromLatin1("En"));
- QCOMPARE(engine.evaluate("eval('qsTr(\\'Hello\\')')", fileName).toString(), QString::fromLatin1("Hallo"));
+ QTest::newRow("eval('qsTr(\\'One\\')')@translatable.js")
+ << QString::fromLatin1("eval('qsTr(\\'One\\')')") << fileName << QString::fromLatin1("En");
+ QTest::newRow("eval('qsTr(\\'Hello\\')')@translatable.js")
+ << QString::fromLatin1("eval('qsTr(\\'Hello\\')')") << fileName << QString::fromLatin1("Hallo");
+ // Plural
+ QTest::newRow("qsTr('%n message(s) saved', '', 1)@translatable.js")
+ << QString::fromLatin1("qsTr('%n message(s) saved', '', 1)") << fileName << QString::fromLatin1("1 melding lagret");
+ QTest::newRow("qsTr('%n message(s) saved', '', 3).arg@translatable.js")
+ << QString::fromLatin1("qsTr('%n message(s) saved', '', 3)") << fileName << QString::fromLatin1("3 meldinger lagret");
- QCOMPARE(engine.evaluate("qsTranslate('FooContext', 'Two')", fileName).toString(), QString::fromLatin1("To"));
- QCOMPARE(engine.evaluate("qsTranslate('FooContext', 'Goodbye')", fileName).toString(), QString::fromLatin1("Farvel"));
+ // Top-level
+ QTest::newRow("qsTranslate('FooContext', 'Two')@translatable.js")
+ << QString::fromLatin1("qsTranslate('FooContext', 'Two')") << fileName << QString::fromLatin1("To");
+ QTest::newRow("qsTranslate('FooContext', 'Goodbye')@translatable.js")
+ << QString::fromLatin1("qsTranslate('FooContext', 'Goodbye')") << fileName << QString::fromLatin1("Farvel");
// From eval
- QCOMPARE(engine.evaluate("eval('qsTranslate(\\'FooContext\\', \\'Two\\')')", fileName).toString(), QString::fromLatin1("To"));
- QCOMPARE(engine.evaluate("eval('qsTranslate(\\'FooContext\\', \\'Goodbye\\')')", fileName).toString(), QString::fromLatin1("Farvel"));
+ QTest::newRow("eval('qsTranslate(\\'FooContext\\', \\'Two\\')')@translatable.js")
+ << QString::fromLatin1("eval('qsTranslate(\\'FooContext\\', \\'Two\\')')") << fileName << QString::fromLatin1("To");
+ QTest::newRow("eval('qsTranslate(\\'FooContext\\', \\'Goodbye\\')')@translatable.js")
+ << QString::fromLatin1("eval('qsTranslate(\\'FooContext\\', \\'Goodbye\\')')") << fileName << QString::fromLatin1("Farvel");
- QCOMPARE(engine.evaluate("qsTranslate('FooContext', 'Goodbye', '', 'UnicodeUTF8')", fileName).toString(), QString::fromLatin1("Farvel"));
- QCOMPARE(engine.evaluate("qsTranslate('FooContext', 'Goodbye', '', 'CodecForTr')", fileName).toString(), QString::fromLatin1("Farvel"));
+ QTest::newRow("qsTranslate('FooContext', 'Goodbye', '', 'UnicodeUTF8')@translatable.js")
+ << QString::fromLatin1("qsTranslate('FooContext', 'Goodbye', '', 'UnicodeUTF8')") << fileName << QString::fromLatin1("Farvel");
+ QTest::newRow("qsTranslate('FooContext', 'Goodbye', '', 'CodecForTr')@translatable.js")
+ << QString::fromLatin1("qsTranslate('FooContext', 'Goodbye', '', 'CodecForTr')") << fileName << QString::fromLatin1("Farvel");
- QCOMPARE(engine.evaluate("qsTranslate('FooContext', 'Goodbye', '', 'UnicodeUTF8', 42)", fileName).toString(), QString::fromLatin1("Goodbye"));
+ QTest::newRow("qsTranslate('FooContext', 'Goodbye', '', 'UnicodeUTF8', 42)@translatable.js")
+ << QString::fromLatin1("qsTranslate('FooContext', 'Goodbye', '', 'UnicodeUTF8', 42)") << fileName << QString::fromLatin1("Goodbye");
- QCOMPARE(engine.evaluate("qsTr('One', 'not the same one')", fileName).toString(), QString::fromLatin1("Enda en"));
+ QTest::newRow("qsTr('One', 'not the same one')@translatable.js")
+ << QString::fromLatin1("qsTr('One', 'not the same one')") << fileName << QString::fromLatin1("Enda en");
- QCOMPARE(engine.evaluate("qsTr('One', 'not the same one', 42)", fileName).toString(), QString::fromLatin1("One"));
+ QTest::newRow("qsTr('One', 'not the same one', 42)@translatable.js")
+ << QString::fromLatin1("qsTr('One', 'not the same one', 42)") << fileName << QString::fromLatin1("One");
- QVERIFY(engine.evaluate("QT_TR_NOOP()").isUndefined());
- QCOMPARE(engine.evaluate("QT_TR_NOOP('One')").toString(), QString::fromLatin1("One"));
-
- QVERIFY(engine.evaluate("QT_TRANSLATE_NOOP()").isUndefined());
- QVERIFY(engine.evaluate("QT_TRANSLATE_NOOP('FooContext')").isUndefined());
- QCOMPARE(engine.evaluate("QT_TRANSLATE_NOOP('FooContext', 'Two')").toString(), QString::fromLatin1("Two"));
+ // Plural
+ QTest::newRow("qsTranslate('FooContext', '%n fooish bar(s) found', '', 'UnicodeUTF8', 1)@translatable.js")
+ << QString::fromLatin1("qsTranslate('FooContext', '%n fooish bar(s) found', '', 'UnicodeUTF8', 1)") << fileName << QString::fromLatin1("1 fooaktig bar funnet");
+ QTest::newRow("qsTranslate('FooContext', '%n fooish bar(s) found', '', 'UnicodeUTF8', 2)@translatable.js")
+ << QString::fromLatin1("qsTranslate('FooContext', '%n fooish bar(s) found', '', 'UnicodeUTF8', 2)") << fileName << QString::fromLatin1("2 fooaktige barer funnet");
// Don't exist in translation
- QCOMPARE(engine.evaluate("qsTr('Three')", fileName).toString(), QString::fromLatin1("Three"));
- QCOMPARE(engine.evaluate("qsTranslate('FooContext', 'So long')", fileName).toString(), QString::fromLatin1("So long"));
- QCOMPARE(engine.evaluate("qsTranslate('BarContext', 'Goodbye')", fileName).toString(), QString::fromLatin1("Goodbye"));
-
- // From C++
- // There is no context, but it shouldn't crash
- QCOMPARE(engine.globalObject().property("qsTr").call(
- QScriptValue(), QScriptValueList() << "One").toString(), QString::fromLatin1("One"));
+ QTest::newRow("qsTr('Three')@translatable.js")
+ << QString::fromLatin1("qsTr('Three')") << fileName << QString::fromLatin1("Three");
+ QTest::newRow("qsTranslate('FooContext', 'So long')@translatable.js")
+ << QString::fromLatin1("qsTranslate('FooContext', 'So long')") << fileName << QString::fromLatin1("So long");
+ QTest::newRow("qsTranslate('BarContext', 'Goodbye')@translatable.js")
+ << QString::fromLatin1("qsTranslate('BarContext', 'Goodbye')") << fileName << QString::fromLatin1("Goodbye");
// Translate strings from the second script (translatable2.js)
QString fileName2 = QString::fromLatin1("translatable2.js");
-
- QCOMPARE(engine.evaluate("qsTr('Three')", fileName2).toString(), QString::fromLatin1("Tre"));
- QCOMPARE(engine.evaluate("qsTr('Happy birthday!')", fileName2).toString(), QString::fromLatin1("Gratulerer med dagen!"));
+ QTest::newRow("qsTr('Three')@translatable2.js")
+ << QString::fromLatin1("qsTr('Three')") << fileName2 << QString::fromLatin1("Tre");
+ QTest::newRow("qsTr('Happy birthday!')@translatable2.js")
+ << QString::fromLatin1("qsTr('Happy birthday!')") << fileName2 << QString::fromLatin1("Gratulerer med dagen!");
// Not translated because translation is only in translatable.js
- QCOMPARE(engine.evaluate("qsTr('One')", fileName2).toString(), QString::fromLatin1("One"));
- QCOMPARE(engine.evaluate("(function() { return qsTr('One'); })()", fileName2).toString(), QString::fromLatin1("One"));
+ QTest::newRow("qsTr('One')@translatable2.js")
+ << QString::fromLatin1("qsTr('One')") << fileName2 << QString::fromLatin1("One");
+ QTest::newRow("(function() { return qsTr('One'); })()@translatable2.js")
+ << QString::fromLatin1("(function() { return qsTr('One'); })()") << fileName2 << QString::fromLatin1("One");
// For qsTranslate() the filename shouldn't matter
- QCOMPARE(engine.evaluate("qsTranslate('FooContext', 'Two')", fileName2).toString(), QString::fromLatin1("To"));
- QCOMPARE(engine.evaluate("qsTranslate('BarContext', 'Congratulations!')", fileName).toString(), QString::fromLatin1("Gratulerer!"));
+ QTest::newRow("qsTranslate('FooContext', 'Two')@translatable2.js")
+ << QString::fromLatin1("qsTranslate('FooContext', 'Two')") << fileName2 << QString::fromLatin1("To");
+ QTest::newRow("qsTranslate('BarContext', 'Congratulations!')@translatable.js")
+ << QString::fromLatin1("qsTranslate('BarContext', 'Congratulations!')") << fileName << QString::fromLatin1("Gratulerer!");
+}
+
+void tst_QScriptEngine::translateScript()
+{
+ QFETCH(QString, expression);
+ QFETCH(QString, fileName);
+ QFETCH(QString, expectedTranslation);
+
+ QScriptEngine engine;
+
+ TranslationScope tranScope(":/translations/translatable_la");
+ engine.installTranslatorFunctions();
+
+ QCOMPARE(engine.evaluate(expression, fileName).toString(), expectedTranslation);
+ QVERIFY(!engine.hasUncaughtException());
+}
+
+void tst_QScriptEngine::translateScript_crossScript()
+{
+ QScriptEngine engine;
+ TranslationScope tranScope(":/translations/translatable_la");
+ engine.installTranslatorFunctions();
+ QString fileName = QString::fromLatin1("translatable.js");
+ QString fileName2 = QString::fromLatin1("translatable2.js");
// qsTr() should use the innermost filename as context
engine.evaluate("function foo(s) { return bar(s); }", fileName);
engine.evaluate("function bar(s) { return qsTr(s); }", fileName2);
@@ -4812,15 +4873,52 @@ void tst_QScriptEngine::translateScript()
QCOMPARE(engine.evaluate("bar('Three')", fileName2).toString(), QString::fromLatin1("Three"));
QCOMPARE(engine.evaluate("bar('One')", fileName).toString(), QString::fromLatin1("En"));
QCOMPARE(engine.evaluate("bar('One')", fileName2).toString(), QString::fromLatin1("En"));
+}
+static QScriptValue callQsTr(QScriptContext *ctx, QScriptEngine *eng)
+{
+ return eng->globalObject().property("qsTr").call(ctx->thisObject(), ctx->argumentsObject());
+}
+
+void tst_QScriptEngine::translateScript_callQsTrFromNative()
+{
+ QScriptEngine engine;
+ TranslationScope tranScope(":/translations/translatable_la");
+ engine.installTranslatorFunctions();
+
+ QString fileName = QString::fromLatin1("translatable.js");
+ QString fileName2 = QString::fromLatin1("translatable2.js");
// Calling qsTr() from a native function
engine.globalObject().setProperty("qsTrProxy", engine.newFunction(callQsTr));
QCOMPARE(engine.evaluate("qsTrProxy('One')", fileName).toString(), QString::fromLatin1("En"));
QCOMPARE(engine.evaluate("qsTrProxy('One')", fileName2).toString(), QString::fromLatin1("One"));
QCOMPARE(engine.evaluate("qsTrProxy('Three')", fileName).toString(), QString::fromLatin1("Three"));
QCOMPARE(engine.evaluate("qsTrProxy('Three')", fileName2).toString(), QString::fromLatin1("Tre"));
+}
- QCoreApplication::instance()->removeTranslator(&translator);
+void tst_QScriptEngine::translateScript_trNoOp()
+{
+ QScriptEngine engine;
+ TranslationScope tranScope(":/translations/translatable_la");
+ engine.installTranslatorFunctions();
+
+ QVERIFY(engine.evaluate("QT_TR_NOOP()").isUndefined());
+ QCOMPARE(engine.evaluate("QT_TR_NOOP('One')").toString(), QString::fromLatin1("One"));
+
+ QVERIFY(engine.evaluate("QT_TRANSLATE_NOOP()").isUndefined());
+ QVERIFY(engine.evaluate("QT_TRANSLATE_NOOP('FooContext')").isUndefined());
+ QCOMPARE(engine.evaluate("QT_TRANSLATE_NOOP('FooContext', 'Two')").toString(), QString::fromLatin1("Two"));
+}
+
+void tst_QScriptEngine::translateScript_callQsTrFromCpp()
+{
+ QScriptEngine engine;
+ TranslationScope tranScope(":/translations/translatable_la");
+ engine.installTranslatorFunctions();
+
+ // There is no context, but it shouldn't crash
+ QCOMPARE(engine.globalObject().property("qsTr").call(
+ QScriptValue(), QScriptValueList() << "One").toString(), QString::fromLatin1("One"));
}
void tst_QScriptEngine::translateWithInvalidArgs_data()
@@ -4890,9 +4988,7 @@ void tst_QScriptEngine::translationContext_data()
void tst_QScriptEngine::translationContext()
{
- QTranslator translator;
- translator.load(":/translations/translatable_la");
- QCoreApplication::instance()->installTranslator(&translator);
+ TranslationScope tranScope(":/translations/translatable_la");
QScriptEngine engine;
engine.installTranslatorFunctions();
@@ -4903,17 +4999,13 @@ void tst_QScriptEngine::translationContext()
QScriptValue ret = engine.evaluate(QString::fromLatin1("qsTr('%0')").arg(text), path);
QVERIFY(ret.isString());
QCOMPARE(ret.toString(), expectedTranslation);
-
- QCoreApplication::instance()->removeTranslator(&translator);
}
void tst_QScriptEngine::translateScriptIdBased()
{
QScriptEngine engine;
- QTranslator translator;
- translator.load(":/translations/idtranslatable_la");
- QCoreApplication::instance()->installTranslator(&translator);
+ TranslationScope tranScope(":/translations/idtranslatable_la");
engine.installTranslatorFunctions();
QString fileName = QString::fromLatin1("idtranslatable.js");
@@ -4995,15 +5087,11 @@ void tst_QScriptEngine::translateScriptUnicode()
QScriptEngine engine;
- QTranslator translator;
- QVERIFY(translator.load(":/translations/translatable-unicode"));
- QCoreApplication::instance()->installTranslator(&translator);
+ TranslationScope tranScope(":/translations/translatable-unicode");
engine.installTranslatorFunctions();
QCOMPARE(engine.evaluate(expression, fileName).toString(), expectedTranslation);
QVERIFY(!engine.hasUncaughtException());
-
- QCoreApplication::instance()->removeTranslator(&translator);
}
void tst_QScriptEngine::translateScriptUnicodeIdBased_data()
@@ -5030,15 +5118,11 @@ void tst_QScriptEngine::translateScriptUnicodeIdBased()
QScriptEngine engine;
- QTranslator translator;
- QVERIFY(translator.load(":/translations/idtranslatable-unicode"));
- QCoreApplication::instance()->installTranslator(&translator);
+ TranslationScope tranScope(":/translations/idtranslatable-unicode");
engine.installTranslatorFunctions();
QCOMPARE(engine.evaluate(expression).toString(), expectedTranslation);
QVERIFY(!engine.hasUncaughtException());
-
- QCoreApplication::instance()->removeTranslator(&translator);
}
void tst_QScriptEngine::functionScopes()
diff --git a/tests/auto/qscriptvalue/tst_qscriptvalue.cpp b/tests/auto/qscriptvalue/tst_qscriptvalue.cpp
index de753d2..97bbf26 100644
--- a/tests/auto/qscriptvalue/tst_qscriptvalue.cpp
+++ b/tests/auto/qscriptvalue/tst_qscriptvalue.cpp
@@ -1341,52 +1341,53 @@ void tst_QScriptValue::toVariant()
}
}
-// unfortunately, this is necessary in order to do qscriptvalue_cast<QPushButton*>(...)
-Q_DECLARE_METATYPE(QPushButton*)
-
-void tst_QScriptValue::toQObject()
+void tst_QScriptValue::toQObject_nonQObject_data()
{
- QScriptEngine eng;
-
- QScriptValue undefined = eng.undefinedValue();
- QCOMPARE(undefined.toQObject(), (QObject *)0);
- QCOMPARE(qscriptvalue_cast<QObject*>(undefined), (QObject *)0);
+ newEngine();
+ QTest::addColumn<QScriptValue>("value");
- QScriptValue null = eng.nullValue();
- QCOMPARE(null.toQObject(), (QObject *)0);
- QCOMPARE(qscriptvalue_cast<QObject*>(null), (QObject *)0);
+ QTest::newRow("invalid") << QScriptValue();
+ QTest::newRow("bool(false)") << QScriptValue(false);
+ QTest::newRow("bool(true)") << QScriptValue(true);
+ QTest::newRow("int") << QScriptValue(123);
+ QTest::newRow("string") << QScriptValue(QString::fromLatin1("ciao"));
+ QTest::newRow("undefined") << QScriptValue(QScriptValue::UndefinedValue);
+ QTest::newRow("null") << QScriptValue(QScriptValue::NullValue);
- {
- QScriptValue falskt = QScriptValue(&eng, false);
- QCOMPARE(falskt.toQObject(), (QObject *)0);
- QCOMPARE(qscriptvalue_cast<QObject*>(falskt), (QObject *)0);
+ QTest::newRow("bool bound(false)") << QScriptValue(engine, false);
+ QTest::newRow("bool bound(true)") << QScriptValue(engine, true);
+ QTest::newRow("int bound") << QScriptValue(engine, 123);
+ QTest::newRow("string bound") << QScriptValue(engine, QString::fromLatin1("ciao"));
+ QTest::newRow("undefined bound") << engine->undefinedValue();
+ QTest::newRow("null bound") << engine->nullValue();
+ QTest::newRow("object") << engine->newObject();
+ QTest::newRow("array") << engine->newArray();
+ QTest::newRow("date") << engine->newDate(124);
+ QTest::newRow("variant(12345)") << engine->newVariant(12345);
+ QTest::newRow("variant((QObject*)0)") << engine->newVariant(qVariantFromValue((QObject*)0));
+ QTest::newRow("newQObject(0)") << engine->newQObject(0);
+}
- QScriptValue sant = QScriptValue(&eng, true);
- QCOMPARE(sant.toQObject(), (QObject *)0);
- QCOMPARE(qscriptvalue_cast<QObject*>(sant), (QObject *)0);
- QScriptValue number = QScriptValue(&eng, 123.0);
- QCOMPARE(number.toQObject(), (QObject *)0);
- QCOMPARE(qscriptvalue_cast<QObject*>(number), (QObject *)0);
+void tst_QScriptValue::toQObject_nonQObject()
+{
+ QFETCH(QScriptValue, value);
+ QCOMPARE(value.toQObject(), (QObject *)0);
+ QCOMPARE(qscriptvalue_cast<QObject*>(value), (QObject *)0);
+}
- QScriptValue str = QScriptValue(&eng, QString("ciao"));
- QCOMPARE(str.toQObject(), (QObject *)0);
- QCOMPARE(qscriptvalue_cast<QObject*>(str), (QObject *)0);
- }
+// unfortunately, this is necessary in order to do qscriptvalue_cast<QPushButton*>(...)
+Q_DECLARE_METATYPE(QPushButton*);
- QScriptValue object = eng.newObject();
- QCOMPARE(object.toQObject(), (QObject *)0);
- QCOMPARE(qscriptvalue_cast<QObject*>(object), (QObject *)0);
+void tst_QScriptValue::toQObject()
+{
+ QScriptEngine eng;
QScriptValue qobject = eng.newQObject(this);
QCOMPARE(qobject.toQObject(), (QObject *)this);
QCOMPARE(qscriptvalue_cast<QObject*>(qobject), (QObject *)this);
QCOMPARE(qscriptvalue_cast<QWidget*>(qobject), (QWidget *)0);
- QScriptValue qobject2 = eng.newQObject(0);
- QCOMPARE(qobject2.toQObject(), (QObject *)0);
- QCOMPARE(qscriptvalue_cast<QObject*>(qobject2), (QObject *)0);
-
QWidget widget;
QScriptValue qwidget = eng.newQObject(&widget);
QCOMPARE(qwidget.toQObject(), (QObject *)&widget);
@@ -1400,25 +1401,6 @@ void tst_QScriptValue::toQObject()
QCOMPARE(qscriptvalue_cast<QWidget*>(qbutton), (QWidget *)&button);
QCOMPARE(qscriptvalue_cast<QPushButton*>(qbutton), &button);
- // V2 constructors
- {
- QScriptValue falskt = QScriptValue(false);
- QCOMPARE(falskt.toQObject(), (QObject *)0);
- QCOMPARE(qscriptvalue_cast<QObject*>(falskt), (QObject *)0);
-
- QScriptValue sant = QScriptValue(true);
- QCOMPARE(sant.toQObject(), (QObject *)0);
- QCOMPARE(qscriptvalue_cast<QObject*>(sant), (QObject *)0);
-
- QScriptValue number = QScriptValue(123.0);
- QCOMPARE(number.toQObject(), (QObject *)0);
- QCOMPARE(qscriptvalue_cast<QObject*>(number), (QObject *)0);
-
- QScriptValue str = QScriptValue(QString("ciao"));
- QCOMPARE(str.toQObject(), (QObject *)0);
- QCOMPARE(qscriptvalue_cast<QObject*>(str), (QObject *)0);
- }
-
// wrapping a QObject* as variant
QScriptValue variant = eng.newVariant(qVariantFromValue((QObject*)&button));
QCOMPARE(variant.toQObject(), (QObject*)&button);
@@ -1437,10 +1419,6 @@ void tst_QScriptValue::toQObject()
QCOMPARE(qscriptvalue_cast<QObject*>(variant3), (QObject*)0);
QCOMPARE(qscriptvalue_cast<QWidget*>(variant3), (QWidget*)0);
QCOMPARE(qscriptvalue_cast<QPushButton*>(variant3), &button);
-
- QScriptValue inv;
- QCOMPARE(inv.toQObject(), (QObject *)0);
- QCOMPARE(qscriptvalue_cast<QObject*>(inv), (QObject *)0);
}
void tst_QScriptValue::toObject()
@@ -2937,127 +2915,169 @@ static QScriptValue ctorReturningNewObject(QScriptContext *, QScriptEngine *eng)
return result;
}
-void tst_QScriptValue::construct()
+void tst_QScriptValue::construct_nonFunction_data()
+{
+ newEngine();
+ QTest::addColumn<QScriptValue>("value");
+
+ QTest::newRow("invalid") << QScriptValue();
+ QTest::newRow("bool") << QScriptValue(false);
+ QTest::newRow("int") << QScriptValue(123);
+ QTest::newRow("string") << QScriptValue(QString::fromLatin1("ciao"));
+ QTest::newRow("undefined") << QScriptValue(QScriptValue::UndefinedValue);
+ QTest::newRow("null") << QScriptValue(QScriptValue::NullValue);
+
+ QTest::newRow("bool bound") << QScriptValue(engine, false);
+ QTest::newRow("int bound") << QScriptValue(engine, 123);
+ QTest::newRow("string bound") << QScriptValue(engine, QString::fromLatin1("ciao"));
+ QTest::newRow("undefined bound") << engine->undefinedValue();
+ QTest::newRow("null bound") << engine->nullValue();
+}
+
+void tst_QScriptValue::construct_nonFunction()
+{
+ QFETCH(QScriptValue, value);
+ QVERIFY(!value.construct().isValid());
+}
+
+void tst_QScriptValue::construct_simple()
{
QScriptEngine eng;
+ QScriptValue fun = eng.evaluate("(function () { this.foo = 123; })");
+ QVERIFY(fun.isFunction());
+ QScriptValue ret = fun.construct();
+ QVERIFY(ret.isObject());
+ QVERIFY(ret.instanceOf(fun));
+ QCOMPARE(ret.property("foo").toInt32(), 123);
+}
- {
- QScriptValue fun = eng.evaluate("(function () { this.foo = 123; })");
- QVERIFY(fun.isFunction());
- QScriptValue ret = fun.construct();
- QVERIFY(ret.isObject());
- QVERIFY(ret.instanceOf(fun));
- QCOMPARE(ret.property("foo").toInt32(), 123);
- }
+void tst_QScriptValue::construct_newObjectJS()
+{
+ QScriptEngine eng;
// returning a different object overrides the default-constructed one
- {
- QScriptValue fun = eng.evaluate("(function () { return { bar: 456 }; })");
- QVERIFY(fun.isFunction());
- QScriptValue ret = fun.construct();
- QVERIFY(ret.isObject());
- QVERIFY(!ret.instanceOf(fun));
- QCOMPARE(ret.property("bar").toInt32(), 456);
- }
+ QScriptValue fun = eng.evaluate("(function () { return { bar: 456 }; })");
+ QVERIFY(fun.isFunction());
+ QScriptValue ret = fun.construct();
+ QVERIFY(ret.isObject());
+ QVERIFY(!ret.instanceOf(fun));
+ QCOMPARE(ret.property("bar").toInt32(), 456);
+}
- {
- QScriptValue fun = eng.newFunction(ctorReturningUndefined);
- QScriptValue ret = fun.construct();
- QVERIFY(ret.isObject());
- QVERIFY(ret.instanceOf(fun));
- QCOMPARE(ret.property("foo").toInt32(), 123);
- }
- {
- QScriptValue fun = eng.newFunction(ctorReturningNewObject);
- QScriptValue ret = fun.construct();
- QVERIFY(ret.isObject());
- QVERIFY(!ret.instanceOf(fun));
- QCOMPARE(ret.property("bar").toInt32(), 456);
- }
+void tst_QScriptValue::construct_undefined()
+{
+ QScriptEngine eng;
+ QScriptValue fun = eng.newFunction(ctorReturningUndefined);
+ QScriptValue ret = fun.construct();
+ QVERIFY(ret.isObject());
+ QVERIFY(ret.instanceOf(fun));
+ QCOMPARE(ret.property("foo").toInt32(), 123);
+}
+void tst_QScriptValue::construct_newObjectCpp()
+{
+ QScriptEngine eng;
+ QScriptValue fun = eng.newFunction(ctorReturningNewObject);
+ QScriptValue ret = fun.construct();
+ QVERIFY(ret.isObject());
+ QVERIFY(!ret.instanceOf(fun));
+ QCOMPARE(ret.property("bar").toInt32(), 456);
+}
+
+void tst_QScriptValue::construct_arg()
+{
+ QScriptEngine eng;
QScriptValue Number = eng.evaluate("Number");
QCOMPARE(Number.isFunction(), true);
- {
- QScriptValueList args;
- args << QScriptValue(&eng, 123);
- QScriptValue ret = Number.construct(args);
- QCOMPARE(ret.isObject(), true);
- QCOMPARE(ret.toNumber(), args.at(0).toNumber());
- }
+ QScriptValueList args;
+ args << QScriptValue(&eng, 123);
+ QScriptValue ret = Number.construct(args);
+ QCOMPARE(ret.isObject(), true);
+ QCOMPARE(ret.toNumber(), args.at(0).toNumber());
+}
+void tst_QScriptValue::construct_proto()
+{
+ QScriptEngine eng;
// test that internal prototype is set correctly
- {
- QScriptValue fun = eng.evaluate("(function() { return this.__proto__; })");
- QCOMPARE(fun.isFunction(), true);
- QCOMPARE(fun.property("prototype").isObject(), true);
- QScriptValue ret = fun.construct();
- QCOMPARE(fun.property("prototype").strictlyEquals(ret), true);
- }
+ QScriptValue fun = eng.evaluate("(function() { return this.__proto__; })");
+ QCOMPARE(fun.isFunction(), true);
+ QCOMPARE(fun.property("prototype").isObject(), true);
+ QScriptValue ret = fun.construct();
+ QCOMPARE(fun.property("prototype").strictlyEquals(ret), true);
+}
+void tst_QScriptValue::construct_returnInt()
+{
+ QScriptEngine eng;
// test that we return the new object even if a non-object value is returned from the function
- {
- QScriptValue fun = eng.evaluate("(function() { return 123; })");
- QCOMPARE(fun.isFunction(), true);
- QScriptValue ret = fun.construct();
- QCOMPARE(ret.isObject(), true);
- }
+ QScriptValue fun = eng.evaluate("(function() { return 123; })");
+ QCOMPARE(fun.isFunction(), true);
+ QScriptValue ret = fun.construct();
+ QCOMPARE(ret.isObject(), true);
+}
- {
- QScriptValue fun = eng.evaluate("(function() { throw new Error('foo'); })");
- QCOMPARE(fun.isFunction(), true);
- QScriptValue ret = fun.construct();
- QCOMPARE(ret.isError(), true);
- QCOMPARE(eng.hasUncaughtException(), true);
- QVERIFY(ret.strictlyEquals(eng.uncaughtException()));
- }
+void tst_QScriptValue::construct_throw()
+{
+ QScriptEngine eng;
+ QScriptValue fun = eng.evaluate("(function() { throw new Error('foo'); })");
+ QCOMPARE(fun.isFunction(), true);
+ QScriptValue ret = fun.construct();
+ QCOMPARE(ret.isError(), true);
+ QCOMPARE(eng.hasUncaughtException(), true);
+ QVERIFY(ret.strictlyEquals(eng.uncaughtException()));
+}
- QScriptValue inv;
- QCOMPARE(inv.construct().isValid(), false);
+void tst_QScriptValue::construct()
+{
+ QScriptEngine eng;
+ QScriptValue fun = eng.evaluate("(function() { return arguments; })");
+ QVERIFY(fun.isFunction());
+ QScriptValue array = eng.newArray(3);
+ array.setProperty(0, QScriptValue(&eng, 123.0));
+ array.setProperty(1, QScriptValue(&eng, 456.0));
+ array.setProperty(2, QScriptValue(&eng, 789.0));
+ // construct with single array object as arguments
+ QScriptValue ret = fun.construct(array);
+ QVERIFY(!eng.hasUncaughtException());
+ QVERIFY(ret.isValid());
+ QVERIFY(ret.isObject());
+ QCOMPARE(ret.property(0).strictlyEquals(array.property(0)), true);
+ QCOMPARE(ret.property(1).strictlyEquals(array.property(1)), true);
+ QCOMPARE(ret.property(2).strictlyEquals(array.property(2)), true);
+ // construct with arguments object as arguments
+ QScriptValue ret2 = fun.construct(ret);
+ QCOMPARE(ret2.property(0).strictlyEquals(ret.property(0)), true);
+ QCOMPARE(ret2.property(1).strictlyEquals(ret.property(1)), true);
+ QCOMPARE(ret2.property(2).strictlyEquals(ret.property(2)), true);
+ // construct with null as arguments
+ QScriptValue ret3 = fun.construct(eng.nullValue());
+ QCOMPARE(ret3.isError(), false);
+ QCOMPARE(ret3.property("length").isNumber(), true);
+ QCOMPARE(ret3.property("length").toNumber(), 0.0);
+ // construct with undefined as arguments
+ QScriptValue ret4 = fun.construct(eng.undefinedValue());
+ QCOMPARE(ret4.isError(), false);
+ QCOMPARE(ret4.property("length").isNumber(), true);
+ QCOMPARE(ret4.property("length").toNumber(), 0.0);
+ // construct with something else as arguments
+ QScriptValue ret5 = fun.construct(QScriptValue(&eng, 123.0));
+ QCOMPARE(ret5.isError(), true);
+ // construct with a non-array object as arguments
+ QScriptValue ret6 = fun.construct(eng.globalObject());
+ QVERIFY(ret6.isError());
+ QCOMPARE(ret6.toString(), QString::fromLatin1("TypeError: Arguments must be an array"));
+}
- {
- QScriptValue fun = eng.evaluate("(function() { return arguments; })");
- QVERIFY(fun.isFunction());
- QScriptValue array = eng.newArray(3);
- array.setProperty(0, QScriptValue(&eng, 123.0));
- array.setProperty(1, QScriptValue(&eng, 456.0));
- array.setProperty(2, QScriptValue(&eng, 789.0));
- // construct with single array object as arguments
- QScriptValue ret = fun.construct(array);
- QVERIFY(!eng.hasUncaughtException());
- QVERIFY(ret.isValid());
- QVERIFY(ret.isObject());
- QCOMPARE(ret.property(0).strictlyEquals(array.property(0)), true);
- QCOMPARE(ret.property(1).strictlyEquals(array.property(1)), true);
- QCOMPARE(ret.property(2).strictlyEquals(array.property(2)), true);
- // construct with arguments object as arguments
- QScriptValue ret2 = fun.construct(ret);
- QCOMPARE(ret2.property(0).strictlyEquals(ret.property(0)), true);
- QCOMPARE(ret2.property(1).strictlyEquals(ret.property(1)), true);
- QCOMPARE(ret2.property(2).strictlyEquals(ret.property(2)), true);
- // construct with null as arguments
- QScriptValue ret3 = fun.construct(eng.nullValue());
- QCOMPARE(ret3.isError(), false);
- QCOMPARE(ret3.property("length").isNumber(), true);
- QCOMPARE(ret3.property("length").toNumber(), 0.0);
- // construct with undefined as arguments
- QScriptValue ret4 = fun.construct(eng.undefinedValue());
- QCOMPARE(ret4.isError(), false);
- QCOMPARE(ret4.property("length").isNumber(), true);
- QCOMPARE(ret4.property("length").toNumber(), 0.0);
- // construct with something else as arguments
- QScriptValue ret5 = fun.construct(QScriptValue(&eng, 123.0));
- QCOMPARE(ret5.isError(), true);
- // construct with a non-array object as arguments
- QScriptValue ret6 = fun.construct(eng.globalObject());
- QVERIFY(ret6.isError());
- QCOMPARE(ret6.toString(), QString::fromLatin1("TypeError: Arguments must be an array"));
- }
-
- // construct on things that are not functions
- QVERIFY(!QScriptValue(false).construct().isValid());
- QVERIFY(!QScriptValue(123).construct().isValid());
- QVERIFY(!QScriptValue(QString::fromLatin1("ciao")).construct().isValid());
- QVERIFY(!QScriptValue(QScriptValue::UndefinedValue).construct().isValid());
- QVERIFY(!QScriptValue(QScriptValue::NullValue).construct().isValid());
+void tst_QScriptValue::construct_twoEngines()
+{
+ QScriptEngine engine;
+ QScriptEngine otherEngine;
+ QScriptValue ctor = engine.evaluate("(function (a, b) { this.foo = 123; })");
+ QScriptValue arg(&otherEngine, 124567);
+ QTest::ignoreMessage(QtWarningMsg, "QScriptValue::construct() failed: cannot construct function with argument created in a different engine");
+ QVERIFY(!ctor.construct(arg).isValid());
+ QTest::ignoreMessage(QtWarningMsg, "QScriptValue::construct() failed: cannot construct function with argument created in a different engine");
+ QVERIFY(!ctor.construct(QScriptValueList() << arg << otherEngine.newObject()).isValid());
}
void tst_QScriptValue::construct_constructorThrowsPrimitive()
diff --git a/tests/auto/qscriptvalue/tst_qscriptvalue.h b/tests/auto/qscriptvalue/tst_qscriptvalue.h
index 7bf0b66..46f5526 100644
--- a/tests/auto/qscriptvalue/tst_qscriptvalue.h
+++ b/tests/auto/qscriptvalue/tst_qscriptvalue.h
@@ -91,6 +91,8 @@ private slots:
void toUInt32();
void toUInt16();
void toVariant();
+ void toQObject_nonQObject_data();
+ void toQObject_nonQObject();
void toQObject();
void toDateTime();
void toRegExp();
@@ -155,7 +157,18 @@ private slots:
void call_array();
void call_nonFunction_data();
void call_nonFunction();
+ void construct_nonFunction_data();
+ void construct_nonFunction();
+ void construct_simple();
+ void construct_newObjectJS();
+ void construct_undefined();
+ void construct_newObjectCpp();
+ void construct_arg();
+ void construct_proto();
+ void construct_returnInt();
+ void construct_throw();
void construct();
+ void construct_twoEngines();
void construct_constructorThrowsPrimitive();
void castToPointer();
void prettyPrinter_data();
diff --git a/tools/linguist/lupdate/qscript.cpp b/tools/linguist/lupdate/qscript.cpp
index 5323022..f9aff34 100644
--- a/tools/linguist/lupdate/qscript.cpp
+++ b/tools/linguist/lupdate/qscript.cpp
@@ -67,6 +67,8 @@ class LU {
Q_DECLARE_TR_FUNCTIONS(LUpdate)
};
+static QString MagicComment(QLatin1String("TRANSLATOR"));
+
class QScriptGrammar
{
public:
@@ -2092,8 +2094,9 @@ public:
~QScriptParser();
void setLexer(QScript::Lexer *);
+ void setTranslator(Translator *);
- bool parse(Translator *translator);
+ bool parse();
QString fileName() const
{ return lexer->fileName(); }
@@ -2129,6 +2132,8 @@ protected:
private:
QScript::Lexer *lexer;
+ Translator *translator;
+ QString trcontext;
QString extracomment;
QString msgid;
QString sourcetext;
@@ -2160,7 +2165,8 @@ QScriptParser::QScriptParser():
sym_stack(0),
state_stack(0),
location_stack(0),
- lexer(0)
+ lexer(0),
+ translator(0)
{
}
@@ -2187,9 +2193,17 @@ void QScriptParser::setLexer(QScript::Lexer *lex)
lexer = lex;
}
-bool QScriptParser::parse(Translator *translator)
+void QScriptParser::setTranslator(Translator *tor)
+{
+ translator = tor;
+}
+
+bool QScriptParser::parse()
{
Q_ASSERT(lexer != 0);
+ Q_ASSERT(translator != 0);
+ trcontext = QFileInfo(fileName()).baseName();
+
const int INITIAL_STATE = 0;
int yytoken = -1;
@@ -2303,11 +2317,10 @@ case 66: {
if (args.at(0).type() != QVariant::String) {
yyMsg(identLineNo) << qPrintable(LU::tr("%1(): text to translate must be a literal string.\n").arg(name));
} else {
- QString context = QFileInfo(fileName()).baseName();
QString text = args.at(0).toString();
QString comment = args.value(1).toString();
bool plural = (args.size() > 2);
- recordMessage(translator, context, text, comment, extracomment,
+ recordMessage(translator, trcontext, text, comment, extracomment,
msgid, extra, plural, fileName(), identLineNo);
}
}
@@ -2533,6 +2546,32 @@ void QScriptParser::processComment(const QChar *chars, int length)
}
}
sourcetext.resize(ptr - (ushort *)sourcetext.data());
+ } else {
+ int idx = 0;
+ ushort c;
+ while ((c = chars[idx].unicode()) == ' ' || c == '\t' || c == '\n')
+ ++idx;
+ if (!memcmp(chars + idx, MagicComment.unicode(), MagicComment.length() * 2)) {
+ idx += MagicComment.length();
+ QString comment = QString(chars + idx, length - idx).simplified();
+ int k = comment.indexOf(QLatin1Char(' '));
+ if (k == -1) {
+ trcontext = comment;
+ } else {
+ trcontext = comment.left(k);
+ comment.remove(0, k + 1);
+ TranslatorMessage msg(
+ trcontext, QString(),
+ comment, QString(),
+ fileName(), lexer->startLineNo(), QStringList(),
+ TranslatorMessage::Finished, /*plural=*/false);
+ msg.setExtraComment(extracomment.simplified());
+ extracomment.clear();
+ translator->append(msg);
+ translator->setExtras(extra);
+ extra.clear();
+ }
+ }
}
}
@@ -2558,7 +2597,8 @@ bool loadQScript(Translator &translator, const QString &filename, ConversionData
QScript::Lexer lexer(&parser);
lexer.setCode(code, filename, /*lineNumber=*/1);
parser.setLexer(&lexer);
- if (!parser.parse(&translator)) {
+ parser.setTranslator(&translator);
+ if (!parser.parse()) {
std::cerr << qPrintable(filename) << ':' << parser.errorLineNumber() << ": "
<< qPrintable(parser.errorMessage()) << std::endl;
return false;
diff --git a/tools/linguist/lupdate/qscript.g b/tools/linguist/lupdate/qscript.g
index 3655f2e..1335f55 100644
--- a/tools/linguist/lupdate/qscript.g
+++ b/tools/linguist/lupdate/qscript.g
@@ -104,6 +104,8 @@ class LU {
Q_DECLARE_TR_FUNCTIONS(LUpdate)
};
+static QString MagicComment(QLatin1String("TRANSLATOR"));
+
static void recordMessage(
Translator *tor, const QString &context, const QString &text, const QString &comment,
const QString &extracomment, const QString &msgid, const TranslatorMessage::ExtraData &extra,
@@ -1423,8 +1425,9 @@ public:
~QScriptParser();
void setLexer(QScript::Lexer *);
+ void setTranslator(Translator *);
- bool parse(Translator *translator);
+ bool parse();
QString fileName() const
{ return lexer->fileName(); }
@@ -1460,6 +1463,8 @@ protected:
private:
QScript::Lexer *lexer;
+ Translator *translator;
+ QString trcontext;
QString extracomment;
QString msgid;
QString sourcetext;
@@ -1491,7 +1496,8 @@ QScriptParser::QScriptParser():
sym_stack(0),
state_stack(0),
location_stack(0),
- lexer(0)
+ lexer(0),
+ translator(0)
{
}
@@ -1518,9 +1524,17 @@ void QScriptParser::setLexer(QScript::Lexer *lex)
lexer = lex;
}
-bool QScriptParser::parse(Translator *translator)
+void QScriptParser::setTranslator(Translator *tor)
+{
+ translator = tor;
+}
+
+bool QScriptParser::parse()
{
Q_ASSERT(lexer != 0);
+ Q_ASSERT(translator != 0);
+ trcontext = QFileInfo(fileName()).baseName();
+
const int INITIAL_STATE = 0;
int yytoken = -1;
@@ -1719,11 +1733,10 @@ case $rule_number: {
if (args.at(0).type() != QVariant::String) {
yyMsg(identLineNo) << qPrintable(LU::tr("%1(): text to translate must be a literal string.\n").arg(name));
} else {
- QString context = QFileInfo(fileName()).baseName();
QString text = args.at(0).toString();
QString comment = args.value(1).toString();
bool plural = (args.size() > 2);
- recordMessage(translator, context, text, comment, extracomment,
+ recordMessage(translator, trcontext, text, comment, extracomment,
msgid, extra, plural, fileName(), identLineNo);
}
}
@@ -2181,6 +2194,32 @@ void QScriptParser::processComment(const QChar *chars, int length)
}
}
sourcetext.resize(ptr - (ushort *)sourcetext.data());
+ } else {
+ int idx = 0;
+ ushort c;
+ while ((c = chars[idx].unicode()) == ' ' || c == '\t' || c == '\n')
+ ++idx;
+ if (!memcmp(chars + idx, MagicComment.unicode(), MagicComment.length() * 2)) {
+ idx += MagicComment.length();
+ QString comment = QString(chars + idx, length - idx).simplified();
+ int k = comment.indexOf(QLatin1Char(' '));
+ if (k == -1) {
+ trcontext = comment;
+ } else {
+ trcontext = comment.left(k);
+ comment.remove(0, k + 1);
+ TranslatorMessage msg(
+ trcontext, QString(),
+ comment, QString(),
+ fileName(), lexer->startLineNo(), QStringList(),
+ TranslatorMessage::Finished, /*plural=*/false);
+ msg.setExtraComment(extracomment.simplified());
+ extracomment.clear();
+ translator->append(msg);
+ translator->setExtras(extra);
+ extra.clear();
+ }
+ }
}
}
@@ -2206,7 +2245,8 @@ bool loadQScript(Translator &translator, const QString &filename, ConversionData
QScript::Lexer lexer(&parser);
lexer.setCode(code, filename, /*lineNumber=*/1);
parser.setLexer(&lexer);
- if (!parser.parse(&translator)) {
+ parser.setTranslator(&translator);
+ if (!parser.parse()) {
std::cerr << qPrintable(filename) << ':' << parser.errorLineNumber() << ": "
<< qPrintable(parser.errorMessage()) << std::endl;
return false;