Skip to content
This repository has been archived by the owner on Aug 31, 2023. It is now read-only.

feat(rome_js_formatter,rome_cli): Add semicolons option #3702

Merged
merged 13 commits into from
Nov 16, 2022

Conversation

MichaReiser
Copy link
Contributor

@MichaReiser MichaReiser commented Nov 13, 2022

Summary

Adds the new --semicolons option that can either be:

  • always (default): Always inserts semicolons at the end of statement or class and type members.
  • as-needed (same as Prettier's --no-semi): Only inserts semicolons where it is necessary to not change the semantics of the program.

Test Plan

I added a handful of tests myself and copied over the prettier tests.

I plan to ship a nightly and ask people to try Rome in their repository and report any issue to get better test coverage.

@netlify
Copy link

netlify bot commented Nov 13, 2022

Deploy Preview for docs-rometools ready!

Name Link
🔨 Latest commit c470039
🔍 Latest deploy log https://app.netlify.com/sites/docs-rometools/deploys/6374af83135e390009553fd1
😎 Deploy Preview https://deploy-preview-3702--docs-rometools.netlify.app/playground
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify site settings.

@jeysal
Copy link
Contributor

jeysal commented Nov 13, 2022

Appreciate the much clearer naming than in Prettier 👍 (semi? Are we only formatting half the code? no-semi? But there are still some semicolons!)

Since not printing semicolons increases the risk of introducing a bug that causes the formatter to print code that behaves differently from the input, what do you think of testing this by doing a semicolons: as-needed print of all formatter test cases we have and then checking it's the same AST as before?
Would be almost as good as a property-based test that checks this condition for all possible trees, but way easier to do using our existing hundreds of tests.
Looks like check_reformat already does something like this IIUC, but of course only with semicolons: as-needed for the few test cases that we come up with.

@github-actions
Copy link

Parser conformance results on ubuntu-latest

js/262

Test result main count This PR count Difference
Total 45879 45879 0
Passed 44936 44936 0
Failed 943 943 0
Panics 0 0 0
Coverage 97.94% 97.94% 0.00%

jsx/babel

Test result main count This PR count Difference
Total 39 39 0
Passed 36 36 0
Failed 3 3 0
Panics 0 0 0
Coverage 92.31% 92.31% 0.00%

symbols/microsoft

Test result main count This PR count Difference
Total 5946 5946 0
Passed 1621 1621 0
Failed 4325 4325 0
Panics 0 0 0
Coverage 27.26% 27.26% 0.00%

ts/babel

Test result main count This PR count Difference
Total 588 588 0
Passed 519 519 0
Failed 69 69 0
Panics 0 0 0
Coverage 88.27% 88.27% 0.00%

ts/microsoft

Test result main count This PR count Difference
Total 16257 16257 0
Passed 12397 12397 0
Failed 3860 3860 0
Panics 0 0 0
Coverage 76.26% 76.26% 0.00%

@MichaReiser
Copy link
Contributor Author

MichaReiser commented Nov 14, 2022

Since not printing semicolons increases the risk of introducing a bug that causes the formatter to print code that behaves differently from the input, what do you think of testing this by doing a semicolons: as-needed print of all formatter test cases we have and then checking it's the same AST as before? Would be almost as good as a property-based test that checks this condition for all possible trees, but way easier to do using our existing hundreds of tests. Looks like check_reformat already does something like this IIUC, but of course only with semicolons: as-needed for the few test cases that we come up with.

I like the idea and tried to implement this real quick, but it turned out to be a bit more complicated:

If a statement needing a semicolon is at the start of a block, then the ; becomes an empty statement that wouldn't exist otherwise:

((b) => (c) => (d) => {
  return 3;
})(x);

// vs 
;((b) => (c) => (d) => {
  return 3;
})(x);

The logic then very quickly becomes rather involved, particularly because semicolons must be skipped too.

@MichaReiser MichaReiser marked this pull request as ready for review November 14, 2022 17:01
@MichaReiser MichaReiser requested a review from a team November 14, 2022 17:01
@MichaReiser MichaReiser added the A-Formatter Area: formatter label Nov 14, 2022
@calibre-analytics
Copy link

calibre-analytics bot commented Nov 14, 2022

Comparing feat(rome_js_formatter,rome_cli): Add semicolons option Snapshot #6 to median since last deploy of rome.tools.

LCP? CLS? TBT?
Overall
Median across all pages and test profiles
303ms
from 276ms
0.049
from 0.009
0ms
no change
Chrome Desktop
Chrome Desktop • Cable
303ms
from 276ms
0.044
from 0.005
0ms
no change
iPhone, 4G LTE
iPhone 12 • 4G LTE
242ms
from 238ms
0.082
from 0.01
0ms
no change
Motorola Moto G Power, 3G connection
Motorola Moto G Power • Regular 3G
1.28s
from 1.05s
0.049
from 0.009
0ms
no change

1 page tested

 Home

Browser previews

Chrome Desktop iPhone, 4G LTE Motorola Moto G Power, 3G connection
Chrome Desktop iPhone, 4G LTE Motorola Moto G Power, 3G connection

Most significant changes

Value Budget
Total JavaScript Size in Bytes
Chrome Desktop
1.33 MB
from 86.8 KB
Total JavaScript Size in Bytes
iPhone, 4G LTE
1.33 MB
from 86.8 KB
Total JavaScript Size in Bytes
Motorola Moto G Power, 3G connection
1.33 MB
from 86.8 KB
Cumulative Layout Shift
Chrome Desktop
0.044
from 0.005
Cumulative Layout Shift
iPhone, 4G LTE
0.082
from 0.01

16 other significant changes: Cumulative Layout Shift on Motorola Moto G Power, 3G connection, Number of Requests on Chrome Desktop, Number of Requests on iPhone, 4G LTE, Number of Requests on Motorola Moto G Power, 3G connection, Total Page Size in Bytes on Chrome Desktop, Total Page Size in Bytes on iPhone, 4G LTE, Total Page Size in Bytes on Motorola Moto G Power, 3G connection, Total Image Size in Bytes on Chrome Desktop, Total Image Size in Bytes on iPhone, 4G LTE, Total Image Size in Bytes on Motorola Moto G Power, 3G connection, Total CSS Size in Bytes on Chrome Desktop, Total CSS Size in Bytes on iPhone, 4G LTE, Total CSS Size in Bytes on Motorola Moto G Power, 3G connection, Total HTML Size in Bytes on Chrome Desktop, Total HTML Size in Bytes on iPhone, 4G LTE, Total HTML Size in Bytes on Motorola Moto G Power, 3G connection

Calibre: Site dashboard | View this PR | Edit settings | View documentation

@MichaReiser
Copy link
Contributor Author

!bench_formatter

@github-actions
Copy link

Formatter Benchmark Results

group                                    main                                   pr
-----                                    ----                                   --
formatter/checker.ts                     1.00   513.5±18.24ms     5.1 MB/sec    1.01   516.2±21.09ms     5.0 MB/sec
formatter/compiler.js                    1.09   290.0±12.78ms     3.6 MB/sec    1.00   266.8±11.71ms     3.9 MB/sec
formatter/d3.min.js                      1.05    217.4±6.48ms  1234.6 KB/sec    1.00   207.1±12.92ms  1296.2 KB/sec
formatter/dojo.js                        1.07     14.3±0.73ms     4.8 MB/sec    1.00     13.4±0.72ms     5.1 MB/sec
formatter/ios.d.ts                       1.02   290.4±12.96ms     6.4 MB/sec    1.00    286.0±9.39ms     6.5 MB/sec
formatter/jquery.min.js                  1.00     56.2±2.80ms  1505.3 KB/sec    1.03     57.9±3.19ms  1460.8 KB/sec
formatter/math.js                        1.08   431.7±11.46ms  1536.1 KB/sec    1.00   400.9±13.18ms  1653.9 KB/sec
formatter/parser.ts                      1.00      9.3±0.52ms     5.2 MB/sec    1.03      9.6±0.51ms     5.1 MB/sec
formatter/pixi.min.js                    1.02    231.7±6.11ms  1939.5 KB/sec    1.00    227.2±9.90ms  1977.8 KB/sec
formatter/react-dom.production.min.js    1.10     72.0±4.29ms  1636.5 KB/sec    1.00     65.7±4.05ms  1792.6 KB/sec
formatter/react.production.min.js        1.02      3.2±0.10ms  1940.0 KB/sec    1.00      3.2±0.21ms  1984.7 KB/sec
formatter/router.ts                      1.00      7.8±0.35ms     7.8 MB/sec    1.04      8.1±0.32ms     7.5 MB/sec
formatter/tex-chtml-full.js              1.01   544.0±10.28ms  1715.3 KB/sec    1.00   537.8±24.32ms  1735.2 KB/sec
formatter/three.min.js                   1.08    279.7±9.15ms     2.1 MB/sec    1.00   259.8±11.19ms     2.3 MB/sec
formatter/typescript.js                  1.04  1850.0±54.80ms     5.1 MB/sec    1.00  1774.6±54.76ms     5.4 MB/sec
formatter/vue.global.prod.js             1.00     87.7±4.46ms  1407.4 KB/sec    1.01     88.8±5.27ms  1389.5 KB/sec

Copy link
Contributor

@ematipico ematipico left a comment

Choose a reason for hiding this comment

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

I left some feedback.

Could you please add two new test cases inside the format command?

  • an invalid case where we print the error message for invalid value for --semicolons
  • a valid case where we pass --semicolons=as-needed and the correct formatted code is printed

crates/rome_js_formatter/src/context.rs Outdated Show resolved Hide resolved
crates/rome_js_formatter/src/context.rs Show resolved Hide resolved
website/src/playground/types.ts Show resolved Hide resolved
crates/rome_js_formatter/src/context.rs Show resolved Hide resolved
crates/rome_js_formatter/src/utils/mod.rs Outdated Show resolved Hide resolved
editors/vscode/configuration_schema.json Outdated Show resolved Hide resolved
website/src/playground/workers/romeWorker.ts Outdated Show resolved Hide resolved
@@ -34,6 +34,11 @@ export enum LoadingState {
Error,
}

export enum Semicolons {
Copy link
Contributor

Choose a reason for hiding this comment

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

Nit: Isn't it possible to import this type from @rometools/wasm-web instead ?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It probably should be, but the types are not exported.

Copy link
Contributor

Choose a reason for hiding this comment

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

Probably because you need to run the script to create the wasm-web package. This type should not be here, could you please delete it?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I re-ran the script but the problem is that wasm-web only exports very few types, options and configuration aren't one of them and I don't feel like playing infer trickeries to get to the type. Let's tackle this separately. I continued what all other options did before.

Add an option to configure whether the formatter should always print semicolons for statements or only as needed.
Copy link
Contributor

@ematipico ematipico left a comment

Choose a reason for hiding this comment

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

Looks good to me, could you please review my last two comments before merging it?

npm/backend-jsonrpc/src/workspace.ts Outdated Show resolved Hide resolved
@@ -34,6 +34,11 @@ export enum LoadingState {
Error,
}

export enum Semicolons {
Copy link
Contributor

Choose a reason for hiding this comment

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

Probably because you need to run the script to create the wasm-web package. This type should not be here, could you please delete it?

@MichaReiser MichaReiser merged commit cb9cd5c into main Nov 16, 2022
@MichaReiser MichaReiser deleted the feat/add-semicolons-options branch November 16, 2022 10:36
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
A-Formatter Area: formatter
Projects
None yet
Development

Successfully merging this pull request may close these issues.

📎 Add configuration option to remove semicolons
4 participants