@domainlang/language 0.6.0 → 0.8.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 +1 -1
- package/out/domain-lang-module.d.ts +2 -0
- package/out/domain-lang-module.js +23 -2
- package/out/domain-lang-module.js.map +1 -1
- package/out/lsp/domain-lang-completion.d.ts +142 -1
- package/out/lsp/domain-lang-completion.js +620 -22
- package/out/lsp/domain-lang-completion.js.map +1 -1
- package/out/lsp/domain-lang-document-symbol-provider.d.ts +79 -0
- package/out/lsp/domain-lang-document-symbol-provider.js +210 -0
- package/out/lsp/domain-lang-document-symbol-provider.js.map +1 -0
- package/out/lsp/domain-lang-index-manager.d.ts +98 -1
- package/out/lsp/domain-lang-index-manager.js +214 -7
- package/out/lsp/domain-lang-index-manager.js.map +1 -1
- package/out/lsp/domain-lang-node-kind-provider.d.ts +27 -0
- package/out/lsp/domain-lang-node-kind-provider.js +87 -0
- package/out/lsp/domain-lang-node-kind-provider.js.map +1 -0
- package/out/lsp/domain-lang-scope-provider.d.ts +100 -0
- package/out/lsp/domain-lang-scope-provider.js +170 -0
- package/out/lsp/domain-lang-scope-provider.js.map +1 -0
- package/out/lsp/domain-lang-workspace-manager.d.ts +46 -0
- package/out/lsp/domain-lang-workspace-manager.js +148 -4
- package/out/lsp/domain-lang-workspace-manager.js.map +1 -1
- package/out/lsp/hover/domain-lang-hover.d.ts +16 -6
- package/out/lsp/hover/domain-lang-hover.js +160 -134
- package/out/lsp/hover/domain-lang-hover.js.map +1 -1
- package/out/lsp/hover/hover-builders.d.ts +57 -0
- package/out/lsp/hover/hover-builders.js +171 -0
- package/out/lsp/hover/hover-builders.js.map +1 -0
- package/out/main.js +116 -20
- package/out/main.js.map +1 -1
- package/out/sdk/index.d.ts +2 -1
- package/out/sdk/index.js +1 -1
- package/out/sdk/index.js.map +1 -1
- package/out/sdk/loader-node.js +1 -1
- package/out/sdk/loader-node.js.map +1 -1
- package/out/sdk/loader.d.ts +55 -2
- package/out/sdk/loader.js +87 -28
- package/out/sdk/loader.js.map +1 -1
- package/out/sdk/query.js +14 -11
- package/out/sdk/query.js.map +1 -1
- package/out/services/import-resolver.d.ts +29 -6
- package/out/services/import-resolver.js +48 -9
- package/out/services/import-resolver.js.map +1 -1
- package/out/services/package-boundary-detector.d.ts +101 -0
- package/out/services/package-boundary-detector.js +211 -0
- package/out/services/package-boundary-detector.js.map +1 -0
- package/out/services/performance-optimizer.js +6 -2
- package/out/services/performance-optimizer.js.map +1 -1
- package/out/services/types.d.ts +24 -0
- package/out/services/types.js.map +1 -1
- package/out/services/workspace-manager.d.ts +73 -6
- package/out/services/workspace-manager.js +210 -57
- package/out/services/workspace-manager.js.map +1 -1
- package/out/utils/import-utils.d.ts +9 -6
- package/out/utils/import-utils.js +26 -15
- package/out/utils/import-utils.js.map +1 -1
- package/out/validation/constants.d.ts +20 -0
- package/out/validation/constants.js +39 -3
- package/out/validation/constants.js.map +1 -1
- package/out/validation/import.d.ts +22 -1
- package/out/validation/import.js +104 -16
- package/out/validation/import.js.map +1 -1
- package/out/validation/maps.js +101 -3
- package/out/validation/maps.js.map +1 -1
- package/package.json +5 -5
- package/src/domain-lang-module.ts +26 -3
- package/src/lsp/domain-lang-completion.ts +736 -27
- package/src/lsp/domain-lang-document-symbol-provider.ts +254 -0
- package/src/lsp/domain-lang-index-manager.ts +250 -7
- package/src/lsp/domain-lang-node-kind-provider.ts +119 -0
- package/src/lsp/domain-lang-scope-provider.ts +250 -0
- package/src/lsp/domain-lang-workspace-manager.ts +187 -4
- package/src/lsp/hover/domain-lang-hover.ts +189 -131
- package/src/lsp/hover/hover-builders.ts +208 -0
- package/src/main.ts +156 -23
- package/src/sdk/index.ts +2 -1
- package/src/sdk/loader-node.ts +2 -1
- package/src/sdk/loader.ts +125 -34
- package/src/sdk/query.ts +15 -11
- package/src/services/import-resolver.ts +60 -9
- package/src/services/package-boundary-detector.ts +238 -0
- package/src/services/performance-optimizer.ts +6 -2
- package/src/services/types.ts +25 -0
- package/src/services/workspace-manager.ts +259 -62
- package/src/utils/import-utils.ts +27 -15
- package/src/validation/constants.ts +47 -6
- package/src/validation/import.ts +124 -16
- package/src/validation/maps.ts +118 -4
|
@@ -30,6 +30,7 @@ export const IssueCodes = {
|
|
|
30
30
|
ImportMissingRef: 'import-missing-ref',
|
|
31
31
|
ImportAbsolutePath: 'import-absolute-path',
|
|
32
32
|
ImportEscapesWorkspace: 'import-escapes-workspace',
|
|
33
|
+
ImportUnresolved: 'import-unresolved',
|
|
33
34
|
// Domain Issues
|
|
34
35
|
DomainNoVision: 'domain-no-vision',
|
|
35
36
|
DomainCircularHierarchy: 'domain-circular-hierarchy',
|
|
@@ -46,7 +47,10 @@ export const IssueCodes = {
|
|
|
46
47
|
// Context/Domain Map Issues
|
|
47
48
|
ContextMapNoContexts: 'context-map-no-contexts',
|
|
48
49
|
ContextMapNoRelationships: 'context-map-no-relationships',
|
|
50
|
+
ContextMapDuplicateRelationship: 'context-map-duplicate-relationship',
|
|
49
51
|
DomainMapNoDomains: 'domain-map-no-domains',
|
|
52
|
+
// Reference Issues
|
|
53
|
+
UnresolvedReference: 'unresolved-reference',
|
|
50
54
|
// Metadata Issues
|
|
51
55
|
MetadataMissingName: 'metadata-missing-name',
|
|
52
56
|
// General Issues
|
|
@@ -62,7 +66,10 @@ const DOCS_BASE = `${REPO_BASE}/dsl/domain-lang/docs`;
|
|
|
62
66
|
* @param docPath - Relative path from docs/ folder
|
|
63
67
|
* @param anchor - Optional section anchor (without #)
|
|
64
68
|
*/
|
|
65
|
-
const buildDocLink = (docPath, anchor) =>
|
|
69
|
+
const buildDocLink = (docPath, anchor) => {
|
|
70
|
+
const anchorPart = anchor ? `#${anchor}` : '';
|
|
71
|
+
return `${DOCS_BASE}/${docPath}${anchorPart}`;
|
|
72
|
+
};
|
|
66
73
|
/**
|
|
67
74
|
* Creates a CodeDescription for clickable documentation links in VS Code.
|
|
68
75
|
* @param docPath - Relative path from docs/ folder
|
|
@@ -102,7 +109,11 @@ export const ValidationMessages = {
|
|
|
102
109
|
* @param inlineClassification - The inline classification name (from 'as')
|
|
103
110
|
* @param blockClassification - The block classification name (from 'classification:')
|
|
104
111
|
*/
|
|
105
|
-
BOUNDED_CONTEXT_CLASSIFICATION_CONFLICT: (bcName, inlineClassification, blockClassification) =>
|
|
112
|
+
BOUNDED_CONTEXT_CLASSIFICATION_CONFLICT: (bcName, inlineClassification, blockClassification) => {
|
|
113
|
+
const inlinePart = inlineClassification ? ` ('as ${inlineClassification}')` : '';
|
|
114
|
+
const blockPart = blockClassification ? ` ('classification: ${blockClassification}')` : '';
|
|
115
|
+
return `Classification specified both inline${inlinePart} and in block${blockPart}. Inline value takes precedence.`;
|
|
116
|
+
},
|
|
106
117
|
/**
|
|
107
118
|
* Warning when team is specified both inline and in a block.
|
|
108
119
|
* Inline value takes precedence.
|
|
@@ -110,7 +121,11 @@ export const ValidationMessages = {
|
|
|
110
121
|
* @param inlineTeam - The inline team name (from 'by')
|
|
111
122
|
* @param blockTeam - The block team name (from 'team:')
|
|
112
123
|
*/
|
|
113
|
-
BOUNDED_CONTEXT_TEAM_CONFLICT: (bcName, inlineTeam, blockTeam) =>
|
|
124
|
+
BOUNDED_CONTEXT_TEAM_CONFLICT: (bcName, inlineTeam, blockTeam) => {
|
|
125
|
+
const inlinePart = inlineTeam ? ` ('by ${inlineTeam}')` : '';
|
|
126
|
+
const blockPart = blockTeam ? ` ('team: ${blockTeam}')` : '';
|
|
127
|
+
return `Team specified both inline${inlinePart} and in block${blockPart}. Inline value takes precedence.`;
|
|
128
|
+
},
|
|
114
129
|
/**
|
|
115
130
|
* Error message when an element is defined multiple times.
|
|
116
131
|
* @param fqn - The fully qualified name of the duplicate element
|
|
@@ -201,6 +216,12 @@ export const ValidationMessages = {
|
|
|
201
216
|
*/
|
|
202
217
|
IMPORT_ESCAPES_WORKSPACE: (alias) => `Local path dependency '${alias}' escapes workspace boundary.\n` +
|
|
203
218
|
`Hint: Local dependencies must be within the workspace. Consider moving the dependency or using a git-based source.`,
|
|
219
|
+
/**
|
|
220
|
+
* Error when import path cannot be resolved to a file.
|
|
221
|
+
* @param uri - The import URI that couldn't be resolved
|
|
222
|
+
*/
|
|
223
|
+
IMPORT_UNRESOLVED: (uri) => `Cannot resolve import '${uri}'.\n` +
|
|
224
|
+
`Hint: Check that the file exists and the path is correct.`,
|
|
204
225
|
// ========================================================================
|
|
205
226
|
// Context Map & Domain Map Validation
|
|
206
227
|
// ========================================================================
|
|
@@ -217,6 +238,12 @@ export const ValidationMessages = {
|
|
|
217
238
|
*/
|
|
218
239
|
CONTEXT_MAP_NO_RELATIONSHIPS: (name, count) => `Context Map '${name}' contains ${count} contexts but no documented relationships.\n` +
|
|
219
240
|
`Hint: Add relationships to show how contexts integrate (e.g., '[OHS] A -> [CF] B').`,
|
|
241
|
+
/**
|
|
242
|
+
* Warning when a context map contains duplicate relationships.
|
|
243
|
+
* @param leftContext - Name of the left context
|
|
244
|
+
* @param rightContext - Name of the right context
|
|
245
|
+
*/
|
|
246
|
+
CONTEXT_MAP_DUPLICATE_RELATIONSHIP: (leftContext, rightContext) => `Duplicate relationship between '${leftContext}' and '${rightContext}' in context map.`,
|
|
220
247
|
/**
|
|
221
248
|
* Warning when domain map contains no domains.
|
|
222
249
|
* @param name - The domain map name
|
|
@@ -224,6 +251,15 @@ export const ValidationMessages = {
|
|
|
224
251
|
DOMAIN_MAP_NO_DOMAINS: (name) => `Domain Map '${name}' contains no domains.\n` +
|
|
225
252
|
`Hint: Use 'contains DomainA, DomainB' to specify which domains are in the map.`,
|
|
226
253
|
// ========================================================================
|
|
254
|
+
// Reference Resolution Validation
|
|
255
|
+
// ========================================================================
|
|
256
|
+
/**
|
|
257
|
+
* Error when a reference cannot be resolved (for MultiReferences).
|
|
258
|
+
* @param type - The type being referenced (e.g., 'BoundedContext')
|
|
259
|
+
* @param name - The unresolved name
|
|
260
|
+
*/
|
|
261
|
+
UNRESOLVED_REFERENCE: (type, name) => `Could not resolve reference to ${type} named '${name}'.`,
|
|
262
|
+
// ========================================================================
|
|
227
263
|
// Metadata Validation
|
|
228
264
|
// ========================================================================
|
|
229
265
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../../src/validation/constants.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAIH,+EAA+E;AAC/E,+BAA+B;AAC/B,+EAA+E;AAE/E;;;;;GAKG;AACH,MAAM,CAAC,MAAM,UAAU,GAAG;IACtB,6BAA6B;IAC7B,gBAAgB,EAAE,oBAAoB;IACtC,sBAAsB,EAAE,0BAA0B;IAClD,mBAAmB,EAAE,wBAAwB;IAC7C,kBAAkB,EAAE,sBAAsB;IAC1C,2BAA2B,EAAE,gCAAgC;IAC7D,yBAAyB,EAAE,+BAA+B;IAC1D,gBAAgB,EAAE,oBAAoB;IACtC,kBAAkB,EAAE,sBAAsB;IAC1C,sBAAsB,EAAE,0BAA0B;
|
|
1
|
+
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../../src/validation/constants.ts"],"names":[],"mappings":"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"}
|
|
@@ -9,12 +9,14 @@ import type { DomainLangServices } from '../domain-lang-module.js';
|
|
|
9
9
|
* the shared WorkspaceManager service with its cached manifest/lock file reading.
|
|
10
10
|
*
|
|
11
11
|
* Checks:
|
|
12
|
+
* - All import URIs resolve to existing files
|
|
12
13
|
* - External imports require manifest + alias
|
|
13
14
|
* - Local path dependencies stay inside workspace
|
|
14
15
|
* - Lock file exists for external dependencies
|
|
15
16
|
*/
|
|
16
17
|
export declare class ImportValidator {
|
|
17
18
|
private readonly workspaceManager;
|
|
19
|
+
private readonly importResolver;
|
|
18
20
|
constructor(services: DomainLangServices);
|
|
19
21
|
/**
|
|
20
22
|
* Validates an import statement asynchronously.
|
|
@@ -33,7 +35,26 @@ export declare class ImportValidator {
|
|
|
33
35
|
*/
|
|
34
36
|
private isExternalImport;
|
|
35
37
|
/**
|
|
36
|
-
*
|
|
38
|
+
* Validates that an import URI resolves to an existing file.
|
|
39
|
+
* Returns true if there was an error (import doesn't resolve).
|
|
40
|
+
*/
|
|
41
|
+
private validateImportResolves;
|
|
42
|
+
/**
|
|
43
|
+
* Checks if a file exists (async).
|
|
44
|
+
*/
|
|
45
|
+
private fileExists;
|
|
46
|
+
/**
|
|
47
|
+
* Finds the dependency configuration that matches the import specifier.
|
|
48
|
+
*
|
|
49
|
+
* Dependencies can be keyed as:
|
|
50
|
+
* - owner/package (recommended, matches "owner/package" or "owner/package/subpath")
|
|
51
|
+
* - short-alias (matches "short-alias" or "short-alias/subpath")
|
|
52
|
+
*
|
|
53
|
+
* @returns The matching key and normalized dependency, or undefined if not found
|
|
54
|
+
*/
|
|
55
|
+
private findDependency;
|
|
56
|
+
/**
|
|
57
|
+
* Gets the normalized dependency configuration for a key.
|
|
37
58
|
*/
|
|
38
59
|
private getDependency;
|
|
39
60
|
/**
|
package/out/validation/import.js
CHANGED
|
@@ -8,6 +8,7 @@ import { ValidationMessages, buildCodeDescription, IssueCodes } from './constant
|
|
|
8
8
|
* the shared WorkspaceManager service with its cached manifest/lock file reading.
|
|
9
9
|
*
|
|
10
10
|
* Checks:
|
|
11
|
+
* - All import URIs resolve to existing files
|
|
11
12
|
* - External imports require manifest + alias
|
|
12
13
|
* - Local path dependencies stay inside workspace
|
|
13
14
|
* - Lock file exists for external dependencies
|
|
@@ -15,6 +16,7 @@ import { ValidationMessages, buildCodeDescription, IssueCodes } from './constant
|
|
|
15
16
|
export class ImportValidator {
|
|
16
17
|
constructor(services) {
|
|
17
18
|
this.workspaceManager = services.imports.WorkspaceManager;
|
|
19
|
+
this.importResolver = services.imports.ImportResolver;
|
|
18
20
|
}
|
|
19
21
|
/**
|
|
20
22
|
* Validates an import statement asynchronously.
|
|
@@ -32,6 +34,12 @@ export class ImportValidator {
|
|
|
32
34
|
});
|
|
33
35
|
return;
|
|
34
36
|
}
|
|
37
|
+
// First, verify the import resolves to a valid file
|
|
38
|
+
// This catches renamed/moved/deleted files immediately
|
|
39
|
+
const resolveError = await this.validateImportResolves(imp, document, accept);
|
|
40
|
+
if (resolveError) {
|
|
41
|
+
return; // Don't continue with other validations if can't resolve
|
|
42
|
+
}
|
|
35
43
|
if (!this.isExternalImport(imp.uri)) {
|
|
36
44
|
return;
|
|
37
45
|
}
|
|
@@ -48,31 +56,32 @@ export class ImportValidator {
|
|
|
48
56
|
});
|
|
49
57
|
return;
|
|
50
58
|
}
|
|
51
|
-
|
|
52
|
-
const
|
|
53
|
-
if (!
|
|
54
|
-
accept('error', ValidationMessages.IMPORT_NOT_IN_MANIFEST(
|
|
59
|
+
// Find the matching dependency by key (owner/package format)
|
|
60
|
+
const match = this.findDependency(manifest, imp.uri);
|
|
61
|
+
if (!match) {
|
|
62
|
+
accept('error', ValidationMessages.IMPORT_NOT_IN_MANIFEST(imp.uri), {
|
|
55
63
|
node: imp,
|
|
56
64
|
property: 'uri',
|
|
57
65
|
codeDescription: buildCodeDescription('language.md', 'imports'),
|
|
58
|
-
data: { code: IssueCodes.ImportNotInManifest, alias }
|
|
66
|
+
data: { code: IssueCodes.ImportNotInManifest, alias: imp.uri }
|
|
59
67
|
});
|
|
60
68
|
return;
|
|
61
69
|
}
|
|
62
|
-
|
|
70
|
+
const { key, dependency } = match;
|
|
71
|
+
this.validateDependencyConfig(dependency, key, accept, imp);
|
|
63
72
|
// External source dependencies require lock file and cached packages
|
|
64
73
|
if (dependency.source) {
|
|
65
74
|
const lockFile = await this.workspaceManager.getLockFile();
|
|
66
75
|
if (!lockFile) {
|
|
67
|
-
accept('error', ValidationMessages.IMPORT_NOT_INSTALLED(
|
|
76
|
+
accept('error', ValidationMessages.IMPORT_NOT_INSTALLED(key), {
|
|
68
77
|
node: imp,
|
|
69
78
|
property: 'uri',
|
|
70
79
|
codeDescription: buildCodeDescription('language.md', 'imports'),
|
|
71
|
-
data: { code: IssueCodes.ImportNotInstalled, alias }
|
|
80
|
+
data: { code: IssueCodes.ImportNotInstalled, alias: key }
|
|
72
81
|
});
|
|
73
82
|
return;
|
|
74
83
|
}
|
|
75
|
-
await this.validateCachedPackage(dependency,
|
|
84
|
+
await this.validateCachedPackage(dependency, key, lockFile, accept, imp);
|
|
76
85
|
}
|
|
77
86
|
}
|
|
78
87
|
/**
|
|
@@ -93,18 +102,93 @@ export class ImportValidator {
|
|
|
93
102
|
return true;
|
|
94
103
|
}
|
|
95
104
|
/**
|
|
96
|
-
*
|
|
105
|
+
* Validates that an import URI resolves to an existing file.
|
|
106
|
+
* Returns true if there was an error (import doesn't resolve).
|
|
97
107
|
*/
|
|
98
|
-
|
|
99
|
-
|
|
108
|
+
async validateImportResolves(imp, document, accept) {
|
|
109
|
+
if (!imp.uri) {
|
|
110
|
+
return true; // Error already reported
|
|
111
|
+
}
|
|
112
|
+
const docDir = path.dirname(document.uri.fsPath);
|
|
113
|
+
try {
|
|
114
|
+
const resolvedUri = await this.importResolver.resolveFrom(docDir, imp.uri);
|
|
115
|
+
// Check if the resolved file actually exists
|
|
116
|
+
const filePath = resolvedUri.fsPath;
|
|
117
|
+
const exists = await this.fileExists(filePath);
|
|
118
|
+
if (!exists) {
|
|
119
|
+
accept('error', ValidationMessages.IMPORT_UNRESOLVED(imp.uri), {
|
|
120
|
+
node: imp,
|
|
121
|
+
property: 'uri',
|
|
122
|
+
codeDescription: buildCodeDescription('language.md', 'imports'),
|
|
123
|
+
data: { code: IssueCodes.ImportUnresolved, uri: imp.uri }
|
|
124
|
+
});
|
|
125
|
+
return true;
|
|
126
|
+
}
|
|
127
|
+
return false;
|
|
128
|
+
}
|
|
129
|
+
catch {
|
|
130
|
+
// Resolution failed - report as unresolved import
|
|
131
|
+
accept('error', ValidationMessages.IMPORT_UNRESOLVED(imp.uri), {
|
|
132
|
+
node: imp,
|
|
133
|
+
property: 'uri',
|
|
134
|
+
codeDescription: buildCodeDescription('language.md', 'imports'),
|
|
135
|
+
data: { code: IssueCodes.ImportUnresolved, uri: imp.uri }
|
|
136
|
+
});
|
|
137
|
+
return true;
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Checks if a file exists (async).
|
|
142
|
+
*/
|
|
143
|
+
async fileExists(filePath) {
|
|
144
|
+
try {
|
|
145
|
+
const stat = await fs.stat(filePath);
|
|
146
|
+
return stat.isFile();
|
|
147
|
+
}
|
|
148
|
+
catch {
|
|
149
|
+
return false;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Finds the dependency configuration that matches the import specifier.
|
|
154
|
+
*
|
|
155
|
+
* Dependencies can be keyed as:
|
|
156
|
+
* - owner/package (recommended, matches "owner/package" or "owner/package/subpath")
|
|
157
|
+
* - short-alias (matches "short-alias" or "short-alias/subpath")
|
|
158
|
+
*
|
|
159
|
+
* @returns The matching key and normalized dependency, or undefined if not found
|
|
160
|
+
*/
|
|
161
|
+
findDependency(manifest, specifier) {
|
|
162
|
+
const dependencies = manifest.dependencies;
|
|
163
|
+
if (!dependencies) {
|
|
164
|
+
return undefined;
|
|
165
|
+
}
|
|
166
|
+
// Sort keys by length descending to match most specific first
|
|
167
|
+
const sortedKeys = Object.keys(dependencies).sort((a, b) => b.length - a.length);
|
|
168
|
+
for (const key of sortedKeys) {
|
|
169
|
+
// Exact match or prefix match (key followed by /)
|
|
170
|
+
if (specifier === key || specifier.startsWith(`${key}/`)) {
|
|
171
|
+
const dependency = this.getDependency(manifest, key);
|
|
172
|
+
if (dependency) {
|
|
173
|
+
return { key, dependency };
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
return undefined;
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* Gets the normalized dependency configuration for a key.
|
|
181
|
+
*/
|
|
182
|
+
getDependency(manifest, key) {
|
|
183
|
+
const dep = manifest.dependencies?.[key];
|
|
100
184
|
if (!dep) {
|
|
101
185
|
return undefined;
|
|
102
186
|
}
|
|
103
187
|
if (typeof dep === 'string') {
|
|
104
|
-
return { source:
|
|
188
|
+
return { source: key, ref: dep };
|
|
105
189
|
}
|
|
106
190
|
if (!dep.source && !dep.path) {
|
|
107
|
-
return { ...dep, source:
|
|
191
|
+
return { ...dep, source: key };
|
|
108
192
|
}
|
|
109
193
|
return dep;
|
|
110
194
|
}
|
|
@@ -240,9 +324,13 @@ export function createImportChecks(services) {
|
|
|
240
324
|
return {
|
|
241
325
|
// Langium 4.x supports async validators via MaybePromise<void>
|
|
242
326
|
ImportStatement: async (imp, accept, cancelToken) => {
|
|
243
|
-
|
|
244
|
-
|
|
327
|
+
// Get document from root (Model), not from ImportStatement
|
|
328
|
+
// Langium sets $document only on the root AST node
|
|
329
|
+
const root = imp.$container;
|
|
330
|
+
const document = root?.$document;
|
|
331
|
+
if (!document) {
|
|
245
332
|
return;
|
|
333
|
+
}
|
|
246
334
|
await validator.checkImportPath(imp, accept, document, cancelToken);
|
|
247
335
|
}
|
|
248
336
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"import.js","sourceRoot":"","sources":["../../src/validation/import.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAClC,OAAO,IAAI,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"import.js","sourceRoot":"","sources":["../../src/validation/import.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAClC,OAAO,IAAI,MAAM,WAAW,CAAC;AAQ7B,OAAO,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAEtF;;;;;;;;;;;GAWG;AACH,MAAM,OAAO,eAAe;IAIxB,YAAY,QAA4B;QACpC,IAAI,CAAC,gBAAgB,GAAG,QAAQ,CAAC,OAAO,CAAC,gBAAgB,CAAC;QAC1D,IAAI,CAAC,cAAc,GAAG,QAAQ,CAAC,OAAO,CAAC,cAAc,CAAC;IAC1D,CAAC;IAED;;;;;OAKG;IACH,KAAK,CAAC,eAAe,CACjB,GAAoB,EACpB,MAA0B,EAC1B,QAAyB,EACzB,YAA4C;QAE5C,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC;YACX,MAAM,CAAC,OAAO,EAAE,kBAAkB,CAAC,kBAAkB,EAAE,EAAE;gBACrD,IAAI,EAAE,GAAG;gBACT,OAAO,EAAE,QAAQ;gBACjB,eAAe,EAAE,oBAAoB,CAAC,aAAa,EAAE,SAAS,CAAC;gBAC/D,IAAI,EAAE,EAAE,IAAI,EAAE,UAAU,CAAC,gBAAgB,EAAE;aAC9C,CAAC,CAAC;YACH,OAAO;QACX,CAAC;QAED,oDAAoD;QACpD,uDAAuD;QACvD,MAAM,YAAY,GAAG,MAAM,IAAI,CAAC,sBAAsB,CAAC,GAAG,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC;QAC9E,IAAI,YAAY,EAAE,CAAC;YACf,OAAO,CAAC,yDAAyD;QACrE,CAAC;QAED,IAAI,CAAC,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;YAClC,OAAO;QACX,CAAC;QAED,sDAAsD;QACtD,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QACjD,MAAM,IAAI,CAAC,gBAAgB,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;QAE/C,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,gBAAgB,CAAC,WAAW,EAAE,CAAC;QAC3D,IAAI,CAAC,QAAQ,EAAE,CAAC;YACZ,MAAM,CAAC,OAAO,EAAE,kBAAkB,CAAC,wBAAwB,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE;gBAClE,IAAI,EAAE,GAAG;gBACT,QAAQ,EAAE,KAAK;gBACf,eAAe,EAAE,oBAAoB,CAAC,aAAa,EAAE,SAAS,CAAC;gBAC/D,IAAI,EAAE,EAAE,IAAI,EAAE,UAAU,CAAC,sBAAsB,EAAE,SAAS,EAAE,GAAG,CAAC,GAAG,EAAE;aACxE,CAAC,CAAC;YACH,OAAO;QACX,CAAC;QAED,6DAA6D;QAC7D,MAAM,KAAK,GAAG,IAAI,CAAC,cAAc,CAAC,QAAQ,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC;QAErD,IAAI,CAAC,KAAK,EAAE,CAAC;YACT,MAAM,CAAC,OAAO,EAAE,kBAAkB,CAAC,sBAAsB,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE;gBAChE,IAAI,EAAE,GAAG;gBACT,QAAQ,EAAE,KAAK;gBACf,eAAe,EAAE,oBAAoB,CAAC,aAAa,EAAE,SAAS,CAAC;gBAC/D,IAAI,EAAE,EAAE,IAAI,EAAE,UAAU,CAAC,mBAAmB,EAAE,KAAK,EAAE,GAAG,CAAC,GAAG,EAAE;aACjE,CAAC,CAAC;YACH,OAAO;QACX,CAAC;QAED,MAAM,EAAE,GAAG,EAAE,UAAU,EAAE,GAAG,KAAK,CAAC;QAClC,IAAI,CAAC,wBAAwB,CAAC,UAAU,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,CAAC,CAAC;QAE5D,qEAAqE;QACrE,IAAI,UAAU,CAAC,MAAM,EAAE,CAAC;YACpB,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,gBAAgB,CAAC,WAAW,EAAE,CAAC;YAC3D,IAAI,CAAC,QAAQ,EAAE,CAAC;gBACZ,MAAM,CAAC,OAAO,EAAE,kBAAkB,CAAC,oBAAoB,CAAC,GAAG,CAAC,EAAE;oBAC1D,IAAI,EAAE,GAAG;oBACT,QAAQ,EAAE,KAAK;oBACf,eAAe,EAAE,oBAAoB,CAAC,aAAa,EAAE,SAAS,CAAC;oBAC/D,IAAI,EAAE,EAAE,IAAI,EAAE,UAAU,CAAC,kBAAkB,EAAE,KAAK,EAAE,GAAG,EAAE;iBAC5D,CAAC,CAAC;gBACH,OAAO;YACX,CAAC;YAED,MAAM,IAAI,CAAC,qBAAqB,CAAC,UAAU,EAAE,GAAG,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,CAAC,CAAC;QAC7E,CAAC;IACL,CAAC;IAED;;;;;;;OAOG;IACK,gBAAgB,CAAC,GAAW;QAChC,IAAI,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,CAAC;YAChD,OAAO,KAAK,CAAC;QACjB,CAAC;QACD,IAAI,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;YACtB,OAAO,KAAK,CAAC;QACjB,CAAC;QACD,OAAO,IAAI,CAAC;IAChB,CAAC;IAED;;;OAGG;IACK,KAAK,CAAC,sBAAsB,CAChC,GAAoB,EACpB,QAAyB,EACzB,MAA0B;QAE1B,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC;YACX,OAAO,IAAI,CAAC,CAAC,yBAAyB;QAC1C,CAAC;QAED,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QAEjD,IAAI,CAAC;YACD,MAAM,WAAW,GAAG,MAAM,IAAI,CAAC,cAAc,CAAC,WAAW,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC;YAE3E,6CAA6C;YAC7C,MAAM,QAAQ,GAAG,WAAW,CAAC,MAAM,CAAC;YACpC,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC;YAE/C,IAAI,CAAC,MAAM,EAAE,CAAC;gBACV,MAAM,CAAC,OAAO,EAAE,kBAAkB,CAAC,iBAAiB,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE;oBAC3D,IAAI,EAAE,GAAG;oBACT,QAAQ,EAAE,KAAK;oBACf,eAAe,EAAE,oBAAoB,CAAC,aAAa,EAAE,SAAS,CAAC;oBAC/D,IAAI,EAAE,EAAE,IAAI,EAAE,UAAU,CAAC,gBAAgB,EAAE,GAAG,EAAE,GAAG,CAAC,GAAG,EAAE;iBAC5D,CAAC,CAAC;gBACH,OAAO,IAAI,CAAC;YAChB,CAAC;YAED,OAAO,KAAK,CAAC;QACjB,CAAC;QAAC,MAAM,CAAC;YACL,kDAAkD;YAClD,MAAM,CAAC,OAAO,EAAE,kBAAkB,CAAC,iBAAiB,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE;gBAC3D,IAAI,EAAE,GAAG;gBACT,QAAQ,EAAE,KAAK;gBACf,eAAe,EAAE,oBAAoB,CAAC,aAAa,EAAE,SAAS,CAAC;gBAC/D,IAAI,EAAE,EAAE,IAAI,EAAE,UAAU,CAAC,gBAAgB,EAAE,GAAG,EAAE,GAAG,CAAC,GAAG,EAAE;aAC5D,CAAC,CAAC;YACH,OAAO,IAAI,CAAC;QAChB,CAAC;IACL,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,UAAU,CAAC,QAAgB;QACrC,IAAI,CAAC;YACD,MAAM,IAAI,GAAG,MAAM,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;YACrC,OAAO,IAAI,CAAC,MAAM,EAAE,CAAC;QACzB,CAAC;QAAC,MAAM,CAAC;YACL,OAAO,KAAK,CAAC;QACjB,CAAC;IACL,CAAC;IAED;;;;;;;;OAQG;IACK,cAAc,CAClB,QAAuB,EACvB,SAAiB;QAEjB,MAAM,YAAY,GAAG,QAAQ,CAAC,YAAY,CAAC;QAC3C,IAAI,CAAC,YAAY,EAAE,CAAC;YAChB,OAAO,SAAS,CAAC;QACrB,CAAC;QAED,8DAA8D;QAC9D,MAAM,UAAU,GAAG,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC;QAEjF,KAAK,MAAM,GAAG,IAAI,UAAU,EAAE,CAAC;YAC3B,kDAAkD;YAClD,IAAI,SAAS,KAAK,GAAG,IAAI,SAAS,CAAC,UAAU,CAAC,GAAG,GAAG,GAAG,CAAC,EAAE,CAAC;gBACvD,MAAM,UAAU,GAAG,IAAI,CAAC,aAAa,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC;gBACrD,IAAI,UAAU,EAAE,CAAC;oBACb,OAAO,EAAE,GAAG,EAAE,UAAU,EAAE,CAAC;gBAC/B,CAAC;YACL,CAAC;QACL,CAAC;QAED,OAAO,SAAS,CAAC;IACrB,CAAC;IAED;;OAEG;IACK,aAAa,CAAC,QAAuB,EAAE,GAAW;QACtD,MAAM,GAAG,GAAG,QAAQ,CAAC,YAAY,EAAE,CAAC,GAAG,CAAC,CAAC;QACzC,IAAI,CAAC,GAAG,EAAE,CAAC;YACP,OAAO,SAAS,CAAC;QACrB,CAAC;QAED,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE,CAAC;YAC1B,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC;QACrC,CAAC;QAED,IAAI,CAAC,GAAG,CAAC,MAAM,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC;YAC3B,OAAO,EAAE,GAAG,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC;QACnC,CAAC;QAED,OAAO,GAAG,CAAC;IACf,CAAC;IAED;;OAEG;IACK,wBAAwB,CAC5B,UAAkC,EAClC,KAAa,EACb,MAA0B,EAC1B,GAAoB;QAEpB,IAAI,UAAU,CAAC,MAAM,IAAI,UAAU,CAAC,IAAI,EAAE,CAAC;YACvC,MAAM,CAAC,OAAO,EAAE,kBAAkB,CAAC,8BAA8B,CAAC,KAAK,CAAC,EAAE;gBACtE,IAAI,EAAE,GAAG;gBACT,QAAQ,EAAE,KAAK;gBACf,eAAe,EAAE,oBAAoB,CAAC,aAAa,EAAE,SAAS,CAAC;gBAC/D,IAAI,EAAE,EAAE,IAAI,EAAE,UAAU,CAAC,2BAA2B,EAAE,KAAK,EAAE;aAChE,CAAC,CAAC;YACH,OAAO;QACX,CAAC;QAED,IAAI,CAAC,UAAU,CAAC,MAAM,IAAI,CAAC,UAAU,CAAC,IAAI,EAAE,CAAC;YACzC,MAAM,CAAC,OAAO,EAAE,kBAAkB,CAAC,6BAA6B,CAAC,KAAK,CAAC,EAAE;gBACrE,IAAI,EAAE,GAAG;gBACT,QAAQ,EAAE,KAAK;gBACf,eAAe,EAAE,oBAAoB,CAAC,aAAa,EAAE,SAAS,CAAC;gBAC/D,IAAI,EAAE,EAAE,IAAI,EAAE,UAAU,CAAC,yBAAyB,EAAE,KAAK,EAAE;aAC9D,CAAC,CAAC;YACH,OAAO;QACX,CAAC;QAED,IAAI,UAAU,CAAC,MAAM,IAAI,CAAC,UAAU,CAAC,GAAG,EAAE,CAAC;YACvC,MAAM,CAAC,OAAO,EAAE,kBAAkB,CAAC,kBAAkB,CAAC,KAAK,CAAC,EAAE;gBAC1D,IAAI,EAAE,GAAG;gBACT,QAAQ,EAAE,KAAK;gBACf,eAAe,EAAE,oBAAoB,CAAC,aAAa,EAAE,SAAS,CAAC;gBAC/D,IAAI,EAAE,EAAE,IAAI,EAAE,UAAU,CAAC,gBAAgB,EAAE,KAAK,EAAE;aACrD,CAAC,CAAC;QACP,CAAC;QAED,IAAI,UAAU,CAAC,IAAI,EAAE,CAAC;YAClB,IAAI,CAAC,2BAA2B,CAAC,UAAU,CAAC,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,CAAC,CAAC;QAC1E,CAAC;IACL,CAAC;IAED;;OAEG;IACK,2BAA2B,CAC/B,cAAsB,EACtB,KAAa,EACb,MAA0B,EAC1B,GAAoB;QAEpB,IAAI,IAAI,CAAC,UAAU,CAAC,cAAc,CAAC,EAAE,CAAC;YAClC,MAAM,CAAC,OAAO,EAAE,kBAAkB,CAAC,oBAAoB,CAAC,KAAK,EAAE,cAAc,CAAC,EAAE;gBAC5E,IAAI,EAAE,GAAG;gBACT,QAAQ,EAAE,KAAK;gBACf,eAAe,EAAE,oBAAoB,CAAC,aAAa,EAAE,SAAS,CAAC;gBAC/D,IAAI,EAAE,EAAE,IAAI,EAAE,UAAU,CAAC,kBAAkB,EAAE,KAAK,EAAE,IAAI,EAAE,cAAc,EAAE;aAC7E,CAAC,CAAC;YACH,OAAO;QACX,CAAC;QAED,IAAI,CAAC;YACD,MAAM,aAAa,GAAG,IAAI,CAAC,gBAAgB,CAAC,gBAAgB,EAAE,CAAC;YAC/D,MAAM,YAAY,GAAG,IAAI,CAAC,OAAO,CAAC,aAAa,EAAE,cAAc,CAAC,CAAC;YACjE,MAAM,mBAAmB,GAAG,IAAI,CAAC,QAAQ,CAAC,aAAa,EAAE,YAAY,CAAC,CAAC;YAEvE,IAAI,mBAAmB,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,UAAU,CAAC,mBAAmB,CAAC,EAAE,CAAC;gBAC/E,MAAM,CAAC,OAAO,EAAE,kBAAkB,CAAC,wBAAwB,CAAC,KAAK,CAAC,EAAE;oBAChE,IAAI,EAAE,GAAG;oBACT,QAAQ,EAAE,KAAK;oBACf,eAAe,EAAE,oBAAoB,CAAC,aAAa,EAAE,SAAS,CAAC;oBAC/D,IAAI,EAAE,EAAE,IAAI,EAAE,UAAU,CAAC,sBAAsB,EAAE,KAAK,EAAE;iBAC3D,CAAC,CAAC;YACP,CAAC;QACL,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACb,mEAAmE;YACnE,0DAA0D;YAC1D,OAAO,CAAC,IAAI,CAAC,8DAA8D,KAAK,EAAE,CAAC,CAAC;QACxF,CAAC;IACL,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,qBAAqB,CAC/B,UAAkC,EAClC,KAAa,EACb,QAAkB,EAClB,MAA0B,EAC1B,GAAoB;QAEpB,wEAAwE;QACxE,MAAM,UAAU,GAAG,UAAU,CAAC,MAAM,IAAI,KAAK,CAAC;QAC9C,MAAM,SAAS,GAAG,QAAQ,CAAC,YAAY,CAAC,UAAU,CAAC,CAAC;QAEpD,IAAI,CAAC,SAAS,EAAE,CAAC;YACb,MAAM,CAAC,OAAO,EAAE,kBAAkB,CAAC,oBAAoB,CAAC,KAAK,CAAC,EAAE;gBAC5D,IAAI,EAAE,GAAG;gBACT,QAAQ,EAAE,KAAK;gBACf,eAAe,EAAE,oBAAoB,CAAC,aAAa,EAAE,SAAS,CAAC;gBAC/D,IAAI,EAAE,EAAE,IAAI,EAAE,UAAU,CAAC,kBAAkB,EAAE,KAAK,EAAE;aACvD,CAAC,CAAC;YACH,OAAO;QACX,CAAC;QAED,IAAI,CAAC;YACD,MAAM,aAAa,GAAG,IAAI,CAAC,gBAAgB,CAAC,gBAAgB,EAAE,CAAC;YAC/D,MAAM,QAAQ,GAAG,IAAI,CAAC,iBAAiB,CAAC,aAAa,EAAE,UAAU,EAAE,SAAS,CAAC,MAAM,CAAC,CAAC;YAErF,MAAM,WAAW,GAAG,MAAM,IAAI,CAAC,eAAe,CAAC,QAAQ,CAAC,CAAC;YACzD,IAAI,CAAC,WAAW,EAAE,CAAC;gBACf,MAAM,CAAC,OAAO,EAAE,kBAAkB,CAAC,oBAAoB,CAAC,KAAK,CAAC,EAAE;oBAC5D,IAAI,EAAE,GAAG;oBACT,QAAQ,EAAE,KAAK;oBACf,eAAe,EAAE,oBAAoB,CAAC,aAAa,EAAE,SAAS,CAAC;oBAC/D,IAAI,EAAE,EAAE,IAAI,EAAE,UAAU,CAAC,kBAAkB,EAAE,KAAK,EAAE;iBACvD,CAAC,CAAC;YACP,CAAC;QACL,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACb,8DAA8D;YAC9D,OAAO,CAAC,IAAI,CAAC,yCAAyC,KAAK,KAAK,KAAK,EAAE,CAAC,CAAC;QAC7E,CAAC;IACL,CAAC;IAED;;;OAGG;IACK,iBAAiB,CAAC,aAAqB,EAAE,MAAc,EAAE,UAAkB;QAC/E,MAAM,CAAC,KAAK,EAAE,IAAI,CAAC,GAAG,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QACxC,OAAO,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,QAAQ,EAAE,UAAU,EAAE,KAAK,EAAE,IAAI,EAAE,UAAU,CAAC,CAAC;IACnF,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,eAAe,CAAC,OAAe;QACzC,IAAI,CAAC;YACD,MAAM,IAAI,GAAG,MAAM,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YACpC,OAAO,IAAI,CAAC,WAAW,EAAE,CAAC;QAC9B,CAAC;QAAC,MAAM,CAAC;YACL,OAAO,KAAK,CAAC;QACjB,CAAC;IACL,CAAC;CACJ;AAED;;;;;GAKG;AACH,MAAM,UAAU,kBAAkB,CAAC,QAA4B;IAC3D,MAAM,SAAS,GAAG,IAAI,eAAe,CAAC,QAAQ,CAAC,CAAC;IAEhD,OAAO;QACH,+DAA+D;QAC/D,eAAe,EAAE,KAAK,EAAE,GAAG,EAAE,MAAM,EAAE,WAAW,EAAE,EAAE;YAChD,2DAA2D;YAC3D,mDAAmD;YACnD,MAAM,IAAI,GAAG,GAAG,CAAC,UAAU,CAAC;YAC5B,MAAM,QAAQ,GAAG,IAAI,EAAE,SAAS,CAAC;YACjC,IAAI,CAAC,QAAQ,EAAE,CAAC;gBACZ,OAAO;YACX,CAAC;YAED,MAAM,SAAS,CAAC,eAAe,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,WAAW,CAAC,CAAC;QACxE,CAAC;KACJ,CAAC;AACN,CAAC"}
|
package/out/validation/maps.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { isThisRef } from '../generated/ast.js';
|
|
2
|
+
import { ValidationMessages, buildCodeDescription, IssueCodes } from './constants.js';
|
|
2
3
|
/**
|
|
3
4
|
* Validates that a context map contains at least one bounded context.
|
|
4
5
|
* Empty context maps are not useful for documentation purposes.
|
|
@@ -15,6 +16,32 @@ function validateContextMapHasContexts(map, accept) {
|
|
|
15
16
|
});
|
|
16
17
|
}
|
|
17
18
|
}
|
|
19
|
+
/**
|
|
20
|
+
* Validates that MultiReference items in a context map resolve.
|
|
21
|
+
* Langium doesn't report errors for unresolved MultiReference items by default,
|
|
22
|
+
* so we need custom validation to catch these cases.
|
|
23
|
+
*
|
|
24
|
+
* @param map - The context map to validate
|
|
25
|
+
* @param accept - The validation acceptor for reporting issues
|
|
26
|
+
*/
|
|
27
|
+
function validateContextMapReferences(map, accept) {
|
|
28
|
+
if (!map.boundedContexts)
|
|
29
|
+
return;
|
|
30
|
+
for (const multiRef of map.boundedContexts) {
|
|
31
|
+
// A MultiReference has a $refText (the source text) and items (resolved refs)
|
|
32
|
+
// If $refText exists but items is empty, the reference didn't resolve
|
|
33
|
+
const refText = multiRef.$refText;
|
|
34
|
+
if (refText && multiRef.items.length === 0) {
|
|
35
|
+
accept('error', ValidationMessages.UNRESOLVED_REFERENCE('BoundedContext', refText), {
|
|
36
|
+
node: map,
|
|
37
|
+
// Find the CST node for this specific reference
|
|
38
|
+
property: 'boundedContexts',
|
|
39
|
+
index: map.boundedContexts.indexOf(multiRef),
|
|
40
|
+
code: IssueCodes.UnresolvedReference
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
18
45
|
/**
|
|
19
46
|
* Validates that a context map has at least one relationship if it contains multiple contexts.
|
|
20
47
|
* Multiple unrelated contexts should have documented relationships.
|
|
@@ -50,11 +77,82 @@ function validateDomainMapHasDomains(map, accept) {
|
|
|
50
77
|
});
|
|
51
78
|
}
|
|
52
79
|
}
|
|
80
|
+
/**
|
|
81
|
+
* Validates that MultiReference items in a domain map resolve.
|
|
82
|
+
*
|
|
83
|
+
* @param map - The domain map to validate
|
|
84
|
+
* @param accept - The validation acceptor for reporting issues
|
|
85
|
+
*/
|
|
86
|
+
function validateDomainMapReferences(map, accept) {
|
|
87
|
+
if (!map.domains)
|
|
88
|
+
return;
|
|
89
|
+
for (const multiRef of map.domains) {
|
|
90
|
+
const refText = multiRef.$refText;
|
|
91
|
+
if (refText && multiRef.items.length === 0) {
|
|
92
|
+
accept('error', ValidationMessages.UNRESOLVED_REFERENCE('Domain', refText), {
|
|
93
|
+
node: map,
|
|
94
|
+
property: 'domains',
|
|
95
|
+
index: map.domains.indexOf(multiRef),
|
|
96
|
+
code: IssueCodes.UnresolvedReference
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Gets a canonical name for a BoundedContextRef for comparison purposes.
|
|
103
|
+
*/
|
|
104
|
+
function getRefKey(ref) {
|
|
105
|
+
if (isThisRef(ref)) {
|
|
106
|
+
return 'this';
|
|
107
|
+
}
|
|
108
|
+
return ref.link?.$refText ?? '';
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Builds a canonical key for a relationship for duplicate detection.
|
|
112
|
+
* The key captures both endpoints, arrow direction, and integration patterns.
|
|
113
|
+
*/
|
|
114
|
+
function buildRelationshipKey(rel) {
|
|
115
|
+
const left = getRefKey(rel.left);
|
|
116
|
+
const right = getRefKey(rel.right);
|
|
117
|
+
const leftPatterns = (rel.leftPatterns ?? []).slice().sort((a, b) => a.localeCompare(b)).join(',');
|
|
118
|
+
const rightPatterns = (rel.rightPatterns ?? []).slice().sort((a, b) => a.localeCompare(b)).join(',');
|
|
119
|
+
return `[${leftPatterns}]${left}${rel.arrow}[${rightPatterns}]${right}`;
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Validates that a context map does not contain duplicate relationships.
|
|
123
|
+
* Two relationships are considered duplicate if they have the same endpoints,
|
|
124
|
+
* direction, and integration patterns.
|
|
125
|
+
*
|
|
126
|
+
* @param map - The context map to validate
|
|
127
|
+
* @param accept - The validation acceptor for reporting issues
|
|
128
|
+
*/
|
|
129
|
+
function validateNoDuplicateRelationships(map, accept) {
|
|
130
|
+
if (!map.relationships || map.relationships.length < 2)
|
|
131
|
+
return;
|
|
132
|
+
const seen = new Map();
|
|
133
|
+
for (let i = 0; i < map.relationships.length; i++) {
|
|
134
|
+
const rel = map.relationships[i];
|
|
135
|
+
const key = buildRelationshipKey(rel);
|
|
136
|
+
if (seen.has(key)) {
|
|
137
|
+
accept('warning', ValidationMessages.CONTEXT_MAP_DUPLICATE_RELATIONSHIP(getRefKey(rel.left), getRefKey(rel.right)), {
|
|
138
|
+
node: rel,
|
|
139
|
+
property: 'arrow',
|
|
140
|
+
codeDescription: buildCodeDescription('language.md', 'context-maps')
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
else {
|
|
144
|
+
seen.set(key, i);
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
}
|
|
53
148
|
export const contextMapChecks = [
|
|
54
149
|
validateContextMapHasContexts,
|
|
55
|
-
|
|
150
|
+
validateContextMapReferences,
|
|
151
|
+
validateContextMapHasRelationships,
|
|
152
|
+
validateNoDuplicateRelationships
|
|
56
153
|
];
|
|
57
154
|
export const domainMapChecks = [
|
|
58
|
-
validateDomainMapHasDomains
|
|
155
|
+
validateDomainMapHasDomains,
|
|
156
|
+
validateDomainMapReferences
|
|
59
157
|
];
|
|
60
158
|
//# sourceMappingURL=maps.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"maps.js","sourceRoot":"","sources":["../../src/validation/maps.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"maps.js","sourceRoot":"","sources":["../../src/validation/maps.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@domainlang/language",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.8.0",
|
|
4
4
|
"displayName": "DomainLang Language",
|
|
5
5
|
"description": "Core language library for DomainLang - parse, validate, and query Domain-Driven Design models programmatically",
|
|
6
6
|
"author": "larsbaunwall",
|
|
@@ -92,12 +92,12 @@
|
|
|
92
92
|
"yaml": "^2.5.0"
|
|
93
93
|
},
|
|
94
94
|
"devDependencies": {
|
|
95
|
-
"@types/node": "~20.
|
|
96
|
-
"@vitest/coverage-v8": "^
|
|
95
|
+
"@types/node": "~20.19.33",
|
|
96
|
+
"@vitest/coverage-v8": "^4.0.18",
|
|
97
97
|
"langium-cli": "~4.2.0",
|
|
98
98
|
"shx": "~0.4.0",
|
|
99
|
-
"typescript": "
|
|
100
|
-
"vitest": "
|
|
99
|
+
"typescript": "^5.9.3",
|
|
100
|
+
"vitest": "^4.0.18"
|
|
101
101
|
},
|
|
102
102
|
"volta": {
|
|
103
103
|
"node": "20.19.2",
|
|
@@ -11,12 +11,16 @@ import { DomainLangGeneratedModule, DomainLangGeneratedSharedModule } from './ge
|
|
|
11
11
|
import { registerValidationChecks } from './validation/domain-lang-validator.js';
|
|
12
12
|
import { QualifiedNameProvider } from './lsp/domain-lang-naming.js';
|
|
13
13
|
import { DomainLangScopeComputation } from './lsp/domain-lang-scope.js';
|
|
14
|
+
import { DomainLangScopeProvider } from './lsp/domain-lang-scope-provider.js';
|
|
14
15
|
import { DomainLangFormatter } from './lsp/domain-lang-formatter.js';
|
|
15
16
|
import { DomainLangHoverProvider } from './lsp/hover/domain-lang-hover.js';
|
|
16
17
|
import { DomainLangCompletionProvider } from './lsp/domain-lang-completion.js';
|
|
17
18
|
import { DomainLangCodeActionProvider } from './lsp/domain-lang-code-actions.js';
|
|
19
|
+
import { DomainLangNodeKindProvider } from './lsp/domain-lang-node-kind-provider.js';
|
|
20
|
+
import { DomainLangDocumentSymbolProvider } from './lsp/domain-lang-document-symbol-provider.js';
|
|
18
21
|
import { ImportResolver } from './services/import-resolver.js';
|
|
19
22
|
import { WorkspaceManager } from './services/workspace-manager.js';
|
|
23
|
+
import { PackageBoundaryDetector } from './services/package-boundary-detector.js';
|
|
20
24
|
import { DomainLangWorkspaceManager } from './lsp/domain-lang-workspace-manager.js';
|
|
21
25
|
import { DomainLangIndexManager } from './lsp/domain-lang-index-manager.js';
|
|
22
26
|
|
|
@@ -26,7 +30,8 @@ import { DomainLangIndexManager } from './lsp/domain-lang-index-manager.js';
|
|
|
26
30
|
export type DomainLangAddedServices = {
|
|
27
31
|
imports: {
|
|
28
32
|
ImportResolver: ImportResolver,
|
|
29
|
-
WorkspaceManager: WorkspaceManager
|
|
33
|
+
WorkspaceManager: WorkspaceManager,
|
|
34
|
+
PackageBoundaryDetector: PackageBoundaryDetector
|
|
30
35
|
},
|
|
31
36
|
references: {
|
|
32
37
|
QualifiedNameProvider: QualifiedNameProvider
|
|
@@ -46,6 +51,9 @@ export type DomainLangAddedServices = {
|
|
|
46
51
|
export type DomainLangServices = LangiumServices & DomainLangAddedServices
|
|
47
52
|
|
|
48
53
|
const DomainLangSharedModule: Module<LangiumSharedServices, PartialLangiumSharedServices> = {
|
|
54
|
+
lsp: {
|
|
55
|
+
NodeKindProvider: () => new DomainLangNodeKindProvider()
|
|
56
|
+
},
|
|
49
57
|
workspace: {
|
|
50
58
|
WorkspaceManager: (services: LangiumSharedServices) => new DomainLangWorkspaceManager(services),
|
|
51
59
|
IndexManager: (services: LangiumSharedServices) => new DomainLangIndexManager(services)
|
|
@@ -60,17 +68,20 @@ const DomainLangSharedModule: Module<LangiumSharedServices, PartialLangiumShared
|
|
|
60
68
|
export const DomainLangModule: Module<DomainLangServices, PartialLangiumServices & DomainLangAddedServices> = {
|
|
61
69
|
imports: {
|
|
62
70
|
ImportResolver: (services) => new ImportResolver(services),
|
|
63
|
-
WorkspaceManager: () => new WorkspaceManager({ autoResolve: false, allowNetwork: false })
|
|
71
|
+
WorkspaceManager: () => new WorkspaceManager({ autoResolve: false, allowNetwork: false }),
|
|
72
|
+
PackageBoundaryDetector: () => new PackageBoundaryDetector()
|
|
64
73
|
},
|
|
65
74
|
references: {
|
|
66
75
|
ScopeComputation: (services) => new DomainLangScopeComputation(services),
|
|
76
|
+
ScopeProvider: (services) => new DomainLangScopeProvider(services),
|
|
67
77
|
QualifiedNameProvider: () => new QualifiedNameProvider()
|
|
68
78
|
},
|
|
69
79
|
lsp: {
|
|
70
80
|
Formatter: () => new DomainLangFormatter(),
|
|
71
81
|
HoverProvider: (services) => new DomainLangHoverProvider(services),
|
|
72
82
|
CompletionProvider: (services) => new DomainLangCompletionProvider(services),
|
|
73
|
-
CodeActionProvider: () => new DomainLangCodeActionProvider()
|
|
83
|
+
CodeActionProvider: () => new DomainLangCodeActionProvider(),
|
|
84
|
+
DocumentSymbolProvider: (services) => new DomainLangDocumentSymbolProvider(services)
|
|
74
85
|
},
|
|
75
86
|
};
|
|
76
87
|
|
|
@@ -105,6 +116,18 @@ export function createDomainLangServices(context: DefaultSharedModuleContext): {
|
|
|
105
116
|
);
|
|
106
117
|
shared.ServiceRegistry.register(DomainLang);
|
|
107
118
|
registerValidationChecks(DomainLang);
|
|
119
|
+
|
|
120
|
+
// Late-bind language services into shared module services.
|
|
121
|
+
// IndexManager and WorkspaceManager are in the shared module (created first),
|
|
122
|
+
// but need access to ImportResolver from the language module (created second).
|
|
123
|
+
const indexManager = shared.workspace.IndexManager;
|
|
124
|
+
if (indexManager instanceof DomainLangIndexManager) {
|
|
125
|
+
indexManager.setLanguageServices(DomainLang);
|
|
126
|
+
}
|
|
127
|
+
const workspaceManager = shared.workspace.WorkspaceManager;
|
|
128
|
+
if (workspaceManager instanceof DomainLangWorkspaceManager) {
|
|
129
|
+
workspaceManager.setLanguageServices(DomainLang);
|
|
130
|
+
}
|
|
108
131
|
|
|
109
132
|
if (!context.connection) {
|
|
110
133
|
// We don't run inside a language server
|