@domainlang/language 0.6.0 → 0.7.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.
Files changed (35) hide show
  1. package/README.md +1 -1
  2. package/out/domain-lang-module.js +2 -0
  3. package/out/domain-lang-module.js.map +1 -1
  4. package/out/lsp/domain-lang-index-manager.d.ts +69 -1
  5. package/out/lsp/domain-lang-index-manager.js +173 -5
  6. package/out/lsp/domain-lang-index-manager.js.map +1 -1
  7. package/out/lsp/domain-lang-scope-provider.d.ts +67 -0
  8. package/out/lsp/domain-lang-scope-provider.js +95 -0
  9. package/out/lsp/domain-lang-scope-provider.js.map +1 -0
  10. package/out/lsp/domain-lang-workspace-manager.d.ts +25 -0
  11. package/out/lsp/domain-lang-workspace-manager.js +102 -3
  12. package/out/lsp/domain-lang-workspace-manager.js.map +1 -1
  13. package/out/main.js +114 -19
  14. package/out/main.js.map +1 -1
  15. package/out/services/import-resolver.d.ts +29 -6
  16. package/out/services/import-resolver.js +48 -9
  17. package/out/services/import-resolver.js.map +1 -1
  18. package/out/validation/constants.d.ts +13 -0
  19. package/out/validation/constants.js +18 -0
  20. package/out/validation/constants.js.map +1 -1
  21. package/out/validation/import.d.ts +11 -0
  22. package/out/validation/import.js +62 -2
  23. package/out/validation/import.js.map +1 -1
  24. package/out/validation/maps.js +51 -2
  25. package/out/validation/maps.js.map +1 -1
  26. package/package.json +1 -1
  27. package/src/domain-lang-module.ts +2 -0
  28. package/src/lsp/domain-lang-index-manager.ts +196 -5
  29. package/src/lsp/domain-lang-scope-provider.ts +134 -0
  30. package/src/lsp/domain-lang-workspace-manager.ts +128 -3
  31. package/src/main.ts +153 -22
  32. package/src/services/import-resolver.ts +60 -9
  33. package/src/validation/constants.ts +24 -0
  34. package/src/validation/import.ts +75 -2
  35. package/src/validation/maps.ts +59 -2
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # @domainlang/language
2
2
 
