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

Flow: losing info about explicitly inexact objects #10040

Closed
mrtnzlml opened this issue May 29, 2019 · 6 comments · Fixed by #10041
Closed

Flow: losing info about explicitly inexact objects #10040

mrtnzlml opened this issue May 29, 2019 · 6 comments · Fixed by #10041
Assignees
Labels
area: flow claimed good first issue i: bug outdated A closed issue/PR that is archived due to age. Recommended to make a new issue pkg: generator

Comments

@mrtnzlml
Copy link

Bug Report

Current Behavior
Babel is currently losing info about explicitly inexact objects when using Flow parser plugin. It should return the code as is. Thanks for checking it! :)

Input Code
This is not possible to reproduce in REPL. Input code:

// @flow strict
  
export type ExplicitlyInexact = { foo: number, ... };

Package.json:

{
  "dependencies": {
    "@babel/cli": "^7.4.4",
    "@babel/core": "^7.4.5"
  }
}

Command:

yarn babel input.js

Output:

// @flow strict
export type ExplicitlyInexact = {
  foo: number
};

As you can see, information about the inexact object (...) is lost.

Expected behavior/code
It should return the code as is:

// @flow strict
export type ExplicitlyInexact = {
  foo: number,
  ...
};

Babel Configuration (.babelrc)

{
  "parserOpts": {
    "plugins": ["flow"]
  }
}

Additional context/Screenshots
https://medium.com/flow-type/on-the-roadmap-exact-objects-by-default-16b72933c5cf

@babel-bot
Copy link
Collaborator

Hey @mrtnzlml! We really appreciate you taking the time to report an issue. The collaborators
on this project attempt to help as many people as possible, but we're a limited number of volunteers,
so it's possible this won't be addressed swiftly.

If you need any help, or just have general Babel or JavaScript questions, we have a vibrant Slack
community
that typically always has someone willing to help. You can sign-up here
for an invite.

@existentialism
Copy link
Member

Looks like generator needs support for printing the trailing ellipsis:

https://github.com/babel/babel/blob/master/packages/babel-generator/src/generators/flow.js#L388

Want to take a stab @mrtnzlml?

@mrtnzlml
Copy link
Author

I am afraid I do not have enough Babel knowledge for this. I could check it later but it would be helpful if someone else did. :) BTW, real-world (similar) example: kiwicom/babel-preset-kiwicom@f592fb7

@nicolo-ribaudo
Copy link
Member

If anyone wants to open a PR, this is the file which handles the printing of flow-related nodes: https://github.com/babel/babel/blob/master/packages/babel-generator/src/generators/flow.js.

As you can see in the @babel/types package, an ObjectTypeAnnotation node can have an inexact boolean flag:

defineType("ObjectTypeAnnotation", {
visitor: ["properties", "indexers", "callProperties", "internalSlots"],
aliases: ["Flow", "FlowType"],
builder: [
"properties",
"indexers",
"callProperties",
"internalSlots",
"exact",
],
fields: {
properties: validate(
arrayOfType(["ObjectTypeProperty", "ObjectTypeSpreadProperty"]),
),
indexers: validateOptional(arrayOfType("ObjectTypeIndexer")),
callProperties: validateOptional(arrayOfType("ObjectTypeCallProperty")),
internalSlots: validateOptional(arrayOfType("ObjectTypeInternalSlot")),
exact: {
validate: assertValueType("boolean"),
default: false,
},
// If the inexact flag is present then this is an object type, and not a
// declare class, declare interface, or interface. If it is true, the
// object uses ... to express that it is inexact.
inexact: validateOptional(assertValueType("boolean")),
},
});

In the printer for that node, we are only checking for the exact flag (which marks {| |} types) but not inexact:

export function ObjectTypeAnnotation(node: Object) {
if (node.exact) {
this.token("{|");
} else {
this.token("{");
}
// TODO: remove the array fallbacks and instead enforce the types to require an array
const props = node.properties.concat(
node.callProperties || [],
node.indexers || [],
node.internalSlots || [],
);
if (props.length) {
this.space();
this.printJoin(props, node, {
addNewlines(leading) {
if (leading && !props[0]) return 1;
},
indent: true,
statement: true,
iterator: () => {
if (props.length !== 1) {
this.token(",");
this.space();
}
},
});
this.space();
}
if (node.exact) {
this.token("|}");
} else {
this.token("}");
}
}

If you don't know how to clone Babel, follow these steps: (you need to have make and yarn available on your machine).

  1. Write a comment there to know other possible contributors that you are working on this bug.
  2. Fork the repo
  3. Run git clone https://github.com/<YOUR_USERNAME>/babel.git && cd babel
  4. Run yarn && make bootstrap
  5. Wait ⏳
  6. Run make watch (or make build whenever you change a file)
  7. Add a test (only input.js; output.js will be automatically generated)
  8. Update the code!
  9. yarn jest [name-of-the-package-to-test] to run the tests
    • If some test outputs don't match but the new results are correct, you can delete the bad output.js files and run the tests again
  10. If it is working, run make test tu run all the tests
  11. Run git push and open a PR!

@mrtnzlml
Copy link
Author

I was actually looking into it now and it looks doable. Especially with your guidance, thanks! I will take it and fix it.

@mrtnzlml
Copy link
Author

Alright, here is my attempt: #10041

Please, have a look and let me know what to improve.

@lock lock bot added the outdated A closed issue/PR that is archived due to age. Recommended to make a new issue label Aug 28, 2019
@lock lock bot locked as resolved and limited conversation to collaborators Aug 28, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area: flow claimed good first issue i: bug outdated A closed issue/PR that is archived due to age. Recommended to make a new issue pkg: generator
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants