@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/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:80, false:82, null:84, starts:94, with:96, ends:98, contains:100, matches:102, not:104, in:106, and:108, or:110};
11
- const spec_Operator = {__proto__:null,"!":113, "+":115, "-":117};
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: "(pOVQPOOQ!QQPOOO!{QPO'#CdO$]QPO'#CmO$dQPO'#CnOVQPO'#CtOVQPO'#CvOOQO'#C|'#C|O$kQPO'#CcO$pQPO'#CcOOQO'#Ck'#CkOOQO'#Cl'#ClOOQO'#Cu'#CuO$uQPO,58xOVQPO,58|OVQPO,59[OVQPO,59]O$zQPO'#CrOOQO'#Cr'#CrO%PQPO'#CrO%}QPO,59XOOQO,59X,59XO&UQPO'#DSO&cQPO,59YO&hQPO,59`O'OQPO,59bO'VQPO'#CeOOQO,58},58}O'VQPO'#ChO'^QPO'#CaOOQO1G.d1G.dOOQO1G.l1G.lO(nQPO1G.hO(uQPO1G.vO(|QPO1G.wOOQO,59^,59^OVQPO1G.sOVQPO'#CwO)dQPO,59nOOQO1G.t1G.tOOQO1G.|1G.|O)oQPO,59PO)tQPO,59SOOQO7+$S7+$SOVQPO7+$bO)yQPO7+$_O*TQPO,59cOOQO-E6u-E6uOOQO1G.k1G.kOOQO1G.n1G.nO*bQPO<<G|OVQPO'#CxO*xQPO<<GyOOQO<<Gy<<GyO+QQPO,59dOOQO-E6v-E6vOOQOAN=eAN=eOVQPO1G/OO+XQPO7+$j",
15
- stateData: "+k~OoOS~O]VO^VOqQOsSOuUOxYOyYOzZO|RO!U[O!Y[O!Z[O![[O~OR]OS]Og`Os^O!O_O!PaO!RaO!SbO!TbO!UcO!VbO!WbO!XbO~ORcXScXgcXmcXscXuWX!OcX!PcX!RcX!ScX!TcX!UcX!VcX!WcX!XcX}cXrcXwcXtcX{cX~O{eO~PVOrvP~PVOujO~OulO~OqmO~O!QsO~O!VsO]fX^fXqfXsfXufXxfXyfXzfX|fX!UfX!YfX!ZfX![fX~O}tO~P!QOwuOrvXtvX~P!QOrwO~Omha}harhawhatha{ha~P!QOtxO~P!QOtvP~PVORTXSTXgTXmTXsTXuZX!OTX!PTX!RTX!STX!TTX!UTX!VTX!WTX!XTX}TXrTXwTXtTX{TX~Or{O~P!QO}|O~P!QOmei}eireiweitei{ei~P!QOwuOrvatva~Ot!QO~Ot!RO~Ow!TO{!VO~P!QOrkawkatka~P!QOmdy}dyrdywdytdy{dy~P!QOw!TO{!YO~O}!ZO~P!QOwlq{lq~P!QO^gRS]qS~",
16
- goto: "%]wPPxPP!Zxx!^!o!r#T#WPPxxxxxxx#ZPx#jx#{$RPPP$XPPPPP%SoVORSTU^_`jltu|!T!ZRn]oWORSTU^_`jltu|!T!ZRkWoXORSTU^_`jltu|!T!ZRo]RkXk`Pdfhipqr}!O!S!W![oTORSTU^_`jltu|!T!ZQvfR!PvQ!U}R!X!UQPOQdRUfSjlQhTQiUQp^Qq_Qr`Q}tQ!OuQ!S|Q!W!TR![!ZQgSQyjRzl",
17
- nodeNames: "⚠ Expression ObjectAccess MemberOf NullSafeMemberOf Property ArrayAccess Call Function Arguments ObjectAccess Method Arguments Number String Boolean Null Object Array Variable TernaryExpression BinaryExpression OperatorKeyword Operator UnaryExpression UnaryOperator Application",
18
- maxTerm: 58,
19
- skippedNodes: [0],
20
- repeatNodeCount: 2,
21
- tokenData: ",l~RqXY#YYZ#Y]^#Ypq#Yqr#krs$Quv#{vw%zwx&Sxy'wyz'|z{(R{|#{|}(Z}!O#{!O!P(`!P!Q#{!Q![(h![!]*}!^!_#s!_!`+S!`!a#s!a!b+Y!c!}+m!}#O,O#P#Q,T#Q#R#{#R#S+m#T#o+m#o#p,Y#p#q,_#q#r,g#r#s#{~#_So~XY#YYZ#Y]^#Ypq#Y~#pPg~!_!`#s~#xPg~!_!`#{~$QOg~~$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~&PPg~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~'|Ou~~(ROt~~(WPg~z{#{~(`Ow~~(ePR~!O!P#{~(mT]~!O!P(|!Q![(h!g!h)|#R#S*w#X#Y)|~)PSO!O)]!P;'S)];'S;=`*q<%lO)]~)bR]~!Q![)k!g!h)|#X#Y)|~)pS]~!Q![)k!g!h)|#R#S*k#X#Y)|~*PR{|*Y}!O*Y!Q![*`~*]P!Q![*`~*eQ]~!Q![*`#R#S*Y~*nP!Q![)k~*tP;=`<%l)]~*zP!Q![(h~+SO}~~+VP!_!`#s~+_R!O~!O!P+h![!]#{!a!b#{~+mOS~~+rSq~!Q![+m!c!}+m#R#S+m#T#o+m~,TOs~~,YOr~~,_O|~~,dPg~#p#q#{~,lO{~",
22
- tokenizers: [0],
23
- topRules: {"Expression":[0,1]},
24
- specialized: [{term: 33, get: (value) => spec_word[value] || -1},{term: 23, get: (value) => spec_Operator[value] || -1}],
25
- tokenPrec: 479
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
- if (node.name === 'Call' && node.firstChild && node.lastChild) {
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('any');
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: (_b = x.returnType) === null || _b === void 0 ? void 0 : _b.join('|'),
198
- info: () => { var _a; return createInfoElement((_a = x.info) !== null && _a !== void 0 ? _a : ''); },
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: () => { var _a; return createInfoElement((_a = x.info) !== null && _a !== void 0 ? _a : ''); },
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 }) => ({ label: name, apply: `${name} `, info, detail, type: "keyword" }))) !== null && _a !== void 0 ? _a : [],
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
- const cursorTooltipBaseTheme = EditorView.baseTheme({
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
- padding: "2px 7px",
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
- cursorTooltipBaseTheme,
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
- if (node.name === 'Call' && node.firstChild && node.lastChild) {
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('any');
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
- if (node.name === 'Call' && node.firstChild && node.lastChild) {
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('any');
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
- if (node.name === 'Call' && node.firstChild && node.lastChild) {
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('any');
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;
@@ -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
- declare const cursorTooltipBaseTheme: import("@codemirror/state").Extension;
6
- export { cursorTooltipField, keywordTooltip, cursorTooltipBaseTheme };
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
- declare const cursorTooltipBaseTheme: import("@codemirror/state").Extension;
6
- export { cursorTooltipField, keywordTooltip, cursorTooltipBaseTheme };
4
+ declare const keywordTooltip: import("@codemirror/state").Extension & {
5
+ active: StateField<readonly Tooltip[]>;
6
+ };
7
+ export { cursorTooltipField, keywordTooltip };