@likec4/language-server 1.43.0 → 1.45.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 (301) hide show
  1. package/browser/package.json +1 -1
  2. package/browser-worker/package.json +1 -1
  3. package/dist/LikeC4LanguageServices.d.ts +13 -34
  4. package/dist/LikeC4LanguageServices.js +152 -0
  5. package/dist/Rpc.js +257 -0
  6. package/dist/ast.d.ts +5 -1
  7. package/dist/ast.js +257 -0
  8. package/dist/browser-worker.js +4 -0
  9. package/dist/browser.js +35 -0
  10. package/dist/bundled.js +44 -0
  11. package/dist/bundled.mjs +3568 -3900
  12. package/dist/documentation/documentation-provider.js +51 -0
  13. package/dist/documentation/index.js +1 -0
  14. package/dist/empty.js +2 -0
  15. package/dist/filesystem/ChokidarWatcher.d.ts +2 -0
  16. package/dist/filesystem/ChokidarWatcher.js +108 -0
  17. package/dist/filesystem/FileSystemWatcher.js +14 -0
  18. package/dist/filesystem/LikeC4FileSystem.d.ts +1 -2
  19. package/dist/filesystem/LikeC4FileSystem.js +126 -0
  20. package/dist/filesystem/index.d.ts +26 -0
  21. package/dist/filesystem/index.js +29 -0
  22. package/dist/formatting/LikeC4Formatter.js +637 -0
  23. package/dist/formatting/utils.js +18 -0
  24. package/dist/generated/ast.js +2155 -0
  25. package/dist/generated/{grammar.mjs → grammar.js} +6 -2
  26. package/dist/generated/module.d.ts +6 -1
  27. package/dist/generated/module.js +27 -0
  28. package/dist/generated-lib/{icons.mjs → icons.js} +11 -7
  29. package/dist/index.d.ts +10 -1
  30. package/dist/index.js +55 -0
  31. package/dist/{likec4lib.mjs → likec4lib.js} +3 -3
  32. package/dist/logger.js +81 -0
  33. package/dist/lsp/CodeActionProvider.d.ts +14 -0
  34. package/dist/lsp/CodeActionProvider.js +33 -0
  35. package/dist/lsp/CodeLensProvider.js +44 -0
  36. package/dist/lsp/CompletionProvider.d.ts +3 -1
  37. package/dist/lsp/CompletionProvider.js +200 -0
  38. package/dist/lsp/DocumentHighlightProvider.js +10 -0
  39. package/dist/lsp/DocumentLinkProvider.js +58 -0
  40. package/dist/lsp/DocumentSymbolProvider.js +306 -0
  41. package/dist/lsp/HoverProvider.js +106 -0
  42. package/dist/lsp/RenameProvider.js +6 -0
  43. package/dist/lsp/SemanticTokenProvider.js +257 -0
  44. package/dist/lsp/index.d.ts +1 -0
  45. package/dist/lsp/index.js +9 -0
  46. package/dist/mcp/MCPServerFactory.js +73 -0
  47. package/dist/mcp/NoopLikeC4MCPServer.js +17 -0
  48. package/dist/mcp/interfaces.js +5 -0
  49. package/dist/mcp/server/StdioLikeC4MCPServer.js +51 -0
  50. package/dist/mcp/server/StreamableLikeC4MCPServer.js +145 -0
  51. package/dist/mcp/server/WithMCPServer.js +56 -0
  52. package/dist/mcp/tools/_common.d.ts +8 -7
  53. package/dist/mcp/tools/_common.js +49 -0
  54. package/dist/mcp/tools/find-relationships.d.ts +7 -8
  55. package/dist/mcp/tools/find-relationships.js +150 -0
  56. package/dist/mcp/tools/list-projects.d.ts +3 -3
  57. package/dist/mcp/tools/list-projects.js +62 -0
  58. package/dist/mcp/tools/open-view.d.ts +6 -7
  59. package/dist/mcp/tools/open-view.js +52 -0
  60. package/dist/mcp/tools/read-deployment.d.ts +6 -7
  61. package/dist/mcp/tools/read-deployment.js +132 -0
  62. package/dist/mcp/tools/read-element.d.ts +6 -7
  63. package/dist/mcp/tools/read-element.js +194 -0
  64. package/dist/mcp/tools/read-project-summary.d.ts +5 -6
  65. package/dist/mcp/tools/read-project-summary.js +176 -0
  66. package/dist/mcp/tools/read-view.d.ts +6 -7
  67. package/dist/mcp/tools/read-view.js +203 -0
  68. package/dist/mcp/tools/search-element.d.ts +3 -3
  69. package/dist/mcp/tools/search-element.js +177 -0
  70. package/dist/mcp/utils.d.ts +2 -2
  71. package/dist/mcp/utils.js +48 -0
  72. package/dist/model/builder/MergedExtends.js +74 -0
  73. package/dist/model/builder/MergedSpecification.js +175 -0
  74. package/dist/model/builder/buildModel.js +176 -0
  75. package/dist/model/deployments-index.js +102 -0
  76. package/dist/model/fqn-index.d.ts +1 -2
  77. package/dist/model/fqn-index.js +247 -0
  78. package/dist/model/index.js +6 -0
  79. package/dist/model/model-builder.d.ts +13 -11
  80. package/dist/model/model-builder.js +232 -0
  81. package/dist/model/model-locator.d.ts +6 -5
  82. package/dist/model/model-locator.js +240 -0
  83. package/dist/model/model-parser-where.js +81 -0
  84. package/dist/model/model-parser.d.ts +309 -304
  85. package/dist/model/model-parser.js +126 -0
  86. package/dist/model/parser/Base.d.ts +2 -2
  87. package/dist/model/parser/Base.js +367 -0
  88. package/dist/model/parser/DeploymentModelParser.d.ts +2 -2
  89. package/dist/model/parser/DeploymentModelParser.js +176 -0
  90. package/dist/model/parser/DeploymentViewParser.d.ts +3 -3
  91. package/dist/model/parser/DeploymentViewParser.js +86 -0
  92. package/dist/model/parser/FqnRefParser.d.ts +2 -2
  93. package/dist/model/parser/FqnRefParser.js +382 -0
  94. package/dist/model/parser/GlobalsParser.d.ts +6 -6
  95. package/dist/model/parser/GlobalsParser.js +84 -0
  96. package/dist/model/parser/ImportsParser.d.ts +11 -12
  97. package/dist/model/parser/ImportsParser.js +24 -0
  98. package/dist/model/parser/ModelParser.d.ts +2 -2
  99. package/dist/model/parser/ModelParser.js +165 -0
  100. package/dist/model/parser/PredicatesParser.d.ts +2 -2
  101. package/dist/model/parser/PredicatesParser.js +45 -0
  102. package/dist/model/parser/SpecificationParser.d.ts +2 -2
  103. package/dist/model/parser/SpecificationParser.js +113 -0
  104. package/dist/model/parser/ValueConverter.js +12 -0
  105. package/dist/model/parser/ViewsParser.d.ts +3 -3
  106. package/dist/model/parser/ViewsParser.js +479 -0
  107. package/dist/model-change/ModelChanges.d.ts +8 -5
  108. package/dist/model-change/ModelChanges.js +129 -0
  109. package/dist/model-change/changeElementStyle.js +134 -0
  110. package/dist/model-change/changeViewLayout.d.ts +2 -2
  111. package/dist/model-change/changeViewLayout.js +28 -0
  112. package/dist/model-change/removeManualLayoutV1.d.ts +7 -0
  113. package/dist/model-change/removeManualLayoutV1.js +27 -0
  114. package/dist/module.d.ts +10 -5
  115. package/dist/module.js +143 -0
  116. package/dist/protocol.d.ts +34 -27
  117. package/dist/protocol.js +123 -0
  118. package/dist/references/index.js +3 -0
  119. package/dist/references/name-provider.js +37 -0
  120. package/dist/references/scope-computation.js +288 -0
  121. package/dist/references/scope-provider.d.ts +3 -3
  122. package/dist/references/scope-provider.js +242 -0
  123. package/dist/shared/NodeKindProvider.js +57 -0
  124. package/dist/shared/{WorkspaceSymbolProvider.mjs → WorkspaceSymbolProvider.js} +1 -1
  125. package/dist/shared/index.js +2 -0
  126. package/dist/test/index.js +1 -0
  127. package/dist/test/testServices.d.ts +16 -16
  128. package/dist/test/testServices.js +210 -0
  129. package/dist/utils/disposable.js +26 -0
  130. package/dist/utils/elementRef.d.ts +1 -1
  131. package/dist/utils/elementRef.js +27 -0
  132. package/dist/utils/fqnRef.js +63 -0
  133. package/dist/utils/index.js +35 -0
  134. package/dist/utils/printDocs.js +1 -0
  135. package/dist/utils/projectId.js +16 -0
  136. package/dist/utils/stringHash.js +5 -0
  137. package/dist/validation/DocumentValidator.js +17 -0
  138. package/dist/validation/_shared.js +26 -0
  139. package/dist/validation/deployment-checks.js +140 -0
  140. package/dist/validation/dynamic-view.js +67 -0
  141. package/dist/validation/element-ref.js +12 -0
  142. package/dist/validation/element.js +49 -0
  143. package/dist/validation/imports.js +46 -0
  144. package/dist/validation/index.d.ts +1 -1
  145. package/dist/validation/index.js +157 -0
  146. package/dist/validation/property-checks.js +108 -0
  147. package/dist/validation/relation.js +55 -0
  148. package/dist/validation/specification.js +190 -0
  149. package/dist/validation/view-predicates/fqn-expr-with.js +43 -0
  150. package/dist/validation/view-predicates/fqn-ref-expr.js +51 -0
  151. package/dist/validation/view-predicates/incoming.js +16 -0
  152. package/dist/validation/view-predicates/index.js +6 -0
  153. package/dist/validation/view-predicates/outgoing.js +20 -0
  154. package/dist/validation/view-predicates/relation-expr.js +46 -0
  155. package/dist/validation/view-predicates/relation-with.js +16 -0
  156. package/dist/validation/view.d.ts +1 -1
  157. package/dist/validation/view.js +42 -0
  158. package/dist/view-utils/assignNavigateTo.js +27 -0
  159. package/dist/view-utils/index.d.ts +1 -0
  160. package/dist/view-utils/index.js +2 -0
  161. package/dist/view-utils/manual-layout.d.ts +6 -0
  162. package/dist/view-utils/manual-layout.js +149 -0
  163. package/dist/views/ConfigurableLayouter.js +51 -0
  164. package/dist/views/LikeC4ManualLayouts.d.ts +42 -0
  165. package/dist/views/LikeC4ManualLayouts.js +209 -0
  166. package/dist/views/{likec4-views.d.ts → LikeC4Views.d.ts} +32 -10
  167. package/dist/views/LikeC4Views.js +216 -0
  168. package/dist/views/index.d.ts +4 -1
  169. package/dist/views/index.js +11 -0
  170. package/dist/workspace/AstNodeDescriptionProvider.js +18 -0
  171. package/dist/workspace/IndexManager.js +21 -0
  172. package/dist/workspace/LangiumDocuments.d.ts +4 -3
  173. package/dist/workspace/LangiumDocuments.js +72 -0
  174. package/dist/workspace/ProjectsManager.d.ts +25 -16
  175. package/dist/workspace/ProjectsManager.js +469 -0
  176. package/dist/workspace/WorkspaceManager.d.ts +3 -2
  177. package/dist/workspace/WorkspaceManager.js +98 -0
  178. package/dist/workspace/index.js +5 -0
  179. package/likec4lib/package.json +1 -1
  180. package/package.json +30 -28
  181. package/protocol/package.json +1 -1
  182. package/dist/LikeC4LanguageServices.mjs +0 -197
  183. package/dist/Rpc.mjs +0 -296
  184. package/dist/ast.mjs +0 -221
  185. package/dist/browser-worker.mjs +0 -2
  186. package/dist/browser.mjs +0 -32
  187. package/dist/documentation/documentation-provider.mjs +0 -48
  188. package/dist/documentation/index.mjs +0 -1
  189. package/dist/empty.mjs +0 -1
  190. package/dist/filesystem/ChokidarWatcher.mjs +0 -68
  191. package/dist/filesystem/FileSystemWatcher.mjs +0 -11
  192. package/dist/filesystem/LikeC4FileSystem.mjs +0 -64
  193. package/dist/filesystem/index.mjs +0 -19
  194. package/dist/formatting/LikeC4Formatter.mjs +0 -511
  195. package/dist/formatting/utils.mjs +0 -15
  196. package/dist/generated/ast.mjs +0 -2150
  197. package/dist/generated/module.mjs +0 -23
  198. package/dist/index.mjs +0 -50
  199. package/dist/logger.mjs +0 -82
  200. package/dist/lsp/CodeLensProvider.mjs +0 -42
  201. package/dist/lsp/CompletionProvider.mjs +0 -208
  202. package/dist/lsp/DocumentHighlightProvider.mjs +0 -10
  203. package/dist/lsp/DocumentLinkProvider.mjs +0 -53
  204. package/dist/lsp/DocumentSymbolProvider.mjs +0 -287
  205. package/dist/lsp/HoverProvider.mjs +0 -104
  206. package/dist/lsp/RenameProvider.mjs +0 -6
  207. package/dist/lsp/SemanticTokenProvider.mjs +0 -276
  208. package/dist/lsp/index.mjs +0 -7
  209. package/dist/mcp/MCPServerFactory.mjs +0 -70
  210. package/dist/mcp/NoopLikeC4MCPServer.mjs +0 -17
  211. package/dist/mcp/interfaces.mjs +0 -4
  212. package/dist/mcp/server/StdioLikeC4MCPServer.mjs +0 -46
  213. package/dist/mcp/server/StreamableLikeC4MCPServer.mjs +0 -153
  214. package/dist/mcp/server/WithMCPServer.mjs +0 -58
  215. package/dist/mcp/tools/_common.mjs +0 -42
  216. package/dist/mcp/tools/find-relationships.mjs +0 -151
  217. package/dist/mcp/tools/list-projects.mjs +0 -62
  218. package/dist/mcp/tools/open-view.mjs +0 -52
  219. package/dist/mcp/tools/read-deployment.mjs +0 -130
  220. package/dist/mcp/tools/read-element.mjs +0 -198
  221. package/dist/mcp/tools/read-project-summary.mjs +0 -178
  222. package/dist/mcp/tools/read-view.mjs +0 -205
  223. package/dist/mcp/tools/search-element.mjs +0 -171
  224. package/dist/mcp/utils.mjs +0 -47
  225. package/dist/model/builder/MergedExtends.mjs +0 -76
  226. package/dist/model/builder/MergedSpecification.mjs +0 -205
  227. package/dist/model/builder/assignTagColors.d.ts +0 -7
  228. package/dist/model/builder/assignTagColors.mjs +0 -51
  229. package/dist/model/builder/buildModel.mjs +0 -226
  230. package/dist/model/deployments-index.mjs +0 -100
  231. package/dist/model/fqn-index.mjs +0 -243
  232. package/dist/model/index.mjs +0 -6
  233. package/dist/model/model-builder.mjs +0 -285
  234. package/dist/model/model-locator.mjs +0 -239
  235. package/dist/model/model-parser-where.mjs +0 -81
  236. package/dist/model/model-parser.mjs +0 -127
  237. package/dist/model/parser/Base.mjs +0 -376
  238. package/dist/model/parser/DeploymentModelParser.mjs +0 -212
  239. package/dist/model/parser/DeploymentViewParser.mjs +0 -95
  240. package/dist/model/parser/FqnRefParser.mjs +0 -398
  241. package/dist/model/parser/GlobalsParser.mjs +0 -82
  242. package/dist/model/parser/ImportsParser.mjs +0 -28
  243. package/dist/model/parser/ModelParser.mjs +0 -190
  244. package/dist/model/parser/PredicatesParser.mjs +0 -45
  245. package/dist/model/parser/SpecificationParser.mjs +0 -120
  246. package/dist/model/parser/ValueConverter.mjs +0 -12
  247. package/dist/model/parser/ViewsParser.mjs +0 -490
  248. package/dist/model-change/ModelChanges.mjs +0 -89
  249. package/dist/model-change/changeElementStyle.mjs +0 -143
  250. package/dist/model-change/changeViewLayout.mjs +0 -32
  251. package/dist/model-change/saveManualLayout.d.ts +0 -11
  252. package/dist/model-change/saveManualLayout.mjs +0 -27
  253. package/dist/module.mjs +0 -180
  254. package/dist/protocol.mjs +0 -65
  255. package/dist/references/index.mjs +0 -3
  256. package/dist/references/name-provider.mjs +0 -39
  257. package/dist/references/scope-computation.mjs +0 -312
  258. package/dist/references/scope-provider.mjs +0 -239
  259. package/dist/shared/NodeKindProvider.mjs +0 -110
  260. package/dist/shared/index.mjs +0 -2
  261. package/dist/test/index.mjs +0 -1
  262. package/dist/test/testServices.mjs +0 -200
  263. package/dist/utils/disposable.mjs +0 -25
  264. package/dist/utils/elementRef.mjs +0 -20
  265. package/dist/utils/fqnRef.mjs +0 -57
  266. package/dist/utils/index.mjs +0 -33
  267. package/dist/utils/printDocs.mjs +0 -1
  268. package/dist/utils/projectId.mjs +0 -16
  269. package/dist/utils/stringHash.mjs +0 -5
  270. package/dist/validation/DocumentValidator.mjs +0 -16
  271. package/dist/validation/_shared.mjs +0 -25
  272. package/dist/validation/deployment-checks.mjs +0 -146
  273. package/dist/validation/dynamic-view.mjs +0 -67
  274. package/dist/validation/element-ref.mjs +0 -12
  275. package/dist/validation/element.mjs +0 -50
  276. package/dist/validation/imports.mjs +0 -25
  277. package/dist/validation/index.mjs +0 -180
  278. package/dist/validation/property-checks.mjs +0 -107
  279. package/dist/validation/relation.mjs +0 -53
  280. package/dist/validation/specification.mjs +0 -173
  281. package/dist/validation/view-predicates/fqn-expr-with.mjs +0 -43
  282. package/dist/validation/view-predicates/fqn-ref-expr.mjs +0 -53
  283. package/dist/validation/view-predicates/incoming.mjs +0 -16
  284. package/dist/validation/view-predicates/index.mjs +0 -6
  285. package/dist/validation/view-predicates/outgoing.mjs +0 -20
  286. package/dist/validation/view-predicates/relation-expr.mjs +0 -39
  287. package/dist/validation/view-predicates/relation-with.mjs +0 -16
  288. package/dist/validation/view.mjs +0 -25
  289. package/dist/view-utils/assignNavigateTo.mjs +0 -25
  290. package/dist/view-utils/index.mjs +0 -1
  291. package/dist/view-utils/manual-layout.mjs +0 -99
  292. package/dist/views/configurable-layouter.mjs +0 -51
  293. package/dist/views/index.mjs +0 -1
  294. package/dist/views/likec4-views.mjs +0 -166
  295. package/dist/workspace/AstNodeDescriptionProvider.mjs +0 -17
  296. package/dist/workspace/IndexManager.mjs +0 -17
  297. package/dist/workspace/LangiumDocuments.mjs +0 -53
  298. package/dist/workspace/ProjectsManager.mjs +0 -360
  299. package/dist/workspace/WorkspaceManager.mjs +0 -83
  300. package/dist/workspace/index.mjs +0 -5
  301. /package/dist/views/{configurable-layouter.d.ts → ConfigurableLayouter.d.ts} +0 -0
