@likec4/language-server 0.33.1 → 0.35.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 +17 -3
- package/dist/ast.d.ts +24 -11
- package/dist/ast.js +12 -9
- package/dist/elementRef.d.ts +1 -1
- package/dist/elementRef.js +2 -3
- package/dist/generated/ast.d.ts +29 -10
- package/dist/generated/ast.js +20 -1
- package/dist/generated/grammar.d.ts +1 -1
- package/dist/generated/grammar.js +11 -11
- package/dist/generated/module.d.ts +7 -3
- package/dist/generated/module.js +3 -3
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/logger.d.ts +6 -4
- package/dist/logger.js +34 -6
- package/dist/{shared → lsp}/CodeLensProvider.d.ts +3 -3
- package/dist/{shared → lsp}/DocumentLinkProvider.d.ts +3 -2
- package/dist/{shared → lsp}/DocumentLinkProvider.js +3 -3
- package/dist/lsp/DocumentSymbolProvider.js +3 -3
- package/dist/lsp/index.d.ts +2 -0
- package/dist/lsp/index.js +2 -0
- package/dist/model/fqn-computation.js +6 -3
- package/dist/model/fqn-index.d.ts +4 -7
- package/dist/model/fqn-index.js +51 -21
- package/dist/model/index.d.ts +1 -0
- package/dist/model/index.js +1 -0
- package/dist/model/model-builder.d.ts +1 -18
- package/dist/model/model-builder.js +111 -340
- package/dist/model/model-locator.js +19 -24
- package/dist/model/model-parser.d.ts +27 -0
- package/dist/model/model-parser.js +293 -0
- package/dist/module.d.ts +2 -1
- package/dist/module.js +20 -29
- package/dist/protocol.d.ts +8 -16
- package/dist/protocol.js +2 -6
- package/dist/references/scope-computation.js +11 -5
- package/dist/references/scope-provider.js +10 -4
- package/dist/registerProtocolHandlers.js +33 -17
- package/dist/shared/index.d.ts +0 -2
- package/dist/shared/index.js +0 -2
- package/dist/test/testServices.d.ts +2 -2
- package/dist/test/testServices.js +16 -10
- package/dist/utils.d.ts +2 -2
- package/dist/utils.js +2 -7
- package/dist/validation/element.d.ts +1 -1
- package/dist/validation/element.js +23 -3
- package/dist/validation/index.js +26 -0
- package/dist/validation/relation.d.ts +1 -1
- package/dist/validation/relation.js +32 -26
- package/package.json +10 -8
- /package/dist/{shared → lsp}/CodeLensProvider.js +0 -0
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import { nonexhaustive } from '@likec4/core
|
|
2
|
-
import { AsFqn } from '@likec4/core/types';
|
|
1
|
+
import { AsFqn, nonexhaustive } from '@likec4/core';
|
|
3
2
|
import { MultiMap } from 'langium';
|
|
4
3
|
import { isEmpty, isNil } from 'remeda';
|
|
5
4
|
import { ElementOps, ast } from '../ast';
|
|
@@ -28,7 +27,11 @@ export function computeDocumentFqn(document, services) {
|
|
|
28
27
|
if (ast.isElement(el)) {
|
|
29
28
|
const fqn = AsFqn(el.name, parent);
|
|
30
29
|
const path = locator.getAstNodePath(el);
|
|
31
|
-
c4fqns.add(fqn,
|
|
30
|
+
c4fqns.add(fqn, {
|
|
31
|
+
el: new WeakRef(el),
|
|
32
|
+
path,
|
|
33
|
+
name: el.name
|
|
34
|
+
});
|
|
32
35
|
ElementOps.writeId(el, fqn);
|
|
33
36
|
if (!isNil(el.body) && !isEmpty(el.body.elements)) {
|
|
34
37
|
el.body.elements.forEach(child => traverseStack.push([child, fqn]));
|
|
@@ -3,14 +3,15 @@ import type { LangiumDocument, LangiumDocuments, Stream } from 'langium';
|
|
|
3
3
|
import type { ast } from '../ast';
|
|
4
4
|
import { type LikeC4LangiumDocument } from '../ast';
|
|
5
5
|
import type { LikeC4Services } from '../module';
|
|
6
|
-
type FqnIndexedDocument = Omit<LikeC4LangiumDocument, 'c4fqns'> & {
|
|
6
|
+
export type FqnIndexedDocument = Omit<LikeC4LangiumDocument, 'c4fqns'> & {
|
|
7
7
|
c4fqns: NonNullable<LikeC4LangiumDocument['c4fqns']>;
|
|
8
8
|
};
|
|
9
9
|
export declare function isFqnIndexedDocument(doc: LangiumDocument): doc is FqnIndexedDocument;
|
|
10
10
|
export interface FqnIndexEntry {
|
|
11
11
|
fqn: Fqn;
|
|
12
12
|
name: string;
|
|
13
|
-
|
|
13
|
+
el: ast.Element;
|
|
14
|
+
doc: FqnIndexedDocument;
|
|
14
15
|
path: string;
|
|
15
16
|
}
|
|
16
17
|
export declare class FqnIndex {
|
|
@@ -19,15 +20,11 @@ export declare class FqnIndex {
|
|
|
19
20
|
private documents;
|
|
20
21
|
private entries;
|
|
21
22
|
getFqn(el: ast.Element): Fqn | null;
|
|
22
|
-
byFqn(fqn: Fqn): Stream<
|
|
23
|
-
path: string;
|
|
24
|
-
doc: LikeC4LangiumDocument;
|
|
25
|
-
}>;
|
|
23
|
+
byFqn(fqn: Fqn): Stream<FqnIndexEntry>;
|
|
26
24
|
directChildrenOf(parent: Fqn): Stream<FqnIndexEntry>;
|
|
27
25
|
/**
|
|
28
26
|
* Returns descedant elements with unique names in the scope
|
|
29
27
|
*/
|
|
30
28
|
uniqueDescedants(parent: Fqn): Stream<FqnIndexEntry>;
|
|
31
29
|
}
|
|
32
|
-
export {};
|
|
33
30
|
//# sourceMappingURL=fqn-index.d.ts.map
|
package/dist/model/fqn-index.js
CHANGED
|
@@ -1,24 +1,48 @@
|
|
|
1
1
|
import { nameFromFqn, parentFqn } from '@likec4/core';
|
|
2
|
-
import { DONE_RESULT, DocumentState, MultiMap, StreamImpl } from 'langium';
|
|
2
|
+
import { DONE_RESULT, DocumentState, MultiMap, StreamImpl, stream } from 'langium';
|
|
3
3
|
import { isNil } from 'remeda';
|
|
4
4
|
import { ElementOps, isLikeC4LangiumDocument } from '../ast';
|
|
5
|
-
import { logger } from '../logger';
|
|
5
|
+
import { logError, logger } from '../logger';
|
|
6
|
+
import { printDocs } from '../utils';
|
|
6
7
|
import { computeDocumentFqn } from './fqn-computation';
|
|
7
8
|
export function isFqnIndexedDocument(doc) {
|
|
8
|
-
return
|
|
9
|
+
return isLikeC4LangiumDocument(doc) && doc.state >= DocumentState.IndexedContent && !isNil(doc.c4fqns);
|
|
9
10
|
}
|
|
10
11
|
export class FqnIndex {
|
|
11
12
|
langiumDocuments;
|
|
12
13
|
constructor(services) {
|
|
13
14
|
this.langiumDocuments = services.shared.workspace.LangiumDocuments;
|
|
15
|
+
// services.shared.workspace.DocumentBuilder.onUpdate((changed,deleted) => {
|
|
16
|
+
// logger.debug('') // empty line to separate batches
|
|
17
|
+
// logger.debug(`[DocumentBuilder.onUpdate]`)
|
|
18
|
+
// if (changed.length > 0) {
|
|
19
|
+
// logger.debug(` changed:\n` + changed.map(u => ' - ' + Utils.basename(u)).join('\n'))
|
|
20
|
+
// }
|
|
21
|
+
// if (deleted.length > 0) {
|
|
22
|
+
// logger.debug(` deleted:\n` + deleted.map(u => ' - ' + Utils.basename(u)).join('\n'))
|
|
23
|
+
// }
|
|
24
|
+
// })
|
|
25
|
+
services.shared.workspace.DocumentBuilder.onBuildPhase(DocumentState.Changed, (docs, _cancelToken) => {
|
|
26
|
+
logger.debug(`[FqnIndex] onChanged (${docs.length} docs):\n` + printDocs(docs));
|
|
27
|
+
for (const doc of docs) {
|
|
28
|
+
if (isLikeC4LangiumDocument(doc)) {
|
|
29
|
+
delete doc.c4fqns;
|
|
30
|
+
delete doc.c4Elements;
|
|
31
|
+
delete doc.c4Specification;
|
|
32
|
+
delete doc.c4Relations;
|
|
33
|
+
delete doc.c4Views;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
});
|
|
14
37
|
services.shared.workspace.DocumentBuilder.onBuildPhase(DocumentState.IndexedContent, (docs, _cancelToken) => {
|
|
38
|
+
logger.debug(`[FqnIndex] onIndexedContent ${docs.length}:\n` + printDocs(docs));
|
|
15
39
|
for (const doc of docs) {
|
|
16
40
|
if (isLikeC4LangiumDocument(doc)) {
|
|
17
41
|
try {
|
|
18
42
|
computeDocumentFqn(doc, services);
|
|
19
43
|
}
|
|
20
44
|
catch (e) {
|
|
21
|
-
|
|
45
|
+
logError(e);
|
|
22
46
|
}
|
|
23
47
|
}
|
|
24
48
|
}
|
|
@@ -28,17 +52,26 @@ export class FqnIndex {
|
|
|
28
52
|
return this.langiumDocuments.all.filter(isFqnIndexedDocument);
|
|
29
53
|
}
|
|
30
54
|
entries() {
|
|
31
|
-
return this.documents().flatMap(doc => doc.c4fqns
|
|
55
|
+
return this.documents().flatMap(doc => doc.c4fqns
|
|
56
|
+
.entries()
|
|
57
|
+
.map(([fqn, entry]) => {
|
|
58
|
+
const el = entry.el.deref();
|
|
59
|
+
if (el) {
|
|
60
|
+
return { ...entry, fqn, el, doc };
|
|
61
|
+
}
|
|
62
|
+
return null;
|
|
63
|
+
})
|
|
64
|
+
.nonNullable());
|
|
32
65
|
}
|
|
33
66
|
getFqn(el) {
|
|
34
|
-
return ElementOps.readId(el) ?? null;
|
|
67
|
+
return el.fqn ?? ElementOps.readId(el) ?? null;
|
|
35
68
|
// if (fqn) {
|
|
36
69
|
// const doc = getDocument(el)
|
|
37
70
|
// if (isFqnIndexedDocument(doc) && doc.c4fqns.has(fqn)) {
|
|
38
71
|
// return fqn
|
|
39
72
|
// }
|
|
40
73
|
// const path = this.services.workspace.AstNodeLocator.getAstNodePath(el)
|
|
41
|
-
//
|
|
74
|
+
// logError(`Clean cached FQN ${fqn} at ${path}`)
|
|
42
75
|
// ElementOps.writeId(el, null)
|
|
43
76
|
// fqn = null
|
|
44
77
|
// }
|
|
@@ -46,31 +79,28 @@ export class FqnIndex {
|
|
|
46
79
|
}
|
|
47
80
|
byFqn(fqn) {
|
|
48
81
|
return this.documents().flatMap(doc => {
|
|
49
|
-
return doc.c4fqns.get(fqn).
|
|
82
|
+
return doc.c4fqns.get(fqn).flatMap(entry => {
|
|
83
|
+
const el = entry.el.deref();
|
|
84
|
+
if (el) {
|
|
85
|
+
return [{ fqn, el, doc, path: entry.path, name: entry.name }];
|
|
86
|
+
}
|
|
87
|
+
return [];
|
|
88
|
+
});
|
|
50
89
|
});
|
|
51
90
|
}
|
|
52
91
|
directChildrenOf(parent) {
|
|
53
|
-
return
|
|
92
|
+
return stream([parent]).flatMap(_parent => {
|
|
54
93
|
const children = this.entries()
|
|
55
|
-
.filter(e => parentFqn(e.fqn) ===
|
|
56
|
-
.map((
|
|
57
|
-
const name = nameFromFqn(e.fqn);
|
|
58
|
-
const entry = { ...e, name };
|
|
59
|
-
return [name, entry];
|
|
60
|
-
})
|
|
94
|
+
.filter(e => parentFqn(e.fqn) === _parent)
|
|
95
|
+
.map((entry) => [entry.name, entry])
|
|
61
96
|
.toArray();
|
|
62
97
|
if (children.length === 0) {
|
|
63
|
-
return
|
|
98
|
+
return [];
|
|
64
99
|
}
|
|
65
100
|
return new MultiMap(children)
|
|
66
101
|
.entriesGroupedByKey()
|
|
67
102
|
.flatMap(([_name, descrs]) => (descrs.length === 1 ? descrs : []))
|
|
68
103
|
.iterator();
|
|
69
|
-
}, iterator => {
|
|
70
|
-
if (iterator) {
|
|
71
|
-
return iterator.next();
|
|
72
|
-
}
|
|
73
|
-
return DONE_RESULT;
|
|
74
104
|
});
|
|
75
105
|
}
|
|
76
106
|
/**
|
package/dist/model/index.d.ts
CHANGED
package/dist/model/index.js
CHANGED
|
@@ -1,30 +1,13 @@
|
|
|
1
|
-
import type
|
|
2
|
-
import { ast } from '../ast';
|
|
3
|
-
import type { LikeC4LangiumDocument } from '../ast';
|
|
1
|
+
import { type c4 } from '@likec4/core';
|
|
4
2
|
import type { LikeC4Services } from '../module';
|
|
5
3
|
export declare class LikeC4ModelBuilder {
|
|
6
4
|
private services;
|
|
7
|
-
private fqnIndex;
|
|
8
5
|
private langiumDocuments;
|
|
9
6
|
private readonly cachedModel;
|
|
10
7
|
constructor(services: LikeC4Services);
|
|
11
8
|
private cleanCache;
|
|
12
9
|
private documents;
|
|
13
10
|
buildModel(): c4.LikeC4Model | null;
|
|
14
|
-
private _buildModel;
|
|
15
|
-
/**
|
|
16
|
-
* @returns if the document was changed
|
|
17
|
-
*/
|
|
18
|
-
protected parseDocument(doc: LikeC4LangiumDocument): void;
|
|
19
|
-
private parseElement;
|
|
20
|
-
private parseRelation;
|
|
21
|
-
private parseElementExpression;
|
|
22
|
-
private parseExpression;
|
|
23
|
-
private parseViewRule;
|
|
24
|
-
private parseElementView;
|
|
25
|
-
protected resolveFqn(node: ast.Element | ast.ExtendElement): c4.Fqn;
|
|
26
|
-
private getAstNodePath;
|
|
27
|
-
private convertTags;
|
|
28
11
|
private scheduledCb;
|
|
29
12
|
private notifyClient;
|
|
30
13
|
}
|