hermes-parser 0.15.1 → 0.17.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/dist/HermesASTAdapter.js +8 -1
- package/dist/HermesASTAdapter.js.flow +11 -2
- package/dist/HermesParserNodeDeserializers.js +71 -1
- package/dist/HermesParserWASM.js +1 -1
- package/dist/HermesToESTreeAdapter.js +4 -2
- package/dist/HermesToESTreeAdapter.js.flow +7 -2
- package/dist/babel/TransformESTreeToBabel.js +1087 -0
- package/dist/babel/TransformESTreeToBabel.js.flow +1246 -0
- package/dist/estree/StripComponentSyntax.js +610 -0
- package/dist/estree/StripComponentSyntax.js.flow +657 -0
- package/dist/estree/StripFlowTypes.js +173 -0
- package/dist/estree/StripFlowTypes.js.flow +156 -0
- package/dist/estree/StripFlowTypesForBabel.js +186 -0
- package/dist/estree/StripFlowTypesForBabel.js.flow +189 -0
- package/dist/generated/ESTreeVisitorKeys.js +2 -0
- package/dist/generated/ParserVisitorKeys.js +7 -0
- package/dist/index.js +31 -11
- package/dist/index.js.flow +31 -13
- package/dist/transform/SimpleTransform.js +32 -5
- package/dist/transform/SimpleTransform.js.flow +45 -7
- package/dist/transform/astNodeMutationHelpers.js +26 -19
- package/dist/transform/astNodeMutationHelpers.js.flow +52 -16
- package/dist/utils/createSyntaxError.js +25 -0
- package/dist/utils/createSyntaxError.js.flow +24 -0
- package/package.json +2 -2
- package/dist/HermesToBabelAdapter.js +0 -797
- package/dist/HermesToBabelAdapter.js.flow +0 -793
|
@@ -49,6 +49,10 @@ const HERMES_AST_VISITOR_KEYS = {
|
|
|
49
49
|
returnType: 'Node',
|
|
50
50
|
predicate: 'Node'
|
|
51
51
|
},
|
|
52
|
+
AsExpression: {
|
|
53
|
+
expression: 'Node',
|
|
54
|
+
typeAnnotation: 'Node'
|
|
55
|
+
},
|
|
52
56
|
AssignmentExpression: {
|
|
53
57
|
left: 'Node',
|
|
54
58
|
right: 'Node'
|
|
@@ -595,6 +599,9 @@ const HERMES_AST_VISITOR_KEYS = {
|
|
|
595
599
|
TypeofTypeAnnotation: {
|
|
596
600
|
argument: 'Node'
|
|
597
601
|
},
|
|
602
|
+
TypeOperator: {
|
|
603
|
+
typeAnnotation: 'Node'
|
|
604
|
+
},
|
|
598
605
|
TypeParameter: {
|
|
599
606
|
bound: 'Node',
|
|
600
607
|
variance: 'Node',
|
package/dist/index.js
CHANGED
|
@@ -15,23 +15,30 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
15
15
|
var _exportNames = {
|
|
16
16
|
parse: true,
|
|
17
17
|
mutateESTreeASTForPrettier: true,
|
|
18
|
+
Transforms: true,
|
|
18
19
|
FlowVisitorKeys: true,
|
|
19
20
|
astArrayMutationHelpers: true,
|
|
20
21
|
astNodeMutationHelpers: true
|
|
21
22
|
};
|
|
22
|
-
exports.mutateESTreeASTForPrettier = exports.astNodeMutationHelpers = exports.astArrayMutationHelpers = void 0;
|
|
23
|
+
exports.mutateESTreeASTForPrettier = exports.astNodeMutationHelpers = exports.astArrayMutationHelpers = exports.Transforms = void 0;
|
|
23
24
|
exports.parse = parse;
|
|
24
25
|
|
|
25
26
|
var HermesParser = _interopRequireWildcard(require("./HermesParser"));
|
|
26
27
|
|
|
27
|
-
var _HermesToBabelAdapter = _interopRequireDefault(require("./HermesToBabelAdapter"));
|
|
28
|
-
|
|
29
28
|
var _HermesToESTreeAdapter = _interopRequireDefault(require("./HermesToESTreeAdapter"));
|
|
30
29
|
|
|
31
30
|
var _ESTreeVisitorKeys = _interopRequireDefault(require("./generated/ESTreeVisitorKeys"));
|
|
32
31
|
|
|
33
32
|
exports.FlowVisitorKeys = _ESTreeVisitorKeys.default;
|
|
34
33
|
|
|
34
|
+
var StripComponentSyntax = _interopRequireWildcard(require("./estree/StripComponentSyntax"));
|
|
35
|
+
|
|
36
|
+
var StripFlowTypesForBabel = _interopRequireWildcard(require("./estree/StripFlowTypesForBabel"));
|
|
37
|
+
|
|
38
|
+
var TransformESTreeToBabel = _interopRequireWildcard(require("./babel/TransformESTreeToBabel"));
|
|
39
|
+
|
|
40
|
+
var StripFlowTypes = _interopRequireWildcard(require("./estree/StripFlowTypes"));
|
|
41
|
+
|
|
35
42
|
var _ParserOptions = require("./ParserOptions");
|
|
36
43
|
|
|
37
44
|
Object.keys(_ParserOptions).forEach(function (key) {
|
|
@@ -107,20 +114,33 @@ function getOptions(options = { ...DEFAULTS
|
|
|
107
114
|
throw new Error('sourceType option must be "script", "module", or "unambiguous" if set');
|
|
108
115
|
}
|
|
109
116
|
|
|
117
|
+
if (options.enableExperimentalComponentSyntax == null) {
|
|
118
|
+
options.enableExperimentalComponentSyntax = true; // Enable by default
|
|
119
|
+
}
|
|
120
|
+
|
|
110
121
|
options.tokens = options.tokens === true;
|
|
111
122
|
options.allowReturnOutsideFunction = options.allowReturnOutsideFunction === true;
|
|
112
123
|
return options;
|
|
113
124
|
}
|
|
114
125
|
|
|
115
|
-
function getAdapter(options, code) {
|
|
116
|
-
return options.babel === true ? new _HermesToBabelAdapter.default(options) : new _HermesToESTreeAdapter.default(options, code);
|
|
117
|
-
} // $FlowExpectedError[unclear-type]
|
|
118
|
-
|
|
119
|
-
|
|
120
126
|
// eslint-disable-next-line no-redeclare
|
|
121
127
|
function parse(code, opts) {
|
|
122
128
|
const options = getOptions(opts);
|
|
123
129
|
const ast = HermesParser.parse(code, options);
|
|
124
|
-
const
|
|
125
|
-
|
|
126
|
-
|
|
130
|
+
const estreeAdapter = new _HermesToESTreeAdapter.default(options, code);
|
|
131
|
+
const estreeAST = estreeAdapter.transform(ast);
|
|
132
|
+
|
|
133
|
+
if (options.babel !== true) {
|
|
134
|
+
return estreeAST;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
const loweredESTreeAST = [StripComponentSyntax.transformProgram, StripFlowTypesForBabel.transformProgram].reduce((ast, transform) => transform(ast, options), estreeAST);
|
|
138
|
+
return TransformESTreeToBabel.transformProgram(loweredESTreeAST, options);
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
const Transforms = {
|
|
142
|
+
stripComponentSyntax: StripComponentSyntax.transformProgram,
|
|
143
|
+
stripFlowTypesForBabel: StripFlowTypesForBabel.transformProgram,
|
|
144
|
+
stripFlowTypes: StripFlowTypes.transformProgram
|
|
145
|
+
};
|
|
146
|
+
exports.Transforms = Transforms;
|
package/dist/index.js.flow
CHANGED
|
@@ -12,11 +12,15 @@
|
|
|
12
12
|
|
|
13
13
|
import type {Program as ESTreeProgram} from 'hermes-estree';
|
|
14
14
|
import type {ParserOptions} from './ParserOptions';
|
|
15
|
+
import type {BabelFile} from './babel/TransformESTreeToBabel';
|
|
15
16
|
|
|
16
17
|
import * as HermesParser from './HermesParser';
|
|
17
|
-
import HermesToBabelAdapter from './HermesToBabelAdapter';
|
|
18
18
|
import HermesToESTreeAdapter from './HermesToESTreeAdapter';
|
|
19
19
|
import FlowVisitorKeys from './generated/ESTreeVisitorKeys';
|
|
20
|
+
import * as StripComponentSyntax from './estree/StripComponentSyntax';
|
|
21
|
+
import * as StripFlowTypesForBabel from './estree/StripFlowTypesForBabel';
|
|
22
|
+
import * as TransformESTreeToBabel from './babel/TransformESTreeToBabel';
|
|
23
|
+
import * as StripFlowTypes from './estree/StripFlowTypes';
|
|
20
24
|
|
|
21
25
|
const DEFAULTS = {
|
|
22
26
|
flow: 'detect',
|
|
@@ -44,6 +48,10 @@ function getOptions(options?: ParserOptions = {...DEFAULTS}) {
|
|
|
44
48
|
);
|
|
45
49
|
}
|
|
46
50
|
|
|
51
|
+
if (options.enableExperimentalComponentSyntax == null) {
|
|
52
|
+
options.enableExperimentalComponentSyntax = true; // Enable by default
|
|
53
|
+
}
|
|
54
|
+
|
|
47
55
|
options.tokens = options.tokens === true;
|
|
48
56
|
options.allowReturnOutsideFunction =
|
|
49
57
|
options.allowReturnOutsideFunction === true;
|
|
@@ -51,18 +59,10 @@ function getOptions(options?: ParserOptions = {...DEFAULTS}) {
|
|
|
51
59
|
return options;
|
|
52
60
|
}
|
|
53
61
|
|
|
54
|
-
function getAdapter(options: ParserOptions, code: string) {
|
|
55
|
-
return options.babel === true
|
|
56
|
-
? new HermesToBabelAdapter(options)
|
|
57
|
-
: new HermesToESTreeAdapter(options, code);
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
// $FlowExpectedError[unclear-type]
|
|
61
|
-
type BabelProgram = Object;
|
|
62
62
|
declare function parse(
|
|
63
63
|
code: string,
|
|
64
64
|
opts: {...ParserOptions, babel: true},
|
|
65
|
-
):
|
|
65
|
+
): BabelFile;
|
|
66
66
|
// eslint-disable-next-line no-redeclare
|
|
67
67
|
declare function parse(
|
|
68
68
|
code: string,
|
|
@@ -75,12 +75,23 @@ declare function parse(
|
|
|
75
75
|
export function parse(
|
|
76
76
|
code: string,
|
|
77
77
|
opts?: ParserOptions,
|
|
78
|
-
):
|
|
78
|
+
): BabelFile | ESTreeProgram {
|
|
79
79
|
const options = getOptions(opts);
|
|
80
80
|
const ast = HermesParser.parse(code, options);
|
|
81
|
-
const adapter = getAdapter(options, code);
|
|
82
81
|
|
|
83
|
-
|
|
82
|
+
const estreeAdapter = new HermesToESTreeAdapter(options, code);
|
|
83
|
+
const estreeAST = estreeAdapter.transform(ast);
|
|
84
|
+
|
|
85
|
+
if (options.babel !== true) {
|
|
86
|
+
return estreeAST;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
const loweredESTreeAST = [
|
|
90
|
+
StripComponentSyntax.transformProgram,
|
|
91
|
+
StripFlowTypesForBabel.transformProgram,
|
|
92
|
+
].reduce((ast, transform) => transform(ast, options), estreeAST);
|
|
93
|
+
|
|
94
|
+
return TransformESTreeToBabel.transformProgram(loweredESTreeAST, options);
|
|
84
95
|
}
|
|
85
96
|
|
|
86
97
|
export type {ParserOptions} from './ParserOptions';
|
|
@@ -92,3 +103,10 @@ export {FlowVisitorKeys};
|
|
|
92
103
|
export * as astArrayMutationHelpers from './transform/astArrayMutationHelpers';
|
|
93
104
|
export * as astNodeMutationHelpers from './transform/astNodeMutationHelpers';
|
|
94
105
|
export {default as mutateESTreeASTForPrettier} from './utils/mutateESTreeASTForPrettier';
|
|
106
|
+
|
|
107
|
+
const Transforms = {
|
|
108
|
+
stripComponentSyntax: StripComponentSyntax.transformProgram,
|
|
109
|
+
stripFlowTypesForBabel: StripFlowTypesForBabel.transformProgram,
|
|
110
|
+
stripFlowTypes: StripFlowTypes.transformProgram,
|
|
111
|
+
};
|
|
112
|
+
export {Transforms};
|
|
@@ -18,9 +18,17 @@ var _SimpleTraverser = require("../traverse/SimpleTraverser");
|
|
|
18
18
|
|
|
19
19
|
var _astNodeMutationHelpers = require("./astNodeMutationHelpers");
|
|
20
20
|
|
|
21
|
+
function setParentPointer(node, parent) {
|
|
22
|
+
if (parent != null) {
|
|
23
|
+
// $FlowExpectedError[cannot-write]
|
|
24
|
+
node.parent = parent;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
21
27
|
/**
|
|
22
28
|
* A simple class to recursively tranform AST trees.
|
|
23
29
|
*/
|
|
30
|
+
|
|
31
|
+
|
|
24
32
|
class SimpleTransform {
|
|
25
33
|
/**
|
|
26
34
|
* Transform the given AST tree.
|
|
@@ -33,10 +41,18 @@ class SimpleTransform {
|
|
|
33
41
|
|
|
34
42
|
_SimpleTraverser.SimpleTraverser.traverse(rootNode, {
|
|
35
43
|
enter: (node, parent) => {
|
|
44
|
+
// Ensure the parent pointers are correctly set before entering the node.
|
|
45
|
+
setParentPointer(node, parent);
|
|
36
46
|
const resultNode = options.transform(node);
|
|
37
47
|
|
|
38
48
|
if (resultNode !== node) {
|
|
39
|
-
|
|
49
|
+
let traversedResultNode = null;
|
|
50
|
+
|
|
51
|
+
if (resultNode != null) {
|
|
52
|
+
// Ensure the new node has the correct parent pointers before recursing again.
|
|
53
|
+
setParentPointer(resultNode, parent);
|
|
54
|
+
traversedResultNode = this.transform(resultNode, options);
|
|
55
|
+
}
|
|
40
56
|
|
|
41
57
|
if (parent == null) {
|
|
42
58
|
if (node !== rootNode) {
|
|
@@ -45,9 +61,10 @@ class SimpleTransform {
|
|
|
45
61
|
|
|
46
62
|
resultRootNode = traversedResultNode;
|
|
47
63
|
} else if (traversedResultNode == null) {
|
|
48
|
-
(0, _astNodeMutationHelpers.removeNodeOnParent)(node, parent);
|
|
64
|
+
(0, _astNodeMutationHelpers.removeNodeOnParent)(node, parent, options.visitorKeys);
|
|
49
65
|
} else {
|
|
50
|
-
(0, _astNodeMutationHelpers.replaceNodeOnParent)(node, parent, traversedResultNode);
|
|
66
|
+
(0, _astNodeMutationHelpers.replaceNodeOnParent)(node, parent, traversedResultNode, options.visitorKeys);
|
|
67
|
+
setParentPointer(traversedResultNode, parent);
|
|
51
68
|
}
|
|
52
69
|
|
|
53
70
|
throw _SimpleTraverser.SimpleTraverser.Skip;
|
|
@@ -71,6 +88,16 @@ class SimpleTransform {
|
|
|
71
88
|
static transform(node, options) {
|
|
72
89
|
return new SimpleTransform().transform(node, options);
|
|
73
90
|
}
|
|
91
|
+
|
|
92
|
+
static transformProgram(program, options) {
|
|
93
|
+
const result = SimpleTransform.transform(program, options);
|
|
94
|
+
|
|
95
|
+
if ((result == null ? void 0 : result.type) === 'Program') {
|
|
96
|
+
return result;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
throw new Error('SimpleTransform.transformProgram: Expected program node.');
|
|
100
|
+
}
|
|
74
101
|
/**
|
|
75
102
|
* Return a new AST node with the given properties overrided if needed.
|
|
76
103
|
*
|
|
@@ -84,8 +111,8 @@ class SimpleTransform {
|
|
|
84
111
|
*/
|
|
85
112
|
|
|
86
113
|
|
|
87
|
-
static nodeWith(node, overrideProps) {
|
|
88
|
-
return (0, _astNodeMutationHelpers.nodeWith)(node, overrideProps);
|
|
114
|
+
static nodeWith(node, overrideProps, visitorKeys) {
|
|
115
|
+
return (0, _astNodeMutationHelpers.nodeWith)(node, overrideProps, visitorKeys);
|
|
89
116
|
}
|
|
90
117
|
|
|
91
118
|
}
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
'use strict';
|
|
12
12
|
|
|
13
13
|
import type {VisitorKeysType} from '../traverse/getVisitorKeys';
|
|
14
|
-
import type {ESNode} from 'hermes-estree';
|
|
14
|
+
import type {ESNode, Program} from 'hermes-estree';
|
|
15
15
|
|
|
16
16
|
import {SimpleTraverser} from '../traverse/SimpleTraverser';
|
|
17
17
|
import {
|
|
@@ -39,6 +39,13 @@ export type TransformOptions = $ReadOnly<{
|
|
|
39
39
|
visitorKeys?: ?VisitorKeysType,
|
|
40
40
|
}>;
|
|
41
41
|
|
|
42
|
+
function setParentPointer(node: ESNode, parent: ?ESNode): void {
|
|
43
|
+
if (parent != null) {
|
|
44
|
+
// $FlowExpectedError[cannot-write]
|
|
45
|
+
node.parent = parent;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
42
49
|
/**
|
|
43
50
|
* A simple class to recursively tranform AST trees.
|
|
44
51
|
*/
|
|
@@ -53,10 +60,20 @@ export class SimpleTransform {
|
|
|
53
60
|
let resultRootNode: ESNode | null = rootNode;
|
|
54
61
|
SimpleTraverser.traverse(rootNode, {
|
|
55
62
|
enter: (node: ESNode, parent: ?ESNode) => {
|
|
63
|
+
// Ensure the parent pointers are correctly set before entering the node.
|
|
64
|
+
setParentPointer(node, parent);
|
|
65
|
+
|
|
56
66
|
const resultNode = options.transform(node);
|
|
57
67
|
if (resultNode !== node) {
|
|
58
|
-
|
|
59
|
-
|
|
68
|
+
let traversedResultNode = null;
|
|
69
|
+
|
|
70
|
+
if (resultNode != null) {
|
|
71
|
+
// Ensure the new node has the correct parent pointers before recursing again.
|
|
72
|
+
setParentPointer(resultNode, parent);
|
|
73
|
+
|
|
74
|
+
traversedResultNode = this.transform(resultNode, options);
|
|
75
|
+
}
|
|
76
|
+
|
|
60
77
|
if (parent == null) {
|
|
61
78
|
if (node !== rootNode) {
|
|
62
79
|
throw new Error(
|
|
@@ -65,9 +82,15 @@ export class SimpleTransform {
|
|
|
65
82
|
}
|
|
66
83
|
resultRootNode = traversedResultNode;
|
|
67
84
|
} else if (traversedResultNode == null) {
|
|
68
|
-
removeNodeOnParent(node, parent);
|
|
85
|
+
removeNodeOnParent(node, parent, options.visitorKeys);
|
|
69
86
|
} else {
|
|
70
|
-
replaceNodeOnParent(
|
|
87
|
+
replaceNodeOnParent(
|
|
88
|
+
node,
|
|
89
|
+
parent,
|
|
90
|
+
traversedResultNode,
|
|
91
|
+
options.visitorKeys,
|
|
92
|
+
);
|
|
93
|
+
setParentPointer(traversedResultNode, parent);
|
|
71
94
|
}
|
|
72
95
|
|
|
73
96
|
throw SimpleTraverser.Skip;
|
|
@@ -88,6 +111,17 @@ export class SimpleTransform {
|
|
|
88
111
|
return new SimpleTransform().transform(node, options);
|
|
89
112
|
}
|
|
90
113
|
|
|
114
|
+
static transformProgram(
|
|
115
|
+
program: Program,
|
|
116
|
+
options: TransformOptions,
|
|
117
|
+
): Program {
|
|
118
|
+
const result = SimpleTransform.transform(program, options);
|
|
119
|
+
if (result?.type === 'Program') {
|
|
120
|
+
return result;
|
|
121
|
+
}
|
|
122
|
+
throw new Error('SimpleTransform.transformProgram: Expected program node.');
|
|
123
|
+
}
|
|
124
|
+
|
|
91
125
|
/**
|
|
92
126
|
* Return a new AST node with the given properties overrided if needed.
|
|
93
127
|
*
|
|
@@ -99,7 +133,11 @@ export class SimpleTransform {
|
|
|
99
133
|
* @return Either the orginal node if the properties matched the existing node or a new node with
|
|
100
134
|
* the new properties.
|
|
101
135
|
*/
|
|
102
|
-
static nodeWith<T: ESNode>(
|
|
103
|
-
|
|
136
|
+
static nodeWith<T: ESNode>(
|
|
137
|
+
node: T,
|
|
138
|
+
overrideProps: Partial<T>,
|
|
139
|
+
visitorKeys?: VisitorKeysType,
|
|
140
|
+
): T {
|
|
141
|
+
return nodeWith<T>(node, overrideProps, visitorKeys);
|
|
104
142
|
}
|
|
105
143
|
}
|
|
@@ -26,12 +26,12 @@ var _getVisitorKeys = require("../traverse/getVisitorKeys");
|
|
|
26
26
|
|
|
27
27
|
var _SimpleTraverser = require("../traverse/SimpleTraverser");
|
|
28
28
|
|
|
29
|
-
function getParentKey(target, parent) {
|
|
29
|
+
function getParentKey(target, parent, visitorKeys) {
|
|
30
30
|
if (parent == null) {
|
|
31
31
|
throw new Error(`Expected parent node to be set on "${target.type}"`);
|
|
32
32
|
}
|
|
33
33
|
|
|
34
|
-
for (const key of (0, _getVisitorKeys.getVisitorKeys)(parent)) {
|
|
34
|
+
for (const key of (0, _getVisitorKeys.getVisitorKeys)(parent, visitorKeys)) {
|
|
35
35
|
if ((0, _getVisitorKeys.isNode)( // $FlowExpectedError[prop-missing]
|
|
36
36
|
parent[key])) {
|
|
37
37
|
if (parent[key] === target) {
|
|
@@ -65,8 +65,8 @@ function getParentKey(target, parent) {
|
|
|
65
65
|
*/
|
|
66
66
|
|
|
67
67
|
|
|
68
|
-
function replaceNodeOnParent(originalNode, originalNodeParent, nodeToReplaceWith) {
|
|
69
|
-
const replacementParent = getParentKey(originalNode, originalNodeParent);
|
|
68
|
+
function replaceNodeOnParent(originalNode, originalNodeParent, nodeToReplaceWith, visitorKeys) {
|
|
69
|
+
const replacementParent = getParentKey(originalNode, originalNodeParent, visitorKeys);
|
|
70
70
|
const parent = replacementParent.node;
|
|
71
71
|
|
|
72
72
|
if (replacementParent.type === 'array') {
|
|
@@ -83,8 +83,8 @@ function replaceNodeOnParent(originalNode, originalNodeParent, nodeToReplaceWith
|
|
|
83
83
|
*/
|
|
84
84
|
|
|
85
85
|
|
|
86
|
-
function removeNodeOnParent(originalNode, originalNodeParent) {
|
|
87
|
-
const replacementParent = getParentKey(originalNode, originalNodeParent);
|
|
86
|
+
function removeNodeOnParent(originalNode, originalNodeParent, visitorKeys) {
|
|
87
|
+
const replacementParent = getParentKey(originalNode, originalNodeParent, visitorKeys);
|
|
88
88
|
const parent = replacementParent.node;
|
|
89
89
|
|
|
90
90
|
if (replacementParent.type === 'array') {
|
|
@@ -101,8 +101,8 @@ function removeNodeOnParent(originalNode, originalNodeParent) {
|
|
|
101
101
|
*/
|
|
102
102
|
|
|
103
103
|
|
|
104
|
-
function setParentPointersInDirectChildren(node) {
|
|
105
|
-
for (const key of (0, _getVisitorKeys.getVisitorKeys)(node)) {
|
|
104
|
+
function setParentPointersInDirectChildren(node, visitorKeys) {
|
|
105
|
+
for (const key of (0, _getVisitorKeys.getVisitorKeys)(node, visitorKeys)) {
|
|
106
106
|
if ((0, _getVisitorKeys.isNode)(node[key])) {
|
|
107
107
|
node[key].parent = node;
|
|
108
108
|
} else if (Array.isArray(node[key])) {
|
|
@@ -117,15 +117,16 @@ function setParentPointersInDirectChildren(node) {
|
|
|
117
117
|
*/
|
|
118
118
|
|
|
119
119
|
|
|
120
|
-
function updateAllParentPointers(node) {
|
|
120
|
+
function updateAllParentPointers(node, visitorKeys) {
|
|
121
121
|
_SimpleTraverser.SimpleTraverser.traverse(node, {
|
|
122
122
|
enter(node, parent) {
|
|
123
123
|
// $FlowExpectedError[cannot-write]
|
|
124
124
|
node.parent = parent;
|
|
125
125
|
},
|
|
126
126
|
|
|
127
|
-
leave() {}
|
|
127
|
+
leave() {},
|
|
128
128
|
|
|
129
|
+
visitorKeys
|
|
129
130
|
});
|
|
130
131
|
}
|
|
131
132
|
/**
|
|
@@ -135,11 +136,17 @@ function updateAllParentPointers(node) {
|
|
|
135
136
|
*/
|
|
136
137
|
|
|
137
138
|
|
|
138
|
-
function nodeWith(node, overrideProps) {
|
|
139
|
+
function nodeWith(node, overrideProps, visitorKeys) {
|
|
139
140
|
// Check if this will actually result in a change, maintaining referential equality is important.
|
|
140
|
-
const willBeUnchanged = Object.entries(overrideProps).every(([key, value]) =>
|
|
141
|
-
|
|
142
|
-
|
|
141
|
+
const willBeUnchanged = Object.entries(overrideProps).every(([key, value]) => {
|
|
142
|
+
if (Array.isArray(value)) {
|
|
143
|
+
// $FlowExpectedError[prop-missing]
|
|
144
|
+
return Array.isArray(node[key]) ? (0, _astArrayMutationHelpers.arrayIsEqual)(node[key], value) : false;
|
|
145
|
+
} // $FlowExpectedError[prop-missing]
|
|
146
|
+
|
|
147
|
+
|
|
148
|
+
return node[key] === value;
|
|
149
|
+
});
|
|
143
150
|
|
|
144
151
|
if (willBeUnchanged) {
|
|
145
152
|
return node;
|
|
@@ -151,7 +158,7 @@ function nodeWith(node, overrideProps) {
|
|
|
151
158
|
...overrideProps
|
|
152
159
|
}; // Ensure parent pointers are correctly set within this nodes children.
|
|
153
160
|
|
|
154
|
-
setParentPointersInDirectChildren(newNode);
|
|
161
|
+
setParentPointersInDirectChildren(newNode, visitorKeys);
|
|
155
162
|
return newNode;
|
|
156
163
|
}
|
|
157
164
|
/**
|
|
@@ -159,12 +166,12 @@ function nodeWith(node, overrideProps) {
|
|
|
159
166
|
*/
|
|
160
167
|
|
|
161
168
|
|
|
162
|
-
function shallowCloneNode(node) {
|
|
169
|
+
function shallowCloneNode(node, visitorKeys) {
|
|
163
170
|
// $FlowExpectedError[cannot-spread-interface]
|
|
164
171
|
const newNode = { ...node
|
|
165
172
|
}; // Ensure parent pointers are correctly set within this nodes children.
|
|
166
173
|
|
|
167
|
-
setParentPointersInDirectChildren(newNode);
|
|
174
|
+
setParentPointersInDirectChildren(newNode, visitorKeys);
|
|
168
175
|
return newNode;
|
|
169
176
|
}
|
|
170
177
|
/**
|
|
@@ -172,7 +179,7 @@ function shallowCloneNode(node) {
|
|
|
172
179
|
*/
|
|
173
180
|
|
|
174
181
|
|
|
175
|
-
function deepCloneNode(node) {
|
|
182
|
+
function deepCloneNode(node, visitorKeys) {
|
|
176
183
|
const clone = JSON.parse(JSON.stringify(node, (key, value) => {
|
|
177
184
|
// null out parent pointers
|
|
178
185
|
if (key === 'parent') {
|
|
@@ -181,6 +188,6 @@ function deepCloneNode(node) {
|
|
|
181
188
|
|
|
182
189
|
return value;
|
|
183
190
|
}));
|
|
184
|
-
updateAllParentPointers(clone);
|
|
191
|
+
updateAllParentPointers(clone, visitorKeys);
|
|
185
192
|
return clone;
|
|
186
193
|
}
|
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
'use strict';
|
|
12
12
|
|
|
13
13
|
import type {ESNode} from 'hermes-estree';
|
|
14
|
+
import type {VisitorKeysType} from '../traverse/getVisitorKeys';
|
|
14
15
|
|
|
15
16
|
import {
|
|
16
17
|
arrayIsEqual,
|
|
@@ -23,6 +24,7 @@ import {SimpleTraverser} from '../traverse/SimpleTraverser';
|
|
|
23
24
|
function getParentKey(
|
|
24
25
|
target: ESNode,
|
|
25
26
|
parent: ESNode,
|
|
27
|
+
visitorKeys?: ?VisitorKeysType,
|
|
26
28
|
): $ReadOnly<
|
|
27
29
|
| {
|
|
28
30
|
type: 'single',
|
|
@@ -39,7 +41,7 @@ function getParentKey(
|
|
|
39
41
|
if (parent == null) {
|
|
40
42
|
throw new Error(`Expected parent node to be set on "${target.type}"`);
|
|
41
43
|
}
|
|
42
|
-
for (const key of getVisitorKeys(parent)) {
|
|
44
|
+
for (const key of getVisitorKeys(parent, visitorKeys)) {
|
|
43
45
|
if (
|
|
44
46
|
isNode(
|
|
45
47
|
// $FlowExpectedError[prop-missing]
|
|
@@ -72,8 +74,13 @@ export function replaceNodeOnParent(
|
|
|
72
74
|
originalNode: ESNode,
|
|
73
75
|
originalNodeParent: ESNode,
|
|
74
76
|
nodeToReplaceWith: ESNode,
|
|
77
|
+
visitorKeys?: ?VisitorKeysType,
|
|
75
78
|
): void {
|
|
76
|
-
const replacementParent = getParentKey(
|
|
79
|
+
const replacementParent = getParentKey(
|
|
80
|
+
originalNode,
|
|
81
|
+
originalNodeParent,
|
|
82
|
+
visitorKeys,
|
|
83
|
+
);
|
|
77
84
|
const parent = replacementParent.node;
|
|
78
85
|
if (replacementParent.type === 'array') {
|
|
79
86
|
// $FlowExpectedError[prop-missing]
|
|
@@ -95,8 +102,13 @@ export function replaceNodeOnParent(
|
|
|
95
102
|
export function removeNodeOnParent(
|
|
96
103
|
originalNode: ESNode,
|
|
97
104
|
originalNodeParent: ESNode,
|
|
105
|
+
visitorKeys?: ?VisitorKeysType,
|
|
98
106
|
): void {
|
|
99
|
-
const replacementParent = getParentKey(
|
|
107
|
+
const replacementParent = getParentKey(
|
|
108
|
+
originalNode,
|
|
109
|
+
originalNodeParent,
|
|
110
|
+
visitorKeys,
|
|
111
|
+
);
|
|
100
112
|
const parent = replacementParent.node;
|
|
101
113
|
if (replacementParent.type === 'array') {
|
|
102
114
|
// $FlowExpectedError[prop-missing]
|
|
@@ -114,8 +126,11 @@ export function removeNodeOnParent(
|
|
|
114
126
|
/**
|
|
115
127
|
* Corrects the parent pointers in direct children of the given node.
|
|
116
128
|
*/
|
|
117
|
-
export function setParentPointersInDirectChildren(
|
|
118
|
-
|
|
129
|
+
export function setParentPointersInDirectChildren(
|
|
130
|
+
node: ESNode,
|
|
131
|
+
visitorKeys?: ?VisitorKeysType,
|
|
132
|
+
): void {
|
|
133
|
+
for (const key: $FlowFixMe of getVisitorKeys(node, visitorKeys)) {
|
|
119
134
|
if (isNode(node[key])) {
|
|
120
135
|
node[key].parent = node;
|
|
121
136
|
} else if (Array.isArray(node[key])) {
|
|
@@ -129,13 +144,17 @@ export function setParentPointersInDirectChildren(node: ESNode): void {
|
|
|
129
144
|
/**
|
|
130
145
|
* Traverses the entire subtree to ensure the parent pointers are set correctly.
|
|
131
146
|
*/
|
|
132
|
-
export function updateAllParentPointers(
|
|
147
|
+
export function updateAllParentPointers(
|
|
148
|
+
node: ESNode,
|
|
149
|
+
visitorKeys?: ?VisitorKeysType,
|
|
150
|
+
) {
|
|
133
151
|
SimpleTraverser.traverse(node, {
|
|
134
152
|
enter(node, parent) {
|
|
135
153
|
// $FlowExpectedError[cannot-write]
|
|
136
154
|
node.parent = parent;
|
|
137
155
|
},
|
|
138
156
|
leave() {},
|
|
157
|
+
visitorKeys,
|
|
139
158
|
});
|
|
140
159
|
}
|
|
141
160
|
|
|
@@ -144,12 +163,23 @@ export function updateAllParentPointers(node: ESNode) {
|
|
|
144
163
|
*
|
|
145
164
|
* This will only create a new object if the overrides actually result in a change.
|
|
146
165
|
*/
|
|
147
|
-
export function nodeWith<T: ESNode>(
|
|
166
|
+
export function nodeWith<T: ESNode>(
|
|
167
|
+
node: T,
|
|
168
|
+
overrideProps: Partial<T>,
|
|
169
|
+
visitorKeys?: ?VisitorKeysType,
|
|
170
|
+
): T {
|
|
148
171
|
// Check if this will actually result in a change, maintaining referential equality is important.
|
|
149
|
-
const willBeUnchanged = Object.entries(overrideProps).every(
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
172
|
+
const willBeUnchanged = Object.entries(overrideProps).every(
|
|
173
|
+
([key, value]) => {
|
|
174
|
+
if (Array.isArray(value)) {
|
|
175
|
+
// $FlowExpectedError[prop-missing]
|
|
176
|
+
return Array.isArray(node[key])
|
|
177
|
+
? arrayIsEqual(node[key], value)
|
|
178
|
+
: false;
|
|
179
|
+
}
|
|
180
|
+
// $FlowExpectedError[prop-missing]
|
|
181
|
+
return node[key] === value;
|
|
182
|
+
},
|
|
153
183
|
);
|
|
154
184
|
if (willBeUnchanged) {
|
|
155
185
|
return node;
|
|
@@ -163,7 +193,7 @@ export function nodeWith<T: ESNode>(node: T, overrideProps: Partial<T>): T {
|
|
|
163
193
|
};
|
|
164
194
|
|
|
165
195
|
// Ensure parent pointers are correctly set within this nodes children.
|
|
166
|
-
setParentPointersInDirectChildren(newNode);
|
|
196
|
+
setParentPointersInDirectChildren(newNode, visitorKeys);
|
|
167
197
|
|
|
168
198
|
return newNode;
|
|
169
199
|
}
|
|
@@ -171,12 +201,15 @@ export function nodeWith<T: ESNode>(node: T, overrideProps: Partial<T>): T {
|
|
|
171
201
|
/**
|
|
172
202
|
* Shallow clones node, providing a new reference for an existing node.
|
|
173
203
|
*/
|
|
174
|
-
export function shallowCloneNode<T: ESNode>(
|
|
204
|
+
export function shallowCloneNode<T: ESNode>(
|
|
205
|
+
node: T,
|
|
206
|
+
visitorKeys?: ?VisitorKeysType,
|
|
207
|
+
): T {
|
|
175
208
|
// $FlowExpectedError[cannot-spread-interface]
|
|
176
209
|
const newNode: T = {...node};
|
|
177
210
|
|
|
178
211
|
// Ensure parent pointers are correctly set within this nodes children.
|
|
179
|
-
setParentPointersInDirectChildren(newNode);
|
|
212
|
+
setParentPointersInDirectChildren(newNode, visitorKeys);
|
|
180
213
|
|
|
181
214
|
return newNode;
|
|
182
215
|
}
|
|
@@ -184,7 +217,10 @@ export function shallowCloneNode<T: ESNode>(node: T): T {
|
|
|
184
217
|
/**
|
|
185
218
|
* Deeply clones node and its entire tree.
|
|
186
219
|
*/
|
|
187
|
-
export function deepCloneNode<T: ESNode>(
|
|
220
|
+
export function deepCloneNode<T: ESNode>(
|
|
221
|
+
node: T,
|
|
222
|
+
visitorKeys?: ?VisitorKeysType,
|
|
223
|
+
): T {
|
|
188
224
|
const clone: T = JSON.parse(
|
|
189
225
|
JSON.stringify(node, (key, value) => {
|
|
190
226
|
// null out parent pointers
|
|
@@ -195,7 +231,7 @@ export function deepCloneNode<T: ESNode>(node: T): T {
|
|
|
195
231
|
}),
|
|
196
232
|
);
|
|
197
233
|
|
|
198
|
-
updateAllParentPointers(clone);
|
|
234
|
+
updateAllParentPointers(clone, visitorKeys);
|
|
199
235
|
|
|
200
236
|
return clone;
|
|
201
237
|
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*
|
|
7
|
+
*
|
|
8
|
+
* @format
|
|
9
|
+
*/
|
|
10
|
+
'use strict';
|
|
11
|
+
|
|
12
|
+
Object.defineProperty(exports, "__esModule", {
|
|
13
|
+
value: true
|
|
14
|
+
});
|
|
15
|
+
exports.createSyntaxError = createSyntaxError;
|
|
16
|
+
|
|
17
|
+
function createSyntaxError(node, err) {
|
|
18
|
+
const syntaxError = new SyntaxError(err); // $FlowExpectedError[prop-missing]
|
|
19
|
+
|
|
20
|
+
syntaxError.loc = {
|
|
21
|
+
line: node.loc.start.line,
|
|
22
|
+
column: node.loc.start.column
|
|
23
|
+
};
|
|
24
|
+
return syntaxError;
|
|
25
|
+
}
|