astronomical 1.0.0-beta.15 → 1.0.0-beta.16
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/lib/cjs/index.js +1 -1
- package/lib/cjs/nodeutils.js +21 -15
- package/lib/cjs/traverse.js +76 -49
- package/lib/cjs/types/nodeutils.d.ts +2 -0
- package/lib/cjs/types/nodeutils.d.ts.map +1 -1
- package/lib/cjs/types/traverse.d.ts +3 -1
- package/lib/cjs/types/traverse.d.ts.map +1 -1
- package/lib/esm/index.mjs +1 -1
- package/lib/esm/nodeutils.js +21 -15
- package/lib/esm/traverse.js +76 -49
- package/lib/esm/types/nodeutils.d.ts +2 -0
- package/lib/esm/types/nodeutils.d.ts.map +1 -1
- package/lib/esm/types/traverse.d.ts +3 -1
- package/lib/esm/types/traverse.d.ts.map +1 -1
- package/package.json +1 -1
package/lib/cjs/index.js
CHANGED
|
@@ -403,7 +403,7 @@ function createQuerier() {
|
|
|
403
403
|
return results;
|
|
404
404
|
}
|
|
405
405
|
function beginHandle(queries, path) {
|
|
406
|
-
const rootPath = createNodePath(path, undefined, undefined, undefined);
|
|
406
|
+
const rootPath = createNodePath(path, undefined, undefined, undefined, undefined);
|
|
407
407
|
return travHandle(queries, rootPath);
|
|
408
408
|
}
|
|
409
409
|
return {
|
package/lib/cjs/nodeutils.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.isExportSpecifier = exports.isScopable = exports.isScope = exports.VISITOR_KEYS = exports.isBinding = exports.isVariableDeclarator = exports.isFunctionExpression = exports.isFunctionDeclaration = exports.isIdentifier = exports.isMemberExpression = exports.isAssignmentExpression = exports.isPrimitive = exports.isLiteral = exports.isNodePath = exports.isNode = void 0;
|
|
3
|
+
exports.isExportSpecifier = exports.isScopable = exports.isScope = exports.VISITOR_KEYS = exports.isBinding = exports.isVariableDeclaration = exports.isVariableDeclarator = exports.isFunctionExpression = exports.isFunctionDeclaration = exports.isIdentifier = exports.isMemberExpression = exports.isAssignmentExpression = exports.isUpdateExpression = exports.isPrimitive = exports.isLiteral = exports.isNodePath = exports.isNode = void 0;
|
|
4
4
|
function isNode(candidate) {
|
|
5
5
|
return typeof candidate === "object" && candidate != null && "type" in candidate;
|
|
6
6
|
}
|
|
@@ -17,6 +17,10 @@ function isPrimitive(value) {
|
|
|
17
17
|
return typeof value == "string" || typeof value == "number" || typeof value == "boolean";
|
|
18
18
|
}
|
|
19
19
|
exports.isPrimitive = isPrimitive;
|
|
20
|
+
function isUpdateExpression(value) {
|
|
21
|
+
return isNode(value) && value.type === "UpdateExpression";
|
|
22
|
+
}
|
|
23
|
+
exports.isUpdateExpression = isUpdateExpression;
|
|
20
24
|
function isAssignmentExpression(node) {
|
|
21
25
|
return node.type === "AssignmentExpression";
|
|
22
26
|
}
|
|
@@ -41,6 +45,10 @@ function isVariableDeclarator(node) {
|
|
|
41
45
|
return node.type === "VariableDeclarator";
|
|
42
46
|
}
|
|
43
47
|
exports.isVariableDeclarator = isVariableDeclarator;
|
|
48
|
+
function isVariableDeclaration(node) {
|
|
49
|
+
return node.type === "VariableDeclaration";
|
|
50
|
+
}
|
|
51
|
+
exports.isVariableDeclaration = isVariableDeclaration;
|
|
44
52
|
function isBinding(node, parentNode, grandParentNode) {
|
|
45
53
|
if (grandParentNode &&
|
|
46
54
|
node.type === "Identifier" &&
|
|
@@ -49,20 +57,18 @@ function isBinding(node, parentNode, grandParentNode) {
|
|
|
49
57
|
return false;
|
|
50
58
|
}
|
|
51
59
|
const keys = bindingIdentifiersKeys[parentNode.type] ?? [];
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
if (
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
return true;
|
|
65
|
-
}
|
|
60
|
+
for (let i = 0; i < keys.length; i++) {
|
|
61
|
+
const key = keys[i];
|
|
62
|
+
const val =
|
|
63
|
+
// @ts-expect-error key must present in parent
|
|
64
|
+
parentNode[key];
|
|
65
|
+
if (Array.isArray(val)) {
|
|
66
|
+
if (val.indexOf(node) >= 0)
|
|
67
|
+
return true;
|
|
68
|
+
}
|
|
69
|
+
else {
|
|
70
|
+
if (val === node)
|
|
71
|
+
return true;
|
|
66
72
|
}
|
|
67
73
|
}
|
|
68
74
|
return false;
|
package/lib/cjs/traverse.js
CHANGED
|
@@ -13,7 +13,7 @@ const scopes = new Array(100000);
|
|
|
13
13
|
function createTraverser() {
|
|
14
14
|
let scopeIdCounter = 0;
|
|
15
15
|
let removedScopes = 0;
|
|
16
|
-
|
|
16
|
+
const nodePathsCreated = {};
|
|
17
17
|
function createScope(parentScopeId) {
|
|
18
18
|
const id = scopeIdCounter++;
|
|
19
19
|
scopes[id] = parentScopeId ?? -1;
|
|
@@ -55,10 +55,10 @@ function createTraverser() {
|
|
|
55
55
|
if (key in path.node) {
|
|
56
56
|
const r = path.node[key];
|
|
57
57
|
if (Array.isArray(r)) {
|
|
58
|
-
return r.map((n, i) => createNodePath(n, i
|
|
58
|
+
return r.map((n, i) => createNodePath(n, i, key, path.scopeId, path.functionScopeId, path));
|
|
59
59
|
}
|
|
60
60
|
else if (r != undefined) {
|
|
61
|
-
return [createNodePath(r, key, key, path.scopeId, path)];
|
|
61
|
+
return [createNodePath(r, key, key, path.scopeId, path.functionScopeId, path)];
|
|
62
62
|
}
|
|
63
63
|
}
|
|
64
64
|
return [];
|
|
@@ -76,32 +76,43 @@ function createTraverser() {
|
|
|
76
76
|
if (Array.isArray(r)) {
|
|
77
77
|
return r.map((n, i) => (0, nodeutils_1.isPrimitive)(n) ? n :
|
|
78
78
|
// isLiteral(n) ? n.value as PrimitiveValue :
|
|
79
|
-
createNodePath(n, i
|
|
79
|
+
createNodePath(n, i, key, path.scopeId, path.functionScopeId, path));
|
|
80
80
|
}
|
|
81
81
|
else if (r != undefined) {
|
|
82
82
|
return [
|
|
83
83
|
(0, nodeutils_1.isPrimitive)(r) ? r :
|
|
84
84
|
// isLiteral(r) ? r.value as PrimitiveValue :
|
|
85
|
-
createNodePath(r, key, key, path.scopeId, path)
|
|
85
|
+
createNodePath(r, key, key, path.scopeId, path.functionScopeId, path)
|
|
86
86
|
];
|
|
87
87
|
}
|
|
88
88
|
}
|
|
89
89
|
return [];
|
|
90
90
|
}
|
|
91
|
-
function createNodePath(node, key, parentKey, scopeId, nodePath) {
|
|
91
|
+
function createNodePath(node, key, parentKey, scopeId, functionScopeId, nodePath) {
|
|
92
92
|
if (node.extra?.nodePath) {
|
|
93
93
|
const path = node.extra.nodePath;
|
|
94
|
-
path.key
|
|
95
|
-
|
|
96
|
-
|
|
94
|
+
if (nodePath && (0, nodeutils_1.isExportSpecifier)(nodePath.node) && key == "exported" && path.key == "local") {
|
|
95
|
+
//Special handling for "export { someName }" as id is both local and exported
|
|
96
|
+
path.key = "exported";
|
|
97
|
+
path.parentPath = nodePath;
|
|
98
|
+
return path;
|
|
99
|
+
}
|
|
100
|
+
if (key != undefined)
|
|
101
|
+
path.key = typeof (key) == "number" ? key.toString() : key;
|
|
102
|
+
if (parentKey != undefined)
|
|
103
|
+
path.parentKey = parentKey;
|
|
104
|
+
if (nodePath != undefined)
|
|
105
|
+
path.parentPath = nodePath;
|
|
97
106
|
return path;
|
|
98
107
|
}
|
|
99
|
-
const finalScope = ((node.extra && node.extra
|
|
108
|
+
const finalScope = ((node.extra && node.extra.scopeId != undefined) ? node.extra.scopeId : scopeId) ?? createScope();
|
|
109
|
+
const finalFScope = ((node.extra && node.extra.functionScopeId != undefined) ? node.extra.functionScopeId : functionScopeId) ?? finalScope;
|
|
100
110
|
const path = {
|
|
101
111
|
node,
|
|
102
112
|
scopeId: finalScope,
|
|
113
|
+
functionScopeId: finalFScope,
|
|
103
114
|
parentPath: nodePath,
|
|
104
|
-
key,
|
|
115
|
+
key: typeof (key) == "number" ? key.toString() : key,
|
|
105
116
|
parentKey
|
|
106
117
|
};
|
|
107
118
|
if ((0, nodeutils_1.isNode)(node)) {
|
|
@@ -109,59 +120,74 @@ function createTraverser() {
|
|
|
109
120
|
node.extra.nodePath = path;
|
|
110
121
|
Object.defineProperty(node.extra, "nodePath", { enumerable: false });
|
|
111
122
|
}
|
|
112
|
-
|
|
113
|
-
if (x == undefined) {
|
|
114
|
-
console.log("x", node, key, parentKey, nodePath?.node?.type);
|
|
115
|
-
}*/
|
|
116
|
-
//nodePathsCreated[node.type] = (nodePathsCreated[node.type] ?? 0) + 1;
|
|
123
|
+
nodePathsCreated[node.type] = (nodePathsCreated[node.type] ?? 0) + 1;
|
|
117
124
|
pathsCreated++;
|
|
118
125
|
return path;
|
|
119
126
|
}
|
|
120
|
-
function registerBinding(
|
|
127
|
+
function registerBinding(stack, scopeId, functionScopeId, key, parentKey) {
|
|
121
128
|
//console.log("x registerBinding?", isIdentifier(node) ? node.name : node.type, parentNode.type, grandParentNode?.type, scopeId, isBinding(node, parentNode, grandParentNode));
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
129
|
+
const node = stack[stack.length - 1];
|
|
130
|
+
if (!(0, nodeutils_1.isIdentifier)(node))
|
|
131
|
+
return;
|
|
132
|
+
const parentNode = stack[stack.length - 2];
|
|
133
|
+
if ((0, nodeutils_1.isAssignmentExpression)(parentNode) || (0, nodeutils_1.isMemberExpression)(parentNode) || (0, nodeutils_1.isUpdateExpression)(parentNode) || (0, nodeutils_1.isExportSpecifier)(parentNode))
|
|
134
|
+
return;
|
|
135
|
+
const grandParentNode = stack[stack.length - 3];
|
|
136
|
+
if (!(0, nodeutils_1.isBinding)(node, parentNode, grandParentNode))
|
|
137
|
+
return;
|
|
138
|
+
if (key == "id" && !(0, nodeutils_1.isVariableDeclarator)(parentNode)) {
|
|
139
|
+
setBinding(functionScopeId, node.name, { path: createNodePath(node, undefined, undefined, scopeId, functionScopeId) });
|
|
140
|
+
return;
|
|
141
|
+
}
|
|
142
|
+
if ((0, nodeutils_1.isVariableDeclarator)(parentNode) && (0, nodeutils_1.isVariableDeclaration)(grandParentNode)) {
|
|
143
|
+
if (grandParentNode.kind == "var") {
|
|
144
|
+
setBinding(functionScopeId, node.name, { path: createNodePath(parentNode, undefined, undefined, scopeId, functionScopeId) });
|
|
145
|
+
return;
|
|
146
|
+
}
|
|
147
|
+
else {
|
|
148
|
+
setBinding(scopeId, node.name, { path: createNodePath(parentNode, undefined, undefined, scopeId, functionScopeId) });
|
|
149
|
+
return;
|
|
132
150
|
}
|
|
133
151
|
}
|
|
152
|
+
if ((0, nodeutils_1.isScope)(node, parentNode)) {
|
|
153
|
+
setBinding(scopeId, node.name, { path: createNodePath(node, key, parentKey, scopeId, functionScopeId) });
|
|
154
|
+
} /*else {
|
|
155
|
+
console.log(node.type, parentNode.type, grandParentNode?.type);
|
|
156
|
+
}*/
|
|
134
157
|
}
|
|
135
158
|
let bindingNodesVisited = 0;
|
|
136
|
-
function registerBindings(
|
|
159
|
+
function registerBindings(stack, scopeId, functionScopeId) {
|
|
160
|
+
const node = stack[stack.length - 1];
|
|
137
161
|
if (!(0, nodeutils_1.isNode)(node))
|
|
138
162
|
return;
|
|
139
|
-
|
|
140
|
-
if (node.extra["scopeId"] != undefined)
|
|
163
|
+
if (node.extra?.scopeId != undefined)
|
|
141
164
|
return;
|
|
142
|
-
node.extra
|
|
165
|
+
node.extra = node.extra ?? {};
|
|
166
|
+
node.extra.scopeId = scopeId;
|
|
143
167
|
bindingNodesVisited++;
|
|
144
|
-
;
|
|
145
168
|
const keys = nodeutils_1.VISITOR_KEYS[node.type];
|
|
146
|
-
//console.log(keys, node);
|
|
147
169
|
if (keys.length == 0)
|
|
148
170
|
return;
|
|
149
171
|
let childScopeId = scopeId;
|
|
150
|
-
// This is also buggy. Need to investigate what creates a new scope
|
|
151
172
|
if ((0, nodeutils_1.isScopable)(node)) {
|
|
152
173
|
childScopeId = createScope(scopeId);
|
|
153
174
|
}
|
|
154
175
|
for (const key of keys) {
|
|
155
176
|
const childNodes = node[key];
|
|
156
177
|
const children = (0, utils_1.toArray)(childNodes).filter(utils_1.isDefined);
|
|
157
|
-
children.forEach((child) => {
|
|
158
|
-
if ((0, nodeutils_1.isNode)(child))
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
178
|
+
children.forEach((child, i) => {
|
|
179
|
+
if (!(0, nodeutils_1.isNode)(child))
|
|
180
|
+
return;
|
|
181
|
+
const f = key == "body" && ((0, nodeutils_1.isFunctionDeclaration)(node) || (0, nodeutils_1.isFunctionExpression)(node)) ? childScopeId : functionScopeId;
|
|
182
|
+
stack.push(child);
|
|
183
|
+
if ((0, nodeutils_1.isIdentifier)(child)) {
|
|
184
|
+
const k = Array.isArray(childNodes) ? i : key;
|
|
185
|
+
registerBinding(stack, childScopeId, f, k, key);
|
|
186
|
+
}
|
|
187
|
+
else {
|
|
188
|
+
registerBindings(stack, childScopeId, f);
|
|
164
189
|
}
|
|
190
|
+
stack.pop();
|
|
165
191
|
});
|
|
166
192
|
}
|
|
167
193
|
if (childScopeId != scopeId && typeof scopes[childScopeId] == "number") { // Scope has not been populated
|
|
@@ -169,35 +195,36 @@ function createTraverser() {
|
|
|
169
195
|
removedScopes++;
|
|
170
196
|
}
|
|
171
197
|
}
|
|
172
|
-
function traverseInner(node, visitor, scopeId, state, path) {
|
|
173
|
-
const nodePath = path ?? createNodePath(node, undefined, undefined, scopeId);
|
|
198
|
+
function traverseInner(node, visitor, scopeId, functionScopeId, state, path) {
|
|
199
|
+
const nodePath = path ?? createNodePath(node, undefined, undefined, scopeId, functionScopeId);
|
|
174
200
|
const keys = nodeutils_1.VISITOR_KEYS[node.type] ?? [];
|
|
175
201
|
if (nodePath.parentPath)
|
|
176
|
-
registerBindings(nodePath.node, nodePath.parentPath.node, nodePath.
|
|
202
|
+
registerBindings([nodePath.parentPath.parentPath?.node, nodePath.parentPath.node, nodePath.node].filter(utils_1.isDefined), nodePath.scopeId, nodePath.functionScopeId);
|
|
177
203
|
for (const key of keys) {
|
|
178
204
|
const childNodes = node[key];
|
|
179
205
|
const children = Array.isArray(childNodes) ? childNodes : childNodes ? [childNodes] : [];
|
|
180
206
|
const nodePaths = children.map((child, i) => {
|
|
181
207
|
if ((0, nodeutils_1.isNode)(child)) {
|
|
182
|
-
return createNodePath(child,
|
|
208
|
+
return createNodePath(child, Array.isArray(childNodes) ? i : key, key, nodePath.scopeId, nodePath.functionScopeId, nodePath);
|
|
183
209
|
}
|
|
184
210
|
return undefined;
|
|
185
211
|
}).filter(x => x != undefined);
|
|
186
212
|
nodePaths.forEach((childPath) => {
|
|
187
213
|
visitor.enter(childPath, state);
|
|
188
|
-
traverseInner(childPath.node, visitor, nodePath.scopeId, state, childPath);
|
|
214
|
+
traverseInner(childPath.node, visitor, nodePath.scopeId, nodePath.functionScopeId, state, childPath);
|
|
189
215
|
visitor.exit(childPath, state);
|
|
190
216
|
});
|
|
191
217
|
}
|
|
192
218
|
}
|
|
193
219
|
const sOut = [];
|
|
194
220
|
function traverse(node, visitor, scopeId, state, path) {
|
|
195
|
-
|
|
221
|
+
const fscope = path?.functionScopeId ?? node.extra?.functionScopeId ?? scopeId;
|
|
222
|
+
traverseInner(node, visitor, scopeId, fscope, state, path);
|
|
196
223
|
if (!sOut.includes(scopeIdCounter)) {
|
|
197
224
|
log.debug("Scopes created", scopeIdCounter, " Scopes removed", removedScopes, "Paths created", pathsCreated, bindingNodesVisited);
|
|
198
225
|
sOut.push(scopeIdCounter);
|
|
199
|
-
|
|
200
|
-
|
|
226
|
+
const k = Object.fromEntries(Object.entries(nodePathsCreated).sort((a, b) => a[1] - b[1]));
|
|
227
|
+
log.debug("Node paths created", k);
|
|
201
228
|
}
|
|
202
229
|
}
|
|
203
230
|
return {
|
|
@@ -5,12 +5,14 @@ export declare function isNode(candidate: unknown): candidate is ASTNode;
|
|
|
5
5
|
export declare function isNodePath(candidate: unknown): candidate is NodePath;
|
|
6
6
|
export declare function isLiteral(candidate: unknown): candidate is ESTree.Literal;
|
|
7
7
|
export declare function isPrimitive(value: unknown): value is PrimitiveValue;
|
|
8
|
+
export declare function isUpdateExpression(value: unknown): value is ESTree.UpdateExpression;
|
|
8
9
|
export declare function isAssignmentExpression(node: ESTree.Node): node is ESTree.AssignmentExpression;
|
|
9
10
|
export declare function isMemberExpression(node: ESTree.Node): node is ESTree.MemberExpression;
|
|
10
11
|
export declare function isIdentifier(node: ESTree.Node): node is ESTree.Identifier;
|
|
11
12
|
export declare function isFunctionDeclaration(node: ESTree.Node): node is ESTree.FunctionDeclaration;
|
|
12
13
|
export declare function isFunctionExpression(node: ESTree.Node): node is ESTree.FunctionExpression;
|
|
13
14
|
export declare function isVariableDeclarator(node: ESTree.Node): node is ESTree.VariableDeclarator;
|
|
15
|
+
export declare function isVariableDeclaration(node: ESTree.Node): node is ESTree.VariableDeclaration;
|
|
14
16
|
export declare function isBinding(node: ESTree.Node, parentNode: ESTree.Node, grandParentNode: ESTree.Node | undefined): boolean;
|
|
15
17
|
export declare const VISITOR_KEYS: Record<ESTree.Node["type"], string[]>;
|
|
16
18
|
export declare function isScope(node: ESTree.Node, parentNode: ESTree.Node): boolean;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"nodeutils.d.ts","sourceRoot":"","sources":["../../../src/nodeutils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACjC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAC/C,OAAO,EAAE,cAAc,EAAE,MAAM,GAAG,CAAC;AAEnC,wBAAgB,MAAM,CAAC,SAAS,EAAE,OAAO,GAAI,SAAS,IAAI,OAAO,CAEhE;AAED,wBAAgB,UAAU,CAAC,SAAS,EAAE,OAAO,GAAI,SAAS,IAAI,QAAQ,CAErE;AAED,wBAAgB,SAAS,CAAC,SAAS,EAAE,OAAO,GAAI,SAAS,IAAI,MAAM,CAAC,OAAO,CAE1E;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,OAAO,GAAI,KAAK,IAAI,cAAc,CAEpE;AAED,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,GAAG,IAAI,IAAI,MAAM,CAAC,oBAAoB,CAE7F;AAED,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,GAAG,IAAI,IAAI,MAAM,CAAC,gBAAgB,CAErF;AAED,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,GAAG,IAAI,IAAI,MAAM,CAAC,UAAU,CAEzE;AAED,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,GAAG,IAAI,IAAI,MAAM,CAAC,mBAAmB,CAE3F;AACD,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,GAAG,IAAI,IAAI,MAAM,CAAC,kBAAkB,CAEzF;AAED,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,GAAG,IAAI,IAAI,MAAM,CAAC,kBAAkB,CAEzF;
|
|
1
|
+
{"version":3,"file":"nodeutils.d.ts","sourceRoot":"","sources":["../../../src/nodeutils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACjC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAC/C,OAAO,EAAE,cAAc,EAAE,MAAM,GAAG,CAAC;AAEnC,wBAAgB,MAAM,CAAC,SAAS,EAAE,OAAO,GAAI,SAAS,IAAI,OAAO,CAEhE;AAED,wBAAgB,UAAU,CAAC,SAAS,EAAE,OAAO,GAAI,SAAS,IAAI,QAAQ,CAErE;AAED,wBAAgB,SAAS,CAAC,SAAS,EAAE,OAAO,GAAI,SAAS,IAAI,MAAM,CAAC,OAAO,CAE1E;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,OAAO,GAAI,KAAK,IAAI,cAAc,CAEpE;AAED,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,OAAO,GAAI,KAAK,IAAI,MAAM,CAAC,gBAAgB,CAEpF;AAED,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,GAAG,IAAI,IAAI,MAAM,CAAC,oBAAoB,CAE7F;AAED,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,GAAG,IAAI,IAAI,MAAM,CAAC,gBAAgB,CAErF;AAED,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,GAAG,IAAI,IAAI,MAAM,CAAC,UAAU,CAEzE;AAED,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,GAAG,IAAI,IAAI,MAAM,CAAC,mBAAmB,CAE3F;AACD,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,GAAG,IAAI,IAAI,MAAM,CAAC,kBAAkB,CAEzF;AAED,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,GAAG,IAAI,IAAI,MAAM,CAAC,kBAAkB,CAEzF;AACD,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,GAAG,IAAI,IAAI,MAAM,CAAC,mBAAmB,CAE3F;AACD,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,UAAU,EAAE,MAAM,CAAC,IAAI,EAAE,eAAe,EAAE,MAAM,CAAC,IAAI,GAAG,SAAS,GAAG,OAAO,CAwBvH;AAuDD,eAAO,MAAM,YAAY,EAAE,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,CA0F9D,CAAC;AAqBF,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,UAAU,EAAE,MAAM,CAAC,IAAI,GAAG,OAAO,CAS3E;AAED,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,GAAG,OAAO,CAqBrD;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,GAAG,IAAI,IAAI,MAAM,CAAC,eAAe,CAEnF"}
|
|
@@ -11,6 +11,7 @@ export type Scope = {
|
|
|
11
11
|
export type ASTNode = ESTree.Node & {
|
|
12
12
|
extra?: {
|
|
13
13
|
scopeId?: number;
|
|
14
|
+
functionScopeId?: number;
|
|
14
15
|
nodePath?: NodePath;
|
|
15
16
|
};
|
|
16
17
|
};
|
|
@@ -20,6 +21,7 @@ export type NodePath = {
|
|
|
20
21
|
parentPath?: NodePath;
|
|
21
22
|
parentKey?: string;
|
|
22
23
|
scopeId: number;
|
|
24
|
+
functionScopeId: number;
|
|
23
25
|
};
|
|
24
26
|
type Visitor<T> = {
|
|
25
27
|
enter: (path: NodePath, state: T) => void;
|
|
@@ -27,7 +29,7 @@ type Visitor<T> = {
|
|
|
27
29
|
};
|
|
28
30
|
export default function createTraverser(): {
|
|
29
31
|
traverse: <T>(node: ASTNode, visitor: Visitor<T>, scopeId: number | undefined, state: T, path?: NodePath) => void;
|
|
30
|
-
createNodePath: (node: ASTNode, key: string | undefined, parentKey: string | undefined, scopeId: number | undefined, nodePath?: NodePath) => NodePath;
|
|
32
|
+
createNodePath: (node: ASTNode, key: string | undefined | number, parentKey: string | undefined, scopeId: number | undefined, functionScopeId: number | undefined, nodePath?: NodePath) => NodePath;
|
|
31
33
|
getChildren: (key: string, path: NodePath) => NodePath[];
|
|
32
34
|
getPrimitiveChildren: (key: string, path: NodePath) => PrimitiveValue[];
|
|
33
35
|
getPrimitiveChildrenOrNodePaths: (key: string, path: NodePath) => Array<PrimitiveValue | NodePath>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"traverse.d.ts","sourceRoot":"","sources":["../../../src/traverse.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAEjC,OAAO,EAAE,cAAc,EAAE,MAAM,GAAG,CAAC;AASnC,MAAM,MAAM,OAAO,GAAG;IACpB,IAAI,EAAE,QAAQ,CAAC;CAChB,CAAA;AAED,MAAM,MAAM,KAAK,GAAG;IAClB,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAClC,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,EAAE,EAAE,MAAM,CAAC;CACZ,CAAC;AAIF,MAAM,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,GAAG;IAClC,KAAK,CAAC,EAAE;QACN,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,QAAQ,CAAC,EAAE,QAAQ,CAAC;KACrB,CAAA;CACF,CAAC;AAEF,MAAM,MAAM,QAAQ,GAAG;IACrB,IAAI,EAAE,OAAO,CAAC;IACd,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,UAAU,CAAC,EAAE,QAAQ,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"traverse.d.ts","sourceRoot":"","sources":["../../../src/traverse.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAEjC,OAAO,EAAE,cAAc,EAAE,MAAM,GAAG,CAAC;AASnC,MAAM,MAAM,OAAO,GAAG;IACpB,IAAI,EAAE,QAAQ,CAAC;CAChB,CAAA;AAED,MAAM,MAAM,KAAK,GAAG;IAClB,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAClC,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,EAAE,EAAE,MAAM,CAAC;CACZ,CAAC;AAIF,MAAM,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,GAAG;IAClC,KAAK,CAAC,EAAE;QACN,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,eAAe,CAAC,EAAE,MAAM,CAAC;QACzB,QAAQ,CAAC,EAAE,QAAQ,CAAC;KACrB,CAAA;CACF,CAAC;AAEF,MAAM,MAAM,QAAQ,GAAG;IACrB,IAAI,EAAE,OAAO,CAAC;IACd,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,UAAU,CAAC,EAAE,QAAQ,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,eAAe,EAAE,MAAM,CAAC;CACzB,CAAC;AAEF,KAAK,OAAO,CAAC,CAAC,IAAI;IAChB,KAAK,EAAE,CAAC,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,KAAK,IAAI,CAAC;IAC1C,IAAI,EAAE,CAAC,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,KAAK,IAAI,CAAC;CAC1C,CAAA;AAED,MAAM,CAAC,OAAO,UAAU,eAAe;wBA4NR,OAAO,gCAEzB,MAAM,GAAG,SAAS,mBAEpB,QAAQ;2BAhJa,OAAO,OAAO,MAAM,GAAG,SAAS,GAAG,MAAM,aAAa,MAAM,GAAG,SAAS,WAAW,MAAM,GAAG,SAAS,mBAAmB,MAAM,GAAG,SAAS,aAAa,QAAQ,KAAI,QAAQ;uBAtC/K,MAAM,QAAQ,QAAQ,KAAI,QAAQ,EAAE;gCAW3B,MAAM,QAAQ,QAAQ,KAAI,cAAc,EAAE;2CAO/B,MAAM,QAAQ,QAAQ,KAAI,MAAM,cAAc,GAAG,QAAQ,CAAC;0BAjD3E,MAAM,QAAQ,MAAM;EAyOlD"}
|
package/lib/esm/index.mjs
CHANGED
|
@@ -403,7 +403,7 @@ function createQuerier() {
|
|
|
403
403
|
return results;
|
|
404
404
|
}
|
|
405
405
|
function beginHandle(queries, path) {
|
|
406
|
-
const rootPath = createNodePath(path, undefined, undefined, undefined);
|
|
406
|
+
const rootPath = createNodePath(path, undefined, undefined, undefined, undefined);
|
|
407
407
|
return travHandle(queries, rootPath);
|
|
408
408
|
}
|
|
409
409
|
return {
|
package/lib/esm/nodeutils.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.isExportSpecifier = exports.isScopable = exports.isScope = exports.VISITOR_KEYS = exports.isBinding = exports.isVariableDeclarator = exports.isFunctionExpression = exports.isFunctionDeclaration = exports.isIdentifier = exports.isMemberExpression = exports.isAssignmentExpression = exports.isPrimitive = exports.isLiteral = exports.isNodePath = exports.isNode = void 0;
|
|
3
|
+
exports.isExportSpecifier = exports.isScopable = exports.isScope = exports.VISITOR_KEYS = exports.isBinding = exports.isVariableDeclaration = exports.isVariableDeclarator = exports.isFunctionExpression = exports.isFunctionDeclaration = exports.isIdentifier = exports.isMemberExpression = exports.isAssignmentExpression = exports.isUpdateExpression = exports.isPrimitive = exports.isLiteral = exports.isNodePath = exports.isNode = void 0;
|
|
4
4
|
function isNode(candidate) {
|
|
5
5
|
return typeof candidate === "object" && candidate != null && "type" in candidate;
|
|
6
6
|
}
|
|
@@ -17,6 +17,10 @@ function isPrimitive(value) {
|
|
|
17
17
|
return typeof value == "string" || typeof value == "number" || typeof value == "boolean";
|
|
18
18
|
}
|
|
19
19
|
exports.isPrimitive = isPrimitive;
|
|
20
|
+
function isUpdateExpression(value) {
|
|
21
|
+
return isNode(value) && value.type === "UpdateExpression";
|
|
22
|
+
}
|
|
23
|
+
exports.isUpdateExpression = isUpdateExpression;
|
|
20
24
|
function isAssignmentExpression(node) {
|
|
21
25
|
return node.type === "AssignmentExpression";
|
|
22
26
|
}
|
|
@@ -41,6 +45,10 @@ function isVariableDeclarator(node) {
|
|
|
41
45
|
return node.type === "VariableDeclarator";
|
|
42
46
|
}
|
|
43
47
|
exports.isVariableDeclarator = isVariableDeclarator;
|
|
48
|
+
function isVariableDeclaration(node) {
|
|
49
|
+
return node.type === "VariableDeclaration";
|
|
50
|
+
}
|
|
51
|
+
exports.isVariableDeclaration = isVariableDeclaration;
|
|
44
52
|
function isBinding(node, parentNode, grandParentNode) {
|
|
45
53
|
if (grandParentNode &&
|
|
46
54
|
node.type === "Identifier" &&
|
|
@@ -49,20 +57,18 @@ function isBinding(node, parentNode, grandParentNode) {
|
|
|
49
57
|
return false;
|
|
50
58
|
}
|
|
51
59
|
const keys = bindingIdentifiersKeys[parentNode.type] ?? [];
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
if (
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
return true;
|
|
65
|
-
}
|
|
60
|
+
for (let i = 0; i < keys.length; i++) {
|
|
61
|
+
const key = keys[i];
|
|
62
|
+
const val =
|
|
63
|
+
// @ts-expect-error key must present in parent
|
|
64
|
+
parentNode[key];
|
|
65
|
+
if (Array.isArray(val)) {
|
|
66
|
+
if (val.indexOf(node) >= 0)
|
|
67
|
+
return true;
|
|
68
|
+
}
|
|
69
|
+
else {
|
|
70
|
+
if (val === node)
|
|
71
|
+
return true;
|
|
66
72
|
}
|
|
67
73
|
}
|
|
68
74
|
return false;
|
package/lib/esm/traverse.js
CHANGED
|
@@ -13,7 +13,7 @@ const scopes = new Array(100000);
|
|
|
13
13
|
function createTraverser() {
|
|
14
14
|
let scopeIdCounter = 0;
|
|
15
15
|
let removedScopes = 0;
|
|
16
|
-
|
|
16
|
+
const nodePathsCreated = {};
|
|
17
17
|
function createScope(parentScopeId) {
|
|
18
18
|
const id = scopeIdCounter++;
|
|
19
19
|
scopes[id] = parentScopeId ?? -1;
|
|
@@ -55,10 +55,10 @@ function createTraverser() {
|
|
|
55
55
|
if (key in path.node) {
|
|
56
56
|
const r = path.node[key];
|
|
57
57
|
if (Array.isArray(r)) {
|
|
58
|
-
return r.map((n, i) => createNodePath(n, i
|
|
58
|
+
return r.map((n, i) => createNodePath(n, i, key, path.scopeId, path.functionScopeId, path));
|
|
59
59
|
}
|
|
60
60
|
else if (r != undefined) {
|
|
61
|
-
return [createNodePath(r, key, key, path.scopeId, path)];
|
|
61
|
+
return [createNodePath(r, key, key, path.scopeId, path.functionScopeId, path)];
|
|
62
62
|
}
|
|
63
63
|
}
|
|
64
64
|
return [];
|
|
@@ -76,32 +76,43 @@ function createTraverser() {
|
|
|
76
76
|
if (Array.isArray(r)) {
|
|
77
77
|
return r.map((n, i) => (0, nodeutils_1.isPrimitive)(n) ? n :
|
|
78
78
|
// isLiteral(n) ? n.value as PrimitiveValue :
|
|
79
|
-
createNodePath(n, i
|
|
79
|
+
createNodePath(n, i, key, path.scopeId, path.functionScopeId, path));
|
|
80
80
|
}
|
|
81
81
|
else if (r != undefined) {
|
|
82
82
|
return [
|
|
83
83
|
(0, nodeutils_1.isPrimitive)(r) ? r :
|
|
84
84
|
// isLiteral(r) ? r.value as PrimitiveValue :
|
|
85
|
-
createNodePath(r, key, key, path.scopeId, path)
|
|
85
|
+
createNodePath(r, key, key, path.scopeId, path.functionScopeId, path)
|
|
86
86
|
];
|
|
87
87
|
}
|
|
88
88
|
}
|
|
89
89
|
return [];
|
|
90
90
|
}
|
|
91
|
-
function createNodePath(node, key, parentKey, scopeId, nodePath) {
|
|
91
|
+
function createNodePath(node, key, parentKey, scopeId, functionScopeId, nodePath) {
|
|
92
92
|
if (node.extra?.nodePath) {
|
|
93
93
|
const path = node.extra.nodePath;
|
|
94
|
-
path.key
|
|
95
|
-
|
|
96
|
-
|
|
94
|
+
if (nodePath && (0, nodeutils_1.isExportSpecifier)(nodePath.node) && key == "exported" && path.key == "local") {
|
|
95
|
+
//Special handling for "export { someName }" as id is both local and exported
|
|
96
|
+
path.key = "exported";
|
|
97
|
+
path.parentPath = nodePath;
|
|
98
|
+
return path;
|
|
99
|
+
}
|
|
100
|
+
if (key != undefined)
|
|
101
|
+
path.key = typeof (key) == "number" ? key.toString() : key;
|
|
102
|
+
if (parentKey != undefined)
|
|
103
|
+
path.parentKey = parentKey;
|
|
104
|
+
if (nodePath != undefined)
|
|
105
|
+
path.parentPath = nodePath;
|
|
97
106
|
return path;
|
|
98
107
|
}
|
|
99
|
-
const finalScope = ((node.extra && node.extra
|
|
108
|
+
const finalScope = ((node.extra && node.extra.scopeId != undefined) ? node.extra.scopeId : scopeId) ?? createScope();
|
|
109
|
+
const finalFScope = ((node.extra && node.extra.functionScopeId != undefined) ? node.extra.functionScopeId : functionScopeId) ?? finalScope;
|
|
100
110
|
const path = {
|
|
101
111
|
node,
|
|
102
112
|
scopeId: finalScope,
|
|
113
|
+
functionScopeId: finalFScope,
|
|
103
114
|
parentPath: nodePath,
|
|
104
|
-
key,
|
|
115
|
+
key: typeof (key) == "number" ? key.toString() : key,
|
|
105
116
|
parentKey
|
|
106
117
|
};
|
|
107
118
|
if ((0, nodeutils_1.isNode)(node)) {
|
|
@@ -109,59 +120,74 @@ function createTraverser() {
|
|
|
109
120
|
node.extra.nodePath = path;
|
|
110
121
|
Object.defineProperty(node.extra, "nodePath", { enumerable: false });
|
|
111
122
|
}
|
|
112
|
-
|
|
113
|
-
if (x == undefined) {
|
|
114
|
-
console.log("x", node, key, parentKey, nodePath?.node?.type);
|
|
115
|
-
}*/
|
|
116
|
-
//nodePathsCreated[node.type] = (nodePathsCreated[node.type] ?? 0) + 1;
|
|
123
|
+
nodePathsCreated[node.type] = (nodePathsCreated[node.type] ?? 0) + 1;
|
|
117
124
|
pathsCreated++;
|
|
118
125
|
return path;
|
|
119
126
|
}
|
|
120
|
-
function registerBinding(
|
|
127
|
+
function registerBinding(stack, scopeId, functionScopeId, key, parentKey) {
|
|
121
128
|
//console.log("x registerBinding?", isIdentifier(node) ? node.name : node.type, parentNode.type, grandParentNode?.type, scopeId, isBinding(node, parentNode, grandParentNode));
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
129
|
+
const node = stack[stack.length - 1];
|
|
130
|
+
if (!(0, nodeutils_1.isIdentifier)(node))
|
|
131
|
+
return;
|
|
132
|
+
const parentNode = stack[stack.length - 2];
|
|
133
|
+
if ((0, nodeutils_1.isAssignmentExpression)(parentNode) || (0, nodeutils_1.isMemberExpression)(parentNode) || (0, nodeutils_1.isUpdateExpression)(parentNode) || (0, nodeutils_1.isExportSpecifier)(parentNode))
|
|
134
|
+
return;
|
|
135
|
+
const grandParentNode = stack[stack.length - 3];
|
|
136
|
+
if (!(0, nodeutils_1.isBinding)(node, parentNode, grandParentNode))
|
|
137
|
+
return;
|
|
138
|
+
if (key == "id" && !(0, nodeutils_1.isVariableDeclarator)(parentNode)) {
|
|
139
|
+
setBinding(functionScopeId, node.name, { path: createNodePath(node, undefined, undefined, scopeId, functionScopeId) });
|
|
140
|
+
return;
|
|
141
|
+
}
|
|
142
|
+
if ((0, nodeutils_1.isVariableDeclarator)(parentNode) && (0, nodeutils_1.isVariableDeclaration)(grandParentNode)) {
|
|
143
|
+
if (grandParentNode.kind == "var") {
|
|
144
|
+
setBinding(functionScopeId, node.name, { path: createNodePath(parentNode, undefined, undefined, scopeId, functionScopeId) });
|
|
145
|
+
return;
|
|
146
|
+
}
|
|
147
|
+
else {
|
|
148
|
+
setBinding(scopeId, node.name, { path: createNodePath(parentNode, undefined, undefined, scopeId, functionScopeId) });
|
|
149
|
+
return;
|
|
132
150
|
}
|
|
133
151
|
}
|
|
152
|
+
if ((0, nodeutils_1.isScope)(node, parentNode)) {
|
|
153
|
+
setBinding(scopeId, node.name, { path: createNodePath(node, key, parentKey, scopeId, functionScopeId) });
|
|
154
|
+
} /*else {
|
|
155
|
+
console.log(node.type, parentNode.type, grandParentNode?.type);
|
|
156
|
+
}*/
|
|
134
157
|
}
|
|
135
158
|
let bindingNodesVisited = 0;
|
|
136
|
-
function registerBindings(
|
|
159
|
+
function registerBindings(stack, scopeId, functionScopeId) {
|
|
160
|
+
const node = stack[stack.length - 1];
|
|
137
161
|
if (!(0, nodeutils_1.isNode)(node))
|
|
138
162
|
return;
|
|
139
|
-
|
|
140
|
-
if (node.extra["scopeId"] != undefined)
|
|
163
|
+
if (node.extra?.scopeId != undefined)
|
|
141
164
|
return;
|
|
142
|
-
node.extra
|
|
165
|
+
node.extra = node.extra ?? {};
|
|
166
|
+
node.extra.scopeId = scopeId;
|
|
143
167
|
bindingNodesVisited++;
|
|
144
|
-
;
|
|
145
168
|
const keys = nodeutils_1.VISITOR_KEYS[node.type];
|
|
146
|
-
//console.log(keys, node);
|
|
147
169
|
if (keys.length == 0)
|
|
148
170
|
return;
|
|
149
171
|
let childScopeId = scopeId;
|
|
150
|
-
// This is also buggy. Need to investigate what creates a new scope
|
|
151
172
|
if ((0, nodeutils_1.isScopable)(node)) {
|
|
152
173
|
childScopeId = createScope(scopeId);
|
|
153
174
|
}
|
|
154
175
|
for (const key of keys) {
|
|
155
176
|
const childNodes = node[key];
|
|
156
177
|
const children = (0, utils_1.toArray)(childNodes).filter(utils_1.isDefined);
|
|
157
|
-
children.forEach((child) => {
|
|
158
|
-
if ((0, nodeutils_1.isNode)(child))
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
178
|
+
children.forEach((child, i) => {
|
|
179
|
+
if (!(0, nodeutils_1.isNode)(child))
|
|
180
|
+
return;
|
|
181
|
+
const f = key == "body" && ((0, nodeutils_1.isFunctionDeclaration)(node) || (0, nodeutils_1.isFunctionExpression)(node)) ? childScopeId : functionScopeId;
|
|
182
|
+
stack.push(child);
|
|
183
|
+
if ((0, nodeutils_1.isIdentifier)(child)) {
|
|
184
|
+
const k = Array.isArray(childNodes) ? i : key;
|
|
185
|
+
registerBinding(stack, childScopeId, f, k, key);
|
|
186
|
+
}
|
|
187
|
+
else {
|
|
188
|
+
registerBindings(stack, childScopeId, f);
|
|
164
189
|
}
|
|
190
|
+
stack.pop();
|
|
165
191
|
});
|
|
166
192
|
}
|
|
167
193
|
if (childScopeId != scopeId && typeof scopes[childScopeId] == "number") { // Scope has not been populated
|
|
@@ -169,35 +195,36 @@ function createTraverser() {
|
|
|
169
195
|
removedScopes++;
|
|
170
196
|
}
|
|
171
197
|
}
|
|
172
|
-
function traverseInner(node, visitor, scopeId, state, path) {
|
|
173
|
-
const nodePath = path ?? createNodePath(node, undefined, undefined, scopeId);
|
|
198
|
+
function traverseInner(node, visitor, scopeId, functionScopeId, state, path) {
|
|
199
|
+
const nodePath = path ?? createNodePath(node, undefined, undefined, scopeId, functionScopeId);
|
|
174
200
|
const keys = nodeutils_1.VISITOR_KEYS[node.type] ?? [];
|
|
175
201
|
if (nodePath.parentPath)
|
|
176
|
-
registerBindings(nodePath.node, nodePath.parentPath.node, nodePath.
|
|
202
|
+
registerBindings([nodePath.parentPath.parentPath?.node, nodePath.parentPath.node, nodePath.node].filter(utils_1.isDefined), nodePath.scopeId, nodePath.functionScopeId);
|
|
177
203
|
for (const key of keys) {
|
|
178
204
|
const childNodes = node[key];
|
|
179
205
|
const children = Array.isArray(childNodes) ? childNodes : childNodes ? [childNodes] : [];
|
|
180
206
|
const nodePaths = children.map((child, i) => {
|
|
181
207
|
if ((0, nodeutils_1.isNode)(child)) {
|
|
182
|
-
return createNodePath(child,
|
|
208
|
+
return createNodePath(child, Array.isArray(childNodes) ? i : key, key, nodePath.scopeId, nodePath.functionScopeId, nodePath);
|
|
183
209
|
}
|
|
184
210
|
return undefined;
|
|
185
211
|
}).filter(x => x != undefined);
|
|
186
212
|
nodePaths.forEach((childPath) => {
|
|
187
213
|
visitor.enter(childPath, state);
|
|
188
|
-
traverseInner(childPath.node, visitor, nodePath.scopeId, state, childPath);
|
|
214
|
+
traverseInner(childPath.node, visitor, nodePath.scopeId, nodePath.functionScopeId, state, childPath);
|
|
189
215
|
visitor.exit(childPath, state);
|
|
190
216
|
});
|
|
191
217
|
}
|
|
192
218
|
}
|
|
193
219
|
const sOut = [];
|
|
194
220
|
function traverse(node, visitor, scopeId, state, path) {
|
|
195
|
-
|
|
221
|
+
const fscope = path?.functionScopeId ?? node.extra?.functionScopeId ?? scopeId;
|
|
222
|
+
traverseInner(node, visitor, scopeId, fscope, state, path);
|
|
196
223
|
if (!sOut.includes(scopeIdCounter)) {
|
|
197
224
|
log.debug("Scopes created", scopeIdCounter, " Scopes removed", removedScopes, "Paths created", pathsCreated, bindingNodesVisited);
|
|
198
225
|
sOut.push(scopeIdCounter);
|
|
199
|
-
|
|
200
|
-
|
|
226
|
+
const k = Object.fromEntries(Object.entries(nodePathsCreated).sort((a, b) => a[1] - b[1]));
|
|
227
|
+
log.debug("Node paths created", k);
|
|
201
228
|
}
|
|
202
229
|
}
|
|
203
230
|
return {
|
|
@@ -5,12 +5,14 @@ export declare function isNode(candidate: unknown): candidate is ASTNode;
|
|
|
5
5
|
export declare function isNodePath(candidate: unknown): candidate is NodePath;
|
|
6
6
|
export declare function isLiteral(candidate: unknown): candidate is ESTree.Literal;
|
|
7
7
|
export declare function isPrimitive(value: unknown): value is PrimitiveValue;
|
|
8
|
+
export declare function isUpdateExpression(value: unknown): value is ESTree.UpdateExpression;
|
|
8
9
|
export declare function isAssignmentExpression(node: ESTree.Node): node is ESTree.AssignmentExpression;
|
|
9
10
|
export declare function isMemberExpression(node: ESTree.Node): node is ESTree.MemberExpression;
|
|
10
11
|
export declare function isIdentifier(node: ESTree.Node): node is ESTree.Identifier;
|
|
11
12
|
export declare function isFunctionDeclaration(node: ESTree.Node): node is ESTree.FunctionDeclaration;
|
|
12
13
|
export declare function isFunctionExpression(node: ESTree.Node): node is ESTree.FunctionExpression;
|
|
13
14
|
export declare function isVariableDeclarator(node: ESTree.Node): node is ESTree.VariableDeclarator;
|
|
15
|
+
export declare function isVariableDeclaration(node: ESTree.Node): node is ESTree.VariableDeclaration;
|
|
14
16
|
export declare function isBinding(node: ESTree.Node, parentNode: ESTree.Node, grandParentNode: ESTree.Node | undefined): boolean;
|
|
15
17
|
export declare const VISITOR_KEYS: Record<ESTree.Node["type"], string[]>;
|
|
16
18
|
export declare function isScope(node: ESTree.Node, parentNode: ESTree.Node): boolean;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"nodeutils.d.ts","sourceRoot":"","sources":["../../../src/nodeutils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACjC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAC/C,OAAO,EAAE,cAAc,EAAE,MAAM,GAAG,CAAC;AAEnC,wBAAgB,MAAM,CAAC,SAAS,EAAE,OAAO,GAAI,SAAS,IAAI,OAAO,CAEhE;AAED,wBAAgB,UAAU,CAAC,SAAS,EAAE,OAAO,GAAI,SAAS,IAAI,QAAQ,CAErE;AAED,wBAAgB,SAAS,CAAC,SAAS,EAAE,OAAO,GAAI,SAAS,IAAI,MAAM,CAAC,OAAO,CAE1E;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,OAAO,GAAI,KAAK,IAAI,cAAc,CAEpE;AAED,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,GAAG,IAAI,IAAI,MAAM,CAAC,oBAAoB,CAE7F;AAED,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,GAAG,IAAI,IAAI,MAAM,CAAC,gBAAgB,CAErF;AAED,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,GAAG,IAAI,IAAI,MAAM,CAAC,UAAU,CAEzE;AAED,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,GAAG,IAAI,IAAI,MAAM,CAAC,mBAAmB,CAE3F;AACD,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,GAAG,IAAI,IAAI,MAAM,CAAC,kBAAkB,CAEzF;AAED,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,GAAG,IAAI,IAAI,MAAM,CAAC,kBAAkB,CAEzF;
|
|
1
|
+
{"version":3,"file":"nodeutils.d.ts","sourceRoot":"","sources":["../../../src/nodeutils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACjC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAC/C,OAAO,EAAE,cAAc,EAAE,MAAM,GAAG,CAAC;AAEnC,wBAAgB,MAAM,CAAC,SAAS,EAAE,OAAO,GAAI,SAAS,IAAI,OAAO,CAEhE;AAED,wBAAgB,UAAU,CAAC,SAAS,EAAE,OAAO,GAAI,SAAS,IAAI,QAAQ,CAErE;AAED,wBAAgB,SAAS,CAAC,SAAS,EAAE,OAAO,GAAI,SAAS,IAAI,MAAM,CAAC,OAAO,CAE1E;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,OAAO,GAAI,KAAK,IAAI,cAAc,CAEpE;AAED,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,OAAO,GAAI,KAAK,IAAI,MAAM,CAAC,gBAAgB,CAEpF;AAED,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,GAAG,IAAI,IAAI,MAAM,CAAC,oBAAoB,CAE7F;AAED,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,GAAG,IAAI,IAAI,MAAM,CAAC,gBAAgB,CAErF;AAED,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,GAAG,IAAI,IAAI,MAAM,CAAC,UAAU,CAEzE;AAED,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,GAAG,IAAI,IAAI,MAAM,CAAC,mBAAmB,CAE3F;AACD,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,GAAG,IAAI,IAAI,MAAM,CAAC,kBAAkB,CAEzF;AAED,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,GAAG,IAAI,IAAI,MAAM,CAAC,kBAAkB,CAEzF;AACD,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,GAAG,IAAI,IAAI,MAAM,CAAC,mBAAmB,CAE3F;AACD,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,UAAU,EAAE,MAAM,CAAC,IAAI,EAAE,eAAe,EAAE,MAAM,CAAC,IAAI,GAAG,SAAS,GAAG,OAAO,CAwBvH;AAuDD,eAAO,MAAM,YAAY,EAAE,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,CA0F9D,CAAC;AAqBF,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,UAAU,EAAE,MAAM,CAAC,IAAI,GAAG,OAAO,CAS3E;AAED,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,GAAG,OAAO,CAqBrD;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,GAAG,IAAI,IAAI,MAAM,CAAC,eAAe,CAEnF"}
|
|
@@ -11,6 +11,7 @@ export type Scope = {
|
|
|
11
11
|
export type ASTNode = ESTree.Node & {
|
|
12
12
|
extra?: {
|
|
13
13
|
scopeId?: number;
|
|
14
|
+
functionScopeId?: number;
|
|
14
15
|
nodePath?: NodePath;
|
|
15
16
|
};
|
|
16
17
|
};
|
|
@@ -20,6 +21,7 @@ export type NodePath = {
|
|
|
20
21
|
parentPath?: NodePath;
|
|
21
22
|
parentKey?: string;
|
|
22
23
|
scopeId: number;
|
|
24
|
+
functionScopeId: number;
|
|
23
25
|
};
|
|
24
26
|
type Visitor<T> = {
|
|
25
27
|
enter: (path: NodePath, state: T) => void;
|
|
@@ -27,7 +29,7 @@ type Visitor<T> = {
|
|
|
27
29
|
};
|
|
28
30
|
export default function createTraverser(): {
|
|
29
31
|
traverse: <T>(node: ASTNode, visitor: Visitor<T>, scopeId: number | undefined, state: T, path?: NodePath) => void;
|
|
30
|
-
createNodePath: (node: ASTNode, key: string | undefined, parentKey: string | undefined, scopeId: number | undefined, nodePath?: NodePath) => NodePath;
|
|
32
|
+
createNodePath: (node: ASTNode, key: string | undefined | number, parentKey: string | undefined, scopeId: number | undefined, functionScopeId: number | undefined, nodePath?: NodePath) => NodePath;
|
|
31
33
|
getChildren: (key: string, path: NodePath) => NodePath[];
|
|
32
34
|
getPrimitiveChildren: (key: string, path: NodePath) => PrimitiveValue[];
|
|
33
35
|
getPrimitiveChildrenOrNodePaths: (key: string, path: NodePath) => Array<PrimitiveValue | NodePath>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"traverse.d.ts","sourceRoot":"","sources":["../../../src/traverse.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAEjC,OAAO,EAAE,cAAc,EAAE,MAAM,GAAG,CAAC;AASnC,MAAM,MAAM,OAAO,GAAG;IACpB,IAAI,EAAE,QAAQ,CAAC;CAChB,CAAA;AAED,MAAM,MAAM,KAAK,GAAG;IAClB,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAClC,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,EAAE,EAAE,MAAM,CAAC;CACZ,CAAC;AAIF,MAAM,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,GAAG;IAClC,KAAK,CAAC,EAAE;QACN,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,QAAQ,CAAC,EAAE,QAAQ,CAAC;KACrB,CAAA;CACF,CAAC;AAEF,MAAM,MAAM,QAAQ,GAAG;IACrB,IAAI,EAAE,OAAO,CAAC;IACd,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,UAAU,CAAC,EAAE,QAAQ,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"traverse.d.ts","sourceRoot":"","sources":["../../../src/traverse.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAEjC,OAAO,EAAE,cAAc,EAAE,MAAM,GAAG,CAAC;AASnC,MAAM,MAAM,OAAO,GAAG;IACpB,IAAI,EAAE,QAAQ,CAAC;CAChB,CAAA;AAED,MAAM,MAAM,KAAK,GAAG;IAClB,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAClC,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,EAAE,EAAE,MAAM,CAAC;CACZ,CAAC;AAIF,MAAM,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,GAAG;IAClC,KAAK,CAAC,EAAE;QACN,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,eAAe,CAAC,EAAE,MAAM,CAAC;QACzB,QAAQ,CAAC,EAAE,QAAQ,CAAC;KACrB,CAAA;CACF,CAAC;AAEF,MAAM,MAAM,QAAQ,GAAG;IACrB,IAAI,EAAE,OAAO,CAAC;IACd,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,UAAU,CAAC,EAAE,QAAQ,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,eAAe,EAAE,MAAM,CAAC;CACzB,CAAC;AAEF,KAAK,OAAO,CAAC,CAAC,IAAI;IAChB,KAAK,EAAE,CAAC,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,KAAK,IAAI,CAAC;IAC1C,IAAI,EAAE,CAAC,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,KAAK,IAAI,CAAC;CAC1C,CAAA;AAED,MAAM,CAAC,OAAO,UAAU,eAAe;wBA4NR,OAAO,gCAEzB,MAAM,GAAG,SAAS,mBAEpB,QAAQ;2BAhJa,OAAO,OAAO,MAAM,GAAG,SAAS,GAAG,MAAM,aAAa,MAAM,GAAG,SAAS,WAAW,MAAM,GAAG,SAAS,mBAAmB,MAAM,GAAG,SAAS,aAAa,QAAQ,KAAI,QAAQ;uBAtC/K,MAAM,QAAQ,QAAQ,KAAI,QAAQ,EAAE;gCAW3B,MAAM,QAAQ,QAAQ,KAAI,cAAc,EAAE;2CAO/B,MAAM,QAAQ,QAAQ,KAAI,MAAM,cAAc,GAAG,QAAQ,CAAC;0BAjD3E,MAAM,QAAQ,MAAM;EAyOlD"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "astronomical",
|
|
3
|
-
"version": "1.0.0-beta.
|
|
3
|
+
"version": "1.0.0-beta.16",
|
|
4
4
|
"description": "offers a way to query a Javascript AST to find specific patterns using a syntax somewhat similar to XPath.",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"lint": "eslint . --ext .ts --fix --ignore-path .gitignore",
|