block-eval-var-over-let.js 2.48 KB
Newer Older
1 2 3 4 5 6 7
// Copyright 2015 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.

// Var-let conflict in a function throws, even if the var is in an eval

// Throws at the top level of a function
8 9 10
assertThrows(function() {
  let x = 1;
  eval('var x');
11
}, SyntaxError);
12 13

// If the eval is in its own block scope, throws
14 15 16
assertThrows(function() {
  let y = 1;
  { eval('var y'); }
17
}, SyntaxError);
18 19

// If the let is in its own block scope, with the eval, throws
20 21 22 23 24
assertThrows(function() {
  {
    let x = 1;
    eval('var x');
  }
25
}, SyntaxError);
26 27

// Legal if the let is no longer visible
28 29 30 31 32 33
assertDoesNotThrow(function() {
  {
    let x = 1;
  }
  eval('var x');
});
34 35 36

// All the same works for const:
// Throws at the top level of a function
37 38 39
assertThrows(function() {
  const x = 1;
  eval('var x');
40
}, SyntaxError);
41 42

// If the eval is in its own block scope, throws
43 44 45
assertThrows(function() {
  const y = 1;
  { eval('var y'); }
46
}, SyntaxError);
47 48

// If the const is in its own block scope, with the eval, throws
49 50 51 52 53
assertThrows(function() {
  {
    const x = 1;
    eval('var x');
  }
54
}, SyntaxError);
55 56

// Legal if the const is no longer visible
57 58 59 60 61 62
assertDoesNotThrow(function() {
  {
    const x = 1;
  }
  eval('var x');
});
63 64

// In global scope
65
let caught = false;
66 67
try {
  let z = 1;
68
  eval('var z');
69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90
} catch (e) {
  caught = true;
}
assertTrue(caught);

// Let declarations beyond a function boundary don't conflict
caught = false;
try {
  let a = 1;
  (function() {
    eval('var a');
  })();
} catch (e) {
  caught = true;
}
assertFalse(caught);

// var across with doesn't conflict
caught = false;
try {
  (function() {
    with ({x: 1}) {
91
      eval("var x");
92 93 94 95 96 97 98 99 100 101 102 103 104
    }
  })();
} catch (e) {
  caught = true;
}
assertFalse(caught);

// var can still conflict with let across a with
caught = false;
try {
  (function() {
    let x;
    with ({x: 1}) {
105
      eval("var x");
106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141
    }
  })();
} catch (e) {
  caught = true;
}
assertTrue(caught);

// Functions declared in eval also conflict
caught = false
try {
  (function() {
    {
      let x = 1;
      eval('function x() {}');
    }
  })();
} catch (e) {
  caught = true;
}
assertTrue(caught);

// TODO(littledan): Hoisting x out of the block should be
// prevented in this case BUG(v8:4479)
caught = false
try {
  (function() {
    {
      let x = 1;
      eval('{ function x() {} }');
    }
  })();
} catch (e) {
  caught = true;
}
// TODO(littledan): switch to assertTrue when bug is fixed
assertTrue(caught);