@likec4/language-server 1.18.0 → 1.19.1

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 (250) hide show
  1. package/dist/LikeC4FileSystem.d.ts +13 -0
  2. package/dist/LikeC4FileSystem.js +27 -0
  3. package/dist/Rpc.d.ts +9 -0
  4. package/dist/Rpc.js +132 -0
  5. package/dist/ast.d.ts +200 -0
  6. package/dist/ast.js +276 -0
  7. package/dist/browser.d.ts +7 -20
  8. package/dist/browser.js +13 -0
  9. package/dist/documentation/documentation-provider.d.ts +8 -0
  10. package/dist/documentation/documentation-provider.js +46 -0
  11. package/dist/documentation/index.d.ts +1 -0
  12. package/dist/documentation/index.js +1 -0
  13. package/dist/formatting/LikeC4Formatter.d.ts +27 -0
  14. package/dist/formatting/LikeC4Formatter.js +261 -0
  15. package/dist/formatting/utils.d.ts +6 -0
  16. package/dist/formatting/utils.js +15 -0
  17. package/dist/generated/ast.d.ts +1242 -0
  18. package/dist/generated/ast.js +1945 -0
  19. package/dist/generated/grammar.d.ts +6 -0
  20. package/dist/generated/grammar.js +3 -0
  21. package/dist/generated/module.d.ts +9 -0
  22. package/dist/generated/module.js +23 -0
  23. package/dist/generated-lib/icons.d.ts +1 -0
  24. package/dist/{likec4lib.mjs → generated-lib/icons.js} +1 -6
  25. package/dist/index.d.ts +9 -31
  26. package/dist/index.js +14 -0
  27. package/dist/like-c4.langium +845 -0
  28. package/dist/likec4lib.d.ts +4 -6
  29. package/dist/likec4lib.js +4 -0
  30. package/dist/logger.d.ts +7 -0
  31. package/dist/logger.js +73 -0
  32. package/dist/lsp/CodeLensProvider.d.ts +9 -0
  33. package/dist/lsp/CodeLensProvider.js +40 -0
  34. package/dist/lsp/CompletionProvider.d.ts +6 -0
  35. package/dist/lsp/CompletionProvider.js +135 -0
  36. package/dist/lsp/DocumentHighlightProvider.d.ts +9 -0
  37. package/dist/lsp/DocumentHighlightProvider.js +10 -0
  38. package/dist/lsp/DocumentLinkProvider.d.ts +11 -0
  39. package/dist/lsp/DocumentLinkProvider.js +49 -0
  40. package/dist/lsp/DocumentSymbolProvider.d.ts +32 -0
  41. package/dist/lsp/DocumentSymbolProvider.js +274 -0
  42. package/dist/lsp/HoverProvider.d.ts +10 -0
  43. package/dist/lsp/HoverProvider.js +69 -0
  44. package/dist/lsp/RenameProvider.d.ts +5 -0
  45. package/dist/lsp/RenameProvider.js +6 -0
  46. package/dist/lsp/SemanticTokenProvider.d.ts +7 -0
  47. package/dist/lsp/SemanticTokenProvider.js +297 -0
  48. package/dist/lsp/index.d.ts +7 -0
  49. package/dist/lsp/index.js +7 -0
  50. package/dist/model/deployments-index.d.ts +60 -0
  51. package/dist/model/deployments-index.js +181 -0
  52. package/dist/model/fqn-computation.d.ts +3 -0
  53. package/dist/model/fqn-computation.js +72 -0
  54. package/dist/model/fqn-index.d.ts +25 -0
  55. package/dist/model/fqn-index.js +96 -0
  56. package/dist/model/index.d.ts +6 -0
  57. package/dist/model/index.js +6 -0
  58. package/dist/model/model-builder.d.ts +32 -0
  59. package/dist/model/model-builder.js +598 -0
  60. package/dist/model/model-locator.d.ts +23 -0
  61. package/dist/model/model-locator.js +126 -0
  62. package/dist/model/model-parser-where.d.ts +3 -0
  63. package/dist/model/model-parser-where.js +70 -0
  64. package/dist/model/model-parser.d.ts +292 -0
  65. package/dist/model/model-parser.js +72 -0
  66. package/dist/model/parser/Base.d.ts +28 -0
  67. package/dist/model/parser/Base.js +87 -0
  68. package/dist/model/parser/DeploymentModelParser.d.ts +33 -0
  69. package/dist/model/parser/DeploymentModelParser.js +162 -0
  70. package/dist/model/parser/DeploymentViewParser.d.ts +38 -0
  71. package/dist/model/parser/DeploymentViewParser.js +98 -0
  72. package/dist/model/parser/FqnRefParser.d.ts +29 -0
  73. package/dist/model/parser/FqnRefParser.js +108 -0
  74. package/dist/model/parser/GlobalsParser.d.ts +66 -0
  75. package/dist/model/parser/GlobalsParser.js +80 -0
  76. package/dist/model/parser/ModelParser.d.ts +27 -0
  77. package/dist/model/parser/ModelParser.js +122 -0
  78. package/dist/model/parser/PredicatesParser.d.ts +34 -0
  79. package/dist/model/parser/PredicatesParser.js +272 -0
  80. package/dist/model/parser/SpecificationParser.d.ts +27 -0
  81. package/dist/model/parser/SpecificationParser.js +120 -0
  82. package/dist/model/parser/ViewsParser.d.ts +64 -0
  83. package/dist/model/parser/ViewsParser.js +377 -0
  84. package/dist/model-change/ModelChanges.d.ts +15 -0
  85. package/dist/model-change/ModelChanges.js +89 -0
  86. package/dist/model-change/changeElementStyle.d.ts +16 -0
  87. package/dist/model-change/changeElementStyle.js +136 -0
  88. package/dist/model-change/changeViewLayout.d.ts +12 -0
  89. package/dist/model-change/changeViewLayout.js +32 -0
  90. package/dist/model-change/saveManualLayout.d.ts +11 -0
  91. package/dist/model-change/saveManualLayout.js +27 -0
  92. package/dist/module.d.ts +70 -0
  93. package/dist/module.js +162 -0
  94. package/dist/protocol.d.ts +38 -23
  95. package/dist/protocol.js +15 -0
  96. package/dist/references/index.d.ts +3 -0
  97. package/dist/references/index.js +3 -0
  98. package/dist/references/name-provider.d.ts +9 -0
  99. package/dist/references/name-provider.js +33 -0
  100. package/dist/references/scope-computation.d.ts +20 -0
  101. package/dist/references/scope-computation.js +281 -0
  102. package/dist/references/scope-provider.d.ts +16 -0
  103. package/dist/references/scope-provider.js +165 -0
  104. package/dist/shared/NodeKindProvider.d.ts +15 -0
  105. package/dist/shared/NodeKindProvider.js +108 -0
  106. package/dist/shared/WorkspaceManager.d.ts +18 -0
  107. package/dist/shared/WorkspaceManager.js +36 -0
  108. package/dist/shared/WorkspaceSymbolProvider.d.ts +3 -0
  109. package/dist/shared/WorkspaceSymbolProvider.js +3 -0
  110. package/dist/shared/index.d.ts +3 -0
  111. package/dist/shared/index.js +3 -0
  112. package/dist/test/index.d.ts +1 -0
  113. package/dist/test/index.js +1 -0
  114. package/dist/test/setup.d.ts +1 -0
  115. package/dist/test/setup.js +7 -0
  116. package/dist/test/testServices.d.ts +22 -0
  117. package/dist/test/testServices.js +119 -0
  118. package/dist/utils/elementRef.d.ts +11 -0
  119. package/dist/utils/elementRef.js +15 -0
  120. package/dist/utils/fqnRef.d.ts +8 -0
  121. package/dist/utils/fqnRef.js +46 -0
  122. package/dist/utils/index.d.ts +1 -0
  123. package/dist/utils/index.js +1 -0
  124. package/dist/utils/printDocs.d.ts +2 -0
  125. package/dist/utils/printDocs.js +1 -0
  126. package/dist/utils/stringHash.d.ts +1 -0
  127. package/dist/utils/stringHash.js +5 -0
  128. package/dist/validation/_shared.d.ts +3 -0
  129. package/dist/validation/_shared.js +22 -0
  130. package/dist/validation/deployment-checks.d.ts +6 -0
  131. package/dist/validation/deployment-checks.js +114 -0
  132. package/dist/validation/dynamic-view-rule.d.ts +4 -0
  133. package/dist/validation/dynamic-view-rule.js +17 -0
  134. package/dist/validation/dynamic-view-step.d.ts +4 -0
  135. package/dist/validation/dynamic-view-step.js +29 -0
  136. package/dist/validation/element.d.ts +4 -0
  137. package/dist/validation/element.js +49 -0
  138. package/dist/validation/index.d.ts +15 -0
  139. package/dist/validation/index.js +152 -0
  140. package/dist/validation/property-checks.d.ts +6 -0
  141. package/dist/validation/property-checks.js +39 -0
  142. package/dist/validation/relation.d.ts +5 -0
  143. package/dist/validation/relation.js +56 -0
  144. package/dist/validation/specification.d.ts +11 -0
  145. package/dist/validation/specification.js +136 -0
  146. package/dist/validation/view-predicates/element-with.d.ts +4 -0
  147. package/dist/validation/view-predicates/element-with.js +31 -0
  148. package/dist/validation/view-predicates/expanded-element.d.ts +4 -0
  149. package/dist/validation/view-predicates/expanded-element.js +12 -0
  150. package/dist/validation/view-predicates/expression-v2.d.ts +5 -0
  151. package/dist/validation/view-predicates/expression-v2.js +83 -0
  152. package/dist/validation/view-predicates/incoming.d.ts +4 -0
  153. package/dist/validation/view-predicates/incoming.js +16 -0
  154. package/dist/validation/view-predicates/index.d.ts +6 -0
  155. package/dist/validation/view-predicates/index.js +6 -0
  156. package/dist/validation/view-predicates/outgoing.d.ts +4 -0
  157. package/dist/validation/view-predicates/outgoing.js +16 -0
  158. package/dist/validation/view-predicates/relation-with.d.ts +4 -0
  159. package/dist/validation/view-predicates/relation-with.js +13 -0
  160. package/dist/validation/view.d.ts +4 -0
  161. package/dist/validation/view.js +23 -0
  162. package/dist/view-utils/assignNavigateTo.d.ts +2 -0
  163. package/dist/view-utils/assignNavigateTo.js +25 -0
  164. package/dist/view-utils/index.d.ts +2 -0
  165. package/dist/view-utils/index.js +2 -0
  166. package/dist/view-utils/manual-layout.d.ts +7 -0
  167. package/dist/view-utils/manual-layout.js +99 -0
  168. package/dist/view-utils/resolve-relative-paths.d.ts +2 -0
  169. package/dist/view-utils/resolve-relative-paths.js +78 -0
  170. package/dist/views/configurable-layouter.d.ts +7 -0
  171. package/dist/views/configurable-layouter.js +55 -0
  172. package/dist/views/index.d.ts +1 -0
  173. package/dist/views/index.js +1 -0
  174. package/dist/views/likec4-views.d.ts +26 -0
  175. package/dist/views/likec4-views.js +113 -0
  176. package/package.json +40 -54
  177. package/src/LikeC4FileSystem.ts +22 -21
  178. package/src/Rpc.ts +13 -7
  179. package/src/ast.ts +44 -133
  180. package/src/browser.ts +11 -11
  181. package/src/documentation/documentation-provider.ts +52 -0
  182. package/src/documentation/index.ts +1 -0
  183. package/src/generated/ast.ts +177 -177
  184. package/src/generated/grammar.ts +1 -1
  185. package/src/index.ts +13 -9
  186. package/src/like-c4.langium +37 -34
  187. package/src/logger.ts +34 -55
  188. package/src/lsp/CompletionProvider.ts +4 -4
  189. package/src/lsp/DocumentSymbolProvider.ts +110 -28
  190. package/src/lsp/HoverProvider.ts +5 -3
  191. package/src/lsp/SemanticTokenProvider.ts +2 -2
  192. package/src/model/deployments-index.ts +18 -14
  193. package/src/model/fqn-computation.ts +8 -8
  194. package/src/model/model-builder.ts +62 -60
  195. package/src/model/model-parser.ts +62 -1574
  196. package/src/model/parser/Base.ts +107 -0
  197. package/src/model/parser/DeploymentModelParser.ts +192 -0
  198. package/src/model/parser/DeploymentViewParser.ts +116 -0
  199. package/src/model/parser/FqnRefParser.ts +118 -0
  200. package/src/model/parser/GlobalsParser.ts +96 -0
  201. package/src/model/parser/ModelParser.ts +141 -0
  202. package/src/model/parser/PredicatesParser.ts +291 -0
  203. package/src/model/parser/SpecificationParser.ts +133 -0
  204. package/src/model/parser/ViewsParser.ts +428 -0
  205. package/src/module.ts +71 -25
  206. package/src/protocol.ts +29 -4
  207. package/src/references/scope-computation.ts +35 -35
  208. package/src/references/scope-provider.ts +13 -7
  209. package/src/utils/{deploymentRef.ts → fqnRef.ts} +27 -2
  210. package/src/validation/_shared.ts +0 -1
  211. package/src/validation/deployment-checks.ts +49 -62
  212. package/src/validation/dynamic-view-rule.ts +5 -4
  213. package/src/validation/dynamic-view-step.ts +23 -26
  214. package/src/validation/index.ts +100 -9
  215. package/src/validation/property-checks.ts +11 -10
  216. package/src/validation/specification.ts +38 -38
  217. package/src/validation/view-predicates/element-with.ts +6 -5
  218. package/src/validation/view-predicates/expanded-element.ts +6 -5
  219. package/src/validation/view-predicates/expression-v2.ts +101 -0
  220. package/src/validation/view-predicates/incoming.ts +6 -5
  221. package/src/validation/view-predicates/index.ts +1 -1
  222. package/src/validation/view-predicates/outgoing.ts +6 -5
  223. package/src/validation/view-predicates/relation-with.ts +6 -5
  224. package/src/validation/view.ts +5 -5
  225. package/src/view-utils/assignNavigateTo.ts +1 -1
  226. package/src/view-utils/manual-layout.ts +25 -0
  227. package/src/views/configurable-layouter.ts +65 -0
  228. package/src/views/index.ts +1 -0
  229. package/src/views/likec4-views.ts +139 -0
  230. package/dist/browser.cjs +0 -25
  231. package/dist/browser.d.cts +0 -23
  232. package/dist/browser.d.mts +0 -23
  233. package/dist/browser.mjs +0 -20
  234. package/dist/index.cjs +0 -53
  235. package/dist/index.d.cts +0 -34
  236. package/dist/index.d.mts +0 -34
  237. package/dist/index.mjs +0 -46
  238. package/dist/likec4lib.cjs +0 -1546
  239. package/dist/likec4lib.d.cts +0 -6
  240. package/dist/likec4lib.d.mts +0 -6
  241. package/dist/protocol.cjs +0 -25
  242. package/dist/protocol.d.cts +0 -48
  243. package/dist/protocol.d.mts +0 -48
  244. package/dist/protocol.mjs +0 -17
  245. package/dist/shared/language-server.CO_nmHiL.cjs +0 -7689
  246. package/dist/shared/language-server.Da6ey08o.d.cts +0 -1619
  247. package/dist/shared/language-server.De7S3e5Z.d.ts +0 -1619
  248. package/dist/shared/language-server.Dj4iDjtB.d.mts +0 -1619
  249. package/dist/shared/language-server.oO_9JoAG.mjs +0 -7666
  250. package/src/validation/view-predicates/deployments.ts +0 -56
