From 77fbf1cada9ea22e9c5b340b52cf7903e3d446cd Mon Sep 17 00:00:00 2001
From: Leonardo Balter <leonardo.balter@gmail.com>
Date: Mon, 6 Mar 2017 22:08:56 -0500
Subject: [PATCH] Additional coverage for computed yield values

Ref #865
Ref https://github.com/tc39/test262/pull/890#issuecomment-284600429
---
 .../default/class-method-definition.template  | 33 ++++++++++++++
 src/generators/default/expression.template    | 25 +++++++++++
 .../default/method-definition.template        | 27 ++++++++++++
 src/generators/default/statement.template     | 25 +++++++++++
 src/generators/non-strict/expression.template | 25 +++++++++++
 .../non-strict/method-definition.template     | 27 ++++++++++++
 src/generators/non-strict/statement.template  | 25 +++++++++++
 .../yield-identifier-non-strict.case          | 26 +++++++++++
 .../yield-identifier-spread-non-strict.case   | 43 +++++++++++++++++++
 .../yield-identifier-spread-strict.case       | 28 ++++++++++++
 src/generators/yield-identifier-strict.case   | 19 ++++++++
 src/generators/yield-spread-arr-multiple.case | 27 ++++++++++++
 src/generators/yield-spread-arr-single.case   | 25 +++++++++++
 src/generators/yield-spread-obj.case          | 33 ++++++++++++++
 14 files changed, 388 insertions(+)
 create mode 100644 src/generators/default/class-method-definition.template
 create mode 100644 src/generators/default/expression.template
 create mode 100644 src/generators/default/method-definition.template
 create mode 100644 src/generators/default/statement.template
 create mode 100644 src/generators/non-strict/expression.template
 create mode 100644 src/generators/non-strict/method-definition.template
 create mode 100644 src/generators/non-strict/statement.template
 create mode 100644 src/generators/yield-identifier-non-strict.case
 create mode 100644 src/generators/yield-identifier-spread-non-strict.case
 create mode 100644 src/generators/yield-identifier-spread-strict.case
 create mode 100644 src/generators/yield-identifier-strict.case
 create mode 100644 src/generators/yield-spread-arr-multiple.case
 create mode 100644 src/generators/yield-spread-arr-single.case
 create mode 100644 src/generators/yield-spread-obj.case