@@ -0,0 +1,102 @@
1
+ import { ancestorsFqn, Fqn } from '@likec4/core';
2
+ import { MultiMap } from '@likec4/core/utils';
3
+ import { isDefined, isTruthy } from 'remeda';
4
+ import { ast, ElementOps, } from '../ast';
5
+ import { logWarnError } from '../logger';
6
+ import { readStrictFqn } from '../utils/elementRef';
7
+ import { DocumentFqnIndex, FqnIndex } from './fqn-index';
8
+ export class DeploymentsIndex extends FqnIndex {
9
+ services;
10
+ Names;
11
+ constructor(services) {
12
+ super(services);
13
+ this.services = services;
14
+ this.Names = services.references.NameProvider;
15
+ }
16
+ createDocumentIndex(document) {
17
+ const rootNodes = document.parseResult.value.deployments.flatMap(m => m.elements);
18
+ if (rootNodes.length === 0) {
19
+ return DocumentFqnIndex.EMPTY;
20
+ }
21
+ const projectId = this.projects.belongsTo(document);
22
+ const root = new Array();
23
+ const children = new MultiMap();
24
+ const descendants = new MultiMap();
25
+ const byfqn = new MultiMap();
26
+ const Names = this.Names;
27
+ const Descriptions = this.services.workspace.AstNodeDescriptionProvider;
28
+ const createAndSaveDescription = (node, name, fqn) => {
29
+ const desc = {
30
+ ...Descriptions.createDescription(node, name, document),
31
+ id: fqn,
32
+ likec4ProjectId: projectId,
33
+ };
34
+ ElementOps.writeId(node, fqn);
35
+ byfqn.set(fqn, desc);
36
+ return desc;
37
+ };
38
+ const traverseNode = (node, parentFqn) => {
39
+ let thisFqn;
40
+ if (ast.isExtendDeployment(node)) {
41
+ thisFqn = readStrictFqn(node.deploymentNode);
42
+ }
43
+ else {
44
+ const name = Names.getName(node);
45
+ if (!isTruthy(name)) {
46
+ return [];
47
+ }
48
+ thisFqn = Fqn(name, parentFqn);
49
+ const desc = createAndSaveDescription(node, name, thisFqn);
50
+ if (!parentFqn) {
51
+ root.push(desc);
52
+ }
53
+ else {
54
+ children.set(parentFqn, desc);
55
+ }
56
+ if (ast.isDeployedInstance(node)) {
57
+ return [];
58
+ }
59
+ }
60
+ let _nested = [];
61
+ if (isDefined(node.body)) {
62
+ for (const child of node.body.elements) {
63
+ if (!ast.isDeploymentRelation(child)) {
64
+ try {
65
+ _nested.push(...traverseNode(child, thisFqn));
66
+ }
67
+ catch (e) {
68
+ logWarnError(e);
69
+ }
70
+ }
71
+ }
72
+ }
73
+ _nested = [
74
+ ...children.get(thisFqn) ?? [],
75
+ ..._nested,
76
+ ];
77
+ for (const child of _nested) {
78
+ descendants.set(thisFqn, child);
79
+ }
80
+ if (ast.isExtendDeployment(node)) {
81
+ for (const ancestor of ancestorsFqn(thisFqn)) {
82
+ for (const child of _nested) {
83
+ descendants.set(ancestor, child);
84
+ }
85
+ }
86
+ }
87
+ return descendants.get(thisFqn) ?? [];
88
+ };
89
+ for (const node of rootNodes) {
90
+ try {
91
+ if (ast.isDeploymentRelation(node)) {
92
+ continue;
93
+ }
94
+ traverseNode(node, null);
95
+ }
96
+ catch (e) {
97
+ logWarnError(e);
98
+ }
99
+ }
100
+ return new DocumentFqnIndex(root, children, descendants, byfqn, projectId);
101
+ }
102
+ }
@@ -7,12 +7,11 @@ import { ADisposable } from '../utils';
7
7
  import { type LangiumDocuments, ProjectsManager } from '../workspace';
