@valtzu/codemirror-lang-el 0.6.2 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md ADDED
@@ -0,0 +1,13 @@
1
+ CHANGELOG
2
+ =========
3
+
4
+ 0.7
5
+ ---
6
+
7
+ * Add support for comments `/*` & `*/`
8
+ * Add support for `xor`
9
+ * Add support for uppercase `TRUE`/`FALSE`/`NULL`
10
+ * Add support for bitwise operators `<<` && `>>`
11
+ * Add some basic styles
12
+ * Resolve type on logical expressions
13
+ * **BC BREAK:** Function parameters are now passed in as objects (see [`ELParameter`](src/types.ts) for details)
package/README.md CHANGED
@@ -57,7 +57,7 @@ yarn add @valtzu/codemirror-lang-el
57
57
  "@codemirror/state": "https://esm.sh/*@codemirror/state@6.4.1",
58
58
  "@codemirror/search": "https://esm.sh/*@codemirror/search@6.5.6",
59
59
  "@codemirror/autocomplete": "https://esm.sh/*@codemirror/autocomplete@6.9.0",
60
- "@codemirror/view": "https://esm.sh/*@codemirror/view@6.17.1",
60
+ "@codemirror/view": "https://esm.sh/*@codemirror/view@6.26.3",
61
61
  "@codemirror/commands": "https://esm.sh/*@codemirror/commands@6.2.5",
62
62
  "@codemirror/language": "https://esm.sh/*@codemirror/language@6.9.0",
63
63
  "@codemirror/lint": "https://esm.sh/*@codemirror/lint@6.4.1",
@@ -67,7 +67,7 @@ yarn add @valtzu/codemirror-lang-el
67
67
  "style-mod": "https://esm.sh/*style-mod@4.1.2",
68
68
  "w3c-keyname": "https://esm.sh/*w3c-keyname@2.2.8",
69
69
  "crelt": "https://esm.sh/*crelt@1.0.6",
70
- "@valtzu/codemirror-lang-el": "https://esm.sh/*@valtzu/codemirror-lang-el@0.4.2"
70
+ "@valtzu/codemirror-lang-el": "https://esm.sh/*@valtzu/codemirror-lang-el@0.6.3"
71
71
  }
72
72
  }
73
73
  </script>
@@ -111,13 +111,6 @@ yarn add @valtzu/codemirror-lang-el
111
111
  doc: 'is_granted(user, user.self.getGroup())',
112
112
  });
113
113
  </script>
