[strong] Deprecate delete
authorAndreas Rossberg <rossberg@chromium.org>
Tue, 17 Feb 2015 16:07:54 +0000 (17:07 +0100)
committerAndreas Rossberg <rossberg@chromium.org>
Tue, 17 Feb 2015 16:08:11 +0000 (16:08 +0000)
R=marja@chromium.org
BUG=

Review URL: https://codereview.chromium.org/932833002

Cr-Commit-Position: refs/heads/master@{#26698}

src/messages.js
src/preparser.h
test/cctest/test-parsing.cc
test/mjsunit/strong/delete.js [new file with mode: 0644]
test/mjsunit/strong/equality.js
test/mjsunit/strong/use-strong.js [new file with mode: 0644]

index edadcae..1270013 100644 (file)
@@ -162,6 +162,7 @@ var kMessages = {
   strict_poison_pill:            ["'caller', 'callee', and 'arguments' properties may not be accessed on strict mode functions or the arguments objects for calls to them"],
   strict_caller:                 ["Illegal access to a strict mode caller function."],
   strong_equal:                  ["Please don't use '==' or '!=' in strong mode, use '===' or '!==' instead"],
+  strong_delete:                 ["Please don't use 'delete' in strong mode, use maps or sets instead"],
   strong_var:                    ["Please don't use 'var' in strong mode, use 'let' or 'const' instead"],
   malformed_arrow_function_parameter_list: ["Malformed arrow function parameter list"],
   generator_poison_pill:         ["'caller' and 'arguments' properties may not be accessed on generator functions."],
index 9f8fc13..e82753c 100644 (file)
@@ -2497,12 +2497,17 @@ ParserBase<Traits>::ParseUnaryExpression(bool* ok) {
     int pos = position();
     ExpressionT expression = ParseUnaryExpression(CHECK_OK);
 
-    // "delete identifier" is a syntax error in strict mode.
-    if (op == Token::DELETE && is_strict(language_mode()) &&
-        this->IsIdentifier(expression)) {
-      ReportMessage("strict_delete");
-      *ok = false;
-      return this->EmptyExpression();
+    if (op == Token::DELETE && is_strict(language_mode())) {
+      if (is_strong(language_mode())) {
+        ReportMessage("strong_delete");
+        *ok = false;
+        return this->EmptyExpression();
+      } else if (this->IsIdentifier(expression)) {
+        // "delete identifier" is a syntax error in strict mode.
+        ReportMessage("strict_delete");
+        *ok = false;
+        return this->EmptyExpression();
+      }
     }
 
     // Allow Traits do rewrite the expression.
index 9eb5d94..f0c3703 100644 (file)
@@ -2891,9 +2891,13 @@ TEST(TooManyArguments) {
 
 TEST(StrictDelete) {
   // "delete <Identifier>" is not allowed in strict mode.
+  const char* strong_context_data[][2] = {
+    {"\"use strong\"; ", ""},
+    { NULL, NULL }
+  };
+
   const char* strict_context_data[][2] = {
     {"\"use strict\"; ", ""},
-    {"\"use strong\"; ", ""},
     { NULL, NULL }
   };
 
@@ -2934,16 +2938,22 @@ TEST(StrictDelete) {
   };
 
   static const ParserFlag always_flags[] = {kAllowStrongMode};
+  RunParserSyncTest(strong_context_data, sloppy_statement_data, kError, NULL, 0,
+                    always_flags, arraysize(always_flags));
   RunParserSyncTest(strict_context_data, sloppy_statement_data, kError, NULL, 0,
                     always_flags, arraysize(always_flags));
   RunParserSyncTest(sloppy_context_data, sloppy_statement_data, kSuccess, NULL,
                     0, always_flags, arraysize(always_flags));
 
+  RunParserSyncTest(strong_context_data, good_statement_data, kError, NULL, 0,
+                    always_flags, arraysize(always_flags));
   RunParserSyncTest(strict_context_data, good_statement_data, kSuccess, NULL, 0,
                     always_flags, arraysize(always_flags));
   RunParserSyncTest(sloppy_context_data, good_statement_data, kSuccess, NULL, 0,
                     always_flags, arraysize(always_flags));
 
+  RunParserSyncTest(strong_context_data, bad_statement_data, kError, NULL, 0,
+                    always_flags, arraysize(always_flags));
   RunParserSyncTest(strict_context_data, bad_statement_data, kError, NULL, 0,
                     always_flags, arraysize(always_flags));
   RunParserSyncTest(sloppy_context_data, bad_statement_data, kError, NULL, 0,
diff --git a/test/mjsunit/strong/delete.js b/test/mjsunit/strong/delete.js
new file mode 100644 (file)
index 0000000..90e229d
--- /dev/null
@@ -0,0 +1,11 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Flags: --strong-mode
+
+(function NoDelete() {
+  const o = {a: 0};
+  assertThrows("'use strong'; delete o.a", SyntaxError);
+  assertThrows("'use strong'; delete o", SyntaxError);
+})();
index d5fe3fd..dd32644 100644 (file)
@@ -7,8 +7,4 @@
 (function NoSloppyEquality() {
   assertThrows("'use strong'; 0 == 0", SyntaxError);
   assertThrows("'use strong'; 0 != 0", SyntaxError);
-  assertThrows("function f() { 'use strong'; 0 == 0 }", SyntaxError);
-  assertThrows("function f() { 'use strong'; 0 != 0 }", SyntaxError);
-  assertTrue(eval("function f() { 'use strong' } 0 == 0"));
-  assertTrue(eval("function f() { 'use strong' } 0 != 1"));
 })();
diff --git a/test/mjsunit/strong/use-strong.js b/test/mjsunit/strong/use-strong.js
new file mode 100644 (file)
index 0000000..d472a6c
--- /dev/null
@@ -0,0 +1,27 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Flags: --strong-mode
+
+(function UseStrongScoping() {
+  assertThrows("'use strong'; 0 == 0", SyntaxError);
+  assertThrows("'use strong'; try {} catch(e) { { 0 == 0 } }", SyntaxError);
+  assertThrows("function f() { 'use strong'; 0 == 0 }", SyntaxError);
+  assertThrows("'use strong'; function f() { 0 == 0 }", SyntaxError);
+  assertThrows("'use strong'; function f() { function g() { 0 == 0 } }", SyntaxError);
+  assertThrows("'use strong'; eval('function f() { 0 == 0 }')", SyntaxError);
+  assertTrue(eval("function f() { 'use strong' } 0 == 0"));
+  assertTrue(eval("eval('\\\'use strong\\\''); 0 == 0"));
+})();
+
+(function UseStrongMixed() {
+  assertThrows("'use strict'; 'use strong'; 0 == 0", SyntaxError);
+  assertThrows("'use strong'; 'use strict'; 0 == 0", SyntaxError);
+  assertThrows("'use strong'; 'use strong'; 0 == 0", SyntaxError);
+  assertThrows("'use strict'; function f() { 'use strong'; 0 == 0 }", SyntaxError);
+  assertThrows("'use strong'; function f() { 'use strict'; 0 == 0 }", SyntaxError);
+  assertTrue(eval("'use strict'; function f() { 'use strong' } 0 == 0"));
+  assertTrue(eval("var x; function f() { 'use strong' } delete x"));
+  assertThrows("'use strict'; var x; function f() { 'use strong' } delete x", SyntaxError);
+})();