package/src/index.ts CHANGED
@@ -1,26 +1,30 @@
1
1
  import { startLanguageServer as startLanguim } from 'langium/lsp'
2
2
  import { createConnection, ProposedFeatures } from 'vscode-languageserver/node'
3
3
  import { LikeC4FileSystem } from './LikeC4FileSystem'
4
- import { createLanguageServices } from './module'
4
+ import { type LikeC4Services, type LikeC4SharedServices, createCustomLanguageServices } from './module'
5
+ import { ConfigurableLayouter } from './views/configurable-layouter'
5
6
 
6
7
  export { logger as lspLogger, setLogLevel } from './logger'
7
- export type * from './model'
8
- export type * from './module'
8
+
9
+ export type { DocumentParser, LikeC4ModelBuilder, LikeC4ModelLocator, LikeC4ModelParser } from './model'
10
+
9
11
  export { createCustomLanguageServices, createLanguageServices, LikeC4Module } from './module'
12
+ export type { LikeC4Services, LikeC4SharedServices } from './module'
13
+ export type { LikeC4Views } from './views'
10
14
  export { LikeC4FileSystem }
11
15
 
12
- export function startLanguageServer() {
16
+ export function startLanguageServer(): {
17
+ shared: LikeC4SharedServices
18
+ likec4: LikeC4Services
19
+ } {
13
20
  /* browser specific setup code */
14
21
  const connection = createConnection(ProposedFeatures.all)
15
22
 
16
23
  // Inject the shared services and language-specific services
17
- const services = createLanguageServices({ connection, ...LikeC4FileSystem })
24
+ const services = createCustomLanguageServices({ connection, ...LikeC4FileSystem }, ConfigurableLayouter)
18
25
 
19
26
  // Start the language server with the shared services
20
27
  startLanguim(services.shared)
21
28
 
22
- return {
23
- ...services,
24
- connection
25
- }
29
+ return services
26
30
  }
@@ -545,7 +545,7 @@ DeploymentNodeBody: '{'
545
545
 
546
546
  DeployedInstance:
547
547
  (name=Id Eq)?
548
- ('instanceOf' | 'instance' 'of')
548
+ 'instanceOf'
549
549
  element=ElementRef
550
550
  title=String?
551
551
  body=DeployedInstanceBody?
@@ -557,18 +557,20 @@ DeployedInstanceBody: '{'
557
557
  props+=ElementProperty*
558
558
  '}';
559
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])*;
560
+ type Referenceable = DeploymentNode | DeployedInstance | Element;
561
+ // Reference to Elements in logical or deployment model
562
+ // Scope computation is based on the parent element:
563
+ // - If parent is DeploymentNode, then it can reference nested DeploymentNodes and DeployedInstances
564
+ // - If parent is DeployedInstance, then it can reference nested Element
565
+ // - If parent is Element, then it can reference nested Element
566
+ // Mix of DeploymentRef and ElementRef
567
+ FqnRef:
568
+ value=[Referenceable:Id] ({infer FqnRef.parent=current} StickyDot value=[Referenceable:Id])*;
567
569
 
