@@ -2605,14 +2605,24 @@ exports.Code = class Code extends Base
2605
2605
2606
2606
# Check for duplicate parameters and separate `this` assignments.
2607
2607
paramNames = []
2608
- @eachParamName (name , node , param ) ->
2608
+ @eachParamName (name , node , param , obj ) ->
2609
2609
node .error " multiple parameters named '#{ name} '" if name in paramNames
2610
2610
paramNames .push name
2611
+
2611
2612
if node .this
2612
2613
name = node .properties [0 ].name .value
2613
2614
name = " _#{ name} " if name in JS_FORBIDDEN
2614
- target = new IdentifierLiteral o .scope .freeVariable name
2615
- param .renameParam node, target
2615
+ target = new IdentifierLiteral o .scope .freeVariable name, reserve : no
2616
+ # `Param` is object destructuring with a default value: ({@prop = 1}) ->
2617
+ # In a case when the variable name is already reserved, we have to assign
2618
+ # a new variable name to the destructured variable: ({prop:prop1 = 1}) ->
2619
+ replacement =
2620
+ if param .name instanceof Obj and obj instanceof Assign and
2621
+ obj .operatorToken .value is ' ='
2622
+ new Assign (new IdentifierLiteral name), target, ' object' # , operatorToken: new Literal ':'
2623
+ else
2624
+ target
2625
+ param .renameParam node, replacement
2616
2626
thisAssignments .push new Assign node, target
2617
2627
2618
2628
# Parse the parameters, adding them to the list of parameters to put in the
@@ -2901,12 +2911,14 @@ exports.Param = class Param extends Base
2901
2911
# `name` is the name of the parameter and `node` is the AST node corresponding
2902
2912
# to that name.
2903
2913
eachName : (iterator , name = @name ) ->
2904
- atParam = (obj ) => iterator " @#{ obj .properties [0 ].name .value } " , obj, @
2914
+ atParam = (obj , originalObj = null ) => iterator " @#{ obj .properties [0 ].name .value } " , obj, @ , originalObj
2905
2915
# * simple literals `foo`
2906
2916
return iterator name .value , name, @ if name instanceof Literal
2907
2917
# * at-params `@foo`
2908
2918
return atParam name if name instanceof Value
2909
2919
for obj in name .objects ? []
2920
+ # Save original obj.
2921
+ nObj = obj
2910
2922
# * destructured parameter with default value
2911
2923
if obj instanceof Assign and not obj .context ?
2912
2924
obj = obj .variable
@@ -2928,7 +2940,7 @@ exports.Param = class Param extends Base
2928
2940
@ eachName iterator, obj .base
2929
2941
# * at-params within destructured parameters `{@foo}`
2930
2942
else if obj .this
2931
- atParam obj
2943
+ atParam obj, nObj
2932
2944
# * simple destructured parameters {foo}
2933
2945
else iterator obj .base .value , obj .base , @
2934
2946
else if obj instanceof Elision
@@ -2945,7 +2957,14 @@ exports.Param = class Param extends Base
2945
2957
if parent instanceof Obj
2946
2958
key = node
2947
2959
key = node .properties [0 ].name if node .this
2948
- new Assign new Value (key), newNode, ' object'
2960
+ # No need to assign a new variable for the destructured variable if the variable isn't reserved.
2961
+ # Examples:
2962
+ # `({@foo}) ->` should compile to `({foo}) { this.foo = foo}`
2963
+ # `foo = 1; ({@foo}) ->` should compile to `foo = 1; ({foo:foo1}) { this.foo = foo1 }`
2964
+ if node .this and key .value is newNode .value
2965
+ new Value newNode
2966
+ else
2967
+ new Assign new Value (key), newNode, ' object'
2949
2968
else
2950
2969
newNode
2951
2970
0 commit comments