@likec4/language-server 1.12.1 → 1.13.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/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/model-graph/index.cjs +1 -1
- package/dist/model-graph/index.d.cts +1 -1
- package/dist/model-graph/index.d.mts +1 -1
- package/dist/model-graph/index.d.ts +1 -1
- package/dist/model-graph/index.mjs +1 -1
- package/dist/shared/{language-server.CzkWpuWT.d.mts → language-server.B-9_mDoo.d.mts} +7 -2
- package/dist/shared/{language-server.BH0brgLf.cjs → language-server.C2ebP2pZ.cjs} +80 -90
- package/dist/shared/{language-server.DJAHXekh.d.cts → language-server.C3oS5yhF.d.cts} +7 -2
- package/dist/shared/{language-server.3Bh0zvVS.cjs → language-server.CbDa016p.cjs} +9 -7
- package/dist/shared/{language-server.DtLmc4Fz.d.cts → language-server.Cnq_hgfm.d.cts} +6 -1
- package/dist/shared/{language-server.BYjS7OIz.mjs → language-server.CrE0nFSB.mjs} +79 -89
- package/dist/shared/{language-server.BxxqS4Id.mjs → language-server.DFLaUdYu.mjs} +7 -6
- package/dist/shared/{language-server.BCDM5gt9.d.ts → language-server.eY70DuKx.d.ts} +6 -1
- package/dist/shared/{language-server.B8Ce0R_D.d.ts → language-server.r5AXAWzc.d.ts} +7 -2
- package/dist/shared/{language-server.BN7V1vQA.d.mts → language-server.ryB8CivX.d.mts} +6 -1
- package/package.json +7 -7
- package/src/ast.ts +1 -1
- package/src/generated/ast.ts +3 -1
- package/src/generated/grammar.ts +1 -1
- package/src/like-c4.langium +4 -2
- package/src/lsp/CompletionProvider.ts +2 -2
- package/src/model/model-parser.ts +78 -69
- package/src/model-change/ModelChanges.ts +0 -28
- package/src/model-change/changeViewLayout.ts +5 -5
- package/src/model-graph/compute-view/compute.ts +1 -1
- package/src/model-graph/dynamic-view/compute.ts +1 -1
- package/src/model-graph/utils/sortNodes.ts +3 -3
- package/src/test/testServices.ts +9 -5
- package/src/utils/graphlib.ts +5 -7
- package/src/validation/_shared.ts +2 -1
- package/src/validation/index.ts +0 -2
- package/src/validation/specification.ts +0 -11
- package/src/view-utils/resolve-extended-views.ts +2 -2
package/src/like-c4.langium
CHANGED
|
@@ -194,8 +194,10 @@ MetadataAttribute:
|
|
|
194
194
|
// Views -------------------------------------
|
|
195
195
|
|
|
196
196
|
ModelViews:
|
|
197
|
-
name='views' '{'
|
|
198
|
-
|
|
197
|
+
name='views' '{' (
|
|
198
|
+
views+=LikeC4ViewRule |
|
|
199
|
+
styles+=ViewRuleStyle
|
|
200
|
+
)*
|
|
199
201
|
'}';
|
|
200
202
|
|
|
201
203
|
type LikeC4View = ElementView | DynamicView;
|
|
@@ -23,10 +23,10 @@ export class LikeC4CompletionProvider extends DefaultCompletionProvider {
|
|
|
23
23
|
if (['views', 'specification', 'model'].includes(keyword.value)) {
|
|
24
24
|
return acceptor(context, {
|
|
25
25
|
label: keyword.value,
|
|
26
|
-
detail: `Insert ${keyword} block`,
|
|
26
|
+
detail: `Insert ${keyword.value} block`,
|
|
27
27
|
kind: CompletionItemKind.Module,
|
|
28
28
|
insertTextFormat: InsertTextFormat.Snippet,
|
|
29
|
-
insertText: `${keyword} {\n\t$0\n}`
|
|
29
|
+
insertText: `${keyword.value} {\n\t$0\n}`
|
|
30
30
|
})
|
|
31
31
|
}
|
|
32
32
|
if (keyword.value === 'dynamic') {
|
|
@@ -36,6 +36,9 @@ import { stringHash } from '../utils'
|
|
|
36
36
|
import { deserializeFromComment, hasManualLayout } from '../view-utils/manual-layout'
|
|
37
37
|
import type { FqnIndex } from './fqn-index'
|
|
38
38
|
import { parseWhereClause } from './model-parser-where'
|
|
39
|
+
import {
|
|
40
|
+
type NotationProperty
|
|
41
|
+
} from '../generated/ast'
|
|
39
42
|
|
|
40
43
|
const { getDocument } = AstUtils
|
|
41
44
|
|
|
@@ -283,17 +286,23 @@ export class LikeC4ModelParser {
|
|
|
283
286
|
}
|
|
284
287
|
|
|
285
288
|
private parseViews(doc: ParsedLikeC4LangiumDocument, isValid: IsValidFn) {
|
|
286
|
-
const
|
|
287
|
-
for (const
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
289
|
+
const viewBlocks = doc.parseResult.value.views.filter(v => isValid(v))
|
|
290
|
+
for (const viewBlock of viewBlocks) {
|
|
291
|
+
const localStyles = viewBlock.styles
|
|
292
|
+
.flatMap(s => this.parseViewRuleStyle(s, isValid))
|
|
293
|
+
const stylesToApply = localStyles
|
|
294
|
+
|
|
295
|
+
for (const view of viewBlock.views) {
|
|
296
|
+
try {
|
|
297
|
+
if (!isValid(view)) {
|
|
298
|
+
continue
|
|
299
|
+
}
|
|
300
|
+
doc.c4Views.push(
|
|
301
|
+
ast.isElementView(view) ? this.parseElementView(view, stylesToApply, isValid) : this.parseDynamicElementView(view, stylesToApply, isValid)
|
|
302
|
+
)
|
|
303
|
+
} catch (e) {
|
|
304
|
+
logWarnError(e)
|
|
291
305
|
}
|
|
292
|
-
doc.c4Views.push(
|
|
293
|
-
ast.isElementView(view) ? this.parseElementView(view, isValid) : this.parseDynamicElementView(view, isValid)
|
|
294
|
-
)
|
|
295
|
-
} catch (e) {
|
|
296
|
-
logWarnError(e)
|
|
297
306
|
}
|
|
298
307
|
}
|
|
299
308
|
}
|
|
@@ -596,16 +605,7 @@ export class LikeC4ModelParser {
|
|
|
596
605
|
return this.parseViewRulePredicate(astRule, isValid)
|
|
597
606
|
}
|
|
598
607
|
if (ast.isViewRuleStyle(astRule)) {
|
|
599
|
-
|
|
600
|
-
const notation = removeIndent(astRule.props.find(ast.isNotationProperty)?.value)
|
|
601
|
-
const targets = this.parseElementExpressionsIterator(astRule.target)
|
|
602
|
-
return {
|
|
603
|
-
targets,
|
|
604
|
-
...(notation && { notation }),
|
|
605
|
-
style: {
|
|
606
|
-
...styleProps
|
|
607
|
-
}
|
|
608
|
-
}
|
|
608
|
+
return this.parseViewRuleStyle(astRule, isValid)
|
|
609
609
|
}
|
|
610
610
|
if (ast.isViewRuleAutoLayout(astRule)) {
|
|
611
611
|
return toAutoLayout(astRule)
|
|
@@ -613,6 +613,26 @@ export class LikeC4ModelParser {
|
|
|
613
613
|
nonexhaustive(astRule)
|
|
614
614
|
}
|
|
615
615
|
|
|
616
|
+
private parseViewRuleStyle(astRule: ast.ViewRuleStyle, isValid: IsValidFn): c4.ViewRuleStyle {
|
|
617
|
+
const styleProps = astRule.props.filter(ast.isStyleProperty)
|
|
618
|
+
const targets = astRule.target
|
|
619
|
+
const notation = astRule.props.find(ast.isNotationProperty)
|
|
620
|
+
return this.parseRuleStyle(styleProps, targets, isValid, notation)
|
|
621
|
+
}
|
|
622
|
+
|
|
623
|
+
private parseRuleStyle(styleProperties: ast.StyleProperty[], elementExpressionsIterator: ast.ElementExpressionsIterator, isValid: IsValidFn, notationProperty?: NotationProperty): c4.ViewRuleStyle {
|
|
624
|
+
const styleProps = toElementStyle(styleProperties, isValid)
|
|
625
|
+
const notation = removeIndent(notationProperty?.value)
|
|
626
|
+
const targets = this.parseElementExpressionsIterator(elementExpressionsIterator)
|
|
627
|
+
return {
|
|
628
|
+
targets,
|
|
629
|
+
...(notation && { notation }),
|
|
630
|
+
style: {
|
|
631
|
+
...styleProps
|
|
632
|
+
}
|
|
633
|
+
}
|
|
634
|
+
}
|
|
635
|
+
|
|
616
636
|
private parseViewManualLaout(node: ast.DynamicView | ast.ElementView): c4.ViewManualLayout | undefined {
|
|
617
637
|
const commentNode = CstUtils.findCommentNode(node.$cstNode, ['BLOCK_COMMENT'])
|
|
618
638
|
if (!commentNode || !hasManualLayout(commentNode.text)) {
|
|
@@ -709,7 +729,7 @@ export class LikeC4ModelParser {
|
|
|
709
729
|
return step
|
|
710
730
|
}
|
|
711
731
|
|
|
712
|
-
private parseElementView(astNode: ast.ElementView, isValid: IsValidFn): ParsedAstElementView {
|
|
732
|
+
private parseElementView(astNode: ast.ElementView, additionalStyles: c4.ViewRuleStyle[], isValid: IsValidFn): ParsedAstElementView {
|
|
713
733
|
const body = astNode.body
|
|
714
734
|
invariant(body, 'ElementView body is not defined')
|
|
715
735
|
const astPath = this.getAstNodePath(astNode)
|
|
@@ -750,14 +770,14 @@ export class LikeC4ModelParser {
|
|
|
750
770
|
description,
|
|
751
771
|
tags,
|
|
752
772
|
links: isNonEmptyArray(links) ? links : null,
|
|
753
|
-
rules: body.rules.flatMap(n => {
|
|
773
|
+
rules: [...additionalStyles, ...body.rules.flatMap(n => {
|
|
754
774
|
try {
|
|
755
775
|
return isValid(n) ? this.parseViewRule(n, isValid) : []
|
|
756
776
|
} catch (e) {
|
|
757
777
|
logWarnError(e)
|
|
758
778
|
return []
|
|
759
779
|
}
|
|
760
|
-
}),
|
|
780
|
+
})],
|
|
761
781
|
...(viewOf && { viewOf }),
|
|
762
782
|
...(manualLayout && { manualLayout })
|
|
763
783
|
}
|
|
@@ -774,7 +794,7 @@ export class LikeC4ModelParser {
|
|
|
774
794
|
return view
|
|
775
795
|
}
|
|
776
796
|
|
|
777
|
-
private parseDynamicElementView(astNode: ast.DynamicView, isValid: IsValidFn): ParsedAstDynamicView {
|
|
797
|
+
private parseDynamicElementView(astNode: ast.DynamicView, additionalStyles: c4.ViewRuleStyle[], isValid: IsValidFn): ParsedAstDynamicView {
|
|
778
798
|
const body = astNode.body
|
|
779
799
|
invariant(body, 'DynamicElementView body is not defined')
|
|
780
800
|
// only valid props
|
|
@@ -807,55 +827,14 @@ export class LikeC4ModelParser {
|
|
|
807
827
|
description,
|
|
808
828
|
tags,
|
|
809
829
|
links: isNonEmptyArray(links) ? links : null,
|
|
810
|
-
rules: body.rules.
|
|
811
|
-
if (!isValid(n)) {
|
|
812
|
-
return acc
|
|
813
|
-
}
|
|
830
|
+
rules: [...additionalStyles, ...body.rules.flatMap(n => {
|
|
814
831
|
try {
|
|
815
|
-
|
|
816
|
-
const include = [] as c4.ElementPredicateExpression[]
|
|
817
|
-
let iter: ast.DynamicViewPredicateIterator | undefined = n.predicates
|
|
818
|
-
while (iter) {
|
|
819
|
-
try {
|
|
820
|
-
if (isValid(iter.value as any)) {
|
|
821
|
-
const c4expr = this.parseElementPredicate(iter.value, isValid)
|
|
822
|
-
include.unshift(c4expr)
|
|
823
|
-
}
|
|
824
|
-
} catch (e) {
|
|
825
|
-
logWarnError(e)
|
|
826
|
-
}
|
|
827
|
-
iter = iter.prev
|
|
828
|
-
}
|
|
829
|
-
if (include.length > 0) {
|
|
830
|
-
acc.push({ include })
|
|
831
|
-
}
|
|
832
|
-
return acc
|
|
833
|
-
}
|
|
834
|
-
if (ast.isViewRuleStyle(n)) {
|
|
835
|
-
const styleProps = toElementStyle(n.props.filter(ast.isStyleProperty), isValid)
|
|
836
|
-
const notation = removeIndent(n.props.find(ast.isNotationProperty)?.value)
|
|
837
|
-
const targets = this.parseElementExpressionsIterator(n.target)
|
|
838
|
-
if (targets.length > 0) {
|
|
839
|
-
acc.push({
|
|
840
|
-
targets,
|
|
841
|
-
...(notation && { notation }),
|
|
842
|
-
style: {
|
|
843
|
-
...styleProps
|
|
844
|
-
}
|
|
845
|
-
})
|
|
846
|
-
}
|
|
847
|
-
return acc
|
|
848
|
-
}
|
|
849
|
-
if (ast.isViewRuleAutoLayout(n)) {
|
|
850
|
-
acc.push(toAutoLayout(n))
|
|
851
|
-
return acc
|
|
852
|
-
}
|
|
853
|
-
nonexhaustive(n)
|
|
832
|
+
return isValid(n) ? this.parseDynamicViewRule(n, isValid) : []
|
|
854
833
|
} catch (e) {
|
|
855
834
|
logWarnError(e)
|
|
856
|
-
return
|
|
835
|
+
return []
|
|
857
836
|
}
|
|
858
|
-
}, [] as Array<c4.DynamicViewRule>),
|
|
837
|
+
}, [] as Array<c4.DynamicViewRule>)],
|
|
859
838
|
steps: body.steps.reduce((acc, n) => {
|
|
860
839
|
try {
|
|
861
840
|
if (isValid(n)) {
|
|
@@ -874,6 +853,36 @@ export class LikeC4ModelParser {
|
|
|
874
853
|
}
|
|
875
854
|
}
|
|
876
855
|
|
|
856
|
+
private parseDynamicViewRule(astRule: ast.DynamicViewRule, isValid: IsValidFn): c4.DynamicViewRule {
|
|
857
|
+
if (ast.isDynamicViewIncludePredicate(astRule)) {
|
|
858
|
+
return this.parseDynamicViewIncludePredicate(astRule, isValid)
|
|
859
|
+
}
|
|
860
|
+
if (ast.isViewRuleStyle(astRule)) {
|
|
861
|
+
return this.parseViewRuleStyle(astRule, isValid)
|
|
862
|
+
}
|
|
863
|
+
if (ast.isViewRuleAutoLayout(astRule)) {
|
|
864
|
+
return toAutoLayout(astRule)
|
|
865
|
+
}
|
|
866
|
+
nonexhaustive(astRule)
|
|
867
|
+
}
|
|
868
|
+
|
|
869
|
+
private parseDynamicViewIncludePredicate(astRule: ast.DynamicViewIncludePredicate, isValid: IsValidFn): c4.DynamicViewIncludeRule {
|
|
870
|
+
const include = [] as c4.ElementPredicateExpression[]
|
|
871
|
+
let iter: ast.DynamicViewPredicateIterator | undefined = astRule.predicates
|
|
872
|
+
while (iter) {
|
|
873
|
+
try {
|
|
874
|
+
if (isValid(iter.value as any)) {
|
|
875
|
+
const c4expr = this.parseElementPredicate(iter.value, isValid)
|
|
876
|
+
include.unshift(c4expr)
|
|
877
|
+
}
|
|
878
|
+
} catch (e) {
|
|
879
|
+
logWarnError(e)
|
|
880
|
+
}
|
|
881
|
+
iter = iter.prev
|
|
882
|
+
}
|
|
883
|
+
return { include }
|
|
884
|
+
}
|
|
885
|
+
|
|
877
886
|
protected resolveFqn(node: ast.Element | ast.ExtendElement) {
|
|
878
887
|
if (ast.isExtendElement(node)) {
|
|
879
888
|
return getFqnElementRef(node.element)
|
|
@@ -9,34 +9,6 @@ import { changeElementStyle } from './changeElementStyle'
|
|
|
9
9
|
import { changeViewLayout } from './changeViewLayout'
|
|
10
10
|
import { saveManualLayout } from './saveManualLayout'
|
|
11
11
|
|
|
12
|
-
// function unionRangeOfAllEdits(ranges: Range[]): Range {
|
|
13
|
-
// let startLine = Number.MAX_SAFE_INTEGER
|
|
14
|
-
// let endLine = Number.MIN_SAFE_INTEGER
|
|
15
|
-
|
|
16
|
-
// let startCharacter = Number.MAX_SAFE_INTEGER
|
|
17
|
-
// let endCharacter = Number.MIN_SAFE_INTEGER
|
|
18
|
-
|
|
19
|
-
// for (const { start, end } of ranges) {
|
|
20
|
-
// if (start.line <= startLine) {
|
|
21
|
-
// if (startLine == start.line) {
|
|
22
|
-
// startCharacter = Math.min(start.character, startCharacter)
|
|
23
|
-
// } else {
|
|
24
|
-
// startLine = start.line
|
|
25
|
-
// startCharacter = start.character
|
|
26
|
-
// }
|
|
27
|
-
// }
|
|
28
|
-
// if (endLine <= end.line) {
|
|
29
|
-
// if (endLine == end.line) {
|
|
30
|
-
// endCharacter = Math.max(end.character, endCharacter)
|
|
31
|
-
// } else {
|
|
32
|
-
// endLine = end.line
|
|
33
|
-
// endCharacter = end.character
|
|
34
|
-
// }
|
|
35
|
-
// }
|
|
36
|
-
// }
|
|
37
|
-
// return Range.create(startLine, startCharacter, endLine, endCharacter)
|
|
38
|
-
// }
|
|
39
|
-
|
|
40
12
|
export class LikeC4ModelChanges {
|
|
41
13
|
private locator: LikeC4ModelLocator
|
|
42
14
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { invariant, type
|
|
1
|
+
import { invariant, type ViewChange } from '@likec4/core'
|
|
2
2
|
import { GrammarUtils } from 'langium'
|
|
3
|
-
import {
|
|
3
|
+
import { isNumber } from 'remeda'
|
|
4
4
|
import { TextEdit } from 'vscode-languageserver-types'
|
|
5
5
|
import { ast, type ParsedAstView, type ParsedLikeC4LangiumDocument, toAstViewLayoutDirection } from '../ast'
|
|
6
6
|
import type { LikeC4Services } from '../module'
|
|
@@ -11,7 +11,7 @@ type ChangeViewLayoutArg = {
|
|
|
11
11
|
view: ParsedAstView
|
|
12
12
|
doc: ParsedLikeC4LangiumDocument
|
|
13
13
|
viewAst: ast.LikeC4View
|
|
14
|
-
layout:
|
|
14
|
+
layout: ViewChange.ChangeAutoLayout['layout']
|
|
15
15
|
}
|
|
16
16
|
|
|
17
17
|
export function changeViewLayout(_services: LikeC4Services, {
|
|
@@ -28,9 +28,9 @@ export function changeViewLayout(_services: LikeC4Services, {
|
|
|
28
28
|
|
|
29
29
|
let newRule = `autoLayout ${newdirection}`
|
|
30
30
|
|
|
31
|
-
if (
|
|
31
|
+
if (isNumber(layout.rankSep)) {
|
|
32
32
|
newRule += ` ${layout.rankSep}`
|
|
33
|
-
if (
|
|
33
|
+
if (isNumber(layout.nodeSep)) {
|
|
34
34
|
newRule += ` ${layout.nodeSep}`
|
|
35
35
|
}
|
|
36
36
|
}
|
|
@@ -178,7 +178,7 @@ export class ComputeCtx {
|
|
|
178
178
|
autoLayout: {
|
|
179
179
|
direction: autoLayoutRule?.direction ?? 'TB',
|
|
180
180
|
...(autoLayoutRule?.nodeSep && { nodeSep: autoLayoutRule.nodeSep }),
|
|
181
|
-
...(autoLayoutRule?.rankSep && { rankSep: autoLayoutRule.rankSep })
|
|
181
|
+
...(autoLayoutRule?.rankSep && { rankSep: autoLayoutRule.rankSep })
|
|
182
182
|
},
|
|
183
183
|
nodes: map(nodes, omit(['notation'])),
|
|
184
184
|
edges: applyCustomRelationProperties(rules, nodes, sortedEdges),
|
|
@@ -203,7 +203,7 @@ export class DynamicViewComputeCtx {
|
|
|
203
203
|
autoLayout: {
|
|
204
204
|
direction: autoLayoutRule?.direction ?? 'LR',
|
|
205
205
|
...(autoLayoutRule?.nodeSep && { nodeSep: autoLayoutRule.nodeSep }),
|
|
206
|
-
...(autoLayoutRule?.rankSep && { rankSep: autoLayoutRule.rankSep })
|
|
206
|
+
...(autoLayoutRule?.rankSep && { rankSep: autoLayoutRule.rankSep })
|
|
207
207
|
},
|
|
208
208
|
nodes: map(nodes, omit(['notation'])),
|
|
209
209
|
edges,
|
|
@@ -8,7 +8,7 @@ import {
|
|
|
8
8
|
invariant,
|
|
9
9
|
nonNullable
|
|
10
10
|
} from '@likec4/core'
|
|
11
|
-
import { difference, filter, map, pipe, sort
|
|
11
|
+
import { difference, filter, map, pipe, sort } from 'remeda'
|
|
12
12
|
import { Graph, postorder } from '../../utils/graphlib'
|
|
13
13
|
|
|
14
14
|
// side effect
|
|
@@ -53,7 +53,7 @@ export function sortNodes({
|
|
|
53
53
|
}
|
|
54
54
|
|
|
55
55
|
for (const n of nodes) {
|
|
56
|
-
g.setNode(n.id)
|
|
56
|
+
g.setNode(n.id, n.id)
|
|
57
57
|
if (n.children.length > 0) {
|
|
58
58
|
// n.children.forEach(c => {
|
|
59
59
|
// g.setEdge(n.id, c, undefined, `${n.id}:${c}`)
|
|
@@ -79,7 +79,7 @@ export function sortNodes({
|
|
|
79
79
|
}
|
|
80
80
|
}
|
|
81
81
|
|
|
82
|
-
let sources = g.sources()
|
|
82
|
+
let sources = g.sources() as unknown as Fqn[]
|
|
83
83
|
if (sources.length === 0) {
|
|
84
84
|
sources = pipe(
|
|
85
85
|
nodes,
|
package/src/test/testServices.ts
CHANGED
|
@@ -75,14 +75,15 @@ export function createTestServices(workspace = 'file:///test/workspace') {
|
|
|
75
75
|
await documentBuilder.build([document], { validation: true })
|
|
76
76
|
})
|
|
77
77
|
|
|
78
|
-
const edits = await
|
|
79
|
-
document,
|
|
78
|
+
const edits = await formatter?.formatDocument(
|
|
79
|
+
document,
|
|
80
80
|
{
|
|
81
|
-
options: {tabSize: 2, insertSpaces: true},
|
|
81
|
+
options: { tabSize: 2, insertSpaces: true },
|
|
82
82
|
textDocument: { uri: document.uri.toString() }
|
|
83
|
-
}
|
|
83
|
+
}
|
|
84
|
+
)
|
|
84
85
|
|
|
85
|
-
return TextDocument.applyEdits(document.textDocument, edits ?? [])
|
|
86
|
+
return TextDocument.applyEdits(document.textDocument, edits ?? [])
|
|
86
87
|
}
|
|
87
88
|
|
|
88
89
|
type ValidateAllResult = {
|
|
@@ -116,6 +117,9 @@ export function createTestServices(workspace = 'file:///test/workspace') {
|
|
|
116
117
|
return model
|
|
117
118
|
}
|
|
118
119
|
|
|
120
|
+
/**
|
|
121
|
+
* This will clear all documents
|
|
122
|
+
*/
|
|
119
123
|
const resetState = async () => {
|
|
120
124
|
await services.shared.workspace.WorkspaceLock.write(async (cancelToken) => {
|
|
121
125
|
const docs = langiumDocuments.all.toArray().map(doc => doc.uri)
|
package/src/utils/graphlib.ts
CHANGED
|
@@ -1,11 +1,9 @@
|
|
|
1
|
-
|
|
2
|
-
// Here is a workaround to import it
|
|
1
|
+
import dagre from '@dagrejs/dagre'
|
|
3
2
|
|
|
4
|
-
|
|
5
|
-
import graphlib from '@dagrejs/graphlib'
|
|
3
|
+
const Graph = dagre.graphlib.Graph
|
|
6
4
|
|
|
7
5
|
export { Graph }
|
|
8
6
|
|
|
9
|
-
export const postorder = graphlib.alg.postorder
|
|
10
|
-
export const findCycles = graphlib.alg.findCycles
|
|
11
|
-
export const isAcyclic = graphlib.alg.isAcyclic
|
|
7
|
+
export const postorder = dagre.graphlib.alg.postorder
|
|
8
|
+
export const findCycles = dagre.graphlib.alg.findCycles
|
|
9
|
+
export const isAcyclic = dagre.graphlib.alg.isAcyclic
|
package/src/validation/index.ts
CHANGED
|
@@ -9,7 +9,6 @@ import { relationBodyChecks, relationChecks } from './relation'
|
|
|
9
9
|
import {
|
|
10
10
|
elementKindChecks,
|
|
11
11
|
modelRuleChecks,
|
|
12
|
-
modelViewsChecks,
|
|
13
12
|
relationshipChecks,
|
|
14
13
|
specificationRuleChecks,
|
|
15
14
|
tagChecks
|
|
@@ -32,7 +31,6 @@ export function registerValidationChecks(services: LikeC4Services) {
|
|
|
32
31
|
IconProperty: iconPropertyRuleChecks(services),
|
|
33
32
|
SpecificationRule: specificationRuleChecks(services),
|
|
34
33
|
Model: modelRuleChecks(services),
|
|
35
|
-
ModelViews: modelViewsChecks(services),
|
|
36
34
|
DynamicViewStep: dynamicViewStep(services),
|
|
37
35
|
LikeC4View: viewChecks(services),
|
|
38
36
|
Element: elementChecks(services),
|
|
@@ -27,17 +27,6 @@ export const modelRuleChecks = (_: LikeC4Services): ValidationCheck<ast.Model> =
|
|
|
27
27
|
}
|
|
28
28
|
}
|
|
29
29
|
|
|
30
|
-
export const modelViewsChecks = (_: LikeC4Services): ValidationCheck<ast.ModelViews> => {
|
|
31
|
-
return (node, accept) => {
|
|
32
|
-
if (node.$containerIndex && node.$containerIndex > 0) {
|
|
33
|
-
accept('warning', `Prefer one views block per document`, {
|
|
34
|
-
node: node,
|
|
35
|
-
property: 'name'
|
|
36
|
-
})
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
|
|
41
30
|
export const elementKindChecks = (services: LikeC4Services): ValidationCheck<ast.ElementKind> => {
|
|
42
31
|
const index = services.shared.workspace.IndexManager
|
|
43
32
|
return tryOrLog((node, accept) => {
|
|
@@ -17,7 +17,7 @@ export function resolveRulesExtendedViews<V extends Record<any, LikeC4View>>(
|
|
|
17
17
|
compound: false
|
|
18
18
|
})
|
|
19
19
|
for (const view of values(unresolvedViews)) {
|
|
20
|
-
g.setNode(view.id)
|
|
20
|
+
g.setNode(view.id, view.id)
|
|
21
21
|
if (isExtendsElementView(view)) {
|
|
22
22
|
// view -> parent
|
|
23
23
|
g.setEdge(view.id, view.extends)
|
|
@@ -40,7 +40,7 @@ export function resolveRulesExtendedViews<V extends Record<any, LikeC4View>>(
|
|
|
40
40
|
g.removeNode(cycledNode)
|
|
41
41
|
}
|
|
42
42
|
|
|
43
|
-
const ordered = postorder(g, g.sources())
|
|
43
|
+
const ordered = postorder(g, g.sources() as unknown as string[])
|
|
44
44
|
|
|
45
45
|
return ordered.reduce((acc, id) => {
|
|
46
46
|
const view = unresolvedViews[id]
|