Home | History | Annotate | Download | only in harmony
      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 // Flags: --no-legacy-const --harmony-sloppy --harmony-sloppy-let
     29 
     30 // Test that we throw early syntax errors in harmony mode
     31 // when using an immutable binding in an assigment or with
     32 // prefix/postfix decrement/increment operators.
     33 
     34 const decls = [
     35   // Const declaration.
     36   function(use) { return "const c = 1; " + use + ";" }, TypeError,
     37   function(use) { return "const x = 0, c = 1; " + use + ";" }, TypeError,
     38   function(use) { return "const c = 1, x = (" + use + ");" }, TypeError,
     39   function(use) { return use + "; const c = 1;" }, ReferenceError,
     40   function(use) { return use + "; const x = 0, c = 1;" }, ReferenceError,
     41   function(use) { return "const x = (" + use + "), c = 1;" }, ReferenceError,
     42   function(use) { return "const c = (" + use + ");" }, ReferenceError,
     43 
     44   // Function expression.
     45   function(use) { return "(function c() { " + use + "; })();"; }, TypeError,
     46   // TODO(rossberg): Once we have default parameters, test using 'c' there.
     47 
     48   // Class expression.
     49   function(use) {
     50     return "new class c { constructor() { " + use + " } };";
     51   }, TypeError,
     52   function(use) {
     53     return "(new class c { m() { " + use + " } }).m();";
     54   }, TypeError,
     55   function(use) {
     56     return "(new class c { get a() { " + use + " } }).a;";
     57   }, TypeError,
     58   function(use) {
     59     return "(new class c { set a(x) { " + use + " } }).a = 0;";
     60   }, TypeError,
     61   function(use) {
     62     return "(class c { static m() { " + use + " } }).s();";
     63   }, TypeError,
     64   function(use) {
     65     return "(class c extends (" + use + ") {});";
     66   }, ReferenceError,
     67   function(use) {
     68     return "(class c { [" + use + "]() {} });";
     69   }, ReferenceError,
     70   function(use) {
     71     return "(class c { get [" + use + "]() {} });";
     72   }, ReferenceError,
     73   function(use) {
     74     return "(class c { set [" + use + "](x) {} });";
     75   }, ReferenceError,
     76   function(use) {
     77     return "(class c { static [" + use + "]() {} });";
     78   }, ReferenceError,
     79 
     80   // For loop.
     81   function(use) {
     82     return "for (const c = 0; " + use + ";) {}"
     83   }, TypeError,
     84   function(use) {
     85     return "for (const x = 0, c = 0; " + use + ";) {}"
     86   }, TypeError,
     87   function(use) {
     88     return "for (const c = 0; ; " + use + ") {}"
     89   }, TypeError,
     90   function(use) {
     91     return "for (const x = 0, c = 0; ; " + use + ") {}"
     92   }, TypeError,
     93   function(use) {
     94     return "for (const c = 0; ;) { " + use + "; }"
     95   }, TypeError,
     96   function(use) {
     97     return "for (const x = 0, c = 0; ;) { " + use + "; }"
     98   }, TypeError,
     99   function(use) {
    100     return "for (const c in {a: 1}) { " + use + "; }"
    101   }, TypeError,
    102   function(use) {
    103     return "for (const c of [1]) { " + use + "; }"
    104   }, TypeError,
    105   function(use) {
    106     return "for (const x = (" + use + "), c = 0; ;) {}"
    107   }, ReferenceError,
    108   function(use) {
    109     return "for (const c = (" + use + "); ;) {}"
    110   }, ReferenceError,
    111 ]
    112 
    113 let uses = [
    114   'c = 1',
    115   'c += 1',
    116   '++c',
    117   'c--',
    118 ];
    119 
    120 let declcontexts = [
    121   function(decl) { return decl; },
    122   function(decl) { return "eval(\'" + decl + "\')"; },
    123   function(decl) { return "{ " + decl + " }"; },
    124   function(decl) { return "(function() { " + decl + " })()"; },
    125 ];
    126 
    127 let usecontexts = [
    128   function(use) { return use; },
    129   function(use) { return "eval(\"" + use + "\")"; },
    130   function(use) { return "(function() { " + use + " })()"; },
    131   function(use) { return "(function() { eval(\"" + use + "\"); })()"; },
    132   function(use) { return "eval(\"(function() { " + use + "; })\")()"; },
    133 ];
    134 
    135 function Test(program, error) {
    136   program = "'use strict'; " + program;
    137   try {
    138     print(program, "  // throw " + error.name);
    139     eval(program);
    140   } catch (e) {
    141     assertInstanceof(e, error);
    142     if (e === TypeError) {
    143       assertTrue(e.toString().indexOf("Assignment to constant variable") >= 0);
    144     }
    145     return;
    146   }
    147   assertUnreachable();
    148 }
    149 
    150 for (var d = 0; d < decls.length; d += 2) {
    151   for (var u = 0; u < uses.length; ++u) {
    152     for (var o = 0; o < declcontexts.length; ++o) {
    153       for (var i = 0; i < usecontexts.length; ++i) {
    154         Test(declcontexts[o](decls[d](usecontexts[i](uses[u]))), decls[d + 1]);
    155       }
    156     }
    157   }
    158 }
    159