Skip to content

Commit 77faac7

Browse files
committed
.
0 parents  commit 77faac7

File tree

11 files changed

+529
-0
lines changed

11 files changed

+529
-0
lines changed

.editorconfig

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
root = true
2+
3+
[*]
4+
indent_style = space
5+
indent_size = 2
6+
end_of_line = lf
7+
charset = utf-8
8+
trim_trailing_whitespace = true
9+
insert_final_newline = true

.github/workflows/main.yml

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
name: main
2+
on:
3+
- pull_request
4+
- push
5+
jobs:
6+
main:
7+
name: '${{ matrix.node }}'
8+
runs-on: ubuntu-latest
9+
steps:
10+
- uses: actions/checkout@v2
11+
- uses: dcodeIO/setup-node-nvm@master
12+
with:
13+
node-version: ${{ matrix.node }}
14+
- run: npm install
15+
- run: npm test
16+
- uses: codecov/codecov-action@v1
17+
strategy:
18+
matrix:
19+
node:
20+
- lts/dubnium
21+
- node

.gitignore

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
.DS_Store
2+
*.log
3+
.nyc_output/
4+
coverage/
5+
node_modules/
6+
yarn.lock

.npmrc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
package-lock=false

.prettierignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
coverage/
2+
*.json
3+
*.md

funding.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
github: wooorm

index.js

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
'use strict'
2+
3+
module.exports = attachComments
4+
5+
var push = [].push
6+
7+
function attachComments(tree, comments) {
8+
walk(tree, {comments: comments.concat().sort(compare), index: 0})
9+
return tree
10+
}
11+
12+
function walk(node, state) {
13+
var children = []
14+
var comments = []
15+
var key
16+
var value
17+
var index
18+
19+
// Done, we can quit.
20+
if (state.index === state.comments.length) {
21+
return
22+
}
23+
24+
// Find all children of `node`
25+
for (key in node) {
26+
value = node[key]
27+
28+
// Ignore comments.
29+
if (value && typeof value === 'object' && key !== 'comments') {
30+
if (typeof value.type === 'string') {
31+
children.push(value)
32+
} else if (Array.isArray(value)) {
33+
index = -1
34+
35+
while (++index < value.length) {
36+
if (value[index] && typeof value[index].type === 'string') {
37+
children.push(value[index])
38+
}
39+
}
40+
}
41+
}
42+
}
43+
44+
// Sort the children.
45+
children.sort(compare)
46+
47+
// Initial comments.
48+
push.apply(
49+
comments,
50+
slice(state, node, false, {leading: true, trailing: false})
51+
)
52+
53+
index = -1
54+
55+
while (++index < children.length) {
56+
walk(children[index], state)
57+
}
58+
59+
// Dangling or trailing comments.
60+
push.apply(
61+
comments,
62+
slice(state, node, true, {
63+
leading: false,
64+
trailing: Boolean(children.length)
65+
})
66+
)
67+
68+
if (comments.length) {
69+
node.comments = comments
70+
}
71+
}
72+
73+
function slice(state, node, compareEnd, fields) {
74+
var result = []
75+
76+
while (
77+
state.comments[state.index] &&
78+
compare(state.comments[state.index], node, compareEnd) < 1
79+
) {
80+
result.push(Object.assign({}, state.comments[state.index++], fields))
81+
}
82+
83+
return result
84+
}
85+
86+
function compare(left, right, compareEnd) {
87+
var field = compareEnd ? 'end' : 'start'
88+
89+
// Offsets.
90+
if (left.range && right.range) {
91+
return left.range[0] - right.range[compareEnd ? 1 : 0]
92+
}
93+
94+
// Points.
95+
if (left.loc && left.loc.start && right.loc && right.loc[field]) {
96+
return (
97+
left.loc.start.line - right.loc[field].line ||
98+
left.loc.start.column - right.loc[field].column
99+
)
100+
}
101+
102+
// Just `start` (and `end`) on nodes.
103+
// Default in most parsers.
104+
if ('start' in left && field in right) {
105+
return left.start - right[field]
106+
}
107+
108+
return NaN
109+
}

