Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(337)

Unified Diff: test/mjsunit/strong/declaration-after-use.js

Issue 943543002: [strong] Declaration-after-use errors. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: minimizing diff Created 5 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« src/parser.cc ('K') | « src/variables.h ('k') | tools/gyp/v8.gyp » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: test/mjsunit/strong/declaration-after-use.js
diff --git a/test/mjsunit/strong/declaration-after-use.js b/test/mjsunit/strong/declaration-after-use.js
new file mode 100644
index 0000000000000000000000000000000000000000..f8faedff0da257a6a970f7484f3fa6815cb066cd
--- /dev/null
+++ b/test/mjsunit/strong/declaration-after-use.js
@@ -0,0 +1,143 @@
+// Copyright 2015 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 --harmony_rest_parameters --harmony_arrow_functions --harmony_classes
+
+// Note that it's essential for these tests that the reference is inside dead
+// code (because we already produce ReferenceErrors for run-time unresolved
+// variables and don't want to confuse those with strong mode errors). But the
+// errors should *not* inside lazy, unexecuted functions, since lazy parsing
+// doesn't produce strong mode scoping errors).
+
+// In addition, assertThrows will call eval and that changes variable binding
+// types (see e.g., UNBOUND_EVAL_SHADOWED). We can avoid unwanted side effects
+// by wrapping the code to be tested inside an outer function.
+function assertThrowsHelper(code, error) {
+ "use strict";
+ let prologue = "(function outer() { ";
+ let epilogue = " })();";
+ assertThrows(prologue + code + epilogue, error);
+}
+
+(function DeclarationAfterUse() {
+ // Note that these tests only test cases where the declaration is found but is
+ // after the use. In particular, we cannot yet detect cases where the use can
+ // possibly bind to a global variable.
+ assertThrowsHelper("'use strong'; if (false) { x; let x = 0; }",
+ ReferenceError);
+ assertThrowsHelper(
+ "function f() { 'use strong'; if (false) { x; let x = 0; } } f();",
+ ReferenceError);
+ assertThrowsHelper(
+ "'use strong'; function f() { if (false) { x; } } let x = 0; f();",
+ ReferenceError);
+
+ assertThrowsHelper(
+ "function f() { 'use strong'; if (false) { x; } } var x = 0; f();",
+ ReferenceError);
+ // Errors are also detected when the declaration and the use are in the same
+ // eval scope.
+ assertThrowsHelper("'use strong'; eval('x; let x = 0;')", ReferenceError);
+
+ // Use occurring in the initializer of the declaration:
+ assertThrowsHelper("'use strong'; if (false) { let x = x + 1; }",
+ ReferenceError);
+ assertThrowsHelper("'use strong'; if (false) { let x = x; }",
+ ReferenceError);
+ assertThrowsHelper("'use strong'; if (false) { let x = y, y = 4; }",
+ ReferenceError);
+ assertThrowsHelper("'use strong'; if (false) { let x = function() { x; } }",
+ ReferenceError);
+ assertThrowsHelper("'use strong'; if (false) { let x = a => { x; } }",
+ ReferenceError);
+ assertThrowsHelper(
+ "'use strong'; if (false) { function f() {}; let x = f(x); }",
+ ReferenceError);
+ assertThrowsHelper("'use strong'; if (false) { const x = x; }",
+ ReferenceError);
+ assertThrowsHelper("'use strong'; if (false) { const x = function() { x; } }",
+ ReferenceError);
+ assertThrowsHelper("'use strong'; if (false) { const x = a => { x; } }",
+ ReferenceError);
+ assertThrowsHelper(
+ "'use strong'; if (false) { function f() {}; const x = f(x); }",
+ ReferenceError);
+
+ assertThrowsHelper(
+ "'use strong'; if (false) { for (let x = x; ; ) { } }",
rossberg 2015/02/24 15:52:40 Perhaps add for (let x = y, y; ;) {}
marja 2015/02/24 18:05:40 Done.
+ ReferenceError);
+ assertThrowsHelper(
+ "'use strong'; if (false) { for (const x = x; ; ) { } }",
+ ReferenceError);
+})();
+
+
+(function DeclarationAfterUseInClasses() {
+ assertThrowsHelper("'use strong'; if (false) { class C extends C { } }",
rossberg 2015/02/24 15:52:40 Also add versions for class expressions: let C
marja 2015/02/24 18:05:41 Added the first 2 cases and a TODO for computed pr
+ ReferenceError);
+
+ assertThrowsHelper(
+ "'use strong'; if (false) { let C = class C2 { constructor() { C; } } }",
+ ReferenceError);
+})();
+
+
+(function UsesWhichAreFine() {
+ "use strong";
+
+ let var1 = 0;
+ var1;
+
+ let var2a = 0, var2b = var2a + 1, var2c = 2 + var2b;
+
+ for (let var3 = 0; var3 < 1; var3++) {
+ var3;
+ }
+
+ for (let var4a = 0, var4b = 0; var4a + var4b < 4; var4a++, var4b++) {
rossberg 2015/02/24 15:52:40 Change to var4b = var4a
marja 2015/02/24 18:05:40 Done.
+ var4a;
+ var4b;
+ }
+
+ let var5 = 5;
+ for (; var5 < 10; ++var5) { }
+
+ let arr = [1, 2];
+ for (let i of arr) {
+ i;
+ }
+
+ try {
+ throw "error";
+ } catch (e) {
+ e;
+ }
+
+ function func1() { func1; this; }
+ func1();
+ func1;
+
+ function * func2() { func2; this; }
+ func2();
+ func2;
+
+ function func4(p, ...rest) { p; rest; this; func2; }
+ func4();
+
+ let func5 = (p1, p2) => { p1; p2; };
+ func5();
+
+ function func6() {
+ var1, var2a, var2b, var2c;
+ }
+
+ (function eval1() {
+ let var6 = 0; // Declaration position will be something large.
+ // But use position will be something small, however, this is not an error,
+ // since the use is inside an eval scope.
+ eval("var6;");
+ })();
+
+ class C { constructor() { C; } };
rossberg 2015/02/24 15:52:40 Add a new C after.
marja 2015/02/24 18:05:40 Done.
+})();
« src/parser.cc ('K') | « src/variables.h ('k') | tools/gyp/v8.gyp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698