@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
@@ -1,338 +0,0 @@
1
- import {
2
- ancestorsFqn,
3
- commonAncestor,
4
- type Element,
5
- type Fqn,
6
- invariant,
7
- isSameHierarchy,
8
- type ModelGlobals,
9
- parentFqn,
10
- type Relation,
11
- type RelationID
12
- } from '@likec4/core'
13
- import { isArray, isString } from 'remeda'
14
-
15
- type Params = {
16
- elements: Record<Fqn, Element>
17
- relations: Record<RelationID, Relation>
18
- // Optional for tests
19
- globals?: ModelGlobals
20
- }
21
-
22
- type RelationEdge = {
23
- source: Element
24
- target: Element
25
- relations: Relation[]
26
- }
27
-
28
- type FqnOrElement = Fqn | Element
29
- type FqnsOrElements = ReadonlyArray<Fqn> | ReadonlyArray<Element>
30
-
31
- const RelationsSet = Set<Relation>
32
- const MapRelations = Map<Fqn, Set<Relation>>
33
-
34
- function intersection<T>(a: Set<T>, b: Set<T>) {
35
- if (a.size === 0 || b.size === 0) {
36
- return new Set<T>()
37
- }
38
- return new Set([...a].filter(value => b.has(value)))
39
- }
40
-
41
- /**
42
- * Used only for views calculations.
43
- * Subject to change.
44
- */
45
- export class LikeC4ModelGraph {
46
- readonly #elements = new Map<Fqn, Element>()
47
- // Parent element for given FQN
48
- readonly #parents = new Map<Fqn, Element>()
49
- // Children elements for given FQN
50
- readonly #children = new Map<Fqn, Element[]>()
51
- readonly #rootElements = new Set<Element>()
52
-
53
- readonly #relations = new Map<RelationID, Relation>()
54
- // Incoming to an element or its descendants
55
- readonly #incoming = new MapRelations()
56
- // Outgoing from an element or its descendants
57
- readonly #outgoing = new MapRelations()
58
- // Relationships inside the element, among descendants
59
- readonly #internal = new MapRelations()
60
-
61
- readonly #cacheAscendingSiblings = new Map<Fqn, Element[]>()
62
-
63
- public readonly globals: ModelGlobals
64
-
65
- constructor(
66
- { elements, relations, globals }: Params
67
- ) {
68
- this.globals = globals ?? {
69
- predicates: {},
70
- dynamicPredicates: {},
71
- styles: {}
72
- }
73
- for (const el of Object.values(elements)) {
74
- this.addElement(el)
75
- }
76
- for (const rel of Object.values(relations)) {
77
- this.addRelation(rel)
78
- }
79
- }
80
-
81
- get rootElements() {
82
- return [...this.#rootElements]
83
- }
84
-
85
- get elements() {
86
- return [...this.#elements.values()]
87
- }
88
-
89
- public element(id: Fqn) {
90
- const el = this.#elements.get(id)
91
- invariant(el, `Element ${id} not found`)
92
- return el
93
- }
94
-
95
- public connectedRelations(id: Fqn) {
96
- return [...this._incomingTo(id), ...this._outgoingFrom(id), ...this._internalOf(id)]
97
- }
98
-
99
- public children(id: Fqn) {
100
- return this._childrenOf(id).slice()
101
- }
102
-
103
- // Get children or element itself if no children
104
- public childrenOrElement(id: Fqn) {
105
- const children = this.children(id)
106
- return children.length > 0 ? children : [this.element(id)]
107
- }
108
-
109
- // Get all sibling (i.e. same parent)
110
- public siblings(element: Fqn | Element) {
111
- const id = isString(element) ? element : element.id
112
- const parent = parentFqn(id)
113
- const siblings = parent ? this._childrenOf(parent) : this.rootElements
114
- return siblings.filter(e => e.id !== id)
115
- }
116
-
117
- /**
118
- * Get all ancestor elements (i.e. parent, parent’s parent, etc.)
119
- * (from closest to root)
120
- */
121
- public ancestors(element: Fqn | Element): Array<Element> {
122
- let id = isString(element) ? element : element.id
123
- const result = [] as Element[]
124
- let parent
125
- while (parent = this.#parents.get(id)) {
126
- result.push(parent)
127
- id = parent.id
128
- }
129
- return result as Array<Element>
130
- }
131
-
132
- /**
133
- * Resolve siblings of the element and its ancestors
134
- * (from closest to root)
135
- */
136
- public ascendingSiblings(element: Fqn | Element): Array<Element> {
137
- const id = isString(element) ? element : element.id
138
- let siblings = this.#cacheAscendingSiblings.get(id)
139
- if (!siblings) {
140
- siblings = [
141
- ...this.siblings(id),
142
- ...this.ancestors(id).flatMap(a => this.siblings(a.id))
143
- ]
144
- this.#cacheAscendingSiblings.set(id, siblings)
145
- }
146
- return siblings.slice()
147
- }
148
-
149
- /**
150
- * Resolve all RelationEdges between element and others (any direction)
151
- */
152
- public anyEdgesBetween(
153
- _element: Fqn | Element,
154
- others: ReadonlyArray<Fqn> | ReadonlyArray<Element>
155
- ): Array<RelationEdge> {
156
- if (others.length === 0) {
157
- return []
158
- }
159
- const element = isString(_element) ? this.element(_element) : _element
160
- const in_element = this._incomingTo(element.id)
161
- const element_out = this._outgoingFrom(element.id)
162
- if (in_element.size === 0 && element_out.size === 0) {
163
- return []
164
- }
165
-
166
- const result = [] as Array<RelationEdge>
167
- for (const _other of others) {
168
- const other = isString(_other) ? this.element(_other) : _other
169
- if (isSameHierarchy(element, other)) {
170
- continue
171
- }
172
-
173
- if (element_out.size > 0) {
174
- const outcoming = intersection(this._incomingTo(other.id), element_out)
175
- // const outcoming = filter(in_other, isOutgoing)
176
- if (outcoming.size > 0) {
177
- result.push({
178
- source: element,
179
- target: other,
180
- relations: [...outcoming]
181
- })
182
- }
183
- }
184
-
185
- if (in_element.size > 0) {
186
- const incoming = intersection(this._outgoingFrom(other.id), in_element)
187
- // const incoming = filter(other_out, isIncoming)
188
- if (incoming.size > 0) {
189
- result.push({
190
- source: other,
191
- target: element,
192
- relations: [...incoming]
193
- })
194
- }
195
- }
196
- }
197
- return result
198
- }
199
-
200
- /**
201
- * Resolve all RelationEdges between elements (any direction)
202
- */
203
- public edgesWithin<T extends Fqn[] | Element[]>(elements: T): Array<RelationEdge> {
204
- if (elements.length < 2) {
205
- return []
206
- }
207
- return elements.reduce((acc, el, index, array) => {
208
- // return acc if last element
209
- if (index === array.length - 1) {
210
- return acc
211
- }
212
- acc.push(...this.anyEdgesBetween(el, array.slice(index + 1) as T))
213
- return acc
214
- }, [] as RelationEdge[])
215
- }
216
-
217
- /**
218
- * Get directed RelationEdge between source and target if exists
219
- */
220
- public edgesBetween(
221
- _sources: FqnOrElement | FqnsOrElements,
222
- _targets: FqnOrElement | FqnsOrElements
223
- ) {
224
- const sources = isArray(_sources) ? _sources : [_sources]
225
- const targets = isArray(_targets) ? _targets : [_targets]
226
- if (sources.length === 0 || targets.length === 0) {
227
- return []
228
- }
229
-
230
- const result = [] as Array<RelationEdge>
231
- for (const _source of sources) {
232
- const source = isString(_source) ? this.element(_source) : _source
233
- const outcoming = this._outgoingFrom(source.id)
234
- if (outcoming.size === 0) {
235
- continue
236
- }
237
- // const isSameAsOut = isIncludedIn(outcoming)
238
-
239
- for (const _target of targets) {
240
- const target = isString(_target) ? this.element(_target) : _target
241
- if (isSameHierarchy(source, target)) {
242
- continue
243
- }
244
- const incoming = this._incomingTo(target.id)
245
- const relations = intersection(outcoming, incoming)
246
- if (relations.size > 0) {
247
- result.push({
248
- source,
249
- target,
250
- relations: [...relations]
251
- })
252
- }
253
- }
254
- }
255
- return result
256
- }
257
-
258
- private addElement(el: Element) {
259
- if (this.#elements.has(el.id)) {
260
- throw new Error(`Element ${el.id} already exists`)
261
- }
262
- this.#elements.set(el.id, el)
263
- const parentId = parentFqn(el.id)
264
- if (parentId) {
265
- this.#parents.set(el.id, this.element(parentId))
266
- this._childrenOf(parentId).push(el)
267
- } else {
268
- this.#rootElements.add(el)
269
- }
270
- }
271
-
272
- private addRelation(rel: Relation) {
273
- if (this.#relations.has(rel.id)) {
274
- throw new Error(`Relation ${rel.id} already exists`)
275
- }
276
- this.#relations.set(rel.id, rel)
277
- this._incomingTo(rel.target).add(rel)
278
- this._outgoingFrom(rel.source).add(rel)
279
-
280
- const relParent = commonAncestor(rel.source, rel.target)
281
- // Process internal relationships
282
- if (relParent) {
283
- for (const ancestor of [relParent, ...ancestorsFqn(relParent)]) {
284
- this._internalOf(ancestor).add(rel)
285
- }
286
- }
287
- // Process source hierarchy
288
- for (const sourceAncestor of ancestorsFqn(rel.source)) {
289
- if (sourceAncestor === relParent) {
290
- break
291
- }
292
- this._outgoingFrom(sourceAncestor).add(rel)
293
- }
294
- // Process target hierarchy
295
- for (const targetAncestor of ancestorsFqn(rel.target)) {
296
- if (targetAncestor === relParent) {
297
- break
298
- }
299
- this._incomingTo(targetAncestor).add(rel)
300
- }
301
- }
302
-
303
- private _childrenOf(id: Fqn) {
304
- let children = this.#children.get(id)
305
- if (!children) {
306
- children = []
307
- this.#children.set(id, children)
308
- }
309
- return children
310
- }
311
-
312
- private _incomingTo(id: Fqn) {
313
- let incoming = this.#incoming.get(id)
314
- if (!incoming) {
315
- incoming = new RelationsSet()
316
- this.#incoming.set(id, incoming)
317
- }
318
- return incoming
319
- }
320
-
321
- private _outgoingFrom(id: Fqn) {
322
- let outgoing = this.#outgoing.get(id)
323
- if (!outgoing) {
324
- outgoing = new RelationsSet()
325
- this.#outgoing.set(id, outgoing)
326
- }
327
- return outgoing
328
- }
329
-
330
- private _internalOf(id: Fqn) {
331
- let internal = this.#internal.get(id)
332
- if (!internal) {
333
- internal = new RelationsSet()
334
- this.#internal.set(id, internal)
335
- }
336
- return internal
337
- }
338
- }