license

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
(The MIT License)
2+
3+
Copyright (c) 2020 Titus Wormer <tituswormer@gmail.com>
4+
5+
Permission is hereby granted, free of charge, to any person obtaining
6+
a copy of this software and associated documentation files (the
7+
'Software'), to deal in the Software without restriction, including
8+
without limitation the rights to use, copy, modify, merge, publish,
9+
distribute, sublicense, and/or sell copies of the Software, and to
10+
permit persons to whom the Software is furnished to do so, subject to
11+
the following conditions:
12+
13+
The above copyright notice and this permission notice shall be
14+
included in all copies or substantial portions of the Software.
15+
16+
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
17+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
19+
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
20+
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
21+
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
22+
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

package.json

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
{
2+
"name": "estree-util-attach-comments",
3+
"version": "0.0.0",
4+
"description": "Attach comments to estree nodes",
5+
"license": "MIT",
6+
"keywords": [
7+
"estree",
8+
"ast",
9+
"ecmascript",
10+
"javascript",
11+
"tree",
12+
"comment",
13+
"acorn",
14+
"espree",
15+
"recast"
16+
],
17+
"repository": "wooorm/estree-util-attach-comments",
18+
"bugs": "https://github.com/wooorm/estree-util-attach-comments/issues",
19+
"funding": {
20+
"type": "github",
21+
"url": "https://github.com/sponsors/wooorm"
22+
},
23+
"author": "Titus Wormer <tituswormer@gmail.com> (https://wooorm.com)",
24+
"contributors": [
25+
"Titus Wormer <tituswormer@gmail.com> (https://wooorm.com)"
26+
],
27+
"files": [
28+
"index.js"
29+
],
30+
"dependencies": {},
31+
"devDependencies": {
32+
"acorn": "^8.0.0",
33+
"estree-walker": "^2.0.0",
34+
"nyc": "^15.0.0",
35+
"prettier": "^2.0.0",
36+
"recast": "^0.20.0",
37+
"remark-cli": "^9.0.0",
38+
"remark-preset-wooorm": "^8.0.0",
39+
"tape": "^5.0.0",
40+
"xo": "^0.36.0"
41+
},
42+
"scripts": {
43+
"format": "remark . -qfo && prettier . -w --loglevel warn && xo --fix",
44+
"test-api": "node test",
45+
"test-coverage": "nyc --reporter lcov tape test.js",
46+
"test": "npm run format && npm run test-coverage"
47+
},
48+
"prettier": {
49+
"tabWidth": 2,
50+
"useTabs": false,
51+
"singleQuote": true,
52+
"bracketSpacing": false,
53+
"semi": false,
54+
"trailingComma": "none"
55+
},
56+
"xo": {
57+
"prettier": true,
58+
"esnext": false,
59+
"rules": {
60+
"guard-for-in": "off",
61+
"max-depth": "off",
62+
"unicorn/explicit-length-check": "off",
63+
"unicorn/prefer-number-properties": "off"
64+
}
65+
},
66+
"nyc": {
67+
"check-coverage": true,
68+
"lines": 100,
69+
"functions": 100,
70+
"branches": 100
71+
},
72+
"remarkConfig": {
73+
"plugins": [
74+
"preset-wooorm"
75+
]
76+
}
77+
}