diff --git a/src/generators/default/class-method-definition.template b/src/generators/default/class-method-definition.template
new file mode 100644
index 0000000000..4515d51ef5
--- /dev/null
+++ b/src/generators/default/class-method-definition.template
@@ -0,0 +1,33 @@
+// Copyright (C) 2017 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+path: language/expressions/class/gen-method-
+name: Generator method as a ClassElement
+esid: prod-GeneratorMethod
+info: |
+  ClassElement[Yield, Await]:
+    MethodDefinition[?Yield, ?Await]
+
+  MethodDefinition[Yield, Await]:
+    GeneratorMethod[?Yield, ?Await]
+
+  14.4 Generator Function Definitions
+
+  GeneratorMethod[Yield, Await]:
+    * PropertyName[?Yield, ?Await] ( UniqueFormalParameters[+Yield, ~Await] ) { GeneratorBody }
+---*/
+
+var callCount = 0;
+
+class C { *gen() {
+    callCount += 1;
+    /*{ body }*/
+}}
+
+var gen = C.prototype.gen;
+
+var iter = gen();
+
+/*{ assertions }*/
+
+assert.sameValue(callCount, 1);
diff --git a/src/generators/default/expression.template b/src/generators/default/expression.template
new file mode 100644
index 0000000000..ddead781f5
--- /dev/null
+++ b/src/generators/default/expression.template
@@ -0,0 +1,25 @@
+// Copyright (C) 2017 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+path: language/expressions/generators/
+name: Generator expression
+esid: prod-GeneratorExpression
+info: |
+  14.4 Generator Function Definitions
+
+  GeneratorExpression:
+    function * BindingIdentifier[+Yield, ~Await]opt ( FormalParameters[+Yield, ~Await] ) { GeneratorBody }
+---*/
+
+var callCount = 0;
+
+var gen = function *() {
+  callCount += 1;
+  /*{ body }*/
+};
+
+var iter = gen();
+
+/*{ assertions }*/
+
+assert.sameValue(callCount, 1);
diff --git a/src/generators/default/method-definition.template b/src/generators/default/method-definition.template
new file mode 100644
index 0000000000..d075f36830
--- /dev/null
+++ b/src/generators/default/method-definition.template
@@ -0,0 +1,27 @@
+// Copyright (C) 2017 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+path: language/expressions/object/method-definition/generator-
+name: Generator method
+esid: prod-GeneratorMethod
+info: |
+  14.4 Generator Function Definitions
+
+  GeneratorMethod[Yield, Await]:
+    * PropertyName[?Yield, ?Await] ( UniqueFormalParameters[+Yield, ~Await] ) { GeneratorBody }
+---*/
+
+var callCount = 0;
+
+var gen = {
+  *method() {
+    callCount += 1;
+    /*{ body }*/
+  }
+}.method;
+
+var iter = gen();
+
+/*{ assertions }*/
+
+assert.sameValue(callCount, 1);
diff --git a/src/generators/default/statement.template b/src/generators/default/statement.template
new file mode 100644
index 0000000000..d70481d62f
--- /dev/null
+++ b/src/generators/default/statement.template
@@ -0,0 +1,25 @@
+// Copyright (C) 2017 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+path: language/statements/generators/
+name: Generator function declaration
+esid: prod-GeneratorDeclaration
+info: |
+  14.4 Generator Function Definitions
+
+  GeneratorDeclaration[Yield, Await, Default]:
+    function * BindingIdentifier[?Yield, ?Await] ( FormalParameters[+Yield, ~Await] ) { GeneratorBody }
+---*/
+
+var callCount = 0;
+
+function *gen() {
+  callCount += 1;
+  /*{ body }*/
+}
+
+var iter = gen();
+
+/*{ assertions }*/
+
+assert.sameValue(callCount, 1);
diff --git a/src/generators/non-strict/expression.template b/src/generators/non-strict/expression.template
new file mode 100644
index 0000000000..1237f25f66
--- /dev/null
+++ b/src/generators/non-strict/expression.template
@@ -0,0 +1,25 @@
+// Copyright (C) 2017 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+path: language/expressions/generators/
+name: Generator expression - valid for non-strict only cases
+esid: prod-GeneratorExpression
+info: |
+  14.4 Generator Function Definitions
+
+  GeneratorExpression:
+    function * BindingIdentifier[+Yield, ~Await]opt ( FormalParameters[+Yield, ~Await] ) { GeneratorBody }
+---*/
+
+var callCount = 0;
+
+var gen = function *() {
+  callCount += 1;
+  /*{ body }*/
+};
+
+var iter = gen();
+
+/*{ assertions }*/
+
+assert.sameValue(callCount, 1);
diff --git a/src/generators/non-strict/method-definition.template b/src/generators/non-strict/method-definition.template
new file mode 100644
index 0000000000..84cee1cfd1
--- /dev/null
+++ b/src/generators/non-strict/method-definition.template
@@ -0,0 +1,27 @@
+// Copyright (C) 2017 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+path: language/expressions/object/method-definition/generator-
+name: Generator method - valid for non-strict only cases
+esid: prod-GeneratorMethod
+info: |
+  14.4 Generator Function Definitions
+
+  GeneratorMethod[Yield, Await]:
+    * PropertyName[?Yield, ?Await] ( UniqueFormalParameters[+Yield, ~Await] ) { GeneratorBody }
+---*/
+
+var callCount = 0;
+
+var gen = {
+  *method() {
+    callCount += 1;
+    /*{ body }*/
+  }
+}.method;
+
+var iter = gen();
+
+/*{ assertions }*/
+
+assert.sameValue(callCount, 1);
diff --git a/src/generators/non-strict/statement.template b/src/generators/non-strict/statement.template
new file mode 100644
index 0000000000..5409b5134a
--- /dev/null
+++ b/src/generators/non-strict/statement.template
@@ -0,0 +1,25 @@
+// Copyright (C) 2017 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+path: language/statements/generators/
+name: Generator function declaration - valid for non-strict only cases
+esid: prod-GeneratorDeclaration
+info: |
+  14.4 Generator Function Definitions
+
+  GeneratorDeclaration[Yield, Await, Default]:
+    function * BindingIdentifier[?Yield, ?Await] ( FormalParameters[+Yield, ~Await] ) { GeneratorBody }
+---*/
+
+var callCount = 0;
+
+function *gen() {
+  callCount += 1;
+  /*{ body }*/
+}
+
+var iter = gen();
+
+/*{ assertions }*/
+
+assert.sameValue(callCount, 1);
diff --git a/src/generators/yield-identifier-non-strict.case b/src/generators/yield-identifier-non-strict.case
new file mode 100644
index 0000000000..c8095df915
--- /dev/null
+++ b/src/generators/yield-identifier-non-strict.case
@@ -0,0 +1,26 @@
+// Copyright (C) 2017 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+desc: >
+  Use of yield as a valid identifier in a function body inside a generator body
+  in non strict mode
+template: non-strict
+flags: [noStrict]
+---*/
+
+//- body
+  return (function(arg) {
+    var yield = arg + 1;
+    return yield;
+  }(yield))
+//- assertions
+var item = iter.next();
+
+assert.sameValue(item.done, false);
+assert.sameValue(item.value, undefined);
+
+item = iter.next(42);
+
+assert.sameValue(item.done, true);
+assert.sameValue(item.value, 43);
diff --git a/src/generators/yield-identifier-spread-non-strict.case b/src/generators/yield-identifier-spread-non-strict.case
new file mode 100644
index 0000000000..219b749fa4
--- /dev/null
+++ b/src/generators/yield-identifier-spread-non-strict.case
@@ -0,0 +1,43 @@
+// Copyright (C) 2017 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+desc: >
+  Mixed use of object spread and yield as a valid identifier in a function body
+  inside a generator body in non strict mode
+template: non-strict
+info: |
+  Spread Properties
+
+  PropertyDefinition[Yield]:
+    (...)
+    ...AssignmentExpression[In, ?Yield]
+features: [object-spread]
+flags: [noStrict]
+---*/
+
+//- body
+  yield {
+     ...yield yield,
+     ...(function(arg) {
+        var yield = arg;
+        return {...yield};
+     }(yield)),
+     ...yield,
+  }
+//- assertions
+var iter = gen();
+
+iter.next();
+iter.next();
+iter.next({ x: 10, a: 0, b: 0 });
+iter.next({ y: 20, a: 1, b: 1 });
+var item = iter.next({ z: 30, b: 2 });
+
+assert.sameValue(item.done, false);
+assert.sameValue(item.value.x, 10);
+assert.sameValue(item.value.y, 20);
+assert.sameValue(item.value.z, 30);
+assert.sameValue(item.value.a, 1);
+assert.sameValue(item.value.b, 2);
+assert.sameValue(Object.keys(item.value).length, 5);
diff --git a/src/generators/yield-identifier-spread-strict.case b/src/generators/yield-identifier-spread-strict.case
new file mode 100644
index 0000000000..7c84ac4dae
--- /dev/null
+++ b/src/generators/yield-identifier-spread-strict.case
@@ -0,0 +1,28 @@
+// Copyright (C) 2017 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+desc: >
+  It's an early error if the AssignmentExpression is a function body with yield
+  as an identifier in strict mode.
+template: default
+info: |
+  Spread Properties
+
+  PropertyDefinition[Yield]:
+    (...)
+    ...AssignmentExpression[In, ?Yield]
+features: [object-spread]
+flags: [onlyStrict]
+negative:
+  phase: early
+  type: SyntaxError
+---*/
+
+//- body
+  return {
+     ...(function() {
+        var yield;
+        throw new Test262Error();
+     }()),
+  }
diff --git a/src/generators/yield-identifier-strict.case b/src/generators/yield-identifier-strict.case
new file mode 100644
index 0000000000..6c9e49f828
--- /dev/null
+++ b/src/generators/yield-identifier-strict.case
@@ -0,0 +1,19 @@
+// Copyright (C) 2017 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+desc: >
+  It's an early error if the generator body has another function body with
+  yield as an identifier in strict mode.
+template: default
+flags: [onlyStrict]
+negative:
+  phase: early
+  type: SyntaxError
+---*/
+
+//- body
+  (function() {
+    var yield;
+    throw new Test262Error();
+  }())
diff --git a/src/generators/yield-spread-arr-multiple.case b/src/generators/yield-spread-arr-multiple.case
new file mode 100644
index 0000000000..9d38f78979
--- /dev/null
+++ b/src/generators/yield-spread-arr-multiple.case
@@ -0,0 +1,27 @@
+// Copyright (C) 2017 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+desc: Use yield value in a array spread position
+template: default
+info: |
+  Array Initializer
+
+  SpreadElement[Yield, Await]:
+    ...AssignmentExpression[+In, ?Yield, ?Await]
+includes:
+  - compareArray.js
+---*/
+
+//- setup
+var arr = ['a', 'b', 'c'];
+var item;
+//- body
+  yield [...yield yield];
+//- assertions
+iter.next(false);
+item = iter.next(['a', 'b', 'c']);
+item = iter.next(item.value);
+
+assert(compareArray(item.value, arr));
+assert.sameValue(item.done, false);
diff --git a/src/generators/yield-spread-arr-single.case b/src/generators/yield-spread-arr-single.case
new file mode 100644
index 0000000000..5f31c2ddf6
--- /dev/null
+++ b/src/generators/yield-spread-arr-single.case
@@ -0,0 +1,25 @@
+// Copyright (C) 2017 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+desc: Use yield value in a array spread position
+template: default
+info: |
+  Array Initializer
+
+  SpreadElement[Yield, Await]:
+    ...AssignmentExpression[+In, ?Yield, ?Await]
+includes:
+  - compareArray.js
+---*/
+
+//- setup
+var arr = ['a', 'b', 'c'];
+//- body
+  yield [...yield];
+//- assertions
+iter.next(false);
+var item = iter.next(['a', 'b', 'c']);
+
+assert(compareArray(item.value, arr));
+assert.sameValue(item.done, false);
diff --git a/src/generators/yield-spread-obj.case b/src/generators/yield-spread-obj.case
new file mode 100644
index 0000000000..ccddbcfc22
--- /dev/null
+++ b/src/generators/yield-spread-obj.case
@@ -0,0 +1,33 @@
+// Copyright (C) 2017 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+desc: Use yield value in a object spread position
+template: default
+info: |
+  Spread Properties
+
+  PropertyDefinition[Yield]:
+    (...)
+    ...AssignmentExpression[In, ?Yield]
+features: [object-spread]
+includes:
+  - compareArray.js
+---*/
+
+//- body
+  yield {
+    ...yield,
+    y: 1,
+    ...yield yield,
+  };
+//- assertions
+iter.next();
+iter.next({ x: 42 });
+iter.next({ x: 'lol' });
+var item = iter.next({ y: 39 });
+
+assert.sameValue(item.value.x, 42);
+assert.sameValue(item.value.y, 39);
+assert.sameValue(Object.keys(item.value).length, 2);
+assert.sameValue(item.done, false);