13fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch// Copyright 2011 the V8 project authors. All rights reserved.
23fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch// Redistribution and use in source and binary forms, with or without
33fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch// modification, are permitted provided that the following conditions are
43fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch// met:
53fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch//
63fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch//     * Redistributions of source code must retain the above copyright
73fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch//       notice, this list of conditions and the following disclaimer.
83fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch//     * Redistributions in binary form must reproduce the above
93fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch//       copyright notice, this list of conditions and the following
103fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch//       disclaimer in the documentation and/or other materials provided
113fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch//       with the distribution.
123fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch//     * Neither the name of Google Inc. nor the names of its
133fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch//       contributors may be used to endorse or promote products derived
143fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch//       from this software without specific prior written permission.
153fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch//
163fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
173fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
183fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
193fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
203fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
213fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
223fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
233fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
243fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
253fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
263fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
273fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
283fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch// Test proper handling of keywords, future reserved words and
293fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch// future reserved words in strict mode as specific by 7.6.1 and 7.6.2
303fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch// in ECMA-262.
313fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
323fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch// This code is based on:
333fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch// http://trac.webkit.org/export/89109/trunk/LayoutTests/fast/js/script-tests/keywords-and-reserved_words.js
343fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
353fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochfunction isKeyword(x)
363fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch{
373fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  try {
383fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    eval("var " + x + ";");
393fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  } catch(e) {
403fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    return true;
413fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  }
423fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
433fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  return false;
443fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch}
453fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
463fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochfunction isStrictKeyword(x)
473fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch{
483fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  try {
493fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    eval("'use strict'; var "+x+";");
503fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  } catch(e) {
513fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    return true;
523fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  }
533fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
543fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  return false;
553fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch}
563fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
573fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochfunction classifyIdentifier(x)
583fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch{
593fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  if (isKeyword(x)) {
603fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    // All non-strict keywords are also keywords in strict code.
613fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    if (!isStrictKeyword(x)) {
623fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      return "ERROR";
633fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    }
643fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    return "keyword";
653fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  }
663fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
673fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  // Check for strict mode future reserved words.
683fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  if (isStrictKeyword(x)) {
693fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    return "strict";
703fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  }
713fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
723fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  return "identifier";
733fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch}
743fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
753fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochfunction testKeyword(word) {
763fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  // Classify word
773fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  assertEquals("keyword", classifyIdentifier(word));
783fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
793fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  // Simple use of a keyword
803fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  assertThrows("var " + word + " = 1;", SyntaxError);
813fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  if (word != "this") {
823fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    assertThrows("typeof (" + word + ");", SyntaxError);
833fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  }
843fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
853fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  // object literal properties
863fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  eval("var x = { " + word + " : 42 };");
873fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  eval("var x = { get " + word + " () {} };");
883fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  eval("var x = { set " + word + " (value) {} };");
893fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
903fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  // object literal with string literal property names
913fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  eval("var x = { '" + word + "' : 42 };");
923fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  eval("var x = { get '" + word + "' () { } };");
933fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  eval("var x = { set '" + word + "' (value) { } };");
943fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
953fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  // Function names and arguments
963fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  assertThrows("function " + word + " () { }", SyntaxError);
973fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  assertThrows("function foo (" + word + ") {}", SyntaxError);
983fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  assertThrows("function foo (a, " + word + ") { }", SyntaxError);
993fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  assertThrows("function foo (" + word + ", a) { }", SyntaxError);
1003fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  assertThrows("function foo (a, " + word + ", b) { }", SyntaxError);
1013fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  assertThrows("var foo = function (" + word + ") { }", SyntaxError);
1023fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
1033fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  // setter parameter
1043fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  assertThrows("var x = { set foo(" + word + ") { } };", SyntaxError);
1053fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch}
1063fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
1073fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch// Not keywords - these are all just identifiers.
1083fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochvar identifiers = [
1093fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  "x",            "keyword",
1103fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  "id",           "strict",
1113fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  "identifier",   "use",
1123fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  // The following are reserved in ES3 but not in ES5.
1133fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  "abstract",     "int",
1143fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  "boolean",      "long",
1153fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  "byte",         "native",
1163fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  "char",         "short",
1173fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  "double",       "synchronized",
1183fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  "final",        "throws",
1193fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  "float",        "transient",
1203fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  "goto",         "volatile" ];
1213fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
1223fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochfor (var i = 0; i < identifiers.length; i++) {
1233fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  assertEquals ("identifier", classifyIdentifier(identifiers[i]));
1243fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch}
1253fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
1263fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch// 7.6.1.1 Keywords
1273fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochvar keywords = [
1283fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  "break",        "in",
1293fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  "case",         "instanceof",
1303fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  "catch",        "new",
1313fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  "continue",     "return",
1323fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  "debugger",     "switch",
1333fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  "default",      "this",
1343fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  "delete",       "throw",
1353fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  "do",           "try",
1363fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  "else",         "typeof",
1373fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  "finally",      "var",
1383fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  "for",          "void",
1393fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  "function",     "while",
1403fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  "if",           "with",
1413fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  // In ES5 "const" is a "future reserved word" but we treat it as a keyword.
1423fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  "const" ];
1433fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
1443fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochfor (var i = 0; i < keywords.length; i++) {
1453fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  testKeyword(keywords[i]);
1463fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch}
1473fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
1483fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch// 7.6.1.2 Future Reserved Words (without "const")
1493fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochvar future_reserved_words = [
1503fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  "class",
1513fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  "enum",
1523fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  "export",
1533fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  "extends",
1543fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  "import",
1553fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  "super" ];
1563fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
1573fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochfor (var i = 0; i < future_reserved_words.length; i++) {
1583fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  testKeyword(future_reserved_words[i]);
1593fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch}
1603fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
1613fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch// 7.6.1.2 Future Reserved Words, in strict mode only.
1623fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochvar future_strict_reserved_words = [
1633fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  "implements",
1643fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  "interface",
1653fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  "let",
1663fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  "package",
1673fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  "private",
1683fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  "protected",
1693fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  "public",
1703fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  "static",
1713fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  "yield" ];
1723fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
1733fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochfor (var i = 0; i < future_strict_reserved_words.length; i++) {
1743fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  assertEquals ("strict", classifyIdentifier(future_strict_reserved_words[i]));
1753fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch}
1763fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
1773fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch// More strict mode specific tests can be found in mjsunit/strict-mode.js.
178