Skip to content

Commit 5a51ab3

Browse files
committed
Change to replace Buffer with Uint8Array
1 parent ed23e6d commit 5a51ab3

File tree

3 files changed

+162
-73
lines changed

3 files changed

+162
-73
lines changed

lib/index.js

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,13 @@
33
* @typedef {import('acorn').Position} Position
44
* @typedef {import('estree-jsx').Comment} Comment
55
* @typedef {import('estree-jsx').Program} Program
6-
* @typedef {import('buffer').Buffer} Buffer
7-
* @typedef {any extends Buffer ? never : Buffer} MaybeBuffer
8-
* This is the same as `Buffer` if Node.js types are included, `never` otherwise.
9-
* @typedef {string | MaybeBuffer} Value
6+
*/
7+
8+
/**
9+
* @typedef {Uint8Array | string} Value
10+
* Input value
1011
*
12+
* When a typed array, must be UTF-8.
1113
*
1214
* @typedef AcornErrorFields
1315
* @property {number} pos
@@ -82,17 +84,26 @@ export function fromJs(value, options) {
8284
parser = parser.extend(...options_.plugins)
8385
}
8486

87+
const text =
88+
typeof value === 'string'
89+
? value.toString()
90+
: new TextDecoder().decode(value)
91+
8592
try {
8693
// @ts-expect-error: Acorn looks enough like estree.
87-
tree = parser.parse(value, {
94+
tree = parser.parse(text, {
8895
ecmaVersion: options_.version || 'latest',
8996
sourceType: options_.module ? 'module' : 'script',
90-
allowReturnOutsideFunction: options_.allowReturnOutsideFunction,
91-
allowImportExportEverywhere: options_.allowImportExportEverywhere,
92-
allowAwaitOutsideFunction: options_.allowAwaitOutsideFunction,
93-
allowHashBang: options_.allowHashBang,
94-
allowSuperOutsideMethod: options_.allowSuperOutsideMethod,
97+
allowReturnOutsideFunction:
98+
options_.allowReturnOutsideFunction || undefined,
99+
allowImportExportEverywhere:
100+
options_.allowImportExportEverywhere || undefined,
101+
allowAwaitOutsideFunction:
102+
options_.allowAwaitOutsideFunction || undefined,
103+
allowHashBang: options_.allowHashBang || undefined,
104+
allowSuperOutsideMethod: options_.allowSuperOutsideMethod || undefined,
95105
locations: true,
106+
// @ts-expect-error: Acorn looks enough like estree.
96107
onComment: comments
97108
})
98109
} catch (error) {

readme.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -207,10 +207,12 @@ type Plugin = (Parser: ParserClass) => ParserClass
207207
208208
Input value (TypeScript type).
209209
210+
When a typed array, must be UTF-8.
211+
210212
###### Type
211213
212214
```ts
213-
type Value = string | Buffer // `Buffer` is added when Node.js types ere used.
215+
type Value = Uint8Array | string
214216
```
215217
216218
### `Version`

test/index.js

Lines changed: 138 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -9,18 +9,16 @@ import jsx from 'acorn-jsx'
99
// @ts-expect-error: untyped.
1010
import stage3 from 'acorn-stage3'
1111
import {fromJs} from '../index.js'
12-
import * as mod from '../index.js'
1312

14-
test('fromJs', () => {
15-
assert.deepEqual(
16-
Object.keys(mod).sort(),
17-
['fromJs'],
18-
'should expose the public api'
19-
)
13+
test('fromJs', async function (t) {
14+
await t.test('should expose the public api', async function () {
15+
assert.deepEqual(Object.keys(await import('../index.js')).sort(), [
16+
'fromJs'
17+
])
18+
})
2019

21-
assert.deepEqual(
22-
fromJs('1 + "2"'),
23-
{
20+
await t.test('should work', async function () {
21+
assert.deepEqual(fromJs('1 + "2"'), {
2422
type: 'Program',
2523
body: [
2624
{
@@ -61,21 +59,20 @@ test('fromJs', () => {
6159
start: {line: 1, column: 1, offset: 0},
6260
end: {line: 1, column: 8, offset: 7}
6361
}
64-
},
65-
'should work'
66-
)
62+
})
63+
})
6764

68-
assert.throws(
69-
function () {
70-
fromJs('import "a"')
71-
},
72-
/Could not parse JavaScript with Acorn/,
73-
'should fail on an import w/o `module: true`'
65+
await t.test(
66+
'should fail on an import w/o `module: true`',
67+
async function () {
68+
assert.throws(function () {
69+
fromJs('import "a"')
70+
}, /Could not parse JavaScript with Acorn/)
71+
}
7472
)
7573

76-
assert.deepEqual(
77-
fromJs('import "a"', {module: true}),
78-
{
74+
await t.test('should support an import w/ `module: true`', async function () {
75+
assert.deepEqual(fromJs('import "a"', {module: true}), {
7976
type: 'Program',
8077
body: [
8178
{
@@ -101,13 +98,11 @@ test('fromJs', () => {
10198
start: {line: 1, column: 1, offset: 0},
10299
end: {line: 1, column: 11, offset: 10}
103100
}
104-
},
105-
'should support an import w/ `module: true`'
106-
)
101+
})
102+
})
107103

108-
assert.deepEqual(
109-
fromJs('<x />', {plugins: [jsx()]}),
110-
{
104+
await t.test('should support a plugin', async function () {
105+
assert.deepEqual(fromJs('<x />', {plugins: [jsx()]}), {
111106
type: 'Program',
112107
body: [
113108
{
@@ -150,13 +145,11 @@ test('fromJs', () => {
150145
start: {line: 1, column: 1, offset: 0},
151146
end: {line: 1, column: 6, offset: 5}
152147
}
153-
},
154-
'should support a plugin'
155-
)
148+
})
149+
})
156150

157-
assert.deepEqual(
158-
fromJs('#!/bin/sh\n1', {allowHashBang: true}),
159-
{
151+
await t.test('should support `options.allowHashBang`', async function () {
152+
assert.deepEqual(fromJs('#!/bin/sh\n1', {allowHashBang: true}), {
160153
type: 'Program',
161154
body: [
162155
{
@@ -190,47 +183,130 @@ test('fromJs', () => {
190183
start: {line: 1, column: 1, offset: 0},
191184
end: {line: 2, column: 2, offset: 11}
192185
}
186+
})
187+
})
188+
189+
assert.deepEqual(
190+
fromJs(new Uint8Array()),
191+
{
192+
type: 'Program',
193+
body: [],
194+
sourceType: 'script',
195+
comments: [],
196+
position: {
197+
start: {line: 1, column: 1, offset: 0},
198+
end: {line: 1, column: 1, offset: 0}
199+
}
193200
},
194-
'should support `options.allowHashBang`'
201+
'should support empty typed arrays'
202+
)
203+
204+
assert.deepEqual(
205+
fromJs(new TextEncoder().encode('let a = 1')),
206+
{
207+
type: 'Program',
208+
body: [
209+
{
210+
type: 'VariableDeclaration',
211+
declarations: [
212+
{
213+
type: 'VariableDeclarator',
214+
id: {
215+
type: 'Identifier',
216+
name: 'a',
217+
position: {
218+
start: {line: 1, column: 5, offset: 4},
219+
end: {line: 1, column: 6, offset: 5}
220+
}
221+
},
222+
init: {
223+
type: 'Literal',
224+
value: 1,
225+
position: {
226+
start: {line: 1, column: 9, offset: 8},
227+
end: {line: 1, column: 10, offset: 9}
228+
}
229+
},
230+
position: {
231+
start: {line: 1, column: 5, offset: 4},
232+
end: {line: 1, column: 10, offset: 9}
233+
}
234+
}
235+
],
236+
kind: 'let',
237+
position: {
238+
start: {line: 1, column: 1, offset: 0},
239+
end: {line: 1, column: 10, offset: 9}
240+
}
241+
}
242+
],
243+
sourceType: 'script',
244+
comments: [],
245+
position: {
246+
start: {line: 1, column: 1, offset: 0},
247+
end: {line: 1, column: 10, offset: 9}
248+
}
249+
},
250+
'should support typed arrays'
251+
)
252+
253+
assert.deepEqual(
254+
fromJs(new Uint8Array()),
255+
{
256+
type: 'Program',
257+
body: [],
258+
sourceType: 'script',
259+
comments: [],
260+
position: {
261+
start: {line: 1, column: 1, offset: 0},
262+
end: {line: 1, column: 1, offset: 0}
263+
}
264+
},
265+
'should support empty typed arrays'
195266
)
196267
})
197268

198-
test('fixtures', async function () {
269+
test('fixtures', async function (t) {
199270
const base = new URL('fixtures/', import.meta.url)
200271
const filenames = await fs.readdir(base)
201-
const tests = filenames.filter((d) => d.charAt(0) !== '.')
272+
const tests = filenames.filter(function (d) {
273+
return d.charAt(0) !== '.'
274+
})
202275

203276
let index = -1
204277
while (++index < tests.length) {
205278
const filename = tests[index]
206-
const valueUrl = new URL(filename + '/index.js', base)
207-
const treeUrl = new URL(filename + '/index.json', base)
208-
const value = String(await fs.readFile(valueUrl))
209-
const parts = filename.split('-')
210-
const module = parts.includes('module')
211-
/** @type {Array<Plugin>} */
212-
const plugins = []
213-
214-
if (parts.includes('jsx')) {
215-
plugins.push(jsx())
216-
}
217279

