| 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
|
| index 8bdccacf6c6f480295a017f16b0d96d91b6e00c5..6202b2fdc668f51e1921bd0237ab93530701b277 100644
|
| --- a/test/mjsunit/strong/declaration-after-use.js
|
| +++ b/test/mjsunit/strong/declaration-after-use.js
|
| @@ -2,7 +2,7 @@
|
| // 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 --harmony-computed-property-names
|
| +// Flags: --strong-mode --harmony_rest_parameters --harmony_arrow_functions --harmony_classes --harmony_computed-property_names --harmony_templates
|
|
|
| // Note that it's essential for these tests that the reference is inside dead
|
| // code (because we already produce ReferenceErrors for run-time unresolved
|
| @@ -13,169 +13,149 @@
|
| // 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) {
|
| +function assertThrowsHelper(code) {
|
| "use strict";
|
| - let prologue = "(function outer() { ";
|
| - let epilogue = " })();";
|
| - assertThrows(prologue + code + epilogue, error);
|
| + let prologue = "(function outer() { if (false) { ";
|
| + let epilogue = " } })();";
|
| +
|
| + assertThrows("'use strong'; " + prologue + code + epilogue, ReferenceError);
|
| +
|
| + // Make sure the error happens only in strong mode (note that we need strict
|
| + // mode here because of let).
|
| + assertDoesNotThrow("'use strict'; " + prologue + code + epilogue);
|
| }
|
|
|
| (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("x; let x = 0;");
|
| + assertThrowsHelper("function f() { x; let x = 0; }");
|
| + assertThrowsHelper("function f() { x; } let x = 0;");
|
| +
|
| + // These tests needs to be done a bit more manually, since var is not allowed
|
| + // in strong mode:
|
| + assertThrows(
|
| + `(function outer() {
|
| + function f() { 'use strong'; if (false) { x; } } var x = 0; f();
|
| + })()`,
|
| + ReferenceError);
|
| + assertDoesNotThrow(
|
| + "(function outer() {\n" +
|
| + " function f() { if (false) { x; } } var x = 0; f(); \n" +
|
| + "})()");
|
| +
|
| + assertThrows(
|
| + "(function outer() {\n" +
|
| + " function f() { 'use strong'; if (false) { x; } } var x; f(); \n" +
|
| + "})()",
|
| + ReferenceError);
|
| + assertDoesNotThrow(
|
| + "(function outer() {\n" +
|
| + " function f() { if (false) { x; } } var x; f(); \n" +
|
| + "})()");
|
|
|
| - assertThrowsHelper(
|
| - "function f() { 'use strong'; if (false) { x; } } var x = 0; f();",
|
| - ReferenceError);
|
| - assertThrowsHelper(
|
| - "function f() { 'use strong'; if (false) { x; } } var x; 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);
|
| + assertThrows("'use strong'; eval('if (false) { x; let x = 0;}')",
|
| + ReferenceError);
|
| + assertDoesNotThrow("'use strict'; eval('if (false) { x; let x = 0; }')");
|
|
|
| // 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; ; ) { } }",
|
| - ReferenceError);
|
| - assertThrowsHelper(
|
| - "'use strong'; if (false) { for (const x = x; ; ) { } }",
|
| - ReferenceError);
|
| - assertThrowsHelper(
|
| - "'use strong'; if (false) { for (let x = y, y; ; ) { } }",
|
| - ReferenceError);
|
| - assertThrowsHelper(
|
| - "'use strong'; if (false) { for (const x = y, y = 0; ; ) { } }",
|
| - ReferenceError);
|
| + assertThrowsHelper("let x = x + 1;");
|
| + assertThrowsHelper("let x = x;");
|
| + assertThrowsHelper("let x = y, y = 4;");
|
| + assertThrowsHelper("let x = function() { x; }");
|
| + assertThrowsHelper("let x = a => { x; }");
|
| + assertThrowsHelper("function f(x) { return x; }; let x = f(x);");
|
| + assertThrowsHelper("const x = x;");
|
| + assertThrowsHelper("const x = function() { x; }");
|
| + assertThrowsHelper("const x = a => { x; }");
|
| + assertThrowsHelper("function f(x) {return x}; const x = f(x);");
|
| +
|
| + assertThrowsHelper("for (let x = x; ; ) { }");
|
| + assertThrowsHelper("for (const x = x; ; ) { }");
|
| + assertThrowsHelper("for (let x = y, y; ; ) { }");
|
| + assertThrowsHelper("for (const x = y, y = 0; ; ) { }");
|
|
|
| // Computed property names
|
| - assertThrowsHelper(
|
| - "'use strong'; if (false) { let o = { 'a': 'b', [o.a]: 'c'}; }",
|
| - ReferenceError);
|
| + assertThrowsHelper("let o = { 'a': 'b', [o.a]: 'c'};");
|
| })();
|
|
|
|
|
| (function DeclarationAfterUseInClasses() {
|
| - assertThrowsHelper("'use strong'; if (false) { class C extends C { } }",
|
| - ReferenceError);
|
| - assertThrowsHelper(
|
| - "'use strong'; if (false) { let C = class C2 extends C { } }",
|
| - ReferenceError);
|
| - assertThrowsHelper(
|
| - "'use strong'; if (false) { let C = class C2 extends C2 { } }",
|
| - ReferenceError);
|
| + assertThrowsHelper("class C extends C { }");
|
| + assertThrowsHelper("let C = class C2 extends C { }");
|
| + assertThrowsHelper("let C = class C2 extends C2 { }");
|
|
|
| - assertThrowsHelper(
|
| - "'use strong'; if (false) { let C = class C2 { constructor() { C; } } }",
|
| - ReferenceError);
|
| + assertThrowsHelper("let C = class C2 { constructor() { C; } }");
|
| + assertThrowsHelper("let C = class C2 { method() { C; } }");
|
| + assertThrowsHelper("let C = class C2 { *generator_method() { C; } }");
|
|
|
| assertThrowsHelper(
|
| - "'use strong'; if (false) { let C = class C2 { method() { C; } } }",
|
| - ReferenceError);
|
| + `let C = class C2 {
|
| + static a() { return 'A'; }
|
| + [C.a()]() { return 'B'; }
|
| + };`);
|
|
|
| assertThrowsHelper(
|
| - "'use strong'; if (false) { " +
|
| - "let C = class C2 { *generator_method() { C; } } }",
|
| - ReferenceError);
|
| + `let C = class C2 {
|
| + static a() { return 'A'; }
|
| + [C2.a()]() { return 'B'; }
|
| + };`);
|
|
|
| assertThrowsHelper(
|
| - "'use strong'; if (false) { let C = class C2 { " +
|
| - "static a() { return 'A'; } [C.a()]() { return 'B'; } }; }",
|
| - ReferenceError);
|
| -
|
| - assertThrowsHelper(
|
| - "'use strong'; if (false) { let C = class C2 { " +
|
| - "static a() { return 'A'; } [C2.a()]() { return 'B'; } }; }",
|
| - ReferenceError);
|
| -
|
| - assertThrowsHelper(
|
| - "'use strong'; if (false) { let C = class C2 { " +
|
| - "[(function() { C; return 'A';})()]() { return 'B'; } }; }",
|
| - ReferenceError);
|
| + `let C = class C2 {
|
| + [(function() { C; return 'A';})()]() { return 'B'; }
|
| + };`);
|
|
|
| // The reference to C or C2 is inside a function, but not a method.
|
| assertThrowsHelper(
|
| - "'use strong'; if (false) { let C = class C2 { " +
|
| - "[(function() { C2; return 'A';})()]() { return 'B'; } }; }",
|
| - ReferenceError);
|
| + `let C = class C2 {
|
| + [(function() { C2; return 'A';})()]() { return 'B'; }
|
| + };`);
|
|
|
| assertThrowsHelper(
|
| - "'use strong'; if (false) { let C = class C2 { " +
|
| - "[(function() { C; return 'A';})()]() { return 'B'; } }; }",
|
| - ReferenceError);
|
| + `let C = class C2 {
|
| + [(function() { C; return 'A';})()]() { return 'B'; }
|
| + };`);
|
|
|
| // The reference to C or C2 is inside a method, but it's not a method of the
|
| // relevant class (C2).
|
| assertThrowsHelper(
|
| - "'use strong'; if (false) { let C = class C2 { " +
|
| - "[(new (class D { m() { C2; return 'A'; } })).m()]() " +
|
| - "{ return 'B'; } } }",
|
| - ReferenceError);
|
| + `let C = class C2 {
|
| + [(new (class D { m() { C2; return 'A'; } })).m()]() {
|
| + return 'B';
|
| + }
|
| + }`);
|
|
|
| assertThrowsHelper(
|
| - "'use strong'; if (false) { let C = class C2 { " +
|
| - "[(new (class D { m() { C; return 'A'; } })).m()]() " +
|
| - "{ return 'B'; } } }",
|
| - ReferenceError);
|
| + `let C = class C2 {
|
| + [(new (class D { m() { C; return 'A'; } })).m()]() {
|
| + return 'B';
|
| + }
|
| + }`);
|
|
|
| assertThrowsHelper(
|
| - "'use strong'; if (false) { let C = class C2 { " +
|
| - "[({m() { C2; return 'A'; }}).m()]() " +
|
| - "{ return 'B'; } } }",
|
| - ReferenceError);
|
| + `let C = class C2 {
|
| + [({m() { C2; return 'A'; }}).m()]() { return 'B'; }
|
| + }`);
|
|
|
| assertThrowsHelper(
|
| - "'use strong'; if (false) { let C = class C2 { " +
|
| - "[({m() { C; return 'A'; }}).m()]() " +
|
| - "{ return 'B'; } } }",
|
| - ReferenceError);
|
| + `let C = class C2 {
|
| + [({m() { C; return 'A'; }}).m()]() { return 'B'; }
|
| + }`);
|
|
|
| assertThrowsHelper(
|
| - "'use strong';\n" +
|
| - "if (false) {\n" +
|
| - " class COuter {\n" +
|
| - " m() {\n" +
|
| - " class CInner {\n" +
|
| - " [({ m() { CInner; return 'A'; } }).m()]() {\n" +
|
| - " return 'B';\n" +
|
| - " }\n" +
|
| - " }\n" +
|
| - " }\n" +
|
| - " }\n" +
|
| - "}",
|
| - ReferenceError);
|
| + `class COuter {
|
| + m() {
|
| + class CInner {
|
| + [({ m() { CInner; return 'A'; } }).m()]() {
|
| + return 'B';
|
| + }
|
| + }
|
| + }
|
| + }`);
|
| })();
|
|
|
|
|
|
|