@domainlang/language 0.1.82 → 0.4.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/README.md +18 -18
- package/out/domain-lang-module.d.ts +2 -0
- package/out/domain-lang-module.js +11 -3
- package/out/domain-lang-module.js.map +1 -1
- package/out/generated/ast.d.ts +8 -19
- package/out/generated/ast.js +1 -10
- package/out/generated/ast.js.map +1 -1
- package/out/generated/grammar.d.ts +1 -1
- package/out/generated/grammar.js +28 -123
- package/out/generated/grammar.js.map +1 -1
- package/out/generated/module.d.ts +1 -1
- package/out/generated/module.js +1 -1
- package/out/index.d.ts +3 -0
- package/out/index.js +5 -0
- package/out/index.js.map +1 -1
- package/out/lsp/domain-lang-code-actions.d.ts +55 -0
- package/out/lsp/domain-lang-code-actions.js +143 -0
- package/out/lsp/domain-lang-code-actions.js.map +1 -0
- package/out/lsp/domain-lang-workspace-manager.d.ts +21 -0
- package/out/lsp/domain-lang-workspace-manager.js +93 -0
- package/out/lsp/domain-lang-workspace-manager.js.map +1 -0
- package/out/lsp/hover/domain-lang-hover.js +0 -4
- package/out/lsp/hover/domain-lang-hover.js.map +1 -1
- package/out/lsp/manifest-diagnostics.d.ts +82 -0
- package/out/lsp/manifest-diagnostics.js +230 -0
- package/out/lsp/manifest-diagnostics.js.map +1 -0
- package/out/sdk/index.d.ts +1 -1
- package/out/sdk/loader-node.d.ts +7 -3
- package/out/sdk/loader-node.js +24 -9
- package/out/sdk/loader-node.js.map +1 -1
- package/out/sdk/types.d.ts +0 -21
- package/out/services/dependency-analyzer.d.ts +3 -39
- package/out/services/dependency-analyzer.js +22 -47
- package/out/services/dependency-analyzer.js.map +1 -1
- package/out/services/dependency-resolver.d.ts +68 -45
- package/out/services/dependency-resolver.js +243 -43
- package/out/services/dependency-resolver.js.map +1 -1
- package/out/services/git-url-resolver.browser.d.ts +4 -12
- package/out/services/git-url-resolver.browser.js +5 -1
- package/out/services/git-url-resolver.browser.js.map +1 -1
- package/out/services/git-url-resolver.d.ts +22 -56
- package/out/services/git-url-resolver.js +70 -36
- package/out/services/git-url-resolver.js.map +1 -1
- package/out/services/governance-validator.d.ts +1 -37
- package/out/services/governance-validator.js +4 -10
- package/out/services/governance-validator.js.map +1 -1
- package/out/services/import-resolver.d.ts +65 -6
- package/out/services/import-resolver.js +223 -5
- package/out/services/import-resolver.js.map +1 -1
- package/out/services/performance-optimizer.d.ts +1 -1
- package/out/services/semver.d.ts +98 -0
- package/out/services/semver.js +195 -0
- package/out/services/semver.js.map +1 -0
- package/out/services/types.d.ts +340 -0
- package/out/services/types.js +46 -0
- package/out/services/types.js.map +1 -0
- package/out/services/workspace-manager.d.ts +57 -10
- package/out/services/workspace-manager.js +187 -21
- package/out/services/workspace-manager.js.map +1 -1
- package/out/syntaxes/domain-lang.monarch.js +1 -1
- package/out/syntaxes/domain-lang.monarch.js.map +1 -1
- package/out/utils/import-utils.d.ts +4 -12
- package/out/utils/import-utils.js +35 -135
- package/out/utils/import-utils.js.map +1 -1
- package/out/validation/constants.d.ts +103 -0
- package/out/validation/constants.js +141 -2
- package/out/validation/constants.js.map +1 -1
- package/out/validation/domain.js +46 -1
- package/out/validation/domain.js.map +1 -1
- package/out/validation/import.d.ts +46 -22
- package/out/validation/import.js +187 -85
- package/out/validation/import.js.map +1 -1
- package/out/validation/manifest.d.ts +144 -0
- package/out/validation/manifest.js +327 -0
- package/out/validation/manifest.js.map +1 -0
- package/out/validation/maps.js +10 -6
- package/out/validation/maps.js.map +1 -1
- package/out/validation/metadata.js +5 -1
- package/out/validation/metadata.js.map +1 -1
- package/package.json +8 -6
- package/src/domain-lang-module.ts +18 -6
- package/src/domain-lang.langium +7 -12
- package/src/generated/ast.ts +7 -20
- package/src/generated/grammar.ts +28 -123
- package/src/generated/module.ts +1 -1
- package/src/index.ts +7 -0
- package/src/lsp/domain-lang-code-actions.ts +189 -0
- package/src/lsp/domain-lang-workspace-manager.ts +104 -0
- package/src/lsp/hover/domain-lang-hover.ts +0 -2
- package/src/lsp/manifest-diagnostics.ts +290 -0
- package/src/sdk/index.ts +0 -2
- package/src/sdk/loader-node.ts +29 -9
- package/src/sdk/types.ts +0 -23
- package/src/services/dependency-analyzer.ts +24 -84
- package/src/services/dependency-resolver.ts +301 -84
- package/src/services/git-url-resolver.browser.ts +9 -14
- package/src/services/git-url-resolver.ts +86 -93
- package/src/services/governance-validator.ts +5 -47
- package/src/services/import-resolver.ts +270 -8
- package/src/services/performance-optimizer.ts +1 -1
- package/src/services/semver.ts +213 -0
- package/src/services/types.ts +415 -0
- package/src/services/workspace-manager.ts +237 -46
- package/src/syntaxes/domain-lang.monarch.ts +1 -1
- package/src/utils/import-utils.ts +38 -160
- package/src/validation/constants.ts +182 -2
- package/src/validation/domain.ts +54 -1
- package/src/validation/import.ts +228 -104
- package/src/validation/manifest.ts +439 -0
- package/src/validation/maps.ts +10 -6
- package/src/validation/metadata.ts +5 -1
package/src/generated/grammar.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/******************************************************************************
|
|
2
|
-
* This file was generated by langium-cli 4.
|
|
2
|
+
* This file was generated by langium-cli 4.2.0.
|
|
3
3
|
* DO NOT EDIT MANUALLY!
|
|
4
4
|
******************************************************************************/
|
|
5
5
|
|
|
@@ -2160,133 +2160,38 @@ export const DomainLangGrammar = (): Grammar => loadedDomainLangGrammar ?? (load
|
|
|
2160
2160
|
"$comment": "/** Imports types or namespaces from another file or module, enabling reuse and modularity. */"
|
|
2161
2161
|
},
|
|
2162
2162
|
{
|
|
2163
|
-
"$type": "
|
|
2163
|
+
"$type": "Assignment",
|
|
2164
|
+
"feature": "uri",
|
|
2165
|
+
"operator": "=",
|
|
2166
|
+
"terminal": {
|
|
2167
|
+
"$type": "RuleCall",
|
|
2168
|
+
"rule": {
|
|
2169
|
+
"$ref": "#/rules@28"
|
|
2170
|
+
},
|
|
2171
|
+
"arguments": []
|
|
2172
|
+
}
|
|
2173
|
+
},
|
|
2174
|
+
{
|
|
2175
|
+
"$type": "Group",
|
|
2164
2176
|
"elements": [
|
|
2165
2177
|
{
|
|
2166
|
-
"$type": "
|
|
2167
|
-
"
|
|
2168
|
-
{
|
|
2169
|
-
"$type": "Keyword",
|
|
2170
|
-
"value": "{"
|
|
2171
|
-
},
|
|
2172
|
-
{
|
|
2173
|
-
"$type": "Assignment",
|
|
2174
|
-
"feature": "symbols",
|
|
2175
|
-
"operator": "+=",
|
|
2176
|
-
"terminal": {
|
|
2177
|
-
"$type": "RuleCall",
|
|
2178
|
-
"rule": {
|
|
2179
|
-
"$ref": "#/rules@27"
|
|
2180
|
-
},
|
|
2181
|
-
"arguments": []
|
|
2182
|
-
}
|
|
2183
|
-
},
|
|
2184
|
-
{
|
|
2185
|
-
"$type": "Group",
|
|
2186
|
-
"elements": [
|
|
2187
|
-
{
|
|
2188
|
-
"$type": "Keyword",
|
|
2189
|
-
"value": ","
|
|
2190
|
-
},
|
|
2191
|
-
{
|
|
2192
|
-
"$type": "Assignment",
|
|
2193
|
-
"feature": "symbols",
|
|
2194
|
-
"operator": "+=",
|
|
2195
|
-
"terminal": {
|
|
2196
|
-
"$type": "RuleCall",
|
|
2197
|
-
"rule": {
|
|
2198
|
-
"$ref": "#/rules@27"
|
|
2199
|
-
},
|
|
2200
|
-
"arguments": []
|
|
2201
|
-
}
|
|
2202
|
-
}
|
|
2203
|
-
],
|
|
2204
|
-
"cardinality": "*"
|
|
2205
|
-
},
|
|
2206
|
-
{
|
|
2207
|
-
"$type": "Keyword",
|
|
2208
|
-
"value": "}"
|
|
2209
|
-
},
|
|
2210
|
-
{
|
|
2211
|
-
"$type": "Keyword",
|
|
2212
|
-
"value": "from"
|
|
2213
|
-
},
|
|
2214
|
-
{
|
|
2215
|
-
"$type": "Assignment",
|
|
2216
|
-
"feature": "uri",
|
|
2217
|
-
"operator": "=",
|
|
2218
|
-
"terminal": {
|
|
2219
|
-
"$type": "RuleCall",
|
|
2220
|
-
"rule": {
|
|
2221
|
-
"$ref": "#/rules@28"
|
|
2222
|
-
},
|
|
2223
|
-
"arguments": []
|
|
2224
|
-
}
|
|
2225
|
-
}
|
|
2226
|
-
]
|
|
2178
|
+
"$type": "Keyword",
|
|
2179
|
+
"value": "as"
|
|
2227
2180
|
},
|
|
2228
2181
|
{
|
|
2229
|
-
"$type": "
|
|
2230
|
-
"
|
|
2231
|
-
|
|
2232
|
-
|
|
2233
|
-
|
|
2234
|
-
|
|
2235
|
-
"
|
|
2236
|
-
"$type": "RuleCall",
|
|
2237
|
-
"rule": {
|
|
2238
|
-
"$ref": "#/rules@28"
|
|
2239
|
-
},
|
|
2240
|
-
"arguments": []
|
|
2241
|
-
}
|
|
2242
|
-
},
|
|
2243
|
-
{
|
|
2244
|
-
"$type": "Group",
|
|
2245
|
-
"elements": [
|
|
2246
|
-
{
|
|
2247
|
-
"$type": "Keyword",
|
|
2248
|
-
"value": "integrity"
|
|
2249
|
-
},
|
|
2250
|
-
{
|
|
2251
|
-
"$type": "Assignment",
|
|
2252
|
-
"feature": "integrity",
|
|
2253
|
-
"operator": "=",
|
|
2254
|
-
"terminal": {
|
|
2255
|
-
"$type": "RuleCall",
|
|
2256
|
-
"rule": {
|
|
2257
|
-
"$ref": "#/rules@28"
|
|
2258
|
-
},
|
|
2259
|
-
"arguments": []
|
|
2260
|
-
}
|
|
2261
|
-
}
|
|
2262
|
-
],
|
|
2263
|
-
"cardinality": "?"
|
|
2182
|
+
"$type": "Assignment",
|
|
2183
|
+
"feature": "alias",
|
|
2184
|
+
"operator": "=",
|
|
2185
|
+
"terminal": {
|
|
2186
|
+
"$type": "RuleCall",
|
|
2187
|
+
"rule": {
|
|
2188
|
+
"$ref": "#/rules@27"
|
|
2264
2189
|
},
|
|
2265
|
-
|
|
2266
|
-
|
|
2267
|
-
"elements": [
|
|
2268
|
-
{
|
|
2269
|
-
"$type": "Keyword",
|
|
2270
|
-
"value": "as"
|
|
2271
|
-
},
|
|
2272
|
-
{
|
|
2273
|
-
"$type": "Assignment",
|
|
2274
|
-
"feature": "alias",
|
|
2275
|
-
"operator": "=",
|
|
2276
|
-
"terminal": {
|
|
2277
|
-
"$type": "RuleCall",
|
|
2278
|
-
"rule": {
|
|
2279
|
-
"$ref": "#/rules@27"
|
|
2280
|
-
},
|
|
2281
|
-
"arguments": []
|
|
2282
|
-
}
|
|
2283
|
-
}
|
|
2284
|
-
],
|
|
2285
|
-
"cardinality": "?"
|
|
2286
|
-
}
|
|
2287
|
-
]
|
|
2190
|
+
"arguments": []
|
|
2191
|
+
}
|
|
2288
2192
|
}
|
|
2289
|
-
]
|
|
2193
|
+
],
|
|
2194
|
+
"cardinality": "?"
|
|
2290
2195
|
}
|
|
2291
2196
|
],
|
|
2292
2197
|
"$comment": "/** Imports types or namespaces from another file or module, enabling reuse and modularity. */"
|
|
@@ -2294,7 +2199,7 @@ export const DomainLangGrammar = (): Grammar => loadedDomainLangGrammar ?? (load
|
|
|
2294
2199
|
"entry": false,
|
|
2295
2200
|
"fragment": false,
|
|
2296
2201
|
"parameters": [],
|
|
2297
|
-
"$comment": "/**\\n * Import Statement -
|
|
2202
|
+
"$comment": "/**\\n * Import Statement - Manifest-centric import system per PRS-010.\\n * \\n * Simplified syntax where import statements use short specifiers:\\n * - External dependencies (from manifest): import \\"core\\" as Core\\n * - Local files: import \\"./shared/types.dlang\\"\\n * - Workspace-relative: import \\"~/contexts/sales.dlang\\"\\n * \\n * All resolution details (source, version, integrity) live in model.yaml manifest.\\n * Named imports and inline integrity checks have been removed per PRS-010.\\n */"
|
|
2298
2203
|
},
|
|
2299
2204
|
{
|
|
2300
2205
|
"$type": "ParserRule",
|
package/src/generated/module.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/******************************************************************************
|
|
2
|
-
* This file was generated by langium-cli 4.
|
|
2
|
+
* This file was generated by langium-cli 4.2.0.
|
|
3
3
|
* DO NOT EDIT MANUALLY!
|
|
4
4
|
******************************************************************************/
|
|
5
5
|
|
package/src/index.ts
CHANGED
|
@@ -6,6 +6,9 @@ export * from './generated/module.js';
|
|
|
6
6
|
// and creates a connection when imported, which breaks CLI/SDK standalone usage
|
|
7
7
|
export * from './ast-augmentation.js';
|
|
8
8
|
|
|
9
|
+
// Export centralized types (canonical source for all service types)
|
|
10
|
+
export * from './services/types.js';
|
|
11
|
+
|
|
9
12
|
// Export services
|
|
10
13
|
export * from './services/workspace-manager.js';
|
|
11
14
|
export * from './services/dependency-resolver.js';
|
|
@@ -15,3 +18,7 @@ export * from './services/import-resolver.js';
|
|
|
15
18
|
export * from './services/relationship-inference.js';
|
|
16
19
|
export * from './services/git-url-resolver.js';
|
|
17
20
|
export * from './services/performance-optimizer.js';
|
|
21
|
+
export * from './services/semver.js';
|
|
22
|
+
|
|
23
|
+
// Export LSP services
|
|
24
|
+
export * from './lsp/manifest-diagnostics.js';
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Code Action Provider for DomainLang.
|
|
3
|
+
*
|
|
4
|
+
* Provides quick-fix code actions for validation diagnostics.
|
|
5
|
+
*
|
|
6
|
+
* Key Features:
|
|
7
|
+
* - "Add dependency to model.yaml" for unknown import aliases
|
|
8
|
+
* - "Run dlang install" for uninstalled dependencies
|
|
9
|
+
*
|
|
10
|
+
* @module
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
import type { CodeAction, CodeActionParams, Command, Diagnostic } from 'vscode-languageserver';
|
|
14
|
+
import { CodeActionKind } from 'vscode-languageserver';
|
|
15
|
+
import type { MaybePromise, LangiumDocument } from 'langium';
|
|
16
|
+
import type { CodeActionProvider } from 'langium/lsp';
|
|
17
|
+
import { IssueCodes } from '../validation/constants.js';
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Shape of diagnostic data used for code action matching.
|
|
21
|
+
* Must match the data structure used in validators.
|
|
22
|
+
*/
|
|
23
|
+
interface ImportDiagnosticData {
|
|
24
|
+
code: string;
|
|
25
|
+
alias?: string;
|
|
26
|
+
specifier?: string;
|
|
27
|
+
path?: string;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Code action provider for DomainLang LSP features.
|
|
32
|
+
*
|
|
33
|
+
* Implements quick fixes for:
|
|
34
|
+
* - Import validation errors (add to model.yaml, run install)
|
|
35
|
+
*/
|
|
36
|
+
export class DomainLangCodeActionProvider implements CodeActionProvider {
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Generates code actions for the given diagnostics.
|
|
40
|
+
*
|
|
41
|
+
* @param document - The document containing the diagnostics
|
|
42
|
+
* @param params - Code action request parameters including diagnostics
|
|
43
|
+
* @returns Array of code actions, or undefined if none applicable
|
|
44
|
+
*/
|
|
45
|
+
getCodeActions(
|
|
46
|
+
document: LangiumDocument,
|
|
47
|
+
params: CodeActionParams
|
|
48
|
+
): MaybePromise<Array<Command | CodeAction> | undefined> {
|
|
49
|
+
const result: CodeAction[] = [];
|
|
50
|
+
const acceptor = (ca: CodeAction | undefined): void => {
|
|
51
|
+
if (ca) result.push(ca);
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
for (const diagnostic of params.context.diagnostics) {
|
|
55
|
+
this.createCodeActions(diagnostic, document, acceptor);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
return result.length > 0 ? result : undefined;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Creates code actions for a specific diagnostic.
|
|
63
|
+
*
|
|
64
|
+
* Matches on diagnostic.data.code to determine which quick fix to offer.
|
|
65
|
+
*/
|
|
66
|
+
private createCodeActions(
|
|
67
|
+
diagnostic: Diagnostic,
|
|
68
|
+
document: LangiumDocument,
|
|
69
|
+
accept: (ca: CodeAction | undefined) => void
|
|
70
|
+
): void {
|
|
71
|
+
const data = diagnostic.data as ImportDiagnosticData | undefined;
|
|
72
|
+
if (!data?.code) return;
|
|
73
|
+
|
|
74
|
+
switch (data.code) {
|
|
75
|
+
case IssueCodes.ImportNotInManifest:
|
|
76
|
+
if (data.alias) {
|
|
77
|
+
accept(this.createAddToManifestAction(diagnostic, document, data.alias));
|
|
78
|
+
}
|
|
79
|
+
break;
|
|
80
|
+
|
|
81
|
+
case IssueCodes.ImportRequiresManifest:
|
|
82
|
+
if (data.specifier) {
|
|
83
|
+
accept(this.createCreateManifestAction(diagnostic, document, data.specifier));
|
|
84
|
+
}
|
|
85
|
+
break;
|
|
86
|
+
|
|
87
|
+
case IssueCodes.ImportNotInstalled:
|
|
88
|
+
if (data.alias) {
|
|
89
|
+
accept(this.createRunInstallAction(diagnostic, data.alias));
|
|
90
|
+
}
|
|
91
|
+
break;
|
|
92
|
+
|
|
93
|
+
case IssueCodes.ImportMissingRef:
|
|
94
|
+
if (data.alias) {
|
|
95
|
+
accept(this.createAddRefAction(diagnostic, data.alias));
|
|
96
|
+
}
|
|
97
|
+
break;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Creates a code action to add a dependency to model.yaml.
|
|
103
|
+
*
|
|
104
|
+
* This generates a WorkspaceEdit that modifies model.yaml to add
|
|
105
|
+
* the missing dependency with a placeholder version.
|
|
106
|
+
*/
|
|
107
|
+
private createAddToManifestAction(
|
|
108
|
+
diagnostic: Diagnostic,
|
|
109
|
+
_document: LangiumDocument,
|
|
110
|
+
alias: string
|
|
111
|
+
): CodeAction {
|
|
112
|
+
// Create a command that will be executed to add the dependency
|
|
113
|
+
// Since we can't directly edit model.yaml from here (it's not the current document),
|
|
114
|
+
// we provide a command that the extension can handle
|
|
115
|
+
return {
|
|
116
|
+
title: `Add '${alias}' to model.yaml`,
|
|
117
|
+
kind: CodeActionKind.QuickFix,
|
|
118
|
+
diagnostics: [diagnostic],
|
|
119
|
+
isPreferred: true,
|
|
120
|
+
command: {
|
|
121
|
+
title: `Add '${alias}' to model.yaml`,
|
|
122
|
+
command: 'domainlang.addDependency',
|
|
123
|
+
arguments: [alias]
|
|
124
|
+
}
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* Creates a code action to create model.yaml with the dependency.
|
|
130
|
+
*/
|
|
131
|
+
private createCreateManifestAction(
|
|
132
|
+
diagnostic: Diagnostic,
|
|
133
|
+
_document: LangiumDocument,
|
|
134
|
+
specifier: string
|
|
135
|
+
): CodeAction {
|
|
136
|
+
const alias = specifier.split('/')[0];
|
|
137
|
+
return {
|
|
138
|
+
title: `Create model.yaml with '${alias}' dependency`,
|
|
139
|
+
kind: CodeActionKind.QuickFix,
|
|
140
|
+
diagnostics: [diagnostic],
|
|
141
|
+
isPreferred: true,
|
|
142
|
+
command: {
|
|
143
|
+
title: `Create model.yaml`,
|
|
144
|
+
command: 'domainlang.createManifest',
|
|
145
|
+
arguments: [alias, specifier]
|
|
146
|
+
}
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
/**
|
|
151
|
+
* Creates a code action to run dlang install.
|
|
152
|
+
*/
|
|
153
|
+
private createRunInstallAction(
|
|
154
|
+
diagnostic: Diagnostic,
|
|
155
|
+
alias: string
|
|
156
|
+
): CodeAction {
|
|
157
|
+
return {
|
|
158
|
+
title: `Run 'dlang install' to fetch '${alias}'`,
|
|
159
|
+
kind: CodeActionKind.QuickFix,
|
|
160
|
+
diagnostics: [diagnostic],
|
|
161
|
+
isPreferred: true,
|
|
162
|
+
command: {
|
|
163
|
+
title: 'Install dependencies',
|
|
164
|
+
command: 'domainlang.install',
|
|
165
|
+
arguments: []
|
|
166
|
+
}
|
|
167
|
+
};
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
/**
|
|
171
|
+
* Creates a code action to add ref to dependency.
|
|
172
|
+
*/
|
|
173
|
+
private createAddRefAction(
|
|
174
|
+
diagnostic: Diagnostic,
|
|
175
|
+
alias: string
|
|
176
|
+
): CodeAction {
|
|
177
|
+
return {
|
|
178
|
+
title: `Add git ref to '${alias}' in model.yaml`,
|
|
179
|
+
kind: CodeActionKind.QuickFix,
|
|
180
|
+
diagnostics: [diagnostic],
|
|
181
|
+
isPreferred: false,
|
|
182
|
+
command: {
|
|
183
|
+
title: 'Add ref',
|
|
184
|
+
command: 'domainlang.addRef',
|
|
185
|
+
arguments: [alias]
|
|
186
|
+
}
|
|
187
|
+
};
|
|
188
|
+
}
|
|
189
|
+
}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import path from 'node:path';
|
|
2
|
+
import YAML from 'yaml';
|
|
3
|
+
import { DefaultWorkspaceManager, URI, UriUtils, type FileSystemNode, type LangiumDocument, type LangiumSharedCoreServices, type WorkspaceFolder } from 'langium';
|
|
4
|
+
import type { CancellationToken } from 'vscode-languageserver-protocol';
|
|
5
|
+
import { ensureImportGraphFromDocument } from '../utils/import-utils.js';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Langium WorkspaceManager override implementing manifest-centric import loading per PRS-010.
|
|
9
|
+
*
|
|
10
|
+
* Behavior:
|
|
11
|
+
* - Skips pre-loading *.dlang during workspace scan (only entry graph is loaded when manifest exists).
|
|
12
|
+
* - Mode A (with manifest): find nearest model.yaml in folder, load entry (default index.dlang) and its import graph.
|
|
13
|
+
* - Mode B (no manifest): no pre-loading; imports resolved on-demand when a document is opened.
|
|
14
|
+
* - Never performs network fetches; relies on cached dependencies/lock files. Missing cache produces diagnostics upstream.
|
|
15
|
+
*/
|
|
16
|
+
export class DomainLangWorkspaceManager extends DefaultWorkspaceManager {
|
|
17
|
+
constructor(services: LangiumSharedCoreServices) {
|
|
18
|
+
super(services);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
override shouldIncludeEntry(entry: FileSystemNode): boolean {
|
|
22
|
+
// Prevent auto-including .dlang files; we'll load via entry/import graph
|
|
23
|
+
const name = UriUtils.basename(entry.uri);
|
|
24
|
+
if (name.toLowerCase().endsWith('.dlang')) {
|
|
25
|
+
return false;
|
|
26
|
+
}
|
|
27
|
+
return super.shouldIncludeEntry(entry);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
override async initializeWorkspace(folders: WorkspaceFolder[], cancelToken?: CancellationToken): Promise<void> {
|
|
31
|
+
await super.initializeWorkspace(folders, cancelToken);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
protected override async loadAdditionalDocuments(folders: WorkspaceFolder[], collector: (document: LangiumDocument) => void): Promise<void> {
|
|
35
|
+
const manifestInfo = await this.findManifestInFolders(folders);
|
|
36
|
+
if (!manifestInfo) {
|
|
37
|
+
return; // Mode B: no manifest
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
const entryUri = URI.file(manifestInfo.entryPath);
|
|
41
|
+
const entryDoc = await this.langiumDocuments.getOrCreateDocument(entryUri);
|
|
42
|
+
collector(entryDoc);
|
|
43
|
+
|
|
44
|
+
const uris = await ensureImportGraphFromDocument(entryDoc, this.langiumDocuments);
|
|
45
|
+
for (const uriString of uris) {
|
|
46
|
+
const uri = URI.parse(uriString);
|
|
47
|
+
const doc = await this.langiumDocuments.getOrCreateDocument(uri);
|
|
48
|
+
collector(doc);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
private async findManifestInFolders(folders: WorkspaceFolder[]): Promise<{ manifestPath: string; entryPath: string } | undefined> {
|
|
53
|
+
for (const folder of folders) {
|
|
54
|
+
const manifestPath = await this.findNearestManifest(folder.uri);
|
|
55
|
+
if (manifestPath) {
|
|
56
|
+
const entry = await this.readEntryFromManifest(manifestPath) ?? 'index.dlang';
|
|
57
|
+
const entryPath = path.resolve(path.dirname(manifestPath), entry);
|
|
58
|
+
return { manifestPath, entryPath };
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
return undefined;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
private async findNearestManifest(startUri: string): Promise<string | undefined> {
|
|
65
|
+
let current = path.resolve(URI.parse(startUri).fsPath);
|
|
66
|
+
const { root } = path.parse(current);
|
|
67
|
+
|
|
68
|
+
while (true) {
|
|
69
|
+
const candidate = path.join(current, 'model.yaml');
|
|
70
|
+
if (await this.pathExists(candidate)) {
|
|
71
|
+
return candidate;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
if (current === root) {
|
|
75
|
+
return undefined;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
const parent = path.dirname(current);
|
|
79
|
+
if (parent === current) {
|
|
80
|
+
return undefined;
|
|
81
|
+
}
|
|
82
|
+
current = parent;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
private async readEntryFromManifest(manifestPath: string): Promise<string | undefined> {
|
|
87
|
+
try {
|
|
88
|
+
const content = await this.fileSystemProvider.readFile(URI.file(manifestPath));
|
|
89
|
+
const manifest = (YAML.parse(content) ?? {}) as { model?: { entry?: string } };
|
|
90
|
+
return manifest.model?.entry;
|
|
91
|
+
} catch {
|
|
92
|
+
return undefined;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
private async pathExists(target: string): Promise<boolean> {
|
|
97
|
+
try {
|
|
98
|
+
await this.fileSystemProvider.stat(URI.file(target));
|
|
99
|
+
return true;
|
|
100
|
+
} catch {
|
|
101
|
+
return false;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
}
|
|
@@ -276,9 +276,7 @@ export class DomainLangHoverProvider extends AstNodeHoverProvider {
|
|
|
276
276
|
if (ast.isImportStatement && ast.isImportStatement(node)) {
|
|
277
277
|
const fields: string[] = [];
|
|
278
278
|
fields.push(`**URI:** \`${node.uri}\``);
|
|
279
|
-
if (node.symbols.length) fields.push(`**Imports:** ${node.symbols.map(s => `\`${s}\``).join(', ')}`);
|
|
280
279
|
if (node.alias) fields.push(`**Alias:** \`${node.alias}\``);
|
|
281
|
-
if (node.integrity) fields.push(`**Integrity:** \`${node.integrity}\``);
|
|
282
280
|
return (commentBlock ? `${commentBlock}\n\n---\n\n` : '') +
|
|
283
281
|
`📦 **\`(import)\`**\n\n` +
|
|
284
282
|
fields.join('\n\n');
|