@likec4/language-server 1.17.1 → 1.18.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 (89) hide show
  1. package/contrib/likec4.tmLanguage.json +1 -1
  2. package/dist/browser.cjs +1 -1
  3. package/dist/browser.d.cts +2 -2
  4. package/dist/browser.d.mts +2 -2
  5. package/dist/browser.d.ts +2 -2
  6. package/dist/browser.mjs +2 -2
  7. package/dist/index.cjs +1 -1
  8. package/dist/index.d.cts +2 -2
  9. package/dist/index.d.mts +2 -2
  10. package/dist/index.d.ts +2 -2
  11. package/dist/index.mjs +2 -2
  12. package/dist/protocol.d.cts +8 -5
  13. package/dist/protocol.d.mts +8 -5
  14. package/dist/protocol.d.ts +8 -5
  15. package/dist/shared/{language-server.DKV_FdPN.cjs → language-server.CO_nmHiL.cjs} +5598 -4213
  16. package/dist/shared/{language-server.BQRvVmE0.d.cts → language-server.Da6ey08o.d.cts} +390 -74
  17. package/dist/shared/{language-server.BysPcTxr.d.ts → language-server.De7S3e5Z.d.ts} +390 -74
  18. package/dist/shared/{language-server._wkyPgso.d.mts → language-server.Dj4iDjtB.d.mts} +390 -74
  19. package/dist/shared/{language-server.BIbAD1T-.mjs → language-server.oO_9JoAG.mjs} +5604 -4230
  20. package/package.json +11 -25
  21. package/src/Rpc.ts +6 -3
  22. package/src/ast.ts +124 -71
  23. package/src/generated/ast.ts +655 -39
  24. package/src/generated/grammar.ts +1 -1
  25. package/src/index.ts +1 -0
  26. package/src/like-c4.langium +170 -22
  27. package/src/logger.ts +7 -2
  28. package/src/lsp/CodeLensProvider.ts +0 -1
  29. package/src/lsp/CompletionProvider.ts +17 -2
  30. package/src/lsp/DocumentSymbolProvider.ts +5 -2
  31. package/src/lsp/HoverProvider.ts +34 -2
  32. package/src/lsp/SemanticTokenProvider.ts +58 -32
  33. package/src/model/deployments-index.ts +218 -0
  34. package/src/model/fqn-computation.ts +1 -1
  35. package/src/model/fqn-index.ts +0 -1
  36. package/src/model/index.ts +1 -0
  37. package/src/model/model-builder.ts +172 -37
  38. package/src/model/model-locator.ts +36 -7
  39. package/src/model/model-parser.ts +554 -92
  40. package/src/model-change/changeViewLayout.ts +2 -2
  41. package/src/module.ts +10 -4
  42. package/src/protocol.ts +10 -6
  43. package/src/references/index.ts +1 -0
  44. package/src/references/name-provider.ts +37 -0
  45. package/src/references/scope-computation.ts +130 -21
  46. package/src/references/scope-provider.ts +63 -36
  47. package/src/shared/NodeKindProvider.ts +15 -3
  48. package/src/utils/deploymentRef.ts +31 -0
  49. package/src/{elementRef.ts → utils/elementRef.ts} +1 -1
  50. package/src/utils/stringHash.ts +2 -2
  51. package/src/validation/_shared.ts +7 -5
  52. package/src/validation/deployment-checks.ts +144 -0
  53. package/src/validation/dynamic-view-step.ts +1 -1
  54. package/src/validation/index.ts +7 -0
  55. package/src/validation/relation.ts +1 -1
  56. package/src/validation/view-predicates/deployments.ts +56 -0
  57. package/src/validation/view-predicates/index.ts +1 -0
  58. package/src/view-utils/assignNavigateTo.ts +6 -5
  59. package/src/view-utils/index.ts +0 -1
  60. package/dist/model-graph/index.cjs +0 -10
  61. package/dist/model-graph/index.d.cts +0 -81
  62. package/dist/model-graph/index.d.mts +0 -81
  63. package/dist/model-graph/index.d.ts +0 -81
  64. package/dist/model-graph/index.mjs +0 -1
  65. package/dist/shared/language-server.D2QdbOJO.cjs +0 -1995
  66. package/dist/shared/language-server.DGrBGmsd.mjs +0 -1981
  67. package/src/model-graph/LikeC4ModelGraph.ts +0 -338
  68. package/src/model-graph/compute-view/__test__/fixture.ts +0 -630
  69. package/src/model-graph/compute-view/compute.ts +0 -788
  70. package/src/model-graph/compute-view/index.ts +0 -33
  71. package/src/model-graph/compute-view/predicates.ts +0 -509
  72. package/src/model-graph/dynamic-view/__test__/fixture.ts +0 -61
  73. package/src/model-graph/dynamic-view/compute.ts +0 -313
  74. package/src/model-graph/dynamic-view/index.ts +0 -29
  75. package/src/model-graph/index.ts +0 -3
  76. package/src/model-graph/utils/applyCustomElementProperties.ts +0 -65
  77. package/src/model-graph/utils/applyCustomRelationProperties.ts +0 -41
  78. package/src/model-graph/utils/applyViewRuleStyles.ts +0 -49
  79. package/src/model-graph/utils/buildComputeNodes.ts +0 -113
  80. package/src/model-graph/utils/buildElementNotations.ts +0 -63
  81. package/src/model-graph/utils/elementExpressionToPredicate.ts +0 -39
  82. package/src/model-graph/utils/relationExpressionToPredicates.ts +0 -43
  83. package/src/model-graph/utils/sortNodes.ts +0 -105
  84. package/src/model-graph/utils/uniqueTags.test.ts +0 -42
  85. package/src/model-graph/utils/uniqueTags.ts +0 -19
  86. package/src/utils/graphlib.ts +0 -9
  87. package/src/view-utils/resolve-extended-views.ts +0 -66
  88. package/src/view-utils/resolve-global-rules.ts +0 -88
  89. package/src/view-utils/view-hash.ts +0 -27