568
570
  DeploymentRelation:
569
- source=DeploymentRef
571
+ source=FqnRef
570
572
  ('->' | '-[' kind=[RelationshipKind:Id] ']->' | kind=[RelationshipKind:DotId])
571
- target=DeploymentRef
573
+ target=FqnRef
572
574
  (
573
575
  title=String
574
576
  technology=String?
@@ -600,7 +602,7 @@ DeploymentViewRule:
600
602
  ;
601
603
 
602
604
  DeploymentViewRuleStyle:
603
- 'style' target=DeploymentExpressionIterator '{'
605
+ 'style' targets=FqnExpressions '{'
604
606
  props+=(
605
607
  StyleProperty |
606
608
  NotationProperty
@@ -614,46 +616,47 @@ DeploymentViewRulePredicate:
614
616
  ;
615
617
 
616
618
  DeploymentViewRulePredicateExpression:
617
- value=DeploymentExpression ({infer DeploymentViewRulePredicateExpression.prev=current} ',' (value=DeploymentExpression)?)*
619
+ value=ExpressionV2 ({infer DeploymentViewRulePredicateExpression.prev=current} ',' (value=ExpressionV2)?)*
618
620
  ;
619
621
 
620
- DeploymentExpression:
621
- DeploymentRelationExpression |
622
- DeploymentElementExpression
622
+ ExpressionV2:
623
+ RelationExpr |
624
+ FqnExpr
623
625
  ;
624
626
 
625
- DeploymentElementExpression:
627
+
628
+ FqnExpr:
626
629
  {infer WildcardExpression} isWildcard?='*' |
627
- DeploymentRefExpression
630
+ FqnRefExpr
628
631
  ;
629
632
 
630
- DeploymentRefExpression:
631
- ref=DeploymentRef selector=(DotUnderscore | DotWildcard)?
633
+ FqnRefExpr:
634
+ ref=FqnRef selector=(DotUnderscore | DotWildcard)?
632
635
  ;
633
636
 
634
- DeploymentRelationExpression:
635
- InOutDeploymentRelationExpression |
636
- DirectedDeploymentRelationExpression
637
+ RelationExpr:
638
+ InOutRelationExpr |
639
+ DirectedRelationExpr
637
640
  ;
638
641
 
639
- InOutDeploymentRelationExpression infers DeploymentRelationExpression:
640
- IncomingDeploymentRelationExpression ({infer InOutDeploymentRelationExpression.inout=current} '->')?
642
+ InOutRelationExpr infers RelationExpr:
643
+ IncomingRelationExpr ({infer InOutRelationExpr.inout=current} '->')?
641
644
  ;
642
645
 
643
- IncomingDeploymentRelationExpression:
644
- '->' to=DeploymentElementExpression;
646
+ IncomingRelationExpr:
647
+ '->' to=FqnExpr;
645
648
 
646
- DirectedDeploymentRelationExpression infers DeploymentRelationExpression:
647
- OutgoingDeploymentRelationExpression ({infer DirectedDeploymentRelationExpression.source=current} target=DeploymentElementExpression)?
649
+ DirectedRelationExpr infers RelationExpr:
650
+ OutgoingRelationExpr ({infer DirectedRelationExpr.source=current} target=FqnExpr)?
648
651
  ;
649
652
 
650
- OutgoingDeploymentRelationExpression:
651
- from=DeploymentElementExpression
653
+ OutgoingRelationExpr:
654
+ from=FqnExpr
652
655
  (isBidirectional?='<->' | '->' | '-[' kind=[RelationshipKind:Id] ']->' | kind=[RelationshipKind:DotId])
653
656
  ;
654
657
 
655
- DeploymentExpressionIterator:
656
- value=DeploymentElementExpression ({infer DeploymentExpressionIterator.prev=current} ',' (value=DeploymentElementExpression)?)*
658
+ FqnExpressions:
659
+ value=FqnExpr ({infer FqnExpressions.prev=current} ',' (value=FqnExpr)?)*
657
660
  ;
658
661
  // Global -------------------------------------
659
662
 
@@ -691,7 +694,7 @@ GlobalStyleGroup:
691
694
  styles+=ViewRuleStyle*
692
695
  '}';
693
696
 
694
- type FqnReferenceable = DeploymentReferenceable | Element | ExtendElement;
697
+ type FqnReferenceable = Referenceable | Element | ExtendElement;
695
698
 
696
699
  // Common properties -------------------------------------
697
700
 
@@ -783,7 +786,7 @@ CustomColorId returns string:
783
786
  IdTerminal | ElementShape | ArrowType | LineOptions | 'element' | 'model';
784
787
 
785
788
  Id returns string:
786
- IdTerminal | ElementShape | ThemeColor | ArrowType | LineOptions | 'element' | 'model' | 'group' | 'node' | 'deployment';
789
+ IdTerminal | ElementShape | ThemeColor | ArrowType | LineOptions | 'element' | 'model' | 'group' | 'node' | 'deployment' | 'instance';
787
790
 
788
791
  fragment EqOperator:
789
792
  (
package/src/logger.ts CHANGED
@@ -1,6 +1,6 @@
1
- import { type ConsolaReporter, LogLevels, rootLogger as root } from '@likec4/log'
1
+ import { nonexhaustive } from '@likec4/core'
2
+ import { type ConsolaReporter, formatLogObj, LogLevels, rootLogger as root } from '@likec4/log'
2
3
  import { BROWSER } from 'esm-env'
3
- import { isError } from 'remeda'
4
4
  import type { Connection } from 'vscode-languageserver'
5
5
 
6
6
  export const logger = root.withTag('lsp')
@@ -22,76 +22,55 @@ export function setLogLevel(level: keyof typeof LogLevels): void {
22
22
  logger.level = LogLevels[level]
23
23
  }
24
24
 
25
- export function logErrorToTelemetry(connection: Connection): void {
26
- const reporter: ConsolaReporter = {
27
- log: ({ level, ...logObj }, ctx) => {
28
- if (level !== LogLevels.error && level !== LogLevels.fatal) {
29
- return
30
- }
31
- const tag = logObj.tag || ''
32
- const parts = logObj.args.map((arg) => {
33
- if (isError(arg)) {
34
- return arg.stack ?? arg.message
35
- }
36
- if (typeof arg === 'string') {
37
- return arg
38
- }
39
- return '' + arg
40
- })
41
- if (tag) {
42
- parts.unshift(`[${tag}]`)
43
- }
44
- const message = parts.join(' ')
45
- connection.telemetry.logEvent({ eventName: 'error', error: message })
46
- }
47
- }
48
- root.addReporter(reporter)
49
- logger.setReporters(root.options.reporters)
50
- }
51
-
52
25
  export function logToLspConnection(connection: Connection): void {
53
26
  const reporter: ConsolaReporter = {
54
- log: ({ level, ...logObj }, ctx) => {
55
- const tag = logObj.tag || ''
56
- const parts = logObj.args.map((arg) => {
57
- if (isError(arg)) {
58
- return arg.stack ?? arg.message
27
+ log: (logObj, _ctx) => {
28
+ const { message, error } = formatLogObj(logObj)
29
+ switch (logObj.type) {
30
+ case 'silent': {
31
+ // ignore
32
+ break
59
33
  }
60
- if (typeof arg === 'string') {
61
- return arg
34
+ case 'verbose':
35
+ case 'trace': {
36
+ connection.tracer.log(message)
37
+ break
62
38
  }
63
- return '' + arg
64
- })
65
- if (tag) {
66
- parts.unshift(`[${tag}]`)
67
- }
68
- const message = parts.join(' ')
69
- switch (true) {
70
- case level >= LogLevels.debug: {
39
+ case 'debug': {
71
40
  connection.console.debug(message)
72
41
  break
73
42
  }
74
- // case level >= LogLevels.info: {
75
- // connection.console.info(message)
76
- // break
77
- // }
78
- case level >= LogLevels.log: {
43
+ case 'log': {
44
+ connection.console.log(message)
45
+ break
46
+ }
47
+ case 'info':
48
+ case 'box':
49
+ case 'ready':
50
+ case 'start':
51
+ case 'success': {
79
52
  connection.console.info(message)
80
53
  break
81
54
  }
82
- case level >= LogLevels.warn: {
55
+ case 'warn': {
83
56
  connection.console.warn(message)
84
57
  break
85
58
  }
86
- case level >= LogLevels.fatal: {
59
+ case 'fail':
60
+ case 'error':
61
+ case 'fatal': {
87
62
  connection.console.error(message)
63
+ if (error) {
64
+ connection.telemetry.logEvent({ eventName: 'error', ...error })
65
+ } else {
66
+ connection.telemetry.logEvent({ eventName: 'error', message })
67
+ }
88
68
  break
89
69
  }
90
- default: {
91
- connection.console.log(message)
92
- }
70
+ default:
71
+ nonexhaustive(logObj.type)
93
72
  }
94
- }
73
+ },
95
74
  }
96
75
  if (BROWSER) {
97
76
  root.addReporter(reporter)
@@ -32,7 +32,7 @@ export class LikeC4CompletionProvider extends DefaultCompletionProvider {
32
32
  'deployment view ${1:view_${TM_FILENAME_BASE}_${CURRENT_SECOND}} {',
33
33
  '\ttitle \'${2:Untitled}\'',
34
34
  '\t',
35
- '\t$0',
35
+ '\tinclude $0',
36
36
  '}'
37
37
  ].join('\n')
38
38
  })
@@ -89,7 +89,7 @@ export class LikeC4CompletionProvider extends DefaultCompletionProvider {
89
89
  detail: `Insert ${keyword.value} block`,
90
90
  kind: CompletionItemKind.Module,
91
91
  insertTextFormat: InsertTextFormat.Snippet,
92
- insertText: `${keyword.value} \${1:name} \${2:*} {\n\t\${3|color,shape,border,opacity,icon|} \$0\n}`
92
+ insertText: `${keyword.value} \${1:name} \${2:*} {\n\t\${3|color,shape,border,opacity,icon|} $0\n}`
93
93
  })
94
94
  }
95
95
  if (AstUtils.hasContainerOfType(context.node, anyPass([ast.isModelViews, ast.isGlobalStyleGroup]))) {
@@ -98,7 +98,7 @@ export class LikeC4CompletionProvider extends DefaultCompletionProvider {
98
98
  detail: `Insert ${keyword.value} block`,
99
99
  kind: CompletionItemKind.Module,
100
100
  insertTextFormat: InsertTextFormat.Snippet,
101
- insertText: `${keyword.value} \${1:*} {\n\t\${2|color,shape,border,opacity,icon|} \$0\n}`
101
+ insertText: `${keyword.value} \${1:*} {\n\t\${2|color,shape,border,opacity,icon|} $0\n}`
102
102
  })
103
103
  }
104
104
  return acceptor(context, {
@@ -106,7 +106,7 @@ export class LikeC4CompletionProvider extends DefaultCompletionProvider {
106
106
  detail: `Insert ${keyword.value} block`,
107
107
  kind: CompletionItemKind.Module,
108
108
  insertTextFormat: InsertTextFormat.Snippet,
109
- insertText: `${keyword.value} {\n\t\${1|color,shape,border,opacity,icon|} \$0\n}`
109
+ insertText: `${keyword.value} {\n\t\${1|color,shape,border,opacity,icon|} $0\n}`
110
110
  })
111
111
  }
112
112
  if (keyword.value === 'extend') {
@@ -1,35 +1,44 @@
1
1
  import { nonexhaustive } from '@likec4/core'
2
- import { type AstNode, GrammarUtils, type MaybePromise } from 'langium'
2
+ import { type AstNode, type MaybePromise, AstUtils, GrammarUtils } from 'langium'
3
3
  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
- import { ast, type LikeC4LangiumDocument } from '../ast'
7
- import { logError } from '../logger'
6
+ import { type LikeC4LangiumDocument, ast } from '../ast'
7
+ import { logError, logWarnError } from '../logger'
8
+ import type { LikeC4ModelLocator, LikeC4ModelParser } from '../model'
8
9
  import type { LikeC4Services } from '../module'
10
+ import type { LikeC4NameProvider } from '../references'
9
11
  import { getFqnElementRef } from '../utils/elementRef'
10
12
 
11
13
  export class LikeC4DocumentSymbolProvider implements DocumentSymbolProvider {
12
14
  protected readonly nodeKindProvider: NodeKindProvider
15
+ protected readonly nameProvider: LikeC4NameProvider
16
+ protected readonly parser: LikeC4ModelParser
17
+ protected readonly locator: LikeC4ModelLocator
13
18
 
14
19
  constructor(private services: LikeC4Services) {
15
20
  this.nodeKindProvider = services.shared.lsp.NodeKindProvider
21
+ this.parser = services.likec4.ModelParser
22
+ this.locator = services.likec4.ModelLocator
23
+ this.nameProvider = services.references.NameProvider
16
24
  }
17
25
 
18
26
  getSymbols({
19
27
  parseResult: {
20
- value: { specifications, models, views, likec4lib }
21
- }
28
+ value: { specifications, models, deployments, views, likec4lib },
29
+ },
22
30
  }: LikeC4LangiumDocument): MaybePromise<DocumentSymbol[]> {
23
31
  return [
24
32
  ...likec4lib.map(l => () => this.getLikec4LibSymbol(l)),
25
33
  ...specifications.map(s => () => this.getSpecSymbol(s)),
26
34
  ...models.map(s => () => this.getModelSymbol(s)),
27
- ...views.map(s => () => this.getModelViewsSymbol(s))
35
+ ...deployments.map(s => () => this.getDeploymentModelSymbol(s)),
36
+ ...views.map(s => () => this.getModelViewsSymbol(s)),
28
37
  ].flatMap(fn => {
29
38
  try {
30
39
  return fn() ?? []
31
40
  } catch (e) {
32
- logError(e)
41
+ logWarnError(e)
33
42
  return []
34
43
  }
35
44
  })
@@ -46,8 +55,8 @@ export class LikeC4DocumentSymbolProvider implements DocumentSymbolProvider {
46
55
  name: 'icons',
47
56
  range: cstModel.range,
48
57
  selectionRange: GrammarUtils.findNodeForKeyword(cstModel, 'icons')?.range ?? cstModel.range,
49
- children
50
- }
58
+ children,
59
+ },
51
60
  ]
52
61
  }
53
62
 
@@ -71,12 +80,12 @@ export class LikeC4DocumentSymbolProvider implements DocumentSymbolProvider {
71
80
  return this.getTagSymbol(nd)
72
81
  }
73
82
  } catch (e) {
74
- logError(e)
83
+ logWarnError(e)
75
84
  return null
76
85
  }
77
86
  nonexhaustive(nd)
78
87
  }),
79
- filter(isTruthy)
88
+ filter(isTruthy),
80
89
  )
81
90
 
82
91
  if (specSymbols.length === 0) return []
@@ -87,8 +96,8 @@ export class LikeC4DocumentSymbolProvider implements DocumentSymbolProvider {
87
96
  name: astSpec.name,
88
97
  range: cstModel.range,
89
98
  selectionRange: specKeywordNode.range,
90
- children: specSymbols
91
- }
99
+ children: specSymbols,
100
+ },
92
101
  ]
