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* be 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 assertThrowsHelper( | |
40 "function f() { 'use strong'; if (false) { x; } } var x; f();", | |
41 ReferenceError); | |
42 // Errors are also detected when the declaration and the use are in the same | |
43 // eval scope. | |
44 assertThrowsHelper("'use strong'; eval('x; let x = 0;')", ReferenceError); | |
45 | |
46 // Use occurring in the initializer of the declaration: | |
47 assertThrowsHelper("'use strong'; if (false) { let x = x + 1; }", | |
48 ReferenceError); | |
49 assertThrowsHelper("'use strong'; if (false) { let x = x; }", | |
50 ReferenceError); | |
51 assertThrowsHelper("'use strong'; if (false) { let x = y, y = 4; }", | |
52 ReferenceError); | |
53 assertThrowsHelper("'use strong'; if (false) { let x = function() { x; } }", | |
54 ReferenceError); | |
55 assertThrowsHelper("'use strong'; if (false) { let x = a => { x; } }", | |
56 ReferenceError); | |
57 assertThrowsHelper( | |
58 "'use strong'; if (false) { function f() {}; let x = f(x); }", | |
59 ReferenceError); | |
60 assertThrowsHelper("'use strong'; if (false) { const x = x; }", | |
61 ReferenceError); | |
62 assertThrowsHelper("'use strong'; if (false) { const x = function() { x; } }", | |
63 ReferenceError); | |
64 assertThrowsHelper("'use strong'; if (false) { const x = a => { x; } }", | |
65 ReferenceError); | |
66 assertThrowsHelper( | |
67 "'use strong'; if (false) { function f() {}; const x = f(x); }", | |
68 ReferenceError); | |
69 | |
70 assertThrowsHelper( | |
71 "'use strong'; if (false) { for (let x = x; ; ) { } }", | |
72 ReferenceError); | |
73 assertThrowsHelper( | |
74 "'use strong'; if (false) { for (const x = x; ; ) { } }", | |
75 ReferenceError); | |
76 assertThrowsHelper( | |
77 "'use strong'; if (false) { for (let x = y, y; ; ) { } }", | |
78 ReferenceError); | |
79 assertThrowsHelper( | |
80 "'use strong'; if (false) { for (const x = y, y = 0; ; ) { } }", | |
81 ReferenceError); | |
82 })(); | |
arv (Not doing code reviews)
2015/02/25 16:37:32
Maybe test for-of loops too?
marja
2015/02/26 12:55:42
Not sure what cases you meant exactly; I thought m
| |
83 | |
84 | |
85 (function DeclarationAfterUseInClasses() { | |
86 assertThrowsHelper("'use strong'; if (false) { class C extends C { } }", | |
87 ReferenceError); | |
88 assertThrowsHelper( | |
89 "'use strong'; if (false) { let C = class C2 extends C { } }", | |
90 ReferenceError); | |
91 assertThrowsHelper( | |
92 "'use strong'; if (false) { let C = class C2 extends C2 { } }", | |
93 ReferenceError); | |
94 | |
95 assertThrowsHelper( | |
96 "'use strong'; if (false) { let C = class C2 { constructor() { C; } } }", | |
97 ReferenceError); | |
98 | |
99 assertThrowsHelper( | |
100 "'use strong'; if (false) { let C = class C2 { method() { C; } } }", | |
arv (Not doing code reviews)
2015/02/25 16:37:32
This is kind of weird.
What about?
let f = funct
arv (Not doing code reviews)
2015/02/25 16:49:18
I realized I misread this one.
I see you already
marja
2015/02/26 12:55:42
Isn't the func1 test below testing this sufficient
| |
101 ReferenceError); | |
102 | |
103 // TODO(marja, rossberg): Make computed property name related cases work + add | |
104 // tests. | |
arv (Not doing code reviews)
2015/02/25 16:37:32
I'm surprised that doesn't work already?
marja
2015/02/26 12:55:42
The basic case works (added it above):
'use stron
| |
105 })(); | |
106 | |
107 | |
108 (function UsesWhichAreFine() { | |
109 "use strong"; | |
110 | |
111 let var1 = 0; | |
112 var1; | |
113 | |
114 let var2a = 0, var2b = var2a + 1, var2c = 2 + var2b; | |
115 | |
116 for (let var3 = 0; var3 < 1; var3++) { | |
117 var3; | |
118 } | |
119 | |
120 for (let var4a = 0, var4b = var4a; var4a + var4b < 4; var4a++, var4b++) { | |
121 var4a; | |
122 var4b; | |
123 } | |
124 | |
125 let var5 = 5; | |
126 for (; var5 < 10; ++var5) { } | |
127 | |
128 let arr = [1, 2]; | |
129 for (let i of arr) { | |
130 i; | |
131 } | |
132 | |
133 try { | |
134 throw "error"; | |
135 } catch (e) { | |
136 e; | |
137 } | |
138 | |
139 function func1() { func1; this; } | |
140 func1(); | |
141 func1; | |
142 | |
143 function * func2() { func2; this; } | |
144 func2(); | |
145 func2; | |
146 | |
147 function func4(p, ...rest) { p; rest; this; func2; } | |
148 func4(); | |
149 | |
150 let func5 = (p1, p2) => { p1; p2; }; | |
151 func5(); | |
152 | |
153 function func6() { | |
154 var1, var2a, var2b, var2c; | |
155 } | |
156 | |
157 (function eval1() { | |
158 let var6 = 0; // Declaration position will be something large. | |
159 // But use position will be something small, however, this is not an error, | |
160 // since the use is inside an eval scope. | |
161 eval("var6;"); | |
162 })(); | |
163 | |
164 class C1 { constructor() { C1; } }; new C1(); | |
165 let C2 = class C3 { constructor() { C3; } }; new C2(); | |
166 | |
167 class C4 { method() { C4; } }; new C4(); | |
168 let C5 = class C6 { method() { C6; } }; new C5(); | |
169 })(); | |
OLD | NEW |