@putout/engine-parser 11.3.0 → 12.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -29
- package/lib/parse.js +2 -15
- package/lib/parsers/acorn.js +4 -3
- package/lib/parsers/babel/index.js +4 -14
- package/lib/print.js +0 -29
- package/package.json +3 -4
- package/lib/recast/move-out-directives.js +0 -30
package/README.md
CHANGED
|
@@ -73,33 +73,6 @@ create node without `memoization`.
|
|
|
73
73
|
|
|
74
74
|
Extract `expression` node from `ExpressionStatement`.
|
|
75
75
|
|
|
76
|
-
### Sourcemaps
|
|
77
|
-
|
|
78
|
-
You have two ways to benefit from source map generation:
|
|
79
|
-
|
|
80
|
-
- using `Recast` print;
|
|
81
|
-
- using `Babel` generator;
|
|
82
|
-
|
|
83
|
-
#### Generate sourcemaps using Recast
|
|
84
|
-
|
|
85
|
-
```js
|
|
86
|
-
const source = `const hello = 'world';`;
|
|
87
|
-
|
|
88
|
-
const ast = parse(source, {
|
|
89
|
-
printer: 'recast',
|
|
90
|
-
sourceFileName: 'hello.js',
|
|
91
|
-
});
|
|
92
|
-
|
|
93
|
-
print(ast, {
|
|
94
|
-
printer: 'recast',
|
|
95
|
-
sourceMapName: 'hello.map',
|
|
96
|
-
});
|
|
97
|
-
|
|
98
|
-
// returns
|
|
99
|
-
`const hello = 'world';
|
|
100
|
-
{"version":3,"sources":["hello.js"],"names":[],"mappings":"AAAA...","file":"hello.map","sourcesContent":["const hello = 'world';"]}`;
|
|
101
|
-
```
|
|
102
|
-
|
|
103
76
|
#### Generate sourcemaps using Babel
|
|
104
77
|
|
|
105
78
|
To generate sourcemap using babel generator, you should use babel parser before.
|
|
@@ -107,9 +80,9 @@ This is low level transformation, because `Babel` doesn't preserve any formattin
|
|
|
107
80
|
|
|
108
81
|
```js
|
|
109
82
|
const {generate} = require('@putout/engine-parser');
|
|
110
|
-
const
|
|
83
|
+
const {parse} = require('@putout/engine-parser/babel');
|
|
111
84
|
|
|
112
|
-
const ast =
|
|
85
|
+
const ast = parse(source, {
|
|
113
86
|
sourceFilename: 'hello.js',
|
|
114
87
|
});
|
|
115
88
|
|
package/lib/parse.js
CHANGED
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
const recast = require('recast');
|
|
4
3
|
const toBabel = require('estree-to-babel');
|
|
5
4
|
const customParser = require('./custom-parser');
|
|
6
|
-
const moveOutDirectives = require('./recast/move-out-directives');
|
|
7
5
|
|
|
8
6
|
module.exports = (source, options) => {
|
|
9
7
|
const {
|
|
@@ -12,7 +10,6 @@ module.exports = (source, options) => {
|
|
|
12
10
|
isTS,
|
|
13
11
|
isFlow,
|
|
14
12
|
isJSX,
|
|
15
|
-
sourceFileName,
|
|
16
13
|
} = options || {};
|
|
17
14
|
|
|
18
15
|
const cookedParser = getParser({
|
|
@@ -21,19 +18,12 @@ module.exports = (source, options) => {
|
|
|
21
18
|
isTS,
|
|
22
19
|
isFlow,
|
|
23
20
|
isJSX,
|
|
24
|
-
sourceFileName,
|
|
25
21
|
});
|
|
26
22
|
|
|
27
|
-
|
|
28
|
-
return cookedParser.parse(source);
|
|
29
|
-
|
|
30
|
-
return recast.parse(source, {
|
|
31
|
-
sourceFileName,
|
|
32
|
-
parser: cookedParser,
|
|
33
|
-
});
|
|
23
|
+
return cookedParser.parse(source);
|
|
34
24
|
};
|
|
35
25
|
|
|
36
|
-
const getParser = ({parser = 'babel', isTS, isFlow, isJSX
|
|
26
|
+
const getParser = ({parser = 'babel', isTS, isFlow, isJSX}) => ({
|
|
37
27
|
parse(source) {
|
|
38
28
|
const ast = toBabel(customParser(source, parser, {
|
|
39
29
|
isTS,
|
|
@@ -41,9 +31,6 @@ const getParser = ({parser = 'babel', isTS, isFlow, isJSX, printer}) => ({
|
|
|
41
31
|
isJSX,
|
|
42
32
|
}));
|
|
43
33
|
|
|
44
|
-
if (printer === 'recast')
|
|
45
|
-
moveOutDirectives(ast);
|
|
46
|
-
|
|
47
34
|
return ast;
|
|
48
35
|
},
|
|
49
36
|
});
|
package/lib/parsers/acorn.js
CHANGED
|
@@ -4,15 +4,15 @@ const once = require('once');
|
|
|
4
4
|
|
|
5
5
|
const initAcorn = once(() => {
|
|
6
6
|
const {Parser} = require('acorn');
|
|
7
|
-
|
|
7
|
+
|
|
8
8
|
const stage3 = require('acorn-stage3');
|
|
9
|
+
const typescript = require('acorn-typescript').default;
|
|
9
10
|
|
|
10
|
-
return Parser.extend(
|
|
11
|
+
return Parser.extend(typescript(), stage3);
|
|
11
12
|
});
|
|
12
13
|
|
|
13
14
|
module.exports.parse = function acornParse(source) {
|
|
14
15
|
const parser = initAcorn();
|
|
15
|
-
|
|
16
16
|
const options = {
|
|
17
17
|
locations: true,
|
|
18
18
|
comment: true,
|
|
@@ -21,6 +21,7 @@ module.exports.parse = function acornParse(source) {
|
|
|
21
21
|
allowAwaitOutsideFunction: true,
|
|
22
22
|
allowReturnOutsideFunction: true,
|
|
23
23
|
allowImportExportEverywhere: true,
|
|
24
|
+
preserveParens: true,
|
|
24
25
|
};
|
|
25
26
|
|
|
26
27
|
const tokensToAvoidEsprima = Array.from(parser.tokenizer(source, options));
|
|
@@ -7,16 +7,13 @@ const options = require('./options');
|
|
|
7
7
|
const getFlow = (a) => !a.indexOf('// @flow');
|
|
8
8
|
const clean = (a) => a.filter(Boolean);
|
|
9
9
|
const initBabel = once(() => require('@putout/babel'));
|
|
10
|
-
const {assign} = Object;
|
|
11
10
|
|
|
12
|
-
|
|
13
|
-
// recast -> sourceFileName
|
|
14
|
-
// babel, putout: sourceFilename
|
|
15
|
-
module.exports.parse = function babelParse(source, {sourceFilename, isTS, isJSX = true, isFlow = getFlow(source), isRecovery}) {
|
|
11
|
+
module.exports.parse = function babelParse(source, {sourceFileName, isTS, isJSX = true, isFlow = getFlow(source), isRecovery}) {
|
|
16
12
|
const {parse} = initBabel();
|
|
17
13
|
const parserOptions = {
|
|
14
|
+
sourceFileName,
|
|
18
15
|
sourceType: 'module',
|
|
19
|
-
tokens:
|
|
16
|
+
tokens: false,
|
|
20
17
|
...options,
|
|
21
18
|
errorRecovery: isRecovery,
|
|
22
19
|
plugins: clean([
|
|
@@ -29,10 +26,6 @@ module.exports.parse = function babelParse(source, {sourceFilename, isTS, isJSX
|
|
|
29
26
|
]),
|
|
30
27
|
};
|
|
31
28
|
|
|
32
|
-
sourceFilename && assign(parserOptions, {
|
|
33
|
-
sourceFilename,
|
|
34
|
-
});
|
|
35
|
-
|
|
36
29
|
return parse(source, parserOptions);
|
|
37
30
|
};
|
|
38
31
|
|
|
@@ -41,11 +34,8 @@ function getBabelLangExts({isTS, isFlow, isJSX}) {
|
|
|
41
34
|
isJSX && 'jsx',
|
|
42
35
|
];
|
|
43
36
|
|
|
44
|
-
if (isTS)
|
|
37
|
+
if (isTS || isFlow)
|
|
45
38
|
return langs.concat(['typescript']);
|
|
46
39
|
|
|
47
|
-
if (isFlow)
|
|
48
|
-
return langs.concat(['flow', 'flowComments']);
|
|
49
|
-
|
|
50
40
|
return langs;
|
|
51
41
|
}
|
package/lib/print.js
CHANGED
|
@@ -1,44 +1,15 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
const recast = require('recast');
|
|
4
3
|
const putoutPrinter = require('@putout/printer');
|
|
5
4
|
const {generate} = require('@putout/babel');
|
|
6
5
|
|
|
7
|
-
const {stringify} = JSON;
|
|
8
6
|
const {isArray} = Array;
|
|
9
7
|
|
|
10
8
|
const maybeArray = (a) => isArray(a) ? a : [a, {}];
|
|
11
9
|
|
|
12
|
-
const btoa = (a) => Buffer
|
|
13
|
-
.from(a, 'binary')
|
|
14
|
-
.toString('base64');
|
|
15
|
-
|
|
16
|
-
const addSourceMap = (sourceMapName, {code, map}) => !sourceMapName ? code : `${code}\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,${btoa(stringify(map))}\n`;
|
|
17
|
-
const fixStrictMode = (a) => a.replace(`\n\n\n'use strict'`, `\n\n'use strict'`);
|
|
18
|
-
|
|
19
10
|
module.exports = (ast, options = {}) => {
|
|
20
|
-
const {sourceMapName} = options;
|
|
21
11
|
const [printer = 'putout', printerOptions] = maybeArray(options.printer);
|
|
22
12
|
|
|
23
|
-
if (printer === 'recast') {
|
|
24
|
-
const printOptions = {
|
|
25
|
-
quote: 'single',
|
|
26
|
-
objectCurlySpacing: false,
|
|
27
|
-
wrapColumn: Infinity,
|
|
28
|
-
...options,
|
|
29
|
-
...printerOptions,
|
|
30
|
-
};
|
|
31
|
-
|
|
32
|
-
const printed = recast.print(ast, printOptions);
|
|
33
|
-
const {map} = printed;
|
|
34
|
-
const code = fixStrictMode(printed.code);
|
|
35
|
-
|
|
36
|
-
return addSourceMap(sourceMapName, {
|
|
37
|
-
code,
|
|
38
|
-
map,
|
|
39
|
-
});
|
|
40
|
-
}
|
|
41
|
-
|
|
42
13
|
if (printer === 'babel')
|
|
43
14
|
return babelPrint(ast);
|
|
44
15
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@putout/engine-parser",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "12.0.0",
|
|
4
4
|
"type": "commonjs",
|
|
5
5
|
"author": "coderaiser <mnemonic.enemy@gmail.com> (https://github.com/coderaiser)",
|
|
6
6
|
"description": "🐊Putout parser",
|
|
@@ -38,7 +38,6 @@
|
|
|
38
38
|
"estree-to-babel": "^10.0.0",
|
|
39
39
|
"nano-memoize": "^3.0.11",
|
|
40
40
|
"once": "^1.4.0",
|
|
41
|
-
"recast": "^0.23.9",
|
|
42
41
|
"try-catch": "^3.0.0"
|
|
43
42
|
},
|
|
44
43
|
"keywords": [
|
|
@@ -47,12 +46,12 @@
|
|
|
47
46
|
],
|
|
48
47
|
"devDependencies": {
|
|
49
48
|
"acorn": "^8.1.1",
|
|
50
|
-
"acorn-jsx": "^5.0.2",
|
|
51
49
|
"acorn-stage3": "^4.0.0",
|
|
50
|
+
"acorn-typescript": "^1.4.13",
|
|
52
51
|
"c8": "^10.0.0",
|
|
53
52
|
"eslint": "^9.0.0",
|
|
54
53
|
"eslint-plugin-n": "^17.0.0",
|
|
55
|
-
"eslint-plugin-putout": "^
|
|
54
|
+
"eslint-plugin-putout": "^24.0.0",
|
|
56
55
|
"espree": "^10.0.0",
|
|
57
56
|
"esprima": "^4.0.1",
|
|
58
57
|
"hermes-parser": "^0.26.0",
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
const {types} = require('@putout/babel');
|
|
4
|
-
const {
|
|
5
|
-
StringLiteral,
|
|
6
|
-
ExpressionStatement,
|
|
7
|
-
} = types;
|
|
8
|
-
|
|
9
|
-
const {assign} = Object;
|
|
10
|
-
|
|
11
|
-
module.exports = (ast) => {
|
|
12
|
-
const {body, directives} = ast.program;
|
|
13
|
-
|
|
14
|
-
if (!directives.length)
|
|
15
|
-
return ast;
|
|
16
|
-
|
|
17
|
-
ast.program.directives = [];
|
|
18
|
-
|
|
19
|
-
for (const directive of directives) {
|
|
20
|
-
const {leadingComments} = directive;
|
|
21
|
-
const {value} = directive.value;
|
|
22
|
-
const expression = assign(ExpressionStatement(StringLiteral(value)), {
|
|
23
|
-
leadingComments,
|
|
24
|
-
});
|
|
25
|
-
|
|
26
|
-
body.unshift(expression);
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
return ast;
|
|
30
|
-
};
|