@likec4/language-server 1.3.0 → 1.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (34) hide show
  1. package/README.md +1 -1
  2. package/contrib/likec4.tmLanguage.json +1 -1
  3. package/package.json +13 -13
  4. package/src/Rpc.ts +23 -1
  5. package/src/ast.ts +11 -12
  6. package/src/generated/ast.ts +101 -31
  7. package/src/generated/grammar.ts +1 -1
  8. package/src/like-c4.langium +58 -33
  9. package/src/lsp/SemanticTokenProvider.ts +12 -14
  10. package/src/model/fqn-computation.ts +29 -7
  11. package/src/model/fqn-index.ts +18 -31
  12. package/src/model/model-builder.ts +13 -9
  13. package/src/model/model-locator.ts +7 -7
  14. package/src/model/model-parser.ts +63 -18
  15. package/src/model-change/changeElementStyle.ts +2 -2
  16. package/src/model-graph/compute-view/__test__/fixture.ts +51 -23
  17. package/src/model-graph/compute-view/compute.ts +47 -16
  18. package/src/model-graph/compute-view/predicates.ts +6 -1
  19. package/src/model-graph/dynamic-view/compute.ts +2 -2
  20. package/src/model-graph/utils/{applyElementCustomProperties.ts → applyCustomElementProperties.ts} +5 -3
  21. package/src/model-graph/utils/applyCustomRelationProperties.ts +50 -0
  22. package/src/model-graph/utils/applyViewRuleStyles.ts +11 -34
  23. package/src/model-graph/utils/elementExpressionToPredicate.ts +32 -0
  24. package/src/references/scope-provider.ts +3 -23
  25. package/src/validation/dynamic-view-rule.ts +5 -7
  26. package/src/validation/element.ts +8 -4
  27. package/src/validation/index.ts +2 -0
  28. package/src/validation/view-predicates/custom-element-expr.ts +17 -6
  29. package/src/validation/view-predicates/custom-relation-expr.ts +15 -0
  30. package/src/validation/view-predicates/index.ts +1 -0
  31. package/src/view-utils/assignNavigateTo.ts +2 -2
  32. package/src/view-utils/manual-layout.ts +4 -2
  33. package/src/view-utils/resolve-extended-views.ts +2 -2
  34. package/src/view-utils/resolve-relative-paths.ts +3 -3
package/README.md CHANGED
@@ -1,5 +1,5 @@
1
1
  # `@likec4/language-server`
2
2
 