93
102
  }
94
103
 
@@ -103,13 +112,29 @@ export class LikeC4DocumentSymbolProvider implements DocumentSymbolProvider {
103
112
  name: astModel.name,
104
113
  range: cstModel.range,
105
114
  selectionRange: nameNode.range,
106
- children: astModel.elements.flatMap(e => this.getElementsSymbol(e))
107
- }
115
+ children: astModel.elements.flatMap(e => this.getElementsSymbol(e)),
116
+ },
117
+ ]
118
+ }
119
+
120
+ protected getDeploymentModelSymbol(astModel: ast.ModelDeployments): DocumentSymbol[] {
121
+ const cstModel = astModel.$cstNode
122
+ if (!cstModel) return []
123
+ const nameNode = GrammarUtils.findNodeForProperty(cstModel, 'name')
124
+ if (!nameNode) return []
125
+ return [
126
+ {
127
+ kind: this.symbolKind(astModel),
128
+ name: astModel.name,
129
+ range: cstModel.range,
130
+ selectionRange: nameNode.range,
131
+ children: astModel.elements.flatMap(e => this.getDeploymentElementSymbol(e)),
132
+ },
108
133
  ]
109
134
  }
110
135
 
111
136
  protected getElementsSymbol(
112
- el: ast.Element | ast.Relation | ast.ExtendElement
137
+ el: ast.Element | ast.Relation | ast.ExtendElement,
113
138
  ): DocumentSymbol[] {
114
139
  try {
115
140
  if (ast.isExtendElement(el)) {
@@ -119,7 +144,7 @@ export class LikeC4DocumentSymbolProvider implements DocumentSymbolProvider {
119
144
  return this.getElementSymbol(el)
120
145
  }
121
146
  } catch (e) {
122
- logError(e)
147
+ logWarnError(e)
123
148
  }
124
149
  return []
125
150
  }
@@ -136,8 +161,8 @@ export class LikeC4DocumentSymbolProvider implements DocumentSymbolProvider {
136
161
  name: getFqnElementRef(astElement.element),
137
162
  range: cst.range,
138
163
  selectionRange: nameNode.range,
139
- children: body.elements.flatMap(e => this.getElementsSymbol(e))
140
- }
164
+ children: body.elements.flatMap(e => this.getElementsSymbol(e)),
165
+ },
141
166
  ]
