@likec4/language-server 1.27.2 → 1.28.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/LikeC4LanguageServices.js +6 -7
- package/dist/ast.d.ts +16 -9
- package/dist/ast.js +58 -79
- package/dist/bundled.mjs +2130 -2127
- package/dist/config/schema.d.ts +3 -3
- package/dist/config/schema.js +12 -5
- package/dist/documentation/documentation-provider.js +3 -1
- package/dist/formatting/LikeC4Formatter.d.ts +0 -2
- package/dist/formatting/LikeC4Formatter.js +24 -53
- package/dist/generated/ast.d.ts +128 -233
- package/dist/generated/ast.js +134 -306
- package/dist/generated/grammar.js +1 -1
- package/dist/lsp/CompletionProvider.d.ts +3 -0
- package/dist/lsp/CompletionProvider.js +128 -113
- package/dist/lsp/DocumentLinkProvider.js +6 -3
- package/dist/lsp/HoverProvider.js +3 -1
- package/dist/lsp/SemanticTokenProvider.js +33 -43
- package/dist/model/builder/MergedSpecification.d.ts +5 -3
- package/dist/model/builder/MergedSpecification.js +21 -7
- package/dist/model/builder/buildModel.d.ts +6 -1
- package/dist/model/builder/buildModel.js +20 -15
- package/dist/model/deployments-index.js +4 -2
- package/dist/model/fqn-index.d.ts +4 -2
- package/dist/model/fqn-index.js +28 -5
- package/dist/model/model-builder.d.ts +2 -2
- package/dist/model/model-builder.js +54 -16
- package/dist/model/model-locator.js +7 -4
- package/dist/model/model-parser.d.ts +215 -52
- package/dist/model/model-parser.js +6 -2
- package/dist/model/parser/Base.d.ts +11 -2
- package/dist/model/parser/Base.js +138 -3
- package/dist/model/parser/DeploymentModelParser.d.ts +19 -2
- package/dist/model/parser/DeploymentModelParser.js +19 -29
- package/dist/model/parser/DeploymentViewParser.d.ts +18 -2
- package/dist/model/parser/DeploymentViewParser.js +6 -24
- package/dist/model/parser/FqnRefParser.d.ts +18 -3
- package/dist/model/parser/FqnRefParser.js +264 -40
- package/dist/model/parser/GlobalsParser.d.ts +35 -18
- package/dist/model/parser/ImportsParser.d.ts +32 -0
- package/dist/model/parser/ImportsParser.js +26 -0
- package/dist/model/parser/ModelParser.d.ts +26 -2
- package/dist/model/parser/ModelParser.js +21 -41
- package/dist/model/parser/PredicatesParser.d.ts +35 -12
- package/dist/model/parser/PredicatesParser.js +20 -271
- package/dist/model/parser/SpecificationParser.d.ts +8 -0
- package/dist/model/parser/SpecificationParser.js +5 -9
- package/dist/model/parser/ViewsParser.d.ts +36 -19
- package/dist/model/parser/ViewsParser.js +15 -11
- package/dist/model-change/changeElementStyle.d.ts +2 -2
- package/dist/model-change/changeElementStyle.js +2 -1
- package/dist/references/name-provider.js +8 -2
- package/dist/references/scope-computation.d.ts +1 -1
- package/dist/references/scope-computation.js +33 -3
- package/dist/references/scope-provider.d.ts +7 -8
- package/dist/references/scope-provider.js +59 -41
- package/dist/shared/NodeKindProvider.js +4 -2
- package/dist/test/testServices.d.ts +2 -0
- package/dist/test/testServices.js +4 -1
- package/dist/utils/elementRef.d.ts +1 -1
- package/dist/utils/elementRef.js +6 -1
- package/dist/utils/fqnRef.d.ts +3 -0
- package/dist/utils/fqnRef.js +15 -4
- package/dist/utils/index.d.ts +1 -0
- package/dist/utils/index.js +9 -0
- package/dist/utils/projectId.d.ts +2 -1
- package/dist/utils/projectId.js +11 -1
- package/dist/validation/_shared.js +2 -2
- package/dist/validation/deployment-checks.js +24 -10
- package/dist/validation/element-ref.d.ts +4 -0
- package/dist/validation/element-ref.js +12 -0
- package/dist/validation/element.d.ts +1 -1
- package/dist/validation/element.js +1 -1
- package/dist/validation/imports.d.ts +5 -0
- package/dist/validation/imports.js +30 -0
- package/dist/validation/index.d.ts +1 -1
- package/dist/validation/index.js +47 -45
- package/dist/validation/relation.d.ts +2 -2
- package/dist/validation/relation.js +24 -27
- package/dist/validation/specification.d.ts +9 -9
- package/dist/validation/specification.js +9 -9
- package/dist/validation/view-predicates/{element-with.d.ts → fqn-expr-with.d.ts} +1 -1
- package/dist/validation/view-predicates/fqn-expr-with.js +42 -0
- package/dist/validation/view-predicates/fqn-ref-expr.d.ts +4 -0
- package/dist/validation/view-predicates/fqn-ref-expr.js +53 -0
- package/dist/validation/view-predicates/incoming.d.ts +1 -1
- package/dist/validation/view-predicates/incoming.js +2 -2
- package/dist/validation/view-predicates/index.d.ts +6 -6
- package/dist/validation/view-predicates/index.js +6 -6
- package/dist/validation/view-predicates/outgoing.d.ts +1 -1
- package/dist/validation/view-predicates/outgoing.js +8 -4
- package/dist/validation/view-predicates/{expanded-element.d.ts → relation-expr.d.ts} +1 -1
- package/dist/validation/view-predicates/relation-expr.js +39 -0
- package/dist/validation/view-predicates/relation-with.d.ts +1 -1
- package/dist/validation/view-predicates/relation-with.js +8 -5
- package/dist/workspace/AstNodeDescriptionProvider.d.ts +1 -1
- package/dist/workspace/AstNodeDescriptionProvider.js +2 -3
- package/dist/workspace/IndexManager.d.ts +1 -1
- package/dist/workspace/IndexManager.js +5 -4
- package/dist/workspace/LangiumDocuments.d.ts +1 -1
- package/dist/workspace/LangiumDocuments.js +3 -5
- package/dist/workspace/ProjectsManager.d.ts +25 -7
- package/dist/workspace/ProjectsManager.js +76 -32
- package/dist/workspace/WorkspaceManager.d.ts +4 -5
- package/dist/workspace/WorkspaceManager.js +53 -20
- package/package.json +12 -10
- package/dist/validation/dynamic-view-rule.d.ts +0 -4
- package/dist/validation/dynamic-view-rule.js +0 -17
- package/dist/validation/view-predicates/element-with.js +0 -31
- package/dist/validation/view-predicates/expanded-element.js +0 -12
- package/dist/validation/view-predicates/expression-v2.d.ts +0 -5
- package/dist/validation/view-predicates/expression-v2.js +0 -83
package/dist/validation/index.js
CHANGED
|
@@ -9,46 +9,47 @@ import {
|
|
|
9
9
|
deploymentRelationChecks,
|
|
10
10
|
extendDeploymentChecks
|
|
11
11
|
} from "./deployment-checks.js";
|
|
12
|
-
import { dynamicViewRulePredicate } from "./dynamic-view-rule.js";
|
|
13
12
|
import { dynamicViewStep } from "./dynamic-view-step.js";
|
|
14
|
-
import {
|
|
13
|
+
import { checkElement } from "./element.js";
|
|
14
|
+
import { checkElementRef } from "./element-ref.js";
|
|
15
|
+
import { checkImported, checkImportsFromPoject } from "./imports.js";
|
|
15
16
|
import { iconPropertyRuleChecks, notesPropertyRuleChecks, opacityPropertyRuleChecks } from "./property-checks.js";
|
|
16
|
-
import {
|
|
17
|
+
import { checkRelationBody, relationChecks } from "./relation.js";
|
|
17
18
|
import {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
19
|
+
checkDeploymentNodeKind,
|
|
20
|
+
checkElementKind,
|
|
21
|
+
checkGlobalPredicate,
|
|
22
|
+
checkGlobals,
|
|
23
|
+
checkGlobalStyleId,
|
|
24
|
+
checkModel,
|
|
25
|
+
checkRelationshipKind,
|
|
26
|
+
checkSpecificationRule,
|
|
27
|
+
checkTag
|
|
27
28
|
} from "./specification.js";
|
|
28
29
|
import { viewChecks } from "./view.js";
|
|
29
30
|
import {
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
relationPredicateWithChecks
|
|
31
|
+
checkFqnExprWith,
|
|
32
|
+
checkFqnRefExpr,
|
|
33
|
+
checkIncomingRelationExpr,
|
|
34
|
+
checkOutgoingRelationExpr,
|
|
35
|
+
checkRelationExpr,
|
|
36
|
+
checkRelationExprWith
|
|
37
37
|
} from "./view-predicates/index.js";
|
|
38
38
|
function validatableAstNodeGuards(predicates) {
|
|
39
39
|
return (n) => predicates.some((p) => p(n));
|
|
40
40
|
}
|
|
41
41
|
const isValidatableAstNode = validatableAstNodeGuards([
|
|
42
|
+
ast.isImportsFromPoject,
|
|
43
|
+
ast.isImported,
|
|
42
44
|
ast.isGlobals,
|
|
43
45
|
ast.isGlobalPredicateGroup,
|
|
44
46
|
ast.isGlobalDynamicPredicateGroup,
|
|
45
47
|
ast.isGlobalStyle,
|
|
46
48
|
ast.isGlobalStyleGroup,
|
|
47
|
-
ast.
|
|
48
|
-
ast.
|
|
49
|
-
ast.
|
|
50
|
-
ast.
|
|
51
|
-
ast.isRelationExpression,
|
|
49
|
+
ast.isFqnExprWith,
|
|
50
|
+
ast.isRelationExprWith,
|
|
51
|
+
ast.isFqnExpr,
|
|
52
|
+
ast.isRelationExpr,
|
|
52
53
|
ast.isDynamicViewParallelSteps,
|
|
53
54
|
ast.isDynamicViewStep,
|
|
54
55
|
ast.isDeploymentViewRule,
|
|
@@ -58,7 +59,6 @@ const isValidatableAstNode = validatableAstNodeGuards([
|
|
|
58
59
|
ast.isFqnRefExpr,
|
|
59
60
|
ast.isViewProperty,
|
|
60
61
|
ast.isStyleProperty,
|
|
61
|
-
ast.isPredicate,
|
|
62
62
|
ast.isTags,
|
|
63
63
|
ast.isViewRule,
|
|
64
64
|
ast.isDynamicViewRule,
|
|
@@ -74,6 +74,7 @@ const isValidatableAstNode = validatableAstNodeGuards([
|
|
|
74
74
|
ast.isStringProperty,
|
|
75
75
|
ast.isNavigateToProperty,
|
|
76
76
|
ast.isElement,
|
|
77
|
+
ast.isElementRef,
|
|
77
78
|
ast.isExtendElement,
|
|
78
79
|
ast.isExtendDeployment,
|
|
79
80
|
ast.isSpecificationElementKind,
|
|
@@ -117,35 +118,36 @@ export function registerValidationChecks(services) {
|
|
|
117
118
|
const registry = services.validation.ValidationRegistry;
|
|
118
119
|
registry.register({
|
|
119
120
|
DeployedInstance: deployedInstanceChecks(services),
|
|
120
|
-
DeploymentNodeKind:
|
|
121
|
+
DeploymentNodeKind: checkDeploymentNodeKind(services),
|
|
121
122
|
DeploymentNode: deploymentNodeChecks(services),
|
|
122
123
|
DeploymentRelation: deploymentRelationChecks(services),
|
|
123
124
|
ExtendDeployment: extendDeploymentChecks(services),
|
|
124
|
-
FqnRefExpr:
|
|
125
|
-
RelationExpr:
|
|
125
|
+
FqnRefExpr: checkFqnRefExpr(services),
|
|
126
|
+
RelationExpr: checkRelationExpr(services),
|
|
126
127
|
NotesProperty: notesPropertyRuleChecks(services),
|
|
127
128
|
OpacityProperty: opacityPropertyRuleChecks(services),
|
|
128
129
|
IconProperty: iconPropertyRuleChecks(services),
|
|
129
|
-
SpecificationRule:
|
|
130
|
-
Model:
|
|
131
|
-
Globals:
|
|
132
|
-
GlobalPredicateGroup:
|
|
133
|
-
GlobalDynamicPredicateGroup:
|
|
134
|
-
GlobalStyleId:
|
|
130
|
+
SpecificationRule: checkSpecificationRule(services),
|
|
131
|
+
Model: checkModel(services),
|
|
132
|
+
Globals: checkGlobals(services),
|
|
133
|
+
GlobalPredicateGroup: checkGlobalPredicate(services),
|
|
134
|
+
GlobalDynamicPredicateGroup: checkGlobalPredicate(services),
|
|
135
|
+
GlobalStyleId: checkGlobalStyleId(services),
|
|
135
136
|
DynamicViewStep: dynamicViewStep(services),
|
|
136
137
|
LikeC4View: viewChecks(services),
|
|
137
|
-
Element:
|
|
138
|
-
|
|
138
|
+
Element: checkElement(services),
|
|
139
|
+
ElementRef: checkElementRef(services),
|
|
140
|
+
ElementKind: checkElementKind(services),
|
|
139
141
|
Relation: relationChecks(services),
|
|
140
|
-
RelationBody:
|
|
141
|
-
Tag:
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
142
|
+
RelationBody: checkRelationBody(services),
|
|
143
|
+
Tag: checkTag(services),
|
|
144
|
+
FqnExprWith: checkFqnExprWith(services),
|
|
145
|
+
RelationExprWith: checkRelationExprWith(services),
|
|
146
|
+
RelationshipKind: checkRelationshipKind(services),
|
|
147
|
+
IncomingRelationExpr: checkIncomingRelationExpr(services),
|
|
148
|
+
OutgoingRelationExpr: checkOutgoingRelationExpr(services),
|
|
149
|
+
ImportsFromPoject: checkImportsFromPoject(services),
|
|
150
|
+
Imported: checkImported(services)
|
|
149
151
|
});
|
|
150
152
|
const connection = services.shared.lsp.Connection;
|
|
151
153
|
if (connection) {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { type ValidationCheck } from 'langium';
|
|
2
2
|
import { ast } from '../ast';
|
|
3
3
|
import type { LikeC4Services } from '../module';
|
|
4
4
|
export declare const relationChecks: (services: LikeC4Services) => ValidationCheck<ast.Relation>;
|
|
5
|
-
export declare const
|
|
5
|
+
export declare const checkRelationBody: (_services: LikeC4Services) => ValidationCheck<ast.RelationBody>;
|
|
@@ -1,50 +1,47 @@
|
|
|
1
|
-
import { isSameHierarchy } from "@likec4/core";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import { elementRef } from "../utils/elementRef.js";
|
|
1
|
+
import { FqnRef, isSameHierarchy } from "@likec4/core";
|
|
2
|
+
import { AstUtils } from "langium";
|
|
3
|
+
import { safeCall } from "../utils/index.js";
|
|
5
4
|
import { tryOrLog } from "./_shared.js";
|
|
6
5
|
export const relationChecks = (services) => {
|
|
7
|
-
const
|
|
6
|
+
const modelParser = services.likec4.ModelParser;
|
|
8
7
|
return tryOrLog((el, accept) => {
|
|
9
|
-
const
|
|
10
|
-
const
|
|
8
|
+
const parser = modelParser.forDocument(AstUtils.getDocument(el));
|
|
9
|
+
const source = safeCall(() => parser._resolveRelationSource(el));
|
|
10
|
+
if (!source) {
|
|
11
|
+
accept("error", "Source not resolved", {
|
|
12
|
+
node: el,
|
|
13
|
+
property: "source"
|
|
14
|
+
});
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
17
|
+
const target = safeCall(() => parser.parseFqnRef(el.target));
|
|
11
18
|
if (!target) {
|
|
12
19
|
accept("error", "Target not resolved", {
|
|
13
20
|
node: el,
|
|
14
21
|
property: "target"
|
|
15
22
|
});
|
|
23
|
+
return;
|
|
16
24
|
}
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
25
|
+
if (FqnRef.isImportRef(source)) {
|
|
26
|
+
if (FqnRef.isImportRef(target)) {
|
|
27
|
+
accept("warning", "Relationship between imported elements may not be visible in origin projects", {
|
|
28
|
+
node: el
|
|
29
|
+
});
|
|
30
|
+
} else {
|
|
31
|
+
accept("warning", "Relationship from imported element to local element may not be visible in origin project", {
|
|
22
32
|
node: el,
|
|
23
33
|
property: "source"
|
|
24
34
|
});
|
|
25
35
|
}
|
|
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
36
|
}
|
|
40
|
-
if (
|
|
37
|
+
if (isSameHierarchy(FqnRef.toModelFqn(source), FqnRef.toModelFqn(target))) {
|
|
41
38
|
accept("error", "Invalid parent-child relationship", {
|
|
42
39
|
node: el
|
|
43
40
|
});
|
|
44
41
|
}
|
|
45
42
|
});
|
|
46
43
|
};
|
|
47
|
-
export const
|
|
44
|
+
export const checkRelationBody = (_services) => {
|
|
48
45
|
return tryOrLog((body, accept) => {
|
|
49
46
|
const relation = body.$container;
|
|
50
47
|
if (relation.tags?.values && body.tags?.values) {
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { type ValidationCheck } from 'langium';
|
|
2
2
|
import { ast } from '../ast';
|
|
3
3
|
import type { LikeC4Services } from '../module';
|
|
4
|
-
export declare const
|
|
5
|
-
export declare const
|
|
6
|
-
export declare const
|
|
7
|
-
export declare const
|
|
8
|
-
export declare const
|
|
9
|
-
export declare const
|
|
10
|
-
export declare const
|
|
11
|
-
export declare const
|
|
12
|
-
export declare const
|
|
4
|
+
export declare const checkSpecificationRule: (_: LikeC4Services) => ValidationCheck<ast.SpecificationRule>;
|
|
5
|
+
export declare const checkModel: (_: LikeC4Services) => ValidationCheck<ast.Model>;
|
|
6
|
+
export declare const checkGlobals: (_: LikeC4Services) => ValidationCheck<ast.Globals>;
|
|
7
|
+
export declare const checkElementKind: (services: LikeC4Services) => ValidationCheck<ast.ElementKind>;
|
|
8
|
+
export declare const checkDeploymentNodeKind: (services: LikeC4Services) => ValidationCheck<ast.DeploymentNodeKind>;
|
|
9
|
+
export declare const checkTag: (services: LikeC4Services) => ValidationCheck<ast.Tag>;
|
|
10
|
+
export declare const checkRelationshipKind: (services: LikeC4Services) => ValidationCheck<ast.RelationshipKind>;
|
|
11
|
+
export declare const checkGlobalPredicate: (services: LikeC4Services) => ValidationCheck<ast.GlobalPredicateGroup | ast.GlobalDynamicPredicateGroup>;
|
|
12
|
+
export declare const checkGlobalStyleId: (services: LikeC4Services) => ValidationCheck<ast.GlobalStyleId>;
|
|
@@ -2,7 +2,7 @@ import { AstUtils } from "langium";
|
|
|
2
2
|
import { ast } from "../ast.js";
|
|
3
3
|
import { projectIdFrom } from "../utils/index.js";
|
|
4
4
|
import { RESERVED_WORDS, tryOrLog } from "./_shared.js";
|
|
5
|
-
export const
|
|
5
|
+
export const checkSpecificationRule = (_) => {
|
|
6
6
|
return tryOrLog((node, accept) => {
|
|
7
7
|
if (node.$containerIndex && node.$containerIndex > 0) {
|
|
8
8
|
accept("warning", `Prefer one specification per document`, {
|
|
@@ -12,7 +12,7 @@ export const specificationRuleChecks = (_) => {
|
|
|
12
12
|
}
|
|
13
13
|
});
|
|
14
14
|
};
|
|
15
|
-
export const
|
|
15
|
+
export const checkModel = (_) => {
|
|
16
16
|
return tryOrLog((node, accept) => {
|
|
17
17
|
if (node.$containerIndex && node.$containerIndex > 0) {
|
|
18
18
|
accept("warning", `Prefer one model per document`, {
|
|
@@ -22,7 +22,7 @@ export const modelRuleChecks = (_) => {
|
|
|
22
22
|
}
|
|
23
23
|
});
|
|
24
24
|
};
|
|
25
|
-
export const
|
|
25
|
+
export const checkGlobals = (_) => {
|
|
26
26
|
return tryOrLog((node, accept) => {
|
|
27
27
|
if (node.$containerIndex && node.$containerIndex > 0) {
|
|
28
28
|
accept("warning", `Prefer one global block per document`, {
|
|
@@ -32,7 +32,7 @@ export const globalsChecks = (_) => {
|
|
|
32
32
|
}
|
|
33
33
|
});
|
|
34
34
|
};
|
|
35
|
-
export const
|
|
35
|
+
export const checkElementKind = (services) => {
|
|
36
36
|
const index = services.shared.workspace.IndexManager;
|
|
37
37
|
return tryOrLog((node, accept) => {
|
|
38
38
|
if (RESERVED_WORDS.includes(node.name)) {
|
|
@@ -63,7 +63,7 @@ export const elementKindChecks = (services) => {
|
|
|
63
63
|
}
|
|
64
64
|
});
|
|
65
65
|
};
|
|
66
|
-
export const
|
|
66
|
+
export const checkDeploymentNodeKind = (services) => {
|
|
67
67
|
const index = services.shared.workspace.IndexManager;
|
|
68
68
|
return tryOrLog((node, accept) => {
|
|
69
69
|
if (RESERVED_WORDS.includes(node.name)) {
|
|
@@ -94,7 +94,7 @@ export const deploymentNodeKindChecks = (services) => {
|
|
|
94
94
|
}
|
|
95
95
|
});
|
|
96
96
|
};
|
|
97
|
-
export const
|
|
97
|
+
export const checkTag = (services) => {
|
|
98
98
|
const index = services.shared.workspace.IndexManager;
|
|
99
99
|
return tryOrLog((node, accept) => {
|
|
100
100
|
const tagname = "#" + node.name;
|
|
@@ -124,7 +124,7 @@ export const tagChecks = (services) => {
|
|
|
124
124
|
}
|
|
125
125
|
});
|
|
126
126
|
};
|
|
127
|
-
export const
|
|
127
|
+
export const checkRelationshipKind = (services) => {
|
|
128
128
|
const index = services.shared.workspace.IndexManager;
|
|
129
129
|
return tryOrLog((node, accept) => {
|
|
130
130
|
if (RESERVED_WORDS.includes(node.name)) {
|
|
@@ -143,7 +143,7 @@ export const relationshipChecks = (services) => {
|
|
|
143
143
|
}
|
|
144
144
|
});
|
|
145
145
|
};
|
|
146
|
-
export const
|
|
146
|
+
export const checkGlobalPredicate = (services) => {
|
|
147
147
|
const index = services.shared.workspace.IndexManager;
|
|
148
148
|
return tryOrLog((node, accept) => {
|
|
149
149
|
const projectId = projectIdFrom(node);
|
|
@@ -158,7 +158,7 @@ export const globalPredicateChecks = (services) => {
|
|
|
158
158
|
}
|
|
159
159
|
});
|
|
160
160
|
};
|
|
161
|
-
export const
|
|
161
|
+
export const checkGlobalStyleId = (services) => {
|
|
162
162
|
const index = services.shared.workspace.IndexManager;
|
|
163
163
|
return tryOrLog((node, accept) => {
|
|
164
164
|
const projectId = projectIdFrom(node);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import type { ValidationCheck } from 'langium';
|
|
2
2
|
import { ast } from '../../ast';
|
|
3
3
|
import type { LikeC4Services } from '../../module';
|
|
4
|
-
export declare const
|
|
4
|
+
export declare const checkFqnExprWith: (services: LikeC4Services) => ValidationCheck<ast.FqnExprWith>;
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { FqnExpr, nonexhaustive } from "@likec4/core";
|
|
2
|
+
import { AstUtils } from "langium";
|
|
3
|
+
import { getViewRulePredicateContainer } from "../../ast.js";
|
|
4
|
+
import { tryOrLog } from "../_shared.js";
|
|
5
|
+
export const checkFqnExprWith = (services) => {
|
|
6
|
+
const modelParser = services.likec4.ModelParser;
|
|
7
|
+
return tryOrLog((el, accept) => {
|
|
8
|
+
const container = getViewRulePredicateContainer(el);
|
|
9
|
+
if (container?.$type !== "DynamicViewIncludePredicate" && container?.isInclude !== true) {
|
|
10
|
+
accept("error", 'Invalid usage inside "exclude"', {
|
|
11
|
+
node: el
|
|
12
|
+
});
|
|
13
|
+
return;
|
|
14
|
+
}
|
|
15
|
+
const isInsideDynamicView = container.$type === "DynamicViewIncludePredicate";
|
|
16
|
+
const parser = modelParser.forDocument(AstUtils.getDocument(container));
|
|
17
|
+
let expr = FqnExpr.unwrap(parser.parseFqnExprWith(el).custom.expr);
|
|
18
|
+
switch (true) {
|
|
19
|
+
case (FqnExpr.isWildcard(expr) && isInsideDynamicView):
|
|
20
|
+
case (FqnExpr.isElementKindExpr(expr) && isInsideDynamicView):
|
|
21
|
+
case (FqnExpr.isElementTagExpr(expr) && isInsideDynamicView): {
|
|
22
|
+
accept("warning", `Predicate is ignored, as not supported in dynamic views`, {
|
|
23
|
+
node: el
|
|
24
|
+
});
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
case FqnExpr.isWildcard(expr):
|
|
28
|
+
case FqnExpr.isModelRef(expr):
|
|
29
|
+
case FqnExpr.isDeploymentRef(expr):
|
|
30
|
+
return;
|
|
31
|
+
case FqnExpr.isElementKindExpr(expr):
|
|
32
|
+
case FqnExpr.isElementTagExpr(expr):
|
|
33
|
+
accept("error", "Invalid target (expect reference to specific element)", {
|
|
34
|
+
node: el,
|
|
35
|
+
property: "subject"
|
|
36
|
+
});
|
|
37
|
+
return;
|
|
38
|
+
default:
|
|
39
|
+
nonexhaustive(expr);
|
|
40
|
+
}
|
|
41
|
+
});
|
|
42
|
+
};
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { FqnExpr, FqnRef } from "@likec4/core";
|
|
2
|
+
import { AstUtils } from "langium";
|
|
3
|
+
import { isTruthy } from "remeda";
|
|
4
|
+
import { ast, getViewRulePredicateContainer, isFqnRefInsideDeployment } from "../../ast.js";
|
|
5
|
+
import { tryOrLog } from "../_shared.js";
|
|
6
|
+
export const checkFqnRefExpr = (services) => {
|
|
7
|
+
const modelParser = services.likec4.ModelParser;
|
|
8
|
+
return tryOrLog((node, accept) => {
|
|
9
|
+
const parser = modelParser.forDocument(AstUtils.getDocument(node));
|
|
10
|
+
const expr = parser.parseFqnRefExpr(node);
|
|
11
|
+
const viewRulePredicate = getViewRulePredicateContainer(node);
|
|
12
|
+
const isInsideDeploymentButNotStyle = isFqnRefInsideDeployment(node) && !AstUtils.hasContainerOfType(
|
|
13
|
+
node,
|
|
14
|
+
(n) => ast.isDeploymentViewRuleStyle(n) || ast.isViewRuleStyle(n)
|
|
15
|
+
);
|
|
16
|
+
if (viewRulePredicate?.$type === "DeploymentViewRulePredicate" || isInsideDeploymentButNotStyle) {
|
|
17
|
+
const isPartOfRelationExpr = AstUtils.hasContainerOfType(node, ast.isRelationExpr);
|
|
18
|
+
if (!isPartOfRelationExpr) {
|
|
19
|
+
if (FqnExpr.isModelRef(expr)) {
|
|
20
|
+
accept("error", "Deployment view predicate must reference deployment model", {
|
|
21
|
+
node
|
|
22
|
+
});
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
if (FqnExpr.isDeploymentRef(expr) && FqnRef.isInsideInstanceRef(expr.ref)) {
|
|
26
|
+
accept("error", "Must reference deployment nodes or instances, but not internals", {
|
|
27
|
+
node
|
|
28
|
+
});
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
if (isTruthy(node.selector) && !ast.isDeploymentNode(node.ref.value?.ref)) {
|
|
33
|
+
accept("warning", `Selector '${node.selector}' applies to deployment nodes only, ignored here`, {
|
|
34
|
+
node,
|
|
35
|
+
property: "selector"
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
if (viewRulePredicate?.$type === "DynamicViewIncludePredicate") {
|
|
41
|
+
switch (true) {
|
|
42
|
+
case FqnExpr.isElementKindExpr(expr):
|
|
43
|
+
case FqnExpr.isElementTagExpr(expr):
|
|
44
|
+
case FqnExpr.isWildcard(expr): {
|
|
45
|
+
accept("warning", `Predicate is ignored, as not supported in dynamic views`, {
|
|
46
|
+
node
|
|
47
|
+
});
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import { type ValidationCheck } from 'langium';
|
|
2
2
|
import { ast } from '../../ast';
|
|
3
3
|
import type { LikeC4Services } from '../../module';
|
|
4
|
-
export declare const
|
|
4
|
+
export declare const checkIncomingRelationExpr: (_services: LikeC4Services) => ValidationCheck<ast.IncomingRelationExpr>;
|
|
@@ -2,9 +2,9 @@ import { AstUtils } from "langium";
|
|
|
2
2
|
import { isNullish } from "remeda";
|
|
3
3
|
import { ast } from "../../ast.js";
|
|
4
4
|
import { tryOrLog } from "../_shared.js";
|
|
5
|
-
export const
|
|
5
|
+
export const checkIncomingRelationExpr = (_services) => {
|
|
6
6
|
return tryOrLog((el, accept) => {
|
|
7
|
-
if (
|
|
7
|
+
if (el.to.$type === "WildcardExpression" && !ast.isInOutRelationExpr(el.$container)) {
|
|
8
8
|
const view = AstUtils.getContainerOfType(el, ast.isElementView);
|
|
9
9
|
if (isNullish(view?.viewOf)) {
|
|
10
10
|
accept("warning", "Predicate is ignored as it concerns all relationships", {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
export
|
|
2
|
-
export
|
|
3
|
-
export
|
|
4
|
-
export
|
|
5
|
-
export
|
|
6
|
-
export
|
|
1
|
+
export { checkFqnExprWith } from './fqn-expr-with';
|
|
2
|
+
export { checkFqnRefExpr } from './fqn-ref-expr';
|
|
3
|
+
export { checkIncomingRelationExpr } from './incoming';
|
|
4
|
+
export { checkOutgoingRelationExpr } from './outgoing';
|
|
5
|
+
export { checkRelationExpr } from './relation-expr';
|
|
6
|
+
export { checkRelationExprWith } from './relation-with';
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
export
|
|
2
|
-
export
|
|
3
|
-
export
|
|
4
|
-
export
|
|
5
|
-
export
|
|
6
|
-
export
|
|
1
|
+
export { checkFqnExprWith } from "./fqn-expr-with.js";
|
|
2
|
+
export { checkFqnRefExpr } from "./fqn-ref-expr.js";
|
|
3
|
+
export { checkIncomingRelationExpr } from "./incoming.js";
|
|
4
|
+
export { checkOutgoingRelationExpr } from "./outgoing.js";
|
|
5
|
+
export { checkRelationExpr } from "./relation-expr.js";
|
|
6
|
+
export { checkRelationExprWith } from "./relation-with.js";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import { type ValidationCheck } from 'langium';
|
|
2
2
|
import { ast } from '../../ast';
|
|
3
3
|
import type { LikeC4Services } from '../../module';
|
|
4
|
-
export declare const
|
|
4
|
+
export declare const checkOutgoingRelationExpr: (_services: LikeC4Services) => ValidationCheck<ast.OutgoingRelationExpr>;
|
|
@@ -1,12 +1,16 @@
|
|
|
1
1
|
import { AstUtils } from "langium";
|
|
2
2
|
import { isNullish } from "remeda";
|
|
3
|
-
import { ast } from "../../ast.js";
|
|
3
|
+
import { ast, getViewRulePredicateContainer } from "../../ast.js";
|
|
4
4
|
import { tryOrLog } from "../_shared.js";
|
|
5
|
-
export const
|
|
5
|
+
export const checkOutgoingRelationExpr = (_services) => {
|
|
6
6
|
return tryOrLog((el, accept) => {
|
|
7
|
-
|
|
7
|
+
const viewRulePredicate = getViewRulePredicateContainer(el);
|
|
8
|
+
if (viewRulePredicate?.$type !== "ViewRulePredicate") {
|
|
9
|
+
return;
|
|
10
|
+
}
|
|
11
|
+
if (el.$container.$type !== "DirectedRelationExpr" && el.from.$type === "WildcardExpression") {
|
|
8
12
|
const view = AstUtils.getContainerOfType(el, ast.isElementView);
|
|
9
|
-
if (isNullish(view
|
|
13
|
+
if (view && isNullish(view.viewOf)) {
|
|
10
14
|
accept("warning", "Predicate is ignored as it concerns all relationships", {
|
|
11
15
|
node: el
|
|
12
16
|
});
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import { type ValidationCheck } from 'langium';
|
|
2
2
|
import { ast } from '../../ast';
|
|
3
3
|
import type { LikeC4Services } from '../../module';
|
|
4
|
-
export declare const
|
|
4
|
+
export declare const checkRelationExpr: (services: LikeC4Services) => ValidationCheck<ast.RelationExpr>;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { FqnExpr, RelationExpr } from "@likec4/core";
|
|
2
|
+
import { AstUtils } from "langium";
|
|
3
|
+
import { ast } from "../../ast.js";
|
|
4
|
+
import { tryOrLog } from "../_shared.js";
|
|
5
|
+
export const checkRelationExpr = (services) => {
|
|
6
|
+
const ModelParser = services.likec4.ModelParser;
|
|
7
|
+
return tryOrLog((node, accept) => {
|
|
8
|
+
const predicate = AstUtils.getContainerOfType(node, ast.isDeploymentViewRulePredicate);
|
|
9
|
+
if (!predicate || predicate.isInclude !== true) {
|
|
10
|
+
return;
|
|
11
|
+
}
|
|
12
|
+
const doc = AstUtils.getDocument(node);
|
|
13
|
+
const parser = ModelParser.forDocument(doc);
|
|
14
|
+
let relationExpr = RelationExpr.unwrap(parser.parseRelationExpr(node));
|
|
15
|
+
const ModelRefOnlyExclude = "Model reference is allowed in exclude predicate only";
|
|
16
|
+
if (RelationExpr.isDirect(relationExpr)) {
|
|
17
|
+
if (FqnExpr.isModelRef(relationExpr.source) || FqnExpr.isModelRef(relationExpr.target)) {
|
|
18
|
+
accept("error", ModelRefOnlyExclude, {
|
|
19
|
+
node
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
let expr;
|
|
25
|
+
if (RelationExpr.isIncoming(relationExpr)) {
|
|
26
|
+
expr = relationExpr.incoming;
|
|
27
|
+
} else if (RelationExpr.isOutgoing(relationExpr)) {
|
|
28
|
+
expr = relationExpr.outgoing;
|
|
29
|
+
} else {
|
|
30
|
+
expr = relationExpr.inout;
|
|
31
|
+
}
|
|
32
|
+
if (FqnExpr.isModelRef(expr)) {
|
|
33
|
+
accept("error", ModelRefOnlyExclude, {
|
|
34
|
+
node
|
|
35
|
+
});
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
});
|
|
39
|
+
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import { type ValidationCheck } from 'langium';
|
|
2
2
|
import { ast } from '../../ast';
|
|
3
3
|
import type { LikeC4Services } from '../../module';
|
|
4
|
-
export declare const
|
|
4
|
+
export declare const checkRelationExprWith: (_services: LikeC4Services) => ValidationCheck<ast.RelationExprWith>;
|
|
@@ -1,13 +1,16 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { ast } from "../../ast.js";
|
|
1
|
+
import { getViewRulePredicateContainer } from "../../ast.js";
|
|
3
2
|
import { tryOrLog } from "../_shared.js";
|
|
4
|
-
export const
|
|
3
|
+
export const checkRelationExprWith = (_services) => {
|
|
5
4
|
return tryOrLog((el, accept) => {
|
|
6
|
-
const container =
|
|
7
|
-
if (
|
|
5
|
+
const container = getViewRulePredicateContainer(el);
|
|
6
|
+
if (!container || container.$type == "DynamicViewIncludePredicate") {
|
|
7
|
+
return;
|
|
8
|
+
}
|
|
9
|
+
if (!container.isInclude) {
|
|
8
10
|
accept("error", 'Invalid usage inside "exclude"', {
|
|
9
11
|
node: el
|
|
10
12
|
});
|
|
13
|
+
return;
|
|
11
14
|
}
|
|
12
15
|
});
|
|
13
16
|
};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { type AstNode, type AstNodeDescription, type LangiumDocument, DefaultAstNodeDescriptionProvider } from 'langium';
|
|
2
2
|
import type { LikeC4Services } from '../module';
|
|
3
3
|
export declare class AstNodeDescriptionProvider extends DefaultAstNodeDescriptionProvider {
|
|
4
|
-
|
|
4
|
+
protected services: LikeC4Services;
|
|
5
5
|
constructor(services: LikeC4Services);
|
|
6
6
|
createDescription(node: AstNode, name: string | undefined, document?: LangiumDocument): AstNodeDescription;
|
|
7
7
|
}
|
|
@@ -3,15 +3,14 @@ import {
|
|
|
3
3
|
DefaultAstNodeDescriptionProvider
|
|
4
4
|
} from "langium";
|
|
5
5
|
export class AstNodeDescriptionProvider extends DefaultAstNodeDescriptionProvider {
|
|
6
|
-
projects;
|
|
7
6
|
constructor(services) {
|
|
8
7
|
super(services);
|
|
9
|
-
this.
|
|
8
|
+
this.services = services;
|
|
10
9
|
}
|
|
11
10
|
createDescription(node, name, document) {
|
|
12
11
|
const doc = document ?? AstUtils.getDocument(node);
|
|
13
12
|
const description = super.createDescription(node, name, document);
|
|
14
|
-
doc.likec4ProjectId ??= this.
|
|
13
|
+
doc.likec4ProjectId ??= this.services.shared.workspace.ProjectsManager.belongsTo(doc.uri);
|
|
15
14
|
description.likec4ProjectId = doc.likec4ProjectId;
|
|
16
15
|
return description;
|
|
17
16
|
}
|
|
@@ -3,7 +3,7 @@ import { type AstNodeDescription, type LangiumDocument, type Stream, DefaultInde
|
|
|
3
3
|
import { CancellationToken } from 'vscode-jsonrpc';
|
|
4
4
|
import type { LikeC4SharedServices } from '../module';
|
|
5
5
|
export declare class IndexManager extends DefaultIndexManager {
|
|
6
|
-
|
|
6
|
+
protected services: LikeC4SharedServices;
|
|
7
7
|
constructor(services: LikeC4SharedServices);
|
|
8
8
|
updateContent(document: LangiumDocument, cancelToken?: CancellationToken): Promise<void>;
|
|
9
9
|
projectElements(projectId: ProjectId, nodeType?: string, uris?: Set<string>): Stream<AstNodeDescription>;
|