@likec4/language-server 0.37.1 → 0.41.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/contrib/likec4.monarch.ts +5 -5
- package/contrib/likec4.tmLanguage.json +1 -1
- package/dist/Rpc.d.ts +7 -0
- package/dist/Rpc.js +130 -0
- package/dist/ast.d.ts +20 -0
- package/dist/ast.js +169 -141
- package/dist/elementRef.js +31 -44
- package/dist/generated/ast.d.ts +48 -7
- package/dist/generated/ast.js +344 -315
- package/dist/generated/grammar.js +2 -3177
- package/dist/generated/module.js +13 -18
- package/dist/index.js +2 -3
- package/dist/logger.js +39 -42
- package/dist/lsp/CodeLensProvider.js +28 -32
- package/dist/lsp/DocumentLinkProvider.js +26 -33
- package/dist/lsp/DocumentSymbolProvider.js +165 -167
- package/dist/lsp/HoverProvider.js +35 -48
- package/dist/lsp/SemanticTokenProvider.js +160 -201
- package/dist/lsp/index.js +5 -6
- package/dist/model/fqn-computation.js +39 -40
- package/dist/model/fqn-index.js +117 -141
- package/dist/model/index.js +5 -6
- package/dist/model/model-builder.d.ts +10 -5
- package/dist/model/model-builder.js +247 -176
- package/dist/model/model-locator.d.ts +1 -1
- package/dist/model/model-locator.js +102 -100
- package/dist/model/model-parser.d.ts +2 -6
- package/dist/model/model-parser.js +284 -286
- package/dist/module.d.ts +4 -1
- package/dist/module.js +69 -60
- package/dist/protocol.d.ts +16 -19
- package/dist/protocol.js +14 -22
- package/dist/references/index.js +2 -3
- package/dist/references/scope-computation.js +72 -69
- package/dist/references/scope-provider.js +126 -116
- package/dist/shared/WorkspaceManager.d.ts +2 -3
- package/dist/shared/WorkspaceManager.js +13 -16
- package/dist/shared/index.js +1 -2
- package/dist/test/index.js +1 -2
- package/dist/test/testServices.js +73 -61
- package/dist/utils.d.ts +1 -0
- package/dist/utils.js +4 -3
- package/dist/validation/element.d.ts +1 -0
- package/dist/validation/element.js +31 -38
- package/dist/validation/index.js +37 -46
- package/dist/validation/relation.js +46 -46
- package/dist/validation/specification.d.ts +1 -0
- package/dist/validation/specification.js +33 -30
- package/dist/validation/view.js +16 -22
- package/dist/view-utils/assignNavigateTo.d.ts +3 -0
- package/dist/view-utils/assignNavigateTo.js +20 -0
- package/dist/view-utils/index.d.ts +4 -0
- package/dist/view-utils/index.js +3 -0
- package/dist/view-utils/resolve-extended-views.d.ts +7 -0
- package/dist/view-utils/resolve-extended-views.js +41 -0
- package/dist/view-utils/resolve-relative-paths.d.ts +3 -0
- package/dist/view-utils/resolve-relative-paths.js +76 -0
- package/package.json +33 -18
- package/dist/registerProtocolHandlers.d.ts +0 -3
- package/dist/registerProtocolHandlers.js +0 -112
|
@@ -1,14 +1,13 @@
|
|
|
1
|
-
import type { LangiumDocument
|
|
1
|
+
import type { LangiumDocument } from 'langium';
|
|
2
2
|
import { DefaultWorkspaceManager } from 'langium';
|
|
3
3
|
import type { WorkspaceFolder } from 'vscode-languageserver';
|
|
4
4
|
export declare class LikeC4WorkspaceManager extends DefaultWorkspaceManager {
|
|
5
|
-
protected readonly documentFactory: LangiumDocumentFactory;
|
|
6
|
-
constructor(services: LangiumSharedServices);
|
|
7
5
|
/**
|
|
8
6
|
* Load all additional documents that shall be visible in the context of the given workspace
|
|
9
7
|
* folders and add them to the collector. This can be used to include built-in libraries of
|
|
10
8
|
* your language, which can be either loaded from provided files or constructed in memory.
|
|
11
9
|
*/
|
|
12
10
|
protected loadAdditionalDocuments(_folders: WorkspaceFolder[], _collector: (document: LangiumDocument) => void): Promise<void>;
|
|
11
|
+
workspace(): WorkspaceFolder | null;
|
|
13
12
|
}
|
|
14
13
|
//# sourceMappingURL=WorkspaceManager.d.ts.map
|
|
@@ -1,18 +1,15 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { nonNullable } from "@likec4/core";
|
|
2
|
+
import { DefaultWorkspaceManager } from "langium";
|
|
2
3
|
export class LikeC4WorkspaceManager extends DefaultWorkspaceManager {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
// collector(this.documentFactory.fromString(builtin.specification.document, URI.parse(builtin.specification.uri)))
|
|
15
|
-
return Promise.resolve();
|
|
16
|
-
}
|
|
4
|
+
/**
|
|
5
|
+
* Load all additional documents that shall be visible in the context of the given workspace
|
|
6
|
+
* folders and add them to the collector. This can be used to include built-in libraries of
|
|
7
|
+
* your language, which can be either loaded from provided files or constructed in memory.
|
|
8
|
+
*/
|
|
9
|
+
loadAdditionalDocuments(_folders, _collector) {
|
|
10
|
+
return Promise.resolve();
|
|
11
|
+
}
|
|
12
|
+
workspace() {
|
|
13
|
+
return this.folders && this.folders.length > 0 ? nonNullable(this.folders[0]) : null;
|
|
14
|
+
}
|
|
17
15
|
}
|
|
18
|
-
//# sourceMappingURL=WorkspaceManager.js.map
|
package/dist/shared/index.js
CHANGED
|
@@ -1,2 +1 @@
|
|
|
1
|
-
export * from
|
|
2
|
-
//# sourceMappingURL=index.js.map
|
|
1
|
+
export * from "./WorkspaceManager.js";
|
package/dist/test/index.js
CHANGED
|
@@ -1,2 +1 @@
|
|
|
1
|
-
export * from
|
|
2
|
-
//# sourceMappingURL=index.js.map
|
|
1
|
+
export * from "./testServices.js";
|
|
@@ -1,65 +1,77 @@
|
|
|
1
|
-
import { createLanguageServices } from
|
|
2
|
-
import { EmptyFileSystem } from
|
|
3
|
-
import { URI, Utils } from
|
|
4
|
-
import stripIndent from
|
|
5
|
-
export function createTestServices(workspace =
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
const
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
const buildModel = async () => {
|
|
51
|
-
await validateAll();
|
|
52
|
-
const model = modelBuilder.buildModel();
|
|
53
|
-
if (!model)
|
|
54
|
-
throw new Error('No model found');
|
|
55
|
-
return model;
|
|
1
|
+
import { createLanguageServices } from "../module.js";
|
|
2
|
+
import { EmptyFileSystem } from "langium";
|
|
3
|
+
import { URI, Utils } from "vscode-uri";
|
|
4
|
+
import stripIndent from "strip-indent";
|
|
5
|
+
export function createTestServices(workspace = "file:///test/workspace") {
|
|
6
|
+
const services = createLanguageServices(EmptyFileSystem).likec4;
|
|
7
|
+
const metaData = services.LanguageMetaData;
|
|
8
|
+
const langiumDocuments = services.shared.workspace.LangiumDocuments;
|
|
9
|
+
const documentBuilder = services.shared.workspace.DocumentBuilder;
|
|
10
|
+
const modelBuilder = services.likec4.ModelBuilder;
|
|
11
|
+
const workspaceUri = URI.parse(workspace);
|
|
12
|
+
const workspaceFolder = {
|
|
13
|
+
name: "test",
|
|
14
|
+
uri: workspaceUri.toString()
|
|
15
|
+
};
|
|
16
|
+
const initPromise = services.shared.workspace.WorkspaceManager.initializeWorkspace([
|
|
17
|
+
workspaceFolder
|
|
18
|
+
]);
|
|
19
|
+
void initPromise.finally(() => {
|
|
20
|
+
Object.assign(services.shared.workspace.WorkspaceManager, {
|
|
21
|
+
folders: [workspaceFolder]
|
|
22
|
+
});
|
|
23
|
+
});
|
|
24
|
+
let documentIndex = 1;
|
|
25
|
+
const parse = async (input, uri) => {
|
|
26
|
+
await initPromise;
|
|
27
|
+
const docUri = Utils.resolvePath(
|
|
28
|
+
workspaceUri,
|
|
29
|
+
"./src/",
|
|
30
|
+
uri ?? `${documentIndex++}${metaData.fileExtensions[0]}`
|
|
31
|
+
);
|
|
32
|
+
const document = services.shared.workspace.LangiumDocumentFactory.fromString(
|
|
33
|
+
stripIndent(input),
|
|
34
|
+
docUri
|
|
35
|
+
);
|
|
36
|
+
langiumDocuments.addDocument(document);
|
|
37
|
+
await documentBuilder.build([document], { validation: false });
|
|
38
|
+
return document;
|
|
39
|
+
};
|
|
40
|
+
const validate = async (input, uri) => {
|
|
41
|
+
await initPromise;
|
|
42
|
+
const document = typeof input === "string" ? await parse(input, uri) : input;
|
|
43
|
+
await documentBuilder.build([document], { validation: true });
|
|
44
|
+
const diagnostics = document.diagnostics ?? [];
|
|
45
|
+
const errors = diagnostics.map((d) => d.message);
|
|
46
|
+
return {
|
|
47
|
+
document,
|
|
48
|
+
diagnostics,
|
|
49
|
+
errors
|
|
56
50
|
};
|
|
51
|
+
};
|
|
52
|
+
const validateAll = async () => {
|
|
53
|
+
await initPromise;
|
|
54
|
+
const docs = langiumDocuments.all.toArray();
|
|
55
|
+
await documentBuilder.build(docs, { validation: true });
|
|
56
|
+
const diagnostics = docs.flatMap((doc) => doc.diagnostics ?? []);
|
|
57
|
+
const errors = diagnostics.map((d) => d.message);
|
|
57
58
|
return {
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
validate,
|
|
61
|
-
validateAll,
|
|
62
|
-
buildModel
|
|
59
|
+
diagnostics,
|
|
60
|
+
errors
|
|
63
61
|
};
|
|
62
|
+
};
|
|
63
|
+
const buildModel = async () => {
|
|
64
|
+
await validateAll();
|
|
65
|
+
const model = modelBuilder.buildModel();
|
|
66
|
+
if (!model)
|
|
67
|
+
throw new Error("No model found");
|
|
68
|
+
return model;
|
|
69
|
+
};
|
|
70
|
+
return {
|
|
71
|
+
services,
|
|
72
|
+
parse,
|
|
73
|
+
validate,
|
|
74
|
+
validateAll,
|
|
75
|
+
buildModel
|
|
76
|
+
};
|
|
64
77
|
}
|
|
65
|
-
//# sourceMappingURL=testServices.js.map
|
package/dist/utils.d.ts
CHANGED
package/dist/utils.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
export
|
|
3
|
-
|
|
1
|
+
export const printDocs = (docs) => docs.map((d) => " - " + d.uri.path).join("\n");
|
|
2
|
+
export function queueMicrotask(cb) {
|
|
3
|
+
return Promise.resolve().then(cb);
|
|
4
|
+
}
|
|
@@ -1,41 +1,34 @@
|
|
|
1
|
-
import { getDocument } from
|
|
1
|
+
import { getDocument } from "langium";
|
|
2
2
|
export const elementChecks = (services) => {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
3
|
+
const fqnIndex = services.likec4.FqnIndex;
|
|
4
|
+
return (el, accept) => {
|
|
5
|
+
const fqn = fqnIndex.getFqn(el);
|
|
6
|
+
if (!fqn) {
|
|
7
|
+
accept("error", "Not indexed element", {
|
|
8
|
+
node: el,
|
|
9
|
+
property: "name"
|
|
10
|
+
});
|
|
11
|
+
return;
|
|
12
|
+
}
|
|
13
|
+
const withSameFqn = fqnIndex.byFqn(fqn).filter((v) => v.el !== el).head();
|
|
14
|
+
if (withSameFqn) {
|
|
15
|
+
accept(
|
|
16
|
+
"error",
|
|
17
|
+
`Duplicate element name ${el.name !== fqn ? el.name + " (" + fqn + ")" : el.name}`,
|
|
18
|
+
{
|
|
19
|
+
node: el,
|
|
20
|
+
property: "name",
|
|
21
|
+
relatedInformation: [
|
|
22
|
+
{
|
|
23
|
+
location: {
|
|
24
|
+
range: withSameFqn.el.$cstNode.range,
|
|
25
|
+
uri: getDocument(withSameFqn.el).uri.toString()
|
|
26
|
+
},
|
|
27
|
+
message: `Already defined here`
|
|
28
|
+
}
|
|
29
|
+
]
|
|
12
30
|
}
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
.head();
|
|
17
|
-
if (withSameFqn) {
|
|
18
|
-
accept('error', `Duplicate element name ${el.name !== fqn ? el.name + ' (' + fqn + ')' : el.name}`, {
|
|
19
|
-
node: el,
|
|
20
|
-
property: 'name',
|
|
21
|
-
relatedInformation: [
|
|
22
|
-
{
|
|
23
|
-
location: {
|
|
24
|
-
range: withSameFqn.el.$cstNode.range,
|
|
25
|
-
uri: getDocument(withSameFqn.el).uri.toString()
|
|
26
|
-
},
|
|
27
|
-
message: `Already defined here`
|
|
28
|
-
}
|
|
29
|
-
]
|
|
30
|
-
});
|
|
31
|
-
}
|
|
32
|
-
// for (let i = 3; i < el.props.length; i++) {
|
|
33
|
-
// accept('error', `Too many properties, max 3 allowed`, {
|
|
34
|
-
// node: el,
|
|
35
|
-
// property: 'props',
|
|
36
|
-
// index: i
|
|
37
|
-
// })
|
|
38
|
-
// }
|
|
39
|
-
};
|
|
31
|
+
);
|
|
32
|
+
}
|
|
33
|
+
};
|
|
40
34
|
};
|
|
41
|
-
//# sourceMappingURL=element.js.map
|
package/dist/validation/index.js
CHANGED
|
@@ -1,49 +1,40 @@
|
|
|
1
|
-
import
|
|
2
|
-
import { logger } from
|
|
3
|
-
import { elementChecks } from
|
|
4
|
-
import { relationChecks } from
|
|
5
|
-
import { elementKindChecks, tagChecks } from
|
|
6
|
-
import { viewChecks } from
|
|
1
|
+
import * as vscodeUri from "vscode-uri";
|
|
2
|
+
import { logger } from "../logger.js";
|
|
3
|
+
import { elementChecks } from "./element.js";
|
|
4
|
+
import { relationChecks } from "./relation.js";
|
|
5
|
+
import { elementKindChecks, tagChecks, relationshipChecks } from "./specification.js";
|
|
6
|
+
import { viewChecks } from "./view.js";
|
|
7
7
|
export function registerValidationChecks(services) {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
message.push(` deleted:`);
|
|
37
|
-
deleted.forEach(u => message.push(` - ${Utils.basename(u)}`));
|
|
38
|
-
}
|
|
39
|
-
logger.debug(message.join('\n'));
|
|
40
|
-
for (const uri of deleted) {
|
|
41
|
-
void connection.sendDiagnostics({
|
|
42
|
-
uri: uri.toString(),
|
|
43
|
-
diagnostics: []
|
|
44
|
-
});
|
|
45
|
-
}
|
|
8
|
+
logger.info("registerValidationChecks");
|
|
9
|
+
const registry = services.validation.ValidationRegistry;
|
|
10
|
+
registry.register({
|
|
11
|
+
ElementView: viewChecks(services),
|
|
12
|
+
Element: elementChecks(services),
|
|
13
|
+
ElementKind: elementKindChecks(services),
|
|
14
|
+
Relation: relationChecks(services),
|
|
15
|
+
Tag: tagChecks(services),
|
|
16
|
+
RelationshipKind: relationshipChecks(services)
|
|
17
|
+
});
|
|
18
|
+
const connection = services.shared.lsp.Connection;
|
|
19
|
+
if (connection) {
|
|
20
|
+
logger.info("registerValidationChecks");
|
|
21
|
+
services.shared.workspace.DocumentBuilder.onUpdate((changed, deleted) => {
|
|
22
|
+
const message = [`[DocumentBuilder.onUpdate]`];
|
|
23
|
+
if (changed.length > 0) {
|
|
24
|
+
message.push(` changed:`);
|
|
25
|
+
changed.forEach((u) => message.push(` - ${vscodeUri.Utils.basename(u)}`));
|
|
26
|
+
}
|
|
27
|
+
if (deleted.length > 0) {
|
|
28
|
+
message.push(` deleted:`);
|
|
29
|
+
deleted.forEach((u) => message.push(` - ${vscodeUri.Utils.basename(u)}`));
|
|
30
|
+
}
|
|
31
|
+
logger.debug(message.join("\n"));
|
|
32
|
+
for (const uri of deleted) {
|
|
33
|
+
void connection.sendDiagnostics({
|
|
34
|
+
uri: uri.toString(),
|
|
35
|
+
diagnostics: []
|
|
46
36
|
});
|
|
47
|
-
|
|
37
|
+
}
|
|
38
|
+
});
|
|
39
|
+
}
|
|
48
40
|
}
|
|
49
|
-
//# sourceMappingURL=index.js.map
|
|
@@ -1,50 +1,50 @@
|
|
|
1
|
-
import { isSameHierarchy } from
|
|
2
|
-
import { ast } from
|
|
3
|
-
import { elementRef } from
|
|
4
|
-
import { logError } from
|
|
1
|
+
import { isSameHierarchy } from "@likec4/core";
|
|
2
|
+
import { ast } from "../ast.js";
|
|
3
|
+
import { elementRef } from "../elementRef.js";
|
|
4
|
+
import { logError } from "../logger.js";
|
|
5
5
|
export const relationChecks = (services) => {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
6
|
+
const fqnIndex = services.likec4.FqnIndex;
|
|
7
|
+
return (el, accept) => {
|
|
8
|
+
try {
|
|
9
|
+
const targetEl = elementRef(el.target);
|
|
10
|
+
const target = targetEl && fqnIndex.getFqn(targetEl);
|
|
11
|
+
if (!target) {
|
|
12
|
+
accept("error", "Target not found (not parsed/indexed yet)", {
|
|
13
|
+
node: el,
|
|
14
|
+
property: "target"
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
let sourceEl;
|
|
18
|
+
if ("source" in el) {
|
|
19
|
+
sourceEl = elementRef(el.source);
|
|
20
|
+
} else {
|
|
21
|
+
if (!ast.isElementBody(el.$container)) {
|
|
22
|
+
accept(
|
|
23
|
+
"error",
|
|
24
|
+
"Invalid relation, expected to have source defined or be inside the element",
|
|
25
|
+
{
|
|
26
|
+
node: el,
|
|
27
|
+
keyword: "->"
|
|
16
28
|
}
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
}
|
|
21
|
-
else {
|
|
22
|
-
if (!ast.isElementBody(el.$container)) {
|
|
23
|
-
accept('error', 'Invalid relation, expected to have source defined or be inside the element', {
|
|
24
|
-
node: el,
|
|
25
|
-
keyword: '->'
|
|
26
|
-
});
|
|
27
|
-
}
|
|
28
|
-
else {
|
|
29
|
-
sourceEl = el.$container.$container;
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
const source = sourceEl && fqnIndex.getFqn(sourceEl);
|
|
33
|
-
if (sourceEl && !source) {
|
|
34
|
-
accept('error', 'Source not found (not parsed/indexed yet)', {
|
|
35
|
-
node: el,
|
|
36
|
-
property: 'source'
|
|
37
|
-
});
|
|
38
|
-
}
|
|
39
|
-
if (source && target && isSameHierarchy(source, target)) {
|
|
40
|
-
return accept('error', 'Invalid parent-child relationship', {
|
|
41
|
-
node: el
|
|
42
|
-
});
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
catch (e) {
|
|
46
|
-
logError(e);
|
|
29
|
+
);
|
|
30
|
+
} else {
|
|
31
|
+
sourceEl = el.$container.$container;
|
|
47
32
|
}
|
|
48
|
-
|
|
33
|
+
}
|
|
34
|
+
const source = sourceEl && fqnIndex.getFqn(sourceEl);
|
|
35
|
+
if (sourceEl && !source) {
|
|
36
|
+
accept("error", "Source not found (not parsed/indexed yet)", {
|
|
37
|
+
node: el,
|
|
38
|
+
property: "source"
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
if (source && target && isSameHierarchy(source, target)) {
|
|
42
|
+
return accept("error", "Invalid parent-child relationship", {
|
|
43
|
+
node: el
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
} catch (e) {
|
|
47
|
+
logError(e);
|
|
48
|
+
}
|
|
49
|
+
};
|
|
49
50
|
};
|
|
50
|
-
//# sourceMappingURL=relation.js.map
|
|
@@ -3,4 +3,5 @@ import { ast } from '../ast';
|
|
|
3
3
|
import type { LikeC4Services } from '../module';
|
|
4
4
|
export declare const elementKindChecks: (services: LikeC4Services) => ValidationCheck<ast.ElementKind>;
|
|
5
5
|
export declare const tagChecks: (services: LikeC4Services) => ValidationCheck<ast.Tag>;
|
|
6
|
+
export declare const relationshipChecks: (services: LikeC4Services) => ValidationCheck<ast.RelationshipKind>;
|
|
6
7
|
//# sourceMappingURL=specification.d.ts.map
|
|
@@ -1,34 +1,37 @@
|
|
|
1
|
-
import { ast } from
|
|
1
|
+
import { ast } from "../ast.js";
|
|
2
2
|
export const elementKindChecks = (services) => {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
property: 'name'
|
|
14
|
-
});
|
|
15
|
-
}
|
|
16
|
-
};
|
|
3
|
+
const index = services.shared.workspace.IndexManager;
|
|
4
|
+
return (node, accept) => {
|
|
5
|
+
const sameKinds = index.allElements(ast.ElementKind).filter((n) => n.name === node.name).limit(2).count();
|
|
6
|
+
if (sameKinds > 1) {
|
|
7
|
+
accept("error", `Duplicate element kind '${node.name}'`, {
|
|
8
|
+
node,
|
|
9
|
+
property: "name"
|
|
10
|
+
});
|
|
11
|
+
}
|
|
12
|
+
};
|
|
17
13
|
};
|
|
18
14
|
export const tagChecks = (services) => {
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
15
|
+
const index = services.shared.workspace.IndexManager;
|
|
16
|
+
return (node, accept) => {
|
|
17
|
+
const sameKinds = index.allElements(ast.Tag).filter((n) => n.name === node.name).limit(2).count();
|
|
18
|
+
if (sameKinds > 1) {
|
|
19
|
+
accept("error", `Duplicate tag '${node.name}'`, {
|
|
20
|
+
node,
|
|
21
|
+
property: "name"
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
};
|
|
25
|
+
};
|
|
26
|
+
export const relationshipChecks = (services) => {
|
|
27
|
+
const index = services.shared.workspace.IndexManager;
|
|
28
|
+
return (node, accept) => {
|
|
29
|
+
const sameKinds = index.allElements(ast.RelationshipKind).filter((n) => n.name === node.name).limit(2).count();
|
|
30
|
+
if (sameKinds > 1) {
|
|
31
|
+
accept("error", `Duplicate RelationshipKind '${node.name}'`, {
|
|
32
|
+
node,
|
|
33
|
+
property: "name"
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
};
|
|
33
37
|
};
|
|
34
|
-
//# sourceMappingURL=specification.js.map
|
package/dist/validation/view.js
CHANGED
|
@@ -1,24 +1,18 @@
|
|
|
1
|
-
import { ast } from
|
|
1
|
+
import { ast } from "../ast.js";
|
|
2
2
|
export const viewChecks = (services) => {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
node: el,
|
|
19
|
-
property: 'name'
|
|
20
|
-
});
|
|
21
|
-
}
|
|
22
|
-
};
|
|
3
|
+
const index = services.shared.workspace.IndexManager;
|
|
4
|
+
return (el, accept) => {
|
|
5
|
+
if (el.extends) {
|
|
6
|
+
}
|
|
7
|
+
if (!el.name) {
|
|
8
|
+
return;
|
|
9
|
+
}
|
|
10
|
+
const anotherViews = index.allElements(ast.View).filter((n) => n.name === el.name).limit(2).count();
|
|
11
|
+
if (anotherViews > 1) {
|
|
12
|
+
accept("error", `Duplicate view '${el.name}'`, {
|
|
13
|
+
node: el,
|
|
14
|
+
property: "name"
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
};
|
|
23
18
|
};
|
|
24
|
-
//# sourceMappingURL=view.js.map
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { find } from "remeda";
|
|
2
|
+
export function assignNavigateTo(views) {
|
|
3
|
+
const allElementViews = /* @__PURE__ */ new Map();
|
|
4
|
+
for (const v of views) {
|
|
5
|
+
if (v.viewOf && !v.extends) {
|
|
6
|
+
const viewsOf = allElementViews.get(v.viewOf) ?? [];
|
|
7
|
+
viewsOf.push(v.id);
|
|
8
|
+
allElementViews.set(v.viewOf, viewsOf);
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
for (const { id, nodes } of views) {
|
|
12
|
+
for (const node of nodes) {
|
|
13
|
+
const navigateTo = find(allElementViews.get(node.id) ?? [], (v) => v !== id);
|
|
14
|
+
if (navigateTo) {
|
|
15
|
+
node.navigateTo = navigateTo;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
return views;
|
|
20
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { type ElementView } from '@likec4/core';
|
|
2
|
+
/**
|
|
3
|
+
* Resolve rules of extended views
|
|
4
|
+
* (Removes invalid views)
|
|
5
|
+
*/
|
|
6
|
+
export declare function resolveRulesExtendedViews<V extends Record<any, ElementView>>(unresolvedViews: V): V;
|
|
7
|
+
//# sourceMappingURL=resolve-extended-views.d.ts.map
|