OLD | NEW |
(Empty) | |
| 1 // Copyright 2013 the V8 project authors. All rights reserved. |
| 2 // Copyright (C) 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved. |
| 3 // |
| 4 // Redistribution and use in source and binary forms, with or without |
| 5 // modification, are permitted provided that the following conditions |
| 6 // are met: |
| 7 // 1. Redistributions of source code must retain the above copyright |
| 8 // notice, this list of conditions and the following disclaimer. |
| 9 // 2. Redistributions in binary form must reproduce the above copyright |
| 10 // notice, this list of conditions and the following disclaimer in the |
| 11 // documentation and/or other materials provided with the distribution. |
| 12 // |
| 13 // THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND AN
Y |
| 14 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
| 15 // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
| 16 // DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR AN
Y |
| 17 // DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
| 18 // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
| 19 // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND O
N |
| 20 // ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| 21 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
| 22 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 23 |
| 24 description( |
| 25 "This test checks that parentheses are preserved when significant, and not added
where inappropriate. " + |
| 26 "We need this test because the JavaScriptCore parser removes all parentheses and
the serializer then adds them back." |
| 27 ); |
| 28 |
| 29 function compileAndSerialize(expression) |
| 30 { |
| 31 var f = eval("(function () { return " + expression + "; })"); |
| 32 var serializedString = f.toString(); |
| 33 serializedString = serializedString.replace(/[ \t\r\n]+/g, " "); |
| 34 serializedString = serializedString.replace("function () { return ", ""); |
| 35 serializedString = serializedString.replace("; }", ""); |
| 36 return serializedString; |
| 37 } |
| 38 |
| 39 function compileAndSerializeLeftmostTest(expression) |
| 40 { |
| 41 var f = eval("(function () { " + expression + "; })"); |
| 42 var serializedString = f.toString(); |
| 43 serializedString = serializedString.replace(/[ \t\r\n]+/g, " "); |
| 44 serializedString = serializedString.replace("function () { ", ""); |
| 45 serializedString = serializedString.replace("; }", ""); |
| 46 return serializedString; |
| 47 } |
| 48 |
| 49 var removesExtraParentheses = compileAndSerialize("(a + b) + c") == "a + b + c"; |
| 50 |
| 51 function testKeepParentheses(expression) |
| 52 { |
| 53 shouldBe("compileAndSerialize('" + expression + "')", |
| 54 "'" + expression + "'"); |
| 55 } |
| 56 |
| 57 function testOptionalParentheses(expression) |
| 58 { |
| 59 stripped_expression = removesExtraParentheses |
| 60 ? expression.replace(/\(/g, '').replace(/\)/g, '') |
| 61 : expression; |
| 62 shouldBe("compileAndSerialize('" + expression + "')", |
| 63 "'" + stripped_expression + "'"); |
| 64 } |
| 65 |
| 66 function testLeftAssociativeSame(opA, opB) |
| 67 { |
| 68 testKeepParentheses("a " + opA + " b " + opB + " c"); |
| 69 testOptionalParentheses("(a " + opA + " b) " + opB + " c"); |
| 70 testKeepParentheses("a " + opA + " (b " + opB + " c)"); |
| 71 } |
| 72 |
| 73 function testRightAssociativeSame(opA, opB) |
| 74 { |
| 75 testKeepParentheses("a " + opA + " b " + opB + " c"); |
| 76 testKeepParentheses("(a " + opA + " b) " + opB + " c"); |
| 77 testOptionalParentheses("a " + opA + " (b " + opB + " c)"); |
| 78 } |
| 79 |
| 80 function testHigherFirst(opHigher, opLower) |
| 81 { |
| 82 testKeepParentheses("a " + opHigher + " b " + opLower + " c"); |
| 83 testOptionalParentheses("(a " + opHigher + " b) " + opLower + " c"); |
| 84 testKeepParentheses("a " + opHigher + " (b " + opLower + " c)"); |
| 85 } |
| 86 |
| 87 function testLowerFirst(opLower, opHigher) |
| 88 { |
| 89 testKeepParentheses("a " + opLower + " b " + opHigher + " c"); |
| 90 testKeepParentheses("(a " + opLower + " b) " + opHigher + " c"); |
| 91 testOptionalParentheses("a " + opLower + " (b " + opHigher + " c)"); |
| 92 } |
| 93 |
| 94 var binaryOperators = [ |
| 95 [ "*", "/", "%" ], [ "+", "-" ], |
| 96 [ "<<", ">>", ">>>" ], |
| 97 [ "<", ">", "<=", ">=", "instanceof", "in" ], |
| 98 [ "==", "!=", "===", "!==" ], |
| 99 [ "&" ], [ "^" ], [ "|" ], |
| 100 [ "&&" ], [ "||" ] |
| 101 ]; |
| 102 |
| 103 for (i = 0; i < binaryOperators.length; ++i) { |
| 104 var ops = binaryOperators[i]; |
| 105 for (j = 0; j < ops.length; ++j) { |
| 106 var op = ops[j]; |
| 107 testLeftAssociativeSame(op, op); |
| 108 if (j != 0) |
| 109 testLeftAssociativeSame(ops[0], op); |
| 110 if (i < binaryOperators.length - 1) { |
| 111 var nextOps = binaryOperators[i + 1]; |
| 112 if (j == 0) |
| 113 for (k = 0; k < nextOps.length; ++k) |
| 114 testHigherFirst(op, nextOps[k]); |
| 115 else |
| 116 testHigherFirst(op, nextOps[0]); |
| 117 } |
| 118 } |
| 119 } |
| 120 |
| 121 var assignmentOperators = [ "=", "*=", "/=" , "%=", "+=", "-=", "<<=", ">>=", ">
>>=", "&=", "^=", "|=" ]; |
| 122 |
| 123 for (i = 0; i < assignmentOperators.length; ++i) { |
| 124 var op = assignmentOperators[i]; |
| 125 testRightAssociativeSame(op, op); |
| 126 if (i != 0) |
| 127 testRightAssociativeSame("=", op); |
| 128 testLowerFirst(op, "+"); |
| 129 shouldThrow("compileAndSerialize('a + b " + op + " c')"); |
| 130 testKeepParentheses("(a + b) " + op + " c"); |
| 131 testKeepParentheses("a + (b " + op + " c)"); |
| 132 } |
| 133 |
| 134 var prefixOperators = [ "delete", "void", "typeof", "++", "--", "+", "-", "~", "
!" ]; |
| 135 var prefixOperatorSpace = [ " ", " ", " ", "", "", " ", " ", "", "" ]; |
| 136 |
| 137 for (i = 0; i < prefixOperators.length; ++i) { |
| 138 var op = prefixOperators[i] + prefixOperatorSpace[i]; |
| 139 testKeepParentheses("" + op + "a + b"); |
| 140 testOptionalParentheses("(" + op + "a) + b"); |
| 141 testKeepParentheses("" + op + "(a + b)"); |
| 142 testKeepParentheses("!" + op + "a"); |
| 143 testOptionalParentheses("!(" + op + "a)"); |
| 144 } |
| 145 |
| 146 |
| 147 testKeepParentheses("!a++"); |
| 148 testOptionalParentheses("!(a++)"); |
| 149 testKeepParentheses("(!a)++"); |
| 150 |
| 151 testKeepParentheses("!a--"); |
| 152 testOptionalParentheses("!(a--)"); |
| 153 testKeepParentheses("(!a)--"); |
| 154 |
| 155 testKeepParentheses("(-1)[a]"); |
| 156 testKeepParentheses("(-1)[a] = b"); |
| 157 testKeepParentheses("(-1)[a] += b"); |
| 158 testKeepParentheses("(-1)[a]++"); |
| 159 testKeepParentheses("++(-1)[a]"); |
| 160 testKeepParentheses("(-1)[a]()"); |
| 161 |
| 162 testKeepParentheses("new (-1)()"); |
| 163 |
| 164 testKeepParentheses("(-1).a"); |
| 165 testKeepParentheses("(-1).a = b"); |
| 166 testKeepParentheses("(-1).a += b"); |
| 167 testKeepParentheses("(-1).a++"); |
| 168 testKeepParentheses("++(-1).a"); |
| 169 testKeepParentheses("(-1).a()"); |
| 170 |
| 171 testKeepParentheses("(- 0)[a]"); |
| 172 testKeepParentheses("(- 0)[a] = b"); |
| 173 testKeepParentheses("(- 0)[a] += b"); |
| 174 testKeepParentheses("(- 0)[a]++"); |
| 175 testKeepParentheses("++(- 0)[a]"); |
| 176 testKeepParentheses("(- 0)[a]()"); |
| 177 |
| 178 testKeepParentheses("new (- 0)()"); |
| 179 |
| 180 testKeepParentheses("(- 0).a"); |
| 181 testKeepParentheses("(- 0).a = b"); |
| 182 testKeepParentheses("(- 0).a += b"); |
| 183 testKeepParentheses("(- 0).a++"); |
| 184 testKeepParentheses("++(- 0).a"); |
| 185 testKeepParentheses("(- 0).a()"); |
| 186 |
| 187 testOptionalParentheses("(1)[a]"); |
| 188 testOptionalParentheses("(1)[a] = b"); |
| 189 testOptionalParentheses("(1)[a] += b"); |
| 190 testOptionalParentheses("(1)[a]++"); |
| 191 testOptionalParentheses("++(1)[a]"); |
| 192 |
| 193 shouldBe("compileAndSerialize('(1)[a]()')", |
| 194 removesExtraParentheses ? "'1[a]()'" : "'(1)[a]()'"); |
| 195 |
| 196 shouldBe("compileAndSerialize('new (1)()')", |
| 197 removesExtraParentheses ? "'new 1()'" : "'new (1)()'"); |
| 198 |
| 199 testKeepParentheses("(1).a"); |
| 200 testKeepParentheses("(1).a = b"); |
| 201 testKeepParentheses("(1).a += b"); |
| 202 testKeepParentheses("(1).a++"); |
| 203 testKeepParentheses("++(1).a"); |
| 204 testKeepParentheses("(1).a()"); |
| 205 |
| 206 for (i = 0; i < assignmentOperators.length; ++i) { |
| 207 var op = assignmentOperators[i]; |
| 208 testKeepParentheses("(-1) " + op + " a"); |
| 209 testKeepParentheses("(- 0) " + op + " a"); |
| 210 testKeepParentheses("1 " + op + " a"); |
| 211 } |
| 212 |
| 213 shouldBe("compileAndSerializeLeftmostTest('({ }).x')", "'({ }).x'"); |
| 214 shouldBe("compileAndSerializeLeftmostTest('x = { }')", "'x = { }'"); |
| 215 shouldBe("compileAndSerializeLeftmostTest('(function () { })()')", "'(function (
) { })()'"); |
| 216 shouldBe("compileAndSerializeLeftmostTest('x = function () { }')", "'x = functio
n () { }'"); |
| 217 |
| 218 shouldBe("compileAndSerializeLeftmostTest('var a')", "'var a'"); |
| 219 shouldBe("compileAndSerializeLeftmostTest('var a = 1')", "'var a = 1'"); |
| 220 shouldBe("compileAndSerializeLeftmostTest('var a, b')", "'var a, b'"); |
| 221 shouldBe("compileAndSerializeLeftmostTest('var a = 1, b = 2')", "'var a = 1, b =
2'"); |
| 222 shouldBe("compileAndSerializeLeftmostTest('var a, b, c')", "'var a, b, c'"); |
| 223 shouldBe("compileAndSerializeLeftmostTest('var a = 1, b = 2, c = 3')", "'var a =
1, b = 2, c = 3'"); |
| 224 |
| 225 shouldBe("compileAndSerializeLeftmostTest('const a = 1')", "'const a = 1'"); |
| 226 shouldBe("compileAndSerializeLeftmostTest('const a = (1, 2)')", "'const a = (1,
2)'"); |
| 227 shouldBe("compileAndSerializeLeftmostTest('const a, b = 1')", "'const a, b = 1'"
); |
| 228 shouldBe("compileAndSerializeLeftmostTest('const a = 1, b')", "'const a = 1, b'"
); |
| 229 shouldBe("compileAndSerializeLeftmostTest('const a = 1, b = 1')", "'const a = 1,
b = 1'"); |
| 230 shouldBe("compileAndSerializeLeftmostTest('const a = (1, 2), b = 1')", "'const a
= (1, 2), b = 1'"); |
| 231 shouldBe("compileAndSerializeLeftmostTest('const a = 1, b = (1, 2)')", "'const a
= 1, b = (1, 2)'"); |
| 232 shouldBe("compileAndSerializeLeftmostTest('const a = (1, 2), b = (1, 2)')", "'co
nst a = (1, 2), b = (1, 2)'"); |
| 233 |
| 234 shouldBe("compileAndSerialize('(function () { new (a.b()).c })')", "'(function (
) { new (a.b()).c })'"); |
OLD | NEW |