oxc-parser 0.73.2 → 0.75.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/generated/deserialize/lazy-types.js +194 -0
- package/generated/deserialize/lazy-visit.js +5457 -0
- package/generated/deserialize/lazy.js +410 -11
- package/index.d.ts +8 -0
- package/index.js +95 -18
- package/package.json +25 -21
- package/raw-transfer/{index.js → common.js} +101 -98
- package/raw-transfer/eager.js +42 -3
- package/raw-transfer/lazy-common.js +4 -1
- package/raw-transfer/lazy.js +95 -21
- package/raw-transfer/node-array.js +127 -92
- package/raw-transfer/supported.js +56 -0
- package/raw-transfer/visitor.js +129 -0
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const {
|
|
4
|
+
NODE_TYPE_IDS_MAP,
|
|
5
|
+
NODE_TYPES_COUNT,
|
|
6
|
+
LEAF_NODE_TYPES_COUNT,
|
|
7
|
+
} = require('../generated/deserialize/lazy-types.js');
|
|
8
|
+
|
|
9
|
+
// Getter for private `#visitorsArr` property of `Visitor` class. Initialized in class body below.
|
|
10
|
+
let getVisitorsArr;
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Visitor class, used to visit an AST.
|
|
14
|
+
*/
|
|
15
|
+
class Visitor {
|
|
16
|
+
#visitorsArr;
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Create `Visitor`.
|
|
20
|
+
*
|
|
21
|
+
* Provide an object where keys are names of AST nodes you want to visit,
|
|
22
|
+
* and values are visitor functions which receive AST node objects of that type.
|
|
23
|
+
*
|
|
24
|
+
* Keys can also be postfixed with `:exit` to visit when exiting the node, rather than entering.
|
|
25
|
+
*
|
|
26
|
+
* ```js
|
|
27
|
+
* const visitor = new Visitor({
|
|
28
|
+
* BinaryExpression(binExpr) {
|
|
29
|
+
* // Do stuff when entering a `BinaryExpression`
|
|
30
|
+
* },
|
|
31
|
+
* 'BinaryExpression:exit'(binExpr) {
|
|
32
|
+
* // Do stuff when exiting a `BinaryExpression`
|
|
33
|
+
* },
|
|
34
|
+
* });
|
|
35
|
+
* ```
|
|
36
|
+
*
|
|
37
|
+
* @constructor
|
|
38
|
+
* @param {Object} visitor - Object defining visit functions for AST nodes
|
|
39
|
+
* @returns {Visitor}
|
|
40
|
+
*/
|
|
41
|
+
constructor(visitor) {
|
|
42
|
+
this.#visitorsArr = createVisitorsArr(visitor);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
static {
|
|
46
|
+
getVisitorsArr = visitor => visitor.#visitorsArr;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
module.exports = { Visitor, getVisitorsArr };
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Create array of visitors, keyed by node type ID.
|
|
54
|
+
*
|
|
55
|
+
* Each element of array is one of:
|
|
56
|
+
*
|
|
57
|
+
* * No visitor for this type = `null`.
|
|
58
|
+
* * Visitor for leaf node = visit function.
|
|
59
|
+
* * Visitor for non-leaf node = object of form `{ enter, exit }`,
|
|
60
|
+
* where each property is either a visitor function or `null`.
|
|
61
|
+
*
|
|
62
|
+
* @param {Object} visitor - Visitors object from user
|
|
63
|
+
* @returns {Array<Object|function|null>} - Array of visitors
|
|
64
|
+
*/
|
|
65
|
+
function createVisitorsArr(visitor) {
|
|
66
|
+
if (visitor === null || typeof visitor !== 'object') {
|
|
67
|
+
throw new Error('`visitors` must be an object');
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// Create empty visitors array
|
|
71
|
+
const visitorsArr = [];
|
|
72
|
+
for (let i = NODE_TYPES_COUNT; i !== 0; i--) {
|
|
73
|
+
visitorsArr.push(null);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// Populate visitors array from provided object
|
|
77
|
+
for (let name of Object.keys(visitor)) {
|
|
78
|
+
const visitFn = visitor[name];
|
|
79
|
+
if (typeof visitFn !== 'function') {
|
|
80
|
+
throw new Error(`'${name}' property of \`visitors\` object is not a function`);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
const isExit = name.endsWith(':exit');
|
|
84
|
+
if (isExit) name = name.slice(0, -5);
|
|
85
|
+
|
|
86
|
+
const typeId = NODE_TYPE_IDS_MAP.get(name);
|
|
87
|
+
if (typeId === void 0) throw new Error(`Unknown node type '${name}' in \`visitors\` object`);
|
|
88
|
+
|
|
89
|
+
if (typeId < LEAF_NODE_TYPES_COUNT) {
|
|
90
|
+
// Leaf node. Store just 1 function.
|
|
91
|
+
const existingVisitFn = visitorsArr[typeId];
|
|
92
|
+
if (existingVisitFn === null) {
|
|
93
|
+
visitorsArr[typeId] = visitFn;
|
|
94
|
+
} else if (isExit) {
|
|
95
|
+
visitorsArr[typeId] = combineVisitFunctions(existingVisitFn, visitFn);
|
|
96
|
+
} else {
|
|
97
|
+
visitorsArr[typeId] = combineVisitFunctions(visitFn, existingVisitFn);
|
|
98
|
+
}
|
|
99
|
+
continue;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
let enterExit = visitorsArr[typeId];
|
|
103
|
+
if (enterExit === null) {
|
|
104
|
+
enterExit = visitorsArr[typeId] = { enter: null, exit: null };
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
if (isExit) {
|
|
108
|
+
enterExit.exit = visitFn;
|
|
109
|
+
} else {
|
|
110
|
+
enterExit.enter = visitFn;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
return visitorsArr;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* Combine 2 visitor functions into 1.
|
|
119
|
+
*
|
|
120
|
+
* @param {function} visit1 - 1st visitor function
|
|
121
|
+
* @param {function} visit2 - 2nd visitor function
|
|
122
|
+
* @returns {function} - Combined visitor function
|
|
123
|
+
*/
|
|
124
|
+
function combineVisitFunctions(visit1, visit2) {
|
|
125
|
+
return function(node) {
|
|
126
|
+
visit1(node);
|
|
127
|
+
visit2(node);
|
|
128
|
+
};
|
|
129
|
+
}
|