Bug 1083467 - Log console warnings for JavaScript 1.6's deprecated for-each-in loops. r=jorendorff
authorChris Peterson <cpeterson@mozilla.com>
Tue, 25 Nov 2014 23:17:21 -0800
changeset 219642 7d0b5801159a89338ec078ed88a68e31f86fedf7
parent 219641 7fa8db59f3567200d07e528e21ef946bd10402e0
child 219643 f6beecf60b094020b517f9eb07fc2fdd2d8b1d50
push id27967
push userryanvm@gmail.com
push dateMon, 15 Dec 2014 18:52:54 +0000
treeherdermozilla-central@5d6e0d038f95 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjorendorff
bugs1083467
milestone37.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1083467 - Log console warnings for JavaScript 1.6's deprecated for-each-in loops. r=jorendorff
js/src/frontend/Parser.cpp
js/src/js.msg
js/src/vm/Xdr.h
--- a/js/src/frontend/Parser.cpp
+++ b/js/src/frontend/Parser.cpp
@@ -4568,16 +4568,20 @@ Parser<FullParseHandler>::forStatement()
     if (allowsForEachIn()) {
         bool matched;
         if (!tokenStream.matchContextualKeyword(&matched, context->names().each))
             return null();
         if (matched) {
             iflags = JSITER_FOREACH;
             isForEach = true;
             sawDeprecatedForEach = true;
+            if (versionNumber() < JSVERSION_LATEST) {
+                if (!report(ParseWarning, pc->sc->strict, null(), JSMSG_DEPRECATED_FOR_EACH))
+                    return null();
+            }
         }
     }
 
     MUST_MATCH_TOKEN(TOK_LP, JSMSG_PAREN_AFTER_FOR);
 
     /*
      * True if we have 'for (var/let/const ...)', except in the oddball case
      * where 'let' begins a let-expression in 'for (let (...) ...)'.
@@ -6750,18 +6754,24 @@ Parser<FullParseHandler>::legacyComprehe
             return null();
 
         pn2->setOp(JSOP_ITER);
         pn2->pn_iflags = JSITER_ENUMERATE;
         if (allowsForEachIn()) {
             bool matched;
             if (!tokenStream.matchContextualKeyword(&matched, context->names().each))
                 return null();
-            if (matched)
+            if (matched) {
                 pn2->pn_iflags |= JSITER_FOREACH;
+                sawDeprecatedForEach = true;
+                if (versionNumber() < JSVERSION_LATEST) {
+                    if (!report(ParseWarning, pc->sc->strict, pn2, JSMSG_DEPRECATED_FOR_EACH))
+                        return null();
+                }
+            }
         }
         MUST_MATCH_TOKEN(TOK_LP, JSMSG_PAREN_AFTER_FOR);
 
         uint32_t startYieldOffset = pc->lastYieldOffset;
 
         RootedPropertyName name(context);
         if (!tokenStream.getToken(&tt))
             return null();
@@ -8352,27 +8362,28 @@ Parser<ParseHandler>::accumulateTelemetr
         DeprecatedLetBlock = 4,           // Added in JS 1.7, but not version-gated
         DeprecatedLetExpression = 5,      // Added in JS 1.7, but not version-gated
     };
 
     // Hazard analysis can't tell that the telemetry callbacks don't GC.
     JS::AutoSuppressGCAnalysis nogc;
 
     // Call back into Firefox's Telemetry reporter.
+    int id = JS_TELEMETRY_DEPRECATED_LANGUAGE_EXTENSIONS_IN_CONTENT;
     if (sawDeprecatedForEach)
-         cx->runtime()->addTelemetry(JS_TELEMETRY_DEPRECATED_LANGUAGE_EXTENSIONS_IN_CONTENT, DeprecatedForEach);
+         cx->runtime()->addTelemetry(id, DeprecatedForEach);
     if (sawDeprecatedDestructuringForIn)
-         cx->runtime()->addTelemetry(JS_TELEMETRY_DEPRECATED_LANGUAGE_EXTENSIONS_IN_CONTENT, DeprecatedDestructuringForIn);
+         cx->runtime()->addTelemetry(id, DeprecatedDestructuringForIn);
     if (sawDeprecatedLegacyGenerator)
-        cx->runtime()->addTelemetry(JS_TELEMETRY_DEPRECATED_LANGUAGE_EXTENSIONS_IN_CONTENT, DeprecatedLegacyGenerator);
+        cx->runtime()->addTelemetry(id, DeprecatedLegacyGenerator);
     if (sawDeprecatedExpressionClosure)
-         cx->runtime()->addTelemetry(JS_TELEMETRY_DEPRECATED_LANGUAGE_EXTENSIONS_IN_CONTENT, DeprecatedExpressionClosure);
+         cx->runtime()->addTelemetry(id, DeprecatedExpressionClosure);
     if (sawDeprecatedLetBlock)
-         cx->runtime()->addTelemetry(JS_TELEMETRY_DEPRECATED_LANGUAGE_EXTENSIONS_IN_CONTENT, DeprecatedLetBlock);
+         cx->runtime()->addTelemetry(id, DeprecatedLetBlock);
     if (sawDeprecatedLetExpression)
-         cx->runtime()->addTelemetry(JS_TELEMETRY_DEPRECATED_LANGUAGE_EXTENSIONS_IN_CONTENT, DeprecatedLetExpression);
+         cx->runtime()->addTelemetry(id, DeprecatedLetExpression);
 }
 
 template class Parser<FullParseHandler>;
 template class Parser<SyntaxParseHandler>;
 
 } /* namespace frontend */
 } /* namespace js */
