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