8
8
  export declare class FqnIndex<AstNd = ast.Element> extends ADisposable {
9
9
  protected services: LikeC4Services;
10
- private cachePrefix;
11
10
  protected projects: ProjectsManager;
12
11
  protected langiumDocuments: LangiumDocuments;
13
12
  protected documentCache: DefaultWeakMap<LikeC4LangiumDocument, DocumentFqnIndex>;
14
13
  protected workspaceCache: WorkspaceCache<string, AstNodeDescriptionWithFqn[]>;
15
- constructor(services: LikeC4Services, cachePrefix?: string);
14
+ constructor(services: LikeC4Services);
16
15
  private documents;
17
16
  get(document: LikeC4LangiumDocument): DocumentFqnIndex;
18
17
  resolve(reference: ast.Referenceable): Fqn;
@@ -0,0 +1,247 @@
1
+ import { invariant, nonNullable } from '@likec4/core';
2
+ import { Fqn } from '@likec4/core/types';
3
+ import { ancestorsFqn, compareNatural, DefaultWeakMap, MultiMap, sortNaturalByFqn } from '@likec4/core/utils';
4
+ import { AstUtils, DocumentState, stream, WorkspaceCache, } from 'langium';
5
+ import { isDefined, isEmpty, isTruthy } from 'remeda';
6
+ import { ast, ElementOps, isLikeC4LangiumDocument, } from '../ast';
7
+ import { logWarnError } from '../logger';
8
+ import { ADisposable } from '../utils';
9
+ import { readStrictFqn } from '../utils/elementRef';
10
+ import { ProjectsManager } from '../workspace';
11
+ export class FqnIndex extends ADisposable {
12
+ services;
13
+ projects;
14
+ langiumDocuments;
15
+ documentCache;
16
+ workspaceCache;
17
+ constructor(services) {
18
+ super();
19
+ this.services = services;
20
+ this.langiumDocuments = services.shared.workspace.LangiumDocuments;
21
+ this.projects = services.shared.workspace.ProjectsManager;
22
+ this.documentCache = new DefaultWeakMap(doc => this.createDocumentIndex(doc));
23
+ this.workspaceCache = new WorkspaceCache(services.shared, DocumentState.IndexedContent);
24
+ this.onDispose(services.shared.workspace.DocumentBuilder.onDocumentPhase(DocumentState.IndexedContent, (doc) => {
25
+ if (isLikeC4LangiumDocument(doc)) {
26
+ this.documentCache.delete(doc);
27
+ }
28
+ }));
29
+ }
30
+ documents(projectId) {
31
+ return this.langiumDocuments.projectDocuments(projectId).filter((d) => isLikeC4LangiumDocument(d)
32
+ && d.state >= DocumentState.IndexedContent);
33
+ }
34
+ get(document) {
35
+ if (document.state < DocumentState.IndexedContent) {
36
+ logWarnError(`Document ${document.uri.path} is not indexed`);
37
+ }
38
+ return this.documentCache.get(document);
39
+ }
40
+ resolve(reference) {
41
+ if (reference.$type === 'Imported') {
42
+ return this.getFqn(reference.imported.ref);
43
+ }
44
+ if (reference.$type === 'Element') {
45
+ return this.getFqn(reference);
46
+ }
47
+ return this.services.likec4.DeploymentsIndex.getFqn(reference);
48
+ }
49
+ getFqn(el) {
50
+ invariant(ast.isElement(el) || ast.isDeploymentElement(el));
51
+ let id = ElementOps.readId(el);
52
+ if (isTruthy(id)) {
53
+ return id;
54
+ }
55
+ // Document index is not yet created
56
+ const doc = AstUtils.getDocument(el);
57
+ invariant(isLikeC4LangiumDocument(doc));
58
+ // Ensure the document is indexed
59
+ this.get(doc);
60
+ // This will create the document index
61
+ return nonNullable(ElementOps.readId(el), 'Element fqn must be set, invalid state');
62
+ }
63
+ byFqn(projectId, fqn) {
64
+ return stream(this.workspaceCache.get(`${projectId}:fqn:${fqn}`, () => {
65
+ return this
66
+ .documents(projectId)
67
+ .flatMap(doc => {
68
+ return this.get(doc).byFqn(fqn);
69
+ })
70
+ .toArray();
71
+ }));
72
+ }
73
+ rootElements(projectId) {
74
+ return stream(this.workspaceCache.get(`${projectId}:rootElements`, () => {
75
+ const allchildren = this.documents(projectId)
76
+ .reduce((map, doc) => {
77
+ this.get(doc).rootElements().forEach(desc => {
78
+ map.set(desc.name, desc);
79
+ });
80
+ return map;
81
+ }, new MultiMap());
82
+ return uniqueByName(allchildren);
83
+ }));
84
+ }
85
+ directChildrenOf(projectId, parent) {
86
+ return stream(this.workspaceCache.get(`${projectId}:directChildrenOf:${parent}`, () => {
87
+ const allchildren = this.documents(projectId)
88
+ .reduce((map, doc) => {
89
+ this.get(doc).children(parent).forEach(desc => {
90
+ map.set(desc.name, desc);
91
+ });
92
+ return map;
93
+ }, new MultiMap());
94
+ return uniqueByName(allchildren);
95
+ }));
96
+ }
97
+ /**
98
+ * Returns descedant elements with unique names in the scope
99
+ */
100
+ uniqueDescedants(projectId, parent) {
101
+ return stream(this.workspaceCache.get(`${projectId}:uniqueDescedants:${parent}`, () => {
102
+ const { children, descendants } = this.documents(projectId)
103
+ .reduce((map, doc) => {
104
+ const docIndex = this.get(doc);
105
+ docIndex.children(parent).forEach(desc => {
106
+ map.children.set(desc.name, desc);
107
+ });
108
+ docIndex.descendants(parent).forEach(desc => {
109
+ map.descendants.set(desc.name, desc);
110
+ });
111
+ return map;
112
+ }, {
113
+ children: new MultiMap(),
114
+ descendants: new MultiMap(),
115
+ });
116
+ const uniqueChildren = uniqueByName(children);
117
+ const uniqueDescendants = [...descendants.associations()]
118
+ .flatMap(([_name, descs]) => descs.length === 1 && !children.has(_name) ? descs : []);
119
+ return [
120
+ ...uniqueChildren,
121
+ ...sortNaturalByFqn(uniqueDescendants),
122
+ ];
123
+ }));
124
+ }
125
+ createDocumentIndex(document) {
126
+ const rootElements = document.parseResult.value.models.flatMap(m => m.elements);
127
+ if (rootElements.length === 0) {
128
+ return DocumentFqnIndex.EMPTY;
129
+ }
130
+ const projectId = document.likec4ProjectId ?? this.projects.belongsTo(document);
131
+ const root = new Array();
132
+ const children = new MultiMap();
133
+ const descendants = new MultiMap();
134
+ const byfqn = new MultiMap();
135
+ const Descriptions = this.services.workspace.AstNodeDescriptionProvider;
136
+ const createAndSaveDescription = (node, name, fqn) => {
137
+ const desc = Object.assign(Descriptions.createDescription(node, name, document), {
138
+ id: fqn,
139
+ likec4ProjectId: projectId,
140
+ });
141
+ ElementOps.writeId(node, fqn);
142
+ byfqn.set(fqn, desc);
143
+ return desc;
144
+ };
145
+ const traverseNode = (el, parentFqn) => {
146
+ let thisFqn;
147
+ if (ast.isElement(el)) {
148
+ thisFqn = Fqn(el.name, parentFqn);
149
+ const desc = createAndSaveDescription(el, el.name, thisFqn);
150
+ if (!parentFqn) {
151
+ root.push(desc);
152
+ }
153
+ else {
154
+ children.set(parentFqn, desc);
155
+ }
156
+ }
157
+ else {
158
+ thisFqn = readStrictFqn(el.element);
159
+ }
160
+ let _nested = [];
161
+ if (isDefined(el.body) && !isEmpty(el.body.elements)) {
162
+ for (const child of el.body.elements) {
163
+ if (!ast.isRelation(child)) {
164
+ try {
165
+ _nested.push(...traverseNode(child, thisFqn));
166
+ }
167
+ catch (e) {
168
+ logWarnError(e);
169
+ }
170
+ }
171
+ }
172
+ }
173
+ const directChildren = children.get(thisFqn) ?? [];
174
+ _nested = [
175
+ ...directChildren,
176
+ ..._nested,
177
+ ];
178
+ for (const child of _nested) {
179
+ descendants.set(thisFqn, child);
180
+ }
181
+ if (ast.isExtendElement(el)) {
182
+ for (const ancestor of ancestorsFqn(thisFqn)) {
183
+ for (const child of _nested) {
184
+ descendants.set(ancestor, child);
185
+ }
186
+ }
187
+ }
188
+ return descendants.get(thisFqn) ?? [];
189
+ };
190
+ for (const node of rootElements) {
191
+ try {
192
+ if (ast.isRelation(node)) {
193
+ continue;
194
+ }
195
+ traverseNode(node, null);
196
+ }
197
+ catch (e) {
198
+ logWarnError(e);
199
+ }
200
+ }
201
+ return new DocumentFqnIndex(root, children, descendants, byfqn, projectId);
202
+ }
203
+ }
204
+ function uniqueByName(multimap) {
205
+ return [...multimap.associations()]
206
+ .flatMap(([_name, descs]) => (descs.length === 1 ? descs : []))
207
+ .sort((a, b) => compareNatural(a.name, b.name));
208
+ }
209
+ export class DocumentFqnIndex {
210
+ _rootElements;
211
+ _children;
212
+ _descendants;
213
+ _byfqn;
214
+ projectId;
215
+ static EMPTY = new DocumentFqnIndex([], new MultiMap(), new MultiMap(), new MultiMap(), ProjectsManager.DefaultProjectId);
216
+ constructor(_rootElements,
217
+ /**
218
+ * direct children of elements
219
+ */
220
+ _children,
221
+ /**
222
+ * All descendants of an element (unique by name)
223
+ */
224
+ _descendants,
225
+ /**
226
+ * All elements by FQN
227
+ */
228
+ _byfqn, projectId) {
229
+ this._rootElements = _rootElements;
230
+ this._children = _children;
231
+ this._descendants = _descendants;
232
+ this._byfqn = _byfqn;
233
+ this.projectId = projectId;
234
+ }
235
+ rootElements() {
236
+ return this._rootElements;
237
+ }
238
+ byFqn(fqn) {
239
+ return this._byfqn.get(fqn) ?? [];
240
+ }
241
+ children(parent) {
242
+ return this._children.get(parent) ?? [];
243
+ }
244
+ descendants(nodeName) {
245
+ return this._descendants.get(nodeName) ?? [];
246
+ }
247
+ }
@@ -0,0 +1,6 @@
1
+ export * from './deployments-index';
2
+ export * from './fqn-index';
3
+ export * from './model-builder';
4
+ export * from './model-locator';
5
+ export * from './model-parser';
6
+ export * from './parser/ValueConverter';
@@ -1,17 +1,18 @@
1
- import { type ViewId } from '@likec4/core';
1
+ import { type LayoutedView, type ProjectId, type UnknownComputed, type UnknownParsed, type ViewId } from '@likec4/core';
2
2
  import { LikeC4Model } from '@likec4/core/model';
3
3
  import type * as c4 from '@likec4/core/types';
4
4
  import { type URI, Disposable } from 'langium';
5
- import { CancellationToken } from 'vscode-jsonrpc';
5
+ import type { CancellationToken } from 'vscode-jsonrpc';
6
6
  import type { LikeC4Services } from '../module';
7
7
  import { ADisposable } from '../utils';
8
8
  type ModelParsedListener = (docs: URI[]) => void;
9
+ type ManualLayouts = Record<ViewId, LayoutedView> | null;
9
10
  export interface LikeC4ModelBuilder extends Disposable {
10
- parseModel(projectId?: c4.ProjectId | undefined, cancelToken?: CancellationToken): Promise<LikeC4Model.Parsed | null>;
11
- unsafeSyncBuildModel(projectId: c4.ProjectId): LikeC4Model.Computed;
12
- buildLikeC4Model(projectId?: c4.ProjectId | undefined, cancelToken?: CancellationToken): Promise<LikeC4Model.Computed>;
13
- computeView(viewId: ViewId, projectId?: c4.ProjectId | undefined, cancelToken?: CancellationToken): Promise<c4.ComputedView | null>;
11
+ parseModel(projectId?: ProjectId | undefined, cancelToken?: CancellationToken): Promise<LikeC4Model<UnknownParsed> | null>;
12
+ unsafeSyncComputeModel(projectId: ProjectId): LikeC4Model<UnknownComputed>;
13
+ computeModel(projectId?: ProjectId | undefined, cancelToken?: CancellationToken): Promise<LikeC4Model<UnknownComputed>>;
14
14
  onModelParsed(callback: ModelParsedListener): Disposable;
15
+ clearCache(): void;
15
16
  }
16
17
  export declare class DefaultLikeC4ModelBuilder extends ADisposable implements LikeC4ModelBuilder {
17
18
  private projects;
@@ -19,6 +20,7 @@ export declare class DefaultLikeC4ModelBuilder extends ADisposable implements Li
19
20
  private listeners;
20
21
  private cache;
21
22
  private DocumentBuilder;
23
+ private manualLayouts;
22
24
  private mutex;
23
25
  constructor(services: LikeC4Services);
24
26
  /**
@@ -32,18 +34,18 @@ export declare class DefaultLikeC4ModelBuilder extends ADisposable implements Li
32
34
  /**
33
35
  * To avoid circular dependencies, first we parse all documents and then we join them.
34
36
  */
35
- private unsafeSyncJoinedModelData;
36
- parseModel(projectId?: c4.ProjectId | undefined, cancelToken?: CancellationToken): Promise<LikeC4Model.Parsed | null>;
37
+ private unsafeSyncJoinedModel;
38
+ parseModel(projectId?: c4.ProjectId | undefined, cancelToken?: CancellationToken): Promise<LikeC4Model<UnknownParsed> | null>;
37
39
  private previousViews;
38
40
  /**
39
41
  * WARNING:
40
42
  * This method is internal and should to be called only when all documents are known to be parsed.
41
43
  * Otherwise, the model may be incomplete.
42
44
  */
43
- unsafeSyncBuildModel(projectId: c4.ProjectId): LikeC4Model.Computed;
44
- buildLikeC4Model(projectId?: c4.ProjectId | undefined, cancelToken?: CancellationToken): Promise<LikeC4Model.Computed>;
45
- computeView(viewId: ViewId, projectId?: c4.ProjectId | undefined, cancelToken?: CancellationToken): Promise<c4.ComputedView | null>;
45
+ unsafeSyncComputeModel(projectId: c4.ProjectId, manualLayouts?: ManualLayouts): LikeC4Model<UnknownComputed>;
46
+ computeModel(projectId?: c4.ProjectId | undefined, cancelToken?: CancellationToken): Promise<LikeC4Model<UnknownComputed>>;
46
47
  onModelParsed(callback: ModelParsedListener): Disposable;
48
+ clearCache(): void;
47
49
  private documents;
48
50
  private notifyListeners;
49
51
  }
@@ -0,0 +1,232 @@
1
+ import { _stage, } from '@likec4/core';
2
+ import { computeView } from '@likec4/core/compute-view';
3
+ import { LikeC4Model } from '@likec4/core/model';
4
+ import { loggable } from '@likec4/log';
5
+ import { deepEqual as eq } from 'fast-equals';
6
+ import { Disposable, DocumentState, interruptAndCheck, WorkspaceCache, } from 'langium';
7
+ import { flatMap, hasAtLeast, isEmpty, mapToObj, pipe, values, } from 'remeda';
8
+ import { isLikeC4Builtin } from '../likec4lib';
9
+ import { logger as mainLogger } from '../logger';
10
+ import { ADisposable, performanceMark } from '../utils';
11
+ import { assignNavigateTo } from '../view-utils';
12
+ import { buildModelData } from './builder/buildModel';
13
+ const parsedWithoutImportsCacheKey = (projectId) => `parsed-without-imports-${projectId}`;
14
+ const parsedModelCacheKey = (projectId) => `parsed-model-${projectId}`;
15
+ const computedModelCacheKey = (projectId) => `computed-model-${projectId}`;
16
+ const builderLogger = mainLogger.getChild('model-builder');
17
+ export class DefaultLikeC4ModelBuilder extends ADisposable {
18
+ projects;
19
+ parser;
20
+ listeners = [];
21
+ cache;
22
+ DocumentBuilder;
23
+ manualLayouts;
24
+ mutex;
25
+ constructor(services) {
26
+ super();
27
+ this.projects = services.shared.workspace.ProjectsManager;
28
+ this.parser = services.likec4.ModelParser;
29
+ this.cache = services.shared.workspace.Cache;
30
+ this.DocumentBuilder = services.shared.workspace.DocumentBuilder;
31
+ this.mutex = services.shared.workspace.WorkspaceLock;
32
+ this.manualLayouts = services.likec4.ManualLayouts;
33
+ this.onDispose(this.DocumentBuilder.onUpdate((_changed, deleted) => {
34
+ if (deleted.length > 0) {
35
+ this.notifyListeners(deleted);
36
+ }
37
+ }));
38
+ this.onDispose(this.DocumentBuilder.onBuildPhase(DocumentState.Validated, (docs, _cancelToken) => {
39
+ const validated = docs.flatMap(d => isLikeC4Builtin(d.uri) || this.projects.isExcluded(d) ? [] : d.uri);
40
+ if (validated.length > 0) {
41
+ this.notifyListeners(validated);
42
+ }
43
+ }));
44
+ builderLogger.debug `created`;
45
+ }
46
+ /**
47
+ * WARNING:
48
+ * This method is internal and should to be called only when all documents are known to be parsed.
49
+ * Otherwise, the model may be incomplete.
50
+ *
51
+ * To avoid circular dependencies, we do not resolve imports here.
52
+ */
53
+ unsafeSyncParseModelData(projectId) {
54
+ const cache = this.cache;
55
+ const logger = builderLogger.getChild(projectId);
56
+ const key = parsedWithoutImportsCacheKey(projectId);
57
+ if (cache.has(key)) {
58
+ logger.debug `unsafeSyncParseModelData from cache`;
59
+ }
60
+ return cache.get(key, () => {
61
+ try {
62
+ const project = this.projects.getProject(projectId);
63
+ const docs = this.documents(projectId);
64
+ if (docs.length === 0) {
65
+ logger.debug `no documents to build model`;
66
+ return null;
67
+ }
68
+ logger.debug `unsafeSyncParseModelData`;
69
+ return buildModelData(project, docs);
70
+ }
71
+ catch (err) {
72
+ builderLogger.warn(`unsafeSyncParseModelData failed for project ${projectId}`, { err });
73
+ return null;
74
+ }
75
+ });
76
+ }
77
+ /**
78
+ * To avoid circular dependencies, first we parse all documents and then we join them.
79
+ */
80
+ unsafeSyncJoinedModel(projectId) {
81
+ const logger = builderLogger.getChild(projectId);
82
+ const cache = this.cache;
83
+ const key = parsedModelCacheKey(projectId);
84
+ if (cache.has(key)) {
85
+ logger.debug `unsafeSyncJoinedModel from cache`;
86
+ }
87
+ return cache.get(key, () => {
88
+ const result = this.unsafeSyncParseModelData(projectId);
89
+ if (!result) {
90
+ return null;
91
+ }
92
+ let parsedData = result.data;
93
+ if (result.imports.size > 0) {
94
+ logger.debug `processing imports of ${projectId}`;
95
+ const imports = [...result.imports.associations()].reduce((acc, [projectId, fqns]) => {
96
+ const anotherProject = this.unsafeSyncParseModelData(projectId);
97
+ if (anotherProject) {
98
+ const imported = pipe([...fqns], flatMap(fqn => anotherProject.data.elements[fqn] ?? []));
99
+ if (hasAtLeast(imported, 1)) {
100
+ acc[projectId] = imported;
101
+ }
102
+ }
103
+ return acc;
104
+ }, {});
105
+ parsedData = {
106
+ ...result.data,
107
+ imports,
108
+ };
109
+ }
110
+ return LikeC4Model.create(parsedData);
111
+ });
112
+ }
113
+ async parseModel(projectId, cancelToken) {
114
+ projectId = this.projects.ensureProjectId(projectId);
115
+ const logger = builderLogger.getChild(projectId);
116
+ const t0 = performanceMark();
117
+ return await this.mutex.read(async () => {
118
+ if (cancelToken?.isCancellationRequested) {
119
+ await interruptAndCheck(cancelToken);
120
+ }
121
+ const parsedModel = this.unsafeSyncJoinedModel(projectId);
122
+ logger.debug `parseModel in ${t0.pretty}`;
123
+ return parsedModel;
124
+ });
125
+ }
126
+ previousViews = {};
127
+ /**
128
+ * WARNING:
129
+ * This method is internal and should to be called only when all documents are known to be parsed.
130
+ * Otherwise, the model may be incomplete.
131
+ */
132
+ unsafeSyncComputeModel(projectId, manualLayouts) {
133
+ const logger = builderLogger.getChild(projectId);
134
+ const cache = this.cache;
135
+ const hasManualLayouts = !!manualLayouts && !isEmpty(manualLayouts);
136
+ const key = computedModelCacheKey(projectId) + (hasManualLayouts ? '+manualLayouts' : '');
137
+ if (cache.has(key)) {
138
+ logger.debug `unsafeSyncBuildModel from cache`;
139
+ }
140
+ return cache.get(key, () => {
141
+ const parsedModel = this.unsafeSyncJoinedModel(projectId);
142
+ if (!parsedModel) {
143
+ return LikeC4Model.EMPTY.asComputed;
144
+ }
145
+ const allViews = [];
146
+ for (const view of values(parsedModel.$data.views)) {
147
+ const result = computeView(view, parsedModel);
148
+ if (!result.isSuccess) {
149
+ logger.warn(loggable(result.error));
150
+ continue;
151
+ }
152
+ if (manualLayouts?.[view.id]) {
153
+ Object.assign(result.view,
154
+ // satisfies enforces that the object has the property
155
+ { hasManualLayout: true });
156
+ }
157
+ allViews.push(result.view);
158
+ }
159
+ assignNavigateTo(allViews);
160
+ const views = mapToObj(allViews, v => {
161
+ const key = computedViewKey(projectId, v.id);
162
+ const previous = this.previousViews[key];
163
+ const view = previous && eq(v, previous) ? previous : v;
164
+ this.previousViews[key] = view;
165
+ return [v.id, view];
166
+ });
167
+ const data = {
168
+ ...parsedModel.$data,
169
+ [_stage]: 'computed',
170
+ views,
171
+ };
172
+ if (hasManualLayouts) {
173
+ data.manualLayouts = manualLayouts;
174
+ }
175
+ return LikeC4Model.create(data);
176
+ });
177
+ }
178
+ async computeModel(projectId, cancelToken) {
179
+ projectId = this.projects.ensureProjectId(projectId);
180
+ const logger = builderLogger.getChild(projectId);
181
+ const t0 = performanceMark();
182
+ return await this.mutex.read(async () => {
183
+ if (cancelToken?.isCancellationRequested) {
184
+ await interruptAndCheck(cancelToken);
185
+ }
186
+ const project = this.projects.getProject(projectId);
187
+ const manualLayouts = await this.manualLayouts.read(project);
188
+ const result = this.unsafeSyncComputeModel(projectId, manualLayouts);
189
+ logger.debug(`buildLikeC4Model in ${t0.pretty}`);
190
+ return result;
191
+ });
192
+ }
193
+ // public async rebuildProject(projectId?: c4.ProjectId | undefined): Promise<void> {
194
+ // await this.mutex.write(async (token) => {
195
+ // projectId = this.projects.ensureProjectId(projectId)
196
+ // this.clearCache()
197
+ // builderLogger.debug(`rebuildProject ${projectId}`)
198
+ // const docs = this.documents(projectId).map(doc => doc.uri)
199
+ // await this.DocumentBuilder.update(docs, [], token)
200
+ // })
201
+ // }
202
+ onModelParsed(callback) {
203
+ this.listeners.push(callback);
204
+ return Disposable.create(() => {
205
+ const index = this.listeners.indexOf(callback);
206
+ if (index >= 0) {
207
+ this.listeners.splice(index, 1);
208
+ }
209
+ });
210
+ }
211
+ clearCache() {
212
+ builderLogger.debug(`clearCache`);
213
+ this.cache.clear();
214
+ this.previousViews = {};
215
+ }
216
+ documents(projectId) {
217
+ return this.parser.documents(projectId).toArray();
218
+ }
219
+ notifyListeners(docs) {
220
+ for (const listener of this.listeners) {
221
+ try {
222
+ listener(docs);
223
+ }
224
+ catch (e) {
225
+ builderLogger.warn(loggable(e));
226
+ }
227
+ }
228
+ }
229
+ }
230
+ function computedViewKey(projectId, viewId) {
231
+ return `computed-view-${projectId}-${viewId}`;
232
+ }
@@ -5,6 +5,11 @@ import { URI } from 'vscode-uri';
5
5
  import type { ParsedAstElement, ParsedAstView, ParsedLikeC4LangiumDocument } from '../ast';
6
6
  import { ast } from '../ast';
7
7
  import type { LikeC4Services } from '../module';
8
+ export type ViewLocateResult = {
9
+ doc: ParsedLikeC4LangiumDocument;
10
+ view: ParsedAstView;
11
+ viewAst: ast.LikeC4View;
12
+ };
8
13
  export declare class LikeC4ModelLocator {
9
14
  private services;
10
15
  private fqnIndex;
@@ -18,11 +23,7 @@ export declare class LikeC4ModelLocator {
18
23
  locateElement(fqn: c4.Fqn, projectId?: c4.ProjectId | undefined): Location | null;
19
24
  locateDeploymentElement(deploymentFqn: c4.DeploymentFqn, projectId?: c4.ProjectId | undefined): Location | null;
20
25
  locateRelation(relationId: c4.RelationId, projectId?: c4.ProjectId): Location | null;
21
- locateViewAst(viewId: c4.ViewId, projectId?: c4.ProjectId | undefined): null | {
22
- doc: ParsedLikeC4LangiumDocument;
23
- view: ParsedAstView;
24
- viewAst: ast.LikeC4View;
25
- };
26
+ locateViewAst(viewId: c4.ViewId, projectId?: c4.ProjectId | undefined): null | ViewLocateResult;
26
27
  locateView(viewId: c4.ViewId, projectId?: c4.ProjectId): Location | null;
27
28
  locateDocumentTags(documentUri: URI, cancelToken?: Cancellation.CancellationToken): Promise<Array<{
28
29
  name: string;