@valtzu/codemirror-lang-el 0.6.2 → 0.7.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/CHANGELOG.md +13 -0
- package/README.md +2 -9
- package/dist/complete.cjs +54 -20
- package/dist/complete.js +54 -20
- package/dist/index.cjs +93 -37
- package/dist/index.d.cts +7 -1
- package/dist/index.d.ts +7 -1
- package/dist/index.js +94 -38
- package/dist/linter.cjs +54 -9
- package/dist/linter.js +54 -9
- package/dist/tooltip.cjs +44 -23
- package/dist/tooltip.d.cts +4 -3
- package/dist/tooltip.d.ts +4 -3
- package/dist/tooltip.js +46 -24
- package/dist/utils.cjs +150 -0
- package/dist/utils.d.cts +53 -0
- package/dist/utils.d.ts +53 -0
- package/dist/utils.js +141 -0
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { LRParser } from '@lezer/lr';
|
|
1
|
+
import { LRParser, LocalTokenGroup } from '@lezer/lr';
|
|
2
2
|
import { syntaxTree, LRLanguage, indentNodeProp, delimitedIndent, foldNodeProp, LanguageSupport } from '@codemirror/language';
|
|
3
3
|
import { styleTags, tags } from '@lezer/highlight';
|
|
4
4
|
import { linter } from '@codemirror/lint';
|
|
@@ -6,25 +6,42 @@ import { insertCompletionText } from '@codemirror/autocomplete';
|
|
|
6
6
|
import { StateField } from '@codemirror/state';
|
|
7
7
|
import { showTooltip, hoverTooltip, EditorView } from '@codemirror/view';
|
|
8
8
|
|
|
9
|
+
// @ts-ignore
|
|
10
|
+
const t = {
|
|
11
|
+
deserialize: (str) => str,
|
|
12
|
+
};
|
|
13
|
+
|
|
9
14
|
// This file was generated by lezer-generator. You probably shouldn't edit it.
|
|
10
|
-
const spec_word = {__proto__:null,true:
|
|
11
|
-
const spec_Operator = {__proto__:null,"?":
|
|
15
|
+
const spec_word = {__proto__:null,true:92, TRUE:94, false:96, FALSE:98, null:100, NULL:102, starts:112, with:114, ends:116, contains:118, matches:120, not:122, in:124, and:126, or:128, xor:130};
|
|
16
|
+
const spec_Operator = {__proto__:null,"?":111, "!":133, "+":135, "-":137};
|
|
12
17
|
const parser = LRParser.deserialize({
|
|
13
18
|
version: 14,
|
|
14
|
-
states: "
|
|
15
|
-
stateData: "
|
|
16
|
-
goto: "%
|
|
17
|
-
nodeNames: "⚠ Expression ObjectAccess MemberOf NullSafeMemberOf Property ArrayAccess Call Function Arguments ObjectAccess Method Arguments Number String Boolean Null Object Array Variable TernaryExpression Operator BinaryExpression OperatorKeyword UnaryExpression UnaryOperator Application",
|
|
18
|
-
maxTerm:
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
19
|
+
states: ")rOYQPOOP!^OPOOQ!cQPOOO#aQPO'#CeO$tQPO'#CnO${QPO'#CoOYQPO'#CuOYQPO'#CwOOQO'#DS'#DSO%SQPO'#CdO%XQPO'#CdOOQO'#Cl'#ClOOQO'#Cm'#CmOOQO'#Cv'#CvP%^OQO'#C]POOO)C>r)C>rO%iQPO,58yOYQPO,58}OYQPO,59_OYQPO,59]O%nQPO'#CtOOQO'#Ct'#CtO%sQPO'#CtO&zQPO,59YOOQO,59Y,59YO'RQPO'#DYO'`QPO,59ZO'eQPO,59aO'{QPO,59cO(SQPO'#CfOOQO,59O,59OO(SQPO'#CiPOOO'#Cx'#CxP(ZOQO,58wPOOO,58w,58wO(fQPO'#CbOOQO1G.e1G.eOOQO1G.m1G.mO)yQPO1G.iO*QQPO1G.yO*hQPO1G.wOOQO,59`,59`OYQPO1G.tOYQPO'#CyO*oQPO,59tOOQO1G.u1G.uOOQO1G.}1G.}O*zQPO,59QO+PQPO,59TPOOO-E6v-E6vPOOO1G.c1G.cOOQO7+$T7+$TOYQPO7+$cO+UQPO7+$`O+`QPO,59eOOQO-E6w-E6wOOQO1G.l1G.lOOQO1G.o1G.oO+mQPO<<G}OYQPO'#CzO,TQPO<<GzOOQO<<Gz<<GzO,]QPO,59fOOQO-E6x-E6xOOQOAN=fAN=fOYQPO1G/QO,dQPO7+$l",
|
|
20
|
+
stateData: ",v~OqOSrPQ~O^WO_WOwROyTO{VO!OZO!PZO!QZO!RZO!S[O!T[O!VSO!_]O!d]O!e]O!f]O~Or^O~OS`OT`OfbOyaO!XcO!YdO![dO!]eO!^eO!_fO!`eO!aeO!beO!ceO~OSdXTdXfdXodXydX{XX!XdX!YdX![dX!]dX!^dX!_dX!`dX!adX!bdX!cdX!WdXxdX}dXzdX!UdX~O!UhO~PYOx|P~PYO{mO~O{oO~OspOtpOurO~OwsO~O!ZyO~O!`yO^hX_hXwhXyhX{hX!OhX!PhX!QhX!RhX!ShX!ThX!VhX!_hX!dhX!ehX!fhX~O!WzO~P!cO}{Ox|Xz|X~P!cOx}O~Ooia!Wiaxia}iazia!Uia~P!cOz!OO~P!cOz|P~PYOspOtpOu!SO~OSUXTUXfUXoUXyUX{[X!XUX!YUX![UX!]UX!^UX!_UX!`UX!aUX!bUX!cUX!WUXxUX}UXzUX!UUX~Ox!TO~P!cOogi!Wgixgi}gizgi!Ugi~P!cO!W!UO~P!cO}{Ox|az|a~Oz!YO~Oz!ZO~O}!]O!U!_O~P!cOxma}mazma~P!cOoey!Weyxey}eyzey!Uey~P!cO}!]O!U!bO~O!W!cO~P!cO}nq!Unq~P!cO_TfS^wS~",
|
|
21
|
+
goto: "%l}P!OP!RPP!d!R!R!g!x!{#^#aPP!R!R!R!R!R!RP!R#d!R#s!R$U$[$bPPPPPPP$hPPPPP%cR_PoWOSTUVabcmoz{!U!]!cRt`oXOSTUVabcmoz{!U!]!cRnXoYOSTUVabcmoz{!U!]!cRu`RnYkbQgiklvwx!V!W![!`!doUOSTUVabcmoz{!U!]!cQq^R!RqQ|iR!X|Q!^!VR!a!^QQOQgSUiTmoQkUQlVQvaQwbQxcQ!VzQ!W{Q![!UQ!`!]R!d!cQjTQ!PmR!Qo",
|
|
22
|
+
nodeNames: "⚠ BlockComment Expression ObjectAccess MemberOf NullSafeMemberOf Property ArrayAccess Call Function Arguments ObjectAccess Method Arguments Number String Boolean Null Object Array Variable TernaryExpression Operator BinaryExpression OperatorKeyword UnaryExpression UnaryOperator Application",
|
|
23
|
+
maxTerm: 68,
|
|
24
|
+
nodeProps: [
|
|
25
|
+
[t, 14,"number",15,"string",16,"bool",17,"null"]
|
|
26
|
+
],
|
|
27
|
+
skippedNodes: [0,1,28],
|
|
28
|
+
repeatNodeCount: 3,
|
|
29
|
+
tokenData: "-a~RqXY#YYZ#Y]^#Ypq#Yqr#krs$Quv#{vw%zwx&Sxy'wyz'|z{(R{|#{|}(Z}!O#{!O!P(`!P!Q(h!Q![(u![!]+[!^!_+a!_!`+l!`!a+r!a!b+}!c!},b!}#O,s#P#Q,x#Q#R#{#R#S,b#T#o,b#o#p,}#p#q-S#q#r-[#r#s#{~#_Sq~XY#YYZ#Y]^#Ypq#Y~#pPf~!_!`#s~#xPf~!_!`#{~$QOf~~$TXOr$Qrs$ps#O$Q#O#P$u#P;'S$Q;'S;=`%t<%l~$Q~O$Q~~$p~$uO_~~$xRO;'S$Q;'S;=`%R;=`O$Q~%UYOr$Qrs$ps#O$Q#O#P$u#P;'S$Q;'S;=`%t;=`<%l$Q<%l~$Q~O$Q~~$p~%wP;=`<%l$Q~&PPf~vw#{~&VXOw&Swx$px#O&S#O#P&r#P;'S&S;'S;=`'q<%l~&S~O&S~~$p~&uRO;'S&S;'S;=`'O;=`O&S~'RYOw&Swx$px#O&S#O#P&r#P;'S&S;'S;=`'q;=`<%l&S<%l~&S~O&S~~$p~'tP;=`<%l&S~'|O{~~(ROz~~(WPf~z{#{~(`O}~~(ePS~!O!P#{~(mPf~z{(p~(uOr~~(zT^~!O!P)Z!Q![(u!g!h*Z#R#S+U#X#Y*Z~)^SO!O)j!P;'S)j;'S;=`+O<%lO)j~)oR^~!Q![)x!g!h*Z#X#Y*Z~)}S^~!Q![)x!g!h*Z#R#S*x#X#Y*Z~*^R{|*g}!O*g!Q![*m~*jP!Q![*m~*rQ^~!Q![*m#R#S*g~*{P!Q![)x~+RP;=`<%l)j~+XP!Q![(u~+aO!W~~+fQf~!^!_#{!_!`#{~+oP!_!`#s~+wQf~!_!`#{!`!a#{~,SRf~!O!P,]![!]#{!a!b#{~,bOT~~,gSw~!Q![,b!c!},b#R#S,b#T#o,b~,xOy~~,}Ox~~-SO!V~~-XPf~#p#q#{~-aO!U~",
|
|
30
|
+
tokenizers: [1, new LocalTokenGroup("j~RQYZXz{^~^Ot~~aP!P!Qd~iOu~~", 25, 35)],
|
|
31
|
+
topRules: {"Expression":[0,2]},
|
|
32
|
+
specialized: [{term: 39, get: (value) => spec_word[value] || -1},{term: 22, get: (value) => spec_Operator[value] || -1}],
|
|
33
|
+
tokenPrec: 536
|
|
26
34
|
});
|
|
27
35
|
|
|
36
|
+
var ELScalar;
|
|
37
|
+
(function (ELScalar) {
|
|
38
|
+
ELScalar["Bool"] = "bool";
|
|
39
|
+
ELScalar["Number"] = "number";
|
|
40
|
+
ELScalar["String"] = "string";
|
|
41
|
+
ELScalar["Null"] = "null";
|
|
42
|
+
ELScalar["Any"] = "any";
|
|
43
|
+
})(ELScalar || (ELScalar = {}));
|
|
44
|
+
|
|
28
45
|
const createInfoElement = (html) => {
|
|
29
46
|
const dom = document.createElement("div");
|
|
30
47
|
dom.innerHTML = html;
|
|
@@ -61,12 +78,16 @@ const resolveIdentifier = (nodeName, identifier, config) => {
|
|
|
61
78
|
}
|
|
62
79
|
};
|
|
63
80
|
function resolveTypes(state, node, config, matchExact) {
|
|
64
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
|
|
81
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l;
|
|
65
82
|
let types = new Set();
|
|
66
83
|
if (!node) {
|
|
67
84
|
return types;
|
|
68
85
|
}
|
|
69
|
-
|
|
86
|
+
let type;
|
|
87
|
+
if (typeof (type = node.type.prop(t)) !== "undefined") {
|
|
88
|
+
types.add(type);
|
|
89
|
+
}
|
|
90
|
+
else if (node.name === 'Call' && node.firstChild && node.lastChild) {
|
|
70
91
|
resolveTypes(state, node.firstChild, config).forEach(x => types.add(x));
|
|
71
92
|
}
|
|
72
93
|
else if (node.name === 'Variable') {
|
|
@@ -102,17 +123,32 @@ function resolveTypes(state, node, config, matchExact) {
|
|
|
102
123
|
resolveTypes(state, node.firstChild.nextSibling, config).forEach(x => types.add(x));
|
|
103
124
|
resolveTypes(state, node.firstChild.nextSibling.nextSibling, config).forEach(x => types.add(x));
|
|
104
125
|
}
|
|
105
|
-
else if (node.name === 'BinaryExpression' && ((
|
|
126
|
+
else if (node.name === 'BinaryExpression' && ((_j = node.firstChild) === null || _j === void 0 ? void 0 : _j.nextSibling) && ((_l = (_k = node.firstChild) === null || _k === void 0 ? void 0 : _k.nextSibling) === null || _l === void 0 ? void 0 : _l.nextSibling)) {
|
|
106
127
|
const operator = state.sliceDoc(node.firstChild.nextSibling.from, node.firstChild.nextSibling.to);
|
|
107
|
-
if (operator == '?:' || operator == '??') {
|
|
108
|
-
resolveTypes(state, node.firstChild, config).forEach(x => types.add(x));
|
|
109
|
-
}
|
|
110
128
|
if (operator == '?:' || operator == '??' || operator == '?') {
|
|
111
|
-
|
|
129
|
+
if (operator == '?:' || operator == '??') {
|
|
130
|
+
resolveTypes(state, node.firstChild, config).forEach(x => types.add(x));
|
|
131
|
+
}
|
|
132
|
+
resolveTypes(state, node.firstChild.nextSibling.nextSibling, config).forEach(x => types.add(x));
|
|
133
|
+
}
|
|
134
|
+
else if (['||', '&&', '==', '!=', '===', '!==', '>=', '<=', '>', '<'].includes(operator) || keywords.find(x => x.name == operator)) {
|
|
135
|
+
types.add(ELScalar.Bool);
|
|
136
|
+
}
|
|
137
|
+
else if (['**', '|', '^', '&', '<<', '>>', '+', '-', '*', '/', '%'].includes(operator)) {
|
|
138
|
+
types.add(ELScalar.Number);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
else if (node.name === 'UnaryExpression' && node.firstChild) {
|
|
142
|
+
const operator = state.sliceDoc(node.firstChild.from, node.firstChild.to);
|
|
143
|
+
if (['not', '!'].includes(operator)) {
|
|
144
|
+
types.add(ELScalar.Bool);
|
|
145
|
+
}
|
|
146
|
+
else if (['+', '-'].includes(operator)) {
|
|
147
|
+
types.add(ELScalar.Number);
|
|
112
148
|
}
|
|
113
149
|
}
|
|
114
150
|
if (types.size === 0) {
|
|
115
|
-
types.add(
|
|
151
|
+
types.add(ELScalar.Any);
|
|
116
152
|
}
|
|
117
153
|
return types;
|
|
118
154
|
}
|
|
@@ -129,6 +165,7 @@ const keywords = [
|
|
|
129
165
|
{ name: 'not' },
|
|
130
166
|
{ name: 'or' },
|
|
131
167
|
{ name: 'and' },
|
|
168
|
+
{ name: 'xor' },
|
|
132
169
|
];
|
|
133
170
|
|
|
134
171
|
/**
|
|
@@ -164,7 +201,7 @@ const expressionLanguageLinterSource = (state) => {
|
|
|
164
201
|
let i = 0;
|
|
165
202
|
let n = node.node.firstChild;
|
|
166
203
|
while (n) {
|
|
167
|
-
if (++i > args.length) {
|
|
204
|
+
if (n.name !== 'BlockComment' && ++i > args.length) {
|
|
168
205
|
diagnostics.push({ from: n.from, to: n.to, severity: 'error', message: `Unexpected argument` });
|
|
169
206
|
}
|
|
170
207
|
n = n.nextSibling;
|
|
@@ -196,15 +233,15 @@ const expressionLanguageLinterSource = (state) => {
|
|
|
196
233
|
const expressionLanguageLinter = linter(view => expressionLanguageLinterSource(view.state));
|
|
197
234
|
|
|
198
235
|
const autocompleteFunction = (x) => {
|
|
199
|
-
var _a, _b;
|
|
236
|
+
var _a, _b, _c;
|
|
200
237
|
return ({
|
|
201
|
-
label: `${x.name}(${((_a = x.args) === null || _a === void 0 ? void 0 : _a.join(',')) || ''})`,
|
|
238
|
+
label: `${x.name}(${((_b = (_a = x.args) === null || _a === void 0 ? void 0 : _a.map(x => x.name)) === null || _b === void 0 ? void 0 : _b.join(',')) || ''})`,
|
|
202
239
|
apply: (view, completion, from, to) => {
|
|
203
240
|
var _a;
|
|
204
241
|
view.dispatch(Object.assign(Object.assign({}, insertCompletionText(view.state, `${x.name}()`, from, to)), { selection: { anchor: from + x.name.length + (((_a = x.args) === null || _a === void 0 ? void 0 : _a.length) > 0 ? 1 : 2) } }));
|
|
205
242
|
},
|
|
206
|
-
detail: (
|
|
207
|
-
info:
|
|
243
|
+
detail: (_c = x.returnType) === null || _c === void 0 ? void 0 : _c.join('|'),
|
|
244
|
+
info: x.info,
|
|
208
245
|
type: "function",
|
|
209
246
|
});
|
|
210
247
|
};
|
|
@@ -213,7 +250,7 @@ const autocompleteIdentifier = (x) => {
|
|
|
213
250
|
return ({
|
|
214
251
|
label: x.name,
|
|
215
252
|
apply: x.name,
|
|
216
|
-
info:
|
|
253
|
+
info: x.info,
|
|
217
254
|
detail: x.detail || ((_a = x.type) === null || _a === void 0 ? void 0 : _a.join('|')),
|
|
218
255
|
type: 'variable',
|
|
219
256
|
});
|
|
@@ -223,7 +260,13 @@ function completeOperatorKeyword(state, config, tree, from, to, explicit) {
|
|
|
223
260
|
return {
|
|
224
261
|
from,
|
|
225
262
|
to,
|
|
226
|
-
options: (_a = keywords.map(({ name, info, detail }) => ({
|
|
263
|
+
options: (_a = keywords.map(({ name, info, detail }) => ({
|
|
264
|
+
label: name,
|
|
265
|
+
apply: `${name} `,
|
|
266
|
+
info: info,
|
|
267
|
+
detail,
|
|
268
|
+
type: "keyword"
|
|
269
|
+
}))) !== null && _a !== void 0 ? _a : [],
|
|
227
270
|
validFor: (text) => { var _a; return (_a = keywords.some(({ name }) => explicit || name.includes(text))) !== null && _a !== void 0 ? _a : false; },
|
|
228
271
|
};
|
|
229
272
|
}
|
|
@@ -268,7 +311,7 @@ function expressionLanguageCompletion(context) {
|
|
|
268
311
|
const config = getExpressionLanguageConfig(state);
|
|
269
312
|
const isIdentifier = (node) => { var _a; return ['Variable', 'Function'].includes((_a = node === null || node === void 0 ? void 0 : node.name) !== null && _a !== void 0 ? _a : ''); };
|
|
270
313
|
const isMember = (node) => { var _a; return ['Property', 'Method'].includes((_a = node === null || node === void 0 ? void 0 : node.name) !== null && _a !== void 0 ? _a : ''); };
|
|
271
|
-
if (prevNode.name == 'String') {
|
|
314
|
+
if (prevNode.name == 'String' || prevNode.name == 'BlockComment') {
|
|
272
315
|
return null;
|
|
273
316
|
}
|
|
274
317
|
if (((_a = prevNode.parent) === null || _a === void 0 ? void 0 : _a.name) == 'ObjectAccess' && ['ObjectAccess', 'ArrayAccess', 'Variable', 'Call', 'Application'].includes(((_b = prevNode.parent.firstChild) === null || _b === void 0 ? void 0 : _b.name) || '')) {
|
|
@@ -308,7 +351,7 @@ function getCursorTooltips(state) {
|
|
|
308
351
|
return state.selection.ranges
|
|
309
352
|
.filter(range => range.empty)
|
|
310
353
|
.map(range => {
|
|
311
|
-
var _a;
|
|
354
|
+
var _a, _b;
|
|
312
355
|
const tree = syntaxTree(state);
|
|
313
356
|
const node = tree.resolveInner(range.from, 0);
|
|
314
357
|
const args = resolveArguments(node);
|
|
@@ -320,7 +363,7 @@ function getCursorTooltips(state) {
|
|
|
320
363
|
return null;
|
|
321
364
|
}
|
|
322
365
|
const n = args.childAfter(range.from - 1);
|
|
323
|
-
const argName = (_a = fn.args) === null || _a === void 0 ? void 0 : _a[n ? getNodeOrdinal(n) : 0];
|
|
366
|
+
const argName = (_b = (_a = fn.args) === null || _a === void 0 ? void 0 : _a[n ? getNodeOrdinal(n) : 0]) === null || _b === void 0 ? void 0 : _b.name;
|
|
324
367
|
if (n && n.from !== range.from || !argName) {
|
|
325
368
|
return null;
|
|
326
369
|
}
|
|
@@ -395,17 +438,29 @@ const keywordTooltip = hoverTooltip((view, pos, side) => {
|
|
|
395
438
|
create: () => ({ dom: createInfoElement(info) }),
|
|
396
439
|
};
|
|
397
440
|
});
|
|
398
|
-
|
|
441
|
+
|
|
442
|
+
const baseTheme = EditorView.baseTheme({
|
|
399
443
|
".cm-tooltip.cm-tooltip-cursor": {
|
|
400
444
|
boxShadow: 'rgba(0, 0, 0, .15) 0 1px 2px',
|
|
401
445
|
border: "1px solid rgba(127, 127, 127, .2)",
|
|
402
|
-
|
|
446
|
+
fontSize: ".85rem",
|
|
447
|
+
padding: ".4rem .5rem",
|
|
403
448
|
borderRadius: "4px",
|
|
404
449
|
"& .cm-tooltip-arrow:before": {},
|
|
405
450
|
"& .cm-tooltip-arrow:after": {
|
|
406
451
|
borderTopColor: "transparent"
|
|
407
|
-
}
|
|
408
|
-
}
|
|
452
|
+
},
|
|
453
|
+
},
|
|
454
|
+
".cm-tooltip.cm-completionInfo, .cm-diagnostic": {
|
|
455
|
+
boxShadow: "rgba(0, 0, 0, .15) 0 2px 5px",
|
|
456
|
+
fontSize: ".85rem",
|
|
457
|
+
padding: ".8rem !important", // Couldn't figure out other means to override https://github.com/codemirror/autocomplete/blob/6.18.1/src/theme.ts#L65
|
|
458
|
+
},
|
|
459
|
+
".cm-completionDetail": {
|
|
460
|
+
float: "right",
|
|
461
|
+
opacity: 0.5,
|
|
462
|
+
fontStyle: "inherit !important",
|
|
463
|
+
},
|
|
409
464
|
});
|
|
410
465
|
|
|
411
466
|
const ELLanguage = LRLanguage.define({
|
|
@@ -439,6 +494,7 @@ const ELLanguage = LRLanguage.define({
|
|
|
439
494
|
OperatorKeyword: tags.operatorKeyword,
|
|
440
495
|
UnaryOperator: tags.operator,
|
|
441
496
|
Operator: tags.operator,
|
|
497
|
+
BlockComment: tags.comment,
|
|
442
498
|
})
|
|
443
499
|
]
|
|
444
500
|
}),
|
|
@@ -453,7 +509,7 @@ function expressionlanguage(config = {}, extensions = []) {
|
|
|
453
509
|
expressionLanguageLinter,
|
|
454
510
|
keywordTooltip,
|
|
455
511
|
cursorTooltipField,
|
|
456
|
-
|
|
512
|
+
baseTheme,
|
|
457
513
|
...extensions,
|
|
458
514
|
]);
|
|
459
515
|
}
|
package/dist/linter.cjs
CHANGED
|
@@ -5,6 +5,20 @@ Object.defineProperty(exports, '__esModule', { value: true });
|
|
|
5
5
|
var lint = require('@codemirror/lint');
|
|
6
6
|
var language = require('@codemirror/language');
|
|
7
7
|
|
|
8
|
+
var ELScalar;
|
|
9
|
+
(function (ELScalar) {
|
|
10
|
+
ELScalar["Bool"] = "bool";
|
|
11
|
+
ELScalar["Number"] = "number";
|
|
12
|
+
ELScalar["String"] = "string";
|
|
13
|
+
ELScalar["Null"] = "null";
|
|
14
|
+
ELScalar["Any"] = "any";
|
|
15
|
+
})(ELScalar || (ELScalar = {}));
|
|
16
|
+
|
|
17
|
+
// @ts-ignore
|
|
18
|
+
const t = {
|
|
19
|
+
deserialize: (str) => str,
|
|
20
|
+
};
|
|
21
|
+
|
|
8
22
|
function resolveFunctionDefinition(node, state, config) {
|
|
9
23
|
var _a;
|
|
10
24
|
if (!node) {
|
|
@@ -35,12 +49,16 @@ const resolveIdentifier = (nodeName, identifier, config) => {
|
|
|
35
49
|
}
|
|
36
50
|
};
|
|
37
51
|
function resolveTypes(state, node, config, matchExact) {
|
|
38
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
|
|
52
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l;
|
|
39
53
|
let types = new Set();
|
|
40
54
|
if (!node) {
|
|
41
55
|
return types;
|
|
42
56
|
}
|
|
43
|
-
|
|
57
|
+
let type;
|
|
58
|
+
if (typeof (type = node.type.prop(t)) !== "undefined") {
|
|
59
|
+
types.add(type);
|
|
60
|
+
}
|
|
61
|
+
else if (node.name === 'Call' && node.firstChild && node.lastChild) {
|
|
44
62
|
resolveTypes(state, node.firstChild, config).forEach(x => types.add(x));
|
|
45
63
|
}
|
|
46
64
|
else if (node.name === 'Variable') {
|
|
@@ -76,23 +94,50 @@ function resolveTypes(state, node, config, matchExact) {
|
|
|
76
94
|
resolveTypes(state, node.firstChild.nextSibling, config).forEach(x => types.add(x));
|
|
77
95
|
resolveTypes(state, node.firstChild.nextSibling.nextSibling, config).forEach(x => types.add(x));
|
|
78
96
|
}
|
|
79
|
-
else if (node.name === 'BinaryExpression' && ((
|
|
97
|
+
else if (node.name === 'BinaryExpression' && ((_j = node.firstChild) === null || _j === void 0 ? void 0 : _j.nextSibling) && ((_l = (_k = node.firstChild) === null || _k === void 0 ? void 0 : _k.nextSibling) === null || _l === void 0 ? void 0 : _l.nextSibling)) {
|
|
80
98
|
const operator = state.sliceDoc(node.firstChild.nextSibling.from, node.firstChild.nextSibling.to);
|
|
81
|
-
if (operator == '?:' || operator == '??') {
|
|
82
|
-
resolveTypes(state, node.firstChild, config).forEach(x => types.add(x));
|
|
83
|
-
}
|
|
84
99
|
if (operator == '?:' || operator == '??' || operator == '?') {
|
|
85
|
-
|
|
100
|
+
if (operator == '?:' || operator == '??') {
|
|
101
|
+
resolveTypes(state, node.firstChild, config).forEach(x => types.add(x));
|
|
102
|
+
}
|
|
103
|
+
resolveTypes(state, node.firstChild.nextSibling.nextSibling, config).forEach(x => types.add(x));
|
|
104
|
+
}
|
|
105
|
+
else if (['||', '&&', '==', '!=', '===', '!==', '>=', '<=', '>', '<'].includes(operator) || keywords.find(x => x.name == operator)) {
|
|
106
|
+
types.add(ELScalar.Bool);
|
|
107
|
+
}
|
|
108
|
+
else if (['**', '|', '^', '&', '<<', '>>', '+', '-', '*', '/', '%'].includes(operator)) {
|
|
109
|
+
types.add(ELScalar.Number);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
else if (node.name === 'UnaryExpression' && node.firstChild) {
|
|
113
|
+
const operator = state.sliceDoc(node.firstChild.from, node.firstChild.to);
|
|
114
|
+
if (['not', '!'].includes(operator)) {
|
|
115
|
+
types.add(ELScalar.Bool);
|
|
116
|
+
}
|
|
117
|
+
else if (['+', '-'].includes(operator)) {
|
|
118
|
+
types.add(ELScalar.Number);
|
|
86
119
|
}
|
|
87
120
|
}
|
|
88
121
|
if (types.size === 0) {
|
|
89
|
-
types.add(
|
|
122
|
+
types.add(ELScalar.Any);
|
|
90
123
|
}
|
|
91
124
|
return types;
|
|
92
125
|
}
|
|
93
126
|
function getExpressionLanguageConfig(state) {
|
|
94
127
|
return state.languageDataAt('expressionLanguageConfig', 0)[0];
|
|
95
128
|
}
|
|
129
|
+
const keywords = [
|
|
130
|
+
{ name: 'starts with', info: 'Check if a string starts with a specific string' },
|
|
131
|
+
{ name: 'ends with', info: 'Check if a string ends with a specific string' },
|
|
132
|
+
{ name: 'contains', info: 'Check if a string is not included in another string' },
|
|
133
|
+
{ name: 'matches', info: 'Check if a string matches a regex pattern' },
|
|
134
|
+
{ name: 'not in', info: 'Check if a value is not included in an array' },
|
|
135
|
+
{ name: 'in', info: 'Check if a value is included in an array' },
|
|
136
|
+
{ name: 'not' },
|
|
137
|
+
{ name: 'or' },
|
|
138
|
+
{ name: 'and' },
|
|
139
|
+
{ name: 'xor' },
|
|
140
|
+
];
|
|
96
141
|
|
|
97
142
|
/**
|
|
98
143
|
* @internal
|
|
@@ -127,7 +172,7 @@ const expressionLanguageLinterSource = (state) => {
|
|
|
127
172
|
let i = 0;
|
|
128
173
|
let n = node.node.firstChild;
|
|
129
174
|
while (n) {
|
|
130
|
-
if (++i > args.length) {
|
|
175
|
+
if (n.name !== 'BlockComment' && ++i > args.length) {
|
|
131
176
|
diagnostics.push({ from: n.from, to: n.to, severity: 'error', message: `Unexpected argument` });
|
|
132
177
|
}
|
|
133
178
|
n = n.nextSibling;
|
package/dist/linter.js
CHANGED
|
@@ -1,6 +1,20 @@
|
|
|
1
1
|
import { linter } from '@codemirror/lint';
|
|
2
2
|
import { syntaxTree } from '@codemirror/language';
|
|
3
3
|
|
|
4
|
+
var ELScalar;
|
|
5
|
+
(function (ELScalar) {
|
|
6
|
+
ELScalar["Bool"] = "bool";
|
|
7
|
+
ELScalar["Number"] = "number";
|
|
8
|
+
ELScalar["String"] = "string";
|
|
9
|
+
ELScalar["Null"] = "null";
|
|
10
|
+
ELScalar["Any"] = "any";
|
|
11
|
+
})(ELScalar || (ELScalar = {}));
|
|
12
|
+
|
|
13
|
+
// @ts-ignore
|
|
14
|
+
const t = {
|
|
15
|
+
deserialize: (str) => str,
|
|
16
|
+
};
|
|
17
|
+
|
|
4
18
|
function resolveFunctionDefinition(node, state, config) {
|
|
5
19
|
var _a;
|
|
6
20
|
if (!node) {
|
|
@@ -31,12 +45,16 @@ const resolveIdentifier = (nodeName, identifier, config) => {
|
|
|
31
45
|
}
|
|
32
46
|
};
|
|
33
47
|
function resolveTypes(state, node, config, matchExact) {
|
|
34
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
|
|
48
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l;
|
|
35
49
|
let types = new Set();
|
|
36
50
|
if (!node) {
|
|
37
51
|
return types;
|
|
38
52
|
}
|
|
39
|
-
|
|
53
|
+
let type;
|
|
54
|
+
if (typeof (type = node.type.prop(t)) !== "undefined") {
|
|
55
|
+
types.add(type);
|
|
56
|
+
}
|
|
57
|
+
else if (node.name === 'Call' && node.firstChild && node.lastChild) {
|
|
40
58
|
resolveTypes(state, node.firstChild, config).forEach(x => types.add(x));
|
|
41
59
|
}
|
|
42
60
|
else if (node.name === 'Variable') {
|
|
@@ -72,23 +90,50 @@ function resolveTypes(state, node, config, matchExact) {
|
|
|
72
90
|
resolveTypes(state, node.firstChild.nextSibling, config).forEach(x => types.add(x));
|
|
73
91
|
resolveTypes(state, node.firstChild.nextSibling.nextSibling, config).forEach(x => types.add(x));
|
|
74
92
|
}
|
|
75
|
-
else if (node.name === 'BinaryExpression' && ((
|
|
93
|
+
else if (node.name === 'BinaryExpression' && ((_j = node.firstChild) === null || _j === void 0 ? void 0 : _j.nextSibling) && ((_l = (_k = node.firstChild) === null || _k === void 0 ? void 0 : _k.nextSibling) === null || _l === void 0 ? void 0 : _l.nextSibling)) {
|
|
76
94
|
const operator = state.sliceDoc(node.firstChild.nextSibling.from, node.firstChild.nextSibling.to);
|
|
77
|
-
if (operator == '?:' || operator == '??') {
|
|
78
|
-
resolveTypes(state, node.firstChild, config).forEach(x => types.add(x));
|
|
79
|
-
}
|
|
80
95
|
if (operator == '?:' || operator == '??' || operator == '?') {
|
|
81
|
-
|
|
96
|
+
if (operator == '?:' || operator == '??') {
|
|
97
|
+
resolveTypes(state, node.firstChild, config).forEach(x => types.add(x));
|
|
98
|
+
}
|
|
99
|
+
resolveTypes(state, node.firstChild.nextSibling.nextSibling, config).forEach(x => types.add(x));
|
|
100
|
+
}
|
|
101
|
+
else if (['||', '&&', '==', '!=', '===', '!==', '>=', '<=', '>', '<'].includes(operator) || keywords.find(x => x.name == operator)) {
|
|
102
|
+
types.add(ELScalar.Bool);
|
|
103
|
+
}
|
|
104
|
+
else if (['**', '|', '^', '&', '<<', '>>', '+', '-', '*', '/', '%'].includes(operator)) {
|
|
105
|
+
types.add(ELScalar.Number);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
else if (node.name === 'UnaryExpression' && node.firstChild) {
|
|
109
|
+
const operator = state.sliceDoc(node.firstChild.from, node.firstChild.to);
|
|
110
|
+
if (['not', '!'].includes(operator)) {
|
|
111
|
+
types.add(ELScalar.Bool);
|
|
112
|
+
}
|
|
113
|
+
else if (['+', '-'].includes(operator)) {
|
|
114
|
+
types.add(ELScalar.Number);
|
|
82
115
|
}
|
|
83
116
|
}
|
|
84
117
|
if (types.size === 0) {
|
|
85
|
-
types.add(
|
|
118
|
+
types.add(ELScalar.Any);
|
|
86
119
|
}
|
|
87
120
|
return types;
|
|
88
121
|
}
|
|
89
122
|
function getExpressionLanguageConfig(state) {
|
|
90
123
|
return state.languageDataAt('expressionLanguageConfig', 0)[0];
|
|
91
124
|
}
|
|
125
|
+
const keywords = [
|
|
126
|
+
{ name: 'starts with', info: 'Check if a string starts with a specific string' },
|
|
127
|
+
{ name: 'ends with', info: 'Check if a string ends with a specific string' },
|
|
128
|
+
{ name: 'contains', info: 'Check if a string is not included in another string' },
|
|
129
|
+
{ name: 'matches', info: 'Check if a string matches a regex pattern' },
|
|
130
|
+
{ name: 'not in', info: 'Check if a value is not included in an array' },
|
|
131
|
+
{ name: 'in', info: 'Check if a value is included in an array' },
|
|
132
|
+
{ name: 'not' },
|
|
133
|
+
{ name: 'or' },
|
|
134
|
+
{ name: 'and' },
|
|
135
|
+
{ name: 'xor' },
|
|
136
|
+
];
|
|
92
137
|
|
|
93
138
|
/**
|
|
94
139
|
* @internal
|
|
@@ -123,7 +168,7 @@ const expressionLanguageLinterSource = (state) => {
|
|
|
123
168
|
let i = 0;
|
|
124
169
|
let n = node.node.firstChild;
|
|
125
170
|
while (n) {
|
|
126
|
-
if (++i > args.length) {
|
|
171
|
+
if (n.name !== 'BlockComment' && ++i > args.length) {
|
|
127
172
|
diagnostics.push({ from: n.from, to: n.to, severity: 'error', message: `Unexpected argument` });
|
|
128
173
|
}
|
|
129
174
|
n = n.nextSibling;
|
package/dist/tooltip.cjs
CHANGED
|
@@ -6,6 +6,20 @@ var state = require('@codemirror/state');
|
|
|
6
6
|
var view = require('@codemirror/view');
|
|
7
7
|
var language = require('@codemirror/language');
|
|
8
8
|
|
|
9
|
+
var ELScalar;
|
|
10
|
+
(function (ELScalar) {
|
|
11
|
+
ELScalar["Bool"] = "bool";
|
|
12
|
+
ELScalar["Number"] = "number";
|
|
13
|
+
ELScalar["String"] = "string";
|
|
14
|
+
ELScalar["Null"] = "null";
|
|
15
|
+
ELScalar["Any"] = "any";
|
|
16
|
+
})(ELScalar || (ELScalar = {}));
|
|
17
|
+
|
|
18
|
+
// @ts-ignore
|
|
19
|
+
const t = {
|
|
20
|
+
deserialize: (str) => str,
|
|
21
|
+
};
|
|
22
|
+
|
|
9
23
|
const createInfoElement = (html) => {
|
|
10
24
|
const dom = document.createElement("div");
|
|
11
25
|
dom.innerHTML = html;
|
|
@@ -42,12 +56,16 @@ const resolveIdentifier = (nodeName, identifier, config) => {
|
|
|
42
56
|
}
|
|
43
57
|
};
|
|
44
58
|
function resolveTypes(state, node, config, matchExact) {
|
|
45
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
|
|
59
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l;
|
|
46
60
|
let types = new Set();
|
|
47
61
|
if (!node) {
|
|
48
62
|
return types;
|
|
49
63
|
}
|
|
50
|
-
|
|
64
|
+
let type;
|
|
65
|
+
if (typeof (type = node.type.prop(t)) !== "undefined") {
|
|
66
|
+
types.add(type);
|
|
67
|
+
}
|
|
68
|
+
else if (node.name === 'Call' && node.firstChild && node.lastChild) {
|
|
51
69
|
resolveTypes(state, node.firstChild, config).forEach(x => types.add(x));
|
|
52
70
|
}
|
|
53
71
|
else if (node.name === 'Variable') {
|
|
@@ -83,17 +101,32 @@ function resolveTypes(state, node, config, matchExact) {
|
|
|
83
101
|
resolveTypes(state, node.firstChild.nextSibling, config).forEach(x => types.add(x));
|
|
84
102
|
resolveTypes(state, node.firstChild.nextSibling.nextSibling, config).forEach(x => types.add(x));
|
|
85
103
|
}
|
|
86
|
-
else if (node.name === 'BinaryExpression' && ((
|
|
104
|
+
else if (node.name === 'BinaryExpression' && ((_j = node.firstChild) === null || _j === void 0 ? void 0 : _j.nextSibling) && ((_l = (_k = node.firstChild) === null || _k === void 0 ? void 0 : _k.nextSibling) === null || _l === void 0 ? void 0 : _l.nextSibling)) {
|
|
87
105
|
const operator = state.sliceDoc(node.firstChild.nextSibling.from, node.firstChild.nextSibling.to);
|
|
88
|
-
if (operator == '?:' || operator == '??') {
|
|
89
|
-
resolveTypes(state, node.firstChild, config).forEach(x => types.add(x));
|
|
90
|
-
}
|
|
91
106
|
if (operator == '?:' || operator == '??' || operator == '?') {
|
|
92
|
-
|
|
107
|
+
if (operator == '?:' || operator == '??') {
|
|
108
|
+
resolveTypes(state, node.firstChild, config).forEach(x => types.add(x));
|
|
109
|
+
}
|
|
110
|
+
resolveTypes(state, node.firstChild.nextSibling.nextSibling, config).forEach(x => types.add(x));
|
|
111
|
+
}
|
|
112
|
+
else if (['||', '&&', '==', '!=', '===', '!==', '>=', '<=', '>', '<'].includes(operator) || keywords.find(x => x.name == operator)) {
|
|
113
|
+
types.add(ELScalar.Bool);
|
|
114
|
+
}
|
|
115
|
+
else if (['**', '|', '^', '&', '<<', '>>', '+', '-', '*', '/', '%'].includes(operator)) {
|
|
116
|
+
types.add(ELScalar.Number);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
else if (node.name === 'UnaryExpression' && node.firstChild) {
|
|
120
|
+
const operator = state.sliceDoc(node.firstChild.from, node.firstChild.to);
|
|
121
|
+
if (['not', '!'].includes(operator)) {
|
|
122
|
+
types.add(ELScalar.Bool);
|
|
123
|
+
}
|
|
124
|
+
else if (['+', '-'].includes(operator)) {
|
|
125
|
+
types.add(ELScalar.Number);
|
|
93
126
|
}
|
|
94
127
|
}
|
|
95
128
|
if (types.size === 0) {
|
|
96
|
-
types.add(
|
|
129
|
+
types.add(ELScalar.Any);
|
|
97
130
|
}
|
|
98
131
|
return types;
|
|
99
132
|
}
|
|
@@ -110,6 +143,7 @@ const keywords = [
|
|
|
110
143
|
{ name: 'not' },
|
|
111
144
|
{ name: 'or' },
|
|
112
145
|
{ name: 'and' },
|
|
146
|
+
{ name: 'xor' },
|
|
113
147
|
];
|
|
114
148
|
|
|
115
149
|
function getNodeOrdinal(node) {
|
|
@@ -132,7 +166,7 @@ function getCursorTooltips(state) {
|
|
|
132
166
|
return state.selection.ranges
|
|
133
167
|
.filter(range => range.empty)
|
|
134
168
|
.map(range => {
|
|
135
|
-
var _a;
|
|
169
|
+
var _a, _b;
|
|
136
170
|
const tree = language.syntaxTree(state);
|
|
137
171
|
const node = tree.resolveInner(range.from, 0);
|
|
138
172
|
const args = resolveArguments(node);
|
|
@@ -144,7 +178,7 @@ function getCursorTooltips(state) {
|
|
|
144
178
|
return null;
|
|
145
179
|
}
|
|
146
180
|
const n = args.childAfter(range.from - 1);
|
|
147
|
-
const argName = (_a = fn.args) === null || _a === void 0 ? void 0 : _a[n ? getNodeOrdinal(n) : 0];
|
|
181
|
+
const argName = (_b = (_a = fn.args) === null || _a === void 0 ? void 0 : _a[n ? getNodeOrdinal(n) : 0]) === null || _b === void 0 ? void 0 : _b.name;
|
|
148
182
|
if (n && n.from !== range.from || !argName) {
|
|
149
183
|
return null;
|
|
150
184
|
}
|
|
@@ -219,19 +253,6 @@ const keywordTooltip = view.hoverTooltip((view, pos, side) => {
|
|
|
219
253
|
create: () => ({ dom: createInfoElement(info) }),
|
|
220
254
|
};
|
|
221
255
|
});
|
|
222
|
-
const cursorTooltipBaseTheme = view.EditorView.baseTheme({
|
|
223
|
-
".cm-tooltip.cm-tooltip-cursor": {
|
|
224
|
-
boxShadow: 'rgba(0, 0, 0, .15) 0 1px 2px',
|
|
225
|
-
border: "1px solid rgba(127, 127, 127, .2)",
|
|
226
|
-
padding: "2px 7px",
|
|
227
|
-
borderRadius: "4px",
|
|
228
|
-
"& .cm-tooltip-arrow:before": {},
|
|
229
|
-
"& .cm-tooltip-arrow:after": {
|
|
230
|
-
borderTopColor: "transparent"
|
|
231
|
-
}
|
|
232
|
-
}
|
|
233
|
-
});
|
|
234
256
|
|
|
235
|
-
exports.cursorTooltipBaseTheme = cursorTooltipBaseTheme;
|
|
236
257
|
exports.cursorTooltipField = cursorTooltipField;
|
|
237
258
|
exports.keywordTooltip = keywordTooltip;
|
package/dist/tooltip.d.cts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { StateField } from "@codemirror/state";
|
|
2
2
|
import { Tooltip } from "@codemirror/view";
|
|
3
3
|
declare const cursorTooltipField: StateField<readonly Tooltip[]>;
|
|
4
|
-
declare const keywordTooltip: import("@codemirror/state").Extension
|
|
5
|
-
|
|
6
|
-
|
|
4
|
+
declare const keywordTooltip: import("@codemirror/state").Extension & {
|
|
5
|
+
active: StateField<readonly Tooltip[]>;
|
|
6
|
+
};
|
|
7
|
+
export { cursorTooltipField, keywordTooltip };
|
package/dist/tooltip.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { StateField } from "@codemirror/state";
|
|
2
2
|
import { Tooltip } from "@codemirror/view";
|
|
3
3
|
declare const cursorTooltipField: StateField<readonly Tooltip[]>;
|
|
4
|
-
declare const keywordTooltip: import("@codemirror/state").Extension
|
|
5
|
-
|
|
6
|
-
|
|
4
|
+
declare const keywordTooltip: import("@codemirror/state").Extension & {
|
|
5
|
+
active: StateField<readonly Tooltip[]>;
|
|
6
|
+
};
|
|
7
|
+
export { cursorTooltipField, keywordTooltip };
|