Skip to content

Commit b7beccc

Browse files
committed
Add JSDoc based types
1 parent 1a84b06 commit b7beccc

File tree

5 files changed

+128
-6
lines changed

5 files changed

+128
-6
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
.DS_Store
2+
*.d.ts
23
*.log
34
coverage/
45
node_modules/

index.js

Lines changed: 50 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,46 @@
11
var push = [].push
22

3+
/**
4+
* @typedef {import('estree').BaseNode} EstreeNode
5+
* @typedef {import('estree').Comment} EstreeComment
6+
*
7+
* @typedef State
8+
* @property {EstreeComment[]} comments
9+
* @property {number} index
10+
*
11+
* @typedef Fields
12+
* @property {boolean} leading
13+
* @property {boolean} trailing
14+
*/
15+
16+
/**
17+
* Attach semistandard estree comment nodes to the tree.
18+
*
19+
* @param {EstreeNode} tree
20+
* @param {EstreeComment[]} [comments]
21+
*/
322
export function attachComments(tree, comments) {
4-
walk(tree, {comments: comments.concat().sort(compare), index: 0})
23+
var list = (comments || []).concat().sort(compare)
24+
if (list.length) walk(tree, {comments: list, index: 0})
525
return tree
626
}
727

28+
/**
29+
* Attach semistandard estree comment nodes to the tree.
30+
*
31+
* @param {EstreeNode} node
32+
* @param {State} state
33+
*/
834
function walk(node, state) {
35+
/** @type {EstreeNode[]} */
936
var children = []
37+
/** @type {EstreeComment[]} */
1038
var comments = []
39+
/** @type {string} */
1140
var key
41+
/** @type {EstreeNode|EstreeNode[]} */
1242
var value
43+
/** @type {number} */
1344
var index
1445

1546
// Done, we can quit.
@@ -23,16 +54,16 @@ function walk(node, state) {
2354

2455
// Ignore comments.
2556
if (value && typeof value === 'object' && key !== 'comments') {
26-
if (typeof value.type === 'string') {
27-
children.push(value)
28-
} else if (Array.isArray(value)) {
57+
if (Array.isArray(value)) {
2958
index = -1
3059

3160
while (++index < value.length) {
3261
if (value[index] && typeof value[index].type === 'string') {
3362
children.push(value[index])
3463
}
3564
}
65+
} else if (typeof value.type === 'string') {
66+
children.push(value)
3667
}
3768
}
3869
}
@@ -62,11 +93,19 @@ function walk(node, state) {
6293
)
6394

6495
if (comments.length) {
96+
// @ts-ignore, yes, because they’re nonstandard.
6597
node.comments = comments
6698
}
6799
}
68100

101+
/**
102+
* @param {State} state
103+
* @param {EstreeNode} node
104+
* @param {boolean} compareEnd
105+
* @param {Fields} fields
106+
*/
69107
function slice(state, node, compareEnd, fields) {
108+
/** @type {EstreeComment[]} */
70109
var result = []
71110

72111
while (
@@ -79,6 +118,12 @@ function slice(state, node, compareEnd, fields) {
79118
return result
80119
}
81120

121+
/**
122+
* @param {EstreeNode|EstreeComment} left
123+
* @param {EstreeNode|EstreeComment} right
124+
* @param {boolean} [compareEnd]
125+
* @returns {number}
126+
*/
82127
function compare(left, right, compareEnd) {
83128
var field = compareEnd ? 'end' : 'start'
84129

@@ -98,6 +143,7 @@ function compare(left, right, compareEnd) {
98143
// Just `start` (and `end`) on nodes.
99144
// Default in most parsers.
100145
if ('start' in left && field in right) {
146+
// @ts-ignore Added by Acorn
101147
return left.start - right[field]
102148
}
103149

package.json

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,25 +27,34 @@
2727
"sideEffects": false,
2828
"type": "module",
2929
"main": "index.js",
30+
"types": "index.d.ts",
3031
"files": [
32+
"index.d.ts",
3133
"index.js"
3234
],
3335
"devDependencies": {
36+
"@types/acorn": "^4.0.5",
37+
"@types/tape": "^4.0.0",
3438
"acorn": "^8.0.0",
3539
"c8": "^7.0.0",
36-
"estree-walker": "^2.0.0",
40+
"estree-walker": "^3.0.0",
3741
"prettier": "^2.0.0",
3842
"recast": "^0.20.0",
3943
"remark-cli": "^9.0.0",
4044
"remark-preset-wooorm": "^8.0.0",
45+
"rimraf": "^3.0.0",
4146
"tape": "^5.0.0",
47+
"type-coverage": "^2.0.0",
48+
"typescript": "^4.0.0",
4249
"xo": "^0.38.0"
4350
},
4451
"scripts": {
52+
"prepack": "npm run build && npm run format",
53+
"build": "rimraf \"*.d.ts\" && tsc && type-coverage",
4554
"format": "remark . -qfo && prettier . -w --loglevel warn && xo --fix",
4655
"test-api": "node test.js",
4756
"test-coverage": "c8 --check-coverage --branches 100 --functions 100 --lines 100 --statements 100 --reporter lcov node test.js",
48-
"test": "npm run format && npm run test-coverage"
57+
"test": "npm run build && npm run format && npm run test-coverage"
4958
},
5059
"prettier": {
5160
"tabWidth": 2,
@@ -70,5 +79,10 @@
7079
"plugins": [
7180
"preset-wooorm"
7281
]
82+
},
83+
"typeCoverage": {
84+
"atLeast": 100,
85+
"detail": true,
86+
"strict": true
7387
}
7488
}

test.js

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,12 @@ import recast from 'recast'
44
import {walk} from 'estree-walker'
55
import {attachComments} from './index.js'
66

7+
/**
8+
* @typedef {import('estree').BaseNode} EstreeNode
9+
* @typedef {import('estree').Program} EstreeProgram
10+
* @typedef {import('estree').Comment} EstreeComment
11+
*/
12+
713
test('estree-attach-comments (recast)', function (t) {
814
t.equal(
915
recast.print(attachComments(...parse(''))).code,
@@ -72,9 +78,13 @@ test('estree-attach-comments (recast)', function (t) {
7278
'should support a bunch of line comments'
7379
)
7480

81+
/** @type {EstreeComment[]} */
7582
var comments = []
83+
/** @type {EstreeProgram} */
84+
// @ts-ignore
7685
var tree = acornParse('/* 1 */ a /* 2 */ + /* 3 */ 1', {
7786
ecmaVersion: 2020,
87+
// @ts-ignore
7888
onComment: comments
7989
})
8090

@@ -87,8 +97,25 @@ test('estree-attach-comments (recast)', function (t) {
8797
)
8898

8999
comments = []
100+
// @ts-ignore
101+
tree = acornParse('1 + 1', {
102+
ecmaVersion: 2020,
103+
// @ts-ignore
104+
onComment: comments
105+
})
106+
107+
t.equal(
108+
recast.print(attachComments(tree)).code,
109+
'1 + 1;',
110+
'should not fail w/o comments'
111+
)
112+
113+
comments = []
114+
/** @type {EstreeProgram} */
115+
// @ts-ignore
90116
tree = acornParse('/* 1 */ a /* 2 */ + /* 3 */ 1', {
91117
ecmaVersion: 2020,
118+
// @ts-ignore
92119
onComment: comments
93120
})
94121

@@ -101,9 +128,11 @@ test('estree-attach-comments (recast)', function (t) {
101128
)
102129

103130
comments = []
131+
// @ts-ignore
104132
tree = acornParse('/* 1 */ a /* 2 */ + /* 3 */ 1', {
105133
ecmaVersion: 2020,
106134
ranges: true,
135+
// @ts-ignore
107136
onComment: comments
108137
})
109138

@@ -116,9 +145,11 @@ test('estree-attach-comments (recast)', function (t) {
116145
)
117146

118147
comments = []
148+
// @ts-ignore
119149
tree = acornParse('/* 1 */ a /* 2 */ + /* 3 */ 1', {
120150
ecmaVersion: 2020,
121151
locations: true,
152+
// @ts-ignore
122153
onComment: comments
123154
})
124155

@@ -133,16 +164,30 @@ test('estree-attach-comments (recast)', function (t) {
133164
t.end()
134165
})
135166

167+
/**
168+
* @param {string} doc
169+
* @returns {[EstreeProgram, EstreeComment[]]}
170+
*/
136171
function parse(doc) {
172+
/** @type {EstreeComment[]} */
137173
var comments = []
174+
/** @type {EstreeProgram} */
175+
// @ts-ignore
138176
var tree = acornParse(doc, {ecmaVersion: 2020, onComment: comments})
139177
return [tree, comments]
140178
}
141179

180+
/**
181+
* @param {EstreeNode|EstreeComment|EstreeNode[]|EstreeComment[]} value
182+
* @returns {void}
183+
*/
142184
function removePositions(value) {
185+
// @ts-ignore
143186
walk(value, {
144187
enter(node) {
188+
// @ts-ignore they most certainly exist.
145189
delete node.start
190+
// @ts-ignore they most certainly exist.
146191
delete node.end
147192
}
148193
})

tsconfig.json

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
{
2+
"files": ["index.js"],
3+
"include": ["*.js"],
4+
"compilerOptions": {
5+
"target": "ES2020",
6+
"lib": ["ES2020"],
7+
"module": "ES2020",
8+
"moduleResolution": "node",
9+
"allowJs": true,
10+
"checkJs": true,
11+
"declaration": true,
12+
"emitDeclarationOnly": true,
13+
"allowSyntheticDefaultImports": true,
14+
"skipLibCheck": true
15+
}
16+
}

0 commit comments

Comments
 (0)