@likec4/language-server 0.6.3 → 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/dist/ast.d.ts +4 -2
- package/dist/ast.js +13 -3
- package/dist/builtin.d.ts +1 -0
- package/dist/builtin.js +1 -0
- package/dist/elementRef.d.ts +2 -1
- package/dist/elementRef.js +1 -0
- package/dist/generated/ast.d.ts +8 -3
- package/dist/generated/ast.js +14 -1
- package/dist/generated/grammar.d.ts +2 -1
- package/dist/generated/grammar.js +43 -37
- package/dist/generated/module.d.ts +2 -1
- package/dist/generated/module.js +2 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.js +2 -0
- package/dist/logger.d.ts +1 -0
- package/dist/logger.js +1 -0
- package/dist/lsp/DocumentSymbolProvider.d.ts +2 -1
- package/dist/lsp/DocumentSymbolProvider.js +29 -11
- package/dist/lsp/HoverProvider.d.ts +2 -1
- package/dist/lsp/HoverProvider.js +1 -0
- package/dist/lsp/SemanticTokenProvider.d.ts +1 -0
- package/dist/lsp/SemanticTokenProvider.js +2 -1
- package/dist/lsp/index.d.ts +1 -0
- package/dist/lsp/index.js +1 -0
- package/dist/model/fqn-index.d.ts +35 -11
- package/dist/model/fqn-index.js +72 -91
- package/dist/model/index.d.ts +1 -0
- package/dist/model/index.js +1 -0
- package/dist/model/model-builder.d.ts +1 -0
- package/dist/model/model-builder.js +12 -5
- package/dist/model/model-locator.d.ts +2 -1
- package/dist/model/model-locator.js +24 -16
- package/dist/module.d.ts +1 -0
- package/dist/module.js +1 -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 +1 -0
- package/dist/references/index.js +1 -0
- package/dist/references/scope-computation.d.ts +5 -1
- package/dist/references/scope-computation.js +13 -3
- package/dist/references/scope-provider.d.ts +4 -0
- package/dist/references/scope-provider.js +40 -30
- package/dist/registerProtocolHandlers.d.ts +1 -0
- package/dist/registerProtocolHandlers.js +7 -6
- package/dist/shared/CodeLensProvider.d.ts +2 -1
- package/dist/shared/CodeLensProvider.js +1 -0
- package/dist/shared/WorkspaceManager.d.ts +3 -2
- package/dist/shared/WorkspaceManager.js +3 -4
- package/dist/shared/index.d.ts +1 -0
- package/dist/shared/index.js +1 -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 +1 -0
- package/dist/utils.js +1 -0
- package/dist/validation/element.d.ts +1 -0
- package/dist/validation/element.js +3 -2
- package/dist/validation/index.d.ts +1 -0
- package/dist/validation/index.js +1 -0
- package/dist/validation/relation.d.ts +1 -0
- package/dist/validation/relation.js +1 -0
- package/dist/validation/specification.d.ts +1 -0
- package/dist/validation/specification.js +1 -0
- package/dist/validation/view.d.ts +1 -0
- package/dist/validation/view.js +1 -0
- package/package.json +26 -31
package/dist/model/fqn-index.js
CHANGED
|
@@ -1,48 +1,80 @@
|
|
|
1
|
-
import { DocumentState, DONE_RESULT, MultiMap, StreamImpl } from 'langium';
|
|
2
|
-
import {
|
|
1
|
+
import { DocumentState, DONE_RESULT, getDocument, MultiMap, StreamImpl } from 'langium';
|
|
2
|
+
import { ElementOps, isLikeC4LangiumDocument } from '../ast';
|
|
3
3
|
import { logger } from '../logger';
|
|
4
|
-
import { parentFqn } from '@likec4/core/utils';
|
|
5
|
-
import
|
|
6
|
-
import {
|
|
4
|
+
import { nameFromFqn, parentFqn } from '@likec4/core/utils';
|
|
5
|
+
import '../elementRef';
|
|
6
|
+
import { isNil } from 'rambdax';
|
|
7
|
+
import '../generated/ast';
|
|
8
|
+
const isFqnIndexedDocument = (doc) => isLikeC4LangiumDocument(doc) && doc.state >= DocumentState.ComputedScopes && !isNil(doc.c4fqns);
|
|
7
9
|
export class FqnIndex {
|
|
8
10
|
services;
|
|
9
11
|
// #fqnMap = new WeakMap<ast.Element, Fqn>()
|
|
10
|
-
|
|
11
|
-
descriptions;
|
|
12
|
+
// protected readonly descriptions: AstNodeDescriptionProvider
|
|
12
13
|
constructor(services) {
|
|
13
14
|
this.services = services;
|
|
14
|
-
this.descriptions = services.workspace.AstNodeDescriptionProvider
|
|
15
|
-
services.shared.workspace.DocumentBuilder.onUpdate((_changed, removed) => {
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
})
|
|
20
|
-
services.shared.workspace.DocumentBuilder.onBuildPhase(
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
15
|
+
// this.descriptions = services.workspace.AstNodeDescriptionProvider
|
|
16
|
+
// services.shared.workspace.DocumentBuilder.onUpdate((_changed, removed) => {
|
|
17
|
+
// for (const uri of [..._changed, ...removed]) {
|
|
18
|
+
// this.cleanIndexedElements(uri)
|
|
19
|
+
// }
|
|
20
|
+
// })
|
|
21
|
+
// services.shared.workspace.DocumentBuilder.onBuildPhase(
|
|
22
|
+
// DocumentState.Parsed,
|
|
23
|
+
// (docs, _cancelToken) => {
|
|
24
|
+
// for (const doc of docs) {
|
|
25
|
+
// this.cleanIndexedElements(doc.uri)
|
|
26
|
+
// this.doIndexElements(doc as LikeC4LangiumDocument)
|
|
27
|
+
// }
|
|
28
|
+
// }
|
|
29
|
+
// )
|
|
30
|
+
}
|
|
31
|
+
documents() {
|
|
32
|
+
return this.services.shared.workspace.LangiumDocuments.all.filter(isFqnIndexedDocument);
|
|
33
|
+
}
|
|
34
|
+
entries() {
|
|
35
|
+
return this.documents().flatMap(doc => doc.c4fqns.entries().map(([fqn, path]) => ({ fqn, path, doc })));
|
|
26
36
|
}
|
|
37
|
+
// private index() {
|
|
38
|
+
// const index = new MultiMap<Fqn, {
|
|
39
|
+
// path: string,
|
|
40
|
+
// doc: LikeC4LangiumDocument
|
|
41
|
+
// }>()
|
|
42
|
+
// this.entries().toMap()
|
|
43
|
+
// this.entries().forEach(({ fqn, path, doc }) => {
|
|
44
|
+
// index.add(fqn, { path, doc })
|
|
45
|
+
// })
|
|
46
|
+
// // for (const doc of this.documents()) {
|
|
47
|
+
// // doc.c4fqns.entries().forEach(([fqn, path]) => {
|
|
48
|
+
// // index.add(fqn, { path, doc })
|
|
49
|
+
// // })
|
|
50
|
+
// // }
|
|
51
|
+
// return index
|
|
52
|
+
// }
|
|
27
53
|
get(el) {
|
|
28
54
|
let fqn = ElementOps.readId(el) ?? null;
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
55
|
+
const doc = getDocument(el);
|
|
56
|
+
if (fqn) {
|
|
57
|
+
if (isFqnIndexedDocument(doc) && doc.c4fqns.has(fqn)) {
|
|
58
|
+
return fqn;
|
|
59
|
+
}
|
|
32
60
|
const path = this.services.workspace.AstNodeLocator.getAstNodePath(el);
|
|
33
61
|
logger.error(`Clean cached FQN ${fqn} at ${path}`);
|
|
34
|
-
|
|
62
|
+
ElementOps.writeId(el, null);
|
|
35
63
|
fqn = null;
|
|
36
64
|
}
|
|
37
65
|
return fqn;
|
|
38
66
|
}
|
|
39
67
|
byFqn(fqn) {
|
|
40
|
-
return this
|
|
68
|
+
return this.documents()
|
|
69
|
+
.flatMap(doc => {
|
|
70
|
+
return doc.c4fqns.get(fqn).map(path => ({ path, doc }));
|
|
71
|
+
});
|
|
41
72
|
}
|
|
42
73
|
directChildrenOf(parent) {
|
|
43
|
-
return this
|
|
44
|
-
.
|
|
45
|
-
.
|
|
74
|
+
return this
|
|
75
|
+
.entries()
|
|
76
|
+
.filter(e => parentFqn(e.fqn) === parent)
|
|
77
|
+
.map((e) => ({ ...e, name: nameFromFqn(e.fqn) }));
|
|
46
78
|
}
|
|
47
79
|
uniqueDescedants(parent) {
|
|
48
80
|
return new StreamImpl(() => {
|
|
@@ -50,24 +82,26 @@ export class FqnIndex {
|
|
|
50
82
|
const children = [];
|
|
51
83
|
const childrenNames = new Set();
|
|
52
84
|
const descedants = [];
|
|
53
|
-
this
|
|
54
|
-
if (fqn.startsWith(prefix)) {
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
85
|
+
this.entries().forEach(e => {
|
|
86
|
+
if (e.fqn.startsWith(prefix)) {
|
|
87
|
+
const name = nameFromFqn(e.fqn);
|
|
88
|
+
const entry = { ...e, name };
|
|
89
|
+
if (parentFqn(e.fqn) === parent) {
|
|
90
|
+
childrenNames.add(name);
|
|
91
|
+
children.push(entry);
|
|
58
92
|
}
|
|
59
93
|
else {
|
|
60
|
-
descedants.push(
|
|
94
|
+
descedants.push(entry);
|
|
61
95
|
}
|
|
62
96
|
}
|
|
63
97
|
});
|
|
64
98
|
if (children.length + descedants.length === 0) {
|
|
65
99
|
return null;
|
|
66
100
|
}
|
|
67
|
-
const nested = new MultiMap(children.map(
|
|
68
|
-
for (const
|
|
69
|
-
if (!childrenNames.has(
|
|
70
|
-
nested.add(
|
|
101
|
+
const nested = new MultiMap(children.map(entry => [entry.name, entry]));
|
|
102
|
+
for (const descedant of descedants) {
|
|
103
|
+
if (!childrenNames.has(descedant.name)) {
|
|
104
|
+
nested.add(descedant.name, descedant);
|
|
71
105
|
}
|
|
72
106
|
}
|
|
73
107
|
return nested
|
|
@@ -81,58 +115,5 @@ export class FqnIndex {
|
|
|
81
115
|
return DONE_RESULT;
|
|
82
116
|
});
|
|
83
117
|
}
|
|
84
|
-
doIndexElements(doc) {
|
|
85
|
-
const visitElement = (element, parent = null) => {
|
|
86
|
-
try {
|
|
87
|
-
const name = element.name;
|
|
88
|
-
const fqn = Fqn(name, parent);
|
|
89
|
-
this.#index.add(fqn, this.descriptions.createDescription(element, name, doc));
|
|
90
|
-
ElementOps.writeId(element, fqn);
|
|
91
|
-
// this.#fqnMap.set(element, fqn)
|
|
92
|
-
if (element.body) {
|
|
93
|
-
for (const nested of element.body.elements) {
|
|
94
|
-
if (ast.isElement(nested)) {
|
|
95
|
-
visitElement(nested, fqn);
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
catch (e) {
|
|
101
|
-
logger.warn(e);
|
|
102
|
-
}
|
|
103
|
-
};
|
|
104
|
-
const visitExtendElement = (extendElement) => {
|
|
105
|
-
try {
|
|
106
|
-
const fqn = strictElementRefFqn(extendElement.element);
|
|
107
|
-
for (const nested of extendElement.body.elements) {
|
|
108
|
-
if (ast.isElement(nested)) {
|
|
109
|
-
visitElement(nested, fqn);
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
catch (e) {
|
|
114
|
-
logger.warn(e);
|
|
115
|
-
}
|
|
116
|
-
};
|
|
117
|
-
const elements = doc.parseResult.value.model?.elements ?? [];
|
|
118
|
-
for (const modelElement of elements) {
|
|
119
|
-
if (ast.isExtendElement(modelElement)) {
|
|
120
|
-
visitExtendElement(modelElement);
|
|
121
|
-
continue;
|
|
122
|
-
}
|
|
123
|
-
if (ast.isElement(modelElement)) {
|
|
124
|
-
visitElement(modelElement);
|
|
125
|
-
continue;
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
cleanIndexedElements(docUri) {
|
|
130
|
-
const docUriAsString = docUri.toString();
|
|
131
|
-
const toDelete = this.#index
|
|
132
|
-
.entries()
|
|
133
|
-
.filter(([, indexed]) => indexed.documentUri.toString() === docUriAsString);
|
|
134
|
-
for (const [fqn, indexed] of toDelete.toArray()) {
|
|
135
|
-
this.#index.delete(fqn, indexed);
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
118
|
}
|
|
119
|
+
//# sourceMappingURL=fqn-index.js.map
|
package/dist/model/index.d.ts
CHANGED
package/dist/model/index.js
CHANGED
|
@@ -10,7 +10,7 @@ import { toAutoLayout } from '../ast';
|
|
|
10
10
|
import { ElementViewOps, ast, c4hash, cleanParsedModel, isLikeC4LangiumDocument, isParsedLikeC4LangiumDocument, resolveRelationPoints, streamModel, toElementStyle } from '../ast';
|
|
11
11
|
import { elementRef, strictElementRefFqn } from '../elementRef';
|
|
12
12
|
import { logger } from '../logger';
|
|
13
|
-
import { Rpc } from '
|
|
13
|
+
import { Rpc } from '../protocol';
|
|
14
14
|
import { failExpectedNever } from '../utils';
|
|
15
15
|
export class LikeC4ModelBuilder {
|
|
16
16
|
services;
|
|
@@ -79,13 +79,17 @@ export class LikeC4ModelBuilder {
|
|
|
79
79
|
const elements = pipe(docs.flatMap(d => d.c4Elements), A.filterMap(flow(toModelElement, O.fromNullable)), A.sort(compareByFqnHierarchically), A.reduce({}, (acc, el) => {
|
|
80
80
|
const parent = parentFqn(el.id);
|
|
81
81
|
if (!parent || parent in acc) {
|
|
82
|
-
|
|
82
|
+
if (el.id in acc) {
|
|
83
|
+
logger.warn(`Duplicate element id: ${el.id}`);
|
|
84
|
+
}
|
|
83
85
|
acc[el.id] = el;
|
|
84
86
|
}
|
|
85
87
|
return acc;
|
|
86
88
|
}));
|
|
87
89
|
const relations = pipe(docs.flatMap(d => d.c4Relations), A.filterMap(flow(toModelRelation, O.fromPredicate(({ source, target }) => source in elements && target in elements))), A.reduce({}, (acc, el) => {
|
|
88
|
-
|
|
90
|
+
if (el.id in acc) {
|
|
91
|
+
logger.warn(`Duplicate relation id: ${el.id}`);
|
|
92
|
+
}
|
|
89
93
|
acc[el.id] = el;
|
|
90
94
|
return acc;
|
|
91
95
|
}));
|
|
@@ -95,13 +99,15 @@ export class LikeC4ModelBuilder {
|
|
|
95
99
|
title = elements[view.viewOf]?.title;
|
|
96
100
|
}
|
|
97
101
|
return {
|
|
98
|
-
...omit(['astPath', 'rules', '
|
|
102
|
+
...omit(['astPath', 'rules', 'title'], view),
|
|
99
103
|
...(!!title ? { title } : {}),
|
|
100
104
|
rules: clone(view.rules)
|
|
101
105
|
};
|
|
102
106
|
};
|
|
103
107
|
const views = pipe(docs.flatMap(d => d.c4Views), A.filterMap(flow(toModelView, O.fromPredicate(v => isNil(v.viewOf) || v.viewOf in elements))), A.reduce({}, (acc, v) => {
|
|
104
|
-
|
|
108
|
+
if (v.id in acc) {
|
|
109
|
+
logger.warn(`Duplicate view id: ${v.id}`);
|
|
110
|
+
}
|
|
105
111
|
acc[v.id] = v;
|
|
106
112
|
return acc;
|
|
107
113
|
}));
|
|
@@ -330,3 +336,4 @@ export class LikeC4ModelBuilder {
|
|
|
330
336
|
await connection.sendNotification(Rpc.onDidChangeModel);
|
|
331
337
|
}
|
|
332
338
|
}
|
|
339
|
+
//# sourceMappingURL=model-builder.js.map
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type * as c4 from '@likec4/core/types';
|
|
2
|
-
import type { Location } from 'vscode-languageserver
|
|
2
|
+
import type { Location } from 'vscode-languageserver';
|
|
3
3
|
import type { ParsedAstElement } from '../ast';
|
|
4
4
|
import { ast } from '../ast';
|
|
5
5
|
import type { LikeC4Services } from '../module';
|
|
@@ -14,3 +14,4 @@ export declare class LikeC4ModelLocator {
|
|
|
14
14
|
locateRelation(relationId: c4.RelationID): Location | null;
|
|
15
15
|
locateView(viewId: c4.ViewID): Location | null;
|
|
16
16
|
}
|
|
17
|
+
//# sourceMappingURL=model-locator.d.ts.map
|
|
@@ -1,6 +1,4 @@
|
|
|
1
|
-
import { getDocument } from 'langium';
|
|
2
|
-
import { findNodeForKeyword, findNodeForProperty } from 'langium';
|
|
3
|
-
import { head } from 'rambdax';
|
|
1
|
+
import { findNodeForKeyword, findNodeForProperty, getDocument } from 'langium';
|
|
4
2
|
import { ast, isParsedLikeC4LangiumDocument } from '../ast';
|
|
5
3
|
export class LikeC4ModelLocator {
|
|
6
4
|
services;
|
|
@@ -25,19 +23,28 @@ export class LikeC4ModelLocator {
|
|
|
25
23
|
return doc.c4Elements.find(e => e.id === fqn) ?? null;
|
|
26
24
|
}
|
|
27
25
|
locateElement(fqn, property = 'name') {
|
|
28
|
-
const
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
26
|
+
for (const doc of this.documents()) {
|
|
27
|
+
if (doc.c4fqns && !doc.c4fqns.has(fqn)) {
|
|
28
|
+
continue;
|
|
29
|
+
}
|
|
30
|
+
const element = doc.c4Elements.find(e => e.id === fqn);
|
|
31
|
+
if (!element) {
|
|
32
|
+
continue;
|
|
33
|
+
}
|
|
34
|
+
const node = this.services.workspace.AstNodeLocator.getAstNode(doc.parseResult.value, element.astPath);
|
|
35
|
+
if (!ast.isElement(node)) {
|
|
36
|
+
continue;
|
|
37
|
+
}
|
|
38
|
+
const propertyNode = findNodeForProperty(node.$cstNode, property) ?? node.$cstNode;
|
|
39
|
+
if (!propertyNode) {
|
|
40
|
+
return null;
|
|
41
|
+
}
|
|
42
|
+
return {
|
|
43
|
+
uri: doc.uri.toString(),
|
|
44
|
+
range: propertyNode.range
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
return null;
|
|
41
48
|
}
|
|
42
49
|
locateRelation(relationId) {
|
|
43
50
|
for (const doc of this.documents()) {
|
|
@@ -106,3 +113,4 @@ export class LikeC4ModelLocator {
|
|
|
106
113
|
return null;
|
|
107
114
|
}
|
|
108
115
|
}
|
|
116
|
+
//# sourceMappingURL=model-locator.js.map
|
package/dist/module.d.ts
CHANGED
package/dist/module.js
CHANGED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import type { Fqn, LikeC4Model, RelationID, ViewID } from '@likec4/core';
|
|
2
|
+
import type { DocumentUri, Location } from 'vscode-languageserver-protocol';
|
|
3
|
+
import { NotificationType0, RequestType0, RequestType } from 'vscode-languageserver-protocol';
|
|
4
|
+
export declare const onDidChangeModel: NotificationType0;
|
|
5
|
+
export declare const fetchModel: RequestType0<{
|
|
6
|
+
model: LikeC4Model | null;
|
|
7
|
+
}, void>;
|
|
8
|
+
export interface BuildDocumentsParams {
|
|
9
|
+
docs: DocumentUri[];
|
|
10
|
+
}
|
|
11
|
+
export declare const buildDocuments: RequestType<BuildDocumentsParams, void, void>;
|
|
12
|
+
export interface LocateElementParams {
|
|
13
|
+
element: Fqn;
|
|
14
|
+
property?: string;
|
|
15
|
+
}
|
|
16
|
+
export declare const locateElement: RequestType<LocateElementParams, Location | null, void>;
|
|
17
|
+
export declare const locateRelation: RequestType<{
|
|
18
|
+
id: RelationID;
|
|
19
|
+
}, Location | null, void>;
|
|
20
|
+
export declare const locateView: RequestType<{
|
|
21
|
+
id: ViewID;
|
|
22
|
+
}, Location | null, void>;
|
|
23
|
+
export declare const Rpc: {
|
|
24
|
+
readonly onDidChangeModel: NotificationType0;
|
|
25
|
+
readonly fetchModel: RequestType0<{
|
|
26
|
+
model: LikeC4Model | null;
|
|
27
|
+
}, void>;
|
|
28
|
+
readonly buildDocuments: RequestType<BuildDocumentsParams, void, void>;
|
|
29
|
+
readonly locateElement: RequestType<LocateElementParams, Location | null, void>;
|
|
30
|
+
readonly locateRelation: RequestType<{
|
|
31
|
+
id: RelationID;
|
|
32
|
+
}, Location | null, void>;
|
|
33
|
+
readonly locateView: RequestType<{
|
|
34
|
+
id: ViewID;
|
|
35
|
+
}, Location | null, void>;
|
|
36
|
+
};
|
|
37
|
+
//# sourceMappingURL=protocol.d.ts.map
|
package/dist/protocol.js
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { NotificationType0, RequestType0, RequestType } from 'vscode-languageserver-protocol';
|
|
2
|
+
//#region From server
|
|
3
|
+
export const onDidChangeModel = new NotificationType0('likec4/onDidChangeModel');
|
|
4
|
+
//#endregion
|
|
5
|
+
//#region To server
|
|
6
|
+
export const fetchModel = new RequestType0('likec4/fetchModel');
|
|
7
|
+
export const buildDocuments = new RequestType('likec4/buildDocuments');
|
|
8
|
+
export const locateElement = new RequestType('likec4/locateElement');
|
|
9
|
+
export const locateRelation = new RequestType('likec4/locateRelation');
|
|
10
|
+
export const locateView = new RequestType('likec4/locateView');
|
|
11
|
+
//#endregion
|
|
12
|
+
export const Rpc = {
|
|
13
|
+
onDidChangeModel,
|
|
14
|
+
fetchModel,
|
|
15
|
+
buildDocuments,
|
|
16
|
+
locateElement,
|
|
17
|
+
locateRelation,
|
|
18
|
+
locateView
|
|
19
|
+
};
|
|
20
|
+
//# sourceMappingURL=protocol.js.map
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { failExpectedNever } from '@likec4/core';
|
|
2
|
+
import { Fqn } from '@likec4/core/types';
|
|
3
|
+
import { MultiMap } from 'langium';
|
|
4
|
+
import { isEmpty, isNil } from 'rambdax';
|
|
5
|
+
import { ElementOps, ast } from '../ast';
|
|
6
|
+
import { strictElementRefFqn } from '../elementRef';
|
|
7
|
+
export function computeDocumentFqn(document, services) {
|
|
8
|
+
const { model } = document.parseResult.value;
|
|
9
|
+
if (!model?.elements) {
|
|
10
|
+
return;
|
|
11
|
+
}
|
|
12
|
+
const c4fqns = document.c4fqns = new MultiMap();
|
|
13
|
+
const locator = services.workspace.AstNodeLocator;
|
|
14
|
+
const traverseStack = model.elements.map(el => [el, null]);
|
|
15
|
+
let pair;
|
|
16
|
+
while ((pair = traverseStack.shift())) {
|
|
17
|
+
const [el, parent] = pair;
|
|
18
|
+
if (ast.isRelation(el)) {
|
|
19
|
+
continue;
|
|
20
|
+
}
|
|
21
|
+
if (ast.isExtendElement(el)) {
|
|
22
|
+
if (!isNil(el.body) && !isEmpty(el.body.elements)) {
|
|
23
|
+
const fqn = strictElementRefFqn(el.element);
|
|
24
|
+
el.body.elements.forEach(child => traverseStack.push([child, fqn]));
|
|
25
|
+
}
|
|
26
|
+
continue;
|
|
27
|
+
}
|
|
28
|
+
if (ast.isElement(el)) {
|
|
29
|
+
const fqn = Fqn(el.name, parent);
|
|
30
|
+
const path = locator.getAstNodePath(el);
|
|
31
|
+
c4fqns.add(fqn, path);
|
|
32
|
+
ElementOps.writeId(el, fqn);
|
|
33
|
+
if (!isNil(el.body) && !isEmpty(el.body.elements)) {
|
|
34
|
+
el.body.elements.forEach(child => traverseStack.push([child, fqn]));
|
|
35
|
+
}
|
|
36
|
+
continue;
|
|
37
|
+
}
|
|
38
|
+
failExpectedNever(el);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=fqn-computation.js.map
|
package/dist/references/index.js
CHANGED
|
@@ -1,10 +1,14 @@
|
|
|
1
1
|
import { DefaultScopeComputation, MultiMap, type AstNodeDescription, type PrecomputedScopes } from 'langium';
|
|
2
|
-
import type { CancellationToken } from 'vscode-languageserver
|
|
2
|
+
import type { CancellationToken } from 'vscode-languageserver';
|
|
3
3
|
import { ast, type LikeC4LangiumDocument } from '../ast';
|
|
4
|
+
import type { LikeC4Services } from '../module';
|
|
4
5
|
type ElementsContainer = ast.Model | ast.ElementBody | ast.ExtendElementBody;
|
|
5
6
|
export declare class LikeC4ScopeComputation extends DefaultScopeComputation {
|
|
7
|
+
private services;
|
|
8
|
+
constructor(services: LikeC4Services);
|
|
6
9
|
computeExports(document: LikeC4LangiumDocument, _cancelToken: CancellationToken): Promise<AstNodeDescription[]>;
|
|
7
10
|
computeLocalScopes(document: LikeC4LangiumDocument, _cancelToken: CancellationToken): Promise<PrecomputedScopes>;
|
|
8
11
|
protected processContainer(container: ElementsContainer, scopes: PrecomputedScopes, document: LikeC4LangiumDocument): MultiMap<string, AstNodeDescription>;
|
|
9
12
|
}
|
|
10
13
|
export {};
|
|
14
|
+
//# sourceMappingURL=scope-computation.d.ts.map
|
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
import { DefaultScopeComputation, MultiMap } from 'langium';
|
|
2
2
|
import { ast } from '../ast';
|
|
3
|
+
import { computeDocumentFqn } from './fqn-computation';
|
|
3
4
|
export class LikeC4ScopeComputation extends DefaultScopeComputation {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
services;
|
|
6
|
+
constructor(services) {
|
|
7
|
+
super(services);
|
|
8
|
+
this.services = services;
|
|
9
|
+
}
|
|
7
10
|
computeExports(document, _cancelToken) {
|
|
8
11
|
const { specification, model, views } = document.parseResult.value;
|
|
9
12
|
const docExports = [];
|
|
@@ -16,13 +19,19 @@ export class LikeC4ScopeComputation extends DefaultScopeComputation {
|
|
|
16
19
|
docExports.push(this.descriptions.createDescription(tag, '#' + tag.name, document));
|
|
17
20
|
}
|
|
18
21
|
}
|
|
22
|
+
document.c4fqns = undefined;
|
|
19
23
|
if (model) {
|
|
20
24
|
for (const elAst of model.elements) {
|
|
21
25
|
if (ast.isElement(elAst)) {
|
|
22
26
|
docExports.push(this.descriptions.createDescription(elAst, elAst.name, document));
|
|
23
27
|
}
|
|
24
28
|
}
|
|
29
|
+
computeDocumentFqn(document, this.services);
|
|
25
30
|
}
|
|
31
|
+
// const c4fqns = document.c4fqns
|
|
32
|
+
// logger.debug(`doc ${document.uri.path}:
|
|
33
|
+
// fqns: ${c4fqns ? Array.from(c4fqns.keys()).join(', ') : '--'}
|
|
34
|
+
// `)
|
|
26
35
|
if (views) {
|
|
27
36
|
for (const viewAst of views.views) {
|
|
28
37
|
if ('name' in viewAst) {
|
|
@@ -74,3 +83,4 @@ export class LikeC4ScopeComputation extends DefaultScopeComputation {
|
|
|
74
83
|
return localScope;
|
|
75
84
|
}
|
|
76
85
|
}
|
|
86
|
+
//# sourceMappingURL=scope-computation.js.map
|
|
@@ -4,7 +4,10 @@ import type { LikeC4Services } from '../module';
|
|
|
4
4
|
export declare class LikeC4ScopeProvider extends DefaultScopeProvider {
|
|
5
5
|
private fqnIndex;
|
|
6
6
|
constructor(services: LikeC4Services);
|
|
7
|
+
private directChildrenOf;
|
|
8
|
+
private uniqueDescedants;
|
|
7
9
|
private scopeElementRef;
|
|
10
|
+
private scopeExtendElement;
|
|
8
11
|
private scopeElementView;
|
|
9
12
|
getScope(context: ReferenceInfo): Scope;
|
|
10
13
|
protected computeScope(node: AstNode, referenceType: string): Scope;
|
|
@@ -13,3 +16,4 @@ export declare class LikeC4ScopeProvider extends DefaultScopeProvider {
|
|
|
13
16
|
*/
|
|
14
17
|
protected getGlobalScope(referenceType: string): Scope;
|
|
15
18
|
}
|
|
19
|
+
//# sourceMappingURL=scope-provider.d.ts.map
|