142
167
  }
143
168
 
@@ -157,8 +182,8 @@ export class LikeC4DocumentSymbolProvider implements DocumentSymbolProvider {
157
182
  range: cst.range,
158
183
  selectionRange: nameNode.range,
159
184
  detail,
160
- children: astElement.body?.elements.flatMap(e => this.getElementsSymbol(e)) ?? []
161
- }
185
+ children: astElement.body?.elements.flatMap(e => this.getElementsSymbol(e)) ?? [],
186
+ },
162
187
  ]
163
188
  }
164
189
  protected getModelViewsSymbol(astViews: ast.ModelViews): DocumentSymbol[] {
@@ -171,13 +196,13 @@ export class LikeC4DocumentSymbolProvider implements DocumentSymbolProvider {
171
196
  name: astViews.name,
172
197
  range: cst.range,
173
198
  selectionRange: nameNode.range,
174
- children: astViews.views.flatMap(e => this.getViewSymbol(e))
175
- }
199
+ children: astViews.views.flatMap(e => this.getViewSymbol(e)),
200
+ },
176
201
  ]
177
202
  }
178
203
 
179
204
  protected getKindSymbol(
180
- astKind: ast.SpecificationElementKind | ast.SpecificationRelationshipKind
205
+ astKind: ast.SpecificationElementKind | ast.SpecificationRelationshipKind,
181
206
  ): DocumentSymbol | null {
182
207
  if (!astKind.$cstNode || !astKind.kind.$cstNode || isEmpty(astKind.kind.name)) return null
183
208
 
@@ -185,7 +210,7 @@ export class LikeC4DocumentSymbolProvider implements DocumentSymbolProvider {
185
210
  kind: this.symbolKind(astKind),
186
211
  name: astKind.kind.name,
187
212
  range: astKind.$cstNode.range,
188
- selectionRange: astKind.kind.$cstNode.range
213
+ selectionRange: astKind.kind.$cstNode.range,
189
214
  }
190
215
  }
