astronomical 1.0.0 → 1.0.1
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 +331 -41
- package/lib/cjs/nodeutils.js +34 -33
- package/lib/cjs/parseQuery.js +4 -5
- package/lib/cjs/types/index.d.ts +36 -1
- package/lib/cjs/types/index.d.ts.map +1 -1
- package/lib/cjs/types/nodeutils.d.ts +14 -14
- package/lib/cjs/types/nodeutils.d.ts.map +1 -1
- package/lib/cjs/utils.js +2 -3
- package/lib/esm/index.mjs +331 -41
- package/lib/esm/nodeutils.js +34 -33
- package/lib/esm/parseQuery.js +4 -5
- package/lib/esm/types/index.d.ts +36 -1
- package/lib/esm/types/index.d.ts.map +1 -1
- package/lib/esm/types/nodeutils.d.ts +14 -14
- package/lib/esm/types/nodeutils.d.ts.map +1 -1
- package/lib/esm/utils.js +2 -3
- package/package.json +2 -2
- package/lib/cjs/traverse.js +0 -239
- package/lib/cjs/types/traverse.d.ts +0 -39
- package/lib/cjs/types/traverse.d.ts.map +0 -1
- package/lib/esm/traverse.js +0 -239
- package/lib/esm/types/traverse.d.ts +0 -39
- package/lib/esm/types/traverse.d.ts.map +0 -1
package/lib/cjs/types/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { ESTree } from "meriyah";
|
|
2
2
|
export declare const functions: {
|
|
3
3
|
join: {
|
|
4
4
|
fn: (result: Result[][]) => Result[];
|
|
@@ -24,5 +24,40 @@ export declare function multiQuery<T extends Record<string, string>>(code: strin
|
|
|
24
24
|
__AST?: ASTNode;
|
|
25
25
|
};
|
|
26
26
|
export declare function parseSource(source: string): ASTNode;
|
|
27
|
+
export type Binding = {
|
|
28
|
+
path: NodePath;
|
|
29
|
+
};
|
|
30
|
+
export type Scope = {
|
|
31
|
+
bindings: Record<string, Binding>;
|
|
32
|
+
parentScopeId?: number;
|
|
33
|
+
id: number;
|
|
34
|
+
};
|
|
35
|
+
export type ASTNode = ESTree.Node & {
|
|
36
|
+
extra?: {
|
|
37
|
+
scopeId?: number;
|
|
38
|
+
functionScopeId?: number;
|
|
39
|
+
nodePath?: NodePath;
|
|
40
|
+
};
|
|
41
|
+
};
|
|
42
|
+
export type NodePath = {
|
|
43
|
+
node: ASTNode;
|
|
44
|
+
key?: string;
|
|
45
|
+
parentPath?: NodePath;
|
|
46
|
+
parentKey?: string;
|
|
47
|
+
scopeId: number;
|
|
48
|
+
functionScopeId: number;
|
|
49
|
+
};
|
|
50
|
+
type Visitor<T> = {
|
|
51
|
+
enter: (path: NodePath, state: T) => void;
|
|
52
|
+
exit: (path: NodePath, state: T) => void;
|
|
53
|
+
};
|
|
54
|
+
export default function createTraverser(): {
|
|
55
|
+
traverse: <T>(node: ASTNode, visitor: Visitor<T>, scopeId: number | undefined, state: T, path?: NodePath) => void;
|
|
56
|
+
createNodePath: (node: ASTNode, key: string | undefined | number, parentKey: string | undefined, scopeId: number | undefined, functionScopeId: number | undefined, nodePath?: NodePath) => NodePath;
|
|
57
|
+
getChildren: (key: string, path: NodePath) => NodePath[];
|
|
58
|
+
getPrimitiveChildren: (key: string, path: NodePath) => PrimitiveValue[];
|
|
59
|
+
getPrimitiveChildrenOrNodePaths: (key: string, path: NodePath) => Array<PrimitiveValue | NodePath>;
|
|
60
|
+
getBinding: (scopeId: number, name: string) => Binding | undefined;
|
|
61
|
+
};
|
|
27
62
|
export {};
|
|
28
63
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
import { ESTree } from "meriyah";
|
|
2
|
-
import { ASTNode, NodePath } from "
|
|
2
|
+
import { ASTNode, NodePath } from ".";
|
|
3
3
|
import { PrimitiveValue } from ".";
|
|
4
|
-
export declare
|
|
5
|
-
export declare
|
|
6
|
-
export declare
|
|
7
|
-
export declare
|
|
8
|
-
export declare
|
|
9
|
-
export declare
|
|
10
|
-
export declare
|
|
11
|
-
export declare
|
|
12
|
-
export declare
|
|
13
|
-
export declare
|
|
14
|
-
export declare
|
|
15
|
-
export declare
|
|
16
|
-
export declare
|
|
4
|
+
export declare const isNode: (candidate: unknown) => candidate is ASTNode;
|
|
5
|
+
export declare const isNodePath: (candidate: unknown) => candidate is NodePath;
|
|
6
|
+
export declare const isLiteral: (candidate: unknown) => candidate is ESTree.Literal;
|
|
7
|
+
export declare const isPrimitive: (value: unknown) => value is PrimitiveValue;
|
|
8
|
+
export declare const isUpdateExpression: (value: unknown) => value is ESTree.UpdateExpression;
|
|
9
|
+
export declare const isAssignmentExpression: (node: ESTree.Node) => node is ESTree.AssignmentExpression;
|
|
10
|
+
export declare const isMemberExpression: (node: ESTree.Node) => node is ESTree.MemberExpression;
|
|
11
|
+
export declare const isIdentifier: (node: ESTree.Node) => node is ESTree.Identifier;
|
|
12
|
+
export declare const isFunctionDeclaration: (node: ESTree.Node) => node is ESTree.FunctionDeclaration;
|
|
13
|
+
export declare const isFunctionExpression: (node: ESTree.Node) => node is ESTree.FunctionExpression;
|
|
14
|
+
export declare const isVariableDeclarator: (node: ESTree.Node) => node is ESTree.VariableDeclarator;
|
|
15
|
+
export declare const isVariableDeclaration: (node: ESTree.Node) => node is ESTree.VariableDeclaration;
|
|
16
|
+
export declare const isBinding: (node: ESTree.Node, parentNode: ESTree.Node, grandParentNode: ESTree.Node | undefined) => boolean;
|
|
17
17
|
export declare const VISITOR_KEYS: Record<ESTree.Node["type"], string[]>;
|
|
18
18
|
export declare function isScope(node: ESTree.Node, parentNode: ESTree.Node): boolean;
|
|
19
19
|
export declare function isScopable(node: 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,
|
|
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,GAAG,CAAC;AACtC,OAAO,EAAE,cAAc,EAAE,MAAM,GAAG,CAAC;AAEnC,eAAO,MAAM,MAAM,cAAe,OAAO,KAAI,SAAS,IAAI,OAEzD,CAAA;AAED,eAAO,MAAM,UAAU,cAAe,OAAO,KAAI,SAAS,IAAI,QAE7D,CAAA;AAED,eAAO,MAAM,SAAS,cAAe,OAAO,KAAI,SAAS,IAAI,MAAM,CAAC,OAEnE,CAAA;AAED,eAAO,MAAM,WAAW,UAAW,OAAO,KAAI,KAAK,IAAI,cAEtD,CAAA;AAED,eAAO,MAAM,kBAAkB,UAAW,OAAO,KAAI,KAAK,IAAI,MAAM,CAAC,gBAEpE,CAAA;AAED,eAAO,MAAM,sBAAsB,SAAU,MAAM,CAAC,IAAI,KAAG,IAAI,IAAI,MAAM,CAAC,oBAEzE,CAAA;AAED,eAAO,MAAM,kBAAkB,SAAU,MAAM,CAAC,IAAI,KAAG,IAAI,IAAI,MAAM,CAAC,gBAErE,CAAA;AAED,eAAO,MAAM,YAAY,SAAU,MAAM,CAAC,IAAI,KAAG,IAAI,IAAI,MAAM,CAAC,UAE/D,CAAA;AAED,eAAO,MAAM,qBAAqB,SAAU,MAAM,CAAC,IAAI,KAAG,IAAI,IAAI,MAAM,CAAC,mBAExE,CAAA;AACD,eAAO,MAAM,oBAAoB,SAAU,MAAM,CAAC,IAAI,KAAG,IAAI,IAAI,MAAM,CAAC,kBAEvE,CAAA;AAED,eAAO,MAAM,oBAAoB,SAAU,MAAM,CAAC,IAAI,KAAG,IAAI,IAAI,MAAM,CAAC,kBAEvE,CAAA;AACD,eAAO,MAAM,qBAAqB,SAAU,MAAM,CAAC,IAAI,KAAG,IAAI,IAAI,MAAM,CAAC,mBAExE,CAAA;AACD,eAAO,MAAM,SAAS,SAAU,MAAM,CAAC,IAAI,cAAc,MAAM,CAAC,IAAI,mBAAmB,MAAM,CAAC,IAAI,GAAG,SAAS,KAAG,OAwBhH,CAAA;AAuDD,eAAO,MAAM,YAAY,EAAE,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,CA2F9D,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"}
|
package/lib/cjs/utils.js
CHANGED
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.toArray = toArray;
|
|
4
|
+
exports.isDefined = isDefined;
|
|
4
5
|
function toArray(value) {
|
|
5
6
|
return Array.isArray(value) ? value : [value];
|
|
6
7
|
}
|
|
7
|
-
exports.toArray = toArray;
|
|
8
8
|
function isDefined(value) {
|
|
9
9
|
return value != undefined && value != null;
|
|
10
10
|
}
|
|
11
|
-
exports.isDefined = isDefined;
|
package/lib/esm/index.mjs
CHANGED
|
@@ -1,19 +1,21 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.
|
|
7
|
-
|
|
3
|
+
exports.functions = void 0;
|
|
4
|
+
exports.isAvailableFunction = isAvailableFunction;
|
|
5
|
+
exports.query = query;
|
|
6
|
+
exports.multiQuery = multiQuery;
|
|
7
|
+
exports.parseSource = parseSource;
|
|
8
|
+
exports.default = createTraverser;
|
|
8
9
|
const parseQuery_1 = require("./parseQuery");
|
|
9
10
|
const meriyah_1 = require("meriyah");
|
|
10
11
|
const nodeutils_1 = require("./nodeutils");
|
|
12
|
+
const utils_1 = require("./utils");
|
|
11
13
|
const debugLogEnabled = false;
|
|
12
14
|
const log = {
|
|
13
|
-
debug: (...args) => {
|
|
15
|
+
debug: debugLogEnabled ? (...args) => {
|
|
14
16
|
if (debugLogEnabled)
|
|
15
|
-
console.debug(...args
|
|
16
|
-
}
|
|
17
|
+
console.debug(...args);
|
|
18
|
+
} : () => { }
|
|
17
19
|
};
|
|
18
20
|
exports.functions = {
|
|
19
21
|
"join": {
|
|
@@ -59,12 +61,13 @@ exports.functions = {
|
|
|
59
61
|
}
|
|
60
62
|
}
|
|
61
63
|
};
|
|
62
|
-
const functionNames = Object.keys(exports.functions);
|
|
64
|
+
const functionNames = new Set(Object.keys(exports.functions));
|
|
63
65
|
function isAvailableFunction(name) {
|
|
64
|
-
return functionNames.
|
|
66
|
+
return functionNames.has(name);
|
|
65
67
|
}
|
|
66
|
-
exports.isAvailableFunction = isAvailableFunction;
|
|
67
68
|
function breadCrumb(path) {
|
|
69
|
+
if (!debugLogEnabled)
|
|
70
|
+
return "";
|
|
68
71
|
return {
|
|
69
72
|
valueOf() {
|
|
70
73
|
if (path.parentPath == undefined)
|
|
@@ -74,7 +77,7 @@ function breadCrumb(path) {
|
|
|
74
77
|
};
|
|
75
78
|
}
|
|
76
79
|
function createQuerier() {
|
|
77
|
-
const traverser = (
|
|
80
|
+
const traverser = createTraverser();
|
|
78
81
|
const { getChildren, getPrimitiveChildren, getPrimitiveChildrenOrNodePaths, getBinding, createNodePath, traverse } = traverser;
|
|
79
82
|
function createFilter(filter, filterResult) {
|
|
80
83
|
if (filter.type == "and" || filter.type == "or" || filter.type == "equals") {
|
|
@@ -148,7 +151,14 @@ function createQuerier() {
|
|
|
148
151
|
if (fnode.node.filter) {
|
|
149
152
|
const filter = createFilter(fnode.node.filter, []);
|
|
150
153
|
const filteredResult = [];
|
|
151
|
-
|
|
154
|
+
const f = { filter: filter, qNode: fnode.node, node: path.node, result: filteredResult };
|
|
155
|
+
state.filters[state.depth].push(f);
|
|
156
|
+
let fmap = state.filtersMap[state.depth].get(fnode.node);
|
|
157
|
+
if (!fmap) {
|
|
158
|
+
fmap = [];
|
|
159
|
+
state.filtersMap[state.depth].set(fnode.node, fmap);
|
|
160
|
+
}
|
|
161
|
+
fmap.push(f);
|
|
152
162
|
addFilterChildrenToState(filter, state);
|
|
153
163
|
const child = fnode.node.child;
|
|
154
164
|
if (child) {
|
|
@@ -207,25 +217,31 @@ function createQuerier() {
|
|
|
207
217
|
if ("type" in filter) {
|
|
208
218
|
if (filter.type == "and") {
|
|
209
219
|
const left = evaluateFilter(filter.left, path);
|
|
210
|
-
if (left.length == 0)
|
|
220
|
+
if (left.length == 0) {
|
|
211
221
|
return [];
|
|
212
|
-
|
|
222
|
+
}
|
|
223
|
+
const r = evaluateFilter(filter.right, path);
|
|
224
|
+
return r;
|
|
213
225
|
}
|
|
214
226
|
if (filter.type == "or") {
|
|
215
227
|
const left = evaluateFilter(filter.left, path);
|
|
216
|
-
if (left.length > 0)
|
|
228
|
+
if (left.length > 0) {
|
|
217
229
|
return left;
|
|
218
|
-
|
|
230
|
+
}
|
|
231
|
+
const r = evaluateFilter(filter.right, path);
|
|
232
|
+
return r;
|
|
219
233
|
}
|
|
220
234
|
if (filter.type == "equals") {
|
|
221
235
|
const left = evaluateFilter(filter.left, path);
|
|
222
236
|
const right = evaluateFilter(filter.right, path);
|
|
223
|
-
|
|
237
|
+
const r = left.filter(x => right.includes(x));
|
|
238
|
+
return r;
|
|
224
239
|
}
|
|
225
240
|
throw new Error("Unknown filter type: " + filter.type);
|
|
226
241
|
}
|
|
227
242
|
if (filter.node.type == "parent") {
|
|
228
|
-
|
|
243
|
+
const r = resolveFilterWithParent(filter.node, path);
|
|
244
|
+
return r;
|
|
229
245
|
}
|
|
230
246
|
return filter.result;
|
|
231
247
|
}
|
|
@@ -261,6 +277,7 @@ function createQuerier() {
|
|
|
261
277
|
return value != undefined && value != null;
|
|
262
278
|
}
|
|
263
279
|
let subQueryCounter = 0;
|
|
280
|
+
const memo = new Map();
|
|
264
281
|
function resolveDirectly(node, path) {
|
|
265
282
|
let startNode = node;
|
|
266
283
|
const startPath = path;
|
|
@@ -294,19 +311,47 @@ function createQuerier() {
|
|
|
294
311
|
startNode = startNode.child;
|
|
295
312
|
}
|
|
296
313
|
//log.debug("DIRECT TRAV RESOLVE", startNode, paths.map(p => breadCrumb(p)));
|
|
297
|
-
const result =
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
314
|
+
const result = [];
|
|
315
|
+
//console.log(paths.length, subQueryCounter);
|
|
316
|
+
for (const path of paths) {
|
|
317
|
+
if ((0, nodeutils_1.isNodePath)(path)) {
|
|
318
|
+
if (memo.has(startNode) && memo.get(startNode).has(path)) {
|
|
319
|
+
result.push(...memo.get(startNode).get(path));
|
|
320
|
+
}
|
|
321
|
+
else {
|
|
322
|
+
const subQueryKey = "subquery-" + subQueryCounter++;
|
|
323
|
+
const subQueryResult = travHandle({ [subQueryKey]: startNode }, path)[subQueryKey];
|
|
324
|
+
if (!memo.has(startNode))
|
|
325
|
+
memo.set(startNode, new Map());
|
|
326
|
+
memo.get(startNode)?.set(path, subQueryResult);
|
|
327
|
+
result.push(...subQueryResult);
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
}
|
|
301
331
|
log.debug("DIRECT TRAV RESOLVE RESULT", result);
|
|
302
332
|
return result;
|
|
303
333
|
}
|
|
304
334
|
function addResultIfTokenMatch(fnode, path, state) {
|
|
305
|
-
const
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
335
|
+
const matchingFilters = [];
|
|
336
|
+
//console.log("FILTERS", state.filters[state.depth].length, state.filtersMap[state.depth].get(fnode.node)?.length);
|
|
337
|
+
const filters = [];
|
|
338
|
+
const nodeFilters = state.filtersMap[state.depth].get(fnode.node);
|
|
339
|
+
if (nodeFilters) {
|
|
340
|
+
for (const f of nodeFilters) {
|
|
341
|
+
if (f.qNode !== fnode.node)
|
|
342
|
+
continue;
|
|
343
|
+
if (f.node !== path.node)
|
|
344
|
+
continue;
|
|
345
|
+
filters.push(f);
|
|
346
|
+
}
|
|
347
|
+
for (const f of filters) {
|
|
348
|
+
if (evaluateFilter(f.filter, path).length > 0) {
|
|
349
|
+
matchingFilters.push(f);
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
if (filters.length > 0 && matchingFilters.length == 0)
|
|
353
|
+
return;
|
|
354
|
+
}
|
|
310
355
|
if (fnode.node.resolve) {
|
|
311
356
|
const binding = resolveBinding(path);
|
|
312
357
|
const resolved = binding ? getChildren("init", binding)[0] : undefined;
|
|
@@ -366,36 +411,51 @@ function createQuerier() {
|
|
|
366
411
|
child: [[], []],
|
|
367
412
|
descendant: [[], []],
|
|
368
413
|
filters: [[], []],
|
|
414
|
+
filtersMap: [new Map(), new Map()],
|
|
369
415
|
matches: [[]],
|
|
370
416
|
functionCalls: [[]]
|
|
371
417
|
};
|
|
372
|
-
|
|
418
|
+
for (const [name, node] of Object.entries(queries)) {
|
|
373
419
|
createFNodeAndAddToState(node, results[name], state);
|
|
374
|
-
}
|
|
420
|
+
}
|
|
375
421
|
state.child[state.depth + 1].forEach(fnode => addPrimitiveAttributeIfMatch(fnode, root));
|
|
376
422
|
state.descendant.slice(0, state.depth + 1).forEach(fnodes => fnodes.forEach(fnode => addPrimitiveAttributeIfMatch(fnode, root)));
|
|
377
423
|
traverse(root.node, {
|
|
378
424
|
enter(path, state) {
|
|
379
|
-
log.debug("ENTER", breadCrumb(path));
|
|
425
|
+
//log.debug("ENTER", breadCrumb(path));
|
|
380
426
|
state.depth++;
|
|
381
427
|
state.child.push([]);
|
|
382
428
|
state.descendant.push([]);
|
|
383
429
|
state.filters.push([]);
|
|
430
|
+
state.filtersMap.push(new Map());
|
|
384
431
|
state.matches.push([]);
|
|
385
432
|
state.functionCalls.push([]);
|
|
386
|
-
state.child[state.depth]
|
|
387
|
-
|
|
433
|
+
for (const fnode of state.child[state.depth]) {
|
|
434
|
+
addIfTokenMatch(fnode, path, state);
|
|
435
|
+
}
|
|
436
|
+
for (const fnodes of state.descendant.slice(0, state.depth + 1)) {
|
|
437
|
+
for (const fnode of fnodes) {
|
|
438
|
+
addIfTokenMatch(fnode, path, state);
|
|
439
|
+
}
|
|
440
|
+
}
|
|
388
441
|
},
|
|
389
442
|
exit(path, state) {
|
|
390
443
|
log.debug("EXIT", breadCrumb(path));
|
|
391
444
|
// Check for attributes as not all attributes are visited
|
|
392
445
|
state.child[state.depth + 1].forEach(fnode => addPrimitiveAttributeIfMatch(fnode, path));
|
|
393
|
-
|
|
394
|
-
|
|
446
|
+
for (const fnodes of state.descendant) {
|
|
447
|
+
for (const fnode of fnodes) {
|
|
448
|
+
addPrimitiveAttributeIfMatch(fnode, path);
|
|
449
|
+
}
|
|
450
|
+
}
|
|
451
|
+
for (const [fNode, path] of state.matches[state.depth]) {
|
|
452
|
+
addResultIfTokenMatch(fNode, path, state);
|
|
453
|
+
}
|
|
395
454
|
state.depth--;
|
|
396
455
|
state.child.pop();
|
|
397
456
|
state.descendant.pop();
|
|
398
457
|
state.filters.pop();
|
|
458
|
+
state.filtersMap.pop();
|
|
399
459
|
state.matches.pop();
|
|
400
460
|
state.functionCalls.pop();
|
|
401
461
|
}
|
|
@@ -404,7 +464,8 @@ function createQuerier() {
|
|
|
404
464
|
}
|
|
405
465
|
function beginHandle(queries, path) {
|
|
406
466
|
const rootPath = createNodePath(path, undefined, undefined, undefined, undefined);
|
|
407
|
-
|
|
467
|
+
const r = travHandle(queries, rootPath);
|
|
468
|
+
return r;
|
|
408
469
|
}
|
|
409
470
|
return {
|
|
410
471
|
beginHandle
|
|
@@ -420,7 +481,6 @@ function query(code, query, returnAST) {
|
|
|
420
481
|
}
|
|
421
482
|
return result[defaultKey];
|
|
422
483
|
}
|
|
423
|
-
exports.query = query;
|
|
424
484
|
function multiQuery(code, namedQueries, returnAST) {
|
|
425
485
|
const start = Date.now();
|
|
426
486
|
const ast = typeof code == "string" ? parseSource(code) : code;
|
|
@@ -435,13 +495,243 @@ function multiQuery(code, namedQueries, returnAST) {
|
|
|
435
495
|
}
|
|
436
496
|
return result;
|
|
437
497
|
}
|
|
438
|
-
exports.multiQuery = multiQuery;
|
|
439
498
|
function parseSource(source) {
|
|
440
499
|
try {
|
|
441
|
-
return (0, meriyah_1.parseScript)(source, { module: true, next: true
|
|
500
|
+
return (0, meriyah_1.parseScript)(source, { module: true, next: true });
|
|
442
501
|
}
|
|
443
502
|
catch (e) {
|
|
444
|
-
return (0, meriyah_1.parseScript)(source, { module: false, next: true
|
|
503
|
+
return (0, meriyah_1.parseScript)(source, { module: false, next: true });
|
|
445
504
|
}
|
|
446
505
|
}
|
|
447
|
-
|
|
506
|
+
const scopes = new Map();
|
|
507
|
+
function createTraverser() {
|
|
508
|
+
let scopeIdCounter = 0;
|
|
509
|
+
let removedScopes = 0;
|
|
510
|
+
const nodePathsCreated = {};
|
|
511
|
+
function createScope(parentScopeId) {
|
|
512
|
+
const id = scopeIdCounter++;
|
|
513
|
+
if (parentScopeId != undefined) {
|
|
514
|
+
scopes.set(id, parentScopeId ?? -1);
|
|
515
|
+
}
|
|
516
|
+
return id;
|
|
517
|
+
}
|
|
518
|
+
function getBinding(scopeId, name) {
|
|
519
|
+
let currentScope = scopes.get(scopeId);
|
|
520
|
+
while (currentScope !== undefined) {
|
|
521
|
+
if (typeof currentScope !== "number") {
|
|
522
|
+
// Full scope: Check for binding
|
|
523
|
+
if (currentScope.bindings[name]) {
|
|
524
|
+
return currentScope.bindings[name];
|
|
525
|
+
}
|
|
526
|
+
// Move to parent scope
|
|
527
|
+
if (currentScope.parentScopeId === -1)
|
|
528
|
+
break; // No parent scope
|
|
529
|
+
currentScope = scopes.get(currentScope.parentScopeId);
|
|
530
|
+
}
|
|
531
|
+
else {
|
|
532
|
+
// Lightweight scope: Retrieve parent scope
|
|
533
|
+
if (currentScope === -1 || currentScope == undefined)
|
|
534
|
+
break; // No parent scope
|
|
535
|
+
currentScope = scopes.get(currentScope);
|
|
536
|
+
}
|
|
537
|
+
}
|
|
538
|
+
return undefined; // Binding not found
|
|
539
|
+
}
|
|
540
|
+
function setBinding(scopeId, name, binding) {
|
|
541
|
+
let scope = scopes.get(scopeId);
|
|
542
|
+
if (typeof scope === "number" || scope === undefined) {
|
|
543
|
+
// Upgrade the lightweight scope to a full scope
|
|
544
|
+
scope = { bindings: {}, id: scopeId, parentScopeId: scope };
|
|
545
|
+
scopes.set(scopeId, scope);
|
|
546
|
+
}
|
|
547
|
+
if (scope && typeof scope !== "number") {
|
|
548
|
+
scope.bindings[name] = binding;
|
|
549
|
+
}
|
|
550
|
+
}
|
|
551
|
+
let pathsCreated = 0;
|
|
552
|
+
function getChildren(key, path) {
|
|
553
|
+
if (key in path.node) {
|
|
554
|
+
const r = path.node[key];
|
|
555
|
+
if (Array.isArray(r)) {
|
|
556
|
+
return r.map((n, i) => createNodePath(n, i, key, path.scopeId, path.functionScopeId, path));
|
|
557
|
+
}
|
|
558
|
+
else if (r != undefined) {
|
|
559
|
+
return [createNodePath(r, key, key, path.scopeId, path.functionScopeId, path)];
|
|
560
|
+
}
|
|
561
|
+
}
|
|
562
|
+
return [];
|
|
563
|
+
}
|
|
564
|
+
function getPrimitiveChildren(key, path) {
|
|
565
|
+
if (key in path.node) {
|
|
566
|
+
const r = path.node[key];
|
|
567
|
+
return (0, utils_1.toArray)(r).filter(utils_1.isDefined).filter(nodeutils_1.isPrimitive);
|
|
568
|
+
}
|
|
569
|
+
return [];
|
|
570
|
+
}
|
|
571
|
+
function getPrimitiveChildrenOrNodePaths(key, path) {
|
|
572
|
+
if (key in path.node) {
|
|
573
|
+
const r = path.node[key];
|
|
574
|
+
if (Array.isArray(r)) {
|
|
575
|
+
return r.map((n, i) => (0, nodeutils_1.isPrimitive)(n) ? n :
|
|
576
|
+
// isLiteral(n) ? n.value as PrimitiveValue :
|
|
577
|
+
createNodePath(n, i, key, path.scopeId, path.functionScopeId, path));
|
|
578
|
+
}
|
|
579
|
+
else if (r != undefined) {
|
|
580
|
+
return [
|
|
581
|
+
(0, nodeutils_1.isPrimitive)(r) ? r :
|
|
582
|
+
// isLiteral(r) ? r.value as PrimitiveValue :
|
|
583
|
+
createNodePath(r, key, key, path.scopeId, path.functionScopeId, path)
|
|
584
|
+
];
|
|
585
|
+
}
|
|
586
|
+
}
|
|
587
|
+
return [];
|
|
588
|
+
}
|
|
589
|
+
function createNodePath(node, key, parentKey, scopeId, functionScopeId, nodePath) {
|
|
590
|
+
if (node.extra?.nodePath) {
|
|
591
|
+
const path = node.extra.nodePath;
|
|
592
|
+
if (nodePath && (0, nodeutils_1.isExportSpecifier)(nodePath.node) && key == "exported" && path.key == "local") {
|
|
593
|
+
//Special handling for "export { someName }" as id is both local and exported
|
|
594
|
+
path.key = "exported";
|
|
595
|
+
path.parentPath = nodePath;
|
|
596
|
+
return path;
|
|
597
|
+
}
|
|
598
|
+
if (key != undefined)
|
|
599
|
+
path.key = typeof (key) == "number" ? key.toString() : key;
|
|
600
|
+
if (parentKey != undefined)
|
|
601
|
+
path.parentKey = parentKey;
|
|
602
|
+
if (nodePath != undefined)
|
|
603
|
+
path.parentPath = nodePath;
|
|
604
|
+
return path;
|
|
605
|
+
}
|
|
606
|
+
const finalScope = ((node.extra && node.extra.scopeId != undefined) ? node.extra.scopeId : scopeId) ?? createScope();
|
|
607
|
+
const finalFScope = ((node.extra && node.extra.functionScopeId != undefined) ? node.extra.functionScopeId : functionScopeId) ?? finalScope;
|
|
608
|
+
const path = {
|
|
609
|
+
node,
|
|
610
|
+
scopeId: finalScope,
|
|
611
|
+
functionScopeId: finalFScope,
|
|
612
|
+
parentPath: nodePath,
|
|
613
|
+
key: typeof (key) == "number" ? key.toString() : key,
|
|
614
|
+
parentKey
|
|
615
|
+
};
|
|
616
|
+
if ((0, nodeutils_1.isNode)(node)) {
|
|
617
|
+
node.extra = node.extra ?? {};
|
|
618
|
+
node.extra.nodePath = path;
|
|
619
|
+
Object.defineProperty(node.extra, "nodePath", { enumerable: false });
|
|
620
|
+
}
|
|
621
|
+
nodePathsCreated[node.type] = (nodePathsCreated[node.type] ?? 0) + 1;
|
|
622
|
+
pathsCreated++;
|
|
623
|
+
return path;
|
|
624
|
+
}
|
|
625
|
+
function registerBinding(stack, scopeId, functionScopeId, key, parentKey) {
|
|
626
|
+
//console.log("x registerBinding?", isIdentifier(node) ? node.name : node.type, parentNode.type, grandParentNode?.type, scopeId, isBinding(node, parentNode, grandParentNode));
|
|
627
|
+
const node = stack[stack.length - 1];
|
|
628
|
+
if (!(0, nodeutils_1.isIdentifier)(node))
|
|
629
|
+
return;
|
|
630
|
+
const parentNode = stack[stack.length - 2];
|
|
631
|
+
if ((0, nodeutils_1.isAssignmentExpression)(parentNode) || (0, nodeutils_1.isMemberExpression)(parentNode) || (0, nodeutils_1.isUpdateExpression)(parentNode) || (0, nodeutils_1.isExportSpecifier)(parentNode))
|
|
632
|
+
return;
|
|
633
|
+
const grandParentNode = stack[stack.length - 3];
|
|
634
|
+
if (!(0, nodeutils_1.isBinding)(node, parentNode, grandParentNode))
|
|
635
|
+
return;
|
|
636
|
+
if (key == "id" && !(0, nodeutils_1.isVariableDeclarator)(parentNode)) {
|
|
637
|
+
setBinding(functionScopeId, node.name, { path: createNodePath(node, undefined, undefined, scopeId, functionScopeId) });
|
|
638
|
+
return;
|
|
639
|
+
}
|
|
640
|
+
if ((0, nodeutils_1.isVariableDeclarator)(parentNode) && (0, nodeutils_1.isVariableDeclaration)(grandParentNode)) {
|
|
641
|
+
if (grandParentNode.kind == "var") {
|
|
642
|
+
setBinding(functionScopeId, node.name, { path: createNodePath(parentNode, undefined, undefined, scopeId, functionScopeId) });
|
|
643
|
+
return;
|
|
644
|
+
}
|
|
645
|
+
else {
|
|
646
|
+
setBinding(scopeId, node.name, { path: createNodePath(parentNode, undefined, undefined, scopeId, functionScopeId) });
|
|
647
|
+
return;
|
|
648
|
+
}
|
|
649
|
+
}
|
|
650
|
+
if ((0, nodeutils_1.isScope)(node, parentNode)) {
|
|
651
|
+
setBinding(scopeId, node.name, { path: createNodePath(node, key, parentKey, scopeId, functionScopeId) });
|
|
652
|
+
} /*else {
|
|
653
|
+
console.log(node.type, parentNode.type, grandParentNode?.type);
|
|
654
|
+
}*/
|
|
655
|
+
}
|
|
656
|
+
let bindingNodesVisited = 0;
|
|
657
|
+
function registerBindings(stack, scopeId, functionScopeId) {
|
|
658
|
+
const node = stack[stack.length - 1];
|
|
659
|
+
if (!(0, nodeutils_1.isNode)(node))
|
|
660
|
+
return;
|
|
661
|
+
if (node.extra?.scopeId != undefined)
|
|
662
|
+
return;
|
|
663
|
+
node.extra = node.extra ?? {};
|
|
664
|
+
node.extra.scopeId = scopeId;
|
|
665
|
+
bindingNodesVisited++;
|
|
666
|
+
const keys = nodeutils_1.VISITOR_KEYS[node.type];
|
|
667
|
+
if (keys.length == 0)
|
|
668
|
+
return;
|
|
669
|
+
let childScopeId = scopeId;
|
|
670
|
+
if ((0, nodeutils_1.isScopable)(node)) {
|
|
671
|
+
childScopeId = createScope(scopeId);
|
|
672
|
+
}
|
|
673
|
+
for (const key of keys) {
|
|
674
|
+
const childNodes = node[key];
|
|
675
|
+
const children = (0, utils_1.toArray)(childNodes).filter(utils_1.isDefined);
|
|
676
|
+
for (const [i, child] of children.entries()) {
|
|
677
|
+
if (!(0, nodeutils_1.isNode)(child))
|
|
678
|
+
continue;
|
|
679
|
+
const f = key === "body" && ((0, nodeutils_1.isFunctionDeclaration)(node) || (0, nodeutils_1.isFunctionExpression)(node)) ? childScopeId : functionScopeId;
|
|
680
|
+
stack.push(child);
|
|
681
|
+
if ((0, nodeutils_1.isIdentifier)(child)) {
|
|
682
|
+
const k = Array.isArray(childNodes) ? i : key;
|
|
683
|
+
registerBinding(stack, childScopeId, f, k, key);
|
|
684
|
+
}
|
|
685
|
+
else {
|
|
686
|
+
registerBindings(stack, childScopeId, f);
|
|
687
|
+
}
|
|
688
|
+
stack.pop();
|
|
689
|
+
}
|
|
690
|
+
}
|
|
691
|
+
if (childScopeId != scopeId && typeof scopes.get(childScopeId) == "number") { // Scope has not been populated
|
|
692
|
+
scopes.set(childScopeId, scopes.get(scopeId));
|
|
693
|
+
removedScopes++;
|
|
694
|
+
}
|
|
695
|
+
}
|
|
696
|
+
function traverseInner(node, visitor, scopeId, functionScopeId, state, path) {
|
|
697
|
+
const nodePath = path ?? createNodePath(node, undefined, undefined, scopeId, functionScopeId);
|
|
698
|
+
const keys = nodeutils_1.VISITOR_KEYS[node.type] ?? [];
|
|
699
|
+
if (nodePath.parentPath)
|
|
700
|
+
registerBindings([nodePath.parentPath.parentPath?.node, nodePath.parentPath.node, nodePath.node].filter(utils_1.isDefined), nodePath.scopeId, nodePath.functionScopeId);
|
|
701
|
+
for (const key of keys) {
|
|
702
|
+
const childNodes = node[key];
|
|
703
|
+
const children = Array.isArray(childNodes) ? childNodes : childNodes ? [childNodes] : [];
|
|
704
|
+
const nodePaths = [];
|
|
705
|
+
for (const [i, child] of children.entries()) {
|
|
706
|
+
if ((0, nodeutils_1.isNode)(child)) {
|
|
707
|
+
const childPath = createNodePath(child, Array.isArray(childNodes) ? i : key, key, nodePath.scopeId, nodePath.functionScopeId, nodePath);
|
|
708
|
+
nodePaths.push(childPath);
|
|
709
|
+
}
|
|
710
|
+
}
|
|
711
|
+
for (const childPath of nodePaths) {
|
|
712
|
+
visitor.enter(childPath, state);
|
|
713
|
+
traverseInner(childPath.node, visitor, nodePath.scopeId, nodePath.functionScopeId, state, childPath);
|
|
714
|
+
visitor.exit(childPath, state);
|
|
715
|
+
}
|
|
716
|
+
}
|
|
717
|
+
}
|
|
718
|
+
const sOut = [];
|
|
719
|
+
function traverse(node, visitor, scopeId, state, path) {
|
|
720
|
+
const fscope = path?.functionScopeId ?? node.extra?.functionScopeId ?? scopeId;
|
|
721
|
+
traverseInner(node, visitor, scopeId, fscope, state, path);
|
|
722
|
+
if (!sOut.includes(scopeIdCounter)) {
|
|
723
|
+
log.debug("Scopes created", scopeIdCounter, " Scopes removed", removedScopes, "Paths created", pathsCreated, bindingNodesVisited);
|
|
724
|
+
sOut.push(scopeIdCounter);
|
|
725
|
+
const k = Object.fromEntries(Object.entries(nodePathsCreated).sort((a, b) => a[1] - b[1]));
|
|
726
|
+
log.debug("Node paths created", k);
|
|
727
|
+
}
|
|
728
|
+
}
|
|
729
|
+
return {
|
|
730
|
+
traverse,
|
|
731
|
+
createNodePath,
|
|
732
|
+
getChildren,
|
|
733
|
+
getPrimitiveChildren,
|
|
734
|
+
getPrimitiveChildrenOrNodePaths,
|
|
735
|
+
getBinding
|
|
736
|
+
};
|
|
737
|
+
}
|