@domainlang/language 0.7.0 → 0.9.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/out/domain-lang-module.d.ts +2 -0
- package/out/domain-lang-module.js +21 -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 +34 -5
- package/out/lsp/domain-lang-index-manager.js +66 -27
- 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 +53 -20
- package/out/lsp/domain-lang-scope-provider.js +119 -44
- package/out/lsp/domain-lang-scope-provider.js.map +1 -1
- package/out/lsp/domain-lang-workspace-manager.d.ts +23 -2
- package/out/lsp/domain-lang-workspace-manager.js +51 -6
- 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 +2 -1
- package/out/main.js.map +1 -1
- package/out/sdk/index.d.ts +31 -11
- package/out/sdk/index.js +30 -11
- package/out/sdk/index.js.map +1 -1
- package/out/sdk/loader-node.d.ts +2 -0
- package/out/sdk/loader-node.js +3 -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/sdk/validator.d.ts +134 -0
- package/out/sdk/validator.js +249 -0
- package/out/sdk/validator.js.map +1 -0
- 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 +7 -0
- package/out/validation/constants.js +21 -3
- package/out/validation/constants.js.map +1 -1
- package/out/validation/import.d.ts +11 -1
- package/out/validation/import.js +42 -14
- package/out/validation/import.js.map +1 -1
- package/out/validation/maps.js +50 -1
- package/out/validation/maps.js.map +1 -1
- package/package.json +8 -9
- package/src/domain-lang-module.ts +24 -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 +79 -27
- package/src/lsp/domain-lang-node-kind-provider.ts +119 -0
- package/src/lsp/domain-lang-scope-provider.ts +171 -55
- package/src/lsp/domain-lang-workspace-manager.ts +64 -6
- package/src/lsp/hover/domain-lang-hover.ts +189 -131
- package/src/lsp/hover/hover-builders.ts +208 -0
- package/src/main.ts +3 -1
- package/src/sdk/index.ts +33 -11
- package/src/sdk/loader-node.ts +6 -1
- package/src/sdk/loader.ts +125 -34
- package/src/sdk/query.ts +15 -11
- package/src/sdk/validator.ts +358 -0
- 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 +23 -6
- package/src/validation/import.ts +49 -14
- package/src/validation/maps.ts +59 -2
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Model validation utilities for Node.js environments.
|
|
3
|
+
*
|
|
4
|
+
* **WARNING: This module is NOT browser-compatible.**
|
|
5
|
+
*
|
|
6
|
+
* Provides validation capabilities that leverage the LSP infrastructure
|
|
7
|
+
* for workspace initialization, import resolution, and document building.
|
|
8
|
+
*
|
|
9
|
+
* @module sdk/validator
|
|
10
|
+
*/
|
|
11
|
+
import { NodeFileSystem } from 'langium/node';
|
|
12
|
+
import { URI } from 'langium';
|
|
13
|
+
import { createDomainLangServices } from '../domain-lang-module.js';
|
|
14
|
+
import { ensureImportGraphFromDocument } from '../utils/import-utils.js';
|
|
15
|
+
import { isModel } from '../generated/ast.js';
|
|
16
|
+
import { dirname, resolve, join } from 'node:path';
|
|
17
|
+
import { existsSync } from 'node:fs';
|
|
18
|
+
/**
|
|
19
|
+
* Convert Langium diagnostic to ValidationDiagnostic.
|
|
20
|
+
*/
|
|
21
|
+
function toValidationDiagnostic(diagnostic, file) {
|
|
22
|
+
return {
|
|
23
|
+
severity: diagnostic.severity ?? 1,
|
|
24
|
+
message: diagnostic.message,
|
|
25
|
+
file,
|
|
26
|
+
line: diagnostic.range.start.line + 1,
|
|
27
|
+
column: diagnostic.range.start.character + 1,
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Validates a DomainLang model file and all its imports.
|
|
32
|
+
*
|
|
33
|
+
* Uses the LSP infrastructure to:
|
|
34
|
+
* - Initialize the workspace
|
|
35
|
+
* - Resolve and load imports
|
|
36
|
+
* - Build and validate all documents
|
|
37
|
+
*
|
|
38
|
+
* @param filePath - Path to the entry .dlang file
|
|
39
|
+
* @param options - Validation options
|
|
40
|
+
* @returns Validation result with errors, warnings, and model statistics
|
|
41
|
+
* @throws Error if file doesn't exist or has invalid extension
|
|
42
|
+
*
|
|
43
|
+
* @example
|
|
44
|
+
* ```typescript
|
|
45
|
+
* import { validateFile } from '@domainlang/language/sdk';
|
|
46
|
+
*
|
|
47
|
+
* const result = await validateFile('./index.dlang');
|
|
48
|
+
*
|
|
49
|
+
* if (!result.valid) {
|
|
50
|
+
* for (const err of result.errors) {
|
|
51
|
+
* console.error(`${err.file}:${err.line}:${err.column}: ${err.message}`);
|
|
52
|
+
* }
|
|
53
|
+
* process.exit(1);
|
|
54
|
+
* }
|
|
55
|
+
*
|
|
56
|
+
* console.log(`✓ Validated ${result.fileCount} files`);
|
|
57
|
+
* console.log(` ${result.domainCount} domains, ${result.bcCount} bounded contexts`);
|
|
58
|
+
* ```
|
|
59
|
+
*/
|
|
60
|
+
export async function validateFile(filePath, options = {}) {
|
|
61
|
+
// Resolve absolute path
|
|
62
|
+
const absolutePath = resolve(filePath);
|
|
63
|
+
// Check file exists
|
|
64
|
+
if (!existsSync(absolutePath)) {
|
|
65
|
+
throw new Error(`File not found: ${filePath}`);
|
|
66
|
+
}
|
|
67
|
+
// Create services with workspace support
|
|
68
|
+
const servicesObj = createDomainLangServices(NodeFileSystem);
|
|
69
|
+
const shared = servicesObj.shared;
|
|
70
|
+
const services = servicesObj.DomainLang;
|
|
71
|
+
// Check file extension
|
|
72
|
+
const extensions = services.LanguageMetaData.fileExtensions;
|
|
73
|
+
if (!extensions.some(ext => absolutePath.endsWith(ext))) {
|
|
74
|
+
throw new Error(`Invalid file extension. Expected: ${extensions.join(', ')}`);
|
|
75
|
+
}
|
|
76
|
+
// Initialize workspace with the specified directory or file's directory
|
|
77
|
+
const workspaceDir = options.workspaceDir ?? dirname(absolutePath);
|
|
78
|
+
const workspaceManager = services.imports.WorkspaceManager;
|
|
79
|
+
await workspaceManager.initialize(workspaceDir);
|
|
80
|
+
// Load and parse the document
|
|
81
|
+
const uri = URI.file(absolutePath);
|
|
82
|
+
const document = await shared.workspace.LangiumDocuments.getOrCreateDocument(uri);
|
|
83
|
+
// Build document initially without validation to load imports
|
|
84
|
+
await shared.workspace.DocumentBuilder.build([document], { validation: false });
|
|
85
|
+
// Load all imported documents via the import graph
|
|
86
|
+
const importResolver = services.imports.ImportResolver;
|
|
87
|
+
await ensureImportGraphFromDocument(document, shared.workspace.LangiumDocuments, importResolver);
|
|
88
|
+
// Build all documents with validation enabled
|
|
89
|
+
const allDocuments = Array.from(shared.workspace.LangiumDocuments.all);
|
|
90
|
+
await shared.workspace.DocumentBuilder.build(allDocuments, { validation: true });
|
|
91
|
+
// Collect diagnostics from the entry document
|
|
92
|
+
const diagnostics = document.diagnostics ?? [];
|
|
93
|
+
const errors = [];
|
|
94
|
+
const warnings = [];
|
|
95
|
+
for (const diagnostic of diagnostics) {
|
|
96
|
+
const validationDiag = toValidationDiagnostic(diagnostic, absolutePath);
|
|
97
|
+
if (diagnostic.severity === 1) {
|
|
98
|
+
errors.push(validationDiag);
|
|
99
|
+
}
|
|
100
|
+
else if (diagnostic.severity === 2) {
|
|
101
|
+
warnings.push(validationDiag);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
// Count model elements across all documents
|
|
105
|
+
let domainCount = 0;
|
|
106
|
+
let bcCount = 0;
|
|
107
|
+
for (const doc of allDocuments) {
|
|
108
|
+
const model = doc.parseResult?.value;
|
|
109
|
+
if (isModel(model)) {
|
|
110
|
+
for (const element of model.children ?? []) {
|
|
111
|
+
if (element.$type === 'Domain') {
|
|
112
|
+
domainCount++;
|
|
113
|
+
}
|
|
114
|
+
else if (element.$type === 'BoundedContext') {
|
|
115
|
+
bcCount++;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
return {
|
|
121
|
+
valid: errors.length === 0,
|
|
122
|
+
fileCount: allDocuments.length,
|
|
123
|
+
domainCount,
|
|
124
|
+
bcCount,
|
|
125
|
+
errors,
|
|
126
|
+
warnings,
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Validates an entire DomainLang workspace.
|
|
131
|
+
*
|
|
132
|
+
* Uses the LSP infrastructure to:
|
|
133
|
+
* - Initialize the workspace from a directory containing model.yaml
|
|
134
|
+
* - Load the entry file (from manifest or default index.dlang)
|
|
135
|
+
* - Resolve and load all imports
|
|
136
|
+
* - Build and validate all documents in the workspace
|
|
137
|
+
* - Collect diagnostics from ALL documents (like VS Code Problems pane)
|
|
138
|
+
*
|
|
139
|
+
* @param workspaceDir - Path to the workspace directory (containing model.yaml)
|
|
140
|
+
* @returns Validation result with diagnostics from all files
|
|
141
|
+
* @throws Error if workspace directory doesn't exist or cannot be loaded
|
|
142
|
+
*
|
|
143
|
+
* @example
|
|
144
|
+
* ```typescript
|
|
145
|
+
* import { validateWorkspace } from '@domainlang/language/sdk';
|
|
146
|
+
*
|
|
147
|
+
* const result = await validateWorkspace('./my-workspace');
|
|
148
|
+
*
|
|
149
|
+
* if (!result.valid) {
|
|
150
|
+
* console.error(`Found ${result.errors.length} errors in ${result.fileCount} files`);
|
|
151
|
+
*
|
|
152
|
+
* for (const err of result.errors) {
|
|
153
|
+
* console.error(`${err.file}:${err.line}:${err.column}: ${err.message}`);
|
|
154
|
+
* }
|
|
155
|
+
* process.exit(1);
|
|
156
|
+
* }
|
|
157
|
+
*
|
|
158
|
+
* console.log(`✓ Validated ${result.fileCount} files`);
|
|
159
|
+
* console.log(` ${result.domainCount} domains, ${result.bcCount} bounded contexts`);
|
|
160
|
+
* console.log(` 0 errors, ${result.warnings.length} warnings`);
|
|
161
|
+
* ```
|
|
162
|
+
*/
|
|
163
|
+
export async function validateWorkspace(workspaceDir) {
|
|
164
|
+
// Resolve absolute path
|
|
165
|
+
const absolutePath = resolve(workspaceDir);
|
|
166
|
+
// Check directory exists
|
|
167
|
+
if (!existsSync(absolutePath)) {
|
|
168
|
+
throw new Error(`Workspace directory not found: ${workspaceDir}`);
|
|
169
|
+
}
|
|
170
|
+
// Create services with workspace support
|
|
171
|
+
const servicesObj = createDomainLangServices(NodeFileSystem);
|
|
172
|
+
const shared = servicesObj.shared;
|
|
173
|
+
const services = servicesObj.DomainLang;
|
|
174
|
+
const workspaceManager = services.imports.WorkspaceManager;
|
|
175
|
+
try {
|
|
176
|
+
// Initialize workspace - this will find and load model.yaml
|
|
177
|
+
await workspaceManager.initialize(absolutePath);
|
|
178
|
+
}
|
|
179
|
+
catch (error) {
|
|
180
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
181
|
+
throw new Error(`Failed to initialize workspace at ${workspaceDir}: ${message}`);
|
|
182
|
+
}
|
|
183
|
+
// Get the manifest to find the entry file
|
|
184
|
+
const manifest = await workspaceManager.getManifest();
|
|
185
|
+
let entryFile = 'index.dlang';
|
|
186
|
+
if (manifest?.model?.entry) {
|
|
187
|
+
entryFile = manifest.model.entry;
|
|
188
|
+
}
|
|
189
|
+
const entryPath = join(absolutePath, entryFile);
|
|
190
|
+
// Check if entry file exists
|
|
191
|
+
if (!existsSync(entryPath)) {
|
|
192
|
+
throw new Error(`Entry file not found: ${entryFile}\n` +
|
|
193
|
+
`Expected at: ${entryPath}\n` +
|
|
194
|
+
(manifest ? `Specified in manifest` : `Using default entry file`));
|
|
195
|
+
}
|
|
196
|
+
// Load and parse the entry document
|
|
197
|
+
const uri = URI.file(entryPath);
|
|
198
|
+
const document = await shared.workspace.LangiumDocuments.getOrCreateDocument(uri);
|
|
199
|
+
// Build document initially without validation to load imports
|
|
200
|
+
await shared.workspace.DocumentBuilder.build([document], { validation: false });
|
|
201
|
+
// Load all imported documents via the import graph
|
|
202
|
+
const importResolver = services.imports.ImportResolver;
|
|
203
|
+
await ensureImportGraphFromDocument(document, shared.workspace.LangiumDocuments, importResolver);
|
|
204
|
+
// Build all documents with validation enabled
|
|
205
|
+
const allDocuments = Array.from(shared.workspace.LangiumDocuments.all);
|
|
206
|
+
await shared.workspace.DocumentBuilder.build(allDocuments, { validation: true });
|
|
207
|
+
// Collect diagnostics from ALL documents (not just entry)
|
|
208
|
+
const errors = [];
|
|
209
|
+
const warnings = [];
|
|
210
|
+
for (const doc of allDocuments) {
|
|
211
|
+
const diagnostics = doc.diagnostics ?? [];
|
|
212
|
+
const docPath = doc.uri.fsPath;
|
|
213
|
+
for (const diagnostic of diagnostics) {
|
|
214
|
+
const validationDiag = toValidationDiagnostic(diagnostic, docPath);
|
|
215
|
+
if (diagnostic.severity === 1) {
|
|
216
|
+
errors.push(validationDiag);
|
|
217
|
+
}
|
|
218
|
+
else if (diagnostic.severity === 2) {
|
|
219
|
+
warnings.push(validationDiag);
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
// Count model elements across all documents
|
|
224
|
+
let domainCount = 0;
|
|
225
|
+
let bcCount = 0;
|
|
226
|
+
for (const doc of allDocuments) {
|
|
227
|
+
const model = doc.parseResult?.value;
|
|
228
|
+
if (isModel(model)) {
|
|
229
|
+
for (const element of model.children ?? []) {
|
|
230
|
+
if (element.$type === 'Domain') {
|
|
231
|
+
domainCount++;
|
|
232
|
+
}
|
|
233
|
+
else if (element.$type === 'BoundedContext') {
|
|
234
|
+
bcCount++;
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
return {
|
|
240
|
+
valid: errors.length === 0,
|
|
241
|
+
fileCount: allDocuments.length,
|
|
242
|
+
domainCount,
|
|
243
|
+
bcCount,
|
|
244
|
+
errors,
|
|
245
|
+
warnings,
|
|
246
|
+
totalDiagnostics: errors.length + warnings.length,
|
|
247
|
+
};
|
|
248
|
+
}
|
|
249
|
+
//# sourceMappingURL=validator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validator.js","sourceRoot":"","sources":["../../src/sdk/validator.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Package Boundary Detector
|
|
3
|
+
*
|
|
4
|
+
* Determines package boundaries for import scoping.
|
|
5
|
+
* Per ADR-003, package boundaries are defined by:
|
|
6
|
+
* - External packages: Files within .dlang/packages/ sharing the same model.yaml
|
|
7
|
+
* - Local files: Each file is its own boundary (non-transitive)
|
|
8
|
+
*
|
|
9
|
+
* Used by DomainLangScopeProvider to enable transitive imports within
|
|
10
|
+
* package boundaries while keeping local file imports non-transitive.
|
|
11
|
+
*/
|
|
12
|
+
import { URI } from 'langium';
|
|
13
|
+
/**
|
|
14
|
+
* Detects and caches package boundaries for efficient scope resolution.
|
|
15
|
+
*/
|
|
16
|
+
export declare class PackageBoundaryDetector {
|
|
17
|
+
/**
|
|
18
|
+
* Cache mapping document URI to its package root path.
|
|
19
|
+
* - External packages: path to directory containing model.yaml
|
|
20
|
+
* - Local files: null (no package boundary)
|
|
21
|
+
*/
|
|
22
|
+
private readonly packageRootCache;
|
|
23
|
+
/**
|
|
24
|
+
* Determines if a document is part of an external package.
|
|
25
|
+
*
|
|
26
|
+
* External packages are stored in .dlang/packages/owner/repo/commit/
|
|
27
|
+
*
|
|
28
|
+
* @param documentUri - The URI of the document to check
|
|
29
|
+
* @returns true if document is in an external package
|
|
30
|
+
*/
|
|
31
|
+
isExternalPackage(documentUri: URI | string): boolean;
|
|
32
|
+
/**
|
|
33
|
+
* Gets the package root for a document.
|
|
34
|
+
*
|
|
35
|
+
* For external packages (.dlang/packages/), walks up from the document
|
|
36
|
+
* to find the nearest model.yaml file within the package structure.
|
|
37
|
+
*
|
|
38
|
+
* For local files, returns null (no package boundary).
|
|
39
|
+
*
|
|
40
|
+
* @param documentUri - The URI of the document
|
|
41
|
+
* @returns Absolute path to package root, or null if not in a package
|
|
42
|
+
*/
|
|
43
|
+
getPackageRoot(documentUri: URI | string): Promise<string | null>;
|
|
44
|
+
/**
|
|
45
|
+
* Checks if two documents are in the same package (synchronous heuristic).
|
|
46
|
+
*
|
|
47
|
+
* This is a fast, synchronous check that compares package commit directories
|
|
48
|
+
* without filesystem access. Documents are in the same package if:
|
|
49
|
+
* - Both are in .dlang/packages/ AND
|
|
50
|
+
* - They share the same owner/repo/commit path
|
|
51
|
+
*
|
|
52
|
+
* This is used by the scope provider which needs synchronous access.
|
|
53
|
+
*
|
|
54
|
+
* Structure: .dlang/packages/owner/repo/commit/...
|
|
55
|
+
*
|
|
56
|
+
* @param doc1Uri - URI of first document
|
|
57
|
+
* @param doc2Uri - URI of second document
|
|
58
|
+
* @returns true if both are in the same package commit directory
|
|
59
|
+
*/
|
|
60
|
+
areInSamePackageSync(doc1Uri: URI | string, doc2Uri: URI | string): boolean;
|
|
61
|
+
/**
|
|
62
|
+
* Gets the package commit directory (owner/repo/commit) from a path.
|
|
63
|
+
*
|
|
64
|
+
* @param fsPath - Filesystem path
|
|
65
|
+
* @returns Commit directory path or null
|
|
66
|
+
*/
|
|
67
|
+
private getPackageCommitDirectory;
|
|
68
|
+
/**
|
|
69
|
+
* Checks if two documents are in the same package.
|
|
70
|
+
*
|
|
71
|
+
* Documents are in the same package if:
|
|
72
|
+
* - Both are external packages AND
|
|
73
|
+
* - They share the same package root (model.yaml location)
|
|
74
|
+
*
|
|
75
|
+
* Local files are never in the same package (each is isolated).
|
|
76
|
+
*
|
|
77
|
+
* @param doc1Uri - URI of first document
|
|
78
|
+
* @param doc2Uri - URI of second document
|
|
79
|
+
* @returns true if both documents are in the same package
|
|
80
|
+
*/
|
|
81
|
+
areInSamePackage(doc1Uri: URI | string, doc2Uri: URI | string): Promise<boolean>;
|
|
82
|
+
/**
|
|
83
|
+
* Finds the package root for an external package by walking up to find model.yaml.
|
|
84
|
+
*
|
|
85
|
+
* External packages have structure: .dlang/packages/owner/repo/commit/...
|
|
86
|
+
* The model.yaml should be at the commit level or just below it.
|
|
87
|
+
*
|
|
88
|
+
* @param fsPath - Filesystem path of the document
|
|
89
|
+
* @returns Path to directory containing model.yaml, or null
|
|
90
|
+
*/
|
|
91
|
+
private findPackageRootForExternal;
|
|
92
|
+
/**
|
|
93
|
+
* Converts a URI to a filesystem path.
|
|
94
|
+
*/
|
|
95
|
+
private toFsPath;
|
|
96
|
+
/**
|
|
97
|
+
* Clears the package root cache.
|
|
98
|
+
* Call this when packages are installed/removed.
|
|
99
|
+
*/
|
|
100
|
+
clearCache(): void;
|
|
101
|
+
}
|
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Package Boundary Detector
|
|
3
|
+
*
|
|
4
|
+
* Determines package boundaries for import scoping.
|
|
5
|
+
* Per ADR-003, package boundaries are defined by:
|
|
6
|
+
* - External packages: Files within .dlang/packages/ sharing the same model.yaml
|
|
7
|
+
* - Local files: Each file is its own boundary (non-transitive)
|
|
8
|
+
*
|
|
9
|
+
* Used by DomainLangScopeProvider to enable transitive imports within
|
|
10
|
+
* package boundaries while keeping local file imports non-transitive.
|
|
11
|
+
*/
|
|
12
|
+
import * as path from 'node:path';
|
|
13
|
+
import * as fs from 'node:fs/promises';
|
|
14
|
+
import { URI } from 'langium';
|
|
15
|
+
/**
|
|
16
|
+
* Detects and caches package boundaries for efficient scope resolution.
|
|
17
|
+
*/
|
|
18
|
+
export class PackageBoundaryDetector {
|
|
19
|
+
constructor() {
|
|
20
|
+
/**
|
|
21
|
+
* Cache mapping document URI to its package root path.
|
|
22
|
+
* - External packages: path to directory containing model.yaml
|
|
23
|
+
* - Local files: null (no package boundary)
|
|
24
|
+
*/
|
|
25
|
+
this.packageRootCache = new Map();
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Determines if a document is part of an external package.
|
|
29
|
+
*
|
|
30
|
+
* External packages are stored in .dlang/packages/owner/repo/commit/
|
|
31
|
+
*
|
|
32
|
+
* @param documentUri - The URI of the document to check
|
|
33
|
+
* @returns true if document is in an external package
|
|
34
|
+
*/
|
|
35
|
+
isExternalPackage(documentUri) {
|
|
36
|
+
const fsPath = this.toFsPath(documentUri);
|
|
37
|
+
const normalized = fsPath.split(path.sep);
|
|
38
|
+
// Check if path contains .dlang/packages/
|
|
39
|
+
const dlangIndex = normalized.indexOf('.dlang');
|
|
40
|
+
if (dlangIndex === -1) {
|
|
41
|
+
return false;
|
|
42
|
+
}
|
|
43
|
+
return dlangIndex + 1 < normalized.length &&
|
|
44
|
+
normalized[dlangIndex + 1] === 'packages';
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Gets the package root for a document.
|
|
48
|
+
*
|
|
49
|
+
* For external packages (.dlang/packages/), walks up from the document
|
|
50
|
+
* to find the nearest model.yaml file within the package structure.
|
|
51
|
+
*
|
|
52
|
+
* For local files, returns null (no package boundary).
|
|
53
|
+
*
|
|
54
|
+
* @param documentUri - The URI of the document
|
|
55
|
+
* @returns Absolute path to package root, or null if not in a package
|
|
56
|
+
*/
|
|
57
|
+
async getPackageRoot(documentUri) {
|
|
58
|
+
const uriString = documentUri.toString();
|
|
59
|
+
// Check cache first
|
|
60
|
+
if (this.packageRootCache.has(uriString)) {
|
|
61
|
+
return this.packageRootCache.get(uriString) ?? null;
|
|
62
|
+
}
|
|
63
|
+
// If not an external package, it has no package boundary
|
|
64
|
+
if (!this.isExternalPackage(documentUri)) {
|
|
65
|
+
this.packageRootCache.set(uriString, null);
|
|
66
|
+
return null;
|
|
67
|
+
}
|
|
68
|
+
const fsPath = this.toFsPath(documentUri);
|
|
69
|
+
const packageRoot = await this.findPackageRootForExternal(fsPath);
|
|
70
|
+
this.packageRootCache.set(uriString, packageRoot);
|
|
71
|
+
return packageRoot;
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Checks if two documents are in the same package (synchronous heuristic).
|
|
75
|
+
*
|
|
76
|
+
* This is a fast, synchronous check that compares package commit directories
|
|
77
|
+
* without filesystem access. Documents are in the same package if:
|
|
78
|
+
* - Both are in .dlang/packages/ AND
|
|
79
|
+
* - They share the same owner/repo/commit path
|
|
80
|
+
*
|
|
81
|
+
* This is used by the scope provider which needs synchronous access.
|
|
82
|
+
*
|
|
83
|
+
* Structure: .dlang/packages/owner/repo/commit/...
|
|
84
|
+
*
|
|
85
|
+
* @param doc1Uri - URI of first document
|
|
86
|
+
* @param doc2Uri - URI of second document
|
|
87
|
+
* @returns true if both are in the same package commit directory
|
|
88
|
+
*/
|
|
89
|
+
areInSamePackageSync(doc1Uri, doc2Uri) {
|
|
90
|
+
// Both must be external packages
|
|
91
|
+
if (!this.isExternalPackage(doc1Uri) || !this.isExternalPackage(doc2Uri)) {
|
|
92
|
+
return false;
|
|
93
|
+
}
|
|
94
|
+
const path1 = this.toFsPath(doc1Uri);
|
|
95
|
+
const path2 = this.toFsPath(doc2Uri);
|
|
96
|
+
const root1 = this.getPackageCommitDirectory(path1);
|
|
97
|
+
const root2 = this.getPackageCommitDirectory(path2);
|
|
98
|
+
return root1 !== null && root1 === root2;
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Gets the package commit directory (owner/repo/commit) from a path.
|
|
102
|
+
*
|
|
103
|
+
* @param fsPath - Filesystem path
|
|
104
|
+
* @returns Commit directory path or null
|
|
105
|
+
*/
|
|
106
|
+
getPackageCommitDirectory(fsPath) {
|
|
107
|
+
const normalized = fsPath.split(path.sep);
|
|
108
|
+
const dlangIndex = normalized.indexOf('.dlang');
|
|
109
|
+
if (dlangIndex === -1) {
|
|
110
|
+
return null;
|
|
111
|
+
}
|
|
112
|
+
const packagesIndex = dlangIndex + 1;
|
|
113
|
+
if (packagesIndex >= normalized.length || normalized[packagesIndex] !== 'packages') {
|
|
114
|
+
return null;
|
|
115
|
+
}
|
|
116
|
+
// Commit directory is at: .dlang/packages/owner/repo/commit
|
|
117
|
+
const commitIndex = packagesIndex + 3;
|
|
118
|
+
if (commitIndex >= normalized.length) {
|
|
119
|
+
return null;
|
|
120
|
+
}
|
|
121
|
+
// Return the path up to and including the commit directory
|
|
122
|
+
return normalized.slice(0, commitIndex + 1).join(path.sep);
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Checks if two documents are in the same package.
|
|
126
|
+
*
|
|
127
|
+
* Documents are in the same package if:
|
|
128
|
+
* - Both are external packages AND
|
|
129
|
+
* - They share the same package root (model.yaml location)
|
|
130
|
+
*
|
|
131
|
+
* Local files are never in the same package (each is isolated).
|
|
132
|
+
*
|
|
133
|
+
* @param doc1Uri - URI of first document
|
|
134
|
+
* @param doc2Uri - URI of second document
|
|
135
|
+
* @returns true if both documents are in the same package
|
|
136
|
+
*/
|
|
137
|
+
async areInSamePackage(doc1Uri, doc2Uri) {
|
|
138
|
+
const root1 = await this.getPackageRoot(doc1Uri);
|
|
139
|
+
const root2 = await this.getPackageRoot(doc2Uri);
|
|
140
|
+
// If either is not in a package, they can't be in the same package
|
|
141
|
+
if (!root1 || !root2) {
|
|
142
|
+
return false;
|
|
143
|
+
}
|
|
144
|
+
return root1 === root2;
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Finds the package root for an external package by walking up to find model.yaml.
|
|
148
|
+
*
|
|
149
|
+
* External packages have structure: .dlang/packages/owner/repo/commit/...
|
|
150
|
+
* The model.yaml should be at the commit level or just below it.
|
|
151
|
+
*
|
|
152
|
+
* @param fsPath - Filesystem path of the document
|
|
153
|
+
* @returns Path to directory containing model.yaml, or null
|
|
154
|
+
*/
|
|
155
|
+
async findPackageRootForExternal(fsPath) {
|
|
156
|
+
const normalized = fsPath.split(path.sep);
|
|
157
|
+
const dlangIndex = normalized.indexOf('.dlang');
|
|
158
|
+
if (dlangIndex === -1) {
|
|
159
|
+
return null;
|
|
160
|
+
}
|
|
161
|
+
// Find the packages directory
|
|
162
|
+
const packagesIndex = dlangIndex + 1;
|
|
163
|
+
if (packagesIndex >= normalized.length || normalized[packagesIndex] !== 'packages') {
|
|
164
|
+
return null;
|
|
165
|
+
}
|
|
166
|
+
// Start from the commit directory level
|
|
167
|
+
// Structure: .dlang/packages/owner/repo/commit/
|
|
168
|
+
const commitIndex = packagesIndex + 3;
|
|
169
|
+
if (commitIndex >= normalized.length) {
|
|
170
|
+
return null;
|
|
171
|
+
}
|
|
172
|
+
// Walk up from the document path to the commit directory
|
|
173
|
+
let currentPath = path.dirname(fsPath);
|
|
174
|
+
const commitPath = normalized.slice(0, commitIndex + 1).join(path.sep);
|
|
175
|
+
// Search upward for model.yaml, but don't go above the commit directory
|
|
176
|
+
while (currentPath.length >= commitPath.length) {
|
|
177
|
+
const manifestPath = path.join(currentPath, 'model.yaml');
|
|
178
|
+
try {
|
|
179
|
+
await fs.access(manifestPath);
|
|
180
|
+
return currentPath;
|
|
181
|
+
}
|
|
182
|
+
catch {
|
|
183
|
+
// model.yaml not found at this level, continue upward
|
|
184
|
+
}
|
|
185
|
+
const parent = path.dirname(currentPath);
|
|
186
|
+
if (parent === currentPath) {
|
|
187
|
+
// Reached filesystem root without finding model.yaml
|
|
188
|
+
break;
|
|
189
|
+
}
|
|
190
|
+
currentPath = parent;
|
|
191
|
+
}
|
|
192
|
+
return null;
|
|
193
|
+
}
|
|
194
|
+
/**
|
|
195
|
+
* Converts a URI to a filesystem path.
|
|
196
|
+
*/
|
|
197
|
+
toFsPath(uri) {
|
|
198
|
+
if (typeof uri === 'string') {
|
|
199
|
+
uri = URI.parse(uri);
|
|
200
|
+
}
|
|
201
|
+
return uri.fsPath;
|
|
202
|
+
}
|
|
203
|
+
/**
|
|
204
|
+
* Clears the package root cache.
|
|
205
|
+
* Call this when packages are installed/removed.
|
|
206
|
+
*/
|
|
207
|
+
clearCache() {
|
|
208
|
+
this.packageRootCache.clear();
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
//# sourceMappingURL=package-boundary-detector.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"package-boundary-detector.js","sourceRoot":"","sources":["../../src/services/package-boundary-detector.ts"],"names":[],"mappings":"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"}
|
|
@@ -56,7 +56,8 @@ export class PerformanceOptimizer {
|
|
|
56
56
|
}
|
|
57
57
|
try {
|
|
58
58
|
const content = await fs.readFile(manifestPath, 'utf-8');
|
|
59
|
-
const
|
|
59
|
+
const { parse } = await import('yaml');
|
|
60
|
+
const manifest = parse(content);
|
|
60
61
|
this.manifestCache.set(cacheKey, {
|
|
61
62
|
value: manifest,
|
|
62
63
|
timestamp: Date.now(),
|
|
@@ -100,7 +101,10 @@ export class PerformanceOptimizer {
|
|
|
100
101
|
try {
|
|
101
102
|
const stat = await fs.stat(lockPath);
|
|
102
103
|
const cached = this.lockFileCache.get(workspaceRoot);
|
|
103
|
-
|
|
104
|
+
// Floor mtimeMs to integer precision to match Date.now() —
|
|
105
|
+
// some filesystems (e.g. APFS) report sub-millisecond mtime,
|
|
106
|
+
// which can exceed the integer timestamp from Date.now().
|
|
107
|
+
if (cached && Math.floor(stat.mtimeMs) > cached.timestamp) {
|
|
104
108
|
stale.push(workspaceRoot);
|
|
105
109
|
}
|
|
106
110
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"performance-optimizer.js","sourceRoot":"","sources":["../../src/services/performance-optimizer.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAGH,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAUlC;;GAEG;AACH,MAAM,OAAO,oBAAoB;IAK7B,YAAY,UAAiC,EAAE;QAJvC,kBAAa,GAAG,IAAI,GAAG,EAAgC,CAAC;QACxD,kBAAa,GAAG,IAAI,GAAG,EAA+B,CAAC;QAI3D,yBAAyB;QACzB,IAAI,CAAC,QAAQ,GAAG,OAAO,CAAC,QAAQ,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC;IACtD,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,iBAAiB,CAAC,aAAqB;QACzC,MAAM,QAAQ,GAAG,IAAI,CAAC,aAAa,CAAC,aAAa,CAAC,CAAC;QACnD,MAAM,MAAM,GAAG,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QAEhD,gCAAgC;QAChC,IAAI,MAAM,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,MAAM,CAAC,SAAS,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC;YAC1D,OAAO,MAAM,CAAC,KAAK,CAAC;QACxB,CAAC;QAED,iBAAiB;QACjB,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,YAAY,CAAC,CAAC;QACxD,IAAI,CAAC;YACD,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;YACrD,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAa,CAAC;YAEjD,WAAW;YACX,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,QAAQ,EAAE;gBAC7B,KAAK,EAAE,QAAQ;gBACf,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;aACxB,CAAC,CAAC;YAEH,OAAO,QAAQ,CAAC;QACpB,CAAC;QAAC,MAAM,CAAC;YACL,OAAO,SAAS,CAAC;QACrB,CAAC;IACL,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,iBAAiB,CAAC,YAAoB;QACxC,MAAM,QAAQ,GAAG,IAAI,CAAC,aAAa,CAAC,YAAY,CAAC,CAAC;QAClD,MAAM,MAAM,GAAG,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QAEhD,IAAI,MAAM,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,MAAM,CAAC,SAAS,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC;YAC1D,OAAO,MAAM,CAAC,KAAK,CAAC;QACxB,CAAC;QAED,IAAI,CAAC;YACD,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;YACzD,MAAM,
|
|
1
|
+
{"version":3,"file":"performance-optimizer.js","sourceRoot":"","sources":["../../src/services/performance-optimizer.ts"],"names":[],"mappings":"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"}
|
package/out/services/types.d.ts
CHANGED
|
@@ -37,6 +37,30 @@
|
|
|
37
37
|
*
|
|
38
38
|
* @module services/types
|
|
39
39
|
*/
|
|
40
|
+
/**
|
|
41
|
+
* Information about an import statement tracked during indexing.
|
|
42
|
+
*
|
|
43
|
+
* Used by IndexManager to track both the import's resolved location
|
|
44
|
+
* and its alias (if any) for scope resolution.
|
|
45
|
+
*
|
|
46
|
+
* @example
|
|
47
|
+
* ```typescript
|
|
48
|
+
* // import "larsbaunwall/ddd-types" as ddd
|
|
49
|
+
* const info: ImportInfo = {
|
|
50
|
+
* specifier: "larsbaunwall/ddd-types",
|
|
51
|
+
* alias: "ddd",
|
|
52
|
+
* resolvedUri: "file:///.dlang/packages/larsbaunwall/ddd-types/abc123/index.dlang"
|
|
53
|
+
* };
|
|
54
|
+
* ```
|
|
55
|
+
*/
|
|
56
|
+
export interface ImportInfo {
|
|
57
|
+
/** The import specifier as written in source (e.g., "./file.dlang", "owner/repo") */
|
|
58
|
+
readonly specifier: string;
|
|
59
|
+
/** Optional alias from 'as' clause (e.g., "ddd" in 'import "pkg" as ddd') */
|
|
60
|
+
readonly alias?: string;
|
|
61
|
+
/** Resolved absolute URI of the imported document */
|
|
62
|
+
readonly resolvedUri: string;
|
|
63
|
+
}
|
|
40
64
|
/**
|
|
41
65
|
* Type of git reference for version pinning.
|
|
42
66
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/services/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/services/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AAwIH;;GAEG;AACH,MAAM,UAAU,wBAAwB,CAAC,GAAmB;IACxD,OAAO,OAAO,GAAG,KAAK,QAAQ,IAAI,GAAG,KAAK,IAAI,CAAC;AACnD,CAAC"}
|