diff options
author | Kai Uwe Broulik <kde@privat.broulik.de> | 2016-04-13 12:53:30 +0200 |
---|---|---|
committer | Kai Uwe Broulik <kde@privat.broulik.de> | 2016-04-28 08:32:35 +0000 |
commit | 7a0f3269b1dc2d6de6b6ce6b478e02cca794404b (patch) | |
tree | e18b57f7c0c26d348d7bfae620c29f1f1422085c | |
parent | 9e44c5594f0fb8c81c917796dd4f44a1698a6632 (diff) |
Add some ECMAScript 6 Number and Math methods and properties
This adds the Number.EPSILON property, the Number.isFinite, Number.isNaN,
and Math.sign methods introduced in ECMAScript 6.
Change-Id: Ib16408a63c202a4ef30a14334f65ac3a1a13cfaf
Reviewed-by: Michael Brasser <michael.brasser@live.com>
Reviewed-by: Lars Knoll <lars.knoll@theqtcompany.com>
-rw-r--r-- | src/qml/doc/src/javascript/functionlist.qdoc | 10 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4mathobject.cpp | 14 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4mathobject_p.h | 1 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4numberobject.cpp | 23 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4numberobject_p.h | 2 | ||||
-rw-r--r-- | tests/auto/qml/qjsengine/tst_qjsengine.cpp | 48 |
6 files changed, 98 insertions, 0 deletions
diff --git a/src/qml/doc/src/javascript/functionlist.qdoc b/src/qml/doc/src/javascript/functionlist.qdoc index 8b9c33f994..8e71e9fbb3 100644 --- a/src/qml/doc/src/javascript/functionlist.qdoc +++ b/src/qml/doc/src/javascript/functionlist.qdoc @@ -231,6 +231,15 @@ \li \l {Number::toLocaleString}{toLocaleString(locale, format, precision)} \endlist + \section2 The Number Object + + \section3 Function Properties + + \list + \li isFinite(x) // ECMAScript 6: Added in Qt 5.8 + \li isNaN(x) // ECMAScript 6: Added in Qt 5.8 + \endlist + \section1 The Math Object \section2 Value Properties @@ -264,6 +273,7 @@ \li pow(x, y) \li random() \li round(x) + \li sign(x) // ECMAScript 6: Added in Qt 5.8 \li sin(x) \li sqrt(x) \li tan(x) diff --git a/src/qml/jsruntime/qv4mathobject.cpp b/src/qml/jsruntime/qv4mathobject.cpp index 4a304b6138..df1c8c6049 100644 --- a/src/qml/jsruntime/qv4mathobject.cpp +++ b/src/qml/jsruntime/qv4mathobject.cpp @@ -80,6 +80,7 @@ Heap::MathObject::MathObject() m->defineDefaultProperty(QStringLiteral("pow"), QV4::MathObject::method_pow, 2); m->defineDefaultProperty(QStringLiteral("random"), QV4::MathObject::method_random, 0); m->defineDefaultProperty(QStringLiteral("round"), QV4::MathObject::method_round, 1); + m->defineDefaultProperty(QStringLiteral("sign"), QV4::MathObject::method_sign, 1); m->defineDefaultProperty(QStringLiteral("sin"), QV4::MathObject::method_sin, 1); m->defineDefaultProperty(QStringLiteral("sqrt"), QV4::MathObject::method_sqrt, 1); m->defineDefaultProperty(QStringLiteral("tan"), QV4::MathObject::method_tan, 1); @@ -299,6 +300,19 @@ ReturnedValue MathObject::method_round(CallContext *context) return Encode(v); } +ReturnedValue MathObject::method_sign(CallContext *context) +{ + double v = context->argc() ? context->args()[0].toNumber() : qt_qnan(); + + if (std::isnan(v)) + return Encode(qt_qnan()); + + if (qIsNull(v)) + return v; + + return Encode(std::signbit(v) ? -1 : 1); +} + ReturnedValue MathObject::method_sin(CallContext *context) { double v = context->argc() ? context->args()[0].toNumber() : qt_qnan(); diff --git a/src/qml/jsruntime/qv4mathobject_p.h b/src/qml/jsruntime/qv4mathobject_p.h index 2b842a312f..01e778d9ec 100644 --- a/src/qml/jsruntime/qv4mathobject_p.h +++ b/src/qml/jsruntime/qv4mathobject_p.h @@ -84,6 +84,7 @@ struct MathObject: Object static ReturnedValue method_pow(CallContext *context); static ReturnedValue method_random(CallContext *context); static ReturnedValue method_round(CallContext *context); + static ReturnedValue method_sign(CallContext *context); static ReturnedValue method_sin(CallContext *context); static ReturnedValue method_sqrt(CallContext *context); static ReturnedValue method_tan(CallContext *context); diff --git a/src/qml/jsruntime/qv4numberobject.cpp b/src/qml/jsruntime/qv4numberobject.cpp index ab3e03b183..f6b3e9a2b3 100644 --- a/src/qml/jsruntime/qv4numberobject.cpp +++ b/src/qml/jsruntime/qv4numberobject.cpp @@ -45,6 +45,7 @@ #include <QtCore/qmath.h> #include <QtCore/QDebug> #include <cassert> +#include <limits> using namespace QV4; @@ -99,12 +100,16 @@ void NumberPrototype::init(ExecutionEngine *engine, Object *ctor) ctor->defineReadonlyProperty(QStringLiteral("NEGATIVE_INFINITY"), Primitive::fromDouble(-qInf())); ctor->defineReadonlyProperty(QStringLiteral("POSITIVE_INFINITY"), Primitive::fromDouble(qInf())); ctor->defineReadonlyProperty(QStringLiteral("MAX_VALUE"), Primitive::fromDouble(1.7976931348623158e+308)); + ctor->defineReadonlyProperty(QStringLiteral("EPSILON"), Primitive::fromDouble(std::numeric_limits<double>::epsilon())); QT_WARNING_PUSH QT_WARNING_DISABLE_INTEL(239) ctor->defineReadonlyProperty(QStringLiteral("MIN_VALUE"), Primitive::fromDouble(5e-324)); QT_WARNING_POP + ctor->defineDefaultProperty(QStringLiteral("isFinite"), method_isFinite, 1); + ctor->defineDefaultProperty(QStringLiteral("isNaN"), method_isNaN, 1); + defineDefaultProperty(QStringLiteral("constructor"), (o = ctor)); defineDefaultProperty(engine->id_toString(), method_toString); defineDefaultProperty(QStringLiteral("toLocaleString"), method_toLocaleString); @@ -134,6 +139,24 @@ inline double thisNumber(ExecutionContext *ctx) return n->value(); } +ReturnedValue NumberPrototype::method_isFinite(CallContext *ctx) +{ + if (!ctx->argc()) + return Encode(false); + + double v = ctx->args()[0].toNumber(); + return Encode(!std::isnan(v) && !qt_is_inf(v)); +} + +ReturnedValue NumberPrototype::method_isNaN(CallContext *ctx) +{ + if (!ctx->argc()) + return Encode(false); + + double v = ctx->args()[0].toNumber(); + return Encode(std::isnan(v)); +} + ReturnedValue NumberPrototype::method_toString(CallContext *ctx) { Scope scope(ctx); diff --git a/src/qml/jsruntime/qv4numberobject_p.h b/src/qml/jsruntime/qv4numberobject_p.h index ca6f686304..bbe22af4bb 100644 --- a/src/qml/jsruntime/qv4numberobject_p.h +++ b/src/qml/jsruntime/qv4numberobject_p.h @@ -87,6 +87,8 @@ struct NumberPrototype: NumberObject { void init(ExecutionEngine *engine, Object *ctor); + static ReturnedValue method_isFinite(CallContext *ctx); + static ReturnedValue method_isNaN(CallContext *ctx); static ReturnedValue method_toString(CallContext *ctx); static ReturnedValue method_toLocaleString(CallContext *ctx); static ReturnedValue method_valueOf(CallContext *ctx); diff --git a/tests/auto/qml/qjsengine/tst_qjsengine.cpp b/tests/auto/qml/qjsengine/tst_qjsengine.cpp index c535258c19..adf944c7e1 100644 --- a/tests/auto/qml/qjsengine/tst_qjsengine.cpp +++ b/tests/auto/qml/qjsengine/tst_qjsengine.cpp @@ -1024,11 +1024,14 @@ void tst_QJSEngine::builtinFunctionNames_data() QTest::newRow("Math.pow") << QString("Math.pow") << QString("pow"); QTest::newRow("Math.random") << QString("Math.random") << QString("random"); QTest::newRow("Math.round") << QString("Math.round") << QString("round"); + QTest::newRow("Math.sign") << QString("Math.sign") << QString("sign"); QTest::newRow("Math.sin") << QString("Math.sin") << QString("sin"); QTest::newRow("Math.sqrt") << QString("Math.sqrt") << QString("sqrt"); QTest::newRow("Math.tan") << QString("Math.tan") << QString("tan"); QTest::newRow("Number") << QString("Number") << QString("Number"); + QTest::newRow("Number.isFinite") << QString("Number.isFinite") << QString("isFinite"); + QTest::newRow("Number.isNaN") << QString("Number.isNaN") << QString("isNaN"); QTest::newRow("Number.prototype.toString") << QString("Number.prototype.toString") << QString("toString"); QTest::newRow("Number.prototype.toLocaleString") << QString("Number.prototype.toLocaleString") << QString("toLocaleString"); QTest::newRow("Number.prototype.valueOf") << QString("Number.prototype.valueOf") << QString("valueOf"); @@ -1920,6 +1923,7 @@ void tst_QJSEngine::jsNumberClass() QVERIFY(ctor.property("NaN").isNumber()); QVERIFY(ctor.property("NEGATIVE_INFINITY").isNumber()); QVERIFY(ctor.property("POSITIVE_INFINITY").isNumber()); + QVERIFY(ctor.property("EPSILON").isNumber()); } QCOMPARE(proto.toNumber(), qreal(0)); QVERIFY(proto.property("constructor").strictlyEquals(ctor)); @@ -1958,6 +1962,50 @@ void tst_QJSEngine::jsNumberClass() QCOMPARE(ret.toNumber(), qreal(456)); } + QVERIFY(ctor.property("isFinite").isCallable()); + { + QJSValue ret = eng.evaluate("Number.isFinite()"); + QVERIFY(ret.isBool()); + QCOMPARE(ret.toBool(), false); + } + { + QJSValue ret = eng.evaluate("Number.isFinite(NaN)"); + QVERIFY(ret.isBool()); + QCOMPARE(ret.toBool(), false); + } + { + QJSValue ret = eng.evaluate("Number.isFinite(Infinity)"); + QVERIFY(ret.isBool()); + QCOMPARE(ret.toBool(), false); + } + { + QJSValue ret = eng.evaluate("Number.isFinite(-Infinity)"); + QVERIFY(ret.isBool()); + QCOMPARE(ret.toBool(), false); + } + { + QJSValue ret = eng.evaluate("Number.isFinite(123)"); + QVERIFY(ret.isBool()); + QCOMPARE(ret.toBool(), true); + } + + QVERIFY(ctor.property("isNaN").isCallable()); + { + QJSValue ret = eng.evaluate("Number.isNaN()"); + QVERIFY(ret.isBool()); + QCOMPARE(ret.toBool(), false); + } + { + QJSValue ret = eng.evaluate("Number.isNaN(NaN)"); + QVERIFY(ret.isBool()); + QCOMPARE(ret.toBool(), true); + } + { + QJSValue ret = eng.evaluate("Number.isNaN(123)"); + QVERIFY(ret.isBool()); + QCOMPARE(ret.toBool(), false); + } + QVERIFY(proto.property("toString").isCallable()); { QJSValue ret = eng.evaluate("new Number(123).toString()"); |