@likec4/language-server 1.17.1 → 1.19.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/contrib/likec4.tmLanguage.json +1 -1
- package/dist/LikeC4FileSystem.d.ts +13 -0
- package/dist/LikeC4FileSystem.js +27 -0
- package/dist/Rpc.d.ts +9 -0
- package/dist/Rpc.js +126 -0
- package/dist/ast.d.ts +200 -0
- package/dist/ast.js +276 -0
- package/dist/browser.d.ts +6 -20
- package/dist/browser.js +13 -0
- package/dist/formatting/LikeC4Formatter.d.ts +27 -0
- package/dist/formatting/LikeC4Formatter.js +261 -0
- package/dist/formatting/utils.d.ts +6 -0
- package/dist/formatting/utils.js +15 -0
- package/dist/generated/ast.d.ts +1242 -0
- package/dist/generated/ast.js +1945 -0
- package/dist/generated/grammar.d.ts +6 -0
- package/dist/generated/grammar.js +3 -0
- package/dist/generated/module.d.ts +9 -0
- package/dist/generated/module.js +23 -0
- package/dist/generated-lib/icons.d.ts +1 -0
- package/dist/{likec4lib.mjs → generated-lib/icons.js} +1 -6
- package/dist/index.d.ts +8 -31
- package/dist/index.js +13 -0
- package/dist/like-c4.langium +845 -0
- package/dist/likec4lib.d.ts +4 -6
- package/dist/likec4lib.js +4 -0
- package/dist/logger.d.ts +7 -0
- package/dist/logger.js +73 -0
- package/dist/lsp/CodeLensProvider.d.ts +9 -0
- package/dist/lsp/CodeLensProvider.js +40 -0
- package/dist/lsp/CompletionProvider.d.ts +6 -0
- package/dist/lsp/CompletionProvider.js +135 -0
- package/dist/lsp/DocumentHighlightProvider.d.ts +9 -0
- package/dist/lsp/DocumentHighlightProvider.js +10 -0
- package/dist/lsp/DocumentLinkProvider.d.ts +11 -0
- package/dist/lsp/DocumentLinkProvider.js +49 -0
- package/dist/lsp/DocumentSymbolProvider.d.ts +23 -0
- package/dist/lsp/DocumentSymbolProvider.js +202 -0
- package/dist/lsp/HoverProvider.d.ts +10 -0
- package/dist/lsp/HoverProvider.js +69 -0
- package/dist/lsp/RenameProvider.d.ts +5 -0
- package/dist/lsp/RenameProvider.js +6 -0
- package/dist/lsp/SemanticTokenProvider.d.ts +7 -0
- package/dist/lsp/SemanticTokenProvider.js +297 -0
- package/dist/lsp/index.d.ts +7 -0
- package/dist/lsp/index.js +7 -0
- package/dist/model/deployments-index.d.ts +60 -0
- package/dist/model/deployments-index.js +181 -0
- package/dist/model/fqn-computation.d.ts +3 -0
- package/dist/model/fqn-computation.js +72 -0
- package/dist/model/fqn-index.d.ts +25 -0
- package/dist/model/fqn-index.js +96 -0
- package/dist/model/index.d.ts +6 -0
- package/dist/model/index.js +6 -0
- package/dist/model/model-builder.d.ts +32 -0
- package/dist/model/model-builder.js +598 -0
- package/dist/model/model-locator.d.ts +23 -0
- package/dist/model/model-locator.js +126 -0
- package/dist/model/model-parser-where.d.ts +3 -0
- package/dist/model/model-parser-where.js +70 -0
- package/dist/model/model-parser.d.ts +292 -0
- package/dist/model/model-parser.js +72 -0
- package/dist/model/parser/Base.d.ts +28 -0
- package/dist/model/parser/Base.js +87 -0
- package/dist/model/parser/DeploymentModelParser.d.ts +33 -0
- package/dist/model/parser/DeploymentModelParser.js +162 -0
- package/dist/model/parser/DeploymentViewParser.d.ts +38 -0
- package/dist/model/parser/DeploymentViewParser.js +98 -0
- package/dist/model/parser/FqnRefParser.d.ts +29 -0
- package/dist/model/parser/FqnRefParser.js +108 -0
- package/dist/model/parser/GlobalsParser.d.ts +66 -0
- package/dist/model/parser/GlobalsParser.js +80 -0
- package/dist/model/parser/ModelParser.d.ts +27 -0
- package/dist/model/parser/ModelParser.js +122 -0
- package/dist/model/parser/PredicatesParser.d.ts +34 -0
- package/dist/model/parser/PredicatesParser.js +272 -0
- package/dist/model/parser/SpecificationParser.d.ts +27 -0
- package/dist/model/parser/SpecificationParser.js +120 -0
- package/dist/model/parser/ViewsParser.d.ts +64 -0
- package/dist/model/parser/ViewsParser.js +377 -0
- package/dist/model-change/ModelChanges.d.ts +15 -0
- package/dist/model-change/ModelChanges.js +89 -0
- package/dist/model-change/changeElementStyle.d.ts +16 -0
- package/dist/model-change/changeElementStyle.js +136 -0
- package/dist/model-change/changeViewLayout.d.ts +12 -0
- package/dist/model-change/changeViewLayout.js +32 -0
- package/dist/model-change/saveManualLayout.d.ts +11 -0
- package/dist/model-change/saveManualLayout.js +27 -0
- package/dist/module.d.ts +62 -0
- package/dist/module.js +123 -0
- package/dist/protocol.d.ts +27 -27
- package/dist/protocol.js +14 -0
- package/dist/references/index.d.ts +3 -0
- package/dist/references/index.js +3 -0
- package/dist/references/name-provider.d.ts +9 -0
- package/dist/references/name-provider.js +33 -0
- package/dist/references/scope-computation.d.ts +20 -0
- package/dist/references/scope-computation.js +281 -0
- package/dist/references/scope-provider.d.ts +16 -0
- package/dist/references/scope-provider.js +165 -0
- package/dist/shared/NodeKindProvider.d.ts +15 -0
- package/dist/shared/NodeKindProvider.js +108 -0
- package/dist/shared/WorkspaceManager.d.ts +18 -0
- package/dist/shared/WorkspaceManager.js +36 -0
- package/dist/shared/WorkspaceSymbolProvider.d.ts +3 -0
- package/dist/shared/WorkspaceSymbolProvider.js +3 -0
- package/dist/shared/index.d.ts +3 -0
- package/dist/shared/index.js +3 -0
- package/dist/test/index.d.ts +1 -0
- package/dist/test/index.js +1 -0
- package/dist/test/setup.d.ts +1 -0
- package/dist/test/setup.js +7 -0
- package/dist/test/testServices.d.ts +22 -0
- package/dist/test/testServices.js +119 -0
- package/dist/utils/elementRef.d.ts +11 -0
- package/dist/utils/elementRef.js +15 -0
- package/dist/utils/fqnRef.d.ts +8 -0
- package/dist/utils/fqnRef.js +46 -0
- package/dist/utils/index.d.ts +1 -0
- package/dist/utils/index.js +1 -0
- package/dist/utils/printDocs.d.ts +2 -0
- package/dist/utils/printDocs.js +1 -0
- package/dist/utils/stringHash.d.ts +1 -0
- package/dist/utils/stringHash.js +5 -0
- package/dist/validation/_shared.d.ts +3 -0
- package/dist/validation/_shared.js +22 -0
- package/dist/validation/deployment-checks.d.ts +6 -0
- package/dist/validation/deployment-checks.js +114 -0
- package/dist/validation/dynamic-view-rule.d.ts +4 -0
- package/dist/validation/dynamic-view-rule.js +16 -0
- package/dist/validation/dynamic-view-step.d.ts +4 -0
- package/dist/validation/dynamic-view-step.js +33 -0
- package/dist/validation/element.d.ts +4 -0
- package/dist/validation/element.js +49 -0
- package/dist/validation/index.d.ts +15 -0
- package/dist/validation/index.js +152 -0
- package/dist/validation/property-checks.d.ts +6 -0
- package/dist/validation/property-checks.js +38 -0
- package/dist/validation/relation.d.ts +5 -0
- package/dist/validation/relation.js +56 -0
- package/dist/validation/specification.d.ts +11 -0
- package/dist/validation/specification.js +136 -0
- package/dist/validation/view-predicates/element-with.d.ts +4 -0
- package/dist/validation/view-predicates/element-with.js +30 -0
- package/dist/validation/view-predicates/expanded-element.d.ts +4 -0
- package/dist/validation/view-predicates/expanded-element.js +11 -0
- package/dist/validation/view-predicates/expression-v2.d.ts +5 -0
- package/dist/validation/view-predicates/expression-v2.js +83 -0
- package/dist/validation/view-predicates/incoming.d.ts +4 -0
- package/dist/validation/view-predicates/incoming.js +15 -0
- package/dist/validation/view-predicates/index.d.ts +6 -0
- package/dist/validation/view-predicates/index.js +6 -0
- package/dist/validation/view-predicates/outgoing.d.ts +4 -0
- package/dist/validation/view-predicates/outgoing.js +15 -0
- package/dist/validation/view-predicates/relation-with.d.ts +4 -0
- package/dist/validation/view-predicates/relation-with.js +12 -0
- package/dist/validation/view.d.ts +4 -0
- package/dist/validation/view.js +23 -0
- package/dist/view-utils/assignNavigateTo.d.ts +2 -0
- package/dist/view-utils/assignNavigateTo.js +25 -0
- package/dist/view-utils/index.d.ts +2 -0
- package/dist/view-utils/index.js +2 -0
- package/dist/view-utils/manual-layout.d.ts +7 -0
- package/dist/view-utils/manual-layout.js +99 -0
- package/dist/view-utils/resolve-relative-paths.d.ts +2 -0
- package/dist/view-utils/resolve-relative-paths.js +78 -0
- package/package.json +42 -73
- package/src/LikeC4FileSystem.ts +22 -21
- package/src/Rpc.ts +6 -3
- package/src/ast.ts +136 -172
- package/src/browser.ts +10 -11
- package/src/generated/ast.ts +656 -40
- package/src/generated/grammar.ts +1 -1
- package/src/index.ts +11 -8
- package/src/like-c4.langium +173 -22
- package/src/logger.ts +41 -57
- package/src/lsp/CodeLensProvider.ts +0 -1
- package/src/lsp/CompletionProvider.ts +20 -5
- package/src/lsp/DocumentSymbolProvider.ts +5 -2
- package/src/lsp/HoverProvider.ts +37 -3
- package/src/lsp/SemanticTokenProvider.ts +58 -32
- package/src/model/deployments-index.ts +222 -0
- package/src/model/fqn-computation.ts +1 -1
- package/src/model/fqn-index.ts +0 -1
- package/src/model/index.ts +1 -0
- package/src/model/model-builder.ts +176 -39
- package/src/model/model-locator.ts +36 -7
- package/src/model/model-parser.ts +69 -1119
- package/src/model/parser/Base.ts +107 -0
- package/src/model/parser/DeploymentModelParser.ts +192 -0
- package/src/model/parser/DeploymentViewParser.ts +116 -0
- package/src/model/parser/FqnRefParser.ts +118 -0
- package/src/model/parser/GlobalsParser.ts +96 -0
- package/src/model/parser/ModelParser.ts +141 -0
- package/src/model/parser/PredicatesParser.ts +291 -0
- package/src/model/parser/SpecificationParser.ts +133 -0
- package/src/model/parser/ViewsParser.ts +428 -0
- package/src/model-change/changeViewLayout.ts +2 -2
- package/src/module.ts +26 -21
- package/src/protocol.ts +10 -6
- package/src/references/index.ts +1 -0
- package/src/references/name-provider.ts +37 -0
- package/src/references/scope-computation.ts +130 -21
- package/src/references/scope-provider.ts +68 -35
- package/src/shared/NodeKindProvider.ts +15 -3
- package/src/{elementRef.ts → utils/elementRef.ts} +1 -1
- package/src/utils/fqnRef.ts +56 -0
- package/src/utils/stringHash.ts +2 -2
- package/src/validation/_shared.ts +6 -5
- package/src/validation/deployment-checks.ts +131 -0
- package/src/validation/dynamic-view-step.ts +1 -1
- package/src/validation/index.ts +104 -6
- package/src/validation/relation.ts +1 -1
- package/src/validation/view-predicates/expression-v2.ts +101 -0
- package/src/validation/view-predicates/index.ts +1 -0
- package/src/view-utils/assignNavigateTo.ts +6 -5
- package/src/view-utils/index.ts +0 -1
- package/src/view-utils/manual-layout.ts +25 -0
- package/dist/browser.cjs +0 -25
- package/dist/browser.d.cts +0 -23
- package/dist/browser.d.mts +0 -23
- package/dist/browser.mjs +0 -20
- package/dist/index.cjs +0 -53
- package/dist/index.d.cts +0 -34
- package/dist/index.d.mts +0 -34
- package/dist/index.mjs +0 -46
- package/dist/likec4lib.cjs +0 -1546
- package/dist/likec4lib.d.cts +0 -6
- package/dist/likec4lib.d.mts +0 -6
- package/dist/model-graph/index.cjs +0 -10
- package/dist/model-graph/index.d.cts +0 -81
- package/dist/model-graph/index.d.mts +0 -81
- package/dist/model-graph/index.d.ts +0 -81
- package/dist/model-graph/index.mjs +0 -1
- package/dist/protocol.cjs +0 -25
- package/dist/protocol.d.cts +0 -45
- package/dist/protocol.d.mts +0 -45
- package/dist/protocol.mjs +0 -17
- package/dist/shared/language-server.BIbAD1T-.mjs +0 -6292
- package/dist/shared/language-server.BQRvVmE0.d.cts +0 -1303
- package/dist/shared/language-server.BysPcTxr.d.ts +0 -1303
- package/dist/shared/language-server.D2QdbOJO.cjs +0 -1995
- package/dist/shared/language-server.DGrBGmsd.mjs +0 -1981
- package/dist/shared/language-server.DKV_FdPN.cjs +0 -6304
- package/dist/shared/language-server._wkyPgso.d.mts +0 -1303
- package/src/model-graph/LikeC4ModelGraph.ts +0 -338
- package/src/model-graph/compute-view/__test__/fixture.ts +0 -630
- package/src/model-graph/compute-view/compute.ts +0 -788
- package/src/model-graph/compute-view/index.ts +0 -33
- package/src/model-graph/compute-view/predicates.ts +0 -509
- package/src/model-graph/dynamic-view/__test__/fixture.ts +0 -61
- package/src/model-graph/dynamic-view/compute.ts +0 -313
- package/src/model-graph/dynamic-view/index.ts +0 -29
- package/src/model-graph/index.ts +0 -3
- package/src/model-graph/utils/applyCustomElementProperties.ts +0 -65
- package/src/model-graph/utils/applyCustomRelationProperties.ts +0 -41
- package/src/model-graph/utils/applyViewRuleStyles.ts +0 -49
- package/src/model-graph/utils/buildComputeNodes.ts +0 -113
- package/src/model-graph/utils/buildElementNotations.ts +0 -63
- package/src/model-graph/utils/elementExpressionToPredicate.ts +0 -39
- package/src/model-graph/utils/relationExpressionToPredicates.ts +0 -43
- package/src/model-graph/utils/sortNodes.ts +0 -105
- package/src/model-graph/utils/uniqueTags.test.ts +0 -42
- package/src/model-graph/utils/uniqueTags.ts +0 -19
- package/src/utils/graphlib.ts +0 -9
- package/src/view-utils/resolve-extended-views.ts +0 -66
- package/src/view-utils/resolve-global-rules.ts +0 -88
- package/src/view-utils/view-hash.ts +0 -27
|
@@ -0,0 +1,281 @@
|
|
|
1
|
+
import { nonexhaustive } from "@likec4/core";
|
|
2
|
+
import {
|
|
3
|
+
DefaultScopeComputation,
|
|
4
|
+
MultiMap
|
|
5
|
+
} from "langium";
|
|
6
|
+
import { entries, filter, flatMap, forEachObj, groupBy, isNullish, isTruthy, pipe } from "remeda";
|
|
7
|
+
import { ast } from "../ast.js";
|
|
8
|
+
import { logError, logWarnError } from "../logger.js";
|
|
9
|
+
function uniqueDescriptions(descs) {
|
|
10
|
+
return pipe(
|
|
11
|
+
descs,
|
|
12
|
+
groupBy((desc) => `${desc.type}.${desc.name}`),
|
|
13
|
+
entries(),
|
|
14
|
+
flatMap(([_, descs2]) => descs2.length === 1 ? descs2 : [])
|
|
15
|
+
);
|
|
16
|
+
}
|
|
17
|
+
export class LikeC4ScopeComputation extends DefaultScopeComputation {
|
|
18
|
+
constructor(services) {
|
|
19
|
+
super(services);
|
|
20
|
+
}
|
|
21
|
+
async computeExports(document, _cancelToken) {
|
|
22
|
+
const docExports = [];
|
|
23
|
+
try {
|
|
24
|
+
const { specifications, models, views, globals, likec4lib, deployments } = document.parseResult.value;
|
|
25
|
+
this.exportLibrary(likec4lib, docExports, document);
|
|
26
|
+
this.exportSpecification(specifications, docExports, document);
|
|
27
|
+
this.exportModel(models, docExports, document);
|
|
28
|
+
this.exportViews(views, docExports, document);
|
|
29
|
+
this.exportGlobals(globals, docExports, document);
|
|
30
|
+
this.exportDeployments(deployments, docExports, document);
|
|
31
|
+
} catch (e) {
|
|
32
|
+
logError(e);
|
|
33
|
+
}
|
|
34
|
+
return docExports;
|
|
35
|
+
}
|
|
36
|
+
exportViews(modelViews, docExports, document) {
|
|
37
|
+
const views = modelViews?.flatMap((m) => m.views);
|
|
38
|
+
if (isNullish(views) || views.length === 0) {
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
for (const viewAst of views) {
|
|
42
|
+
try {
|
|
43
|
+
if (isTruthy(viewAst.name)) {
|
|
44
|
+
docExports.push(this.descriptions.createDescription(viewAst, viewAst.name, document));
|
|
45
|
+
}
|
|
46
|
+
} catch (e) {
|
|
47
|
+
logError(e);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
exportGlobals(globals, docExports, document) {
|
|
52
|
+
if (isNullish(globals) || globals.length === 0) {
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
for (const globalPredicateAst of globals.flatMap((g) => g.predicates)) {
|
|
56
|
+
try {
|
|
57
|
+
const id = globalPredicateAst;
|
|
58
|
+
if (isTruthy(id.name)) {
|
|
59
|
+
docExports.push(this.descriptions.createDescription(id, id.name, document));
|
|
60
|
+
}
|
|
61
|
+
} catch (e) {
|
|
62
|
+
logError(e);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
for (const globalStyleAst of globals.flatMap((g) => g.styles)) {
|
|
66
|
+
try {
|
|
67
|
+
const id = globalStyleAst.id;
|
|
68
|
+
if (isTruthy(id.name)) {
|
|
69
|
+
docExports.push(this.descriptions.createDescription(id, id.name, document));
|
|
70
|
+
}
|
|
71
|
+
} catch (e) {
|
|
72
|
+
logError(e);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
exportModel(models, docExports, document) {
|
|
77
|
+
if (isNullish(models) || models.length === 0) {
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
for (const elAst of models.flatMap((m) => m.elements)) {
|
|
81
|
+
try {
|
|
82
|
+
if (ast.isElement(elAst) && isTruthy(elAst.name)) {
|
|
83
|
+
docExports.push(this.descriptions.createDescription(elAst, elAst.name, document));
|
|
84
|
+
}
|
|
85
|
+
} catch (e) {
|
|
86
|
+
logError(e);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
exportLibrary(likec4lib, docExports, document) {
|
|
91
|
+
if (isNullish(likec4lib)) {
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
try {
|
|
95
|
+
for (const iconAst of likec4lib.flatMap((l) => l.icons)) {
|
|
96
|
+
docExports.push(this.descriptions.createDescription(iconAst, iconAst.name, document));
|
|
97
|
+
}
|
|
98
|
+
} catch (e) {
|
|
99
|
+
logError(e);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
exportSpecification(specifications, docExports, document) {
|
|
103
|
+
if (isNullish(specifications) || specifications.length === 0) {
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
for (const spec of specifications.flatMap((s) => [
|
|
107
|
+
...s.elements,
|
|
108
|
+
...s.relationships,
|
|
109
|
+
...s.deploymentNodes,
|
|
110
|
+
...s.tags,
|
|
111
|
+
...s.colors
|
|
112
|
+
])) {
|
|
113
|
+
try {
|
|
114
|
+
switch (true) {
|
|
115
|
+
case ast.isSpecificationDeploymentNodeKind(spec):
|
|
116
|
+
case ast.isSpecificationElementKind(spec): {
|
|
117
|
+
if (isTruthy(spec.kind.name)) {
|
|
118
|
+
docExports.push(
|
|
119
|
+
this.descriptions.createDescription(spec.kind, spec.kind.name, document)
|
|
120
|
+
);
|
|
121
|
+
}
|
|
122
|
+
continue;
|
|
123
|
+
}
|
|
124
|
+
case ast.isSpecificationTag(spec): {
|
|
125
|
+
if (isTruthy(spec.tag.name)) {
|
|
126
|
+
docExports.push(
|
|
127
|
+
this.descriptions.createDescription(spec.tag, "#" + spec.tag.name, document)
|
|
128
|
+
);
|
|
129
|
+
}
|
|
130
|
+
continue;
|
|
131
|
+
}
|
|
132
|
+
case ast.isSpecificationRelationshipKind(spec): {
|
|
133
|
+
if (isTruthy(spec.kind.name)) {
|
|
134
|
+
docExports.push(
|
|
135
|
+
this.descriptions.createDescription(spec.kind, spec.kind.name, document),
|
|
136
|
+
this.descriptions.createDescription(spec.kind, "." + spec.kind.name, document)
|
|
137
|
+
);
|
|
138
|
+
}
|
|
139
|
+
continue;
|
|
140
|
+
}
|
|
141
|
+
case ast.isSpecificationColor(spec): {
|
|
142
|
+
if (isTruthy(spec.name.name)) {
|
|
143
|
+
docExports.push(
|
|
144
|
+
this.descriptions.createDescription(spec.name, spec.name.name, document)
|
|
145
|
+
);
|
|
146
|
+
}
|
|
147
|
+
continue;
|
|
148
|
+
}
|
|
149
|
+
// Thow error if not exhaustive
|
|
150
|
+
default:
|
|
151
|
+
nonexhaustive(spec);
|
|
152
|
+
}
|
|
153
|
+
} catch (e) {
|
|
154
|
+
logError(e);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
exportDeployments(modelDeployments, docExports, document) {
|
|
159
|
+
const nodes = modelDeployments?.flatMap((m) => m.elements);
|
|
160
|
+
if (isNullish(nodes) || nodes.length === 0) {
|
|
161
|
+
return;
|
|
162
|
+
}
|
|
163
|
+
for (const node of nodes) {
|
|
164
|
+
try {
|
|
165
|
+
if (ast.isDeploymentNode(node) && isTruthy(node.name)) {
|
|
166
|
+
docExports.push(this.descriptions.createDescription(node, node.name, document));
|
|
167
|
+
}
|
|
168
|
+
} catch (e) {
|
|
169
|
+
logWarnError(e);
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
computeLocalScopes(document, _cancelToken) {
|
|
174
|
+
return new Promise((resolve) => {
|
|
175
|
+
const root = document.parseResult.value;
|
|
176
|
+
const descendants = [];
|
|
177
|
+
const scopes = new MultiMap();
|
|
178
|
+
for (const model of root.models) {
|
|
179
|
+
try {
|
|
180
|
+
descendants.push(
|
|
181
|
+
...this.processContainer(model, scopes, document)
|
|
182
|
+
);
|
|
183
|
+
} catch (e) {
|
|
184
|
+
logError(e);
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
for (const deployment of root.deployments) {
|
|
188
|
+
try {
|
|
189
|
+
descendants.push(
|
|
190
|
+
...this.processDeployments(deployment, scopes, document)
|
|
191
|
+
);
|
|
192
|
+
} catch (e) {
|
|
193
|
+
logWarnError(e);
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
uniqueDescriptions(descendants).forEach((desc) => {
|
|
197
|
+
scopes.add(root, desc);
|
|
198
|
+
});
|
|
199
|
+
resolve(scopes);
|
|
200
|
+
});
|
|
201
|
+
}
|
|
202
|
+
processContainer(container, scopes, document) {
|
|
203
|
+
const localScope = new MultiMap();
|
|
204
|
+
const descedants = [];
|
|
205
|
+
for (const el of container.elements) {
|
|
206
|
+
if (ast.isRelation(el)) {
|
|
207
|
+
continue;
|
|
208
|
+
}
|
|
209
|
+
let subcontainer;
|
|
210
|
+
if (ast.isElement(el)) {
|
|
211
|
+
if (isTruthy(el.name)) {
|
|
212
|
+
localScope.add(el.name, this.descriptions.createDescription(el, el.name, document));
|
|
213
|
+
}
|
|
214
|
+
subcontainer = el.body;
|
|
215
|
+
} else if (ast.isExtendElement(el)) {
|
|
216
|
+
subcontainer = el.body;
|
|
217
|
+
}
|
|
218
|
+
if (subcontainer && subcontainer.elements.length > 0) {
|
|
219
|
+
try {
|
|
220
|
+
descedants.push(
|
|
221
|
+
...this.processContainer(subcontainer, scopes, document)
|
|
222
|
+
);
|
|
223
|
+
} catch (e) {
|
|
224
|
+
logWarnError(e);
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
if (descedants.length) {
|
|
229
|
+
pipe(
|
|
230
|
+
descedants,
|
|
231
|
+
filter((desc) => !localScope.has(desc.name)),
|
|
232
|
+
groupBy((desc) => desc.name),
|
|
233
|
+
forEachObj((descs, name) => {
|
|
234
|
+
if (descs.length === 1) {
|
|
235
|
+
localScope.add(name, descs[0]);
|
|
236
|
+
}
|
|
237
|
+
})
|
|
238
|
+
);
|
|
239
|
+
}
|
|
240
|
+
const local = [...localScope.values()];
|
|
241
|
+
scopes.addAll(container, local);
|
|
242
|
+
return local;
|
|
243
|
+
}
|
|
244
|
+
processDeployments(container, scopes, document) {
|
|
245
|
+
const localnames = /* @__PURE__ */ new Set();
|
|
246
|
+
const descedants = [];
|
|
247
|
+
for (const el of container.elements) {
|
|
248
|
+
if (ast.isDeploymentRelation(el)) {
|
|
249
|
+
continue;
|
|
250
|
+
}
|
|
251
|
+
let name = this.nameProvider.getName(el);
|
|
252
|
+
if (isTruthy(name)) {
|
|
253
|
+
const desc = this.descriptions.createDescription(el, name, document);
|
|
254
|
+
scopes.add(container, desc);
|
|
255
|
+
localnames.add(desc.name);
|
|
256
|
+
}
|
|
257
|
+
if (ast.isDeploymentNode(el) && el.body) {
|
|
258
|
+
try {
|
|
259
|
+
descedants.push(
|
|
260
|
+
...this.processDeployments(el.body, scopes, document)
|
|
261
|
+
);
|
|
262
|
+
} catch (e) {
|
|
263
|
+
logWarnError(e);
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
if (descedants.length > 0) {
|
|
268
|
+
pipe(
|
|
269
|
+
descedants,
|
|
270
|
+
filter((desc) => !localnames.has(desc.name)),
|
|
271
|
+
groupBy((desc) => desc.name),
|
|
272
|
+
forEachObj((descs, name) => {
|
|
273
|
+
if (descs.length === 1) {
|
|
274
|
+
scopes.add(container, descs[0]);
|
|
275
|
+
}
|
|
276
|
+
})
|
|
277
|
+
);
|
|
278
|
+
}
|
|
279
|
+
return [...scopes.get(container).values()];
|
|
280
|
+
}
|
|
281
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { DefaultScopeProvider, type ReferenceInfo, type Scope } from 'langium';
|
|
2
|
+
import { ast } from '../ast';
|
|
3
|
+
import type { LikeC4Services } from '../module';
|
|
4
|
+
export declare class LikeC4ScopeProvider extends DefaultScopeProvider {
|
|
5
|
+
private deploymentsIndex;
|
|
6
|
+
private fqnIndex;
|
|
7
|
+
constructor(services: LikeC4Services);
|
|
8
|
+
private directChildrenOf;
|
|
9
|
+
private uniqueDescedants;
|
|
10
|
+
private scopeElementRef;
|
|
11
|
+
private scopeExtendElement;
|
|
12
|
+
private scopeElementView;
|
|
13
|
+
getScope(context: ReferenceInfo): Scope;
|
|
14
|
+
protected getScopeForFqnRef(container: ast.FqnRef, context: ReferenceInfo): any;
|
|
15
|
+
protected computeScope(context: ReferenceInfo, referenceType?: any): any;
|
|
16
|
+
}
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
import { nonexhaustive } from "@likec4/core";
|
|
2
|
+
import {
|
|
3
|
+
AstUtils,
|
|
4
|
+
DefaultScopeProvider,
|
|
5
|
+
DONE_RESULT,
|
|
6
|
+
EMPTY_SCOPE,
|
|
7
|
+
EMPTY_STREAM,
|
|
8
|
+
MapScope,
|
|
9
|
+
stream,
|
|
10
|
+
StreamImpl,
|
|
11
|
+
StreamScope
|
|
12
|
+
} from "langium";
|
|
13
|
+
import { ast } from "../ast.js";
|
|
14
|
+
import { logger } from "../logger.js";
|
|
15
|
+
import { elementRef, getFqnElementRef } from "../utils/elementRef.js";
|
|
16
|
+
const { getDocument } = AstUtils;
|
|
17
|
+
export class LikeC4ScopeProvider extends DefaultScopeProvider {
|
|
18
|
+
deploymentsIndex;
|
|
19
|
+
fqnIndex;
|
|
20
|
+
constructor(services) {
|
|
21
|
+
super(services);
|
|
22
|
+
this.fqnIndex = services.likec4.FqnIndex;
|
|
23
|
+
this.deploymentsIndex = services.likec4.DeploymentsIndex;
|
|
24
|
+
}
|
|
25
|
+
directChildrenOf(parent) {
|
|
26
|
+
return this.fqnIndex.directChildrenOf(parent);
|
|
27
|
+
}
|
|
28
|
+
// we need lazy resolving here
|
|
29
|
+
uniqueDescedants(of) {
|
|
30
|
+
return new StreamImpl(
|
|
31
|
+
() => {
|
|
32
|
+
const element = of();
|
|
33
|
+
const fqn = element && this.fqnIndex.getFqn(element);
|
|
34
|
+
if (fqn) {
|
|
35
|
+
return this.fqnIndex.uniqueDescedants(fqn).iterator();
|
|
36
|
+
}
|
|
37
|
+
return null;
|
|
38
|
+
},
|
|
39
|
+
(iterator) => {
|
|
40
|
+
if (iterator) {
|
|
41
|
+
return iterator.next();
|
|
42
|
+
}
|
|
43
|
+
return DONE_RESULT;
|
|
44
|
+
}
|
|
45
|
+
);
|
|
46
|
+
}
|
|
47
|
+
scopeElementRef(ref) {
|
|
48
|
+
return this.uniqueDescedants(() => ref.el.ref);
|
|
49
|
+
}
|
|
50
|
+
scopeExtendElement({ element }) {
|
|
51
|
+
return stream([element.el.$nodeDescription]).nonNullable().concat(this.uniqueDescedants(() => elementRef(element)));
|
|
52
|
+
}
|
|
53
|
+
scopeElementView({ viewOf, extends: ext }) {
|
|
54
|
+
if (viewOf) {
|
|
55
|
+
return stream([viewOf.el.$nodeDescription]).nonNullable().concat(this.uniqueDescedants(() => elementRef(viewOf)));
|
|
56
|
+
}
|
|
57
|
+
if (ext) {
|
|
58
|
+
return stream([ext]).flatMap((v) => {
|
|
59
|
+
const view = v.view.ref;
|
|
60
|
+
return view ? this.scopeElementView(view) : EMPTY_STREAM;
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
return EMPTY_STREAM;
|
|
64
|
+
}
|
|
65
|
+
getScope(context) {
|
|
66
|
+
try {
|
|
67
|
+
const referenceType = this.reflection.getReferenceType(context);
|
|
68
|
+
try {
|
|
69
|
+
const container = context.container;
|
|
70
|
+
if (ast.isFqnRef(container)) {
|
|
71
|
+
return this.getScopeForFqnRef(container, context);
|
|
72
|
+
}
|
|
73
|
+
if (referenceType !== ast.Element) {
|
|
74
|
+
return this.getGlobalScope(referenceType, context);
|
|
75
|
+
}
|
|
76
|
+
if (ast.isFqnElementRef(container) && context.property === "el") {
|
|
77
|
+
const parent = container.parent;
|
|
78
|
+
if (!parent) {
|
|
79
|
+
return this.getGlobalScope(referenceType, context);
|
|
80
|
+
}
|
|
81
|
+
return new StreamScope(this.directChildrenOf(getFqnElementRef(parent)));
|
|
82
|
+
}
|
|
83
|
+
if (ast.isElementRef(container) && context.property === "el") {
|
|
84
|
+
const parent = container.parent;
|
|
85
|
+
if (parent) {
|
|
86
|
+
return new StreamScope(this.scopeElementRef(parent));
|
|
87
|
+
}
|
|
88
|
+
if (context.reference.$refText === "this" || context.reference.$refText === "it") {
|
|
89
|
+
const closestElement = AstUtils.getContainerOfType(container, ast.isElement);
|
|
90
|
+
if (closestElement) {
|
|
91
|
+
return new MapScope([
|
|
92
|
+
this.descriptions.createDescription(closestElement, context.reference.$refText)
|
|
93
|
+
]);
|
|
94
|
+
} else {
|
|
95
|
+
return EMPTY_SCOPE;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
return this.computeScope(context);
|
|
100
|
+
} catch (e) {
|
|
101
|
+
logger.warn(e);
|
|
102
|
+
return this.getGlobalScope(referenceType, context);
|
|
103
|
+
}
|
|
104
|
+
} catch (e) {
|
|
105
|
+
logger.warn(e);
|
|
106
|
+
return EMPTY_SCOPE;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
getScopeForFqnRef(container, context) {
|
|
110
|
+
const parent = container.parent;
|
|
111
|
+
if (!parent) {
|
|
112
|
+
return this.createScope(
|
|
113
|
+
// First preference for deployment nodes
|
|
114
|
+
this.computeScope(context, ast.DeploymentNode).getAllElements(),
|
|
115
|
+
this.createScope(
|
|
116
|
+
// Second preference for deployed instances
|
|
117
|
+
this.computeScope(context, ast.DeployedInstance).getAllElements(),
|
|
118
|
+
// Third preference for elements if we are in deployment view
|
|
119
|
+
AstUtils.hasContainerOfType(container, ast.isDeploymentView) ? this.computeScope(context, ast.Element) : EMPTY_SCOPE
|
|
120
|
+
)
|
|
121
|
+
);
|
|
122
|
+
}
|
|
123
|
+
const parentRef = parent.value.ref;
|
|
124
|
+
if (!parentRef) {
|
|
125
|
+
return EMPTY_SCOPE;
|
|
126
|
+
}
|
|
127
|
+
if (ast.isDeploymentNode(parentRef)) {
|
|
128
|
+
return new StreamScope(this.deploymentsIndex.nested(parentRef));
|
|
129
|
+
}
|
|
130
|
+
if (ast.isDeployedInstance(parentRef)) {
|
|
131
|
+
return new StreamScope(this.scopeElementRef(parentRef.element));
|
|
132
|
+
}
|
|
133
|
+
if (ast.isElement(parentRef)) {
|
|
134
|
+
return new StreamScope(this.uniqueDescedants(() => parentRef));
|
|
135
|
+
}
|
|
136
|
+
return nonexhaustive(parentRef);
|
|
137
|
+
}
|
|
138
|
+
computeScope(context, referenceType = this.reflection.getReferenceType(context)) {
|
|
139
|
+
const isElementReference = this.reflection.isSubtype(referenceType, ast.Element);
|
|
140
|
+
const scopes = [];
|
|
141
|
+
const doc = getDocument(context.container);
|
|
142
|
+
const precomputed = doc.precomputedScopes;
|
|
143
|
+
if (!precomputed) {
|
|
144
|
+
return this.getGlobalScope(referenceType, context);
|
|
145
|
+
}
|
|
146
|
+
const byReferenceType = (desc) => this.reflection.isSubtype(desc.type, referenceType);
|
|
147
|
+
let container = context.container;
|
|
148
|
+
while (container) {
|
|
149
|
+
const elements = precomputed.get(container).filter(byReferenceType);
|
|
150
|
+
if (elements.length > 0) {
|
|
151
|
+
scopes.push(stream(elements));
|
|
152
|
+
}
|
|
153
|
+
if (isElementReference && ast.isExtendElementBody(container)) {
|
|
154
|
+
scopes.push(this.scopeExtendElement(container.$container));
|
|
155
|
+
}
|
|
156
|
+
if (isElementReference && ast.isElementViewBody(container)) {
|
|
157
|
+
scopes.push(this.scopeElementView(container.$container));
|
|
158
|
+
}
|
|
159
|
+
container = container.$container;
|
|
160
|
+
}
|
|
161
|
+
return scopes.reduceRight((outerScope, elements) => {
|
|
162
|
+
return this.createScope(elements, outerScope);
|
|
163
|
+
}, this.getGlobalScope(referenceType, context));
|
|
164
|
+
}
|
|
165
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { type AstNode, type AstNodeDescription } from 'langium';
|
|
2
|
+
import type { LangiumSharedServices, NodeKindProvider as LspNodeKindProvider } from 'langium/lsp';
|
|
3
|
+
import { CompletionItemKind, SymbolKind } from 'vscode-languageserver-types';
|
|
4
|
+
export declare class NodeKindProvider implements LspNodeKindProvider {
|
|
5
|
+
private services;
|
|
6
|
+
constructor(services: LangiumSharedServices);
|
|
7
|
+
/**
|
|
8
|
+
* Returns a `SymbolKind` as used by `WorkspaceSymbolProvider` or `DocumentSymbolProvider`.
|
|
9
|
+
*/
|
|
10
|
+
getSymbolKind(node: AstNode | AstNodeDescription): SymbolKind;
|
|
11
|
+
/**
|
|
12
|
+
* Returns a `CompletionItemKind` as used by the `CompletionProvider`.
|
|
13
|
+
*/
|
|
14
|
+
getCompletionItemKind(node: AstNode | AstNodeDescription): CompletionItemKind;
|
|
15
|
+
}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import { isAstNode } from "langium";
|
|
2
|
+
import { CompletionItemKind, SymbolKind } from "vscode-languageserver-types";
|
|
3
|
+
import { ast } from "../ast.js";
|
|
4
|
+
export class NodeKindProvider {
|
|
5
|
+
constructor(services) {
|
|
6
|
+
this.services = services;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Returns a `SymbolKind` as used by `WorkspaceSymbolProvider` or `DocumentSymbolProvider`.
|
|
10
|
+
*/
|
|
11
|
+
// prettier-ignore
|
|
12
|
+
getSymbolKind(node) {
|
|
13
|
+
const nodeType = isAstNode(node) ? node.$type : node.type;
|
|
14
|
+
const hasType = (...types) => types.some((t) => this.services.AstReflection.isSubtype(nodeType, t));
|
|
15
|
+
switch (true) {
|
|
16
|
+
case hasType(
|
|
17
|
+
ast.Element,
|
|
18
|
+
ast.ExtendElement,
|
|
19
|
+
ast.DeploymentNode,
|
|
20
|
+
ast.DeployedInstance
|
|
21
|
+
):
|
|
22
|
+
return SymbolKind.Constructor;
|
|
23
|
+
case hasType(
|
|
24
|
+
ast.Model,
|
|
25
|
+
ast.ModelViews,
|
|
26
|
+
ast.ModelDeployments,
|
|
27
|
+
ast.Globals,
|
|
28
|
+
ast.SpecificationRule
|
|
29
|
+
):
|
|
30
|
+
return SymbolKind.Namespace;
|
|
31
|
+
case hasType(ast.LikeC4View):
|
|
32
|
+
return SymbolKind.Class;
|
|
33
|
+
case hasType(
|
|
34
|
+
ast.Tag,
|
|
35
|
+
ast.LibIcon,
|
|
36
|
+
ast.CustomColor,
|
|
37
|
+
ast.SpecificationTag
|
|
38
|
+
):
|
|
39
|
+
return SymbolKind.EnumMember;
|
|
40
|
+
case hasType(
|
|
41
|
+
ast.RelationshipKind,
|
|
42
|
+
ast.SpecificationRelationshipKind
|
|
43
|
+
):
|
|
44
|
+
return SymbolKind.Event;
|
|
45
|
+
case hasType(
|
|
46
|
+
ast.ElementKind,
|
|
47
|
+
ast.DeploymentNodeKind,
|
|
48
|
+
ast.SpecificationElementKind,
|
|
49
|
+
ast.SpecificationDeploymentNodeKind
|
|
50
|
+
):
|
|
51
|
+
return SymbolKind.TypeParameter;
|
|
52
|
+
}
|
|
53
|
+
return SymbolKind.Field;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Returns a `CompletionItemKind` as used by the `CompletionProvider`.
|
|
57
|
+
*/
|
|
58
|
+
getCompletionItemKind(node) {
|
|
59
|
+
const nodeType = isAstNode(node) ? node.$type : node.type;
|
|
60
|
+
const hasType = (...types) => types.some((t) => this.services.AstReflection.isSubtype(nodeType, t));
|
|
61
|
+
switch (true) {
|
|
62
|
+
case hasType(
|
|
63
|
+
ast.CustomColor
|
|
64
|
+
):
|
|
65
|
+
return CompletionItemKind.Color;
|
|
66
|
+
case hasType(
|
|
67
|
+
ast.Element,
|
|
68
|
+
ast.DeploymentNode,
|
|
69
|
+
ast.DeployedInstance,
|
|
70
|
+
ast.ExtendElement
|
|
71
|
+
):
|
|
72
|
+
return CompletionItemKind.Constructor;
|
|
73
|
+
case hasType(
|
|
74
|
+
ast.Model,
|
|
75
|
+
ast.ModelViews,
|
|
76
|
+
ast.ModelDeployments,
|
|
77
|
+
ast.Globals,
|
|
78
|
+
ast.SpecificationRule
|
|
79
|
+
):
|
|
80
|
+
return CompletionItemKind.Module;
|
|
81
|
+
case hasType(
|
|
82
|
+
ast.LikeC4View
|
|
83
|
+
):
|
|
84
|
+
return CompletionItemKind.Class;
|
|
85
|
+
case hasType(
|
|
86
|
+
ast.Tag,
|
|
87
|
+
ast.LibIcon,
|
|
88
|
+
ast.CustomColor,
|
|
89
|
+
ast.SpecificationTag
|
|
90
|
+
):
|
|
91
|
+
return CompletionItemKind.EnumMember;
|
|
92
|
+
case hasType(
|
|
93
|
+
ast.RelationshipKind,
|
|
94
|
+
ast.SpecificationRelationshipKind
|
|
95
|
+
):
|
|
96
|
+
return CompletionItemKind.Event;
|
|
97
|
+
case hasType(
|
|
98
|
+
ast.ElementKind,
|
|
99
|
+
ast.SpecificationElementKind,
|
|
100
|
+
ast.DeploymentNodeKind,
|
|
101
|
+
ast.SpecificationDeploymentNodeKind
|
|
102
|
+
):
|
|
103
|
+
return CompletionItemKind.TypeParameter;
|
|
104
|
+
default:
|
|
105
|
+
return CompletionItemKind.Reference;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { LangiumDocument } from 'langium';
|
|
2
|
+
import { DefaultWorkspaceManager } from 'langium';
|
|
3
|
+
import type { LangiumSharedServices } from 'langium/lsp';
|
|
4
|
+
import type { WorkspaceFolder } from 'vscode-languageserver';
|
|
5
|
+
import { URI } from 'vscode-uri';
|
|
6
|
+
export declare class LikeC4WorkspaceManager extends DefaultWorkspaceManager {
|
|
7
|
+
private documentFactory;
|
|
8
|
+
constructor(services: LangiumSharedServices);
|
|
9
|
+
/**
|
|
10
|
+
* Load all additional documents that shall be visible in the context of the given workspace
|
|
11
|
+
* folders and add them to the collector. This can be used to include built-in libraries of
|
|
12
|
+
* your language, which can be either loaded from provided files or constructed in memory.
|
|
13
|
+
*/
|
|
14
|
+
protected loadAdditionalDocuments(folders: WorkspaceFolder[], collector: (document: LangiumDocument) => void): Promise<void>;
|
|
15
|
+
workspace(): any;
|
|
16
|
+
get workspaceUri(): URI;
|
|
17
|
+
get workspaceURL(): URL;
|
|
18
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { hasAtLeast, invariant } from "@likec4/core";
|
|
2
|
+
import { DefaultWorkspaceManager } from "langium";
|
|
3
|
+
import { URI } from "vscode-uri";
|
|
4
|
+
import * as BuiltIn from "../likec4lib.js";
|
|
5
|
+
export class LikeC4WorkspaceManager extends DefaultWorkspaceManager {
|
|
6
|
+
documentFactory;
|
|
7
|
+
constructor(services) {
|
|
8
|
+
super(services);
|
|
9
|
+
this.documentFactory = services.workspace.LangiumDocumentFactory;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Load all additional documents that shall be visible in the context of the given workspace
|
|
13
|
+
* folders and add them to the collector. This can be used to include built-in libraries of
|
|
14
|
+
* your language, which can be either loaded from provided files or constructed in memory.
|
|
15
|
+
*/
|
|
16
|
+
async loadAdditionalDocuments(folders, collector) {
|
|
17
|
+
collector(this.documentFactory.fromString(BuiltIn.Content, URI.parse(BuiltIn.Uri)));
|
|
18
|
+
await super.loadAdditionalDocuments(folders, collector);
|
|
19
|
+
}
|
|
20
|
+
workspace() {
|
|
21
|
+
if (this.folders && hasAtLeast(this.folders, 1)) {
|
|
22
|
+
return this.folders[0];
|
|
23
|
+
}
|
|
24
|
+
return null;
|
|
25
|
+
}
|
|
26
|
+
get workspaceUri() {
|
|
27
|
+
const workspace = this.workspace();
|
|
28
|
+
invariant(workspace, "Workspace not initialized");
|
|
29
|
+
return URI.parse(workspace.uri);
|
|
30
|
+
}
|
|
31
|
+
get workspaceURL() {
|
|
32
|
+
const workspace = this.workspace();
|
|
33
|
+
invariant(workspace, "Workspace not initialized");
|
|
34
|
+
return new URL(workspace.uri);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './testServices';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./testServices.js";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|