Commit 0be4c58b authored by Tom Schuster's avatar Tom Schuster
Browse files

Bug 1536860 - Warn about deprecated Array generics. r=jorendorff

Differential Revision: https://phabricator.services.mozilla.com/D24207

--HG--
extra : moz-landing-system : lando
parent ed07da86
Loading
Loading
Loading
Loading
+19 −0
Original line number Diff line number Diff line
@@ -45,6 +45,7 @@ function ArrayIndexOf(searchElement/*, fromIndex*/) {
}

function ArrayStaticIndexOf(list, searchElement/*, fromIndex*/) {
    WarnDeprecatedArrayMethod(ARRAY_GENERICS_INDEXOF, "indexOf");
    if (arguments.length < 1)
        ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, "Array.indexOf");
    var fromIndex = arguments.length > 2 ? arguments[2] : 0;
@@ -86,6 +87,7 @@ function ArrayLastIndexOf(searchElement/*, fromIndex*/) {
}

function ArrayStaticLastIndexOf(list, searchElement/*, fromIndex*/) {
    WarnDeprecatedArrayMethod(ARRAY_GENERICS_LASTINDEXOF, "lastIndexOf");
    if (arguments.length < 1)
        ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, "Array.lastIndexOf");
    var fromIndex;
@@ -132,6 +134,7 @@ function ArrayEvery(callbackfn/*, thisArg*/) {
}

function ArrayStaticEvery(list, callbackfn/*, thisArg*/) {
    WarnDeprecatedArrayMethod(ARRAY_GENERICS_EVERY, "every");
    if (arguments.length < 2)
        ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, "Array.every");
    if (!IsCallable(callbackfn))
@@ -173,6 +176,7 @@ function ArraySome(callbackfn/*, thisArg*/) {
}

function ArrayStaticSome(list, callbackfn/*, thisArg*/) {
    WarnDeprecatedArrayMethod(ARRAY_GENERICS_SOME, "some");
    if (arguments.length < 2)
        ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, "Array.some");
    if (!IsCallable(callbackfn))
@@ -258,6 +262,7 @@ function ArrayForEach(callbackfn/*, thisArg*/) {
}

function ArrayStaticForEach(list, callbackfn/*, thisArg*/) {
    WarnDeprecatedArrayMethod(ARRAY_GENERICS_FOREACH, "forEach");
    if (arguments.length < 2)
        ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, "Array.forEach");
    if (!IsCallable(callbackfn))
@@ -302,6 +307,7 @@ function ArrayMap(callbackfn/*, thisArg*/) {
}

function ArrayStaticMap(list, callbackfn/*, thisArg*/) {
    WarnDeprecatedArrayMethod(ARRAY_GENERICS_MAP, "map");
    if (arguments.length < 2)
        ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, "Array.map");
    if (!IsCallable(callbackfn))
@@ -350,6 +356,7 @@ function ArrayFilter(callbackfn/*, thisArg*/) {
}

function ArrayStaticFilter(list, callbackfn/*, thisArg*/) {
    WarnDeprecatedArrayMethod(ARRAY_GENERICS_FILTER, "filter");
    if (arguments.length < 2)
        ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, "Array.filter");
    if (!IsCallable(callbackfn))
@@ -418,6 +425,7 @@ function ArrayReduce(callbackfn/*, initialValue*/) {
}

function ArrayStaticReduce(list, callbackfn) {
    WarnDeprecatedArrayMethod(ARRAY_GENERICS_REDUCE, "reduce");
    if (arguments.length < 2)
        ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, "Array.reduce");
    if (!IsCallable(callbackfn))
@@ -489,6 +497,7 @@ function ArrayReduceRight(callbackfn/*, initialValue*/) {
}

function ArrayStaticReduceRight(list, callbackfn) {
    WarnDeprecatedArrayMethod(ARRAY_GENERICS_REDUCERIGHT, "reduceRight");
    if (arguments.length < 2)
        ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, "Array.reduceRight");
    if (!IsCallable(callbackfn))
@@ -1221,6 +1230,7 @@ function FlattenIntoArray(target, source, sourceLen, start, depth, mapperFunctio
}

