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

object rest - fix when destructuring in variables/parameters #4755

Merged
merged 5 commits into from
Nov 15, 2016

Conversation

hzoo
Copy link
Member

@hzoo hzoo commented Oct 19, 2016

Description

Fixes #4074

The issue is that this plugin (http://babeljs.io/docs/plugins/transform-object-rest-spread/) depends on the destructuring/parameter plugins to work correctly. Thus it doesn't work standalone and this PR is trying to fix that!

REPL

Test with http://astexplorer.net/#/Y32VLF7LZ0/16

Test Cases

RestProperty

  • Parameters
function a({ b, ...c }) {}
  • VariableDeclaration
const { a, ...b } = c;
  • ExportNamedDeclaration
export var { a, ...b } = c;
  • CatchClause
try {} catch ({a, ...b}) {}
  • AssignmentExpression
({a, ...b} = c);
  • ForXStatement
for ({a, ...b} of []) {}

SpreadProperty

  • ObjectExpression
var a = { ...b, ...c }

Testing

Can test locally by replacing in node_modules: https://gist.github.com/hzoo/d269ccfd5758c556c900f47dd752cd61

replace node_modules/babel-plugin-transform-object-rest-spread/lib/index.js


Future

#4755 (comment)

@hzoo hzoo added the PR: Bug Fix 🐛 A type of pull request used for our changelog categories label Oct 19, 2016
var { [a]: b, ...c } = z;
var {x1, ...y1} = z;
let {x2, y2, ...z2} = z;
const {w3, x3, y3, ...z4} = z;
Copy link
Member

Choose a reason for hiding this comment

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

Should also check, just to see if things are preserved as expected:

let [ x4, { y4, ...z4 } ] = z
let { x: { y: [ y5 ] = [], ...z5 } = {} } = z

var { x1 } = z;
var y1 = babelHelpers.objectWithoutProperties(z, ["x1"]);
var { [a]: b } = z;
var c = babelHelpers.objectWithoutProperties(z, [a]);
Copy link
Member

Choose a reason for hiding this comment

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

(unrelated but) this breaks in real code when typeof a is not string or symbol :(

@codecov-io
Copy link

codecov-io commented Nov 4, 2016

Current coverage is 89.32% (diff: 100%)

Merging #4755 into master will increase coverage by 0.04%

@@             master      #4755   diff @@
==========================================
  Files           196        196          
  Lines         13816      13936   +120   
  Methods        1436       1449    +13   
  Messages          0          0          
  Branches       3211       3239    +28   
==========================================
+ Hits          12335      12449   +114   
- Misses         1481       1487     +6   
  Partials          0          0          

Powered by Codecov. Last update 62ae3c7...ddfcd88

@hzoo
Copy link
Member Author

hzoo commented Nov 8, 2016

cc @sebmarkbage

http://astexplorer.net/#/Y32VLF7LZ0/13 based on the destructuring transform there are a few other (weird) ways to use RestProperty?

Common

// VariableDeclaration
const { a, ...b } = c;
// in Parameters
function a({ b, ...c }) {}
// ExportNamedDeclaration
export var { b, ...c } = asdf2;

Odd/not fixed yet

// AssignmentExpression
({a, ...b} = c);

// ForXStatement
for (let {a, ...b} of []) {}

// CatchClause
try {}
catch ({a, ...b}) {}

@hzoo hzoo force-pushed the object-rest-standalone branch 3 times, most recently from 98a6238 to 7e173dd Compare November 8, 2016 22:49
@sebmarkbage
Copy link

const { ...a, b } = c; is not valid. Rest is only allowed as the last property.

@hzoo
Copy link
Member Author

hzoo commented Nov 8, 2016

Oops that is a wrong example! We already fixed those static errors in babylon (https://github.com/babel/babylon/releases/tag/v6.11.3)

@DrewML
Copy link
Member

DrewML commented Nov 9, 2016

Was going to ask if it'd be worth breaking out any of the copied code from visitor/transform code from one of the plugins so both can use it, but in reality that level of abstraction is probably just going to create more of a maintenance pain.

Copy link
Member

@DrewML DrewML left a comment

Choose a reason for hiding this comment

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

Stared at the test cases for quite a bit, and I couldn't find anything you weren't covering.

@hzoo
Copy link
Member Author

hzoo commented Nov 10, 2016

Yeah exactly - I think in reality not everything is updated/shared that much anyway?

var y1 = babelHelpers.objectWithoutProperties(z, ["x1"]);
x1++;
var { [a]: b } = z;
var c = babelHelpers.objectWithoutProperties(z, [a]);
Copy link
Member

@Jessidhia Jessidhia Nov 10, 2016

Choose a reason for hiding this comment

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

a is evaluated twice (fine here, but what if it's a CallExpression or a MemberExpression?)

Copy link
Member

Choose a reason for hiding this comment

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

objectWithoutProperties also won't behave correctly if typeof a !== 'string': https://github.com/babel/babel/blob/master/packages/babel-helpers/src/helpers.js#L434

function hasRestProperty(node) {
for (let property of (node.properties)) {
if (t.isRestProperty(property)) {
return true;
Copy link
Member

Choose a reason for hiding this comment

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

to be more type consistent I would also add a return false at the end of the function.

RestProperty(path) {
if (!this.originalPath.node) {
return;
}
Copy link
Member

Choose a reason for hiding this comment

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

Too bad we don't have working coverage reports, would be interested if this is covered. Don't see why it should be falsey.

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 think it was because at the time I was getting an infinite loop or the node was removed and I was trying to use it - will remove.

@hzoo
Copy link
Member Author

hzoo commented Nov 15, 2016

Ok let's do this. 🎉 finally

@danez danez deleted the object-rest-standalone branch November 16, 2016 08:43
@danez
Copy link
Member

danez commented Nov 16, 2016

 👍

@gustavohenke
Copy link

Docs are still mentioning this PR: https://babeljs.io/docs/plugins/transform-object-rest-spread/

@xpepermint
Copy link

xpepermint commented Nov 28, 2016

+ if I include this plugin, webpack ignores other plugins and my file grows from ~80KB to 800KB

lukyth added a commit to lukyth/babel that referenced this pull request Dec 2, 2016
iamchenxin added a commit to iamchenxin/init-app that referenced this pull request Dec 6, 2016
https://babeljs.io/docs/plugins/transform-object-rest-spread/
Object Rest currently depends on the destructuring transform and parameters transform
Even if you are using Node 6 or a platform that supports destructuring, transform-es2015-destructuring and transform-es2015-parameters will currently need to be enabled if using object rest properties.

There is a PR open to fix this and make this transform standalone: babel/babel#4755
@swernerx
Copy link

swernerx commented Dec 6, 2016

It seems like the docs here are still wrong about this: https://babeljs.io/docs/plugins/transform-object-rest-spread/

panagosg7 pushed a commit to panagosg7/babel that referenced this pull request Jan 17, 2017
)

* object rest - fix when destructuring in variables/parameters

* fixes + ExportNamedDeclaration support

* Account for CatchClause

* support ForXStatement

* support assignment expression? + PR fixes
@migueloller
Copy link

I've been having issues with Babel and transform-object-rest-spread. Ultimately the issue went away after including transform-es2015-destructuring.

When looking at the transpiled code it looks like the line that is causing the error was transpiled away but looking further it seems that it was moved elsewhere.

Here's what my .babelrc looks like:

{
  "presets": [
    ["env", {
      "targets": {
        "node": 7.2
      }
    }]
  ],
  "plugins": [
    "transform-class-properties",
    "transform-object-rest-spread",
    "transform-flow-strip-types"
  ]
}

I tried reproducing this in the Babel REPL but was unable to. Is it possible I'm seeing some type of edge case?

@hzoo
Copy link
Member Author

hzoo commented Jan 19, 2017

In order to help you more you'll need to provide a repro case with code, otherwise it's not easy to find the issue. There are a few issues with it already that have PRs. #5088, #5151.

if you need more want help, I would recommend checking out our slack community

@migueloller
Copy link

I think #5151 is the problem I'm seeing! I'll wait for it to be merged and check back again because I can't find a way to reproduce my specific case.

Thanks @hzoo!

@olalonde
Copy link

On a related note, would be nice to have a tool that takes a git commit as input and tells you whether it was published on npm (bonus: alerts you by email when it is :)).

@hzoo
Copy link
Member Author

hzoo commented Jan 19, 2017

😄 yeah I want the bot (babel-bot) to make a message when the merged pr is released and in what version etc.

edit: https://github.com/babel/babel-bot

@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.

Object rest spread not working correctly in object destructuring (T7086)