blob: 866abeef4b076019239f18530a9855ce164cd3c2 [file] [log] [blame]
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001// Copyright 2011 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// Test for conflicting variable bindings.
6
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007function CheckException(e) {
8 var string = e.toString();
9 assertTrue(string.indexOf("has already been declared") >= 0 ||
10 string.indexOf("redeclaration") >= 0);
11 return 'Conflict';
12}
13
14
15function TestGlobal(s,e) {
16 try {
17 return eval(s + e);
18 } catch (x) {
19 return CheckException(x);
20 }
21}
22
23
24function TestFunction(s,e) {
25 try {
26 return eval("(function(){" + s + " return " + e + "})")();
27 } catch (x) {
28 return CheckException(x);
29 }
30}
31
32
33function TestBlock(s,e) {
34 try {
35 return eval("(function(){ {" + s + "} return " + e + "})")();
36 } catch (x) {
37 return CheckException(x);
38 }
39}
40
41function TestAll(expected,s,opt_e) {
42 var e = "";
43 var msg = s;
44 if (opt_e) { e = opt_e; msg += opt_e; }
45 // TODO(littledan): Add tests using Realm.eval to ensure that global eval
46 // works as expected.
47 assertEquals(expected === 'LocalConflict' ? 'NoConflict' : expected,
48 TestGlobal(s,e), "global:'" + msg + "'");
49 assertEquals(expected === 'LocalConflict' ? 'NoConflict' : expected,
50 TestFunction(s,e), "function:'" + msg + "'");
51 assertEquals(expected === 'LocalConflict' ? 'Conflict' : expected,
52 TestBlock(s,e), "block:'" + msg + "'");
53}
54
55
56function TestConflict(s) {
57 TestAll('Conflict', s);
58 TestAll('Conflict', 'eval("' + s + '");');
59}
60
61function TestNoConflict(s) {
62 TestAll('NoConflict', s, "'NoConflict'");
63 TestAll('NoConflict', 'eval("' + s + '");', "'NoConflict'");
64}
65
66function TestLocalConflict(s) {
67 TestAll('LocalConflict', s, "'NoConflict'");
68 TestAll('NoConflict', 'eval("' + s + '");', "'NoConflict'");
69}
70
71var letbinds = [ "let x;",
72 "let x = 0;",
73 "let x = undefined;",
74 "let x = function() {};",
75 "let x, y;",
76 "let y, x;",
77 "const x = 0;",
78 "const x = undefined;",
79 "const x = function() {};",
80 "const x = 2, y = 3;",
81 "const y = 4, x = 5;",
82 "class x { }",
83 ];
84function forCompatible(bind) {
85 return !bind.startsWith('class');
86}
87var varbinds = [ "var x;",
88 "var x = 0;",
89 "var x = undefined;",
90 "var x = function() {};",
91 "var x, y;",
92 "var y, x;",
93 ];
94var funbind = "function x() {}";
95
96for (var l = 0; l < letbinds.length; ++l) {
97 // Test conflicting let/var bindings.
98 for (var v = 0; v < varbinds.length; ++v) {
99 // Same level.
100 TestConflict(letbinds[l] + varbinds[v]);
101 TestConflict(varbinds[v] + letbinds[l]);
102 // Different level.
103 TestConflict(letbinds[l] + '{' + varbinds[v] + '}');
104 TestConflict('{' + varbinds[v] +'}' + letbinds[l]);
105 TestNoConflict(varbinds[v] + '{' + letbinds[l] + '}');
106 TestNoConflict('{' + letbinds[l] + '}' + varbinds[v]);
107 // For loop.
108 if (forCompatible(letbinds[l])) {
109 TestConflict('for (' + letbinds[l] + '0;) {' + varbinds[v] + '}');
110 }
111 TestNoConflict('for (' + varbinds[v] + '0;) {' + letbinds[l] + '}');
112 }
113
114 // Test conflicting let/let bindings.
115 for (var k = 0; k < letbinds.length; ++k) {
116 // Same level.
117 TestConflict(letbinds[l] + letbinds[k]);
118 TestConflict(letbinds[k] + letbinds[l]);
119 // Different level.
120 TestNoConflict(letbinds[l] + '{ ' + letbinds[k] + '}');
121 TestNoConflict('{' + letbinds[k] +'} ' + letbinds[l]);
122 // For loop.
123 if (forCompatible(letbinds[l])) {
124 TestNoConflict('for (' + letbinds[l] + '0;) {' + letbinds[k] + '}');
125 }
126 if (forCompatible(letbinds[k])) {
127 TestNoConflict('for (' + letbinds[k] + '0;) {' + letbinds[l] + '}');
128 }
129 }
130
131 // Test conflicting function/let bindings.
132 // Same level.
133 TestConflict(letbinds[l] + funbind);
134 TestConflict(funbind + letbinds[l]);
135 // Different level.
136 TestNoConflict(letbinds[l] + '{' + funbind + '}');
137 TestNoConflict('{' + funbind + '}' + letbinds[l]);
138 TestNoConflict(funbind + '{' + letbinds[l] + '}');
139 TestNoConflict('{' + letbinds[l] + '}' + funbind);
140 // For loop.
141 if (forCompatible(letbinds[l])) {
142 TestNoConflict('for (' + letbinds[l] + '0;) {' + funbind + '}');
143 }
144
145 // Test conflicting parameter/let bindings.
146 TestConflict('(function(x) {' + letbinds[l] + '})();');
147}
148
149// Test conflicting function/var bindings.
150for (var v = 0; v < varbinds.length; ++v) {
151 // Same level.
152 TestLocalConflict(varbinds[v] + funbind);
153 TestLocalConflict(funbind + varbinds[v]);
154 // Different level.
155 TestLocalConflict(funbind + '{' + varbinds[v] + '}');
156 TestLocalConflict('{' + varbinds[v] +'}' + funbind);
157 TestNoConflict(varbinds[v] + '{' + funbind + '}');
158 TestNoConflict('{' + funbind + '}' + varbinds[v]);
159 // For loop.
160 TestNoConflict('for (' + varbinds[v] + '0;) {' + funbind + '}');
161}
162
163// Test conflicting catch/var bindings.
164for (var v = 0; v < varbinds.length; ++v) {
165 TestNoConflict('try {} catch(x) {' + varbinds[v] + '}');
166}
167
168// Test conflicting parameter/var bindings.
169for (var v = 0; v < varbinds.length; ++v) {
170 TestNoConflict('(function (x) {' + varbinds[v] + '})();');
171}
172
173// Test conflicting catch/function bindings.
174TestNoConflict('try {} catch(x) {' + funbind + '}');
175
176// Test conflicting parameter/function bindings.
177TestNoConflict('(function (x) {' + funbind + '})();');