@likec4/language-server 1.17.1 → 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.
Files changed (268) hide show
  1. package/contrib/likec4.tmLanguage.json +1 -1
  2. package/dist/LikeC4FileSystem.d.ts +13 -0
  3. package/dist/LikeC4FileSystem.js +27 -0
  4. package/dist/Rpc.d.ts +9 -0
  5. package/dist/Rpc.js +126 -0
  6. package/dist/ast.d.ts +200 -0
  7. package/dist/ast.js +276 -0
  8. package/dist/browser.d.ts +6 -20
  9. package/dist/browser.js +13 -0
  10. package/dist/formatting/LikeC4Formatter.d.ts +27 -0
  11. package/dist/formatting/LikeC4Formatter.js +261 -0
  12. package/dist/formatting/utils.d.ts +6 -0
  13. package/dist/formatting/utils.js +15 -0
  14. package/dist/generated/ast.d.ts +1242 -0
  15. package/dist/generated/ast.js +1945 -0
  16. package/dist/generated/grammar.d.ts +6 -0
  17. package/dist/generated/grammar.js +3 -0
  18. package/dist/generated/module.d.ts +9 -0
  19. package/dist/generated/module.js +23 -0
  20. package/dist/generated-lib/icons.d.ts +1 -0
  21. package/dist/{likec4lib.mjs → generated-lib/icons.js} +1 -6
  22. package/dist/index.d.ts +8 -31
  23. package/dist/index.js +13 -0
  24. package/dist/like-c4.langium +845 -0
  25. package/dist/likec4lib.d.ts +4 -6
  26. package/dist/likec4lib.js +4 -0
  27. package/dist/logger.d.ts +7 -0
  28. package/dist/logger.js +73 -0
  29. package/dist/lsp/CodeLensProvider.d.ts +9 -0
  30. package/dist/lsp/CodeLensProvider.js +40 -0
  31. package/dist/lsp/CompletionProvider.d.ts +6 -0
  32. package/dist/lsp/CompletionProvider.js +135 -0
  33. package/dist/lsp/DocumentHighlightProvider.d.ts +9 -0
  34. package/dist/lsp/DocumentHighlightProvider.js +10 -0
  35. package/dist/lsp/DocumentLinkProvider.d.ts +11 -0
  36. package/dist/lsp/DocumentLinkProvider.js +49 -0
  37. package/dist/lsp/DocumentSymbolProvider.d.ts +23 -0
  38. package/dist/lsp/DocumentSymbolProvider.js +202 -0
  39. package/dist/lsp/HoverProvider.d.ts +10 -0
  40. package/dist/lsp/HoverProvider.js +69 -0
  41. package/dist/lsp/RenameProvider.d.ts +5 -0
  42. package/dist/lsp/RenameProvider.js +6 -0
  43. package/dist/lsp/SemanticTokenProvider.d.ts +7 -0
  44. package/dist/lsp/SemanticTokenProvider.js +297 -0
  45. package/dist/lsp/index.d.ts +7 -0
  46. package/dist/lsp/index.js +7 -0
  47. package/dist/model/deployments-index.d.ts +60 -0
  48. package/dist/model/deployments-index.js +181 -0
  49. package/dist/model/fqn-computation.d.ts +3 -0
  50. package/dist/model/fqn-computation.js +72 -0
  51. package/dist/model/fqn-index.d.ts +25 -0
  52. package/dist/model/fqn-index.js +96 -0
  53. package/dist/model/index.d.ts +6 -0
  54. package/dist/model/index.js +6 -0
  55. package/dist/model/model-builder.d.ts +32 -0
  56. package/dist/model/model-builder.js +598 -0
  57. package/dist/model/model-locator.d.ts +23 -0
  58. package/dist/model/model-locator.js +126 -0
  59. package/dist/model/model-parser-where.d.ts +3 -0
  60. package/dist/model/model-parser-where.js +70 -0
  61. package/dist/model/model-parser.d.ts +292 -0
  62. package/dist/model/model-parser.js +72 -0
  63. package/dist/model/parser/Base.d.ts +28 -0
  64. package/dist/model/parser/Base.js +87 -0
  65. package/dist/model/parser/DeploymentModelParser.d.ts +33 -0
  66. package/dist/model/parser/DeploymentModelParser.js +162 -0
  67. package/dist/model/parser/DeploymentViewParser.d.ts +38 -0
  68. package/dist/model/parser/DeploymentViewParser.js +98 -0
  69. package/dist/model/parser/FqnRefParser.d.ts +29 -0
  70. package/dist/model/parser/FqnRefParser.js +108 -0
  71. package/dist/model/parser/GlobalsParser.d.ts +66 -0
  72. package/dist/model/parser/GlobalsParser.js +80 -0
  73. package/dist/model/parser/ModelParser.d.ts +27 -0
  74. package/dist/model/parser/ModelParser.js +122 -0
  75. package/dist/model/parser/PredicatesParser.d.ts +34 -0
  76. package/dist/model/parser/PredicatesParser.js +272 -0
  77. package/dist/model/parser/SpecificationParser.d.ts +27 -0
  78. package/dist/model/parser/SpecificationParser.js +120 -0
  79. package/dist/model/parser/ViewsParser.d.ts +64 -0
  80. package/dist/model/parser/ViewsParser.js +377 -0
  81. package/dist/model-change/ModelChanges.d.ts +15 -0
  82. package/dist/model-change/ModelChanges.js +89 -0
  83. package/dist/model-change/changeElementStyle.d.ts +16 -0
  84. package/dist/model-change/changeElementStyle.js +136 -0
  85. package/dist/model-change/changeViewLayout.d.ts +12 -0
  86. package/dist/model-change/changeViewLayout.js +32 -0
  87. package/dist/model-change/saveManualLayout.d.ts +11 -0
  88. package/dist/model-change/saveManualLayout.js +27 -0
  89. package/dist/module.d.ts +62 -0
  90. package/dist/module.js +123 -0
  91. package/dist/protocol.d.ts +27 -27
  92. package/dist/protocol.js +14 -0
  93. package/dist/references/index.d.ts +3 -0
  94. package/dist/references/index.js +3 -0
  95. package/dist/references/name-provider.d.ts +9 -0
  96. package/dist/references/name-provider.js +33 -0
  97. package/dist/references/scope-computation.d.ts +20 -0
  98. package/dist/references/scope-computation.js +281 -0
  99. package/dist/references/scope-provider.d.ts +16 -0
  100. package/dist/references/scope-provider.js +165 -0
  101. package/dist/shared/NodeKindProvider.d.ts +15 -0
  102. package/dist/shared/NodeKindProvider.js +108 -0
  103. package/dist/shared/WorkspaceManager.d.ts +18 -0
  104. package/dist/shared/WorkspaceManager.js +36 -0
  105. package/dist/shared/WorkspaceSymbolProvider.d.ts +3 -0
  106. package/dist/shared/WorkspaceSymbolProvider.js +3 -0
  107. package/dist/shared/index.d.ts +3 -0
  108. package/dist/shared/index.js +3 -0
  109. package/dist/test/index.d.ts +1 -0
  110. package/dist/test/index.js +1 -0
  111. package/dist/test/setup.d.ts +1 -0
  112. package/dist/test/setup.js +7 -0
  113. package/dist/test/testServices.d.ts +22 -0
  114. package/dist/test/testServices.js +119 -0
  115. package/dist/utils/elementRef.d.ts +11 -0
  116. package/dist/utils/elementRef.js +15 -0
  117. package/dist/utils/fqnRef.d.ts +8 -0
  118. package/dist/utils/fqnRef.js +46 -0
  119. package/dist/utils/index.d.ts +1 -0
  120. package/dist/utils/index.js +1 -0
  121. package/dist/utils/printDocs.d.ts +2 -0
  122. package/dist/utils/printDocs.js +1 -0
  123. package/dist/utils/stringHash.d.ts +1 -0
  124. package/dist/utils/stringHash.js +5 -0
  125. package/dist/validation/_shared.d.ts +3 -0
  126. package/dist/validation/_shared.js +22 -0
  127. package/dist/validation/deployment-checks.d.ts +6 -0
  128. package/dist/validation/deployment-checks.js +114 -0
  129. package/dist/validation/dynamic-view-rule.d.ts +4 -0
  130. package/dist/validation/dynamic-view-rule.js +16 -0
  131. package/dist/validation/dynamic-view-step.d.ts +4 -0
  132. package/dist/validation/dynamic-view-step.js +33 -0
  133. package/dist/validation/element.d.ts +4 -0
  134. package/dist/validation/element.js +49 -0
  135. package/dist/validation/index.d.ts +15 -0
  136. package/dist/validation/index.js +152 -0
  137. package/dist/validation/property-checks.d.ts +6 -0
  138. package/dist/validation/property-checks.js +38 -0
  139. package/dist/validation/relation.d.ts +5 -0
  140. package/dist/validation/relation.js +56 -0
  141. package/dist/validation/specification.d.ts +11 -0
  142. package/dist/validation/specification.js +136 -0
  143. package/dist/validation/view-predicates/element-with.d.ts +4 -0
  144. package/dist/validation/view-predicates/element-with.js +30 -0
  145. package/dist/validation/view-predicates/expanded-element.d.ts +4 -0
  146. package/dist/validation/view-predicates/expanded-element.js +11 -0
  147. package/dist/validation/view-predicates/expression-v2.d.ts +5 -0
  148. package/dist/validation/view-predicates/expression-v2.js +83 -0
  149. package/dist/validation/view-predicates/incoming.d.ts +4 -0
  150. package/dist/validation/view-predicates/incoming.js +15 -0
  151. package/dist/validation/view-predicates/index.d.ts +6 -0
  152. package/dist/validation/view-predicates/index.js +6 -0
  153. package/dist/validation/view-predicates/outgoing.d.ts +4 -0
  154. package/dist/validation/view-predicates/outgoing.js +15 -0
  155. package/dist/validation/view-predicates/relation-with.d.ts +4 -0
  156. package/dist/validation/view-predicates/relation-with.js +12 -0
  157. package/dist/validation/view.d.ts +4 -0
  158. package/dist/validation/view.js +23 -0
  159. package/dist/view-utils/assignNavigateTo.d.ts +2 -0
  160. package/dist/view-utils/assignNavigateTo.js +25 -0
  161. package/dist/view-utils/index.d.ts +2 -0
  162. package/dist/view-utils/index.js +2 -0
  163. package/dist/view-utils/manual-layout.d.ts +7 -0
  164. package/dist/view-utils/manual-layout.js +99 -0
  165. package/dist/view-utils/resolve-relative-paths.d.ts +2 -0
  166. package/dist/view-utils/resolve-relative-paths.js +78 -0
  167. package/package.json +42 -73
  168. package/src/LikeC4FileSystem.ts +22 -21
  169. package/src/Rpc.ts +6 -3
  170. package/src/ast.ts +136 -172
  171. package/src/browser.ts +10 -11
  172. package/src/generated/ast.ts +656 -40
  173. package/src/generated/grammar.ts +1 -1
  174. package/src/index.ts +11 -8
  175. package/src/like-c4.langium +173 -22
  176. package/src/logger.ts +41 -57
  177. package/src/lsp/CodeLensProvider.ts +0 -1
  178. package/src/lsp/CompletionProvider.ts +20 -5
  179. package/src/lsp/DocumentSymbolProvider.ts +5 -2
  180. package/src/lsp/HoverProvider.ts +37 -3
  181. package/src/lsp/SemanticTokenProvider.ts +58 -32
  182. package/src/model/deployments-index.ts +222 -0
  183. package/src/model/fqn-computation.ts +1 -1
  184. package/src/model/fqn-index.ts +0 -1
  185. package/src/model/index.ts +1 -0
  186. package/src/model/model-builder.ts +176 -39
  187. package/src/model/model-locator.ts +36 -7
  188. package/src/model/model-parser.ts +69 -1119
  189. package/src/model/parser/Base.ts +107 -0
  190. package/src/model/parser/DeploymentModelParser.ts +192 -0
  191. package/src/model/parser/DeploymentViewParser.ts +116 -0
  192. package/src/model/parser/FqnRefParser.ts +118 -0
  193. package/src/model/parser/GlobalsParser.ts +96 -0
  194. package/src/model/parser/ModelParser.ts +141 -0
  195. package/src/model/parser/PredicatesParser.ts +291 -0
  196. package/src/model/parser/SpecificationParser.ts +133 -0
  197. package/src/model/parser/ViewsParser.ts +428 -0
  198. package/src/model-change/changeViewLayout.ts +2 -2
  199. package/src/module.ts +26 -21
  200. package/src/protocol.ts +10 -6
  201. package/src/references/index.ts +1 -0
  202. package/src/references/name-provider.ts +37 -0
  203. package/src/references/scope-computation.ts +130 -21
  204. package/src/references/scope-provider.ts +68 -35
  205. package/src/shared/NodeKindProvider.ts +15 -3
  206. package/src/{elementRef.ts → utils/elementRef.ts} +1 -1
  207. package/src/utils/fqnRef.ts +56 -0
  208. package/src/utils/stringHash.ts +2 -2
  209. package/src/validation/_shared.ts +6 -5
  210. package/src/validation/deployment-checks.ts +131 -0
  211. package/src/validation/dynamic-view-step.ts +1 -1
  212. package/src/validation/index.ts +104 -6
  213. package/src/validation/relation.ts +1 -1
  214. package/src/validation/view-predicates/expression-v2.ts +101 -0
  215. package/src/validation/view-predicates/index.ts +1 -0
  216. package/src/view-utils/assignNavigateTo.ts +6 -5
  217. package/src/view-utils/index.ts +0 -1
  218. package/src/view-utils/manual-layout.ts +25 -0
  219. package/dist/browser.cjs +0 -25
  220. package/dist/browser.d.cts +0 -23
  221. package/dist/browser.d.mts +0 -23
  222. package/dist/browser.mjs +0 -20
  223. package/dist/index.cjs +0 -53
  224. package/dist/index.d.cts +0 -34
  225. package/dist/index.d.mts +0 -34
  226. package/dist/index.mjs +0 -46
  227. package/dist/likec4lib.cjs +0 -1546
  228. package/dist/likec4lib.d.cts +0 -6
  229. package/dist/likec4lib.d.mts +0 -6
  230. package/dist/model-graph/index.cjs +0 -10
  231. package/dist/model-graph/index.d.cts +0 -81
  232. package/dist/model-graph/index.d.mts +0 -81
  233. package/dist/model-graph/index.d.ts +0 -81
  234. package/dist/model-graph/index.mjs +0 -1
  235. package/dist/protocol.cjs +0 -25
  236. package/dist/protocol.d.cts +0 -45
  237. package/dist/protocol.d.mts +0 -45
  238. package/dist/protocol.mjs +0 -17
  239. package/dist/shared/language-server.BIbAD1T-.mjs +0 -6292
  240. package/dist/shared/language-server.BQRvVmE0.d.cts +0 -1303
  241. package/dist/shared/language-server.BysPcTxr.d.ts +0 -1303
  242. package/dist/shared/language-server.D2QdbOJO.cjs +0 -1995
  243. package/dist/shared/language-server.DGrBGmsd.mjs +0 -1981
  244. package/dist/shared/language-server.DKV_FdPN.cjs +0 -6304
  245. package/dist/shared/language-server._wkyPgso.d.mts +0 -1303
  246. package/src/model-graph/LikeC4ModelGraph.ts +0 -338
  247. package/src/model-graph/compute-view/__test__/fixture.ts +0 -630
  248. package/src/model-graph/compute-view/compute.ts +0 -788
  249. package/src/model-graph/compute-view/index.ts +0 -33
  250. package/src/model-graph/compute-view/predicates.ts +0 -509
  251. package/src/model-graph/dynamic-view/__test__/fixture.ts +0 -61
  252. package/src/model-graph/dynamic-view/compute.ts +0 -313
  253. package/src/model-graph/dynamic-view/index.ts +0 -29
  254. package/src/model-graph/index.ts +0 -3
  255. package/src/model-graph/utils/applyCustomElementProperties.ts +0 -65
  256. package/src/model-graph/utils/applyCustomRelationProperties.ts +0 -41
  257. package/src/model-graph/utils/applyViewRuleStyles.ts +0 -49
  258. package/src/model-graph/utils/buildComputeNodes.ts +0 -113
  259. package/src/model-graph/utils/buildElementNotations.ts +0 -63
  260. package/src/model-graph/utils/elementExpressionToPredicate.ts +0 -39
  261. package/src/model-graph/utils/relationExpressionToPredicates.ts +0 -43
  262. package/src/model-graph/utils/sortNodes.ts +0 -105
  263. package/src/model-graph/utils/uniqueTags.test.ts +0 -42
  264. package/src/model-graph/utils/uniqueTags.ts +0 -19
  265. package/src/utils/graphlib.ts +0 -9
  266. package/src/view-utils/resolve-extended-views.ts +0 -66
  267. package/src/view-utils/resolve-global-rules.ts +0 -88
  268. package/src/view-utils/view-hash.ts +0 -27