114
- <style>
115
- .cm-completionDetail {
116
- float: right;
117
- opacity: 0.5;
118
- font-style: inherit !important;
119
- }
120
- </style>
121
114
  ```
122
115
 
123
116
  ### Contributing
package/dist/complete.cjs CHANGED
@@ -5,12 +5,20 @@ Object.defineProperty(exports, '__esModule', { value: true });
5
5
  var autocomplete = require('@codemirror/autocomplete');
6
6
  var language = require('@codemirror/language');
7
7
 
8
- const createInfoElement = (html) => {
9
- const dom = document.createElement("div");
10
- dom.innerHTML = html;
11
- dom.className = 'cm-diagnostic';
12
- return dom;
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,
13
20
  };
21
+
14
22
  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); };
15
23
  const resolveIdentifier = (nodeName, identifier, config) => {
16
24
  var _a;
@@ -24,12 +32,16 @@ const resolveIdentifier = (nodeName, identifier, config) => {
24
32
  }
25
33
  };
26
34
  function resolveTypes(state, node, config, matchExact) {
27
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
35
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l;
28
36
  let types = new Set();
29
37
  if (!node) {
30
38
  return types;
31
39
  }
32
- if (node.name === 'Call' && node.firstChild && node.lastChild) {
40
+ let type;
41
+ if (typeof (type = node.type.prop(t)) !== "undefined") {
42
+ types.add(type);
43
+ }
44
+ else if (node.name === 'Call' && node.firstChild && node.lastChild) {
33
45
  resolveTypes(state, node.firstChild, config).forEach(x => types.add(x));
34
46
  }
35
47
  else if (node.name === 'Variable') {
@@ -65,17 +77,32 @@ function resolveTypes(state, node, config, matchExact) {
65
77
  resolveTypes(state, node.firstChild.nextSibling, config).forEach(x => types.add(x));
66
78
  resolveTypes(state, node.firstChild.nextSibling.nextSibling, config).forEach(x => types.add(x));
67
79
  }
68
- else if (node.name === 'BinaryExpression' && ((_k = (_j = node.firstChild) === null || _j === void 0 ? void 0 : _j.nextSibling) === null || _k === void 0 ? void 0 : _k.name) == 'Operator' && node.lastChild) {
80
+ 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)) {
69
81
  const operator = state.sliceDoc(node.firstChild.nextSibling.from, node.firstChild.nextSibling.to);
70
- if (operator == '?:' || operator == '??') {
71
- resolveTypes(state, node.firstChild, config).forEach(x => types.add(x));
72
- }
73
82
  if (operator == '?:' || operator == '??' || operator == '?') {
74
- resolveTypes(state, node.lastChild, config).forEach(x => types.add(x));
83
+ if (operator == '?:' || operator == '??') {
84
+ resolveTypes(state, node.firstChild, config).forEach(x => types.add(x));
85
+ }
86
+ resolveTypes(state, node.firstChild.nextSibling.nextSibling, config).forEach(x => types.add(x));
87
+ }
88
+ else if (['||', '&&', '==', '!=', '===', '!==', '>=', '<=', '>', '<'].includes(operator) || keywords.find(x => x.name == operator)) {
89
+ types.add(ELScalar.Bool);
90
+ }
91
+ else if (['**', '|', '^', '&', '<<', '>>', '+', '-', '*', '/', '%'].includes(operator)) {
92
+ types.add(ELScalar.Number);
93
+ }
94
+ }
95
+ else if (node.name === 'UnaryExpression' && node.firstChild) {
96
+ const operator = state.sliceDoc(node.firstChild.from, node.firstChild.to);
97
+ if (['not', '!'].includes(operator)) {
98
+ types.add(ELScalar.Bool);
99
+ }
100
+ else if (['+', '-'].includes(operator)) {
101
+ types.add(ELScalar.Number);
75
102
  }
76
103
  }
77
104
  if (types.size === 0) {
78
- types.add('any');
105
+ types.add(ELScalar.Any);
79
106
  }
80
107
  return types;
81
108
  }
@@ -92,18 +119,19 @@ const keywords = [
92
119
  { name: 'not' },
93
120
  { name: 'or' },
94
121
  { name: 'and' },
122
+ { name: 'xor' },
95
123
  ];
96
124
 
97
125
  const autocompleteFunction = (x) => {
98
- var _a, _b;
126
+ var _a, _b, _c;
99
127
  return ({
100
- label: `${x.name}(${((_a = x.args) === null || _a === void 0 ? void 0 : _a.join(',')) || ''})`,
128
+ 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(',')) || ''})`,
101
129
  apply: (view, completion, from, to) => {
102
130
  var _a;
103
131
  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) } }));
104
132
  },
105
- detail: (_b = x.returnType) === null || _b === void 0 ? void 0 : _b.join('|'),
106
- info: () => { var _a; return createInfoElement((_a = x.info) !== null && _a !== void 0 ? _a : ''); },
133
+ detail: (_c = x.returnType) === null || _c === void 0 ? void 0 : _c.join('|'),
134
+ info: x.info,
107
135
  type: "function",
108
136
  });
109
137
  };