--- a/js/src/js.msg
+++ b/js/src/js.msg
@@ -222,16 +222,17 @@ MSG_DEF(JSMSG_CURLY_BEFORE_CATCH,      0
 MSG_DEF(JSMSG_CURLY_BEFORE_FINALLY,    0, JSEXN_SYNTAXERR, "missing { before finally block")
 MSG_DEF(JSMSG_CURLY_BEFORE_SWITCH,     0, JSEXN_SYNTAXERR, "missing { before switch body")
 MSG_DEF(JSMSG_CURLY_BEFORE_TRY,        0, JSEXN_SYNTAXERR, "missing { before try block")
 MSG_DEF(JSMSG_CURLY_IN_COMPOUND,       0, JSEXN_SYNTAXERR, "missing } in compound statement")
 MSG_DEF(JSMSG_DECLARATION_AFTER_EXPORT,0, JSEXN_SYNTAXERR, "missing declaration after 'export' keyword")
 MSG_DEF(JSMSG_DECLARATION_AFTER_IMPORT,0, JSEXN_SYNTAXERR, "missing declaration after 'import' keyword")
 MSG_DEF(JSMSG_DEPRECATED_DELETE_OPERAND, 0, JSEXN_SYNTAXERR, "applying the 'delete' operator to an unqualified name is deprecated")
 MSG_DEF(JSMSG_DEPRECATED_LET_BLOCK,      0, JSEXN_NONE, "JavaScript 1.7's let blocks are deprecated")
+MSG_DEF(JSMSG_DEPRECATED_FOR_EACH,     0, JSEXN_NONE, "JavaScript 1.6's for-each-in loops are deprecated; consider using ES6 for-of instead")
 MSG_DEF(JSMSG_DEPRECATED_LET_EXPRESSION, 0, JSEXN_NONE, "JavaScript 1.7's let expressions are deprecated")
 MSG_DEF(JSMSG_DEPRECATED_OCTAL,        0, JSEXN_SYNTAXERR, "octal literals and octal escape sequences are deprecated")
 MSG_DEF(JSMSG_DEPRECATED_PRAGMA,       1, JSEXN_NONE, "Using //@ to indicate {0} pragmas is deprecated. Use //# instead")
 MSG_DEF(JSMSG_DUPLICATE_FORMAL,        1, JSEXN_SYNTAXERR, "duplicate formal argument {0}")
 MSG_DEF(JSMSG_DUPLICATE_LABEL,         0, JSEXN_SYNTAXERR, "duplicate label")
 MSG_DEF(JSMSG_DUPLICATE_PROPERTY,      1, JSEXN_SYNTAXERR, "property name {0} appears more than once in object literal")
 MSG_DEF(JSMSG_EMPTY_CONSEQUENT,        0, JSEXN_SYNTAXERR, "mistyped ; after conditional?")
 MSG_DEF(JSMSG_EQUAL_AS_ASSIGN,         0, JSEXN_SYNTAXERR, "test for equality (==) mistyped as assignment (=)?")
--- a/js/src/vm/Xdr.h
+++ b/js/src/vm/Xdr.h
@@ -30,17 +30,17 @@ namespace js {
  *  https://developer.mozilla.org/en-US/docs/SpiderMonkey/Internals/Bytecode
  *
  * === GREETINGS, FELLOW SUBTRAHEND INCREMENTER! ===
  * For the time being, please increment the subtrahend by 2 each time it
  * changes, because we have two flavors of bytecode: with JSOP_SYMBOL (in
  * Nightly) and without (all others).  FIXME: Bug 1066322 - Enable ES6 symbols
  * in all builds.
  */
-static const uint32_t XDR_BYTECODE_VERSION_SUBTRAHEND = 220;
+static const uint32_t XDR_BYTECODE_VERSION_SUBTRAHEND = 222;
 static_assert(XDR_BYTECODE_VERSION_SUBTRAHEND % 2 == 0, "see the comment above");
 static const uint32_t XDR_BYTECODE_VERSION =
     uint32_t(0xb973c0de - (XDR_BYTECODE_VERSION_SUBTRAHEND
 #ifdef JS_HAS_SYMBOLS
                                                            + 1
 #endif
                                                               ));