@likec4/language-server 0.28.3 → 0.30.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 +4 -3
- package/dist/ast.d.ts +0 -2
- package/dist/ast.js +9 -16
- package/dist/elementRef.js +1 -1
- package/dist/generated/ast.d.ts +30 -53
- package/dist/generated/ast.js +15 -45
- package/dist/generated/grammar.js +463 -589
- package/dist/lsp/SemanticTokenProvider.js +5 -1
- package/dist/model/fqn-computation.js +3 -4
- package/dist/model/fqn-index.d.ts +10 -9
- package/dist/model/fqn-index.js +7 -5
- package/dist/model/model-builder.d.ts +4 -2
- package/dist/model/model-builder.js +43 -30
- package/dist/references/scope-provider.js +11 -14
- package/dist/validation/element.d.ts +0 -1
- package/dist/validation/element.js +2 -8
- package/dist/validation/relation.js +20 -30
- package/package.json +3 -3
- package/dist/tsconfig.tsbuildinfo +0 -1
|
@@ -116,7 +116,11 @@ export class LikeC4SemanticTokenProvider extends AbstractSemanticTokenProvider {
|
|
|
116
116
|
});
|
|
117
117
|
return;
|
|
118
118
|
}
|
|
119
|
-
|
|
119
|
+
// ViewProperty | ElementStringProperty | RelationStringProperty | LinkProperty
|
|
120
|
+
if (ast.isViewProperty(node) ||
|
|
121
|
+
ast.isElementStringProperty(node) ||
|
|
122
|
+
ast.isRelationStringProperty(node) ||
|
|
123
|
+
ast.isLinkProperty(node)) {
|
|
120
124
|
acceptor({
|
|
121
125
|
node,
|
|
122
126
|
property: 'key',
|
|
@@ -1,11 +1,10 @@
|
|
|
1
|
-
import { failExpectedNever } from '@likec4/core';
|
|
2
|
-
import { Fqn } from '@likec4/core/types';
|
|
1
|
+
import { failExpectedNever, AsFqn } from '@likec4/core';
|
|
3
2
|
import { MultiMap } from 'langium';
|
|
4
3
|
import { isEmpty, isNil } from 'remeda';
|
|
5
4
|
import { ElementOps, ast } from '../ast';
|
|
6
5
|
import { strictElementRefFqn } from '../elementRef';
|
|
7
6
|
export function computeDocumentFqn(document, services) {
|
|
8
|
-
const c4fqns = document.c4fqns = new MultiMap();
|
|
7
|
+
const c4fqns = (document.c4fqns = new MultiMap());
|
|
9
8
|
const { model } = document.parseResult.value;
|
|
10
9
|
if (!model?.elements) {
|
|
11
10
|
return;
|
|
@@ -26,7 +25,7 @@ export function computeDocumentFqn(document, services) {
|
|
|
26
25
|
continue;
|
|
27
26
|
}
|
|
28
27
|
if (ast.isElement(el)) {
|
|
29
|
-
const fqn =
|
|
28
|
+
const fqn = AsFqn(el.name, parent);
|
|
30
29
|
const path = locator.getAstNodePath(el);
|
|
31
30
|
c4fqns.add(fqn, path);
|
|
32
31
|
ElementOps.writeId(el, fqn);
|
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import type { Fqn } from '@likec4/core
|
|
2
|
-
import type { LangiumDocument, LangiumDocuments } from 'langium';
|
|
3
|
-
import { StreamImpl } from 'langium';
|
|
1
|
+
import type { Fqn } from '@likec4/core';
|
|
2
|
+
import type { LangiumDocument, LangiumDocuments, Stream } from 'langium';
|
|
4
3
|
import type { ast } from '../ast';
|
|
5
4
|
import { type LikeC4LangiumDocument } from '../ast';
|
|
6
5
|
import type { LikeC4Services } from '../module';
|
|
@@ -15,18 +14,20 @@ export interface FqnIndexEntry {
|
|
|
15
14
|
path: string;
|
|
16
15
|
}
|
|
17
16
|
export declare class FqnIndex {
|
|
18
|
-
private services;
|
|
19
17
|
protected langiumDocuments: LangiumDocuments;
|
|
20
18
|
constructor(services: LikeC4Services);
|
|
21
19
|
private documents;
|
|
22
20
|
private entries;
|
|
23
|
-
|
|
24
|
-
byFqn(fqn: Fqn):
|
|
21
|
+
getFqn(el: ast.Element): Fqn | null;
|
|
22
|
+
byFqn(fqn: Fqn): Stream<{
|
|
25
23
|
path: string;
|
|
26
|
-
doc:
|
|
24
|
+
doc: LikeC4LangiumDocument;
|
|
27
25
|
}>;
|
|
28
|
-
directChildrenOf(parent: Fqn):
|
|
29
|
-
|
|
26
|
+
directChildrenOf(parent: Fqn): Stream<FqnIndexEntry>;
|
|
27
|
+
/**
|
|
28
|
+
* Returns descedant elements with unique names in the scope
|
|
29
|
+
*/
|
|
30
|
+
uniqueDescedants(parent: Fqn): Stream<FqnIndexEntry>;
|
|
30
31
|
}
|
|
31
32
|
export {};
|
|
32
33
|
//# sourceMappingURL=fqn-index.d.ts.map
|
package/dist/model/fqn-index.js
CHANGED
|
@@ -1,17 +1,15 @@
|
|
|
1
|
-
import { nameFromFqn, parentFqn } from '@likec4/core
|
|
1
|
+
import { nameFromFqn, parentFqn } from '@likec4/core';
|
|
2
2
|
import { DONE_RESULT, DocumentState, MultiMap, StreamImpl } from 'langium';
|
|
3
3
|
import { isNil } from 'remeda';
|
|
4
4
|
import { ElementOps, isLikeC4LangiumDocument } from '../ast';
|
|
5
5
|
import { logger } from '../logger';
|
|
6
6
|
import { computeDocumentFqn } from './fqn-computation';
|
|
7
7
|
export function isFqnIndexedDocument(doc) {
|
|
8
|
-
return isLikeC4LangiumDocument(doc) && doc.state >= DocumentState.IndexedContent && !isNil(doc.c4fqns);
|
|
8
|
+
return (isLikeC4LangiumDocument(doc) && doc.state >= DocumentState.IndexedContent && !isNil(doc.c4fqns));
|
|
9
9
|
}
|
|
10
10
|
export class FqnIndex {
|
|
11
|
-
services;
|
|
12
11
|
langiumDocuments;
|
|
13
12
|
constructor(services) {
|
|
14
|
-
this.services = services;
|
|
15
13
|
this.langiumDocuments = services.shared.workspace.LangiumDocuments;
|
|
16
14
|
services.shared.workspace.DocumentBuilder.onBuildPhase(DocumentState.IndexedContent, (docs, _cancelToken) => {
|
|
17
15
|
for (const doc of docs) {
|
|
@@ -32,7 +30,7 @@ export class FqnIndex {
|
|
|
32
30
|
entries() {
|
|
33
31
|
return this.documents().flatMap(doc => doc.c4fqns.entries().map(([fqn, path]) => ({ fqn, path, doc })));
|
|
34
32
|
}
|
|
35
|
-
|
|
33
|
+
getFqn(el) {
|
|
36
34
|
return ElementOps.readId(el) ?? null;
|
|
37
35
|
// if (fqn) {
|
|
38
36
|
// const doc = getDocument(el)
|
|
@@ -75,6 +73,9 @@ export class FqnIndex {
|
|
|
75
73
|
return DONE_RESULT;
|
|
76
74
|
});
|
|
77
75
|
}
|
|
76
|
+
/**
|
|
77
|
+
* Returns descedant elements with unique names in the scope
|
|
78
|
+
*/
|
|
78
79
|
uniqueDescedants(parent) {
|
|
79
80
|
return new StreamImpl(() => {
|
|
80
81
|
const prefix = `${parent}.`;
|
|
@@ -86,6 +87,7 @@ export class FqnIndex {
|
|
|
86
87
|
.forEach(e => {
|
|
87
88
|
const name = nameFromFqn(e.fqn);
|
|
88
89
|
const entry = { ...e, name };
|
|
90
|
+
// To keep direct children always
|
|
89
91
|
if (parentFqn(e.fqn) === parent) {
|
|
90
92
|
childrenNames.add(name);
|
|
91
93
|
nested.add(name, entry);
|
|
@@ -5,10 +5,12 @@ export declare class LikeC4ModelBuilder {
|
|
|
5
5
|
private services;
|
|
6
6
|
private fqnIndex;
|
|
7
7
|
private langiumDocuments;
|
|
8
|
+
private readonly cachedModel;
|
|
8
9
|
constructor(services: LikeC4Services);
|
|
9
|
-
private
|
|
10
|
+
private cleanCache;
|
|
10
11
|
private documents;
|
|
11
|
-
buildModel(): c4.LikeC4Model |
|
|
12
|
+
buildModel(): c4.LikeC4Model | null;
|
|
13
|
+
private _buildModel;
|
|
12
14
|
/**
|
|
13
15
|
* @returns if the document was changed
|
|
14
16
|
*/
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ModelIndex, assignNavigateTo, computeView } from '@likec4/core';
|
|
1
|
+
import { ModelIndex, assignNavigateTo, computeView, invariant } from '@likec4/core';
|
|
2
2
|
import { DefaultElementShape, DefaultThemeColor } from '@likec4/core/types';
|
|
3
3
|
import { compareByFqnHierarchically, parentFqn } from '@likec4/core/utils';
|
|
4
4
|
import { DocumentState, getDocument } from 'langium';
|
|
@@ -6,7 +6,6 @@ import objectHash from 'object-hash';
|
|
|
6
6
|
import { clone } from 'rambdax';
|
|
7
7
|
import * as R from 'remeda';
|
|
8
8
|
import stripIndent from 'strip-indent';
|
|
9
|
-
import invariant from 'tiny-invariant';
|
|
10
9
|
import { ElementViewOps, ast, cleanParsedModel, isLikeC4LangiumDocument, isValidLikeC4LangiumDocument, resolveRelationPoints, streamModel, toAutoLayout, toElementStyle } from '../ast';
|
|
11
10
|
import { elementRef, strictElementRefFqn } from '../elementRef';
|
|
12
11
|
import { logger } from '../logger';
|
|
@@ -16,6 +15,7 @@ export class LikeC4ModelBuilder {
|
|
|
16
15
|
services;
|
|
17
16
|
fqnIndex;
|
|
18
17
|
langiumDocuments;
|
|
18
|
+
cachedModel = {};
|
|
19
19
|
constructor(services) {
|
|
20
20
|
this.services = services;
|
|
21
21
|
this.fqnIndex = services.likec4.FqnIndex;
|
|
@@ -23,9 +23,6 @@ export class LikeC4ModelBuilder {
|
|
|
23
23
|
services.shared.workspace.DocumentBuilder.onBuildPhase(DocumentState.Validated, (docs, cancelToken) => {
|
|
24
24
|
let countOfChangedDocs = 0;
|
|
25
25
|
for (const doc of docs) {
|
|
26
|
-
if (cancelToken.isCancellationRequested) {
|
|
27
|
-
break;
|
|
28
|
-
}
|
|
29
26
|
if (!isLikeC4LangiumDocument(doc)) {
|
|
30
27
|
continue;
|
|
31
28
|
}
|
|
@@ -38,22 +35,31 @@ export class LikeC4ModelBuilder {
|
|
|
38
35
|
logger.error(e);
|
|
39
36
|
}
|
|
40
37
|
}
|
|
41
|
-
if (countOfChangedDocs > 0
|
|
42
|
-
this.
|
|
38
|
+
if (countOfChangedDocs > 0) {
|
|
39
|
+
this.cleanCache();
|
|
40
|
+
this.notifyClient(cancelToken);
|
|
43
41
|
}
|
|
44
42
|
});
|
|
45
43
|
}
|
|
46
|
-
|
|
47
|
-
|
|
44
|
+
cleanCache() {
|
|
45
|
+
delete this.cachedModel.last;
|
|
48
46
|
}
|
|
49
47
|
documents() {
|
|
50
48
|
return this.langiumDocuments.all.filter(isValidLikeC4LangiumDocument).toArray();
|
|
51
49
|
}
|
|
52
50
|
buildModel() {
|
|
51
|
+
if ('last' in this.cachedModel) {
|
|
52
|
+
logger.debug('returning cached model');
|
|
53
|
+
return this.cachedModel.last;
|
|
54
|
+
}
|
|
55
|
+
return (this.cachedModel.last = this._buildModel());
|
|
56
|
+
}
|
|
57
|
+
_buildModel() {
|
|
58
|
+
logger.debug('_buildModel');
|
|
53
59
|
const docs = this.documents();
|
|
54
60
|
if (docs.length === 0) {
|
|
55
61
|
logger.debug('No documents to build model from');
|
|
56
|
-
return;
|
|
62
|
+
return null;
|
|
57
63
|
}
|
|
58
64
|
// TODO:
|
|
59
65
|
try {
|
|
@@ -61,27 +67,32 @@ export class LikeC4ModelBuilder {
|
|
|
61
67
|
kinds: {}
|
|
62
68
|
};
|
|
63
69
|
R.forEach(R.map(docs, R.prop('c4Specification')), spec => Object.assign(c4Specification.kinds, spec.kinds));
|
|
64
|
-
const toModelElement = (
|
|
65
|
-
const kind = c4Specification.kinds[
|
|
70
|
+
const toModelElement = ({ astPath, ...parsed }) => {
|
|
71
|
+
const kind = c4Specification.kinds[parsed.kind];
|
|
66
72
|
if (kind) {
|
|
67
|
-
const { astPath, ...model } = el;
|
|
68
73
|
return {
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
74
|
+
shape: kind.shape,
|
|
75
|
+
color: kind.color,
|
|
76
|
+
description: null,
|
|
77
|
+
technology: null,
|
|
78
|
+
tags: [],
|
|
79
|
+
...parsed
|
|
72
80
|
};
|
|
73
81
|
}
|
|
74
82
|
return null;
|
|
75
83
|
};
|
|
76
84
|
const elements = R.pipe(R.flatMap(docs, d => d.c4Elements), R.map(toModelElement), R.compact, R.sort(compareByFqnHierarchically), R.reduce((acc, el) => {
|
|
77
85
|
const parent = parentFqn(el.id);
|
|
78
|
-
if (
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
86
|
+
if (parent && R.isNil(acc[parent])) {
|
|
87
|
+
logger.warn(`No parent found for ${el.id}`);
|
|
88
|
+
return acc;
|
|
89
|
+
}
|
|
90
|
+
if (el.id in acc) {
|
|
91
|
+
// should not happen, as validated
|
|
92
|
+
logger.warn(`Duplicate element id: ${el.id}`);
|
|
93
|
+
return acc;
|
|
84
94
|
}
|
|
95
|
+
acc[el.id] = el;
|
|
85
96
|
return acc;
|
|
86
97
|
}, {}));
|
|
87
98
|
const toModelRelation = ({ astPath, source, target, ...model }) => {
|
|
@@ -121,7 +132,7 @@ export class LikeC4ModelBuilder {
|
|
|
121
132
|
}
|
|
122
133
|
catch (e) {
|
|
123
134
|
logger.error(e);
|
|
124
|
-
return;
|
|
135
|
+
return null;
|
|
125
136
|
}
|
|
126
137
|
}
|
|
127
138
|
/**
|
|
@@ -187,7 +198,7 @@ export class LikeC4ModelBuilder {
|
|
|
187
198
|
invariant(astNode.kind.ref, 'Element kind is not resolved: ' + astNode.name);
|
|
188
199
|
const kind = astNode.kind.ref.name;
|
|
189
200
|
const tags = (astNode.body && this.convertTags(astNode.body)) ?? [];
|
|
190
|
-
const styleProps = astNode.body?.props.find(ast.
|
|
201
|
+
const styleProps = astNode.body?.props.find(ast.isElementStyleProperties)?.props;
|
|
191
202
|
const { color, shape } = toElementStyle(styleProps);
|
|
192
203
|
const astPath = this.getAstNodePath(astNode);
|
|
193
204
|
let [title, description, technology] = astNode.props;
|
|
@@ -217,7 +228,7 @@ export class LikeC4ModelBuilder {
|
|
|
217
228
|
target
|
|
218
229
|
};
|
|
219
230
|
const id = objectHash(hashdata);
|
|
220
|
-
const title = astNode.title ?? astNode.
|
|
231
|
+
const title = astNode.title ?? astNode.body?.props.find(p => p.key === 'title')?.value ?? '';
|
|
221
232
|
return {
|
|
222
233
|
id,
|
|
223
234
|
...hashdata,
|
|
@@ -333,7 +344,7 @@ export class LikeC4ModelBuilder {
|
|
|
333
344
|
if (ast.isExtendElement(node)) {
|
|
334
345
|
return strictElementRefFqn(node.element);
|
|
335
346
|
}
|
|
336
|
-
const fqn = this.fqnIndex.
|
|
347
|
+
const fqn = this.fqnIndex.getFqn(node);
|
|
337
348
|
invariant(fqn, `Not indexed element: ${this.getAstNodePath(node)}`);
|
|
338
349
|
return fqn;
|
|
339
350
|
}
|
|
@@ -344,8 +355,8 @@ export class LikeC4ModelBuilder {
|
|
|
344
355
|
return el.tags?.value.map(tagRef => tagRef.ref?.name) ?? [];
|
|
345
356
|
}
|
|
346
357
|
scheduledCb = null;
|
|
347
|
-
notifyClient() {
|
|
348
|
-
const connection = this.
|
|
358
|
+
notifyClient(cancelToken) {
|
|
359
|
+
const connection = this.services.shared.lsp.Connection;
|
|
349
360
|
if (!connection) {
|
|
350
361
|
return;
|
|
351
362
|
}
|
|
@@ -356,8 +367,10 @@ export class LikeC4ModelBuilder {
|
|
|
356
367
|
this.scheduledCb = setTimeout(() => {
|
|
357
368
|
logger.debug('send onDidChangeModel');
|
|
358
369
|
this.scheduledCb = null;
|
|
359
|
-
|
|
360
|
-
|
|
370
|
+
if (!cancelToken.isCancellationRequested) {
|
|
371
|
+
void connection.sendNotification(Rpc.onDidChangeModel, '');
|
|
372
|
+
}
|
|
373
|
+
}, 300);
|
|
361
374
|
}
|
|
362
375
|
}
|
|
363
376
|
//# sourceMappingURL=model-builder.js.map
|
|
@@ -17,18 +17,15 @@ export class LikeC4ScopeProvider extends DefaultScopeProvider {
|
|
|
17
17
|
this.fqnIndex = services.likec4.FqnIndex;
|
|
18
18
|
}
|
|
19
19
|
directChildrenOf(parent) {
|
|
20
|
-
return this.fqnIndex
|
|
21
|
-
.directChildrenOf(parent)
|
|
22
|
-
.map(toAstNodeDescription);
|
|
20
|
+
return this.fqnIndex.directChildrenOf(parent).map(toAstNodeDescription);
|
|
23
21
|
}
|
|
22
|
+
// we need lazy resolving here
|
|
24
23
|
uniqueDescedants(of) {
|
|
25
24
|
return new StreamImpl(() => {
|
|
26
25
|
const element = of();
|
|
27
|
-
const fqn = element && this.fqnIndex.
|
|
26
|
+
const fqn = element && this.fqnIndex.getFqn(element);
|
|
28
27
|
if (fqn) {
|
|
29
|
-
return this.fqnIndex.uniqueDescedants(fqn)
|
|
30
|
-
.map(toAstNodeDescription)
|
|
31
|
-
.iterator();
|
|
28
|
+
return this.fqnIndex.uniqueDescedants(fqn).map(toAstNodeDescription).iterator();
|
|
32
29
|
}
|
|
33
30
|
return null;
|
|
34
31
|
}, iterator => {
|
|
@@ -57,21 +54,21 @@ export class LikeC4ScopeProvider extends DefaultScopeProvider {
|
|
|
57
54
|
getScope(context) {
|
|
58
55
|
const referenceType = this.reflection.getReferenceType(context);
|
|
59
56
|
try {
|
|
60
|
-
const
|
|
57
|
+
const container = context.container;
|
|
61
58
|
// const path = this.services.workspace.AstNodeLocator.getAstNodePath(node)
|
|
62
59
|
if (referenceType === ast.Element) {
|
|
63
|
-
if (ast.isStrictElementRef(
|
|
64
|
-
if (isElementRefHead(
|
|
60
|
+
if (ast.isStrictElementRef(container)) {
|
|
61
|
+
if (isElementRefHead(container)) {
|
|
65
62
|
return this.getGlobalScope(referenceType);
|
|
66
63
|
}
|
|
67
|
-
const parent = parentStrictElementRef(
|
|
64
|
+
const parent = parentStrictElementRef(container);
|
|
68
65
|
return new StreamScope(this.directChildrenOf(parent));
|
|
69
66
|
}
|
|
70
|
-
if (ast.isElementRef(
|
|
71
|
-
return new StreamScope(this.scopeElementRef(
|
|
67
|
+
if (ast.isElementRef(container) && !isElementRefHead(container)) {
|
|
68
|
+
return new StreamScope(this.scopeElementRef(container));
|
|
72
69
|
}
|
|
73
70
|
}
|
|
74
|
-
return this.computeScope(
|
|
71
|
+
return this.computeScope(container, referenceType);
|
|
75
72
|
}
|
|
76
73
|
catch (e) {
|
|
77
74
|
// console.error(e)
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
export const elementChecks = (services) => {
|
|
2
2
|
const fqnIndex = services.likec4.FqnIndex;
|
|
3
3
|
return (el, accept) => {
|
|
4
|
-
const fqn = fqnIndex.
|
|
4
|
+
const fqn = fqnIndex.getFqn(el);
|
|
5
5
|
if (!fqn) {
|
|
6
|
-
accept('error', 'Not indexed', {
|
|
6
|
+
accept('error', 'Not indexed element', {
|
|
7
7
|
node: el,
|
|
8
8
|
property: 'name'
|
|
9
9
|
});
|
|
@@ -11,12 +11,6 @@ export const elementChecks = (services) => {
|
|
|
11
11
|
}
|
|
12
12
|
const withSameFqn = fqnIndex.byFqn(fqn).limit(2).count();
|
|
13
13
|
if (withSameFqn > 1) {
|
|
14
|
-
// console.error(withSameFqn.map(e => ({
|
|
15
|
-
// fqn,
|
|
16
|
-
// name: el.name,
|
|
17
|
-
// path: e.path,
|
|
18
|
-
// doc: e.doc.uri.toString()
|
|
19
|
-
// })))
|
|
20
14
|
accept('error', `Duplicate element name ${el.name !== fqn ? el.name + ' (' + fqn + ')' : el.name}`, {
|
|
21
15
|
node: el,
|
|
22
16
|
property: 'name'
|
|
@@ -1,31 +1,36 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { BaseError } from '@likec4/core';
|
|
2
2
|
import { isSameHierarchy } from '@likec4/core/utils';
|
|
3
|
+
import { resolveRelationPoints } from '../ast';
|
|
3
4
|
export const relationChecks = (services) => {
|
|
4
5
|
const fqnIndex = services.likec4.FqnIndex;
|
|
5
6
|
return (el, accept) => {
|
|
6
7
|
try {
|
|
7
8
|
const coupling = resolveRelationPoints(el);
|
|
8
|
-
const target = fqnIndex.
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
9
|
+
const target = fqnIndex.getFqn(coupling.target);
|
|
10
|
+
const source = fqnIndex.getFqn(coupling.source);
|
|
11
|
+
if (!target || !source) {
|
|
12
|
+
if (!target) {
|
|
13
|
+
accept('error', 'Target not found', {
|
|
14
|
+
node: el,
|
|
15
|
+
property: 'target'
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
if (!source) {
|
|
19
|
+
accept('error', 'Source not found', {
|
|
20
|
+
node: el,
|
|
21
|
+
property: 'source'
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
return;
|
|
20
25
|
}
|
|
21
26
|
if (isSameHierarchy(source, target)) {
|
|
22
|
-
return accept('error', 'Invalid relation
|
|
27
|
+
return accept('error', 'Invalid parent-child relation', {
|
|
23
28
|
node: el
|
|
24
29
|
});
|
|
25
30
|
}
|
|
26
31
|
}
|
|
27
32
|
catch (e) {
|
|
28
|
-
if (e instanceof
|
|
33
|
+
if (e instanceof BaseError) {
|
|
29
34
|
return accept('error', e.message, {
|
|
30
35
|
node: el
|
|
31
36
|
});
|
|
@@ -34,21 +39,6 @@ export const relationChecks = (services) => {
|
|
|
34
39
|
node: el
|
|
35
40
|
});
|
|
36
41
|
}
|
|
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
42
|
};
|
|
53
43
|
};
|
|
54
44
|
//# sourceMappingURL=relation.js.map
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@likec4/language-server",
|
|
3
3
|
"description": "LikeC4 Language Server",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.30.0",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"bugs": "https://github.com/likec4/likec4/issues",
|
|
7
7
|
"homepage": "https://likec4.dev",
|
|
@@ -46,6 +46,7 @@
|
|
|
46
46
|
},
|
|
47
47
|
"scripts": {
|
|
48
48
|
"turbo-build": "run -T turbo run build --filter='language-server'",
|
|
49
|
+
"turbo-compile": "run -T turbo run compile --filter='language-server'",
|
|
49
50
|
"compile": "tsc --noEmit",
|
|
50
51
|
"watch:langium": "langium generate --watch",
|
|
51
52
|
"watch:ts": "tsc --watch",
|
|
@@ -58,14 +59,13 @@
|
|
|
58
59
|
"test:watch": "run -T vitest"
|
|
59
60
|
},
|
|
60
61
|
"dependencies": {
|
|
61
|
-
"@likec4/core": "0.
|
|
62
|
+
"@likec4/core": "0.30.0",
|
|
62
63
|
"langium": "^1.2.1",
|
|
63
64
|
"nanoid": "^4.0.2",
|
|
64
65
|
"object-hash": "^3.0.0",
|
|
65
66
|
"rambdax": "^9.1.1",
|
|
66
67
|
"remeda": "^1.23.0",
|
|
67
68
|
"strip-indent": "^4.0.0",
|
|
68
|
-
"tiny-invariant": "^1.3.1",
|
|
69
69
|
"vscode-languageserver": "~8.1.0",
|
|
70
70
|
"vscode-languageserver-protocol": "~3.17.3"
|
|
71
71
|
},
|