@likec4/language-server 0.37.0 → 0.40.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.
Files changed (75) hide show
  1. package/dist/Rpc.d.ts +6 -0
  2. package/dist/Rpc.js +130 -0
  3. package/dist/ast.d.ts +0 -97
  4. package/dist/ast.js +127 -143
  5. package/dist/elementRef.d.ts +1 -2
  6. package/dist/elementRef.js +31 -44
  7. package/dist/generated/ast.d.ts +4 -5
  8. package/dist/generated/ast.js +310 -315
  9. package/dist/generated/grammar.d.ts +0 -2
  10. package/dist/generated/grammar.js +2 -3177
  11. package/dist/generated/module.d.ts +1 -6
  12. package/dist/generated/module.js +13 -18
  13. package/dist/index.d.ts +0 -1
  14. package/dist/index.js +2 -3
  15. package/dist/logger.d.ts +0 -1
  16. package/dist/logger.js +39 -42
  17. package/dist/lsp/CodeLensProvider.d.ts +0 -1
  18. package/dist/lsp/CodeLensProvider.js +28 -32
  19. package/dist/lsp/DocumentLinkProvider.d.ts +0 -1
  20. package/dist/lsp/DocumentLinkProvider.js +26 -33
  21. package/dist/lsp/DocumentSymbolProvider.d.ts +0 -1
  22. package/dist/lsp/DocumentSymbolProvider.js +165 -167
  23. package/dist/lsp/HoverProvider.d.ts +0 -1
  24. package/dist/lsp/HoverProvider.js +35 -48
  25. package/dist/lsp/SemanticTokenProvider.d.ts +0 -1
  26. package/dist/lsp/SemanticTokenProvider.js +153 -201
  27. package/dist/lsp/index.d.ts +0 -1
  28. package/dist/lsp/index.js +5 -6
  29. package/dist/model/fqn-computation.d.ts +0 -1
  30. package/dist/model/fqn-computation.js +39 -40
  31. package/dist/model/fqn-index.d.ts +0 -1
  32. package/dist/model/fqn-index.js +112 -142
  33. package/dist/model/index.d.ts +0 -1
  34. package/dist/model/index.js +5 -6
  35. package/dist/model/model-builder.d.ts +10 -6
  36. package/dist/model/model-builder.js +242 -157
  37. package/dist/model/model-locator.d.ts +1 -2
  38. package/dist/model/model-locator.js +102 -100
  39. package/dist/model/model-parser.d.ts +2 -7
  40. package/dist/model/model-parser.js +296 -287
  41. package/dist/module.d.ts +4 -2
  42. package/dist/module.js +69 -60
  43. package/dist/protocol.d.ts +16 -20
  44. package/dist/protocol.js +14 -22
  45. package/dist/references/index.d.ts +0 -1
  46. package/dist/references/index.js +2 -3
  47. package/dist/references/scope-computation.d.ts +2 -3
  48. package/dist/references/scope-computation.js +68 -70
  49. package/dist/references/scope-provider.d.ts +1 -2
  50. package/dist/references/scope-provider.js +126 -116
  51. package/dist/shared/WorkspaceManager.d.ts +2 -4
  52. package/dist/shared/WorkspaceManager.js +13 -16
  53. package/dist/shared/index.d.ts +0 -1
  54. package/dist/shared/index.js +1 -2
  55. package/dist/test/index.d.ts +0 -1
  56. package/dist/test/index.js +1 -2
  57. package/dist/test/testServices.d.ts +6 -7
  58. package/dist/test/testServices.js +64 -61
  59. package/dist/utils.d.ts +1 -1
  60. package/dist/utils.js +4 -3
  61. package/dist/validation/element.d.ts +0 -2
  62. package/dist/validation/element.js +28 -39
  63. package/dist/validation/index.d.ts +0 -1
  64. package/dist/validation/index.js +36 -46
  65. package/dist/validation/relation.d.ts +0 -2
  66. package/dist/validation/relation.js +43 -47
  67. package/dist/validation/specification.d.ts +0 -2
  68. package/dist/validation/specification.js +21 -30
  69. package/dist/validation/view.d.ts +0 -2
  70. package/dist/validation/view.js +16 -22
  71. package/package.json +20 -13
  72. package/contrib/likec4.monarch.ts +0 -48
  73. package/contrib/likec4.tmLanguage.json +0 -73
  74. package/dist/registerProtocolHandlers.d.ts +0 -3
  75. package/dist/registerProtocolHandlers.js +0 -112
