Skip to content

Commit 7fae5af

Browse files
authored
Change to return undefined for invalid points, positions
Closes GH-1. Reviewed-by: Remco Haszing <remcohaszing@gmail.com> Reviewed-by: Christian Murphy <christian.murphy.42@gmail.com>
1 parent 9c57f3d commit 7fae5af

File tree

3 files changed

+52
-36
lines changed

3 files changed

+52
-36
lines changed

lib/index.js

Lines changed: 34 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
/**
2-
* @typedef {import('unist').Position} Position
2+
* @typedef {import('unist').Position} UnistPosition
3+
* @typedef {import('unist').Point} UnistPoint
34
*
4-
* @typedef {[number, number]} RangeLike
5+
* @typedef {[number | null | undefined, number | null | undefined]} RangeLike
56
*
67
* @typedef PointLike
78
* @property {number | null | undefined} [line]
@@ -23,39 +24,49 @@
2324
*
2425
* @param {NodeLike | null | undefined} [node]
2526
* estree node.
26-
* @returns {Position}
27+
* @returns {UnistPosition | undefined}
2728
* unist position.
2829
*/
2930
export function positionFromEstree(node) {
3031
const nodeLike = node || {}
3132
const loc = nodeLike.loc || {}
32-
const range = nodeLike.range || [0, 0]
33-
const startColumn = loc.start
34-
? numberOrUndefined(loc.start.column)
35-
: undefined
36-
const endColumn = loc.end ? numberOrUndefined(loc.end.column) : undefined
33+
const range = nodeLike.range || [undefined, undefined]
34+
const start = pointOrUndefined(loc.start, range[0] || nodeLike.start)
35+
const end = pointOrUndefined(loc.end, range[1] || nodeLike.end)
3736

38-
return {
39-
start: {
40-
// @ts-expect-error: return no point / no position next major.
41-
line: loc.start ? numberOrUndefined(loc.start.line) : undefined,
42-
// @ts-expect-error: return no point / no position next major.
43-
column: startColumn === undefined ? undefined : startColumn + 1,
44-
offset: numberOrUndefined(range[0] || nodeLike.start)
45-
},
46-
end: {
47-
// @ts-expect-error: return no point / no position next major.
48-
line: loc.end ? numberOrUndefined(loc.end.line) : undefined,
49-
// @ts-expect-error: return no point / no position next major.
50-
column: endColumn === undefined ? undefined : endColumn + 1,
51-
offset: numberOrUndefined(range[1] || nodeLike.end)
37+
if (start && end) {
38+
return {start, end}
39+
}
40+
}
41+
42+
/**
43+
*
44+
* @param {unknown} estreePoint
45+
* @param {unknown} estreeOffset
46+
* @returns {UnistPoint | undefined}
47+
*/
48+
function pointOrUndefined(estreePoint, estreeOffset) {
49+
if (estreePoint && typeof estreePoint === 'object') {
50+
const line =
51+
'line' in estreePoint ? numberOrUndefined(estreePoint.line) : undefined
52+
const column =
53+
'column' in estreePoint
54+
? numberOrUndefined(estreePoint.column)
55+
: undefined
56+
57+
if (line && column !== undefined) {
58+
return {
59+
line,
60+
column: column + 1,
61+
offset: numberOrUndefined(estreeOffset)
62+
}
5263
}
5364
}
5465
}
5566

5667
/**
5768
*
58-
* @param {number | null | undefined} value
69+
* @param {unknown} value
5970
* @returns {number | undefined}
6071
*/
6172
function numberOrUndefined(value) {

readme.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ Turn an estree `node` into a unist `position`.
106106

107107
###### Returns
108108

109-
unist position ([`Position`][position]).
109+
unist position, if valid ([`Position`][position] or `undefined`).
110110

111111
## Types
112112

test.js

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -13,19 +13,13 @@ test('positionFromEstree', () => {
1313

1414
assert.deepEqual(
1515
positionFromEstree(),
16-
{
17-
start: {line: undefined, column: undefined, offset: undefined},
18-
end: {line: undefined, column: undefined, offset: undefined}
19-
},
16+
undefined,
2017
'should support a missing node'
2118
)
2219

2320
assert.deepEqual(
2421
positionFromEstree(parse('x', {ecmaVersion: 2020})),
25-
{
26-
start: {line: undefined, column: undefined, offset: 0},
27-
end: {line: undefined, column: undefined, offset: 1}
28-
},
22+
undefined,
2923
'should support node w/o `loc`s'
3024
)
3125

@@ -40,10 +34,21 @@ test('positionFromEstree', () => {
4034

4135
assert.deepEqual(
4236
positionFromEstree(parse('x', {ecmaVersion: 2020, ranges: true})),
43-
{
44-
start: {line: undefined, column: undefined, offset: 0},
45-
end: {line: undefined, column: undefined, offset: 1}
46-
},
37+
undefined,
4738
'should support node w/ `range`s'
4839
)
40+
41+
assert.deepEqual(
42+
positionFromEstree({loc: {start: {}, end: {}}}),
43+
undefined,
44+
'should handle points w/o line/column'
45+
)
46+
47+
assert.deepEqual(
48+
positionFromEstree({
49+
loc: {start: {line: -1, column: -1}, end: {line: 1, column: 0}}
50+
}),
51+
undefined,
52+
'should handle points w/ too low values'
53+
)
4954
})

0 commit comments

Comments
 (0)