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

feat(rome_formatter): Source Map iteration over deleted ranges #3219

Merged
merged 3 commits into from
Sep 14, 2022

Conversation

MichaReiser
Copy link
Contributor

This PR adds a DeletedRanges iterator to the TransformedSourceMap that allows iterating over all deleted ranges including the deleted text.

The comments refactoring needs a way to identify if a trivia piece is right before the closing ) in the original tree because we want to keep trailing comments inside parentheses with the preceding nodes

!(
  a
  // some comment
);
b

The comment should be a trailing comment of a and not become a leading comment of b because the transformed tree has the following shape

!a
  // Some comment
b;

Such an iterator requires a fast way to get the text of a deleted range. This isn't possible with SyntaxNodeText because resolving the text requires iterating to the token with the given offset which is O(n). That's why this PR changes the TransfromedSourceMap to hold a String with the original source text to get O(1) access to the original text.

The downside of doing so is that the source text must be built up insideof the SyntaxRewriter and is stored twice in memory.

The cost of traversal should offset the cost in the comments builder and the memory allocation is short-lived, not adding a lot of pressure if Rome's running as a server.

Tests

I added a new unit test that shows how the new iterator can be used

This PR adds a `DeletedRanges` iterator to the `TransformedSourceMap` that allows iterating over all deleted ranges including the deleted text.

The comments refactoring needs a way to identify if a trivia piece is right before the closing `)` in the original tree because we want to keep trailing comments inside parentheses with the preceding nodes

```javascript
!(
  a
  // some comment
);
b
```

The comment should be a trailing comment of `a` and not become a leading comment of `b` because the transformed tree has the following shape

```javascript
!a
  // Some comment
b;
```

Such an iterator requires a fast way to get the text of a deleted range. This isn't possible with `SyntaxNodeText` because resolving the text requires iterating to the token with the given offset which is `O(n)`. That's why this PR changes the `TransfromedSourceMap` to hold a `String` with the original source text to get `O(1)` access to the original text.

The downside of doing so is that the source text must be built up insideof the `SyntaxRewriter` and is stored twice in memory.

The cost of traversal should offset the cost in the comments builder and the memory allocation is short-lived, not adding a lot of pressure if Rome's running as a server.

## Tests
I added a new unit test that shows how the new iterator can be used
@MichaReiser MichaReiser added the A-Formatter Area: formatter label Sep 14, 2022
@MichaReiser MichaReiser added this to the 0.10.0 milestone Sep 14, 2022
@MichaReiser MichaReiser temporarily deployed to netlify-playground September 14, 2022 09:21 Inactive
@netlify
Copy link

netlify bot commented Sep 14, 2022

Deploy Preview for rometools canceled.

Name Link
🔨 Latest commit 06fe4f9
🔍 Latest deploy log https://app.netlify.com/sites/rometools/deploys/6321a99a014db30009aea84b

Comment on lines -268 to -272
fn map_verbatim_ranges(&self, ranges: &mut [TextRange]) {
for range in ranges {
*range = self.source_range(*range)
}
}
Copy link
Contributor Author

Choose a reason for hiding this comment

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

mapping the verbatim ranges isn't necessary because these ranges represent ranges in the printed document and not in the source tree.

This has gone unnoticed thus far because no formatter used the verbatim formatting.

Comment on lines +16 to 18
let mut rewriter = JsFormatSyntaxRewriter::default();
let transformed = rewriter.transform(root);
(transformed, rewriter.finish())
Copy link
Contributor Author

Choose a reason for hiding this comment

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

@ematipico this will make you happy... It's no longer passing root twice ;)

@MichaReiser
Copy link
Contributor Author

!bench_formatter

@MichaReiser MichaReiser requested a review from leops September 14, 2022 09:24
@github-actions
Copy link

github-actions bot commented Sep 14, 2022

@MichaReiser MichaReiser temporarily deployed to netlify-playground September 14, 2022 09:28 Inactive
@github-actions
Copy link

Formatter Benchmark Results

group                                    main                                   pr
-----                                    ----                                   --
formatter/checker.ts                     1.00    468.8±4.79ms     5.5 MB/sec    1.00    470.3±3.41ms     5.5 MB/sec
formatter/compiler.js                    1.00    257.8±1.87ms     4.1 MB/sec    1.03    265.4±4.44ms     3.9 MB/sec
formatter/d3.min.js                      1.00    222.5±1.98ms  1206.3 KB/sec    1.04    231.4±1.24ms  1160.0 KB/sec
formatter/dojo.js                        1.00     13.9±0.06ms     4.9 MB/sec    1.03     14.3±0.08ms     4.8 MB/sec
formatter/ios.d.ts                       1.00    283.5±2.35ms     6.6 MB/sec    1.01    285.4±1.29ms     6.5 MB/sec
formatter/jquery.min.js                  1.00     58.3±0.64ms  1452.1 KB/sec    1.02     59.6±0.98ms  1419.7 KB/sec
formatter/math.js                        1.00    436.9±2.26ms  1517.6 KB/sec    1.01    440.7±3.86ms  1504.6 KB/sec
formatter/parser.ts                      1.00      9.4±0.01ms     5.2 MB/sec    1.02      9.6±0.02ms     5.1 MB/sec
formatter/pixi.min.js                    1.00    250.6±2.27ms  1793.5 KB/sec    1.01    252.9±1.77ms  1776.8 KB/sec
formatter/react-dom.production.min.js    1.00     72.3±0.72ms  1629.8 KB/sec    1.03     74.4±0.69ms  1583.1 KB/sec
formatter/react.production.min.js        1.00      3.5±0.00ms  1785.5 KB/sec    1.02      3.6±0.00ms  1751.2 KB/sec
formatter/router.ts                      1.00      7.4±0.03ms     8.3 MB/sec    1.02      7.6±0.04ms     8.1 MB/sec
formatter/tex-chtml-full.js              1.00    553.3±2.92ms  1686.5 KB/sec    1.01    560.5±2.82ms  1664.9 KB/sec
formatter/three.min.js                   1.00    278.1±2.37ms     2.1 MB/sec    1.01    281.0±1.89ms     2.1 MB/sec
formatter/typescript.js                  1.00   1704.0±7.44ms     5.6 MB/sec    1.01  1727.5±18.07ms     5.5 MB/sec
formatter/vue.global.prod.js             1.00     93.9±0.80ms  1313.4 KB/sec    1.03     96.7±0.96ms  1275.5 KB/sec

@MichaReiser MichaReiser temporarily deployed to netlify-playground September 14, 2022 10:14 Inactive
@MichaReiser MichaReiser merged commit a4999f4 into main Sep 14, 2022
@MichaReiser MichaReiser deleted the feat/source-map-deleted-ranges branch September 14, 2022 11:22
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.

2 participants
点击 这是indexloc提供的php浏览器服务,不要输入任何密码和下载