@@ -1,147 +1,117 @@
1
- import { nameFromFqn, parentFqn } from '@likec4/core';
2
- import { DONE_RESULT, DocumentState, MultiMap, StreamImpl, stream } from 'langium';
3
- import { isNil } from 'remeda';
4
- import { ElementOps, isLikeC4LangiumDocument } from '../ast';
5
- import { logError, logger } from '../logger';
6
- import { printDocs } from '../utils';
7
- import { computeDocumentFqn } from './fqn-computation';
1
+ import { nameFromFqn, parentFqn } from "@likec4/core";
2
+ import { DONE_RESULT, DocumentState, MultiMap, StreamImpl, stream } from "langium";
3
+ import { isNil } from "remeda";
4
+ import { ElementOps, isLikeC4LangiumDocument } from "../ast.js";
5
+ import { logError, logger } from "../logger.js";
6
+ import { printDocs } from "../utils.js";
7
+ import { computeDocumentFqn } from "./fqn-computation.js";
8
8
  export function isFqnIndexedDocument(doc) {
9
- return isLikeC4LangiumDocument(doc) && doc.state >= DocumentState.IndexedContent && !isNil(doc.c4fqns);
9
+ return isLikeC4LangiumDocument(doc) && doc.state >= DocumentState.IndexedContent && !isNil(doc.c4fqns);
10
10
  }
