@likec4/language-server 1.17.1 → 1.19.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 (268) hide show
  1. package/contrib/likec4.tmLanguage.json +1 -1
  2. package/dist/LikeC4FileSystem.d.ts +13 -0
  3. package/dist/LikeC4FileSystem.js +27 -0
  4. package/dist/Rpc.d.ts +9 -0
  5. package/dist/Rpc.js +126 -0
  6. package/dist/ast.d.ts +200 -0
  7. package/dist/ast.js +276 -0
  8. package/dist/browser.d.ts +6 -20
  9. package/dist/browser.js +13 -0
  10. package/dist/formatting/LikeC4Formatter.d.ts +27 -0
  11. package/dist/formatting/LikeC4Formatter.js +261 -0
  12. package/dist/formatting/utils.d.ts +6 -0
  13. package/dist/formatting/utils.js +15 -0
  14. package/dist/generated/ast.d.ts +1242 -0
  15. package/dist/generated/ast.js +1945 -0
  16. package/dist/generated/grammar.d.ts +6 -0
  17. package/dist/generated/grammar.js +3 -0
  18. package/dist/generated/module.d.ts +9 -0
  19. package/dist/generated/module.js +23 -0
  20. package/dist/generated-lib/icons.d.ts +1 -0
  21. package/dist/{likec4lib.mjs → generated-lib/icons.js} +1 -6
  22. package/dist/index.d.ts +8 -31
  23. package/dist/index.js +13 -0
  24. package/dist/like-c4.langium +845 -0
  25. package/dist/likec4lib.d.ts +4 -6
  26. package/dist/likec4lib.js +4 -0
  27. package/dist/logger.d.ts +7 -0
  28. package/dist/logger.js +73 -0
  29. package/dist/lsp/CodeLensProvider.d.ts +9 -0
  30. package/dist/lsp/CodeLensProvider.js +40 -0
  31. package/dist/lsp/CompletionProvider.d.ts +6 -0
  32. package/dist/lsp/CompletionProvider.js +135 -0
  33. package/dist/lsp/DocumentHighlightProvider.d.ts +9 -0
  34. package/dist/lsp/DocumentHighlightProvider.js +10 -0
  35. package/dist/lsp/DocumentLinkProvider.d.ts +11 -0
  36. package/dist/lsp/DocumentLinkProvider.js +49 -0
  37. package/dist/lsp/DocumentSymbolProvider.d.ts +23 -0
  38. package/dist/lsp/DocumentSymbolProvider.js +202 -0
  39. package/dist/lsp/HoverProvider.d.ts +10 -0
  40. package/dist/lsp/HoverProvider.js +69 -0
  41. package/dist/lsp/RenameProvider.d.ts +5 -0
  42. package/dist/lsp/RenameProvider.js +6 -0
  43. package/dist/lsp/SemanticTokenProvider.d.ts +7 -0
  44. package/dist/lsp/SemanticTokenProvider.js +297 -0
  45. package/dist/lsp/index.d.ts +7 -0
  46. package/dist/lsp/index.js +7 -0
  47. package/dist/model/deployments-index.d.ts +60 -0
  48. package/dist/model/deployments-index.js +181 -0
  49. package/dist/model/fqn-computation.d.ts +3 -0
  50. package/dist/model/fqn-computation.js +72 -0
  51. package/dist/model/fqn-index.d.ts +25 -0
  52. package/dist/model/fqn-index.js +96 -0
  53. package/dist/model/index.d.ts +6 -0
  54. package/dist/model/index.js +6 -0
  55. package/dist/model/model-builder.d.ts +32 -0
  56. package/dist/model/model-builder.js +598 -0
  57. package/dist/model/model-locator.d.ts +23 -0
  58. package/dist/model/model-locator.js +126 -0
  59. package/dist/model/model-parser-where.d.ts +3 -0
  60. package/dist/model/model-parser-where.js +70 -0
  61. package/dist/model/model-parser.d.ts +292 -0
  62. package/dist/model/model-parser.js +72 -0
  63. package/dist/model/parser/Base.d.ts +28 -0
  64. package/dist/model/parser/Base.js +87 -0
  65. package/dist/model/parser/DeploymentModelParser.d.ts +33 -0
  66. package/dist/model/parser/DeploymentModelParser.js +162 -0
  67. package/dist/model/parser/DeploymentViewParser.d.ts +38 -0
  68. package/dist/model/parser/DeploymentViewParser.js +98 -0
  69. package/dist/model/parser/FqnRefParser.d.ts +29 -0
  70. package/dist/model/parser/FqnRefParser.js +108 -0
  71. package/dist/model/parser/GlobalsParser.d.ts +66 -0
  72. package/dist/model/parser/GlobalsParser.js +80 -0
  73. package/dist/model/parser/ModelParser.d.ts +27 -0
  74. package/dist/model/parser/ModelParser.js +122 -0
  75. package/dist/model/parser/PredicatesParser.d.ts +34 -0
  76. package/dist/model/parser/PredicatesParser.js +272 -0
  77. package/dist/model/parser/SpecificationParser.d.ts +27 -0
  78. package/dist/model/parser/SpecificationParser.js +120 -0
  79. package/dist/model/parser/ViewsParser.d.ts +64 -0
  80. package/dist/model/parser/ViewsParser.js +377 -0
  81. package/dist/model-change/ModelChanges.d.ts +15 -0
  82. package/dist/model-change/ModelChanges.js +89 -0
  83. package/dist/model-change/changeElementStyle.d.ts +16 -0
  84. package/dist/model-change/changeElementStyle.js +136 -0
  85. package/dist/model-change/changeViewLayout.d.ts +12 -0
  86. package/dist/model-change/changeViewLayout.js +32 -0
  87. package/dist/model-change/saveManualLayout.d.ts +11 -0
  88. package/dist/model-change/saveManualLayout.js +27 -0
  89. package/dist/module.d.ts +62 -0
  90. package/dist/module.js +123 -0
  91. package/dist/protocol.d.ts +27 -27
  92. package/dist/protocol.js +14 -0
  93. package/dist/references/index.d.ts +3 -0
  94. package/dist/references/index.js +3 -0
  95. package/dist/references/name-provider.d.ts +9 -0
  96. package/dist/references/name-provider.js +33 -0
  97. package/dist/references/scope-computation.d.ts +20 -0
  98. package/dist/references/scope-computation.js +281 -0
  99. package/dist/references/scope-provider.d.ts +16 -0
  100. package/dist/references/scope-provider.js +165 -0
  101. package/dist/shared/NodeKindProvider.d.ts +15 -0
  102. package/dist/shared/NodeKindProvider.js +108 -0
  103. package/dist/shared/WorkspaceManager.d.ts +18 -0
  104. package/dist/shared/WorkspaceManager.js +36 -0
  105. package/dist/shared/WorkspaceSymbolProvider.d.ts +3 -0
  106. package/dist/shared/WorkspaceSymbolProvider.js +3 -0
  107. package/dist/shared/index.d.ts +3 -0
  108. package/dist/shared/index.js +3 -0
  109. package/dist/test/index.d.ts +1 -0
  110. package/dist/test/index.js +1 -0
  111. package/dist/test/setup.d.ts +1 -0
  112. package/dist/test/setup.js +7 -0
  113. package/dist/test/testServices.d.ts +22 -0
  114. package/dist/test/testServices.js +119 -0
  115. package/dist/utils/elementRef.d.ts +11 -0
  116. package/dist/utils/elementRef.js +15 -0
  117. package/dist/utils/fqnRef.d.ts +8 -0
  118. package/dist/utils/fqnRef.js +46 -0
  119. package/dist/utils/index.d.ts +1 -0
  120. package/dist/utils/index.js +1 -0
  121. package/dist/utils/printDocs.d.ts +2 -0
  122. package/dist/utils/printDocs.js +1 -0
  123. package/dist/utils/stringHash.d.ts +1 -0
  124. package/dist/utils/stringHash.js +5 -0
  125. package/dist/validation/_shared.d.ts +3 -0
  126. package/dist/validation/_shared.js +22 -0
  127. package/dist/validation/deployment-checks.d.ts +6 -0
  128. package/dist/validation/deployment-checks.js +114 -0
  129. package/dist/validation/dynamic-view-rule.d.ts +4 -0
  130. package/dist/validation/dynamic-view-rule.js +16 -0
  131. package/dist/validation/dynamic-view-step.d.ts +4 -0
  132. package/dist/validation/dynamic-view-step.js +33 -0
  133. package/dist/validation/element.d.ts +4 -0
  134. package/dist/validation/element.js +49 -0
  135. package/dist/validation/index.d.ts +15 -0
  136. package/dist/validation/index.js +152 -0
  137. package/dist/validation/property-checks.d.ts +6 -0
  138. package/dist/validation/property-checks.js +38 -0
  139. package/dist/validation/relation.d.ts +5 -0
  140. package/dist/validation/relation.js +56 -0
  141. package/dist/validation/specification.d.ts +11 -0
  142. package/dist/validation/specification.js +136 -0
  143. package/dist/validation/view-predicates/element-with.d.ts +4 -0
  144. package/dist/validation/view-predicates/element-with.js +30 -0
  145. package/dist/validation/view-predicates/expanded-element.d.ts +4 -0
  146. package/dist/validation/view-predicates/expanded-element.js +11 -0
  147. package/dist/validation/view-predicates/expression-v2.d.ts +5 -0
  148. package/dist/validation/view-predicates/expression-v2.js +83 -0
  149. package/dist/validation/view-predicates/incoming.d.ts +4 -0
  150. package/dist/validation/view-predicates/incoming.js +15 -0
  151. package/dist/validation/view-predicates/index.d.ts +6 -0
  152. package/dist/validation/view-predicates/index.js +6 -0
  153. package/dist/validation/view-predicates/outgoing.d.ts +4 -0
  154. package/dist/validation/view-predicates/outgoing.js +15 -0
  155. package/dist/validation/view-predicates/relation-with.d.ts +4 -0
  156. package/dist/validation/view-predicates/relation-with.js +12 -0
  157. package/dist/validation/view.d.ts +4 -0
  158. package/dist/validation/view.js +23 -0
  159. package/dist/view-utils/assignNavigateTo.d.ts +2 -0
  160. package/dist/view-utils/assignNavigateTo.js +25 -0
  161. package/dist/view-utils/index.d.ts +2 -0
  162. package/dist/view-utils/index.js +2 -0
  163. package/dist/view-utils/manual-layout.d.ts +7 -0
  164. package/dist/view-utils/manual-layout.js +99 -0
  165. package/dist/view-utils/resolve-relative-paths.d.ts +2 -0
  166. package/dist/view-utils/resolve-relative-paths.js +78 -0
  167. package/package.json +42 -73
  168. package/src/LikeC4FileSystem.ts +22 -21
  169. package/src/Rpc.ts +6 -3
  170. package/src/ast.ts +136 -172
  171. package/src/browser.ts +10 -11
  172. package/src/generated/ast.ts +656 -40
  173. package/src/generated/grammar.ts +1 -1
  174. package/src/index.ts +11 -8
  175. package/src/like-c4.langium +173 -22
  176. package/src/logger.ts +41 -57
  177. package/src/lsp/CodeLensProvider.ts +0 -1
  178. package/src/lsp/CompletionProvider.ts +20 -5
  179. package/src/lsp/DocumentSymbolProvider.ts +5 -2
  180. package/src/lsp/HoverProvider.ts +37 -3
  181. package/src/lsp/SemanticTokenProvider.ts +58 -32
  182. package/src/model/deployments-index.ts +222 -0
  183. package/src/model/fqn-computation.ts +1 -1
  184. package/src/model/fqn-index.ts +0 -1
  185. package/src/model/index.ts +1 -0
  186. package/src/model/model-builder.ts +176 -39
  187. package/src/model/model-locator.ts +36 -7
  188. package/src/model/model-parser.ts +69 -1119
  189. package/src/model/parser/Base.ts +107 -0
  190. package/src/model/parser/DeploymentModelParser.ts +192 -0
  191. package/src/model/parser/DeploymentViewParser.ts +116 -0
  192. package/src/model/parser/FqnRefParser.ts +118 -0
  193. package/src/model/parser/GlobalsParser.ts +96 -0
  194. package/src/model/parser/ModelParser.ts +141 -0
  195. package/src/model/parser/PredicatesParser.ts +291 -0
  196. package/src/model/parser/SpecificationParser.ts +133 -0
  197. package/src/model/parser/ViewsParser.ts +428 -0
  198. package/src/model-change/changeViewLayout.ts +2 -2
  199. package/src/module.ts +26 -21
  200. package/src/protocol.ts +10 -6
  201. package/src/references/index.ts +1 -0
  202. package/src/references/name-provider.ts +37 -0
  203. package/src/references/scope-computation.ts +130 -21
  204. package/src/references/scope-provider.ts +68 -35
  205. package/src/shared/NodeKindProvider.ts +15 -3
  206. package/src/{elementRef.ts → utils/elementRef.ts} +1 -1
  207. package/src/utils/fqnRef.ts +56 -0
  208. package/src/utils/stringHash.ts +2 -2
  209. package/src/validation/_shared.ts +6 -5
  210. package/src/validation/deployment-checks.ts +131 -0
  211. package/src/validation/dynamic-view-step.ts +1 -1
  212. package/src/validation/index.ts +104 -6
  213. package/src/validation/relation.ts +1 -1
  214. package/src/validation/view-predicates/expression-v2.ts +101 -0
  215. package/src/validation/view-predicates/index.ts +1 -0
  216. package/src/view-utils/assignNavigateTo.ts +6 -5
  217. package/src/view-utils/index.ts +0 -1
  218. package/src/view-utils/manual-layout.ts +25 -0
  219. package/dist/browser.cjs +0 -25
  220. package/dist/browser.d.cts +0 -23
  221. package/dist/browser.d.mts +0 -23
  222. package/dist/browser.mjs +0 -20
  223. package/dist/index.cjs +0 -53
  224. package/dist/index.d.cts +0 -34
  225. package/dist/index.d.mts +0 -34
  226. package/dist/index.mjs +0 -46
  227. package/dist/likec4lib.cjs +0 -1546
  228. package/dist/likec4lib.d.cts +0 -6
  229. package/dist/likec4lib.d.mts +0 -6
  230. package/dist/model-graph/index.cjs +0 -10
  231. package/dist/model-graph/index.d.cts +0 -81
  232. package/dist/model-graph/index.d.mts +0 -81
  233. package/dist/model-graph/index.d.ts +0 -81
  234. package/dist/model-graph/index.mjs +0 -1
  235. package/dist/protocol.cjs +0 -25
  236. package/dist/protocol.d.cts +0 -45
  237. package/dist/protocol.d.mts +0 -45
  238. package/dist/protocol.mjs +0 -17
  239. package/dist/shared/language-server.BIbAD1T-.mjs +0 -6292
  240. package/dist/shared/language-server.BQRvVmE0.d.cts +0 -1303
  241. package/dist/shared/language-server.BysPcTxr.d.ts +0 -1303
  242. package/dist/shared/language-server.D2QdbOJO.cjs +0 -1995
  243. package/dist/shared/language-server.DGrBGmsd.mjs +0 -1981
  244. package/dist/shared/language-server.DKV_FdPN.cjs +0 -6304
  245. package/dist/shared/language-server._wkyPgso.d.mts +0 -1303
  246. package/src/model-graph/LikeC4ModelGraph.ts +0 -338
  247. package/src/model-graph/compute-view/__test__/fixture.ts +0 -630
  248. package/src/model-graph/compute-view/compute.ts +0 -788
  249. package/src/model-graph/compute-view/index.ts +0 -33
  250. package/src/model-graph/compute-view/predicates.ts +0 -509
  251. package/src/model-graph/dynamic-view/__test__/fixture.ts +0 -61
  252. package/src/model-graph/dynamic-view/compute.ts +0 -313
  253. package/src/model-graph/dynamic-view/index.ts +0 -29
  254. package/src/model-graph/index.ts +0 -3
  255. package/src/model-graph/utils/applyCustomElementProperties.ts +0 -65
  256. package/src/model-graph/utils/applyCustomRelationProperties.ts +0 -41
  257. package/src/model-graph/utils/applyViewRuleStyles.ts +0 -49
  258. package/src/model-graph/utils/buildComputeNodes.ts +0 -113
  259. package/src/model-graph/utils/buildElementNotations.ts +0 -63
  260. package/src/model-graph/utils/elementExpressionToPredicate.ts +0 -39
  261. package/src/model-graph/utils/relationExpressionToPredicates.ts +0 -43
  262. package/src/model-graph/utils/sortNodes.ts +0 -105
  263. package/src/model-graph/utils/uniqueTags.test.ts +0 -42
  264. package/src/model-graph/utils/uniqueTags.ts +0 -19
  265. package/src/utils/graphlib.ts +0 -9
  266. package/src/view-utils/resolve-extended-views.ts +0 -66
  267. package/src/view-utils/resolve-global-rules.ts +0 -88
  268. package/src/view-utils/view-hash.ts +0 -27
