astronomical 1.0.0-beta.16 → 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/index.js
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
|
+
}
|
package/lib/cjs/nodeutils.js
CHANGED
|
@@ -1,55 +1,58 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
4
|
-
|
|
3
|
+
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
|
+
exports.isScope = isScope;
|
|
5
|
+
exports.isScopable = isScopable;
|
|
6
|
+
exports.isExportSpecifier = isExportSpecifier;
|
|
7
|
+
const isNode = (candidate) => {
|
|
5
8
|
return typeof candidate === "object" && candidate != null && "type" in candidate;
|
|
6
|
-
}
|
|
9
|
+
};
|
|
7
10
|
exports.isNode = isNode;
|
|
8
|
-
|
|
11
|
+
const isNodePath = (candidate) => {
|
|
9
12
|
return typeof candidate === "object" && candidate != null && "node" in candidate;
|
|
10
|
-
}
|
|
13
|
+
};
|
|
11
14
|
exports.isNodePath = isNodePath;
|
|
12
|
-
|
|
13
|
-
return isNode(candidate) && candidate.type === "Literal";
|
|
14
|
-
}
|
|
15
|
+
const isLiteral = (candidate) => {
|
|
16
|
+
return (0, exports.isNode)(candidate) && candidate.type === "Literal";
|
|
17
|
+
};
|
|
15
18
|
exports.isLiteral = isLiteral;
|
|
16
|
-
|
|
19
|
+
const isPrimitive = (value) => {
|
|
17
20
|
return typeof value == "string" || typeof value == "number" || typeof value == "boolean";
|
|
18
|
-
}
|
|
21
|
+
};
|
|
19
22
|
exports.isPrimitive = isPrimitive;
|
|
20
|
-
|
|
21
|
-
return isNode(value) && value.type === "UpdateExpression";
|
|
22
|
-
}
|
|
23
|
+
const isUpdateExpression = (value) => {
|
|
24
|
+
return (0, exports.isNode)(value) && value.type === "UpdateExpression";
|
|
25
|
+
};
|
|
23
26
|
exports.isUpdateExpression = isUpdateExpression;
|
|
24
|
-
|
|
27
|
+
const isAssignmentExpression = (node) => {
|
|
25
28
|
return node.type === "AssignmentExpression";
|
|
26
|
-
}
|
|
29
|
+
};
|
|
27
30
|
exports.isAssignmentExpression = isAssignmentExpression;
|
|
28
|
-
|
|
31
|
+
const isMemberExpression = (node) => {
|
|
29
32
|
return node.type === "MemberExpression";
|
|
30
|
-
}
|
|
33
|
+
};
|
|
31
34
|
exports.isMemberExpression = isMemberExpression;
|
|
32
|
-
|
|
35
|
+
const isIdentifier = (node) => {
|
|
33
36
|
return node.type === "Identifier";
|
|
34
|
-
}
|
|
37
|
+
};
|
|
35
38
|
exports.isIdentifier = isIdentifier;
|
|
36
|
-
|
|
39
|
+
const isFunctionDeclaration = (node) => {
|
|
37
40
|
return node.type === "FunctionDeclaration";
|
|
38
|
-
}
|
|
41
|
+
};
|
|
39
42
|
exports.isFunctionDeclaration = isFunctionDeclaration;
|
|
40
|
-
|
|
43
|
+
const isFunctionExpression = (node) => {
|
|
41
44
|
return node.type === "FunctionExpression";
|
|
42
|
-
}
|
|
45
|
+
};
|
|
43
46
|
exports.isFunctionExpression = isFunctionExpression;
|
|
44
|
-
|
|
47
|
+
const isVariableDeclarator = (node) => {
|
|
45
48
|
return node.type === "VariableDeclarator";
|
|
46
|
-
}
|
|
49
|
+
};
|
|
47
50
|
exports.isVariableDeclarator = isVariableDeclarator;
|
|
48
|
-
|
|
51
|
+
const isVariableDeclaration = (node) => {
|
|
49
52
|
return node.type === "VariableDeclaration";
|
|
50
|
-
}
|
|
53
|
+
};
|
|
51
54
|
exports.isVariableDeclaration = isVariableDeclaration;
|
|
52
|
-
|
|
55
|
+
const isBinding = (node, parentNode, grandParentNode) => {
|
|
53
56
|
if (grandParentNode &&
|
|
54
57
|
node.type === "Identifier" &&
|
|
55
58
|
parentNode.type === "Property" &&
|
|
@@ -72,7 +75,7 @@ function isBinding(node, parentNode, grandParentNode) {
|
|
|
72
75
|
}
|
|
73
76
|
}
|
|
74
77
|
return false;
|
|
75
|
-
}
|
|
78
|
+
};
|
|
76
79
|
exports.isBinding = isBinding;
|
|
77
80
|
const bindingIdentifiersKeys = {
|
|
78
81
|
DeclareClass: ["id"],
|
|
@@ -148,6 +151,7 @@ exports.VISITOR_KEYS = {
|
|
|
148
151
|
FunctionExpression: ["id", "params", "body"],
|
|
149
152
|
Identifier: [],
|
|
150
153
|
IfStatement: ["test", "consequent", "alternate"],
|
|
154
|
+
ImportAttribute: ["key", "value"],
|
|
151
155
|
ImportDeclaration: ["specifiers", "source"],
|
|
152
156
|
ImportDefaultSpecifier: ["local"],
|
|
153
157
|
ImportNamespaceSpecifier: ["local"],
|
|
@@ -227,9 +231,8 @@ function isScope(node, parentNode) {
|
|
|
227
231
|
if (isPattern(node) && (isFunction(parentNode) || isCatchClause(parentNode))) {
|
|
228
232
|
return true;
|
|
229
233
|
}
|
|
230
|
-
return isFunctionDeclaration(parentNode) || isFunctionExpression(parentNode) || isScopable(node);
|
|
234
|
+
return (0, exports.isFunctionDeclaration)(parentNode) || (0, exports.isFunctionExpression)(parentNode) || isScopable(node);
|
|
231
235
|
}
|
|
232
|
-
exports.isScope = isScope;
|
|
233
236
|
function isScopable(node) {
|
|
234
237
|
switch (node.type) {
|
|
235
238
|
case "BlockStatement":
|
|
@@ -252,8 +255,6 @@ function isScopable(node) {
|
|
|
252
255
|
}
|
|
253
256
|
return false;
|
|
254
257
|
}
|
|
255
|
-
exports.isScopable = isScopable;
|
|
256
258
|
function isExportSpecifier(node) {
|
|
257
259
|
return node.type === "ExportSpecifier";
|
|
258
260
|
}
|
|
259
|
-
exports.isExportSpecifier = isExportSpecifier;
|
package/lib/cjs/parseQuery.js
CHANGED
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.tokenize = tokenize;
|
|
4
|
+
exports.parse = parse;
|
|
4
5
|
const _1 = require(".");
|
|
5
6
|
const nodeutils_1 = require("./nodeutils");
|
|
6
7
|
const debugLogEnabled = false;
|
|
7
8
|
const log = {
|
|
8
|
-
debug: (...args) => {
|
|
9
|
+
debug: debugLogEnabled ? (...args) => {
|
|
9
10
|
if (debugLogEnabled)
|
|
10
11
|
console.debug(...args);
|
|
11
|
-
}
|
|
12
|
+
} : () => { }
|
|
12
13
|
};
|
|
13
14
|
const supportedIdentifiers = Object.fromEntries(Object.keys(nodeutils_1.VISITOR_KEYS).map(k => [k, k]));
|
|
14
15
|
function isIdentifierToken(token) {
|
|
@@ -149,7 +150,6 @@ function tokenize(input) {
|
|
|
149
150
|
}
|
|
150
151
|
return result;
|
|
151
152
|
}
|
|
152
|
-
exports.tokenize = tokenize;
|
|
153
153
|
function buildFilter(tokens) {
|
|
154
154
|
log.debug("BUILD FILTER", tokens);
|
|
155
155
|
tokens.shift();
|
|
@@ -295,4 +295,3 @@ function parse(input) {
|
|
|
295
295
|
throw new Error("No root element found");
|
|
296
296
|
return result;
|
|
297
297
|
}
|
|
298
|
-
exports.parse = parse;
|