191
216
 
@@ -195,7 +220,7 @@ export class LikeC4DocumentSymbolProvider implements DocumentSymbolProvider {
195
220
  kind: this.symbolKind(astTag),
196
221
  name: '#' + astTag.tag.name,
197
222
  range: astTag.$cstNode.range,
198
- selectionRange: astTag.tag.$cstNode.range
223
+ selectionRange: astTag.tag.$cstNode.range,
199
224
  }
200
225
  }
201
226
 
@@ -205,7 +230,7 @@ export class LikeC4DocumentSymbolProvider implements DocumentSymbolProvider {
205
230
  kind: this.symbolKind(astTag),
206
231
  name: astTag.name,
207
232
  range: astTag.$cstNode.range,
208
- selectionRange: astTag.$cstNode.range
233
+ selectionRange: astTag.$cstNode.range,
209
234
  }
210
235
  }
211
236
 
@@ -220,8 +245,65 @@ export class LikeC4DocumentSymbolProvider implements DocumentSymbolProvider {
220
245
  name: nameNode.text,
221
246
  range: cst.range,
222
247
  selectionRange: nameNode.range,
223
- children: []
248
+ children: [],
249
+ },
250
+ ]
251
+ }
252
+
253
+ protected getDeploymentElementSymbol(el: ast.DeploymentElement | ast.DeploymentRelation): DocumentSymbol[] {
254
+ try {
255
+ if (ast.isDeploymentNode(el)) {
256
+ return this.getDeploymentNodeSymbol(el)
224
257
  }
258
+ if (ast.isDeployedInstance(el)) {
259
+ return this.getDeployedInstanceSymbol(el)
260
+ }
261
+ } catch (e) {
262
+ logWarnError(e)
263
+ }
264
+ return []
265
+ }
266
+
267
+ protected getDeploymentNodeSymbol(astElement: ast.DeploymentNode): DocumentSymbol[] {
268
+ const cst = astElement.$cstNode
269
+ const nameNode = this.nameProvider.getNameNode(astElement)
270
+ if (!nameNode || !cst) return []
271
+
272
+ const name = this.nameProvider.getNameStrict(astElement)
273
+ const kind = astElement.kind.$refText
274
+ // TODO: return the title as well
275
+ const detail = kind // + (astElement.title ? ': ' + astElement.title : '').replaceAll('\n', ' ').trim()
276
+ return [
277
+ {
278
+ kind: this.symbolKind(astElement),
279
+ name: name,
280
+ range: cst.range,
281
+ selectionRange: nameNode.range,
282
+ detail,
283
+ children: astElement.body?.elements.flatMap(e => this.getDeploymentElementSymbol(e)) ?? [],
284
+ },
285
+ ]
286
+ }
287
+
288
+ protected getDeployedInstanceSymbol(astElement: ast.DeployedInstance): DocumentSymbol[] {
289
+ const cst = astElement.$cstNode
290
+ const nameNode = this.nameProvider.getNameNode(astElement)
291
+ if (!nameNode || !cst) return []
292
+
293
+ const doc = AstUtils.getDocument(astElement)
294
+ const instance = this.parser.forDocument(doc).parseDeployedInstance(astElement)
295
+
296
+ const name = this.nameProvider.getNameStrict(astElement)
297
+ const detail = 'instance of ' + instance.element
298
+ return [
299
+ {
300
+ kind: this.symbolKind(astElement),
301
+ name: name,
302
+ range: cst.range,
303
+ selectionRange: nameNode.range,
304
+ detail,
305
+ children: [],
306
+ },
225
307
  ]
226
308
  }
