@likec4/language-server 0.6.2 → 0.8.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 +31 -0
- package/contrib/likec4.tmLanguage.json +73 -0
- package/dist/ast.d.ts +75 -0
- package/dist/ast.js +143 -0
- package/dist/builtin.d.ts +5 -0
- package/dist/builtin.js +9 -0
- package/dist/elementRef.d.ts +7 -0
- package/dist/elementRef.js +40 -0
- package/dist/generated/ast.d.ts +364 -0
- package/dist/generated/ast.js +389 -0
- package/dist/generated/grammar.d.ts +7 -0
- package/dist/generated/grammar.js +2548 -0
- package/dist/generated/module.d.ts +10 -0
- package/dist/generated/module.js +27 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +3 -0
- package/dist/logger.d.ts +9 -0
- package/dist/logger.js +21 -0
- package/dist/lsp/DocumentSymbolProvider.d.ts +22 -0
- package/dist/lsp/DocumentSymbolProvider.js +167 -0
- package/dist/lsp/HoverProvider.d.ts +9 -0
- package/dist/lsp/HoverProvider.js +55 -0
- package/dist/lsp/SemanticTokenProvider.d.ts +7 -0
- package/dist/lsp/SemanticTokenProvider.js +222 -0
- package/dist/lsp/index.d.ts +4 -0
- package/dist/lsp/index.js +4 -0
- package/dist/model/fqn-index.d.ts +41 -0
- package/dist/model/fqn-index.js +119 -0
- package/dist/model/index.d.ts +4 -0
- package/dist/model/index.js +4 -0
- package/dist/model/model-builder.d.ts +27 -0
- package/dist/model/model-builder.js +339 -0
- package/dist/model/model-locator.d.ts +17 -0
- package/dist/model/model-locator.js +116 -0
- package/dist/module.d.ts +21 -0
- package/dist/module.js +66 -0
- package/dist/protocol.d.ts +37 -0
- package/dist/protocol.js +20 -0
- package/dist/references/fqn-computation.d.ts +4 -0
- package/dist/references/fqn-computation.js +41 -0
- package/dist/references/index.d.ts +3 -0
- package/dist/references/index.js +3 -0
- package/dist/references/scope-computation.d.ts +14 -0
- package/dist/references/scope-computation.js +86 -0
- package/dist/references/scope-provider.d.ts +19 -0
- package/dist/references/scope-provider.js +120 -0
- package/dist/registerProtocolHandlers.d.ts +3 -0
- package/dist/registerProtocolHandlers.js +65 -0
- package/dist/shared/CodeLensProvider.d.ts +9 -0
- package/dist/shared/CodeLensProvider.js +36 -0
- package/dist/shared/WorkspaceManager.d.ts +14 -0
- package/dist/shared/WorkspaceManager.js +18 -0
- package/dist/shared/index.d.ts +3 -0
- package/dist/shared/index.js +3 -0
- package/dist/test/index.d.ts +2 -0
- package/dist/test/index.js +2 -0
- package/dist/test/testServices.d.ts +16 -0
- package/dist/test/testServices.js +58 -0
- package/dist/utils.d.ts +3 -0
- package/dist/utils.js +8 -0
- package/dist/validation/element.d.ts +6 -0
- package/dist/validation/element.js +21 -0
- package/dist/validation/index.d.ts +3 -0
- package/dist/validation/index.js +23 -0
- package/dist/validation/relation.d.ts +5 -0
- package/dist/validation/relation.js +54 -0
- package/dist/validation/specification.d.ts +6 -0
- package/dist/validation/specification.js +34 -0
- package/dist/validation/view.d.ts +5 -0
- package/dist/validation/view.js +21 -0
- package/package.json +26 -31
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { createLanguageServices } from '../module';
|
|
2
|
+
import { EmptyFileSystem } from 'langium';
|
|
3
|
+
import { URI } from 'vscode-uri';
|
|
4
|
+
export function createTestServices() {
|
|
5
|
+
const services = createLanguageServices(EmptyFileSystem).likec4;
|
|
6
|
+
const metaData = services.LanguageMetaData;
|
|
7
|
+
const langiumDocuments = services.shared.workspace.LangiumDocuments;
|
|
8
|
+
const documentBuilder = services.shared.workspace.DocumentBuilder;
|
|
9
|
+
const modelBuilder = services.likec4.ModelBuilder;
|
|
10
|
+
const initPromise = services.shared.workspace.WorkspaceManager.initializeWorkspace([]);
|
|
11
|
+
let documentIndex = 1;
|
|
12
|
+
const parse = async (input, uri) => {
|
|
13
|
+
await initPromise;
|
|
14
|
+
uri = uri ?? `${documentIndex++}${metaData.fileExtensions[0]}`;
|
|
15
|
+
const document = services.shared.workspace.LangiumDocumentFactory.fromString(input, URI.file(uri));
|
|
16
|
+
langiumDocuments.addDocument(document);
|
|
17
|
+
await documentBuilder.build([document], { validationChecks: 'none' });
|
|
18
|
+
return document;
|
|
19
|
+
};
|
|
20
|
+
const validate = async (input) => {
|
|
21
|
+
await initPromise;
|
|
22
|
+
const document = typeof input === 'string' ? await parse(input) : input;
|
|
23
|
+
await documentBuilder.build([document], { validationChecks: 'all' });
|
|
24
|
+
const diagnostics = document.diagnostics ?? [];
|
|
25
|
+
const errors = diagnostics.map(d => d.message);
|
|
26
|
+
return {
|
|
27
|
+
document,
|
|
28
|
+
diagnostics,
|
|
29
|
+
errors
|
|
30
|
+
};
|
|
31
|
+
};
|
|
32
|
+
const validateAll = async () => {
|
|
33
|
+
await initPromise;
|
|
34
|
+
const docs = langiumDocuments.all.toArray();
|
|
35
|
+
await documentBuilder.build(docs, { validationChecks: 'all' });
|
|
36
|
+
const diagnostics = docs.flatMap(doc => doc.diagnostics ?? []);
|
|
37
|
+
const errors = diagnostics.map(d => d.message);
|
|
38
|
+
return {
|
|
39
|
+
diagnostics,
|
|
40
|
+
errors
|
|
41
|
+
};
|
|
42
|
+
};
|
|
43
|
+
const buildModel = async () => {
|
|
44
|
+
await validateAll();
|
|
45
|
+
const model = modelBuilder.buildModel();
|
|
46
|
+
if (!model)
|
|
47
|
+
throw new Error('No model found');
|
|
48
|
+
return model;
|
|
49
|
+
};
|
|
50
|
+
return {
|
|
51
|
+
services,
|
|
52
|
+
parse,
|
|
53
|
+
validate,
|
|
54
|
+
validateAll,
|
|
55
|
+
buildModel
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
//# sourceMappingURL=testServices.js.map
|
package/dist/utils.d.ts
ADDED
package/dist/utils.js
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export function failExpectedNever(arg) {
|
|
2
|
+
throw new Error(`Unexpected value: ${JSON.stringify(arg)}`);
|
|
3
|
+
}
|
|
4
|
+
export function ignoreNeverInRuntime(arg) {
|
|
5
|
+
console.warn(`Unexpected and ignored value: ${JSON.stringify(arg)}`);
|
|
6
|
+
// throw new Error(`Unexpected value: ${arg}`);
|
|
7
|
+
}
|
|
8
|
+
//# sourceMappingURL=utils.js.map
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/// <reference types="react" />
|
|
2
|
+
import type { ValidationCheck } from 'langium';
|
|
3
|
+
import type { ast } from '../ast';
|
|
4
|
+
import type { LikeC4Services } from '../module';
|
|
5
|
+
export declare const elementChecks: (services: LikeC4Services) => ValidationCheck<ast.Element>;
|
|
6
|
+
//# sourceMappingURL=element.d.ts.map
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export const elementChecks = (services) => {
|
|
2
|
+
const fqnIndex = services.likec4.FqnIndex;
|
|
3
|
+
return (el, accept) => {
|
|
4
|
+
const fqn = fqnIndex.get(el);
|
|
5
|
+
if (!fqn) {
|
|
6
|
+
accept('error', 'Not indexed', {
|
|
7
|
+
node: el,
|
|
8
|
+
property: 'name'
|
|
9
|
+
});
|
|
10
|
+
return;
|
|
11
|
+
}
|
|
12
|
+
const withSameFqn = fqnIndex.byFqn(fqn).limit(2).count();
|
|
13
|
+
if (withSameFqn > 1) {
|
|
14
|
+
accept('error', `Duplicate element name ${el.name !== fqn ? el.name + ' (' + fqn + ')' : el.name}`, {
|
|
15
|
+
node: el,
|
|
16
|
+
property: 'name'
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
};
|
|
20
|
+
};
|
|
21
|
+
//# sourceMappingURL=element.js.map
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { elementChecks } from './element';
|
|
2
|
+
import { relationChecks } from './relation';
|
|
3
|
+
import { elementKindChecks, tagChecks } from './specification';
|
|
4
|
+
import { viewChecks } from './view';
|
|
5
|
+
export function registerValidationChecks(services) {
|
|
6
|
+
const registry = services.validation.ValidationRegistry;
|
|
7
|
+
// const checks: ValidationChecks = {
|
|
8
|
+
// Element: validator.checkElementNameDuplicates,
|
|
9
|
+
// Tag: validator.checkTagDuplicates,
|
|
10
|
+
// ElementKind: elementKindChecks(services),
|
|
11
|
+
// ElementStyleProperty: validator.checkElementStyleProperty,
|
|
12
|
+
// View: validator.checkViewNameDuplicates,
|
|
13
|
+
// ColorStyleProperty: validator.checkColorStyleProperty,
|
|
14
|
+
// }
|
|
15
|
+
registry.register({
|
|
16
|
+
ElementView: viewChecks(services),
|
|
17
|
+
Element: elementChecks(services),
|
|
18
|
+
ElementKind: elementKindChecks(services),
|
|
19
|
+
Relation: relationChecks(services),
|
|
20
|
+
Tag: tagChecks(services)
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { ValidationCheck } from 'langium';
|
|
2
|
+
import type { ast } from '../ast';
|
|
3
|
+
import type { LikeC4Services } from '../module';
|
|
4
|
+
export declare const relationChecks: (services: LikeC4Services) => ValidationCheck<ast.Relation>;
|
|
5
|
+
//# sourceMappingURL=relation.d.ts.map
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { resolveRelationPoints } from '../ast';
|
|
2
|
+
import { isSameHierarchy } from '@likec4/core/utils';
|
|
3
|
+
export const relationChecks = (services) => {
|
|
4
|
+
const fqnIndex = services.likec4.FqnIndex;
|
|
5
|
+
return (el, accept) => {
|
|
6
|
+
try {
|
|
7
|
+
const coupling = resolveRelationPoints(el);
|
|
8
|
+
const target = fqnIndex.get(coupling.target);
|
|
9
|
+
if (!target) {
|
|
10
|
+
return accept('error', 'Invalid target', {
|
|
11
|
+
node: el,
|
|
12
|
+
property: 'target'
|
|
13
|
+
});
|
|
14
|
+
}
|
|
15
|
+
const source = fqnIndex.get(coupling.source);
|
|
16
|
+
if (!source) {
|
|
17
|
+
return accept('error', 'Invalid source', {
|
|
18
|
+
node: el
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
if (isSameHierarchy(source, target)) {
|
|
22
|
+
return accept('error', 'Invalid relation (same hierarchy)', {
|
|
23
|
+
node: el
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
catch (e) {
|
|
28
|
+
if (e instanceof Error) {
|
|
29
|
+
return accept('error', e.message, {
|
|
30
|
+
node: el
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
accept('error', 'Invalid relation', {
|
|
34
|
+
node: el
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
// const fqn = fqnIndex.get(el)
|
|
38
|
+
// if (!fqn) {
|
|
39
|
+
// accept('error', 'Not indexed', {
|
|
40
|
+
// node: el,
|
|
41
|
+
// property: 'name',
|
|
42
|
+
// })
|
|
43
|
+
// return
|
|
44
|
+
// }
|
|
45
|
+
// const withSameFqn = fqnIndex.byFqn(fqn)
|
|
46
|
+
// if (withSameFqn.length > 1) {
|
|
47
|
+
// accept('error', `Duplicate element name ${el.name !== fqn ? el.name +' (' + fqn + ')' : el.name}`, {
|
|
48
|
+
// node: el,
|
|
49
|
+
// property: 'name',
|
|
50
|
+
// })
|
|
51
|
+
// }
|
|
52
|
+
};
|
|
53
|
+
};
|
|
54
|
+
//# sourceMappingURL=relation.js.map
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { ValidationCheck } from 'langium';
|
|
2
|
+
import { ast } from '../ast';
|
|
3
|
+
import type { LikeC4Services } from '../module';
|
|
4
|
+
export declare const elementKindChecks: (services: LikeC4Services) => ValidationCheck<ast.ElementKind>;
|
|
5
|
+
export declare const tagChecks: (services: LikeC4Services) => ValidationCheck<ast.Tag>;
|
|
6
|
+
//# sourceMappingURL=specification.d.ts.map
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { ast } from '../ast';
|
|
2
|
+
export const elementKindChecks = (services) => {
|
|
3
|
+
const index = services.shared.workspace.IndexManager;
|
|
4
|
+
return (node, accept) => {
|
|
5
|
+
const sameKinds = index
|
|
6
|
+
.allElements(ast.ElementKind)
|
|
7
|
+
.filter(n => n.name === node.name)
|
|
8
|
+
.limit(2)
|
|
9
|
+
.count();
|
|
10
|
+
if (sameKinds > 1) {
|
|
11
|
+
accept('error', `Duplicate element kind '${node.name}'`, {
|
|
12
|
+
node: node,
|
|
13
|
+
property: 'name'
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
};
|
|
17
|
+
};
|
|
18
|
+
export const tagChecks = (services) => {
|
|
19
|
+
const index = services.shared.workspace.IndexManager;
|
|
20
|
+
return (node, accept) => {
|
|
21
|
+
const sameKinds = index
|
|
22
|
+
.allElements(ast.Tag)
|
|
23
|
+
.filter(n => n.name === node.name)
|
|
24
|
+
.limit(2)
|
|
25
|
+
.count();
|
|
26
|
+
if (sameKinds > 1) {
|
|
27
|
+
accept('error', `Duplicate tag '${node.name}'`, {
|
|
28
|
+
node: node,
|
|
29
|
+
property: 'name'
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
};
|
|
33
|
+
};
|
|
34
|
+
//# sourceMappingURL=specification.js.map
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { ast } from '../ast';
|
|
2
|
+
export const viewChecks = (services) => {
|
|
3
|
+
const index = services.shared.workspace.IndexManager;
|
|
4
|
+
return (el, accept) => {
|
|
5
|
+
if (!el.name) {
|
|
6
|
+
return;
|
|
7
|
+
}
|
|
8
|
+
const anotherViews = index
|
|
9
|
+
.allElements(ast.View)
|
|
10
|
+
.filter(n => n.name === el.name)
|
|
11
|
+
.limit(2)
|
|
12
|
+
.count();
|
|
13
|
+
if (anotherViews > 1) {
|
|
14
|
+
accept('error', `Duplicate view '${el.name}'`, {
|
|
15
|
+
node: el,
|
|
16
|
+
property: 'name'
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
};
|
|
20
|
+
};
|
|
21
|
+
//# sourceMappingURL=view.js.map
|
package/package.json
CHANGED
|
@@ -1,21 +1,26 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@likec4/language-server",
|
|
3
3
|
"description": "LikeC4 Language Server",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.8.0",
|
|
5
5
|
"license": "MIT",
|
|
6
|
-
"type": "module",
|
|
7
6
|
"bugs": "https://github.com/likec4/likec4/issues",
|
|
8
|
-
"homepage": "https://
|
|
7
|
+
"homepage": "https://likec4.dev",
|
|
9
8
|
"author": "Denis Davydkov <denis@davydkov.com>",
|
|
10
9
|
"files": [
|
|
11
10
|
"dist",
|
|
12
|
-
"contrib"
|
|
11
|
+
"contrib",
|
|
12
|
+
"!**/__mocks__/",
|
|
13
|
+
"!**/__test__/",
|
|
14
|
+
"!**/*.spec.js",
|
|
15
|
+
"!**/*.spec.d.ts",
|
|
16
|
+
"!**/*.map"
|
|
13
17
|
],
|
|
14
18
|
"repository": {
|
|
15
19
|
"type": "git",
|
|
16
20
|
"url": "https://github.com/likec4/likec4.git",
|
|
17
21
|
"directory": "packages/language-server"
|
|
18
22
|
},
|
|
23
|
+
"type": "module",
|
|
19
24
|
"main": "./dist/index.js",
|
|
20
25
|
"module": "./dist/index.js",
|
|
21
26
|
"types": "./dist/index.d.ts",
|
|
@@ -23,12 +28,12 @@
|
|
|
23
28
|
".": {
|
|
24
29
|
"types": "./dist/index.d.ts",
|
|
25
30
|
"import": "./dist/index.js",
|
|
26
|
-
"require": "./dist/index.
|
|
31
|
+
"require": "./dist/index.js"
|
|
27
32
|
},
|
|
28
33
|
"./builtin": {
|
|
29
34
|
"types": "./dist/builtin.d.ts",
|
|
30
35
|
"import": "./dist/builtin.js",
|
|
31
|
-
"require": "./dist/builtin.
|
|
36
|
+
"require": "./dist/builtin.js"
|
|
32
37
|
}
|
|
33
38
|
},
|
|
34
39
|
"publishConfig": {
|
|
@@ -41,58 +46,48 @@
|
|
|
41
46
|
".": {
|
|
42
47
|
"types": "./dist/index.d.ts",
|
|
43
48
|
"import": "./dist/index.js",
|
|
44
|
-
"require": "./dist/index.
|
|
49
|
+
"require": "./dist/index.js"
|
|
45
50
|
},
|
|
46
51
|
"./builtin": {
|
|
47
52
|
"types": "./dist/builtin.d.ts",
|
|
48
53
|
"import": "./dist/builtin.js",
|
|
49
|
-
"require": "./dist/builtin.
|
|
54
|
+
"require": "./dist/builtin.js"
|
|
50
55
|
}
|
|
51
56
|
}
|
|
52
57
|
},
|
|
53
58
|
"scripts": {
|
|
54
|
-
"
|
|
55
|
-
"
|
|
56
|
-
"build:langium": "langium generate",
|
|
57
|
-
"build:ts": "tsc",
|
|
59
|
+
"turbo-build": "run -T turbo run build --filter='language-server'",
|
|
60
|
+
"compile": "tsc --noEmit",
|
|
58
61
|
"watch:langium": "langium generate --watch",
|
|
59
62
|
"watch:ts": "tsc --watch",
|
|
60
63
|
"generate": "langium generate",
|
|
61
|
-
"build": "
|
|
62
|
-
"dev": "run
|
|
64
|
+
"build": "tsc",
|
|
65
|
+
"dev": "run-p 'watch:*'",
|
|
63
66
|
"lint": "run -T eslint src/ --fix",
|
|
64
67
|
"clean": "run -T rimraf dist contrib",
|
|
65
68
|
"test": "vitest run",
|
|
66
69
|
"test:watch": "vitest"
|
|
67
70
|
},
|
|
68
71
|
"dependencies": {
|
|
69
|
-
"@likec4/core": "0.
|
|
70
|
-
"@likec4/language-protocol": "0.6.2",
|
|
72
|
+
"@likec4/core": "0.7.0",
|
|
71
73
|
"@mobily/ts-belt": "^3.13.1",
|
|
74
|
+
"langium": "^1.2.0",
|
|
72
75
|
"nanoid": "^4.0.2",
|
|
73
76
|
"object-hash": "^3.0.0",
|
|
74
|
-
"rambdax": "^9.1.
|
|
77
|
+
"rambdax": "^9.1.1",
|
|
75
78
|
"strip-indent": "^4.0.0",
|
|
76
79
|
"tiny-invariant": "^1.3.1",
|
|
77
|
-
"type-fest": "^3.
|
|
78
|
-
"vscode-
|
|
79
|
-
|
|
80
|
-
"peerDependencies": {
|
|
81
|
-
"langium": "^1.1.0",
|
|
82
|
-
"vscode-languageserver-protocol": "~3.17.2"
|
|
83
|
-
},
|
|
84
|
-
"peerDependenciesMeta": {
|
|
85
|
-
"vscode-languageserver-protocol": {
|
|
86
|
-
"optional": true
|
|
87
|
-
}
|
|
80
|
+
"type-fest": "^3.9.0",
|
|
81
|
+
"vscode-languageserver": "~8.1.0",
|
|
82
|
+
"vscode-languageserver-protocol": "~3.17.3"
|
|
88
83
|
},
|
|
89
84
|
"devDependencies": {
|
|
90
85
|
"@types/node": "^18.15.11",
|
|
91
86
|
"@types/object-hash": "^3.0.2",
|
|
92
|
-
"langium-cli": "^1.
|
|
87
|
+
"langium-cli": "^1.2.0",
|
|
93
88
|
"npm-run-all": "^4.1.5",
|
|
94
89
|
"typescript": "^5.0.4",
|
|
95
|
-
"vite": "^4.
|
|
96
|
-
"vitest": "^0.
|
|
90
|
+
"vite": "^4.3.3",
|
|
91
|
+
"vitest": "^0.31.0"
|
|
97
92
|
}
|
|
98
93
|
}
|