@jbrowse/jexl 4.0.1 → 5.0.0
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/README.md +163 -20
- package/dist/Expression.d.ts +16 -0
- package/dist/Expression.js +28 -4
- package/dist/Expression.js.map +1 -1
- package/dist/Jexl.d.ts +20 -8
- package/dist/Jexl.js +34 -15
- package/dist/Jexl.js.map +1 -1
- package/dist/Lexer.d.ts +4 -3
- package/dist/Lexer.js +29 -21
- package/dist/Lexer.js.map +1 -1
- package/dist/analyze.d.ts +84 -0
- package/dist/analyze.js +259 -0
- package/dist/analyze.js.map +1 -0
- package/dist/check.d.ts +109 -0
- package/dist/check.js +1267 -0
- package/dist/check.js.map +1 -0
- package/dist/collections.d.ts +3 -0
- package/dist/collections.js +140 -0
- package/dist/collections.js.map +1 -0
- package/dist/conditions.d.ts +62 -0
- package/dist/conditions.js +207 -0
- package/dist/conditions.js.map +1 -0
- package/dist/errors.d.ts +5 -0
- package/dist/errors.js +18 -0
- package/dist/errors.js.map +1 -0
- package/dist/evaluator/compile.d.ts +10 -7
- package/dist/evaluator/compile.js +274 -97
- package/dist/evaluator/compile.js.map +1 -1
- package/dist/grammar.d.ts +19 -9
- package/dist/grammar.js +66 -40
- package/dist/grammar.js.map +1 -1
- package/dist/index.d.ts +9 -0
- package/dist/index.js +16 -1
- package/dist/index.js.map +1 -1
- package/dist/operators.d.ts +34 -0
- package/dist/operators.js +131 -0
- package/dist/operators.js.map +1 -0
- package/dist/parser/Parser.d.ts +48 -91
- package/dist/parser/Parser.js +347 -221
- package/dist/parser/Parser.js.map +1 -1
- package/dist/types.d.ts +11 -5
- package/esm/Expression.d.ts +16 -0
- package/esm/Expression.js +28 -4
- package/esm/Expression.js.map +1 -1
- package/esm/Jexl.d.ts +20 -8
- package/esm/Jexl.js +34 -15
- package/esm/Jexl.js.map +1 -1
- package/esm/Lexer.d.ts +4 -3
- package/esm/Lexer.js +29 -21
- package/esm/Lexer.js.map +1 -1
- package/esm/analyze.d.ts +84 -0
- package/esm/analyze.js +256 -0
- package/esm/analyze.js.map +1 -0
- package/esm/check.d.ts +109 -0
- package/esm/check.js +1260 -0
- package/esm/check.js.map +1 -0
- package/esm/collections.d.ts +3 -0
- package/esm/collections.js +137 -0
- package/esm/collections.js.map +1 -0
- package/esm/conditions.d.ts +62 -0
- package/esm/conditions.js +200 -0
- package/esm/conditions.js.map +1 -0
- package/esm/errors.d.ts +5 -0
- package/esm/errors.js +14 -0
- package/esm/errors.js.map +1 -0
- package/esm/evaluator/compile.d.ts +10 -7
- package/esm/evaluator/compile.js +274 -97
- package/esm/evaluator/compile.js.map +1 -1
- package/esm/grammar.d.ts +19 -9
- package/esm/grammar.js +66 -39
- package/esm/grammar.js.map +1 -1
- package/esm/index.d.ts +9 -0
- package/esm/index.js +4 -0
- package/esm/index.js.map +1 -1
- package/esm/operators.d.ts +34 -0
- package/esm/operators.js +123 -0
- package/esm/operators.js.map +1 -0
- package/esm/parser/Parser.d.ts +48 -91
- package/esm/parser/Parser.js +349 -192
- package/esm/parser/Parser.js.map +1 -1
- package/esm/types.d.ts +11 -5
- package/package.json +1 -1
- package/src/Expression.ts +34 -4
- package/src/Jexl.ts +52 -16
- package/src/Lexer.ts +32 -21
- package/src/analyze.ts +378 -0
- package/src/check.ts +1682 -0
- package/src/collections.ts +148 -0
- package/src/conditions.ts +262 -0
- package/src/errors.ts +15 -0
- package/src/evaluator/compile.ts +332 -100
- package/src/grammar.ts +123 -42
- package/src/index.ts +15 -0
- package/src/operators.ts +151 -0
- package/src/parser/Parser.ts +389 -199
- package/src/types.ts +13 -3
- package/dist/parser/handlers.d.ts +0 -115
- package/dist/parser/handlers.js +0 -352
- package/dist/parser/handlers.js.map +0 -1
- package/dist/parser/states.d.ts +0 -47
- package/dist/parser/states.js +0 -176
- package/dist/parser/states.js.map +0 -1
- package/esm/parser/handlers.d.ts +0 -115
- package/esm/parser/handlers.js +0 -328
- package/esm/parser/handlers.js.map +0 -1
- package/esm/parser/states.d.ts +0 -47
- package/esm/parser/states.js +0 -140
- package/esm/parser/states.js.map +0 -1
- package/src/parser/handlers.ts +0 -372
- package/src/parser/states.ts +0 -159
package/dist/Lexer.js
CHANGED
|
@@ -4,15 +4,20 @@
|
|
|
4
4
|
* Copyright 2020 Tom Shawver
|
|
5
5
|
*/
|
|
6
6
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
const errors_ts_1 = require("./errors.js");
|
|
7
8
|
// what an identifier and a number look like, written once: the split regex
|
|
8
9
|
// below carves elements out of the expression with these, and _createToken
|
|
9
10
|
// then re-tests the elements it produced. Two spellings of either would
|
|
10
11
|
// disagree on some input, and each disagreement is an "Invalid expression
|
|
11
12
|
// token" for something the splitter was happy to produce.
|
|
12
13
|
const identChars = String.raw `a-zA-Zа-яА-Я_\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u00FF$`;
|
|
13
|
-
const
|
|
14
|
+
const identPart = `[${identChars}0-9]`;
|
|
15
|
+
const identPattern = `[${identChars}]${identPart}*`;
|
|
16
|
+
// a word operator such as `in`, but not part of a longer name. \b would do only
|
|
17
|
+
// for ASCII names, and split `in$` or `inà` into the operator and a remainder
|
|
18
|
+
const wholeWord = (word) => `(?<!${identPart})${word}(?!${identPart})`;
|
|
14
19
|
// unsigned: whether a leading '-' negates is decided separately, in getTokens
|
|
15
|
-
const numberPattern = String.raw `(?:(?:[0-9]*\.[0-9]+)|[0-9]+)
|
|
20
|
+
const numberPattern = String.raw `(?:(?:[0-9]*\.[0-9]+)|[0-9]+)(?:[eE][+-]?[0-9]+)?`;
|
|
16
21
|
const numericRegex = new RegExp(`^-?${numberPattern}$`);
|
|
17
22
|
const identRegex = new RegExp(`^${identPattern}$`);
|
|
18
23
|
const escEscRegex = /\\\\/g;
|
|
@@ -32,11 +37,10 @@ const preOpRegexElems = [
|
|
|
32
37
|
String.raw `"(?:(?:\\")|[^"])*"`,
|
|
33
38
|
// Whitespace
|
|
34
39
|
String.raw `\s+`,
|
|
35
|
-
//
|
|
36
|
-
|
|
37
|
-
String.raw `\bfalse\b`
|
|
40
|
+
// ahead of the grammar's '.', so that '.5' is a number rather than a dot
|
|
41
|
+
numberPattern
|
|
38
42
|
];
|
|
39
|
-
const postOpRegexElems = [identPattern
|
|
43
|
+
const postOpRegexElems = [identPattern];
|
|
40
44
|
const unaryMinusToken = () => ({
|
|
41
45
|
type: 'unaryOp',
|
|
42
46
|
value: '-',
|
|
@@ -50,7 +54,8 @@ const minusNegatesAfter = new Set([
|
|
|
50
54
|
'question',
|
|
51
55
|
'colon',
|
|
52
56
|
'comma',
|
|
53
|
-
'semicolon'
|
|
57
|
+
'semicolon',
|
|
58
|
+
'arrow'
|
|
54
59
|
]);
|
|
55
60
|
/**
|
|
56
61
|
* Lexer handles the lexical parsing of a Jexl string. Its responsibility is to
|
|
@@ -105,6 +110,7 @@ class Lexer {
|
|
|
105
110
|
// 1") accumulates on the minus rather than on the token before it, which
|
|
106
111
|
// is what lets the parser's error messages quote the expression verbatim.
|
|
107
112
|
let pendingMinus;
|
|
113
|
+
let offset = 0;
|
|
108
114
|
for (const element of elements) {
|
|
109
115
|
if (this._isWhitespace(element)) {
|
|
110
116
|
const last = pendingMinus ?? tokens.at(-1);
|
|
@@ -123,20 +129,21 @@ class Lexer {
|
|
|
123
129
|
else if (pendingMinus) {
|
|
124
130
|
if (numericRegex.exec(element)) {
|
|
125
131
|
// fold the sign into the number, so "-1" stays a single literal
|
|
126
|
-
const token = this._createToken('-' + element);
|
|
132
|
+
const token = this._createToken('-' + element, offset);
|
|
127
133
|
token.raw = pendingMinus.raw + element;
|
|
128
134
|
tokens.push(token);
|
|
129
135
|
}
|
|
130
136
|
else {
|
|
131
137
|
// anything else gets a standalone prefix operator, letting "-x",
|
|
132
138
|
// "-(a + b)" and "-foo.bar" negate a computed value
|
|
133
|
-
tokens.push(pendingMinus, this._createToken(element));
|
|
139
|
+
tokens.push(pendingMinus, this._createToken(element, offset));
|
|
134
140
|
}
|
|
135
141
|
pendingMinus = undefined;
|
|
136
142
|
}
|
|
137
143
|
else {
|
|
138
|
-
tokens.push(this._createToken(element));
|
|
144
|
+
tokens.push(this._createToken(element, offset));
|
|
139
145
|
}
|
|
146
|
+
offset += element.length;
|
|
140
147
|
}
|
|
141
148
|
// Catch a - at the end of the string. Let the parser handle that issue.
|
|
142
149
|
if (pendingMinus) {
|
|
@@ -185,7 +192,7 @@ class Lexer {
|
|
|
185
192
|
* @throws {Error} if the provided string is not a valid expression element.
|
|
186
193
|
* @private
|
|
187
194
|
*/
|
|
188
|
-
_createToken(element) {
|
|
195
|
+
_createToken(element, offset = 0) {
|
|
189
196
|
const token = {
|
|
190
197
|
type: 'literal',
|
|
191
198
|
value: element,
|
|
@@ -193,7 +200,7 @@ class Lexer {
|
|
|
193
200
|
};
|
|
194
201
|
if (element.startsWith('`')) {
|
|
195
202
|
token.type = 'templateString';
|
|
196
|
-
token.value = this._parseTemplateString(element);
|
|
203
|
+
token.value = this._parseTemplateString(element, offset);
|
|
197
204
|
return token;
|
|
198
205
|
}
|
|
199
206
|
else if (element.startsWith('"') || element.startsWith("'")) {
|
|
@@ -205,6 +212,9 @@ class Lexer {
|
|
|
205
212
|
else if (element === 'true' || element === 'false') {
|
|
206
213
|
token.value = element === 'true';
|
|
207
214
|
}
|
|
215
|
+
else if (element === 'null') {
|
|
216
|
+
token.value = null;
|
|
217
|
+
}
|
|
208
218
|
else if (Object.hasOwn(this._grammar.elements, element)) {
|
|
209
219
|
token.type = this._grammar.elements[element].type;
|
|
210
220
|
}
|
|
@@ -212,24 +222,22 @@ class Lexer {
|
|
|
212
222
|
token.type = 'identifier';
|
|
213
223
|
}
|
|
214
224
|
else {
|
|
215
|
-
throw new
|
|
225
|
+
throw new errors_ts_1.JexlSyntaxError(`Invalid expression token: ${element}`, offset);
|
|
216
226
|
}
|
|
217
227
|
return token;
|
|
218
228
|
}
|
|
219
229
|
/**
|
|
220
230
|
* Escapes a string so that it can be treated as a string literal within a
|
|
221
|
-
* regular expression.
|
|
231
|
+
* regular expression. A word such as `in` also stops matching inside a
|
|
232
|
+
* longer name.
|
|
222
233
|
* @param {string} str The string to be escaped
|
|
223
234
|
* @returns {string} the RegExp-escaped string.
|
|
224
235
|
* @see https://developer.mozilla.org/en/docs/Web/JavaScript/Guide/Regular_Expressions
|
|
225
236
|
* @private
|
|
226
237
|
*/
|
|
227
238
|
_escapeRegExp(str) {
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
str = String.raw `\b` + str + String.raw `\b`;
|
|
231
|
-
}
|
|
232
|
-
return str;
|
|
239
|
+
const escaped = str.replaceAll(/[.*+?^${}()|[\]\\]/g, String.raw `\$&`);
|
|
240
|
+
return identRegex.exec(str) ? wholeWord(escaped) : escaped;
|
|
233
241
|
}
|
|
234
242
|
/**
|
|
235
243
|
* Gets a RegEx object appropriate for splitting a Jexl string into its core
|
|
@@ -299,7 +307,7 @@ class Lexer {
|
|
|
299
307
|
.replaceAll(escQuoteRegex[quote], quote)
|
|
300
308
|
.replaceAll(escEscRegex, '\\');
|
|
301
309
|
}
|
|
302
|
-
_parseTemplateString(str) {
|
|
310
|
+
_parseTemplateString(str, offset = 0) {
|
|
303
311
|
const parts = [];
|
|
304
312
|
let current = 1;
|
|
305
313
|
let staticStart = 1;
|
|
@@ -343,7 +351,7 @@ class Lexer {
|
|
|
343
351
|
current++;
|
|
344
352
|
}
|
|
345
353
|
if (braceDepth !== 0) {
|
|
346
|
-
throw new
|
|
354
|
+
throw new errors_ts_1.JexlSyntaxError(`Unclosed interpolation in template string: ${str}`, offset + interpStart - '${'.length);
|
|
347
355
|
}
|
|
348
356
|
parts.push({
|
|
349
357
|
type: 'interpolation',
|
package/dist/Lexer.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Lexer.js","sourceRoot":"","sources":["../src/Lexer.ts"],"names":[],"mappings":";AAAA;;;GAGG;;
|
|
1
|
+
{"version":3,"file":"Lexer.js","sourceRoot":"","sources":["../src/Lexer.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import type { AstNode } from './types.ts';
|
|
2
|
+
export type PathKey = string | number;
|
|
3
|
+
/**
|
|
4
|
+
* A value the expression reads out of its context: the variable `root`, then
|
|
5
|
+
* each literal key in `path`. `dynamic` means a computed key followed, so the
|
|
6
|
+
* read reaches somewhere under `path` that only evaluation can name.
|
|
7
|
+
*
|
|
8
|
+
* A dot and a bracket both add a key.
|
|
9
|
+
*/
|
|
10
|
+
export interface Read {
|
|
11
|
+
root: string;
|
|
12
|
+
path: PathKey[];
|
|
13
|
+
dynamic?: true;
|
|
14
|
+
}
|
|
15
|
+
export type CallArg = {
|
|
16
|
+
type: 'literal';
|
|
17
|
+
value: string | number | boolean | null;
|
|
18
|
+
} | {
|
|
19
|
+
type: 'path';
|
|
20
|
+
read: Read;
|
|
21
|
+
} | {
|
|
22
|
+
type: 'dynamic';
|
|
23
|
+
};
|
|
24
|
+
/** A path under the row, the record a per-row expression is evaluated for. */
|
|
25
|
+
export interface Field {
|
|
26
|
+
path: PathKey[];
|
|
27
|
+
dynamic?: true;
|
|
28
|
+
}
|
|
29
|
+
export interface Call {
|
|
30
|
+
name: string;
|
|
31
|
+
args: CallArg[];
|
|
32
|
+
}
|
|
33
|
+
export interface Analysis {
|
|
34
|
+
/** The context variables read, in the order first read. */
|
|
35
|
+
variables: string[];
|
|
36
|
+
/**
|
|
37
|
+
* Every path whose value the expression uses, in the order first used. A
|
|
38
|
+
* path only extended, as `feature` is in `feature.score`, is not a use.
|
|
39
|
+
*/
|
|
40
|
+
reads: Read[];
|
|
41
|
+
/** The reads that are fields of the row, as `row` and `env` say. */
|
|
42
|
+
fields: Field[];
|
|
43
|
+
/** The paths whose value the expression returns as is. */
|
|
44
|
+
returns: Read[];
|
|
45
|
+
/**
|
|
46
|
+
* Whether the expression is only a path: a name, then dots and literal
|
|
47
|
+
* subscripts, as in `score` or `feature.INFO.DP[0]`. Its one read is then
|
|
48
|
+
* its value, which a host can read without jexl.
|
|
49
|
+
*/
|
|
50
|
+
bare: boolean;
|
|
51
|
+
/** Every call, outermost first, including accessor calls. */
|
|
52
|
+
calls: Call[];
|
|
53
|
+
/** The names the expression writes into its context. */
|
|
54
|
+
assigned: string[];
|
|
55
|
+
}
|
|
56
|
+
export interface AnalyzeOptions {
|
|
57
|
+
/**
|
|
58
|
+
* Functions that read a path: `name(subject, ...keys)` reads the subject,
|
|
59
|
+
* then this prefix, then each key. `{ get: [] }` makes `get(feature, 'x')`
|
|
60
|
+
* and `feature.get('x')` both read `feature.x`.
|
|
61
|
+
*/
|
|
62
|
+
accessors?: Record<string, readonly PathKey[]>;
|
|
63
|
+
/** The variable holding the row, whose reads `fields` lists: `'feature'`. */
|
|
64
|
+
row?: string;
|
|
65
|
+
/**
|
|
66
|
+
* For a host that binds each of the row's fields as a variable, so that
|
|
67
|
+
* `pvalue` means the row's `pvalue`: the variables it binds to anything
|
|
68
|
+
* else. Every other variable the expression reads is then a field.
|
|
69
|
+
*/
|
|
70
|
+
env?: readonly string[];
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Lists what an expression reads from its context, without evaluating it or
|
|
74
|
+
* consulting any registered function.
|
|
75
|
+
*
|
|
76
|
+
* A name assigned earlier in the expression is a local: `x = feature.score;
|
|
77
|
+
* x > 1` reads `feature.score` and no `x`. An assignment that may not run — in
|
|
78
|
+
* a conditional's branch, or right of a binary operator, which may short-circuit
|
|
79
|
+
* — counts its value as read and binds nothing past that operand, so a later
|
|
80
|
+
* read of the name is a context read.
|
|
81
|
+
*
|
|
82
|
+
* Every path evaluation reads is reported, or a prefix of it is.
|
|
83
|
+
*/
|
|
84
|
+
export declare function analyze(ast: AstNode | null, { accessors, row, env }?: AnalyzeOptions): Analysis;
|
package/dist/analyze.js
ADDED
|
@@ -0,0 +1,259 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/*
|
|
3
|
+
* Jexl
|
|
4
|
+
* Copyright 2020 Tom Shawver
|
|
5
|
+
*/
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.analyze = analyze;
|
|
8
|
+
function literalKey(node) {
|
|
9
|
+
const value = literalValue(node);
|
|
10
|
+
return typeof value === 'boolean' ? String(value) : (value ?? undefined);
|
|
11
|
+
}
|
|
12
|
+
function literalValue(ast) {
|
|
13
|
+
const node = ast;
|
|
14
|
+
if (node.type === 'Literal') {
|
|
15
|
+
return node.value;
|
|
16
|
+
}
|
|
17
|
+
if (node.type === 'TemplateLiteral' &&
|
|
18
|
+
node.parts.every((part) => part.type === 'static')) {
|
|
19
|
+
return node.parts.map((part) => part.value).join('');
|
|
20
|
+
}
|
|
21
|
+
return undefined;
|
|
22
|
+
}
|
|
23
|
+
function extend(read, keys, dynamic = false) {
|
|
24
|
+
if (read.dynamic) {
|
|
25
|
+
return read;
|
|
26
|
+
}
|
|
27
|
+
const path = [...read.path, ...keys];
|
|
28
|
+
return dynamic
|
|
29
|
+
? { root: read.root, path, dynamic }
|
|
30
|
+
: { root: read.root, path };
|
|
31
|
+
}
|
|
32
|
+
function isBarePath(ast) {
|
|
33
|
+
const node = ast;
|
|
34
|
+
if (node.type === 'Identifier') {
|
|
35
|
+
return !node.from || isBarePath(node.from);
|
|
36
|
+
}
|
|
37
|
+
return (node.type === 'FilterExpression' &&
|
|
38
|
+
literalKey(node.expr) !== undefined &&
|
|
39
|
+
isBarePath(node.subject));
|
|
40
|
+
}
|
|
41
|
+
function fieldOf({ root, path, dynamic }, row, env) {
|
|
42
|
+
const fieldPath = root === row
|
|
43
|
+
? path
|
|
44
|
+
: env && !env.includes(root)
|
|
45
|
+
? [root, ...path]
|
|
46
|
+
: undefined;
|
|
47
|
+
return (fieldPath && (dynamic ? { path: fieldPath, dynamic } : { path: fieldPath }));
|
|
48
|
+
}
|
|
49
|
+
function classify(node, value) {
|
|
50
|
+
const literal = literalValue(node);
|
|
51
|
+
if (literal !== undefined) {
|
|
52
|
+
return { type: 'literal', value: literal };
|
|
53
|
+
}
|
|
54
|
+
return value.length === 1
|
|
55
|
+
? { type: 'path', read: value[0] }
|
|
56
|
+
: { type: 'dynamic' };
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Lists what an expression reads from its context, without evaluating it or
|
|
60
|
+
* consulting any registered function.
|
|
61
|
+
*
|
|
62
|
+
* A name assigned earlier in the expression is a local: `x = feature.score;
|
|
63
|
+
* x > 1` reads `feature.score` and no `x`. An assignment that may not run — in
|
|
64
|
+
* a conditional's branch, or right of a binary operator, which may short-circuit
|
|
65
|
+
* — counts its value as read and binds nothing past that operand, so a later
|
|
66
|
+
* read of the name is a context read.
|
|
67
|
+
*
|
|
68
|
+
* Every path evaluation reads is reported, or a prefix of it is.
|
|
69
|
+
*/
|
|
70
|
+
function analyze(ast, { accessors = {}, row, env } = {}) {
|
|
71
|
+
const reads = new Map();
|
|
72
|
+
const calls = [];
|
|
73
|
+
const assigned = new Set();
|
|
74
|
+
function consume(value) {
|
|
75
|
+
for (const read of value) {
|
|
76
|
+
const key = JSON.stringify([read.root, read.path, read.dynamic]);
|
|
77
|
+
if (!reads.has(key)) {
|
|
78
|
+
reads.set(key, read);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
function use(node, scope) {
|
|
83
|
+
consume(walk(node, scope));
|
|
84
|
+
}
|
|
85
|
+
function release(scope, outer) {
|
|
86
|
+
for (const [name, binding] of scope) {
|
|
87
|
+
if (!binding.used && outer?.get(name) !== binding) {
|
|
88
|
+
consume(binding.value);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
function branch(node, scope) {
|
|
93
|
+
if (!node) {
|
|
94
|
+
return [];
|
|
95
|
+
}
|
|
96
|
+
const inner = new Map(scope);
|
|
97
|
+
const value = walk(node, inner);
|
|
98
|
+
release(inner, scope);
|
|
99
|
+
return value;
|
|
100
|
+
}
|
|
101
|
+
function call(node, scope) {
|
|
102
|
+
const record = { name: node.name, args: [] };
|
|
103
|
+
calls.push(record);
|
|
104
|
+
const [subjectNode, ...keyNodes] = node.args;
|
|
105
|
+
const prefix = Object.hasOwn(accessors, node.name)
|
|
106
|
+
? accessors[node.name]
|
|
107
|
+
: undefined;
|
|
108
|
+
if (!prefix || !subjectNode) {
|
|
109
|
+
for (const arg of node.args) {
|
|
110
|
+
const value = walk(arg, scope);
|
|
111
|
+
record.args.push(classify(arg, value));
|
|
112
|
+
consume(value);
|
|
113
|
+
}
|
|
114
|
+
return [];
|
|
115
|
+
}
|
|
116
|
+
const subject = walk(subjectNode, scope);
|
|
117
|
+
record.args.push(classify(subjectNode, subject));
|
|
118
|
+
const keys = [...prefix];
|
|
119
|
+
let dynamic = false;
|
|
120
|
+
for (const arg of keyNodes) {
|
|
121
|
+
const key = literalKey(arg);
|
|
122
|
+
if (key === undefined) {
|
|
123
|
+
const value = walk(arg, scope);
|
|
124
|
+
record.args.push(classify(arg, value));
|
|
125
|
+
consume(value);
|
|
126
|
+
dynamic = true;
|
|
127
|
+
}
|
|
128
|
+
else {
|
|
129
|
+
record.args.push({ type: 'literal', value: literalValue(arg) });
|
|
130
|
+
if (!dynamic) {
|
|
131
|
+
keys.push(key);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
return subject.map((read) => extend(read, keys, dynamic));
|
|
136
|
+
}
|
|
137
|
+
function walk(ast, scope) {
|
|
138
|
+
const node = ast;
|
|
139
|
+
switch (node.type) {
|
|
140
|
+
case 'Literal': {
|
|
141
|
+
return [];
|
|
142
|
+
}
|
|
143
|
+
case 'Identifier': {
|
|
144
|
+
if (node.from) {
|
|
145
|
+
return walk(node.from, scope).map((read) => extend(read, [node.value]));
|
|
146
|
+
}
|
|
147
|
+
const binding = scope.get(node.value);
|
|
148
|
+
if (binding) {
|
|
149
|
+
binding.used = true;
|
|
150
|
+
return binding.value;
|
|
151
|
+
}
|
|
152
|
+
return [{ root: node.value, path: [] }];
|
|
153
|
+
}
|
|
154
|
+
case 'FilterExpression': {
|
|
155
|
+
const subject = walk(node.subject, scope);
|
|
156
|
+
const key = literalKey(node.expr);
|
|
157
|
+
if (key !== undefined) {
|
|
158
|
+
return subject.map((read) => extend(read, [key]));
|
|
159
|
+
}
|
|
160
|
+
use(node.expr, scope);
|
|
161
|
+
return subject.map((read) => extend(read, [], true));
|
|
162
|
+
}
|
|
163
|
+
case 'FunctionCall': {
|
|
164
|
+
return call(node, scope);
|
|
165
|
+
}
|
|
166
|
+
case 'ConditionalExpression': {
|
|
167
|
+
const test = walk(node.test, scope);
|
|
168
|
+
consume(test);
|
|
169
|
+
const consequent = node.consequent
|
|
170
|
+
? branch(node.consequent, scope)
|
|
171
|
+
: test;
|
|
172
|
+
return [...consequent, ...branch(node.alternate, scope)];
|
|
173
|
+
}
|
|
174
|
+
case 'BinaryExpression': {
|
|
175
|
+
use(node.left, scope);
|
|
176
|
+
consume(branch(node.right, scope));
|
|
177
|
+
return [];
|
|
178
|
+
}
|
|
179
|
+
case 'UnaryExpression': {
|
|
180
|
+
use(node.right, scope);
|
|
181
|
+
return [];
|
|
182
|
+
}
|
|
183
|
+
case 'ArrayLiteral': {
|
|
184
|
+
for (const item of node.value) {
|
|
185
|
+
use(item, scope);
|
|
186
|
+
}
|
|
187
|
+
return [];
|
|
188
|
+
}
|
|
189
|
+
case 'ObjectLiteral': {
|
|
190
|
+
for (const value of Object.values(node.value)) {
|
|
191
|
+
use(value, scope);
|
|
192
|
+
}
|
|
193
|
+
return [];
|
|
194
|
+
}
|
|
195
|
+
case 'TemplateLiteral': {
|
|
196
|
+
for (const part of node.parts) {
|
|
197
|
+
if (part.type === 'expression') {
|
|
198
|
+
use(part.value, scope);
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
return [];
|
|
202
|
+
}
|
|
203
|
+
case 'SequenceExpression': {
|
|
204
|
+
const exprs = node.expressions;
|
|
205
|
+
for (const expr of exprs.slice(0, -1)) {
|
|
206
|
+
const value = walk(expr, scope);
|
|
207
|
+
if (expr.type !== 'AssignmentExpression') {
|
|
208
|
+
consume(value);
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
return walk(exprs.at(-1), scope);
|
|
212
|
+
}
|
|
213
|
+
case 'AssignmentExpression': {
|
|
214
|
+
const value = walk(node.right, scope);
|
|
215
|
+
const name = node.left.value;
|
|
216
|
+
const previous = scope.get(name);
|
|
217
|
+
if (previous && !previous.used) {
|
|
218
|
+
consume(previous.value);
|
|
219
|
+
}
|
|
220
|
+
scope.set(name, { value, used: false });
|
|
221
|
+
assigned.add(name);
|
|
222
|
+
return value;
|
|
223
|
+
}
|
|
224
|
+
case 'Lambda': {
|
|
225
|
+
const inner = new Map(scope);
|
|
226
|
+
for (const param of node.params) {
|
|
227
|
+
inner.set(param, { value: [], used: true });
|
|
228
|
+
}
|
|
229
|
+
use(node.body, inner);
|
|
230
|
+
return [];
|
|
231
|
+
}
|
|
232
|
+
default: {
|
|
233
|
+
throw new Error(`Corrupt AST: unknown node type '${ast.type}'`);
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
const scope = new Map();
|
|
238
|
+
const returns = ast ? walk(ast, scope) : [];
|
|
239
|
+
consume(returns);
|
|
240
|
+
release(scope);
|
|
241
|
+
const readList = [...reads.values()];
|
|
242
|
+
const fields = new Map();
|
|
243
|
+
for (const read of readList) {
|
|
244
|
+
const field = fieldOf(read, row, env);
|
|
245
|
+
if (field) {
|
|
246
|
+
fields.set(JSON.stringify(field), field);
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
return {
|
|
250
|
+
variables: [...new Set(readList.map((read) => read.root))],
|
|
251
|
+
reads: readList,
|
|
252
|
+
fields: [...fields.values()],
|
|
253
|
+
returns,
|
|
254
|
+
bare: ast !== null && isBarePath(ast),
|
|
255
|
+
calls,
|
|
256
|
+
assigned: [...assigned]
|
|
257
|
+
};
|
|
258
|
+
}
|
|
259
|
+
//# sourceMappingURL=analyze.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"analyze.js","sourceRoot":"","sources":["../src/analyze.ts"],"names":[],"mappings":"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"}
|
package/dist/check.d.ts
ADDED
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import type { AnalyzeOptions } from './analyze.ts';
|
|
2
|
+
import type { AstNode } from './types.ts';
|
|
3
|
+
/**
|
|
4
|
+
* How many values a field holds: one, a list of exactly that many when a
|
|
5
|
+
* number, or a list whose length follows the record, as VCF's `Number=A`, `R`,
|
|
6
|
+
* `G` and `.` do.
|
|
7
|
+
*/
|
|
8
|
+
export type Cardinality = 'one' | 'perAlt' | 'perAllele' | 'perGenotype' | 'many' | number;
|
|
9
|
+
/**
|
|
10
|
+
* One field of a row, as a file header declares it. A `record` field's own
|
|
11
|
+
* fields are further entries whose path extends its path, including when the
|
|
12
|
+
* record is a list of them. A path key of `*` stands for every key of a map,
|
|
13
|
+
* such as a VCF record's sample names. An entry with an empty path describes
|
|
14
|
+
* the row itself.
|
|
15
|
+
*/
|
|
16
|
+
export interface FieldSchema {
|
|
17
|
+
path: readonly string[];
|
|
18
|
+
type: 'number' | 'string' | 'boolean' | 'flag' | 'record';
|
|
19
|
+
cardinality?: Cardinality;
|
|
20
|
+
integer?: boolean;
|
|
21
|
+
description?: string;
|
|
22
|
+
/** Every value the field takes, where the header enumerates them. */
|
|
23
|
+
categories?: readonly string[];
|
|
24
|
+
domain?: readonly [number, number];
|
|
25
|
+
/** For a record: its fields were observed in data rather than declared. */
|
|
26
|
+
open?: boolean;
|
|
27
|
+
}
|
|
28
|
+
interface FromField {
|
|
29
|
+
field?: FieldSchema;
|
|
30
|
+
}
|
|
31
|
+
export type Type = {
|
|
32
|
+
kind: 'unknown';
|
|
33
|
+
} | {
|
|
34
|
+
kind: 'undefined';
|
|
35
|
+
} | (FromField & {
|
|
36
|
+
kind: 'number';
|
|
37
|
+
values?: readonly number[];
|
|
38
|
+
domain?: readonly [number, number];
|
|
39
|
+
}) | (FromField & {
|
|
40
|
+
kind: 'string';
|
|
41
|
+
values?: readonly string[];
|
|
42
|
+
}) | (FromField & {
|
|
43
|
+
kind: 'boolean';
|
|
44
|
+
}) | (FromField & {
|
|
45
|
+
kind: 'list';
|
|
46
|
+
of: Type;
|
|
47
|
+
cardinality: Exclude<Cardinality, 'one'>;
|
|
48
|
+
}) | (FromField & {
|
|
49
|
+
kind: 'record';
|
|
50
|
+
fields: ReadonlyMap<string, Type>;
|
|
51
|
+
each?: Type;
|
|
52
|
+
open: boolean;
|
|
53
|
+
}) | {
|
|
54
|
+
kind: 'union';
|
|
55
|
+
of: readonly Type[];
|
|
56
|
+
} | {
|
|
57
|
+
kind: 'lambda';
|
|
58
|
+
returns: Type;
|
|
59
|
+
};
|
|
60
|
+
export type ParamType = 'number' | 'string' | 'boolean' | 'list' | 'record' | 'any' | 'member' | 'lambda';
|
|
61
|
+
export interface Signature {
|
|
62
|
+
params: readonly (ParamType | readonly ParamType[])[];
|
|
63
|
+
/** How many trailing params a call may leave out. */
|
|
64
|
+
optional?: number;
|
|
65
|
+
/** Whether the last param repeats. */
|
|
66
|
+
variadic?: boolean;
|
|
67
|
+
returns?: 'number' | 'string' | 'boolean' | Type | ((args: readonly Type[]) => Type);
|
|
68
|
+
}
|
|
69
|
+
export type Severity = 'error' | 'warning' | 'info';
|
|
70
|
+
export type DiagnosticCode = 'unknown-variable' | 'unknown-field' | 'unknown-function' | 'arity' | 'argument-type' | 'list-operand' | 'list-lengths' | 'invalid-pattern' | 'string-numeric' | 'never-equal' | 'unknown-category' | 'index-scalar' | 'index-range' | 'dot-through-list' | 'dotted-key';
|
|
71
|
+
export interface Diagnostic {
|
|
72
|
+
code: DiagnosticCode;
|
|
73
|
+
severity: Severity;
|
|
74
|
+
message: string;
|
|
75
|
+
node: AstNode;
|
|
76
|
+
/** Replacements for `node`'s text, best first. */
|
|
77
|
+
suggestions?: string[];
|
|
78
|
+
}
|
|
79
|
+
export interface CheckOptions {
|
|
80
|
+
schema?: readonly FieldSchema[];
|
|
81
|
+
functions?: Readonly<Record<string, Signature>>;
|
|
82
|
+
accessors?: AnalyzeOptions['accessors'];
|
|
83
|
+
/** The variable holding the row. Without one, every free name is a field. */
|
|
84
|
+
row?: string;
|
|
85
|
+
/**
|
|
86
|
+
* The other variables the host binds, and their types. When given, any name
|
|
87
|
+
* that is neither these, the row nor a field is reported.
|
|
88
|
+
*/
|
|
89
|
+
env?: Readonly<Record<string, Type>>;
|
|
90
|
+
}
|
|
91
|
+
export interface CheckResult {
|
|
92
|
+
diagnostics: Diagnostic[];
|
|
93
|
+
type: Type;
|
|
94
|
+
}
|
|
95
|
+
export declare const UNKNOWN: Type;
|
|
96
|
+
/**
|
|
97
|
+
* Renders a tree back to expression text, for messages and suggestions. The
|
|
98
|
+
* text parses back to the same tree.
|
|
99
|
+
*/
|
|
100
|
+
export declare function print(ast: AstNode): string;
|
|
101
|
+
/** The type of a row whose fields `schema` declares. */
|
|
102
|
+
export declare function recordOf(schema: readonly FieldSchema[]): Type;
|
|
103
|
+
export declare function union(a: Type, b: Type): Type;
|
|
104
|
+
/**
|
|
105
|
+
* Checks an expression against the fields a host's data declares and the
|
|
106
|
+
* functions it registers, without evaluating it, and infers what it answers.
|
|
107
|
+
*/
|
|
108
|
+
export declare function check(ast: AstNode | null, { schema, functions, accessors, row, env }?: CheckOptions): CheckResult;
|
|
109
|
+
export {};
|