function ArrayStaticConcat(arr, arg1) {
    WarnDeprecatedArrayMethod(ARRAY_GENERICS_CONCAT, "concat");
    if (arguments.length < 1)
        ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, "Array.concat");
    var args = callFunction(std_Array_slice, arguments, 1);
@@ -1228,24 +1238,28 @@ function ArrayStaticConcat(arr, arg1) {
}

function ArrayStaticJoin(arr, separator) {
    WarnDeprecatedArrayMethod(ARRAY_GENERICS_JOIN, "join");
    if (arguments.length < 1)
        ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, "Array.join");
    return callFunction(std_Array_join, arr, separator);
}

function ArrayStaticReverse(arr) {
    WarnDeprecatedArrayMethod(ARRAY_GENERICS_REVERSE, "reverse");
    if (arguments.length < 1)
        ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, "Array.reverse");
    return callFunction(std_Array_reverse, arr);
}

function ArrayStaticSort(arr, comparefn) {
    WarnDeprecatedArrayMethod(ARRAY_GENERICS_SORT, "sort");
    if (arguments.length < 1)
        ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, "Array.sort");
    return callFunction(ArraySort, arr, comparefn);
}

function ArrayStaticPush(arr, arg1) {
    WarnDeprecatedArrayMethod(ARRAY_GENERICS_PUSH, "push");
    if (arguments.length < 1)
        ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, "Array.push");
    var args = callFunction(std_Array_slice, arguments, 1);
@@ -1253,18 +1267,21 @@ function ArrayStaticPush(arr, arg1) {
}

function ArrayStaticPop(arr) {
    WarnDeprecatedArrayMethod(ARRAY_GENERICS_POP, "pop");
    if (arguments.length < 1)
        ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, "Array.pop");
    return callFunction(std_Array_pop, arr);
}

function ArrayStaticShift(arr) {
    WarnDeprecatedArrayMethod(ARRAY_GENERICS_SHIFT, "shift");
    if (arguments.length < 1)
        ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, "Array.shift");
    return callFunction(std_Array_shift, arr);
}

function ArrayStaticUnshift(arr, arg1) {
    WarnDeprecatedArrayMethod(ARRAY_GENERICS_UNSHIFT, "unshift");
    if (arguments.length < 1)
        ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, "Array.unshift");
    var args = callFunction(std_Array_slice, arguments, 1);
@@ -1272,6 +1289,7 @@ function ArrayStaticUnshift(arr, arg1) {
}

function ArrayStaticSplice(arr, start, deleteCount) {
    WarnDeprecatedArrayMethod(ARRAY_GENERICS_SPLICE, "splice");
    if (arguments.length < 1)
        ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, "Array.splice");
    var args = callFunction(std_Array_slice, arguments, 1);
@@ -1279,6 +1297,7 @@ function ArrayStaticSplice(arr, start, deleteCount) {
}

function ArrayStaticSlice(arr, start, end) {
    WarnDeprecatedArrayMethod(ARRAY_GENERICS_SLICE, "slice");
    if (arguments.length < 1)
        ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, "Array.slice");
    return callFunction(std_Array_slice, arr, start, end);
+21 −0
Original line number Diff line number Diff line
@@ -118,6 +118,27 @@
#define MODULE_STATUS_EVALUATED 4
#define MODULE_STATUS_EVALUATED_ERROR 5

#define ARRAY_GENERICS_INDEXOF 0
#define ARRAY_GENERICS_LASTINDEXOF 1
#define ARRAY_GENERICS_EVERY 2
#define ARRAY_GENERICS_SOME 3
#define ARRAY_GENERICS_FOREACH 4
#define ARRAY_GENERICS_MAP 5
#define ARRAY_GENERICS_FILTER 6
#define ARRAY_GENERICS_REDUCE 7
#define ARRAY_GENERICS_REDUCERIGHT 8
#define ARRAY_GENERICS_CONCAT 9
#define ARRAY_GENERICS_JOIN 10
#define ARRAY_GENERICS_REVERSE 11
#define ARRAY_GENERICS_SORT 12
#define ARRAY_GENERICS_PUSH 13
#define ARRAY_GENERICS_POP 14
#define ARRAY_GENERICS_SHIFT 15
#define ARRAY_GENERICS_UNSHIFT 16
#define ARRAY_GENERICS_SPLICE 17
#define ARRAY_GENERICS_SLICE 18
#define ARRAY_GENERICS_METHODS_LIMIT 19

