@likec4/language-server 1.27.3 → 1.28.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/LikeC4LanguageServices.js +6 -7
- package/dist/ast.d.ts +16 -9
- package/dist/ast.js +58 -79
- package/dist/bundled.mjs +2130 -2127
- package/dist/config/schema.d.ts +3 -3
- package/dist/config/schema.js +12 -5
- package/dist/documentation/documentation-provider.js +3 -1
- package/dist/formatting/LikeC4Formatter.d.ts +0 -2
- package/dist/formatting/LikeC4Formatter.js +24 -53
- package/dist/generated/ast.d.ts +128 -233
- package/dist/generated/ast.js +134 -306
- package/dist/generated/grammar.js +1 -1
- package/dist/lsp/CompletionProvider.d.ts +3 -0
- package/dist/lsp/CompletionProvider.js +128 -113
- package/dist/lsp/DocumentLinkProvider.js +6 -3
- package/dist/lsp/HoverProvider.js +3 -1
- package/dist/lsp/SemanticTokenProvider.js +33 -43
- package/dist/model/builder/MergedSpecification.d.ts +5 -3
- package/dist/model/builder/MergedSpecification.js +21 -7
- package/dist/model/builder/buildModel.d.ts +6 -1
- package/dist/model/builder/buildModel.js +20 -15
- package/dist/model/deployments-index.js +4 -2
- package/dist/model/fqn-index.d.ts +4 -2
- package/dist/model/fqn-index.js +28 -5
- package/dist/model/model-builder.d.ts +2 -2
- package/dist/model/model-builder.js +54 -16
- package/dist/model/model-locator.js +7 -4
- package/dist/model/model-parser.d.ts +215 -52
- package/dist/model/model-parser.js +6 -2
- package/dist/model/parser/Base.d.ts +11 -2
- package/dist/model/parser/Base.js +138 -3
- package/dist/model/parser/DeploymentModelParser.d.ts +19 -2
- package/dist/model/parser/DeploymentModelParser.js +19 -29
- package/dist/model/parser/DeploymentViewParser.d.ts +18 -2
- package/dist/model/parser/DeploymentViewParser.js +6 -24
- package/dist/model/parser/FqnRefParser.d.ts +18 -3
- package/dist/model/parser/FqnRefParser.js +264 -40
- package/dist/model/parser/GlobalsParser.d.ts +35 -18
- package/dist/model/parser/ImportsParser.d.ts +32 -0
- package/dist/model/parser/ImportsParser.js +26 -0
- package/dist/model/parser/ModelParser.d.ts +26 -2
- package/dist/model/parser/ModelParser.js +21 -41
- package/dist/model/parser/PredicatesParser.d.ts +35 -12
- package/dist/model/parser/PredicatesParser.js +20 -271
- package/dist/model/parser/SpecificationParser.d.ts +8 -0
- package/dist/model/parser/SpecificationParser.js +5 -9
- package/dist/model/parser/ViewsParser.d.ts +36 -19
- package/dist/model/parser/ViewsParser.js +15 -11
- package/dist/model-change/changeElementStyle.d.ts +2 -2
- package/dist/model-change/changeElementStyle.js +2 -1
- package/dist/references/name-provider.js +8 -2
- package/dist/references/scope-computation.d.ts +1 -1
- package/dist/references/scope-computation.js +33 -3
- package/dist/references/scope-provider.d.ts +7 -8
- package/dist/references/scope-provider.js +59 -41
- package/dist/shared/NodeKindProvider.js +4 -2
- package/dist/test/testServices.d.ts +2 -0
- package/dist/test/testServices.js +4 -1
- package/dist/utils/elementRef.d.ts +1 -1
- package/dist/utils/elementRef.js +6 -1
- package/dist/utils/fqnRef.d.ts +3 -0
- package/dist/utils/fqnRef.js +15 -4
- package/dist/utils/index.d.ts +1 -0
- package/dist/utils/index.js +9 -0
- package/dist/utils/projectId.d.ts +2 -1
- package/dist/utils/projectId.js +11 -1
- package/dist/validation/_shared.js +2 -2
- package/dist/validation/deployment-checks.js +24 -10
- package/dist/validation/element-ref.d.ts +4 -0
- package/dist/validation/element-ref.js +12 -0
- package/dist/validation/element.d.ts +1 -1
- package/dist/validation/element.js +1 -1
- package/dist/validation/imports.d.ts +5 -0
- package/dist/validation/imports.js +30 -0
- package/dist/validation/index.d.ts +1 -1
- package/dist/validation/index.js +47 -45
- package/dist/validation/relation.d.ts +2 -2
- package/dist/validation/relation.js +24 -27
- package/dist/validation/specification.d.ts +9 -9
- package/dist/validation/specification.js +9 -9
- package/dist/validation/view-predicates/{element-with.d.ts → fqn-expr-with.d.ts} +1 -1
- package/dist/validation/view-predicates/fqn-expr-with.js +42 -0
- package/dist/validation/view-predicates/fqn-ref-expr.d.ts +4 -0
- package/dist/validation/view-predicates/fqn-ref-expr.js +53 -0
- package/dist/validation/view-predicates/incoming.d.ts +1 -1
- package/dist/validation/view-predicates/incoming.js +2 -2
- package/dist/validation/view-predicates/index.d.ts +6 -6
- package/dist/validation/view-predicates/index.js +6 -6
- package/dist/validation/view-predicates/outgoing.d.ts +1 -1
- package/dist/validation/view-predicates/outgoing.js +8 -4
- package/dist/validation/view-predicates/{expanded-element.d.ts → relation-expr.d.ts} +1 -1
- package/dist/validation/view-predicates/relation-expr.js +39 -0
- package/dist/validation/view-predicates/relation-with.d.ts +1 -1
- package/dist/validation/view-predicates/relation-with.js +8 -5
- package/dist/workspace/AstNodeDescriptionProvider.d.ts +1 -1
- package/dist/workspace/AstNodeDescriptionProvider.js +2 -3
- package/dist/workspace/IndexManager.d.ts +1 -1
- package/dist/workspace/IndexManager.js +5 -4
- package/dist/workspace/LangiumDocuments.d.ts +1 -1
- package/dist/workspace/LangiumDocuments.js +3 -5
- package/dist/workspace/ProjectsManager.d.ts +25 -7
- package/dist/workspace/ProjectsManager.js +76 -32
- package/dist/workspace/WorkspaceManager.d.ts +4 -5
- package/dist/workspace/WorkspaceManager.js +53 -20
- package/package.json +12 -10
- package/dist/validation/dynamic-view-rule.d.ts +0 -4
- package/dist/validation/dynamic-view-rule.js +0 -17
- package/dist/validation/view-predicates/element-with.js +0 -31
- package/dist/validation/view-predicates/expanded-element.js +0 -12
- package/dist/validation/view-predicates/expression-v2.d.ts +0 -5
- package/dist/validation/view-predicates/expression-v2.js +0 -83
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
computeColorValues,
|
|
3
3
|
DeploymentElement,
|
|
4
|
+
isGlobalFqn,
|
|
4
5
|
parentFqn,
|
|
5
6
|
sortByFqnHierarchically
|
|
6
7
|
} from "@likec4/core";
|
|
@@ -22,7 +23,7 @@ import { logger } from "../../logger.js";
|
|
|
22
23
|
import { resolveRelativePaths } from "../../view-utils/index.js";
|
|
23
24
|
import { MergedExtends } from "./MergedExtends.js";
|
|
24
25
|
import { MergedSpecification } from "./MergedSpecification.js";
|
|
25
|
-
export function
|
|
26
|
+
export function buildModelData(docs) {
|
|
26
27
|
const c4Specification = new MergedSpecification(docs);
|
|
27
28
|
const customColorDefinitions = mapValues(
|
|
28
29
|
c4Specification.specs.colors,
|
|
@@ -58,7 +59,7 @@ export function buildModel(docs) {
|
|
|
58
59
|
flatMap((d) => map(d.c4Relations, c4Specification.toModelRelation)),
|
|
59
60
|
filter((rel) => {
|
|
60
61
|
if (!rel) return false;
|
|
61
|
-
if (isNullish(elements[rel.source]) || isNullish(elements[rel.target])) {
|
|
62
|
+
if (isNullish(elements[rel.source]) && !isGlobalFqn(rel.source) || isNullish(elements[rel.target]) && !isGlobalFqn(rel.target)) {
|
|
62
63
|
logger.debug`Invalid relation ${rel.id}
|
|
63
64
|
source: ${rel.source} resolved: ${!!elements[rel.source]}
|
|
64
65
|
target: ${rel.target} resolved: ${!!elements[rel.target]}\n`;
|
|
@@ -176,19 +177,23 @@ export function buildModel(docs) {
|
|
|
176
177
|
resolveRulesExtendedViews
|
|
177
178
|
);
|
|
178
179
|
return {
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
180
|
+
data: {
|
|
181
|
+
specification: {
|
|
182
|
+
tags: Array.from(c4Specification.specs.tags),
|
|
183
|
+
elements: c4Specification.specs.elements,
|
|
184
|
+
relationships: c4Specification.specs.relationships,
|
|
185
|
+
deployments: c4Specification.specs.deployments
|
|
186
|
+
},
|
|
187
|
+
elements,
|
|
188
|
+
relations,
|
|
189
|
+
globals: c4Specification.globals,
|
|
190
|
+
views,
|
|
191
|
+
deployments: {
|
|
192
|
+
elements: deploymentElements,
|
|
193
|
+
relations: deploymentRelations
|
|
194
|
+
},
|
|
195
|
+
imports: {}
|
|
184
196
|
},
|
|
185
|
-
|
|
186
|
-
relations,
|
|
187
|
-
globals: c4Specification.globals,
|
|
188
|
-
views,
|
|
189
|
-
deployments: {
|
|
190
|
-
elements: deploymentElements,
|
|
191
|
-
relations: deploymentRelations
|
|
192
|
-
}
|
|
197
|
+
imports: c4Specification.imports
|
|
193
198
|
};
|
|
194
199
|
}
|
|
@@ -20,6 +20,7 @@ export class DeploymentsIndex extends FqnIndex {
|
|
|
20
20
|
if (rootNodes.length === 0) {
|
|
21
21
|
return DocumentFqnIndex.EMPTY;
|
|
22
22
|
}
|
|
23
|
+
const projectId = document.likec4ProjectId ??= this.projects.belongsTo(document);
|
|
23
24
|
const root = new Array();
|
|
24
25
|
const children = new MultiMap();
|
|
25
26
|
const descendants = new MultiMap();
|
|
@@ -29,7 +30,8 @@ export class DeploymentsIndex extends FqnIndex {
|
|
|
29
30
|
const createAndSaveDescription = (node, name, fqn) => {
|
|
30
31
|
const desc = {
|
|
31
32
|
...Descriptions.createDescription(node, name, document),
|
|
32
|
-
id: fqn
|
|
33
|
+
id: fqn,
|
|
34
|
+
likec4ProjectId: projectId
|
|
33
35
|
};
|
|
34
36
|
ElementOps.writeId(node, fqn);
|
|
35
37
|
byfqn.set(fqn, desc);
|
|
@@ -93,6 +95,6 @@ export class DeploymentsIndex extends FqnIndex {
|
|
|
93
95
|
logWarnError(e);
|
|
94
96
|
}
|
|
95
97
|
}
|
|
96
|
-
return new DocumentFqnIndex(root, children, descendants, byfqn,
|
|
98
|
+
return new DocumentFqnIndex(root, children, descendants, byfqn, projectId);
|
|
97
99
|
}
|
|
98
100
|
}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { type Fqn, type ProjectId } from '@likec4/core/types';
|
|
2
2
|
import { DefaultWeakMap, MultiMap } from '@likec4/core/utils';
|
|
3
|
-
import { type
|
|
3
|
+
import { type Stream, WorkspaceCache } from 'langium';
|
|
4
4
|
import { type AstNodeDescriptionWithFqn, type LikeC4LangiumDocument, ast } from '../ast';
|
|
5
5
|
import type { LikeC4Services } from '../module';
|
|
6
6
|
import { ADisposable } from '../utils';
|
|
7
7
|
import { type LangiumDocuments, ProjectsManager } from '../workspace';
|
|
8
|
-
export declare class FqnIndex<AstNd
|
|
8
|
+
export declare class FqnIndex<AstNd = ast.Element> extends ADisposable {
|
|
9
9
|
protected services: LikeC4Services;
|
|
10
10
|
private cachePrefix;
|
|
11
11
|
protected projects: ProjectsManager;
|
|
@@ -15,8 +15,10 @@ export declare class FqnIndex<AstNd extends AstNode = ast.Element> extends ADisp
|
|
|
15
15
|
constructor(services: LikeC4Services, cachePrefix?: string);
|
|
16
16
|
private documents;
|
|
17
17
|
get(document: LikeC4LangiumDocument): DocumentFqnIndex;
|
|
18
|
+
resolve(reference: ast.Referenceable): Fqn;
|
|
18
19
|
getFqn(el: AstNd): Fqn;
|
|
19
20
|
byFqn(projectId: ProjectId, fqn: Fqn): Stream<AstNodeDescriptionWithFqn>;
|
|
21
|
+
rootElements(projectId: ProjectId): Stream<AstNodeDescriptionWithFqn>;
|
|
20
22
|
directChildrenOf(projectId: ProjectId, parent: Fqn): Stream<AstNodeDescriptionWithFqn>;
|
|
21
23
|
/**
|
|
22
24
|
* Returns descedant elements with unique names in the scope
|
package/dist/model/fqn-index.js
CHANGED
|
@@ -29,11 +29,10 @@ export class FqnIndex extends ADisposable {
|
|
|
29
29
|
this.onDispose(
|
|
30
30
|
services.shared.workspace.DocumentBuilder.onDocumentPhase(
|
|
31
31
|
DocumentState.IndexedContent,
|
|
32
|
-
|
|
32
|
+
(doc) => {
|
|
33
33
|
if (isLikeC4LangiumDocument(doc)) {
|
|
34
34
|
this.documentCache.set(doc, this.createDocumentIndex(doc));
|
|
35
35
|
}
|
|
36
|
-
return await Promise.resolve();
|
|
37
36
|
}
|
|
38
37
|
)
|
|
39
38
|
);
|
|
@@ -53,6 +52,15 @@ export class FqnIndex extends ADisposable {
|
|
|
53
52
|
}
|
|
54
53
|
return this.documentCache.get(document);
|
|
55
54
|
}
|
|
55
|
+
resolve(reference) {
|
|
56
|
+
if (reference.$type === "Imported") {
|
|
57
|
+
return this.getFqn(reference.imported.ref);
|
|
58
|
+
}
|
|
59
|
+
if (reference.$type === "Element") {
|
|
60
|
+
return this.getFqn(reference);
|
|
61
|
+
}
|
|
62
|
+
return this.services.likec4.DeploymentsIndex.getFqn(reference);
|
|
63
|
+
}
|
|
56
64
|
getFqn(el) {
|
|
57
65
|
invariant(ast.isElement(el) || ast.isDeploymentElement(el));
|
|
58
66
|
let id = ElementOps.readId(el);
|
|
@@ -66,12 +74,25 @@ export class FqnIndex extends ADisposable {
|
|
|
66
74
|
return nonNullable(ElementOps.readId(el), "Element fqn must be set, invalid state");
|
|
67
75
|
}
|
|
68
76
|
byFqn(projectId, fqn) {
|
|
69
|
-
return stream(this.workspaceCache.get(`${this.cachePrefix}:${projectId}:${fqn}`, () => {
|
|
77
|
+
return stream(this.workspaceCache.get(`${this.cachePrefix}:${projectId}:fqn:${fqn}`, () => {
|
|
70
78
|
return this.documents(projectId).toArray().flatMap((doc) => {
|
|
71
79
|
return this.get(doc).byFqn(fqn);
|
|
72
80
|
});
|
|
73
81
|
}));
|
|
74
82
|
}
|
|
83
|
+
rootElements(projectId) {
|
|
84
|
+
return stream(
|
|
85
|
+
this.workspaceCache.get(`${this.cachePrefix}:${projectId}:rootElements`, () => {
|
|
86
|
+
const allchildren = this.documents(projectId).reduce((map, doc) => {
|
|
87
|
+
this.get(doc).rootElements().forEach((desc) => {
|
|
88
|
+
map.set(desc.name, desc);
|
|
89
|
+
});
|
|
90
|
+
return map;
|
|
91
|
+
}, new MultiMap());
|
|
92
|
+
return uniqueByName(allchildren).sort((a, b) => compareNatural(a.name, b.name));
|
|
93
|
+
})
|
|
94
|
+
);
|
|
95
|
+
}
|
|
75
96
|
directChildrenOf(projectId, parent) {
|
|
76
97
|
return stream(
|
|
77
98
|
this.workspaceCache.get(`${this.cachePrefix}:${projectId}:directChildrenOf:${parent}`, () => {
|
|
@@ -118,6 +139,7 @@ export class FqnIndex extends ADisposable {
|
|
|
118
139
|
if (rootElements.length === 0) {
|
|
119
140
|
return DocumentFqnIndex.EMPTY;
|
|
120
141
|
}
|
|
142
|
+
const projectId = document.likec4ProjectId ??= this.projects.belongsTo(document);
|
|
121
143
|
const root = new Array();
|
|
122
144
|
const children = new MultiMap();
|
|
123
145
|
const descendants = new MultiMap();
|
|
@@ -126,7 +148,8 @@ export class FqnIndex extends ADisposable {
|
|
|
126
148
|
const createAndSaveDescription = (node, name, fqn) => {
|
|
127
149
|
const desc = {
|
|
128
150
|
...Descriptions.createDescription(node, name, document),
|
|
129
|
-
id: fqn
|
|
151
|
+
id: fqn,
|
|
152
|
+
likec4ProjectId: projectId
|
|
130
153
|
};
|
|
131
154
|
ElementOps.writeId(node, fqn);
|
|
132
155
|
byfqn.set(fqn, desc);
|
|
@@ -184,7 +207,7 @@ export class FqnIndex extends ADisposable {
|
|
|
184
207
|
logWarnError(e);
|
|
185
208
|
}
|
|
186
209
|
}
|
|
187
|
-
return new DocumentFqnIndex(root, children, descendants, byfqn,
|
|
210
|
+
return new DocumentFqnIndex(root, children, descendants, byfqn, projectId);
|
|
188
211
|
}
|
|
189
212
|
}
|
|
190
213
|
function uniqueByName(multimap) {
|
|
@@ -18,7 +18,6 @@ export declare class DefaultLikeC4ModelBuilder extends ADisposable implements Li
|
|
|
18
18
|
private listeners;
|
|
19
19
|
private cache;
|
|
20
20
|
private DocumentBuilder;
|
|
21
|
-
private LangiumDocuments;
|
|
22
21
|
private mutex;
|
|
23
22
|
constructor(services: LikeC4Services);
|
|
24
23
|
/**
|
|
@@ -26,7 +25,8 @@ export declare class DefaultLikeC4ModelBuilder extends ADisposable implements Li
|
|
|
26
25
|
* This method is internal and should to be called only when all documents are known to be parsed.
|
|
27
26
|
* Otherwise, the model may be incomplete.
|
|
28
27
|
*/
|
|
29
|
-
private
|
|
28
|
+
private unsafeSyncParseModelData;
|
|
29
|
+
private unsafeSyncJoinedModelData;
|
|
30
30
|
parseModel(projectId?: c4.ProjectId | undefined, cancelToken?: CancellationToken): Promise<c4.ParsedLikeC4ModelData | null>;
|
|
31
31
|
private previousViews;
|
|
32
32
|
/**
|
|
@@ -12,7 +12,9 @@ import {
|
|
|
12
12
|
import prettyMs from "pretty-ms";
|
|
13
13
|
import {
|
|
14
14
|
filter,
|
|
15
|
+
flatMap,
|
|
15
16
|
groupBy,
|
|
17
|
+
hasAtLeast,
|
|
16
18
|
isNot,
|
|
17
19
|
mapToObj,
|
|
18
20
|
pipe,
|
|
@@ -24,7 +26,8 @@ import { isLikeC4Builtin } from "../likec4lib.js";
|
|
|
24
26
|
import { logger as mainLogger, logWarnError } from "../logger.js";
|
|
25
27
|
import { ADisposable } from "../utils/index.js";
|
|
26
28
|
import { assignNavigateTo } from "../view-utils/index.js";
|
|
27
|
-
import {
|
|
29
|
+
import { buildModelData } from "./builder/buildModel.js";
|
|
30
|
+
const parsedWithoutImportsCacheKey = (projectId) => `parsed-without-imports-${projectId}`;
|
|
28
31
|
const parsedModelCacheKey = (projectId) => `parsed-model-${projectId}`;
|
|
29
32
|
const computedModelCacheKey = (projectId) => `computed-model-${projectId}`;
|
|
30
33
|
const logger = mainLogger.getChild("ModelBuilder");
|
|
@@ -34,7 +37,6 @@ export class DefaultLikeC4ModelBuilder extends ADisposable {
|
|
|
34
37
|
listeners = [];
|
|
35
38
|
cache;
|
|
36
39
|
DocumentBuilder;
|
|
37
|
-
LangiumDocuments;
|
|
38
40
|
mutex;
|
|
39
41
|
constructor(services) {
|
|
40
42
|
super();
|
|
@@ -42,7 +44,6 @@ export class DefaultLikeC4ModelBuilder extends ADisposable {
|
|
|
42
44
|
this.parser = services.likec4.ModelParser;
|
|
43
45
|
this.cache = services.ValidatedWorkspaceCache;
|
|
44
46
|
this.DocumentBuilder = services.shared.workspace.DocumentBuilder;
|
|
45
|
-
this.LangiumDocuments = services.shared.workspace.LangiumDocuments;
|
|
46
47
|
this.mutex = services.shared.workspace.WorkspaceLock;
|
|
47
48
|
this.onDispose(
|
|
48
49
|
this.DocumentBuilder.onUpdate((_changed, deleted) => {
|
|
@@ -69,20 +70,57 @@ export class DefaultLikeC4ModelBuilder extends ADisposable {
|
|
|
69
70
|
* This method is internal and should to be called only when all documents are known to be parsed.
|
|
70
71
|
* Otherwise, the model may be incomplete.
|
|
71
72
|
*/
|
|
72
|
-
|
|
73
|
+
unsafeSyncParseModelData(projectId) {
|
|
73
74
|
const cache = this.cache;
|
|
74
75
|
const log = logger.getChild(["project", projectId]);
|
|
75
|
-
|
|
76
|
-
|
|
76
|
+
const key = parsedWithoutImportsCacheKey(projectId);
|
|
77
|
+
if (cache.has(key)) {
|
|
78
|
+
log.debug`unsafeSyncBuildModelData from cache, project ${projectId}`;
|
|
77
79
|
}
|
|
78
|
-
return cache.get(
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
80
|
+
return cache.get(key, () => {
|
|
81
|
+
try {
|
|
82
|
+
const docs = this.documents(projectId);
|
|
83
|
+
if (docs.length === 0) {
|
|
84
|
+
logger.debug`no documents to build model, project ${projectId}`;
|
|
85
|
+
return null;
|
|
86
|
+
}
|
|
87
|
+
log.debug`unsafeSyncBuildModelData, project ${projectId}`;
|
|
88
|
+
return buildModelData(docs);
|
|
89
|
+
} catch (e) {
|
|
90
|
+
logWarnError(e);
|
|
82
91
|
return null;
|
|
83
92
|
}
|
|
84
|
-
|
|
85
|
-
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
unsafeSyncJoinedModelData(projectId) {
|
|
96
|
+
const cache = this.cache;
|
|
97
|
+
const key = parsedModelCacheKey(projectId);
|
|
98
|
+
return cache.get(key, () => {
|
|
99
|
+
const result = this.unsafeSyncParseModelData(projectId);
|
|
100
|
+
if (!result) {
|
|
101
|
+
return null;
|
|
102
|
+
}
|
|
103
|
+
if (result.imports.size > 0) {
|
|
104
|
+
logger.debug`processing imports of ${projectId}`;
|
|
105
|
+
const imports = [...result.imports.associations()].reduce((acc, [projectId2, fqns]) => {
|
|
106
|
+
const anotherProject = this.unsafeSyncParseModelData(projectId2);
|
|
107
|
+
if (anotherProject) {
|
|
108
|
+
const imported = pipe(
|
|
109
|
+
[...fqns],
|
|
110
|
+
flatMap((fqn) => anotherProject.data.elements[fqn] ?? [])
|
|
111
|
+
);
|
|
112
|
+
if (hasAtLeast(imported, 1)) {
|
|
113
|
+
acc[projectId2] = imported;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
return acc;
|
|
117
|
+
}, {});
|
|
118
|
+
return {
|
|
119
|
+
...result.data,
|
|
120
|
+
imports
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
return result.data;
|
|
86
124
|
});
|
|
87
125
|
}
|
|
88
126
|
async parseModel(projectId, cancelToken = CancellationToken.None) {
|
|
@@ -91,14 +129,14 @@ export class DefaultLikeC4ModelBuilder extends ADisposable {
|
|
|
91
129
|
const cache = this.cache;
|
|
92
130
|
const cached = cache.get(parsedModelCacheKey(project));
|
|
93
131
|
if (cached) {
|
|
94
|
-
log.debug
|
|
132
|
+
log.debug`parseModel from cache, project ${project}`;
|
|
95
133
|
return cached;
|
|
96
134
|
}
|
|
97
135
|
const t0 = performance.now();
|
|
98
136
|
return await this.mutex.read(async () => {
|
|
99
137
|
await interruptAndCheck(cancelToken);
|
|
100
|
-
const result = this.
|
|
101
|
-
log.debug(`parseModel in ${prettyMs(performance.now() - t0)}`);
|
|
138
|
+
const result = this.unsafeSyncJoinedModelData(project);
|
|
139
|
+
log.debug(`parseModel, project ${project} in ${prettyMs(performance.now() - t0)}`);
|
|
102
140
|
return result;
|
|
103
141
|
});
|
|
104
142
|
}
|
|
@@ -112,7 +150,7 @@ export class DefaultLikeC4ModelBuilder extends ADisposable {
|
|
|
112
150
|
const cache = this.cache;
|
|
113
151
|
const viewsCache = this.cache;
|
|
114
152
|
return cache.get(computedModelCacheKey(projectId), () => {
|
|
115
|
-
const parsed = this.
|
|
153
|
+
const parsed = this.unsafeSyncJoinedModelData(projectId);
|
|
116
154
|
if (!parsed) {
|
|
117
155
|
return LikeC4Model.EMPTY;
|
|
118
156
|
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { splitGlobalFqn } from "@likec4/core";
|
|
1
2
|
import { AstUtils, GrammarUtils } from "langium";
|
|
2
3
|
import { isString } from "remeda";
|
|
3
4
|
import { ast } from "../ast.js";
|
|
@@ -50,8 +51,9 @@ export class LikeC4ModelLocator {
|
|
|
50
51
|
return doc.c4Elements.find((e) => e.id === fqn) ?? null;
|
|
51
52
|
}
|
|
52
53
|
locateElement(fqn, projectId) {
|
|
53
|
-
|
|
54
|
-
|
|
54
|
+
let [_projectId, _fqn] = splitGlobalFqn(fqn);
|
|
55
|
+
_projectId ??= this.projects.ensureProjectId(projectId);
|
|
56
|
+
const entry = this.fqnIndex.byFqn(_projectId, _fqn).head();
|
|
55
57
|
const docsegment = entry?.nameSegment ?? entry?.selectionSegment;
|
|
56
58
|
if (!entry || !docsegment) {
|
|
57
59
|
return null;
|
|
@@ -62,8 +64,9 @@ export class LikeC4ModelLocator {
|
|
|
62
64
|
};
|
|
63
65
|
}
|
|
64
66
|
locateDeploymentElement(fqn, projectId) {
|
|
65
|
-
|
|
66
|
-
|
|
67
|
+
let [_projectId, _fqn] = splitGlobalFqn(fqn);
|
|
68
|
+
_projectId ??= this.projects.ensureProjectId(projectId);
|
|
69
|
+
const entry = this.deploymentsIndex.byFqn(_projectId, _fqn).head();
|
|
67
70
|
const docsegment = entry?.nameSegment ?? entry?.selectionSegment;
|
|
68
71
|
if (!entry || !docsegment) {
|
|
69
72
|
return null;
|