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

Unified Diff: test/mjsunit/strong/mutually-recursive-classes.js

Issue 1060913005: [strong] Stricter check for referring to other classes inside methods. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: code review (rossberg@) Created 5 years, 8 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
« no previous file with comments | « src/variables.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: test/mjsunit/strong/mutually-recursive-classes.js
diff --git a/test/mjsunit/strong/mutually-recursive-classes.js b/test/mjsunit/strong/mutually-recursive-classes.js
index c8d6fad260fd9fad4cfc8bc7d2ca1868df8143e3..c8cf9788ba232db00e94f19fb897a22e513cc3a6 100644
--- a/test/mjsunit/strong/mutually-recursive-classes.js
+++ b/test/mjsunit/strong/mutually-recursive-classes.js
@@ -2,23 +2,20 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-// Flags: --strong-mode
+// Flags: --strong-mode --harmony-arrow-functions
+"use strict"
-// 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* be inside lazy, unexecuted functions, since lazy parsing
-// doesn't produce strong mode scoping errors).
+let prologue_dead = "(function outer() { if (false) { ";
+let epilogue_dead = " } })();";
-// 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) {
- "use strict";
- let prologue_dead = "(function outer() { if (false) { ";
- let epilogue_dead = " } })();";
+let prologue_live = "(function outer() { ";
+let epilogue_live = "})();";
- assertThrows("'use strong'; " + prologue_dead + code + epilogue_dead, ReferenceError);
+// For code which already throws a run-time error in non-strong mode; we assert
+// that we now get the error already compilation time.
+function assertLateErrorsBecomeEarly(code) {
+ assertThrows("'use strong'; " + prologue_dead + code + epilogue_dead,
+ ReferenceError);
// Make sure the error happens only in strong mode (note that we need strict
// mode here because of let).
@@ -26,24 +23,35 @@ function assertThrowsHelper(code) {
// But if we don't put the references inside a dead code, it throws a run-time
// error (also in strict mode).
- let prologue_live = "(function outer() { ";
- let epilogue_live = "})();";
+ assertThrows("'use strong'; " + prologue_live + code + epilogue_live,
+ ReferenceError);
+ assertThrows("'use strict'; " + prologue_live + code + epilogue_live,
+ ReferenceError);
+}
+
+// For code which doesn't throw an error at all in non-strong mode.
+function assertNonErrorsBecomeEarly(code) {
+ assertThrows("'use strong'; " + prologue_dead + code + epilogue_dead,
+ ReferenceError);
+ assertDoesNotThrow("'use strict'; " + prologue_dead + code + epilogue_dead);
- assertThrows("'use strong'; " + prologue_live + code + epilogue_live, ReferenceError);
- assertThrows("'use strict'; " + prologue_live + code + epilogue_live, ReferenceError);
+ assertThrows("'use strong'; " + prologue_live + code + epilogue_live,
+ ReferenceError);
+ assertDoesNotThrow("'use strict'; " + prologue_live + code + epilogue_live,
+ ReferenceError);
}
(function InitTimeReferenceForward() {
// It's never OK to have an init time reference to a class which hasn't been
// declared.
- assertThrowsHelper(
- `class A extends B { };
+ assertLateErrorsBecomeEarly(
+ `class A extends B { }
class B {}`);
- assertThrowsHelper(
+ assertLateErrorsBecomeEarly(
`class A {
[B.sm()]() { }
- };
+ }
class B {
static sm() { return 0; }
}`);
@@ -54,7 +62,7 @@ function assertThrowsHelper(code) {
"use strong";
class A {
static sm() { return 0; }
- };
+ }
let i = "making these classes non-consecutive";
class B extends A {};
"by inserting statements and declarations in between";
@@ -68,10 +76,154 @@ function assertThrowsHelper(code) {
class A {
m() { B; }
static sm() { B; }
- };
+ }
// No statements or declarations between the classes.
class B {
m() { A; }
static sm() { A; }
- };
+ }
+})();
+
+(function MutualRecursionWithMoreClasses() {
+ "use strong";
+ class A {
+ m() { B; C; }
+ static sm() { B; C; }
+ }
+ class B {
+ m() { A; C; }
+ static sm() { A; C; }
+ }
+ class C {
+ m() { A; B; }
+ static sm() { A; B; }
+ }
+})();
+
+(function ReferringForwardInDeeperScopes() {
+ "use strong";
+
+ function foo() {
+ class A1 {
+ m() { B1; }
+ }
+ class B1 { }
+ }
+
+ class Outer {
+ m() {
+ class A2 {
+ m() { B2; }
+ }
+ class B2 { }
+ }
+ }
+
+ for (let i = 0; i < 1; ++i) {
+ class A3 {
+ m() { B3; }
+ }
+ class B3 { }
+ }
+
+ (a, b) => {
+ class A4 {
+ m() { B4; }
+ }
+ class B4 { }
+ }
+})();
+
+(function ReferringForwardButClassesNotConsecutive() {
+ assertNonErrorsBecomeEarly(
+ `class A {
+ m() { B; }
+ }
+ ;
+ class B {}`);
+
+ assertNonErrorsBecomeEarly(
+ `let A = class {
+ m() { B; }
+ }
+ class B {}`);
+
+ assertNonErrorsBecomeEarly(
+ `class A {
+ m() { B1; } // Just a normal use-before-declaration.
+ }
+ let B1 = class B2 {}`);
+
+ assertNonErrorsBecomeEarly(
+ `class A {
+ m() { B; }
+ }
+ let i = 0;
+ class B {}`);
+
+ assertNonErrorsBecomeEarly(
+ `class A {
+ m() { B; }
+ }
+ function foo() {}
+ class B {}`);
+
+ assertNonErrorsBecomeEarly(
+ `function foo() {
+ class A {
+ m() { B; }
+ }
+ }
+ class B {}`);
+
+ assertNonErrorsBecomeEarly(
+ `class A extends class B { m() { C; } } {
+ }
+ class C { }`);
+
+ assertLateErrorsBecomeEarly(
+ `class A extends class B { [C.sm()]() { } } {
+ }
+ class C { static sm() { return 'a';} }`);
+
+ assertLateErrorsBecomeEarly(
+ `class A extends class B extends C { } {
+ }
+ class C { }`);
+})();
+
+
+(function RegressionForClassResolution() {
+ assertNonErrorsBecomeEarly(
+ `let A = class B {
+ m() { C; }
+ }
+ ;;;;
+ class C {}
+ class B {}`);
+})();
+
+
+(function TestMultipleMethodScopes() {
+ "use strong";
+
+ // Test cases where the reference is inside multiple method scopes.
+ class A1 {
+ m() {
+ class C1 {
+ m() { B1; }
+ }
+ }
+ }
+ class B1 { }
+
+ ;
+
+ class A2 {
+ m() {
+ class C2 extends B2 {
+ }
+ }
+ }
+ class B2 { }
})();
« no previous file with comments | « src/variables.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698