@likec4/language-server 1.43.0 → 1.44.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/browser/package.json +1 -1
- package/browser-worker/package.json +1 -1
- package/dist/LikeC4LanguageServices.d.ts +12 -19
- package/dist/LikeC4LanguageServices.js +182 -0
- package/dist/Rpc.js +245 -0
- package/dist/ast.d.ts +5 -1
- package/dist/ast.js +253 -0
- package/dist/browser-worker.js +4 -0
- package/dist/browser.js +35 -0
- package/dist/bundled.js +42 -0
- package/dist/bundled.mjs +3542 -3896
- package/dist/documentation/documentation-provider.js +51 -0
- package/dist/documentation/index.js +1 -0
- package/dist/empty.js +2 -0
- package/dist/filesystem/ChokidarWatcher.js +97 -0
- package/dist/filesystem/FileSystemWatcher.js +14 -0
- package/dist/filesystem/LikeC4FileSystem.d.ts +1 -2
- package/dist/filesystem/LikeC4FileSystem.js +126 -0
- package/dist/filesystem/index.d.ts +26 -0
- package/dist/filesystem/index.js +29 -0
- package/dist/formatting/LikeC4Formatter.js +637 -0
- package/dist/formatting/utils.js +18 -0
- package/dist/generated/ast.js +2155 -0
- package/dist/generated/{grammar.mjs → grammar.js} +6 -2
- package/dist/generated/module.d.ts +6 -1
- package/dist/generated/module.js +27 -0
- package/dist/generated-lib/{icons.mjs → icons.js} +11 -7
- package/dist/index.d.ts +7 -0
- package/dist/index.js +53 -0
- package/dist/{likec4lib.mjs → likec4lib.js} +3 -3
- package/dist/logger.js +81 -0
- package/dist/lsp/CodeActionProvider.d.ts +14 -0
- package/dist/lsp/CodeActionProvider.js +33 -0
- package/dist/lsp/CodeLensProvider.js +44 -0
- package/dist/lsp/CompletionProvider.d.ts +3 -1
- package/dist/lsp/CompletionProvider.js +200 -0
- package/dist/lsp/DocumentHighlightProvider.js +10 -0
- package/dist/lsp/DocumentLinkProvider.js +58 -0
- package/dist/lsp/DocumentSymbolProvider.js +306 -0
- package/dist/lsp/HoverProvider.js +106 -0
- package/dist/lsp/RenameProvider.js +6 -0
- package/dist/lsp/SemanticTokenProvider.js +257 -0
- package/dist/lsp/index.d.ts +1 -0
- package/dist/lsp/index.js +9 -0
- package/dist/mcp/MCPServerFactory.js +73 -0
- package/dist/mcp/NoopLikeC4MCPServer.js +17 -0
- package/dist/mcp/interfaces.js +5 -0
- package/dist/mcp/server/StdioLikeC4MCPServer.js +47 -0
- package/dist/mcp/server/StreamableLikeC4MCPServer.js +145 -0
- package/dist/mcp/server/WithMCPServer.js +56 -0
- package/dist/mcp/tools/_common.d.ts +8 -7
- package/dist/mcp/tools/_common.js +49 -0
- package/dist/mcp/tools/find-relationships.d.ts +7 -8
- package/dist/mcp/tools/find-relationships.js +150 -0
- package/dist/mcp/tools/list-projects.d.ts +3 -3
- package/dist/mcp/tools/list-projects.js +62 -0
- package/dist/mcp/tools/open-view.d.ts +6 -7
- package/dist/mcp/tools/open-view.js +52 -0
- package/dist/mcp/tools/read-deployment.d.ts +6 -7
- package/dist/mcp/tools/read-deployment.js +132 -0
- package/dist/mcp/tools/read-element.d.ts +6 -7
- package/dist/mcp/tools/read-element.js +194 -0
- package/dist/mcp/tools/read-project-summary.d.ts +5 -6
- package/dist/mcp/tools/read-project-summary.js +176 -0
- package/dist/mcp/tools/read-view.d.ts +6 -7
- package/dist/mcp/tools/read-view.js +203 -0
- package/dist/mcp/tools/search-element.d.ts +3 -3
- package/dist/mcp/tools/search-element.js +177 -0
- package/dist/mcp/utils.d.ts +2 -2
- package/dist/mcp/utils.js +48 -0
- package/dist/model/builder/MergedExtends.js +74 -0
- package/dist/model/builder/MergedSpecification.js +175 -0
- package/dist/model/builder/buildModel.js +176 -0
- package/dist/model/deployments-index.js +102 -0
- package/dist/model/fqn-index.js +250 -0
- package/dist/model/index.js +6 -0
- package/dist/model/model-builder.d.ts +13 -11
- package/dist/model/model-builder.js +234 -0
- package/dist/model/model-locator.d.ts +6 -5
- package/dist/model/model-locator.js +240 -0
- package/dist/model/model-parser-where.js +81 -0
- package/dist/model/model-parser.d.ts +309 -304
- package/dist/model/model-parser.js +119 -0
- package/dist/model/parser/Base.d.ts +2 -2
- package/dist/model/parser/Base.js +367 -0
- package/dist/model/parser/DeploymentModelParser.d.ts +2 -2
- package/dist/model/parser/DeploymentModelParser.js +176 -0
- package/dist/model/parser/DeploymentViewParser.d.ts +3 -3
- package/dist/model/parser/DeploymentViewParser.js +86 -0
- package/dist/model/parser/FqnRefParser.d.ts +2 -2
- package/dist/model/parser/FqnRefParser.js +382 -0
- package/dist/model/parser/GlobalsParser.d.ts +6 -6
- package/dist/model/parser/GlobalsParser.js +84 -0
- package/dist/model/parser/ImportsParser.d.ts +11 -12
- package/dist/model/parser/ImportsParser.js +24 -0
- package/dist/model/parser/ModelParser.d.ts +2 -2
- package/dist/model/parser/ModelParser.js +165 -0
- package/dist/model/parser/PredicatesParser.d.ts +2 -2
- package/dist/model/parser/PredicatesParser.js +45 -0
- package/dist/model/parser/SpecificationParser.d.ts +2 -2
- package/dist/model/parser/SpecificationParser.js +109 -0
- package/dist/model/parser/ValueConverter.js +12 -0
- package/dist/model/parser/ViewsParser.d.ts +3 -3
- package/dist/model/parser/ViewsParser.js +477 -0
- package/dist/model-change/ModelChanges.d.ts +6 -3
- package/dist/model-change/ModelChanges.js +102 -0
- package/dist/model-change/changeElementStyle.js +134 -0
- package/dist/model-change/changeViewLayout.d.ts +2 -2
- package/dist/model-change/changeViewLayout.js +28 -0
- package/dist/model-change/removeManualLayoutV1.d.ts +7 -0
- package/dist/model-change/removeManualLayoutV1.js +27 -0
- package/dist/module.d.ts +10 -5
- package/dist/module.js +143 -0
- package/dist/protocol.d.ts +1 -17
- package/dist/protocol.js +114 -0
- package/dist/references/index.js +3 -0
- package/dist/references/name-provider.js +37 -0
- package/dist/references/scope-computation.js +288 -0
- package/dist/references/scope-provider.d.ts +3 -3
- package/dist/references/scope-provider.js +242 -0
- package/dist/shared/NodeKindProvider.js +57 -0
- package/dist/shared/{WorkspaceSymbolProvider.mjs → WorkspaceSymbolProvider.js} +1 -1
- package/dist/shared/index.js +2 -0
- package/dist/test/index.js +1 -0
- package/dist/test/testServices.d.ts +16 -16
- package/dist/test/testServices.js +210 -0
- package/dist/utils/disposable.js +26 -0
- package/dist/utils/elementRef.d.ts +1 -1
- package/dist/utils/elementRef.js +27 -0
- package/dist/utils/fqnRef.js +63 -0
- package/dist/utils/index.js +35 -0
- package/dist/utils/printDocs.js +1 -0
- package/dist/utils/projectId.js +16 -0
- package/dist/utils/stringHash.js +5 -0
- package/dist/validation/DocumentValidator.js +17 -0
- package/dist/validation/_shared.js +26 -0
- package/dist/validation/deployment-checks.js +140 -0
- package/dist/validation/dynamic-view.js +67 -0
- package/dist/validation/element-ref.js +12 -0
- package/dist/validation/element.js +49 -0
- package/dist/validation/imports.js +46 -0
- package/dist/validation/index.d.ts +1 -1
- package/dist/validation/index.js +157 -0
- package/dist/validation/property-checks.js +108 -0
- package/dist/validation/relation.js +55 -0
- package/dist/validation/specification.js +190 -0
- package/dist/validation/view-predicates/fqn-expr-with.js +43 -0
- package/dist/validation/view-predicates/fqn-ref-expr.js +51 -0
- package/dist/validation/view-predicates/incoming.js +16 -0
- package/dist/validation/view-predicates/index.js +6 -0
- package/dist/validation/view-predicates/outgoing.js +20 -0
- package/dist/validation/view-predicates/relation-expr.js +46 -0
- package/dist/validation/view-predicates/relation-with.js +16 -0
- package/dist/validation/view.d.ts +1 -1
- package/dist/validation/view.js +42 -0
- package/dist/view-utils/assignNavigateTo.js +27 -0
- package/dist/view-utils/index.d.ts +1 -0
- package/dist/view-utils/index.js +2 -0
- package/dist/view-utils/manual-layout.d.ts +6 -0
- package/dist/view-utils/manual-layout.js +151 -0
- package/dist/views/ConfigurableLayouter.js +51 -0
- package/dist/views/LikeC4ManualLayouts.d.ts +28 -0
- package/dist/views/LikeC4ManualLayouts.js +132 -0
- package/dist/views/{likec4-views.d.ts → LikeC4Views.d.ts} +9 -8
- package/dist/views/LikeC4Views.js +200 -0
- package/dist/views/index.d.ts +4 -1
- package/dist/views/index.js +11 -0
- package/dist/workspace/AstNodeDescriptionProvider.js +15 -0
- package/dist/workspace/IndexManager.js +21 -0
- package/dist/workspace/LangiumDocuments.d.ts +1 -1
- package/dist/workspace/LangiumDocuments.js +58 -0
- package/dist/workspace/ProjectsManager.d.ts +8 -3
- package/dist/workspace/ProjectsManager.js +373 -0
- package/dist/workspace/WorkspaceManager.d.ts +3 -2
- package/dist/workspace/WorkspaceManager.js +93 -0
- package/dist/workspace/index.js +5 -0
- package/likec4lib/package.json +1 -1
- package/package.json +25 -24
- package/protocol/package.json +1 -1
- package/dist/LikeC4LanguageServices.mjs +0 -197
- package/dist/Rpc.mjs +0 -296
- package/dist/ast.mjs +0 -221
- package/dist/browser-worker.mjs +0 -2
- package/dist/browser.mjs +0 -32
- package/dist/documentation/documentation-provider.mjs +0 -48
- package/dist/documentation/index.mjs +0 -1
- package/dist/empty.mjs +0 -1
- package/dist/filesystem/ChokidarWatcher.mjs +0 -68
- package/dist/filesystem/FileSystemWatcher.mjs +0 -11
- package/dist/filesystem/LikeC4FileSystem.mjs +0 -64
- package/dist/filesystem/index.mjs +0 -19
- package/dist/formatting/LikeC4Formatter.mjs +0 -511
- package/dist/formatting/utils.mjs +0 -15
- package/dist/generated/ast.mjs +0 -2150
- package/dist/generated/module.mjs +0 -23
- package/dist/index.mjs +0 -50
- package/dist/logger.mjs +0 -82
- package/dist/lsp/CodeLensProvider.mjs +0 -42
- package/dist/lsp/CompletionProvider.mjs +0 -208
- package/dist/lsp/DocumentHighlightProvider.mjs +0 -10
- package/dist/lsp/DocumentLinkProvider.mjs +0 -53
- package/dist/lsp/DocumentSymbolProvider.mjs +0 -287
- package/dist/lsp/HoverProvider.mjs +0 -104
- package/dist/lsp/RenameProvider.mjs +0 -6
- package/dist/lsp/SemanticTokenProvider.mjs +0 -276
- package/dist/lsp/index.mjs +0 -7
- package/dist/mcp/MCPServerFactory.mjs +0 -70
- package/dist/mcp/NoopLikeC4MCPServer.mjs +0 -17
- package/dist/mcp/interfaces.mjs +0 -4
- package/dist/mcp/server/StdioLikeC4MCPServer.mjs +0 -46
- package/dist/mcp/server/StreamableLikeC4MCPServer.mjs +0 -153
- package/dist/mcp/server/WithMCPServer.mjs +0 -58
- package/dist/mcp/tools/_common.mjs +0 -42
- package/dist/mcp/tools/find-relationships.mjs +0 -151
- package/dist/mcp/tools/list-projects.mjs +0 -62
- package/dist/mcp/tools/open-view.mjs +0 -52
- package/dist/mcp/tools/read-deployment.mjs +0 -130
- package/dist/mcp/tools/read-element.mjs +0 -198
- package/dist/mcp/tools/read-project-summary.mjs +0 -178
- package/dist/mcp/tools/read-view.mjs +0 -205
- package/dist/mcp/tools/search-element.mjs +0 -171
- package/dist/mcp/utils.mjs +0 -47
- package/dist/model/builder/MergedExtends.mjs +0 -76
- package/dist/model/builder/MergedSpecification.mjs +0 -205
- package/dist/model/builder/assignTagColors.d.ts +0 -7
- package/dist/model/builder/assignTagColors.mjs +0 -51
- package/dist/model/builder/buildModel.mjs +0 -226
- package/dist/model/deployments-index.mjs +0 -100
- package/dist/model/fqn-index.mjs +0 -243
- package/dist/model/index.mjs +0 -6
- package/dist/model/model-builder.mjs +0 -285
- package/dist/model/model-locator.mjs +0 -239
- package/dist/model/model-parser-where.mjs +0 -81
- package/dist/model/model-parser.mjs +0 -127
- package/dist/model/parser/Base.mjs +0 -376
- package/dist/model/parser/DeploymentModelParser.mjs +0 -212
- package/dist/model/parser/DeploymentViewParser.mjs +0 -95
- package/dist/model/parser/FqnRefParser.mjs +0 -398
- package/dist/model/parser/GlobalsParser.mjs +0 -82
- package/dist/model/parser/ImportsParser.mjs +0 -28
- package/dist/model/parser/ModelParser.mjs +0 -190
- package/dist/model/parser/PredicatesParser.mjs +0 -45
- package/dist/model/parser/SpecificationParser.mjs +0 -120
- package/dist/model/parser/ValueConverter.mjs +0 -12
- package/dist/model/parser/ViewsParser.mjs +0 -490
- package/dist/model-change/ModelChanges.mjs +0 -89
- package/dist/model-change/changeElementStyle.mjs +0 -143
- package/dist/model-change/changeViewLayout.mjs +0 -32
- package/dist/model-change/saveManualLayout.d.ts +0 -11
- package/dist/model-change/saveManualLayout.mjs +0 -27
- package/dist/module.mjs +0 -180
- package/dist/protocol.mjs +0 -65
- package/dist/references/index.mjs +0 -3
- package/dist/references/name-provider.mjs +0 -39
- package/dist/references/scope-computation.mjs +0 -312
- package/dist/references/scope-provider.mjs +0 -239
- package/dist/shared/NodeKindProvider.mjs +0 -110
- package/dist/shared/index.mjs +0 -2
- package/dist/test/index.mjs +0 -1
- package/dist/test/testServices.mjs +0 -200
- package/dist/utils/disposable.mjs +0 -25
- package/dist/utils/elementRef.mjs +0 -20
- package/dist/utils/fqnRef.mjs +0 -57
- package/dist/utils/index.mjs +0 -33
- package/dist/utils/printDocs.mjs +0 -1
- package/dist/utils/projectId.mjs +0 -16
- package/dist/utils/stringHash.mjs +0 -5
- package/dist/validation/DocumentValidator.mjs +0 -16
- package/dist/validation/_shared.mjs +0 -25
- package/dist/validation/deployment-checks.mjs +0 -146
- package/dist/validation/dynamic-view.mjs +0 -67
- package/dist/validation/element-ref.mjs +0 -12
- package/dist/validation/element.mjs +0 -50
- package/dist/validation/imports.mjs +0 -25
- package/dist/validation/index.mjs +0 -180
- package/dist/validation/property-checks.mjs +0 -107
- package/dist/validation/relation.mjs +0 -53
- package/dist/validation/specification.mjs +0 -173
- package/dist/validation/view-predicates/fqn-expr-with.mjs +0 -43
- package/dist/validation/view-predicates/fqn-ref-expr.mjs +0 -53
- package/dist/validation/view-predicates/incoming.mjs +0 -16
- package/dist/validation/view-predicates/index.mjs +0 -6
- package/dist/validation/view-predicates/outgoing.mjs +0 -20
- package/dist/validation/view-predicates/relation-expr.mjs +0 -39
- package/dist/validation/view-predicates/relation-with.mjs +0 -16
- package/dist/validation/view.mjs +0 -25
- package/dist/view-utils/assignNavigateTo.mjs +0 -25
- package/dist/view-utils/index.mjs +0 -1
- package/dist/view-utils/manual-layout.mjs +0 -99
- package/dist/views/configurable-layouter.mjs +0 -51
- package/dist/views/index.mjs +0 -1
- package/dist/views/likec4-views.mjs +0 -166
- package/dist/workspace/AstNodeDescriptionProvider.mjs +0 -17
- package/dist/workspace/IndexManager.mjs +0 -17
- package/dist/workspace/LangiumDocuments.mjs +0 -53
- package/dist/workspace/ProjectsManager.mjs +0 -360
- package/dist/workspace/WorkspaceManager.mjs +0 -83
- package/dist/workspace/index.mjs +0 -5
- /package/dist/views/{configurable-layouter.d.ts → ConfigurableLayouter.d.ts} +0 -0
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { isAncestor } from '@likec4/core';
|
|
2
|
+
import { AstUtils } from 'langium';
|
|
3
|
+
import { isEmpty } from 'remeda';
|
|
4
|
+
import { ast } from '../ast';
|
|
5
|
+
import { elementRef } from '../utils/elementRef';
|
|
6
|
+
import { tryOrLog } from './_shared';
|
|
7
|
+
export const dynamicViewStepSingle = (services) => {
|
|
8
|
+
const fqnIndex = services.likec4.FqnIndex;
|
|
9
|
+
return tryOrLog((el, accept) => {
|
|
10
|
+
const sourceEl = elementRef(el.source);
|
|
11
|
+
const source = sourceEl && fqnIndex.getFqn(sourceEl);
|
|
12
|
+
if (!source) {
|
|
13
|
+
accept('error', 'Source not found (not parsed/indexed yet)', {
|
|
14
|
+
node: el,
|
|
15
|
+
property: 'source',
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
const targetEl = elementRef(el.target);
|
|
19
|
+
const target = targetEl && fqnIndex.getFqn(targetEl);
|
|
20
|
+
if (!target) {
|
|
21
|
+
accept('error', 'Target not found (not parsed/indexed yet)', {
|
|
22
|
+
node: el,
|
|
23
|
+
property: 'target',
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
if (source && target && (isAncestor(source, target) || isAncestor(target, source))) {
|
|
27
|
+
accept('error', 'Invalid parent-child relationship', {
|
|
28
|
+
node: el,
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
};
|
|
33
|
+
export const dynamicViewStepChain = (services) => {
|
|
34
|
+
const fqnIndex = services.likec4.FqnIndex;
|
|
35
|
+
return tryOrLog((el, accept) => {
|
|
36
|
+
const source = el.source;
|
|
37
|
+
if (ast.isDynamicStepSingle(source) && source.isBackward) {
|
|
38
|
+
accept('error', 'Invalid chain after backward step', {
|
|
39
|
+
node: el,
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
const targetEl = elementRef(el.target);
|
|
43
|
+
const target = targetEl && fqnIndex.getFqn(targetEl);
|
|
44
|
+
if (!target) {
|
|
45
|
+
accept('error', 'Target not found (not parsed/indexed yet)', {
|
|
46
|
+
node: el,
|
|
47
|
+
property: 'target',
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
});
|
|
51
|
+
};
|
|
52
|
+
export const dynamicViewDisplayVariant = (_services) => {
|
|
53
|
+
return tryOrLog((prop, accept) => {
|
|
54
|
+
if (isEmpty(prop.value) || (prop.value !== 'diagram' && prop.value !== 'sequence')) {
|
|
55
|
+
accept('error', 'Invalid display variant: "diagram" or "sequence" are allowed', {
|
|
56
|
+
node: prop,
|
|
57
|
+
property: 'value',
|
|
58
|
+
});
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
if (!AstUtils.hasContainerOfType(prop, ast.isDynamicViewBody)) {
|
|
62
|
+
accept('error', `Display mode can be defined only inside dynamic view`, {
|
|
63
|
+
node: prop,
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
});
|
|
67
|
+
};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { isReferenceToDeploymentModel } from '../utils';
|
|
2
|
+
import { tryOrLog } from './_shared';
|
|
3
|
+
export const checkElementRef = (_services) => {
|
|
4
|
+
return tryOrLog((el, accept) => {
|
|
5
|
+
if (isReferenceToDeploymentModel(el.modelElement)) {
|
|
6
|
+
accept('error', 'Only model elements allowed here', {
|
|
7
|
+
node: el,
|
|
8
|
+
property: 'modelElement',
|
|
9
|
+
});
|
|
10
|
+
}
|
|
11
|
+
});
|
|
12
|
+
};
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { AstUtils } from 'langium';
|
|
2
|
+
import { projectIdFrom } from '../utils';
|
|
3
|
+
import { RESERVED_WORDS, tryOrLog } from './_shared';
|
|
4
|
+
const { getDocument } = AstUtils;
|
|
5
|
+
export const checkElement = (services) => {
|
|
6
|
+
const fqnIndex = services.likec4.FqnIndex;
|
|
7
|
+
const locator = services.workspace.AstNodeLocator;
|
|
8
|
+
return tryOrLog((el, accept) => {
|
|
9
|
+
const fqn = fqnIndex.getFqn(el);
|
|
10
|
+
if (!fqn) {
|
|
11
|
+
accept('error', 'Not indexed element', {
|
|
12
|
+
node: el,
|
|
13
|
+
property: 'name',
|
|
14
|
+
});
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
17
|
+
if (RESERVED_WORDS.includes(el.name)) {
|
|
18
|
+
accept('error', `Reserved word: ${el.name}`, {
|
|
19
|
+
node: el,
|
|
20
|
+
property: 'name',
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
const doc = getDocument(el);
|
|
24
|
+
const docUri = doc.uri;
|
|
25
|
+
const elPath = locator.getAstNodePath(el);
|
|
26
|
+
const withSameFqn = fqnIndex
|
|
27
|
+
.byFqn(projectIdFrom(doc), fqn)
|
|
28
|
+
.filter(v => v.documentUri !== docUri || v.path !== elPath)
|
|
29
|
+
.head();
|
|
30
|
+
if (withSameFqn) {
|
|
31
|
+
const isAnotherDoc = withSameFqn.documentUri !== docUri;
|
|
32
|
+
accept('error', `Duplicate element name ${el.name !== fqn ? el.name + ' (' + fqn + ')' : el.name}`, {
|
|
33
|
+
node: el,
|
|
34
|
+
property: 'name',
|
|
35
|
+
...isAnotherDoc && {
|
|
36
|
+
relatedInformation: [
|
|
37
|
+
{
|
|
38
|
+
location: {
|
|
39
|
+
range: (withSameFqn.nameSegment?.range ?? withSameFqn.selectionSegment?.range),
|
|
40
|
+
uri: withSameFqn.documentUri.toString(),
|
|
41
|
+
},
|
|
42
|
+
message: `conflicting element`,
|
|
43
|
+
},
|
|
44
|
+
],
|
|
45
|
+
},
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
});
|
|
49
|
+
};
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { AstUtils } from 'langium';
|
|
2
|
+
import { projectIdFrom } from '../utils';
|
|
3
|
+
import { tryOrLog } from './_shared';
|
|
4
|
+
const { getDocument } = AstUtils;
|
|
5
|
+
export const checkImportsFromPoject = (services) => {
|
|
6
|
+
const projects = services.shared.workspace.ProjectsManager;
|
|
7
|
+
return tryOrLog((el, accept) => {
|
|
8
|
+
const doc = getDocument(el);
|
|
9
|
+
const projectId = projectIdFrom(doc);
|
|
10
|
+
if (el.project === projectId) {
|
|
11
|
+
accept('error', 'Imported project cannot be the same as the current project', {
|
|
12
|
+
node: el,
|
|
13
|
+
property: 'project',
|
|
14
|
+
});
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
17
|
+
if (!projects.all.includes(el.project)) {
|
|
18
|
+
accept('error', 'Imported project not found', {
|
|
19
|
+
node: el,
|
|
20
|
+
property: 'project',
|
|
21
|
+
});
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
});
|
|
25
|
+
};
|
|
26
|
+
// export const checkImported = (services: LikeC4Services): ValidationCheck<ast.Imported> => {
|
|
27
|
+
// const fqnIndex = services.likec4.FqnIndex
|
|
28
|
+
// const projects = services.shared.workspace.ProjectsManager
|
|
29
|
+
// return tryOrLog((el, accept) => {
|
|
30
|
+
// const doc = getDocument(el)
|
|
31
|
+
// const importFromProject = el.$container.project as ProjectId
|
|
32
|
+
// if (importFromProject === projectId || !projects.all.includes(importFromProject)) {
|
|
33
|
+
// accept('error', 'Invalid import', {
|
|
34
|
+
// node: el,
|
|
35
|
+
// })
|
|
36
|
+
// return
|
|
37
|
+
// }
|
|
38
|
+
// const fqn = fqnIndex.byFqn(importFromProject, el.element.$refText as Fqn).head()
|
|
39
|
+
// if (!fqn) {
|
|
40
|
+
// accept('error', `Imported element not found in project "${importFromProject}"`, {
|
|
41
|
+
// node: el,
|
|
42
|
+
// })
|
|
43
|
+
// return
|
|
44
|
+
// }
|
|
45
|
+
// })
|
|
46
|
+
// }
|
|
@@ -4,7 +4,7 @@ import type { LikeC4Services } from '../module';
|
|
|
4
4
|
export { LikeC4DocumentValidator } from './DocumentValidator';
|
|
5
5
|
type Guard<N extends AstNode> = (n: AstNode) => n is N;
|
|
6
6
|
type Guarded<G> = G extends Guard<infer N> ? N : never;
|
|
7
|
-
declare const isValidatableAstNode: (n: AstNode) => n is ast.DynamicViewDisplayVariantProperty | ast.LinkProperty | ast.ViewStringProperty | ast.ElementStringProperty | ast.ElementStyleProperty | ast.IconProperty | ast.MetadataBody | ast.RelationStringProperty | ast.MetadataAttribute | ast.NotationProperty | ast.NotesProperty | ast.SpecificationElementStringProperty | ast.SpecificationRelationshipStringProperty | ast.HexColor | ast.RGBAColor | ast.DeployedInstance | ast.DeploymentNode | ast.DeploymentViewRulePredicate | ast.DeploymentViewRuleStyle | ast.ViewRuleAutoLayout | ast.DynamicViewGlobalPredicateRef | ast.DynamicViewIncludePredicate | ast.ViewRuleGlobalStyle | ast.ViewRuleStyle | ast.DynamicStepChain | ast.DynamicStepSingle | ast.ElementKindExpression | ast.ElementTagExpression | ast.FqnRefExpr | ast.WildcardExpression | ast.FqnExprWhere | ast.FqnExprWith | ast.DirectedRelationExpr | ast.InOutRelationExpr | ast.IncomingRelationExpr | ast.OutgoingRelationExpr | ast.RelationExprWhere | ast.RelationExprWith | ast.Element | ast.ExtendDeployment | ast.ExtendElement | ast.Imported | ast.DeploymentView | ast.DynamicView | ast.ElementView | ast.ArrowProperty | ast.ColorProperty | ast.LineProperty | ast.PaddingSizeProperty | ast.ShapeSizeProperty | ast.TextSizeProperty | ast.BorderProperty | ast.MultipleProperty | ast.OpacityProperty | ast.ShapeProperty | ast.ViewRuleGlobalPredicateRef | ast.ViewRuleGroup | ast.ViewRulePredicate | ast.DynamicViewParallelSteps | ast.
|
|
7
|
+
declare const isValidatableAstNode: (n: AstNode) => n is ast.DynamicViewDisplayVariantProperty | ast.LinkProperty | ast.ViewStringProperty | ast.ElementStringProperty | ast.ElementStyleProperty | ast.IconProperty | ast.MetadataBody | ast.RelationStringProperty | ast.MetadataAttribute | ast.NotationProperty | ast.NotesProperty | ast.SpecificationElementStringProperty | ast.SpecificationRelationshipStringProperty | ast.HexColor | ast.RGBAColor | ast.DeployedInstance | ast.DeploymentNode | ast.DeploymentViewRulePredicate | ast.DeploymentViewRuleStyle | ast.ViewRuleAutoLayout | ast.DynamicViewGlobalPredicateRef | ast.DynamicViewIncludePredicate | ast.ViewRuleGlobalStyle | ast.ViewRuleStyle | ast.DynamicStepChain | ast.DynamicStepSingle | ast.ElementKindExpression | ast.ElementTagExpression | ast.FqnRefExpr | ast.WildcardExpression | ast.FqnExprWhere | ast.FqnExprWith | ast.DirectedRelationExpr | ast.InOutRelationExpr | ast.IncomingRelationExpr | ast.OutgoingRelationExpr | ast.RelationExprWhere | ast.RelationExprWith | ast.Element | ast.ExtendDeployment | ast.ExtendElement | ast.Imported | ast.DeploymentView | ast.DynamicView | ast.ElementView | ast.ArrowProperty | ast.ColorProperty | ast.LineProperty | ast.PaddingSizeProperty | ast.ShapeSizeProperty | ast.TextSizeProperty | ast.BorderProperty | ast.MultipleProperty | ast.OpacityProperty | ast.ShapeProperty | ast.ViewRuleGlobalPredicateRef | ast.ViewRuleGroup | ast.ViewRulePredicate | ast.DynamicViewParallelSteps | ast.SpecificationRelationshipKind | ast.SpecificationRule | ast.ElementRef | ast.DeploymentRelation | ast.Relation | ast.GlobalDynamicPredicateGroup | ast.Globals | ast.GlobalPredicateGroup | ast.GlobalStyle | ast.SpecificationDeploymentNodeKind | ast.SpecificationElementKind | ast.GlobalStyleGroup | ast.SpecificationColor | ast.NavigateToProperty | ast.Tags | ast.ImportsFromPoject | ast.SpecificationTag;
|
|
8
8
|
type ValidatableAstNode = Guarded<typeof isValidatableAstNode>;
|
|
9
9
|
export declare function checksFromDiagnostics(doc: LikeC4LangiumDocument): {
|
|
10
10
|
isValid: (n: ValidatableAstNode) => boolean;
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
import { onNextTick } from '@likec4/core/utils';
|
|
2
|
+
import { loggable } from '@likec4/log';
|
|
3
|
+
import { DocumentState } from 'langium';
|
|
4
|
+
import { isNullish } from 'remeda';
|
|
5
|
+
import { DiagnosticSeverity } from 'vscode-languageserver-types';
|
|
6
|
+
import { ast } from '../ast';
|
|
7
|
+
import { logger } from '../logger';
|
|
8
|
+
import { deployedInstanceChecks, deploymentNodeChecks, deploymentRelationChecks, extendDeploymentChecks, } from './deployment-checks';
|
|
9
|
+
import { dynamicViewDisplayVariant, dynamicViewStepChain, dynamicViewStepSingle } from './dynamic-view';
|
|
10
|
+
import { checkElement } from './element';
|
|
11
|
+
import { checkElementRef } from './element-ref';
|
|
12
|
+
import { checkImportsFromPoject } from './imports';
|
|
13
|
+
import { colorLiteralRuleChecks, iconPropertyRuleChecks, notesPropertyRuleChecks, opacityPropertyRuleChecks, } from './property-checks';
|
|
14
|
+
import { checkRelationBody, relationChecks } from './relation';
|
|
15
|
+
import { checkDeploymentNodeKind, checkElementKind, checkGlobalPredicate, checkGlobals, checkGlobalStyleId, checkModel, checkRelationshipKind, checkSpecificationRule, checkTag, } from './specification';
|
|
16
|
+
import { viewChecks } from './view';
|
|
17
|
+
import { checkFqnExprWith, checkFqnRefExpr, checkIncomingRelationExpr, checkOutgoingRelationExpr, checkRelationExpr, checkRelationExprWith, } from './view-predicates';
|
|
18
|
+
export { LikeC4DocumentValidator } from './DocumentValidator';
|
|
19
|
+
function validatableAstNodeGuards(predicates) {
|
|
20
|
+
return (n) => predicates.some(p => p(n));
|
|
21
|
+
}
|
|
22
|
+
const isValidatableAstNode = validatableAstNodeGuards([
|
|
23
|
+
ast.isImportsFromPoject,
|
|
24
|
+
ast.isImported,
|
|
25
|
+
ast.isGlobals,
|
|
26
|
+
ast.isGlobalPredicateGroup,
|
|
27
|
+
ast.isGlobalDynamicPredicateGroup,
|
|
28
|
+
ast.isGlobalStyle,
|
|
29
|
+
ast.isGlobalStyleGroup,
|
|
30
|
+
ast.isFqnExprWith,
|
|
31
|
+
ast.isRelationExprWith,
|
|
32
|
+
ast.isFqnExpr,
|
|
33
|
+
ast.isRelationExpr,
|
|
34
|
+
ast.isDynamicViewParallelSteps,
|
|
35
|
+
ast.isDynamicStepChain,
|
|
36
|
+
ast.isDynamicStepSingle,
|
|
37
|
+
ast.isDeploymentViewRule,
|
|
38
|
+
ast.isDeploymentViewRulePredicate,
|
|
39
|
+
ast.isExpressionV2,
|
|
40
|
+
ast.isRelationExpr,
|
|
41
|
+
ast.isFqnRefExpr,
|
|
42
|
+
ast.isViewProperty,
|
|
43
|
+
ast.isStyleProperty,
|
|
44
|
+
ast.isTags,
|
|
45
|
+
ast.isViewRule,
|
|
46
|
+
ast.isDynamicViewRule,
|
|
47
|
+
ast.isLikeC4View,
|
|
48
|
+
ast.isViewRuleStyleOrGlobalRef,
|
|
49
|
+
ast.isDeployedInstance,
|
|
50
|
+
ast.isDeploymentNode,
|
|
51
|
+
ast.isDeploymentRelation,
|
|
52
|
+
ast.isRelationshipStyleProperty,
|
|
53
|
+
ast.isDynamicViewDisplayVariantProperty,
|
|
54
|
+
ast.isMetadataProperty,
|
|
55
|
+
ast.isRelation,
|
|
56
|
+
ast.isElementProperty,
|
|
57
|
+
ast.isStringProperty,
|
|
58
|
+
ast.isNavigateToProperty,
|
|
59
|
+
ast.isElement,
|
|
60
|
+
ast.isElementRef,
|
|
61
|
+
ast.isExtendElement,
|
|
62
|
+
ast.isExtendDeployment,
|
|
63
|
+
ast.isSpecificationElementKind,
|
|
64
|
+
ast.isSpecificationRelationshipKind,
|
|
65
|
+
ast.isSpecificationDeploymentNodeKind,
|
|
66
|
+
ast.isSpecificationTag,
|
|
67
|
+
ast.isSpecificationColor,
|
|
68
|
+
ast.isSpecificationRule,
|
|
69
|
+
ast.isColorLiteral,
|
|
70
|
+
]);
|
|
71
|
+
const findInvalidContainer = (node) => {
|
|
72
|
+
let nd = node;
|
|
73
|
+
while (nd && !ast.isLikeC4Grammar(nd)) {
|
|
74
|
+
if (isValidatableAstNode(nd)) {
|
|
75
|
+
return nd;
|
|
76
|
+
}
|
|
77
|
+
nd = nd.$container;
|
|
78
|
+
}
|
|
79
|
+
return undefined;
|
|
80
|
+
};
|
|
81
|
+
export function checksFromDiagnostics(doc) {
|
|
82
|
+
const errors = doc.state >= DocumentState.Validated
|
|
83
|
+
? (doc.diagnostics?.filter(d => d.severity === DiagnosticSeverity.Error) ?? [])
|
|
84
|
+
: [];
|
|
85
|
+
const invalidNodes = new WeakSet();
|
|
86
|
+
for (const { node } of errors) {
|
|
87
|
+
if (isNullish(node) || invalidNodes.has(node)) {
|
|
88
|
+
continue;
|
|
89
|
+
}
|
|
90
|
+
invalidNodes.add(node);
|
|
91
|
+
const container = findInvalidContainer(node);
|
|
92
|
+
if (container) {
|
|
93
|
+
invalidNodes.add(container);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
const isValid = (n) => !invalidNodes.has(n);
|
|
97
|
+
return {
|
|
98
|
+
isValid,
|
|
99
|
+
invalidNodes,
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
export function registerValidationChecks(services) {
|
|
103
|
+
logger.debug('registerValidationChecks');
|
|
104
|
+
const registry = services.validation.ValidationRegistry;
|
|
105
|
+
registry.register({
|
|
106
|
+
DeployedInstance: deployedInstanceChecks(services),
|
|
107
|
+
DeploymentNodeKind: checkDeploymentNodeKind(services),
|
|
108
|
+
DeploymentNode: deploymentNodeChecks(services),
|
|
109
|
+
DeploymentRelation: deploymentRelationChecks(services),
|
|
110
|
+
ExtendDeployment: extendDeploymentChecks(services),
|
|
111
|
+
FqnRefExpr: checkFqnRefExpr(services),
|
|
112
|
+
RelationExpr: checkRelationExpr(services),
|
|
113
|
+
NotesProperty: notesPropertyRuleChecks(services),
|
|
114
|
+
OpacityProperty: opacityPropertyRuleChecks(services),
|
|
115
|
+
IconProperty: iconPropertyRuleChecks(services),
|
|
116
|
+
SpecificationRule: checkSpecificationRule(services),
|
|
117
|
+
Model: checkModel(services),
|
|
118
|
+
Globals: checkGlobals(services),
|
|
119
|
+
GlobalPredicateGroup: checkGlobalPredicate(services),
|
|
120
|
+
GlobalDynamicPredicateGroup: checkGlobalPredicate(services),
|
|
121
|
+
GlobalStyleId: checkGlobalStyleId(services),
|
|
122
|
+
DynamicStepSingle: dynamicViewStepSingle(services),
|
|
123
|
+
DynamicStepChain: dynamicViewStepChain(services),
|
|
124
|
+
LikeC4View: viewChecks(services),
|
|
125
|
+
Element: checkElement(services),
|
|
126
|
+
ElementRef: checkElementRef(services),
|
|
127
|
+
ElementKind: checkElementKind(services),
|
|
128
|
+
Relation: relationChecks(services),
|
|
129
|
+
RelationBody: checkRelationBody(services),
|
|
130
|
+
Tag: checkTag(services),
|
|
131
|
+
FqnExprWith: checkFqnExprWith(services),
|
|
132
|
+
RelationExprWith: checkRelationExprWith(services),
|
|
133
|
+
RelationshipKind: checkRelationshipKind(services),
|
|
134
|
+
IncomingRelationExpr: checkIncomingRelationExpr(services),
|
|
135
|
+
OutgoingRelationExpr: checkOutgoingRelationExpr(services),
|
|
136
|
+
ImportsFromPoject: checkImportsFromPoject(services),
|
|
137
|
+
// Imported: checkImported(services),
|
|
138
|
+
ColorLiteral: colorLiteralRuleChecks(services),
|
|
139
|
+
DynamicViewDisplayVariantProperty: dynamicViewDisplayVariant(services),
|
|
140
|
+
});
|
|
141
|
+
const connection = services.shared.lsp.Connection;
|
|
142
|
+
if (connection) {
|
|
143
|
+
// delay initialization
|
|
144
|
+
onNextTick(() => {
|
|
145
|
+
// workaround for bug in langium
|
|
146
|
+
services.shared.workspace.DocumentBuilder.onUpdate((_, deleted) => {
|
|
147
|
+
for (const uri of deleted) {
|
|
148
|
+
logger.debug(`clear diagnostics for deleted ${uri.path}`);
|
|
149
|
+
connection.sendDiagnostics({
|
|
150
|
+
uri: uri.toString(),
|
|
151
|
+
diagnostics: [],
|
|
152
|
+
}).catch(e => logger.error(loggable(e)));
|
|
153
|
+
}
|
|
154
|
+
});
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import { nonexhaustive } from '@likec4/core';
|
|
2
|
+
import { AstUtils } from 'langium';
|
|
3
|
+
import { isNumber, isString } from 'remeda';
|
|
4
|
+
import { ast } from '../ast';
|
|
5
|
+
import { tryOrLog } from './_shared';
|
|
6
|
+
export const opacityPropertyRuleChecks = (_) => {
|
|
7
|
+
return tryOrLog((node, accept) => {
|
|
8
|
+
const opacity = parseFloat(node.value);
|
|
9
|
+
if (isNaN(opacity) || opacity < 0 || opacity > 100) {
|
|
10
|
+
accept('warning', `Value ignored, must be between 0% and 100%`, {
|
|
11
|
+
node,
|
|
12
|
+
property: 'value',
|
|
13
|
+
});
|
|
14
|
+
}
|
|
15
|
+
});
|
|
16
|
+
};
|
|
17
|
+
export const iconPropertyRuleChecks = (_) => {
|
|
18
|
+
return (node, accept) => {
|
|
19
|
+
const container = node.$container;
|
|
20
|
+
const anotherIcon = container.props.some(p => ast.isIconProperty(p) && p !== node);
|
|
21
|
+
if (anotherIcon) {
|
|
22
|
+
accept('error', `Icon must be defined once`, {
|
|
23
|
+
node,
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
if (ast.isElementStyleProperty(container) && ast.isElementBody(container.$container)
|
|
27
|
+
&& container.$container.props.some(p => ast.isIconProperty(p))) {
|
|
28
|
+
accept('warning', `Redundant as icon defined on element`, {
|
|
29
|
+
node,
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
if (node.value?.startsWith('file://')) {
|
|
33
|
+
accept('error', `Icon URI must not start with file://`, {
|
|
34
|
+
node,
|
|
35
|
+
property: 'value',
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
};
|
|
39
|
+
};
|
|
40
|
+
export const notesPropertyRuleChecks = (_) => {
|
|
41
|
+
return (node, accept) => {
|
|
42
|
+
if (!AstUtils.hasContainerOfType(node, ast.isDynamicViewStep)) {
|
|
43
|
+
accept('error', `Notes can be defined only inside dynamic view`, {
|
|
44
|
+
node,
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
};
|
|
49
|
+
export const colorLiteralRuleChecks = (_) => {
|
|
50
|
+
return (node, accept) => {
|
|
51
|
+
if (node.$type === 'HexColor') {
|
|
52
|
+
if (node.hex === undefined || (isString(node.hex) && !node.hex.match(/^[a-fA-F0-9]+$/))) {
|
|
53
|
+
accept('error', `Invalid HEX`, {
|
|
54
|
+
node,
|
|
55
|
+
property: 'hex',
|
|
56
|
+
});
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
const length = isNumber(node.hex) ? node.hex.toString().length : node.hex.length;
|
|
60
|
+
if (length !== 6 && length !== 3 && length !== 8) {
|
|
61
|
+
accept('error', `Invalid value "${node.$cstNode?.text}", must be 3, 6 or 8 characters long`, {
|
|
62
|
+
node,
|
|
63
|
+
property: 'hex',
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
if (node.$type === 'RGBAColor') {
|
|
69
|
+
if (!isNumber(node.red) || node.red < 0 || node.red > 255) {
|
|
70
|
+
accept('error', `Invalid value, must be between 0 and 255`, {
|
|
71
|
+
node,
|
|
72
|
+
property: 'red',
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
if (!isNumber(node.green) || node.green < 0 || node.green > 255) {
|
|
76
|
+
accept('error', `Invalid value, must be between 0 and 255`, {
|
|
77
|
+
node,
|
|
78
|
+
property: 'green',
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
if (!isNumber(node.blue) || node.blue < 0 || node.blue > 255) {
|
|
82
|
+
accept('error', `Invalid value, must be between 0 and 255`, {
|
|
83
|
+
node,
|
|
84
|
+
property: 'blue',
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
if (isNumber(node.alpha)) {
|
|
88
|
+
if (node.alpha < 0 || node.alpha > 1) {
|
|
89
|
+
accept('error', `Invalid value, must be between 0 and 1`, {
|
|
90
|
+
node,
|
|
91
|
+
property: 'alpha',
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
if (isString(node.alpha)) {
|
|
96
|
+
const alpha = parseFloat(node.alpha);
|
|
97
|
+
if (alpha < 0 || alpha > 100) {
|
|
98
|
+
accept('error', `Invalid value, must be between 0% and 100%`, {
|
|
99
|
+
node,
|
|
100
|
+
property: 'alpha',
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
nonexhaustive(node);
|
|
107
|
+
};
|
|
108
|
+
};
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { FqnRef, isSameHierarchy } from '@likec4/core';
|
|
2
|
+
import { AstUtils } from 'langium';
|
|
3
|
+
import { ast } from '../ast';
|
|
4
|
+
import { safeCall } from '../utils';
|
|
5
|
+
import { tryOrLog } from './_shared';
|
|
6
|
+
export const relationChecks = (services) => {
|
|
7
|
+
const modelParser = services.likec4.ModelParser;
|
|
8
|
+
return tryOrLog((el, accept) => {
|
|
9
|
+
const parser = modelParser.forDocument(AstUtils.getDocument(el));
|
|
10
|
+
const source = safeCall(() => parser._resolveRelationSource(el));
|
|
11
|
+
if (!source) {
|
|
12
|
+
accept('error', 'Source not resolved', {
|
|
13
|
+
node: el,
|
|
14
|
+
property: 'source',
|
|
15
|
+
});
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
const target = safeCall(() => parser.parseFqnRef(el.target));
|
|
19
|
+
if (!target) {
|
|
20
|
+
accept('error', 'Target not resolved', {
|
|
21
|
+
node: el,
|
|
22
|
+
property: 'target',
|
|
23
|
+
});
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
if (FqnRef.isImportRef(source)) {
|
|
27
|
+
if (FqnRef.isImportRef(target)) {
|
|
28
|
+
accept('warning', 'Relationship between imported elements may not be visible in origin projects', {
|
|
29
|
+
node: el,
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
else {
|
|
33
|
+
accept('warning', 'Relationship from imported element to local element may not be visible in origin project', {
|
|
34
|
+
node: el,
|
|
35
|
+
property: 'source',
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
if (isSameHierarchy(FqnRef.flatten(source), FqnRef.flatten(target))) {
|
|
40
|
+
accept('error', 'Invalid parent-child relationship', {
|
|
41
|
+
node: el,
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
});
|
|
45
|
+
};
|
|
46
|
+
export const checkRelationBody = (_services) => {
|
|
47
|
+
return tryOrLog((body, accept) => {
|
|
48
|
+
const relation = body.$container;
|
|
49
|
+
if (relation.tags?.values && body.tags?.values) {
|
|
50
|
+
accept('error', 'Relation cannot have tags in both header and body', {
|
|
51
|
+
node: body.tags,
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
});
|
|
55
|
+
};
|