@@ -112,7 +140,7 @@ const autocompleteIdentifier = (x) => {
112
140
  return ({
113
141
  label: x.name,
114
142
  apply: x.name,
115
- info: () => { var _a; return createInfoElement((_a = x.info) !== null && _a !== void 0 ? _a : ''); },
143
+ info: x.info,
116
144
  detail: x.detail || ((_a = x.type) === null || _a === void 0 ? void 0 : _a.join('|')),
117
145
  type: 'variable',
118
146
  });
@@ -122,7 +150,13 @@ function completeOperatorKeyword(state, config, tree, from, to, explicit) {
122
150
  return {
123
151
  from,
124
152
  to,
125
- options: (_a = keywords.map(({ name, info, detail }) => ({ label: name, apply: `${name} `, info, detail, type: "keyword" }))) !== null && _a !== void 0 ? _a : [],
153
+ options: (_a = keywords.map(({ name, info, detail }) => ({
154
+ label: name,
155
+ apply: `${name} `,
156
+ info: info,
157
+ detail,
158
+ type: "keyword"
159
+ }))) !== null && _a !== void 0 ? _a : [],
126
160
  validFor: (text) => { var _a; return (_a = keywords.some(({ name }) => explicit || name.includes(text))) !== null && _a !== void 0 ? _a : false; },
127
161
  };
128
162
  }
@@ -167,7 +201,7 @@ function expressionLanguageCompletion(context) {
167
201
  const config = getExpressionLanguageConfig(state);
168
202
  const isIdentifier = (node) => { var _a; return ['Variable', 'Function'].includes((_a = node === null || node === void 0 ? void 0 : node.name) !== null && _a !== void 0 ? _a : ''); };
169
203
  const isMember = (node) => { var _a; return ['Property', 'Method'].includes((_a = node === null || node === void 0 ? void 0 : node.name) !== null && _a !== void 0 ? _a : ''); };
170
- if (prevNode.name == 'String') {
204
+ if (prevNode.name == 'String' || prevNode.name == 'BlockComment') {
171
205
  return null;
172
206
  }
173
207
  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) || '')) {
package/dist/complete.js CHANGED
@@ -1,12 +1,20 @@
1
1
  import { insertCompletionText } from '@codemirror/autocomplete';
2
2
  import { syntaxTree } from '@codemirror/language';
3
3
 
4
- const createInfoElement = (html) => {
5
- const dom = document.createElement("div");
6
- dom.innerHTML = html;
7
- dom.className = 'cm-diagnostic';
8
- return dom;
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,
9
16
  };
17
+
10
18
  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); };
11
19
  const resolveIdentifier = (nodeName, identifier, config) => {
12
20
  var _a;
@@ -20,12 +28,16 @@ const resolveIdentifier = (nodeName, identifier, config) => {
20
28
  }
21
29
  };
