Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix #4843: bad output when assigning to @prop in destructuring assignment with defaults #4848

Merged
merged 4 commits into from
Jan 16, 2018

Conversation

zdenko
Copy link
Collaborator

@zdenko zdenko commented Jan 7, 2018

Fixes #4843.

works = "maybe"
drinks = "beer"
class A
  constructor: ({@works = 'no', @drinks = 'wine'}) ->

a = new A {works: 'yes', drinks: 'coffee'}

Ouput

var A, a, drinks, works;

works = maybe;
drinks = beer;

A = class A {
  constructor({works: works1 = 'no', drinks: drinks1 = 'wine'}) {
    this.works = works1;
    this.drinks = drinks1;
  }

};

a = new A({
  works: 'yes',
  drinks: 'coffee'
});

# * simple literals `foo`
return iterator name.value, name, @ if name instanceof Literal
# * at-params `@foo`
return atParam name if name instanceof Value
for obj in name.objects ? []
# Save original obj.
nObj = obj
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In case of object destructuring parameter with the default value, e.g. ({@works = "no", @drinks}) ->, when replacement function is called from @renameParam, the parent is Assign in case of @works = "no", and Obj in case of @drinks.
Because of this @works = "no" is changed to works1 = "no" and @drinks to drinks:drinks1.

The best way, I could find, to solve this, was to pass Assign ({works:works1}) to @renameParam instead of Identifier (works1).
But, because Param::eachName passes obj.variable (@works in this case) to the iterator, I had to find a way to detect if param has a default value set in order to create a correct replacement. Passing original obj seems like a way to go.
Another way would be passing index and use it to check the argument in the Code::eachParamName (e.g. param.name.parameters[i]).

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, now I get it. I don't like that atParam magically references a variable from the for loop, tbh. Can you please make it explicit?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You mean to pass it as an argument?

atParam = (obj, originalObject = no) => iterator "@#{obj.properties[0].name.value}", obj, @, originalObject

....

else if obj.this
  atParam obj, nObj

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes.

@zdenko
Copy link
Collaborator Author

zdenko commented Jan 10, 2018

While working on this PR I noticed that object destructuring variables in parameters are always replaced, even if the variable isn't reserved in the scope.

class A
  constructor: ({@works}) ->

###
Output
var A;

A = class A {
  constructor({
      works: works
    }) {
    this.works = works;
  }
};
###

I don't think this is required, so I've changed the logic and now variables are replaced only if needed.

class A
  constructor: ({@works}) ->

###
A = class A {
  constructor({works}) {
    this.works = works;
  }
};
###

foo = 1
class B
  constructor: ({@foo}) ->

###
foo = 1;
B = class B {
  constructor({foo:foo1}) {
    this.foo = foo1;
  }
};
###

@zdenko zdenko changed the title Fix #4843: Fix #4843: bad output when assigning to @prop in destructuring assignment with defaults Jan 10, 2018
@GeoffreyBooth GeoffreyBooth merged commit c8c8c16 into jashkenas:master Jan 16, 2018
@Inve1951
Copy link
Contributor

gj, thx @zdenko 👍

zdenko added a commit to zdenko/coffeescript that referenced this pull request Jan 17, 2018
…ng assignment with defaults (jashkenas#4848)

* fix jashkenas#4843

* improvements

* typo

* small fix
GeoffreyBooth pushed a commit that referenced this pull request Feb 1, 2018
…ariables (#4853)

* fix #2047

* Additional check for 'step'; tests

* Fix #4105 (#4855)

* Update output

* Throw warning for unsupported runtimes, e.g. Node < 6 (#4839)

* fix #1403 (#4854)

* Update output

* [Change]: Destructuring with non-final spread should still use rest syntax (#4517) (#4825)

* destructuring optimization

* refactor

* minor improvement, fix errors

* minor refactoring

* improvements

* Update output

* Update output

* Fix #4843: bad output when assigning to @prop in destructuring assignment with defaults (#4848)

* fix #4843

* improvements

* typo

* small fix

* Fix #3441: parentheses wrapping expression throw invalid error  (#4849)

* fix #3441

* improvements

* refactor

* Fix #1726: expression in property access causes unexpected results (#4851)

* fix #1726

* Explain what's happening, rather than just linking to an issue

* Updated output

* Optimization

* Update output

* remove casting to number

* cleanup tests
@GeoffreyBooth GeoffreyBooth mentioned this pull request Feb 1, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants