@likec4/language-server 1.19.1 → 1.20.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/contrib/likec4.tmLanguage.json +1 -1
- package/dist/generated/ast.d.ts +55 -14
- package/dist/generated/ast.js +72 -4
- package/dist/generated/grammar.js +1 -1
- package/dist/like-c4.langium +13 -6
- package/dist/lsp/SemanticTokenProvider.d.ts +1 -1
- package/dist/lsp/SemanticTokenProvider.js +7 -0
- package/dist/model/model-parser-where.js +12 -6
- package/dist/model/model-parser.d.ts +5 -0
- package/dist/model/parser/DeploymentModelParser.d.ts +1 -0
- package/dist/model/parser/DeploymentViewParser.d.ts +2 -1
- package/dist/model/parser/DeploymentViewParser.js +3 -0
- package/dist/model/parser/FqnRefParser.d.ts +1 -0
- package/dist/model/parser/FqnRefParser.js +13 -0
- package/dist/model/parser/GlobalsParser.d.ts +1 -0
- package/dist/model/parser/ViewsParser.d.ts +1 -0
- package/dist/validation/index.d.ts +1 -1
- package/package.json +11 -11
- package/src/generated/ast.ts +134 -17
- package/src/generated/grammar.ts +1 -1
- package/src/like-c4.langium +13 -6
- package/src/lsp/SemanticTokenProvider.ts +51 -44
- package/src/model/model-parser-where.ts +22 -14
- package/src/model/parser/DeploymentViewParser.ts +10 -7
- package/src/model/parser/FqnRefParser.ts +14 -0
package/src/like-c4.langium
CHANGED
|
@@ -413,11 +413,13 @@ WhereRelationNegation:
|
|
|
413
413
|
|
|
414
414
|
WhereRelation:
|
|
415
415
|
{infer WhereRelationTag} 'tag' EqOperator value=[Tag:TagId]? |
|
|
416
|
-
{infer WhereRelationKind} 'kind' EqOperator value=[RelationshipKind:Id]?
|
|
416
|
+
{infer WhereRelationKind} 'kind' EqOperator value=[RelationshipKind:Id]? |
|
|
417
|
+
{infer WhereRelationParticipantTag} participant=Participant StickyDot 'tag' EqOperator value=[Tag:TagId]? |
|
|
418
|
+
{infer WhereRelationParticipantKind} participant=Participant StickyDot 'kind' EqOperator value=[DeploymentNodeOrElementKind:Id]?
|
|
417
419
|
;
|
|
418
|
-
|
|
419
|
-
type WhereTagEqual = WhereElementTag | WhereRelationTag;
|
|
420
|
-
type WhereKindEqual = WhereElementKind | WhereRelationKind;
|
|
420
|
+
type DeploymentNodeOrElementKind = ElementKind | DeploymentNodeKind
|
|
421
|
+
type WhereTagEqual = WhereElementTag | WhereRelationTag | WhereRelationParticipantTag;
|
|
422
|
+
type WhereKindEqual = WhereElementKind | WhereRelationKind | WhereRelationParticipantKind;
|
|
421
423
|
|
|
422
424
|
type WhereExpression = WhereElementExpression | WhereRelationExpression;
|
|
423
425
|
|
|
@@ -620,10 +622,13 @@ DeploymentViewRulePredicateExpression:
|
|
|
620
622
|
;
|
|
621
623
|
|
|
622
624
|
ExpressionV2:
|
|
623
|
-
|
|
625
|
+
RelationPredicateOrWhereV2 |
|
|
624
626
|
FqnExpr
|
|
625
627
|
;
|
|
626
628
|
|
|
629
|
+
RelationPredicateOrWhereV2:
|
|
630
|
+
RelationExpr ({infer RelationPredicateWhereV2.subject=current} 'where' where=WhereRelationExpression?)?
|
|
631
|
+
;
|
|
627
632
|
|
|
628
633
|
FqnExpr:
|
|
629
634
|
{infer WildcardExpression} isWildcard?='*' |
|
|
@@ -766,6 +771,8 @@ ThemeColor returns string:
|
|
|
766
771
|
'primary' | 'secondary' | 'muted' | 'slate' | 'blue' | 'indigo' | 'sky' | 'red' | 'gray' | 'green' | 'amber';
|
|
767
772
|
ElementShape returns string:
|
|
768
773
|
'rectangle' | 'person' | 'browser' | 'mobile' | 'cylinder' | 'storage' | 'queue';
|
|
774
|
+
Participant returns string:
|
|
775
|
+
'source' | 'target';
|
|
769
776
|
|
|
770
777
|
CustomColorValue returns string:
|
|
771
778
|
Hash (Id | Hex | Number);
|
|
@@ -786,7 +793,7 @@ CustomColorId returns string:
|
|
|
786
793
|
IdTerminal | ElementShape | ArrowType | LineOptions | 'element' | 'model';
|
|
787
794
|
|
|
788
795
|
Id returns string:
|
|
789
|
-
IdTerminal | ElementShape | ThemeColor | ArrowType | LineOptions | 'element' | 'model' | 'group' | 'node' | 'deployment' | 'instance';
|
|
796
|
+
IdTerminal | ElementShape | ThemeColor | ArrowType | LineOptions | Participant | 'element' | 'model' | 'group' | 'node' | 'deployment' | 'instance';
|
|
790
797
|
|
|
791
798
|
fragment EqOperator:
|
|
792
799
|
(
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { AstNode } from 'langium'
|
|
2
|
-
import {
|
|
2
|
+
import { type SemanticTokenAcceptor, AbstractSemanticTokenProvider } from 'langium/lsp'
|
|
3
3
|
import { isTruthy } from 'remeda'
|
|
4
4
|
import { SemanticTokenModifiers, SemanticTokenTypes } from 'vscode-languageserver-types'
|
|
5
5
|
import { ast } from '../ast'
|
|
@@ -8,7 +8,7 @@ export class LikeC4SemanticTokenProvider extends AbstractSemanticTokenProvider {
|
|
|
8
8
|
// eslint-disable-next-line @typescript-eslint/no-invalid-void-type
|
|
9
9
|
protected override highlightElement(
|
|
10
10
|
node: AstNode,
|
|
11
|
-
acceptor: SemanticTokenAcceptor
|
|
11
|
+
acceptor: SemanticTokenAcceptor,
|
|
12
12
|
): void | undefined | 'prune' {
|
|
13
13
|
if (ast.isElement(node) || ast.isDeploymentNode(node)) {
|
|
14
14
|
return this.highlightNameAndKind(node, acceptor)
|
|
@@ -21,8 +21,8 @@ export class LikeC4SemanticTokenProvider extends AbstractSemanticTokenProvider {
|
|
|
21
21
|
type: SemanticTokenTypes.variable,
|
|
22
22
|
modifier: [
|
|
23
23
|
SemanticTokenModifiers.definition,
|
|
24
|
-
SemanticTokenModifiers.readonly
|
|
25
|
-
]
|
|
24
|
+
SemanticTokenModifiers.readonly,
|
|
25
|
+
],
|
|
26
26
|
})
|
|
27
27
|
}
|
|
28
28
|
return
|
|
@@ -34,7 +34,7 @@ export class LikeC4SemanticTokenProvider extends AbstractSemanticTokenProvider {
|
|
|
34
34
|
return acceptor({
|
|
35
35
|
node,
|
|
36
36
|
property: 'name',
|
|
37
|
-
type: SemanticTokenTypes.function
|
|
37
|
+
type: SemanticTokenTypes.function,
|
|
38
38
|
})
|
|
39
39
|
}
|
|
40
40
|
if (ast.isLibIcon(node)) {
|
|
@@ -42,7 +42,7 @@ export class LikeC4SemanticTokenProvider extends AbstractSemanticTokenProvider {
|
|
|
42
42
|
node,
|
|
43
43
|
property: 'name',
|
|
44
44
|
type: SemanticTokenTypes.type,
|
|
45
|
-
modifier: [SemanticTokenModifiers.definition]
|
|
45
|
+
modifier: [SemanticTokenModifiers.definition],
|
|
46
46
|
})
|
|
47
47
|
return 'prune'
|
|
48
48
|
}
|
|
@@ -51,7 +51,7 @@ export class LikeC4SemanticTokenProvider extends AbstractSemanticTokenProvider {
|
|
|
51
51
|
acceptor({
|
|
52
52
|
node,
|
|
53
53
|
property: 'kind',
|
|
54
|
-
type: SemanticTokenTypes.function
|
|
54
|
+
type: SemanticTokenTypes.function,
|
|
55
55
|
})
|
|
56
56
|
return
|
|
57
57
|
}
|
|
@@ -59,14 +59,14 @@ export class LikeC4SemanticTokenProvider extends AbstractSemanticTokenProvider {
|
|
|
59
59
|
acceptor({
|
|
60
60
|
node,
|
|
61
61
|
property: 'kind',
|
|
62
|
-
type: SemanticTokenTypes.function
|
|
62
|
+
type: SemanticTokenTypes.function,
|
|
63
63
|
})
|
|
64
64
|
}
|
|
65
65
|
if (ast.isNavigateToProperty(node) || ast.isRelationNavigateToProperty(node)) {
|
|
66
66
|
acceptor({
|
|
67
67
|
node,
|
|
68
68
|
property: 'key',
|
|
69
|
-
type: SemanticTokenTypes.property
|
|
69
|
+
type: SemanticTokenTypes.property,
|
|
70
70
|
})
|
|
71
71
|
acceptor({
|
|
72
72
|
node,
|
|
@@ -74,8 +74,8 @@ export class LikeC4SemanticTokenProvider extends AbstractSemanticTokenProvider {
|
|
|
74
74
|
type: SemanticTokenTypes.variable,
|
|
75
75
|
modifier: [
|
|
76
76
|
SemanticTokenModifiers.definition,
|
|
77
|
-
SemanticTokenModifiers.readonly
|
|
78
|
-
]
|
|
77
|
+
SemanticTokenModifiers.readonly,
|
|
78
|
+
],
|
|
79
79
|
})
|
|
80
80
|
return 'prune'
|
|
81
81
|
}
|
|
@@ -85,8 +85,8 @@ export class LikeC4SemanticTokenProvider extends AbstractSemanticTokenProvider {
|
|
|
85
85
|
type: SemanticTokenTypes.variable,
|
|
86
86
|
modifier: [
|
|
87
87
|
SemanticTokenModifiers.definition,
|
|
88
|
-
SemanticTokenModifiers.readonly
|
|
89
|
-
]
|
|
88
|
+
SemanticTokenModifiers.readonly,
|
|
89
|
+
],
|
|
90
90
|
})
|
|
91
91
|
return 'prune'
|
|
92
92
|
}
|
|
@@ -98,8 +98,8 @@ export class LikeC4SemanticTokenProvider extends AbstractSemanticTokenProvider {
|
|
|
98
98
|
type: SemanticTokenTypes.variable,
|
|
99
99
|
modifier: [
|
|
100
100
|
SemanticTokenModifiers.definition,
|
|
101
|
-
SemanticTokenModifiers.readonly
|
|
102
|
-
]
|
|
101
|
+
SemanticTokenModifiers.readonly,
|
|
102
|
+
],
|
|
103
103
|
})
|
|
104
104
|
}
|
|
105
105
|
return
|
|
@@ -108,7 +108,7 @@ export class LikeC4SemanticTokenProvider extends AbstractSemanticTokenProvider {
|
|
|
108
108
|
acceptor({
|
|
109
109
|
node,
|
|
110
110
|
property: 'value',
|
|
111
|
-
type: SemanticTokenTypes.function
|
|
111
|
+
type: SemanticTokenTypes.function,
|
|
112
112
|
})
|
|
113
113
|
return
|
|
114
114
|
}
|
|
@@ -119,17 +119,24 @@ export class LikeC4SemanticTokenProvider extends AbstractSemanticTokenProvider {
|
|
|
119
119
|
type: SemanticTokenTypes.type,
|
|
120
120
|
modifier: [
|
|
121
121
|
SemanticTokenModifiers.definition,
|
|
122
|
-
SemanticTokenModifiers.readonly
|
|
123
|
-
]
|
|
122
|
+
SemanticTokenModifiers.readonly,
|
|
123
|
+
],
|
|
124
124
|
})
|
|
125
125
|
return
|
|
126
126
|
}
|
|
127
|
+
if ((ast.isWhereRelationParticipantKind(node) || ast.isWhereRelationParticipantTag(node))) {
|
|
128
|
+
acceptor({
|
|
129
|
+
node,
|
|
130
|
+
property: 'participant',
|
|
131
|
+
type: SemanticTokenTypes.keyword,
|
|
132
|
+
})
|
|
133
|
+
}
|
|
127
134
|
if (ast.isElementKindExpression(node) && isTruthy(node.kind)) {
|
|
128
135
|
acceptor({
|
|
129
136
|
node,
|
|
130
137
|
property: 'kind',
|
|
131
138
|
type: SemanticTokenTypes.type,
|
|
132
|
-
modifier: [SemanticTokenModifiers.definition]
|
|
139
|
+
modifier: [SemanticTokenModifiers.definition],
|
|
133
140
|
})
|
|
134
141
|
return 'prune'
|
|
135
142
|
}
|
|
@@ -138,7 +145,7 @@ export class LikeC4SemanticTokenProvider extends AbstractSemanticTokenProvider {
|
|
|
138
145
|
node,
|
|
139
146
|
property: 'tag',
|
|
140
147
|
type: SemanticTokenTypes.type,
|
|
141
|
-
modifier: [SemanticTokenModifiers.definition]
|
|
148
|
+
modifier: [SemanticTokenModifiers.definition],
|
|
142
149
|
})
|
|
143
150
|
return 'prune'
|
|
144
151
|
}
|
|
@@ -149,8 +156,8 @@ export class LikeC4SemanticTokenProvider extends AbstractSemanticTokenProvider {
|
|
|
149
156
|
type: node.parent ? SemanticTokenTypes.property : SemanticTokenTypes.variable,
|
|
150
157
|
modifier: [
|
|
151
158
|
SemanticTokenModifiers.definition,
|
|
152
|
-
SemanticTokenModifiers.readonly
|
|
153
|
-
]
|
|
159
|
+
SemanticTokenModifiers.readonly,
|
|
160
|
+
],
|
|
154
161
|
})
|
|
155
162
|
return !node.parent ? 'prune' : undefined
|
|
156
163
|
}
|
|
@@ -161,8 +168,8 @@ export class LikeC4SemanticTokenProvider extends AbstractSemanticTokenProvider {
|
|
|
161
168
|
type: node.parent ? SemanticTokenTypes.property : SemanticTokenTypes.variable,
|
|
162
169
|
modifier: [
|
|
163
170
|
SemanticTokenModifiers.definition,
|
|
164
|
-
SemanticTokenModifiers.readonly
|
|
165
|
-
]
|
|
171
|
+
SemanticTokenModifiers.readonly,
|
|
172
|
+
],
|
|
166
173
|
})
|
|
167
174
|
return !node.parent ? 'prune' : undefined
|
|
168
175
|
}
|
|
@@ -170,7 +177,7 @@ export class LikeC4SemanticTokenProvider extends AbstractSemanticTokenProvider {
|
|
|
170
177
|
acceptor({
|
|
171
178
|
node,
|
|
172
179
|
keyword: 'color',
|
|
173
|
-
type: SemanticTokenTypes.keyword
|
|
180
|
+
type: SemanticTokenTypes.keyword,
|
|
174
181
|
})
|
|
175
182
|
acceptor({
|
|
176
183
|
node,
|
|
@@ -178,8 +185,8 @@ export class LikeC4SemanticTokenProvider extends AbstractSemanticTokenProvider {
|
|
|
178
185
|
type: SemanticTokenTypes.type,
|
|
179
186
|
modifier: [
|
|
180
187
|
SemanticTokenModifiers.declaration,
|
|
181
|
-
SemanticTokenModifiers.readonly
|
|
182
|
-
]
|
|
188
|
+
SemanticTokenModifiers.readonly,
|
|
189
|
+
],
|
|
183
190
|
})
|
|
184
191
|
return
|
|
185
192
|
}
|
|
@@ -193,15 +200,15 @@ export class LikeC4SemanticTokenProvider extends AbstractSemanticTokenProvider {
|
|
|
193
200
|
type: SemanticTokenTypes.type,
|
|
194
201
|
modifier: [
|
|
195
202
|
SemanticTokenModifiers.declaration,
|
|
196
|
-
SemanticTokenModifiers.readonly
|
|
197
|
-
]
|
|
203
|
+
SemanticTokenModifiers.readonly,
|
|
204
|
+
],
|
|
198
205
|
})
|
|
199
206
|
}
|
|
200
207
|
if (ast.isTags(node)) {
|
|
201
208
|
return acceptor({
|
|
202
209
|
node,
|
|
203
210
|
property: 'values',
|
|
204
|
-
type: SemanticTokenTypes.interface
|
|
211
|
+
type: SemanticTokenTypes.interface,
|
|
205
212
|
})
|
|
206
213
|
}
|
|
207
214
|
if (ast.isTag(node)) {
|
|
@@ -209,7 +216,7 @@ export class LikeC4SemanticTokenProvider extends AbstractSemanticTokenProvider {
|
|
|
209
216
|
node,
|
|
210
217
|
property: 'name',
|
|
211
218
|
type: SemanticTokenTypes.type,
|
|
212
|
-
modifier: [SemanticTokenModifiers.definition]
|
|
219
|
+
modifier: [SemanticTokenModifiers.definition],
|
|
213
220
|
})
|
|
214
221
|
}
|
|
215
222
|
if (
|
|
@@ -219,19 +226,19 @@ export class LikeC4SemanticTokenProvider extends AbstractSemanticTokenProvider {
|
|
|
219
226
|
acceptor({
|
|
220
227
|
node,
|
|
221
228
|
property: 'key',
|
|
222
|
-
type: SemanticTokenTypes.property
|
|
229
|
+
type: SemanticTokenTypes.property,
|
|
223
230
|
})
|
|
224
231
|
}
|
|
225
232
|
if (ast.isOpacityProperty(node)) {
|
|
226
233
|
acceptor({
|
|
227
234
|
node,
|
|
228
235
|
property: 'key',
|
|
229
|
-
type: SemanticTokenTypes.property
|
|
236
|
+
type: SemanticTokenTypes.property,
|
|
230
237
|
})
|
|
231
238
|
acceptor({
|
|
232
239
|
node,
|
|
233
240
|
property: 'value',
|
|
234
|
-
type: SemanticTokenTypes.number
|
|
241
|
+
type: SemanticTokenTypes.number,
|
|
235
242
|
})
|
|
236
243
|
return 'prune'
|
|
237
244
|
}
|
|
@@ -243,14 +250,14 @@ export class LikeC4SemanticTokenProvider extends AbstractSemanticTokenProvider {
|
|
|
243
250
|
acceptor({
|
|
244
251
|
node,
|
|
245
252
|
property: 'key',
|
|
246
|
-
type: SemanticTokenTypes.property
|
|
253
|
+
type: SemanticTokenTypes.property,
|
|
247
254
|
})
|
|
248
255
|
if (ast.isIconProperty(node) && (node.libicon || node.value === 'none')) {
|
|
249
256
|
acceptor({
|
|
250
257
|
node,
|
|
251
258
|
property: node.libicon ? 'libicon' : 'value',
|
|
252
259
|
type: SemanticTokenTypes.enum,
|
|
253
|
-
modifier: [SemanticTokenModifiers.defaultLibrary]
|
|
260
|
+
modifier: [SemanticTokenModifiers.defaultLibrary],
|
|
254
261
|
})
|
|
255
262
|
return 'prune'
|
|
256
263
|
}
|
|
@@ -258,7 +265,7 @@ export class LikeC4SemanticTokenProvider extends AbstractSemanticTokenProvider {
|
|
|
258
265
|
acceptor({
|
|
259
266
|
node,
|
|
260
267
|
property: 'value',
|
|
261
|
-
type: SemanticTokenTypes.string
|
|
268
|
+
type: SemanticTokenTypes.string,
|
|
262
269
|
})
|
|
263
270
|
}
|
|
264
271
|
return 'prune'
|
|
@@ -273,13 +280,13 @@ export class LikeC4SemanticTokenProvider extends AbstractSemanticTokenProvider {
|
|
|
273
280
|
acceptor({
|
|
274
281
|
node,
|
|
275
282
|
property: 'key',
|
|
276
|
-
type: SemanticTokenTypes.property
|
|
283
|
+
type: SemanticTokenTypes.property,
|
|
277
284
|
})
|
|
278
285
|
if ('value' in node) {
|
|
279
286
|
acceptor({
|
|
280
287
|
node,
|
|
281
288
|
property: 'value',
|
|
282
|
-
type: SemanticTokenTypes.enum
|
|
289
|
+
type: SemanticTokenTypes.enum,
|
|
283
290
|
})
|
|
284
291
|
}
|
|
285
292
|
return 'prune'
|
|
@@ -293,14 +300,14 @@ export class LikeC4SemanticTokenProvider extends AbstractSemanticTokenProvider {
|
|
|
293
300
|
type: SemanticTokenTypes.variable,
|
|
294
301
|
modifier: [
|
|
295
302
|
SemanticTokenModifiers.declaration,
|
|
296
|
-
SemanticTokenModifiers.readonly
|
|
297
|
-
]
|
|
303
|
+
SemanticTokenModifiers.readonly,
|
|
304
|
+
],
|
|
298
305
|
})
|
|
299
306
|
acceptor({
|
|
300
307
|
node,
|
|
301
308
|
property: 'kind',
|
|
302
309
|
type: SemanticTokenTypes.keyword,
|
|
303
|
-
modifier: []
|
|
310
|
+
modifier: [],
|
|
304
311
|
})
|
|
305
312
|
}
|
|
306
313
|
|
|
@@ -313,8 +320,8 @@ export class LikeC4SemanticTokenProvider extends AbstractSemanticTokenProvider {
|
|
|
313
320
|
modifier: [
|
|
314
321
|
SemanticTokenModifiers.declaration,
|
|
315
322
|
SemanticTokenModifiers.readonly,
|
|
316
|
-
'local'
|
|
317
|
-
]
|
|
323
|
+
'local',
|
|
324
|
+
],
|
|
318
325
|
})
|
|
319
326
|
}
|
|
320
327
|
}
|
|
@@ -5,40 +5,48 @@ import { ast } from '../ast'
|
|
|
5
5
|
|
|
6
6
|
const parseEquals = (
|
|
7
7
|
{ operator, not }: ast.WhereKindEqual | ast.WhereTagEqual,
|
|
8
|
-
value: string
|
|
8
|
+
value: string,
|
|
9
9
|
): c4.EqualOperator<string> => {
|
|
10
10
|
if (operator.startsWith('!=')) {
|
|
11
11
|
return {
|
|
12
|
-
neq: value
|
|
12
|
+
neq: value,
|
|
13
13
|
}
|
|
14
14
|
}
|
|
15
15
|
if (operator.startsWith('=')) {
|
|
16
16
|
return {
|
|
17
|
-
eq: value
|
|
17
|
+
eq: value,
|
|
18
18
|
}
|
|
19
19
|
}
|
|
20
20
|
return not ? { neq: value } : { eq: value }
|
|
21
21
|
}
|
|
22
22
|
|
|
23
|
+
function parseParticipant(astNode: ast.WhereExpression): ast.Participant | null {
|
|
24
|
+
if (!ast.isWhereRelationParticipantKind(astNode) && !ast.isWhereRelationParticipantTag(astNode)) {
|
|
25
|
+
return null
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
return astNode.participant
|
|
29
|
+
}
|
|
30
|
+
|
|
23
31
|
export function parseWhereClause(astNode: ast.WhereExpression): c4.WhereOperator<string, string> {
|
|
24
32
|
switch (true) {
|
|
25
33
|
case ast.isWhereTagEqual(astNode): {
|
|
26
34
|
const tag = astNode.value?.ref?.name
|
|
35
|
+
const participant = parseParticipant(astNode)
|
|
27
36
|
invariant(tag, 'Expected tag name')
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
}
|
|
37
|
+
const tagOperator = { tag: parseEquals(astNode, tag) }
|
|
38
|
+
return participant ? { participant, operator: tagOperator } : tagOperator
|
|
31
39
|
}
|
|
32
40
|
case ast.isWhereKindEqual(astNode): {
|
|
33
41
|
const kind = astNode.value?.ref?.name
|
|
42
|
+
const participant = parseParticipant(astNode)
|
|
34
43
|
invariant(kind, 'Expected kind name')
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
}
|
|
44
|
+
const kindOperator = { kind: parseEquals(astNode, kind) }
|
|
45
|
+
return participant ? { participant, operator: kindOperator } : kindOperator
|
|
38
46
|
}
|
|
39
47
|
case ast.isWhereElementNegation(astNode) || ast.isWhereRelationNegation(astNode): {
|
|
40
48
|
return {
|
|
41
|
-
not: parseWhereClause(astNode.value)
|
|
49
|
+
not: parseWhereClause(astNode.value),
|
|
42
50
|
}
|
|
43
51
|
}
|
|
44
52
|
case ast.isWhereBinaryExpression(astNode): {
|
|
@@ -49,21 +57,21 @@ export function parseWhereClause(astNode: ast.WhereExpression): c4.WhereOperator
|
|
|
49
57
|
case 'and': {
|
|
50
58
|
const operands = [
|
|
51
59
|
isAndOperator(left) ? left.and : left,
|
|
52
|
-
isAndOperator(right) ? right.and : right
|
|
60
|
+
isAndOperator(right) ? right.and : right,
|
|
53
61
|
].flat()
|
|
54
62
|
invariant(isNonEmptyArray(operands), 'Expected non-empty array')
|
|
55
63
|
return {
|
|
56
|
-
and: operands
|
|
64
|
+
and: operands,
|
|
57
65
|
}
|
|
58
66
|
}
|
|
59
67
|
case 'or': {
|
|
60
68
|
const operands = [
|
|
61
69
|
isOrOperator(left) ? left.or : left,
|
|
62
|
-
isOrOperator(right) ? right.or : right
|
|
70
|
+
isOrOperator(right) ? right.or : right,
|
|
63
71
|
].flat()
|
|
64
72
|
invariant(isNonEmptyArray(operands), 'Expected non-empty array')
|
|
65
73
|
return {
|
|
66
|
-
or: operands
|
|
74
|
+
or: operands,
|
|
67
75
|
}
|
|
68
76
|
}
|
|
69
77
|
default:
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type * as c4 from '@likec4/core'
|
|
2
|
-
import {
|
|
2
|
+
import { invariant, isNonEmptyArray, nonexhaustive } from '@likec4/core'
|
|
3
3
|
import { isNonNullish } from 'remeda'
|
|
4
|
-
import {
|
|
4
|
+
import { type ParsedAstDeploymentView, ast, toAutoLayout, toElementStyle, ViewOps } from '../../ast'
|
|
5
5
|
import { logWarnError } from '../../logger'
|
|
6
6
|
import { stringHash } from '../../utils'
|
|
7
7
|
import { parseViewManualLayout } from '../../view-utils/manual-layout'
|
|
@@ -14,7 +14,7 @@ export type WithDeploymentView = ReturnType<typeof DeploymentViewParser>
|
|
|
14
14
|
export function DeploymentViewParser<TBase extends WithExpressionV2 & WithDeploymentModel>(B: TBase) {
|
|
15
15
|
return class DeploymentViewParser extends B {
|
|
16
16
|
parseDeploymentView(
|
|
17
|
-
astNode: ast.DeploymentView
|
|
17
|
+
astNode: ast.DeploymentView,
|
|
18
18
|
): ParsedAstDeploymentView {
|
|
19
19
|
const body = astNode.body
|
|
20
20
|
invariant(body, 'DynamicElementView body is not defined')
|
|
@@ -26,7 +26,7 @@ export function DeploymentViewParser<TBase extends WithExpressionV2 & WithDeploy
|
|
|
26
26
|
if (!id) {
|
|
27
27
|
id = 'deployment_' + stringHash(
|
|
28
28
|
this.doc.uri.toString(),
|
|
29
|
-
astPath
|
|
29
|
+
astPath,
|
|
30
30
|
) as c4.ViewId
|
|
31
31
|
}
|
|
32
32
|
|
|
@@ -56,7 +56,7 @@ export function DeploymentViewParser<TBase extends WithExpressionV2 & WithDeploy
|
|
|
56
56
|
return []
|
|
57
57
|
}
|
|
58
58
|
}),
|
|
59
|
-
...(manualLayout && { manualLayout })
|
|
59
|
+
...(manualLayout && { manualLayout }),
|
|
60
60
|
}
|
|
61
61
|
}
|
|
62
62
|
|
|
@@ -87,6 +87,9 @@ export function DeploymentViewParser<TBase extends WithExpressionV2 & WithDeploy
|
|
|
87
87
|
case ast.isRelationExpr(expr):
|
|
88
88
|
exprs.unshift(this.parseRelationExpr(expr))
|
|
89
89
|
break
|
|
90
|
+
case ast.isRelationPredicateWhereV2(expr):
|
|
91
|
+
exprs.unshift(this.parseRelationWhereExpr(expr))
|
|
92
|
+
break
|
|
90
93
|
default:
|
|
91
94
|
nonexhaustive(expr)
|
|
92
95
|
}
|
|
@@ -108,8 +111,8 @@ export function DeploymentViewParser<TBase extends WithExpressionV2 & WithDeploy
|
|
|
108
111
|
targets,
|
|
109
112
|
...(notation && { notation }),
|
|
110
113
|
style: {
|
|
111
|
-
...toElementStyle(styleProps, this.isValid)
|
|
112
|
-
}
|
|
114
|
+
...toElementStyle(styleProps, this.isValid),
|
|
115
|
+
},
|
|
113
116
|
}
|
|
114
117
|
}
|
|
115
118
|
}
|
|
@@ -4,6 +4,7 @@ import { isNonNullish } from 'remeda'
|
|
|
4
4
|
import { ast } from '../../ast'
|
|
5
5
|
import { logWarnError } from '../../logger'
|
|
6
6
|
import { instanceRef } from '../../utils/fqnRef'
|
|
7
|
+
import { parseWhereClause } from '../model-parser-where'
|
|
7
8
|
import type { Base } from './Base'
|
|
8
9
|
|
|
9
10
|
export type WithExpressionV2 = ReturnType<typeof ExpressionV2Parser>
|
|
@@ -89,7 +90,20 @@ export function ExpressionV2Parser<TBase extends Base>(B: TBase) {
|
|
|
89
90
|
return exprs.reverse()
|
|
90
91
|
}
|
|
91
92
|
|
|
93
|
+
parseRelationWhereExpr(astNode: ast.RelationPredicateWhereV2): c4.RelationExpr {
|
|
94
|
+
return {
|
|
95
|
+
where: {
|
|
96
|
+
expr: this.parseRelationExpr(astNode.subject as ast.RelationExpr),
|
|
97
|
+
condition: astNode.where ? parseWhereClause(astNode.where) : {
|
|
98
|
+
kind: { neq: '--always-true--' },
|
|
99
|
+
},
|
|
100
|
+
},
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
92
104
|
parseRelationExpr(astNode: ast.RelationExpr): c4.RelationExpr {
|
|
105
|
+
if (ast.isRelationPredicateWhere(astNode)) {
|
|
106
|
+
}
|
|
93
107
|
if (ast.isDirectedRelationExpr(astNode)) {
|
|
94
108
|
return {
|
|
95
109
|
source: this.parseFqnExpr(astNode.source.from),
|