@likec4/language-server 0.6.0 → 0.6.2

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.
Files changed (67) hide show
  1. package/package.json +19 -18
  2. package/dist/ast.d.ts +0 -72
  3. package/dist/ast.js +0 -133
  4. package/dist/builtin.d.ts +0 -4
  5. package/dist/builtin.js +0 -8
  6. package/dist/elementRef.d.ts +0 -6
  7. package/dist/elementRef.js +0 -39
  8. package/dist/generated/ast.d.ts +0 -359
  9. package/dist/generated/ast.js +0 -376
  10. package/dist/generated/grammar.d.ts +0 -6
  11. package/dist/generated/grammar.js +0 -2542
  12. package/dist/generated/module.d.ts +0 -9
  13. package/dist/generated/module.js +0 -26
  14. package/dist/index.d.ts +0 -4
  15. package/dist/index.js +0 -15
  16. package/dist/logger.d.ts +0 -8
  17. package/dist/logger.js +0 -20
  18. package/dist/lsp/DocumentSymbolProvider.d.ts +0 -20
  19. package/dist/lsp/DocumentSymbolProvider.js +0 -149
  20. package/dist/lsp/HoverProvider.d.ts +0 -8
  21. package/dist/lsp/HoverProvider.js +0 -54
  22. package/dist/lsp/SemanticTokenProvider.d.ts +0 -6
  23. package/dist/lsp/SemanticTokenProvider.js +0 -221
  24. package/dist/lsp/index.d.ts +0 -3
  25. package/dist/lsp/index.js +0 -3
  26. package/dist/model/fqn-index.d.ts +0 -17
  27. package/dist/model/fqn-index.js +0 -138
  28. package/dist/model/index.d.ts +0 -3
  29. package/dist/model/index.js +0 -3
  30. package/dist/model/model-builder.d.ts +0 -26
  31. package/dist/model/model-builder.js +0 -332
  32. package/dist/model/model-locator.d.ts +0 -16
  33. package/dist/model/model-locator.js +0 -108
  34. package/dist/module.d.ts +0 -18
  35. package/dist/module.js +0 -61
  36. package/dist/protocol.d.ts +0 -35
  37. package/dist/protocol.js +0 -19
  38. package/dist/references/index.d.ts +0 -2
  39. package/dist/references/index.js +0 -2
  40. package/dist/references/scope-computation.d.ts +0 -10
  41. package/dist/references/scope-computation.js +0 -76
  42. package/dist/references/scope-provider.d.ts +0 -15
  43. package/dist/references/scope-provider.js +0 -110
  44. package/dist/registerProtocolHandlers.d.ts +0 -2
  45. package/dist/registerProtocolHandlers.js +0 -49
  46. package/dist/shared/CodeLensProvider.d.ts +0 -8
  47. package/dist/shared/CodeLensProvider.js +0 -35
  48. package/dist/shared/WorkspaceManager.d.ts +0 -13
  49. package/dist/shared/WorkspaceManager.js +0 -19
  50. package/dist/shared/index.d.ts +0 -2
  51. package/dist/shared/index.js +0 -2
  52. package/dist/test/index.d.ts +0 -1
  53. package/dist/test/index.js +0 -1
  54. package/dist/test/testServices.d.ts +0 -15
  55. package/dist/test/testServices.js +0 -57
  56. package/dist/utils.d.ts +0 -2
  57. package/dist/utils.js +0 -7
  58. package/dist/validation/element.d.ts +0 -4
  59. package/dist/validation/element.js +0 -20
  60. package/dist/validation/index.d.ts +0 -2
  61. package/dist/validation/index.js +0 -22
  62. package/dist/validation/relation.d.ts +0 -4
  63. package/dist/validation/relation.js +0 -53
  64. package/dist/validation/specification.d.ts +0 -5
  65. package/dist/validation/specification.js +0 -33
  66. package/dist/validation/view.d.ts +0 -4
  67. package/dist/validation/view.js +0 -20
