@valtzu/codemirror-lang-el 0.4.2 → 0.5.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.cjs CHANGED
@@ -4,99 +4,217 @@ Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
5
  var lr = require('@lezer/lr');
6
6
  var language = require('@codemirror/language');
7
+ var autocomplete = require('@codemirror/autocomplete');
8
+ var view = require('@codemirror/view');
7
9
  var highlight = require('@lezer/highlight');
10
+ var state = require('@codemirror/state');
8
11
  var lint = require('@codemirror/lint');
9
- var view = require('@codemirror/view');
10
12
 
11
13
  // This file was generated by lezer-generator. You probably shouldn't edit it.
14
+ 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};
15
+ const spec_Operator = {__proto__:null,"!":113, "+":115, "-":117};
12
16
  const parser = lr.LRParser.deserialize({
13
17
  version: 14,
14
- states: "'[OVQPOOQtQQO'#C^O!YQQOOO#TQPO'#ChO#[QPO'#CiOVQPO'#CnOOQO'#Cu'#CuOVQPO'#CuO#cQPO,58xOVQPO,58|OVQPO,59UOVQPO,59VO#hQPO,58}O#oQQO,59SOOQO,59S,59SO#vQQO,59TOOQO,59T,59TO$QQQO,59YO$hQQO,59aOOQO1G.d1G.dO$oQQO1G.hO$vQQO1G.pO$}QQO1G.qO%eQQO1G.iOOQO1G.i1G.iOVQPO1G.nOVQPO'#CpO%oQPO1G.oOOQO1G.o1G.oOOQO1G.{1G.{OOQO7+$S7+$SOVQPO7+$[O%wQPO7+$TOOQO7+$T7+$TO&PQQO7+$YO&ZQQO,59[OOQO-E6n-E6nOOQO7+$Z7+$ZO&hQQO<<GvOOQO<<Go<<GoOVQPO'#CqO'OQPO<<GtOOQO<<Gt<<GtO'WQQO,59]OOQO-E6o-E6oOOQOAN=`AN=`OVQPO1G.wO'_QQO7+$c",
15
- stateData: "'s~OhOS~OTQOWUOXUOYUOZUOcTOkSOmVOpRO~ORWOSWO`ZOaZOkXOrYO~Om[ORiXSiX`iXaiXfiXkiXriXqiXjiXniXliXoiX~Oo^O~PVOj`O~PVOTcO~OlhO~PVOqiO~PtOjlOnjO~PtOfbaqbajbanbalbaoba~PtOlmO~PtOjnO~PtOqoO~PtOf_iq_ij_in_il_io_i~PtOlqOnjO~PtOjuOnjO~OlwOnjO~OnxOozO~PtOjdandalda~PtOf^yq^yj^yn^yl^yo^y~PtOnxOo}O~Oq!OO~PtOneqoeq~PtORSc`YZWTY~",
16
- goto: "#ijPPkPPP{{PPPP{{{{PP{P!]!gPPP!mmQORSTVXYZ[ijox!OmUORSTVXYZ[ijox!OQk_QpgTtkpQyrR|yQPOQ]RQ_SQaTQbVQdXQeYQfZQg[QriQsjQvoQ{xR!P!O",
17
- nodeNames: "⚠ Expression ObjectAccess NullSafeMemberOf MemberOf Identifier ArrayAccess FunctionCall Number String Boolean Null Object Array TernaryExpression BinaryExpression OperatorKeyword Operator UnaryExpression UnaryOperator",
18
- maxTerm: 34,
18
+ 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",
19
+ 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~",
20
+ 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",
21
+ 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",
22
+ maxTerm: 58,
19
23
  skippedNodes: [0],
20
24
  repeatNodeCount: 2,
21
- tokenData: "AZ~R!QXY$XYZ$X]^$Xpq$Xqr$jrs%Ruv$|vw&{wx'Txy(xyz(}z{)S{|)[|})c}!O)[!O!P)h!P!Q$|!Q![)p![!],V!^!_$t!_!`,[!`!a$t!a!b,b!c!},u!}#O-W#P#Q-]#Q#R$|#R#S,u#T#U-b#U#V,u#V#W.u#W#X,u#X#Y2Z#Y#Z4u#Z#],u#]#^7V#^#a,u#a#b7n#b#c:S#c#d=c#d#g,u#g#h=z#h#i?w#i#o,u#o#p@w#p#q@|#q#rAU#r#s$|~$^Sh~XY$XYZ$X]^$Xpq$XR$qPaQcP!_!`$tQ$yPaQ!_!`$|Q%ROaQ~%UXOr%Rrs%qs#O%R#O#P%v#P;'S%R;'S;=`&u<%l~%R~O%R~~%q~%vOX~~%yRO;'S%R;'S;=`&S;=`O%R~&VYOr%Rrs%qs#O%R#O#P%v#P;'S%R;'S;=`&u;=`<%l%R<%l~%R~O%R~~%q~&xP;=`<%l%RQ'QPaQvw$|~'WXOw'Twx%qx#O'T#O#P's#P;'S'T;'S;=`(r<%l~'T~O'T~~%q~'vRO;'S'T;'S;=`(P;=`O'T~(SYOw'Twx%qx#O'T#O#P's#P;'S'T;'S;=`(r;=`<%l'T<%l~'T~O'T~~%q~(uP;=`<%l'T~(}Om~~)SOl~Q)XPaQz{$|R)cOaQcP~)hOn~~)mPS~!O!P$|~)uTW~!O!P*U!Q![)p!g!h+U#R#S,P#X#Y+U~*XSO!O*e!P;'S*e;'S;=`+y<%lO*e~*jRW~!Q![*s!g!h+U#X#Y+U~*xSW~!Q![*s!g!h+U#R#S+s#X#Y+U~+XR{|+b}!O+b!Q![+h~+eP!Q![+h~+mQW~!Q![+h#R#S+b~+vP!Q![*s~+|P;=`<%l*e~,SP!Q![)p~,[Oq~Q,_P!_!`$t~,gRr~!O!P,p![!]$|!a!b$|~,uOR~~,zST~!Q![,u!c!},u#R#S,u#T#o,u~-]Ok~~-bOj~~-gUT~!Q![,u!c!},u#R#S,u#T#b,u#b#c-y#c#o,u~.OUT~!Q![,u!c!},u#R#S,u#T#W,u#W#X.b#X#o,u~.iS`~T~!Q![,u!c!},u#R#S,u#T#o,u~.zUT~!Q![,u!c!},u#R#S,u#T#c,u#c#d/^#d#o,u~/cUT~!Q![,u!c!},u#R#S,u#T#b,u#b#c/u#c#o,u~/zUT~!Q![,u!c!},u#R#S,u#T#h,u#h#i0^#i#o,u~0cTT~!Q![,u!c!},u#R#S,u#T#U0r#U#o,u~0wUT~!Q![,u!c!},u#R#S,u#T#],u#]#^1Z#^#o,u~1`UT~!Q![,u!c!},u#R#S,u#T#b,u#b#c1r#c#o,u~1wUT~!Q![,u!c!},u#R#S,u#T#g,u#g#h.b#h#o,u~2`UT~!Q![,u!c!},u#R#S,u#T#b,u#b#c2r#c#o,u~2wUT~!Q![,u!c!},u#R#S,u#T#W,u#W#X3Z#X#o,u~3`UT~!Q![,u!c!},u#R#S,u#T#g,u#g#h3r#h#o,u~3wTT~pq4W!Q![,u!c!},u#R#S,u#T#o,u~4ZP#k#l4^~4aP#]#^4d~4gP#h#i4j~4mP#[#]4p~4uO`~~4zTT~!Q![,u!c!},u#R#S,u#T#U5Z#U#o,u~5`UT~!Q![,u!c!},u#R#S,u#T#`,u#`#a5r#a#o,u~5wUT~!Q![,u!c!},u#R#S,u#T#g,u#g#h6Z#h#o,u~6`UT~!Q![,u!c!},u#R#S,u#T#X,u#X#Y6r#Y#o,u~6ySY~T~!Q![,u!c!},u#R#S,u#T#o,u~7[UT~!Q![,u!c!},u#R#S,u#T#b,u#b#c.b#c#o,u~7sTT~!Q![,u!c!},u#R#S,u#T#U8S#U#o,u~8XUT~!Q![,u!c!},u#R#S,u#T#h,u#h#i8k#i#o,u~8pUT~!Q![,u!c!},u#R#S,u#T#V,u#V#W9S#W#o,u~9XUT~!Q![,u!c!},u#R#S,u#T#[,u#[#]9k#]#o,u~9pUT~!Q![,u!c!},u#R#S,u#T#X,u#X#Y1r#Y#o,u~:XWT~!Q![,u!c!},u#R#S,u#T#c,u#c#d:q#d#i,u#i#j<O#j#o,u~:vUT~!Q![,u!c!},u#R#S,u#T#h,u#h#i;Y#i#o,u~;cTcP`~T~pq;r!Q![,u!c!},u#R#S,u#T#o,u~;uP#]#^;x~;{P#b#c4p~<TUT~!Q![,u!c!},u#R#S,u#T#`,u#`#a<g#a#o,u~<lUT~!Q![,u!c!},u#R#S,u#T#`,u#`#a=O#a#o,u~=VSZ~T~!Q![,u!c!},u#R#S,u#T#o,u~=hUT~!Q![,u!c!},u#R#S,u#T#f,u#f#g.b#g#o,u~>PUT~!Q![,u!c!},u#R#S,u#T#h,u#h#i>c#i#o,u~>hTT~!Q![,u!c!},u#R#S,u#T#U>w#U#o,u~>|UT~!Q![,u!c!},u#R#S,u#T#f,u#f#g?`#g#o,u~?eUT~!Q![,u!c!},u#R#S,u#T#h,u#h#i3Z#i#o,u~?|UT~!Q![,u!c!},u#R#S,u#T#f,u#f#g@`#g#o,u~@eUT~!Q![,u!c!},u#R#S,u#T#i,u#i#j6Z#j#o,u~@|Op~QARPaQ#p#q$|~AZOo~",
22
- tokenizers: [0, 1],
25
+ 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{~",
26
+ tokenizers: [0],
23
27
  topRules: {"Expression":[0,1]},
24
- tokenPrec: 301
28
+ specialized: [{term: 33, get: (value) => spec_word[value] || -1},{term: 23, get: (value) => spec_Operator[value] || -1}],
29
+ tokenPrec: 479
25
30
  });
26
31
 
27
- const isFunction = (identifier, config) => { var _a; return (_a = config.functions) === null || _a === void 0 ? void 0 : _a.find(fn => fn.name === identifier); };
28
- const isVariable = (identifier, config) => { var _a; return (_a = config.identifiers) === null || _a === void 0 ? void 0 : _a.find(variable => variable.name === identifier); };
29
- const autocompleteFunction = (x) => { var _a, _b, _c; return ({ label: `${x.name}(${((_a = x.args) === null || _a === void 0 ? void 0 : _a.join(',')) || ''})`, apply: `${x.name}(${!((_b = x.args) === null || _b === void 0 ? void 0 : _b.length) ? ')' : ''}`, detail: (_c = x.returnType) === null || _c === void 0 ? void 0 : _c.join('|'), info: x.info, type: "function" }); };
32
+ const autocompleteFunction = (x) => {
33
+ var _a, _b;
34
+ return ({
35
+ label: `${x.name}(${((_a = x.args) === null || _a === void 0 ? void 0 : _a.join(',')) || ''})`,
36
+ apply: (view, completion, from, to) => {
37
+ var _a;
38
+ view.dispatch(Object.assign(Object.assign({}, autocomplete.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) } }));
39
+ },
40
+ detail: (_b = x.returnType) === null || _b === void 0 ? void 0 : _b.join('|'),
41
+ info: x.info, type: "function"
42
+ });
43
+ };
30
44
  const autocompleteIdentifier = (x) => { var _a; return ({ label: x.name, apply: x.name, info: x.info, detail: x.detail || ((_a = x.type) === null || _a === void 0 ? void 0 : _a.join('|')), type: 'variable' }); };
