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 |