Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // Copyright 2015 the V8 project authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 // Flags: --strong-mode --harmony_rest_parameters --harmony_arrow_functions --ha rmony_classes | |
| 6 | |
| 7 // Note that it's essential for these tests that the reference is inside dead | |
| 8 // code (because we already produce ReferenceErrors for run-time unresolved | |
| 9 // variables and don't want to confuse those with strong mode errors). But the | |
| 10 // errors should *not* inside lazy, unexecuted functions, since lazy parsing | |
| 11 // doesn't produce strong mode scoping errors). | |
| 12 | |
| 13 // In addition, assertThrows will call eval and that changes variable binding | |
| 14 // types (see e.g., UNBOUND_EVAL_SHADOWED). We can avoid unwanted side effects | |
| 15 // by wrapping the code to be tested inside an outer function. | |
| 16 function assertThrowsHelper(code, error) { | |
| 17 "use strict"; | |
| 18 let prologue = "(function outer() { "; | |
| 19 let epilogue = " })();"; | |
| 20 assertThrows(prologue + code + epilogue, error); | |
| 21 } | |
| 22 | |
| 23 (function DeclarationAfterUse() { | |
| 24 // Note that these tests only test cases where the declaration is found but is | |
| 25 // after the use. In particular, we cannot yet detect cases where the use can | |
| 26 // possibly bind to a global variable. | |
| 27 assertThrowsHelper("'use strong'; if (false) { x; let x = 0; }", | |
| 28 ReferenceError); | |
| 29 assertThrowsHelper( | |
| 30 "function f() { 'use strong'; if (false) { x; let x = 0; } } f();", | |
| 31 ReferenceError); | |
| 32 assertThrowsHelper( | |
| 33 "'use strong'; function f() { if (false) { x; } } let x = 0; f();", | |
| 34 ReferenceError); | |
| 35 | |
| 36 assertThrowsHelper( | |
| 37 "function f() { 'use strong'; if (false) { x; } } var x = 0; f();", | |
| 38 ReferenceError); | |
| 39 // Errors are also detected when the declaration and the use are in the same | |
| 40 // eval scope. | |
| 41 assertThrowsHelper("'use strong'; eval('x; let x = 0;')", ReferenceError); | |
| 42 | |
| 43 // Use occurring in the initializer of the declaration: | |
| 44 assertThrowsHelper("'use strong'; if (false) { let x = x + 1; }", | |
| 45 ReferenceError); | |
| 46 assertThrowsHelper("'use strong'; if (false) { let x = x; }", | |
| 47 ReferenceError); | |
| 48 assertThrowsHelper("'use strong'; if (false) { let x = y, y = 4; }", | |
| 49 ReferenceError); | |
| 50 assertThrowsHelper("'use strong'; if (false) { let x = function() { x; } }", | |
| 51 ReferenceError); | |
| 52 assertThrowsHelper("'use strong'; if (false) { let x = a => { x; } }", | |
| 53 ReferenceError); | |
| 54 assertThrowsHelper( | |
| 55 "'use strong'; if (false) { function f() {}; let x = f(x); }", | |
| 56 ReferenceError); | |
| 57 assertThrowsHelper("'use strong'; if (false) { const x = x; }", | |
| 58 ReferenceError); | |
| 59 assertThrowsHelper("'use strong'; if (false) { const x = function() { x; } }", | |
| 60 ReferenceError); | |
| 61 assertThrowsHelper("'use strong'; if (false) { const x = a => { x; } }", | |
| 62 ReferenceError); | |
| 63 assertThrowsHelper( | |
| 64 "'use strong'; if (false) { function f() {}; const x = f(x); }", | |
| 65 ReferenceError); | |
| 66 | |
| 67 assertThrowsHelper( | |
| 68 "'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.
| |
| 69 ReferenceError); | |
| 70 assertThrowsHelper( | |
| 71 "'use strong'; if (false) { for (const x = x; ; ) { } }", | |
| 72 ReferenceError); | |
| 73 })(); | |
| 74 | |
| 75 | |
| 76 (function DeclarationAfterUseInClasses() { | |
| 77 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
| |
| 78 ReferenceError); | |
| 79 | |
| 80 assertThrowsHelper( | |
| 81 "'use strong'; if (false) { let C = class C2 { constructor() { C; } } }", | |
| 82 ReferenceError); | |
| 83 })(); | |
| 84 | |
| 85 | |
| 86 (function UsesWhichAreFine() { | |
| 87 "use strong"; | |
| 88 | |
| 89 let var1 = 0; | |
| 90 var1; | |
| 91 | |
| 92 let var2a = 0, var2b = var2a + 1, var2c = 2 + var2b; | |
| 93 | |
| 94 for (let var3 = 0; var3 < 1; var3++) { | |
| 95 var3; | |
| 96 } | |
| 97 | |
| 98 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.
| |
| 99 var4a; | |
| 100 var4b; | |
| 101 } | |
| 102 | |
| 103 let var5 = 5; | |
| 104 for (; var5 < 10; ++var5) { } | |
| 105 | |
| 106 let arr = [1, 2]; | |
| 107 for (let i of arr) { | |
| 108 i; | |
| 109 } | |
| 110 | |
| 111 try { | |
| 112 throw "error"; | |
| 113 } catch (e) { | |
| 114 e; | |
| 115 } | |
| 116 | |
| 117 function func1() { func1; this; } | |
| 118 func1(); | |
| 119 func1; | |
| 120 | |
| 121 function * func2() { func2; this; } | |
| 122 func2(); | |
| 123 func2; | |
| 124 | |
| 125 function func4(p, ...rest) { p; rest; this; func2; } | |
| 126 func4(); | |
| 127 | |
| 128 let func5 = (p1, p2) => { p1; p2; }; | |
| 129 func5(); | |
| 130 | |
| 131 function func6() { | |
| 132 var1, var2a, var2b, var2c; | |
| 133 } | |
| 134 | |
| 135 (function eval1() { | |
| 136 let var6 = 0; // Declaration position will be something large. | |
| 137 // But use position will be something small, however, this is not an error, | |
| 138 // since the use is inside an eval scope. | |
| 139 eval("var6;"); | |
| 140 })(); | |
| 141 | |
| 142 class C { constructor() { C; } }; | |
|
rossberg
2015/02/24 15:52:40
Add a
new C
after.
marja
2015/02/24 18:05:40
Done.
| |
| 143 })(); | |
| OLD | NEW |