1
0
Fork 0
mirror of https://github.com/jashkenas/coffeescript.git synced 2022-11-09 12:23:24 -05:00

Fix #4790: Double-check that we're not creating a bound generator function, even if the yield got stuffed inside a compiler-generated IIFE (#4792)

This commit is contained in:
Geoffrey Booth 2017-11-21 17:14:32 -08:00 committed by GitHub
parent 9812d28748
commit 7864acabc3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 27 additions and 1 deletions

View file

@ -3731,7 +3731,7 @@
// parameters after the splat, they are declared via expressions in the
// function body.
compileNode(o) {
var answer, body, boundMethodCheck, comment, condition, exprs, generatedVariables, haveBodyParam, haveSplatParam, i, ifTrue, j, k, l, len1, len2, len3, m, methodScope, modifiers, name, param, paramNames, paramToAddToScope, params, paramsAfterSplat, ref, ref1, ref2, ref3, ref4, ref5, ref6, ref7, ref8, scopeVariablesCount, signature, splatParamName, thisAssignments, wasEmpty;
var answer, body, boundMethodCheck, comment, condition, exprs, generatedVariables, haveBodyParam, haveSplatParam, i, ifTrue, j, k, l, len1, len2, len3, m, methodScope, modifiers, name, param, paramNames, paramToAddToScope, params, paramsAfterSplat, ref, ref1, ref2, ref3, ref4, ref5, ref6, ref7, ref8, scopeVariablesCount, signature, splatParamName, thisAssignments, wasEmpty, yieldNode;
if (this.ctor) {
if (this.isAsync) {
this.name.error('Class constructor may not be async');
@ -3941,6 +3941,14 @@
if (!(wasEmpty || this.noReturn)) {
this.body.makeReturn();
}
// JavaScript doesnt allow bound (`=>`) functions to also be generators.
// This is usually caught via `Op::compileContinuation`, but double-check:
if (this.bound && this.isGenerator) {
yieldNode = this.body.contains(function(node) {
return node instanceof Op && node.operator === 'yield';
});
(yieldNode || this).error('yield cannot occur inside bound (fat arrow) functions');
}
// Assemble the output
modifiers = [];
if (this.isMethod && this.isStatic) {

View file

@ -2699,6 +2699,12 @@ exports.Code = class Code extends Base
@body.expressions.unshift new Call(boundMethodCheck, [new Value(new ThisLiteral), @classVariable])
@body.makeReturn() unless wasEmpty or @noReturn
# JavaScript doesnt allow bound (`=>`) functions to also be generators.
# This is usually caught via `Op::compileContinuation`, but double-check:
if @bound and @isGenerator
yieldNode = @body.contains (node) -> node instanceof Op and node.operator is 'yield'
(yieldNode or @).error 'yield cannot occur inside bound (fat arrow) functions'
# Assemble the output
modifiers = []
modifiers.push 'static' if @isMethod and @isStatic

View file

@ -1197,6 +1197,18 @@ test "bound functions cannot be generators", ->
^^^^^^^^^^
'''
test "#4790: bound functions cannot be generators, even when were creating IIFEs", ->
assertErrorFormat '''
=>
for x in []
for y in []
yield z
''', '''
[stdin]:4:7: error: yield cannot occur inside bound (fat arrow) functions
yield z
^^^^^^^
'''
test "CoffeeScript keywords cannot be used as unaliased names in import lists", ->
assertErrorFormat """
import { unless, baz as bar } from 'lib'