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 issue semi-colon gets inserted unnecessarily #5749

Merged
merged 2 commits into from
May 19, 2017

Conversation

buunguyen
Copy link
Member

Q A
Patch: Bug Fix? yes
Major: Breaking Change? no
Minor: New Feature? no
Deprecations? no
Spec Compliancy? yes
Tests Added/Pass? yes
Fixed Tickets Fixes #5744
License MIT
Doc PR no
Dependency Changes no

Original:

if (true) [a, b] = [b, a];

Transpiled version:

if (true) {
  ;
  var _ref = [b, a];
  a = _ref[0];
  b = _ref[1];
  _ref;
}

The problem is insertAfter could push an empty expression statement, resulting in the semi-colon. This change checks to make sure the expression statement is not empty before pushing.

@codecov
Copy link

codecov bot commented May 19, 2017

Codecov Report

Merging #5749 into 7.0 will decrease coverage by <.01%.
The diff coverage is 0%.

Impacted file tree graph

@@            Coverage Diff             @@
##              7.0    #5749      +/-   ##
==========================================
- Coverage   84.63%   84.62%   -0.01%     
==========================================
  Files         282      282              
  Lines        9861     9862       +1     
  Branches     2766     2766              
==========================================
  Hits         8346     8346              
  Misses        997      997              
- Partials      518      519       +1
Impacted Files Coverage Δ
packages/babel-traverse/src/path/modification.js 73.07% <0%> (-1.69%) ⬇️
packages/babel-traverse/src/path/context.js 87.06% <0%> (+0.86%) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update ce6f672...a0df33b. Read the comment docs.

@@ -126,7 +126,10 @@ export function insertAfter(nodes) {
if (Array.isArray(this.container)) {
return this._containerInsertAfter(nodes);
} else if (this.isStatementOrBlock()) {
if (this.node) nodes.unshift(this.node);
// Unshift current node if it's not an empty expression
if (this.node && (!this.isExpressionStatement() || this.node.expression != null)) {
Copy link
Member

Choose a reason for hiding this comment

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

Is it better to do ^ or just check if it's an not an EmptyExpression?

Copy link
Member Author

Choose a reason for hiding this comment

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

I can't find EmptyExpression or isEmptyExpression in the codebase. Or did you mean we should create a new method isEmptyExpression to wrap the above? Like:

if (this.node && !this.isEmptyExpression()) {...}
...
isEmptyExpression() => this.isExpressionStatement() && this.node.expression == null

Copy link
Member Author

Choose a reason for hiding this comment

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

Or you probably meant EmptyStatement :). Let me try that.

Copy link
Member

Choose a reason for hiding this comment

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

oh sorry I thought it was "EmptyStatement"

Copy link
Member Author

Choose a reason for hiding this comment

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

I just tried, it doesn't work.

In this particular case, this.node is of type ExpressionStatement. this.isEmptyStatement() returns false because ExpressionStatement isn't EmptyStatement and they aren't aliases of one another.

I wondered why this.node wasn't EmptyStatement in the first place and dug in a bit more. Turns out this line https://github.com/babel/babel/blob/7.0/packages/babel-traverse/src/path/replacement.js#L50 sets this.container['expression'] = null and this.container is this.node in the piece of code in question.

Copy link
Member

Choose a reason for hiding this comment

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

And do we want to make the same change in insertBefore?

Copy link
Member Author

Choose a reason for hiding this comment

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

I thought so too, but couldn't come up with a test for that case. Basically we need something that results in:

{
  code 
  code 
  ;  <--  empty statement here
}

Without a test/bug that exposes the above behavior, there's no guarantee such situation is possible. Currently, the behavior is caused by that line to this.container['expression'] = null, which is only invoked before insertAfter. I haven't seen anything line that before insertBefore. That said, I could definitely make that change to insertBefore for the extra caution. Let me know.

Copy link
Member

Choose a reason for hiding this comment

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

Ah ok I see. I guess this.container['expression'] = null is rather a weird way to do things but we can do this

Copy link
Member

@hzoo hzoo left a comment

Choose a reason for hiding this comment

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

lgtm was just curious about how we should do the check

@existentialism existentialism added the PR: Bug Fix 🐛 A type of pull request used for our changelog categories label May 19, 2017
@hzoo hzoo merged commit c474fd4 into babel:7.0 May 19, 2017
@hzoo
Copy link
Member

hzoo commented May 19, 2017

Thanks for looking into this and doing a through investigation!

@buunguyen buunguyen deleted the redundant-semi-colon branch June 1, 2017 17:28
@lock lock bot added the outdated A closed issue/PR that is archived due to age. Recommended to make a new issue label Oct 6, 2019
@lock lock bot locked as resolved and limited conversation to collaborators Oct 6, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
outdated A closed issue/PR that is archived due to age. Recommended to make a new issue PR: Bug Fix 🐛 A type of pull request used for our changelog categories
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants