astronomical 1.0.0-beta.13 → 1.0.0-beta.15
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 +312 -323
- package/lib/cjs/nodeutils.js +13 -1
- package/lib/cjs/traverse.js +182 -139
- package/lib/cjs/types/index.d.ts +8 -3
- package/lib/cjs/types/index.d.ts.map +1 -1
- package/lib/cjs/types/nodeutils.d.ts +5 -1
- package/lib/cjs/types/nodeutils.d.ts.map +1 -1
- package/lib/cjs/types/traverse.d.ts +9 -4
- package/lib/cjs/types/traverse.d.ts.map +1 -1
- package/lib/cjs/types/utils.d.ts +3 -0
- package/lib/cjs/types/utils.d.ts.map +1 -0
- package/lib/cjs/utils.js +11 -0
- package/lib/esm/index.mjs +312 -323
- package/lib/esm/nodeutils.js +13 -1
- package/lib/esm/traverse.js +182 -139
- package/lib/esm/types/index.d.ts +8 -3
- package/lib/esm/types/index.d.ts.map +1 -1
- package/lib/esm/types/nodeutils.d.ts +5 -1
- package/lib/esm/types/nodeutils.d.ts.map +1 -1
- package/lib/esm/types/traverse.d.ts +9 -4
- package/lib/esm/types/traverse.d.ts.map +1 -1
- package/lib/esm/types/utils.d.ts +3 -0
- package/lib/esm/types/utils.d.ts.map +1 -0
- package/lib/esm/utils.js +11 -0
- package/package.json +1 -1
package/lib/cjs/index.js
CHANGED
|
@@ -1,32 +1,13 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var
|
|
3
|
-
|
|
4
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
-
}) : function(o, v) {
|
|
16
|
-
o["default"] = v;
|
|
17
|
-
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
-
if (mod && mod.__esModule) return mod;
|
|
20
|
-
var result = {};
|
|
21
|
-
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
-
__setModuleDefault(result, mod);
|
|
23
|
-
return result;
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
24
4
|
};
|
|
25
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
6
|
exports.parseSource = exports.multiQuery = exports.query = exports.isAvailableFunction = exports.functions = void 0;
|
|
27
|
-
const traverse_1 =
|
|
7
|
+
const traverse_1 = __importDefault(require("./traverse"));
|
|
28
8
|
const parseQuery_1 = require("./parseQuery");
|
|
29
9
|
const meriyah_1 = require("meriyah");
|
|
10
|
+
const nodeutils_1 = require("./nodeutils");
|
|
30
11
|
const debugLogEnabled = false;
|
|
31
12
|
const log = {
|
|
32
13
|
debug: (...args) => {
|
|
@@ -83,10 +64,6 @@ function isAvailableFunction(name) {
|
|
|
83
64
|
return functionNames.includes(name);
|
|
84
65
|
}
|
|
85
66
|
exports.isAvailableFunction = isAvailableFunction;
|
|
86
|
-
function beginHandle(queries, path) {
|
|
87
|
-
const rootPath = (0, traverse_1.createNodePath)(path, undefined, undefined, undefined);
|
|
88
|
-
return travHandle(queries, rootPath);
|
|
89
|
-
}
|
|
90
67
|
function breadCrumb(path) {
|
|
91
68
|
return {
|
|
92
69
|
valueOf() {
|
|
@@ -96,354 +73,366 @@ function breadCrumb(path) {
|
|
|
96
73
|
}
|
|
97
74
|
};
|
|
98
75
|
}
|
|
99
|
-
function
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
76
|
+
function createQuerier() {
|
|
77
|
+
const traverser = (0, traverse_1.default)();
|
|
78
|
+
const { getChildren, getPrimitiveChildren, getPrimitiveChildrenOrNodePaths, getBinding, createNodePath, traverse } = traverser;
|
|
79
|
+
function createFilter(filter, filterResult) {
|
|
80
|
+
if (filter.type == "and" || filter.type == "or" || filter.type == "equals") {
|
|
81
|
+
return {
|
|
82
|
+
type: filter.type,
|
|
83
|
+
left: createFilter(filter.left, []),
|
|
84
|
+
right: createFilter(filter.right, [])
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
else if (filter.type == "literal") {
|
|
88
|
+
const r = [filter.value];
|
|
89
|
+
return {
|
|
90
|
+
node: filter,
|
|
91
|
+
result: r
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
return createFNode(filter, filterResult);
|
|
106
95
|
}
|
|
107
|
-
|
|
108
|
-
const r = [filter.value];
|
|
96
|
+
function createFNode(token, result) {
|
|
109
97
|
return {
|
|
110
|
-
node:
|
|
111
|
-
result:
|
|
98
|
+
node: token,
|
|
99
|
+
result: result
|
|
112
100
|
};
|
|
113
101
|
}
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
node: token,
|
|
119
|
-
result: result
|
|
120
|
-
};
|
|
121
|
-
}
|
|
122
|
-
function addFilterChildrenToState(filter, state) {
|
|
123
|
-
if ("type" in filter && (filter.type == "and" || filter.type == "or" || filter.type == "equals")) {
|
|
124
|
-
addFilterChildrenToState(filter.left, state);
|
|
125
|
-
addFilterChildrenToState(filter.right, state);
|
|
126
|
-
}
|
|
127
|
-
else if ("node" in filter) {
|
|
128
|
-
if (filter.node.type == "child") {
|
|
129
|
-
log.debug("ADDING FILTER CHILD", filter.node);
|
|
130
|
-
state.child[state.depth + 1].push(filter);
|
|
102
|
+
function addFilterChildrenToState(filter, state) {
|
|
103
|
+
if ("type" in filter && (filter.type == "and" || filter.type == "or" || filter.type == "equals")) {
|
|
104
|
+
addFilterChildrenToState(filter.left, state);
|
|
105
|
+
addFilterChildrenToState(filter.right, state);
|
|
131
106
|
}
|
|
132
|
-
if (
|
|
133
|
-
|
|
134
|
-
|
|
107
|
+
else if ("node" in filter) {
|
|
108
|
+
if (filter.node.type == "child") {
|
|
109
|
+
log.debug("ADDING FILTER CHILD", filter.node);
|
|
110
|
+
state.child[state.depth + 1].push(filter);
|
|
111
|
+
}
|
|
112
|
+
if (filter.node.type == "descendant") {
|
|
113
|
+
log.debug("ADDING FILTER DESCENDANT", filter.node);
|
|
114
|
+
state.descendant[state.depth + 1].push(filter);
|
|
115
|
+
}
|
|
135
116
|
}
|
|
136
117
|
}
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
118
|
+
function createFNodeAndAddToState(token, result, state) {
|
|
119
|
+
log.debug("ADDING FNODE", token);
|
|
120
|
+
const fnode = createFNode(token, result);
|
|
121
|
+
if (token.type == "child") {
|
|
122
|
+
state.child[state.depth + 1].push(fnode);
|
|
123
|
+
}
|
|
124
|
+
else if (token.type == "descendant") {
|
|
125
|
+
state.descendant[state.depth + 1].push(fnode);
|
|
126
|
+
}
|
|
127
|
+
return fnode;
|
|
146
128
|
}
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
129
|
+
function isMatch(fnode, path) {
|
|
130
|
+
if (fnode.node.attribute) {
|
|
131
|
+
const m = fnode.node.value == path.parentKey || fnode.node.value == path.key;
|
|
132
|
+
if (m)
|
|
133
|
+
log.debug("ATTR MATCH", fnode.node.value, breadCrumb(path));
|
|
134
|
+
return m;
|
|
135
|
+
}
|
|
136
|
+
if (fnode.node.value == "*") {
|
|
137
|
+
return true;
|
|
138
|
+
}
|
|
139
|
+
const m = fnode.node.value == path.node.type;
|
|
152
140
|
if (m)
|
|
153
|
-
log.debug("
|
|
141
|
+
log.debug("NODE MATCH", fnode.node.value, breadCrumb(path));
|
|
154
142
|
return m;
|
|
155
143
|
}
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
144
|
+
function addIfTokenMatch(fnode, path, state) {
|
|
145
|
+
if (!isMatch(fnode, path))
|
|
146
|
+
return;
|
|
147
|
+
state.matches[state.depth].push([fnode, path]);
|
|
148
|
+
if (fnode.node.filter) {
|
|
149
|
+
const filter = createFilter(fnode.node.filter, []);
|
|
150
|
+
const filteredResult = [];
|
|
151
|
+
state.filters[state.depth].push({ filter: filter, qNode: fnode.node, node: path.node, result: filteredResult });
|
|
152
|
+
addFilterChildrenToState(filter, state);
|
|
153
|
+
const child = fnode.node.child;
|
|
154
|
+
if (child) {
|
|
155
|
+
if (child.type == "function") {
|
|
156
|
+
const fr = addFunction(fnode, child, path, state);
|
|
157
|
+
state.functionCalls[state.depth].push(fr);
|
|
158
|
+
}
|
|
159
|
+
else {
|
|
160
|
+
createFNodeAndAddToState(child, filteredResult, state);
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
else {
|
|
165
|
+
const child = fnode.node.child;
|
|
166
|
+
if (child?.type == "function") {
|
|
176
167
|
const fr = addFunction(fnode, child, path, state);
|
|
177
168
|
state.functionCalls[state.depth].push(fr);
|
|
178
169
|
}
|
|
179
|
-
else {
|
|
180
|
-
createFNodeAndAddToState(child,
|
|
170
|
+
else if (child && !fnode.node.binding && !fnode.node.resolve) {
|
|
171
|
+
createFNodeAndAddToState(child, fnode.result, state);
|
|
181
172
|
}
|
|
182
173
|
}
|
|
183
174
|
}
|
|
184
|
-
|
|
185
|
-
const
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
}
|
|
190
|
-
else if (child && !fnode.node.binding && !fnode.node.resolve) {
|
|
191
|
-
createFNodeAndAddToState(child, fnode.result, state);
|
|
192
|
-
}
|
|
193
|
-
}
|
|
194
|
-
}
|
|
195
|
-
function addFunction(rootNode, functionCall, path, state) {
|
|
196
|
-
const functionNode = { node: rootNode.node, functionCall: functionCall, parameters: [], result: [] };
|
|
197
|
-
for (const param of functionCall.parameters) {
|
|
198
|
-
if (param.type == "literal") {
|
|
199
|
-
functionNode.parameters.push({ node: param, result: [param.value] });
|
|
200
|
-
}
|
|
201
|
-
else {
|
|
202
|
-
if (param.type == "function") {
|
|
203
|
-
functionNode.parameters.push(addFunction(functionNode, param, path, state));
|
|
175
|
+
function addFunction(rootNode, functionCall, path, state) {
|
|
176
|
+
const functionNode = { node: rootNode.node, functionCall: functionCall, parameters: [], result: [] };
|
|
177
|
+
for (const param of functionCall.parameters) {
|
|
178
|
+
if (param.type == "literal") {
|
|
179
|
+
functionNode.parameters.push({ node: param, result: [param.value] });
|
|
204
180
|
}
|
|
205
181
|
else {
|
|
206
|
-
|
|
182
|
+
if (param.type == "function") {
|
|
183
|
+
functionNode.parameters.push(addFunction(functionNode, param, path, state));
|
|
184
|
+
}
|
|
185
|
+
else {
|
|
186
|
+
functionNode.parameters.push(createFNodeAndAddToState(param, [], state));
|
|
187
|
+
}
|
|
207
188
|
}
|
|
208
189
|
}
|
|
190
|
+
return functionNode;
|
|
209
191
|
}
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
.
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
return evaluateFilter(filter.right, path);
|
|
192
|
+
function addPrimitiveAttributeIfMatch(fnode, path) {
|
|
193
|
+
if (!fnode.node.attribute || fnode.node.value == undefined)
|
|
194
|
+
return;
|
|
195
|
+
if (fnode.node.child || fnode.node.filter)
|
|
196
|
+
return;
|
|
197
|
+
if (!Object.hasOwn(path.node, fnode.node.value))
|
|
198
|
+
return;
|
|
199
|
+
const nodes = getPrimitiveChildren(fnode.node.value, path);
|
|
200
|
+
if (nodes.length == 0)
|
|
201
|
+
return;
|
|
202
|
+
log.debug("PRIMITIVE", fnode.node.value, nodes);
|
|
203
|
+
fnode.result.push(...nodes);
|
|
204
|
+
}
|
|
205
|
+
function evaluateFilter(filter, path) {
|
|
206
|
+
log.debug("EVALUATING FILTER", filter, breadCrumb(path));
|
|
207
|
+
if ("type" in filter) {
|
|
208
|
+
if (filter.type == "and") {
|
|
209
|
+
const left = evaluateFilter(filter.left, path);
|
|
210
|
+
if (left.length == 0)
|
|
211
|
+
return [];
|
|
212
|
+
return evaluateFilter(filter.right, path);
|
|
213
|
+
}
|
|
214
|
+
if (filter.type == "or") {
|
|
215
|
+
const left = evaluateFilter(filter.left, path);
|
|
216
|
+
if (left.length > 0)
|
|
217
|
+
return left;
|
|
218
|
+
return evaluateFilter(filter.right, path);
|
|
219
|
+
}
|
|
220
|
+
if (filter.type == "equals") {
|
|
221
|
+
const left = evaluateFilter(filter.left, path);
|
|
222
|
+
const right = evaluateFilter(filter.right, path);
|
|
223
|
+
return left.filter(x => right.includes(x));
|
|
224
|
+
}
|
|
225
|
+
throw new Error("Unknown filter type: " + filter.type);
|
|
245
226
|
}
|
|
246
|
-
if (filter.type == "
|
|
247
|
-
|
|
248
|
-
const right = evaluateFilter(filter.right, path);
|
|
249
|
-
return left.filter(x => right.includes(x));
|
|
227
|
+
if (filter.node.type == "parent") {
|
|
228
|
+
return resolveFilterWithParent(filter.node, path);
|
|
250
229
|
}
|
|
251
|
-
|
|
230
|
+
return filter.result;
|
|
252
231
|
}
|
|
253
|
-
|
|
254
|
-
|
|
232
|
+
function resolveBinding(path) {
|
|
233
|
+
if (!(0, nodeutils_1.isIdentifier)(path.node))
|
|
234
|
+
return undefined;
|
|
235
|
+
log.debug("RESOLVING BINDING FOR ", path.node);
|
|
236
|
+
const name = path.node.name;
|
|
237
|
+
if (name == undefined || typeof name != "string")
|
|
238
|
+
return undefined;
|
|
239
|
+
//const binding = path.scope.getBinding(name);
|
|
240
|
+
const binding = getBinding(path.scopeId, name);
|
|
241
|
+
if (!binding)
|
|
242
|
+
return undefined;
|
|
243
|
+
log.debug("THIS IS THE BINDING", binding);
|
|
244
|
+
return binding.path;
|
|
255
245
|
}
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
const binding = (0, traverse_1.getBinding)(path.scopeId, name);
|
|
270
|
-
if (!binding)
|
|
271
|
-
return undefined;
|
|
272
|
-
log.debug("THIS IS THE BINDING", binding);
|
|
273
|
-
return binding.path;
|
|
274
|
-
}
|
|
275
|
-
function resolveFilterWithParent(node, path) {
|
|
276
|
-
let startNode = node;
|
|
277
|
-
let startPath = path;
|
|
278
|
-
while (startNode.type == "parent") {
|
|
279
|
-
if (!startNode.child)
|
|
280
|
-
throw new Error("Parent filter must have child");
|
|
281
|
-
if (!startPath.parentPath)
|
|
282
|
-
return [];
|
|
283
|
-
log.debug("STEP OUT", startNode, breadCrumb(startPath));
|
|
284
|
-
startNode = startNode.child;
|
|
285
|
-
startPath = startPath.parentPath;
|
|
246
|
+
function resolveFilterWithParent(node, path) {
|
|
247
|
+
let startNode = node;
|
|
248
|
+
let startPath = path;
|
|
249
|
+
while (startNode.type == "parent") {
|
|
250
|
+
if (!startNode.child)
|
|
251
|
+
throw new Error("Parent filter must have child");
|
|
252
|
+
if (!startPath.parentPath)
|
|
253
|
+
return [];
|
|
254
|
+
log.debug("STEP OUT", startNode, breadCrumb(startPath));
|
|
255
|
+
startNode = startNode.child;
|
|
256
|
+
startPath = startPath.parentPath;
|
|
257
|
+
}
|
|
258
|
+
return resolveDirectly(startNode, startPath);
|
|
286
259
|
}
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
260
|
+
function isDefined(value) {
|
|
261
|
+
return value != undefined && value != null;
|
|
262
|
+
}
|
|
263
|
+
let subQueryCounter = 0;
|
|
264
|
+
function resolveDirectly(node, path) {
|
|
265
|
+
let startNode = node;
|
|
266
|
+
const startPath = path;
|
|
267
|
+
let paths = [startPath];
|
|
268
|
+
while (startNode.attribute && startNode.type == "child") {
|
|
269
|
+
const lookup = startNode.value;
|
|
270
|
+
if (!lookup)
|
|
271
|
+
throw new Error("Selector must have a value");
|
|
272
|
+
//log.debug("STEP IN ", lookup, paths.map(p => breadCrumb(p)));
|
|
273
|
+
const nodes = paths.filter(nodeutils_1.isNodePath).map(n => getPrimitiveChildrenOrNodePaths(lookup, n)).flat();
|
|
274
|
+
//log.debug("LOOKUP", lookup, path.node.type, nodes.map(n => n.node));
|
|
275
|
+
//console.log(nodes);
|
|
276
|
+
if (nodes.length == 0)
|
|
277
|
+
return [];
|
|
278
|
+
paths = nodes;
|
|
279
|
+
if (startNode.resolve) {
|
|
280
|
+
const resolved = paths.filter(nodeutils_1.isNodePath).map(p => resolveBinding(p)).filter(isDefined).map(p => getChildren("init", p)).flat();
|
|
281
|
+
if (resolved.length > 0)
|
|
282
|
+
paths = resolved;
|
|
283
|
+
}
|
|
284
|
+
else if (startNode.binding) {
|
|
285
|
+
paths = paths.filter(nodeutils_1.isNodePath).map(p => resolveBinding(p)).filter(isDefined);
|
|
286
|
+
}
|
|
287
|
+
const filter = startNode.filter;
|
|
288
|
+
if (filter) {
|
|
289
|
+
paths = paths.filter(nodeutils_1.isNodePath).filter(p => travHandle({ subquery: filter }, p).subquery.length > 0);
|
|
290
|
+
}
|
|
291
|
+
if (!startNode.child) {
|
|
292
|
+
return paths.map(p => (0, nodeutils_1.isPrimitive)(p) ? p : p.node);
|
|
293
|
+
}
|
|
294
|
+
startNode = startNode.child;
|
|
312
295
|
}
|
|
313
|
-
|
|
314
|
-
|
|
296
|
+
//log.debug("DIRECT TRAV RESOLVE", startNode, paths.map(p => breadCrumb(p)));
|
|
297
|
+
const result = paths.filter(nodeutils_1.isNodePath).flatMap(path => {
|
|
298
|
+
const subQueryKey = "subquery-" + subQueryCounter++;
|
|
299
|
+
return travHandle({ [subQueryKey]: startNode }, path)[subQueryKey];
|
|
300
|
+
});
|
|
301
|
+
log.debug("DIRECT TRAV RESOLVE RESULT", result);
|
|
302
|
+
return result;
|
|
303
|
+
}
|
|
304
|
+
function addResultIfTokenMatch(fnode, path, state) {
|
|
305
|
+
const filters = state.filters[state.depth].filter(f => f.node == path.node && f.qNode == fnode.node);
|
|
306
|
+
const matchingFilters = filters.filter(f => evaluateFilter(f.filter, path).length > 0);
|
|
307
|
+
log.debug("RESULT MATCH", fnode.node.value, breadCrumb(path), filters.length, matchingFilters.length);
|
|
308
|
+
if (filters.length > 0 && matchingFilters.length == 0)
|
|
309
|
+
return;
|
|
310
|
+
if (fnode.node.resolve) {
|
|
311
|
+
const binding = resolveBinding(path);
|
|
312
|
+
const resolved = binding ? getChildren("init", binding)[0] : undefined;
|
|
313
|
+
if (fnode.node.child) {
|
|
314
|
+
const result = resolveDirectly(fnode.node.child, resolved ?? path);
|
|
315
|
+
fnode.result.push(...result);
|
|
316
|
+
}
|
|
317
|
+
else {
|
|
318
|
+
fnode.result.push(path.node);
|
|
319
|
+
}
|
|
315
320
|
}
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
321
|
+
else if (fnode.node.binding) {
|
|
322
|
+
const binding = resolveBinding(path);
|
|
323
|
+
if (binding) {
|
|
324
|
+
if (fnode.node.child) {
|
|
325
|
+
const result = resolveDirectly(fnode.node.child, binding);
|
|
326
|
+
fnode.result.push(...result);
|
|
327
|
+
}
|
|
328
|
+
else {
|
|
329
|
+
fnode.result.push(binding.node);
|
|
330
|
+
}
|
|
331
|
+
}
|
|
319
332
|
}
|
|
320
|
-
if (!
|
|
321
|
-
|
|
333
|
+
else if (!fnode.node.child) {
|
|
334
|
+
fnode.result.push(path.node);
|
|
322
335
|
}
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
return travHandle({ [subQueryKey]: startNode }, path)[subQueryKey];
|
|
329
|
-
});
|
|
330
|
-
log.debug("DIRECT TRAV RESOLVE RESULT", result);
|
|
331
|
-
return result;
|
|
332
|
-
}
|
|
333
|
-
function addResultIfTokenMatch(fnode, path, state) {
|
|
334
|
-
const filters = state.filters[state.depth].filter(f => f.node == path.node && f.qNode == fnode.node);
|
|
335
|
-
const matchingFilters = filters.filter(f => evaluateFilter(f.filter, path).length > 0);
|
|
336
|
-
log.debug("RESULT MATCH", fnode.node.value, breadCrumb(path), filters.length, matchingFilters.length);
|
|
337
|
-
if (filters.length > 0 && matchingFilters.length == 0)
|
|
338
|
-
return;
|
|
339
|
-
if (fnode.node.resolve) {
|
|
340
|
-
const binding = resolveBinding(path);
|
|
341
|
-
const resolved = binding ? (0, traverse_1.getChildren)("init", binding)[0] : undefined;
|
|
342
|
-
if (fnode.node.child) {
|
|
343
|
-
const result = resolveDirectly(fnode.node.child, resolved ?? path);
|
|
344
|
-
fnode.result.push(...result);
|
|
336
|
+
else if (fnode.node.child.type == "function") {
|
|
337
|
+
const functionCallResult = state.functionCalls[state.depth].find(f => f.node == fnode.node);
|
|
338
|
+
if (!functionCallResult)
|
|
339
|
+
throw new Error("Did not find expected function call for " + fnode.node.child.function);
|
|
340
|
+
resolveFunctionCalls(fnode, functionCallResult, path, state);
|
|
345
341
|
}
|
|
346
|
-
else {
|
|
347
|
-
fnode.result.
|
|
342
|
+
else if (matchingFilters.length > 0) {
|
|
343
|
+
log.debug("HAS MATCHING FILTER", fnode.result.length, matchingFilters.length, breadCrumb(path));
|
|
344
|
+
fnode.result.push(...matchingFilters.flatMap(f => f.result));
|
|
348
345
|
}
|
|
349
346
|
}
|
|
350
|
-
|
|
351
|
-
const
|
|
352
|
-
|
|
353
|
-
if (
|
|
354
|
-
|
|
355
|
-
|
|
347
|
+
function resolveFunctionCalls(fnode, functionCallResult, path, state) {
|
|
348
|
+
const parameterResults = [];
|
|
349
|
+
for (const p of functionCallResult.parameters) {
|
|
350
|
+
if ("parameters" in p) {
|
|
351
|
+
resolveFunctionCalls(p, p, path, state);
|
|
352
|
+
parameterResults.push(p.result);
|
|
356
353
|
}
|
|
357
354
|
else {
|
|
358
|
-
|
|
355
|
+
parameterResults.push(p.result);
|
|
359
356
|
}
|
|
360
357
|
}
|
|
358
|
+
const functionResult = exports.functions[functionCallResult.functionCall.function].fn(parameterResults);
|
|
359
|
+
log.debug("PARAMETER RESULTS", functionCallResult.functionCall.function, parameterResults, functionResult);
|
|
360
|
+
fnode.result.push(...functionResult);
|
|
361
361
|
}
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
362
|
+
function travHandle(queries, root) {
|
|
363
|
+
const results = Object.fromEntries(Object.keys(queries).map(name => [name, []]));
|
|
364
|
+
const state = {
|
|
365
|
+
depth: 0,
|
|
366
|
+
child: [[], []],
|
|
367
|
+
descendant: [[], []],
|
|
368
|
+
filters: [[], []],
|
|
369
|
+
matches: [[]],
|
|
370
|
+
functionCalls: [[]]
|
|
371
|
+
};
|
|
372
|
+
Object.entries(queries).forEach(([name, node]) => {
|
|
373
|
+
createFNodeAndAddToState(node, results[name], state);
|
|
374
|
+
});
|
|
375
|
+
state.child[state.depth + 1].forEach(fnode => addPrimitiveAttributeIfMatch(fnode, root));
|
|
376
|
+
state.descendant.slice(0, state.depth + 1).forEach(fnodes => fnodes.forEach(fnode => addPrimitiveAttributeIfMatch(fnode, root)));
|
|
377
|
+
traverse(root.node, {
|
|
378
|
+
enter(path, state) {
|
|
379
|
+
log.debug("ENTER", breadCrumb(path));
|
|
380
|
+
state.depth++;
|
|
381
|
+
state.child.push([]);
|
|
382
|
+
state.descendant.push([]);
|
|
383
|
+
state.filters.push([]);
|
|
384
|
+
state.matches.push([]);
|
|
385
|
+
state.functionCalls.push([]);
|
|
386
|
+
state.child[state.depth].forEach(fnode => addIfTokenMatch(fnode, path, state));
|
|
387
|
+
state.descendant.slice(0, state.depth + 1).forEach(fnodes => fnodes.forEach(fnode => addIfTokenMatch(fnode, path, state)));
|
|
388
|
+
},
|
|
389
|
+
exit(path, state) {
|
|
390
|
+
log.debug("EXIT", breadCrumb(path));
|
|
391
|
+
// Check for attributes as not all attributes are visited
|
|
392
|
+
state.child[state.depth + 1].forEach(fnode => addPrimitiveAttributeIfMatch(fnode, path));
|
|
393
|
+
state.descendant.forEach(fnodes => fnodes.forEach(fnode => addPrimitiveAttributeIfMatch(fnode, path)));
|
|
394
|
+
state.matches[state.depth].forEach(([fNode, path]) => addResultIfTokenMatch(fNode, path, state));
|
|
395
|
+
state.depth--;
|
|
396
|
+
state.child.pop();
|
|
397
|
+
state.descendant.pop();
|
|
398
|
+
state.filters.pop();
|
|
399
|
+
state.matches.pop();
|
|
400
|
+
state.functionCalls.pop();
|
|
401
|
+
}
|
|
402
|
+
}, root.scopeId, state, root);
|
|
403
|
+
return results;
|
|
374
404
|
}
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
for (const p of functionCallResult.parameters) {
|
|
379
|
-
if ("parameters" in p) {
|
|
380
|
-
resolveFunctionCalls(p, p, path, state);
|
|
381
|
-
parameterResults.push(p.result);
|
|
382
|
-
}
|
|
383
|
-
else {
|
|
384
|
-
parameterResults.push(p.result);
|
|
385
|
-
}
|
|
405
|
+
function beginHandle(queries, path) {
|
|
406
|
+
const rootPath = createNodePath(path, undefined, undefined, undefined);
|
|
407
|
+
return travHandle(queries, rootPath);
|
|
386
408
|
}
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
fnode.result.push(...functionResult);
|
|
390
|
-
}
|
|
391
|
-
function travHandle(queries, root) {
|
|
392
|
-
const results = Object.fromEntries(Object.keys(queries).map(name => [name, []]));
|
|
393
|
-
const state = {
|
|
394
|
-
depth: 0,
|
|
395
|
-
child: [[], []],
|
|
396
|
-
descendant: [[], []],
|
|
397
|
-
filters: [[], []],
|
|
398
|
-
matches: [[]],
|
|
399
|
-
functionCalls: [[]]
|
|
409
|
+
return {
|
|
410
|
+
beginHandle
|
|
400
411
|
};
|
|
401
|
-
Object.entries(queries).forEach(([name, node]) => {
|
|
402
|
-
createFNodeAndAddToState(node, results[name], state);
|
|
403
|
-
});
|
|
404
|
-
state.child[state.depth + 1].forEach(fnode => addPrimitiveAttributeIfMatch(fnode, root));
|
|
405
|
-
state.descendant.slice(0, state.depth + 1).forEach(fnodes => fnodes.forEach(fnode => addPrimitiveAttributeIfMatch(fnode, root)));
|
|
406
|
-
(0, traverse_1.default)(root.node, {
|
|
407
|
-
enter(path, state) {
|
|
408
|
-
log.debug("ENTER", breadCrumb(path));
|
|
409
|
-
state.depth++;
|
|
410
|
-
state.child.push([]);
|
|
411
|
-
state.descendant.push([]);
|
|
412
|
-
state.filters.push([]);
|
|
413
|
-
state.matches.push([]);
|
|
414
|
-
state.functionCalls.push([]);
|
|
415
|
-
state.child[state.depth].forEach(fnode => addIfTokenMatch(fnode, path, state));
|
|
416
|
-
state.descendant.slice(0, state.depth + 1).forEach(fnodes => fnodes.forEach(fnode => addIfTokenMatch(fnode, path, state)));
|
|
417
|
-
},
|
|
418
|
-
exit(path, state) {
|
|
419
|
-
log.debug("EXIT", breadCrumb(path));
|
|
420
|
-
// Check for attributes as not all attributes are visited
|
|
421
|
-
state.child[state.depth + 1].forEach(fnode => addPrimitiveAttributeIfMatch(fnode, path));
|
|
422
|
-
state.descendant.forEach(fnodes => fnodes.forEach(fnode => addPrimitiveAttributeIfMatch(fnode, path)));
|
|
423
|
-
state.matches[state.depth].forEach(([fNode, path]) => addResultIfTokenMatch(fNode, path, state));
|
|
424
|
-
state.depth--;
|
|
425
|
-
state.child.pop();
|
|
426
|
-
state.descendant.pop();
|
|
427
|
-
state.filters.pop();
|
|
428
|
-
state.matches.pop();
|
|
429
|
-
state.functionCalls.pop();
|
|
430
|
-
}
|
|
431
|
-
}, root.scopeId, state, root);
|
|
432
|
-
return results;
|
|
433
412
|
}
|
|
434
413
|
const defaultKey = "__default__";
|
|
435
|
-
function query(code, query) {
|
|
436
|
-
|
|
414
|
+
function query(code, query, returnAST) {
|
|
415
|
+
const result = multiQuery(code, { [defaultKey]: query }, returnAST);
|
|
416
|
+
if (returnAST) {
|
|
417
|
+
const r = result[defaultKey];
|
|
418
|
+
r.__AST = result.__AST;
|
|
419
|
+
return r;
|
|
420
|
+
}
|
|
421
|
+
return result[defaultKey];
|
|
437
422
|
}
|
|
438
423
|
exports.query = query;
|
|
439
|
-
function multiQuery(code, namedQueries) {
|
|
424
|
+
function multiQuery(code, namedQueries, returnAST) {
|
|
440
425
|
const start = Date.now();
|
|
441
426
|
const ast = typeof code == "string" ? parseSource(code) : code;
|
|
442
427
|
if (ast == null)
|
|
443
428
|
throw new Error("Could not pase code");
|
|
444
429
|
const queries = Object.fromEntries(Object.entries(namedQueries).map(([name, query]) => [name, (0, parseQuery_1.parse)(query)]));
|
|
445
|
-
const
|
|
430
|
+
const querier = createQuerier();
|
|
431
|
+
const result = querier.beginHandle(queries, ast);
|
|
446
432
|
log.debug("Query time: ", Date.now() - start);
|
|
433
|
+
if (returnAST) {
|
|
434
|
+
return { ...result, __AST: ast };
|
|
435
|
+
}
|
|
447
436
|
return result;
|
|
448
437
|
}
|
|
449
438
|
exports.multiQuery = multiQuery;
|