@valtzu/codemirror-lang-el 0.10.0 → 1.1.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 CHANGED
@@ -1,6 +1,18 @@
1
1
  CHANGELOG
2
2
  =========
3
3
 
4
+ 1.1
5
+ ---
6
+
7
+ * Lint right-side argument type for `in` operator
8
+ * Fix `undefined` in completion keyword tooltip (#19)
9
+
10
+ 1.0
11
+ ---
12
+
13
+ * Render completion info as HTML
14
+ * Bump to stable
15
+
4
16
  0.10
5
17
  ---
6
18
 
@@ -0,0 +1,108 @@
1
+
2
+ ## Enum
3
+
4
+ - [ELScalar](#elscalar)
5
+
6
+ ### ELScalar
7
+
8
+
9
+
10
+ | Property | Type | Description |
11
+ | ---------- | ---------- | ---------- |
12
+ | `Bool` | `'bool'` | Equivalent to PHP `bool` |
13
+ | `Number` | `'number'` | Equivalent to PHP `int` or `float` |
14
+ | `String` | `'string'` | Equivalent to PHP `string` |
15
+ | `Null` | `'null'` | Equivalent to PHP `null` |
16
+ | `Any` | `'any'` | Equivalent to PHP `mixed` |
17
+
18
+
19
+ ## Interfaces
20
+
21
+ - [ExpressionLanguageConfig](#expressionlanguageconfig)
22
+ - [ELType](#eltype)
23
+ - [ELIdentifier](#elidentifier)
24
+ - [ELFunction](#elfunction)
25
+ - [ELParameter](#elparameter)
26
+ - [ELKeyword](#elkeyword)
27
+
28
+ ### ExpressionLanguageConfig
29
+
30
+ The configuration object that is passed to `expressionlanguage` function
31
+
32
+ | Property | Type | Description |
33
+ | ---------- | ---------- | ---------- |
34
+ | `types` | `{ [key: string]: ELType; } or undefined` | Type definitions used in `identifiers` and `functions` |
35
+ | `identifiers` | `ELIdentifier[] or undefined` | Top-level variables |
36
+ | `functions` | `ELFunction[] or undefined` | Top-level functions |
37
+
38
+
39
+ ### ELType
40
+
41
+
42
+
43
+ | Property | Type | Description |
44
+ | ---------- | ---------- | ---------- |
45
+ | `identifiers` | `ELIdentifier[] or undefined` | Properties of the object |
46
+ | `functions` | `ELFunction[] or undefined` | Methods of the object |
47
+ | `info` | `string or undefined` | |
48
+
49
+
50
+ ### ELIdentifier
51
+
52
+ Represents a variable or a property of an object
53
+
54
+ | Property | Type | Description |
55
+ | ---------- | ---------- | ---------- |
56
+ | `name` | `string` | |
57
+ | `detail` | `string or undefined` | If set, this is shown instead of `type` |
58
+ | `info` | `string or undefined` | Text to show in hover tooltip, autocomplete etc. |
59
+ | `type` | `string[] or undefined` | All possible types for this identifier |
60
+
61
+
62
+ ### ELFunction
63
+
64
+ Represents a function or a method of an object
65
+
66
+ | Property | Type | Description |
67
+ | ---------- | ---------- | ---------- |
68
+ | `name` | `string` | |
69
+ | `args` | `ELParameter[] or undefined` | |
70
+ | `info` | `string or undefined` | |
71
+ | `returnType` | `string[] or undefined` | |
72
+
73
+
74
+ ### ELParameter
75
+
76
+
77
+
78
+ | Property | Type | Description |
79
+ | ---------- | ---------- | ---------- |
80
+ | `name` | `string` | |
81
+ | `type` | `string[] or undefined` | |
82
+ | `info` | `string or undefined` | |
83
+ | `optional` | `boolean or undefined` | |
84
+
85
+
86
+ ### ELKeyword
87
+
88
+
89
+
90
+ | Property | Type | Description |
91
+ | ---------- | ---------- | ---------- |
92
+ | `name` | `string` | |
93
+ | `detail` | `string or undefined` | |
94
+ | `info` | `string or undefined` | |
95
+
96
+
97
+ ## Types
98
+
99
+ - [ELTypeName](#eltypename)
100
+
101
+ ### ELTypeName
102
+
103
+ One of predefined types (`ELScalar`) or a custom type from `ExpressionLanguageConfig.types`
104
+
105
+ | Type | Type |
106
+ | ---------- | ---------- |
107
+ | `ELTypeName` | `ELScalar or string` |
108
+
package/README.md CHANGED
@@ -1,7 +1,5 @@
1
1
  ## Symfony Expression Language support for CodeMirror 6
2
2
 
3
- > :warning: **This is unstable**: Expect breaking changes until v1 is out.
4
-
5
3
  ### Features
6
4
 
7
5
  #### Linting
@@ -38,6 +36,16 @@
38
36
 
39
37
  ### Installation
40
38
 
39
+ #### Web Component
40
+
41
+ If you're using Bootstrap UI, check the [Web Component](https://github.com/valtzu/symfony-expression-editor) to hide all CodeMirror stuff.
42
+
43
+ ```html
44
+ <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet">
45
+ <script type="module" src="https://esm.sh/symfony-expression-editor@0.1.0"></script>
46
+ <textarea class="form-control" is="expression-editor" rows="1">'foobar' starts with 'foo'</textarea>
47
+ ```
48
+
41
49
  #### Symfony AssetMapper
42
50
 
43
51
  ```
@@ -58,6 +66,10 @@ yarn add @valtzu/codemirror-lang-el
58
66
 
59
67
  ---
60
68
 
69
+ ### Configuration
70
+
71
+ See [CONFIGURATION.md](CONFIGURATION.md)
72
+
61
73
  ### Example
62
74
 
63
75
  [Live demo](https://jsfiddle.net/turse2xq/)
package/dist/index.cjs CHANGED
@@ -35,12 +35,20 @@ const parser = lr.LRParser.deserialize({
35
35
  tokenPrec: 532
36
36
  });
37
37
 
38
+ // generate CONFIGURATION.md from this file by running "tsdoc --src=src/types.ts --dest=CONFIGURATION.md --noemoji --types"
38
39
  exports.ELScalar = void 0;
39
40
  (function (ELScalar) {
41
+ /** Equivalent to PHP `bool` */
40
42
  ELScalar["Bool"] = "bool";
43
+ /** Equivalent to PHP `int` or `float` */
41
44
  ELScalar["Number"] = "number";
45
+ /** Equivalent to PHP `string` */
42
46
  ELScalar["String"] = "string";
47
+ /** Equivalent to PHP `null` */
43
48
  ELScalar["Null"] = "null";
49
+ /** Equivalent to PHP `array` */
50
+ ELScalar["Array"] = "array";
51
+ /** Equivalent to PHP `mixed` */
44
52
  ELScalar["Any"] = "any";
45
53
  })(exports.ELScalar || (exports.ELScalar = {}));
46
54
 
@@ -70,6 +78,14 @@ const createInfoElement = (html) => {
70
78
  dom.className = 'cm-diagnostic';
71
79
  return dom;
72
80
  };
81
+ const createCompletionInfoElement = (html) => {
82
+ if (!html) {
83
+ return undefined;
84
+ }
85
+ const dom = document.createElement("div");
86
+ dom.innerHTML = html;
87
+ return { dom };
88
+ };
73
89
  function resolveFunctionDefinition(node, state, config) {
74
90
  var _a;
75
91
  if (!node) {
@@ -192,6 +208,7 @@ const keywords = [
192
208
 
193
209
  var utils = /*#__PURE__*/Object.freeze({
194
210
  __proto__: null,
211
+ createCompletionInfoElement: createCompletionInfoElement,
195
212
  createInfoElement: createInfoElement,
196
213
  getExpressionLanguageConfig: getExpressionLanguageConfig,
197
214
  keywords: keywords,
@@ -270,6 +287,19 @@ const expressionLanguageLinterSource = (state) => {
270
287
  diagnostics.push({ from, to, severity: 'error', message: `${node.node.name} <code>${identifier}</code> not found` });
271
288
  }
272
289
  break;
290
+ case BinaryExpression:
291
+ const operatorNode = node.node.getChild(OperatorKeyword);
292
+ if (operatorNode) {
293
+ const operator = state.sliceDoc(operatorNode.from, operatorNode.to);
294
+ if (operator === 'in') {
295
+ const rightArgument = node.node.lastChild;
296
+ const types = resolveTypes(state, rightArgument, config);
297
+ if (!types.has(exports.ELScalar.Array)) {
298
+ diagnostics.push({ from: rightArgument.from, to: rightArgument.to, severity: 'error', message: `<code>${exports.ELScalar.Array}</code> expected, got <code>${[...types].join('|')}</code>` });
299
+ }
300
+ }
301
+ }
302
+ break;
273
303
  }
274
304
  if (identifier && ((_f = node.node.parent) === null || _f === void 0 ? void 0 : _f.type.isError)) {
275
305
  diagnostics.push({ from, to, severity: 'error', message: `Unexpected identifier <code>${identifier}</code>` });
@@ -301,7 +331,7 @@ const autocompleteFunction = (x) => {
301
331
  view.dispatch(Object.assign(Object.assign({}, autocomplete.insertCompletionText(view.state, `${x.name}()`, from, to)), { selection: { anchor: from + x.name.length + (((_b = (_a = x.args) === null || _a === void 0 ? void 0 : _a.length) !== null && _b !== void 0 ? _b : 0) > 0 ? 1 : 2) } }));
302
332
  },
303
333
  detail: (_c = x.returnType) === null || _c === void 0 ? void 0 : _c.join('|'),
304
- info: x.info,
334
+ info: () => createCompletionInfoElement(x.info),
305
335
  type: "function",
306
336
  });
307
337
  };
@@ -310,7 +340,7 @@ const autocompleteIdentifier = (x) => {
310
340
  return ({
311
341
  label: x.name,
312
342
  apply: x.name,
313
- info: x.info,
343
+ info: () => createCompletionInfoElement(x.info),
314
344
  detail: x.detail || ((_a = x.type) === null || _a === void 0 ? void 0 : _a.join('|')),
315
345
  type: 'variable',
316
346
  });
@@ -323,7 +353,7 @@ function completeOperatorKeyword(state, config, tree, from, to, explicit) {
323
353
  options: (_a = keywords.map(({ name, info, detail }) => ({
324
354
  label: name,
325
355
  apply: `${name} `,
326
- info: info,
356
+ info: () => createCompletionInfoElement(info),
327
357
  detail,
328
358
  type: "keyword"
329
359
  }))) !== null && _a !== void 0 ? _a : [],
@@ -536,6 +566,9 @@ const baseTheme = view.EditorView.baseTheme({
536
566
  fontSize: ".8em",
537
567
  fontStyle: "monospace",
538
568
  backgroundColor: "rgba(127, 127, 127, .3)",
569
+ display: 'inline-block',
570
+ padding: '2px 4px',
571
+ borderRadius: '3px',
539
572
  },
540
573
  });
541
574
 
package/dist/index.d.cts CHANGED
@@ -5,14 +5,37 @@ import { CompletionContext, CompletionResult } from '@codemirror/autocomplete';
5
5
  import { SyntaxNode } from '@lezer/common';
6
6
  import { Tooltip } from '@codemirror/view';
7
7
 
8
+ /**
9
+ * The configuration object that is passed to `expressionlanguage` function
10
+ */
11
+ interface ExpressionLanguageConfig {
12
+ /** Type definitions used in `identifiers` & `functions` */
13
+ types?: {
14
+ [key: string]: ELType;
15
+ };
16
+ /** Top-level variables */
17
+ identifiers?: ELIdentifier[];
18
+ /** Top-level functions */
19
+ functions?: ELFunction[];
20
+ }
21
+ interface ELType {
22
+ /** Properties of the object */
23
+ identifiers?: ELIdentifier[];
24
+ /** Methods of the object */
25
+ functions?: ELFunction[];
26
+ info?: string;
27
+ }
8
28
  /**
9
29
  * Represents a variable or a property of an object
10
30
  */
11
31
  interface ELIdentifier {
12
32
  name: string;
33
+ /** If set, this is shown instead of `type` */
13
34
  detail?: string;
35
+ /** Text to show in hover tooltip, autocomplete etc. */
14
36
  info?: string;
15
- type?: string[];
37
+ /** All possible types for this identifier */
38
+ type?: ELTypeName[];
16
39
  }
17
40
  /**
18
41
  * Represents a function or a method of an object
@@ -21,51 +44,54 @@ interface ELFunction {
21
44
  name: string;
22
45
  args?: ELParameter[];
23
46
  info?: string;
24
- returnType?: string[];
47
+ returnType?: ELTypeName[];
25
48
  }
26
49
  interface ELParameter {
27
50
  name: string;
28
- type?: string[];
51
+ type?: ELTypeName[];
29
52
  info?: string;
30
53
  optional?: boolean;
31
54
  }
32
- interface ELType {
33
- identifiers?: ELIdentifier[];
34
- functions?: ELFunction[];
35
- info?: string;
36
- }
37
- interface ExpressionLanguageConfig {
38
- types?: {
39
- [key: string]: ELType;
40
- };
41
- identifiers?: ELIdentifier[];
42
- functions?: ELFunction[];
43
- }
44
55
  interface ELKeyword {
45
56
  name: string;
46
57
  detail?: string;
47
58
  info?: string;
48
59
  }
49
60
  declare enum ELScalar {
61
+ /** Equivalent to PHP `bool` */
50
62
  Bool = "bool",
63
+ /** Equivalent to PHP `int` or `float` */
51
64
  Number = "number",
65
+ /** Equivalent to PHP `string` */
52
66
  String = "string",
67
+ /** Equivalent to PHP `null` */
53
68
  Null = "null",
69
+ /** Equivalent to PHP `array` */
70
+ Array = "array",
71
+ /** Equivalent to PHP `mixed` */
54
72
  Any = "any"
55
73
  }
74
+ /**
75
+ * One of predefined types (`ELScalar`) or a custom type from `ExpressionLanguageConfig.types`
76
+ */
77
+ type ELTypeName = ELScalar | string;
56
78
 
57
79
  declare function expressionLanguageCompletion(context: CompletionContext): CompletionResult | null;
58
80
 
59
81
  declare const complete_d_expressionLanguageCompletion: typeof expressionLanguageCompletion;
60
82
  declare namespace complete_d {
61
- export { complete_d_expressionLanguageCompletion as expressionLanguageCompletion };
83
+ export {
84
+ complete_d_expressionLanguageCompletion as expressionLanguageCompletion,
85
+ };
62
86
  }
63
87
 
64
88
  declare const expressionLanguageLinter: _codemirror_state.Extension;
65
89
 
66
90
  declare const linter_d_expressionLanguageLinter: typeof expressionLanguageLinter;
67
91
  declare namespace linter_d {
68
- export { linter_d_expressionLanguageLinter as expressionLanguageLinter };
92
+ export {
93
+ linter_d_expressionLanguageLinter as expressionLanguageLinter,
94
+ };
69
95
  }
70
96
 
71
97
  declare const Function: number;
@@ -74,6 +100,9 @@ declare const Property: number;
74
100
  declare const Variable: number;
75
101
 
76
102
  declare const createInfoElement: (html: string) => HTMLDivElement;
103
+ declare const createCompletionInfoElement: (html: string) => {
104
+ dom: HTMLDivElement;
105
+ } | undefined;
77
106
  declare function resolveFunctionDefinition(node: SyntaxNode | null, state: EditorState, config: ExpressionLanguageConfig): ELFunction | undefined;
78
107
  declare const resolveIdentifier: (nodeTypeId: typeof Method | typeof Property | typeof Function | typeof Variable, identifier?: string, config?: {
79
108
  identifiers?: ELIdentifier[];
@@ -83,6 +112,7 @@ declare function resolveTypes(state: EditorState, node: SyntaxNode | undefined |
83
112
  declare function getExpressionLanguageConfig(state: EditorState): ExpressionLanguageConfig;
84
113
  declare const keywords: ELKeyword[];
85
114
 
115
+ declare const utils_d_createCompletionInfoElement: typeof createCompletionInfoElement;
86
116
  declare const utils_d_createInfoElement: typeof createInfoElement;
87
117
  declare const utils_d_getExpressionLanguageConfig: typeof getExpressionLanguageConfig;
88
118
  declare const utils_d_keywords: typeof keywords;
@@ -90,7 +120,15 @@ declare const utils_d_resolveFunctionDefinition: typeof resolveFunctionDefinitio
90
120
  declare const utils_d_resolveIdentifier: typeof resolveIdentifier;
91
121
  declare const utils_d_resolveTypes: typeof resolveTypes;
92
122
  declare namespace utils_d {
93
- export { utils_d_createInfoElement as createInfoElement, utils_d_getExpressionLanguageConfig as getExpressionLanguageConfig, utils_d_keywords as keywords, utils_d_resolveFunctionDefinition as resolveFunctionDefinition, utils_d_resolveIdentifier as resolveIdentifier, utils_d_resolveTypes as resolveTypes };
123
+ export {
124
+ utils_d_createCompletionInfoElement as createCompletionInfoElement,
125
+ utils_d_createInfoElement as createInfoElement,
126
+ utils_d_getExpressionLanguageConfig as getExpressionLanguageConfig,
127
+ utils_d_keywords as keywords,
128
+ utils_d_resolveFunctionDefinition as resolveFunctionDefinition,
129
+ utils_d_resolveIdentifier as resolveIdentifier,
130
+ utils_d_resolveTypes as resolveTypes,
131
+ };
94
132
  }
95
133
 
96
134
  declare const cursorTooltipField: StateField<readonly Tooltip[]>;
@@ -101,10 +139,14 @@ declare const keywordTooltip: _codemirror_state.Extension & {
101
139
  declare const tooltip_d_cursorTooltipField: typeof cursorTooltipField;
102
140
  declare const tooltip_d_keywordTooltip: typeof keywordTooltip;
103
141
  declare namespace tooltip_d {
104
- export { tooltip_d_cursorTooltipField as cursorTooltipField, tooltip_d_keywordTooltip as keywordTooltip };
142
+ export {
143
+ tooltip_d_cursorTooltipField as cursorTooltipField,
144
+ tooltip_d_keywordTooltip as keywordTooltip,
145
+ };
105
146
  }
106
147
 
107
148
  declare const ELLanguage: LRLanguage;
108
149
  declare function expressionlanguage(config?: ExpressionLanguageConfig, extensions?: Extension[]): LanguageSupport;
109
150
 
110
- export { type ELFunction, type ELIdentifier, type ELKeyword, ELLanguage, type ELParameter, ELScalar, type ELType, type ExpressionLanguageConfig, complete_d as _complete, linter_d as _linter, tooltip_d as _tooltip, utils_d as _utils, expressionlanguage };
151
+ export { ELLanguage, ELScalar, complete_d as _complete, linter_d as _linter, tooltip_d as _tooltip, utils_d as _utils, expressionlanguage };
152
+ export type { ELFunction, ELIdentifier, ELKeyword, ELParameter, ELType, ELTypeName, ExpressionLanguageConfig };
package/dist/index.d.ts CHANGED
@@ -5,14 +5,37 @@ import { CompletionContext, CompletionResult } from '@codemirror/autocomplete';
5
5
  import { SyntaxNode } from '@lezer/common';
6
6
  import { Tooltip } from '@codemirror/view';
7
7
 
8
+ /**
9
+ * The configuration object that is passed to `expressionlanguage` function
10
+ */
11
+ interface ExpressionLanguageConfig {
12
+ /** Type definitions used in `identifiers` & `functions` */
13
+ types?: {
14
+ [key: string]: ELType;
15
+ };
16
+ /** Top-level variables */
17
+ identifiers?: ELIdentifier[];
18
+ /** Top-level functions */
19
+ functions?: ELFunction[];
20
+ }
21
+ interface ELType {
22
+ /** Properties of the object */
23
+ identifiers?: ELIdentifier[];
24
+ /** Methods of the object */
25
+ functions?: ELFunction[];
26
+ info?: string;
27
+ }
8
28
  /**
9
29
  * Represents a variable or a property of an object
10
30
  */
11
31
  interface ELIdentifier {
12
32
  name: string;
33
+ /** If set, this is shown instead of `type` */
13
34
  detail?: string;
35
+ /** Text to show in hover tooltip, autocomplete etc. */
14
36
  info?: string;
15
- type?: string[];
37
+ /** All possible types for this identifier */
38
+ type?: ELTypeName[];
16
39
  }
17
40
  /**
18
41
  * Represents a function or a method of an object
@@ -21,51 +44,54 @@ interface ELFunction {
21
44
  name: string;
22
45
  args?: ELParameter[];
23
46
  info?: string;
24
- returnType?: string[];
47
+ returnType?: ELTypeName[];
25
48
  }
26
49
  interface ELParameter {
27
50
  name: string;
28
- type?: string[];
51
+ type?: ELTypeName[];
29
52
  info?: string;
30
53
  optional?: boolean;
31
54
  }
32
- interface ELType {
33
- identifiers?: ELIdentifier[];
34
- functions?: ELFunction[];
35
- info?: string;
36
- }
37
- interface ExpressionLanguageConfig {
38
- types?: {
39
- [key: string]: ELType;
40
- };
41
- identifiers?: ELIdentifier[];
42
- functions?: ELFunction[];
43
- }
44
55
  interface ELKeyword {
45
56
  name: string;
46
57
  detail?: string;
47
58
  info?: string;
48
59
  }
49
60
  declare enum ELScalar {
61
+ /** Equivalent to PHP `bool` */
50
62
  Bool = "bool",
63
+ /** Equivalent to PHP `int` or `float` */
51
64
  Number = "number",
65
+ /** Equivalent to PHP `string` */
52
66
  String = "string",
67
+ /** Equivalent to PHP `null` */
53
68
  Null = "null",
69
+ /** Equivalent to PHP `array` */
70
+ Array = "array",
71
+ /** Equivalent to PHP `mixed` */
54
72
  Any = "any"
55
73
  }
74
+ /**
75
+ * One of predefined types (`ELScalar`) or a custom type from `ExpressionLanguageConfig.types`
76
+ */
77
+ type ELTypeName = ELScalar | string;
56
78
 
57
79
  declare function expressionLanguageCompletion(context: CompletionContext): CompletionResult | null;
58
80
 
59
81
  declare const complete_d_expressionLanguageCompletion: typeof expressionLanguageCompletion;
60
82
  declare namespace complete_d {
61
- export { complete_d_expressionLanguageCompletion as expressionLanguageCompletion };
83
+ export {
84
+ complete_d_expressionLanguageCompletion as expressionLanguageCompletion,
85
+ };
62
86
  }
63
87
 
64
88
  declare const expressionLanguageLinter: _codemirror_state.Extension;
65
89
 
66
90
  declare const linter_d_expressionLanguageLinter: typeof expressionLanguageLinter;
67
91
  declare namespace linter_d {
68
- export { linter_d_expressionLanguageLinter as expressionLanguageLinter };
92
+ export {
93
+ linter_d_expressionLanguageLinter as expressionLanguageLinter,
94
+ };
69
95
  }
70
96
 
71
97
  declare const Function: number;
@@ -74,6 +100,9 @@ declare const Property: number;
74
100
  declare const Variable: number;
75
101
 
76
102
  declare const createInfoElement: (html: string) => HTMLDivElement;
103
+ declare const createCompletionInfoElement: (html: string) => {
104
+ dom: HTMLDivElement;
105
+ } | undefined;
77
106
  declare function resolveFunctionDefinition(node: SyntaxNode | null, state: EditorState, config: ExpressionLanguageConfig): ELFunction | undefined;
78
107
  declare const resolveIdentifier: (nodeTypeId: typeof Method | typeof Property | typeof Function | typeof Variable, identifier?: string, config?: {
79
108
  identifiers?: ELIdentifier[];
@@ -83,6 +112,7 @@ declare function resolveTypes(state: EditorState, node: SyntaxNode | undefined |
83
112
  declare function getExpressionLanguageConfig(state: EditorState): ExpressionLanguageConfig;
84
113
  declare const keywords: ELKeyword[];
85
114
 
115
+ declare const utils_d_createCompletionInfoElement: typeof createCompletionInfoElement;
86
116
  declare const utils_d_createInfoElement: typeof createInfoElement;
87
117
  declare const utils_d_getExpressionLanguageConfig: typeof getExpressionLanguageConfig;
88
118
  declare const utils_d_keywords: typeof keywords;
@@ -90,7 +120,15 @@ declare const utils_d_resolveFunctionDefinition: typeof resolveFunctionDefinitio
90
120
  declare const utils_d_resolveIdentifier: typeof resolveIdentifier;
91
121
  declare const utils_d_resolveTypes: typeof resolveTypes;
92
122
  declare namespace utils_d {
93
- export { utils_d_createInfoElement as createInfoElement, utils_d_getExpressionLanguageConfig as getExpressionLanguageConfig, utils_d_keywords as keywords, utils_d_resolveFunctionDefinition as resolveFunctionDefinition, utils_d_resolveIdentifier as resolveIdentifier, utils_d_resolveTypes as resolveTypes };
123
+ export {
124
+ utils_d_createCompletionInfoElement as createCompletionInfoElement,
125
+ utils_d_createInfoElement as createInfoElement,
126
+ utils_d_getExpressionLanguageConfig as getExpressionLanguageConfig,
127
+ utils_d_keywords as keywords,
128
+ utils_d_resolveFunctionDefinition as resolveFunctionDefinition,
129
+ utils_d_resolveIdentifier as resolveIdentifier,
130
+ utils_d_resolveTypes as resolveTypes,
131
+ };
94
132
  }
95
133
 
96
134
  declare const cursorTooltipField: StateField<readonly Tooltip[]>;
@@ -101,10 +139,14 @@ declare const keywordTooltip: _codemirror_state.Extension & {
101
139
  declare const tooltip_d_cursorTooltipField: typeof cursorTooltipField;
102
140
  declare const tooltip_d_keywordTooltip: typeof keywordTooltip;
103
141
  declare namespace tooltip_d {
104
- export { tooltip_d_cursorTooltipField as cursorTooltipField, tooltip_d_keywordTooltip as keywordTooltip };
142
+ export {
143
+ tooltip_d_cursorTooltipField as cursorTooltipField,
144
+ tooltip_d_keywordTooltip as keywordTooltip,
145
+ };
105
146
  }
106
147
 
107
148
  declare const ELLanguage: LRLanguage;
108
149
  declare function expressionlanguage(config?: ExpressionLanguageConfig, extensions?: Extension[]): LanguageSupport;
109
150
 
110
- export { type ELFunction, type ELIdentifier, type ELKeyword, ELLanguage, type ELParameter, ELScalar, type ELType, type ExpressionLanguageConfig, complete_d as _complete, linter_d as _linter, tooltip_d as _tooltip, utils_d as _utils, expressionlanguage };
151
+ export { ELLanguage, ELScalar, complete_d as _complete, linter_d as _linter, tooltip_d as _tooltip, utils_d as _utils, expressionlanguage };
152
+ export type { ELFunction, ELIdentifier, ELKeyword, ELParameter, ELType, ELTypeName, ExpressionLanguageConfig };
package/dist/index.js CHANGED
@@ -33,11 +33,19 @@ const parser = /*@__PURE__*/LRParser.deserialize({
33
33
  tokenPrec: 532
34
34
  });
35
35
 
36
+ // generate CONFIGURATION.md from this file by running "tsdoc --src=src/types.ts --dest=CONFIGURATION.md --noemoji --types"
36
37
  var ELScalar = /*@__PURE__*/(function (ELScalar) {
38
+ /** Equivalent to PHP `bool` */
37
39
  ELScalar["Bool"] = "bool";
40
+ /** Equivalent to PHP `int` or `float` */
38
41
  ELScalar["Number"] = "number";
42
+ /** Equivalent to PHP `string` */
39
43
  ELScalar["String"] = "string";
44
+ /** Equivalent to PHP `null` */
40
45
  ELScalar["Null"] = "null";
46
+ /** Equivalent to PHP `array` */
47
+ ELScalar["Array"] = "array";
48
+ /** Equivalent to PHP `mixed` */
41
49
  ELScalar["Any"] = "any";
42
50
  return ELScalar})(ELScalar || (ELScalar = {}));
43
51
 
@@ -67,6 +75,14 @@ const createInfoElement = (html) => {
67
75
  dom.className = 'cm-diagnostic';
68
76
  return dom;
69
77
  };
78
+ const createCompletionInfoElement = (html) => {
79
+ if (!html) {
80
+ return undefined;
81
+ }
82
+ const dom = document.createElement("div");
83
+ dom.innerHTML = html;
84
+ return { dom };
85
+ };
70
86
  function resolveFunctionDefinition(node, state, config) {
71
87
  var _a;
72
88
  if (!node) {
@@ -189,6 +205,7 @@ const keywords = [
189
205
 
190
206
  var utils = /*#__PURE__*//*@__PURE__*/Object.freeze({
191
207
  __proto__: null,
208
+ createCompletionInfoElement: createCompletionInfoElement,
192
209
  createInfoElement: createInfoElement,
193
210
  getExpressionLanguageConfig: getExpressionLanguageConfig,
194
211
  keywords: keywords,
@@ -267,6 +284,19 @@ const expressionLanguageLinterSource = (state) => {
267
284
  diagnostics.push({ from, to, severity: 'error', message: `${node.node.name} <code>${identifier}</code> not found` });
268
285
  }
269
286
  break;
287
+ case BinaryExpression:
288
+ const operatorNode = node.node.getChild(OperatorKeyword);
289
+ if (operatorNode) {
290
+ const operator = state.sliceDoc(operatorNode.from, operatorNode.to);
291
+ if (operator === 'in') {
292
+ const rightArgument = node.node.lastChild;
293
+ const types = resolveTypes(state, rightArgument, config);
294
+ if (!types.has(ELScalar.Array)) {
295
+ diagnostics.push({ from: rightArgument.from, to: rightArgument.to, severity: 'error', message: `<code>${ELScalar.Array}</code> expected, got <code>${[...types].join('|')}</code>` });
296
+ }
297
+ }
298
+ }
299
+ break;
270
300
  }
271
301
  if (identifier && ((_f = node.node.parent) === null || _f === void 0 ? void 0 : _f.type.isError)) {
272
302
  diagnostics.push({ from, to, severity: 'error', message: `Unexpected identifier <code>${identifier}</code>` });
@@ -298,7 +328,7 @@ const autocompleteFunction = (x) => {
298
328
  view.dispatch(Object.assign(Object.assign({}, insertCompletionText(view.state, `${x.name}()`, from, to)), { selection: { anchor: from + x.name.length + (((_b = (_a = x.args) === null || _a === void 0 ? void 0 : _a.length) !== null && _b !== void 0 ? _b : 0) > 0 ? 1 : 2) } }));
299
329
  },
300
330
  detail: (_c = x.returnType) === null || _c === void 0 ? void 0 : _c.join('|'),
301
- info: x.info,
331
+ info: () => createCompletionInfoElement(x.info),
302
332
  type: "function",
303
333
  });
304
334
  };
@@ -307,7 +337,7 @@ const autocompleteIdentifier = (x) => {
307
337
  return ({
308
338
  label: x.name,
309
339
  apply: x.name,
310
- info: x.info,
340
+ info: () => createCompletionInfoElement(x.info),
311
341
  detail: x.detail || ((_a = x.type) === null || _a === void 0 ? void 0 : _a.join('|')),
312
342
  type: 'variable',
313
343
  });
@@ -320,7 +350,7 @@ function completeOperatorKeyword(state, config, tree, from, to, explicit) {
320
350
  options: (_a = keywords.map(({ name, info, detail }) => ({
321
351
  label: name,
322
352
  apply: `${name} `,
323
- info: info,
353
+ info: () => createCompletionInfoElement(info),
324
354
  detail,
325
355
  type: "keyword"
326
356
  }))) !== null && _a !== void 0 ? _a : [],
@@ -533,6 +563,9 @@ const baseTheme = /*@__PURE__*/EditorView.baseTheme({
533
563
  fontSize: ".8em",
534
564
  fontStyle: "monospace",
535
565
  backgroundColor: "rgba(127, 127, 127, .3)",
566
+ display: 'inline-block',
567
+ padding: '2px 4px',
568
+ borderRadius: '3px',
536
569
  },
537
570
  });
538
571
 
package/package.json CHANGED
@@ -27,7 +27,8 @@
27
27
  "devDependencies": {
28
28
  "@codemirror/buildhelper": "^1.0.0",
29
29
  "@types/mocha": "^10.0.10",
30
- "@types/node": "^22.10.5"
30
+ "@types/node": "^22.10.5",
31
+ "tsdoc-markdown": "^1.1.1"
31
32
  },
32
33
  "license": "MIT",
33
34
  "repository": {
@@ -38,5 +39,5 @@
38
39
  "access": "public",
39
40
  "registry": "https://registry.npmjs.org/"
40
41
  },
41
- "version": "0.10.0"
42
+ "version": "1.1.0"
42
43
  }