1 /*
   2  * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  * 
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  * 
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  * 
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  * 
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  */
  23 
  24 /**
  25  * JDK-8151700: Add support for ES6 for-of
  26  *
  27  * @test
  28  * @run
  29  * @option --language=es6
  30  */
  31 
  32 let result = "";
  33 for (let a of [1, 2, "foo"]) {
  34     result += a;
  35 }
  36 
  37 if (result !== "12foo") {
  38     throw new Error("unexpcected result: " + result);
  39 }
  40 
  41 let sum = 0;
  42 let numbers = [1, 2, 3, 4];
  43 numbers.ten = 10; // not iterated over
  44 
  45 for (let n of numbers) {
  46     sum += n;
  47 }
  48 
  49 if (sum !== 10) {
  50     throw new Error("unexpected sum: " + sum);;
  51 }
  52 
  53 if (typeof n !== "undefined") {
  54     throw new Error("n is visible outside of for-of");
  55 }
  56 
  57 let message = "Hello";
  58 result = "";
  59 
  60 for(const c of message) {
  61     result += c;
  62 }
  63 
  64 if (result !== "Hello") {
  65     throw new Error("unexpected result: " + result);
  66 }
  67 
  68 if (typeof c !== "undefined") {
  69     throw new Error("c is visible outside of for-of")
  70 }
  71 
  72 // Callbacks with per-iteration scope
  73 
  74 result = "";
  75 let funcs = [];
  76 
  77 for (let a of [1, 2, "foo"]) {
  78     funcs.push(function() { result += a; });
  79 }
  80 
  81 funcs.forEach(function(f) { f(); });
  82 if (result !== "12foo") {
  83     throw new Error("unexpcected result: " + result);
  84 }
  85 
  86 result = "";
  87 funcs = [];
  88 
  89 for (const a of [1, 2, "foo"]) {
  90     funcs.push(function() { result += a; });
  91 }
  92 
  93 funcs.forEach(function(f) { f(); });
  94 if (result !== "12foo") {
  95     throw new Error("unexpcected result: " + result);
  96 }
  97 
  98 // Set
  99 var set = new Set(["foo", "bar", "foo"]);
 100 result = "";
 101 
 102 for (var w of set) {
 103     result += w;
 104 }
 105 
 106 if (result !== "foobar") {
 107     throw new Error("unexpected result: " + result);
 108 }
 109 
 110 // Maps
 111 var map = new Map([["a", 1], ["b", 2]]);
 112 result = "";
 113 
 114 for (var entry of map) {
 115     result += entry;
 116 }
 117 
 118 if (result !== "a,1b,2") {
 119     throw new Error("unexpected result: " + result);
 120 }
 121 
 122 // per-iteration scope
 123 
 124 let array = ["a", "b", "c"];
 125 funcs = [];
 126 
 127 for (let i of array) {
 128     for (let j of array) {
 129         for (let k of array) {
 130             funcs.push(function () {
 131                 return i + j + k;
 132             });
 133         }
 134     }
 135 }
 136 
 137 Assert.assertEquals(funcs.length, 3 * 3 * 3);
 138 let count = 0;
 139 
 140 for (let i = 0; i < 3; i++) {
 141     for (let j = 0; j < 3; j++) {
 142         for (let k = 0; k < 3; k++) {
 143             Assert.assertEquals(funcs[count++](), array[i] + array[j] + array[k]);
 144         }
 145     }
 146 }
 147 
 148 // per-iteration scope with const declaration
 149 
 150 funcs = [];
 151 
 152 for (const i of array) {
 153     for (const j of array) {
 154         for (const k of array) {
 155             funcs.push(function () {
 156                 return i + j + k;
 157             });
 158         }
 159     }
 160 }
 161 
 162 Assert.assertEquals(funcs.length, 3 * 3 * 3);
 163 count = 0;
 164 
 165 for (let i = 0; i < 3; i++) {
 166     for (let j = 0; j < 3; j++) {
 167         for (let k = 0; k < 3; k++) {
 168             Assert.assertEquals(funcs[count++](), array[i] + array[j] + array[k]);
 169         }
 170     }
 171 }
 172 
 173 // fibonacci iterator
 174 
 175 let fibonacci = {};
 176 
 177 fibonacci[Symbol.iterator] = function() {
 178     let previous = 0, current = 1;
 179     return {
 180         next: function() {
 181             let tmp = current;
 182             current = previous + current;
 183             previous = tmp;
 184             return { done: false, value: current };
 185         }
 186     }
 187 };
 188 
 189 for (f of fibonacci) {
 190     if (f > 100000) {
 191         break;
 192     }
 193 }
 194 
 195 Assert.assertTrue(f === 121393);
 196