Home | History | Annotate | Download | only in harmony
      1 // Copyright 2015 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 // Flags: --harmony-sloppy --harmony-sloppy-let --harmony-sloppy-function --no-legacy-const
      6 
      7 // Var-let conflict in a function throws, even if the var is in an eval
      8 
      9 // Throws at the top level of a function
     10 assertThrows(function() {
     11   let x = 1;
     12   eval('var x');
     13 }, TypeError);
     14 
     15 // If the eval is in its own block scope, throws
     16 assertThrows(function() {
     17   let y = 1;
     18   { eval('var y'); }
     19 }, TypeError);
     20 
     21 // If the let is in its own block scope, with the eval, throws
     22 assertThrows(function() {
     23   {
     24     let x = 1;
     25     eval('var x');
     26   }
     27 }, TypeError);
     28 
     29 // Legal if the let is no longer visible
     30 assertDoesNotThrow(function() {
     31   {
     32     let x = 1;
     33   }
     34   eval('var x');
     35 });
     36 
     37 // All the same works for const:
     38 // Throws at the top level of a function
     39 assertThrows(function() {
     40   const x = 1;
     41   eval('var x');
     42 }, TypeError);
     43 
     44 // If the eval is in its own block scope, throws
     45 assertThrows(function() {
     46   const y = 1;
     47   { eval('var y'); }
     48 }, TypeError);
     49 
     50 // If the const is in its own block scope, with the eval, throws
     51 assertThrows(function() {
     52   {
     53     const x = 1;
     54     eval('var x');
     55   }
     56 }, TypeError);
     57 
     58 // Legal if the const is no longer visible
     59 assertDoesNotThrow(function() {
     60   {
     61     const x = 1;
     62   }
     63   eval('var x');
     64 });
     65 
     66 // In global scope
     67 let caught = false;
     68 try {
     69   let z = 1;
     70   eval('var z');
     71 } catch (e) {
     72   caught = true;
     73 }
     74 assertTrue(caught);
     75 
     76 // Let declarations beyond a function boundary don't conflict
     77 caught = false;
     78 try {
     79   let a = 1;
     80   (function() {
     81     eval('var a');
     82   })();
     83 } catch (e) {
     84   caught = true;
     85 }
     86 assertFalse(caught);
     87 
     88 // var across with doesn't conflict
     89 caught = false;
     90 try {
     91   (function() {
     92     with ({x: 1}) {
     93       eval("var x");
     94     }
     95   })();
     96 } catch (e) {
     97   caught = true;
     98 }
     99 assertFalse(caught);
    100 
    101 // var can still conflict with let across a with
    102 caught = false;
    103 try {
    104   (function() {
    105     let x;
    106     with ({x: 1}) {
    107       eval("var x");
    108     }
    109   })();
    110 } catch (e) {
    111   caught = true;
    112 }
    113 assertTrue(caught);
    114 
    115 // Functions declared in eval also conflict
    116 caught = false
    117 try {
    118   (function() {
    119     {
    120       let x = 1;
    121       eval('function x() {}');
    122     }
    123   })();
    124 } catch (e) {
    125   caught = true;
    126 }
    127 assertTrue(caught);
    128 
    129 // TODO(littledan): Hoisting x out of the block should be
    130 // prevented in this case BUG(v8:4479)
    131 caught = false
    132 try {
    133   (function() {
    134     {
    135       let x = 1;
    136       eval('{ function x() {} }');
    137     }
    138   })();
    139 } catch (e) {
    140   caught = true;
    141 }
    142 // TODO(littledan): switch to assertTrue when bug is fixed
    143 assertTrue(caught);
    144