@@ -0,0 +1,152 @@
1
+ import { isNullish } from "remeda";
2
+ import { DiagnosticSeverity } from "vscode-languageserver-types";
3
+ import { ast } from "../ast.js";
4
+ import { logger } from "../logger.js";
5
+ import { deployedInstanceChecks, deploymentNodeChecks, deploymentRelationChecks } from "./deployment-checks.js";
6
+ import { dynamicViewRulePredicate } from "./dynamic-view-rule.js";
7
+ import { dynamicViewStep } from "./dynamic-view-step.js";
8
+ import { elementChecks } from "./element.js";
9
+ import { iconPropertyRuleChecks, notesPropertyRuleChecks, opacityPropertyRuleChecks } from "./property-checks.js";
10
+ import { relationBodyChecks, relationChecks } from "./relation.js";
11
+ import {
12
+ elementKindChecks,
13
+ globalPredicateChecks,
14
+ globalsChecks,
15
+ globalStyleIdChecks,
16
+ modelRuleChecks,
17
+ relationshipChecks,
18
+ specificationRuleChecks,
19
+ tagChecks
20
+ } from "./specification.js";
21
+ import { viewChecks } from "./view.js";
22
+ import {
23
+ elementPredicateWithChecks,
24
+ expandElementExprChecks,
25
+ fqnRefExprChecks,
26
+ incomingExpressionChecks,
27
+ outgoingExpressionChecks,
28
+ relationExprChecks,
29
+ relationPredicateWithChecks
30
+ } from "./view-predicates/index.js";
31
+ function validatableAstNodeGuards(predicates) {
32
+ return (n) => predicates.some((p) => p(n));
33
+ }
34
+ const isValidatableAstNode = validatableAstNodeGuards([
35
+ ast.isGlobals,
36
+ ast.isGlobalPredicateGroup,
37
+ ast.isGlobalDynamicPredicateGroup,
38
+ ast.isGlobalStyle,
39
+ ast.isGlobalStyleGroup,
40
+ ast.isDynamicViewPredicateIterator,
41
+ ast.isElementPredicateWith,
42
+ ast.isRelationPredicateWith,
43
+ ast.isElementExpression,
44
+ ast.isRelationExpression,
45
+ ast.isDynamicViewParallelSteps,
46
+ ast.isDynamicViewStep,
47
+ ast.isDeploymentViewRule,
48
+ ast.isDeploymentViewRulePredicate,
49
+ ast.isExpressionV2,
50
+ ast.isRelationExpr,
51
+ ast.isFqnRefExpr,
52
+ ast.isViewProperty,
53
+ ast.isStyleProperty,
54
+ ast.isPredicate,
55
+ ast.isTags,
56
+ ast.isViewRule,
57
+ ast.isDynamicViewRule,
58
+ ast.isLikeC4View,
59
+ ast.isViewRuleStyleOrGlobalRef,
60
+ ast.isDeployedInstance,
61
+ ast.isDeploymentNode,
62
+ ast.isDeploymentRelation,
63
+ ast.isRelationshipStyleProperty,
64
+ ast.isMetadataProperty,
65
+ ast.isRelation,
66
+ ast.isElementProperty,
67
+ ast.isStringProperty,
68
+ ast.isNavigateToProperty,
69
+ ast.isElement,
70
+ ast.isExtendElement,
71
+ ast.isSpecificationElementKind,
72
+ ast.isSpecificationRelationshipKind,
73
+ ast.isSpecificationDeploymentNodeKind,
74
+ ast.isSpecificationTag,
75
+ ast.isSpecificationColor,
76
+ ast.isSpecificationRule
77
+ ]);
78
+ const findInvalidContainer = (node) => {
79
+ let nd = node;
80
+ while (nd && !ast.isLikeC4Grammar(nd)) {
81
+ if (isValidatableAstNode(nd)) {
82
+ return nd;
83
+ }
84
+ nd = nd.$container;
85
+ }
86
+ return void 0;
87
+ };
88
+ export function checksFromDiagnostics(doc) {
89
+ const errors = doc.diagnostics?.filter((d) => d.severity === DiagnosticSeverity.Error) ?? [];
90
+ const invalidNodes = /* @__PURE__ */ new WeakSet();
91
+ for (const { node } of errors) {
92
+ if (isNullish(node) || invalidNodes.has(node)) {
93
+ continue;
94
+ }
95
+ invalidNodes.add(node);
96
+ const container = findInvalidContainer(node);
97
+ if (container) {
98
+ invalidNodes.add(container);
99
+ }
100
+ }
101
+ const isValid = (n) => !invalidNodes.has(n);
102
+ return {
103
+ isValid,
104
+ invalidNodes
105
+ };
106
+ }
107
+ export function registerValidationChecks(services) {
108
+ logger.debug("registerValidationChecks");
109
+ const registry = services.validation.ValidationRegistry;
110
+ registry.register({
111
+ DeployedInstance: deployedInstanceChecks(services),
112
+ DeploymentNode: deploymentNodeChecks(services),
113
+ DeploymentRelation: deploymentRelationChecks(services),
114
+ FqnRefExpr: fqnRefExprChecks(services),
115
+ RelationExpr: relationExprChecks(services),
116
+ NotesProperty: notesPropertyRuleChecks(services),
117
+ OpacityProperty: opacityPropertyRuleChecks(services),
118
+ IconProperty: iconPropertyRuleChecks(services),
119
+ SpecificationRule: specificationRuleChecks(services),
120
+ Model: modelRuleChecks(services),
121
+ Globals: globalsChecks(services),
122
+ GlobalPredicateGroup: globalPredicateChecks(services),
123
+ GlobalDynamicPredicateGroup: globalPredicateChecks(services),
124
+ GlobalStyleId: globalStyleIdChecks(services),
125
+ DynamicViewStep: dynamicViewStep(services),
126
+ LikeC4View: viewChecks(services),
127
+ Element: elementChecks(services),
128
+ ElementKind: elementKindChecks(services),
129
+ Relation: relationChecks(services),
130
+ RelationBody: relationBodyChecks(services),
131
+ Tag: tagChecks(services),
132
+ DynamicViewPredicateIterator: dynamicViewRulePredicate(services),
133
+ ElementPredicateWith: elementPredicateWithChecks(services),
134
+ RelationPredicateWith: relationPredicateWithChecks(services),
135
+ ExpandElementExpression: expandElementExprChecks(services),
136
+ RelationshipKind: relationshipChecks(services),
137
+ IncomingRelationExpression: incomingExpressionChecks(services),
138
+ OutgoingRelationExpression: outgoingExpressionChecks(services)
139
+ });
140
+ const connection = services.shared.lsp.Connection;
141
+ if (connection) {
142
+ services.shared.workspace.DocumentBuilder.onUpdate((_, deleted) => {
143
+ for (const uri of deleted) {
144
+ logger.debug(`clear diagnostics for deleted ${uri.path}`);
145
+ void connection.sendDiagnostics({
146
+ uri: uri.toString(),
147
+ diagnostics: []
148
+ });
149
+ }
150
+ });
151
+ }
152
+ }
@@ -0,0 +1,6 @@
1
+ import { type ValidationCheck } from 'langium';
2
+ import { ast } from '../ast';
3
+ import type { LikeC4Services } from '../module';
4
+ export declare const opacityPropertyRuleChecks: (_: LikeC4Services) => ValidationCheck<ast.OpacityProperty>;
5
+ export declare const iconPropertyRuleChecks: (_: LikeC4Services) => ValidationCheck<ast.IconProperty>;
6
+ export declare const notesPropertyRuleChecks: (_: LikeC4Services) => ValidationCheck<ast.NotesProperty>;
@@ -0,0 +1,38 @@
1
+ import { AstUtils } from "langium";
2
+ import { ast } from "../ast.js";
3
+ export const opacityPropertyRuleChecks = (_) => {
4
+ return (node, accept) => {
5
+ const opacity = parseFloat(node.value);
6
+ if (isNaN(opacity) || opacity < 0 || opacity > 100) {
7
+ accept("warning", `Value ignored, must be between 0% and 100%`, {
8
+ node,
9
+ property: "value"
10
+ });
11
+ }
12
+ };
13
+ };
14
+ export const iconPropertyRuleChecks = (_) => {
15
+ return (node, accept) => {
16
+ const container = node.$container;
17
+ const anotherIcon = container.props.some((p) => ast.isIconProperty(p) && p !== node);
18
+ if (anotherIcon) {
19
+ accept("error", `Icon must be defined once`, {
20
+ node
21
+ });
22
+ }
23
+ if (ast.isElementStyleProperty(container) && ast.isElementBody(container.$container) && container.$container.props.some((p) => ast.isIconProperty(p))) {
24
+ accept("warning", `Redundant as icon defined on element`, {
25
+ node
26
+ });
27
+ }
28
+ };
29
+ };
30
+ export const notesPropertyRuleChecks = (_) => {
31
+ return (node, accept) => {
32
+ if (!AstUtils.hasContainerOfType(node, ast.isDynamicViewStep)) {
33
+ accept("error", `Notes can be defined only inside dynamic view`, {
34
+ node
35
+ });
36
+ }
37
+ };
38
+ };
@@ -0,0 +1,5 @@
1
+ import type { ValidationCheck } from 'langium';
2
+ import { ast } from '../ast';
3
+ import type { LikeC4Services } from '../module';
4
+ export declare const relationChecks: (services: LikeC4Services) => ValidationCheck<ast.Relation>;
5
+ export declare const relationBodyChecks: (_services: LikeC4Services) => ValidationCheck<ast.RelationBody>;
@@ -0,0 +1,56 @@
1
+ import { isSameHierarchy } from "@likec4/core";
2
+ import { isDefined } from "remeda";
3
+ import { ast } from "../ast.js";
4
+ import { elementRef } from "../utils/elementRef.js";
5
+ import { tryOrLog } from "./_shared.js";
6
+ export const relationChecks = (services) => {
7
+ const fqnIndex = services.likec4.FqnIndex;
8
+ return tryOrLog((el, accept) => {
9
+ const targetEl = elementRef(el.target);
10
+ const target = targetEl && fqnIndex.getFqn(targetEl);
11
+ if (!target) {
12
+ accept("error", "Target not resolved", {
13
+ node: el,
14
+ property: "target"
15
+ });
16
+ }
17
+ let sourceEl;
18
+ if (isDefined(el.source)) {
19
+ sourceEl = elementRef(el.source);
20
+ if (!sourceEl) {
21
+ return accept("error", "Source not resolved", {
22
+ node: el,
23
+ property: "source"
24
+ });
25
+ }
26
+ } else {
27
+ if (!ast.isElementBody(el.$container)) {
28
+ return accept("error", "Sourceless relation must be nested", {
29
+ node: el
30
+ });
31
+ }
32
+ sourceEl = el.$container.$container;
33
+ }
34
+ const source = fqnIndex.getFqn(sourceEl);
35
+ if (!source) {
36
+ accept("error", "Source not resolved", {
37
+ node: el
38
+ });
39
+ }
40
+ if (source && target && isSameHierarchy(source, target)) {
41
+ accept("error", "Invalid parent-child relationship", {
42
+ node: el
43
+ });
44
+ }
45
+ });
46
+ };
47
+ export const relationBodyChecks = (_services) => {
48
+ return tryOrLog((body, accept) => {
49
+ const relation = body.$container;
50
+ if (relation.tags?.values && body.tags?.values) {
51
+ accept("error", "Relation cannot have tags in both header and body", {
52
+ node: body.tags
53
+ });
54
+ }
55
+ });
56
+ };
@@ -0,0 +1,11 @@
1
+ import { type ValidationCheck } from 'langium';
2
+ import { ast } from '../ast';
3
+ import type { LikeC4Services } from '../module';
4
+ export declare const specificationRuleChecks: (_: LikeC4Services) => ValidationCheck<ast.SpecificationRule>;
5
+ export declare const modelRuleChecks: (_: LikeC4Services) => ValidationCheck<ast.Model>;
6
+ export declare const globalsChecks: (_: LikeC4Services) => ValidationCheck<ast.Globals>;
7
+ export declare const elementKindChecks: (services: LikeC4Services) => ValidationCheck<ast.ElementKind>;
8
+ export declare const tagChecks: (services: LikeC4Services) => ValidationCheck<ast.Tag>;
9
+ export declare const relationshipChecks: (services: LikeC4Services) => ValidationCheck<ast.RelationshipKind>;
10
+ export declare const globalPredicateChecks: (services: LikeC4Services) => ValidationCheck<ast.GlobalPredicateGroup | ast.GlobalDynamicPredicateGroup>;
11
+ export declare const globalStyleIdChecks: (services: LikeC4Services) => ValidationCheck<ast.GlobalStyleId>;
@@ -0,0 +1,136 @@
1
+ import { AstUtils } from "langium";
2
+ import { ast } from "../ast.js";
3
+ import { RESERVED_WORDS, tryOrLog } from "./_shared.js";
4
+ export const specificationRuleChecks = (_) => {
5
+ return (node, accept) => {
6
+ if (node.$containerIndex && node.$containerIndex > 0) {
7
+ accept("warning", `Prefer one specification per document`, {
8
+ node,
9
+ property: "name"
10
+ });
11
+ }
12
+ };
13
+ };
14
+ export const modelRuleChecks = (_) => {
15
+ return (node, accept) => {
16
+ if (node.$containerIndex && node.$containerIndex > 0) {
17
+ accept("warning", `Prefer one model per document`, {
18
+ node,
19
+ property: "name"
20
+ });
21
+ }
22
+ };
23
+ };
24
+ export const globalsChecks = (_) => {
25
+ return (node, accept) => {
26
+ if (node.$containerIndex && node.$containerIndex > 0) {
27
+ accept("warning", `Prefer one global block per document`, {
28
+ node,
29
+ property: "name"
30
+ });
31
+ }
32
+ };
33
+ };
34
+ export const elementKindChecks = (services) => {
35
+ const index = services.shared.workspace.IndexManager;
36
+ return tryOrLog((node, accept) => {
37
+ if (RESERVED_WORDS.includes(node.name)) {
38
+ accept("error", `Reserved word: ${node.name}`, {
39
+ node,
40
+ property: "name"
41
+ });
42
+ }
43
+ const sameKind = index.allElements(ast.ElementKind).filter((n) => n.name === node.name && n.node !== node).head();
44
+ if (sameKind) {
45
+ const isAnotherDoc = sameKind.documentUri !== AstUtils.getDocument(node).uri;
46
+ accept("error", `Duplicate element kind '${node.name}'`, {
47
+ node,
48
+ property: "name",
49
+ ...isAnotherDoc && {
50
+ relatedInformation: [
51
+ {
52
+ location: {
53
+ range: sameKind.nameSegment.range,
54
+ uri: sameKind.documentUri.toString()
55
+ },
56
+ message: `conflicting definition`
57
+ }
58
+ ]
59
+ }
60
+ });
61
+ }
62
+ });
63
+ };
64
+ export const tagChecks = (services) => {
65
+ const index = services.shared.workspace.IndexManager;
66
+ return (node, accept) => {
67
+ const tagname = "#" + node.name;
68
+ const sameTag = index.allElements(ast.Tag).filter((n) => n.name === tagname && n.node !== node).head();
69
+ if (sameTag) {
70
+ const isAnotherDoc = sameTag.documentUri !== AstUtils.getDocument(node).uri;
71
+ accept(
72
+ "error",
73
+ `Duplicate tag '${node.name}'`,
74
+ {
75
+ node,
76
+ property: "name",
77
+ ...isAnotherDoc && {
78
+ relatedInformation: [
79
+ {
80
+ location: {
81
+ range: sameTag.nameSegment.range,
82
+ uri: sameTag.documentUri.toString()
83
+ },
84
+ message: `conflicting definition`
85
+ }
86
+ ]
87
+ }
88
+ }
89
+ );
90
+ }
91
+ };
92
+ };
93
+ export const relationshipChecks = (services) => {
94
+ const index = services.shared.workspace.IndexManager;
95
+ return (node, accept) => {
96
+ if (RESERVED_WORDS.includes(node.name)) {
97
+ accept("error", `Reserved word: ${node.name}`, {
98
+ node,
99
+ property: "name"
100
+ });
101
+ }
102
+ const sameKinds = index.allElements(ast.RelationshipKind).filter((n) => n.name === node.name).limit(2).count();
103
+ if (sameKinds > 1) {
104
+ accept("error", `Duplicate RelationshipKind '${node.name}'`, {
105
+ node,
106
+ property: "name"
107
+ });
108
+ }
109
+ };
110
+ };
111
+ export const globalPredicateChecks = (services) => {
112
+ const index = services.shared.workspace.IndexManager;
113
+ return (node, accept) => {
114
+ const predicateGroups = index.allElements(ast.GlobalPredicateGroup);
115
+ const dynamicPredicateGroups = index.allElements(ast.GlobalDynamicPredicateGroup);
116
+ const sameName = predicateGroups.concat(dynamicPredicateGroups).filter((s) => s.name === node.name).limit(2).count();
117
+ if (sameName > 1) {
118
+ accept("error", `Duplicate GlobalPredicateGroup or GlobalDynamicPredicateGroup name '${node.name}'`, {
119
+ node,
120
+ property: "name"
121
+ });
122
+ }
123
+ };
124
+ };
125
+ export const globalStyleIdChecks = (services) => {
126
+ const index = services.shared.workspace.IndexManager;
127
+ return (node, accept) => {
128
+ const sameName = index.allElements(ast.GlobalStyleId).filter((s) => s.name === node.name).limit(2).count();
129
+ if (sameName > 1) {
130
+ accept("error", `Duplicate GlobalStyleId name '${node.name}'`, {
131
+ node,
132
+ property: "name"
133
+ });
134
+ }
135
+ };
136
+ };
@@ -0,0 +1,4 @@
1
+ import type { ValidationCheck } from 'langium';
2
+ import { ast } from '../../ast';
3
+ import type { LikeC4Services } from '../../module';
4
+ export declare const elementPredicateWithChecks: (_services: LikeC4Services) => ValidationCheck<ast.ElementPredicateWith>;
@@ -0,0 +1,30 @@
1
+ import { nonexhaustive } from "@likec4/core";
2
+ import { AstUtils } from "langium";
3
+ import { ast } from "../../ast.js";
4
+ export const elementPredicateWithChecks = (_services) => {
5
+ return (el, accept) => {
6
+ const container = AstUtils.getContainerOfType(el, ast.isViewRulePredicate);
7
+ if (ast.isExcludePredicate(container)) {
8
+ accept("error", 'Invalid usage inside "exclude"', {
9
+ node: el
10
+ });
11
+ }
12
+ const subject = ast.isElementPredicateWhere(el.subject) ? el.subject.subject : el.subject;
13
+ switch (true) {
14
+ case ast.isElementRef(subject):
15
+ case ast.isElementDescedantsExpression(subject):
16
+ case ast.isExpandElementExpression(subject):
17
+ case ast.isWildcardExpression(subject):
18
+ return;
19
+ case ast.isElementKindExpression(subject):
20
+ case ast.isElementTagExpression(subject):
21
+ accept("error", "Invalid target (expect reference to specific element)", {
22
+ node: el,
23
+ property: "subject"
24
+ });
25
+ return;
26
+ default:
27
+ nonexhaustive(subject);
28
+ }
29
+ };
30
+ };
@@ -0,0 +1,4 @@
1
+ import { type ValidationCheck } from 'langium';
2
+ import { ast } from '../../ast';
3
+ import type { LikeC4Services } from '../../module';
4
+ export declare const expandElementExprChecks: (_services: LikeC4Services) => ValidationCheck<ast.ExpandElementExpression>;
@@ -0,0 +1,11 @@
1
+ import { AstUtils } from "langium";
2
+ import { ast } from "../../ast.js";
3
+ export const expandElementExprChecks = (_services) => {
4
+ return (el, accept) => {
5
+ if (AstUtils.hasContainerOfType(el, ast.isRelationExpression)) {
6
+ accept("warning", `Redundant usage, expand predicate resolves parent element only when used in relations`, {
7
+ node: el
8
+ });
9
+ }
10
+ };
11
+ };
@@ -0,0 +1,5 @@
1
+ import { type ValidationCheck } from 'langium';
2
+ import { ast } from '../../ast';
3
+ import type { LikeC4Services } from '../../module';
4
+ export declare const relationExprChecks: (services: LikeC4Services) => ValidationCheck<ast.RelationExpr>;
5
+ export declare const fqnRefExprChecks: (services: LikeC4Services) => ValidationCheck<ast.FqnRefExpr>;
@@ -0,0 +1,83 @@
1
+ import { FqnExpr, FqnRef } from "@likec4/core";
2
+ import { AstUtils } from "langium";
3
+ import { isNonNullish, isNullish } from "remeda";
4
+ import { ast } from "../../ast.js";
5
+ import { tryOrLog } from "../_shared.js";
6
+ export const relationExprChecks = (services) => {
7
+ const ModelParser = services.likec4.ModelParser;
8
+ return tryOrLog((node, accept) => {
9
+ if (node.$container.$type !== "DeploymentViewRulePredicateExpression") {
10
+ return;
11
+ }
12
+ const predicate = AstUtils.getContainerOfType(node, ast.isDeploymentViewRulePredicate);
13
+ if (!predicate || predicate.isInclude !== true) {
14
+ return;
15
+ }
16
+ const doc = AstUtils.getDocument(node);
17
+ const parser = ModelParser.forDocument(doc);
18
+ const ModelRefOnlyExclude = "Model reference is allowed in exclude predicate only";
19
+ if (ast.isDirectedRelationExpr(node)) {
20
+ if (FqnExpr.isModelRef(parser.parseFqnExpr(node.source.from))) {
21
+ accept("error", ModelRefOnlyExclude, {
22
+ node: node.source,
23
+ property: "from"
24
+ });
25
+ }
26
+ if (FqnExpr.isModelRef(parser.parseFqnExpr(node.target))) {
27
+ accept("error", ModelRefOnlyExclude, {
28
+ node,
29
+ property: "target"
30
+ });
31
+ }
32
+ return;
33
+ }
34
+ let expr;
35
+ if (ast.isIncomingRelationExpr(node)) {
36
+ expr = node.to;
37
+ } else if (ast.isOutgoingRelationExpr(node)) {
38
+ expr = node.from;
39
+ } else {
40
+ expr = node.inout.to;
41
+ }
42
+ if (FqnExpr.isModelRef(parser.parseFqnExpr(expr))) {
43
+ accept("error", ModelRefOnlyExclude, {
44
+ node
45
+ });
46
+ return;
47
+ }
48
+ });
49
+ };
50
+ export const fqnRefExprChecks = (services) => {
51
+ const ModelParser = services.likec4.ModelParser;
52
+ return tryOrLog((node, accept) => {
53
+ const referenceTo = node.ref.value.ref;
54
+ if (isNullish(referenceTo)) {
55
+ accept("error", "Invalid empty reference", {
56
+ node
57
+ });
58
+ return;
59
+ }
60
+ const doc = AstUtils.getDocument(node);
61
+ const expr = ModelParser.forDocument(doc).parseFqnRefExpr(node);
62
+ if (node.$container.$type === "DeploymentViewRulePredicateExpression") {
63
+ if (FqnExpr.isModelRef(expr)) {
64
+ accept("error", "Deployment view predicate must reference deployment model", {
65
+ node
66
+ });
67
+ return;
68
+ }
69
+ if (FqnExpr.isDeploymentRef(expr) && FqnRef.isInsideInstanceRef(expr.ref)) {
70
+ accept("error", "Must reference deployment nodes or instances, but not internals", {
71
+ node
72
+ });
73
+ return;
74
+ }
75
+ }
76
+ if (!ast.isDeploymentNode(referenceTo) && isNonNullish(node.selector)) {
77
+ accept("warning", `Selector '${node.selector}' applies to deployment nodes only, ignored here`, {
78
+ node,
79
+ property: "selector"
80
+ });
81
+ }
82
+ });
83
+ };
@@ -0,0 +1,4 @@
1
+ import { type ValidationCheck } from 'langium';
2
+ import { ast } from '../../ast';
3
+ import type { LikeC4Services } from '../../module';
4
+ export declare const incomingExpressionChecks: (_services: LikeC4Services) => ValidationCheck<ast.IncomingRelationExpression>;
@@ -0,0 +1,15 @@
1
+ import { AstUtils } from "langium";
2
+ import { isNullish } from "remeda";
3
+ import { ast } from "../../ast.js";
4
+ export const incomingExpressionChecks = (_services) => {
5
+ return (el, accept) => {
6
+ if (ast.isWildcardExpression(el.to) && !ast.isInOutRelationExpression(el.$container)) {
7
+ const view = AstUtils.getContainerOfType(el, ast.isElementView);
8
+ if (isNullish(view?.viewOf)) {
9
+ accept("warning", "Predicate is ignored as it concerns all relationships", {
10
+ node: el
11
+ });
12
+ }
13
+ }
14
+ };
15
+ };
@@ -0,0 +1,6 @@
1
+ export * from './element-with';
2
+ export * from './expanded-element';
3
+ export * from './expression-v2';
4
+ export * from './incoming';
5
+ export * from './outgoing';
6
+ export * from './relation-with';
@@ -0,0 +1,6 @@
1
+ export * from "./element-with.js";
2
+ export * from "./expanded-element.js";
3
+ export * from "./expression-v2.js";
4
+ export * from "./incoming.js";
5
+ export * from "./outgoing.js";
6
+ export * from "./relation-with.js";
@@ -0,0 +1,4 @@
1
+ import { type ValidationCheck } from 'langium';
2
+ import { ast } from '../../ast';
3
+ import type { LikeC4Services } from '../../module';
4
+ export declare const outgoingExpressionChecks: (_services: LikeC4Services) => ValidationCheck<ast.OutgoingRelationExpression>;
@@ -0,0 +1,15 @@
1
+ import { AstUtils } from "langium";
2
+ import { isNullish } from "remeda";
3
+ import { ast } from "../../ast.js";
4
+ export const outgoingExpressionChecks = (_services) => {
5
+ return (el, accept) => {
6
+ if (ast.isWildcardExpression(el.from) && !ast.isDirectedRelationExpression(el.$container)) {
7
+ const view = AstUtils.getContainerOfType(el, ast.isElementView);
8
+ if (isNullish(view?.viewOf)) {
9
+ accept("warning", "Predicate is ignored as it concerns all relationships", {
10
+ node: el
11
+ });
12
+ }
13
+ }
14
+ };
15
+ };
@@ -0,0 +1,4 @@
1
+ import { type ValidationCheck } from 'langium';
2
+ import { ast } from '../../ast';
3
+ import type { LikeC4Services } from '../../module';
4
+ export declare const relationPredicateWithChecks: (_services: LikeC4Services) => ValidationCheck<ast.RelationPredicateWith>;
@@ -0,0 +1,12 @@
1
+ import { AstUtils } from "langium";
2
+ import { ast } from "../../ast.js";
3
+ export const relationPredicateWithChecks = (_services) => {
4
+ return (el, accept) => {
5
+ const container = AstUtils.getContainerOfType(el, ast.isViewRulePredicate);
6
+ if (ast.isExcludePredicate(container)) {
7
+ accept("error", 'Invalid usage inside "exclude"', {
8
+ node: el
9
+ });
10
+ }
11
+ };
12
+ };
@@ -0,0 +1,4 @@
1
+ import { type ValidationCheck } from 'langium';
2
+ import { ast } from '../ast';
3
+ import type { LikeC4Services } from '../module';
4
+ export declare const viewChecks: (services: LikeC4Services) => ValidationCheck<ast.LikeC4View>;
@@ -0,0 +1,23 @@
1
+ import { ast } from "../ast.js";
2
+ import { RESERVED_WORDS } from "./_shared.js";
3
+ export const viewChecks = (services) => {
4
+ const index = services.shared.workspace.IndexManager;
5
+ return (el, accept) => {
6
+ if (!el.name) {
7
+ return;
8
+ }
9
+ if (RESERVED_WORDS.includes(el.name)) {
10
+ accept("error", `Reserved word: ${el.name}`, {
11
+ node: el,
12
+ property: "name"
13
+ });
14
+ }
15
+ const anotherViews = index.allElements(ast.LikeC4View).filter((n) => n.name === el.name).limit(2).count();
16
+ if (anotherViews > 1) {
17
+ accept("error", `Duplicate view '${el.name}'`, {
18
+ node: el,
19
+ property: "name"
20
+ });
21
+ }
22
+ };
23
+ };
@@ -0,0 +1,2 @@
1
+ import { ComputedView } from '@likec4/core';
2
+ export declare function assignNavigateTo<R extends Iterable<ComputedView>>(views: R): R;