readme.md

Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
# estree-util-attach-comments
2+
3+
[![Build][build-badge]][build]
4+
[![Coverage][coverage-badge]][coverage]
5+
[![Downloads][downloads-badge]][downloads]
6+
[![Size][size-badge]][size]
7+
8+
Attach semistandard [estree][] comment nodes (such as from [espree][] or
9+
[acorn][] with a couple lines of code) to the nodes in that tree.
10+
11+
This is useful because certain estree parsers give you an array (espree and
12+
acorn) whereas other estree tools expect comments to be embedded on nodes in the
13+
tree.
14+
15+
## Install
16+
17+
[npm][]:
18+
19+
```sh
20+
npm install estree-util-attach-comments
21+
```
22+
23+
## Use
24+
25+
Say we have this weird code:
26+
27+
```js
28+
/* 1 */ function /* 2 */ a /* 3 */ (/* 4 */b) /* 5 */ { /* 6 */ return /* 7 */ b + /* 8 */ 1 /* 9 */ }
29+
```
30+
31+
```js
32+
var acorn = require('acorn')
33+
var recast = require('recast')
34+
var attachComments = require('estree-util-attach-comments')
35+
36+
var comments = []
37+
var tree = acorn.parse(code, {ecmaVersion: 2020, onComment: comments})
38+
39+
attachComments(tree, comments)
40+
41+
console.log(recast.print(tree).code)
42+
```
43+
44+
Yields:
45+
46+
```js
47+
/* 1 */
48+
function /* 2 */
49+
a(
50+
/* 3 */
51+
/* 4 */
52+
b
53+
) /* 5 */
54+
{
55+
/* 6 */
56+
return (
57+
/* 7 */
58+
b + /* 8 */
59+
1
60+
);
61+
}/* 9 */
62+
```
63+
64+
Note that the lines are added by `recast` in this case.
65+
And, some of these weird comments are off, but they’re pretty close.
66+
67+
## API
68+
69+
### `attachComment(tree, comments)`
70+
71+
Attach semistandard estree comment nodes to the tree.
72+
73+
This mutates the given [`tree`][estree] ([`Program`][program]).
74+
It takes `comments`, walks the tree, and adds comments as close as possible
75+
to where they originated.
76+
77+
Comment nodes are given two boolean fields: `leading` (`true` for `/* a */ b`)
78+
and `trailing` (`true` for `a /* b */`).
79+
Both fields are `false` for dangling comments: `[/* a */]`.
80+
This is what `recast` uses too, and is somewhat similar to Babel, which is not
81+
estree but instead uses `leadingComments`, `trailingComments`, and
82+
`innerComments` arrays on nodes.
83+
84+
The algorithm checks any node: even recent (or future) proposals or nonstandard
85+
syntax such as JSX, because it ducktypes to find nodes instead of having a list
86+
of visitor keys.
87+
88+
The algorithm supports `loc` fields (line/column), `range` fields (offsets),
89+
and direct `start` / `end` fields.
90+
91+
###### Returns
92+
93+
`Node` — The given `tree`.
94+
95+
## License
96+
97+
[MIT][license] © [Titus Wormer][author]
98+
99+
<!-- Definitions -->
100+
101+
[build-badge]: https://github.com/wooorm/estree-util-attach-comments/workflows/main/badge.svg
102+
103+
[build]: https://github.com/wooorm/estree-util-attach-comments/actions
104+
105+
[coverage-badge]: https://img.shields.io/codecov/c/github/wooorm/estree-util-attach-comments.svg
106+
107+
[coverage]: https://codecov.io/github/wooorm/estree-util-attach-comments
108+
109+
[downloads-badge]: https://img.shields.io/npm/dm/estree-util-attach-comments.svg
110+
111+
[downloads]: https://www.npmjs.com/package/estree-util-attach-comments
112+
113+
[size-badge]: https://img.shields.io/bundlephobia/minzip/estree-util-attach-comments.svg
114+
115+
[size]: https://bundlephobia.com/result?p=estree-util-attach-comments
116+
117+
[npm]: https://docs.npmjs.com/cli/install
118+
119+
[license]: license
120+
121+
[author]: https://wooorm.com
122+
123+
[acorn]: https://github.com/acornjs/acorn
124+
125+
[estree]: https://github.com/estree/estree
126+
127+
[espree]: https://github.com/eslint/espree
128+
129+
[program]: https://github.com/estree/estree/blob/master/es5.md#programs

0 commit comments

Comments
 (0)