227
309
 
@@ -1,4 +1,4 @@
1
- import { type AstNode, type MaybePromise } from 'langium'
1
+ import { type AstNode, AstUtils, type MaybePromise } from 'langium'
2
2
  import { AstNodeHoverProvider } from 'langium/lsp'
3
3
  import { isTruthy } from 'remeda'
4
4
  import stripIndent from 'strip-indent'
@@ -30,7 +30,8 @@ export class LikeC4HoverProvider extends AstNodeHoverProvider {
30
30
  }
31
31
 
32
32
  if (ast.isDeploymentNode(node)) {
33
- const el = this.parser.parseDeploymentNode(node, () => true)
33
+ const doc = AstUtils.getDocument(node)
34
+ const el = this.parser.forDocument(doc).parseDeploymentNode(node)
34
35
  const lines = [el.id as string + ' ']
35
36
  if (el.title !== node.name) {
36
37
  lines.push(`### ${el.title}`)
@@ -45,7 +46,8 @@ export class LikeC4HoverProvider extends AstNodeHoverProvider {
45
46
  }
46
47
 
47
48
  if (ast.isDeployedInstance(node)) {
48
- const instance = this.parser.parseDeployedInstance(node, () => true)
49
+ const doc = AstUtils.getDocument(node)
50
+ const instance = this.parser.forDocument(doc).parseDeployedInstance(node)
49
51
  const el = this.locator.getParsedElement(instance.element)
50
52
  const lines = [instance.id + ' ', `instance of \`${instance.element}\``]
51
53
  if (el) {
@@ -90,7 +90,7 @@ export class LikeC4SemanticTokenProvider extends AbstractSemanticTokenProvider {
90
90
  })
91
91
  return 'prune'
92
92
  }
93
- if (ast.isDeploymentRefExpression(node)) {
93
+ if (ast.isFqnRefExpr(node)) {
94
94
  if (node.selector) {
95
95
  acceptor({
96
96
  node,
@@ -142,7 +142,7 @@ export class LikeC4SemanticTokenProvider extends AbstractSemanticTokenProvider {
142
142
  })
143
143
  return 'prune'
144
144
  }
145
- if (ast.isDeploymentRef(node)) {
145
+ if (ast.isFqnRef(node)) {
146
146
  acceptor({
147
147
  node,
148
148
  property: 'value',