@@ -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.isFqnRefExpr(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.isFqnRef(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',
@@ -0,0 +1,222 @@
1
+ import type { Fqn } from '@likec4/core'
2
+ import type { LangiumDocument, LangiumDocuments, Stream } from 'langium'
3
+ import { AstUtils, DocumentState, MultiMap } from 'langium'
4
+ import { forEachObj, groupBy, isTruthy, pipe, prop } from 'remeda'
5
+ import {
6
+ type DeploymentAstNodeDescription,
7
+ type LikeC4LangiumDocument,
8
+ ast,
9
+ ElementOps,
10
+ isLikeC4LangiumDocument,
11
+ } from '../ast'
12
+ import { logWarnError } from '../logger'
13
+ import type { LikeC4Services } from '../module'
14
+ import type { LikeC4NameProvider } from '../references'
15
+
16
+ const DeploymentsIndexKey = Symbol.for('DeploymentsIndex')
17
+
18
+ type IndexedDocument = LangiumDocument & {
19
+ [DeploymentsIndexKey]?: DocumentDeploymentsIndex
20
+ }
21
+
22
+ export class DeploymentsIndex {
23
+ protected Names: LikeC4NameProvider
24
+ protected langiumDocuments: LangiumDocuments
25
+
26
+ constructor(private services: LikeC4Services) {
27
+ this.Names = services.references.NameProvider
28
+ this.langiumDocuments = services.shared.workspace.LangiumDocuments
29
+
30
+ services.shared.workspace.DocumentBuilder.onBuildPhase(
31
+ DocumentState.IndexedContent,
32
+ (docs, _cancelToken) => {
33
+ for (const doc of docs) {
34
+ delete (doc as IndexedDocument)[DeploymentsIndexKey]
35
+ }
36
+ },
37
+ )
38
+ }
39
+
40
+ private documents() {
41
+ return this.langiumDocuments.all.filter((d): d is LikeC4LangiumDocument =>
42
+ isLikeC4LangiumDocument(d) && d.state >= DocumentState.IndexedContent
43
+ )
44
+ }
45
+
46
+ public get(document: LikeC4LangiumDocument): DocumentDeploymentsIndex {
47
+ if (document.state < DocumentState.IndexedContent) {
48
+ logWarnError(`Document ${document.uri.path} is not indexed`)
49
+ }
50
+ return (document as IndexedDocument)[DeploymentsIndexKey] ??= this.createDocumentIndex(document)
51
+ }
52
+ /**
53
+ * Nested elements (nodes/artifacts) of the node
54
+ * @param nodeName Name of the deployment node
55
+ * @returns Stream of artifacts
56
+ */
57
+ public nested(node: ast.DeploymentNode): Stream<DeploymentAstNodeDescription> {
58
+ const fqnName = this.getFqn(node)
59
+ return this.documents().flatMap(doc => this.get(doc).nested(fqnName))
60
+ }
61
+
62
+ public byFqn(fqnName: string): Stream<DeploymentAstNodeDescription> {
63
+ return this.documents().flatMap(doc => this.get(doc).byFqn(fqnName))
64
+ }
65
+
66
+ public getFqn(node: ast.DeploymentElement): Fqn {
67
+ let id = ElementOps.readId(node)
68
+ if (isTruthy(id)) {
69
+ return id
70
+ }
71
+ const fqn = [
72
+ this.Names.getNameStrict(node),
73
+ ]
74
+ let _node = node
75
+ let parentNode: ast.DeploymentNode | undefined
76
+ while ((parentNode = AstUtils.getContainerOfType(_node.$container, ast.isDeploymentNode))) {
77
+ fqn.push(this.Names.getNameStrict(parentNode))
78
+ _node = parentNode
79
+ }
80
+ id = fqn.reduceRight((acc, cur) => `${acc}.${cur}`) as Fqn
81
+ ElementOps.writeId(node, id)
82
+ return id
83
+ }
84
+
85
+ public createDocumentIndex(document: LikeC4LangiumDocument): DocumentDeploymentsIndex {
86
+ const rootNodes = document.parseResult.value.deployments.flatMap(m => m.elements)
87
+ if (rootNodes.length === 0) {
88
+ return DocumentDeploymentsIndex.EMPTY
89
+ }
90
+ const _root = new Array<DeploymentAstNodeDescription>()
91
+ const _nested = new MultiMap<string, DeploymentAstNodeDescription>()
92
+ const _byfqn = new MultiMap<string, DeploymentAstNodeDescription>()
93
+ const Names = this.Names
94
+ const Descriptions = this.services.workspace.AstNodeDescriptionProvider
95
+
96
+ const createAndSaveDescription = (
97
+ props: { node: ast.DeploymentNode | ast.DeployedInstance; name: string; fqn: string },
98
+ ) => {
99
+ const desc = {
100
+ ...Descriptions.createDescription(props.node, props.name, document),
101
+ fqn: props.fqn,
102
+ }
103
+ ElementOps.writeId(props.node, props.fqn as Fqn)
104
+ _byfqn.add(props.fqn, desc)
105
+ return desc
106
+ }
107
+
108
+ const traverseNode = (
109
+ container: ast.DeploymentNode,
110
+ parentFqn: string,
111
+ ): readonly DeploymentAstNodeDescription[] => {
112
+ const _descedants = [] as DeploymentAstNodeDescription[]
113
+ const children = container.body?.elements
114
+ if (!children || children.length === 0) {
115
+ return []
116
+ }
117
+ const directChildren = new Set<string>()
118
+ for (const node of children) {
119
+ if (ast.isDeploymentRelation(node)) {
120
+ continue
121
+ }
122
+ try {
123
+ const name = Names.getName(node)
124
+ if (isTruthy(name)) {
125
+ const fqn = `${parentFqn}.${name}`
126
+ const desc = createAndSaveDescription({ node, name, fqn })
127
+ _nested.add(parentFqn, desc)
128
+ directChildren.add(desc.name)
129
+ if (ast.isDeploymentNode(node) && node.body) {
130
+ _descedants.push(...traverseNode(node, fqn))
131
+ }
132
+ }
133
+ } catch (e) {
134
+ logWarnError(e)
135
+ }
136
+ }
137
+ if (_descedants.length > 0) {
138
+ pipe(
139
+ _descedants,
140
+ groupBy(prop('name')),
141
+ forEachObj((descs, key) => {
142
+ if (descs.length > 1 || directChildren.has(key)) {
143
+ return
144
+ }
145
+ _nested.add(parentFqn, descs[0])
146
+ }),
147
+ )
148
+ }
149
+ return _nested.get(parentFqn)
150
+ }
151
+
152
+ for (const node of rootNodes) {
153
+ try {
154
+ if (ast.isDeploymentRelation(node)) {
155
+ continue
156
+ }
157
+ const name = Names.getName(node)
158
+ if (isTruthy(name)) {
159
+ _root.push(createAndSaveDescription({ node, name, fqn: name }))
160
+ traverseNode(node, name)
161
+ }
162
+ } catch (e) {
163
+ logWarnError(e)
164
+ }
165
+ }
166
+ return new DocumentDeploymentsIndex(_root, _nested, _byfqn)
167
+ }
168
+ }
169
+
170
+ /**
171
+ * Index of deployment elements in the document
172
+ */
173
+ export class DocumentDeploymentsIndex {
174
+ static readonly EMPTY = new DocumentDeploymentsIndex([], new MultiMap(), new MultiMap())
175
+
176
+ constructor(
177
+ private _rootNodes: Array<DeploymentAstNodeDescription>,
178
+ /**
179
+ * Nested of a deployment node
180
+ */
181
+ private _nested: MultiMap<string, DeploymentAstNodeDescription>,
182
+ /**
183
+ * All elements by FQN
184
+ */
185
+ private _byfqn: MultiMap<string, DeploymentAstNodeDescription>,
186
+ ) {}
187
+
188
+ public rootNodes(): readonly DeploymentAstNodeDescription[] {
189
+ return this._rootNodes
190
+ }
191
+
192
+ public byFqn(fqnName: string): readonly DeploymentAstNodeDescription[] {
193
+ return this._byfqn.get(fqnName)
194
+ }
195
+
196
+ /**
197
+ * Returns artifacts of a deployment node
198
+ * @param nodeName Name of the deployment node
199
+ * @returns Stream of artifacts
200
+ */
201
+ public nested(nodeName: string): readonly DeploymentAstNodeDescription[] {
202
+ return this._nested.get(nodeName)
203
+ }
204
+
205
+ /**
206
+ * Returns all deployment elements in the document,
207
+ * with unique combination "type and name"
208
+ */
209
+ public unique(): readonly DeploymentAstNodeDescription[] {
210
+ const result = [] as DeploymentAstNodeDescription[]
211
+ pipe(
212
+ [...this._byfqn.values()],
213
+ groupBy(prop('name')),
214
+ forEachObj(descs => {
215
+ if (descs.length === 1) {
216
+ result.push(descs[0])
217
+ }
218
+ }),
219
+ )
220
+ return result
221
+ }
222
+ }
@@ -3,9 +3,9 @@ import type * as c4 from '@likec4/core'
3
3
  import { type AstNodeDescription, type AstNodeLocator, AstUtils, CstUtils, GrammarUtils, MultiMap } from 'langium'
4
4
  import { isDefined, isEmpty } from 'remeda'
5
5
  import { ast, ElementOps, type LikeC4LangiumDocument } from '../ast'
6
- import { getFqnElementRef } from '../elementRef'
7
6
  import { logError } from '../logger'
8
7
  import type { LikeC4Services } from '../module'
8
+ import { getFqnElementRef } from '../utils/elementRef'
9
9
 
10
10
  const { findNodeForProperty } = GrammarUtils
11
11
  const { toDocumentSegment } = CstUtils
@@ -6,7 +6,6 @@ import type { ast, DocFqnIndexAstNodeDescription, FqnIndexedDocument } from '../
6
6
  import { ElementOps, isFqnIndexedDocument, isLikeC4LangiumDocument } from '../ast'
7
7
  import { logger, logWarnError } from '../logger'
8
8
  import type { LikeC4Services } from '../module'
9
- import { printDocs } from '../utils/printDocs'
10
9
  import { computeDocumentFqn } from './fqn-computation'
11
10
 
12
11
  export interface FqnIndexEntry {
@@ -1,3 +1,4 @@
1
+ export * from './deployments-index'
1
2
  export * from './fqn-computation'
2
3
  export * from './fqn-index'
3
4
  export * from './model-builder'