22
30
  function resolveTypes(state, node, config, matchExact) {
23
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
31
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l;
24
32
  let types = new Set();
25
33
  if (!node) {
26
34
  return types;
27
35
  }
28
- if (node.name === 'Call' && node.firstChild && node.lastChild) {
36
+ let type;
37
+ if (typeof (type = node.type.prop(t)) !== "undefined") {
38
+ types.add(type);
39
+ }
40
+ else if (node.name === 'Call' && node.firstChild && node.lastChild) {
29
41
  resolveTypes(state, node.firstChild, config).forEach(x => types.add(x));
30
42
  }
31
43
  else if (node.name === 'Variable') {
@@ -61,17 +73,32 @@ function resolveTypes(state, node, config, matchExact) {
61
73
  resolveTypes(state, node.firstChild.nextSibling, config).forEach(x => types.add(x));
62
74
  resolveTypes(state, node.firstChild.nextSibling.nextSibling, config).forEach(x => types.add(x));
63
75
  }
64
- else if (node.name === 'BinaryExpression' && ((_k = (_j = node.firstChild) === null || _j === void 0 ? void 0 : _j.nextSibling) === null || _k === void 0 ? void 0 : _k.name) == 'Operator' && node.lastChild) {
76
+ 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)) {
65
77
  const operator = state.sliceDoc(node.firstChild.nextSibling.from, node.firstChild.nextSibling.to);
66
- if (operator == '?:' || operator == '??') {
67
- resolveTypes(state, node.firstChild, config).forEach(x => types.add(x));
68
- }
69
78
  if (operator == '?:' || operator == '??' || operator == '?') {
70
- resolveTypes(state, node.lastChild, config).forEach(x => types.add(x));
79
+ if (operator == '?:' || operator == '??') {
80
+ resolveTypes(state, node.firstChild, config).forEach(x => types.add(x));
81
+ }
82
+ resolveTypes(state, node.firstChild.nextSibling.nextSibling, config).forEach(x => types.add(x));
83
+ }
84
+ else if (['||', '&&', '==', '!=', '===', '!==', '>=', '<=', '>', '<'].includes(operator) || keywords.find(x => x.name == operator)) {
85
+ types.add(ELScalar.Bool);
86
+ }
87
+ else if (['**', '|', '^', '&', '<<', '>>', '+', '-', '*', '/', '%'].includes(operator)) {
88
+ types.add(ELScalar.Number);
89
+ }
90
+ }
91
+ else if (node.name === 'UnaryExpression' && node.firstChild) {
92
+ const operator = state.sliceDoc(node.firstChild.from, node.firstChild.to);
93
+ if (['not', '!'].includes(operator)) {
94
+ types.add(ELScalar.Bool);
95
+ }
96
+ else if (['+', '-'].includes(operator)) {
97
+ types.add(ELScalar.Number);
71
98
  }
72
99
  }
73
100
  if (types.size === 0) {
74
- types.add('any');
101
+ types.add(ELScalar.Any);
75
102
  }
76
103
  return types;
77
104
  }
@@ -88,18 +115,19 @@ const keywords = [
88
115
  { name: 'not' },
89
116
  { name: 'or' },
90
117
  { name: 'and' },
118
+ { name: 'xor' },
91
119
  ];
92
120
 
93
121
  const autocompleteFunction = (x) => {
94
- var _a, _b;
122
+ var _a, _b, _c;
95
123
  return ({
96
- label: `${x.name}(${((_a = x.args) === null || _a === void 0 ? void 0 : _a.join(',')) || ''})`,
124
+ 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(',')) || ''})`,
97
125
  apply: (view, completion, from, to) => {
98
126
  var _a;
99
127
  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) } }));
100
128
  },
101
- detail: (_b = x.returnType) === null || _b === void 0 ? void 0 : _b.join('|'),
102
- info: () => { var _a; return createInfoElement((_a = x.info) !== null && _a !== void 0 ? _a : ''); },
129
+ detail: (_c = x.returnType) === null || _c === void 0 ? void 0 : _c.join('|'),
130
+ info: x.info,
103
131
  type: "function",
104
132
  });
105
133
  };
@@ -108,7 +136,7 @@ const autocompleteIdentifier = (x) => {
108
136
  return ({
109
137
  label: x.name,
110
138
  apply: x.name,
111
- info: () => { var _a; return createInfoElement((_a = x.info) !== null && _a !== void 0 ? _a : ''); },
139
+ info: x.info,
112
140
  detail: x.detail || ((_a = x.type) === null || _a === void 0 ? void 0 : _a.join('|')),
113
141
  type: 'variable',
114
142
  });
@@ -118,7 +146,13 @@ function completeOperatorKeyword(state, config, tree, from, to, explicit) {
118
146
  return {
119
147
  from,
120
148
  to,
121
- options: (_a = keywords.map(({ name, info, detail }) => ({ label: name, apply: `${name} `, info, detail, type: "keyword" }))) !== null && _a !== void 0 ? _a : [],
149
+ options: (_a = keywords.map(({ name, info, detail }) => ({
150
+ label: name,
151
+ apply: `${name} `,
152
+ info: info,
153
+ detail,
154
+ type: "keyword"
155
+ }))) !== null && _a !== void 0 ? _a : [],
122
156
  validFor: (text) => { var _a; return (_a = keywords.some(({ name }) => explicit || name.includes(text))) !== null && _a !== void 0 ? _a : false; },
123
157
  };
124
158
  }
@@ -163,7 +197,7 @@ function expressionLanguageCompletion(context) {
163
197
  const config = getExpressionLanguageConfig(state);
164
198
  const isIdentifier = (node) => { var _a; return ['Variable', 'Function'].includes((_a = node === null || node === void 0 ? void 0 : node.name) !== null && _a !== void 0 ? _a : ''); };
165
199
  const isMember = (node) => { var _a; return ['Property', 'Method'].includes((_a = node === null || node === void 0 ? void 0 : node.name) !== null && _a !== void 0 ? _a : ''); };
166
- if (prevNode.name == 'String') {
200
+ if (prevNode.name == 'String' || prevNode.name == 'BlockComment') {
167
201
  return null;
168
202
  }
169
203
  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) || '')) {
package/dist/index.cjs CHANGED
@@ -10,25 +10,42 @@ var autocomplete = require('@codemirror/autocomplete');
10
10
  var state = require('@codemirror/state');
11
11
  var view = require('@codemirror/view');
12
12
 
13
+ // @ts-ignore
14
+ const t = {
15
+ deserialize: (str) => str,
16
+ };
17
+
13
18
  // 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,"?":93, "!":113, "+":115, "-":117};
19
+ 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};
20
+ const spec_Operator = {__proto__:null,"?":111, "!":133, "+":135, "-":137};
16
21
  const parser = lr.LRParser.deserialize({
17
22
  version: 14,
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'#CsOOQO'#Cs'#CsO%PQPO'#CsO%}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.xO)]QPO1G.vOOQO,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]Oe_Os^O!O`O!PaO!RaO!SbO!TbO!UcO!VbO!WbO!XbO~ORcXScXecXmcXscXuWX!OcX!PcX!RcX!ScX!TcX!UcX!VcX!WcX!XcX}cXrcXwcXtcX{cX~O{eO~PVOrvP~PVOujO~OulO~OqmO~O!QsO~O!VsO]gX^gXqgXsgXugXxgXygXzgX|gX!UgX!YgX!ZgX![gX~O}tO~P!QOwuOrvXtvX~P!QOrwO~Omha}harhawhatha{ha~P!QOtxO~P!QOtvP~PVORTXSTXeTXmTXsTXuZX!OTX!PTX!RTX!STX!TTX!UTX!VTX!WTX!XTX}TXrTXwTXtTX{TX~Or{O~P!QOmfi}firfiwfitfi{fi~P!QO}|O~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^SeR]qR~",
20
- goto: "%]wPPxPP!Zxx!^!o!r#T#WPPxxxxxxPx#Zx#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 Operator BinaryExpression OperatorKeyword UnaryExpression UnaryOperator Application",
22
- maxTerm: 58,
23
- skippedNodes: [0],
24
- repeatNodeCount: 2,
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~#pPe~!_!`#s~#xPe~!_!`#{~$QOe~~$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~&PPe~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~~(WPe~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~+_Re~!O!P+h![!]#{!a!b#{~+mOS~~+rSq~!Q![+m!c!}+m#R#S+m#T#o+m~,TOs~~,YOr~~,_O|~~,dPe~#p#q#{~,lO{~",
26
- tokenizers: [0],
27
- topRules: {"Expression":[0,1]},
28
- specialized: [{term: 33, get: (value) => spec_word[value] || -1},{term: 21, get: (value) => spec_Operator[value] || -1}],
29
- tokenPrec: 479
23
+ 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",
24
+ 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~",
25
+ 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",
26
+ 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",
27
+ maxTerm: 68,
28
+ nodeProps: [
29
+ [t, 14,"number",15,"string",16,"bool",17,"null"]
30
+ ],
31
+ skippedNodes: [0,1,28],
32
+ repeatNodeCount: 3,
33
+ 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~",
34
+ tokenizers: [1, new lr.LocalTokenGroup("j~RQYZXz{^~^Ot~~aP!P!Qd~iOu~~", 25, 35)],
35
+ topRules: {"Expression":[0,2]},
36
+ specialized: [{term: 39, get: (value) => spec_word[value] || -1},{term: 22, get: (value) => spec_Operator[value] || -1}],
37
+ tokenPrec: 536
30
38
  });
