Ben Murdoch | 257744e | 2011-11-30 15:57:28 +0000 | [diff] [blame] | 1 | # Copyright 2011 the V8 project authors. All rights reserved. |
| 2 | # Redistribution and use in source and binary forms, with or without |
| 3 | # modification, are permitted provided that the following conditions are |
| 4 | # met: |
| 5 | # |
| 6 | # * Redistributions of source code must retain the above copyright |
| 7 | # notice, this list of conditions and the following disclaimer. |
| 8 | # * Redistributions in binary form must reproduce the above |
| 9 | # copyright notice, this list of conditions and the following |
| 10 | # disclaimer in the documentation and/or other materials provided |
| 11 | # with the distribution. |
| 12 | # * Neither the name of Google Inc. nor the names of its |
| 13 | # contributors may be used to endorse or promote products derived |
| 14 | # from this software without specific prior written permission. |
| 15 | # |
| 16 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
| 17 | # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
| 18 | # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
| 19 | # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
| 20 | # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
| 21 | # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
| 22 | # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| 23 | # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| 24 | # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| 25 | # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| 26 | # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 27 | |
| 28 | # Templatated tests with eval/arguments/future reserved words. |
| 29 | |
| 30 | # ---------------------------------------------------------------------- |
| 31 | # Constants and utility functions |
| 32 | |
| 33 | reserved_words = [ |
| 34 | 'class', |
| 35 | 'const', # Has other error message than other reserved words. |
| 36 | 'enum', |
| 37 | 'export', |
| 38 | 'extends', |
| 39 | 'import', |
| 40 | 'super' |
| 41 | ] |
| 42 | |
| 43 | strict_reserved_words = [ |
| 44 | 'implements', |
| 45 | 'interface', |
| 46 | 'let', |
| 47 | 'package', |
| 48 | 'private', |
| 49 | 'protected', |
| 50 | 'public', |
| 51 | 'static', |
| 52 | 'yield' |
| 53 | ] |
| 54 | |
| 55 | assign_ops = { |
| 56 | "=": "assign", |
| 57 | "+=": "addeq", |
| 58 | "-=": "subeq", |
| 59 | "*=": "muleq", |
| 60 | "/=": "diveq", |
| 61 | "%=": "modeq", |
| 62 | "&=": "andeq", |
| 63 | "|=": "oreq", |
| 64 | "^=": "xoreq", |
| 65 | "<<=": "shleq", |
| 66 | ">>=": "asreq", |
| 67 | ">>>=": "lsreq" |
| 68 | } |
| 69 | |
| 70 | |
| 71 | # A template that performs the same strict-mode test in different |
| 72 | # scopes (global scope, function scope, and nested function scope). |
| 73 | def StrictTemplate(name, source): |
| 74 | def MakeTests(replacement, expectation): |
| 75 | Template(name, '"use strict";\n' + source)(replacement, expectation) |
| 76 | Template(name + '-infunc', |
| 77 | 'function foo() {\n "use strict";\n' + source +'\n}\n')( |
| 78 | replacement, expectation) |
| 79 | Template(name + '-infunc2', |
| 80 | 'function foo() {\n "use strict";\n function bar() {\n' + |
| 81 | source +'\n }\n}\n')(replacement, expectation) |
| 82 | return MakeTests |
| 83 | |
| 84 | # ---------------------------------------------------------------------- |
| 85 | # Test templates |
| 86 | |
| 87 | arg_name_own = Template("argument-name-own-$id", """ |
| 88 | function foo($id) { |
| 89 | "use strict"; |
| 90 | } |
| 91 | """) |
| 92 | |
| 93 | arg_name_nested = Template("argument-name-nested-$id", """ |
| 94 | function foo() { |
| 95 | "use strict"; |
| 96 | function bar($id) { } |
| 97 | } |
| 98 | """) |
| 99 | |
| 100 | func_name_own = Template("function-name-own-$id", """ |
| 101 | function $id(foo) { |
| 102 | "use strict"; |
| 103 | } |
| 104 | """) |
| 105 | |
| 106 | func_name_nested = Template("function-name-nested-$id", """ |
| 107 | function foo() { |
| 108 | "use strict"; |
| 109 | function $id(bar) { } |
| 110 | } |
| 111 | """) |
| 112 | |
| 113 | catch_var = StrictTemplate("catch-$id", """ |
| 114 | try { } catch ($id) { } |
| 115 | """) |
| 116 | |
| 117 | declare_var = StrictTemplate("var-$id", """ |
| 118 | var $id = 42; |
| 119 | """) |
| 120 | |
| 121 | assign_var = StrictTemplate("assign-$id-$opname", """ |
| 122 | var x = $id $op 42; |
| 123 | """) |
| 124 | |
| 125 | prefix_var = StrictTemplate("prefix-$opname-$id", """ |
| 126 | var x = $op$id; |
| 127 | """) |
| 128 | |
| 129 | postfix_var = StrictTemplate("postfix-$opname-$id", """ |
| 130 | var x = $id$op; |
| 131 | """) |
| 132 | |
| 133 | read_var = StrictTemplate("read-reserved-$id", """ |
| 134 | var x = $id; |
| 135 | """) |
| 136 | |
| 137 | setter_arg = StrictTemplate("setter-param-$id", """ |
| 138 | var x = {set foo($id) { }}; |
| 139 | """) |
| 140 | |
Ben Murdoch | 3ef787d | 2012-04-12 10:51:47 +0100 | [diff] [blame] | 141 | label_normal = Template("label-normal-$id", """ |
| 142 | $id: ''; |
| 143 | """) |
| 144 | |
| 145 | label_strict = StrictTemplate("label-strict-$id", """ |
| 146 | $id: ''; |
| 147 | """) |
| 148 | |
| 149 | break_normal = Template("break-normal-$id", """ |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 150 | $id: for (;false;) { |
Ben Murdoch | 3ef787d | 2012-04-12 10:51:47 +0100 | [diff] [blame] | 151 | break $id; |
| 152 | } |
| 153 | """) |
| 154 | |
| 155 | break_strict = StrictTemplate("break-strict-$id", """ |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 156 | $id: for (;false;) { |
Ben Murdoch | 3ef787d | 2012-04-12 10:51:47 +0100 | [diff] [blame] | 157 | break $id; |
| 158 | } |
| 159 | """) |
| 160 | |
| 161 | continue_normal = Template("continue-normal-$id", """ |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 162 | $id: for (;false;) { |
Ben Murdoch | 3ef787d | 2012-04-12 10:51:47 +0100 | [diff] [blame] | 163 | continue $id; |
| 164 | } |
| 165 | """) |
| 166 | |
| 167 | continue_strict = StrictTemplate("continue-strict-$id", """ |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 168 | $id: for (;false;) { |
Ben Murdoch | 3ef787d | 2012-04-12 10:51:47 +0100 | [diff] [blame] | 169 | continue $id; |
| 170 | } |
| 171 | """) |
| 172 | |
Ben Murdoch | 257744e | 2011-11-30 15:57:28 +0000 | [diff] [blame] | 173 | non_strict_use = Template("nonstrict-$id", """ |
| 174 | var $id = 42; |
| 175 | $id++; |
| 176 | $id--; |
| 177 | ++$id; |
| 178 | --$id; |
| 179 | $id += 10; |
| 180 | $id -= 10; |
| 181 | try {} catch ($id) { } |
| 182 | function $id($id) { } |
| 183 | var x = {$id: 42}; |
| 184 | x = {get $id() {}, set $id(value) {}}; |
| 185 | function foo() { "use strict;" } |
| 186 | var $id = 42; |
| 187 | $id++; |
| 188 | $id--; |
| 189 | ++$id; |
| 190 | --$id; |
| 191 | $id += 10; |
| 192 | $id -= 10; |
| 193 | try {} catch ($id) { } |
| 194 | function $id($id) { } |
| 195 | x = {$id: 42}; |
| 196 | x = {get $id() {}, set $id(value) {}}; |
Ben Murdoch | 3ef787d | 2012-04-12 10:51:47 +0100 | [diff] [blame] | 197 | $id: ''; |
Ben Murdoch | 257744e | 2011-11-30 15:57:28 +0000 | [diff] [blame] | 198 | """) |
| 199 | |
Ben Murdoch | 3fb3ca8 | 2011-12-02 17:19:32 +0000 | [diff] [blame] | 200 | identifier_name_source = """ |
| 201 | var x = {$id: 42}; |
| 202 | x = {get $id() {}, set $id(value) {}}; |
| 203 | x.$id = 42; |
| 204 | function foo() { "use strict;" } |
| 205 | x = {$id: 42}; |
| 206 | x = {get $id() {}, set $id(value) {}}; |
| 207 | x.$id = 42; |
| 208 | """ |
| 209 | |
| 210 | identifier_name = Template("identifier_name-$id", identifier_name_source) |
| 211 | identifier_name_strict = StrictTemplate("identifier_name_strict-$id", |
| 212 | identifier_name_source) |
| 213 | |
Ben Murdoch | 257744e | 2011-11-30 15:57:28 +0000 | [diff] [blame] | 214 | # ---------------------------------------------------------------------- |
| 215 | # Run tests |
| 216 | |
| 217 | # eval and arguments have specific exceptions for different uses. |
| 218 | for id in ["eval", "arguments"]: |
| 219 | arg_name_own({"id": id}, "strict_param_name") |
| 220 | arg_name_nested({"id": id}, "strict_param_name") |
| 221 | func_name_own({"id": id}, "strict_function_name") |
| 222 | func_name_nested({"id": id}, "strict_function_name") |
| 223 | setter_arg({"id": id}, "strict_param_name") |
| 224 | for op in assign_ops.keys(): |
| 225 | assign_var({"id": id, "op":op, "opname": assign_ops[op]}, |
| 226 | "strict_lhs_assignment") |
| 227 | catch_var({"id": id}, "strict_catch_variable") |
| 228 | declare_var({"id": id}, "strict_var_name") |
| 229 | prefix_var({"id": id, "op":"++", "opname":"inc"}, "strict_lhs_prefix") |
| 230 | prefix_var({"id": id, "op":"--", "opname":"dec"}, "strict_lhs_prefix") |
| 231 | postfix_var({"id": id, "op":"++", "opname":"inc"}, "strict_lhs_postfix") |
| 232 | postfix_var({"id": id, "op":"--", "opname":"dec"}, "strict_lhs_postfix") |
Ben Murdoch | 3ef787d | 2012-04-12 10:51:47 +0100 | [diff] [blame] | 233 | label_normal({"id": id}, None) |
| 234 | label_strict({"id": id}, None) |
| 235 | break_normal({"id": id}, None) |
| 236 | break_strict({"id": id}, None) |
| 237 | continue_normal({"id": id}, None) |
| 238 | continue_strict({"id": id}, None) |
Ben Murdoch | 257744e | 2011-11-30 15:57:28 +0000 | [diff] [blame] | 239 | non_strict_use({"id": id}, None) |
| 240 | |
| 241 | |
| 242 | # Reserved words just throw the same exception in all cases |
| 243 | # (with "const" being special, as usual). |
| 244 | for reserved_word in reserved_words + strict_reserved_words: |
Ben Murdoch | 3fb3ca8 | 2011-12-02 17:19:32 +0000 | [diff] [blame] | 245 | if (reserved_word in strict_reserved_words): |
| 246 | message = "strict_reserved_word" |
Ben Murdoch | 3ef787d | 2012-04-12 10:51:47 +0100 | [diff] [blame] | 247 | label_message = None |
Ben Murdoch | 3fb3ca8 | 2011-12-02 17:19:32 +0000 | [diff] [blame] | 248 | elif (reserved_word == "const"): |
| 249 | message = "unexpected_token" |
Ben Murdoch | 3ef787d | 2012-04-12 10:51:47 +0100 | [diff] [blame] | 250 | label_message = message |
Ben Murdoch | 3fb3ca8 | 2011-12-02 17:19:32 +0000 | [diff] [blame] | 251 | else: |
| 252 | message = "reserved_word" |
Ben Murdoch | 3ef787d | 2012-04-12 10:51:47 +0100 | [diff] [blame] | 253 | label_message = message |
Ben Murdoch | 257744e | 2011-11-30 15:57:28 +0000 | [diff] [blame] | 254 | arg_name_own({"id":reserved_word}, message) |
| 255 | arg_name_nested({"id":reserved_word}, message) |
| 256 | setter_arg({"id": reserved_word}, message) |
| 257 | func_name_own({"id":reserved_word}, message) |
| 258 | func_name_nested({"id":reserved_word}, message) |
| 259 | for op in assign_ops.keys(): |
| 260 | assign_var({"id":reserved_word, "op":op, "opname": assign_ops[op]}, message) |
| 261 | catch_var({"id":reserved_word}, message) |
| 262 | declare_var({"id":reserved_word}, message) |
| 263 | prefix_var({"id":reserved_word, "op":"++", "opname":"inc"}, message) |
| 264 | prefix_var({"id":reserved_word, "op":"--", "opname":"dec"}, message) |
| 265 | postfix_var({"id":reserved_word, "op":"++", "opname":"inc"}, message) |
| 266 | postfix_var({"id":reserved_word, "op":"--", "opname":"dec"}, message) |
| 267 | read_var({"id": reserved_word}, message) |
Ben Murdoch | 3fb3ca8 | 2011-12-02 17:19:32 +0000 | [diff] [blame] | 268 | identifier_name({"id": reserved_word}, None); |
| 269 | identifier_name_strict({"id": reserved_word}, None); |
Ben Murdoch | 3ef787d | 2012-04-12 10:51:47 +0100 | [diff] [blame] | 270 | label_normal({"id": reserved_word}, label_message) |
| 271 | break_normal({"id": reserved_word}, label_message) |
| 272 | continue_normal({"id": reserved_word}, label_message) |
| 273 | if (reserved_word == "const"): |
| 274 | # The error message for this case is different because |
| 275 | # ParseLabelledStatementOrExpression will try to parse this as an expression |
| 276 | # first, effectively disallowing the use in ParseVariableDeclarations, i.e. |
| 277 | # the preparser never sees that 'const' was intended to be a label. |
| 278 | label_strict({"id": reserved_word}, "strict_const") |
| 279 | else: |
| 280 | label_strict({"id": reserved_word}, message) |
| 281 | break_strict({"id": reserved_word}, message) |
| 282 | continue_strict({"id": reserved_word}, message) |
Ben Murdoch | 257744e | 2011-11-30 15:57:28 +0000 | [diff] [blame] | 283 | |
| 284 | |
Ben Murdoch | 3fb3ca8 | 2011-12-02 17:19:32 +0000 | [diff] [blame] | 285 | # Future reserved words in strict mode behave like normal identifiers |
| 286 | # in a non strict context. |
| 287 | for reserved_word in strict_reserved_words: |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 288 | non_strict_use({"id": reserved_word}, None) |