Make "let" a reserved word for Web scripts. Bug 730139, r=jorendorff.
authorAdam <adam@sigterm.info>
Fri, 02 Mar 2012 18:28:29 -0600
changeset 88554 6d139ebc0f43b3bba6daccfb91db8cbc2c378823
parent 88553 9fbb5a2b9f2e9a80d419d1da496c74c92c2ad1e6
child 88555 e4f70bd4f96dcc917303518996c866f4d6551f39
push id1
push userroot
push dateMon, 20 Oct 2014 17:29:22 +0000
reviewersjorendorff
bugs730139
milestone13.0a1
Make "let" a reserved word for Web scripts. Bug 730139, r=jorendorff.
content/xbl/test/test_bug389322.xhtml
js/src/frontend/TokenStream.cpp
js/src/jit-test/tests/basic/regress-bug720680.js
js/src/tests/ecma_5/misc/future-reserved-words.js
js/src/tests/js1_5/LexicalConventions/jstests.list
js/src/tests/js1_5/LexicalConventions/let.js
js/src/tests/js1_5/Regress/regress-351515.js
js/src/tests/js1_6/extensions/regress-352392.js
--- a/content/xbl/test/test_bug389322.xhtml
+++ b/content/xbl/test/test_bug389322.xhtml
@@ -108,17 +108,17 @@ function report(testName, success) {
     let (x=1) (x);
     var success = true;
   }
   catch (e) { success = false; }
   report("HTML script tags with explicit version", success)
 ]]></script>
 <script type="text/javascript"><![CDATA[
   try {
-    let (x=1) (x);
+    eval("let (x=1) (x)");
     var success = false;
   }
   catch (e) { success = true; }
   is(success, true, "JS 1.7 should not work in versionless HTML script tags");
 ]]></script>
 </pre>
 </body>
 </html>
--- a/js/src/frontend/TokenStream.cpp
+++ b/js/src/frontend/TokenStream.cpp
@@ -1317,22 +1317,28 @@ TokenStream::checkForKeyword(const jscha
                 *ttp = kw->tokentype;
                 *topp = (JSOp) kw->op;
                 return true;
             }
             return ReportCompileErrorNumber(cx, this, NULL, JSREPORT_ERROR,
                                             JSMSG_RESERVED_ID, kw->chars);
         }
 
+        /* The let keyword is reserved on <1.7 */
+        if (kw->tokentype == TOK_LET) {
+            return ReportCompileErrorNumber(cx, this, NULL, JSREPORT_ERROR,
+                                            JSMSG_RESERVED_ID, kw->chars);
+        }
+
         /*
          * The keyword is not in this version. Treat it as an identifier,
-         * unless it is let or yield which we treat as TOK_STRICT_RESERVED by
-         * falling through to the code below (ES5 forbids them in strict mode).
+         * unless it is yield which we treat as TOK_STRICT_RESERVED by
+         * falling through to the code below (ES5 forbids it in strict mode).
          */
-        if (kw->tokentype != TOK_LET && kw->tokentype != TOK_YIELD)
+        if (kw->tokentype != TOK_YIELD)
             return true;
     }
 
     /* Strict reserved word. */
     if (isStrictMode())
         return ReportStrictModeError(cx, this, NULL, NULL, JSMSG_RESERVED_ID, kw->chars);
     return ReportCompileErrorNumber(cx, this, NULL, JSREPORT_STRICT | JSREPORT_WARNING,
                                     JSMSG_RESERVED_ID, kw->chars);
--- a/js/src/jit-test/tests/basic/regress-bug720680.js
+++ b/js/src/jit-test/tests/basic/regress-bug720680.js
@@ -4,12 +4,12 @@ eval("\
 function TimeFromYear( y ) {}\
 addTestCase( -2208988800000 );\
 function addTestCase( t ) {\
   var start = TimeFromYear((addTestCase(addTestCase << t, 0)));\
     new TestCase( \
                   SECTION,\
                   '(new Date('+d+')).getUTCDay()',\
                   WeekDay((d)),\
-                  (new Date(let ({ stop } = 'properties.length' )('/ab[c\\\n]/'))).getUTCDay() \
+                  (new Date(foo ({ stop } = 'properties.length' )('/ab[c\\\n]/'))).getUTCDay() \
                 );\
 }\
 ");
--- a/js/src/tests/ecma_5/misc/future-reserved-words.js
+++ b/js/src/tests/ecma_5/misc/future-reserved-words.js
@@ -16,24 +16,24 @@ print(BUGNUMBER + ": " + summary);
 var futureReservedWords =
   [
    "class",
    // "const", // Mozilla extension enabled even for versionless code
    "enum",
    "export",
    "extends",
    "import",
+   "let",  // Reserved even for versionless code, contrary to ES5 - see bug 730139
    "super",
   ];
 
 var strictFutureReservedWords =
   [
    "implements",
    "interface",
-   "let", // enabled: this file doesn't execute as JS1.7
    "package",
    "private",
    "protected",
    "public",
    "static",
    "yield", // enabled: this file doesn't execute as JS1.7
   ];
 
--- a/js/src/tests/js1_5/LexicalConventions/jstests.list
+++ b/js/src/tests/js1_5/LexicalConventions/jstests.list
@@ -1,5 +1,6 @@
 url-prefix ../../jsreftest.html?test=js1_5/LexicalConventions/
+script let.js
 script lexical-001.js
 script regress-177314.js
 script regress-343675.js
 script regress-469940.js
new file mode 100644
--- /dev/null
+++ b/js/src/tests/js1_5/LexicalConventions/let.js
@@ -0,0 +1,14 @@
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/
+ */
+
+var actual = 'No error';
+try {
+    eval("var let = true");
+} catch (exc) {
+    actual = exc + '';
+}
+
+reportCompare('SyntaxError: let is a reserved identifier', actual, 'ok'); 
+
--- a/js/src/tests/js1_5/Regress/regress-351515.js
+++ b/js/src/tests/js1_5/Regress/regress-351515.js
@@ -42,27 +42,25 @@ var actual = 'No Error';
 var expect = 'No Error';
 
 
 //-----------------------------------------------------------------------------
 test();
 //-----------------------------------------------------------------------------
 
 yield = 1;
-let   = 1;
 
 function test()
 {
   enterFunc ('test');
   printBugNumber(BUGNUMBER);
   printStatus (summary);
  
-  function f(yield, let) { return yield+let; }
+  function f(yield) { return yield; }
 
   var yield = 1;
-  var let = 1;
 
   function yield() {}
 
   reportCompare(expect, actual, summary);
 
   exitFunc ('test');
 }
--- a/js/src/tests/js1_6/extensions/regress-352392.js
+++ b/js/src/tests/js1_6/extensions/regress-352392.js
@@ -47,17 +47,17 @@ test();
 //-----------------------------------------------------------------------------
 
 function test()
 {
   enterFunc ('test');
   printBugNumber(BUGNUMBER);
   printStatus (summary);
 
-  expect = 'SyntaxError: invalid for each loop';
+  expect = 'SyntaxError: let is a reserved identifier';
   try
   {
     var obj = { };
     Object.defineProperty(obj, "y", { get: Array.prototype.map, enumerable: true, configurable: true });
     eval('(function() { for each(let z in obj) { } })()');
   }
   catch(ex)
   {