@likec4/language-server 1.8.0 → 1.9.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 +21 -0
- package/dist/browser.d.cts +22 -0
- package/dist/browser.d.mts +22 -0
- package/dist/browser.d.ts +22 -0
- package/dist/browser.mjs +19 -0
- package/dist/index.cjs +10 -0
- package/dist/index.d.cts +18 -0
- package/dist/index.d.mts +18 -0
- package/dist/index.d.ts +18 -0
- package/dist/index.mjs +1 -0
- package/dist/likec4lib.cjs +961 -0
- package/dist/likec4lib.d.cts +6 -0
- package/dist/likec4lib.d.mts +6 -0
- package/dist/likec4lib.d.ts +6 -0
- package/dist/likec4lib.mjs +957 -0
- package/dist/model-graph/index.cjs +10 -0
- package/dist/model-graph/index.d.cts +79 -0
- package/dist/model-graph/index.d.mts +79 -0
- package/dist/model-graph/index.d.ts +79 -0
- package/dist/model-graph/index.mjs +1 -0
- package/dist/node.cjs +18 -0
- package/dist/node.d.cts +20 -0
- package/dist/node.d.mts +20 -0
- package/dist/node.d.ts +20 -0
- package/dist/node.mjs +16 -0
- package/dist/protocol.cjs +25 -0
- package/dist/protocol.d.cts +43 -0
- package/dist/protocol.d.mts +43 -0
- package/dist/protocol.d.ts +43 -0
- package/dist/protocol.mjs +17 -0
- package/dist/shared/language-server.86lmJ8ZN.d.cts +1194 -0
- package/dist/shared/language-server.B1TZgyoH.cjs +5371 -0
- package/dist/shared/language-server.CCB4ESN5.mjs +1606 -0
- package/dist/shared/language-server.CFTY6j4e.d.mts +1194 -0
- package/dist/shared/language-server.D0bOlrCi.cjs +1619 -0
- package/dist/shared/language-server.Q-wtPShM.mjs +5360 -0
- package/dist/shared/language-server.RjhrBZS0.d.ts +1194 -0
- package/package.json +35 -20
- package/src/ast.ts +44 -32
- package/src/browser.ts +0 -3
- package/src/elementRef.ts +1 -1
- package/src/generated/ast.ts +105 -86
- package/src/generated/grammar.ts +1 -1
- package/src/generated-lib/icons.ts +1 -1
- package/src/like-c4.langium +30 -18
- package/src/likec4lib.ts +2 -3
- package/src/logger.ts +9 -1
- package/src/lsp/RenameProvider.ts +8 -0
- package/src/lsp/SemanticTokenProvider.ts +19 -1
- package/src/lsp/index.ts +1 -0
- package/src/model/fqn-computation.ts +33 -23
- package/src/model/fqn-index.ts +5 -20
- package/src/model/model-builder.ts +147 -90
- package/src/model/model-locator.ts +1 -1
- package/src/model/model-parser-where.ts +3 -2
- package/src/model/model-parser.ts +57 -19
- package/src/model-graph/LikeC4ModelGraph.ts +42 -21
- package/src/model-graph/compute-view/__test__/fixture.ts +16 -14
- package/src/model-graph/compute-view/compute.ts +9 -6
- package/src/model-graph/compute-view/predicates.ts +3 -3
- package/src/model-graph/dynamic-view/__test__/fixture.ts +1 -0
- package/src/model-graph/dynamic-view/compute.ts +2 -1
- package/src/model-graph/utils/elementExpressionToPredicate.ts +1 -1
- package/src/model-graph/utils/sortNodes.ts +2 -6
- package/src/module.ts +23 -3
- package/src/protocol.ts +4 -5
- package/src/references/scope-computation.ts +10 -1
- package/src/references/scope-provider.ts +22 -9
- package/src/shared/NodeKindProvider.ts +73 -34
- package/src/test/setup.ts +3 -8
- package/src/utils/graphlib.ts +11 -0
- package/src/validation/_shared.ts +24 -0
- package/src/validation/element.ts +9 -9
- package/src/validation/index.ts +2 -1
- package/src/validation/relation.ts +45 -39
- package/src/validation/specification.ts +15 -2
- package/src/validation/view.ts +7 -0
- package/src/view-utils/manual-layout.ts +1 -1
- package/src/view-utils/resolve-extended-views.ts +19 -10
- package/src/view-utils/resolve-relative-paths.ts +5 -7
- package/src/view-utils/view-hash.ts +1 -1
- package/src/reset.d.ts +0 -2
|
@@ -3,14 +3,13 @@ import {
|
|
|
3
3
|
commonAncestor,
|
|
4
4
|
type Element,
|
|
5
5
|
type Fqn,
|
|
6
|
-
InvalidModelError,
|
|
7
6
|
invariant,
|
|
8
7
|
isSameHierarchy,
|
|
9
|
-
isString,
|
|
10
8
|
parentFqn,
|
|
11
9
|
type Relation,
|
|
12
10
|
type RelationID
|
|
13
11
|
} from '@likec4/core'
|
|
12
|
+
import { isArray, isString } from 'remeda'
|
|
14
13
|
|
|
15
14
|
type Params = {
|
|
16
15
|
elements: Record<Fqn, Element>
|
|
@@ -25,7 +24,7 @@ type RelationEdge = {
|
|
|
25
24
|
}
|
|
26
25
|
|
|
27
26
|
type FqnOrElement = Fqn | Element
|
|
28
|
-
type FqnsOrElements = Fqn
|
|
27
|
+
type FqnsOrElements = ReadonlyArray<Fqn> | ReadonlyArray<Element>
|
|
29
28
|
|
|
30
29
|
const RelationsSet = Set<Relation>
|
|
31
30
|
const MapRelations = Map<Fqn, Set<Relation>>
|
|
@@ -37,9 +36,16 @@ function intersection<T>(a: Set<T>, b: Set<T>) {
|
|
|
37
36
|
return new Set([...a].filter(value => b.has(value)))
|
|
38
37
|
}
|
|
39
38
|
|
|
39
|
+
/**
|
|
40
|
+
* Used only for views calculations.
|
|
41
|
+
* Subject to change.
|
|
42
|
+
*/
|
|
40
43
|
export class LikeC4ModelGraph {
|
|
41
44
|
#elements = new Map<Fqn, Element>()
|
|
42
|
-
|
|
45
|
+
// Parent element for given FQN
|
|
46
|
+
#parents = new Map<Fqn, Element>()
|
|
47
|
+
// Children elements for given FQN
|
|
48
|
+
#children = new Map<Fqn, Element[]>()
|
|
43
49
|
#rootElements = new Set<Element>()
|
|
44
50
|
|
|
45
51
|
#relations = new Map<RelationID, Relation>()
|
|
@@ -47,7 +53,7 @@ export class LikeC4ModelGraph {
|
|
|
47
53
|
#incoming = new MapRelations()
|
|
48
54
|
// Outgoing from an element or its descendants
|
|
49
55
|
#outgoing = new MapRelations()
|
|
50
|
-
// Relationships inside the element descendants
|
|
56
|
+
// Relationships inside the element, among descendants
|
|
51
57
|
#internal = new MapRelations()
|
|
52
58
|
|
|
53
59
|
#cacheAscendingSiblings = new Map<Fqn, Element[]>()
|
|
@@ -80,7 +86,7 @@ export class LikeC4ModelGraph {
|
|
|
80
86
|
}
|
|
81
87
|
|
|
82
88
|
public children(id: Fqn) {
|
|
83
|
-
return this._childrenOf(id).
|
|
89
|
+
return this._childrenOf(id).slice()
|
|
84
90
|
}
|
|
85
91
|
|
|
86
92
|
// Get children or element itself if no children
|
|
@@ -93,19 +99,30 @@ export class LikeC4ModelGraph {
|
|
|
93
99
|
public siblings(element: Fqn | Element) {
|
|
94
100
|
const id = isString(element) ? element : element.id
|
|
95
101
|
const parent = parentFqn(id)
|
|
96
|
-
const
|
|
97
|
-
return
|
|
102
|
+
const siblings = parent ? this._childrenOf(parent) : this.rootElements
|
|
103
|
+
return siblings.filter(e => e.id !== id)
|
|
98
104
|
}
|
|
99
105
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
106
|
+
/**
|
|
107
|
+
* Get all ancestor elements (i.e. parent, parent’s parent, etc.)
|
|
108
|
+
* (from closest to root)
|
|
109
|
+
*/
|
|
110
|
+
public ancestors(element: Fqn | Element): Array<Element> {
|
|
111
|
+
let id = isString(element) ? element : element.id
|
|
112
|
+
const result = [] as Element[]
|
|
113
|
+
let parent
|
|
114
|
+
while (parent = this.#parents.get(id)) {
|
|
115
|
+
result.push(parent)
|
|
116
|
+
id = parent.id
|
|
117
|
+
}
|
|
118
|
+
return result as Array<Element>
|
|
103
119
|
}
|
|
104
120
|
|
|
105
121
|
/**
|
|
106
122
|
* Resolve siblings of the element and its ancestors
|
|
123
|
+
* (from closest to root)
|
|
107
124
|
*/
|
|
108
|
-
public ascendingSiblings(element: Fqn | Element) {
|
|
125
|
+
public ascendingSiblings(element: Fqn | Element): Array<Element> {
|
|
109
126
|
const id = isString(element) ? element : element.id
|
|
110
127
|
let siblings = this.#cacheAscendingSiblings.get(id)
|
|
111
128
|
if (!siblings) {
|
|
@@ -121,7 +138,10 @@ export class LikeC4ModelGraph {
|
|
|
121
138
|
/**
|
|
122
139
|
* Resolve all RelationEdges between element and others (any direction)
|
|
123
140
|
*/
|
|
124
|
-
public anyEdgesBetween(
|
|
141
|
+
public anyEdgesBetween(
|
|
142
|
+
_element: Fqn | Element,
|
|
143
|
+
others: ReadonlyArray<Fqn> | ReadonlyArray<Element>
|
|
144
|
+
): Array<RelationEdge> {
|
|
125
145
|
if (others.length === 0) {
|
|
126
146
|
return []
|
|
127
147
|
}
|
|
@@ -169,7 +189,7 @@ export class LikeC4ModelGraph {
|
|
|
169
189
|
/**
|
|
170
190
|
* Resolve all RelationEdges between elements (any direction)
|
|
171
191
|
*/
|
|
172
|
-
public edgesWithin<T extends Fqn[] | Element[]>(elements: T): RelationEdge
|
|
192
|
+
public edgesWithin<T extends Fqn[] | Element[]>(elements: T): Array<RelationEdge> {
|
|
173
193
|
if (elements.length < 2) {
|
|
174
194
|
return []
|
|
175
195
|
}
|
|
@@ -190,8 +210,8 @@ export class LikeC4ModelGraph {
|
|
|
190
210
|
_sources: FqnOrElement | FqnsOrElements,
|
|
191
211
|
_targets: FqnOrElement | FqnsOrElements
|
|
192
212
|
) {
|
|
193
|
-
const sources =
|
|
194
|
-
const targets =
|
|
213
|
+
const sources = isArray(_sources) ? _sources : [_sources]
|
|
214
|
+
const targets = isArray(_targets) ? _targets : [_targets]
|
|
195
215
|
if (sources.length === 0 || targets.length === 0) {
|
|
196
216
|
return []
|
|
197
217
|
}
|
|
@@ -226,12 +246,13 @@ export class LikeC4ModelGraph {
|
|
|
226
246
|
|
|
227
247
|
private addElement(el: Element) {
|
|
228
248
|
if (this.#elements.has(el.id)) {
|
|
229
|
-
throw new
|
|
249
|
+
throw new Error(`Element ${el.id} already exists`)
|
|
230
250
|
}
|
|
231
251
|
this.#elements.set(el.id, el)
|
|
232
|
-
const
|
|
233
|
-
if (
|
|
234
|
-
this.
|
|
252
|
+
const parentId = parentFqn(el.id)
|
|
253
|
+
if (parentId) {
|
|
254
|
+
this.#parents.set(el.id, this.element(parentId))
|
|
255
|
+
this._childrenOf(parentId).push(el)
|
|
235
256
|
} else {
|
|
236
257
|
this.#rootElements.add(el)
|
|
237
258
|
}
|
|
@@ -239,7 +260,7 @@ export class LikeC4ModelGraph {
|
|
|
239
260
|
|
|
240
261
|
private addRelation(rel: Relation) {
|
|
241
262
|
if (this.#relations.has(rel.id)) {
|
|
242
|
-
throw new
|
|
263
|
+
throw new Error(`Relation ${rel.id} already exists`)
|
|
243
264
|
}
|
|
244
265
|
this.#relations.set(rel.id, rel)
|
|
245
266
|
this._incomingTo(rel.target).add(rel)
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
type BorderStyle,
|
|
3
|
+
type Color,
|
|
3
4
|
type ComputedView,
|
|
4
5
|
type CustomElementExpr as C4CustomElementExpr,
|
|
5
6
|
type CustomRelationExpr as C4CustomRelationExpr,
|
|
@@ -17,7 +18,6 @@ import {
|
|
|
17
18
|
type RelationshipLineType,
|
|
18
19
|
type RelationWhereExpr,
|
|
19
20
|
type Tag,
|
|
20
|
-
type ThemeColor,
|
|
21
21
|
type ViewID,
|
|
22
22
|
type ViewRule,
|
|
23
23
|
type ViewRulePredicate,
|
|
@@ -210,28 +210,29 @@ export const fakeElements = {
|
|
|
210
210
|
|
|
211
211
|
export type FakeElementIds = keyof typeof fakeElements
|
|
212
212
|
|
|
213
|
-
const rel = ({
|
|
213
|
+
const rel = <Source extends FakeElementIds, Target extends FakeElementIds>({
|
|
214
214
|
source,
|
|
215
215
|
target,
|
|
216
216
|
title,
|
|
217
217
|
...props
|
|
218
218
|
}: {
|
|
219
|
-
source:
|
|
220
|
-
target:
|
|
219
|
+
source: Source
|
|
220
|
+
target: Target
|
|
221
221
|
title?: string
|
|
222
222
|
kind?: string
|
|
223
|
-
color?:
|
|
223
|
+
color?: Color
|
|
224
224
|
line?: RelationshipLineType
|
|
225
225
|
head?: RelationshipArrowType
|
|
226
226
|
tail?: RelationshipArrowType
|
|
227
227
|
tags?: NonEmptyArray<TestTag>
|
|
228
|
-
})
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
228
|
+
}) =>
|
|
229
|
+
({
|
|
230
|
+
id: `${source}:${target}` as RelationID,
|
|
231
|
+
title: title ?? '',
|
|
232
|
+
source: source as Fqn,
|
|
233
|
+
target: target as Fqn,
|
|
234
|
+
...(props as any)
|
|
235
|
+
}) as Omit<Relation, 'id'> & { id: `${Source}:${Target}` }
|
|
235
236
|
|
|
236
237
|
export const fakeRelations = [
|
|
237
238
|
rel({
|
|
@@ -321,7 +322,7 @@ export const fakeRelations = [
|
|
|
321
322
|
})
|
|
322
323
|
]
|
|
323
324
|
|
|
324
|
-
export type FakeRelationIds =
|
|
325
|
+
export type FakeRelationIds = (typeof fakeRelations)[number]['id']
|
|
325
326
|
|
|
326
327
|
export const fakeModel = new LikeC4ModelGraph({
|
|
327
328
|
elements: fakeElements,
|
|
@@ -335,6 +336,7 @@ const emptyView = {
|
|
|
335
336
|
description: null,
|
|
336
337
|
tags: null,
|
|
337
338
|
links: null,
|
|
339
|
+
customColorDefinitions: {},
|
|
338
340
|
rules: []
|
|
339
341
|
}
|
|
340
342
|
|
|
@@ -370,7 +372,7 @@ export function $custom(
|
|
|
370
372
|
description?: string
|
|
371
373
|
technology?: string
|
|
372
374
|
shape?: ElementShape
|
|
373
|
-
color?:
|
|
375
|
+
color?: Color
|
|
374
376
|
border?: BorderStyle
|
|
375
377
|
icon?: string
|
|
376
378
|
opacity?: number
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type {
|
|
2
|
+
Color,
|
|
2
3
|
ComputedEdge,
|
|
3
4
|
ComputedElementView,
|
|
4
5
|
EdgeId,
|
|
@@ -212,7 +213,7 @@ export class ComputeCtx {
|
|
|
212
213
|
description?: string | undefined
|
|
213
214
|
technology?: string | undefined
|
|
214
215
|
kind?: RelationshipKind | undefined
|
|
215
|
-
color?:
|
|
216
|
+
color?: Color | undefined
|
|
216
217
|
line?: RelationshipLineType | undefined
|
|
217
218
|
head?: RelationshipArrowType | undefined
|
|
218
219
|
tail?: RelationshipArrowType | undefined
|
|
@@ -273,7 +274,7 @@ export class ComputeCtx {
|
|
|
273
274
|
edge,
|
|
274
275
|
this.getEdgeLabel(relation),
|
|
275
276
|
isTruthy(relation.description) && { description: relation.description },
|
|
276
|
-
isTruthy(relation.technology) && {
|
|
277
|
+
isTruthy(relation.technology) && { technology: relation.technology },
|
|
277
278
|
isTruthy(relation.kind) && { kind: relation.kind },
|
|
278
279
|
relation.color && { color: relation.color },
|
|
279
280
|
relation.line && { line: relation.line },
|
|
@@ -537,16 +538,18 @@ export class ComputeCtx {
|
|
|
537
538
|
return this
|
|
538
539
|
}
|
|
539
540
|
nonexhaustive(expr)
|
|
540
|
-
}
|
|
541
|
+
}
|
|
541
542
|
|
|
542
|
-
protected getEdgeLabel(
|
|
543
|
+
protected getEdgeLabel(
|
|
544
|
+
relation: { title: String | undefined; technology?: String | undefined }
|
|
545
|
+
): { label: String } | false {
|
|
543
546
|
const labelParts: String[] = []
|
|
544
547
|
|
|
545
|
-
if(isTruthy(relation.title)) {
|
|
548
|
+
if (isTruthy(relation.title)) {
|
|
546
549
|
labelParts.push(relation.title)
|
|
547
550
|
}
|
|
548
551
|
|
|
549
|
-
if(isTruthy(relation.technology)) {
|
|
552
|
+
if (isTruthy(relation.technology)) {
|
|
550
553
|
labelParts.push(`[${relation.technology}]`)
|
|
551
554
|
}
|
|
552
555
|
|
|
@@ -306,15 +306,15 @@ function edgesIncomingExpr(this: ComputeCtx, expr: Expr.ElementExpression) {
|
|
|
306
306
|
return this.graph.edgesBetween(sources, targets)
|
|
307
307
|
}
|
|
308
308
|
|
|
309
|
-
const filterEdges = (edges: ComputeCtx.Edge
|
|
309
|
+
const filterEdges = (edges: ReadonlyArray<ComputeCtx.Edge>, where?: RelationPredicateFn) => {
|
|
310
310
|
if (!where) {
|
|
311
|
-
return edges
|
|
311
|
+
return edges as ComputeCtx.Edge[]
|
|
312
312
|
}
|
|
313
313
|
return pipe(
|
|
314
314
|
edges,
|
|
315
315
|
map(e => ({ ...e, relations: e.relations.filter(where) })),
|
|
316
316
|
remedaFilter(e => e.relations.length > 0)
|
|
317
|
-
)
|
|
317
|
+
) as ComputeCtx.Edge[]
|
|
318
318
|
}
|
|
319
319
|
|
|
320
320
|
const filterRelations = (edges: ComputeCtx.Edge[], where?: RelationPredicateFn) => {
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type {
|
|
2
|
+
Color,
|
|
2
3
|
ComputedDynamicView,
|
|
3
4
|
ComputedEdge,
|
|
4
5
|
DynamicView,
|
|
@@ -38,7 +39,7 @@ export namespace DynamicViewComputeCtx {
|
|
|
38
39
|
title: string | null
|
|
39
40
|
description?: string
|
|
40
41
|
technology?: string
|
|
41
|
-
color?:
|
|
42
|
+
color?: Color
|
|
42
43
|
line?: RelationshipLineType
|
|
43
44
|
head?: RelationshipArrowType
|
|
44
45
|
tail?: RelationshipArrowType
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Expr, nonexhaustive, parentFqn } from '@likec4/core'
|
|
2
|
-
import { type Element, whereOperatorAsPredicate } from '@likec4/core
|
|
2
|
+
import { type Element, whereOperatorAsPredicate } from '@likec4/core'
|
|
3
3
|
import { isNullish } from 'remeda'
|
|
4
4
|
|
|
5
5
|
type Predicate<T> = (x: T) => boolean
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import pkg from '@dagrejs/graphlib'
|
|
2
1
|
import {
|
|
3
2
|
compareByFqnHierarchically,
|
|
4
3
|
compareRelations,
|
|
@@ -10,10 +9,7 @@ import {
|
|
|
10
9
|
nonNullable
|
|
11
10
|
} from '@likec4/core'
|
|
12
11
|
import { difference, filter, map, pipe, sort, take } from 'remeda'
|
|
13
|
-
|
|
14
|
-
// '@dagrejs/graphlib' is a CommonJS module
|
|
15
|
-
// Here is a workaround to import it
|
|
16
|
-
const { Graph, alg } = pkg
|
|
12
|
+
import { Graph, postorder } from '../../utils/graphlib'
|
|
17
13
|
|
|
18
14
|
// side effect
|
|
19
15
|
function sortChildren(nodes: readonly ComputedNode[]) {
|
|
@@ -92,7 +88,7 @@ export function sortNodes({
|
|
|
92
88
|
map(n => n.id)
|
|
93
89
|
)
|
|
94
90
|
}
|
|
95
|
-
const orderedIds =
|
|
91
|
+
const orderedIds = postorder(g, sources).reverse() as Fqn[]
|
|
96
92
|
const sorted = orderedIds.map(getNode)
|
|
97
93
|
if (sorted.length < nodes.length) {
|
|
98
94
|
const unsorted = difference(nodes, sorted)
|
package/src/module.ts
CHANGED
|
@@ -9,7 +9,7 @@ import {
|
|
|
9
9
|
type PartialLangiumSharedServices
|
|
10
10
|
} from 'langium/lsp'
|
|
11
11
|
import { LikeC4GeneratedModule, LikeC4GeneratedSharedModule } from './generated/module'
|
|
12
|
-
import { logErrorToTelemetry } from './logger'
|
|
12
|
+
import { logErrorToTelemetry, logToLspConnection } from './logger'
|
|
13
13
|
import {
|
|
14
14
|
LikeC4CodeLensProvider,
|
|
15
15
|
LikeC4CompletionProvider,
|
|
@@ -17,6 +17,7 @@ import {
|
|
|
17
17
|
LikeC4DocumentLinkProvider,
|
|
18
18
|
LikeC4DocumentSymbolProvider,
|
|
19
19
|
LikeC4HoverProvider,
|
|
20
|
+
LikeC4RenameProvider,
|
|
20
21
|
LikeC4SemanticTokenProvider
|
|
21
22
|
} from './lsp'
|
|
22
23
|
import { FqnIndex, LikeC4ModelBuilder, LikeC4ModelLocator, LikeC4ModelParser } from './model'
|
|
@@ -69,6 +70,7 @@ export interface LikeC4AddedServices {
|
|
|
69
70
|
ModelChanges: LikeC4ModelChanges
|
|
70
71
|
}
|
|
71
72
|
lsp: {
|
|
73
|
+
RenameProvider: LikeC4RenameProvider
|
|
72
74
|
CompletionProvider: LikeC4CompletionProvider
|
|
73
75
|
DocumentHighlightProvider: LikeC4DocumentHighlightProvider
|
|
74
76
|
DocumentSymbolProvider: LikeC4DocumentSymbolProvider
|
|
@@ -101,6 +103,7 @@ export const LikeC4Module: Module<LikeC4Services, PartialLangiumServices & LikeC
|
|
|
101
103
|
ModelLocator: bind(LikeC4ModelLocator)
|
|
102
104
|
},
|
|
103
105
|
lsp: {
|
|
106
|
+
RenameProvider: bind(LikeC4RenameProvider),
|
|
104
107
|
CompletionProvider: bind(LikeC4CompletionProvider),
|
|
105
108
|
DocumentHighlightProvider: bind(LikeC4DocumentHighlightProvider),
|
|
106
109
|
DocumentSymbolProvider: bind(LikeC4DocumentSymbolProvider),
|
|
@@ -136,7 +139,15 @@ export function createCustomLanguageServices<I1, I2, I3, I extends I1 & I2 & I3
|
|
|
136
139
|
const likec4 = inject(modules)
|
|
137
140
|
shared.ServiceRegistry.register(likec4)
|
|
138
141
|
registerValidationChecks(likec4)
|
|
139
|
-
|
|
142
|
+
|
|
143
|
+
if (!context.connection) {
|
|
144
|
+
// We don't run inside a language server
|
|
145
|
+
// Therefore, initialize the configuration provider instantly
|
|
146
|
+
shared.workspace.ConfigurationProvider.initialized({})
|
|
147
|
+
} else {
|
|
148
|
+
likec4.Rpc.init()
|
|
149
|
+
}
|
|
150
|
+
|
|
140
151
|
return { shared, likec4 }
|
|
141
152
|
}
|
|
142
153
|
|
|
@@ -146,6 +157,7 @@ export function createSharedServices(context: LanguageServicesContext = {}): Lik
|
|
|
146
157
|
...context
|
|
147
158
|
}
|
|
148
159
|
if (context.connection) {
|
|
160
|
+
logToLspConnection(context.connection)
|
|
149
161
|
logErrorToTelemetry(context.connection)
|
|
150
162
|
}
|
|
151
163
|
|
|
@@ -164,7 +176,15 @@ export function createLanguageServices(context: LanguageServicesContext = {}): {
|
|
|
164
176
|
const likec4 = inject(createDefaultModule({ shared }), LikeC4GeneratedModule, LikeC4Module)
|
|
165
177
|
shared.ServiceRegistry.register(likec4)
|
|
166
178
|
registerValidationChecks(likec4)
|
|
167
|
-
|
|
179
|
+
|
|
180
|
+
if (!context.connection) {
|
|
181
|
+
// We don't run inside a language server
|
|
182
|
+
// Therefore, initialize the configuration provider instantly
|
|
183
|
+
shared.workspace.ConfigurationProvider.initialized({})
|
|
184
|
+
} else {
|
|
185
|
+
likec4.Rpc.init()
|
|
186
|
+
}
|
|
187
|
+
|
|
168
188
|
return { shared, likec4 }
|
|
169
189
|
}
|
|
170
190
|
|
package/src/protocol.ts
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import type {
|
|
2
|
-
|
|
2
|
+
ComputedLikeC4Model,
|
|
3
3
|
ComputedView,
|
|
4
4
|
Fqn,
|
|
5
|
-
|
|
6
|
-
LikeC4Model,
|
|
5
|
+
ParsedLikeC4Model,
|
|
7
6
|
RelationID,
|
|
8
7
|
ViewChange,
|
|
9
8
|
ViewID
|
|
@@ -17,12 +16,12 @@ export type OnDidChangeModelNotification = typeof onDidChangeModel
|
|
|
17
16
|
// #endregion
|
|
18
17
|
|
|
19
18
|
// #region To server
|
|
20
|
-
export const fetchModel = new RequestType0<{ model:
|
|
19
|
+
export const fetchModel = new RequestType0<{ model: ParsedLikeC4Model | null }, void>(
|
|
21
20
|
'likec4/fetchModel'
|
|
22
21
|
)
|
|
23
22
|
export type FetchModelRequest = typeof fetchModel
|
|
24
23
|
|
|
25
|
-
export const fetchComputedModel = new RequestType0<{ model:
|
|
24
|
+
export const fetchComputedModel = new RequestType0<{ model: ComputedLikeC4Model | null }, void>(
|
|
26
25
|
'likec4/fetchComputedModel'
|
|
27
26
|
)
|
|
28
27
|
export type FetchComputedModelRequest = typeof fetchComputedModel
|
|
@@ -106,7 +106,8 @@ export class LikeC4ScopeComputation extends DefaultScopeComputation {
|
|
|
106
106
|
const spec of specifications.flatMap(s => [
|
|
107
107
|
...s.elements,
|
|
108
108
|
...s.relationships,
|
|
109
|
-
...s.tags
|
|
109
|
+
...s.tags,
|
|
110
|
+
...s.colors
|
|
110
111
|
])
|
|
111
112
|
) {
|
|
112
113
|
try {
|
|
@@ -136,6 +137,14 @@ export class LikeC4ScopeComputation extends DefaultScopeComputation {
|
|
|
136
137
|
}
|
|
137
138
|
continue
|
|
138
139
|
}
|
|
140
|
+
case ast.isSpecificationColor(spec): {
|
|
141
|
+
if (isTruthy(spec.name.name)) {
|
|
142
|
+
docExports.push(
|
|
143
|
+
this.descriptions.createDescription(spec.name, spec.name.name, document)
|
|
144
|
+
)
|
|
145
|
+
}
|
|
146
|
+
continue
|
|
147
|
+
}
|
|
139
148
|
// Thow error if not exhaustive
|
|
140
149
|
default:
|
|
141
150
|
nonexhaustive(spec)
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { invariant } from '@likec4/core'
|
|
2
|
+
import type * as c4 from '@likec4/core'
|
|
2
3
|
import type { AstNode } from 'langium'
|
|
3
4
|
import {
|
|
4
5
|
type AstNodeDescription,
|
|
@@ -7,6 +8,7 @@ import {
|
|
|
7
8
|
DONE_RESULT,
|
|
8
9
|
EMPTY_SCOPE,
|
|
9
10
|
EMPTY_STREAM,
|
|
11
|
+
MapScope,
|
|
10
12
|
type ReferenceInfo,
|
|
11
13
|
type Scope,
|
|
12
14
|
type Stream,
|
|
@@ -102,6 +104,17 @@ export class LikeC4ScopeProvider extends DefaultScopeProvider {
|
|
|
102
104
|
if (parent) {
|
|
103
105
|
return new StreamScope(this.scopeElementRef(parent))
|
|
104
106
|
}
|
|
107
|
+
// if we have elementRef "this" or "it" we resolve it to the closest element
|
|
108
|
+
if (context.reference.$refText === 'this' || context.reference.$refText === 'it') {
|
|
109
|
+
const closestElement = AstUtils.getContainerOfType(container, ast.isElement)
|
|
110
|
+
if (closestElement) {
|
|
111
|
+
return new MapScope([
|
|
112
|
+
this.descriptions.createDescription(closestElement, context.reference.$refText)
|
|
113
|
+
])
|
|
114
|
+
} else {
|
|
115
|
+
return EMPTY_SCOPE
|
|
116
|
+
}
|
|
117
|
+
}
|
|
105
118
|
}
|
|
106
119
|
return this.computeScope(context)
|
|
107
120
|
} catch (e) {
|
|
@@ -116,26 +129,26 @@ export class LikeC4ScopeProvider extends DefaultScopeProvider {
|
|
|
116
129
|
|
|
117
130
|
protected computeScope(context: ReferenceInfo) {
|
|
118
131
|
const referenceType = this.reflection.getReferenceType(context)
|
|
132
|
+
// computeScope is called only for elements
|
|
133
|
+
invariant(referenceType === ast.Element, 'Invalid reference type')
|
|
119
134
|
const scopes: Stream<AstNodeDescription>[] = []
|
|
120
135
|
const doc = getDocument(context.container)
|
|
121
136
|
const precomputed = doc.precomputedScopes
|
|
122
137
|
|
|
123
138
|
if (precomputed) {
|
|
124
139
|
const byReferenceType = (desc: AstNodeDescription) => this.reflection.isSubtype(desc.type, referenceType)
|
|
125
|
-
|
|
126
140
|
let container: AstNode | undefined = context.container
|
|
127
141
|
while (container) {
|
|
128
142
|
const elements = precomputed.get(container).filter(byReferenceType)
|
|
129
143
|
if (elements.length > 0) {
|
|
130
144
|
scopes.push(stream(elements))
|
|
131
145
|
}
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
}
|
|
146
|
+
|
|
147
|
+
if (ast.isExtendElementBody(container)) {
|
|
148
|
+
scopes.push(this.scopeExtendElement(container.$container))
|
|
149
|
+
}
|
|
150
|
+
if (ast.isElementViewBody(container)) {
|
|
151
|
+
scopes.push(this.scopeElementView(container.$container))
|
|
139
152
|
}
|
|
140
153
|
container = container.$container
|
|
141
154
|
}
|