@valtzu/codemirror-lang-el 0.6.1 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +13 -0
- package/README.md +2 -9
- package/dist/complete.cjs +58 -15
- package/dist/complete.js +58 -15
- package/dist/index.cjs +97 -32
- package/dist/index.d.cts +7 -1
- package/dist/index.d.ts +7 -1
- package/dist/index.js +98 -33
- package/dist/linter.cjs +58 -4
- package/dist/linter.js +58 -4
- package/dist/tooltip.cjs +48 -18
- package/dist/tooltip.d.cts +4 -3
- package/dist/tooltip.d.ts +4 -3
- package/dist/tooltip.js +50 -19
- package/dist/utils.cjs +150 -0
- package/dist/utils.d.cts +53 -0
- package/dist/utils.d.ts +53 -0
- package/dist/utils.js +141 -0
- package/package.json +1 -1
package/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.
|
|
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.
|
|
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
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
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;
|
|
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
|
-
|
|
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,8 +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
|
}
|
|
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)) {
|
|
81
|
+
const operator = state.sliceDoc(node.firstChild.nextSibling.from, node.firstChild.nextSibling.to);
|
|
82
|
+
if (operator == '?:' || operator == '??' || operator == '?') {
|
|
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);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
68
104
|
if (types.size === 0) {
|
|
69
|
-
types.add(
|
|
105
|
+
types.add(ELScalar.Any);
|
|
70
106
|
}
|
|
71
107
|
return types;
|
|
72
108
|
}
|
|
@@ -83,18 +119,19 @@ const keywords = [
|
|
|
83
119
|
{ name: 'not' },
|
|
84
120
|
{ name: 'or' },
|
|
85
121
|
{ name: 'and' },
|
|
122
|
+
{ name: 'xor' },
|
|
86
123
|
];
|
|
87
124
|
|
|
88
125
|
const autocompleteFunction = (x) => {
|
|
89
|
-
var _a, _b;
|
|
126
|
+
var _a, _b, _c;
|
|
90
127
|
return ({
|
|
91
|
-
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(',')) || ''})`,
|
|
92
129
|
apply: (view, completion, from, to) => {
|
|
93
130
|
var _a;
|
|
94
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) } }));
|
|
95
132
|
},
|
|
96
|
-
detail: (
|
|
97
|
-
info:
|
|
133
|
+
detail: (_c = x.returnType) === null || _c === void 0 ? void 0 : _c.join('|'),
|
|
134
|
+
info: x.info,
|
|
98
135
|
type: "function",
|
|
99
136
|
});
|
|
100
137
|
};
|
|
@@ -103,7 +140,7 @@ const autocompleteIdentifier = (x) => {
|
|
|
103
140
|
return ({
|
|
104
141
|
label: x.name,
|
|
105
142
|
apply: x.name,
|
|
106
|
-
info:
|
|
143
|
+
info: x.info,
|
|
107
144
|
detail: x.detail || ((_a = x.type) === null || _a === void 0 ? void 0 : _a.join('|')),
|
|
108
145
|
type: 'variable',
|
|
109
146
|
});
|
|
@@ -113,7 +150,13 @@ function completeOperatorKeyword(state, config, tree, from, to, explicit) {
|
|
|
113
150
|
return {
|
|
114
151
|
from,
|
|
115
152
|
to,
|
|
116
|
-
options: (_a = keywords.map(({ name, info, detail }) => ({
|
|
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 : [],
|
|
117
160
|
validFor: (text) => { var _a; return (_a = keywords.some(({ name }) => explicit || name.includes(text))) !== null && _a !== void 0 ? _a : false; },
|
|
118
161
|
};
|
|
119
162
|
}
|
|
@@ -158,7 +201,7 @@ function expressionLanguageCompletion(context) {
|
|
|
158
201
|
const config = getExpressionLanguageConfig(state);
|
|
159
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 : ''); };
|
|
160
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 : ''); };
|
|
161
|
-
if (prevNode.name == 'String') {
|
|
204
|
+
if (prevNode.name == 'String' || prevNode.name == 'BlockComment') {
|
|
162
205
|
return null;
|
|
163
206
|
}
|
|
164
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
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
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;
|
|
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
|
-
|
|
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,8 +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
|
}
|
|
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)) {
|
|
77
|
+
const operator = state.sliceDoc(node.firstChild.nextSibling.from, node.firstChild.nextSibling.to);
|
|
78
|
+
if (operator == '?:' || operator == '??' || operator == '?') {
|
|
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);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
64
100
|
if (types.size === 0) {
|
|
65
|
-
types.add(
|
|
101
|
+
types.add(ELScalar.Any);
|
|
66
102
|
}
|
|
67
103
|
return types;
|
|
68
104
|
}
|
|
@@ -79,18 +115,19 @@ const keywords = [
|
|
|
79
115
|
{ name: 'not' },
|
|
80
116
|
{ name: 'or' },
|
|
81
117
|
{ name: 'and' },
|
|
118
|
+
{ name: 'xor' },
|
|
82
119
|
];
|
|
83
120
|
|
|
84
121
|
const autocompleteFunction = (x) => {
|
|
85
|
-
var _a, _b;
|
|
122
|
+
var _a, _b, _c;
|
|
86
123
|
return ({
|
|
87
|
-
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(',')) || ''})`,
|
|
88
125
|
apply: (view, completion, from, to) => {
|
|
89
126
|
var _a;
|
|
90
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) } }));
|
|
91
128
|
},
|
|
92
|
-
detail: (
|
|
93
|
-
info:
|
|
129
|
+
detail: (_c = x.returnType) === null || _c === void 0 ? void 0 : _c.join('|'),
|
|
130
|
+
info: x.info,
|
|
94
131
|
type: "function",
|
|
95
132
|
});
|
|
96
133
|
};
|
|
@@ -99,7 +136,7 @@ const autocompleteIdentifier = (x) => {
|
|
|
99
136
|
return ({
|
|
100
137
|
label: x.name,
|
|
101
138
|
apply: x.name,
|
|
102
|
-
info:
|
|
139
|
+
info: x.info,
|
|
103
140
|
detail: x.detail || ((_a = x.type) === null || _a === void 0 ? void 0 : _a.join('|')),
|
|
104
141
|
type: 'variable',
|
|
105
142
|
});
|
|
@@ -109,7 +146,13 @@ function completeOperatorKeyword(state, config, tree, from, to, explicit) {
|
|
|
109
146
|
return {
|
|
110
147
|
from,
|
|
111
148
|
to,
|
|
112
|
-
options: (_a = keywords.map(({ name, info, detail }) => ({
|
|
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 : [],
|
|
113
156
|
validFor: (text) => { var _a; return (_a = keywords.some(({ name }) => explicit || name.includes(text))) !== null && _a !== void 0 ? _a : false; },
|
|
114
157
|
};
|
|
115
158
|
}
|
|
@@ -154,7 +197,7 @@ function expressionLanguageCompletion(context) {
|
|
|
154
197
|
const config = getExpressionLanguageConfig(state);
|
|
155
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 : ''); };
|
|
156
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 : ''); };
|
|
157
|
-
if (prevNode.name == 'String') {
|
|
200
|
+
if (prevNode.name == 'String' || prevNode.name == 'BlockComment') {
|
|
158
201
|
return null;
|
|
159
202
|
}
|
|
160
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:
|
|
15
|
-
const spec_Operator = {__proto__:null,"!":
|
|
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: "
|
|
19
|
-
stateData: "
|
|
20
|
-
goto: "%
|
|
21
|
-
nodeNames: "⚠ Expression ObjectAccess MemberOf NullSafeMemberOf Property ArrayAccess Call Function Arguments ObjectAccess Method Arguments Number String Boolean Null Object Array Variable TernaryExpression BinaryExpression OperatorKeyword
|
|
22
|
-
maxTerm:
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
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;
|
|
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
|
-
|
|
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,8 +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
|
}
|
|
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)) {
|
|
131
|
+
const operator = state.sliceDoc(node.firstChild.nextSibling.from, node.firstChild.nextSibling.to);
|
|
132
|
+
if (operator == '?:' || operator == '??' || operator == '?') {
|
|
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);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
109
154
|
if (types.size === 0) {
|
|
110
|
-
types.add(
|
|
155
|
+
types.add(ELScalar.Any);
|
|
111
156
|
}
|
|
112
157
|
return types;
|
|
113
158
|
}
|
|
@@ -124,6 +169,7 @@ const keywords = [
|
|
|
124
169
|
{ name: 'not' },
|
|
125
170
|
{ name: 'or' },
|
|
126
171
|
{ name: 'and' },
|
|
172
|
+
{ name: 'xor' },
|
|
127
173
|
];
|
|
128
174
|
|
|
129
175
|
/**
|
|
@@ -159,7 +205,7 @@ const expressionLanguageLinterSource = (state) => {
|
|
|
159
205
|
let i = 0;
|
|
160
206
|
let n = node.node.firstChild;
|
|
161
207
|
while (n) {
|
|
162
|
-
if (++i > args.length) {
|
|
208
|
+
if (n.name !== 'BlockComment' && ++i > args.length) {
|
|
163
209
|
diagnostics.push({ from: n.from, to: n.to, severity: 'error', message: `Unexpected argument` });
|
|
164
210
|
}
|
|
165
211
|
n = n.nextSibling;
|
|
@@ -191,15 +237,15 @@ const expressionLanguageLinterSource = (state) => {
|
|
|
191
237
|
const expressionLanguageLinter = lint.linter(view => expressionLanguageLinterSource(view.state));
|
|
192
238
|
|
|
193
239
|
const autocompleteFunction = (x) => {
|
|
194
|
-
var _a, _b;
|
|
240
|
+
var _a, _b, _c;
|
|
195
241
|
return ({
|
|
196
|
-
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(',')) || ''})`,
|
|
197
243
|
apply: (view, completion, from, to) => {
|
|
198
244
|
var _a;
|
|
199
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) } }));
|
|
200
246
|
},
|
|
201
|
-
detail: (
|
|
202
|
-
info:
|
|
247
|
+
detail: (_c = x.returnType) === null || _c === void 0 ? void 0 : _c.join('|'),
|
|
248
|
+
info: x.info,
|
|
203
249
|
type: "function",
|
|
204
250
|
});
|
|
205
251
|
};
|
|
@@ -208,7 +254,7 @@ const autocompleteIdentifier = (x) => {
|
|
|
208
254
|
return ({
|
|
209
255
|
label: x.name,
|
|
210
256
|
apply: x.name,
|
|
211
|
-
info:
|
|
257
|
+
info: x.info,
|
|
212
258
|
detail: x.detail || ((_a = x.type) === null || _a === void 0 ? void 0 : _a.join('|')),
|
|
213
259
|
type: 'variable',
|
|
214
260
|
});
|
|
@@ -218,7 +264,13 @@ function completeOperatorKeyword(state, config, tree, from, to, explicit) {
|
|
|
218
264
|
return {
|
|
219
265
|
from,
|
|
220
266
|
to,
|
|
221
|
-
options: (_a = keywords.map(({ name, info, detail }) => ({
|
|
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 : [],
|
|
222
274
|
validFor: (text) => { var _a; return (_a = keywords.some(({ name }) => explicit || name.includes(text))) !== null && _a !== void 0 ? _a : false; },
|
|
223
275
|
};
|
|
224
276
|
}
|
|
@@ -263,7 +315,7 @@ function expressionLanguageCompletion(context) {
|
|
|
263
315
|
const config = getExpressionLanguageConfig(state);
|
|
264
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 : ''); };
|
|
265
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 : ''); };
|
|
266
|
-
if (prevNode.name == 'String') {
|
|
318
|
+
if (prevNode.name == 'String' || prevNode.name == 'BlockComment') {
|
|
267
319
|
return null;
|
|
268
320
|
}
|
|
269
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) || '')) {
|
|
@@ -303,7 +355,7 @@ function getCursorTooltips(state) {
|
|
|
303
355
|
return state.selection.ranges
|
|
304
356
|
.filter(range => range.empty)
|
|
305
357
|
.map(range => {
|
|
306
|
-
var _a;
|
|
358
|
+
var _a, _b;
|
|
307
359
|
const tree = language.syntaxTree(state);
|
|
308
360
|
const node = tree.resolveInner(range.from, 0);
|
|
309
361
|
const args = resolveArguments(node);
|
|
@@ -315,7 +367,7 @@ function getCursorTooltips(state) {
|
|
|
315
367
|
return null;
|
|
316
368
|
}
|
|
317
369
|
const n = args.childAfter(range.from - 1);
|
|
318
|
-
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;
|
|
319
371
|
if (n && n.from !== range.from || !argName) {
|
|
320
372
|
return null;
|
|
321
373
|
}
|
|
@@ -390,17 +442,29 @@ const keywordTooltip = view.hoverTooltip((view, pos, side) => {
|
|
|
390
442
|
create: () => ({ dom: createInfoElement(info) }),
|
|
391
443
|
};
|
|
392
444
|
});
|
|
393
|
-
|
|
445
|
+
|
|
446
|
+
const baseTheme = view.EditorView.baseTheme({
|
|
394
447
|
".cm-tooltip.cm-tooltip-cursor": {
|
|
395
448
|
boxShadow: 'rgba(0, 0, 0, .15) 0 1px 2px',
|
|
396
449
|
border: "1px solid rgba(127, 127, 127, .2)",
|
|
397
|
-
|
|
450
|
+
fontSize: ".85rem",
|
|
451
|
+
padding: ".4rem .5rem",
|
|
398
452
|
borderRadius: "4px",
|
|
399
453
|
"& .cm-tooltip-arrow:before": {},
|
|
400
454
|
"& .cm-tooltip-arrow:after": {
|
|
401
455
|
borderTopColor: "transparent"
|
|
402
|
-
}
|
|
403
|
-
}
|
|
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
|
+
},
|
|
404
468
|
});
|
|
405
469
|
|
|
406
470
|
const ELLanguage = language.LRLanguage.define({
|
|
@@ -434,6 +498,7 @@ const ELLanguage = language.LRLanguage.define({
|
|
|
434
498
|
OperatorKeyword: highlight.tags.operatorKeyword,
|
|
435
499
|
UnaryOperator: highlight.tags.operator,
|
|
436
500
|
Operator: highlight.tags.operator,
|
|
501
|
+
BlockComment: highlight.tags.comment,
|
|
437
502
|
})
|
|
438
503
|
]
|
|
439
504
|
}),
|
|
@@ -448,7 +513,7 @@ function expressionlanguage(config = {}, extensions = []) {
|
|
|
448
513
|
expressionLanguageLinter,
|
|
449
514
|
keywordTooltip,
|
|
450
515
|
cursorTooltipField,
|
|
451
|
-
|
|
516
|
+
baseTheme,
|
|
452
517
|
...extensions,
|
|
453
518
|
]);
|
|
454
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:
|
|
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:
|
|
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[];
|