package/src/index.ts CHANGED
@@ -8,6 +8,7 @@ export type * from './model'
8
8
  export type * from './module'
9
9
  export { createCustomLanguageServices, createLanguageServices, LikeC4Module } from './module'
10
10
  export { LikeC4FileSystem }
11
+
11
12
  export function startLanguageServer() {
12
13
  /* browser specific setup code */
13
14
  const connection = createConnection(ProposedFeatures.all)
@@ -6,6 +6,7 @@ entry LikeC4Grammar:
6
6
  models+=Model |
7
7
  views+=ModelViews |
8
8
  globals+=Globals |
9
+ deployments+=ModelDeployments |
9
10
  likec4lib+=LikeC4Lib
10
11
  )*
11
12
  ;
@@ -18,22 +19,15 @@ LikeC4Lib:
18
19
  '}'
19
20
  '}';
20
21
 
21
- LibIcon:
22
- name=IconId;
22
+ LibIcon: name=IconId;
23
23
 
24
24
  // Specification -------------------------------------
25
25
 
26
- ElementKind:
27
- name=Id;
28
-
29
- Tag:
30
- name=Id;
31
-
32
- RelationshipKind:
33
- name=Id;
34
-
35
- CustomColor:
36
- name=CustomColorId;
26
+ ElementKind: name=Id;
27
+ Tag: name=Id;
28
+ RelationshipKind: name=Id;
29
+ CustomColor: name=CustomColorId;
30
+ DeploymentNodeKind: name=Id;
37
31
 
38
32
  SpecificationRule:
39
33
  name='specification' '{'
@@ -41,7 +35,8 @@ SpecificationRule:
41
35
  elements+=SpecificationElementKind |