@@ -1,138 +0,0 @@
1
- import { DocumentState, DONE_RESULT, MultiMap, StreamImpl } from 'langium';
2
- import { ast, ElementOps } from '../ast';
3
- import { logger } from '../logger';
4
- import { parentFqn } from '@likec4/core/utils';
5
- import { Fqn } from '@likec4/core/types';
6
- import { strictElementRefFqn } from '../elementRef';
7
- export class FqnIndex {
8
- services;
9
- // #fqnMap = new WeakMap<ast.Element, Fqn>()
10
- #index = new MultiMap();
11
- descriptions;
12
- constructor(services) {
13
- this.services = services;
14
- this.descriptions = services.workspace.AstNodeDescriptionProvider;
15
- services.shared.workspace.DocumentBuilder.onUpdate((_changed, removed) => {
16
- for (const uri of [...removed]) {
17
- this.cleanIndexedElements(uri);
18
- }
19
- });
20
- services.shared.workspace.DocumentBuilder.onBuildPhase(DocumentState.ComputedScopes, (docs, _cancelToken) => {
21
- for (const doc of docs) {
22
- this.cleanIndexedElements(doc.uri);
23
- this.doIndexElements(doc);
24
- }
25
- });
26
- }
27
- get(el) {
28
- let fqn = ElementOps.readId(el) ?? null;
29
- // if ()
30
- // let fqn = this.#fqnMap.get(el) ?? null
31
- if (fqn && !this.#index.has(fqn)) {
32
- const path = this.services.workspace.AstNodeLocator.getAstNodePath(el);
33
- logger.error(`Clean cached FQN ${fqn} at ${path}`);
34
- // this.#fqnMap.delete(el)
35
- fqn = null;
36
- }
37
- return fqn;
38
- }
39
- byFqn(fqn) {
40
- return this.#index.get(fqn);
41
- }
42
- directChildrenOf(parent) {
43
- return this.#index
44
- .entriesGroupedByKey()
45
- .flatMap(([fqn, descrs]) => (descrs.length === 1 && parentFqn(fqn) === parent ? descrs : []));
46
- }
47
- uniqueDescedants(parent) {
48
- return new StreamImpl(() => {
49
- const prefix = `${parent}.`;
50
- const children = [];
51
- const childrenNames = new Set();
52
- const descedants = [];
53
- this.#index.entries().forEach(([fqn, desc]) => {
54
- if (fqn.startsWith(prefix)) {
55
- if (parentFqn(fqn) === parent) {
56
- childrenNames.add(desc.name);
57
- children.push([fqn, desc]);
58
- }
59
- else {
60
- descedants.push([fqn, desc]);
61
- }
62
- }
63
- });
64
- if (children.length + descedants.length === 0) {
65
- return null;
66
- }
67
- const nested = new MultiMap(children.map(([_fqn, desc]) => [desc.name, desc]));
68
- for (const [_, indexed] of descedants) {
69
- if (!childrenNames.has(indexed.name)) {
70
- nested.add(indexed.name, indexed);
71
- }
72
- }
73
- return nested
74
- .entriesGroupedByKey()
75
- .flatMap(([_name, descrs]) => (descrs.length === 1 ? descrs : []))
76
- .iterator();
77
- }, iterator => {
78
- if (iterator) {
79
- return iterator.next();
80
- }
81
- return DONE_RESULT;
82
- });
83
- }
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
- }
@@ -1,3 +0,0 @@
1
- export * from './fqn-index';
2
- export * from './model-builder';
3
- export * from './model-locator';
@@ -1,3 +0,0 @@
1
- export * from './fqn-index';
2
- export * from './model-builder';
3
- export * from './model-locator';
@@ -1,26 +0,0 @@
1
- import type * as c4 from '@likec4/core/types';
2
- import { ast, type LikeC4LangiumDocument } from '../ast';
3
- import type { LikeC4Services } from '../module';
4
- export declare class LikeC4ModelBuilder {
5
- private services;
6
- private fqnIndex;
7
- private langiumDocuments;
8
- constructor(services: LikeC4Services);
9
- private get connection();
10
- private documents;
11
- buildModel(): c4.LikeC4Model | undefined;
12
- /**
13
- * @returns if the document was changed
14
- */
15
- protected parseDocument(doc: LikeC4LangiumDocument): boolean;
16
- private parseElement;
17
- private parseRelation;
18
- private parseElementExpression;
19
- private parseExpression;
20
- private parseViewRule;
21
- private parseElementView;
22
- protected resolveFqn(node: ast.Element | ast.ExtendElement): c4.Fqn;
23
- private getAstNodePath;
24
- private convertTags;
25
- private notifyClient;
26
- }
@@ -1,332 +0,0 @@
1
- import { computeViews } from '@likec4/core/compute-view';
2
- import { DefaultElementShape, DefaultThemeColor } from '@likec4/core/types';
3
- import { compareByFqnHierarchically, parentFqn } from '@likec4/core/utils';
4
- import { A, O, flow, pipe } from '@mobily/ts-belt';
5
- import { DocumentState, getDocument, interruptAndCheck } from 'langium';
6
- import objectHash from 'object-hash';
7
- import { clone, isNil, mergeDeepRight, omit, reduce } from 'rambdax';
8
- import invariant from 'tiny-invariant';
9
- import { toAutoLayout } from '../ast';
10
- import { ElementViewOps, ast, c4hash, cleanParsedModel, isLikeC4LangiumDocument, isParsedLikeC4LangiumDocument, resolveRelationPoints, streamModel, toElementStyle } from '../ast';
11
- import { elementRef, strictElementRefFqn } from '../elementRef';
12
- import { logger } from '../logger';
13
- import { Rpc } from '../protocol';
14
- import { failExpectedNever } from '../utils';
15
- export class LikeC4ModelBuilder {
16
- services;
17
- fqnIndex;
18
- langiumDocuments;
19
- constructor(services) {
20
- this.services = services;
21
- this.fqnIndex = services.likec4.FqnIndex;
22
- this.langiumDocuments = services.shared.workspace.LangiumDocuments;
23
- services.shared.workspace.DocumentBuilder.onBuildPhase(DocumentState.Validated, async (docs, cancelToken) => {
24
- let countOfChangedDocs = 0;
25
- try {
26
- for (const doc of docs) {
27
- await interruptAndCheck(cancelToken);
28
- try {
29
- if (isLikeC4LangiumDocument(doc) && this.parseDocument(doc)) {
30
- countOfChangedDocs++;
31
- }
32
- }
33
- catch (e) {
34
- logger.warn(`Error parsing document ${doc.uri.toString()}`);
35
- }
36
- }
37
- }
38
- finally {
39
- if (countOfChangedDocs > 0 && !cancelToken.isCancellationRequested) {
40
- await this.notifyClient();
41
- }
42
- }
43
- });
44
- }
45
- get connection() {
46
- return this.services.shared.lsp.Connection;
47
- }
48
- documents() {
49
- return this.langiumDocuments.all.toArray().filter(isParsedLikeC4LangiumDocument);
50
- }
51
- buildModel() {
52
- const docs = this.documents();
53
- if (docs.length === 0) {
54
- return;
55
- }
56
- try {
57
- const c4Specification = reduce((acc, doc) => mergeDeepRight(acc, doc.c4Specification), {
58
- kinds: {}
59
- }, docs);
60
- // const c4Specification = docs.reduce<ParsedAstSpecification>((acc, doc) => {
61
- // return mergeDeepRight(acc, doc.c4Specification)
62
- // }, {
63
- // kinds: {}
64
- // })
65
- const toModelElement = (el) => {
66
- const kind = c4Specification.kinds[el.kind];
67
- if (kind) {
68
- return {
69
- ...(kind.shape !== DefaultElementShape ? { shape: kind.shape } : {}),
70
- ...(kind.color !== DefaultThemeColor ? { color: kind.color } : {}),
71
- ...omit(['astPath'], el)
72
- };
73
- }
74
- return null;
75
- };
76
- const toModelRelation = (rel) => {
77
- return omit(['astPath'], rel);
78
- };
79
- const elements = pipe(docs.flatMap(d => d.c4Elements), A.filterMap(flow(toModelElement, O.fromNullable)), A.sort(compareByFqnHierarchically), A.reduce({}, (acc, el) => {
80
- const parent = parentFqn(el.id);
81
- if (!parent || parent in acc) {
82
- invariant(!(el.id in acc), 'Duplicate element id: ' + el.id);
83
- acc[el.id] = el;
84
- }
85
- return acc;
86
- }));
87
- 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
- invariant(!(el.id in acc), 'Duplicate relation id: ' + el.id);
89
- acc[el.id] = el;
90
- return acc;
91
- }));
92
- const toModelView = (view) => {
93
- let title = view.title;
94
- if (!title && view.viewOf) {
95
- title = elements[view.viewOf]?.title;
96
- }
97
- return {
98
- ...omit(['astPath', 'rules', 'tite'], view),
99
- ...(!!title ? { title } : {}),
100
- rules: clone(view.rules)
101
- };
102
- };
103
- 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
- invariant(!(v.id in acc), 'Duplicate view id: ' + v.id);
105
- acc[v.id] = v;
106
- return acc;
107
- }));
108
- return computeViews({
109
- elements,
110
- relations,
111
- views
112
- });
113
- }
114
- catch (e) {
115
- logger.error(e);
116
- return;
117
- }
118
- }
119
- /**
120
- * @returns if the document was changed
121
- */
122
- parseDocument(doc) {
123
- const { elements, relations, views, specification } = cleanParsedModel(doc);
124
- const spec = doc.parseResult.value.specification;
125
- if (spec) {
126
- for (const { kind, style } of spec.elementKinds) {
127
- try {
128
- const styleProps = toElementStyle(style?.props);
129
- specification.kinds[kind.name] = {
130
- color: styleProps.color ?? DefaultThemeColor,
131
- shape: styleProps.shape ?? DefaultElementShape
132
- };
133
- }
134
- catch (e) {
135
- logger.warn(e);
136
- }
137
- }
138
- }
139
- for (const el of streamModel(doc)) {
140
- if (ast.isElement(el)) {
141
- try {
142
- elements.push(this.parseElement(el));
143
- }
144
- catch (e) {
145
- logger.warn(e);
146
- }
147
- continue;
148
- }
149
- if (ast.isRelation(el)) {
150
- try {
151
- relations.push(this.parseRelation(el));
152
- }
153
- catch (e) {
154
- logger.warn(e);
155
- }
156
- continue;
157
- }
158
- failExpectedNever(el);
159
- }
160
- const docviews = doc.parseResult.value.views?.views;
161
- if (docviews) {
162
- for (const view of docviews) {
163
- try {
164
- const v = this.parseElementView(view);
165
- ElementViewOps.writeId(view, v.id);
166
- views.push(v);
167
- }
168
- catch (e) {
169
- logger.warn(e);
170
- }
171
- }
172
- }
173
- const prevHash = doc.c4hash ?? '';
174
- doc.c4hash = c4hash(doc);
175
- return prevHash !== doc.c4hash;
176
- }
177
- parseElement(astNode) {
178
- const id = this.resolveFqn(astNode);
179
- invariant(astNode.kind.ref, 'Element kind is not resolved: ' + astNode.name);
180
- const kind = astNode.kind.ref.name;
181
- const tags = (astNode.body && this.convertTags(astNode.body)) ?? [];
182
- const styleProps = astNode.body?.props.find(ast.isElementStyleProperty)?.props;
183
- const { color, shape } = toElementStyle(styleProps);
184
- const astPath = this.getAstNodePath(astNode);
185
- let [title, description, technology] = astNode.props;
186
- const bodyProps = astNode.body?.props.filter((p) => ast.isElementStringProperty(p)) ?? [];
187
- title = title ?? bodyProps.find(p => p.key === 'title')?.value;
188
- description = description ?? bodyProps.find(p => p.key === 'description')?.value;
189
- technology = technology ?? bodyProps.find(p => p.key === 'technology')?.value;
190
- return {
191
- id,
192
- kind,
193
- astPath,
194
- title: title ?? astNode.name,
195
- ...(technology && { technology }),
196
- ...(description && { description }),
197
- ...(tags.length > 0 ? { tags } : {}),
198
- ...(shape && shape !== DefaultElementShape ? { shape } : {}),
199
- ...(color && color !== DefaultThemeColor ? { color } : {})
200
- };
201
- }
202
- parseRelation(astNode) {
203
- const coupling = resolveRelationPoints(astNode);
204
- const target = this.resolveFqn(coupling.target);
205
- const source = this.resolveFqn(coupling.source);
206
- const hashdata = {
207
- astPath: this.getAstNodePath(astNode),
208
- source,
209
- target
210
- };
211
- const id = objectHash(hashdata);
212
- const title = astNode.title ?? astNode.definition?.props.find(p => p.key === 'title')?.value ?? '';
213
- return {
214
- id,
215
- ...hashdata,
216
- title
217
- };
218
- }
219
- parseElementExpression(astNode) {
220
- if (ast.isWildcardExpression(astNode)) {
221
- return {
222
- wildcard: true
223
- };
224
- }
225
- if (ast.isElementRefExpression(astNode)) {
226
- const element = elementRef(astNode.id);
227
- invariant(element, 'Element not found ' + astNode.id.$cstNode?.text);
228
- return {
229
- element: this.resolveFqn(element),
230
- isDescedants: astNode.isDescedants
231
- };
232
- }
233
- failExpectedNever(astNode);
234
- }
235
- parseExpression(astNode) {
236
- if (ast.isElementExpression(astNode)) {
237
- return this.parseElementExpression(astNode);
238
- }
239
- if (ast.isIncomingExpression(astNode)) {
240
- return {
241
- incoming: this.parseElementExpression(astNode.target)
242
- };
243
- }
244
- if (ast.isOutgoingExpression(astNode)) {
245
- return {
246
- outgoing: this.parseElementExpression(astNode.source)
247
- };
248
- }
249
- if (ast.isInOutExpression(astNode)) {
250
- return {
251
- inout: this.parseElementExpression(astNode.inout.target)
252
- };
253
- }
254
- if (ast.isRelationExpression(astNode)) {
255
- return {
256
- source: this.parseElementExpression(astNode.source),
257
- target: this.parseElementExpression(astNode.target)
258
- };
259
- }
260
- failExpectedNever(astNode);
261
- }
262
- parseViewRule(astNode) {
263
- if (ast.isViewRuleExpression(astNode)) {
264
- const exprs = astNode.expressions.map(n => this.parseExpression(n));
265
- return {
266
- isInclude: astNode.isInclude,
267
- exprs
268
- };
269
- }
270
- if (ast.isViewRuleStyle(astNode)) {
271
- const styleProps = toElementStyle(astNode.props);
272
- return {
273
- targets: astNode.targets.map(n => this.parseElementExpression(n)),
274
- style: {
275
- ...styleProps
276
- }
277
- };
278
- }
279
- if (ast.isViewRuleAutoLayout(astNode)) {
280
- return {
281
- autoLayout: toAutoLayout(astNode.direction)
282
- };
283
- }
284
- failExpectedNever(astNode);
285
- }
286
- parseElementView(astNode) {
287
- const viewOfEl = astNode.viewOf && elementRef(astNode.viewOf);
288
- const viewOf = viewOfEl && this.resolveFqn(viewOfEl);
289
- const astPath = this.getAstNodePath(astNode);
290
- let id = astNode.name;
291
- if (!id) {
292
- const doc = getDocument(astNode).uri.toString();
293
- id = objectHash({
294
- doc,
295
- astPath,
296
- viewOf: viewOf ?? null
297
- });
298
- }
299
- const title = astNode.properties.find(p => p.key === 'title')?.value;
300
- const description = astNode.properties.find(p => p.key === 'description')?.value;
301
- return {
302
- id,
303
- astPath,
304
- ...(viewOf && { viewOf }),
305
- ...(title && { title }),
306
- ...(description && { description }),
307
- rules: astNode.rules.map(n => this.parseViewRule(n))
308
- };
309
- }
310
- resolveFqn(node) {
311
- if (ast.isExtendElement(node)) {
312
- return strictElementRefFqn(node.element);
313
- }
314
- const fqn = this.fqnIndex.get(node);
315
- invariant(fqn, `Not indexed element: ${this.getAstNodePath(node)}`);
316
- return fqn;
317
- }
318
- getAstNodePath(node) {
319
- return this.services.workspace.AstNodeLocator.getAstNodePath(node);
320
- }
321
- convertTags(el) {
322
- return el.tags?.value.map(tagRef => tagRef.ref?.name) ?? [];
323
- }
324
- async notifyClient() {
325
- const connection = this.connection;
326
- if (!connection) {
327
- return;
328
- }
329
- logger.debug('Send onDidChangeModel');
330
- await connection.sendNotification(Rpc.onDidChangeModel, null);
331
- }
332
- }
@@ -1,16 +0,0 @@
1
- import type * as c4 from '@likec4/core/types';
2
- import type { Location } from 'vscode-languageserver-protocol';
3
- import type { ParsedAstElement } from '../ast';
4
- import { ast } from '../ast';
5
- import type { LikeC4Services } from '../module';
6
- export declare class LikeC4ModelLocator {
7
- private services;
8
- private fqnIndex;
9
- private langiumDocuments;
10
- constructor(services: LikeC4Services);
11
- private documents;
12
- getParsedElement(astNode: ast.Element): ParsedAstElement | null;
13
- locateElement(fqn: c4.Fqn, property?: string): Location | null;
14
- locateRelation(relationId: c4.RelationID): Location | null;
15
- locateView(viewId: c4.ViewID): Location | null;
16
- }
@@ -1,108 +0,0 @@
1
- import { getDocument } from 'langium';
2
- import { findNodeForKeyword, findNodeForProperty } from 'langium';
3
- import { head } from 'rambdax';
4
- import { ast, isParsedLikeC4LangiumDocument } from '../ast';
5
- export class LikeC4ModelLocator {
6
- services;
7
- fqnIndex;
8
- langiumDocuments;
9
- constructor(services) {
10
- this.services = services;
11
- this.fqnIndex = services.likec4.FqnIndex;
12
- this.langiumDocuments = services.shared.workspace.LangiumDocuments;
13
- }
14
- documents() {
15
- return this.langiumDocuments.all.toArray().filter(isParsedLikeC4LangiumDocument);
16
- }
17
- getParsedElement(astNode) {
18
- const doc = getDocument(astNode);
19
- if (!isParsedLikeC4LangiumDocument(doc)) {
20
- return null;
21
- }
22
- const fqn = this.fqnIndex.get(astNode);
23
- if (!fqn)
24
- return null;
25
- return doc.c4Elements.find(e => e.id === fqn) ?? null;
26
- }
27
- locateElement(fqn, property = 'name') {
28
- const descr = head(this.fqnIndex.byFqn(fqn));
29
- if (!descr)
30
- return null;
31
- const docUri = descr.documentUri.toString();
32
- const doc = this.documents().find(d => d.uri.toString() === docUri);
33
- const node = doc && this.services.workspace.AstNodeLocator.getAstNode(doc.parseResult.value, descr.path);
34
- if (!ast.isElement(node) || !node.$cstNode)
35
- return null;
36
- const propertyNode = findNodeForProperty(node.$cstNode, property);
37
- return {
38
- uri: docUri,
39
- range: propertyNode?.range ?? node.$cstNode.range
40
- };
41
- }
42
- locateRelation(relationId) {
43
- for (const doc of this.documents()) {
44
- const relation = doc.c4Relations.find(r => r.id === relationId);
45
- if (!relation) {
46
- continue;
47
- }
48
- const node = this.services.workspace.AstNodeLocator.getAstNode(doc.parseResult.value, relation.astPath);
49
- if (!ast.isRelation(node)) {
50
- continue;
51
- }
52
- if (node.title) {
53
- const targetNode = findNodeForProperty(node.$cstNode, 'title');
54
- if (targetNode) {
55
- return {
56
- uri: doc.uri.toString(),
57
- range: {
58
- start: targetNode.range.start,
59
- end: targetNode.range.start
60
- }
61
- };
62
- }
63
- }
64
- const targetNode = findNodeForKeyword(node.$cstNode, '->');
65
- if (!targetNode) {
66
- return null;
67
- }
68
- return {
69
- uri: doc.uri.toString(),
70
- range: {
71
- start: targetNode.range.end,
72
- end: targetNode.range.end
73
- }
74
- };
75
- }
76
- return null;
77
- }
78
- locateView(viewId) {
79
- for (const doc of this.documents()) {
80
- const view = doc.c4Views.find(r => r.id === viewId);
81
- if (!view) {
82
- continue;
83
- }
84
- const node = this.services.workspace.AstNodeLocator.getAstNode(doc.parseResult.value, view.astPath);
85
- if (!ast.isElementView(node)) {
86
- continue;
87
- }
88
- let targetNode = node.$cstNode;
89
- if (node.name) {
90
- targetNode = findNodeForProperty(node.$cstNode, 'name') ?? targetNode;
91
- }
92
- else if (node.viewOf) {
93
- targetNode = findNodeForProperty(node.$cstNode, 'viewOf') ?? targetNode;
94
- }
95
- if (!targetNode) {
96
- return null;
97
- }
98
- return {
99
- uri: doc.uri.toString(),
100
- range: {
101
- start: targetNode.range.start,
102
- end: targetNode.range.start
103
- }
104
- };
105
- }
106
- return null;
107
- }
108
- }
package/dist/module.d.ts DELETED
@@ -1,18 +0,0 @@
1
- import type { DefaultSharedModuleContext, LangiumServices, LangiumSharedServices, Module, PartialLangiumServices } from 'langium';
2
- import { FqnIndex, LikeC4ModelBuilder, LikeC4ModelLocator } from './model';
3
- /**
4
- * Declaration of custom services - add your own service classes here.
5
- */
6
- export interface LikeC4AddedServices {
7
- likec4: {
8
- FqnIndex: FqnIndex;
9
- ModelBuilder: LikeC4ModelBuilder;
10
- ModelLocator: LikeC4ModelLocator;
11
- };
12
- }
13
- export type LikeC4Services = LangiumServices & LikeC4AddedServices;
14
- export declare const LikeC4Module: Module<LikeC4Services, PartialLangiumServices & LikeC4AddedServices>;
15
- export declare function createLanguageServices(context: DefaultSharedModuleContext): {
16
- shared: LangiumSharedServices;
17
- likec4: LikeC4Services;
18
- };