@oml/language 0.9.0 → 0.11.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.
@@ -1,34 +1,42 @@
1
1
  // Copyright (c) 2026 Modelware. All rights reserved.
2
2
 
3
- import { DocumentState, type LangiumDocument } from 'langium';
3
+ import { DocumentState, URI, type LangiumDocument } from 'langium';
4
4
  import type { LangiumSharedServices } from 'langium/lsp';
5
- import { isOntology } from './generated/ast.js';
6
- import { isTransientEditorDocumentUri } from './oml-utils.js';
5
+ import { isAspect, isConcept, isConceptInstance, isDescription, isOntology, isRelationEntity, isRelationInstance, isScalar } from './generated/ast.js';
6
+ import { collectOntologyMembers, getIriForNode, isTransientEditorDocumentUri } from './oml-utils.js';
7
7
 
8
- const ontologyIndexByShared = new WeakMap<object, OntologyModelIndex>();
8
+ const OML_LABEL_IRI = 'http://opencaesar.io/oml#label';
9
9
 
10
- export function getOntologyModelIndex(shared: LangiumSharedServices): OntologyModelIndex {
10
+ const ontologyIndexByShared = new WeakMap<object, OmlIndex>();
11
+
12
+ export function getOntologyModelIndex(shared: LangiumSharedServices): OmlIndex {
11
13
  const key = shared as object;
12
14
  const existing = ontologyIndexByShared.get(key);
13
15
  if (existing) {
14
16
  return existing;
15
17
  }
16
- const created = new OntologyModelIndex(shared);
18
+ const created = new OmlIndex(shared);
17
19
  ontologyIndexByShared.set(key, created);
18
20
  return created;
19
21
  }
20
22
 
21
- export class OntologyModelIndex {
22
- private readonly ontologyIdentifierToModelUri = new Map<string, string>();
23
- private readonly modelUriToOntologyIri = new Map<string, string>();
23
+ export class OmlIndex {
24
24
  private readonly workspaceModelUrisByOntologyIri = new Map<string, Set<string>>();
25
- private readonly workspaceOntologyIriByModelUri = new Map<string, string>();
26
25
  private readonly workspaceNamespaceByModelUri = new Map<string, string>();
26
+ private readonly memberLabelByIri = new Map<string, string>();
27
+ private readonly labeledMemberIrisByModelUri = new Map<string, Set<string>>();
28
+ private readonly instanceIrisByTypeIri = new Map<string, Set<string>>();
29
+ private readonly instanceTypeIrisByModelUri = new Map<string, Map<string, Set<string>>>();
30
+ private readonly subTypeIrisByTypeIri = new Map<string, Set<string>>();
31
+ private readonly typeSuperIrisByModelUri = new Map<string, Map<string, Set<string>>>();
27
32
 
28
33
  constructor(private readonly shared: LangiumSharedServices) {
29
34
  this.shared.workspace.DocumentBuilder.onDocumentPhase(DocumentState.Parsed, (document) => {
30
35
  this.indexDocument(document);
31
36
  });
37
+ this.shared.workspace.DocumentBuilder.onDocumentPhase(DocumentState.Linked, (document) => {
38
+ this.indexLinkedDocument(document);
39
+ });
32
40
  }
33
41
 
34
42
  resolveModelUri(identifier: string): string | undefined {
@@ -46,11 +54,83 @@ export class OntologyModelIndex {
46
54
  }
47
55
 
48
56
  resolveOntologyIri(modelUri: string): string | undefined {
49
- this.ensureIndexedFromLoadedDocuments();
50
- return this.modelUriToOntologyIri.get(modelUri);
57
+ const document = this.shared.workspace.LangiumDocuments.getDocument(URI.parse(modelUri));
58
+ if (!document) {
59
+ return undefined;
60
+ }
61
+ return this.getOntologyIri(document);
62
+ }
63
+
64
+ getMemberLabel(memberIri: string): string | undefined {
65
+ return this.memberLabelByIri.get(this.normalizeIri(memberIri));
66
+ }
67
+
68
+ getMemberLabelSnapshot(modelUris: Iterable<string>): Record<string, string> {
69
+ const snapshot: Record<string, string> = {};
70
+ for (const modelUri of modelUris) {
71
+ const labeledMemberIris = this.labeledMemberIrisByModelUri.get(modelUri);
72
+ if (!labeledMemberIris) {
73
+ continue;
74
+ }
75
+ for (const memberIri of labeledMemberIris) {
76
+ const label = this.memberLabelByIri.get(memberIri);
77
+ if (label) {
78
+ snapshot[memberIri] = label;
79
+ }
80
+ }
81
+ }
82
+ return snapshot;
83
+ }
84
+
85
+ getTypeMemberIris(typeIri: string): string[] {
86
+ const normalizedTypeIri = this.normalizeIri(typeIri);
87
+ if (!normalizedTypeIri) {
88
+ return [];
89
+ }
90
+ const candidateTypeIris = new Set<string>();
91
+ const worklist = [normalizedTypeIri];
92
+ while (worklist.length > 0) {
93
+ const current = worklist.pop()!;
94
+ if (candidateTypeIris.has(current)) {
95
+ continue;
96
+ }
97
+ candidateTypeIris.add(current);
98
+ const subTypes = this.subTypeIrisByTypeIri.get(current);
99
+ if (!subTypes) {
100
+ continue;
101
+ }
102
+ for (const subType of subTypes) {
103
+ if (!candidateTypeIris.has(subType)) {
104
+ worklist.push(subType);
105
+ }
106
+ }
107
+ }
108
+ const iris: string[] = [];
109
+ for (const candidateTypeIri of candidateTypeIris) {
110
+ const instanceIris = this.instanceIrisByTypeIri.get(candidateTypeIri);
111
+ if (!instanceIris) {
112
+ continue;
113
+ }
114
+ iris.push(...instanceIris);
115
+ }
116
+ return [...new Set(iris)].sort();
51
117
  }
52
118
 
53
- removeModel(modelUri: string): void {
119
+ getAllDescriptionInstanceIris(): string[] {
120
+ const iris = new Set<string>();
121
+ for (const instanceIris of this.instanceIrisByTypeIri.values()) {
122
+ for (const iri of instanceIris) {
123
+ iris.add(iri);
124
+ }
125
+ }
126
+ return [...iris].sort();
127
+ }
128
+
129
+ removeDocument(document: LangiumDocument): void {
130
+ const modelUri = document.uri.toString();
131
+ this.removeLabelsForModelUri(modelUri);
132
+ this.removeTypesForModelUri(modelUri);
133
+ this.removeTypeHierarchyForModelUri(modelUri);
54
134
  this.unindexModelUri(modelUri);
55
135
  }
56
136
 
@@ -68,57 +148,180 @@ export class OntologyModelIndex {
68
148
  private indexDocument(document: LangiumDocument): void {
69
149
  const modelUri = document.uri.toString();
70
150
  this.unindexModelUri(modelUri);
71
- const root = document.parseResult?.value;
72
- if (!isOntology(root)) {
151
+ const ontologyIri = this.getOntologyIri(document);
152
+ if (!ontologyIri) {
73
153
  return;
74
154
  }
75
- const namespace = this.normalizeNamespace((root as any).namespace ?? '');
155
+ const namespace = this.getNamespace(document);
76
156
  if (!namespace) {
77
157
  return;
78
158
  }
79
159
  if (isTransientEditorDocumentUri(modelUri)) {
80
160
  return;
81
161
  }
82
- const ontologyIri = this.ontologyIriFromNamespace(namespace);
83
162
  const modelUris = this.workspaceModelUrisByOntologyIri.get(ontologyIri) ?? new Set<string>();
84
163
  modelUris.add(modelUri);
85
164
  this.workspaceModelUrisByOntologyIri.set(ontologyIri, modelUris);
86
- this.workspaceOntologyIriByModelUri.set(modelUri, ontologyIri);
87
165
  this.workspaceNamespaceByModelUri.set(modelUri, namespace);
88
- this.modelUriToOntologyIri.set(modelUri, ontologyIri);
89
- if (modelUris.size === 1) {
90
- this.ontologyIdentifierToModelUri.set(namespace, modelUri);
91
- this.ontologyIdentifierToModelUri.set(ontologyIri, modelUri);
166
+ }
167
+
168
+ private indexLinkedDocument(document: LangiumDocument): void {
169
+ const modelUri = document.uri.toString();
170
+ this.removeLabelsForModelUri(modelUri);
171
+ this.removeTypesForModelUri(modelUri);
172
+ this.removeTypeHierarchyForModelUri(modelUri);
173
+ const root = document.parseResult?.value;
174
+ if (!isOntology(root) || isTransientEditorDocumentUri(modelUri)) {
175
+ return;
176
+ }
177
+
178
+ this.indexTypeHierarchy(root as any, modelUri);
179
+
180
+ if (!isDescription(root)) {
92
181
  return;
93
182
  }
94
- this.ontologyIdentifierToModelUri.delete(namespace);
95
- this.ontologyIdentifierToModelUri.delete(ontologyIri);
183
+
184
+ const labeledMemberIris = new Set<string>();
185
+ const typedInstanceIrisByTypeIri = new Map<string, Set<string>>();
186
+ for (const member of collectOntologyMembers(root as any)) {
187
+ const memberIri = this.normalizeIri(getIriForNode(member) ?? '');
188
+ if (!memberIri) {
189
+ continue;
190
+ }
191
+ const label = this.extractLabel(member);
192
+ if (label !== undefined) {
193
+ this.memberLabelByIri.set(memberIri, label);
194
+ labeledMemberIris.add(memberIri);
195
+ }
196
+
197
+ if (!isConceptInstance(member) && !isRelationInstance(member)) {
198
+ continue;
199
+ }
200
+ const instanceIri = this.resolveInstanceIri(member);
201
+ if (!instanceIri) {
202
+ continue;
203
+ }
204
+ const ownedTypes = Array.isArray((member as any).ownedTypes) ? (member as any).ownedTypes : [];
205
+ for (const typeAssertion of ownedTypes) {
206
+ const typeIri = this.resolveTypeIri(typeAssertion?.type);
207
+ if (!typeIri) {
208
+ continue;
209
+ }
210
+ const instanceIris = this.instanceIrisByTypeIri.get(typeIri) ?? new Set<string>();
211
+ instanceIris.add(instanceIri);
212
+ this.instanceIrisByTypeIri.set(typeIri, instanceIris);
213
+
214
+ const modelTypeIris = typedInstanceIrisByTypeIri.get(typeIri) ?? new Set<string>();
215
+ modelTypeIris.add(instanceIri);
216
+ typedInstanceIrisByTypeIri.set(typeIri, modelTypeIris);
217
+ }
218
+ }
219
+
220
+ if (labeledMemberIris.size > 0) {
221
+ this.labeledMemberIrisByModelUri.set(modelUri, labeledMemberIris);
222
+ }
223
+ if (typedInstanceIrisByTypeIri.size > 0) {
224
+ this.instanceTypeIrisByModelUri.set(modelUri, typedInstanceIrisByTypeIri);
225
+ }
226
+ }
227
+
228
+ private indexTypeHierarchy(root: any, modelUri: string): void {
229
+ const typeSuperIrisByTypeIri = new Map<string, Set<string>>();
230
+ for (const member of collectOntologyMembers(root as any)) {
231
+ if (!isConcept(member) && !isAspect(member) && !isRelationEntity(member) && !isScalar(member)) {
232
+ continue;
233
+ }
234
+ const typeIri = this.normalizeIri(getIriForNode(member) ?? '');
235
+ if (!typeIri) {
236
+ continue;
237
+ }
238
+ const directSupers = typeSuperIrisByTypeIri.get(typeIri) ?? new Set<string>();
239
+ const specializations = Array.isArray((member as any).ownedSpecializations) ? (member as any).ownedSpecializations : [];
240
+ for (const specialization of specializations) {
241
+ const superIri = this.normalizeIri(getIriForNode(specialization?.superTerm?.ref) ?? '');
242
+ if (!superIri) {
243
+ continue;
244
+ }
245
+ directSupers.add(superIri);
246
+ const subTypes = this.subTypeIrisByTypeIri.get(superIri) ?? new Set<string>();
247
+ subTypes.add(typeIri);
248
+ this.subTypeIrisByTypeIri.set(superIri, subTypes);
249
+ }
250
+ if (directSupers.size > 0) {
251
+ typeSuperIrisByTypeIri.set(typeIri, directSupers);
252
+ }
253
+ }
254
+ if (typeSuperIrisByTypeIri.size > 0) {
255
+ this.typeSuperIrisByModelUri.set(modelUri, typeSuperIrisByTypeIri);
256
+ }
96
257
  }
97
258
 
98
259
  private unindexModelUri(modelUri: string): void {
99
- for (const [identifier, uri] of this.ontologyIdentifierToModelUri.entries()) {
100
- if (uri === modelUri) {
101
- this.ontologyIdentifierToModelUri.delete(identifier);
102
- }
103
- }
104
- const ontologyIri = this.workspaceOntologyIriByModelUri.get(modelUri);
105
- if (ontologyIri) {
106
- const modelUris = this.workspaceModelUrisByOntologyIri.get(ontologyIri);
107
- modelUris?.delete(modelUri);
108
- if (!modelUris || modelUris.size === 0) {
109
- this.workspaceModelUrisByOntologyIri.delete(ontologyIri);
110
- } else if (modelUris.size === 1) {
111
- const survivingModelUri = [...modelUris][0];
112
- const survivingNamespace = this.workspaceNamespaceByModelUri.get(survivingModelUri);
113
- this.ontologyIdentifierToModelUri.set(ontologyIri, survivingModelUri);
114
- if (survivingNamespace) {
115
- this.ontologyIdentifierToModelUri.set(survivingNamespace, survivingModelUri);
260
+ const namespace = this.workspaceNamespaceByModelUri.get(modelUri);
261
+ if (!namespace) {
262
+ return;
263
+ }
264
+ this.workspaceNamespaceByModelUri.delete(modelUri);
265
+ const ontologyIri = this.ontologyIriFromNamespace(namespace);
266
+ const modelUris = this.workspaceModelUrisByOntologyIri.get(ontologyIri);
267
+ if (!modelUris) {
268
+ return;
269
+ }
270
+ modelUris.delete(modelUri);
271
+ if (modelUris.size === 0) {
272
+ this.workspaceModelUrisByOntologyIri.delete(ontologyIri);
273
+ }
274
+ }
275
+
276
+ private removeLabelsForModelUri(modelUri: string): void {
277
+ const labeledMemberIris = this.labeledMemberIrisByModelUri.get(modelUri);
278
+ if (!labeledMemberIris) {
279
+ return;
280
+ }
281
+ for (const memberIri of labeledMemberIris) {
282
+ this.memberLabelByIri.delete(memberIri);
283
+ }
284
+ this.labeledMemberIrisByModelUri.delete(modelUri);
285
+ }
286
+
287
+ private removeTypesForModelUri(modelUri: string): void {
288
+ const typedInstanceIrisByTypeIri = this.instanceTypeIrisByModelUri.get(modelUri);
289
+ if (!typedInstanceIrisByTypeIri) {
290
+ return;
291
+ }
292
+ for (const [typeIri, instanceIris] of typedInstanceIrisByTypeIri.entries()) {
293
+ const globalInstanceIris = this.instanceIrisByTypeIri.get(typeIri);
294
+ if (!globalInstanceIris) {
295
+ continue;
296
+ }
297
+ for (const instanceIri of instanceIris) {
298
+ globalInstanceIris.delete(instanceIri);
299
+ }
300
+ if (globalInstanceIris.size === 0) {
301
+ this.instanceIrisByTypeIri.delete(typeIri);
302
+ }
303
+ }
304
+ this.instanceTypeIrisByModelUri.delete(modelUri);
305
+ }
306
+
307
+ private removeTypeHierarchyForModelUri(modelUri: string): void {
308
+ const typeSuperIrisByTypeIri = this.typeSuperIrisByModelUri.get(modelUri);
309
+ if (!typeSuperIrisByTypeIri) {
310
+ return;
311
+ }
312
+ for (const [typeIri, superIris] of typeSuperIrisByTypeIri.entries()) {
313
+ for (const superIri of superIris) {
314
+ const subTypes = this.subTypeIrisByTypeIri.get(superIri);
315
+ if (!subTypes) {
316
+ continue;
317
+ }
318
+ subTypes.delete(typeIri);
319
+ if (subTypes.size === 0) {
320
+ this.subTypeIrisByTypeIri.delete(superIri);
116
321
  }
117
322
  }
118
- this.workspaceOntologyIriByModelUri.delete(modelUri);
119
- this.workspaceNamespaceByModelUri.delete(modelUri);
120
323
  }
121
- this.modelUriToOntologyIri.delete(modelUri);
324
+ this.typeSuperIrisByModelUri.delete(modelUri);
122
325
  }
123
326
 
124
327
  getDuplicateWorkspaceModelUris(identifier: string): string[] {
@@ -139,7 +342,90 @@ export class OntologyModelIndex {
139
342
  return namespace.replace(/^<|>$/g, '');
140
343
  }
141
344
 
345
+ private normalizeIri(iri: string): string {
346
+ return iri.replace(/^<|>$/g, '').trim();
347
+ }
348
+
349
+ private getOntologyIri(document: LangiumDocument): string | undefined {
350
+ const namespace = this.getNamespace(document);
351
+ if (!namespace) {
352
+ return undefined;
353
+ }
354
+ return this.ontologyIriFromNamespace(namespace);
355
+ }
356
+
357
+ private getNamespace(document: LangiumDocument): string | undefined {
358
+ const root = document.parseResult?.value;
359
+ if (!isOntology(root)) {
360
+ return undefined;
361
+ }
362
+ const namespace = this.normalizeNamespace((root as any).namespace ?? '');
363
+ if (!namespace) {
364
+ return undefined;
365
+ }
366
+ return namespace;
367
+ }
368
+
142
369
  private ontologyIriFromNamespace(namespace: string): string {
143
370
  return namespace.replace(/[\/#]+$/, '');
144
371
  }
372
+
373
+ private extractLabel(member: any): string | undefined {
374
+ const annotations = Array.isArray(member?.ownedAnnotations) ? member.ownedAnnotations : [];
375
+ if (annotations.length === 0) {
376
+ return undefined;
377
+ }
378
+ for (const annotation of annotations) {
379
+ const propertyIri = this.normalizeIri(getIriForNode(annotation?.property?.ref) ?? '');
380
+ if (propertyIri !== OML_LABEL_IRI) {
381
+ continue;
382
+ }
383
+ const label = this.readAnnotationLiteral(annotation);
384
+ if (label) {
385
+ return label;
386
+ }
387
+ }
388
+ return undefined;
389
+ }
390
+
391
+ private readAnnotationLiteral(annotation: any): string | undefined {
392
+ const literal = Array.isArray(annotation?.literalValues) ? annotation.literalValues[0] : undefined;
393
+ if (!literal) {
394
+ return undefined;
395
+ }
396
+ const value = literal?.value;
397
+ if (typeof value === 'string') {
398
+ return value.trim();
399
+ }
400
+ if (typeof value === 'number' || typeof value === 'boolean') {
401
+ return String(value);
402
+ }
403
+ return undefined;
404
+ }
405
+
406
+ private resolveInstanceIri(member: any): string | undefined {
407
+ const namedIri = this.normalizeIri(getIriForNode(member) ?? '');
408
+ if (namedIri) {
409
+ return namedIri;
410
+ }
411
+ const resolved = member?.ref?.ref ?? member?.ref?._ref;
412
+ if (resolved) {
413
+ const resolvedIri = this.normalizeIri(getIriForNode(resolved) ?? '');
414
+ if (resolvedIri) {
415
+ return resolvedIri;
416
+ }
417
+ }
418
+ return undefined;
419
+ }
420
+
421
+ private resolveTypeIri(typeRef: any): string | undefined {
422
+ const resolved = typeRef?.ref ?? typeRef?._ref;
423
+ if (resolved) {
424
+ const resolvedIri = this.normalizeIri(getIriForNode(resolved) ?? '');
425
+ if (resolvedIri) {
426
+ return resolvedIri;
427
+ }
428
+ }
429
+ return undefined;
430
+ }
145
431
  }
@@ -114,6 +114,7 @@ export class OmlRenameProvider extends DefaultRenameProvider {
114
114
  }
115
115
 
116
116
  private buildReplacement(refText: string, newName: string): string {
117
+ const escapedName = escapeIdentifier(newName);
117
118
  if (refText.startsWith('<') && refText.endsWith('>')) {
118
119
  const inner = refText.slice(1, -1);
119
120
  return `<${this.replaceIriTail(inner, newName)}>`;
@@ -125,7 +126,7 @@ export class OmlRenameProvider extends DefaultRenameProvider {
125
126
  if (qnameMatch) {
126
127
  return `${qnameMatch[1]}${newName}`;
127
128
  }
128
- return newName;
129
+ return escapedName;
129
130
  }
130
131
 
131
132
  private replaceIriTail(iri: string, newName: string): string {
@@ -138,3 +139,22 @@ export class OmlRenameProvider extends DefaultRenameProvider {
138
139
  return newName;
139
140
  }
140
141
  }
142
+
143
+ const OML_KEYWORDS = new Set([
144
+ 'all', 'annotation', 'as', 'aspect', 'asymmetric', 'builtIn', 'builtin', 'bundle', 'concept', 'description',
145
+ 'differentFrom', 'domain', 'entity', 'exactly', 'extends', 'forward', 'from', 'functional', 'includes',
146
+ 'instance', 'inverse', 'irreflexive', 'key', 'language', 'length', 'max', 'maxExclusive', 'maxInclusive',
147
+ 'maxLength', 'min', 'minExclusive', 'minInclusive', 'minLength', 'oneOf', 'pattern', 'property', 'range', 'ref',
148
+ 'reflexive', 'relation', 'restricts', 'reverse', 'rule', 'sameAs', 'scalar', 'self', 'some', 'symmetric', 'to',
149
+ 'transitive', 'uses', 'vocabulary'
150
+ ]);
151
+
152
+ function escapeIdentifier(value: string): string {
153
+ if (!value) {
154
+ return '';
155
+ }
156
+ if (value.startsWith('^')) {
157
+ return value;
158
+ }
159
+ return OML_KEYWORDS.has(value) ? `^${value}` : value;
160
+ }
@@ -164,6 +164,7 @@ const GITHUB_COPILOT_TRANSIENT_DOCUMENT_SCHEMES = new Set([
164
164
  'chat-editing-text-model',
165
165
  'chat-editing-snapshot-text-model',
166
166
  'vscode-chat-code-block',
167
+ 'git',
167
168
  ]);
168
169
 
169
170
  export function isTransientEditorDocumentUri(uri: string): boolean {
@@ -1,10 +0,0 @@
1
- import { DefaultIndexManager, type AstNode, type LangiumDocument, type LangiumSharedCoreServices, type ReferenceDescription } from 'langium';
2
- import type { CancellationToken } from 'vscode-jsonrpc';
3
- export declare class OmlIndexManager extends DefaultIndexManager {
4
- private readonly services;
5
- constructor(services: LangiumSharedCoreServices);
6
- findAllReferences(targetNode: AstNode, astNodePath: string): import("langium").Stream<ReferenceDescription>;
7
- updateReferences(document: LangiumDocument, cancelToken?: CancellationToken): Promise<void>;
8
- isAffected(document: LangiumDocument, changedUris: Set<string>): boolean;
9
- private canonicalizeUri;
10
- }
@@ -1,48 +0,0 @@
1
- // Copyright (c) 2026 Modelware. All rights reserved.
2
- import { AstUtils, DefaultIndexManager, URI, UriUtils, stream } from 'langium';
3
- import { canonicalizeWorkspaceDocumentUri } from './oml-workspace.js';
4
- export class OmlIndexManager extends DefaultIndexManager {
5
- constructor(services) {
6
- super(services);
7
- this.services = services;
8
- }
9
- findAllReferences(targetNode, astNodePath) {
10
- const targetDocUri = this.canonicalizeUri(AstUtils.getDocument(targetNode).uri);
11
- const result = [];
12
- this.referenceIndex.forEach(docRefs => {
13
- docRefs.forEach(refDescr => {
14
- if (UriUtils.equals(this.canonicalizeUri(refDescr.targetUri), targetDocUri) && refDescr.targetPath === astNodePath) {
15
- result.push(refDescr);
16
- }
17
- });
18
- });
19
- return stream(result);
20
- }
21
- async updateReferences(document, cancelToken) {
22
- const services = this.serviceRegistry.getServices(document.uri);
23
- const references = await services.workspace.ReferenceDescriptionProvider.createDescriptions(document, cancelToken);
24
- const sourceUri = this.canonicalizeUri(document.uri);
25
- this.referenceIndex.set(document.uri.toString(), references.map(ref => {
26
- const targetUri = this.canonicalizeUri(ref.targetUri);
27
- return {
28
- ...ref,
29
- sourceUri,
30
- targetUri,
31
- local: UriUtils.equals(sourceUri, targetUri),
32
- };
33
- }));
34
- }
35
- isAffected(document, changedUris) {
36
- const references = this.referenceIndex.get(document.uri.toString());
37
- if (!references) {
38
- return false;
39
- }
40
- const canonicalChangedUris = new Set(Array.from(changedUris, uri => this.canonicalizeUri(uri).toString()));
41
- return references.some(ref => !ref.local && canonicalChangedUris.has(this.canonicalizeUri(ref.targetUri).toString()));
42
- }
43
- canonicalizeUri(uri) {
44
- const parsedUri = typeof uri === 'string' ? URI.parse(uri) : uri;
45
- return canonicalizeWorkspaceDocumentUri(this.services.workspace.WorkspaceManager, parsedUri);
46
- }
47
- }
48
- //# sourceMappingURL=oml-index-manager.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"oml-index-manager.js","sourceRoot":"","sources":["../../src/oml/oml-index-manager.ts"],"names":[],"mappings":"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"}
@@ -1,56 +0,0 @@
1
- // Copyright (c) 2026 Modelware. All rights reserved.
2
-
3
- import { AstUtils, DefaultIndexManager, URI, UriUtils, stream, type AstNode, type LangiumDocument, type LangiumSharedCoreServices, type ReferenceDescription } from 'langium';
4
- import type { CancellationToken } from 'vscode-jsonrpc';
5
- import { canonicalizeWorkspaceDocumentUri } from './oml-workspace.js';
6
-
7
- export class OmlIndexManager extends DefaultIndexManager {
8
- private readonly services: LangiumSharedCoreServices;
9
-
10
- constructor(services: LangiumSharedCoreServices) {
11
- super(services);
12
- this.services = services;
13
- }
14
-
15
- override findAllReferences(targetNode: AstNode, astNodePath: string) {
16
- const targetDocUri = this.canonicalizeUri(AstUtils.getDocument(targetNode).uri);
17
- const result: ReferenceDescription[] = [];
18
- this.referenceIndex.forEach(docRefs => {
19
- docRefs.forEach(refDescr => {
20
- if (UriUtils.equals(this.canonicalizeUri(refDescr.targetUri), targetDocUri) && refDescr.targetPath === astNodePath) {
21
- result.push(refDescr);
22
- }
23
- });
24
- });
25
- return stream(result);
26
- }
27
-
28
- override async updateReferences(document: LangiumDocument, cancelToken?: CancellationToken): Promise<void> {
29
- const services = this.serviceRegistry.getServices(document.uri);
30
- const references = await services.workspace.ReferenceDescriptionProvider.createDescriptions(document, cancelToken);
31
- const sourceUri = this.canonicalizeUri(document.uri);
32
- this.referenceIndex.set(document.uri.toString(), references.map(ref => {
33
- const targetUri = this.canonicalizeUri(ref.targetUri);
34
- return {
35
- ...ref,
36
- sourceUri,
37
- targetUri,
38
- local: UriUtils.equals(sourceUri, targetUri),
39
- };
40
- }));
41
- }
42
-
43
- override isAffected(document: LangiumDocument, changedUris: Set<string>): boolean {
44
- const references = this.referenceIndex.get(document.uri.toString());
45
- if (!references) {
46
- return false;
47
- }
48
- const canonicalChangedUris = new Set(Array.from(changedUris, uri => this.canonicalizeUri(uri).toString()));
49
- return references.some(ref => !ref.local && canonicalChangedUris.has(this.canonicalizeUri(ref.targetUri).toString()));
50
- }
51
-
52
- private canonicalizeUri(uri: URI | string): URI {
53
- const parsedUri = typeof uri === 'string' ? URI.parse(uri) : uri;
54
- return canonicalizeWorkspaceDocumentUri(this.services.workspace.WorkspaceManager, parsedUri);
55
- }
56
- }