#define INTL_INTERNALS_OBJECT_SLOT 0

#define NOT_OBJECT_KIND_DESCRIPTOR 0
+1 −0
Original line number Diff line number Diff line
@@ -562,6 +562,7 @@ MSG_DEF(JSMSG_TYPEDOBJECT_NOT_CONSTRUCTIBLE, 0, JSEXN_TYPEERR, "not constructibl

// Array
MSG_DEF(JSMSG_TOO_LONG_ARRAY,         0, JSEXN_TYPEERR, "Too long array")
MSG_DEF(JSMSG_DEPRECATED_ARRAY_METHOD, 2, JSEXN_WARN, "Array.{0} is deprecated; use Array.prototype.{1} instead")

// Typed array
MSG_DEF(JSMSG_BAD_INDEX,               0, JSEXN_RANGEERR, "invalid or out-of-range index")
+1 −0
Original line number Diff line number Diff line
@@ -438,6 +438,7 @@ class JS::Realm : public JS::shadow::Realm {
   */
  uint32_t globalWriteBarriered = 0;

  uint32_t warnedAboutArrayGenericsMethods = 0;
#ifdef DEBUG
  bool firedOnNewGlobalObject = false;
#endif
+37 −0
Original line number Diff line number Diff line
@@ -2059,6 +2059,42 @@ static bool intrinsic_GetBuiltinIntlConstructor(JSContext* cx, unsigned argc,
  return true;
}

static bool intrinsic_WarnDeprecatedMethod(JSContext* cx, unsigned argc,
                                           Value* vp) {
  CallArgs args = CallArgsFromVp(argc, vp);
  MOZ_ASSERT(args.length() == 2);
  MOZ_RELEASE_ASSERT(args[0].isInt32());
  MOZ_ASSERT(args[1].isString());

  uint32_t id = uint32_t(args[0].toInt32());
  MOZ_ASSERT(id < ARRAY_GENERICS_METHODS_LIMIT);

  uint32_t mask = (1 << id);
  if (!(cx->realm()->warnedAboutArrayGenericsMethods & mask)) {
    JSFlatString* name = args[1].toString()->ensureFlat(cx);
    if (!name) {
      return false;
    }

    AutoStableStringChars stableChars(cx);
    if (!stableChars.initTwoByte(cx, name)) {
      return false;
    }
    const char16_t* nameChars = stableChars.twoByteRange().begin().get();

    if (!JS_ReportErrorFlagsAndNumberUC(cx, JSREPORT_WARNING, GetErrorMessage,
                                        nullptr, JSMSG_DEPRECATED_ARRAY_METHOD,
                                        nameChars, nameChars)) {
      return false;
    }

    cx->realm()->warnedAboutArrayGenericsMethods |= mask;
  }

  args.rval().setUndefined();
  return true;
}

static bool intrinsic_ThrowArgTypeNotObject(JSContext* cx, unsigned argc,
                                            Value* vp) {
  CallArgs args = CallArgsFromVp(argc, vp);
@@ -2767,6 +2803,7 @@ static const JSFunctionSpec intrinsic_functions[] = {
    JS_INLINABLE_FN("StringSplitString", intrinsic_StringSplitString, 2, 0,
                    IntrinsicStringSplitString),
    JS_FN("StringSplitStringLimit", intrinsic_StringSplitStringLimit, 3, 0),
    JS_FN("WarnDeprecatedArrayMethod", intrinsic_WarnDeprecatedMethod, 2, 0),
    JS_FN("ThrowArgTypeNotObject", intrinsic_ThrowArgTypeNotObject, 2, 0),

    // See builtin/RegExp.h for descriptions of the regexp_* functions.