11
11
  export class FqnIndex {
12
- langiumDocuments;
13
- constructor(services) {
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
- }
12
+ langiumDocuments;
13
+ constructor(services) {
14
+ this.langiumDocuments = services.shared.workspace.LangiumDocuments;
15
+ services.shared.workspace.DocumentBuilder.onBuildPhase(DocumentState.Changed, (docs, _cancelToken) => {
16
+ logger.debug(`[FqnIndex] onChanged (${docs.length} docs):
17
+ ` + printDocs(docs));
18
+ for (const doc of docs) {
19
+ if (isLikeC4LangiumDocument(doc)) {
20
+ delete doc.c4fqns;
21
+ delete doc.c4Elements;
22
+ delete doc.c4Specification;
23
+ delete doc.c4Relations;
24
+ delete doc.c4Views;
25
+ }
26
+ }
27
+ });
28
+ services.shared.workspace.DocumentBuilder.onBuildPhase(DocumentState.IndexedContent, (docs, _cancelToken) => {
29
+ logger.debug(`[FqnIndex] onIndexedContent ${docs.length}:
30
+ ` + printDocs(docs));
31
+ for (const doc of docs) {
32
+ if (isLikeC4LangiumDocument(doc)) {
33
+ try {
34
+ computeDocumentFqn(doc, services);
35
+ } catch (e) {
36
+ logError(e);
37
+ }
38
+ }
39
+ }
40
+ });
41
+ }
42
+ documents() {
43
+ return this.langiumDocuments.all.filter(isFqnIndexedDocument);
44
+ }
45
+ entries(filterByFqn = () => true) {
46
+ return this.documents().flatMap(
47
+ (doc) => doc.c4fqns.entries().filter(([fqn]) => filterByFqn(fqn)).map(([fqn, entry]) => {
48
+ const el = entry.el.deref();
49
+ if (el) {
50
+ return { ...entry, fqn, el, doc };
51
+ }
52
+ return null;
53
+ }).nonNullable()
54
+ );
55
+ }
56
+ getFqn(el) {
57
+ return el.fqn ?? ElementOps.readId(el) ?? null;
58
+ }
59
+ byFqn(fqn) {
60
+ return this.documents().flatMap((doc) => {
61
+ return doc.c4fqns.get(fqn).flatMap((entry) => {
62
+ const el = entry.el.deref();
63
+ if (el) {
64
+ return [{ fqn, el, doc, path: entry.path, name: entry.name }];
65
+ }
66
+ return [];
67
+ });
68
+ });
69
+ }
70
+ directChildrenOf(parent) {
71
+ return stream([parent]).flatMap((_parent) => {
72
+ const children = this.entries((fqn) => parentFqn(fqn) === _parent).map((entry) => [entry.name, entry]).toArray();
73
+ if (children.length === 0) {
74
+ return [];
75
+ }
76
+ return new MultiMap(children).entriesGroupedByKey().flatMap(([_name, descrs]) => descrs.length === 1 ? descrs : []).iterator();
77
+ });
78
+ }
79
+ /**
80
+ * Returns descedant elements with unique names in the scope
81
+ */
82
+ uniqueDescedants(parent) {
83
+ return new StreamImpl(
84
+ () => {
85
+ const prefix = `${parent}.`;
86
+ const childrenNames = /* @__PURE__ */ new Set();
87
+ const descedants = [];
88
+ const nested = new MultiMap();
89
+ this.entries((f) => f.startsWith(prefix)).forEach((e) => {
90
+ const name = nameFromFqn(e.fqn);
91
+ const entry = { ...e, name };
92
+ if (parentFqn(e.fqn) === parent) {
93
+ childrenNames.add(name);
94
+ nested.add(name, entry);
95
+ } else {
96
+ descedants.push(entry);
97
+ }
36
98
  });
37
- services.shared.workspace.DocumentBuilder.onBuildPhase(DocumentState.IndexedContent, (docs, _cancelToken) => {
38
- logger.debug(`[FqnIndex] onIndexedContent ${docs.length}:\n` + printDocs(docs));
39
- for (const doc of docs) {
40
- if (isLikeC4LangiumDocument(doc)) {
41
- try {
42
- computeDocumentFqn(doc, services);
43
- }
44
- catch (e) {
45
- logError(e);
46
- }
47
- }
48
- }
49
- });
50
- }
51
- documents() {
52
- return this.langiumDocuments.all.filter(isFqnIndexedDocument);
53
- }
54
- entries(filterByFqn = () => true) {
55
- return this.documents().flatMap(doc => doc.c4fqns
56
- .entries()
57
- .filter(([fqn]) => filterByFqn(fqn))
58
- .map(([fqn, entry]) => {
59
- const el = entry.el.deref();
60
- if (el) {
61
- return { ...entry, fqn, el, doc };
62
- }
63
- return null;
64
- })
65
- .nonNullable());
66
- }
67
- getFqn(el) {
68
- return el.fqn ?? ElementOps.readId(el) ?? null;
69
- // if (fqn) {
70
- // const doc = getDocument(el)
71
- // if (isFqnIndexedDocument(doc) && doc.c4fqns.has(fqn)) {
72
- // return fqn
73
- // }
74
- // const path = this.services.workspace.AstNodeLocator.getAstNodePath(el)
75
- // logError(`Clean cached FQN ${fqn} at ${path}`)
76
- // ElementOps.writeId(el, null)
77
- // fqn = null
78
- // }
79
- // return fqn
80
- }
81
- byFqn(fqn) {
82
- return this.documents().flatMap(doc => {
83
- return doc.c4fqns.get(fqn).flatMap(entry => {
84
- const el = entry.el.deref();
85
- if (el) {
86
- return [{ fqn, el, doc, path: entry.path, name: entry.name }];
87
- }
88
- return [];
89
- });
90
- });
91
- }
92
- directChildrenOf(parent) {
93
- return stream([parent]).flatMap(_parent => {
94
- const children = this.entries(fqn => parentFqn(fqn) === _parent)
95
- .map((entry) => [entry.name, entry])
96
- .toArray();
97
- if (children.length === 0) {
98
- return [];
99
- }
100
- return new MultiMap(children)
101
- .entriesGroupedByKey()
102
- .flatMap(([_name, descrs]) => (descrs.length === 1 ? descrs : []))
103
- .iterator();
104
- });
105
- }
106
- /**
107
- * Returns descedant elements with unique names in the scope
108
- */
109
- uniqueDescedants(parent) {
110
- return new StreamImpl(() => {
111
- const prefix = `${parent}.`;
112
- const childrenNames = new Set();
113
- const descedants = [];
114
- const nested = new MultiMap();
115
- this.entries(f => f.startsWith(prefix)).forEach(e => {
116
- const name = nameFromFqn(e.fqn);
117
- const entry = { ...e, name };
118
- // To keep direct children always
119
- if (parentFqn(e.fqn) === parent) {
120
- childrenNames.add(name);
121
- nested.add(name, entry);
122
- }
123
- else {
124
- descedants.push(entry);
125
- }
126
- });
127
- if (nested.size + descedants.length === 0) {
128
- return null;
129
- }
130
- for (const descedant of descedants) {
131
- if (!childrenNames.has(descedant.name)) {
132
- nested.add(descedant.name, descedant);
133
- }
134
- }
135
- return nested
136
- .entriesGroupedByKey()
137
- .flatMap(([_name, descrs]) => (descrs.length === 1 ? descrs : []))
138
- .iterator();
139
- }, iterator => {
140
- if (iterator) {
141
- return iterator.next();
142
- }
143
- return DONE_RESULT;
144
- });
145
- }
99
+ if (nested.size + descedants.length === 0) {
100
+ return null;
101
+ }
102
+ for (const descedant of descedants) {
103
+ if (!childrenNames.has(descedant.name)) {
104
+ nested.add(descedant.name, descedant);
105
+ }
106
+ }
107
+ return nested.entriesGroupedByKey().flatMap(([_name, descrs]) => descrs.length === 1 ? descrs : []).iterator();
108
+ },
109
+ (iterator) => {
110
+ if (iterator) {
111
+ return iterator.next();
112
+ }
113
+ return DONE_RESULT;
114
+ }
115
+ );
116
+ }
146
117
  }
