@likec4/language-server 1.18.0 → 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.
- package/dist/LikeC4FileSystem.d.ts +13 -0
- package/dist/LikeC4FileSystem.js +27 -0
- package/dist/Rpc.d.ts +9 -0
- package/dist/Rpc.js +126 -0
- package/dist/ast.d.ts +200 -0
- package/dist/ast.js +276 -0
- package/dist/browser.d.ts +6 -20
- package/dist/browser.js +13 -0
- package/dist/formatting/LikeC4Formatter.d.ts +27 -0
- package/dist/formatting/LikeC4Formatter.js +261 -0
- package/dist/formatting/utils.d.ts +6 -0
- package/dist/formatting/utils.js +15 -0
- package/dist/generated/ast.d.ts +1242 -0
- package/dist/generated/ast.js +1945 -0
- package/dist/generated/grammar.d.ts +6 -0
- package/dist/generated/grammar.js +3 -0
- package/dist/generated/module.d.ts +9 -0
- package/dist/generated/module.js +23 -0
- package/dist/generated-lib/icons.d.ts +1 -0
- package/dist/{likec4lib.mjs → generated-lib/icons.js} +1 -6
- package/dist/index.d.ts +8 -31
- package/dist/index.js +13 -0
- package/dist/like-c4.langium +845 -0
- package/dist/likec4lib.d.ts +4 -6
- package/dist/likec4lib.js +4 -0
- package/dist/logger.d.ts +7 -0
- package/dist/logger.js +73 -0
- package/dist/lsp/CodeLensProvider.d.ts +9 -0
- package/dist/lsp/CodeLensProvider.js +40 -0
- package/dist/lsp/CompletionProvider.d.ts +6 -0
- package/dist/lsp/CompletionProvider.js +135 -0
- package/dist/lsp/DocumentHighlightProvider.d.ts +9 -0
- package/dist/lsp/DocumentHighlightProvider.js +10 -0
- package/dist/lsp/DocumentLinkProvider.d.ts +11 -0
- package/dist/lsp/DocumentLinkProvider.js +49 -0
- package/dist/lsp/DocumentSymbolProvider.d.ts +23 -0
- package/dist/lsp/DocumentSymbolProvider.js +202 -0
- package/dist/lsp/HoverProvider.d.ts +10 -0
- package/dist/lsp/HoverProvider.js +69 -0
- package/dist/lsp/RenameProvider.d.ts +5 -0
- package/dist/lsp/RenameProvider.js +6 -0
- package/dist/lsp/SemanticTokenProvider.d.ts +7 -0
- package/dist/lsp/SemanticTokenProvider.js +297 -0
- package/dist/lsp/index.d.ts +7 -0
- package/dist/lsp/index.js +7 -0
- package/dist/model/deployments-index.d.ts +60 -0
- package/dist/model/deployments-index.js +181 -0
- package/dist/model/fqn-computation.d.ts +3 -0
- package/dist/model/fqn-computation.js +72 -0
- package/dist/model/fqn-index.d.ts +25 -0
- package/dist/model/fqn-index.js +96 -0
- package/dist/model/index.d.ts +6 -0
- package/dist/model/index.js +6 -0
- package/dist/model/model-builder.d.ts +32 -0
- package/dist/model/model-builder.js +598 -0
- package/dist/model/model-locator.d.ts +23 -0
- package/dist/model/model-locator.js +126 -0
- package/dist/model/model-parser-where.d.ts +3 -0
- package/dist/model/model-parser-where.js +70 -0
- package/dist/model/model-parser.d.ts +292 -0
- package/dist/model/model-parser.js +72 -0
- package/dist/model/parser/Base.d.ts +28 -0
- package/dist/model/parser/Base.js +87 -0
- package/dist/model/parser/DeploymentModelParser.d.ts +33 -0
- package/dist/model/parser/DeploymentModelParser.js +162 -0
- package/dist/model/parser/DeploymentViewParser.d.ts +38 -0
- package/dist/model/parser/DeploymentViewParser.js +98 -0
- package/dist/model/parser/FqnRefParser.d.ts +29 -0
- package/dist/model/parser/FqnRefParser.js +108 -0
- package/dist/model/parser/GlobalsParser.d.ts +66 -0
- package/dist/model/parser/GlobalsParser.js +80 -0
- package/dist/model/parser/ModelParser.d.ts +27 -0
- package/dist/model/parser/ModelParser.js +122 -0
- package/dist/model/parser/PredicatesParser.d.ts +34 -0
- package/dist/model/parser/PredicatesParser.js +272 -0
- package/dist/model/parser/SpecificationParser.d.ts +27 -0
- package/dist/model/parser/SpecificationParser.js +120 -0
- package/dist/model/parser/ViewsParser.d.ts +64 -0
- package/dist/model/parser/ViewsParser.js +377 -0
- package/dist/model-change/ModelChanges.d.ts +15 -0
- package/dist/model-change/ModelChanges.js +89 -0
- package/dist/model-change/changeElementStyle.d.ts +16 -0
- package/dist/model-change/changeElementStyle.js +136 -0
- package/dist/model-change/changeViewLayout.d.ts +12 -0
- package/dist/model-change/changeViewLayout.js +32 -0
- package/dist/model-change/saveManualLayout.d.ts +11 -0
- package/dist/model-change/saveManualLayout.js +27 -0
- package/dist/module.d.ts +62 -0
- package/dist/module.js +123 -0
- package/dist/protocol.d.ts +20 -23
- package/dist/protocol.js +14 -0
- package/dist/references/index.d.ts +3 -0
- package/dist/references/index.js +3 -0
- package/dist/references/name-provider.d.ts +9 -0
- package/dist/references/name-provider.js +33 -0
- package/dist/references/scope-computation.d.ts +20 -0
- package/dist/references/scope-computation.js +281 -0
- package/dist/references/scope-provider.d.ts +16 -0
- package/dist/references/scope-provider.js +165 -0
- package/dist/shared/NodeKindProvider.d.ts +15 -0
- package/dist/shared/NodeKindProvider.js +108 -0
- package/dist/shared/WorkspaceManager.d.ts +18 -0
- package/dist/shared/WorkspaceManager.js +36 -0
- package/dist/shared/WorkspaceSymbolProvider.d.ts +3 -0
- package/dist/shared/WorkspaceSymbolProvider.js +3 -0
- package/dist/shared/index.d.ts +3 -0
- package/dist/shared/index.js +3 -0
- package/dist/test/index.d.ts +1 -0
- package/dist/test/index.js +1 -0
- package/dist/test/setup.d.ts +1 -0
- package/dist/test/setup.js +7 -0
- package/dist/test/testServices.d.ts +22 -0
- package/dist/test/testServices.js +119 -0
- package/dist/utils/elementRef.d.ts +11 -0
- package/dist/utils/elementRef.js +15 -0
- package/dist/utils/fqnRef.d.ts +8 -0
- package/dist/utils/fqnRef.js +46 -0
- package/dist/utils/index.d.ts +1 -0
- package/dist/utils/index.js +1 -0
- package/dist/utils/printDocs.d.ts +2 -0
- package/dist/utils/printDocs.js +1 -0
- package/dist/utils/stringHash.d.ts +1 -0
- package/dist/utils/stringHash.js +5 -0
- package/dist/validation/_shared.d.ts +3 -0
- package/dist/validation/_shared.js +22 -0
- package/dist/validation/deployment-checks.d.ts +6 -0
- package/dist/validation/deployment-checks.js +114 -0
- package/dist/validation/dynamic-view-rule.d.ts +4 -0
- package/dist/validation/dynamic-view-rule.js +16 -0
- package/dist/validation/dynamic-view-step.d.ts +4 -0
- package/dist/validation/dynamic-view-step.js +33 -0
- package/dist/validation/element.d.ts +4 -0
- package/dist/validation/element.js +49 -0
- package/dist/validation/index.d.ts +15 -0
- package/dist/validation/index.js +152 -0
- package/dist/validation/property-checks.d.ts +6 -0
- package/dist/validation/property-checks.js +38 -0
- package/dist/validation/relation.d.ts +5 -0
- package/dist/validation/relation.js +56 -0
- package/dist/validation/specification.d.ts +11 -0
- package/dist/validation/specification.js +136 -0
- package/dist/validation/view-predicates/element-with.d.ts +4 -0
- package/dist/validation/view-predicates/element-with.js +30 -0
- package/dist/validation/view-predicates/expanded-element.d.ts +4 -0
- package/dist/validation/view-predicates/expanded-element.js +11 -0
- package/dist/validation/view-predicates/expression-v2.d.ts +5 -0
- package/dist/validation/view-predicates/expression-v2.js +83 -0
- package/dist/validation/view-predicates/incoming.d.ts +4 -0
- package/dist/validation/view-predicates/incoming.js +15 -0
- package/dist/validation/view-predicates/index.d.ts +6 -0
- package/dist/validation/view-predicates/index.js +6 -0
- package/dist/validation/view-predicates/outgoing.d.ts +4 -0
- package/dist/validation/view-predicates/outgoing.js +15 -0
- package/dist/validation/view-predicates/relation-with.d.ts +4 -0
- package/dist/validation/view-predicates/relation-with.js +12 -0
- package/dist/validation/view.d.ts +4 -0
- package/dist/validation/view.js +23 -0
- package/dist/view-utils/assignNavigateTo.d.ts +2 -0
- package/dist/view-utils/assignNavigateTo.js +25 -0
- package/dist/view-utils/index.d.ts +2 -0
- package/dist/view-utils/index.js +2 -0
- package/dist/view-utils/manual-layout.d.ts +7 -0
- package/dist/view-utils/manual-layout.js +99 -0
- package/dist/view-utils/resolve-relative-paths.d.ts +2 -0
- package/dist/view-utils/resolve-relative-paths.js +78 -0
- package/package.json +36 -53
- package/src/LikeC4FileSystem.ts +22 -21
- package/src/ast.ts +44 -133
- package/src/browser.ts +10 -11
- package/src/generated/ast.ts +177 -177
- package/src/generated/grammar.ts +1 -1
- package/src/index.ts +10 -8
- package/src/like-c4.langium +37 -34
- package/src/logger.ts +34 -55
- package/src/lsp/CompletionProvider.ts +4 -4
- package/src/lsp/HoverProvider.ts +5 -3
- package/src/lsp/SemanticTokenProvider.ts +2 -2
- package/src/model/deployments-index.ts +18 -14
- package/src/model/model-builder.ts +10 -8
- package/src/model/model-parser.ts +62 -1574
- package/src/model/parser/Base.ts +107 -0
- package/src/model/parser/DeploymentModelParser.ts +192 -0
- package/src/model/parser/DeploymentViewParser.ts +116 -0
- package/src/model/parser/FqnRefParser.ts +118 -0
- package/src/model/parser/GlobalsParser.ts +96 -0
- package/src/model/parser/ModelParser.ts +141 -0
- package/src/model/parser/PredicatesParser.ts +291 -0
- package/src/model/parser/SpecificationParser.ts +133 -0
- package/src/model/parser/ViewsParser.ts +428 -0
- package/src/module.ts +17 -18
- package/src/references/scope-provider.ts +13 -7
- package/src/utils/{deploymentRef.ts → fqnRef.ts} +27 -2
- package/src/validation/_shared.ts +0 -1
- package/src/validation/deployment-checks.ts +49 -62
- package/src/validation/index.ts +100 -9
- package/src/validation/view-predicates/expression-v2.ts +101 -0
- package/src/validation/view-predicates/index.ts +1 -1
- package/src/view-utils/assignNavigateTo.ts +1 -1
- package/src/view-utils/manual-layout.ts +25 -0
- package/dist/browser.cjs +0 -25
- package/dist/browser.d.cts +0 -23
- package/dist/browser.d.mts +0 -23
- package/dist/browser.mjs +0 -20
- package/dist/index.cjs +0 -53
- package/dist/index.d.cts +0 -34
- package/dist/index.d.mts +0 -34
- package/dist/index.mjs +0 -46
- package/dist/likec4lib.cjs +0 -1546
- package/dist/likec4lib.d.cts +0 -6
- package/dist/likec4lib.d.mts +0 -6
- package/dist/protocol.cjs +0 -25
- package/dist/protocol.d.cts +0 -48
- package/dist/protocol.d.mts +0 -48
- package/dist/protocol.mjs +0 -17
- package/dist/shared/language-server.CO_nmHiL.cjs +0 -7689
- package/dist/shared/language-server.Da6ey08o.d.cts +0 -1619
- package/dist/shared/language-server.De7S3e5Z.d.ts +0 -1619
- package/dist/shared/language-server.Dj4iDjtB.d.mts +0 -1619
- package/dist/shared/language-server.oO_9JoAG.mjs +0 -7666
- package/src/validation/view-predicates/deployments.ts +0 -56
|
@@ -0,0 +1,428 @@
|
|
|
1
|
+
import type * as c4 from '@likec4/core'
|
|
2
|
+
import { invariant, isNonEmptyArray, nonexhaustive } from '@likec4/core'
|
|
3
|
+
import { isArray, isDefined, isNonNullish, isTruthy } from 'remeda'
|
|
4
|
+
import type { Writable } from 'type-fest'
|
|
5
|
+
import {
|
|
6
|
+
ast,
|
|
7
|
+
type ParsedAstDynamicView,
|
|
8
|
+
type ParsedAstElementView,
|
|
9
|
+
toAutoLayout,
|
|
10
|
+
toColor,
|
|
11
|
+
toElementStyle,
|
|
12
|
+
ViewOps
|
|
13
|
+
} from '../../ast'
|
|
14
|
+
import type { NotationProperty } from '../../generated/ast'
|
|
15
|
+
import { logger, logWarnError } from '../../logger'
|
|
16
|
+
import { stringHash } from '../../utils'
|
|
17
|
+
import { elementRef } from '../../utils/elementRef'
|
|
18
|
+
import { parseViewManualLayout } from '../../view-utils/manual-layout'
|
|
19
|
+
import { removeIndent, toSingleLine } from './Base'
|
|
20
|
+
import type { WithDeploymentView } from './DeploymentViewParser'
|
|
21
|
+
import type { WithPredicates } from './PredicatesParser'
|
|
22
|
+
|
|
23
|
+
export type WithViewsParser = ReturnType<typeof ViewsParser>
|
|
24
|
+
|
|
25
|
+
export function ViewsParser<TBase extends WithPredicates & WithDeploymentView>(B: TBase) {
|
|
26
|
+
return class ViewsParser extends B {
|
|
27
|
+
parseViews() {
|
|
28
|
+
const isValid = this.isValid
|
|
29
|
+
for (const viewBlock of this.doc.parseResult.value.views) {
|
|
30
|
+
const localStyles = viewBlock.styles.flatMap(s => {
|
|
31
|
+
try {
|
|
32
|
+
return isValid(s) ? this.parseViewRuleStyleOrGlobalRef(s) : []
|
|
33
|
+
} catch (e) {
|
|
34
|
+
logWarnError(e)
|
|
35
|
+
return []
|
|
36
|
+
}
|
|
37
|
+
})
|
|
38
|
+
|
|
39
|
+
for (const view of viewBlock.views) {
|
|
40
|
+
try {
|
|
41
|
+
if (!isValid(view)) {
|
|
42
|
+
continue
|
|
43
|
+
}
|
|
44
|
+
switch (true) {
|
|
45
|
+
case ast.isElementView(view):
|
|
46
|
+
this.doc.c4Views.push(this.parseElementView(view, localStyles))
|
|
47
|
+
break
|
|
48
|
+
case ast.isDynamicView(view):
|
|
49
|
+
this.doc.c4Views.push(this.parseDynamicElementView(view, localStyles))
|
|
50
|
+
break
|
|
51
|
+
case ast.isDeploymentView(view):
|
|
52
|
+
this.doc.c4Views.push(this.parseDeploymentView(view))
|
|
53
|
+
break
|
|
54
|
+
default:
|
|
55
|
+
nonexhaustive(view)
|
|
56
|
+
}
|
|
57
|
+
} catch (e) {
|
|
58
|
+
logWarnError(e)
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
parseElementView(astNode: ast.ElementView, additionalStyles: c4.ViewRuleStyleOrGlobalRef[]): ParsedAstElementView {
|
|
65
|
+
const body = astNode.body
|
|
66
|
+
invariant(body, 'ElementView body is not defined')
|
|
67
|
+
const astPath = this.getAstNodePath(astNode)
|
|
68
|
+
|
|
69
|
+
let viewOf = null as c4.Fqn | null
|
|
70
|
+
if ('viewOf' in astNode) {
|
|
71
|
+
const viewOfEl = elementRef(astNode.viewOf)
|
|
72
|
+
const _viewOf = viewOfEl && this.resolveFqn(viewOfEl)
|
|
73
|
+
if (!_viewOf) {
|
|
74
|
+
logger.warn('viewOf is not resolved: ' + astNode.$cstNode?.text)
|
|
75
|
+
} else {
|
|
76
|
+
viewOf = _viewOf
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
let id = astNode.name
|
|
81
|
+
if (!id) {
|
|
82
|
+
id = 'view_' + stringHash(
|
|
83
|
+
this.doc.uri.toString(),
|
|
84
|
+
astPath,
|
|
85
|
+
viewOf ?? ''
|
|
86
|
+
) as c4.ViewId
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
const title = toSingleLine(body.props.find(p => p.key === 'title')?.value) ?? null
|
|
90
|
+
const description = removeIndent(body.props.find(p => p.key === 'description')?.value) ?? null
|
|
91
|
+
|
|
92
|
+
const tags = this.convertTags(body)
|
|
93
|
+
const links = this.convertLinks(body)
|
|
94
|
+
|
|
95
|
+
const manualLayout = parseViewManualLayout(astNode)
|
|
96
|
+
|
|
97
|
+
const view: ParsedAstElementView = {
|
|
98
|
+
__: 'element',
|
|
99
|
+
id: id as c4.ViewId,
|
|
100
|
+
astPath,
|
|
101
|
+
title,
|
|
102
|
+
description,
|
|
103
|
+
tags,
|
|
104
|
+
links: isNonEmptyArray(links) ? links : null,
|
|
105
|
+
rules: [
|
|
106
|
+
...additionalStyles,
|
|
107
|
+
...body.rules.flatMap(n => {
|
|
108
|
+
try {
|
|
109
|
+
return this.isValid(n) ? this.parseViewRule(n) : []
|
|
110
|
+
} catch (e) {
|
|
111
|
+
logWarnError(e)
|
|
112
|
+
return []
|
|
113
|
+
}
|
|
114
|
+
})
|
|
115
|
+
],
|
|
116
|
+
...(viewOf && { viewOf }),
|
|
117
|
+
...(manualLayout && { manualLayout })
|
|
118
|
+
}
|
|
119
|
+
ViewOps.writeId(astNode, view.id)
|
|
120
|
+
|
|
121
|
+
if ('extends' in astNode) {
|
|
122
|
+
const extendsView = astNode.extends.view.ref
|
|
123
|
+
invariant(extendsView?.name, 'view extends is not resolved: ' + astNode.$cstNode?.text)
|
|
124
|
+
return Object.assign(view, {
|
|
125
|
+
extends: extendsView.name as c4.ViewId
|
|
126
|
+
})
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
return view
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
parseViewRule(astRule: ast.ViewRule): c4.ViewRule {
|
|
133
|
+
if (ast.isViewRulePredicate(astRule)) {
|
|
134
|
+
return this.parseViewRulePredicate(astRule)
|
|
135
|
+
}
|
|
136
|
+
if (ast.isViewRuleGlobalPredicateRef(astRule)) {
|
|
137
|
+
return this.parseViewRuleGlobalPredicateRef(astRule)
|
|
138
|
+
}
|
|
139
|
+
if (ast.isViewRuleStyleOrGlobalRef(astRule)) {
|
|
140
|
+
return this.parseViewRuleStyleOrGlobalRef(astRule)
|
|
141
|
+
}
|
|
142
|
+
if (ast.isViewRuleAutoLayout(astRule)) {
|
|
143
|
+
return toAutoLayout(astRule)
|
|
144
|
+
}
|
|
145
|
+
if (ast.isViewRuleGroup(astRule)) {
|
|
146
|
+
return this.parseViewRuleGroup(astRule)
|
|
147
|
+
}
|
|
148
|
+
nonexhaustive(astRule)
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
parseViewRulePredicate(astNode: ast.ViewRulePredicate): c4.ViewRulePredicate {
|
|
152
|
+
const exprs = [] as c4.Expression[]
|
|
153
|
+
let predicate = astNode.predicates
|
|
154
|
+
while (predicate) {
|
|
155
|
+
const { value, prev } = predicate
|
|
156
|
+
try {
|
|
157
|
+
if (isTruthy(value) && this.isValid(value as any)) {
|
|
158
|
+
exprs.unshift(this.parsePredicate(value))
|
|
159
|
+
}
|
|
160
|
+
} catch (e) {
|
|
161
|
+
logWarnError(e)
|
|
162
|
+
}
|
|
163
|
+
if (!prev) {
|
|
164
|
+
break
|
|
165
|
+
}
|
|
166
|
+
predicate = prev
|
|
167
|
+
}
|
|
168
|
+
return ast.isIncludePredicate(astNode) ? { include: exprs } : { exclude: exprs }
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
parseViewRuleGlobalPredicateRef(
|
|
172
|
+
astRule: ast.ViewRuleGlobalPredicateRef | ast.DynamicViewGlobalPredicateRef
|
|
173
|
+
): c4.ViewRuleGlobalPredicateRef {
|
|
174
|
+
return {
|
|
175
|
+
predicateId: astRule.predicate.$refText as c4.GlobalPredicateId
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
parseViewRuleStyleOrGlobalRef(astRule: ast.ViewRuleStyleOrGlobalRef): c4.ViewRuleStyleOrGlobalRef {
|
|
180
|
+
if (ast.isViewRuleStyle(astRule)) {
|
|
181
|
+
return this.parseViewRuleStyle(astRule)
|
|
182
|
+
}
|
|
183
|
+
if (ast.isViewRuleGlobalStyle(astRule)) {
|
|
184
|
+
return this.parseViewRuleGlobalStyle(astRule)
|
|
185
|
+
}
|
|
186
|
+
nonexhaustive(astRule)
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
parseViewRuleGroup(astNode: ast.ViewRuleGroup): c4.ViewRuleGroup {
|
|
190
|
+
const groupRules = [] as c4.ViewRuleGroup['groupRules']
|
|
191
|
+
for (const rule of astNode.groupRules) {
|
|
192
|
+
try {
|
|
193
|
+
if (!this.isValid(rule)) {
|
|
194
|
+
continue
|
|
195
|
+
}
|
|
196
|
+
if (ast.isViewRulePredicate(rule)) {
|
|
197
|
+
groupRules.push(this.parseViewRulePredicate(rule))
|
|
198
|
+
continue
|
|
199
|
+
}
|
|
200
|
+
if (ast.isViewRuleGroup(rule)) {
|
|
201
|
+
groupRules.push(this.parseViewRuleGroup(rule))
|
|
202
|
+
continue
|
|
203
|
+
}
|
|
204
|
+
nonexhaustive(rule)
|
|
205
|
+
} catch (e) {
|
|
206
|
+
logWarnError(e)
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
return {
|
|
210
|
+
title: toSingleLine(astNode.title) ?? null,
|
|
211
|
+
groupRules,
|
|
212
|
+
...toElementStyle(astNode.props, this.isValid)
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
parseViewRuleStyle(astRule: ast.ViewRuleStyle | ast.GlobalStyle): c4.ViewRuleStyle {
|
|
217
|
+
const styleProps = astRule.props.filter(ast.isStyleProperty)
|
|
218
|
+
const targets = astRule.target
|
|
219
|
+
const notation = astRule.props.find(ast.isNotationProperty)
|
|
220
|
+
return this.parseRuleStyle(styleProps, targets, notation)
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
parseRuleStyle(
|
|
224
|
+
styleProperties: ast.StyleProperty[],
|
|
225
|
+
elementExpressionsIterator: ast.ElementExpressionsIterator,
|
|
226
|
+
notationProperty?: NotationProperty
|
|
227
|
+
): c4.ViewRuleStyle {
|
|
228
|
+
const styleProps = toElementStyle(styleProperties, this.isValid)
|
|
229
|
+
const notation = removeIndent(notationProperty?.value)
|
|
230
|
+
const targets = this.parseElementExpressionsIterator(elementExpressionsIterator)
|
|
231
|
+
return {
|
|
232
|
+
targets,
|
|
233
|
+
...(notation && { notation }),
|
|
234
|
+
style: {
|
|
235
|
+
...styleProps
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
parseViewRuleGlobalStyle(astRule: ast.ViewRuleGlobalStyle): c4.ViewRuleGlobalStyle {
|
|
241
|
+
return {
|
|
242
|
+
styleId: astRule.style.$refText as c4.GlobalStyleID
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
parseDynamicElementView(
|
|
247
|
+
astNode: ast.DynamicView,
|
|
248
|
+
additionalStyles: c4.ViewRuleStyleOrGlobalRef[]
|
|
249
|
+
): ParsedAstDynamicView {
|
|
250
|
+
const body = astNode.body
|
|
251
|
+
invariant(body, 'DynamicElementView body is not defined')
|
|
252
|
+
// only valid props
|
|
253
|
+
const isValid = this.isValid
|
|
254
|
+
const props = body.props.filter(isValid)
|
|
255
|
+
const astPath = this.getAstNodePath(astNode)
|
|
256
|
+
|
|
257
|
+
let id = astNode.name
|
|
258
|
+
if (!id) {
|
|
259
|
+
id = 'dynamic_' + stringHash(
|
|
260
|
+
this.doc.uri.toString(),
|
|
261
|
+
astPath
|
|
262
|
+
) as c4.ViewId
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
const title = toSingleLine(props.find(p => p.key === 'title')?.value) ?? null
|
|
266
|
+
const description = removeIndent(props.find(p => p.key === 'description')?.value) ?? null
|
|
267
|
+
|
|
268
|
+
const tags = this.convertTags(body)
|
|
269
|
+
const links = this.convertLinks(body)
|
|
270
|
+
|
|
271
|
+
ViewOps.writeId(astNode, id as c4.ViewId)
|
|
272
|
+
|
|
273
|
+
const manualLayout = parseViewManualLayout(astNode)
|
|
274
|
+
|
|
275
|
+
return {
|
|
276
|
+
__: 'dynamic',
|
|
277
|
+
id: id as c4.ViewId,
|
|
278
|
+
astPath,
|
|
279
|
+
title,
|
|
280
|
+
description,
|
|
281
|
+
tags,
|
|
282
|
+
links: isNonEmptyArray(links) ? links : null,
|
|
283
|
+
rules: [
|
|
284
|
+
...additionalStyles,
|
|
285
|
+
...body.rules.flatMap(n => {
|
|
286
|
+
try {
|
|
287
|
+
return isValid(n) ? this.parseDynamicViewRule(n) : []
|
|
288
|
+
} catch (e) {
|
|
289
|
+
logWarnError(e)
|
|
290
|
+
return []
|
|
291
|
+
}
|
|
292
|
+
}, [] as Array<c4.DynamicViewRule>)
|
|
293
|
+
],
|
|
294
|
+
steps: body.steps.reduce((acc, n) => {
|
|
295
|
+
try {
|
|
296
|
+
if (isValid(n)) {
|
|
297
|
+
if (ast.isDynamicViewParallelSteps(n)) {
|
|
298
|
+
acc.push(this.parseDynamicParallelSteps(n))
|
|
299
|
+
} else {
|
|
300
|
+
acc.push(this.parseDynamicStep(n))
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
} catch (e) {
|
|
304
|
+
logWarnError(e)
|
|
305
|
+
}
|
|
306
|
+
return acc
|
|
307
|
+
}, [] as c4.DynamicViewStepOrParallel[]),
|
|
308
|
+
...(manualLayout && { manualLayout })
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
parseDynamicViewRule(astRule: ast.DynamicViewRule): c4.DynamicViewRule {
|
|
313
|
+
if (ast.isDynamicViewIncludePredicate(astRule)) {
|
|
314
|
+
return this.parseDynamicViewIncludePredicate(astRule)
|
|
315
|
+
}
|
|
316
|
+
if (ast.isDynamicViewGlobalPredicateRef(astRule)) {
|
|
317
|
+
return this.parseViewRuleGlobalPredicateRef(astRule)
|
|
318
|
+
}
|
|
319
|
+
if (ast.isViewRuleStyleOrGlobalRef(astRule)) {
|
|
320
|
+
return this.parseViewRuleStyleOrGlobalRef(astRule)
|
|
321
|
+
}
|
|
322
|
+
if (ast.isViewRuleAutoLayout(astRule)) {
|
|
323
|
+
return toAutoLayout(astRule)
|
|
324
|
+
}
|
|
325
|
+
nonexhaustive(astRule)
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
parseDynamicViewIncludePredicate(astRule: ast.DynamicViewIncludePredicate): c4.DynamicViewIncludeRule {
|
|
329
|
+
const include = [] as c4.ElementPredicateExpression[]
|
|
330
|
+
let iter: ast.DynamicViewPredicateIterator | undefined = astRule.predicates
|
|
331
|
+
while (iter) {
|
|
332
|
+
try {
|
|
333
|
+
if (isNonNullish(iter.value) && this.isValid(iter.value as any)) {
|
|
334
|
+
const c4expr = this.parseElementPredicate(iter.value)
|
|
335
|
+
include.unshift(c4expr)
|
|
336
|
+
}
|
|
337
|
+
} catch (e) {
|
|
338
|
+
logWarnError(e)
|
|
339
|
+
}
|
|
340
|
+
iter = iter.prev
|
|
341
|
+
}
|
|
342
|
+
return { include }
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
parseDynamicParallelSteps(node: ast.DynamicViewParallelSteps): c4.DynamicViewParallelSteps {
|
|
346
|
+
return {
|
|
347
|
+
__parallel: node.steps.map(step => this.parseDynamicStep(step))
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
parseDynamicStep(node: ast.DynamicViewStep): c4.DynamicViewStep {
|
|
352
|
+
const sourceEl = elementRef(node.source)
|
|
353
|
+
if (!sourceEl) {
|
|
354
|
+
throw new Error('Invalid reference to source')
|
|
355
|
+
}
|
|
356
|
+
const targetEl = elementRef(node.target)
|
|
357
|
+
if (!targetEl) {
|
|
358
|
+
throw new Error('Invalid reference to target')
|
|
359
|
+
}
|
|
360
|
+
let source = this.resolveFqn(sourceEl)
|
|
361
|
+
let target = this.resolveFqn(targetEl)
|
|
362
|
+
const title = removeIndent(node.title) ?? null
|
|
363
|
+
|
|
364
|
+
let step: Writable<c4.DynamicViewStep> = {
|
|
365
|
+
source,
|
|
366
|
+
target,
|
|
367
|
+
title
|
|
368
|
+
}
|
|
369
|
+
if (node.isBackward) {
|
|
370
|
+
step = {
|
|
371
|
+
source: target,
|
|
372
|
+
target: source,
|
|
373
|
+
title,
|
|
374
|
+
isBackward: true
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
if (!isArray(node.custom?.props)) {
|
|
378
|
+
return step
|
|
379
|
+
}
|
|
380
|
+
for (const prop of node.custom.props) {
|
|
381
|
+
try {
|
|
382
|
+
switch (true) {
|
|
383
|
+
case ast.isRelationNavigateToProperty(prop): {
|
|
384
|
+
const viewId = prop.value.view.ref?.name
|
|
385
|
+
if (isTruthy(viewId)) {
|
|
386
|
+
step.navigateTo = viewId as c4.ViewId
|
|
387
|
+
}
|
|
388
|
+
break
|
|
389
|
+
}
|
|
390
|
+
case ast.isRelationStringProperty(prop):
|
|
391
|
+
case ast.isNotationProperty(prop):
|
|
392
|
+
case ast.isNotesProperty(prop): {
|
|
393
|
+
if (isDefined(prop.value)) {
|
|
394
|
+
step[prop.key] = removeIndent(prop.value) ?? ''
|
|
395
|
+
}
|
|
396
|
+
break
|
|
397
|
+
}
|
|
398
|
+
case ast.isArrowProperty(prop): {
|
|
399
|
+
if (isDefined(prop.value)) {
|
|
400
|
+
step[prop.key] = prop.value
|
|
401
|
+
}
|
|
402
|
+
break
|
|
403
|
+
}
|
|
404
|
+
case ast.isColorProperty(prop): {
|
|
405
|
+
const value = toColor(prop)
|
|
406
|
+
if (isDefined(value)) {
|
|
407
|
+
step[prop.key] = value
|
|
408
|
+
}
|
|
409
|
+
break
|
|
410
|
+
}
|
|
411
|
+
case ast.isLineProperty(prop): {
|
|
412
|
+
if (isDefined(prop.value)) {
|
|
413
|
+
step[prop.key] = prop.value
|
|
414
|
+
}
|
|
415
|
+
break
|
|
416
|
+
}
|
|
417
|
+
default:
|
|
418
|
+
nonexhaustive(prop)
|
|
419
|
+
}
|
|
420
|
+
}
|
|
421
|
+
catch (e) {
|
|
422
|
+
logWarnError(e)
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
return step
|
|
426
|
+
}
|
|
427
|
+
}
|
|
428
|
+
}
|
package/src/module.ts
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
|
-
import { DocumentCache, EmptyFileSystem, inject,
|
|
1
|
+
import { type Module, DocumentCache, EmptyFileSystem, inject, WorkspaceCache } from 'langium'
|
|
2
2
|
import {
|
|
3
|
-
createDefaultModule,
|
|
4
|
-
createDefaultSharedModule,
|
|
5
3
|
type DefaultSharedModuleContext,
|
|
6
4
|
type LangiumServices,
|
|
7
5
|
type LangiumSharedServices,
|
|
8
6
|
type PartialLangiumServices,
|
|
9
|
-
type PartialLangiumSharedServices
|
|
7
|
+
type PartialLangiumSharedServices,
|
|
8
|
+
createDefaultModule,
|
|
9
|
+
createDefaultSharedModule,
|
|
10
10
|
} from 'langium/lsp'
|
|
11
11
|
import { LikeC4Formatter } from './formatting/LikeC4Formatter'
|
|
12
12
|
import { LikeC4GeneratedModule, LikeC4GeneratedSharedModule } from './generated/module'
|
|
13
|
-
import {
|
|
13
|
+
import { logToLspConnection } from './logger'
|
|
14
14
|
import {
|
|
15
15
|
LikeC4CodeLensProvider,
|
|
16
16
|
LikeC4CompletionProvider,
|
|
@@ -18,7 +18,7 @@ import {
|
|
|
18
18
|
LikeC4DocumentLinkProvider,
|
|
19
19
|
LikeC4DocumentSymbolProvider,
|
|
20
20
|
LikeC4HoverProvider,
|
|
21
|
-
LikeC4SemanticTokenProvider
|
|
21
|
+
LikeC4SemanticTokenProvider,
|
|
22
22
|
} from './lsp'
|
|
23
23
|
import { DeploymentsIndex, FqnIndex, LikeC4ModelBuilder, LikeC4ModelLocator, LikeC4ModelParser } from './model'
|
|
24
24
|
import { LikeC4ModelChanges } from './model-change/ModelChanges'
|
|
@@ -48,11 +48,11 @@ const LikeC4SharedModule: Module<
|
|
|
48
48
|
> = {
|
|
49
49
|
lsp: {
|
|
50
50
|
NodeKindProvider: services => new NodeKindProvider(services),
|
|
51
|
-
WorkspaceSymbolProvider: services => new WorkspaceSymbolProvider(services)
|
|
51
|
+
WorkspaceSymbolProvider: services => new WorkspaceSymbolProvider(services),
|
|
52
52
|
},
|
|
53
53
|
workspace: {
|
|
54
|
-
WorkspaceManager: services => new LikeC4WorkspaceManager(services)
|
|
55
|
-
}
|
|
54
|
+
WorkspaceManager: services => new LikeC4WorkspaceManager(services),
|
|
55
|
+
},
|
|
56
56
|
}
|
|
57
57
|
|
|
58
58
|
/**
|
|
@@ -105,7 +105,7 @@ export const LikeC4Module: Module<LikeC4Services, PartialLangiumServices & LikeC
|
|
|
105
105
|
FqnIndex: bind(FqnIndex),
|
|
106
106
|
ModelParser: bind(LikeC4ModelParser),
|
|
107
107
|
ModelBuilder: bind(LikeC4ModelBuilder),
|
|
108
|
-
ModelLocator: bind(LikeC4ModelLocator)
|
|
108
|
+
ModelLocator: bind(LikeC4ModelLocator),
|
|
109
109
|
},
|
|
110
110
|
lsp: {
|
|
111
111
|
// RenameProvider: bind(LikeC4RenameProvider),
|
|
@@ -116,13 +116,13 @@ export const LikeC4Module: Module<LikeC4Services, PartialLangiumServices & LikeC
|
|
|
116
116
|
HoverProvider: bind(LikeC4HoverProvider),
|
|
117
117
|
CodeLensProvider: bind(LikeC4CodeLensProvider),
|
|
118
118
|
DocumentLinkProvider: bind(LikeC4DocumentLinkProvider),
|
|
119
|
-
Formatter: bind(LikeC4Formatter)
|
|
119
|
+
Formatter: bind(LikeC4Formatter),
|
|
120
120
|
},
|
|
121
121
|
references: {
|
|
122
122
|
NameProvider: bind(LikeC4NameProvider),
|
|
123
123
|
ScopeComputation: bind(LikeC4ScopeComputation),
|
|
124
|
-
ScopeProvider: bind(LikeC4ScopeProvider)
|
|
125
|
-
}
|
|
124
|
+
ScopeProvider: bind(LikeC4ScopeProvider),
|
|
125
|
+
},
|
|
126
126
|
}
|
|
127
127
|
|
|
128
128
|
export type LanguageServicesContext = Partial<DefaultSharedModuleContext>
|
|
@@ -131,7 +131,7 @@ export function createCustomLanguageServices<I1, I2, I3, I extends I1 & I2 & I3
|
|
|
131
131
|
context: LanguageServicesContext,
|
|
132
132
|
module: Module<I, I1>,
|
|
133
133
|
module2?: Module<I, I2>,
|
|
134
|
-
module3?: Module<I, I3
|
|
134
|
+
module3?: Module<I, I3>,
|
|
135
135
|
): { shared: LikeC4SharedServices; likec4: I } {
|
|
136
136
|
const shared = createSharedServices(context)
|
|
137
137
|
const modules = [
|
|
@@ -140,7 +140,7 @@ export function createCustomLanguageServices<I1, I2, I3, I extends I1 & I2 & I3
|
|
|
140
140
|
LikeC4Module,
|
|
141
141
|
module,
|
|
142
142
|
module2,
|
|
143
|
-
module3
|
|
143
|
+
module3,
|
|
144
144
|
].reduce(_merge, {}) as Module<I>
|
|
145
145
|
|
|
146
146
|
const likec4 = inject(modules)
|
|
@@ -161,17 +161,16 @@ export function createCustomLanguageServices<I1, I2, I3, I extends I1 & I2 & I3
|
|
|
161
161
|
export function createSharedServices(context: LanguageServicesContext = {}): LikeC4SharedServices {
|
|
162
162
|
const moduleContext: DefaultSharedModuleContext = {
|
|
163
163
|
...EmptyFileSystem,
|
|
164
|
-
...context
|
|
164
|
+
...context,
|
|
165
165
|
}
|
|
166
166
|
if (context.connection) {
|
|
167
167
|
logToLspConnection(context.connection)
|
|
168
|
-
logErrorToTelemetry(context.connection)
|
|
169
168
|
}
|
|
170
169
|
|
|
171
170
|
return inject(
|
|
172
171
|
createDefaultSharedModule(moduleContext),
|
|
173
172
|
LikeC4GeneratedSharedModule,
|
|
174
|
-
LikeC4SharedModule
|
|
173
|
+
LikeC4SharedModule,
|
|
175
174
|
)
|
|
176
175
|
}
|
|
177
176
|
|
|
@@ -16,7 +16,7 @@ import {
|
|
|
16
16
|
StreamImpl,
|
|
17
17
|
StreamScope
|
|
18
18
|
} from 'langium'
|
|
19
|
-
import { ast
|
|
19
|
+
import { ast } from '../ast'
|
|
20
20
|
import { logger } from '../logger'
|
|
21
21
|
import type { DeploymentsIndex, FqnIndex } from '../model'
|
|
22
22
|
import type { LikeC4Services } from '../module'
|
|
@@ -91,8 +91,8 @@ export class LikeC4ScopeProvider extends DefaultScopeProvider {
|
|
|
91
91
|
const referenceType = this.reflection.getReferenceType(context)
|
|
92
92
|
try {
|
|
93
93
|
const container = context.container
|
|
94
|
-
if (ast.
|
|
95
|
-
return this.
|
|
94
|
+
if (ast.isFqnRef(container)) {
|
|
95
|
+
return this.getScopeForFqnRef(container, context)
|
|
96
96
|
}
|
|
97
97
|
|
|
98
98
|
if (referenceType !== ast.Element) {
|
|
@@ -134,14 +134,20 @@ export class LikeC4ScopeProvider extends DefaultScopeProvider {
|
|
|
134
134
|
}
|
|
135
135
|
}
|
|
136
136
|
|
|
137
|
-
protected
|
|
137
|
+
protected getScopeForFqnRef(container: ast.FqnRef, context: ReferenceInfo) {
|
|
138
138
|
const parent = container.parent
|
|
139
139
|
if (!parent) {
|
|
140
|
-
return
|
|
140
|
+
return this.createScope(
|
|
141
141
|
// First preference for deployment nodes
|
|
142
142
|
this.computeScope(context, ast.DeploymentNode).getAllElements(),
|
|
143
|
-
|
|
144
|
-
|
|
143
|
+
this.createScope(
|
|
144
|
+
// Second preference for deployed instances
|
|
145
|
+
this.computeScope(context, ast.DeployedInstance).getAllElements(),
|
|
146
|
+
// Third preference for elements if we are in deployment view
|
|
147
|
+
AstUtils.hasContainerOfType(container, ast.isDeploymentView)
|
|
148
|
+
? this.computeScope(context, ast.Element)
|
|
149
|
+
: EMPTY_SCOPE
|
|
150
|
+
)
|
|
145
151
|
)
|
|
146
152
|
}
|
|
147
153
|
const parentRef = parent.value.ref
|
|
@@ -2,7 +2,7 @@ import { AstUtils } from 'langium'
|
|
|
2
2
|
import { isNullish } from 'remeda'
|
|
3
3
|
import { ast } from '../ast'
|
|
4
4
|
|
|
5
|
-
export function instanceRef(deploymentRef: ast.
|
|
5
|
+
export function instanceRef(deploymentRef: ast.FqnRef): ast.DeployedInstance | null {
|
|
6
6
|
let referenceable
|
|
7
7
|
while ((referenceable = deploymentRef.value?.ref)) {
|
|
8
8
|
if (ast.isDeploymentNode(referenceable)) {
|
|
@@ -19,7 +19,7 @@ export function instanceRef(deploymentRef: ast.DeploymentRef): ast.DeployedInsta
|
|
|
19
19
|
return null
|
|
20
20
|
}
|
|
21
21
|
|
|
22
|
-
export function deploymentNodeRef(deploymentRef: ast.
|
|
22
|
+
export function deploymentNodeRef(deploymentRef: ast.FqnRef): ast.DeploymentNode | null {
|
|
23
23
|
let referenceable = deploymentRef.value.ref ?? null
|
|
24
24
|
if (!referenceable || ast.isDeploymentNode(referenceable)) {
|
|
25
25
|
return referenceable
|
|
@@ -29,3 +29,28 @@ export function deploymentNodeRef(deploymentRef: ast.DeploymentRef): ast.Deploym
|
|
|
29
29
|
// we find artifact first and then its container
|
|
30
30
|
return artifact ? AstUtils.getContainerOfType(artifact, ast.isDeploymentNode) ?? null : null
|
|
31
31
|
}
|
|
32
|
+
|
|
33
|
+
export function isReferenceToLogicalModel(node: ast.FqnRef) {
|
|
34
|
+
// iterate up the root parent
|
|
35
|
+
while (node.parent) {
|
|
36
|
+
node = node.parent
|
|
37
|
+
}
|
|
38
|
+
return ast.isElement(node.value.ref)
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Returns true if node references deployment model
|
|
43
|
+
*/
|
|
44
|
+
export function isReferenceToDeploymentModel(node: ast.FqnRef) {
|
|
45
|
+
let referenceable
|
|
46
|
+
while ((referenceable = node.value?.ref)) {
|
|
47
|
+
if (ast.isDeploymentElement(referenceable)) {
|
|
48
|
+
return true
|
|
49
|
+
}
|
|
50
|
+
if (isNullish(node.parent)) {
|
|
51
|
+
return false
|
|
52
|
+
}
|
|
53
|
+
node = node.parent
|
|
54
|
+
}
|
|
55
|
+
return false
|
|
56
|
+
}
|