astronomical 1.0.0-beta.12 → 1.0.0-beta.14
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 +315 -318
- package/lib/cjs/nodeutils.js +5 -1
- package/lib/cjs/traverse.js +149 -172
- package/lib/cjs/types/index.d.ts +7 -3
- package/lib/cjs/types/index.d.ts.map +1 -1
- package/lib/cjs/types/nodeutils.d.ts +2 -3
- package/lib/cjs/types/nodeutils.d.ts.map +1 -1
- package/lib/cjs/types/traverse.d.ts +19 -14
- 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 +315 -318
- package/lib/esm/nodeutils.js +5 -1
- package/lib/esm/traverse.js +149 -172
- package/lib/esm/types/index.d.ts +7 -3
- package/lib/esm/types/index.d.ts.map +1 -1
- package/lib/esm/types/nodeutils.d.ts +2 -3
- package/lib/esm/types/nodeutils.d.ts.map +1 -1
- package/lib/esm/types/traverse.d.ts +19 -14
- 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 +2 -2
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,349 +73,369 @@ 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, 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
|
-
|
|
192
|
+
function addPrimitiveAttributeIfMatch(fnode, path) {
|
|
193
|
+
if (!fnode.node.attribute || !fnode.node.value)
|
|
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 lookup = getChildren(fnode.node.value, path);
|
|
200
|
+
const nodes = toArray(lookup)
|
|
201
|
+
.filter(n => n.node != undefined)
|
|
202
|
+
.filter(n => (0, nodeutils_1.isPrimitive)(n.node));
|
|
203
|
+
if (nodes.length == 0)
|
|
204
|
+
return;
|
|
205
|
+
log.debug("PRIMITIVE", fnode.node.value, nodes.map(n => n.node));
|
|
206
|
+
fnode.result.push(...nodes.map(n => n.node));
|
|
207
|
+
}
|
|
208
|
+
function evaluateFilter(filter, path) {
|
|
209
|
+
log.debug("EVALUATING FILTER", filter, breadCrumb(path));
|
|
210
|
+
if ("type" in filter) {
|
|
211
|
+
if (filter.type == "and") {
|
|
212
|
+
const left = evaluateFilter(filter.left, path);
|
|
213
|
+
if (left.length == 0)
|
|
214
|
+
return [];
|
|
215
|
+
return evaluateFilter(filter.right, path);
|
|
216
|
+
}
|
|
217
|
+
if (filter.type == "or") {
|
|
218
|
+
const left = evaluateFilter(filter.left, path);
|
|
219
|
+
if (left.length > 0)
|
|
220
|
+
return left;
|
|
221
|
+
return evaluateFilter(filter.right, path);
|
|
222
|
+
}
|
|
223
|
+
if (filter.type == "equals") {
|
|
224
|
+
const left = evaluateFilter(filter.left, path);
|
|
225
|
+
const right = evaluateFilter(filter.right, path);
|
|
226
|
+
return left.filter(x => right.includes(x));
|
|
227
|
+
}
|
|
228
|
+
throw new Error("Unknown filter type: " + filter.type);
|
|
239
229
|
}
|
|
240
|
-
if (filter.type == "
|
|
241
|
-
|
|
242
|
-
if (left.length > 0)
|
|
243
|
-
return left;
|
|
244
|
-
return evaluateFilter(filter.right, path);
|
|
230
|
+
if (filter.node.type == "parent") {
|
|
231
|
+
return resolveFilterWithParent(filter.node, path);
|
|
245
232
|
}
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
233
|
+
return filter.result;
|
|
234
|
+
}
|
|
235
|
+
function resolveBinding(path) {
|
|
236
|
+
if (!(0, nodeutils_1.isIdentifier)(path.node))
|
|
237
|
+
return undefined;
|
|
238
|
+
log.debug("RESOLVING BINDING FOR ", path.node);
|
|
239
|
+
const name = path.node.name;
|
|
240
|
+
if (name == undefined || typeof name != "string")
|
|
241
|
+
return undefined;
|
|
242
|
+
//const binding = path.scope.getBinding(name);
|
|
243
|
+
const binding = getBinding(path.scopeId, name);
|
|
244
|
+
if (!binding)
|
|
245
|
+
return undefined;
|
|
246
|
+
log.debug("THIS IS THE BINDING", binding);
|
|
247
|
+
return binding.path;
|
|
248
|
+
}
|
|
249
|
+
function resolveFilterWithParent(node, path) {
|
|
250
|
+
let startNode = node;
|
|
251
|
+
let startPath = path;
|
|
252
|
+
while (startNode.type == "parent") {
|
|
253
|
+
if (!startNode.child)
|
|
254
|
+
throw new Error("Parent filter must have child");
|
|
255
|
+
if (!startPath.parentPath)
|
|
256
|
+
return [];
|
|
257
|
+
log.debug("STEP OUT", startNode, breadCrumb(startPath));
|
|
258
|
+
startNode = startNode.child;
|
|
259
|
+
startPath = startPath.parentPath;
|
|
250
260
|
}
|
|
251
|
-
|
|
261
|
+
return resolveDirectly(startNode, startPath);
|
|
252
262
|
}
|
|
253
|
-
|
|
254
|
-
|
|
263
|
+
const toArray = (value) => Array.isArray(value) ? value : [value];
|
|
264
|
+
function isDefined(value) {
|
|
265
|
+
return value != undefined && value != null;
|
|
255
266
|
}
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
267
|
+
let subQueryCounter = 0;
|
|
268
|
+
function resolveDirectly(node, path) {
|
|
269
|
+
let startNode = node;
|
|
270
|
+
const startPath = path;
|
|
271
|
+
let paths = [startPath];
|
|
272
|
+
while (startNode.attribute && startNode.type == "child") {
|
|
273
|
+
const lookup = startNode.value;
|
|
274
|
+
if (!lookup)
|
|
275
|
+
throw new Error("Selector must have a value");
|
|
276
|
+
log.debug("STEP IN ", lookup, paths.map(p => breadCrumb(p)));
|
|
277
|
+
const nodes = paths.map(n => getChildren(lookup, n)).map(toArray).flat().filter(n => n.node != undefined);
|
|
278
|
+
log.debug("LOOKUP", lookup, path.node.type, nodes.map(n => n.node), nodes.filter(n => n.node == undefined));
|
|
279
|
+
if (nodes.length == 0)
|
|
280
|
+
return [];
|
|
281
|
+
paths = nodes;
|
|
282
|
+
if (startNode.resolve) {
|
|
283
|
+
const resolved = paths.map(p => resolveBinding(p)).filter(isDefined).map(p => getChildren("init", p)).flatMap(toArray).filter(p => p.node != undefined).filter(isDefined);
|
|
284
|
+
if (resolved.length > 0)
|
|
285
|
+
paths = resolved;
|
|
286
|
+
}
|
|
287
|
+
else if (startNode.binding) {
|
|
288
|
+
paths = paths.map(p => resolveBinding(p)).filter(isDefined);
|
|
289
|
+
}
|
|
290
|
+
const filter = startNode.filter;
|
|
291
|
+
if (filter) {
|
|
292
|
+
paths = paths.filter(p => travHandle({ subquery: filter }, p).subquery.length > 0);
|
|
293
|
+
}
|
|
294
|
+
if (!startNode.child) {
|
|
295
|
+
return paths.map(p => p.node);
|
|
296
|
+
}
|
|
297
|
+
startNode = startNode.child;
|
|
298
|
+
}
|
|
299
|
+
log.debug("DIRECT TRAV RESOLVE", startNode, paths.map(p => breadCrumb(p)));
|
|
300
|
+
const result = paths.flatMap(path => {
|
|
301
|
+
const subQueryKey = "subquery-" + subQueryCounter++;
|
|
302
|
+
return travHandle({ [subQueryKey]: startNode }, path)[subQueryKey];
|
|
303
|
+
});
|
|
304
|
+
log.debug("DIRECT TRAV RESOLVE RESULT", result);
|
|
305
|
+
return result;
|
|
286
306
|
}
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
const
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
const nodes = paths.map(n => n.get(lookup)).map(toArray).flat().filter(n => n.node != undefined);
|
|
304
|
-
log.debug("LOOKUP", lookup, nodes.map(n => n.node), nodes.filter(n => n.node == undefined));
|
|
305
|
-
if (nodes.length == 0)
|
|
306
|
-
return [];
|
|
307
|
-
paths = nodes;
|
|
308
|
-
if (startNode.resolve) {
|
|
309
|
-
const resolved = paths.map(p => resolveBinding(p)).filter(isDefined).map(p => p.get("init")).flatMap(toArray).filter(p => p.node != undefined).filter(isDefined);
|
|
310
|
-
if (resolved.length > 0)
|
|
311
|
-
paths = resolved;
|
|
307
|
+
function addResultIfTokenMatch(fnode, path, state) {
|
|
308
|
+
const filters = state.filters[state.depth].filter(f => f.node == path.node && f.qNode == fnode.node);
|
|
309
|
+
const matchingFilters = filters.filter(f => evaluateFilter(f.filter, path).length > 0);
|
|
310
|
+
log.debug("RESULT MATCH", fnode.node.value, breadCrumb(path), filters.length, matchingFilters.length);
|
|
311
|
+
if (filters.length > 0 && matchingFilters.length == 0)
|
|
312
|
+
return;
|
|
313
|
+
if (fnode.node.resolve) {
|
|
314
|
+
const binding = resolveBinding(path);
|
|
315
|
+
const resolved = binding ? getChildren("init", binding)[0] : undefined;
|
|
316
|
+
if (fnode.node.child) {
|
|
317
|
+
const result = resolveDirectly(fnode.node.child, resolved ?? path);
|
|
318
|
+
fnode.result.push(...result);
|
|
319
|
+
}
|
|
320
|
+
else {
|
|
321
|
+
fnode.result.push(path.node);
|
|
322
|
+
}
|
|
312
323
|
}
|
|
313
|
-
else if (
|
|
314
|
-
|
|
324
|
+
else if (fnode.node.binding) {
|
|
325
|
+
const binding = resolveBinding(path);
|
|
326
|
+
if (binding) {
|
|
327
|
+
if (fnode.node.child) {
|
|
328
|
+
const result = resolveDirectly(fnode.node.child, binding);
|
|
329
|
+
fnode.result.push(...result);
|
|
330
|
+
}
|
|
331
|
+
else {
|
|
332
|
+
fnode.result.push(binding.node);
|
|
333
|
+
}
|
|
334
|
+
}
|
|
315
335
|
}
|
|
316
|
-
if (!
|
|
317
|
-
|
|
336
|
+
else if (!fnode.node.child) {
|
|
337
|
+
fnode.result.push(path.node);
|
|
318
338
|
}
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
return travHandle({ [subQueryKey]: startNode }, path)[subQueryKey];
|
|
325
|
-
});
|
|
326
|
-
log.debug("DIRECT TRAV RESOLVE RESULT", result);
|
|
327
|
-
return result;
|
|
328
|
-
}
|
|
329
|
-
function addResultIfTokenMatch(fnode, path, state) {
|
|
330
|
-
const filters = state.filters[state.depth].filter(f => f.node == path.node && f.qNode == fnode.node);
|
|
331
|
-
const matchingFilters = filters.filter(f => evaluateFilter(f.filter, path).length > 0);
|
|
332
|
-
log.debug("RESULT MATCH", fnode.node.value, breadCrumb(path), filters.length, matchingFilters.length);
|
|
333
|
-
if (filters.length > 0 && matchingFilters.length == 0)
|
|
334
|
-
return;
|
|
335
|
-
if (fnode.node.resolve) {
|
|
336
|
-
const [resolved] = toArray(resolveBinding(path)?.get("init")).filter(isDefined).filter(p => p.node != undefined);
|
|
337
|
-
if (fnode.node.child) {
|
|
338
|
-
const result = resolveDirectly(fnode.node.child, resolved ?? path);
|
|
339
|
-
fnode.result.push(...result);
|
|
339
|
+
else if (fnode.node.child.type == "function") {
|
|
340
|
+
const functionCallResult = state.functionCalls[state.depth].find(f => f.node == fnode.node);
|
|
341
|
+
if (!functionCallResult)
|
|
342
|
+
throw new Error("Did not find expected function call for " + fnode.node.child.function);
|
|
343
|
+
resolveFunctionCalls(fnode, functionCallResult, path, state);
|
|
340
344
|
}
|
|
341
|
-
else {
|
|
342
|
-
fnode.result.
|
|
345
|
+
else if (matchingFilters.length > 0) {
|
|
346
|
+
log.debug("HAS MATCHING FILTER", fnode.result.length, matchingFilters.length, breadCrumb(path));
|
|
347
|
+
fnode.result.push(...matchingFilters.flatMap(f => f.result));
|
|
343
348
|
}
|
|
344
349
|
}
|
|
345
|
-
|
|
346
|
-
const
|
|
347
|
-
|
|
348
|
-
if (
|
|
349
|
-
|
|
350
|
-
|
|
350
|
+
function resolveFunctionCalls(fnode, functionCallResult, path, state) {
|
|
351
|
+
const parameterResults = [];
|
|
352
|
+
for (const p of functionCallResult.parameters) {
|
|
353
|
+
if ("parameters" in p) {
|
|
354
|
+
resolveFunctionCalls(p, p, path, state);
|
|
355
|
+
parameterResults.push(p.result);
|
|
351
356
|
}
|
|
352
357
|
else {
|
|
353
|
-
|
|
358
|
+
parameterResults.push(p.result);
|
|
354
359
|
}
|
|
355
360
|
}
|
|
361
|
+
const functionResult = exports.functions[functionCallResult.functionCall.function].fn(parameterResults);
|
|
362
|
+
log.debug("PARAMETER RESULTS", functionCallResult.functionCall.function, parameterResults, functionResult);
|
|
363
|
+
fnode.result.push(...functionResult);
|
|
356
364
|
}
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
365
|
+
function travHandle(queries, root) {
|
|
366
|
+
const results = Object.fromEntries(Object.keys(queries).map(name => [name, []]));
|
|
367
|
+
const state = {
|
|
368
|
+
depth: 0,
|
|
369
|
+
child: [[], []],
|
|
370
|
+
descendant: [[], []],
|
|
371
|
+
filters: [[], []],
|
|
372
|
+
matches: [[]],
|
|
373
|
+
functionCalls: [[]]
|
|
374
|
+
};
|
|
375
|
+
Object.entries(queries).forEach(([name, node]) => {
|
|
376
|
+
createFNodeAndAddToState(node, results[name], state);
|
|
377
|
+
});
|
|
378
|
+
state.child[state.depth + 1].forEach(fnode => addPrimitiveAttributeIfMatch(fnode, root));
|
|
379
|
+
state.descendant.slice(0, state.depth + 1).forEach(fnodes => fnodes.forEach(fnode => addPrimitiveAttributeIfMatch(fnode, root)));
|
|
380
|
+
traverse(root.node, {
|
|
381
|
+
enter(path, state) {
|
|
382
|
+
log.debug("ENTER", breadCrumb(path));
|
|
383
|
+
state.depth++;
|
|
384
|
+
state.child.push([]);
|
|
385
|
+
state.descendant.push([]);
|
|
386
|
+
state.filters.push([]);
|
|
387
|
+
state.matches.push([]);
|
|
388
|
+
state.functionCalls.push([]);
|
|
389
|
+
state.child[state.depth].forEach(fnode => addIfTokenMatch(fnode, path, state));
|
|
390
|
+
state.descendant.slice(0, state.depth + 1).forEach(fnodes => fnodes.forEach(fnode => addIfTokenMatch(fnode, path, state)));
|
|
391
|
+
},
|
|
392
|
+
exit(path, state) {
|
|
393
|
+
log.debug("EXIT", breadCrumb(path));
|
|
394
|
+
// Check for attributes as not all attributes are visited
|
|
395
|
+
state.child[state.depth + 1].forEach(fnode => addPrimitiveAttributeIfMatch(fnode, path));
|
|
396
|
+
state.descendant.forEach(fnodes => fnodes.forEach(fnode => addPrimitiveAttributeIfMatch(fnode, path)));
|
|
397
|
+
state.matches[state.depth].forEach(([fNode, path]) => addResultIfTokenMatch(fNode, path, state));
|
|
398
|
+
state.depth--;
|
|
399
|
+
state.child.pop();
|
|
400
|
+
state.descendant.pop();
|
|
401
|
+
state.filters.pop();
|
|
402
|
+
state.matches.pop();
|
|
403
|
+
state.functionCalls.pop();
|
|
404
|
+
}
|
|
405
|
+
}, root.scopeId, state, root);
|
|
406
|
+
return results;
|
|
369
407
|
}
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
for (const p of functionCallResult.parameters) {
|
|
374
|
-
if ("parameters" in p) {
|
|
375
|
-
resolveFunctionCalls(p, p, path, state);
|
|
376
|
-
parameterResults.push(p.result);
|
|
377
|
-
}
|
|
378
|
-
else {
|
|
379
|
-
parameterResults.push(p.result);
|
|
380
|
-
}
|
|
408
|
+
function beginHandle(queries, path) {
|
|
409
|
+
const rootPath = createNodePath(path, undefined, undefined, undefined);
|
|
410
|
+
return travHandle(queries, rootPath);
|
|
381
411
|
}
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
fnode.result.push(...functionResult);
|
|
385
|
-
}
|
|
386
|
-
function travHandle(queries, root) {
|
|
387
|
-
const results = Object.fromEntries(Object.keys(queries).map(name => [name, []]));
|
|
388
|
-
const state = {
|
|
389
|
-
depth: 0,
|
|
390
|
-
child: [[], []],
|
|
391
|
-
descendant: [[], []],
|
|
392
|
-
filters: [[], []],
|
|
393
|
-
matches: [[]],
|
|
394
|
-
functionCalls: [[]]
|
|
412
|
+
return {
|
|
413
|
+
beginHandle
|
|
395
414
|
};
|
|
396
|
-
Object.entries(queries).forEach(([name, node]) => {
|
|
397
|
-
createFNodeAndAddToState(node, results[name], state);
|
|
398
|
-
});
|
|
399
|
-
state.child[state.depth + 1].forEach(fnode => addPrimitiveAttributeIfMatch(fnode, root));
|
|
400
|
-
state.descendant.slice(0, state.depth + 1).forEach(fnodes => fnodes.forEach(fnode => addPrimitiveAttributeIfMatch(fnode, root)));
|
|
401
|
-
(0, traverse_1.default)(root.node, {
|
|
402
|
-
enter(path, state) {
|
|
403
|
-
log.debug("ENTER", breadCrumb(path));
|
|
404
|
-
state.depth++;
|
|
405
|
-
state.child.push([]);
|
|
406
|
-
state.descendant.push([]);
|
|
407
|
-
state.filters.push([]);
|
|
408
|
-
state.matches.push([]);
|
|
409
|
-
state.functionCalls.push([]);
|
|
410
|
-
state.child[state.depth].forEach(fnode => addIfTokenMatch(fnode, path, state));
|
|
411
|
-
state.descendant.slice(0, state.depth + 1).forEach(fnodes => fnodes.forEach(fnode => addIfTokenMatch(fnode, path, state)));
|
|
412
|
-
},
|
|
413
|
-
exit(path, state) {
|
|
414
|
-
log.debug("EXIT", breadCrumb(path));
|
|
415
|
-
// Check for attributes as not all attributes are visited
|
|
416
|
-
state.child[state.depth + 1].forEach(fnode => addPrimitiveAttributeIfMatch(fnode, path));
|
|
417
|
-
state.descendant.forEach(fnodes => fnodes.forEach(fnode => addPrimitiveAttributeIfMatch(fnode, path)));
|
|
418
|
-
state.matches[state.depth].forEach(([fNode, path]) => addResultIfTokenMatch(fNode, path, state));
|
|
419
|
-
state.depth--;
|
|
420
|
-
state.child.pop();
|
|
421
|
-
state.descendant.pop();
|
|
422
|
-
state.filters.pop();
|
|
423
|
-
state.matches.pop();
|
|
424
|
-
state.functionCalls.pop();
|
|
425
|
-
}
|
|
426
|
-
}, root.scopeId, state, root);
|
|
427
|
-
return results;
|
|
428
415
|
}
|
|
429
416
|
const defaultKey = "__default__";
|
|
430
|
-
function query(code, query) {
|
|
431
|
-
|
|
417
|
+
function query(code, query, returnAST) {
|
|
418
|
+
const result = multiQuery(code, { [defaultKey]: query }, returnAST);
|
|
419
|
+
if (returnAST) {
|
|
420
|
+
const r = result[defaultKey];
|
|
421
|
+
r.__AST = result.__AST;
|
|
422
|
+
return r;
|
|
423
|
+
}
|
|
424
|
+
return result[defaultKey];
|
|
432
425
|
}
|
|
433
426
|
exports.query = query;
|
|
434
|
-
function multiQuery(code, namedQueries) {
|
|
427
|
+
function multiQuery(code, namedQueries, returnAST) {
|
|
435
428
|
const start = Date.now();
|
|
436
429
|
const ast = typeof code == "string" ? parseSource(code) : code;
|
|
437
430
|
if (ast == null)
|
|
438
431
|
throw new Error("Could not pase code");
|
|
439
432
|
const queries = Object.fromEntries(Object.entries(namedQueries).map(([name, query]) => [name, (0, parseQuery_1.parse)(query)]));
|
|
440
|
-
const
|
|
433
|
+
const querier = createQuerier();
|
|
434
|
+
const result = querier.beginHandle(queries, ast);
|
|
441
435
|
log.debug("Query time: ", Date.now() - start);
|
|
436
|
+
if (returnAST) {
|
|
437
|
+
return { ...result, __AST: ast };
|
|
438
|
+
}
|
|
442
439
|
return result;
|
|
443
440
|
}
|
|
444
441
|
exports.multiQuery = multiQuery;
|