Skip to content

Commit c8d28dd

Browse files
committed
Add support for the Meriyah parser
Meriyah is a fast and modern implementation of ECMAScript parser
1 parent 74feafb commit c8d28dd

File tree

8 files changed

+61
-3
lines changed

8 files changed

+61
-3
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,7 @@ const tsAst = recast.parse(source, {
168168
});
169169
```
170170

171-
**Note:** Some of these parsers import npm packages that Recast does not directly depend upon, so please be aware you may have to run `npm install babylon@next` to use the `typescript`, `flow`, or `babylon` parsers, or `npm install acorn` to use the `acorn` parser. Only Esprima is installed by default when Recast is installed.
171+
**Note:** Some of these parsers import npm packages that Recast does not directly depend upon, so please be aware you may have to run `npm install babylon@next` to use the `typescript`, `flow`, or `babylon` parsers, or `npm install acorn` to use the `acorn` parser, or `npm install meriyah` to use the `meriyah` parser. Only Esprima is installed by default when Recast is installed.
172172

173173
After calling `recast.parse`, if you're going to transform the AST, make sure that the `.original` property is preserved. With Babel, for instance, if you call `transformFromAST`, you must pass `cloneInputAst: false` in its options. ([More detail](https://github.com/babel/babel/issues/12882).
174174

lib/parser.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -78,8 +78,8 @@ export function parse(source: string, options?: Partial<Options>) {
7878
program = ast;
7979
// In order to ensure we reprint leading and trailing program
8080
// comments, wrap the original Program node with a File node. Only
81-
// ESTree parsers (Acorn and Esprima) return a Program as the root AST
82-
// node. Most other (Babylon-like) parsers return a File.
81+
// ESTree parsers (Acorn, Esprima, Meriyah) return a Program as the root
82+
// AST node. Most other (Babylon-like) parsers return a File.
8383
file = b.file(ast, options.sourceFileName || null);
8484
file.loc = {
8585
start: lines.firstPos(),

package-lock.json

Lines changed: 16 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@
6161
"flow-parser": "0.156.0",
6262
"glob": "7.2.0",
6363
"lint-staged": "^12.4.1",
64+
"meriyah": "^4.2.1",
6465
"mocha": "9.0.2",
6566
"prettier": "^2.6.2",
6667
"reify": "0.20.12",

parsers/meriyah.ts

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
// This module is suitable for passing as options.parser when calling
2+
// recast.parse to process JavaScript code with Meriyah:
3+
//
4+
// const ast = recast.parse(source, {
5+
// parser: require("recast/parsers/meriyah")
6+
// });
7+
//
8+
import { getOption } from "../lib/util";
9+
10+
const convertComment = (comment: any) => {
11+
let { type } = comment
12+
type = type.charAt(0) === 'S' ? 'Line' : 'Block'
13+
return { ...comment, type }
14+
}
15+
16+
export function parse(source: string, options?: any) {
17+
const comments: any[] = [];
18+
const tokens: any[] = [];
19+
const ast = require("meriyah").parse(source, {
20+
module: getOption(options, "sourceType", "module") === "module",
21+
specDeviation: getOption(options, "tolerant", true),
22+
jsx: getOption(options, "jsx", false),
23+
ranges: getOption(options, "range", false),
24+
loc: true,
25+
raw: true,
26+
next: true,
27+
globalReturn: true,
28+
onComment: comments,
29+
onToken: tokens,
30+
});
31+
32+
ast.comments = comments.map(convertComment)
33+
ast.tokens = tokens;
34+
35+
return ast;
36+
}

test/comments.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ const nodeMajorVersion = parseInt(process.versions.node, 10);
2323
describe("comments", function () {
2424
[
2525
"../parsers/acorn",
26+
"../parsers/meriyah",
2627
"../parsers/babel",
2728
"../parsers/esprima",
2829
"../parsers/flow",
@@ -180,6 +181,7 @@ function runTestsForParser(parserId: any) {
180181
const info = (
181182
{
182183
acorn: esprimaInfo,
184+
meriyah: esprimaInfo,
183185
babel: babelInfo,
184186
esprima: esprimaInfo,
185187
flow: babelInfo,

test/parser.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ const nodeMajorVersion = parseInt(process.versions.node, 10);
1515
describe("parser", function () {
1616
[
1717
"../parsers/acorn",
18+
"../parsers/meriyah",
1819
"../parsers/babel",
1920
"../parsers/esprima",
2021
"../parsers/flow",
@@ -84,6 +85,7 @@ function runTestsForParser(parserId: string) {
8485

8586
const lineCommentTypes: { [name: string]: string } = {
8687
acorn: "Line",
88+
meriyah: "Line",
8789
babel: "CommentLine",
8890
esprima: "Line",
8991
flow: "CommentLine",

test/printer.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1692,6 +1692,7 @@ describe("printer", function () {
16921692

16931693
checkWith(require("../parsers/esprima"));
16941694
checkWith(require("../parsers/acorn"));
1695+
checkWith(require("../parsers/meriyah"));
16951696

16961697
if (nodeMajorVersion >= 6) {
16971698
checkWith(require("../parsers/babel"));

0 commit comments

Comments
 (0)