42
36
  tags+=SpecificationTag |
43
37
  relationships+=SpecificationRelationshipKind |
44
- colors+=SpecificationColor
38
+ colors+=SpecificationColor |
39
+ deploymentNodes+=SpecificationDeploymentNodeKind
45
40
  )*
46
41
  '}';
47
42
 
@@ -56,6 +51,14 @@ SpecificationElementKind:
56
51
  SpecificationElementStringProperty:
57
52
  key=('technology' | 'notation') ':'? value=String ';'?;
58
53
 
54
+ SpecificationDeploymentNodeKind:
55
+ 'deploymentNode' kind=DeploymentNodeKind ('{'
56
+ props+=(
57
+ SpecificationElementStringProperty |
58
+ ElementStyleProperty
59
+ )*
60
+ '}')?;
61
+
59
62
  SpecificationTag:
60
63
  'tag' tag=Tag;
61
64
 
@@ -201,9 +204,9 @@ ModelViews:
201
204
  )*
202
205
  '}';
203
206
 
204
- type LikeC4View = ElementView | DynamicView;
207
+ type LikeC4View = ElementView | DynamicView | DeploymentView;
205
208
  LikeC4ViewRule returns LikeC4View:
206
- ElementView | DynamicView;
209
+ ElementView | DynamicView | DeploymentView;
207
210
 
208
211
  ElementView:
