@likec4/language-server 1.25.1 → 1.26.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/LikeC4FileSystem.js +6 -1
- package/dist/LikeC4LanguageServices.d.ts +77 -0
- package/dist/LikeC4LanguageServices.js +118 -0
- package/dist/Rpc.js +106 -28
- package/dist/ast.d.ts +10 -0
- package/dist/bundled.mjs +2352 -2278
- package/dist/config/index.d.ts +1 -0
- package/dist/config/index.js +1 -0
- package/dist/config/schema.d.ts +8 -0
- package/dist/config/schema.js +19 -0
- package/dist/index.d.ts +1 -0
- package/dist/lsp/CodeLensProvider.js +3 -1
- package/dist/model/builder/buildModel.d.ts +8 -1
- package/dist/model/deployments-index.js +1 -1
- package/dist/model/fqn-index.d.ts +9 -6
- package/dist/model/fqn-index.js +24 -14
- package/dist/model/model-builder.d.ts +16 -6
- package/dist/model/model-builder.js +64 -50
- package/dist/model/model-locator.d.ts +11 -10
- package/dist/model/model-locator.js +32 -14
- package/dist/model/model-parser.d.ts +148 -148
- package/dist/model/model-parser.js +2 -2
- package/dist/model/parser/ModelParser.js +14 -2
- package/dist/model-change/ModelChanges.d.ts +1 -1
- package/dist/model-change/ModelChanges.js +2 -2
- package/dist/module.d.ts +9 -3
- package/dist/module.js +19 -5
- package/dist/protocol.d.ts +98 -16
- package/dist/protocol.js +21 -6
- package/dist/references/scope-provider.d.ts +24 -11
- package/dist/references/scope-provider.js +97 -68
- package/dist/shared/index.d.ts +0 -1
- package/dist/shared/index.js +0 -1
- package/dist/test/testServices.d.ts +15 -1
- package/dist/test/testServices.js +65 -17
- package/dist/utils/index.d.ts +3 -0
- package/dist/utils/index.js +3 -0
- package/dist/utils/projectId.d.ts +3 -0
- package/dist/utils/projectId.js +6 -0
- package/dist/validation/deployment-checks.js +5 -2
- package/dist/validation/element.js +2 -1
- package/dist/validation/specification.js +14 -7
- package/dist/validation/view.js +10 -8
- package/dist/views/index.d.ts +1 -1
- package/dist/views/index.js +1 -1
- package/dist/views/likec4-views.d.ts +17 -8
- package/dist/views/likec4-views.js +12 -11
- package/dist/workspace/AstNodeDescriptionProvider.d.ts +7 -0
- package/dist/workspace/AstNodeDescriptionProvider.js +18 -0
- package/dist/workspace/IndexManager.d.ts +10 -0
- package/dist/workspace/IndexManager.js +17 -0
- package/dist/workspace/LangiumDocuments.d.ts +14 -0
- package/dist/workspace/LangiumDocuments.js +31 -0
- package/dist/workspace/ProjectsManager.d.ts +48 -0
- package/dist/workspace/ProjectsManager.js +150 -0
- package/dist/{shared → workspace}/WorkspaceManager.d.ts +8 -2
- package/dist/{shared → workspace}/WorkspaceManager.js +22 -0
- package/dist/workspace/index.d.ts +5 -0
- package/dist/workspace/index.js +5 -0
- package/package.json +17 -8
package/dist/module.js
CHANGED
|
@@ -15,6 +15,7 @@ import {
|
|
|
15
15
|
LikeC4GeneratedModule,
|
|
16
16
|
LikeC4GeneratedSharedModule
|
|
17
17
|
} from "./generated/module.js";
|
|
18
|
+
import { DefaultLikeC4LanguageServices } from "./LikeC4LanguageServices.js";
|
|
18
19
|
import { logger } from "./logger.js";
|
|
19
20
|
import {
|
|
20
21
|
LikeC4CodeLensProvider,
|
|
@@ -26,9 +27,9 @@ import {
|
|
|
26
27
|
LikeC4SemanticTokenProvider
|
|
27
28
|
} from "./lsp/index.js";
|
|
28
29
|
import {
|
|
30
|
+
DefaultLikeC4ModelBuilder,
|
|
29
31
|
DeploymentsIndex,
|
|
30
32
|
FqnIndex,
|
|
31
|
-
LikeC4ModelBuilder,
|
|
32
33
|
LikeC4ModelLocator,
|
|
33
34
|
LikeC4ModelParser
|
|
34
35
|
} from "./model/index.js";
|
|
@@ -40,18 +41,27 @@ import {
|
|
|
40
41
|
} from "./references/index.js";
|
|
41
42
|
import { Rpc } from "./Rpc.js";
|
|
42
43
|
import {
|
|
43
|
-
LikeC4WorkspaceManager,
|
|
44
44
|
NodeKindProvider,
|
|
45
45
|
WorkspaceSymbolProvider
|
|
46
46
|
} from "./shared/index.js";
|
|
47
47
|
import { registerValidationChecks } from "./validation/index.js";
|
|
48
|
-
import {
|
|
48
|
+
import { DefaultLikeC4Views } from "./views/index.js";
|
|
49
|
+
import {
|
|
50
|
+
AstNodeDescriptionProvider,
|
|
51
|
+
IndexManager,
|
|
52
|
+
LangiumDocuments,
|
|
53
|
+
LikeC4WorkspaceManager,
|
|
54
|
+
ProjectsManager
|
|
55
|
+
} from "./workspace/index.js";
|
|
49
56
|
const LikeC4SharedModule = {
|
|
50
57
|
lsp: {
|
|
51
58
|
NodeKindProvider: (services) => new NodeKindProvider(services),
|
|
52
59
|
WorkspaceSymbolProvider: (services) => new WorkspaceSymbolProvider(services)
|
|
53
60
|
},
|
|
54
61
|
workspace: {
|
|
62
|
+
IndexManager: (services) => new IndexManager(services),
|
|
63
|
+
LangiumDocuments: (services) => new LangiumDocuments(services),
|
|
64
|
+
ProjectsManager: (services) => new ProjectsManager(services),
|
|
55
65
|
WorkspaceManager: (services) => new LikeC4WorkspaceManager(services)
|
|
56
66
|
}
|
|
57
67
|
};
|
|
@@ -65,16 +75,17 @@ export const LikeC4Module = {
|
|
|
65
75
|
ValidatedWorkspaceCache: (services) => new WorkspaceCache(services.shared, DocumentState.Validated),
|
|
66
76
|
Rpc: bind(Rpc),
|
|
67
77
|
likec4: {
|
|
78
|
+
LanguageServices: bind(DefaultLikeC4LanguageServices),
|
|
68
79
|
Layouter: (_services) => {
|
|
69
80
|
logger.debug("Creating GraphvizLayouter with GraphvizWasmAdapter");
|
|
70
81
|
return new GraphvizLayouter(new GraphvizWasmAdapter());
|
|
71
82
|
},
|
|
72
|
-
Views: bind(
|
|
83
|
+
Views: bind(DefaultLikeC4Views),
|
|
73
84
|
DeploymentsIndex: bind(DeploymentsIndex),
|
|
74
85
|
ModelChanges: bind(LikeC4ModelChanges),
|
|
75
86
|
FqnIndex: bind(FqnIndex),
|
|
76
87
|
ModelParser: bind(LikeC4ModelParser),
|
|
77
|
-
ModelBuilder: bind(
|
|
88
|
+
ModelBuilder: bind(DefaultLikeC4ModelBuilder),
|
|
78
89
|
ModelLocator: bind(LikeC4ModelLocator)
|
|
79
90
|
},
|
|
80
91
|
lsp: {
|
|
@@ -88,6 +99,9 @@ export const LikeC4Module = {
|
|
|
88
99
|
DocumentLinkProvider: bind(LikeC4DocumentLinkProvider),
|
|
89
100
|
Formatter: bind(LikeC4Formatter)
|
|
90
101
|
},
|
|
102
|
+
workspace: {
|
|
103
|
+
AstNodeDescriptionProvider: bind(AstNodeDescriptionProvider)
|
|
104
|
+
},
|
|
91
105
|
references: {
|
|
92
106
|
NameProvider: bind(LikeC4NameProvider),
|
|
93
107
|
ScopeComputation: bind(LikeC4ScopeComputation),
|
package/dist/protocol.d.ts
CHANGED
|
@@ -1,41 +1,79 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { ComputedLikeC4ModelData, ComputedView, DiagramView, Fqn, LayoutedLikeC4ModelData, NonEmptyArray, ProjectId, RelationId, ViewChange, ViewId } from '@likec4/core';
|
|
2
2
|
import { NotificationType, RequestType, RequestType0 } from 'vscode-jsonrpc';
|
|
3
3
|
import type { DiagnosticSeverity, DocumentUri, Location, Position } from 'vscode-languageserver-types';
|
|
4
|
-
export declare
|
|
5
|
-
|
|
4
|
+
export declare namespace DidChangeModelNotification {
|
|
5
|
+
const type: NotificationType<string>;
|
|
6
|
+
type Type = typeof type;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Request to fetch the computed model data
|
|
10
|
+
* If LSP has multiple projects, the projectId is required.
|
|
11
|
+
* otherwise throws an error.
|
|
12
|
+
*/
|
|
6
13
|
export declare namespace FetchComputedModel {
|
|
7
14
|
type Params = {
|
|
15
|
+
projectId?: string | undefined;
|
|
8
16
|
cleanCaches?: boolean | undefined;
|
|
9
17
|
};
|
|
10
18
|
type Res = {
|
|
11
|
-
model:
|
|
19
|
+
model: ComputedLikeC4ModelData | null;
|
|
12
20
|
};
|
|
13
|
-
const
|
|
14
|
-
type Req = typeof
|
|
21
|
+
const req: RequestType<Params, Res, void>;
|
|
22
|
+
type Req = typeof req;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Request to fetch all views of all projects
|
|
26
|
+
*/
|
|
27
|
+
export declare namespace FetchViewsFromAllProjects {
|
|
28
|
+
type Res = {
|
|
29
|
+
views: Array<{
|
|
30
|
+
id: ViewId;
|
|
31
|
+
title: string;
|
|
32
|
+
projectId: ProjectId;
|
|
33
|
+
}>;
|
|
34
|
+
};
|
|
35
|
+
const req: RequestType0<Res, void>;
|
|
36
|
+
type Req = typeof req;
|
|
15
37
|
}
|
|
38
|
+
/**
|
|
39
|
+
* Request to compute a view.
|
|
40
|
+
* If LSP has multiple projects, the projectId is required.
|
|
41
|
+
* otherwise throws an error.
|
|
42
|
+
*/
|
|
16
43
|
export declare namespace ComputeView {
|
|
17
44
|
type Params = {
|
|
18
45
|
viewId: ViewId;
|
|
46
|
+
projectId?: string;
|
|
19
47
|
};
|
|
20
48
|
type Result = {
|
|
21
49
|
view: ComputedView | null;
|
|
22
50
|
};
|
|
23
|
-
const
|
|
24
|
-
type Req = typeof
|
|
51
|
+
const req: RequestType<Params, Result, void>;
|
|
52
|
+
type Req = typeof req;
|
|
25
53
|
}
|
|
54
|
+
/**
|
|
55
|
+
* Request to fetch the layouted model data
|
|
56
|
+
* If LSP has multiple projects, the projectId is required.
|
|
57
|
+
* otherwise throws an error.
|
|
58
|
+
*/
|
|
26
59
|
export declare namespace FetchLayoutedModel {
|
|
60
|
+
type Params = {
|
|
61
|
+
projectId?: string | undefined;
|
|
62
|
+
};
|
|
27
63
|
type Res = {
|
|
28
|
-
model:
|
|
64
|
+
model: LayoutedLikeC4ModelData | null;
|
|
29
65
|
};
|
|
30
|
-
const
|
|
31
|
-
type Req = typeof
|
|
66
|
+
const req: RequestType<Params, Res, void>;
|
|
67
|
+
type Req = typeof req;
|
|
32
68
|
}
|
|
33
69
|
/**
|
|
34
70
|
* Request to layout a view.
|
|
71
|
+
* If LSP has multiple projects, the projectId is required.
|
|
35
72
|
*/
|
|
36
73
|
export declare namespace LayoutView {
|
|
37
74
|
type Params = {
|
|
38
75
|
viewId: ViewId;
|
|
76
|
+
projectId?: string | undefined;
|
|
39
77
|
};
|
|
40
78
|
type Res = {
|
|
41
79
|
result: {
|
|
@@ -43,14 +81,17 @@ export declare namespace LayoutView {
|
|
|
43
81
|
diagram: DiagramView;
|
|
44
82
|
} | null;
|
|
45
83
|
};
|
|
46
|
-
const
|
|
47
|
-
type Req = typeof
|
|
84
|
+
const req: RequestType<Params, Res, void>;
|
|
85
|
+
type Req = typeof req;
|
|
48
86
|
}
|
|
49
87
|
/**
|
|
50
|
-
* Request to
|
|
88
|
+
* Request to validate all views
|
|
89
|
+
* If projects ID is provided, it will validate only the views of that project.
|
|
51
90
|
*/
|
|
52
91
|
export declare namespace ValidateLayout {
|
|
53
|
-
type Params =
|
|
92
|
+
type Params = {
|
|
93
|
+
projectId?: string;
|
|
94
|
+
};
|
|
54
95
|
type Res = {
|
|
55
96
|
result: {
|
|
56
97
|
uri: string;
|
|
@@ -63,9 +104,22 @@ export declare namespace ValidateLayout {
|
|
|
63
104
|
};
|
|
64
105
|
}[] | null;
|
|
65
106
|
};
|
|
66
|
-
const Req:
|
|
107
|
+
const Req: RequestType<Params, Res, void>;
|
|
67
108
|
type Req = typeof Req;
|
|
68
109
|
}
|
|
110
|
+
/**
|
|
111
|
+
* Request to build documents.
|
|
112
|
+
*/
|
|
113
|
+
export declare namespace FetchProjects {
|
|
114
|
+
type Params = never;
|
|
115
|
+
type Res = {
|
|
116
|
+
projects: {
|
|
117
|
+
[projectId: ProjectId]: NonEmptyArray<DocumentUri>;
|
|
118
|
+
};
|
|
119
|
+
};
|
|
120
|
+
const req: RequestType0<Res, void>;
|
|
121
|
+
type Req = typeof req;
|
|
122
|
+
}
|
|
69
123
|
/**
|
|
70
124
|
* Request to build documents.
|
|
71
125
|
*/
|
|
@@ -78,29 +132,57 @@ export declare namespace BuildDocuments {
|
|
|
78
132
|
}
|
|
79
133
|
/**
|
|
80
134
|
* Request to locate an element, relation, deployment or view.
|
|
135
|
+
* If LSP has multiple projects, the projectId is required.
|
|
81
136
|
*/
|
|
82
137
|
export declare namespace Locate {
|
|
83
138
|
type Params = {
|
|
84
139
|
element: Fqn;
|
|
140
|
+
projectId?: string | undefined;
|
|
85
141
|
property?: string;
|
|
86
142
|
} | {
|
|
143
|
+
projectId?: string | undefined;
|
|
87
144
|
relation: RelationId;
|
|
88
145
|
} | {
|
|
89
146
|
deployment: Fqn;
|
|
147
|
+
projectId?: string | undefined;
|
|
90
148
|
property?: string;
|
|
91
149
|
} | {
|
|
92
150
|
view: ViewId;
|
|
151
|
+
projectId?: string | undefined;
|
|
93
152
|
};
|
|
94
153
|
type Res = Location | null;
|
|
95
154
|
const Req: RequestType<Params, Res, void>;
|
|
96
155
|
type Req = typeof Req;
|
|
97
156
|
}
|
|
157
|
+
/**
|
|
158
|
+
* Request to change the view
|
|
159
|
+
* If LSP has multiple projects, the projectId is required.
|
|
160
|
+
*/
|
|
98
161
|
export declare namespace ChangeView {
|
|
99
162
|
type Params = {
|
|
100
163
|
viewId: ViewId;
|
|
101
164
|
change: ViewChange;
|
|
165
|
+
projectId?: string | undefined;
|
|
102
166
|
};
|
|
103
167
|
type Res = Location | null;
|
|
104
168
|
const Req: RequestType<Params, Res, void>;
|
|
105
169
|
type Req = typeof Req;
|
|
106
170
|
}
|
|
171
|
+
/**
|
|
172
|
+
* Request to fetch telemetry metrics
|
|
173
|
+
*/
|
|
174
|
+
export declare namespace FetchTelemetryMetrics {
|
|
175
|
+
type Res = {
|
|
176
|
+
metrics: null | {
|
|
177
|
+
elementKinds: number;
|
|
178
|
+
relationshipKinds: number;
|
|
179
|
+
tags: number;
|
|
180
|
+
elements: number;
|
|
181
|
+
relationships: number;
|
|
182
|
+
views: number;
|
|
183
|
+
projects: number;
|
|
184
|
+
};
|
|
185
|
+
};
|
|
186
|
+
const req: RequestType0<Res, void>;
|
|
187
|
+
type Req = typeof req;
|
|
188
|
+
}
|
package/dist/protocol.js
CHANGED
|
@@ -1,25 +1,36 @@
|
|
|
1
1
|
import { NotificationType, RequestType, RequestType0 } from "vscode-jsonrpc";
|
|
2
|
-
export
|
|
2
|
+
export var DidChangeModelNotification;
|
|
3
|
+
((DidChangeModelNotification2) => {
|
|
4
|
+
DidChangeModelNotification2.type = new NotificationType("likec4/onDidChangeModel");
|
|
5
|
+
})(DidChangeModelNotification || (DidChangeModelNotification = {}));
|
|
3
6
|
export var FetchComputedModel;
|
|
4
7
|
((FetchComputedModel2) => {
|
|
5
|
-
FetchComputedModel2.
|
|
8
|
+
FetchComputedModel2.req = new RequestType("likec4/fetchComputedModel");
|
|
6
9
|
})(FetchComputedModel || (FetchComputedModel = {}));
|
|
10
|
+
export var FetchViewsFromAllProjects;
|
|
11
|
+
((FetchViewsFromAllProjects2) => {
|
|
12
|
+
FetchViewsFromAllProjects2.req = new RequestType0("likec4/fetchViewsFromAllProjects");
|
|
13
|
+
})(FetchViewsFromAllProjects || (FetchViewsFromAllProjects = {}));
|
|
7
14
|
export var ComputeView;
|
|
8
15
|
((ComputeView2) => {
|
|
9
|
-
ComputeView2.
|
|
16
|
+
ComputeView2.req = new RequestType("likec4/computeView");
|
|
10
17
|
})(ComputeView || (ComputeView = {}));
|
|
11
18
|
export var FetchLayoutedModel;
|
|
12
19
|
((FetchLayoutedModel2) => {
|
|
13
|
-
FetchLayoutedModel2.
|
|
20
|
+
FetchLayoutedModel2.req = new RequestType("likec4/fetchLayoutedModel");
|
|
14
21
|
})(FetchLayoutedModel || (FetchLayoutedModel = {}));
|
|
15
22
|
export var LayoutView;
|
|
16
23
|
((LayoutView2) => {
|
|
17
|
-
LayoutView2.
|
|
24
|
+
LayoutView2.req = new RequestType("likec4/layout-view");
|
|
18
25
|
})(LayoutView || (LayoutView = {}));
|
|
19
26
|
export var ValidateLayout;
|
|
20
27
|
((ValidateLayout2) => {
|
|
21
|
-
ValidateLayout2.Req = new
|
|
28
|
+
ValidateLayout2.Req = new RequestType("likec4/validate-layout");
|
|
22
29
|
})(ValidateLayout || (ValidateLayout = {}));
|
|
30
|
+
export var FetchProjects;
|
|
31
|
+
((FetchProjects2) => {
|
|
32
|
+
FetchProjects2.req = new RequestType0("likec4/fetch-projects");
|
|
33
|
+
})(FetchProjects || (FetchProjects = {}));
|
|
23
34
|
export var BuildDocuments;
|
|
24
35
|
((BuildDocuments2) => {
|
|
25
36
|
BuildDocuments2.Req = new RequestType("likec4/build");
|
|
@@ -32,3 +43,7 @@ export var ChangeView;
|
|
|
32
43
|
((ChangeView2) => {
|
|
33
44
|
ChangeView2.Req = new RequestType("likec4/change-view");
|
|
34
45
|
})(ChangeView || (ChangeView = {}));
|
|
46
|
+
export var FetchTelemetryMetrics;
|
|
47
|
+
((FetchTelemetryMetrics2) => {
|
|
48
|
+
FetchTelemetryMetrics2.req = new RequestType0("likec4/metrics");
|
|
49
|
+
})(FetchTelemetryMetrics || (FetchTelemetryMetrics = {}));
|
|
@@ -1,18 +1,23 @@
|
|
|
1
|
-
import { type
|
|
1
|
+
import { type ProjectId } from '@likec4/core';
|
|
2
|
+
import { type AstNodeDescription, type ReferenceInfo, type Scope, type Stream, DefaultScopeProvider } from 'langium';
|
|
2
3
|
import { ast } from '../ast';
|
|
4
|
+
import type { DeploymentsIndex, FqnIndex } from '../model';
|
|
3
5
|
import type { LikeC4Services } from '../module';
|
|
6
|
+
import type { IndexManager } from '../workspace';
|
|
4
7
|
export declare class LikeC4ScopeProvider extends DefaultScopeProvider {
|
|
5
|
-
|
|
6
|
-
|
|
8
|
+
protected deploymentsIndex: DeploymentsIndex;
|
|
9
|
+
protected fqnIndex: FqnIndex;
|
|
10
|
+
protected readonly indexManager: IndexManager;
|
|
7
11
|
constructor(services: LikeC4Services);
|
|
8
|
-
private uniqueDescedants;
|
|
9
12
|
getScope(context: ReferenceInfo): Scope;
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
protected
|
|
13
|
+
protected genUniqueDescedants(of: () => ast.Element | ast.DeploymentNode | undefined): Generator<Stream<import("../ast").AstNodeDescriptionWithFqn>, void, any>;
|
|
14
|
+
protected streamScopeElementRef(ref: ast.ElementRef): Stream<AstNodeDescription>;
|
|
15
|
+
protected streamScopeExtendElement({ element }: ast.ExtendElement): Stream<AstNodeDescription>;
|
|
16
|
+
protected streamScopeElementView({ viewOf, extends: ext }: ast.ElementView): Stream<AstNodeDescription>;
|
|
17
|
+
protected getScopeForStrictFqnRef(projectId: ProjectId, container: ast.StrictFqnRef, context: ReferenceInfo): any;
|
|
18
|
+
protected streamScopeExtendDeployment({ deploymentNode }: ast.ExtendDeployment): Stream<AstNodeDescription>;
|
|
19
|
+
protected streamForFqnRef(projectId: ProjectId, container: ast.FqnRef, context: ReferenceInfo): Stream<AstNodeDescription>;
|
|
20
|
+
protected genScopeForFqnRef(projectId: ProjectId, container: ast.FqnRef, context: ReferenceInfo): Generator<any, void, any>;
|
|
16
21
|
/**
|
|
17
22
|
* Computes the scope for a given reference context.
|
|
18
23
|
*
|
|
@@ -24,5 +29,13 @@ export declare class LikeC4ScopeProvider extends DefaultScopeProvider {
|
|
|
24
29
|
* It then iterates through the container hierarchy, collecting relevant scopes based on the reference type and container type.
|
|
25
30
|
* Finally, it combines the collected scopes with the global scope to produce the final scope.
|
|
26
31
|
*/
|
|
27
|
-
protected computeScope(context: ReferenceInfo, referenceType?: any): any
|
|
32
|
+
protected computeScope(projectId: ProjectId, context: ReferenceInfo, referenceType?: any): Generator<any, void, any>;
|
|
33
|
+
/**
|
|
34
|
+
* Create a global scope filtered for the given reference type.
|
|
35
|
+
*/
|
|
36
|
+
protected getProjectScope(projectId: ProjectId, referenceType: string, context: ReferenceInfo): Scope;
|
|
37
|
+
/**
|
|
38
|
+
* Create a global scope filtered for the given reference type.
|
|
39
|
+
*/
|
|
40
|
+
protected getGlobalScope(referenceType: string, context: ReferenceInfo): Scope;
|
|
28
41
|
}
|
|
@@ -12,64 +12,45 @@ import {
|
|
|
12
12
|
} from "langium";
|
|
13
13
|
import { ast } from "../ast.js";
|
|
14
14
|
import { logWarnError } from "../logger.js";
|
|
15
|
+
import { projectIdFrom } from "../utils/index.js";
|
|
15
16
|
import { elementRef, readStrictFqn } from "../utils/elementRef.js";
|
|
16
17
|
const { getDocument } = AstUtils;
|
|
17
18
|
export class LikeC4ScopeProvider extends DefaultScopeProvider {
|
|
18
19
|
deploymentsIndex;
|
|
19
20
|
fqnIndex;
|
|
21
|
+
indexManager;
|
|
20
22
|
constructor(services) {
|
|
21
23
|
super(services);
|
|
24
|
+
this.indexManager = services.shared.workspace.IndexManager;
|
|
22
25
|
this.fqnIndex = services.likec4.FqnIndex;
|
|
23
26
|
this.deploymentsIndex = services.likec4.DeploymentsIndex;
|
|
24
27
|
}
|
|
25
|
-
// we need lazy resolving here
|
|
26
|
-
uniqueDescedants(of) {
|
|
27
|
-
return new StreamImpl(
|
|
28
|
-
() => {
|
|
29
|
-
const element = of();
|
|
30
|
-
if (element && ast.isElement(element)) {
|
|
31
|
-
const fqn = this.fqnIndex.getFqn(element);
|
|
32
|
-
return this.fqnIndex.uniqueDescedants(fqn).iterator();
|
|
33
|
-
}
|
|
34
|
-
if (element && ast.isDeploymentNode(element)) {
|
|
35
|
-
const fqn = this.deploymentsIndex.getFqn(element);
|
|
36
|
-
return this.deploymentsIndex.uniqueDescedants(fqn).iterator();
|
|
37
|
-
}
|
|
38
|
-
return null;
|
|
39
|
-
},
|
|
40
|
-
(iterator) => {
|
|
41
|
-
if (iterator) {
|
|
42
|
-
return iterator.next();
|
|
43
|
-
}
|
|
44
|
-
return DONE_RESULT;
|
|
45
|
-
}
|
|
46
|
-
);
|
|
47
|
-
}
|
|
48
28
|
getScope(context) {
|
|
49
29
|
try {
|
|
30
|
+
const projectId = projectIdFrom(context.container);
|
|
50
31
|
const referenceType = this.reflection.getReferenceType(context);
|
|
51
32
|
try {
|
|
52
33
|
const container = context.container;
|
|
53
34
|
if (ast.isFqnRef(container)) {
|
|
54
|
-
return this.
|
|
35
|
+
return new StreamScope(this.streamForFqnRef(projectId, container, context));
|
|
55
36
|
}
|
|
56
37
|
if (ast.isStrictFqnRef(container)) {
|
|
57
|
-
return this.getScopeForStrictFqnRef(container, context);
|
|
38
|
+
return this.getScopeForStrictFqnRef(projectId, container, context);
|
|
58
39
|
}
|
|
59
40
|
if (referenceType !== ast.Element) {
|
|
60
|
-
return this.
|
|
41
|
+
return this.getProjectScope(projectId, referenceType, context);
|
|
61
42
|
}
|
|
62
43
|
if (ast.isStrictFqnElementRef(container) && context.property === "el") {
|
|
63
44
|
const parent = container.parent;
|
|
64
45
|
if (!parent) {
|
|
65
|
-
return this.
|
|
46
|
+
return this.getProjectScope(projectId, referenceType, context);
|
|
66
47
|
}
|
|
67
|
-
return new StreamScope(this.fqnIndex.directChildrenOf(readStrictFqn(parent)));
|
|
48
|
+
return new StreamScope(this.fqnIndex.directChildrenOf(projectId, readStrictFqn(parent)));
|
|
68
49
|
}
|
|
69
50
|
if (ast.isElementRef(container) && context.property === "el") {
|
|
70
51
|
const parent = container.parent;
|
|
71
52
|
if (parent) {
|
|
72
|
-
return new StreamScope(this.
|
|
53
|
+
return new StreamScope(this.streamScopeElementRef(parent));
|
|
73
54
|
}
|
|
74
55
|
if (context.reference.$refText === "this" || context.reference.$refText === "it") {
|
|
75
56
|
const closestElement = AstUtils.getContainerOfType(container, ast.isElement);
|
|
@@ -82,78 +63,93 @@ export class LikeC4ScopeProvider extends DefaultScopeProvider {
|
|
|
82
63
|
}
|
|
83
64
|
}
|
|
84
65
|
}
|
|
85
|
-
return this.computeScope(context);
|
|
66
|
+
return new StreamScope(stream(this.computeScope(projectId, context)));
|
|
86
67
|
} catch (e) {
|
|
87
68
|
logWarnError(e);
|
|
88
|
-
return this.
|
|
69
|
+
return this.getProjectScope(projectId, referenceType, context);
|
|
89
70
|
}
|
|
90
71
|
} catch (e) {
|
|
91
72
|
logWarnError(e);
|
|
92
73
|
return EMPTY_SCOPE;
|
|
93
74
|
}
|
|
94
75
|
}
|
|
95
|
-
|
|
96
|
-
|
|
76
|
+
// we need lazy resolving here
|
|
77
|
+
*genUniqueDescedants(of) {
|
|
78
|
+
const element = of();
|
|
79
|
+
if (!element) {
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
const projectId = projectIdFrom(element);
|
|
83
|
+
if (ast.isElement(element)) {
|
|
84
|
+
const fqn = this.fqnIndex.getFqn(element);
|
|
85
|
+
yield* this.fqnIndex.uniqueDescedants(projectId, fqn);
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
if (ast.isDeploymentNode(element)) {
|
|
89
|
+
const fqn = this.deploymentsIndex.getFqn(element);
|
|
90
|
+
yield* this.deploymentsIndex.uniqueDescedants(projectId, fqn);
|
|
91
|
+
}
|
|
97
92
|
}
|
|
98
|
-
|
|
99
|
-
return stream(
|
|
93
|
+
streamScopeElementRef(ref) {
|
|
94
|
+
return stream(this.genUniqueDescedants(() => ref.el.ref));
|
|
100
95
|
}
|
|
101
|
-
|
|
96
|
+
streamScopeExtendElement({ element }) {
|
|
97
|
+
return stream([element.el.$nodeDescription]).nonNullable().concat(this.genUniqueDescedants(() => elementRef(element)));
|
|
98
|
+
}
|
|
99
|
+
streamScopeElementView({ viewOf, extends: ext }) {
|
|
102
100
|
if (viewOf) {
|
|
103
|
-
return stream([viewOf.el.$nodeDescription]).nonNullable().concat(this.
|
|
101
|
+
return stream([viewOf.el.$nodeDescription]).nonNullable().concat(this.genUniqueDescedants(() => elementRef(viewOf)));
|
|
104
102
|
}
|
|
105
103
|
if (ext) {
|
|
106
104
|
return stream([ext]).flatMap((v) => {
|
|
107
105
|
const view = v.view.ref;
|
|
108
|
-
return view ? this.
|
|
106
|
+
return view ? this.streamScopeElementView(view) : EMPTY_STREAM;
|
|
109
107
|
});
|
|
110
108
|
}
|
|
111
109
|
return EMPTY_STREAM;
|
|
112
110
|
}
|
|
113
|
-
getScopeForStrictFqnRef(container, context) {
|
|
111
|
+
getScopeForStrictFqnRef(projectId, container, context) {
|
|
114
112
|
const parent = container.parent;
|
|
115
113
|
if (!parent) {
|
|
116
|
-
return this.
|
|
114
|
+
return this.getProjectScope(projectId, ast.DeploymentNode, context);
|
|
117
115
|
}
|
|
118
116
|
return new StreamScope(
|
|
119
|
-
this.deploymentsIndex.directChildrenOf(readStrictFqn(parent)).filter((desc) => this.reflection.isSubtype(desc.type, ast.DeploymentNode))
|
|
117
|
+
this.deploymentsIndex.directChildrenOf(projectId, readStrictFqn(parent)).filter((desc) => this.reflection.isSubtype(desc.type, ast.DeploymentNode))
|
|
120
118
|
);
|
|
121
119
|
}
|
|
122
|
-
|
|
123
|
-
return stream([deploymentNode.value.$nodeDescription]).nonNullable().concat(this.
|
|
120
|
+
streamScopeExtendDeployment({ deploymentNode }) {
|
|
121
|
+
return stream([deploymentNode.value.$nodeDescription]).nonNullable().concat(this.genUniqueDescedants(() => {
|
|
124
122
|
const target = deploymentNode.value.ref;
|
|
125
123
|
return target && ast.isDeploymentNode(target) ? target : void 0;
|
|
126
124
|
}));
|
|
127
125
|
}
|
|
128
|
-
|
|
126
|
+
streamForFqnRef(projectId, container, context) {
|
|
129
127
|
const parent = container.parent;
|
|
130
128
|
if (!parent) {
|
|
131
|
-
return this.
|
|
132
|
-
// First preference for deployment nodes
|
|
133
|
-
this.computeScope(context, ast.DeploymentNode).getAllElements(),
|
|
134
|
-
this.createScope(
|
|
135
|
-
// Second preference for deployed instances
|
|
136
|
-
this.computeScope(context, ast.DeployedInstance).getAllElements(),
|
|
137
|
-
// Third preference for elements if we are in deployment view
|
|
138
|
-
AstUtils.hasContainerOfType(container, ast.isDeploymentView) ? this.computeScope(context, ast.Element) : EMPTY_SCOPE
|
|
139
|
-
)
|
|
140
|
-
);
|
|
129
|
+
return stream(this.genScopeForFqnRef(projectId, container, context));
|
|
141
130
|
}
|
|
142
131
|
const parentRef = parent.value.ref;
|
|
143
132
|
if (!parentRef) {
|
|
144
|
-
return
|
|
133
|
+
return EMPTY_STREAM;
|
|
145
134
|
}
|
|
146
135
|
if (ast.isDeploymentNode(parentRef)) {
|
|
147
|
-
return
|
|
136
|
+
return stream(this.genUniqueDescedants(() => parentRef));
|
|
148
137
|
}
|
|
149
138
|
if (ast.isDeployedInstance(parentRef)) {
|
|
150
|
-
return
|
|
139
|
+
return stream(this.streamScopeElementRef(parentRef.element));
|
|
151
140
|
}
|
|
152
141
|
if (ast.isElement(parentRef)) {
|
|
153
|
-
return
|
|
142
|
+
return stream(this.genUniqueDescedants(() => parentRef));
|
|
154
143
|
}
|
|
155
144
|
return nonexhaustive(parentRef);
|
|
156
145
|
}
|
|
146
|
+
*genScopeForFqnRef(projectId, container, context) {
|
|
147
|
+
yield* this.computeScope(projectId, context, ast.DeploymentNode);
|
|
148
|
+
yield* this.computeScope(projectId, context, ast.DeployedInstance);
|
|
149
|
+
if (AstUtils.hasContainerOfType(container, ast.isDeploymentView)) {
|
|
150
|
+
yield* this.computeScope(projectId, context, ast.Element);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
157
153
|
/**
|
|
158
154
|
* Computes the scope for a given reference context.
|
|
159
155
|
*
|
|
@@ -165,35 +161,68 @@ export class LikeC4ScopeProvider extends DefaultScopeProvider {
|
|
|
165
161
|
* It then iterates through the container hierarchy, collecting relevant scopes based on the reference type and container type.
|
|
166
162
|
* Finally, it combines the collected scopes with the global scope to produce the final scope.
|
|
167
163
|
*/
|
|
168
|
-
computeScope(context, referenceType = this.reflection.getReferenceType(context)) {
|
|
164
|
+
*computeScope(projectId, context, referenceType = this.reflection.getReferenceType(context)) {
|
|
169
165
|
const isElementReference = this.reflection.isSubtype(referenceType, ast.Element);
|
|
170
166
|
const isDeploymentReference = this.reflection.isSubtype(referenceType, ast.DeploymentElement);
|
|
171
|
-
const scopes = [];
|
|
172
167
|
const doc = getDocument(context.container);
|
|
173
168
|
const precomputed = doc.precomputedScopes;
|
|
174
169
|
if (!precomputed) {
|
|
175
|
-
|
|
170
|
+
yield* this.getProjectScope(projectId, referenceType, context).getAllElements();
|
|
171
|
+
return;
|
|
176
172
|
}
|
|
177
173
|
const byReferenceType = (desc) => this.reflection.isSubtype(desc.type, referenceType);
|
|
178
174
|
let container = context.container;
|
|
179
175
|
while (container) {
|
|
180
176
|
const elements = precomputed.get(container).filter(byReferenceType);
|
|
181
177
|
if (elements.length > 0) {
|
|
182
|
-
|
|
178
|
+
yield* elements;
|
|
183
179
|
}
|
|
184
180
|
if (isDeploymentReference && ast.isExtendDeploymentBody(container)) {
|
|
185
|
-
|
|
181
|
+
yield* this.streamScopeExtendDeployment(container.$container);
|
|
186
182
|
}
|
|
187
183
|
if (isElementReference && ast.isExtendElementBody(container)) {
|
|
188
|
-
|
|
184
|
+
yield* this.streamScopeExtendElement(container.$container);
|
|
189
185
|
}
|
|
190
186
|
if (isElementReference && ast.isElementViewBody(container)) {
|
|
191
|
-
|
|
187
|
+
yield* this.streamScopeElementView(container.$container);
|
|
192
188
|
}
|
|
193
189
|
container = container.$container;
|
|
194
190
|
}
|
|
195
|
-
|
|
196
|
-
return this.createScope(elements, outerScope);
|
|
197
|
-
}, this.getGlobalScope(referenceType, context));
|
|
191
|
+
yield* this.getProjectScope(projectId, referenceType, context).getAllElements();
|
|
198
192
|
}
|
|
193
|
+
/**
|
|
194
|
+
* Create a global scope filtered for the given reference type.
|
|
195
|
+
*/
|
|
196
|
+
getProjectScope(projectId, referenceType, context) {
|
|
197
|
+
if (referenceType === ast.LibIcon) {
|
|
198
|
+
return super.getGlobalScope(referenceType, context);
|
|
199
|
+
}
|
|
200
|
+
return this.globalScopeCache.get(
|
|
201
|
+
`${projectId}::${referenceType}`,
|
|
202
|
+
() => new MapScope(this.indexManager.projectElements(projectId, referenceType))
|
|
203
|
+
);
|
|
204
|
+
}
|
|
205
|
+
/**
|
|
206
|
+
* Create a global scope filtered for the given reference type.
|
|
207
|
+
*/
|
|
208
|
+
getGlobalScope(referenceType, context) {
|
|
209
|
+
if (referenceType === ast.LibIcon) {
|
|
210
|
+
return super.getGlobalScope(referenceType, context);
|
|
211
|
+
}
|
|
212
|
+
const projectId = projectIdFrom(context.container);
|
|
213
|
+
return this.getProjectScope(projectId, referenceType, context);
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
function lazyStream(fn) {
|
|
217
|
+
return new StreamImpl(
|
|
218
|
+
() => {
|
|
219
|
+
return fn().iterator();
|
|
220
|
+
},
|
|
221
|
+
(iterator) => {
|
|
222
|
+
if (iterator) {
|
|
223
|
+
return iterator.next();
|
|
224
|
+
}
|
|
225
|
+
return DONE_RESULT;
|
|
226
|
+
}
|
|
227
|
+
);
|
|
199
228
|
}
|
package/dist/shared/index.d.ts
CHANGED
package/dist/shared/index.js
CHANGED