@likec4/language-server 1.17.0 → 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.
- package/contrib/likec4.tmLanguage.json +1 -1
- package/dist/browser.cjs +1 -1
- package/dist/browser.d.cts +2 -2
- package/dist/browser.d.mts +2 -2
- package/dist/browser.d.ts +2 -2
- package/dist/browser.mjs +2 -2
- package/dist/index.cjs +1 -1
- package/dist/index.d.cts +2 -2
- package/dist/index.d.mts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.mjs +2 -2
- package/dist/protocol.d.cts +8 -5
- package/dist/protocol.d.mts +8 -5
- package/dist/protocol.d.ts +8 -5
- package/dist/shared/{language-server.DZRuJVSg.cjs → language-server.CO_nmHiL.cjs} +5605 -4215
- package/dist/shared/{language-server.DJo88TnT.d.cts → language-server.Da6ey08o.d.cts} +391 -110
- package/dist/shared/{language-server.PEjk7U9s.d.ts → language-server.De7S3e5Z.d.ts} +391 -110
- package/dist/shared/{language-server.BgDKnNok.d.mts → language-server.Dj4iDjtB.d.mts} +391 -110
- package/dist/shared/{language-server.B8qSDsWW.mjs → language-server.oO_9JoAG.mjs} +5594 -4215
- package/package.json +17 -31
- package/src/Rpc.ts +6 -3
- package/src/ast.ts +124 -71
- package/src/formatting/LikeC4Formatter.ts +9 -4
- package/src/generated/ast.ts +656 -40
- package/src/generated/grammar.ts +2 -2
- package/src/generated/module.ts +3 -2
- package/src/index.ts +1 -0
- package/src/like-c4.langium +170 -22
- package/src/logger.ts +7 -2
- package/src/lsp/CodeLensProvider.ts +0 -1
- package/src/lsp/CompletionProvider.ts +17 -2
- package/src/lsp/DocumentSymbolProvider.ts +5 -2
- package/src/lsp/HoverProvider.ts +34 -2
- package/src/lsp/SemanticTokenProvider.ts +58 -32
- package/src/model/deployments-index.ts +218 -0
- package/src/model/fqn-computation.ts +1 -1
- package/src/model/fqn-index.ts +0 -1
- package/src/model/index.ts +1 -0
- package/src/model/model-builder.ts +172 -37
- package/src/model/model-locator.ts +36 -7
- package/src/model/model-parser.ts +554 -92
- package/src/model-change/changeViewLayout.ts +2 -2
- package/src/module.ts +10 -4
- package/src/protocol.ts +10 -6
- package/src/references/index.ts +1 -0
- package/src/references/name-provider.ts +37 -0
- package/src/references/scope-computation.ts +130 -21
- package/src/references/scope-provider.ts +63 -36
- package/src/shared/NodeKindProvider.ts +15 -3
- package/src/utils/deploymentRef.ts +31 -0
- package/src/{elementRef.ts → utils/elementRef.ts} +1 -1
- package/src/utils/stringHash.ts +2 -2
- package/src/validation/_shared.ts +7 -5
- package/src/validation/deployment-checks.ts +144 -0
- package/src/validation/dynamic-view-step.ts +1 -1
- package/src/validation/index.ts +7 -0
- package/src/validation/relation.ts +1 -1
- package/src/validation/view-predicates/deployments.ts +56 -0
- package/src/validation/view-predicates/index.ts +1 -0
- package/src/view-utils/assignNavigateTo.ts +6 -5
- package/src/view-utils/index.ts +0 -1
- package/dist/model-graph/index.cjs +0 -10
- package/dist/model-graph/index.d.cts +0 -81
- package/dist/model-graph/index.d.mts +0 -81
- package/dist/model-graph/index.d.ts +0 -81
- package/dist/model-graph/index.mjs +0 -1
- package/dist/shared/language-server.BGGRJRnr.d.mts +0 -1338
- package/dist/shared/language-server.BXFhlTPo.mjs +0 -1953
- package/dist/shared/language-server.Bmpq16Gw.d.ts +0 -1338
- package/dist/shared/language-server.C1ZfM22X.d.cts +0 -1338
- package/dist/shared/language-server.N8HLDQqz.cjs +0 -1967
- package/src/model-graph/LikeC4ModelGraph.ts +0 -338
- package/src/model-graph/compute-view/__test__/fixture.ts +0 -630
- package/src/model-graph/compute-view/compute.ts +0 -788
- package/src/model-graph/compute-view/index.ts +0 -33
- package/src/model-graph/compute-view/predicates.ts +0 -509
- package/src/model-graph/dynamic-view/__test__/fixture.ts +0 -61
- package/src/model-graph/dynamic-view/compute.ts +0 -281
- package/src/model-graph/dynamic-view/index.ts +0 -29
- package/src/model-graph/index.ts +0 -3
- package/src/model-graph/utils/applyCustomElementProperties.ts +0 -65
- package/src/model-graph/utils/applyCustomRelationProperties.ts +0 -41
- package/src/model-graph/utils/applyViewRuleStyles.ts +0 -49
- package/src/model-graph/utils/buildComputeNodes.ts +0 -113
- package/src/model-graph/utils/buildElementNotations.ts +0 -63
- package/src/model-graph/utils/elementExpressionToPredicate.ts +0 -39
- package/src/model-graph/utils/relationExpressionToPredicates.ts +0 -43
- package/src/model-graph/utils/sortNodes.ts +0 -105
- package/src/model-graph/utils/uniqueTags.test.ts +0 -42
- package/src/model-graph/utils/uniqueTags.ts +0 -19
- package/src/utils/graphlib.ts +0 -9
- package/src/view-utils/resolve-extended-views.ts +0 -66
- package/src/view-utils/resolve-global-rules.ts +0 -88
- 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
|
-
}
|