209
212
  'view' name=Id? (
@@ -372,7 +375,7 @@ ElementSelectorExpression infers ElementExpression:
372
375
  ElementDescedantsExpression infers ElementExpression:
373
376
  ElementRef (
374
377
  {infer ExpandElementExpression.expand=current} DotUnderscore |
375
- {infer ElementDescedantsExpression.parent=current} DotWildcard
378
+ {infer ElementDescedantsExpression.parent=current} suffix=DotWildcard
376
379
  )?
377
380
  ;
378
381
 
@@ -410,7 +413,7 @@ WhereRelationNegation:
410
413
 
411
414
  WhereRelation:
412
415
  {infer WhereRelationTag} 'tag' EqOperator value=[Tag:TagId]? |
413
- {infer WhereRelationKind} 'kind' EqOperator value=[RelationshipKind]?
416
+ {infer WhereRelationKind} 'kind' EqOperator value=[RelationshipKind:Id]?
414
417
  ;
415
418
 
416
419
  type WhereTagEqual = WhereElementTag | WhereRelationTag;
@@ -436,7 +439,7 @@ DirectedRelationExpressions infers RelationExpression:
436
439
 
437
440
  OutgoingRelationExpression:
438
441
  from=ElementExpression
439
- (isBidirectional?='<->' | '->' | '-[' kind=[RelationshipKind] ']->' | kind=[RelationshipKind:DotId])
442
+ (isBidirectional?='<->' | '->' | '-[' kind=[RelationshipKind:Id] ']->' | kind=[RelationshipKind:DotId])
440
443
  ;
441
444
 
442
445
  // Comma-separated list of ElementExpressions
@@ -509,6 +512,149 @@ NavigateToProperty:
509
512
  RelationNavigateToProperty:
510
513
  key='navigateTo' value=DynamicViewRef;
511
514
 
515
+ // Deployment -------------------------------------
516
+
517
+ ModelDeployments:
518
+ name='deployment' '{'
519
+ elements+=(
520
+ DeploymentNode |
521
+ DeploymentRelation
522
+ )*
523
+ '}';
524
+
525
+ type DeploymentElement = DeploymentNode | DeployedInstance;
526
+
527
+ DeploymentNode:
528
+ (
529
+ kind=[DeploymentNodeKind:Id] name=Id |
530
+ name=Id Eq kind=[DeploymentNodeKind:Id]
531
+ )
532
+ title=String?
533
+ body=DeploymentNodeBody?
534
+ ;
535
+
536
+ DeploymentNodeBody: '{'
537
+ tags=Tags?
538
+ props+=ElementProperty*
539
+ elements+=(
540
+ DeployedInstance |
541
+ DeploymentRelation |
542
+ DeploymentNode
543
+ )*
544
+ '}';
545
+
546
+ DeployedInstance:
547
+ (name=Id Eq)?
548
+ ('instanceOf' | 'instance' 'of')
549
+ element=ElementRef
550
+ title=String?
551
+ body=DeployedInstanceBody?
552
+ ';'?
553
+ ;
554
+
555
+ DeployedInstanceBody: '{'
556
+ tags=Tags?
557
+ props+=ElementProperty*
558
+ '}';
559
+
560
+ // Rules:
561
+ // - DeployedInstance can be referenced from DeploymentNode
562
+ // - Element can be referenced from DeployedInstance
563
+ // Forced by scope computation
564
+ type DeploymentReferenceable = DeploymentNode | DeployedInstance | Element;
565
+ DeploymentRef:
566
+ value=[DeploymentReferenceable:Id] ({infer DeploymentRef.parent=current} StickyDot value=[DeploymentReferenceable:Id])*;
567
+
568
+ DeploymentRelation:
569
+ source=DeploymentRef
570
+ ('->' | '-[' kind=[RelationshipKind:Id] ']->' | kind=[RelationshipKind:DotId])
571
+ target=DeploymentRef
572
+ (
573
+ title=String
574
+ technology=String?
575
+ )?
576
+ tags=Tags?
577
+ body=DeploymentRelationBody?
578
+ ;
579
+
580
+ DeploymentRelationBody: '{'
581
+ tags=Tags?
582
+ props+=RelationProperty*
583
+ '}'
584
+ ;
585
+
586
+ DeploymentView:
587
+ 'deployment' 'view' name=Id body=DeploymentViewBody?
588
+ ;
589
+
590
+ DeploymentViewBody: '{'
591
+ tags=Tags?
592
+ props+=ViewProperty*
593
+ rules+=DeploymentViewRule*
594
+ '}';
595
+
596
+ DeploymentViewRule:
597
+ DeploymentViewRulePredicate |
598
+ DeploymentViewRuleStyle |
599
+ ViewRuleAutoLayout
600
+ ;
601
+
602
+ DeploymentViewRuleStyle:
603
+ 'style' target=DeploymentExpressionIterator '{'
604
+ props+=(
605
+ StyleProperty |
606
+ NotationProperty
607
+ )*
608
+ '}';
609
+
610
+
611
+ DeploymentViewRulePredicate:
612
+ (isInclude?='include' | 'exclude')
613
+ expr=DeploymentViewRulePredicateExpression
614
+ ;
615
+
616
+ DeploymentViewRulePredicateExpression:
617
+ value=DeploymentExpression ({infer DeploymentViewRulePredicateExpression.prev=current} ',' (value=DeploymentExpression)?)*
618
+ ;
619
+
620
+ DeploymentExpression:
621
+ DeploymentRelationExpression |
622
+ DeploymentElementExpression
623
+ ;
624
+
625
+ DeploymentElementExpression:
626
+ {infer WildcardExpression} isWildcard?='*' |
627
+ DeploymentRefExpression
628
+ ;
629
+
630
+ DeploymentRefExpression:
631
+ ref=DeploymentRef selector=(DotUnderscore | DotWildcard)?
632
+ ;
633
+
634
+ DeploymentRelationExpression:
635
+ InOutDeploymentRelationExpression |
636
+ DirectedDeploymentRelationExpression
637
+ ;
638
+
639
+ InOutDeploymentRelationExpression infers DeploymentRelationExpression:
640
+ IncomingDeploymentRelationExpression ({infer InOutDeploymentRelationExpression.inout=current} '->')?
641
+ ;
642
+
643
+ IncomingDeploymentRelationExpression:
644
+ '->' to=DeploymentElementExpression;
645
+
646
+ DirectedDeploymentRelationExpression infers DeploymentRelationExpression:
647
+ OutgoingDeploymentRelationExpression ({infer DirectedDeploymentRelationExpression.source=current} target=DeploymentElementExpression)?
648
+ ;
649
+
650
+ OutgoingDeploymentRelationExpression:
651
+ from=DeploymentElementExpression
652
+ (isBidirectional?='<->' | '->' | '-[' kind=[RelationshipKind:Id] ']->' | kind=[RelationshipKind:DotId])
653
+ ;
654
+
655
+ DeploymentExpressionIterator:
656
+ value=DeploymentElementExpression ({infer DeploymentExpressionIterator.prev=current} ',' (value=DeploymentElementExpression)?)*
657
+ ;
512
658
  // Global -------------------------------------
513
659
 
514
660
  Globals:
@@ -545,6 +691,8 @@ GlobalStyleGroup:
545
691
  styles+=ViewRuleStyle*
546
692
  '}';
547
693
 
694
+ type FqnReferenceable = DeploymentReferenceable | Element | ExtendElement;
695
+
548
696
  // Common properties -------------------------------------
549
697
 
550
698
  LinkProperty:
@@ -635,7 +783,7 @@ CustomColorId returns string:
635
783
  IdTerminal | ElementShape | ArrowType | LineOptions | 'element' | 'model';
636
784
 
637
785
  Id returns string:
638
- IdTerminal | ElementShape | ThemeColor | ArrowType | LineOptions | 'element' | 'model' | 'group';
786
+ IdTerminal | ElementShape | ThemeColor | ArrowType | LineOptions | 'element' | 'model' | 'group' | 'node' | 'deployment';
639
787
 
640
788
  fragment EqOperator:
641
789
  (
@@ -674,8 +822,8 @@ terminal LIB_ICON: /(aws|azure|gcp|tech):[-\w]*/;
674
822
  terminal URI_WITH_SCHEMA: /\w+:\/\/\S+/;
675
823
  terminal URI_RELATIVE: /\.{0,2}\/[^\/]\S+/;
676
824
 
677
- terminal DotUnderscore: /\b\._/;
678
- terminal DotWildcard: /\b\.\*/;
825
+ terminal DotUnderscore: /\b\._(?![_a-zA-Z])/;
826
+ terminal DotWildcard: /\b\.\*{1,2}/;
679
827
  terminal Hash: '#';
680
828
 
681
829
  // No space allowed before dot
package/src/logger.ts CHANGED
@@ -1,9 +1,10 @@
1
- /* eslint-disable @typescript-eslint/no-explicit-any */
2
1
  import { type ConsolaReporter, LogLevels, rootLogger as root } from '@likec4/log'
2
+ import { BROWSER } from 'esm-env'
3
3
  import { isError } from 'remeda'
4
4
  import type { Connection } from 'vscode-languageserver'
5
5
 
6
6
  export const logger = root.withTag('lsp')
7
+ // export const logger = root
7
8
 
8
9
  export function logError(err: unknown): void {
9
10
  logger.error(err)
@@ -92,6 +93,10 @@ export function logToLspConnection(connection: Connection): void {
92
93
  }
93
94
  }
94
95
  }
95
- root.setReporters([reporter])
96
+ if (BROWSER) {
97
+ root.addReporter(reporter)
98
+ } else {
99
+ root.setReporters([reporter])
100
+ }
96
101
  logger.setReporters(root.options.reporters)
97
102
  }