31
- const expressionLanguageLinter = (config) => lint.linter(view => {
45
+ const resolveCallable = (identifier, config) => { var _a; return (_a = config === null || config === void 0 ? void 0 : config.functions) === null || _a === void 0 ? void 0 : _a.find(x => x.name === identifier); };
46
+ const resolveIdentifier = (nodeName, identifier, config) => {
47
+ var _a;
48
+ switch (nodeName) {
49
+ case 'Method':
50
+ case 'Function':
51
+ return resolveCallable(identifier, config);
52
+ case 'Property':
53
+ case 'Variable':
54
+ return (_a = config === null || config === void 0 ? void 0 : config.identifiers) === null || _a === void 0 ? void 0 : _a.find(x => x.name === identifier);
55
+ }
56
+ };
57
+ const cursorTooltipBaseTheme = view.EditorView.baseTheme({
58
+ ".cm-tooltip.cm-tooltip-cursor": {
59
+ boxShadow: 'rgba(0, 0, 0, .15) 0 1px 2px',
60
+ border: "1px solid rgba(127, 127, 127, .2)",
61
+ padding: "2px 7px",
62
+ borderRadius: "4px",
63
+ "& .cm-tooltip-arrow:before": {},
64
+ "& .cm-tooltip-arrow:after": {
65
+ borderTopColor: "transparent"
66
+ }
67
+ }
68
+ });
69
+ function getNodeOrdinal(node) {
70
+ let ordinal = -1;
71
+ for (let c = node; c; c = c.prevSibling, ordinal++)
72
+ ;
73
+ return ordinal;
74
+ }
75
+ function resolveArguments(node) {
76
+ let c = node;
77
+ while (c && c.name !== 'Arguments') {
78
+ c = c.parent;
79
+ }
80
+ return c;
81
+ }
82
+ function resolveFunctionDefinition(node, state, config) {
83
+ var _a;
84
+ if (!node) {
85
+ return undefined;
86
+ }
87
+ let identifier;
88
+ if (node.name === 'ObjectAccess' && node.lastChild) {
89
+ const leftArgument = (_a = node.firstChild) === null || _a === void 0 ? void 0 : _a.node;
90
+ const types = Array.from(resolveTypes(state, leftArgument, config));
91
+ identifier = state.sliceDoc(node.lastChild.from, node.lastChild.to);
92
+ return types.map(type => { var _a; return resolveCallable(identifier, (_a = config.types) === null || _a === void 0 ? void 0 : _a[type]); }).find(x => x);
93
+ }
94
+ else if (node.name === 'Function') {
95
+ identifier = state.sliceDoc(node.from, node.node.firstChild ? node.node.firstChild.from - 1 : node.to);
96
+ return resolveCallable(identifier, config);
97
+ }
98
+ }
99
+ function getCursorTooltips(state, config) {
100
+ // @ts-ignore
101
+ return state.selection.ranges
102
+ .filter(range => range.empty)
103
+ .map(range => {
104
+ var _a;
105
+ const tree = language.syntaxTree(state);
106
+ const node = tree.resolveInner(range.from, 0);
107
+ const args = resolveArguments(node);
108
+ if (!args || !args.prevSibling) {
109
+ return null;
110
+ }
111
+ const fn = resolveFunctionDefinition(args.prevSibling, state, config);
112
+ if (!fn) {
113
+ return null;
114
+ }
115
+ const n = args.childAfter(range.from - 1);
116
+ const argName = (_a = fn.args) === null || _a === void 0 ? void 0 : _a[n ? getNodeOrdinal(n) : 0];
117
+ if (n && n.from !== range.from || !argName) {
118
+ return null;
119
+ }
120
+ return {
121
+ pos: range.head,
122
+ above: true,
123
+ strictSide: false,
124
+ arrow: true,
125
+ create: () => {
126
+ let dom = document.createElement("div");
127
+ dom.className = "cm-tooltip-cursor";
128
+ dom.textContent = `${argName}`;
129
+ return { dom };
130
+ },
131
+ };
132
+ }).filter(x => x);
133
+ }
134
+ const cursorTooltipField = (config) => state.StateField.define({
135
+ create: (state) => getCursorTooltips(state, config),
136
+ update(tooltips, tr) {
137
+ if (!tr.docChanged && !tr.selection) {
138
+ return tooltips;
139
+ }
140
+ return getCursorTooltips(tr.state, config);
141
+ },
142
+ provide: f => view.showTooltip.computeN([f], state => state.field(f))
143
+ });
144
+ const expressionLanguageLinterSource = (config) => (state) => {
32
145
  let diagnostics = [];
33
- let previousNode = null;
34
- language.syntaxTree(view.state).cursor().iterate(node => {
35
- var _a, _b, _c, _d, _e;
36
- if (((_a = node.node.parent) === null || _a === void 0 ? void 0 : _a.name) == 'ObjectAccess' && ((_b = node.node.parent) === null || _b === void 0 ? void 0 : _b.firstChild) && node.name == "Identifier" && node.node.prevSibling) {
37
- const leftArgument = node.node.parent.firstChild.node;
38
- const types = resolveTypes(view.state, leftArgument, config, true);
39
- const identifier = view.state.sliceDoc(node.from, node.to);
40
- if (((_d = (_c = node.node.parent) === null || _c === void 0 ? void 0 : _c.parent) === null || _d === void 0 ? void 0 : _d.name) === 'FunctionCall' && !node.node.parent.prevSibling) {
41
- if (!Array.from(types).find(type => { var _a, _b, _c; return (_c = (_b = (_a = config.types) === null || _a === void 0 ? void 0 : _a[type]) === null || _b === void 0 ? void 0 : _b.functions) === null || _c === void 0 ? void 0 : _c.find(x => x.name === identifier); })) {
42
- diagnostics.push({
43
- from: node.from,
44
- to: node.to,
45
- severity: 'error',
46
- message: `Method '${identifier}' not found in ${Array.from(types).join('|')}`,
47
- });
146
+ language.syntaxTree(state).cursor().iterate(node => {
147
+ var _a, _b, _c, _d, _e, _f, _g;
148
+ const { from, to, name } = node;
149
+ let identifier;
150
+ switch (name) {
151
+ case '⚠':
152
+ if (state.doc.length === 0 || from === 0) {
153
+ // Don't show error on empty doc (even though it is an error)
154
+ return;
155
+ }
156
+ identifier = state.sliceDoc(from, to);
157
+ if (identifier.length === 0) {
158
+ diagnostics.push({ from, to: (_c = (_b = (_a = node.node.parent) === null || _a === void 0 ? void 0 : _a.parent) === null || _b === void 0 ? void 0 : _b.to) !== null && _c !== void 0 ? _c : to, severity: 'error', message: `Expression expected` });
159
+ }
160
+ else {
161
+ const type = /^[a-zA-Z_]+[a-zA-Z_0-9]*$/.test(identifier) ? 'identifier' : 'operator';
162
+ diagnostics.push({ from, to, severity: 'error', message: `Unexpected ${type} '${identifier}'` });
48
163
  }
49
- }
50
- else if (types.size > 0) {
51
- if (!Array.from(types).find(type => { var _a, _b, _c; return (_c = (_b = (_a = config.types) === null || _a === void 0 ? void 0 : _a[type]) === null || _b === void 0 ? void 0 : _b.identifiers) === null || _c === void 0 ? void 0 : _c.find(x => x.name === identifier); })) {
52
- diagnostics.push({
53
- from: node.from,
54
- to: node.to,
55
- severity: 'warning',
56
- message: `Property '${identifier}' not found in ${Array.from(types).join('|')}`,
57
- });
164
+ return;
165
+ case 'Arguments':
166
+ const args = (_d = resolveFunctionDefinition(node.node.prevSibling, state, config)) === null || _d === void 0 ? void 0 : _d.args;
167
+ if (!args) {
168
+ return;
58
169
  }
59
- }
60
- return;
170
+ let i = 0;
171
+ let n = node.node.firstChild;
172
+ while (n) {
173
+ if (++i > args.length) {
174
+ diagnostics.push({ from: n.from, to: n.to, severity: 'error', message: `Unexpected argument` });
175
+ }
176
+ n = n.nextSibling;
177
+ }
178
+ break;
179
+ case 'Property':
180
+ case 'Method':
181
+ const leftArgument = (_f = (_e = node.node.parent) === null || _e === void 0 ? void 0 : _e.firstChild) === null || _f === void 0 ? void 0 : _f.node;
182
+ const types = Array.from(resolveTypes(state, leftArgument, config));
183
+ identifier = state.sliceDoc(from, to);
184
+ if (!types.find(type => { var _a; return resolveIdentifier(name, identifier, (_a = config.types) === null || _a === void 0 ? void 0 : _a[type]); })) {
185
+ diagnostics.push({ from, to, severity: 'error', message: `${node.name} "${identifier}" not found in ${types.join('|')}` });
186
+ }
187
+ break;
188
+ case 'Variable':
189
+ case 'Function':
190
+ identifier = state.sliceDoc(from, node.node.firstChild ? node.node.firstChild.from - 1 : to);
191
+ if (!resolveIdentifier(name, identifier, config)) {
192
+ diagnostics.push({ from, to, severity: 'error', message: `${node.node.name} "${identifier}" not found` });
193
+ }
194
+ break;
61
195
  }
62
- if (node.name == "Identifier") {
63
- if ((previousNode === null || previousNode === void 0 ? void 0 : previousNode.name) == "Identifier" && !['Array', 'FunctionCall'].includes(((_e = node.node.parent) === null || _e === void 0 ? void 0 : _e.name) || '')) {
64
- diagnostics.push({
65
- from: node.from,
66
- to: node.to,
67
- severity: 'error',
68
- message: `Unexpected identifier after another identifier`,
69
- });
70
- }
71
- const identifier = view.state.sliceDoc(node.from, node.to);
72
- if (!isFunction(identifier, config) && !isVariable(identifier, config)) {
73
- diagnostics.push({
74
- from: node.from,
75
- to: node.to,
76
- severity: 'error',
77
- message: `Identifier "${identifier}" not found`,
78
- });
79
- }
196
+ if (identifier && ((_g = node.node.parent) === null || _g === void 0 ? void 0 : _g.type.isError)) {
197
+ diagnostics.push({ from, to, severity: 'error', message: `Unexpected identifier "${identifier}"` });
80
198
  }
81
- previousNode = node.node;
82
199
  });
83
200
  return diagnostics;
84
- });
201
+ };
202
+ const expressionLanguageLinter = (config) => lint.linter(view => expressionLanguageLinterSource(config)(view.state));
85
203
  const keywordTooltip = (config) => view.hoverTooltip((view, pos, side) => {
86
204
  var _a, _b, _c, _d, _e, _f;
87
205
  const tree = language.syntaxTree(view.state).resolveInner(pos, side);
88
- if (tree.name !== 'Identifier') {
206
+ if (!['Function', 'Variable', 'Method', 'Property'].includes(tree.name)) {
89
207
  return null;
90
208
  }
91
209
  const skipEmpty = (x) => x;
92
210
  let info;
93
211
  if (((_a = tree.parent) === null || _a === void 0 ? void 0 : _a.firstChild) && ((_b = tree.parent) === null || _b === void 0 ? void 0 : _b.name) === 'ObjectAccess' && tree.prevSibling) {
94
212
  const node = tree.parent.firstChild;
95
- const types = resolveTypes(view.state, node, config, true);
213
+ const types = Array.from(resolveTypes(view.state, node, config));
96
214
  const name = view.state.sliceDoc(tree.from, tree.to);
97
215
  info = [
98
- ...Array.from(types).map(type => { var _a, _b, _c, _d; return (_d = (_c = (_b = (_a = config.types) === null || _a === void 0 ? void 0 : _a[type]) === null || _b === void 0 ? void 0 : _b.identifiers) === null || _c === void 0 ? void 0 : _c.find(x => x.name === name)) === null || _d === void 0 ? void 0 : _d.info; }).filter(skipEmpty),
99
- ...Array.from(types).map(type => { var _a, _b, _c, _d; return (_d = (_c = (_b = (_a = config.types) === null || _a === void 0 ? void 0 : _a[type]) === null || _b === void 0 ? void 0 : _b.functions) === null || _c === void 0 ? void 0 : _c.find(x => x.name === name)) === null || _d === void 0 ? void 0 : _d.info; }).filter(skipEmpty),
216
+ ...types.map(type => { var _a, _b, _c, _d; return (_d = (_c = (_b = (_a = config.types) === null || _a === void 0 ? void 0 : _a[type]) === null || _b === void 0 ? void 0 : _b.identifiers) === null || _c === void 0 ? void 0 : _c.find(x => x.name === name)) === null || _d === void 0 ? void 0 : _d.info; }).filter(skipEmpty),
217
+ ...types.map(type => { var _a, _b, _c, _d; return (_d = (_c = (_b = (_a = config.types) === null || _a === void 0 ? void 0 : _a[type]) === null || _b === void 0 ? void 0 : _b.functions) === null || _c === void 0 ? void 0 : _c.find(x => x.name === name)) === null || _d === void 0 ? void 0 : _d.info; }).filter(skipEmpty),
100
218
  ].join('\n');
101
219
  }
102
220
  else {
@@ -114,8 +232,8 @@ const keywordTooltip = (config) => view.hoverTooltip((view, pos, side) => {
114
232
  end: tree.to,
115
233
  above: true,
116
234
  create(view) {
117
- let dom = document.createElement("div");
118
- dom.textContent = info;
235
+ const dom = document.createElement("div");
236
+ dom[config.htmlTooltip ? 'innerHTML' : 'textContent'] = info;
119
237
  dom.className = 'cm-diagnostic';
120
238
  return { dom };
121
239
  },
@@ -125,13 +243,20 @@ const ELLanguage = language.LRLanguage.define({
125
243
  parser: parser.configure({
126
244
  props: [
127
245
  language.indentNodeProp.add({
128
- Application: language.delimitedIndent({ closing: ")", align: false })
246
+ Application: language.delimitedIndent({ closing: ")", align: false }),
247
+ Arguments: language.delimitedIndent({ closing: ")", align: false }),
248
+ Object: language.delimitedIndent({ closing: "}", align: false }),
129
249
  }),
130
250
  language.foldNodeProp.add({
131
- Application: language.foldInside
251
+ Application: ({ from, to }) => ({ from: from + 1, to: to - 1 }),
252
+ Arguments: ({ from, to }) => ({ from: from + 1, to: to - 1 }),
253
+ Object: ({ from, to }) => ({ from: from + 1, to: to - 1 }),
132
254
  }),
133
255
  highlight.styleTags({
134
- Identifier: highlight.tags.variableName,
256
+ Property: highlight.tags.propertyName,
257
+ Variable: highlight.tags.variableName,
258
+ Function: highlight.tags.function(highlight.tags.variableName),
259
+ Method: highlight.tags.function(highlight.tags.propertyName),
135
260
  Boolean: highlight.tags.bool,
136
261
  String: highlight.tags.string,
137
262
  Number: highlight.tags.number,
@@ -139,10 +264,12 @@ const ELLanguage = language.LRLanguage.define({
139
264
  ')': highlight.tags.paren,
140
265
  '[': highlight.tags.squareBracket,
141
266
  ']': highlight.tags.squareBracket,
267
+ ',': highlight.tags.punctuation,
268
+ MemberOf: highlight.tags.punctuation,
269
+ NullSafeMemberOf: highlight.tags.punctuation,
142
270
  OperatorKeyword: highlight.tags.operatorKeyword,
271
+ UnaryOperator: highlight.tags.operator,
143
272
  Operator: highlight.tags.operator,
144
- MemberOf: highlight.tags.operator,
145
- NullSafeMemberOf: highlight.tags.operator,
146
273
  })
147
274
  ]
148
275
  }),
@@ -150,46 +277,61 @@ const ELLanguage = language.LRLanguage.define({
150
277
  });
151
278
  function completeOperatorKeyword(state, config, tree, from, to, explicit) {
152
279
  var _a, _b;
153
- const text = state.sliceDoc(from, to);
154
280
  return {
155
281
  from,
156
282
  to,
157
- options: (_b = (_a = config.operatorKeywords) === null || _a === void 0 ? void 0 : _a.filter(({ name }) => explicit || name.startsWith(text)).map(({ name, info, detail }) => ({ label: name, apply: `${name} `, info, detail, type: "keyword" }))) !== null && _b !== void 0 ? _b : [],
158
- validFor: (text) => { var _a, _b; return (_b = (_a = config.operatorKeywords) === null || _a === void 0 ? void 0 : _a.some(({ name }) => explicit || name.startsWith(text))) !== null && _b !== void 0 ? _b : false; },
283
+ options: (_b = (_a = config.operatorKeywords) === null || _a === void 0 ? void 0 : _a.map(({ name, info, detail }) => ({ label: name, apply: `${name} `, info, detail, type: "keyword" }))) !== null && _b !== void 0 ? _b : [],
284
+ validFor: (text) => { var _a, _b; return (_b = (_a = config.operatorKeywords) === null || _a === void 0 ? void 0 : _a.some(({ name }) => explicit || name.includes(text))) !== null && _b !== void 0 ? _b : false; },
159
285
  };
160
286
  }
161
- function completeIdentifier(state, config, tree, from, to, explicit) {
162
- var _a, _b, _c, _d;
163
- const text = state.sliceDoc(from, to).toLowerCase();
164
- const identifiers = (_b = (_a = config.identifiers) === null || _a === void 0 ? void 0 : _a.filter(({ name }) => explicit || name.toLowerCase().startsWith(text))) !== null && _b !== void 0 ? _b : [];
165
- const functions = (_d = (_c = config.functions) === null || _c === void 0 ? void 0 : _c.filter(({ name }) => explicit || name.toLowerCase().startsWith(text))) !== null && _d !== void 0 ? _d : [];
287
+ function completeIdentifier(state, config, tree, from, to) {
288
+ var _a, _b;
289
+ const identifiers = (_a = config.identifiers) !== null && _a !== void 0 ? _a : []; //?.filter(({ name }) => explicit || name.toLowerCase().startsWith(text)) ?? [];
290
+ const functions = (_b = config.functions) !== null && _b !== void 0 ? _b : []; //?.filter(({ name }) => explicit || name.toLowerCase().startsWith(text)) ?? [];
166
291
  return {
167
292
  from,
168
293
  to,
169
294
  options: [...(identifiers.map(autocompleteIdentifier)), ...(functions.map(autocompleteFunction))],
170
- // validFor: identifier,
171
- filter: false,
295
+ validFor: /^[a-zA-Z_]+[a-zA-Z_0-9]*$/,
172
296
  };
173
297
  }
174
298
  function resolveTypes(state, node, config, matchExact) {
175
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m;
299
+ var _a, _b, _c, _d, _e, _f, _g, _h;
176
300
  let types = new Set();
177
- if (node.name === 'FunctionCall' && node.firstChild && node.lastChild) {
178
- resolveTypes(state, node.firstChild, config, matchExact).forEach(x => types.add(x));
301
+ if (!node) {
302
+ return types;
303
+ }
304
+ if (node.name === 'Call' && node.firstChild && node.lastChild) {
305
+ resolveTypes(state, node.firstChild, config).forEach(x => types.add(x));
306
+ }
307
+ else if (node.name === 'Variable') {
308
+ const varName = state.sliceDoc(node.from, node.to) || '';
309
+ // @ts-ignore
310
+ (_b = (_a = resolveIdentifier(node.name, varName, config)) === null || _a === void 0 ? void 0 : _a.type) === null || _b === void 0 ? void 0 : _b.forEach((x) => types.add(x));
179
311
  }
180
- else if (node.name === 'Identifier') {
312
+ else if (node.name === 'Function') {
181
313
  const varName = state.sliceDoc(node.from, node.to) || '';
182
- (_c = (_b = (_a = config.functions) === null || _a === void 0 ? void 0 : _a.find(x => x.name == varName)) === null || _b === void 0 ? void 0 : _b.returnType) === null || _c === void 0 ? void 0 : _c.forEach(x => types.add(x));
183
- (_f = (_e = (_d = config.identifiers) === null || _d === void 0 ? void 0 : _d.find(x => x.name == varName)) === null || _e === void 0 ? void 0 : _e.type) === null || _f === void 0 ? void 0 : _f.forEach(x => types.add(x));
314
+ // @ts-ignore
315
+ (_d = (_c = resolveIdentifier(node.name, varName, config)) === null || _c === void 0 ? void 0 : _c.returnType) === null || _d === void 0 ? void 0 : _d.forEach((x) => types.add(x));
184
316
  }
185
- else if (node.name === 'ObjectAccess' && node.firstChild && ((_g = node.lastChild) === null || _g === void 0 ? void 0 : _g.name) === 'Identifier') {
186
- const baseTypes = resolveTypes(state, node.firstChild, config, matchExact);
317
+ else if (node.name === 'ObjectAccess' && node.firstChild && ((_e = node.lastChild) === null || _e === void 0 ? void 0 : _e.name) === 'Property') {
187
318
  const varName = state.sliceDoc(node.lastChild.from, node.lastChild.to) || '';
188
- for (const baseType of baseTypes) {
189
- const type = (_h = config.types) === null || _h === void 0 ? void 0 : _h[baseType];
190
- (_k = (_j = type === null || type === void 0 ? void 0 : type.functions) === null || _j === void 0 ? void 0 : _j.filter(x => matchExact ? x.name === varName : x.name.startsWith(varName))) === null || _k === void 0 ? void 0 : _k.forEach(def => (def.returnType || ['any']).forEach(x => types.add(x)));
191
- (_m = (_l = type === null || type === void 0 ? void 0 : type.identifiers) === null || _l === void 0 ? void 0 : _l.filter(x => matchExact ? x.name === varName : x.name.startsWith(varName))) === null || _m === void 0 ? void 0 : _m.forEach(def => (def.type || ['any']).forEach(x => types.add(x)));
192
- }
319
+ (_f = resolveTypes(state, node.firstChild, config)) === null || _f === void 0 ? void 0 : _f.forEach(baseType => {
320
+ var _a, _b, _c, _d;
321
+ // @ts-ignore
322
+ (_d = (_c = resolveIdentifier((_a = node.lastChild) === null || _a === void 0 ? void 0 : _a.name, varName, (_b = config.types) === null || _b === void 0 ? void 0 : _b[baseType])) === null || _c === void 0 ? void 0 : _c.type) === null || _d === void 0 ? void 0 : _d.forEach((x) => types.add(x));
323
+ });
324
+ }
325
+ else if (node.name === 'ObjectAccess' && node.firstChild && ((_g = node.lastChild) === null || _g === void 0 ? void 0 : _g.name) === 'Method') {
326
+ const varName = state.sliceDoc(node.lastChild.from, node.lastChild.to) || '';
327
+ (_h = resolveTypes(state, node.firstChild, config)) === null || _h === void 0 ? void 0 : _h.forEach(baseType => {
328
+ var _a, _b, _c, _d;
329
+ // @ts-ignore
330
+ (_d = (_c = resolveIdentifier((_a = node.lastChild) === null || _a === void 0 ? void 0 : _a.name, varName, (_b = config.types) === null || _b === void 0 ? void 0 : _b[baseType])) === null || _c === void 0 ? void 0 : _c.returnType) === null || _d === void 0 ? void 0 : _d.forEach((x) => types.add(x));
331
+ });
332
+ }
333
+ else if (node.name === 'Application' && node.firstChild) {
334
+ resolveTypes(state, node.firstChild, config).forEach(x => types.add(x));
193
335
  }
194
336
  if (types.size === 0) {
195
337
  types.add('any');
@@ -201,42 +343,46 @@ function completeMember(state, config, tree, from, to, explicit) {
201
343
  if (((_a = tree.parent) === null || _a === void 0 ? void 0 : _a.name) != 'ObjectAccess' || !tree.parent.firstChild) {
202
344
  return null;
203
345
  }
204
- const types = resolveTypes(state, tree.parent.firstChild.node, config, false);
346
+ state.sliceDoc(from, to);
347
+ const types = resolveTypes(state, tree.parent.firstChild.node, config);
205
348
  if (!(types === null || types === void 0 ? void 0 : types.size)) {
206
349
  return null;
207
350
  }
208
- const varName = state.sliceDoc(from, to);
209
351
  let options = [];
210
352
  for (const type of types) {
211
353
  const typeDeclaration = (_b = config.types) === null || _b === void 0 ? void 0 : _b[type];
212
- options.push(...(((_c = typeDeclaration === null || typeDeclaration === void 0 ? void 0 : typeDeclaration.identifiers) === null || _c === void 0 ? void 0 : _c.filter(x => x.name.startsWith(varName)).map(autocompleteIdentifier)) || []), ...(((_d = typeDeclaration === null || typeDeclaration === void 0 ? void 0 : typeDeclaration.functions) === null || _d === void 0 ? void 0 : _d.filter(x => x.name.startsWith(varName)).map(autocompleteFunction)) || []));
354
+ options.push(...(((_c = typeDeclaration === null || typeDeclaration === void 0 ? void 0 : typeDeclaration.identifiers) === null || _c === void 0 ? void 0 : _c.map(autocompleteIdentifier)) || []), ...(((_d = typeDeclaration === null || typeDeclaration === void 0 ? void 0 : typeDeclaration.functions) === null || _d === void 0 ? void 0 : _d.map(autocompleteFunction)) || []));
213
355
  }
214
356
  return {
215
357
  from,
216
358
  to,
217
359
  options,
218
- filter: false,
360
+ validFor: /^[a-zA-Z_]+[a-zA-Z_0-9]*$/,
219
361
  };
220
362
  }
221
363
  function expressionLanguageCompletionFor(config, context) {
222
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
364
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m;
223
365
  const { state, pos, explicit } = context;
224
- const tree = language.syntaxTree(state).resolveInner(pos, -1);
225
- const isOperator = (node) => node && ['Operator', 'OperatorKeyword'].includes(node.name);
226
- const isIdentifier = (node) => (node === null || node === void 0 ? void 0 : node.name) === 'Identifier';
227
- const prevNode = ((_a = tree.parent) === null || _a === void 0 ? void 0 : _a.node.type.isError) ? tree.parent.prevSibling : tree.prevSibling;
228
- if (tree.name == 'String') {
366
+ const tree = language.syntaxTree(state);
367
+ const prevNode = tree.resolveInner(pos, state.sliceDoc(pos - 1, pos) === ')' ? 0 : -1);
368
+ const isIdentifier = (node) => { var _a; return ['Variable', 'Function'].includes((_a = node === null || node === void 0 ? void 0 : node.name) !== null && _a !== void 0 ? _a : ''); };
369
+ const isMember = (node) => { var _a; return ['Property', 'Method'].includes((_a = node === null || node === void 0 ? void 0 : node.name) !== null && _a !== void 0 ? _a : ''); };
370
+ if (prevNode.name == 'String') {
229
371
  return null;
230
372
  }
231
- if (((_b = tree.parent) === null || _b === void 0 ? void 0 : _b.name) == 'ObjectAccess' && ['ObjectAccess', 'ArrayAccess', 'Identifier', 'FunctionCall'].includes(((_c = tree.parent.firstChild) === null || _c === void 0 ? void 0 : _c.name) || '')) {
232
- return completeMember(state, config, tree, isIdentifier(tree.node) ? tree.from : pos, pos);
373
+ if (((_a = prevNode.parent) === null || _a === void 0 ? void 0 : _a.name) == 'ObjectAccess' && ['ObjectAccess', 'ArrayAccess', 'Variable', 'Call'].includes(((_b = prevNode.parent.firstChild) === null || _b === void 0 ? void 0 : _b.name) || '')) {
374
+ return completeMember(state, config, prevNode, isIdentifier(prevNode) || isMember(prevNode) ? prevNode.from : pos, pos);
233
375
  }
234
- // No idea what's going on here, just added conditions until all the tests passed :)
235
- if (prevNode && !isOperator(prevNode.node) && (((_d = tree.parent) === null || _d === void 0 ? void 0 : _d.node.type.isError) || ((_e = tree.node.parent) === null || _e === void 0 ? void 0 : _e.name) === 'BinaryExpression') || (tree.name === 'Expression' && !((_g = (_f = tree.lastChild) === null || _f === void 0 ? void 0 : _f.type) === null || _g === void 0 ? void 0 : _g.isError) && !isOperator((_h = tree.lastChild) === null || _h === void 0 ? void 0 : _h.node))) {
236
- return completeOperatorKeyword(state, config, tree, tree.name !== 'Expression' ? tree.from : pos, pos, explicit);
376
+ if (['Expression', 'UnaryExpression', 'BinaryExpression', 'TernaryExpression'].includes(prevNode.name) && prevNode.lastChild && !((_c = prevNode.lastChild) === null || _c === void 0 ? void 0 : _c.type.isError)
377
+ || ['Arguments', 'Array'].includes(prevNode.name) && prevNode.lastChild && !((_d = prevNode.lastChild) === null || _d === void 0 ? void 0 : _d.type.isError)
378
+ || ['Expression', 'UnaryExpression', 'BinaryExpression', 'TernaryExpression'].includes((_f = (_e = prevNode.parent) === null || _e === void 0 ? void 0 : _e.name) !== null && _f !== void 0 ? _f : '') && prevNode.type.isError
379
+ || ['Variable', 'Function'].includes((_h = (_g = prevNode.parent) === null || _g === void 0 ? void 0 : _g.name) !== null && _h !== void 0 ? _h : '') && prevNode.type.isError) {
380
+ return completeOperatorKeyword(state, config, prevNode, !['Expression', 'UnaryExpression', 'BinaryExpression', 'TernaryExpression', 'Arguments'].includes(prevNode.name) ? prevNode.from : pos, pos, explicit);
237
381
  }
238
- if (tree.name === 'Expression' || isIdentifier(tree.node) || (tree.name === 'BinaryExpression' && isOperator((_k = (_j = tree.lastChild) === null || _j === void 0 ? void 0 : _j.prevSibling) === null || _k === void 0 ? void 0 : _k.node) && explicit)) {
239
- return completeIdentifier(state, config, tree, isIdentifier(tree.node) ? tree.from : pos, pos, explicit);
382
+ if (['Expression', 'UnaryExpression', 'BinaryExpression', 'TernaryExpression'].includes(prevNode.name) && ((_j = prevNode.lastChild) === null || _j === void 0 ? void 0 : _j.type.isError)
383
+ || ['Expression', 'UnaryExpression', 'BinaryExpression', 'TernaryExpression', 'Arguments'].includes((_l = (_k = prevNode.parent) === null || _k === void 0 ? void 0 : _k.name) !== null && _l !== void 0 ? _l : '') && !prevNode.type.isError
384
+ || ['Arguments', 'Array'].includes((_m = prevNode.name) !== null && _m !== void 0 ? _m : '')) {
385
+ return completeIdentifier(state, config, prevNode, isIdentifier(prevNode) ? prevNode.from : pos, pos);
240
386
  }
241
387
  return null;
242
388
  }
@@ -261,9 +407,11 @@ function expressionlanguage(config = {}, extensions = []) {
261
407
  expressionLanguageLinter(config),
262
408
  keywordTooltip(config),
263
409
  ...extensions,
410
+ [cursorTooltipField(config), cursorTooltipBaseTheme],
264
411
  ]);
265
412
  }
266
413
 
267
414
  exports.ELLanguage = ELLanguage;
415
+ exports.expressionLanguageLinterSource = expressionLanguageLinterSource;
268
416
  exports.expressionlanguage = expressionlanguage;
269
417
  exports.keywordTooltip = keywordTooltip;
package/dist/index.d.cts CHANGED
@@ -1,4 +1,6 @@
1
1
  import { LRLanguage, LanguageSupport } from "@codemirror/language";
2
+ import { EditorState } from "@codemirror/state";
3
+ import { Diagnostic } from "@codemirror/lint";
2
4
  interface ELIdentifier {
3
5
  name: string;
4
6
  detail?: string;
@@ -27,8 +29,10 @@ interface ExpressionLanguageConfig {
27
29
  detail?: string;
28
30
  info?: string;
29
31
  }[];
32
+ htmlTooltip?: boolean;
30
33
  }
34
+ declare const expressionLanguageLinterSource: (config: ExpressionLanguageConfig) => (state: EditorState) => Diagnostic[];
31
35
  declare const keywordTooltip: (config: ExpressionLanguageConfig) => import("@codemirror/state").Extension;
32
36
  declare const ELLanguage: LRLanguage;
33
37
  declare function expressionlanguage(config?: ExpressionLanguageConfig, extensions?: Array<any>): LanguageSupport;
34
- export { ELIdentifier, ELFunction, ExpressionLanguageConfig, keywordTooltip, ELLanguage, expressionlanguage };
38
+ export { ELIdentifier, ELFunction, ExpressionLanguageConfig, expressionLanguageLinterSource, keywordTooltip, ELLanguage, expressionlanguage };
package/dist/index.d.ts CHANGED
@@ -1,4 +1,6 @@
1
1
  import { LRLanguage, LanguageSupport } from "@codemirror/language";
2
+ import { EditorState } from "@codemirror/state";
3
+ import { Diagnostic } from "@codemirror/lint";
2
4
  interface ELIdentifier {
3
5
  name: string;
4
6
  detail?: string;
@@ -27,8 +29,10 @@ interface ExpressionLanguageConfig {
27
29
  detail?: string;
28
30
  info?: string;
29
31
  }[];
32
+ htmlTooltip?: boolean;
30
33
  }
34
+ declare const expressionLanguageLinterSource: (config: ExpressionLanguageConfig) => (state: EditorState) => Diagnostic[];
31
35
  declare const keywordTooltip: (config: ExpressionLanguageConfig) => import("@codemirror/state").Extension;
32
36
  declare const ELLanguage: LRLanguage;
33
37
  declare function expressionlanguage(config?: ExpressionLanguageConfig, extensions?: Array<any>): LanguageSupport;
34
- export { ELIdentifier, ELFunction, ExpressionLanguageConfig, keywordTooltip, ELLanguage, expressionlanguage };
38
+ export { ELIdentifier, ELFunction, ExpressionLanguageConfig, expressionLanguageLinterSource, keywordTooltip, ELLanguage, expressionlanguage };
package/dist/index.js CHANGED
@@ -1,98 +1,216 @@
1
1
  import { LRParser } from '@lezer/lr';
2
- import { LRLanguage, indentNodeProp, delimitedIndent, foldNodeProp, foldInside, syntaxTree, LanguageSupport } from '@codemirror/language';
2
+ import { LRLanguage, indentNodeProp, delimitedIndent, foldNodeProp, syntaxTree, LanguageSupport } from '@codemirror/language';
3
+ import { insertCompletionText } from '@codemirror/autocomplete';
4
+ import { EditorView, hoverTooltip, showTooltip } from '@codemirror/view';
3
5
  import { styleTags, tags } from '@lezer/highlight';
6
+ import { StateField } from '@codemirror/state';
4
7
  import { linter } from '@codemirror/lint';
5
- import { hoverTooltip } from '@codemirror/view';
6
8
 
7
9
  // 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};
8
12
  const parser = LRParser.deserialize({
9
13
  version: 14,
10
- states: "'[OVQPOOQtQQO'#C^O!YQQOOO#TQPO'#ChO#[QPO'#CiOVQPO'#CnOOQO'#Cu'#CuOVQPO'#CuO#cQPO,58xOVQPO,58|OVQPO,59UOVQPO,59VO#hQPO,58}O#oQQO,59SOOQO,59S,59SO#vQQO,59TOOQO,59T,59TO$QQQO,59YO$hQQO,59aOOQO1G.d1G.dO$oQQO1G.hO$vQQO1G.pO$}QQO1G.qO%eQQO1G.iOOQO1G.i1G.iOVQPO1G.nOVQPO'#CpO%oQPO1G.oOOQO1G.o1G.oOOQO1G.{1G.{OOQO7+$S7+$SOVQPO7+$[O%wQPO7+$TOOQO7+$T7+$TO&PQQO7+$YO&ZQQO,59[OOQO-E6n-E6nOOQO7+$Z7+$ZO&hQQO<<GvOOQO<<Go<<GoOVQPO'#CqO'OQPO<<GtOOQO<<Gt<<GtO'WQQO,59]OOQO-E6o-E6oOOQOAN=`AN=`OVQPO1G.wO'_QQO7+$c",
11
- stateData: "'s~OhOS~OTQOWUOXUOYUOZUOcTOkSOmVOpRO~ORWOSWO`ZOaZOkXOrYO~Om[ORiXSiX`iXaiXfiXkiXriXqiXjiXniXliXoiX~Oo^O~PVOj`O~PVOTcO~OlhO~PVOqiO~PtOjlOnjO~PtOfbaqbajbanbalbaoba~PtOlmO~PtOjnO~PtOqoO~PtOf_iq_ij_in_il_io_i~PtOlqOnjO~PtOjuOnjO~OlwOnjO~OnxOozO~PtOjdandalda~PtOf^yq^yj^yn^yl^yo^y~PtOnxOo}O~Oq!OO~PtOneqoeq~PtORSc`YZWTY~",
12
- goto: "#ijPPkPPP{{PPPP{{{{PP{P!]!gPPP!mmQORSTVXYZ[ijox!OmUORSTVXYZ[ijox!OQk_QpgTtkpQyrR|yQPOQ]RQ_SQaTQbVQdXQeYQfZQg[QriQsjQvoQ{xR!P!O",
13
- nodeNames: "⚠ Expression ObjectAccess NullSafeMemberOf MemberOf Identifier ArrayAccess FunctionCall Number String Boolean Null Object Array TernaryExpression BinaryExpression OperatorKeyword Operator UnaryExpression UnaryOperator",
14
- maxTerm: 34,
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,
15
19
  skippedNodes: [0],
16
20
  repeatNodeCount: 2,
17
- tokenData: "AZ~R!QXY$XYZ$X]^$Xpq$Xqr$jrs%Ruv$|vw&{wx'Txy(xyz(}z{)S{|)[|})c}!O)[!O!P)h!P!Q$|!Q![)p![!],V!^!_$t!_!`,[!`!a$t!a!b,b!c!},u!}#O-W#P#Q-]#Q#R$|#R#S,u#T#U-b#U#V,u#V#W.u#W#X,u#X#Y2Z#Y#Z4u#Z#],u#]#^7V#^#a,u#a#b7n#b#c:S#c#d=c#d#g,u#g#h=z#h#i?w#i#o,u#o#p@w#p#q@|#q#rAU#r#s$|~$^Sh~XY$XYZ$X]^$Xpq$XR$qPaQcP!_!`$tQ$yPaQ!_!`$|Q%ROaQ~%UXOr%Rrs%qs#O%R#O#P%v#P;'S%R;'S;=`&u<%l~%R~O%R~~%q~%vOX~~%yRO;'S%R;'S;=`&S;=`O%R~&VYOr%Rrs%qs#O%R#O#P%v#P;'S%R;'S;=`&u;=`<%l%R<%l~%R~O%R~~%q~&xP;=`<%l%RQ'QPaQvw$|~'WXOw'Twx%qx#O'T#O#P's#P;'S'T;'S;=`(r<%l~'T~O'T~~%q~'vRO;'S'T;'S;=`(P;=`O'T~(SYOw'Twx%qx#O'T#O#P's#P;'S'T;'S;=`(r;=`<%l'T<%l~'T~O'T~~%q~(uP;=`<%l'T~(}Om~~)SOl~Q)XPaQz{$|R)cOaQcP~)hOn~~)mPS~!O!P$|~)uTW~!O!P*U!Q![)p!g!h+U#R#S,P#X#Y+U~*XSO!O*e!P;'S*e;'S;=`+y<%lO*e~*jRW~!Q![*s!g!h+U#X#Y+U~*xSW~!Q![*s!g!h+U#R#S+s#X#Y+U~+XR{|+b}!O+b!Q![+h~+eP!Q![+h~+mQW~!Q![+h#R#S+b~+vP!Q![*s~+|P;=`<%l*e~,SP!Q![)p~,[Oq~Q,_P!_!`$t~,gRr~!O!P,p![!]$|!a!b$|~,uOR~~,zST~!Q![,u!c!},u#R#S,u#T#o,u~-]Ok~~-bOj~~-gUT~!Q![,u!c!},u#R#S,u#T#b,u#b#c-y#c#o,u~.OUT~!Q![,u!c!},u#R#S,u#T#W,u#W#X.b#X#o,u~.iS`~T~!Q![,u!c!},u#R#S,u#T#o,u~.zUT~!Q![,u!c!},u#R#S,u#T#c,u#c#d/^#d#o,u~/cUT~!Q![,u!c!},u#R#S,u#T#b,u#b#c/u#c#o,u~/zUT~!Q![,u!c!},u#R#S,u#T#h,u#h#i0^#i#o,u~0cTT~!Q![,u!c!},u#R#S,u#T#U0r#U#o,u~0wUT~!Q![,u!c!},u#R#S,u#T#],u#]#^1Z#^#o,u~1`UT~!Q![,u!c!},u#R#S,u#T#b,u#b#c1r#c#o,u~1wUT~!Q![,u!c!},u#R#S,u#T#g,u#g#h.b#h#o,u~2`UT~!Q![,u!c!},u#R#S,u#T#b,u#b#c2r#c#o,u~2wUT~!Q![,u!c!},u#R#S,u#T#W,u#W#X3Z#X#o,u~3`UT~!Q![,u!c!},u#R#S,u#T#g,u#g#h3r#h#o,u~3wTT~pq4W!Q![,u!c!},u#R#S,u#T#o,u~4ZP#k#l4^~4aP#]#^4d~4gP#h#i4j~4mP#[#]4p~4uO`~~4zTT~!Q![,u!c!},u#R#S,u#T#U5Z#U#o,u~5`UT~!Q![,u!c!},u#R#S,u#T#`,u#`#a5r#a#o,u~5wUT~!Q![,u!c!},u#R#S,u#T#g,u#g#h6Z#h#o,u~6`UT~!Q![,u!c!},u#R#S,u#T#X,u#X#Y6r#Y#o,u~6ySY~T~!Q![,u!c!},u#R#S,u#T#o,u~7[UT~!Q![,u!c!},u#R#S,u#T#b,u#b#c.b#c#o,u~7sTT~!Q![,u!c!},u#R#S,u#T#U8S#U#o,u~8XUT~!Q![,u!c!},u#R#S,u#T#h,u#h#i8k#i#o,u~8pUT~!Q![,u!c!},u#R#S,u#T#V,u#V#W9S#W#o,u~9XUT~!Q![,u!c!},u#R#S,u#T#[,u#[#]9k#]#o,u~9pUT~!Q![,u!c!},u#R#S,u#T#X,u#X#Y1r#Y#o,u~:XWT~!Q![,u!c!},u#R#S,u#T#c,u#c#d:q#d#i,u#i#j<O#j#o,u~:vUT~!Q![,u!c!},u#R#S,u#T#h,u#h#i;Y#i#o,u~;cTcP`~T~pq;r!Q![,u!c!},u#R#S,u#T#o,u~;uP#]#^;x~;{P#b#c4p~<TUT~!Q![,u!c!},u#R#S,u#T#`,u#`#a<g#a#o,u~<lUT~!Q![,u!c!},u#R#S,u#T#`,u#`#a=O#a#o,u~=VSZ~T~!Q![,u!c!},u#R#S,u#T#o,u~=hUT~!Q![,u!c!},u#R#S,u#T#f,u#f#g.b#g#o,u~>PUT~!Q![,u!c!},u#R#S,u#T#h,u#h#i>c#i#o,u~>hTT~!Q![,u!c!},u#R#S,u#T#U>w#U#o,u~>|UT~!Q![,u!c!},u#R#S,u#T#f,u#f#g?`#g#o,u~?eUT~!Q![,u!c!},u#R#S,u#T#h,u#h#i3Z#i#o,u~?|UT~!Q![,u!c!},u#R#S,u#T#f,u#f#g@`#g#o,u~@eUT~!Q![,u!c!},u#R#S,u#T#i,u#i#j6Z#j#o,u~@|Op~QARPaQ#p#q$|~AZOo~",
18
- tokenizers: [0, 1],
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],
19
23
  topRules: {"Expression":[0,1]},
20
- tokenPrec: 301
24
+ specialized: [{term: 33, get: (value) => spec_word[value] || -1},{term: 23, get: (value) => spec_Operator[value] || -1}],
25
+ tokenPrec: 479
21
26
  });
22
27
 
23
- const isFunction = (identifier, config) => { var _a; return (_a = config.functions) === null || _a === void 0 ? void 0 : _a.find(fn => fn.name === identifier); };
24
- const isVariable = (identifier, config) => { var _a; return (_a = config.identifiers) === null || _a === void 0 ? void 0 : _a.find(variable => variable.name === identifier); };
25
- const autocompleteFunction = (x) => { var _a, _b, _c; return ({ label: `${x.name}(${((_a = x.args) === null || _a === void 0 ? void 0 : _a.join(',')) || ''})`, apply: `${x.name}(${!((_b = x.args) === null || _b === void 0 ? void 0 : _b.length) ? ')' : ''}`, detail: (_c = x.returnType) === null || _c === void 0 ? void 0 : _c.join('|'), info: x.info, type: "function" }); };
28
+ const autocompleteFunction = (x) => {
29
+ var _a, _b;
30
+ return ({
31
+ label: `${x.name}(${((_a = x.args) === null || _a === void 0 ? void 0 : _a.join(',')) || ''})`,
32
+ apply: (view, completion, from, to) => {
33
+ var _a;
34
+ 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) } }));
35
+ },
36
+ detail: (_b = x.returnType) === null || _b === void 0 ? void 0 : _b.join('|'),
37
+ info: x.info, type: "function"
38
+ });
39
+ };
26
40
  const autocompleteIdentifier = (x) => { var _a; return ({ label: x.name, apply: x.name, info: x.info, detail: x.detail || ((_a = x.type) === null || _a === void 0 ? void 0 : _a.join('|')), type: 'variable' }); };
27
- const expressionLanguageLinter = (config) => linter(view => {
41
+ const resolveCallable = (identifier, config) => { var _a; return (_a = config === null || config === void 0 ? void 0 : config.functions) === null || _a === void 0 ? void 0 : _a.find(x => x.name === identifier); };
42
+ const resolveIdentifier = (nodeName, identifier, config) => {
43
+ var _a;
44
+ switch (nodeName) {
45
+ case 'Method':
46
+ case 'Function':
47
+ return resolveCallable(identifier, config);
48
+ case 'Property':
49
+ case 'Variable':
50
+ return (_a = config === null || config === void 0 ? void 0 : config.identifiers) === null || _a === void 0 ? void 0 : _a.find(x => x.name === identifier);
51
+ }
52
+ };
53
+ const cursorTooltipBaseTheme = EditorView.baseTheme({
54
+ ".cm-tooltip.cm-tooltip-cursor": {
55
+ boxShadow: 'rgba(0, 0, 0, .15) 0 1px 2px',
56
+ border: "1px solid rgba(127, 127, 127, .2)",
57
+ padding: "2px 7px",
58
+ borderRadius: "4px",
59
+ "& .cm-tooltip-arrow:before": {},
60
+ "& .cm-tooltip-arrow:after": {
61
+ borderTopColor: "transparent"
62
+ }
63
+ }
64
+ });
65
+ function getNodeOrdinal(node) {
66
+ let ordinal = -1;
67
+ for (let c = node; c; c = c.prevSibling, ordinal++)
68
+ ;
69
+ return ordinal;
70
+ }
71
+ function resolveArguments(node) {
72
+ let c = node;
73
+ while (c && c.name !== 'Arguments') {
74
+ c = c.parent;
75
+ }
76
+ return c;
77
+ }
78
+ function resolveFunctionDefinition(node, state, config) {
79
+ var _a;
80
+ if (!node) {
81
+ return undefined;
82
+ }
83
+ let identifier;
84
+ if (node.name === 'ObjectAccess' && node.lastChild) {
85
+ const leftArgument = (_a = node.firstChild) === null || _a === void 0 ? void 0 : _a.node;
86
+ const types = Array.from(resolveTypes(state, leftArgument, config));
87
+ identifier = state.sliceDoc(node.lastChild.from, node.lastChild.to);
88
+ return types.map(type => { var _a; return resolveCallable(identifier, (_a = config.types) === null || _a === void 0 ? void 0 : _a[type]); }).find(x => x);
89
+ }
90
+ else if (node.name === 'Function') {
91
+ identifier = state.sliceDoc(node.from, node.node.firstChild ? node.node.firstChild.from - 1 : node.to);
92
+ return resolveCallable(identifier, config);
93
+ }
94
+ }
95
+ function getCursorTooltips(state, config) {
96
+ // @ts-ignore
97
+ return state.selection.ranges
98
+ .filter(range => range.empty)
99
+ .map(range => {
100
+ var _a;
101
+ const tree = syntaxTree(state);
102
+ const node = tree.resolveInner(range.from, 0);
103
+ const args = resolveArguments(node);
104
+ if (!args || !args.prevSibling) {
105
+ return null;
106
+ }
107
+ const fn = resolveFunctionDefinition(args.prevSibling, state, config);
108
+ if (!fn) {
109
+ return null;
110
+ }
111
+ const n = args.childAfter(range.from - 1);
112
+ const argName = (_a = fn.args) === null || _a === void 0 ? void 0 : _a[n ? getNodeOrdinal(n) : 0];
113
+ if (n && n.from !== range.from || !argName) {
114
+ return null;
115
+ }
116
+ return {
117
+ pos: range.head,
118
+ above: true,
119
+ strictSide: false,
120
+ arrow: true,
121
+ create: () => {
122
+ let dom = document.createElement("div");
123
+ dom.className = "cm-tooltip-cursor";
124
+ dom.textContent = `${argName}`;
125
+ return { dom };
126
+ },
127
+ };
128
+ }).filter(x => x);
129
+ }
130
+ const cursorTooltipField = (config) => StateField.define({
131
+ create: (state) => getCursorTooltips(state, config),
132
+ update(tooltips, tr) {
133
+ if (!tr.docChanged && !tr.selection) {
134
+ return tooltips;
135
+ }
136
+ return getCursorTooltips(tr.state, config);
137
+ },
138
+ provide: f => showTooltip.computeN([f], state => state.field(f))
139
+ });
140
+ const expressionLanguageLinterSource = (config) => (state) => {
28
141
  let diagnostics = [];
29
- let previousNode = null;
30
- syntaxTree(view.state).cursor().iterate(node => {
31
- var _a, _b, _c, _d, _e;
32
- if (((_a = node.node.parent) === null || _a === void 0 ? void 0 : _a.name) == 'ObjectAccess' && ((_b = node.node.parent) === null || _b === void 0 ? void 0 : _b.firstChild) && node.name == "Identifier" && node.node.prevSibling) {
33
- const leftArgument = node.node.parent.firstChild.node;
34
- const types = resolveTypes(view.state, leftArgument, config, true);
35
- const identifier = view.state.sliceDoc(node.from, node.to);
36
- if (((_d = (_c = node.node.parent) === null || _c === void 0 ? void 0 : _c.parent) === null || _d === void 0 ? void 0 : _d.name) === 'FunctionCall' && !node.node.parent.prevSibling) {
37
- if (!Array.from(types).find(type => { var _a, _b, _c; return (_c = (_b = (_a = config.types) === null || _a === void 0 ? void 0 : _a[type]) === null || _b === void 0 ? void 0 : _b.functions) === null || _c === void 0 ? void 0 : _c.find(x => x.name === identifier); })) {
38
- diagnostics.push({
39
- from: node.from,
40
- to: node.to,
41
- severity: 'error',
42
- message: `Method '${identifier}' not found in ${Array.from(types).join('|')}`,
43
- });
142
+ syntaxTree(state).cursor().iterate(node => {
143
+ var _a, _b, _c, _d, _e, _f, _g;
144
+ const { from, to, name } = node;
145
+ let identifier;
146
+ switch (name) {
147
+ case '⚠':
148
+ if (state.doc.length === 0 || from === 0) {
149
+ // Don't show error on empty doc (even though it is an error)
150
+ return;
151
+ }
152
+ identifier = state.sliceDoc(from, to);
153
+ if (identifier.length === 0) {
154
+ diagnostics.push({ from, to: (_c = (_b = (_a = node.node.parent) === null || _a === void 0 ? void 0 : _a.parent) === null || _b === void 0 ? void 0 : _b.to) !== null && _c !== void 0 ? _c : to, severity: 'error', message: `Expression expected` });
155
+ }
156
+ else {
157
+ const type = /^[a-zA-Z_]+[a-zA-Z_0-9]*$/.test(identifier) ? 'identifier' : 'operator';
158
+ diagnostics.push({ from, to, severity: 'error', message: `Unexpected ${type} '${identifier}'` });
159
+ }
160
+ return;
161
+ case 'Arguments':
162
+ const args = (_d = resolveFunctionDefinition(node.node.prevSibling, state, config)) === null || _d === void 0 ? void 0 : _d.args;
163
+ if (!args) {
164
+ return;
44
165
  }
45
- }
46
- else if (types.size > 0) {
47
- if (!Array.from(types).find(type => { var _a, _b, _c; return (_c = (_b = (_a = config.types) === null || _a === void 0 ? void 0 : _a[type]) === null || _b === void 0 ? void 0 : _b.identifiers) === null || _c === void 0 ? void 0 : _c.find(x => x.name === identifier); })) {
48
- diagnostics.push({
49
- from: node.from,
50
- to: node.to,
51
- severity: 'warning',
52
- message: `Property '${identifier}' not found in ${Array.from(types).join('|')}`,
53
- });
166
+ let i = 0;
167
+ let n = node.node.firstChild;
168
+ while (n) {
169
+ if (++i > args.length) {
170
+ diagnostics.push({ from: n.from, to: n.to, severity: 'error', message: `Unexpected argument` });
171
+ }
172
+ n = n.nextSibling;
54
173
  }
55
- }
56
- return;
174
+ break;
175
+ case 'Property':
176
+ case 'Method':
177
+ const leftArgument = (_f = (_e = node.node.parent) === null || _e === void 0 ? void 0 : _e.firstChild) === null || _f === void 0 ? void 0 : _f.node;
178
+ const types = Array.from(resolveTypes(state, leftArgument, config));
179
+ identifier = state.sliceDoc(from, to);
180
+ if (!types.find(type => { var _a; return resolveIdentifier(name, identifier, (_a = config.types) === null || _a === void 0 ? void 0 : _a[type]); })) {
181
+ diagnostics.push({ from, to, severity: 'error', message: `${node.name} "${identifier}" not found in ${types.join('|')}` });
182
+ }
183
+ break;
184
+ case 'Variable':
185
+ case 'Function':
186
+ identifier = state.sliceDoc(from, node.node.firstChild ? node.node.firstChild.from - 1 : to);
187
+ if (!resolveIdentifier(name, identifier, config)) {
188
+ diagnostics.push({ from, to, severity: 'error', message: `${node.node.name} "${identifier}" not found` });
189
+ }
190
+ break;
57
191
  }
58
- if (node.name == "Identifier") {
59
- if ((previousNode === null || previousNode === void 0 ? void 0 : previousNode.name) == "Identifier" && !['Array', 'FunctionCall'].includes(((_e = node.node.parent) === null || _e === void 0 ? void 0 : _e.name) || '')) {
60
- diagnostics.push({
61
- from: node.from,
62
- to: node.to,
63
- severity: 'error',
64
- message: `Unexpected identifier after another identifier`,
65
- });
66
- }
67
- const identifier = view.state.sliceDoc(node.from, node.to);
68
- if (!isFunction(identifier, config) && !isVariable(identifier, config)) {
69
- diagnostics.push({
70
- from: node.from,
71
- to: node.to,
72
- severity: 'error',
73
- message: `Identifier "${identifier}" not found`,
74
- });
75
- }
192
+ if (identifier && ((_g = node.node.parent) === null || _g === void 0 ? void 0 : _g.type.isError)) {
193
+ diagnostics.push({ from, to, severity: 'error', message: `Unexpected identifier "${identifier}"` });
76
194
  }
77
- previousNode = node.node;
78
195
  });
79
196
  return diagnostics;
80
- });
197
+ };
198
+ const expressionLanguageLinter = (config) => linter(view => expressionLanguageLinterSource(config)(view.state));
81
199
  const keywordTooltip = (config) => hoverTooltip((view, pos, side) => {
82
200
  var _a, _b, _c, _d, _e, _f;
83
201
  const tree = syntaxTree(view.state).resolveInner(pos, side);
84
- if (tree.name !== 'Identifier') {
202
+ if (!['Function', 'Variable', 'Method', 'Property'].includes(tree.name)) {
85
203
  return null;
86
204
  }
87
205
  const skipEmpty = (x) => x;
88
206
  let info;
89
207
  if (((_a = tree.parent) === null || _a === void 0 ? void 0 : _a.firstChild) && ((_b = tree.parent) === null || _b === void 0 ? void 0 : _b.name) === 'ObjectAccess' && tree.prevSibling) {
90
208
  const node = tree.parent.firstChild;
91
- const types = resolveTypes(view.state, node, config, true);
209
+ const types = Array.from(resolveTypes(view.state, node, config));
92
210
  const name = view.state.sliceDoc(tree.from, tree.to);
93
211
  info = [
94
- ...Array.from(types).map(type => { var _a, _b, _c, _d; return (_d = (_c = (_b = (_a = config.types) === null || _a === void 0 ? void 0 : _a[type]) === null || _b === void 0 ? void 0 : _b.identifiers) === null || _c === void 0 ? void 0 : _c.find(x => x.name === name)) === null || _d === void 0 ? void 0 : _d.info; }).filter(skipEmpty),
95
- ...Array.from(types).map(type => { var _a, _b, _c, _d; return (_d = (_c = (_b = (_a = config.types) === null || _a === void 0 ? void 0 : _a[type]) === null || _b === void 0 ? void 0 : _b.functions) === null || _c === void 0 ? void 0 : _c.find(x => x.name === name)) === null || _d === void 0 ? void 0 : _d.info; }).filter(skipEmpty),
212
+ ...types.map(type => { var _a, _b, _c, _d; return (_d = (_c = (_b = (_a = config.types) === null || _a === void 0 ? void 0 : _a[type]) === null || _b === void 0 ? void 0 : _b.identifiers) === null || _c === void 0 ? void 0 : _c.find(x => x.name === name)) === null || _d === void 0 ? void 0 : _d.info; }).filter(skipEmpty),
213
+ ...types.map(type => { var _a, _b, _c, _d; return (_d = (_c = (_b = (_a = config.types) === null || _a === void 0 ? void 0 : _a[type]) === null || _b === void 0 ? void 0 : _b.functions) === null || _c === void 0 ? void 0 : _c.find(x => x.name === name)) === null || _d === void 0 ? void 0 : _d.info; }).filter(skipEmpty),
96
214
  ].join('\n');
97
215
  }
98
216
  else {
@@ -110,8 +228,8 @@ const keywordTooltip = (config) => hoverTooltip((view, pos, side) => {
110
228
  end: tree.to,
111
229
  above: true,
112
230
  create(view) {
113
- let dom = document.createElement("div");
114
- dom.textContent = info;
231
+ const dom = document.createElement("div");
232
+ dom[config.htmlTooltip ? 'innerHTML' : 'textContent'] = info;
115
233
  dom.className = 'cm-diagnostic';
116
234
  return { dom };
117
235
  },
@@ -121,13 +239,20 @@ const ELLanguage = LRLanguage.define({
121
239
  parser: parser.configure({
122
240
  props: [
123
241
  indentNodeProp.add({
124
- Application: delimitedIndent({ closing: ")", align: false })
242
+ Application: delimitedIndent({ closing: ")", align: false }),
243
+ Arguments: delimitedIndent({ closing: ")", align: false }),
244
+ Object: delimitedIndent({ closing: "}", align: false }),
125
245
  }),
126
246
  foldNodeProp.add({
127
- Application: foldInside
247
+ Application: ({ from, to }) => ({ from: from + 1, to: to - 1 }),
248
+ Arguments: ({ from, to }) => ({ from: from + 1, to: to - 1 }),
249
+ Object: ({ from, to }) => ({ from: from + 1, to: to - 1 }),
128
250
  }),
129
251
  styleTags({
130
- Identifier: tags.variableName,
252
+ Property: tags.propertyName,
253
+ Variable: tags.variableName,
254
+ Function: tags.function(tags.variableName),
255
+ Method: tags.function(tags.propertyName),
131
256
  Boolean: tags.bool,
132
257
  String: tags.string,
133
258
  Number: tags.number,
@@ -135,10 +260,12 @@ const ELLanguage = LRLanguage.define({
135
260
  ')': tags.paren,
136
261
  '[': tags.squareBracket,
137
262
  ']': tags.squareBracket,
263
+ ',': tags.punctuation,
264
+ MemberOf: tags.punctuation,
265
+ NullSafeMemberOf: tags.punctuation,
138
266
  OperatorKeyword: tags.operatorKeyword,
267
+ UnaryOperator: tags.operator,
139
268
  Operator: tags.operator,
140
- MemberOf: tags.operator,
141
- NullSafeMemberOf: tags.operator,
142
269
  })
143
270
  ]
144
271
  }),
@@ -146,46 +273,61 @@ const ELLanguage = LRLanguage.define({
146
273
  });
147
274
  function completeOperatorKeyword(state, config, tree, from, to, explicit) {
148
275
  var _a, _b;
149
- const text = state.sliceDoc(from, to);
150
276
  return {
151
277
  from,
152
278
  to,
153
- options: (_b = (_a = config.operatorKeywords) === null || _a === void 0 ? void 0 : _a.filter(({ name }) => explicit || name.startsWith(text)).map(({ name, info, detail }) => ({ label: name, apply: `${name} `, info, detail, type: "keyword" }))) !== null && _b !== void 0 ? _b : [],
154
- validFor: (text) => { var _a, _b; return (_b = (_a = config.operatorKeywords) === null || _a === void 0 ? void 0 : _a.some(({ name }) => explicit || name.startsWith(text))) !== null && _b !== void 0 ? _b : false; },
279
+ options: (_b = (_a = config.operatorKeywords) === null || _a === void 0 ? void 0 : _a.map(({ name, info, detail }) => ({ label: name, apply: `${name} `, info, detail, type: "keyword" }))) !== null && _b !== void 0 ? _b : [],
280
+ validFor: (text) => { var _a, _b; return (_b = (_a = config.operatorKeywords) === null || _a === void 0 ? void 0 : _a.some(({ name }) => explicit || name.includes(text))) !== null && _b !== void 0 ? _b : false; },
155
281
  };
156
282
  }
157
- function completeIdentifier(state, config, tree, from, to, explicit) {
158
- var _a, _b, _c, _d;
159
- const text = state.sliceDoc(from, to).toLowerCase();
160
- const identifiers = (_b = (_a = config.identifiers) === null || _a === void 0 ? void 0 : _a.filter(({ name }) => explicit || name.toLowerCase().startsWith(text))) !== null && _b !== void 0 ? _b : [];
161
- const functions = (_d = (_c = config.functions) === null || _c === void 0 ? void 0 : _c.filter(({ name }) => explicit || name.toLowerCase().startsWith(text))) !== null && _d !== void 0 ? _d : [];
283
+ function completeIdentifier(state, config, tree, from, to) {
284
+ var _a, _b;
285
+ const identifiers = (_a = config.identifiers) !== null && _a !== void 0 ? _a : []; //?.filter(({ name }) => explicit || name.toLowerCase().startsWith(text)) ?? [];
286
+ const functions = (_b = config.functions) !== null && _b !== void 0 ? _b : []; //?.filter(({ name }) => explicit || name.toLowerCase().startsWith(text)) ?? [];
162
287
  return {
163
288
  from,
164
289
  to,
165
290
  options: [...(identifiers.map(autocompleteIdentifier)), ...(functions.map(autocompleteFunction))],
166
- // validFor: identifier,
167
- filter: false,
291
+ validFor: /^[a-zA-Z_]+[a-zA-Z_0-9]*$/,
168
292
  };
169
293
  }
170
294
  function resolveTypes(state, node, config, matchExact) {
171
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m;
295
+ var _a, _b, _c, _d, _e, _f, _g, _h;
172
296
  let types = new Set();
173
- if (node.name === 'FunctionCall' && node.firstChild && node.lastChild) {
174
- resolveTypes(state, node.firstChild, config, matchExact).forEach(x => types.add(x));
297
+ if (!node) {
298
+ return types;
299
+ }
300
+ if (node.name === 'Call' && node.firstChild && node.lastChild) {
301
+ resolveTypes(state, node.firstChild, config).forEach(x => types.add(x));
175
302
  }
176
- else if (node.name === 'Identifier') {
303
+ else if (node.name === 'Variable') {
177
304
  const varName = state.sliceDoc(node.from, node.to) || '';
178
- (_c = (_b = (_a = config.functions) === null || _a === void 0 ? void 0 : _a.find(x => x.name == varName)) === null || _b === void 0 ? void 0 : _b.returnType) === null || _c === void 0 ? void 0 : _c.forEach(x => types.add(x));
179
- (_f = (_e = (_d = config.identifiers) === null || _d === void 0 ? void 0 : _d.find(x => x.name == varName)) === null || _e === void 0 ? void 0 : _e.type) === null || _f === void 0 ? void 0 : _f.forEach(x => types.add(x));
305
+ // @ts-ignore
306
+ (_b = (_a = resolveIdentifier(node.name, varName, config)) === null || _a === void 0 ? void 0 : _a.type) === null || _b === void 0 ? void 0 : _b.forEach((x) => types.add(x));
180
307
  }
181
- else if (node.name === 'ObjectAccess' && node.firstChild && ((_g = node.lastChild) === null || _g === void 0 ? void 0 : _g.name) === 'Identifier') {
182
- const baseTypes = resolveTypes(state, node.firstChild, config, matchExact);
308
+ else if (node.name === 'Function') {
309
+ const varName = state.sliceDoc(node.from, node.to) || '';
310
+ // @ts-ignore
311
+ (_d = (_c = resolveIdentifier(node.name, varName, config)) === null || _c === void 0 ? void 0 : _c.returnType) === null || _d === void 0 ? void 0 : _d.forEach((x) => types.add(x));
312
+ }
313
+ else if (node.name === 'ObjectAccess' && node.firstChild && ((_e = node.lastChild) === null || _e === void 0 ? void 0 : _e.name) === 'Property') {
183
314
  const varName = state.sliceDoc(node.lastChild.from, node.lastChild.to) || '';
184
- for (const baseType of baseTypes) {
185
- const type = (_h = config.types) === null || _h === void 0 ? void 0 : _h[baseType];
186
- (_k = (_j = type === null || type === void 0 ? void 0 : type.functions) === null || _j === void 0 ? void 0 : _j.filter(x => matchExact ? x.name === varName : x.name.startsWith(varName))) === null || _k === void 0 ? void 0 : _k.forEach(def => (def.returnType || ['any']).forEach(x => types.add(x)));
187
- (_m = (_l = type === null || type === void 0 ? void 0 : type.identifiers) === null || _l === void 0 ? void 0 : _l.filter(x => matchExact ? x.name === varName : x.name.startsWith(varName))) === null || _m === void 0 ? void 0 : _m.forEach(def => (def.type || ['any']).forEach(x => types.add(x)));
188
- }
315
+ (_f = resolveTypes(state, node.firstChild, config)) === null || _f === void 0 ? void 0 : _f.forEach(baseType => {
316
+ var _a, _b, _c, _d;
317
+ // @ts-ignore
318
+ (_d = (_c = resolveIdentifier((_a = node.lastChild) === null || _a === void 0 ? void 0 : _a.name, varName, (_b = config.types) === null || _b === void 0 ? void 0 : _b[baseType])) === null || _c === void 0 ? void 0 : _c.type) === null || _d === void 0 ? void 0 : _d.forEach((x) => types.add(x));
319
+ });
320
+ }
321
+ else if (node.name === 'ObjectAccess' && node.firstChild && ((_g = node.lastChild) === null || _g === void 0 ? void 0 : _g.name) === 'Method') {
322
+ const varName = state.sliceDoc(node.lastChild.from, node.lastChild.to) || '';
323
+ (_h = resolveTypes(state, node.firstChild, config)) === null || _h === void 0 ? void 0 : _h.forEach(baseType => {
324
+ var _a, _b, _c, _d;
325
+ // @ts-ignore
326
+ (_d = (_c = resolveIdentifier((_a = node.lastChild) === null || _a === void 0 ? void 0 : _a.name, varName, (_b = config.types) === null || _b === void 0 ? void 0 : _b[baseType])) === null || _c === void 0 ? void 0 : _c.returnType) === null || _d === void 0 ? void 0 : _d.forEach((x) => types.add(x));
327
+ });
328
+ }
329
+ else if (node.name === 'Application' && node.firstChild) {
330
+ resolveTypes(state, node.firstChild, config).forEach(x => types.add(x));
189
331
  }
190
332
  if (types.size === 0) {
191
333
  types.add('any');
@@ -197,42 +339,46 @@ function completeMember(state, config, tree, from, to, explicit) {
197
339
  if (((_a = tree.parent) === null || _a === void 0 ? void 0 : _a.name) != 'ObjectAccess' || !tree.parent.firstChild) {
198
340
  return null;
199
341
  }
200
- const types = resolveTypes(state, tree.parent.firstChild.node, config, false);
342
+ state.sliceDoc(from, to);
343
+ const types = resolveTypes(state, tree.parent.firstChild.node, config);
201
344
  if (!(types === null || types === void 0 ? void 0 : types.size)) {
202
345
  return null;
203
346
  }
204
- const varName = state.sliceDoc(from, to);
205
347
  let options = [];
206
348
  for (const type of types) {
207
349
  const typeDeclaration = (_b = config.types) === null || _b === void 0 ? void 0 : _b[type];
208
- options.push(...(((_c = typeDeclaration === null || typeDeclaration === void 0 ? void 0 : typeDeclaration.identifiers) === null || _c === void 0 ? void 0 : _c.filter(x => x.name.startsWith(varName)).map(autocompleteIdentifier)) || []), ...(((_d = typeDeclaration === null || typeDeclaration === void 0 ? void 0 : typeDeclaration.functions) === null || _d === void 0 ? void 0 : _d.filter(x => x.name.startsWith(varName)).map(autocompleteFunction)) || []));
350
+ options.push(...(((_c = typeDeclaration === null || typeDeclaration === void 0 ? void 0 : typeDeclaration.identifiers) === null || _c === void 0 ? void 0 : _c.map(autocompleteIdentifier)) || []), ...(((_d = typeDeclaration === null || typeDeclaration === void 0 ? void 0 : typeDeclaration.functions) === null || _d === void 0 ? void 0 : _d.map(autocompleteFunction)) || []));
209
351
  }
210
352
  return {
211
353
  from,
212
354
  to,
213
355
  options,
214
- filter: false,
356
+ validFor: /^[a-zA-Z_]+[a-zA-Z_0-9]*$/,
215
357
  };
216
358
  }
217
359
  function expressionLanguageCompletionFor(config, context) {
218
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
360
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m;
219
361
  const { state, pos, explicit } = context;
220
- const tree = syntaxTree(state).resolveInner(pos, -1);
221
- const isOperator = (node) => node && ['Operator', 'OperatorKeyword'].includes(node.name);
222
- const isIdentifier = (node) => (node === null || node === void 0 ? void 0 : node.name) === 'Identifier';
223
- const prevNode = ((_a = tree.parent) === null || _a === void 0 ? void 0 : _a.node.type.isError) ? tree.parent.prevSibling : tree.prevSibling;
224
- if (tree.name == 'String') {
362
+ const tree = syntaxTree(state);
363
+ const prevNode = tree.resolveInner(pos, state.sliceDoc(pos - 1, pos) === ')' ? 0 : -1);
364
+ const isIdentifier = (node) => { var _a; return ['Variable', 'Function'].includes((_a = node === null || node === void 0 ? void 0 : node.name) !== null && _a !== void 0 ? _a : ''); };
365
+ const isMember = (node) => { var _a; return ['Property', 'Method'].includes((_a = node === null || node === void 0 ? void 0 : node.name) !== null && _a !== void 0 ? _a : ''); };
366
+ if (prevNode.name == 'String') {
225
367
  return null;
226
368
  }
227
- if (((_b = tree.parent) === null || _b === void 0 ? void 0 : _b.name) == 'ObjectAccess' && ['ObjectAccess', 'ArrayAccess', 'Identifier', 'FunctionCall'].includes(((_c = tree.parent.firstChild) === null || _c === void 0 ? void 0 : _c.name) || '')) {
228
- return completeMember(state, config, tree, isIdentifier(tree.node) ? tree.from : pos, pos);
369
+ if (((_a = prevNode.parent) === null || _a === void 0 ? void 0 : _a.name) == 'ObjectAccess' && ['ObjectAccess', 'ArrayAccess', 'Variable', 'Call'].includes(((_b = prevNode.parent.firstChild) === null || _b === void 0 ? void 0 : _b.name) || '')) {
370
+ return completeMember(state, config, prevNode, isIdentifier(prevNode) || isMember(prevNode) ? prevNode.from : pos, pos);
229
371
  }
230
- // No idea what's going on here, just added conditions until all the tests passed :)
231
- if (prevNode && !isOperator(prevNode.node) && (((_d = tree.parent) === null || _d === void 0 ? void 0 : _d.node.type.isError) || ((_e = tree.node.parent) === null || _e === void 0 ? void 0 : _e.name) === 'BinaryExpression') || (tree.name === 'Expression' && !((_g = (_f = tree.lastChild) === null || _f === void 0 ? void 0 : _f.type) === null || _g === void 0 ? void 0 : _g.isError) && !isOperator((_h = tree.lastChild) === null || _h === void 0 ? void 0 : _h.node))) {
232
- return completeOperatorKeyword(state, config, tree, tree.name !== 'Expression' ? tree.from : pos, pos, explicit);
372
+ if (['Expression', 'UnaryExpression', 'BinaryExpression', 'TernaryExpression'].includes(prevNode.name) && prevNode.lastChild && !((_c = prevNode.lastChild) === null || _c === void 0 ? void 0 : _c.type.isError)
373
+ || ['Arguments', 'Array'].includes(prevNode.name) && prevNode.lastChild && !((_d = prevNode.lastChild) === null || _d === void 0 ? void 0 : _d.type.isError)
374
+ || ['Expression', 'UnaryExpression', 'BinaryExpression', 'TernaryExpression'].includes((_f = (_e = prevNode.parent) === null || _e === void 0 ? void 0 : _e.name) !== null && _f !== void 0 ? _f : '') && prevNode.type.isError
375
+ || ['Variable', 'Function'].includes((_h = (_g = prevNode.parent) === null || _g === void 0 ? void 0 : _g.name) !== null && _h !== void 0 ? _h : '') && prevNode.type.isError) {
376
+ return completeOperatorKeyword(state, config, prevNode, !['Expression', 'UnaryExpression', 'BinaryExpression', 'TernaryExpression', 'Arguments'].includes(prevNode.name) ? prevNode.from : pos, pos, explicit);
233
377
  }
234
- if (tree.name === 'Expression' || isIdentifier(tree.node) || (tree.name === 'BinaryExpression' && isOperator((_k = (_j = tree.lastChild) === null || _j === void 0 ? void 0 : _j.prevSibling) === null || _k === void 0 ? void 0 : _k.node) && explicit)) {
235
- return completeIdentifier(state, config, tree, isIdentifier(tree.node) ? tree.from : pos, pos, explicit);
378
+ if (['Expression', 'UnaryExpression', 'BinaryExpression', 'TernaryExpression'].includes(prevNode.name) && ((_j = prevNode.lastChild) === null || _j === void 0 ? void 0 : _j.type.isError)
379
+ || ['Expression', 'UnaryExpression', 'BinaryExpression', 'TernaryExpression', 'Arguments'].includes((_l = (_k = prevNode.parent) === null || _k === void 0 ? void 0 : _k.name) !== null && _l !== void 0 ? _l : '') && !prevNode.type.isError
380
+ || ['Arguments', 'Array'].includes((_m = prevNode.name) !== null && _m !== void 0 ? _m : '')) {
381
+ return completeIdentifier(state, config, prevNode, isIdentifier(prevNode) ? prevNode.from : pos, pos);
236
382
  }
237
383
  return null;
238
384
  }
@@ -257,7 +403,8 @@ function expressionlanguage(config = {}, extensions = []) {
257
403
  expressionLanguageLinter(config),
258
404
  keywordTooltip(config),
259
405
  ...extensions,
406
+ [cursorTooltipField(config), cursorTooltipBaseTheme],
260
407
  ]);
261
408
  }
262
409
 
263
- export { ELLanguage, expressionlanguage, keywordTooltip };
410
+ export { ELLanguage, expressionLanguageLinterSource, expressionlanguage, keywordTooltip };
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@valtzu/codemirror-lang-el",
3
3
  "description": "Symfony Expression Language language support for CodeMirror",
4
4
  "scripts": {
5
- "test": "mocha test/test.js test/test-complete.js",
5
+ "test": "mocha test/*.js",
6
6
  "dev": "rollup -c -w",
7
7
  "prepare": "rollup -c"
8
8
  },
@@ -42,5 +42,5 @@
42
42
  "access": "public",
43
43
  "registry": "https://registry.npmjs.org/"
44
44
  },
45
- "version": "0.4.2"
45
+ "version": "0.5.0"
46
46
  }