218-
if (parts.includes('stage3')) {
219-
plugins.push(stage3)
220-
}
280+
await t.test(filename, async function () {
281+
const valueUrl = new URL(filename + '/index.js', base)
282+
const treeUrl = new URL(filename + '/index.json', base)
283+
const value = String(await fs.readFile(valueUrl))
284+
const parts = filename.split('-')
285+
const module = parts.includes('module')
286+
/** @type {Array<Plugin>} */
287+
const plugins = []
221288

222-
const actual = fromJs(value, {module, plugins})
223-
/** @type {string} */
224-
let expected
289+
if (parts.includes('jsx')) {
290+
plugins.push(jsx())
291+
}
225292

226-
try {
227-
expected = JSON.parse(String(await fs.readFile(treeUrl)))
228-
} catch {
229-
// New fixture.
230-
expected = JSON.stringify(actual, null, 2) + '\n'
231-
await fs.writeFile(treeUrl, expected)
232-
}
293+
if (parts.includes('stage3')) {
294+
plugins.push(stage3)
295+
}
296+
297+
const actual = fromJs(value, {module, plugins})
298+
/** @type {string} */
299+
let expected
300+
301+
try {
302+
expected = JSON.parse(String(await fs.readFile(treeUrl)))
303+
} catch {
304+
// New fixture.
305+
expected = JSON.stringify(actual, null, 2) + '\n'
306+
await fs.writeFile(treeUrl, expected)
307+
}
233308

234-
assert.deepEqual(actual, expected, filename)
309+
assert.deepEqual(actual, expected)
310+
})
235311
}
236312
})

0 commit comments

Comments
 (0)