@@ -7,7 +7,6 @@ import type { LikeC4Services } from '../module'
7
7
 
8
8
  export class LikeC4CodeLensProvider implements CodeLensProvider {
9
9
  constructor(private services: LikeC4Services) {
10
- //
11
10
  }
12
11
 
13
12
  async provideCodeLens(
@@ -22,6 +22,21 @@ export class LikeC4CompletionProvider extends DefaultCompletionProvider {
22
22
  if (!this.filterKeyword(context, keyword)) {
23
23
  return
24
24
  }
25
+ if (keyword.value === 'deployment' && AstUtils.hasContainerOfType(context.node, ast.isModelViews)) {
26
+ return acceptor(context, {
27
+ label: keyword.value,
28
+ detail: `Insert deployment view`,
29
+ kind: CompletionItemKind.Class,
30
+ insertTextFormat: InsertTextFormat.Snippet,
31
+ insertText: [
32
+ 'deployment view ${1:view_${TM_FILENAME_BASE}_${CURRENT_SECOND}} {',
33
+ '\ttitle \'${2:Untitled}\'',
34
+ '\t',
35
+ '\t$0',
36
+ '}'
37
+ ].join('\n')
38
+ })
39
+ }
25
40
  if (['title', 'description', 'technology'].includes(keyword.value)) {
26
41
  return acceptor(context, {
27
42
  label: keyword.value,
@@ -30,7 +45,7 @@ export class LikeC4CompletionProvider extends DefaultCompletionProvider {
30
45
  insertText: `${keyword.value} '\${0}'`
31
46
  })
32
47
  }
33
- if (['views', 'specification', 'model', 'with'].includes(keyword.value)) {
48
+ if (['views', 'specification', 'model', 'deployment', 'with'].includes(keyword.value)) {
34
49
  return acceptor(context, {
35
50
  label: keyword.value,
36
51
  detail: `Insert ${keyword.value} block`,
@@ -52,7 +67,7 @@ export class LikeC4CompletionProvider extends DefaultCompletionProvider {
52
67
  ].join('\n')
53
68
  })
54
69
  }
55
- if (keyword.value === 'dynamic') {
70
+ if (keyword.value === 'dynamic' && AstUtils.hasContainerOfType(context.node, ast.isModelViews)) {
56
71
  return acceptor(context, {
57
72
  label: keyword.value,
58
73
  detail: `Insert dynamic view`,
@@ -4,9 +4,9 @@ import type { DocumentSymbolProvider, NodeKindProvider } from 'langium/lsp'
4
4
  import { filter, isEmpty, isTruthy, map, pipe } from 'remeda'
5
5
  import { type DocumentSymbol, SymbolKind } from 'vscode-languageserver-types'
6
6
  import { ast, type LikeC4LangiumDocument } from '../ast'
7
- import { getFqnElementRef } from '../elementRef'
8
7
  import { logError } from '../logger'
9
8
  import type { LikeC4Services } from '../module'
9
+ import { getFqnElementRef } from '../utils/elementRef'
10
10
 
11
11
  export class LikeC4DocumentSymbolProvider implements DocumentSymbolProvider {
12
12
  protected readonly nodeKindProvider: NodeKindProvider
@@ -61,7 +61,10 @@ export class LikeC4DocumentSymbolProvider implements DocumentSymbolProvider {
61
61
  [...astSpec.elements, ...astSpec.tags, ...astSpec.relationships],
62
62
  map(nd => {
63
63
  try {
64
- if (ast.isSpecificationElementKind(nd) || ast.isSpecificationRelationshipKind(nd)) {
64
+ if (
65
+ ast.isSpecificationElementKind(nd) || ast.isSpecificationRelationshipKind(nd)
66
+ || ast.isSpecificationDeploymentNodeKind(nd)
67
+ ) {
65
68
  return this.getKindSymbol(nd)
66
69
  }
67
70
  if (ast.isSpecificationTag(nd)) {
@@ -4,14 +4,16 @@ import { isTruthy } from 'remeda'
4
4
  import stripIndent from 'strip-indent'
5
5
  import type { Hover } from 'vscode-languageserver-types'
6
6
  import { ast } from '../ast'
7
- import type { LikeC4ModelLocator } from '../model'
7
+ import type { LikeC4ModelLocator, LikeC4ModelParser } from '../model'
8
8
  import type { LikeC4Services } from '../module'
9
9
 
10
10
  export class LikeC4HoverProvider extends AstNodeHoverProvider {
11
+ private parser: LikeC4ModelParser
11
12
  private locator: LikeC4ModelLocator
12
13
 
13
14
  constructor(services: LikeC4Services) {
14
15
  super(services)
16
+ this.parser = services.likec4.ModelParser
15
17
  this.locator = services.likec4.ModelLocator
16
18
  }
17
19
 
@@ -27,6 +29,36 @@ export class LikeC4HoverProvider extends AstNodeHoverProvider {
27
29
  }
28
30
  }
29
31
 
32
+ if (ast.isDeploymentNode(node)) {
33
+ const el = this.parser.parseDeploymentNode(node, () => true)
34
+ const lines = [el.id as string + ' ']
35
+ if (el.title !== node.name) {
36
+ lines.push(`### ${el.title}`)
37
+ }
38
+ lines.push('Deployment: `' + el.kind + '` ')
39
+ return {
40
+ contents: {
41
+ kind: 'markdown',
42
+ value: lines.join('\n')
43
+ }
44
+ }
45
+ }
46
+
47
+ if (ast.isDeployedInstance(node)) {
48
+ const instance = this.parser.parseDeployedInstance(node, () => true)
49
+ const el = this.locator.getParsedElement(instance.element)
50
+ const lines = [instance.id + ' ', `instance of \`${instance.element}\``]
51
+ if (el) {
52
+ lines.push(`### ${el.title}`, 'Element: `' + el.kind + '` ')
53
+ }
54
+ return {
55
+ contents: {
56
+ kind: 'markdown',
57
+ value: lines.join('\n')
58
+ }
59
+ }
60
+ }
61
+
30
62
  // if (ast.isElementKind(node)) {
31
63
  // const spec = this.specIndex.get(node.name as ElementKind)
32
64
  // return {
@@ -45,7 +77,7 @@ export class LikeC4HoverProvider extends AstNodeHoverProvider {
45
77
  if (!el) {
46
78
  return
47
79
  }
48
- const lines = [el.id, `### ${el.title}`, '`' + el.kind + '` ']
80
+ const lines = [el.id, `### ${el.title}`, 'Element: `' + el.kind + '` ']
49
81
  return {
50
82
  contents: {
51
83
  kind: 'markdown',
@@ -10,6 +10,26 @@ export class LikeC4SemanticTokenProvider extends AbstractSemanticTokenProvider {
10
10
  node: AstNode,
11
11
  acceptor: SemanticTokenAcceptor
12
12
  ): void | undefined | 'prune' {
13
+ if (ast.isElement(node) || ast.isDeploymentNode(node)) {
14
+ return this.highlightNameAndKind(node, acceptor)
15
+ }
16
+ if (ast.isDeployedInstance(node)) {
17
+ if ('name' in node) {
18
+ acceptor({
19
+ node,
20
+ property: 'name',
21
+ type: SemanticTokenTypes.variable,
22
+ modifier: [
23
+ SemanticTokenModifiers.definition,
24
+ SemanticTokenModifiers.readonly
25
+ ]
26
+ })
27
+ }
28
+ return
29
+ }
30
+ if (ast.isLikeC4View(node)) {
31
+ return this.highlightView(node, acceptor)
32
+ }
13
33
  if (ast.isRelationshipKind(node)) {
14
34
  return acceptor({
15
35
  node,
@@ -70,6 +90,20 @@ export class LikeC4SemanticTokenProvider extends AbstractSemanticTokenProvider {
70
90
  })
71
91
  return 'prune'
72
92
  }
93
+ if (ast.isDeploymentRefExpression(node)) {
94
+ if (node.selector) {
95
+ acceptor({
96
+ node,
97
+ property: 'selector',
98
+ type: SemanticTokenTypes.variable,
99
+ modifier: [
100
+ SemanticTokenModifiers.definition,
101
+ SemanticTokenModifiers.readonly
102
+ ]
103
+ })
104
+ }
105
+ return
106
+ }
73
107
  if (ast.isWhereRelationKind(node) && isTruthy(node.value)) {
74
108
  acceptor({
75
109
  node,
@@ -108,6 +142,18 @@ export class LikeC4SemanticTokenProvider extends AbstractSemanticTokenProvider {
108
142
  })
109
143
  return 'prune'
110
144
  }
145
+ if (ast.isDeploymentRef(node)) {
146
+ acceptor({
147
+ node,
148
+ property: 'value',
149
+ type: node.parent ? SemanticTokenTypes.property : SemanticTokenTypes.variable,
150
+ modifier: [
151
+ SemanticTokenModifiers.definition,
152
+ SemanticTokenModifiers.readonly
153
+ ]
154
+ })
155
+ return !node.parent ? 'prune' : undefined
156
+ }
111
157
  if (ast.isElementRef(node) || ast.isFqnElementRef(node)) {
112
158
  acceptor({
113
159
  node,
@@ -137,7 +183,10 @@ export class LikeC4SemanticTokenProvider extends AbstractSemanticTokenProvider {
137
183
  })
138
184
  return
139
185
  }
140
- if (ast.isSpecificationElementKind(node) || ast.isSpecificationRelationshipKind(node)) {
186
+ if (
187
+ ast.isSpecificationElementKind(node) || ast.isSpecificationRelationshipKind(node)
188
+ || ast.isSpecificationDeploymentNodeKind(node)
189
+ ) {
141
190
  acceptor({
142
191
  node,
143
192
  property: 'kind',
@@ -196,30 +245,13 @@ export class LikeC4SemanticTokenProvider extends AbstractSemanticTokenProvider {
196
245
  property: 'key',
197
246
  type: SemanticTokenTypes.property
198
247
  })
199
- if (ast.isIconProperty(node)) {
200
- if (node.libicon) {
201
- acceptor({
202
- node,
203
- property: 'libicon',
204
- type: SemanticTokenTypes.enum,
205
- modifier: [SemanticTokenModifiers.defaultLibrary]
206
- })
207
- } else {
208
- if (node.value === 'none') {
209
- acceptor({
210
- node,
211
- property: 'value',
212
- type: SemanticTokenTypes.enum,
213
- modifier: [SemanticTokenModifiers.defaultLibrary]
214
- })
215
- } else {
216
- acceptor({
217
- node,
218
- property: 'value',
219
- type: SemanticTokenTypes.string
220
- })
221
- }
222
- }
248
+ if (ast.isIconProperty(node) && (node.libicon || node.value === 'none')) {
249
+ acceptor({
250
+ node,
251
+ property: node.libicon ? 'libicon' : 'value',
252
+ type: SemanticTokenTypes.enum,
253
+ modifier: [SemanticTokenModifiers.defaultLibrary]
254
+ })
223
255
  return 'prune'
224
256
  }
225
257
  if ('value' in node && node.value) {
@@ -252,15 +284,9 @@ export class LikeC4SemanticTokenProvider extends AbstractSemanticTokenProvider {
252
284
  }
253
285
  return 'prune'
254
286
  }
255
- if (ast.isElement(node)) {
256
- return this.highlightAstElement(node, acceptor)
257
- }
258
- if (ast.isLikeC4View(node)) {
259
- return this.highlightView(node, acceptor)
260
- }
261
287
  }
262
288
 
263
- private highlightAstElement(node: ast.Element, acceptor: SemanticTokenAcceptor) {
289
+ private highlightNameAndKind(node: ast.Element | ast.DeploymentNode, acceptor: SemanticTokenAcceptor) {
264
290
  acceptor({
265
291
  node,
266
292
  property: 'name',