@likec4/language-server 1.21.0 → 1.22.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/README.md +4 -1
- package/bin/likec4-language-server.mjs +5 -2
- package/dist/LikeC4FileSystem.js +2 -2
- package/dist/browser.d.ts +3 -3
- package/dist/browser.js +17 -2
- package/dist/bundled.d.ts +8 -0
- package/dist/bundled.js +25 -0
- package/dist/bundled.mjs +2587 -4306
- package/dist/generated-lib/icons.js +1 -0
- package/dist/index.d.ts +3 -3
- package/dist/index.js +23 -2
- package/dist/logger.d.ts +9 -3
- package/dist/logger.js +35 -55
- package/dist/model/fqn-computation.js +2 -2
- package/dist/model/model-builder.js +13 -14
- package/dist/model-change/ModelChanges.js +2 -2
- package/dist/module.js +1 -4
- package/dist/references/scope-provider.js +3 -3
- package/dist/view-utils/manual-layout.js +2 -2
- package/dist/views/configurable-layouter.js +4 -4
- package/dist/views/likec4-views.d.ts +2 -1
- package/dist/views/likec4-views.js +2 -2
- package/package.json +14 -14
- package/dist/test/setup.d.ts +0 -1
- package/dist/test/setup.js +0 -7
- package/src/LikeC4FileSystem.ts +0 -38
- package/src/Rpc.ts +0 -134
- package/src/ast.ts +0 -556
- package/src/browser.ts +0 -35
- package/src/documentation/documentation-provider.ts +0 -52
- package/src/documentation/index.ts +0 -1
- package/src/formatting/LikeC4Formatter.ts +0 -639
- package/src/formatting/utils.ts +0 -26
- package/src/generated/ast.ts +0 -3735
- package/src/generated/grammar.ts +0 -10
- package/src/generated/module.ts +0 -33
- package/src/generated-lib/icons.ts +0 -1537
- package/src/index.ts +0 -30
- package/src/like-c4.langium +0 -901
- package/src/likec4lib.ts +0 -6
- package/src/logger.ts +0 -80
- package/src/lsp/CodeLensProvider.ts +0 -50
- package/src/lsp/CompletionProvider.ts +0 -147
- package/src/lsp/DocumentHighlightProvider.ts +0 -12
- package/src/lsp/DocumentLinkProvider.ts +0 -65
- package/src/lsp/DocumentSymbolProvider.ts +0 -313
- package/src/lsp/HoverProvider.ts +0 -92
- package/src/lsp/RenameProvider.ts +0 -8
- package/src/lsp/SemanticTokenProvider.ts +0 -383
- package/src/lsp/index.ts +0 -8
- package/src/model/deployments-index.ts +0 -209
- package/src/model/fqn-computation.ts +0 -83
- package/src/model/fqn-index.ts +0 -138
- package/src/model/index.ts +0 -6
- package/src/model/model-builder.ts +0 -724
- package/src/model/model-locator.ts +0 -146
- package/src/model/model-parser-where.ts +0 -84
- package/src/model/model-parser.ts +0 -86
- package/src/model/parser/Base.ts +0 -113
- package/src/model/parser/DeploymentModelParser.ts +0 -192
- package/src/model/parser/DeploymentViewParser.ts +0 -122
- package/src/model/parser/FqnRefParser.ts +0 -143
- package/src/model/parser/GlobalsParser.ts +0 -96
- package/src/model/parser/ModelParser.ts +0 -170
- package/src/model/parser/PredicatesParser.ts +0 -315
- package/src/model/parser/SpecificationParser.ts +0 -133
- package/src/model/parser/ViewsParser.ts +0 -428
- package/src/model-change/ModelChanges.ts +0 -101
- package/src/model-change/changeElementStyle.ts +0 -172
- package/src/model-change/changeViewLayout.ts +0 -47
- package/src/model-change/saveManualLayout.ts +0 -41
- package/src/module.ts +0 -255
- package/src/protocol.ts +0 -93
- package/src/references/index.ts +0 -3
- package/src/references/name-provider.ts +0 -37
- package/src/references/scope-computation.ts +0 -364
- package/src/references/scope-provider.ts +0 -201
- package/src/shared/NodeKindProvider.ts +0 -121
- package/src/shared/WorkspaceManager.ts +0 -48
- package/src/shared/WorkspaceSymbolProvider.ts +0 -3
- package/src/shared/index.ts +0 -3
- package/src/test/index.ts +0 -1
- package/src/test/setup.ts +0 -8
- package/src/test/testServices.ts +0 -152
- package/src/utils/disposable.ts +0 -30
- package/src/utils/elementRef.ts +0 -26
- package/src/utils/fqnRef.ts +0 -56
- package/src/utils/index.ts +0 -2
- package/src/utils/printDocs.ts +0 -3
- package/src/utils/stringHash.ts +0 -6
- package/src/validation/_shared.ts +0 -29
- package/src/validation/deployment-checks.ts +0 -131
- package/src/validation/dynamic-view-rule.ts +0 -23
- package/src/validation/dynamic-view-step.ts +0 -36
- package/src/validation/element.ts +0 -56
- package/src/validation/index.ts +0 -171
- package/src/validation/property-checks.ts +0 -52
- package/src/validation/relation.ts +0 -63
- package/src/validation/specification.ts +0 -205
- package/src/validation/view-predicates/element-with.ts +0 -36
- package/src/validation/view-predicates/expanded-element.ts +0 -16
- package/src/validation/view-predicates/expression-v2.ts +0 -101
- package/src/validation/view-predicates/incoming.ts +0 -20
- package/src/validation/view-predicates/index.ts +0 -6
- package/src/validation/view-predicates/outgoing.ts +0 -20
- package/src/validation/view-predicates/relation-with.ts +0 -17
- package/src/validation/view.ts +0 -37
- package/src/view-utils/assignNavigateTo.ts +0 -31
- package/src/view-utils/index.ts +0 -2
- package/src/view-utils/manual-layout.ts +0 -116
- package/src/view-utils/resolve-relative-paths.ts +0 -90
- package/src/views/configurable-layouter.ts +0 -65
- package/src/views/index.ts +0 -1
- package/src/views/likec4-views.ts +0 -139
package/src/Rpc.ts
DELETED
|
@@ -1,134 +0,0 @@
|
|
|
1
|
-
import { debounce, funnel } from 'remeda'
|
|
2
|
-
import { logError, logger } from './logger'
|
|
3
|
-
import type { LikeC4Services } from './module'
|
|
4
|
-
|
|
5
|
-
import { nonexhaustive } from '@likec4/core'
|
|
6
|
-
import { Disposable, interruptAndCheck, URI, UriUtils } from 'langium'
|
|
7
|
-
import { isLikeC4LangiumDocument } from './ast'
|
|
8
|
-
import { Scheme } from './likec4lib'
|
|
9
|
-
import {
|
|
10
|
-
buildDocuments,
|
|
11
|
-
changeView,
|
|
12
|
-
computeView,
|
|
13
|
-
fetchComputedModel,
|
|
14
|
-
fetchModel,
|
|
15
|
-
layoutView,
|
|
16
|
-
locate,
|
|
17
|
-
onDidChangeModel,
|
|
18
|
-
} from './protocol'
|
|
19
|
-
import { ADisposable } from './utils'
|
|
20
|
-
|
|
21
|
-
export class Rpc extends ADisposable {
|
|
22
|
-
constructor(private services: LikeC4Services) {
|
|
23
|
-
super()
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
init() {
|
|
27
|
-
const modelBuilder = this.services.likec4.ModelBuilder
|
|
28
|
-
const modelLocator = this.services.likec4.ModelLocator
|
|
29
|
-
const modelEditor = this.services.likec4.ModelChanges
|
|
30
|
-
const views = this.services.likec4.Views
|
|
31
|
-
const connection = this.services.shared.lsp.Connection
|
|
32
|
-
if (!connection) {
|
|
33
|
-
logger.info(`[ServerRpc] no connection, not initializing`)
|
|
34
|
-
return
|
|
35
|
-
}
|
|
36
|
-
logger.info(`[ServerRpc] init`)
|
|
37
|
-
const LangiumDocuments = this.services.shared.workspace.LangiumDocuments
|
|
38
|
-
const DocumentBuilder = this.services.shared.workspace.DocumentBuilder
|
|
39
|
-
|
|
40
|
-
const notifyModelParsed = funnel(
|
|
41
|
-
() => {
|
|
42
|
-
connection.sendNotification(onDidChangeModel, '').catch(e => {
|
|
43
|
-
logger.warn(`[ServerRpc] error sending onDidChangeModel: ${e}`)
|
|
44
|
-
return Promise.resolve()
|
|
45
|
-
})
|
|
46
|
-
},
|
|
47
|
-
{
|
|
48
|
-
minQuietPeriodMs: 250,
|
|
49
|
-
maxBurstDurationMs: 1000,
|
|
50
|
-
minGapMs: 200,
|
|
51
|
-
},
|
|
52
|
-
)
|
|
53
|
-
|
|
54
|
-
let isFirstBuild = true
|
|
55
|
-
|
|
56
|
-
this.onDispose(
|
|
57
|
-
modelBuilder.onModelParsed(() => notifyModelParsed.call()),
|
|
58
|
-
connection.onRequest(fetchComputedModel, async ({ cleanCaches }, cancelToken) => {
|
|
59
|
-
if (cleanCaches) {
|
|
60
|
-
this.services.WorkspaceCache.clear()
|
|
61
|
-
this.services.DocumentCache.clear()
|
|
62
|
-
}
|
|
63
|
-
const model = await modelBuilder.buildComputedModel(cancelToken)
|
|
64
|
-
return { model }
|
|
65
|
-
}),
|
|
66
|
-
connection.onRequest(fetchModel, async cancelToken => {
|
|
67
|
-
const model = await modelBuilder.buildModel(cancelToken)
|
|
68
|
-
return { model }
|
|
69
|
-
}),
|
|
70
|
-
connection.onRequest(computeView, async ({ viewId }, cancelToken) => {
|
|
71
|
-
const view = await modelBuilder.computeView(viewId, cancelToken)
|
|
72
|
-
return { view }
|
|
73
|
-
}),
|
|
74
|
-
connection.onRequest(layoutView, async ({ viewId }, cancelToken) => {
|
|
75
|
-
const result = await views.layoutView(viewId, cancelToken)
|
|
76
|
-
return { result }
|
|
77
|
-
}),
|
|
78
|
-
connection.onRequest(buildDocuments, async ({ docs }, cancelToken) => {
|
|
79
|
-
const changed = docs.map(d => URI.parse(d))
|
|
80
|
-
const notChanged = (uri: URI) => changed.every(c => !UriUtils.equals(c, uri))
|
|
81
|
-
const deleted = LangiumDocuments.all
|
|
82
|
-
.filter(d => isLikeC4LangiumDocument(d) && notChanged(d.uri) && d.uri.scheme !== Scheme)
|
|
83
|
-
.map(d => d.uri)
|
|
84
|
-
.toArray()
|
|
85
|
-
logger.debug(
|
|
86
|
-
`[ServerRpc] received request to build:
|
|
87
|
-
changed (total ${changed.length}):${docs.map(d => '\n - ' + d).join('')}
|
|
88
|
-
deleted (total ${deleted.length}):${deleted.map(d => '\n - ' + d.toString()).join('\n')}`,
|
|
89
|
-
)
|
|
90
|
-
|
|
91
|
-
if (!isFirstBuild && (changed.length + deleted.length) > 0) {
|
|
92
|
-
await Promise.allSettled(
|
|
93
|
-
[...changed, ...deleted].map(async d => {
|
|
94
|
-
const uri = d.toString()
|
|
95
|
-
logger.debug(`clear diagnostics for ${uri}`)
|
|
96
|
-
try {
|
|
97
|
-
await connection.sendDiagnostics({
|
|
98
|
-
uri,
|
|
99
|
-
diagnostics: [],
|
|
100
|
-
})
|
|
101
|
-
} catch (e) {
|
|
102
|
-
// Ignore
|
|
103
|
-
logger.warn(`error clearing diagnostics for ${uri}: ${e}`)
|
|
104
|
-
}
|
|
105
|
-
}),
|
|
106
|
-
)
|
|
107
|
-
}
|
|
108
|
-
isFirstBuild = false
|
|
109
|
-
await interruptAndCheck(cancelToken)
|
|
110
|
-
await DocumentBuilder.update(changed, deleted, cancelToken)
|
|
111
|
-
}),
|
|
112
|
-
connection.onRequest(locate, params => {
|
|
113
|
-
switch (true) {
|
|
114
|
-
case 'element' in params:
|
|
115
|
-
return modelLocator.locateElement(params.element, params.property ?? 'name')
|
|
116
|
-
case 'relation' in params:
|
|
117
|
-
return modelLocator.locateRelation(params.relation)
|
|
118
|
-
case 'view' in params:
|
|
119
|
-
return modelLocator.locateView(params.view)
|
|
120
|
-
case 'deployment' in params:
|
|
121
|
-
return modelLocator.locateDeploymentElement(params.deployment, params.property ?? 'name')
|
|
122
|
-
default:
|
|
123
|
-
nonexhaustive(params)
|
|
124
|
-
}
|
|
125
|
-
}),
|
|
126
|
-
connection.onRequest(changeView, async (request, _cancelToken) => {
|
|
127
|
-
return await modelEditor.applyChange(request)
|
|
128
|
-
}),
|
|
129
|
-
Disposable.create(() => {
|
|
130
|
-
notifyModelParsed.cancel()
|
|
131
|
-
}),
|
|
132
|
-
)
|
|
133
|
-
}
|
|
134
|
-
}
|
package/src/ast.ts
DELETED
|
@@ -1,556 +0,0 @@
|
|
|
1
|
-
import type * as c4 from '@likec4/core'
|
|
2
|
-
import { DefaultArrowType, DefaultLineStyle, DefaultRelationshipColor, LinkedList, nonexhaustive } from '@likec4/core'
|
|
3
|
-
import type { AstNode, AstNodeDescription, DiagnosticInfo, LangiumDocument, MultiMap } from 'langium'
|
|
4
|
-
import { DocumentState } from 'langium'
|
|
5
|
-
import { clamp, isBoolean, isDefined, isNullish, isTruthy } from 'remeda'
|
|
6
|
-
import type { ConditionalPick, SetRequired, ValueOf, Writable } from 'type-fest'
|
|
7
|
-
import type { Diagnostic } from 'vscode-languageserver-types'
|
|
8
|
-
import type { LikeC4Grammar } from './generated/ast'
|
|
9
|
-
import * as ast from './generated/ast'
|
|
10
|
-
import { LikeC4LanguageMetaData } from './generated/module'
|
|
11
|
-
import { elementRef } from './utils/elementRef'
|
|
12
|
-
import type { IsValidFn } from './validation'
|
|
13
|
-
|
|
14
|
-
export { ast }
|
|
15
|
-
|
|
16
|
-
const idattr = Symbol.for('idattr')
|
|
17
|
-
|
|
18
|
-
declare module './generated/ast' {
|
|
19
|
-
export interface Element {
|
|
20
|
-
[idattr]?: c4.Fqn | undefined
|
|
21
|
-
}
|
|
22
|
-
export interface ElementView {
|
|
23
|
-
[idattr]?: c4.ViewId | undefined
|
|
24
|
-
}
|
|
25
|
-
export interface DynamicView {
|
|
26
|
-
[idattr]?: c4.ViewId | undefined
|
|
27
|
-
}
|
|
28
|
-
export interface DeploymentView {
|
|
29
|
-
[idattr]?: c4.ViewId | undefined
|
|
30
|
-
}
|
|
31
|
-
export interface DeploymentNode {
|
|
32
|
-
[idattr]?: c4.Fqn | undefined
|
|
33
|
-
}
|
|
34
|
-
export interface DeployedInstance {
|
|
35
|
-
[idattr]?: c4.Fqn | undefined
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
type ParsedElementStyle = {
|
|
40
|
-
shape?: c4.ElementShape
|
|
41
|
-
icon?: c4.IconUrl
|
|
42
|
-
color?: c4.Color
|
|
43
|
-
border?: c4.BorderStyle
|
|
44
|
-
opacity?: number
|
|
45
|
-
multiple?: boolean
|
|
46
|
-
size?: c4.ShapeSize
|
|
47
|
-
padding?: c4.SpacingSize
|
|
48
|
-
textSize?: c4.TextSize
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
export interface ParsedAstSpecification {
|
|
52
|
-
tags: Set<c4.Tag>
|
|
53
|
-
elements: Record<c4.ElementKind, {
|
|
54
|
-
technology?: string
|
|
55
|
-
notation?: string
|
|
56
|
-
style: ParsedElementStyle
|
|
57
|
-
}>
|
|
58
|
-
relationships: Record<
|
|
59
|
-
c4.RelationshipKind,
|
|
60
|
-
{
|
|
61
|
-
technology?: string
|
|
62
|
-
notation?: string
|
|
63
|
-
color?: c4.Color
|
|
64
|
-
line?: c4.RelationshipLineType
|
|
65
|
-
head?: c4.RelationshipArrowType
|
|
66
|
-
tail?: c4.RelationshipArrowType
|
|
67
|
-
}
|
|
68
|
-
>
|
|
69
|
-
colors: Record<
|
|
70
|
-
c4.CustomColor,
|
|
71
|
-
{
|
|
72
|
-
color: c4.HexColorLiteral
|
|
73
|
-
}
|
|
74
|
-
>
|
|
75
|
-
deployments: Record<c4.DeploymentNodeKind, c4.DeploymentNodeKindSpecification>
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
export interface ParsedAstElement {
|
|
79
|
-
id: c4.Fqn
|
|
80
|
-
astPath: string
|
|
81
|
-
kind: c4.ElementKind
|
|
82
|
-
title: string
|
|
83
|
-
description?: string
|
|
84
|
-
technology?: string
|
|
85
|
-
tags?: c4.NonEmptyArray<c4.Tag>
|
|
86
|
-
links?: c4.NonEmptyArray<ParsedLink>
|
|
87
|
-
style: ParsedElementStyle
|
|
88
|
-
metadata?: { [key: string]: string }
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
export interface ParsedAstExtendElement {
|
|
92
|
-
id: c4.Fqn
|
|
93
|
-
astPath: string
|
|
94
|
-
tags?: c4.NonEmptyArray<c4.Tag>
|
|
95
|
-
links?: c4.NonEmptyArray<ParsedLink>
|
|
96
|
-
metadata?: { [key: string]: string }
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
export interface ParsedAstRelation {
|
|
100
|
-
id: c4.RelationId
|
|
101
|
-
astPath: string
|
|
102
|
-
source: c4.Fqn
|
|
103
|
-
target: c4.Fqn
|
|
104
|
-
kind?: c4.RelationshipKind
|
|
105
|
-
tags?: c4.NonEmptyArray<c4.Tag>
|
|
106
|
-
title: string
|
|
107
|
-
description?: string
|
|
108
|
-
technology?: string
|
|
109
|
-
color?: c4.Color
|
|
110
|
-
line?: c4.RelationshipLineType
|
|
111
|
-
head?: c4.RelationshipArrowType
|
|
112
|
-
tail?: c4.RelationshipArrowType
|
|
113
|
-
links?: c4.NonEmptyArray<ParsedLink>
|
|
114
|
-
navigateTo?: c4.ViewId
|
|
115
|
-
metadata?: { [key: string]: string }
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
// Alias for easier refactoring
|
|
119
|
-
export type ParsedAstDeployment = c4.DeploymentElement
|
|
120
|
-
export namespace ParsedAstDeployment {
|
|
121
|
-
export type Node = c4.DeploymentNode
|
|
122
|
-
export type Instance = c4.DeployedInstance
|
|
123
|
-
}
|
|
124
|
-
export type ParsedAstDeploymentRelation = c4.DeploymentRelation & {
|
|
125
|
-
astPath: string
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
// Alias for refactoring
|
|
129
|
-
export type ParsedAstGlobals = Writable<c4.ModelGlobals>
|
|
130
|
-
|
|
131
|
-
export interface ParsedAstElementView {
|
|
132
|
-
__: 'element'
|
|
133
|
-
id: c4.ViewId
|
|
134
|
-
viewOf?: c4.Fqn
|
|
135
|
-
extends?: c4.ViewId
|
|
136
|
-
astPath: string
|
|
137
|
-
title: string | null
|
|
138
|
-
description: string | null
|
|
139
|
-
tags: c4.NonEmptyArray<c4.Tag> | null
|
|
140
|
-
links: c4.NonEmptyArray<ParsedLink> | null
|
|
141
|
-
rules: c4.ViewRule[]
|
|
142
|
-
manualLayout?: c4.ViewManualLayout
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
export interface ParsedAstDynamicView {
|
|
146
|
-
__: 'dynamic'
|
|
147
|
-
id: c4.ViewId
|
|
148
|
-
astPath: string
|
|
149
|
-
title: string | null
|
|
150
|
-
description: string | null
|
|
151
|
-
tags: c4.NonEmptyArray<c4.Tag> | null
|
|
152
|
-
links: c4.NonEmptyArray<ParsedLink> | null
|
|
153
|
-
steps: c4.DynamicViewStepOrParallel[]
|
|
154
|
-
rules: Array<c4.DynamicViewRule>
|
|
155
|
-
manualLayout?: c4.ViewManualLayout
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
export interface ParsedAstDeploymentView {
|
|
159
|
-
__: 'deployment'
|
|
160
|
-
id: c4.ViewId
|
|
161
|
-
astPath: string
|
|
162
|
-
title: string | null
|
|
163
|
-
description: string | null
|
|
164
|
-
tags: c4.NonEmptyArray<c4.Tag> | null
|
|
165
|
-
links: c4.NonEmptyArray<ParsedLink> | null
|
|
166
|
-
rules: Array<c4.DeploymentViewRule>
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
export type ParsedAstView = ParsedAstElementView | ParsedAstDynamicView | ParsedAstDeploymentView
|
|
170
|
-
export const ViewOps = {
|
|
171
|
-
writeId<T extends ast.LikeC4View>(node: T, id: c4.ViewId): T {
|
|
172
|
-
node[idattr] = id
|
|
173
|
-
return node
|
|
174
|
-
},
|
|
175
|
-
readId(node: ast.LikeC4View): c4.ViewId | undefined {
|
|
176
|
-
return node[idattr]
|
|
177
|
-
},
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
export interface ParsedLink {
|
|
181
|
-
title?: string
|
|
182
|
-
url: string
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
export const ElementOps = {
|
|
186
|
-
writeId(node: ast.Element | ast.DeploymentElement, id: c4.Fqn | null) {
|
|
187
|
-
if (isNullish(id)) {
|
|
188
|
-
node[idattr] = undefined
|
|
189
|
-
} else {
|
|
190
|
-
node[idattr] = id
|
|
191
|
-
}
|
|
192
|
-
return node
|
|
193
|
-
},
|
|
194
|
-
readId(node: ast.Element | ast.DeploymentElement) {
|
|
195
|
-
return node[idattr]
|
|
196
|
-
},
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
export interface DocFqnIndexAstNodeDescription extends AstNodeDescription {
|
|
200
|
-
fqn: c4.Fqn
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
export interface DeploymentAstNodeDescription extends AstNodeDescription {
|
|
204
|
-
// Fullname of the artifact or node
|
|
205
|
-
fqn: string
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
// export type LikeC4AstNode = ast.LikeC4AstType[keyof ast.LikeC4AstType]
|
|
209
|
-
export type LikeC4AstNode = ValueOf<ConditionalPick<ast.LikeC4AstType, AstNode>>
|
|
210
|
-
type LikeC4DocumentDiagnostic = Diagnostic & DiagnosticInfo<LikeC4AstNode>
|
|
211
|
-
|
|
212
|
-
export interface LikeC4DocumentProps {
|
|
213
|
-
diagnostics?: Array<LikeC4DocumentDiagnostic>
|
|
214
|
-
c4Specification?: ParsedAstSpecification
|
|
215
|
-
c4Elements?: ParsedAstElement[]
|
|
216
|
-
c4ExtendElements?: ParsedAstExtendElement[]
|
|
217
|
-
c4Relations?: ParsedAstRelation[]
|
|
218
|
-
c4Globals?: ParsedAstGlobals
|
|
219
|
-
c4Views?: ParsedAstView[]
|
|
220
|
-
c4Deployments?: ParsedAstDeployment[]
|
|
221
|
-
c4DeploymentRelations?: ParsedAstDeploymentRelation[]
|
|
222
|
-
// Fqn -> Element
|
|
223
|
-
c4fqnIndex?: MultiMap<c4.Fqn, DocFqnIndexAstNodeDescription>
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
type LikeC4GrammarDocument = Omit<LangiumDocument<LikeC4Grammar>, 'diagnostics'>
|
|
227
|
-
|
|
228
|
-
export interface LikeC4LangiumDocument extends LikeC4GrammarDocument, LikeC4DocumentProps {}
|
|
229
|
-
export interface FqnIndexedDocument extends SetRequired<LikeC4LangiumDocument, 'c4fqnIndex'> {}
|
|
230
|
-
|
|
231
|
-
export interface ParsedLikeC4LangiumDocument extends LikeC4GrammarDocument, Required<LikeC4DocumentProps> {}
|
|
232
|
-
|
|
233
|
-
export function isLikeC4LangiumDocument(doc: LangiumDocument): doc is LikeC4LangiumDocument {
|
|
234
|
-
return doc.textDocument.languageId === LikeC4LanguageMetaData.languageId
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
export function isFqnIndexedDocument(doc: LangiumDocument): doc is FqnIndexedDocument {
|
|
238
|
-
return isLikeC4LangiumDocument(doc) && doc.state >= DocumentState.IndexedContent && !!doc.c4fqnIndex
|
|
239
|
-
}
|
|
240
|
-
|
|
241
|
-
export function isParsedLikeC4LangiumDocument(
|
|
242
|
-
doc: LangiumDocument,
|
|
243
|
-
): doc is ParsedLikeC4LangiumDocument {
|
|
244
|
-
return (
|
|
245
|
-
isLikeC4LangiumDocument(doc)
|
|
246
|
-
&& doc.state == DocumentState.Validated
|
|
247
|
-
&& !!doc.c4Specification
|
|
248
|
-
&& !!doc.c4Elements
|
|
249
|
-
&& !!doc.c4ExtendElements
|
|
250
|
-
&& !!doc.c4Relations
|
|
251
|
-
&& !!doc.c4Views
|
|
252
|
-
&& !!doc.c4fqnIndex
|
|
253
|
-
&& !!doc.c4Deployments
|
|
254
|
-
&& !!doc.c4DeploymentRelations
|
|
255
|
-
)
|
|
256
|
-
}
|
|
257
|
-
|
|
258
|
-
export function* streamModel(doc: LikeC4LangiumDocument) {
|
|
259
|
-
const traverseStack = LinkedList.from(doc.parseResult.value.models.flatMap(m => m.elements))
|
|
260
|
-
const relations = [] as ast.Relation[]
|
|
261
|
-
let el
|
|
262
|
-
while ((el = traverseStack.shift())) {
|
|
263
|
-
if (ast.isRelation(el)) {
|
|
264
|
-
relations.push(el)
|
|
265
|
-
continue
|
|
266
|
-
}
|
|
267
|
-
if (el.body && el.body.elements && el.body.elements.length > 0) {
|
|
268
|
-
for (const child of el.body.elements) {
|
|
269
|
-
traverseStack.push(child)
|
|
270
|
-
}
|
|
271
|
-
}
|
|
272
|
-
yield el
|
|
273
|
-
}
|
|
274
|
-
yield* relations
|
|
275
|
-
return
|
|
276
|
-
}
|
|
277
|
-
|
|
278
|
-
export function* streamDeploymentModel(doc: LikeC4LangiumDocument) {
|
|
279
|
-
const traverseStack = LinkedList.from<ast.DeploymentRelation | ast.DeploymentElement>(
|
|
280
|
-
doc.parseResult.value.deployments.flatMap(m => m.elements),
|
|
281
|
-
)
|
|
282
|
-
const relations = [] as ast.DeploymentRelation[]
|
|
283
|
-
let el
|
|
284
|
-
while ((el = traverseStack.shift())) {
|
|
285
|
-
if (ast.isDeploymentRelation(el)) {
|
|
286
|
-
relations.push(el)
|
|
287
|
-
continue
|
|
288
|
-
}
|
|
289
|
-
if (ast.isDeploymentNode(el) && el.body && el.body.elements.length > 0) {
|
|
290
|
-
for (const child of el.body.elements) {
|
|
291
|
-
traverseStack.push(child)
|
|
292
|
-
}
|
|
293
|
-
}
|
|
294
|
-
yield el
|
|
295
|
-
}
|
|
296
|
-
yield* relations
|
|
297
|
-
return
|
|
298
|
-
}
|
|
299
|
-
|
|
300
|
-
export function resolveRelationPoints(node: ast.Relation): {
|
|
301
|
-
source: ast.Element
|
|
302
|
-
target: ast.Element
|
|
303
|
-
} {
|
|
304
|
-
const target = elementRef(node.target)
|
|
305
|
-
if (!target) {
|
|
306
|
-
throw new Error('RelationRefError: Invalid reference to target')
|
|
307
|
-
}
|
|
308
|
-
if (isDefined(node.source)) {
|
|
309
|
-
const source = elementRef(node.source)
|
|
310
|
-
if (!source) {
|
|
311
|
-
throw new Error('RelationRefError: Invalid reference to source')
|
|
312
|
-
}
|
|
313
|
-
return {
|
|
314
|
-
source,
|
|
315
|
-
target,
|
|
316
|
-
}
|
|
317
|
-
}
|
|
318
|
-
if (!ast.isElementBody(node.$container)) {
|
|
319
|
-
throw new Error('RelationRefError: Invalid container for sourceless relation')
|
|
320
|
-
}
|
|
321
|
-
return {
|
|
322
|
-
source: node.$container.$container,
|
|
323
|
-
target,
|
|
324
|
-
}
|
|
325
|
-
}
|
|
326
|
-
|
|
327
|
-
export function parseAstOpacityProperty({ value }: ast.OpacityProperty): number {
|
|
328
|
-
const opacity = parseFloat(value)
|
|
329
|
-
return isNaN(opacity) ? 100 : clamp(opacity, { min: 0, max: 100 })
|
|
330
|
-
}
|
|
331
|
-
|
|
332
|
-
export function parseAstSizeValue({ value }: { value: ast.SizeValue }): 'xs' | 'sm' | 'md' | 'lg' | 'xl' {
|
|
333
|
-
switch (value) {
|
|
334
|
-
case 'xs':
|
|
335
|
-
case 'sm':
|
|
336
|
-
case 'md':
|
|
337
|
-
case 'lg':
|
|
338
|
-
case 'xl':
|
|
339
|
-
return value
|
|
340
|
-
case 'xsmall':
|
|
341
|
-
return 'xs'
|
|
342
|
-
case 'small':
|
|
343
|
-
return 'sm'
|
|
344
|
-
case 'medium':
|
|
345
|
-
return 'md'
|
|
346
|
-
case 'large':
|
|
347
|
-
return 'lg'
|
|
348
|
-
case 'xlarge':
|
|
349
|
-
return 'xl'
|
|
350
|
-
default:
|
|
351
|
-
nonexhaustive(value)
|
|
352
|
-
}
|
|
353
|
-
}
|
|
354
|
-
|
|
355
|
-
export function toElementStyle(props: Array<ast.StyleProperty> | undefined, isValid: IsValidFn) {
|
|
356
|
-
const result = {} as ParsedElementStyle
|
|
357
|
-
if (!props || props.length === 0) {
|
|
358
|
-
return result
|
|
359
|
-
}
|
|
360
|
-
for (const prop of props) {
|
|
361
|
-
if (!isValid(prop)) {
|
|
362
|
-
continue
|
|
363
|
-
}
|
|
364
|
-
switch (true) {
|
|
365
|
-
case ast.isBorderProperty(prop): {
|
|
366
|
-
if (isTruthy(prop.value)) {
|
|
367
|
-
result.border = prop.value
|
|
368
|
-
}
|
|
369
|
-
break
|
|
370
|
-
}
|
|
371
|
-
case ast.isColorProperty(prop): {
|
|
372
|
-
const color = toColor(prop)
|
|
373
|
-
if (isTruthy(color)) {
|
|
374
|
-
result.color = color
|
|
375
|
-
}
|
|
376
|
-
break
|
|
377
|
-
}
|
|
378
|
-
case ast.isShapeProperty(prop): {
|
|
379
|
-
if (isTruthy(prop.value)) {
|
|
380
|
-
result.shape = prop.value
|
|
381
|
-
}
|
|
382
|
-
break
|
|
383
|
-
}
|
|
384
|
-
case ast.isIconProperty(prop): {
|
|
385
|
-
const icon = prop.libicon?.ref?.name ?? prop.value
|
|
386
|
-
if (isTruthy(icon)) {
|
|
387
|
-
result.icon = icon as c4.IconUrl
|
|
388
|
-
}
|
|
389
|
-
break
|
|
390
|
-
}
|
|
391
|
-
case ast.isOpacityProperty(prop): {
|
|
392
|
-
result.opacity = parseAstOpacityProperty(prop)
|
|
393
|
-
break
|
|
394
|
-
}
|
|
395
|
-
case ast.isMultipleProperty(prop): {
|
|
396
|
-
result.multiple = isBoolean(prop.value) ? prop.value : false
|
|
397
|
-
break
|
|
398
|
-
}
|
|
399
|
-
case ast.isShapeSizeProperty(prop): {
|
|
400
|
-
if (isTruthy(prop.value)) {
|
|
401
|
-
result.size = parseAstSizeValue(prop)
|
|
402
|
-
}
|
|
403
|
-
break
|
|
404
|
-
}
|
|
405
|
-
case ast.isPaddingSizeProperty(prop): {
|
|
406
|
-
if (isTruthy(prop.value)) {
|
|
407
|
-
result.padding = parseAstSizeValue(prop)
|
|
408
|
-
}
|
|
409
|
-
break
|
|
410
|
-
}
|
|
411
|
-
case ast.isTextSizeProperty(prop): {
|
|
412
|
-
if (isTruthy(prop.value)) {
|
|
413
|
-
result.textSize = parseAstSizeValue(prop)
|
|
414
|
-
}
|
|
415
|
-
break
|
|
416
|
-
}
|
|
417
|
-
default:
|
|
418
|
-
nonexhaustive(prop)
|
|
419
|
-
}
|
|
420
|
-
}
|
|
421
|
-
return result
|
|
422
|
-
}
|
|
423
|
-
|
|
424
|
-
export function toRelationshipStyle(props: ast.RelationshipStyleProperty[] | undefined, isValid: IsValidFn) {
|
|
425
|
-
const result = {} as {
|
|
426
|
-
color?: c4.Color
|
|
427
|
-
line?: c4.RelationshipLineType
|
|
428
|
-
head?: c4.RelationshipArrowType
|
|
429
|
-
tail?: c4.RelationshipArrowType
|
|
430
|
-
}
|
|
431
|
-
if (!props || props.length === 0) {
|
|
432
|
-
return result
|
|
433
|
-
}
|
|
434
|
-
for (const prop of props) {
|
|
435
|
-
if (!isValid(prop)) {
|
|
436
|
-
continue
|
|
437
|
-
}
|
|
438
|
-
switch (true) {
|
|
439
|
-
case ast.isColorProperty(prop): {
|
|
440
|
-
const color = toColor(prop)
|
|
441
|
-
if (isTruthy(color)) {
|
|
442
|
-
result.color = color
|
|
443
|
-
}
|
|
444
|
-
break
|
|
445
|
-
}
|
|
446
|
-
case ast.isLineProperty(prop): {
|
|
447
|
-
result.line = prop.value
|
|
448
|
-
break
|
|
449
|
-
}
|
|
450
|
-
case ast.isArrowProperty(prop): {
|
|
451
|
-
switch (prop.key) {
|
|
452
|
-
case 'head': {
|
|
453
|
-
result.head = prop.value
|
|
454
|
-
break
|
|
455
|
-
}
|
|
456
|
-
case 'tail': {
|
|
457
|
-
result.tail = prop.value
|
|
458
|
-
break
|
|
459
|
-
}
|
|
460
|
-
default: {
|
|
461
|
-
nonexhaustive(prop)
|
|
462
|
-
}
|
|
463
|
-
}
|
|
464
|
-
break
|
|
465
|
-
}
|
|
466
|
-
default: {
|
|
467
|
-
nonexhaustive(prop)
|
|
468
|
-
}
|
|
469
|
-
}
|
|
470
|
-
}
|
|
471
|
-
return result
|
|
472
|
-
}
|
|
473
|
-
|
|
474
|
-
export function toRelationshipStyleExcludeDefaults(
|
|
475
|
-
props: ast.SpecificationRelationshipKind['props'] | undefined,
|
|
476
|
-
isValid: IsValidFn,
|
|
477
|
-
) {
|
|
478
|
-
const { color, line, head, tail } = toRelationshipStyle(props?.filter(ast.isRelationshipStyleProperty), isValid)
|
|
479
|
-
return {
|
|
480
|
-
...(color && color !== DefaultRelationshipColor ? { color } : {}),
|
|
481
|
-
...(line && line !== DefaultLineStyle ? { line } : {}),
|
|
482
|
-
...(head && head !== DefaultArrowType ? { head } : {}),
|
|
483
|
-
...(tail ? { tail } : {}),
|
|
484
|
-
}
|
|
485
|
-
}
|
|
486
|
-
|
|
487
|
-
export function toColor(astNode: ast.ColorProperty): c4.Color | undefined {
|
|
488
|
-
return astNode?.themeColor ?? (astNode?.customColor?.$refText as (c4.HexColorLiteral | undefined))
|
|
489
|
-
}
|
|
490
|
-
|
|
491
|
-
export function toAutoLayout(
|
|
492
|
-
rule: ast.ViewRuleAutoLayout,
|
|
493
|
-
): c4.ViewRuleAutoLayout {
|
|
494
|
-
const rankSep = rule.rankSep
|
|
495
|
-
const nodeSep = rule.nodeSep
|
|
496
|
-
|
|
497
|
-
let direction: c4.ViewRuleAutoLayout['direction']
|
|
498
|
-
switch (rule.direction) {
|
|
499
|
-
case 'TopBottom': {
|
|
500
|
-
direction = 'TB'
|
|
501
|
-
break
|
|
502
|
-
}
|
|
503
|
-
case 'BottomTop': {
|
|
504
|
-
direction = 'BT'
|
|
505
|
-
break
|
|
506
|
-
}
|
|
507
|
-
case 'LeftRight': {
|
|
508
|
-
direction = 'LR'
|
|
509
|
-
break
|
|
510
|
-
}
|
|
511
|
-
case 'RightLeft': {
|
|
512
|
-
direction = 'RL'
|
|
513
|
-
break
|
|
514
|
-
}
|
|
515
|
-
default:
|
|
516
|
-
nonexhaustive(rule.direction)
|
|
517
|
-
}
|
|
518
|
-
|
|
519
|
-
return {
|
|
520
|
-
direction,
|
|
521
|
-
...(nodeSep && { nodeSep }),
|
|
522
|
-
...(rankSep && { rankSep }),
|
|
523
|
-
}
|
|
524
|
-
}
|
|
525
|
-
|
|
526
|
-
export function toAstViewLayoutDirection(c4: c4.ViewRuleAutoLayout['direction']): ast.ViewLayoutDirection {
|
|
527
|
-
switch (c4) {
|
|
528
|
-
case 'TB': {
|
|
529
|
-
return 'TopBottom'
|
|
530
|
-
}
|
|
531
|
-
case 'BT': {
|
|
532
|
-
return 'BottomTop'
|
|
533
|
-
}
|
|
534
|
-
case 'LR': {
|
|
535
|
-
return 'LeftRight'
|
|
536
|
-
}
|
|
537
|
-
case 'RL': {
|
|
538
|
-
return 'RightLeft'
|
|
539
|
-
}
|
|
540
|
-
default:
|
|
541
|
-
nonexhaustive(c4)
|
|
542
|
-
}
|
|
543
|
-
}
|
|
544
|
-
|
|
545
|
-
export function elementExpressionFromPredicate(predicate: ast.ElementPredicate): ast.ElementExpression {
|
|
546
|
-
if (ast.isElementExpression(predicate)) {
|
|
547
|
-
return predicate
|
|
548
|
-
}
|
|
549
|
-
if (ast.isElementPredicateWhere(predicate)) {
|
|
550
|
-
return predicate.subject
|
|
551
|
-
}
|
|
552
|
-
if (ast.isElementPredicateWith(predicate)) {
|
|
553
|
-
return elementExpressionFromPredicate(predicate.subject)
|
|
554
|
-
}
|
|
555
|
-
nonexhaustive(predicate)
|
|
556
|
-
}
|