3
- [docs](https://docs.likec4.dev/) | [playground](https://playground.likec4.dev/) | [demo](https://template.likec4.dev/view/cloud)
3
+ [docs](https://likec4.dev/) | [playground](https://playground.likec4.dev/) | [demo](https://template.likec4.dev/view/cloud)
4
4
 
5
5
  Language Server Protocol (LSP) based on [languim](https://github.com/languim/languim) library.
@@ -12,7 +12,7 @@
12
12
  },
13
13
  {
14
14
  "name": "keyword.control.likec4",
15
- "match": "\\b(BottomTop|LeftRight|RightLeft|TopBottom|amber|autoLayout|blue|border|browser|color|crow|cylinder|dashed|description|diamond|dotted|dynamic|element|exclude|extend|extends|gray|green|head|icon|include|indigo|it|kind|line|link|mobile|model|muted|navigateTo|none|normal|odiamond|of|onormal|opacity|open|person|primary|queue|rectangle|red|relationship|secondary|shape|sky|slate|solid|specification|storage|style|tag|tail|technology|this|title|vee|view|views|with)\\b"
15
+ "match": "\\b(BottomTop|LeftRight|RightLeft|TopBottom|amber|autoLayout|blue|border|browser|color|crow|cylinder|dashed|description|diamond|dot|dotted|dynamic|element|exclude|extend|extends|gray|green|head|icon|include|indigo|it|kind|line|link|mobile|model|muted|navigateTo|none|normal|odiamond|odot|of|onormal|opacity|open|person|primary|queue|rectangle|red|relationship|secondary|shape|sky|slate|solid|specification|storage|style|tag|tail|technology|this|title|vee|view|views|with)\\b"
16
16
  },
17
17
  {
18
18
  "name": "string.quoted.double.likec4",
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@likec4/language-server",
3
3
  "description": "LikeC4 Language Server",
4
- "version": "1.3.0",
4
+ "version": "1.5.0",
5
5
  "license": "MIT",
6
6
  "bugs": "https://github.com/likec4/likec4/issues",
7
7
  "homepage": "https://likec4.dev",
@@ -78,38 +78,38 @@
78
78
  "lint": "run -T eslint src/ --fix",
79
79
  "clean": "run -T rimraf dist contrib",
80
80
  "test": "vitest run --no-isolate",
81
+ "vitest:ui": "vitest --no-isolate --ui",
81
82
  "test:watch": "vitest"
82
83
  },
83
84
  "dependencies": {
84
85
  "@dagrejs/graphlib": "^2.2.2",
85
- "@likec4/core": "1.3.0",
86
+ "@likec4/core": "1.5.0",
86
87
  "@total-typescript/ts-reset": "^0.5.1",
87
88
  "fast-equals": "^5.0.1",
88
89
  "indent-string": "^5.0.0",
89
90
  "json5": "^2.2.3",
90
- "langium": "3.1.0",
91
+ "langium": "3.1.2",
91
92
  "object-hash": "^3.0.0",
92
93
  "p-debounce": "^4.0.0",
93
- "rambdax": "^9.1.1",
94
- "remeda": "^1.61.0",
94
+ "remeda": "^2.3.0",
95
95
  "string-hash": "^1.1.3",
96
96
  "strip-indent": "^4.0.0",
97
- "type-fest": "^4.18.2",
97
+ "type-fest": "^4.21.0",
98
98
  "ufo": "^1.5.3",
99
99
  "vscode-languageserver": "9.0.1",
100
100
  "vscode-languageserver-protocol": "3.17.5",
101
101
  "vscode-uri": "3.0.8"
102
102
  },
103
103
  "devDependencies": {
104
- "@likec4/tsconfig": "1.3.0",
105
- "@types/node": "^20.14.2",
104
+ "@likec4/tsconfig": "1.5.0",
105
+ "@types/node": "^20.14.10",
106
106
  "@types/object-hash": "^3.0.6",
107
107
  "@types/string-hash": "^1.1.3",
108
- "execa": "^9.1.0",
108
+ "execa": "^9.3.0",
109
109
  "langium-cli": "3.1.0",
110
- "npm-run-all2": "^6.1.2",
111
- "typescript": "^5.4.5",
112
- "vitest": "~1.5.3"
110
+ "npm-run-all2": "^6.2.2",
111
+ "typescript": "^5.5.3",
112
+ "vitest": "~1.6.0"
113
113
  },
114
- "packageManager": "yarn@4.3.0"
114
+ "packageManager": "yarn@4.3.1"
115
115
  }
package/src/Rpc.ts CHANGED
@@ -3,7 +3,7 @@ import { logError, logger } from './logger'
3
3
  import type { LikeC4Services } from './module'
4
4
 
5
5
  import { nonexhaustive } from '@likec4/core'
6
- import { Disposable, URI, UriUtils } from 'langium'
6
+ import { Disposable, interruptAndCheck, URI, UriUtils } from 'langium'
7
7
  import { isLikeC4LangiumDocument } from './ast'
8
8
  import {
9
9
  buildDocuments,
@@ -46,6 +46,8 @@ export class Rpc implements Disposable {
46
46
  }
47
47
  )
48
48
 
49
+ let isFirstBuild = true
50
+
49
51
  this.disposables.push(
50
52
  Disposable.create(() => {
51
53
  notifyModelParsed.cancel()
@@ -75,6 +77,26 @@ export class Rpc implements Disposable {
75
77
  changed (total ${changed.length}):${docs.map(d => '\n - ' + d).join('')}
76
78
  deleted (total ${deleted.length}):${deleted.map(d => '\n - ' + d.toString()).join('\n')}`
77
79
  )
80
+
81
+ if (!isFirstBuild && (changed.length + deleted.length) > 0) {
82
+ await Promise.allSettled(
83
+ [...changed, ...deleted].map(async d => {
84
+ const uri = d.toString()
85
+ logger.debug(`clear diagnostics for ${uri}`)
86
+ try {
87
+ await connection.sendDiagnostics({
88
+ uri,
89
+ diagnostics: []
90
+ })
91
+ } catch (e) {
92
+ // Ignore
93
+ logger.warn(`error clearing diagnostics for ${uri}: ${e}`)
94
+ }
95
+ })
96
+ )
97
+ await interruptAndCheck(cancelToken)
98
+ }
99
+ isFirstBuild = false
78
100
  await DocumentBuilder.update(changed, deleted, cancelToken)
79
101
  }),
80
102
  connection.onRequest(locate, params => {
package/src/ast.ts CHANGED
@@ -6,7 +6,7 @@ import {
6
6
  nonexhaustive,
7
7
  RelationRefError
8
8
  } from '@likec4/core'
9
- import type { AstNode, DiagnosticInfo, LangiumDocument, MultiMap } from 'langium'
9
+ import type { AstNode, AstNodeDescription, DiagnosticInfo, LangiumDocument, MultiMap } from 'langium'
10
10
  import { AstUtils, DocumentState } from 'langium'
11
11
  import { clamp, isNullish } from 'remeda'
12
12
  import type { ConditionalPick, SetRequired, ValueOf } from 'type-fest'
@@ -133,10 +133,8 @@ export const ElementOps = {
133
133
  }
134
134
  }
135
135
 
136
- export interface DocFqnIndexEntry {
137
- name: string
138
- el: WeakRef<ast.Element>
139
- path: string
136
+ export interface DocFqnIndexAstNodeDescription extends AstNodeDescription {
137
+ fqn: c4.Fqn
140
138
  }
141
139
 
142
140
  // export type LikeC4AstNode = ast.LikeC4AstType[keyof ast.LikeC4AstType]
@@ -150,14 +148,14 @@ export interface LikeC4DocumentProps {
150
148
  c4Relations?: ParsedAstRelation[]
151
149
  c4Views?: ParsedAstView[]
152
150
  // Fqn -> Element
153
- c4fqns?: MultiMap<c4.Fqn, DocFqnIndexEntry>
151
+ c4fqnIndex?: MultiMap<c4.Fqn, DocFqnIndexAstNodeDescription>
154
152
  }
155
153
 
156
154
  export interface LikeC4LangiumDocument
157
155
  extends Omit<LangiumDocument<LikeC4Grammar>, 'diagnostics'>, LikeC4DocumentProps
158
156
  {}
159
157
  export interface FqnIndexedDocument
160
- extends Omit<LangiumDocument<LikeC4Grammar>, 'diagnostics'>, SetRequired<LikeC4DocumentProps, 'c4fqns'>
158
+ extends Omit<LangiumDocument<LikeC4Grammar>, 'diagnostics'>, SetRequired<LikeC4DocumentProps, 'c4fqnIndex'>
161
159
  {}
162
160
 
163
161
  // export type ParsedLikeC4LangiumDocument = SetRequired<FqnIndexedDocument, keyof LikeC4DocumentProps>
@@ -166,7 +164,7 @@ export interface ParsedLikeC4LangiumDocument
166
164
  {}
167
165
 
168
166
  export function cleanParsedModel(doc: LikeC4LangiumDocument) {
169
- const props: Required<Omit<LikeC4DocumentProps, 'c4fqns' | 'diagnostics'>> = {
167
+ const props: Required<Omit<LikeC4DocumentProps, 'c4fqnIndex' | 'diagnostics'>> = {
170
168
  c4Specification: {
171
169
  kinds: {},
172
170
  relationships: {}
@@ -179,7 +177,7 @@ export function cleanParsedModel(doc: LikeC4LangiumDocument) {
179
177
  }
180
178
 
181
179
  export function isFqnIndexedDocument(doc: LangiumDocument): doc is FqnIndexedDocument {
182
- return isLikeC4LangiumDocument(doc) && doc.state >= DocumentState.IndexedContent && !!doc.c4fqns
180
+ return isLikeC4LangiumDocument(doc) && doc.state >= DocumentState.IndexedContent && !!doc.c4fqnIndex
183
181
  }
184
182
 
185
183
  export function isLikeC4LangiumDocument(doc: LangiumDocument): doc is LikeC4LangiumDocument {
@@ -196,7 +194,7 @@ export function isParsedLikeC4LangiumDocument(
196
194
  && !!doc.c4Elements
197
195
  && !!doc.c4Relations
198
196
  && !!doc.c4Views
199
- && !!doc.c4fqns
197
+ && !!doc.c4fqnIndex
200
198
  )
201
199
  }
202
200
 
@@ -209,15 +207,16 @@ function validatableAstNodeGuards<const Predicates extends Guard<AstNode>[]>(
209
207
  return (n: AstNode): n is Guarded<Predicates[number]> => predicates.some(p => p(n))
210
208
  }
211
209
  const isValidatableAstNode = validatableAstNodeGuards([
212
- ast.isCustomElementExprBody,
210
+ ast.isCustomElementExpr,
211
+ ast.isCustomRelationExpr,
213
212
  ast.isViewRulePredicateExpr,
214
213
  ast.isDynamicViewRulePredicate,
214
+ ast.isDynamicViewStep,
215
215
  ast.isViewProperty,
216
216
  ast.isStyleProperty,
217
217
  ast.isTags,
218
218
  ast.isViewRule,
219
219
  ast.isDynamicViewRule,
220
- ast.isDynamicViewStep,
221
220
  ast.isElementViewBody,
222
221
  ast.isDynamicViewBody,
223
222
  ast.isLikeC4View,
@@ -20,18 +20,15 @@ export const LikeC4Terminals = {
20
20
  Dot: /\./,
21
21
  NotEqual: /\!\={1,2}/,
22
22
  Eq: /\={1,2}/,
23
- Colon: /:/,
24
- SemiColon: /;/,
25
- Comma: /,/,
26
23
  Percent: /\b\d+%/,
27
24
  String: /"[^"]*"|'[^']*'/,
28
25
  IdTerminal: /\b[_]*[a-zA-Z][_-\w]*/,
29
26
  };
30
27
 
31
- export type ArrowType = 'crow' | 'diamond' | 'none' | 'normal' | 'odiamond' | 'onormal' | 'open' | 'vee';
28
+ export type ArrowType = 'crow' | 'diamond' | 'dot' | 'none' | 'normal' | 'odiamond' | 'odot' | 'onormal' | 'open' | 'vee';
32
29
 
33
30
  export function isArrowType(item: unknown): item is ArrowType {
34
- return item === 'none' || item === 'normal' || item === 'onormal' || item === 'diamond' || item === 'odiamond' || item === 'crow' || item === 'open' || item === 'vee';
31
+ return item === 'none' || item === 'normal' || item === 'onormal' || item === 'dot' || item === 'odot' || item === 'diamond' || item === 'odiamond' || item === 'crow' || item === 'open' || item === 'vee';
35
32
  }
36
33
 
37
34
  export type BorderStyleValue = 'none' | LineOptions;
@@ -62,6 +59,14 @@ export function isElementExpr(item: unknown): item is ElementExpr {
62
59
  return reflection.isInstance(item, ElementExpr);
63
60
  }
64
61
 
62
+ export type ElementPredicateExpression = CustomElementExpr | ElementExpr;
63
+
64
+ export const ElementPredicateExpression = 'ElementPredicateExpression';
65
+
66
+ export function isElementPredicateExpression(item: unknown): item is ElementPredicateExpression {
67
+ return reflection.isInstance(item, ElementPredicateExpression);
68
+ }
69
+
65
70
  export type ElementProperty = ElementStringProperty | LinkProperty | StyleProperties;
66
71
 
67
72
  export const ElementProperty = 'ElementProperty';
@@ -104,6 +109,14 @@ export function isRelation(item: unknown): item is Relation {
104
109
  return reflection.isInstance(item, Relation);
105
110
  }
106
111
 
112
+ export type RelationPredicateExpression = OutgoingExpr | ViewRulePredicateRelations;
113
+
114
+ export const RelationPredicateExpression = 'RelationPredicateExpression';
115
+
116
+ export function isRelationPredicateExpression(item: unknown): item is RelationPredicateExpression {
117
+ return reflection.isInstance(item, RelationPredicateExpression);
118
+ }
119
+
107
120
  export type RelationProperty = LinkProperty | RelationStringProperty | RelationStyleProperty;
108
121
 
109
122
  export const RelationProperty = 'RelationProperty';
@@ -120,7 +133,7 @@ export function isRelationshipStyleProperty(item: unknown): item is Relationship
120
133
  return reflection.isInstance(item, RelationshipStyleProperty);
121
134
  }
122
135
 
123
- export type StringProperty = ElementStringProperty | ViewStringProperty;
136
+ export type StringProperty = ElementStringProperty | RelationStringProperty | ViewStringProperty;
124
137
 
125
138
  export const StringProperty = 'StringProperty';
126
139
 
@@ -184,7 +197,7 @@ export function isViewRulePredicate(item: unknown): item is ViewRulePredicate {
184
197
  return reflection.isInstance(item, ViewRulePredicate);
185
198
  }
186
199
 
187
- export type ViewRulePredicateExpr = CustomElementExpr | ElementExpr | InOutExpr | IncomingExpr | OutgoingExpr | RelationExpr;
200
+ export type ViewRulePredicateExpr = ElementPredicateExpression | RelationPredicateExpression;
188
201
 
189
202
  export const ViewRulePredicateExpr = 'ViewRulePredicateExpr';
190
203
 
@@ -192,8 +205,16 @@ export function isViewRulePredicateExpr(item: unknown): item is ViewRulePredicat
192
205
  return reflection.isInstance(item, ViewRulePredicateExpr);
193
206
  }
194
207
 
208
+ export type ViewRulePredicateRelations = CustomRelationExpr | InOutExpr | IncomingExpr | RelationExpr;
209
+
210
+ export const ViewRulePredicateRelations = 'ViewRulePredicateRelations';
211
+
212
+ export function isViewRulePredicateRelations(item: unknown): item is ViewRulePredicateRelations {
213
+ return reflection.isInstance(item, ViewRulePredicateRelations);
214
+ }
215
+
195
216
  export interface ArrowProperty extends AstNode {
196
- readonly $container: RelationStyleProperty | SpecificationRelationshipKind;
217
+ readonly $container: CustomRelationExprBody | RelationStyleProperty | SpecificationRelationshipKind;
197
218
  readonly $type: 'ArrowProperty';
198
219
  key: 'head' | 'tail';
199
220
  value: ArrowType;
@@ -219,7 +240,7 @@ export function isBorderProperty(item: unknown): item is BorderProperty {
219
240
  }
220
241
 
221
242
  export interface ColorProperty extends AstNode {
222
- readonly $container: CustomElementExprBody | RelationStyleProperty | SpecificationRelationshipKind | StyleProperties | ViewRuleStyle;
243
+ readonly $container: CustomElementExprBody | CustomRelationExprBody | RelationStyleProperty | SpecificationRelationshipKind | StyleProperties | ViewRuleStyle;
223
244
  readonly $type: 'ColorProperty';
224
245
  key: 'color';
225
246
  value: ThemeColor;
@@ -256,6 +277,31 @@ export function isCustomElementExprBody(item: unknown): item is CustomElementExp
256
277
  return reflection.isInstance(item, CustomElementExprBody);
257
278
  }
258
279
 
280
+ export interface CustomRelationExpr extends AstNode {
281
+ readonly $container: ExcludePredicate | IncludePredicate;
282
+ readonly $type: 'CustomRelationExpr';
283
+ body: CustomRelationExprBody;
284
+ relation: RelationExpr;
285
+ }
286
+
287
+ export const CustomRelationExpr = 'CustomRelationExpr';
288
+
289
+ export function isCustomRelationExpr(item: unknown): item is CustomRelationExpr {
290
+ return reflection.isInstance(item, CustomRelationExpr);
291
+ }
292
+
293
+ export interface CustomRelationExprBody extends AstNode {
294
+ readonly $container: CustomRelationExpr;
295
+ readonly $type: 'CustomRelationExprBody';
296
+ props: Array<RelationStringProperty | RelationshipStyleProperty>;
297
+ }
298
+
299
+ export const CustomRelationExprBody = 'CustomRelationExprBody';
300
+
301
+ export function isCustomRelationExprBody(item: unknown): item is CustomRelationExprBody {
302
+ return reflection.isInstance(item, CustomRelationExprBody);
303
+ }
304
+
259
305
  export interface DescedantsExpr extends AstNode {
260
306
  readonly $container: CustomElementExpr | DynamicViewRulePredicate | ExcludePredicate | IncludePredicate | IncomingExpr | OutgoingExpr | RelationExpr | ViewRuleStyle;
261
307
  readonly $type: 'DescedantsExpr';
@@ -299,8 +345,7 @@ export function isDynamicViewBody(item: unknown): item is DynamicViewBody {
299
345
  export interface DynamicViewRulePredicate extends AstNode {
300
346
  readonly $container: DynamicViewBody;
301
347
  readonly $type: 'DynamicViewRulePredicate';
302
- commas: Array<string>;
303
- expressions: Array<ViewRulePredicateExpr>;
348
+ expressions: Array<ElementPredicateExpression>;
304
349
  }
305
350
 
306
351
  export const DynamicViewRulePredicate = 'DynamicViewRulePredicate';
@@ -463,7 +508,6 @@ export function isElementViewRef(item: unknown): item is ElementViewRef {
463
508
  export interface ExcludePredicate extends AstNode {
464
509
  readonly $container: ElementViewBody;
465
510
  readonly $type: 'ExcludePredicate';
466
- commas: Array<string>;
467
511
  expressions: Array<ViewRulePredicateExpr>;
468
512
  }
469
513
 
@@ -573,7 +617,6 @@ export function isImplicitRelation(item: unknown): item is ImplicitRelation {
573
617
  export interface IncludePredicate extends AstNode {
574
618
  readonly $container: ElementViewBody;
575
619
  readonly $type: 'IncludePredicate';
576
- commas: Array<string>;
577
620
  expressions: Array<ViewRulePredicateExpr>;
578
621
  }
579
622
 
@@ -584,7 +627,7 @@ export function isIncludePredicate(item: unknown): item is IncludePredicate {
584
627
  }
585
628
 
586
629
  export interface IncomingExpr extends AstNode {
587
- readonly $container: DynamicViewRulePredicate | ExcludePredicate | InOutExpr | IncludePredicate;
630
+ readonly $container: ExcludePredicate | InOutExpr | IncludePredicate;
588
631
  readonly $type: 'IncomingExpr';
589
632
  to: ElementExpr;
590
633
  }
@@ -596,7 +639,7 @@ export function isIncomingExpr(item: unknown): item is IncomingExpr {
596
639
  }
597
640
 
598
641
  export interface InOutExpr extends AstNode {
599
- readonly $container: DynamicViewRulePredicate | ExcludePredicate | IncludePredicate;
642
+ readonly $container: ExcludePredicate | IncludePredicate;
600
643
  readonly $type: 'InOutExpr';
601
644
  inout: IncomingExpr;
602
645
  }
@@ -621,7 +664,7 @@ export function isLikeC4Grammar(item: unknown): item is LikeC4Grammar {
621
664
  }
622
665
 
623
666
  export interface LineProperty extends AstNode {
624
- readonly $container: RelationStyleProperty | SpecificationRelationshipKind;
667
+ readonly $container: CustomRelationExprBody | RelationStyleProperty | SpecificationRelationshipKind;
625
668
  readonly $type: 'LineProperty';
626
669
  key: 'line';
627
670
  value: LineOptions;
@@ -699,7 +742,7 @@ export function isOpacityProperty(item: unknown): item is OpacityProperty {
699
742
  }
700
743
 
701
744
  export interface OutgoingExpr extends AstNode {
702
- readonly $container: DynamicViewRulePredicate | ExcludePredicate | IncludePredicate;
745
+ readonly $container: ExcludePredicate | IncludePredicate;
703
746
  readonly $type: 'OutgoingExpr';
704
747
  from: ElementExpr;
705
748
  }
@@ -724,7 +767,7 @@ export function isRelationBody(item: unknown): item is RelationBody {
724
767
  }
725
768
 
726
769
  export interface RelationExpr extends AstNode {
727
- readonly $container: DynamicViewRulePredicate | ExcludePredicate | IncludePredicate;
770
+ readonly $container: CustomRelationExpr | ExcludePredicate | IncludePredicate;
728
771
  readonly $type: 'RelationExpr';
729
772
  isBidirectional: boolean;
730
773
  source: ElementExpr;
@@ -750,7 +793,7 @@ export function isRelationshipKind(item: unknown): item is RelationshipKind {
750
793
  }
751
794
 
752
795
  export interface RelationStringProperty extends AstNode {
753
- readonly $container: RelationBody;
796
+ readonly $container: CustomRelationExprBody | RelationBody;
754
797
  readonly $type: 'RelationStringProperty';
755
798
  key: 'title';
756
799
  value: string;
@@ -869,7 +912,6 @@ export function isTag(item: unknown): item is Tag {
869
912
  export interface Tags extends AstNode {
870
913
  readonly $container: DynamicViewBody | ElementBody | ElementViewBody | ExplicitRelation | ImplicitRelation | RelationBody;
871
914
  readonly $type: 'Tags';
872
- comma: Array<string>;
873
915
  value: Array<Reference<Tag>>;
874
916
  }
875
917
 
@@ -906,7 +948,6 @@ export function isViewRuleAutoLayout(item: unknown): item is ViewRuleAutoLayout
906
948
  export interface ViewRuleStyle extends AstNode {
907
949
  readonly $container: DynamicViewBody | ElementViewBody;
908
950
  readonly $type: 'ViewRuleStyle';
909
- commas: Array<string>;
910
951
  styleprops: Array<StyleProperty>;
911
952
  targets: Array<ElementExpr>;
912
953
  }
@@ -948,6 +989,8 @@ export type LikeC4AstType = {
948
989
  ColorProperty: ColorProperty
949
990
  CustomElementExpr: CustomElementExpr
950
991
  CustomElementExprBody: CustomElementExprBody
992
+ CustomRelationExpr: CustomRelationExpr
993
+ CustomRelationExprBody: CustomRelationExprBody
951
994
  DescedantsExpr: DescedantsExpr
952
995
  DynamicView: DynamicView
953
996
  DynamicViewBody: DynamicViewBody
@@ -959,6 +1002,7 @@ export type LikeC4AstType = {
959
1002
  ElementExpr: ElementExpr
960
1003
  ElementKind: ElementKind
961
1004
  ElementKindExpr: ElementKindExpr
1005
+ ElementPredicateExpression: ElementPredicateExpression
962
1006
  ElementProperty: ElementProperty
963
1007
  ElementRef: ElementRef
964
1008
  ElementStringProperty: ElementStringProperty
@@ -989,6 +1033,7 @@ export type LikeC4AstType = {
989
1033
  Relation: Relation
990
1034
  RelationBody: RelationBody
991
1035
  RelationExpr: RelationExpr
1036
+ RelationPredicateExpression: RelationPredicateExpression
992
1037
  RelationProperty: RelationProperty
993
1038
  RelationStringProperty: RelationStringProperty
994
1039
  RelationStyleProperty: RelationStyleProperty
@@ -1010,6 +1055,7 @@ export type LikeC4AstType = {
1010
1055
  ViewRuleAutoLayout: ViewRuleAutoLayout
1011
1056
  ViewRulePredicate: ViewRulePredicate
1012
1057
  ViewRulePredicateExpr: ViewRulePredicateExpr
1058
+ ViewRulePredicateRelations: ViewRulePredicateRelations
1013
1059
  ViewRuleStyle: ViewRuleStyle
1014
1060
  ViewStringProperty: ViewStringProperty
1015
1061
  WildcardExpr: WildcardExpr
@@ -1018,7 +1064,7 @@ export type LikeC4AstType = {
1018
1064
  export class LikeC4AstReflection extends AbstractAstReflection {
1019
1065
 
1020
1066
  getAllTypes(): string[] {
1021
- return [ArrowProperty, BorderProperty, ColorProperty, CustomElementExpr, CustomElementExprBody, DescedantsExpr, DynamicView, DynamicViewBody, DynamicViewRule, DynamicViewRulePredicate, DynamicViewStep, Element, ElementBody, ElementExpr, ElementKind, ElementKindExpr, ElementProperty, ElementRef, ElementStringProperty, ElementTagExpr, ElementView, ElementViewBody, ElementViewRef, ExcludePredicate, ExpandElementExpr, ExplicitRelation, ExtendElement, ExtendElementBody, FqnElementRef, IconProperty, ImplicitRelation, InOutExpr, IncludePredicate, IncomingExpr, LikeC4Grammar, LikeC4View, LineProperty, LinkProperty, Model, ModelViews, NavigateToProperty, OpacityProperty, OutgoingExpr, Relation, RelationBody, RelationExpr, RelationProperty, RelationStringProperty, RelationStyleProperty, RelationshipKind, RelationshipStyleProperty, ShapeProperty, SpecificationElementKind, SpecificationRelationshipKind, SpecificationRule, SpecificationTag, StringProperty, StyleProperties, StyleProperty, Tag, Tags, ViewProperty, ViewRef, ViewRule, ViewRuleAutoLayout, ViewRulePredicate, ViewRulePredicateExpr, ViewRuleStyle, ViewStringProperty, WildcardExpr];
1067
+ return [ArrowProperty, BorderProperty, ColorProperty, CustomElementExpr, CustomElementExprBody, CustomRelationExpr, CustomRelationExprBody, DescedantsExpr, DynamicView, DynamicViewBody, DynamicViewRule, DynamicViewRulePredicate, DynamicViewStep, Element, ElementBody, ElementExpr, ElementKind, ElementKindExpr, ElementPredicateExpression, ElementProperty, ElementRef, ElementStringProperty, ElementTagExpr, ElementView, ElementViewBody, ElementViewRef, ExcludePredicate, ExpandElementExpr, ExplicitRelation, ExtendElement, ExtendElementBody, FqnElementRef, IconProperty, ImplicitRelation, InOutExpr, IncludePredicate, IncomingExpr, LikeC4Grammar, LikeC4View, LineProperty, LinkProperty, Model, ModelViews, NavigateToProperty, OpacityProperty, OutgoingExpr, Relation, RelationBody, RelationExpr, RelationPredicateExpression, RelationProperty, RelationStringProperty, RelationStyleProperty, RelationshipKind, RelationshipStyleProperty, ShapeProperty, SpecificationElementKind, SpecificationRelationshipKind, SpecificationRule, SpecificationTag, StringProperty, StyleProperties, StyleProperty, Tag, Tags, ViewProperty, ViewRef, ViewRule, ViewRuleAutoLayout, ViewRulePredicate, ViewRulePredicateExpr, ViewRulePredicateRelations, ViewRuleStyle, ViewStringProperty, WildcardExpr];
1022
1068
  }
1023
1069
 
1024
1070
  protected override computeIsSubtype(subtype: string, supertype: string): boolean {
@@ -1037,12 +1083,14 @@ export class LikeC4AstReflection extends AbstractAstReflection {
1037
1083
  return this.isSubtype(RelationshipStyleProperty, supertype) || this.isSubtype(StyleProperty, supertype);
1038
1084
  }
1039
1085
  case CustomElementExpr:
1040
- case ElementExpr:
1086
+ case ElementExpr: {
1087
+ return this.isSubtype(ElementPredicateExpression, supertype);
1088
+ }
1089
+ case CustomRelationExpr:
1041
1090
  case IncomingExpr:
1042
1091
  case InOutExpr:
1043
- case OutgoingExpr:
1044
1092
  case RelationExpr: {
1045
- return this.isSubtype(ViewRulePredicateExpr, supertype);
1093
+ return this.isSubtype(ViewRulePredicateRelations, supertype);
1046
1094
  }
1047
1095
  case DescedantsExpr:
1048
1096
  case ElementKindExpr:
@@ -1059,6 +1107,10 @@ export class LikeC4AstReflection extends AbstractAstReflection {
1059
1107
  case DynamicViewRulePredicate: {
1060
1108
  return this.isSubtype(DynamicViewRule, supertype);
1061
1109
  }
1110
+ case ElementPredicateExpression:
1111
+ case RelationPredicateExpression: {
1112
+ return this.isSubtype(ViewRulePredicateExpr, supertype);
1113
+ }
1062
1114
  case ElementStringProperty: {
1063
1115
  return this.isSubtype(ElementProperty, supertype) || this.isSubtype(StringProperty, supertype);
1064
1116
  }
@@ -1073,7 +1125,13 @@ export class LikeC4AstReflection extends AbstractAstReflection {
1073
1125
  case LinkProperty: {
1074
1126
  return this.isSubtype(ElementProperty, supertype) || this.isSubtype(RelationProperty, supertype) || this.isSubtype(ViewProperty, supertype);
1075
1127
  }
1076
- case RelationStringProperty:
1128
+ case OutgoingExpr:
1129
+ case ViewRulePredicateRelations: {
1130
+ return this.isSubtype(RelationPredicateExpression, supertype);
1131
+ }
1132
+ case RelationStringProperty: {
1133
+ return this.isSubtype(RelationProperty, supertype) || this.isSubtype(StringProperty, supertype);
1134
+ }
1077
1135
  case RelationStyleProperty: {
1078
1136
  return this.isSubtype(RelationProperty, supertype);
1079
1137
  }
@@ -1174,6 +1232,23 @@ export class LikeC4AstReflection extends AbstractAstReflection {
1174
1232
  ]
1175
1233
  };
1176
1234
  }
1235
+ case CustomRelationExpr: {
1236
+ return {
1237
+ name: CustomRelationExpr,
1238
+ properties: [
1239
+ { name: 'body' },
1240
+ { name: 'relation' }
1241
+ ]
1242
+ };
1243
+ }
1244
+ case CustomRelationExprBody: {
1245
+ return {
1246
+ name: CustomRelationExprBody,
1247
+ properties: [
1248
+ { name: 'props', defaultValue: [] }
1249
+ ]
1250
+ };
1251
+ }
1177
1252
  case DescedantsExpr: {
1178
1253
  return {
1179
1254
  name: DescedantsExpr,
@@ -1206,7 +1281,6 @@ export class LikeC4AstReflection extends AbstractAstReflection {
1206
1281
  return {
1207
1282
  name: DynamicViewRulePredicate,
1208
1283
  properties: [
1209
- { name: 'commas', defaultValue: [] },
1210
1284
  { name: 'expressions', defaultValue: [] }
1211
1285
  ]
1212
1286
  };
@@ -1322,7 +1396,6 @@ export class LikeC4AstReflection extends AbstractAstReflection {
1322
1396
  return {
1323
1397
  name: ExcludePredicate,
1324
1398
  properties: [
1325
- { name: 'commas', defaultValue: [] },
1326
1399
  { name: 'expressions', defaultValue: [] }
1327
1400
  ]
1328
1401
  };
@@ -1400,7 +1473,6 @@ export class LikeC4AstReflection extends AbstractAstReflection {
1400
1473
  return {
1401
1474
  name: IncludePredicate,
1402
1475
  properties: [
1403
- { name: 'commas', defaultValue: [] },
1404
1476
  { name: 'expressions', defaultValue: [] }
1405
1477
  ]
1406
1478
  };
@@ -1605,7 +1677,6 @@ export class LikeC4AstReflection extends AbstractAstReflection {
1605
1677
  return {
1606
1678
  name: Tags,
1607
1679
  properties: [
1608
- { name: 'comma', defaultValue: [] },
1609
1680
  { name: 'value', defaultValue: [] }
1610
1681
  ]
1611
1682
  };
@@ -1630,7 +1701,6 @@ export class LikeC4AstReflection extends AbstractAstReflection {
1630
1701
  return {
1631
1702
  name: ViewRuleStyle,
1632
1703
  properties: [
1633
- { name: 'commas', defaultValue: [] },
1634
1704
  { name: 'styleprops', defaultValue: [] },
1635
1705
  { name: 'targets', defaultValue: [] }
1636
1706
  ]