3
- [![npm version](https://img.shields.io/npm/v/@domainlang/language.svg)](https://www.npmjs.com/package/@domainlang/language)[![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=DomainLang_DomainLang&metric=alert_status)](https://sonarcloud.io/summary/new_code?id=DomainLang_DomainLang)[![Security Rating](https://sonarcloud.io/api/project_badges/measure?project=DomainLang_DomainLang&metric=security_rating)](https://sonarcloud.io/summary/new_code?id=DomainLang_DomainLang)[![Vulnerabilities](https://sonarcloud.io/api/project_badges/measure?project=DomainLang_DomainLang&metric=vulnerabilities)](https://sonarcloud.io/summary/new_code?id=DomainLang_DomainLang)
3
+ [![npm version](https://img.shields.io/npm/v/@domainlang/language.svg)](https://www.npmjs.com/package/@domainlang/language)[![Security Rating](https://sonarcloud.io/api/project_badges/measure?project=DomainLang_DomainLang&metric=security_rating)](https://sonarcloud.io/summary/new_code?id=DomainLang_DomainLang)[![Vulnerabilities](https://sonarcloud.io/api/project_badges/measure?project=DomainLang_DomainLang&metric=vulnerabilities)](https://sonarcloud.io/summary/new_code?id=DomainLang_DomainLang)
4
4
  [![License](https://img.shields.io/npm/l/@domainlang/language.svg)](https://github.com/DomainLang/DomainLang/blob/main/LICENSE)
5
5
 
6
6
  Core language library for [DomainLang](https://github.com/DomainLang/DomainLang) - a Domain-Driven Design modeling language built with [Langium](https://langium.org/).
@@ -4,6 +4,7 @@ import { DomainLangGeneratedModule, DomainLangGeneratedSharedModule } from './ge
4
4
  import { registerValidationChecks } from './validation/domain-lang-validator.js';
5
5
  import { QualifiedNameProvider } from './lsp/domain-lang-naming.js';
6
6
  import { DomainLangScopeComputation } from './lsp/domain-lang-scope.js';
7
+ import { DomainLangScopeProvider } from './lsp/domain-lang-scope-provider.js';
7
8
  import { DomainLangFormatter } from './lsp/domain-lang-formatter.js';
8
9
  import { DomainLangHoverProvider } from './lsp/hover/domain-lang-hover.js';
9
10
  import { DomainLangCompletionProvider } from './lsp/domain-lang-completion.js';
@@ -30,6 +31,7 @@ export const DomainLangModule = {
30
31
  },
31
32
  references: {
32
33
  ScopeComputation: (services) => new DomainLangScopeComputation(services),
34
+ ScopeProvider: (services) => new DomainLangScopeProvider(services),
33
35
  QualifiedNameProvider: () => new QualifiedNameProvider()
34
36
  },
35
37
  lsp: {
@@ -1 +1 @@
1
- {"version":3,"file":"domain-lang-module.js","sourceRoot":"","sources":["../src/domain-lang-module.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"domain-lang-module.js","sourceRoot":"","sources":["../src/domain-lang-module.ts"],"names":[],"mappings":"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"}
@@ -14,6 +14,7 @@ import { CancellationToken } from 'vscode-jsonrpc';
14
14
  * **How it works:**
15
15
  * - When a document is indexed, we ensure all its imports are also loaded
16
16
  * - Maintains a reverse dependency graph: importedUri → Set<importingUri>
17
+ * - Also tracks import specifiers to detect when file moves affect resolution
17
18
  * - Overrides `isAffected()` to also check this graph
18
19
  * - This integrates with Langium's native `DocumentBuilder.update()` flow
19
20
  *
@@ -31,6 +32,13 @@ export declare class DomainLangIndexManager extends DefaultIndexManager {
31
32
  * Value: Set of URIs of documents that import the key document
32
33
  */
33
34
  private readonly importDependencies;
35
+ /**
36
+ * Maps document URI to its import specifiers and their resolved URIs.
37
+ * Used to detect when file moves could affect import resolution.
38
+ * Key: importing document URI
39
+ * Value: Map of import specifier → resolved URI
40
+ */
41
+ private readonly documentImportSpecifiers;
34
42
  /**
35
43
  * Tracks documents that have had their imports loaded to avoid redundant work.
36
44
  * Cleared on workspace config changes.
@@ -68,7 +76,9 @@ export declare class DomainLangIndexManager extends DefaultIndexManager {
68
76
  isAffected(document: LangiumDocument, changedUris: Set<string>): boolean;
69
77
  /**
70
78
  * Tracks import dependencies for a document.
71
- * For each import in the document, records that the imported URI is depended upon.
79
+ * For each import in the document, records:
80
+ * 1. That the imported URI is depended upon (for direct change detection)
81
+ * 2. The import specifier used (for file move detection)
72
82
  */
73
83
  private trackImportDependencies;
74
84
  /**
@@ -99,4 +109,62 @@ export declare class DomainLangIndexManager extends DefaultIndexManager {
99
109
  * Called when a document's content changes.
100
110
  */
101
111
  markForReprocessing(uri: string): void;
112
+ /**
113
+ * Gets all documents that import the given URI.
114
+ * Used to find documents that need rebuilding when a file changes.
115
+ *
116
+ * @param uri - The URI of the changed/deleted file
117
+ * @returns Set of URIs (as strings) of documents that import this file
118
+ */
119
+ getDependentDocuments(uri: string): Set<string>;
120
+ /**
121
+ * Gets the resolved import URIs for a document.
122
+ * Returns only URIs where import resolution succeeded (non-empty resolved URI).
123
+ *
124
+ * @param documentUri - The URI of the document
125
+ * @returns Set of resolved import URIs, or empty set if none
126
+ */
127
+ getResolvedImports(documentUri: string): Set<string>;
128
+ /**
129
+ * Gets all documents that would be affected by changes to the given URIs.
130
+ * This includes direct dependents and transitive dependents.
131
+ *
132
+ * @param changedUris - URIs of changed/deleted files
133
+ * @returns Set of all affected document URIs
134
+ */
135
+ getAllAffectedDocuments(changedUris: Iterable<string>): Set<string>;
136
+ /**
137
+ * Gets documents that have import specifiers which might be affected by file moves.
138
+ *
139
+ * When a file is moved/renamed, import specifiers that previously resolved to it
140
+ * (or could now resolve to it) need to be re-evaluated. This method finds documents
141
+ * whose imports might resolve differently after the file system change.
142
+ *
143
+ * @param changedUris - URIs of changed/deleted/created files
144
+ * @returns Set of document URIs that should be rebuilt
145
+ */
146
+ getDocumentsWithPotentiallyAffectedImports(changedUris: Iterable<string>): Set<string>;
147
+ /**
148
+ * Extracts path segments from URIs for fuzzy matching.
149
+ */
150
+ private extractPathSegments;
151
+ /**
152
+ * Adds path segments from a single URI to the set.
153
+ */
154
+ private addPathSegmentsFromUri;
155
+ /**
156
+ * Finds documents with import specifiers matching any of the given paths.
157
+ */
158
+ private findDocumentsMatchingPaths;
159
+ /**
160
+ * Checks if any specifier OR its resolved URI matches the changed paths.
161
+ *
162
+ * This handles both regular imports and path aliases:
163
+ * - Regular: `./domains/sales.dlang` matches path `sales.dlang`
164
+ * - Aliased: `@domains/sales.dlang` resolves to `/full/path/domains/sales.dlang`
165
+ * When the file moves, the resolved URI matches but the specifier doesn't
166
+ *
167
+ * We check both to ensure moves of aliased imports trigger revalidation.
168
+ */
169
+ private hasMatchingSpecifierOrResolvedUri;
102
170
  }
@@ -14,6 +14,7 @@ import { resolveImportPath } from '../utils/import-utils.js';
14
14
  * **How it works:**
15
15
  * - When a document is indexed, we ensure all its imports are also loaded
16
16
  * - Maintains a reverse dependency graph: importedUri → Set<importingUri>
17
+ * - Also tracks import specifiers to detect when file moves affect resolution
17
18
  * - Overrides `isAffected()` to also check this graph
18
19
  * - This integrates with Langium's native `DocumentBuilder.update()` flow
19
20
  *
@@ -33,6 +34,13 @@ export class DomainLangIndexManager extends DefaultIndexManager {
33
34
  * Value: Set of URIs of documents that import the key document
34
35
  */
35
36
  this.importDependencies = new Map();
37
+ /**
38
+ * Maps document URI to its import specifiers and their resolved URIs.
39
+ * Used to detect when file moves could affect import resolution.
40
+ * Key: importing document URI
41
+ * Value: Map of import specifier → resolved URI
42
+ */
43
+ this.documentImportSpecifiers = new Map();
36
44
  /**
37
45
  * Tracks documents that have had their imports loaded to avoid redundant work.
38
46
  * Cleared on workspace config changes.
@@ -97,13 +105,16 @@ export class DomainLangIndexManager extends DefaultIndexManager {
97
105
  }
98
106
  /**
99
107
  * Tracks import dependencies for a document.
100
- * For each import in the document, records that the imported URI is depended upon.
108
+ * For each import in the document, records:
109
+ * 1. That the imported URI is depended upon (for direct change detection)
110
+ * 2. The import specifier used (for file move detection)
101
111
  */
102
112
  async trackImportDependencies(document) {
103
113
  const importingUri = document.uri.toString();
104
114
  // First, remove old dependencies from this document
105
115
  // (in case imports changed)
106
116
  this.removeDocumentFromDependencies(importingUri);
117
+ this.documentImportSpecifiers.delete(importingUri);
107
118
  // Skip if document isn't ready (no parse result)
108
119
  if (document.state < DocumentState.Parsed) {
109
120
  return;
@@ -112,12 +123,15 @@ export class DomainLangIndexManager extends DefaultIndexManager {
112
123
  if (!model.imports) {
113
124
  return;
114
125
  }
126
+ const specifierMap = new Map();
115
127
  for (const imp of model.imports) {
116
128
  if (!imp.uri)
117
129
  continue;
118
130
  try {
119
131
  const resolvedUri = await resolveImportPath(document, imp.uri);
120
132
  const importedUri = resolvedUri.toString();
133
+ // Track the specifier → resolved URI mapping
134
+ specifierMap.set(imp.uri, importedUri);
121
135
  // Add to reverse dependency graph: importedUri → importingUri
122
136
  let dependents = this.importDependencies.get(importedUri);
123
137
  if (!dependents) {
@@ -127,9 +141,13 @@ export class DomainLangIndexManager extends DefaultIndexManager {
127
141
  dependents.add(importingUri);
128
142
  }
129
143
  catch {
130
- // Import resolution failed - validation will report the error
144
+ // Import resolution failed - still track the specifier with empty resolution
145
+ specifierMap.set(imp.uri, '');
131
146
  }
132
147
  }
148
+ if (specifierMap.size > 0) {
149
+ this.documentImportSpecifiers.set(importingUri, specifierMap);
150
+ }
133
151
  }
134
152
  /**
135
153
  * Ensures all imported documents are loaded and available.
@@ -168,8 +186,10 @@ export class DomainLangIndexManager extends DefaultIndexManager {
168
186
  }
169
187
  // Load or create the imported document
170
188
  const importedDoc = await langiumDocuments.getOrCreateDocument(resolvedUri);
171
- // If document is new (not yet indexed), add to batch
172
- if (importedDoc.state < DocumentState.IndexedContent) {
189
+ // If document is not yet validated, add to batch for building
190
+ // This ensures all imported documents reach Validated state,
191
+ // preventing "workspace state is already Validated" errors
192
+ if (importedDoc.state < DocumentState.Validated) {
173
193
  newDocs.push(importedDoc);
174
194
  }
175
195
  }
@@ -177,7 +197,7 @@ export class DomainLangIndexManager extends DefaultIndexManager {
177
197
  // Import resolution failed - validation will report the error
178
198
  }
179
199
  }
180
- // Build any newly discovered documents
200
+ // Build any newly discovered documents to Validated state
181
201
  // This triggers indexing which will recursively load their imports
182
202
  if (newDocs.length > 0) {
183
203
  await documentBuilder.build(newDocs, { validation: true });
@@ -208,6 +228,7 @@ export class DomainLangIndexManager extends DefaultIndexManager {
208
228
  */
209
229
  clearImportDependencies() {
210
230
  this.importDependencies.clear();
231
+ this.documentImportSpecifiers.clear();
211
232
  this.importsLoaded.clear();
212
233
  }
213
234
  /**
@@ -217,5 +238,152 @@ export class DomainLangIndexManager extends DefaultIndexManager {
217
238
  markForReprocessing(uri) {
218
239
  this.importsLoaded.delete(uri);
219
240
  }
241
+ /**
242
+ * Gets all documents that import the given URI.
243
+ * Used to find documents that need rebuilding when a file changes.
244
+ *
245
+ * @param uri - The URI of the changed/deleted file
246
+ * @returns Set of URIs (as strings) of documents that import this file
247
+ */
248
+ getDependentDocuments(uri) {
249
+ return this.importDependencies.get(uri) ?? new Set();
250
+ }
251
+ /**
252
+ * Gets the resolved import URIs for a document.
253
+ * Returns only URIs where import resolution succeeded (non-empty resolved URI).
254
+ *
255
+ * @param documentUri - The URI of the document
256
+ * @returns Set of resolved import URIs, or empty set if none
257
+ */
258
+ getResolvedImports(documentUri) {
259
+ const specifierMap = this.documentImportSpecifiers.get(documentUri);
260
+ if (!specifierMap) {
261
+ return new Set();
262
+ }
263
+ const resolved = new Set();
264
+ for (const resolvedUri of specifierMap.values()) {
265
+ // Only include successfully resolved imports (non-empty string)
266
+ if (resolvedUri) {
267
+ resolved.add(resolvedUri);
268
+ }
269
+ }
270
+ return resolved;
271
+ }
272
+ /**
273
+ * Gets all documents that would be affected by changes to the given URIs.
274
+ * This includes direct dependents and transitive dependents.
275
+ *
276
+ * @param changedUris - URIs of changed/deleted files
277
+ * @returns Set of all affected document URIs
278
+ */
279
+ getAllAffectedDocuments(changedUris) {
280
+ const affected = new Set();
281
+ const toProcess = [...changedUris];
282
+ while (toProcess.length > 0) {
283
+ const uri = toProcess.pop();
284
+ if (!uri) {
285
+ continue;
286
+ }
287
+ const dependents = this.importDependencies.get(uri);
288
+ if (dependents) {
289
+ for (const dep of dependents) {
290
+ if (!affected.has(dep)) {
291
+ affected.add(dep);
292
+ // Also check transitive dependents
293
+ toProcess.push(dep);
294
+ }
295
+ }
296
+ }
297
+ }
298
+ return affected;
299
+ }
300
+ /**
301
+ * Gets documents that have import specifiers which might be affected by file moves.
302
+ *
303
+ * When a file is moved/renamed, import specifiers that previously resolved to it
304
+ * (or could now resolve to it) need to be re-evaluated. This method finds documents
305
+ * whose imports might resolve differently after the file system change.
306
+ *
307
+ * @param changedUris - URIs of changed/deleted/created files
308
+ * @returns Set of document URIs that should be rebuilt
309
+ */
310
+ getDocumentsWithPotentiallyAffectedImports(changedUris) {
311
+ const changedPaths = this.extractPathSegments(changedUris);
312
+ return this.findDocumentsMatchingPaths(changedPaths);
313
+ }
314
+ /**
315
+ * Extracts path segments from URIs for fuzzy matching.
316
+ */
317
+ extractPathSegments(uris) {
318
+ const paths = new Set();
319
+ for (const uri of uris) {
320
+ this.addPathSegmentsFromUri(uri, paths);
321
+ }
322
+ return paths;
323
+ }
324
+ /**
325
+ * Adds path segments from a single URI to the set.
326
+ */
327
+ addPathSegmentsFromUri(uri, paths) {
328
+ try {
329
+ const url = new URL(uri);
330
+ const pathParts = url.pathname.split('/').filter(p => p.length > 0);
331
+ // Add filename
332
+ const fileName = pathParts.at(-1);
333
+ if (fileName) {
334
+ paths.add(fileName);
335
+ }
336
+ // Add parent/filename combination
337
+ if (pathParts.length >= 2) {
338
+ paths.add(pathParts.slice(-2).join('/'));
339
+ }
340
+ // Add grandparent/parent/filename combination
341
+ if (pathParts.length >= 3) {
342
+ paths.add(pathParts.slice(-3).join('/'));
343
+ }
344
+ }
345
+ catch {
346
+ // Invalid URI, skip
347
+ }
348
+ }
349
+ /**
350
+ * Finds documents with import specifiers matching any of the given paths.
351
+ */
352
+ findDocumentsMatchingPaths(changedPaths) {
353
+ const affected = new Set();
354
+ for (const [docUri, specifierMap] of this.documentImportSpecifiers) {
355
+ if (this.hasMatchingSpecifierOrResolvedUri(specifierMap, changedPaths)) {
356
+ affected.add(docUri);
357
+ }
358
+ }
359
+ return affected;
360
+ }
361
+ /**
362
+ * Checks if any specifier OR its resolved URI matches the changed paths.
363
+ *
364
+ * This handles both regular imports and path aliases:
365
+ * - Regular: `./domains/sales.dlang` matches path `sales.dlang`
366
+ * - Aliased: `@domains/sales.dlang` resolves to `/full/path/domains/sales.dlang`
367
+ * When the file moves, the resolved URI matches but the specifier doesn't
368
+ *
369
+ * We check both to ensure moves of aliased imports trigger revalidation.
370
+ */
371
+ hasMatchingSpecifierOrResolvedUri(specifierMap, changedPaths) {
372
+ for (const [specifier, resolvedUri] of specifierMap.entries()) {
373
+ const normalizedSpecifier = specifier.replace(/^[.@/]+/, '');
374
+ for (const changedPath of changedPaths) {
375
+ // Check the raw specifier (handles relative imports)
376
+ if (specifier.includes(changedPath) || changedPath.endsWith(normalizedSpecifier)) {
377
+ return true;
378
+ }
379
+ // Check the resolved URI (handles path aliases like @domains/...)
380
+ // The resolved URI contains the full file path which matches moved files
381
+ if (resolvedUri?.includes(changedPath)) {
382
+ return true;
383
+ }
384
+ }
385
+ }
386
+ return false;
387
+ }
220
388
  }
221
389
  //# sourceMappingURL=domain-lang-index-manager.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"domain-lang-index-manager.js","sourceRoot":"","sources":["../../src/lsp/domain-lang-index-manager.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,mBAAmB,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAC7D,OAAO,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AACnD,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAG7D;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,MAAM,OAAO,sBAAuB,SAAQ,mBAAmB;IAmB3D,YAAY,QAAmC;QAC3C,KAAK,CAAC,QAAQ,CAAC,CAAC;QAnBpB;;;;WAIG;QACc,uBAAkB,GAAG,IAAI,GAAG,EAAuB,CAAC;QAErE;;;WAGG;QACc,kBAAa,GAAG,IAAI,GAAG,EAAU,CAAC;QAS/C,IAAI,CAAC,cAAc,GAAG,QAAQ,CAAC;IACnC,CAAC;IAED;;;;;;;OAOG;IACM,KAAK,CAAC,aAAa,CAAC,QAAyB,EAAE,WAAW,GAAG,iBAAiB,CAAC,IAAI;QACxF,0CAA0C;QAC1C,MAAM,KAAK,CAAC,aAAa,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAC;QAEjD,yDAAyD;QACzD,MAAM,IAAI,CAAC,mBAAmB,CAAC,QAAQ,CAAC,CAAC;QACzC,MAAM,IAAI,CAAC,uBAAuB,CAAC,QAAQ,CAAC,CAAC;IACjD,CAAC;IAED;;OAEG;IACM,MAAM,CAAC,GAAQ;QACpB,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QAClB,MAAM,SAAS,GAAG,GAAG,CAAC,QAAQ,EAAE,CAAC;QACjC,IAAI,CAAC,wBAAwB,CAAC,SAAS,CAAC,CAAC;QACzC,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;IACzC,CAAC;IAED;;OAEG;IACM,aAAa,CAAC,GAAQ;QAC3B,KAAK,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC;QACzB,MAAM,SAAS,GAAG,GAAG,CAAC,QAAQ,EAAE,CAAC;QACjC,IAAI,CAAC,wBAAwB,CAAC,SAAS,CAAC,CAAC;QACzC,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;IACzC,CAAC;IAED;;;;;;OAMG;IACM,UAAU,CAAC,QAAyB,EAAE,WAAwB;QACnE,kDAAkD;QAClD,IAAI,KAAK,CAAC,UAAU,CAAC,QAAQ,EAAE,WAAW,CAAC,EAAE,CAAC;YAC1C,OAAO,IAAI,CAAC;QAChB,CAAC;QAED,qCAAqC;QACrC,MAAM,MAAM,GAAG,QAAQ,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC;QACvC,KAAK,MAAM,UAAU,IAAI,WAAW,EAAE,CAAC;YACnC,MAAM,UAAU,GAAG,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;YAC3D,IAAI,UAAU,EAAE,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;gBAC1B,OAAO,IAAI,CAAC;YAChB,CAAC;QACL,CAAC;QAED,OAAO,KAAK,CAAC;IACjB,CAAC;IAED;;;OAGG;IACK,KAAK,CAAC,uBAAuB,CAAC,QAAyB;QAC3D,MAAM,YAAY,GAAG,QAAQ,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC;QAE7C,oDAAoD;QACpD,4BAA4B;QAC5B,IAAI,CAAC,8BAA8B,CAAC,YAAY,CAAC,CAAC;QAElD,iDAAiD;QACjD,IAAI,QAAQ,CAAC,KAAK,GAAG,aAAa,CAAC,MAAM,EAAE,CAAC;YACxC,OAAO;QACX,CAAC;QAED,MAAM,KAAK,GAAG,QAAQ,CAAC,WAAW,CAAC,KAAyB,CAAC;QAC7D,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC;YACjB,OAAO;QACX,CAAC;QAED,KAAK,MAAM,GAAG,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC;YAC9B,IAAI,CAAC,GAAG,CAAC,GAAG;gBAAE,SAAS;YAEvB,IAAI,CAAC;gBACD,MAAM,WAAW,GAAG,MAAM,iBAAiB,CAAC,QAAQ,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC;gBAC/D,MAAM,WAAW,GAAG,WAAW,CAAC,QAAQ,EAAE,CAAC;gBAE3C,8DAA8D;gBAC9D,IAAI,UAAU,GAAG,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;gBAC1D,IAAI,CAAC,UAAU,EAAE,CAAC;oBACd,UAAU,GAAG,IAAI,GAAG,EAAE,CAAC;oBACvB,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAAC,WAAW,EAAE,UAAU,CAAC,CAAC;gBACzD,CAAC;gBACD,UAAU,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;YACjC,CAAC;YAAC,MAAM,CAAC;gBACL,8DAA8D;YAClE,CAAC;QACL,CAAC;IACL,CAAC;IAED;;;;;;OAMG;IACK,KAAK,CAAC,mBAAmB,CAAC,QAAyB;QACvD,MAAM,SAAS,GAAG,QAAQ,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC;QAE1C,sEAAsE;QACtE,IAAI,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC;YACpC,OAAO;QACX,CAAC;QACD,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QAElC,iDAAiD;QACjD,IAAI,QAAQ,CAAC,KAAK,GAAG,aAAa,CAAC,MAAM,EAAE,CAAC;YACxC,OAAO;QACX,CAAC;QAED,MAAM,KAAK,GAAG,QAAQ,CAAC,WAAW,CAAC,KAAyB,CAAC;QAC7D,IAAI,CAAC,KAAK,CAAC,OAAO,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC/C,OAAO;QACX,CAAC;QAED,MAAM,gBAAgB,GAAG,IAAI,CAAC,cAAc,CAAC,SAAS,CAAC,gBAAgB,CAAC;QACxE,MAAM,eAAe,GAAG,IAAI,CAAC,cAAc,CAAC,SAAS,CAAC,eAAe,CAAC;QACtE,MAAM,OAAO,GAAsB,EAAE,CAAC;QAEtC,KAAK,MAAM,GAAG,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC;YAC9B,IAAI,CAAC,GAAG,CAAC,GAAG;gBAAE,SAAS;YAEvB,IAAI,CAAC;gBACD,MAAM,WAAW,GAAG,MAAM,iBAAiB,CAAC,QAAQ,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC;gBAC/D,MAAM,iBAAiB,GAAG,WAAW,CAAC,QAAQ,EAAE,CAAC;gBAEjD,yBAAyB;gBACzB,IAAI,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,iBAAiB,CAAC,EAAE,CAAC;oBAC5C,SAAS;gBACb,CAAC;gBAED,uCAAuC;gBACvC,MAAM,WAAW,GAAG,MAAM,gBAAgB,CAAC,mBAAmB,CAAC,WAAW,CAAC,CAAC;gBAE5E,qDAAqD;gBACrD,IAAI,WAAW,CAAC,KAAK,GAAG,aAAa,CAAC,cAAc,EAAE,CAAC;oBACnD,OAAO,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;gBAC9B,CAAC;YACL,CAAC;YAAC,MAAM,CAAC;gBACL,8DAA8D;YAClE,CAAC;QACL,CAAC;QAED,uCAAuC;QACvC,mEAAmE;QACnE,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACrB,MAAM,eAAe,CAAC,KAAK,CAAC,OAAO,EAAE,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC,CAAC;QAC/D,CAAC;IACL,CAAC;IAED;;;OAGG;IACK,wBAAwB,CAAC,GAAW;QACxC,iCAAiC;QACjC,IAAI,CAAC,kBAAkB,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QAEpC,mDAAmD;QACnD,IAAI,CAAC,8BAA8B,CAAC,GAAG,CAAC,CAAC;IAC7C,CAAC;IAED;;;OAGG;IACK,8BAA8B,CAAC,GAAW;QAC9C,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,kBAAkB,CAAC,MAAM,EAAE,EAAE,CAAC;YAClD,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QACrB,CAAC;IACL,CAAC;IAED;;;OAGG;IACH,uBAAuB;QACnB,IAAI,CAAC,kBAAkB,CAAC,KAAK,EAAE,CAAC;QAChC,IAAI,CAAC,aAAa,CAAC,KAAK,EAAE,CAAC;IAC/B,CAAC;IAED;;;OAGG;IACH,mBAAmB,CAAC,GAAW;QAC3B,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IACnC,CAAC;CACJ"}
1
+ {"version":3,"file":"domain-lang-index-manager.js","sourceRoot":"","sources":["../../src/lsp/domain-lang-index-manager.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,67 @@
1
+ /**
2
+ * DomainLang Scope Provider
3
+ *
4
+ * Implements import-based scoping for the DomainLang DSL.
5
+ *
6
+ * **Key Concept:**
7
+ * Unlike languages with global namespaces, DomainLang enforces strict import-based scoping:
8
+ * - Elements are only visible if they are defined in the current document OR explicitly imported
9
+ * - The global scope is restricted to imported documents only
10
+ * - Transitive imports do NOT provide scope (only direct imports)
11
+ *
12
+ * **Why this matters:**
13
+ * Without this, Langium's DefaultScopeProvider would make ALL indexed documents visible
14
+ * in the global scope, which would:
15
+ * 1. Allow referencing elements that haven't been imported
16
+ * 2. Make the import system meaningless
17
+ * 3. Create confusion about dependencies between files
18
+ *
19
+ * @see https://langium.org/docs/recipes/scoping/ for Langium scoping patterns
20
+ */
21
+ import type { ReferenceInfo, Scope } from 'langium';
22
+ import { DefaultScopeProvider } from 'langium';
23
+ import type { DomainLangServices } from '../domain-lang-module.js';
24
+ /**
25
+ * Custom scope provider that restricts cross-file references to imported documents only.
26
+ *
27
+ * Extends Langium's DefaultScopeProvider to override the global scope computation.
28
+ */
29
+ export declare class DomainLangScopeProvider extends DefaultScopeProvider {
30
+ /**
31
+ * Reference to IndexManager for getting resolved imports.
32
+ */
33
+ private readonly domainLangIndexManager;
34
+ constructor(services: DomainLangServices);
35
+ /**
36
+ * Override getGlobalScope to restrict it to imported documents only.
37
+ *
38
+ * The default Langium behavior includes ALL documents in the workspace.
39
+ * We restrict this to:
40
+ * 1. The current document's own exported symbols
41
+ * 2. Exported symbols from directly imported documents
42
+ *
43
+ * @param referenceType - The AST type being referenced
44
+ * @param context - Information about the reference
45
+ * @returns A scope containing only visible elements
46
+ */
47
+ protected getGlobalScope(referenceType: string, context: ReferenceInfo): Scope;
48
+ /**
49
+ * Gets the set of document URIs that are directly imported by the given document.
50
+ *
51
+ * Uses the resolved imports tracked by DomainLangIndexManager during indexing.
52
+ * This ensures accurate resolution including path aliases.
53
+ *
54
+ * @param document - The document to get imports for
55
+ * @returns Set of imported document URIs (as strings)
56
+ */
57
+ private getImportedDocumentUris;
58
+ /**
59
+ * Filters the global index to only include descriptions from imported documents.
60
+ *
61
+ * @param referenceType - The AST type being referenced
62
+ * @param currentDocument - The document making the reference
63
+ * @param importedUris - Set of URIs that are in scope
64
+ * @returns Stream of filtered descriptions
65
+ */
66
+ private filterDescriptionsByImports;
67
+ }
@@ -0,0 +1,95 @@
1
+ /**
2
+ * DomainLang Scope Provider
3
+ *
4
+ * Implements import-based scoping for the DomainLang DSL.
5
+ *
6
+ * **Key Concept:**
7
+ * Unlike languages with global namespaces, DomainLang enforces strict import-based scoping:
8
+ * - Elements are only visible if they are defined in the current document OR explicitly imported
9
+ * - The global scope is restricted to imported documents only
10
+ * - Transitive imports do NOT provide scope (only direct imports)
11
+ *
12
+ * **Why this matters:**
13
+ * Without this, Langium's DefaultScopeProvider would make ALL indexed documents visible
14
+ * in the global scope, which would:
15
+ * 1. Allow referencing elements that haven't been imported
16
+ * 2. Make the import system meaningless
17
+ * 3. Create confusion about dependencies between files
18
+ *
19
+ * @see https://langium.org/docs/recipes/scoping/ for Langium scoping patterns
20
+ */
21
+ import { AstUtils, DefaultScopeProvider, EMPTY_SCOPE, MapScope } from 'langium';
22
+ /**
23
+ * Custom scope provider that restricts cross-file references to imported documents only.
24
+ *
25
+ * Extends Langium's DefaultScopeProvider to override the global scope computation.
26
+ */
27
+ export class DomainLangScopeProvider extends DefaultScopeProvider {
28
+ constructor(services) {
29
+ super(services);
30
+ this.domainLangIndexManager = services.shared.workspace.IndexManager;
31
+ }
32
+ /**
33
+ * Override getGlobalScope to restrict it to imported documents only.
34
+ *
35
+ * The default Langium behavior includes ALL documents in the workspace.
36
+ * We restrict this to:
37
+ * 1. The current document's own exported symbols
38
+ * 2. Exported symbols from directly imported documents
39
+ *
40
+ * @param referenceType - The AST type being referenced
41
+ * @param context - Information about the reference
42
+ * @returns A scope containing only visible elements
43
+ */
44
+ getGlobalScope(referenceType, context) {
45
+ const document = AstUtils.getDocument(context.container);
46
+ if (!document) {
47
+ return EMPTY_SCOPE;
48
+ }
49
+ // Get the set of URIs that are in scope for this document
50
+ const importedUris = this.getImportedDocumentUris(document);
51
+ // Filter the global index to only include descriptions from imported documents
52
+ const filteredDescriptions = this.filterDescriptionsByImports(referenceType, document, importedUris);
53
+ // Create a scope from the filtered descriptions
54
+ return new MapScope(filteredDescriptions);
55
+ }
56
+ /**
57
+ * Gets the set of document URIs that are directly imported by the given document.
58
+ *
59
+ * Uses the resolved imports tracked by DomainLangIndexManager during indexing.
60
+ * This ensures accurate resolution including path aliases.
61
+ *
62
+ * @param document - The document to get imports for
63
+ * @returns Set of imported document URIs (as strings)
64
+ */
65
+ getImportedDocumentUris(document) {
66
+ const docUri = document.uri.toString();
67
+ // Get resolved imports from the index manager (tracked during indexing)
68
+ const resolvedImports = this.domainLangIndexManager.getResolvedImports(docUri);
69
+ // Always include the current document itself
70
+ const importedUris = new Set([docUri]);
71
+ // Add all resolved import URIs
72
+ for (const resolvedUri of resolvedImports) {
73
+ importedUris.add(resolvedUri);
74
+ }
75
+ return importedUris;
76
+ }
77
+ /**
78
+ * Filters the global index to only include descriptions from imported documents.
79
+ *
80
+ * @param referenceType - The AST type being referenced
81
+ * @param currentDocument - The document making the reference
82
+ * @param importedUris - Set of URIs that are in scope
83
+ * @returns Stream of filtered descriptions
84
+ */
85
+ filterDescriptionsByImports(referenceType, currentDocument, importedUris) {
86
+ // Get all descriptions of the reference type from the index
87
+ const allDescriptions = this.indexManager.allElements(referenceType);
88
+ // Filter to only those from imported documents
89
+ return allDescriptions.filter(desc => {
90
+ const descDocUri = desc.documentUri.toString();
91
+ return importedUris.has(descDocUri);
92
+ });
93
+ }
94
+ }
95
+ //# sourceMappingURL=domain-lang-scope-provider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"domain-lang-scope-provider.js","sourceRoot":"","sources":["../../src/lsp/domain-lang-scope-provider.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AASH,OAAO,EACH,QAAQ,EACR,oBAAoB,EACpB,WAAW,EACX,QAAQ,EACX,MAAM,SAAS,CAAC;AAIjB;;;;GAIG;AACH,MAAM,OAAO,uBAAwB,SAAQ,oBAAoB;IAM7D,YAAY,QAA4B;QACpC,KAAK,CAAC,QAAQ,CAAC,CAAC;QAChB,IAAI,CAAC,sBAAsB,GAAG,QAAQ,CAAC,MAAM,CAAC,SAAS,CAAC,YAAsC,CAAC;IACnG,CAAC;IAED;;;;;;;;;;;OAWG;IACgB,cAAc,CAAC,aAAqB,EAAE,OAAsB;QAC3E,MAAM,QAAQ,GAAG,QAAQ,CAAC,WAAW,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;QACzD,IAAI,CAAC,QAAQ,EAAE,CAAC;YACZ,OAAO,WAAW,CAAC;QACvB,CAAC;QAED,0DAA0D;QAC1D,MAAM,YAAY,GAAG,IAAI,CAAC,uBAAuB,CAAC,QAAQ,CAAC,CAAC;QAE5D,+EAA+E;QAC/E,MAAM,oBAAoB,GAAG,IAAI,CAAC,2BAA2B,CACzD,aAAa,EACb,QAAQ,EACR,YAAY,CACf,CAAC;QAEF,gDAAgD;QAChD,OAAO,IAAI,QAAQ,CAAC,oBAAoB,CAAC,CAAC;IAC9C,CAAC;IAED;;;;;;;;OAQG;IACK,uBAAuB,CAAC,QAAyB;QACrD,MAAM,MAAM,GAAG,QAAQ,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC;QAEvC,wEAAwE;QACxE,MAAM,eAAe,GAAG,IAAI,CAAC,sBAAsB,CAAC,kBAAkB,CAAC,MAAM,CAAC,CAAC;QAE/E,6CAA6C;QAC7C,MAAM,YAAY,GAAG,IAAI,GAAG,CAAS,CAAC,MAAM,CAAC,CAAC,CAAC;QAE/C,+BAA+B;QAC/B,KAAK,MAAM,WAAW,IAAI,eAAe,EAAE,CAAC;YACxC,YAAY,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;QAClC,CAAC;QAED,OAAO,YAAY,CAAC;IACxB,CAAC;IAED;;;;;;;OAOG;IACK,2BAA2B,CAC/B,aAAqB,EACrB,eAAgC,EAChC,YAAyB;QAEzB,4DAA4D;QAC5D,MAAM,eAAe,GAAG,IAAI,CAAC,YAAY,CAAC,WAAW,CAAC,aAAa,CAAC,CAAC;QAErE,+CAA+C;QAC/C,OAAO,eAAe,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE;YACjC,MAAM,UAAU,GAAG,IAAI,CAAC,WAAW,CAAC,QAAQ,EAAE,CAAC;YAC/C,OAAO,YAAY,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;QACxC,CAAC,CAAC,CAAC;IACP,CAAC;CACJ"}
@@ -52,6 +52,31 @@ export declare class DomainLangWorkspaceManager extends DefaultWorkspaceManager
52
52
  shouldIncludeEntry(entry: FileSystemNode): boolean;
53
53
  initializeWorkspace(folders: WorkspaceFolder[], cancelToken?: CancellationToken): Promise<void>;
54
54
  protected loadAdditionalDocuments(folders: WorkspaceFolder[], collector: (document: LangiumDocument) => void): Promise<void>;
55
+ /**
56
+ * Loads standalone .dlang files from workspace folders recursively.
57
+ *
58
+ * Skips:
59
+ * - Module directories (directories with model.yaml) - loaded via import graph
60
+ * - `.dlang/cache` directory - package cache managed by CLI
61
+ *
62
+ * @param folders - Workspace folders to scan
63
+ * @param moduleDirectories - Set of directories containing model.yaml (to skip)
64
+ * @param collector - Document collector callback
65
+ */
66
+ private loadStandaloneFiles;
67
+ /**
68
+ * Recursively loads .dlang files from a directory.
69
+ * Skips module directories and the .dlang/cache package cache.
70
+ */
71
+ private loadDlangFilesRecursively;
72
+ /**
73
+ * Checks if a directory entry is a .dlang file.
74
+ */
75
+ private isDlangFile;
76
+ /**
77
+ * Attempts to load a document, returning undefined on failure.
78
+ */
79
+ private tryLoadDocument;
55
80
  /**
56
81
  * Finds ALL model.yaml files in the workspace.
57
82
  * Delegates to shared manifest utilities.