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

Remove whitespace generation #5833

Merged
merged 2 commits into from
Jun 28, 2017
Merged

Remove whitespace generation #5833

merged 2 commits into from
Jun 28, 2017

Conversation

danez
Copy link
Member

@danez danez commented Jun 7, 2017

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

This removes the whitespace generation and the generator would now simply print everything according to the default settings and not based on the AST tokens.
By removing this babel can use babylon without tokens, which brings a performance boost in babylon.

This change on it's own doesn't change the performance much. I tried printing react a 100 times with (14.8s) and without (15.0s) this change and it is neglectable, but at least not bad.

I removed all expected files and regenerated them.

@@ -1,11 +1,9 @@
var test = {
/**
* Before bracket init
*/
["a"]: "1",
*/["a"]: "1",
Copy link
Member

Choose a reason for hiding this comment

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

Seems like a bad case here.

function test() {}

// Copyright (C) 2012 Yusuke Suzuki <utatane.tea@gmail.com>
function test() {} // Copyright (C) 2012 Yusuke Suzuki <utatane.tea@gmail.com>
Copy link
Member

Choose a reason for hiding this comment

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

Hmm, also an unfortunate case.

@loganfsmyth
Copy link
Member

Love this PR, anything to simplify codegen is a plus in my book.

I'd vote for including newlines after all block comments to make some of these examples nicer, and maybe to include a newline after all declaration statements?

@danez
Copy link
Member Author

danez commented Jun 8, 2017

Yes will look into this, what I also noticed is that

function a () {
};

gets reprinted as

function a() {
}

;

But this is because of the EmptyStatement after the function. I wasn't sure how to fix that because the generation always prints a newline after a Node. And I didn't want to create special hacks in the code for EmptyStatement.

@codecov
Copy link

codecov bot commented Jun 8, 2017

Codecov Report

Merging #5833 into 7.0 will decrease coverage by 0.06%.
The diff coverage is 100%.

Impacted file tree graph

@@            Coverage Diff             @@
##              7.0    #5833      +/-   ##
==========================================
- Coverage   85.25%   85.19%   -0.07%     
==========================================
  Files         284      283       -1     
  Lines        9963     9921      -42     
  Branches     2781     2765      -16     
==========================================
- Hits         8494     8452      -42     
+ Misses        969      967       -2     
- Partials      500      502       +2
Impacted Files Coverage Δ
packages/babel-generator/src/generators/flow.js 98.89% <100%> (-0.37%) ⬇️
packages/babel-generator/src/index.js 79.31% <100%> (-0.69%) ⬇️
packages/babel-generator/src/node/whitespace.js 96.05% <100%> (+3.86%) ⬆️
packages/babel-generator/src/printer.js 97.9% <100%> (-0.5%) ⬇️
packages/babel-generator/src/generators/classes.js 98.27% <0%> (-1.73%) ⬇️
...bel-plugin-transform-es2015-classes/src/vanilla.js 90.63% <0%> (ø) ⬆️
packages/babel-traverse/src/path/context.js 86.2% <0%> (ø) ⬆️
packages/babel-traverse/src/visitors.js 86.66% <0%> (+0.95%) ⬆️
... and 1 more

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 5387d9f...80cef9c. Read the comment docs.

@danez
Copy link
Member Author

danez commented Jun 8, 2017

Okay I change the generation now:

  • Add newline after last empty SwitchCase, to avoid
switch {
case 'a':
  break;
default:}
  • Add newlines around block comments if they are non-flow comments or contain newlines

I'm not sure how I could add a newline after every declaration.

I also made two commits. One with the code changes and one with the test fixes.

var a: { y: string, (): number, (x: string): string, };
var a: { <T>(x: T): number };
interface A { (): number };
var a: { (): number
Copy link
Member

Choose a reason for hiding this comment

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

Weird asymmetry on these objects. I think if the closing bracket is on its own line, the opening one should be too.

Copy link
Member Author

Choose a reason for hiding this comment

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

Fixed

interface A { foo: () => number };
interface Dictionary { length: number, [index: string]: string, };
interface A {}
;
Copy link
Member

Choose a reason for hiding this comment

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

Are these actually parsed as EmptyStatement nodes, or is the semicolon being printed weirdly.

Copy link
Member Author

Choose a reason for hiding this comment

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

Not sure about this and how to approach. There is always an EmptyStatement generated after declarations with semicolon, and I'm not sure how we could ignore it if possible.

Copy link
Member

Choose a reason for hiding this comment

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

Looking at the AST from Flow itself, the semicolons are not in the grammar for interface declarations, which means the current behavior of parsing them as EmptyStatement nodes is correct. We should probably just remove the semicolons from the actual.js files, but I understand if you don't want to for now.

comment.type === "CommentBlock" &&
(
(!comment.value.startsWith(":") &&
!comment.value.startsWith("flow-include")) ||
Copy link
Member

Choose a reason for hiding this comment

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

Do we have any tests for this? Does Flow actually require these to be on the same line, or is this just for making it nicer to read? I don't love having a special case like this.

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 tested and they don't need to be on the same line. Will remove

Copy link
Member Author

@danez danez Jun 8, 2017

Choose a reason for hiding this comment

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

Should I leave the case that only block comments with newlines inside them get newlines around them? Or add newlines around to all block comments?

So that inline block comments stay inline? like function a(a/*, b */) {}

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 removed it now, all BlockComments have newline around them now.

@hzoo
Copy link
Member

hzoo commented Jun 9, 2017

Are we removing end of file newlines now?

@danez
Copy link
Member Author

danez commented Jun 9, 2017

Not sure about the actual output, in the fixture runner they are always trimmed. I will check

@danez
Copy link
Member Author

danez commented Jun 17, 2017

@hzoo It seems to me we are always removing whitespaces at the end already here: https://github.com/babel/babel/blob/7.0/packages/babel-generator/src/buffer.js#L45

Although we might remove the trim-right here also, as it is probably irrelevant now if there is a whitespace at then end or not.

@peey
Copy link
Contributor

peey commented Jun 18, 2017

Could we do this for code generation - don't worry too much about styling while generating code, but then pipe it through a linter's autofix for style consistency in the generated code?

That should free us from worrying about special cases like switch-case and empty statement.

Pros:

  • Standard output for the same input no matter the style

Cons:

  • Dependence on external tools for support of features that the generated code would use (shouldn't be a problem in most cases)

@hzoo
Copy link
Member

hzoo commented Jun 19, 2017

then pipe it through a linter's autofix for style consistency in the generated code

The purpose was to make babel-generator faster so having to use another tool would go against this idea especially since it's easier to just encode the logic in the printer itself rather than in an autofixer. And if we were going to do that I would just use prettier as the printer anyway (which is much slower than hardcoding something simple)?

I think we just want it to look presentable but focus on speed. Again it's generated output not the source code (why we removed the options for quotes).

@danez
Copy link
Member Author

danez commented Jun 20, 2017

Let me know if I should change more in this PR.

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.

@danez I'm totally good with this, I would just be more generous with adding newlines/whitespace (less checks to see if it's necessary or not) and then maybe figure out the ; thing so tests look more "normal" later

return {
before: node.consequent.length || parent.cases[0] === node,
after: !node.consequent.length && parent.cases[parent.cases.length - 1] === node,
Copy link
Member

Choose a reason for hiding this comment

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

This doesn't make sense.

Copy link
Member Author

Choose a reason for hiding this comment

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

Why not? It only covers the case of empty last case

switch() {
  default:
}

Copy link
Member

Choose a reason for hiding this comment

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

Oh, i read this as two !node.consequent.length && last(node.consequent). Never mind.

if (
parent.callProperties[0] === node &&
(!parent.properties || !parent.properties.length)
) {
Copy link
Member

Choose a reason for hiding this comment

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

Negative indent.

danez and others added 2 commits June 27, 2017 21:30
Changes to printing:
* Add newline after last empty SwitchCase
* Add newlines around block comments if they are non-flow comments or contain newlines
Copy link
Member

@existentialism existentialism left a comment

Choose a reason for hiding this comment

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

I'll work on fixing the semis in the test fixtures

@existentialism existentialism merged commit b3372a5 into babel:7.0 Jun 28, 2017
@hzoo hzoo added performance PR: Internal 🏠 A type of pull request used for our changelog categories labels Jun 28, 2017
@hzoo
Copy link
Member

hzoo commented Jun 28, 2017

Alright then!

@danez danez deleted the remove-tokens branch June 29, 2017 03:43
@danez
Copy link
Member Author

danez commented Jun 29, 2017

Thanks for taking care.

@sebmck
Copy link
Contributor

sebmck commented Jun 29, 2017

For what it's worth, you can still retain newlines when printing a statement list by comparing the loc.end.line and loc.start.line of two adjacent statements and inserting the correct amount of newlines.

@hzoo hzoo mentioned this pull request Sep 16, 2017
2 tasks
@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
area: perf outdated A closed issue/PR that is archived due to age. Recommended to make a new issue pkg: generator PR: Internal 🏠 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

7 participants