31
39
 
40
+ var ELScalar;
41
+ (function (ELScalar) {
42
+ ELScalar["Bool"] = "bool";
43
+ ELScalar["Number"] = "number";
44
+ ELScalar["String"] = "string";
45
+ ELScalar["Null"] = "null";
46
+ ELScalar["Any"] = "any";
47
+ })(ELScalar || (ELScalar = {}));
48
+
32
49
  const createInfoElement = (html) => {
33
50
  const dom = document.createElement("div");
34
51
  dom.innerHTML = html;
@@ -65,12 +82,16 @@ const resolveIdentifier = (nodeName, identifier, config) => {
65
82
  }
66
83
  };
67
84
  function resolveTypes(state, node, config, matchExact) {
68
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
85
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l;
69
86
  let types = new Set();
70
87
  if (!node) {
71
88
  return types;
72
89
  }
73
- if (node.name === 'Call' && node.firstChild && node.lastChild) {
90
+ let type;
91
+ if (typeof (type = node.type.prop(t)) !== "undefined") {
92
+ types.add(type);
93
+ }
94
+ else if (node.name === 'Call' && node.firstChild && node.lastChild) {
74
95
  resolveTypes(state, node.firstChild, config).forEach(x => types.add(x));
75
96
  }
76
97
  else if (node.name === 'Variable') {
@@ -106,17 +127,32 @@ function resolveTypes(state, node, config, matchExact) {
106
127
  resolveTypes(state, node.firstChild.nextSibling, config).forEach(x => types.add(x));
107
128
  resolveTypes(state, node.firstChild.nextSibling.nextSibling, config).forEach(x => types.add(x));
108
129
  }
109
- else if (node.name === 'BinaryExpression' && ((_k = (_j = node.firstChild) === null || _j === void 0 ? void 0 : _j.nextSibling) === null || _k === void 0 ? void 0 : _k.name) == 'Operator' && node.lastChild) {
130
+ 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)) {
110
131
  const operator = state.sliceDoc(node.firstChild.nextSibling.from, node.firstChild.nextSibling.to);
111
- if (operator == '?:' || operator == '??') {
112
- resolveTypes(state, node.firstChild, config).forEach(x => types.add(x));
113
- }
114
132
  if (operator == '?:' || operator == '??' || operator == '?') {
115
- resolveTypes(state, node.lastChild, config).forEach(x => types.add(x));
133
+ if (operator == '?:' || operator == '??') {
134
+ resolveTypes(state, node.firstChild, config).forEach(x => types.add(x));
135
+ }
136
+ resolveTypes(state, node.firstChild.nextSibling.nextSibling, config).forEach(x => types.add(x));
137
+ }
138
+ else if (['||', '&&', '==', '!=', '===', '!==', '>=', '<=', '>', '<'].includes(operator) || keywords.find(x => x.name == operator)) {
139
+ types.add(ELScalar.Bool);
140
+ }
141
+ else if (['**', '|', '^', '&', '<<', '>>', '+', '-', '*', '/', '%'].includes(operator)) {
142
+ types.add(ELScalar.Number);
143
+ }
144
+ }
145
+ else if (node.name === 'UnaryExpression' && node.firstChild) {
146
+ const operator = state.sliceDoc(node.firstChild.from, node.firstChild.to);
147
+ if (['not', '!'].includes(operator)) {
148
+ types.add(ELScalar.Bool);
149
+ }
150
+ else if (['+', '-'].includes(operator)) {
151
+ types.add(ELScalar.Number);
116
152
  }
117
153
  }
118
154
  if (types.size === 0) {
119
- types.add('any');
155
+ types.add(ELScalar.Any);
120
156
  }
121
157
  return types;
122
158
  }
@@ -133,6 +169,7 @@ const keywords = [
133
169
  { name: 'not' },
134
170
  { name: 'or' },
135
171
  { name: 'and' },
172
+ { name: 'xor' },
136
173
  ];
137
174
 
138
175
  /**
@@ -168,7 +205,7 @@ const expressionLanguageLinterSource = (state) => {
168
205
  let i = 0;
169
206
  let n = node.node.firstChild;
170
207
  while (n) {
171
- if (++i > args.length) {
208
+ if (n.name !== 'BlockComment' && ++i > args.length) {
172
209
  diagnostics.push({ from: n.from, to: n.to, severity: 'error', message: `Unexpected argument` });
173
210
  }
174
211
  n = n.nextSibling;
@@ -200,15 +237,15 @@ const expressionLanguageLinterSource = (state) => {
200
237
  const expressionLanguageLinter = lint.linter(view => expressionLanguageLinterSource(view.state));
201
238
 
202
239
  const autocompleteFunction = (x) => {
203
- var _a, _b;
240
+ var _a, _b, _c;
204
241
  return ({
205
- label: `${x.name}(${((_a = x.args) === null || _a === void 0 ? void 0 : _a.join(',')) || ''})`,
242
+ 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(',')) || ''})`,
206
243
  apply: (view, completion, from, to) => {
207
244
  var _a;
208
245
  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) } }));
209
246
  },
210
- detail: (_b = x.returnType) === null || _b === void 0 ? void 0 : _b.join('|'),
211
- info: () => { var _a; return createInfoElement((_a = x.info) !== null && _a !== void 0 ? _a : ''); },
247
+ detail: (_c = x.returnType) === null || _c === void 0 ? void 0 : _c.join('|'),
248
+ info: x.info,
212
249
  type: "function",
213
250
  });
214
251
  };
@@ -217,7 +254,7 @@ const autocompleteIdentifier = (x) => {
217
254
  return ({
218
255
  label: x.name,
219
256
  apply: x.name,
220
- info: () => { var _a; return createInfoElement((_a = x.info) !== null && _a !== void 0 ? _a : ''); },
257
+ info: x.info,
221
258
  detail: x.detail || ((_a = x.type) === null || _a === void 0 ? void 0 : _a.join('|')),
222
259
  type: 'variable',
223
260
  });
@@ -227,7 +264,13 @@ function completeOperatorKeyword(state, config, tree, from, to, explicit) {
227
264
  return {
228
265
  from,
229
266
  to,
230
- options: (_a = keywords.map(({ name, info, detail }) => ({ label: name, apply: `${name} `, info, detail, type: "keyword" }))) !== null && _a !== void 0 ? _a : [],
267
+ options: (_a = keywords.map(({ name, info, detail }) => ({
268
+ label: name,
269
+ apply: `${name} `,
270
+ info: info,
271
+ detail,
272
+ type: "keyword"
273
+ }))) !== null && _a !== void 0 ? _a : [],
231
274
  validFor: (text) => { var _a; return (_a = keywords.some(({ name }) => explicit || name.includes(text))) !== null && _a !== void 0 ? _a : false; },
232
275
  };
233
276
  }
@@ -272,7 +315,7 @@ function expressionLanguageCompletion(context) {
272
315
  const config = getExpressionLanguageConfig(state);
273
316
  const isIdentifier = (node) => { var _a; return ['Variable', 'Function'].includes((_a = node === null || node === void 0 ? void 0 : node.name) !== null && _a !== void 0 ? _a : ''); };
274
317
  const isMember = (node) => { var _a; return ['Property', 'Method'].includes((_a = node === null || node === void 0 ? void 0 : node.name) !== null && _a !== void 0 ? _a : ''); };
275
- if (prevNode.name == 'String') {
318
+ if (prevNode.name == 'String' || prevNode.name == 'BlockComment') {
276
319
  return null;
277
320
  }
278
321
  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) || '')) {
@@ -312,7 +355,7 @@ function getCursorTooltips(state) {
312
355
  return state.selection.ranges
313
356
  .filter(range => range.empty)
314
357
  .map(range => {
315
- var _a;
358
+ var _a, _b;
316
359
  const tree = language.syntaxTree(state);
317
360
  const node = tree.resolveInner(range.from, 0);
318
361
  const args = resolveArguments(node);
@@ -324,7 +367,7 @@ function getCursorTooltips(state) {
324
367
  return null;
325
368
  }
326
369
  const n = args.childAfter(range.from - 1);
327
- const argName = (_a = fn.args) === null || _a === void 0 ? void 0 : _a[n ? getNodeOrdinal(n) : 0];
370
+ 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;
328
371
  if (n && n.from !== range.from || !argName) {
329
372
  return null;
330
373
  }
@@ -399,17 +442,29 @@ const keywordTooltip = view.hoverTooltip((view, pos, side) => {
399
442
  create: () => ({ dom: createInfoElement(info) }),
400
443
  };
401
444
  });
402
- const cursorTooltipBaseTheme = view.EditorView.baseTheme({
445
+
446
+ const baseTheme = view.EditorView.baseTheme({
403
447
  ".cm-tooltip.cm-tooltip-cursor": {
404
448
  boxShadow: 'rgba(0, 0, 0, .15) 0 1px 2px',
405
449
  border: "1px solid rgba(127, 127, 127, .2)",
406
- padding: "2px 7px",
450
+ fontSize: ".85rem",
451
+ padding: ".4rem .5rem",
407
452
  borderRadius: "4px",
408
453
  "& .cm-tooltip-arrow:before": {},
409
454
  "& .cm-tooltip-arrow:after": {
410
455
  borderTopColor: "transparent"
411
- }
412
- }
456
+ },
457
+ },
458
+ ".cm-tooltip.cm-completionInfo, .cm-diagnostic": {
459
+ boxShadow: "rgba(0, 0, 0, .15) 0 2px 5px",
460
+ fontSize: ".85rem",
461
+ padding: ".8rem !important", // Couldn't figure out other means to override https://github.com/codemirror/autocomplete/blob/6.18.1/src/theme.ts#L65
462
+ },
463
+ ".cm-completionDetail": {
464
+ float: "right",
465
+ opacity: 0.5,
466
+ fontStyle: "inherit !important",
467
+ },
413
468
  });
414
469
 
415
470
  const ELLanguage = language.LRLanguage.define({
@@ -443,6 +498,7 @@ const ELLanguage = language.LRLanguage.define({
443
498
  OperatorKeyword: highlight.tags.operatorKeyword,
444
499
  UnaryOperator: highlight.tags.operator,
445
500
  Operator: highlight.tags.operator,
501
+ BlockComment: highlight.tags.comment,
446
502
  })
447
503
  ]
448
504
  }),
@@ -457,7 +513,7 @@ function expressionlanguage(config = {}, extensions = []) {
457
513
  expressionLanguageLinter,
458
514
  keywordTooltip,
459
515
  cursorTooltipField,
460
- cursorTooltipBaseTheme,
516
+ baseTheme,
461
517
  ...extensions,
462
518
  ]);
463
519
  }
package/dist/index.d.cts CHANGED
@@ -14,10 +14,16 @@ interface ELIdentifier {
14
14
  */
15
15
  interface ELFunction {
16
16
  name: string;
17
- args: string[]; // maybe these could be ELIdentifier[] ?
17
+ args: ELParameter[];
18
18
  info?: string;
19
19
  returnType?: string[];
20
20
  }
21
+ interface ELParameter {
22
+ name: string;
23
+ type?: string[];
24
+ info?: string;
25
+ optional?: boolean;
26
+ }
21
27
  interface ELType {
22
28
  identifiers?: ELIdentifier[];
23
29
  functions?: ELFunction[];
package/dist/index.d.ts CHANGED
@@ -14,10 +14,16 @@ interface ELIdentifier {
14
14
  */
15
15
  interface ELFunction {
16
16
  name: string;
17
- args: string[]; // maybe these could be ELIdentifier[] ?
17
+ args: ELParameter[];
18
18
  info?: string;
19
19
  returnType?: string[];
20
20
  }
21
+ interface ELParameter {
22
+ name: string;
23
+ type?: string[];
24
+ info?: string;
25
+ optional?: boolean;
26
+ }
21
27
  interface ELType {
22
28
  identifiers?: ELIdentifier[];
23
29
  functions?: ELFunction[];