@valtzu/codemirror-lang-el 0.6.1 → 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 +58 -15
- package/dist/complete.js +58 -15
- package/dist/index.cjs +97 -32
- package/dist/index.d.cts +7 -1
- package/dist/index.d.ts +7 -1
- package/dist/index.js +98 -33
- package/dist/linter.cjs +58 -4
- package/dist/linter.js +58 -4
- package/dist/tooltip.cjs +48 -18
- package/dist/tooltip.d.cts +4 -3
- package/dist/tooltip.d.ts +4 -3
- package/dist/tooltip.js +50 -19
- 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 BinaryExpression OperatorKeyword
|
|
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;
|
|
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,8 +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
|
}
|
|
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)) {
|
|
127
|
+
const operator = state.sliceDoc(node.firstChild.nextSibling.from, node.firstChild.nextSibling.to);
|
|
128
|
+
if (operator == '?:' || operator == '??' || operator == '?') {
|
|
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);
|
|
148
|
+
}
|
|
149
|
+
}
|
|
105
150
|
if (types.size === 0) {
|
|
106
|
-
types.add(
|
|
151
|
+
types.add(ELScalar.Any);
|
|
107
152
|
}
|
|
108
153
|
return types;
|
|
109
154
|
}
|
|
@@ -120,6 +165,7 @@ const keywords = [
|
|
|
120
165
|
{ name: 'not' },
|
|
121
166
|
{ name: 'or' },
|
|
122
167
|
{ name: 'and' },
|
|
168
|
+
{ name: 'xor' },
|
|
123
169
|
];
|
|
124
170
|
|
|
125
171
|
/**
|
|
@@ -155,7 +201,7 @@ const expressionLanguageLinterSource = (state) => {
|
|
|
155
201
|
let i = 0;
|
|
156
202
|
let n = node.node.firstChild;
|
|
157
203
|
while (n) {
|
|
158
|
-
if (++i > args.length) {
|
|
204
|
+
if (n.name !== 'BlockComment' && ++i > args.length) {
|
|
159
205
|
diagnostics.push({ from: n.from, to: n.to, severity: 'error', message: `Unexpected argument` });
|
|
160
206
|
}
|
|
161
207
|
n = n.nextSibling;
|
|
@@ -187,15 +233,15 @@ const expressionLanguageLinterSource = (state) => {
|
|
|
187
233
|
const expressionLanguageLinter = linter(view => expressionLanguageLinterSource(view.state));
|
|
188
234
|
|
|
189
235
|
const autocompleteFunction = (x) => {
|
|
190
|
-
var _a, _b;
|
|
236
|
+
var _a, _b, _c;
|
|
191
237
|
return ({
|
|
192
|
-
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(',')) || ''})`,
|
|
193
239
|
apply: (view, completion, from, to) => {
|
|
194
240
|
var _a;
|
|
195
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) } }));
|
|
196
242
|
},
|
|
197
|
-
detail: (
|
|
198
|
-
info:
|
|
243
|
+
detail: (_c = x.returnType) === null || _c === void 0 ? void 0 : _c.join('|'),
|
|
244
|
+
info: x.info,
|
|
199
245
|
type: "function",
|
|
200
246
|
});
|
|
201
247
|
};
|
|
@@ -204,7 +250,7 @@ const autocompleteIdentifier = (x) => {
|
|
|
204
250
|
return ({
|
|
205
251
|
label: x.name,
|
|
206
252
|
apply: x.name,
|
|
207
|
-
info:
|
|
253
|
+
info: x.info,
|
|
208
254
|
detail: x.detail || ((_a = x.type) === null || _a === void 0 ? void 0 : _a.join('|')),
|
|
209
255
|
type: 'variable',
|
|
210
256
|
});
|
|
@@ -214,7 +260,13 @@ function completeOperatorKeyword(state, config, tree, from, to, explicit) {
|
|
|
214
260
|
return {
|
|
215
261
|
from,
|
|
216
262
|
to,
|
|
217
|
-
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 : [],
|
|
218
270
|
validFor: (text) => { var _a; return (_a = keywords.some(({ name }) => explicit || name.includes(text))) !== null && _a !== void 0 ? _a : false; },
|
|
219
271
|
};
|
|
220
272
|
}
|
|
@@ -259,7 +311,7 @@ function expressionLanguageCompletion(context) {
|
|
|
259
311
|
const config = getExpressionLanguageConfig(state);
|
|
260
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 : ''); };
|
|
261
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 : ''); };
|
|
262
|
-
if (prevNode.name == 'String') {
|
|
314
|
+
if (prevNode.name == 'String' || prevNode.name == 'BlockComment') {
|
|
263
315
|
return null;
|
|
264
316
|
}
|
|
265
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) || '')) {
|
|
@@ -299,7 +351,7 @@ function getCursorTooltips(state) {
|
|
|
299
351
|
return state.selection.ranges
|
|
300
352
|
.filter(range => range.empty)
|
|
301
353
|
.map(range => {
|
|
302
|
-
var _a;
|
|
354
|
+
var _a, _b;
|
|
303
355
|
const tree = syntaxTree(state);
|
|
304
356
|
const node = tree.resolveInner(range.from, 0);
|
|
305
357
|
const args = resolveArguments(node);
|
|
@@ -311,7 +363,7 @@ function getCursorTooltips(state) {
|
|
|
311
363
|
return null;
|
|
312
364
|
}
|
|
313
365
|
const n = args.childAfter(range.from - 1);
|
|
314
|
-
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;
|
|
315
367
|
if (n && n.from !== range.from || !argName) {
|
|
316
368
|
return null;
|
|
317
369
|
}
|
|
@@ -386,17 +438,29 @@ const keywordTooltip = hoverTooltip((view, pos, side) => {
|
|
|
386
438
|
create: () => ({ dom: createInfoElement(info) }),
|
|
387
439
|
};
|
|
388
440
|
});
|
|
389
|
-
|
|
441
|
+
|
|
442
|
+
const baseTheme = EditorView.baseTheme({
|
|
390
443
|
".cm-tooltip.cm-tooltip-cursor": {
|
|
391
444
|
boxShadow: 'rgba(0, 0, 0, .15) 0 1px 2px',
|
|
392
445
|
border: "1px solid rgba(127, 127, 127, .2)",
|
|
393
|
-
|
|
446
|
+
fontSize: ".85rem",
|
|
447
|
+
padding: ".4rem .5rem",
|
|
394
448
|
borderRadius: "4px",
|
|
395
449
|
"& .cm-tooltip-arrow:before": {},
|
|
396
450
|
"& .cm-tooltip-arrow:after": {
|
|
397
451
|
borderTopColor: "transparent"
|
|
398
|
-
}
|
|
399
|
-
}
|
|
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
|
+
},
|
|
400
464
|
});
|
|
401
465
|
|
|
402
466
|
const ELLanguage = LRLanguage.define({
|
|
@@ -430,6 +494,7 @@ const ELLanguage = LRLanguage.define({
|
|
|
430
494
|
OperatorKeyword: tags.operatorKeyword,
|
|
431
495
|
UnaryOperator: tags.operator,
|
|
432
496
|
Operator: tags.operator,
|
|
497
|
+
BlockComment: tags.comment,
|
|
433
498
|
})
|
|
434
499
|
]
|
|
435
500
|
}),
|
|
@@ -444,7 +509,7 @@ function expressionlanguage(config = {}, extensions = []) {
|
|
|
444
509
|
expressionLanguageLinter,
|
|
445
510
|
keywordTooltip,
|
|
446
511
|
cursorTooltipField,
|
|
447
|
-
|
|
512
|
+
baseTheme,
|
|
448
513
|
...extensions,
|
|
449
514
|
]);
|
|
450
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;
|
|
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,14 +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
|
}
|
|
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)) {
|
|
98
|
+
const operator = state.sliceDoc(node.firstChild.nextSibling.from, node.firstChild.nextSibling.to);
|
|
99
|
+
if (operator == '?:' || operator == '??' || operator == '?') {
|
|
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);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
79
121
|
if (types.size === 0) {
|
|
80
|
-
types.add(
|
|
122
|
+
types.add(ELScalar.Any);
|
|
81
123
|
}
|
|
82
124
|
return types;
|
|
83
125
|
}
|
|
84
126
|
function getExpressionLanguageConfig(state) {
|
|
85
127
|
return state.languageDataAt('expressionLanguageConfig', 0)[0];
|
|
86
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
|
+
];
|
|
87
141
|
|
|
88
142
|
/**
|
|
89
143
|
* @internal
|
|
@@ -118,7 +172,7 @@ const expressionLanguageLinterSource = (state) => {
|
|
|
118
172
|
let i = 0;
|
|
119
173
|
let n = node.node.firstChild;
|
|
120
174
|
while (n) {
|
|
121
|
-
if (++i > args.length) {
|
|
175
|
+
if (n.name !== 'BlockComment' && ++i > args.length) {
|
|
122
176
|
diagnostics.push({ from: n.from, to: n.to, severity: 'error', message: `Unexpected argument` });
|
|
123
177
|
}
|
|
124
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;
|
|
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,14 +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
|
}
|
|
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)) {
|
|
94
|
+
const operator = state.sliceDoc(node.firstChild.nextSibling.from, node.firstChild.nextSibling.to);
|
|
95
|
+
if (operator == '?:' || operator == '??' || operator == '?') {
|
|
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);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
75
117
|
if (types.size === 0) {
|
|
76
|
-
types.add(
|
|
118
|
+
types.add(ELScalar.Any);
|
|
77
119
|
}
|
|
78
120
|
return types;
|
|
79
121
|
}
|
|
80
122
|
function getExpressionLanguageConfig(state) {
|
|
81
123
|
return state.languageDataAt('expressionLanguageConfig', 0)[0];
|
|
82
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
|
+
];
|
|
83
137
|
|
|
84
138
|
/**
|
|
85
139
|
* @internal
|
|
@@ -114,7 +168,7 @@ const expressionLanguageLinterSource = (state) => {
|
|
|
114
168
|
let i = 0;
|
|
115
169
|
let n = node.node.firstChild;
|
|
116
170
|
while (n) {
|
|
117
|
-
if (++i > args.length) {
|
|
171
|
+
if (n.name !== 'BlockComment' && ++i > args.length) {
|
|
118
172
|
diagnostics.push({ from: n.from, to: n.to, severity: 'error', message: `Unexpected argument` });
|
|
119
173
|
}
|
|
120
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;
|
|
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,8 +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
|
}
|
|
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)) {
|
|
105
|
+
const operator = state.sliceDoc(node.firstChild.nextSibling.from, node.firstChild.nextSibling.to);
|
|
106
|
+
if (operator == '?:' || operator == '??' || operator == '?') {
|
|
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);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
86
128
|
if (types.size === 0) {
|
|
87
|
-
types.add(
|
|
129
|
+
types.add(ELScalar.Any);
|
|
88
130
|
}
|
|
89
131
|
return types;
|
|
90
132
|
}
|
|
@@ -101,6 +143,7 @@ const keywords = [
|
|
|
101
143
|
{ name: 'not' },
|
|
102
144
|
{ name: 'or' },
|
|
103
145
|
{ name: 'and' },
|
|
146
|
+
{ name: 'xor' },
|
|
104
147
|
];
|
|
105
148
|
|
|
106
149
|
function getNodeOrdinal(node) {
|
|
@@ -123,7 +166,7 @@ function getCursorTooltips(state) {
|
|
|
123
166
|
return state.selection.ranges
|
|
124
167
|
.filter(range => range.empty)
|
|
125
168
|
.map(range => {
|
|
126
|
-
var _a;
|
|
169
|
+
var _a, _b;
|
|
127
170
|
const tree = language.syntaxTree(state);
|
|
128
171
|
const node = tree.resolveInner(range.from, 0);
|
|
129
172
|
const args = resolveArguments(node);
|
|
@@ -135,7 +178,7 @@ function getCursorTooltips(state) {
|
|
|
135
178
|
return null;
|
|
136
179
|
}
|
|
137
180
|
const n = args.childAfter(range.from - 1);
|
|
138
|
-
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;
|
|
139
182
|
if (n && n.from !== range.from || !argName) {
|
|
140
183
|
return null;
|
|
141
184
|
}
|
|
@@ -210,19 +253,6 @@ const keywordTooltip = view.hoverTooltip((view, pos, side) => {
|
|
|
210
253
|
create: () => ({ dom: createInfoElement(info) }),
|
|
211
254
|
};
|
|
212
255
|
});
|
|
213
|
-
const cursorTooltipBaseTheme = view.EditorView.baseTheme({
|
|
214
|
-
".cm-tooltip.cm-tooltip-cursor": {
|
|
215
|
-
boxShadow: 'rgba(0, 0, 0, .15) 0 1px 2px',
|
|
216
|
-
border: "1px solid rgba(127, 127, 127, .2)",
|
|
217
|
-
padding: "2px 7px",
|
|
218
|
-
borderRadius: "4px",
|
|
219
|
-
"& .cm-tooltip-arrow:before": {},
|
|
220
|
-
"& .cm-tooltip-arrow:after": {
|
|
221
|
-
borderTopColor: "transparent"
|
|
222
|
-
}
|
|
223
|
-
}
|
|
224
|
-
});
|
|
225
256
|
|
|
226
|
-
exports.cursorTooltipBaseTheme = cursorTooltipBaseTheme;
|
|
227
257
|
exports.cursorTooltipField = cursorTooltipField;
|
|
228
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 };
|