mirror of
https://github.com/jashkenas/coffeescript.git
synced 2026-05-03 03:00:14 -04:00
If compiling a function parameter creates any generated variables (e.g. ref), shift the declarations for those variables into the parent scope; fixes #4413
This commit is contained in:
@@ -3675,7 +3675,7 @@
|
||||
// parameters after the splat, they are declared via expressions in the
|
||||
// function body.
|
||||
compileNode(o) {
|
||||
var answer, body, boundMethodCheck, comment, condition, exprs, 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, 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, scopeVariablesCount, signature, splatParamName, thisAssignments, wasEmpty;
|
||||
if (this.ctor) {
|
||||
if (this.isAsync) {
|
||||
this.name.error('Class constructor may not be async');
|
||||
@@ -3900,7 +3900,15 @@
|
||||
if (haveSplatParam && i === params.length - 1) {
|
||||
signature.push(this.makeCode('...'));
|
||||
}
|
||||
// Compile this parameter, but if any generated variables get created
|
||||
// (e.g. `ref`), shift those into the parent scope since we can’t put a
|
||||
// `var` line inside a function parameter list.
|
||||
scopeVariablesCount = o.scope.variables.length;
|
||||
signature.push(...param.compileToFragments(o));
|
||||
if (scopeVariablesCount !== o.scope.variables.length) {
|
||||
generatedVariables = o.scope.variables.splice(scopeVariablesCount);
|
||||
o.scope.parent.variables.push(...generatedVariables);
|
||||
}
|
||||
}
|
||||
signature.push(this.makeCode(')'));
|
||||
// Block comments between `)` and `->`/`=>` get output between `)` and `{`.
|
||||
|
||||
@@ -2674,7 +2674,14 @@ exports.Code = class Code extends Base
|
||||
for param, i in params
|
||||
signature.push @makeCode ', ' if i isnt 0
|
||||
signature.push @makeCode '...' if haveSplatParam and i is params.length - 1
|
||||
# Compile this parameter, but if any generated variables get created
|
||||
# (e.g. `ref`), shift those into the parent scope since we can’t put a
|
||||
# `var` line inside a function parameter list.
|
||||
scopeVariablesCount = o.scope.variables.length
|
||||
signature.push param.compileToFragments(o)...
|
||||
if scopeVariablesCount isnt o.scope.variables.length
|
||||
generatedVariables = o.scope.variables.splice scopeVariablesCount
|
||||
o.scope.parent.variables.push generatedVariables...
|
||||
signature.push @makeCode ')'
|
||||
# Block comments between `)` and `->`/`=>` get output between `)` and `{`.
|
||||
if @funcGlyph?.comments?
|
||||
|
||||
@@ -471,3 +471,12 @@ test "#3845/#3446: chain after function glyph", ->
|
||||
doThing()
|
||||
.then (@result) =>
|
||||
.catch handleError
|
||||
|
||||
test "#4413: expressions in function parameters that create generated variables have those variables declared correctly", ->
|
||||
'use strict'
|
||||
# We’re in strict mode because we want an error to be thrown if the generated
|
||||
# variable (`ref`) is assigned before being declared.
|
||||
foo = -> null
|
||||
bar = -> 33
|
||||
f = (a = foo() ? bar()) -> a
|
||||
eq f(), 33
|
||||
|
||||
Reference in New Issue
Block a user