147
- //# sourceMappingURL=fqn-index.js.map
@@ -3,4 +3,3 @@ export * from './fqn-index';
3
3
  export * from './model-builder';
4
4
  export * from './model-locator';
5
5
  export * from './model-parser';
6
- //# sourceMappingURL=index.d.ts.map
@@ -1,6 +1,5 @@
1
- export * from './fqn-computation';
2
- export * from './fqn-index';
3
- export * from './model-builder';
4
- export * from './model-locator';
5
- export * from './model-parser';
6
- //# sourceMappingURL=index.js.map
1
+ export * from "./fqn-computation.js";
2
+ export * from "./fqn-index.js";
3
+ export * from "./model-builder.js";
4
+ export * from "./model-locator.js";
5
+ export * from "./model-parser.js";
@@ -1,16 +1,20 @@
1
1
  import { type ViewID, type c4 } from '@likec4/core';
2
+ import type { URI } from 'langium';
3
+ import { Disposable } from 'vscode-languageserver';
2
4
  import type { LikeC4Services } from '../module';
5
+ type ModelParsedListener = (docs: URI[]) => void;
3
6
  export declare class LikeC4ModelBuilder {
4
7
  private services;
5
8
  private langiumDocuments;
6
- private readonly cachedModel;
9
+ private workspaceManager;
10
+ private listeners;
7
11
  constructor(services: LikeC4Services);
8
- private cleanCache;
9
- private documents;
12
+ get workspaceUri(): any;
10
13
  buildRawModel(): c4.LikeC4RawModel | null;
11
14
  buildModel(): c4.LikeC4Model | null;
12
15
  computeView(viewId: ViewID): c4.ComputedView | null;
13
- private scheduledCb;
14
- private notifyClient;
16
+ onModelParsed(callback: ModelParsedListener): Disposable;
17
+ private documents;
18
+ private notifyListeners;
15
19
  }
16
- //# sourceMappingURL=model-builder.d.ts.map
20
+ export {};