for-each-in-catch.js 3.45 KB
Newer Older
1 2 3 4 5 6 7
// Copyright 2016 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

function checkIsRedeclarationError(code) {
  try {
    eval(`
8 9 10 11 12
      checkIsRedeclarationError: {
        break checkIsRedeclarationError;
        ${code}
      }
    `);
13
    assertUnreachable();
14 15 16
  } catch (e) {
    assertInstanceof(e, SyntaxError);
    assertTrue(e.toString().includes("has already been declared"));
17 18 19 20
  }
}

function checkIsNotRedeclarationError(code) {
21 22 23 24 25 26
  assertDoesNotThrow(() => eval(`
    checkIsNotRedeclarationError_label: {
      break checkIsNotRedeclarationError_label;
      ${code}
    }
  `));
27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54
}


let var_e = [
  'var e',
  'var {e}',
  'var {f, e}',
  'var [e]',
  'var {f:e}',
  'var [[[], e]]'
];

let not_var_e = [
  'var f',
  'var {}',
  'var {e:f}',
  'e',
  '{e}',
  'let e',
  'const e',
  'let {e}',
  'const {e}',
  'let [e]',
  'const [e]',
  'let {f:e}',
  'const {f:e}'
];

55 56
// Check that both `for (var ... of ...)` and `for (var ... in ...)`
// can redeclare a simple catch variable.
57
for (let binding of var_e) {
58 59 60 61 62 63 64
  checkIsNotRedeclarationError(`
    try {
      throw 0;
    } catch (e) {
      for (${binding} of []);
    }
  `);
65 66

  checkIsNotRedeclarationError(`
67 68 69 70 71 72
    try {
      throw 0;
    } catch (e) {
      for (${binding} in []);
    }
  `);
73 74
}

75
// Check that the above applies even for nested catches.
76
for (let binding of var_e) {
77
  checkIsNotRedeclarationError(`
78
    try {
79 80 81 82 83 84 85 86 87 88 89
      throw 0;
    } catch (e) {
      try {
        throw 1;
      } catch (f) {
        try {
          throw 2;
        } catch ({}) {
          for (${binding} of []);
        }
      }
90
    }
91
  `);
92 93 94

  checkIsNotRedeclarationError(`
    try {
95 96 97 98 99 100 101 102 103 104 105
      throw 0;
    } catch (e) {
      try {
        throw 1;
      } catch (f) {
        try {
          throw 2;
        } catch ({}) {
          for (${binding} in []);
        }
      }
106
    }
107
  `);
108 109
}

110 111
// Check that the above applies if a declaration scope is between the
// catch and the loop.
112 113
for (let binding of var_e) {
  checkIsNotRedeclarationError(`
114 115 116 117 118 119
    try {
      throw 0;
    } catch (e) {
      (()=>{for (${binding} of []);})();
    }
  `);
120 121

  checkIsNotRedeclarationError(`
122 123 124 125 126 127 128 129
    try {
      throw 0;
    } catch (e) {
      (function() {
        for (${binding} of []);
      })();
    }
  `);
130 131 132 133 134
}

// Check that there is no error when not declaring a var named e.
for (let binding of not_var_e) {
  checkIsNotRedeclarationError(`
135 136 137 138 139 140
    try {
      throw 0;
    } catch (e) {
      for (${binding} of []);
    }
  `);
141 142 143
}

// Check that there is an error for both for-in and for-of when redeclaring
144
// a non-simple catch parameter.
145 146
for (let binding of var_e) {
  checkIsRedeclarationError(`
147 148 149 150 151 152
    try {
      throw 0;
    } catch ({e}) {
      for (${binding} of []);
    }
  `);
153 154

  checkIsRedeclarationError(`
155 156 157 158 159 160
    try {
      throw 0;
    } catch ({e}) {
      for (${binding} in []);
    }
  `);
161 162 163 164 165 166
}

// Check that the above error occurs even for nested catches.
for (let binding of var_e) {
  checkIsRedeclarationError(`
    try {
167 168 169 170 171 172 173 174 175 176 177
      throw 0;
    } catch ({e}) {
      try {
        throw 1;
      } catch (f) {
        try {
          throw 2;
        } catch ({}) {
          for (${binding} of []);
        }
      }
178
    }
179
  `);
180 181 182

  checkIsRedeclarationError(`
    try {
183 184 185 186 187 188 189 190 191 192 193
      throw 0;
    } catch ({e}) {
      try {
        throw 1;
      } catch (f) {
        try {
          throw 2;
        } catch ({}) {
          for (${binding} in []);
        }
      }
194
    }
195
  `);
196
}