@jbrowse/jexl 4.0.1 → 5.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/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 +292 -99
- package/dist/evaluator/compile.js.map +1 -1
- package/dist/grammar.d.ts +22 -9
- package/dist/grammar.js +83 -55
- 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 +292 -99
- package/esm/evaluator/compile.js.map +1 -1
- package/esm/grammar.d.ts +22 -9
- package/esm/grammar.js +79 -53
- 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 +351 -102
- package/src/grammar.ts +137 -55
- 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/esm/analyze.js
ADDED
|
@@ -0,0 +1,256 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Jexl
|
|
3
|
+
* Copyright 2020 Tom Shawver
|
|
4
|
+
*/
|
|
5
|
+
function literalKey(node) {
|
|
6
|
+
const value = literalValue(node);
|
|
7
|
+
return typeof value === 'boolean' ? String(value) : (value ?? undefined);
|
|
8
|
+
}
|
|
9
|
+
function literalValue(ast) {
|
|
10
|
+
const node = ast;
|
|
11
|
+
if (node.type === 'Literal') {
|
|
12
|
+
return node.value;
|
|
13
|
+
}
|
|
14
|
+
if (node.type === 'TemplateLiteral' &&
|
|
15
|
+
node.parts.every((part) => part.type === 'static')) {
|
|
16
|
+
return node.parts.map((part) => part.value).join('');
|
|
17
|
+
}
|
|
18
|
+
return undefined;
|
|
19
|
+
}
|
|
20
|
+
function extend(read, keys, dynamic = false) {
|
|
21
|
+
if (read.dynamic) {
|
|
22
|
+
return read;
|
|
23
|
+
}
|
|
24
|
+
const path = [...read.path, ...keys];
|
|
25
|
+
return dynamic
|
|
26
|
+
? { root: read.root, path, dynamic }
|
|
27
|
+
: { root: read.root, path };
|
|
28
|
+
}
|
|
29
|
+
function isBarePath(ast) {
|
|
30
|
+
const node = ast;
|
|
31
|
+
if (node.type === 'Identifier') {
|
|
32
|
+
return !node.from || isBarePath(node.from);
|
|
33
|
+
}
|
|
34
|
+
return (node.type === 'FilterExpression' &&
|
|
35
|
+
literalKey(node.expr) !== undefined &&
|
|
36
|
+
isBarePath(node.subject));
|
|
37
|
+
}
|
|
38
|
+
function fieldOf({ root, path, dynamic }, row, env) {
|
|
39
|
+
const fieldPath = root === row
|
|
40
|
+
? path
|
|
41
|
+
: env && !env.includes(root)
|
|
42
|
+
? [root, ...path]
|
|
43
|
+
: undefined;
|
|
44
|
+
return (fieldPath && (dynamic ? { path: fieldPath, dynamic } : { path: fieldPath }));
|
|
45
|
+
}
|
|
46
|
+
function classify(node, value) {
|
|
47
|
+
const literal = literalValue(node);
|
|
48
|
+
if (literal !== undefined) {
|
|
49
|
+
return { type: 'literal', value: literal };
|
|
50
|
+
}
|
|
51
|
+
return value.length === 1
|
|
52
|
+
? { type: 'path', read: value[0] }
|
|
53
|
+
: { type: 'dynamic' };
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Lists what an expression reads from its context, without evaluating it or
|
|
57
|
+
* consulting any registered function.
|
|
58
|
+
*
|
|
59
|
+
* A name assigned earlier in the expression is a local: `x = feature.score;
|
|
60
|
+
* x > 1` reads `feature.score` and no `x`. An assignment that may not run — in
|
|
61
|
+
* a conditional's branch, or right of a binary operator, which may short-circuit
|
|
62
|
+
* — counts its value as read and binds nothing past that operand, so a later
|
|
63
|
+
* read of the name is a context read.
|
|
64
|
+
*
|
|
65
|
+
* Every path evaluation reads is reported, or a prefix of it is.
|
|
66
|
+
*/
|
|
67
|
+
export function analyze(ast, { accessors = {}, row, env } = {}) {
|
|
68
|
+
const reads = new Map();
|
|
69
|
+
const calls = [];
|
|
70
|
+
const assigned = new Set();
|
|
71
|
+
function consume(value) {
|
|
72
|
+
for (const read of value) {
|
|
73
|
+
const key = JSON.stringify([read.root, read.path, read.dynamic]);
|
|
74
|
+
if (!reads.has(key)) {
|
|
75
|
+
reads.set(key, read);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
function use(node, scope) {
|
|
80
|
+
consume(walk(node, scope));
|
|
81
|
+
}
|
|
82
|
+
function release(scope, outer) {
|
|
83
|
+
for (const [name, binding] of scope) {
|
|
84
|
+
if (!binding.used && outer?.get(name) !== binding) {
|
|
85
|
+
consume(binding.value);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
function branch(node, scope) {
|
|
90
|
+
if (!node) {
|
|
91
|
+
return [];
|
|
92
|
+
}
|
|
93
|
+
const inner = new Map(scope);
|
|
94
|
+
const value = walk(node, inner);
|
|
95
|
+
release(inner, scope);
|
|
96
|
+
return value;
|
|
97
|
+
}
|
|
98
|
+
function call(node, scope) {
|
|
99
|
+
const record = { name: node.name, args: [] };
|
|
100
|
+
calls.push(record);
|
|
101
|
+
const [subjectNode, ...keyNodes] = node.args;
|
|
102
|
+
const prefix = Object.hasOwn(accessors, node.name)
|
|
103
|
+
? accessors[node.name]
|
|
104
|
+
: undefined;
|
|
105
|
+
if (!prefix || !subjectNode) {
|
|
106
|
+
for (const arg of node.args) {
|
|
107
|
+
const value = walk(arg, scope);
|
|
108
|
+
record.args.push(classify(arg, value));
|
|
109
|
+
consume(value);
|
|
110
|
+
}
|
|
111
|
+
return [];
|
|
112
|
+
}
|
|
113
|
+
const subject = walk(subjectNode, scope);
|
|
114
|
+
record.args.push(classify(subjectNode, subject));
|
|
115
|
+
const keys = [...prefix];
|
|
116
|
+
let dynamic = false;
|
|
117
|
+
for (const arg of keyNodes) {
|
|
118
|
+
const key = literalKey(arg);
|
|
119
|
+
if (key === undefined) {
|
|
120
|
+
const value = walk(arg, scope);
|
|
121
|
+
record.args.push(classify(arg, value));
|
|
122
|
+
consume(value);
|
|
123
|
+
dynamic = true;
|
|
124
|
+
}
|
|
125
|
+
else {
|
|
126
|
+
record.args.push({ type: 'literal', value: literalValue(arg) });
|
|
127
|
+
if (!dynamic) {
|
|
128
|
+
keys.push(key);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
return subject.map((read) => extend(read, keys, dynamic));
|
|
133
|
+
}
|
|
134
|
+
function walk(ast, scope) {
|
|
135
|
+
const node = ast;
|
|
136
|
+
switch (node.type) {
|
|
137
|
+
case 'Literal': {
|
|
138
|
+
return [];
|
|
139
|
+
}
|
|
140
|
+
case 'Identifier': {
|
|
141
|
+
if (node.from) {
|
|
142
|
+
return walk(node.from, scope).map((read) => extend(read, [node.value]));
|
|
143
|
+
}
|
|
144
|
+
const binding = scope.get(node.value);
|
|
145
|
+
if (binding) {
|
|
146
|
+
binding.used = true;
|
|
147
|
+
return binding.value;
|
|
148
|
+
}
|
|
149
|
+
return [{ root: node.value, path: [] }];
|
|
150
|
+
}
|
|
151
|
+
case 'FilterExpression': {
|
|
152
|
+
const subject = walk(node.subject, scope);
|
|
153
|
+
const key = literalKey(node.expr);
|
|
154
|
+
if (key !== undefined) {
|
|
155
|
+
return subject.map((read) => extend(read, [key]));
|
|
156
|
+
}
|
|
157
|
+
use(node.expr, scope);
|
|
158
|
+
return subject.map((read) => extend(read, [], true));
|
|
159
|
+
}
|
|
160
|
+
case 'FunctionCall': {
|
|
161
|
+
return call(node, scope);
|
|
162
|
+
}
|
|
163
|
+
case 'ConditionalExpression': {
|
|
164
|
+
const test = walk(node.test, scope);
|
|
165
|
+
consume(test);
|
|
166
|
+
const consequent = node.consequent
|
|
167
|
+
? branch(node.consequent, scope)
|
|
168
|
+
: test;
|
|
169
|
+
return [...consequent, ...branch(node.alternate, scope)];
|
|
170
|
+
}
|
|
171
|
+
case 'BinaryExpression': {
|
|
172
|
+
use(node.left, scope);
|
|
173
|
+
consume(branch(node.right, scope));
|
|
174
|
+
return [];
|
|
175
|
+
}
|
|
176
|
+
case 'UnaryExpression': {
|
|
177
|
+
use(node.right, scope);
|
|
178
|
+
return [];
|
|
179
|
+
}
|
|
180
|
+
case 'ArrayLiteral': {
|
|
181
|
+
for (const item of node.value) {
|
|
182
|
+
use(item, scope);
|
|
183
|
+
}
|
|
184
|
+
return [];
|
|
185
|
+
}
|
|
186
|
+
case 'ObjectLiteral': {
|
|
187
|
+
for (const value of Object.values(node.value)) {
|
|
188
|
+
use(value, scope);
|
|
189
|
+
}
|
|
190
|
+
return [];
|
|
191
|
+
}
|
|
192
|
+
case 'TemplateLiteral': {
|
|
193
|
+
for (const part of node.parts) {
|
|
194
|
+
if (part.type === 'expression') {
|
|
195
|
+
use(part.value, scope);
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
return [];
|
|
199
|
+
}
|
|
200
|
+
case 'SequenceExpression': {
|
|
201
|
+
const exprs = node.expressions;
|
|
202
|
+
for (const expr of exprs.slice(0, -1)) {
|
|
203
|
+
const value = walk(expr, scope);
|
|
204
|
+
if (expr.type !== 'AssignmentExpression') {
|
|
205
|
+
consume(value);
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
return walk(exprs.at(-1), scope);
|
|
209
|
+
}
|
|
210
|
+
case 'AssignmentExpression': {
|
|
211
|
+
const value = walk(node.right, scope);
|
|
212
|
+
const name = node.left.value;
|
|
213
|
+
const previous = scope.get(name);
|
|
214
|
+
if (previous && !previous.used) {
|
|
215
|
+
consume(previous.value);
|
|
216
|
+
}
|
|
217
|
+
scope.set(name, { value, used: false });
|
|
218
|
+
assigned.add(name);
|
|
219
|
+
return value;
|
|
220
|
+
}
|
|
221
|
+
case 'Lambda': {
|
|
222
|
+
const inner = new Map(scope);
|
|
223
|
+
for (const param of node.params) {
|
|
224
|
+
inner.set(param, { value: [], used: true });
|
|
225
|
+
}
|
|
226
|
+
use(node.body, inner);
|
|
227
|
+
return [];
|
|
228
|
+
}
|
|
229
|
+
default: {
|
|
230
|
+
throw new Error(`Corrupt AST: unknown node type '${ast.type}'`);
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
const scope = new Map();
|
|
235
|
+
const returns = ast ? walk(ast, scope) : [];
|
|
236
|
+
consume(returns);
|
|
237
|
+
release(scope);
|
|
238
|
+
const readList = [...reads.values()];
|
|
239
|
+
const fields = new Map();
|
|
240
|
+
for (const read of readList) {
|
|
241
|
+
const field = fieldOf(read, row, env);
|
|
242
|
+
if (field) {
|
|
243
|
+
fields.set(JSON.stringify(field), field);
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
return {
|
|
247
|
+
variables: [...new Set(readList.map((read) => read.root))],
|
|
248
|
+
reads: readList,
|
|
249
|
+
fields: [...fields.values()],
|
|
250
|
+
returns,
|
|
251
|
+
bare: ast !== null && isBarePath(ast),
|
|
252
|
+
calls,
|
|
253
|
+
assigned: [...assigned]
|
|
254
|
+
};
|
|
255
|
+
}
|
|
256
|
+
//# 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/esm/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 {};
|