aboutsummaryrefslogtreecommitdiffstats
path: root/subprojects/language/src/main/java/tools/refinery/language/scoping/imports/ImportCollection.java
diff options
context:
space:
mode:
Diffstat (limited to 'subprojects/language/src/main/java/tools/refinery/language/scoping/imports/ImportCollection.java')
-rw-r--r--subprojects/language/src/main/java/tools/refinery/language/scoping/imports/ImportCollection.java76
1 files changed, 76 insertions, 0 deletions
diff --git a/subprojects/language/src/main/java/tools/refinery/language/scoping/imports/ImportCollection.java b/subprojects/language/src/main/java/tools/refinery/language/scoping/imports/ImportCollection.java
new file mode 100644
index 00000000..63171138
--- /dev/null
+++ b/subprojects/language/src/main/java/tools/refinery/language/scoping/imports/ImportCollection.java
@@ -0,0 +1,76 @@
1/*
2 * SPDX-FileCopyrightText: 2024 The Refinery Authors <https://refinery.tools/>
3 *
4 * SPDX-License-Identifier: EPL-2.0
5 */
6package tools.refinery.language.scoping.imports;
7
8import org.eclipse.emf.common.util.URI;
9import org.jetbrains.annotations.NotNull;
10import org.jetbrains.annotations.Nullable;
11
12import java.util.*;
13
14public class ImportCollection {
15 public static ImportCollection EMPTY = new ImportCollection() {
16 @Override
17 public void add(Import importEntry) {
18 throw new UnsupportedOperationException("Read-only collection");
19 }
20
21 @Override
22 public void remove(URI uri) {
23 throw new UnsupportedOperationException("Read-only collection");
24 }
25 };
26
27 private final Map<URI, Import> importMap = new HashMap<>();
28
29 public void add(Import importEntry) {
30 importMap.compute(importEntry.uri(), (ignored, originalEntry) -> merge(originalEntry, importEntry));
31 }
32
33 public void addAll(Iterable<? extends Import> imports) {
34 imports.forEach(this::add);
35 }
36
37 public void remove(URI uri) {
38 importMap.remove(uri);
39 }
40
41 public List<Import> toList() {
42 return List.copyOf(importMap.values());
43 }
44
45 public Set<URI> toUriSet() {
46 return new LinkedHashSet<>(importMap.keySet());
47 }
48
49 @NotNull
50 private static Import merge(@Nullable Import left, @NotNull Import right) {
51 if (left == null) {
52 return right;
53 }
54 if (!left.uri().equals(right.uri())) {
55 throw new IllegalArgumentException("Expected URIs '%s' and '%s' to be equal".formatted(
56 left.uri(), right.uri()));
57 }
58 return switch (left) {
59 case TransitiveImport transitiveLeft ->
60 right instanceof TransitiveImport ? left : merge(right, transitiveLeft);
61 case NamedImport namedLeft -> switch (right) {
62 case TransitiveImport ignored -> namedLeft;
63 case NamedImport namedRight -> {
64 if (!namedLeft.qualifiedName().equals(namedRight.qualifiedName())) {
65 throw new IllegalArgumentException("Expected qualified names '%s' and '%s' to be equal"
66 .formatted(namedLeft.qualifiedName(), namedRight.qualifiedName()));
67 }
68 var mergedAliases = new LinkedHashSet<>(namedLeft.aliases());
69 mergedAliases.addAll(namedRight.aliases());
70 yield new NamedImport(namedLeft.uri(), namedLeft.qualifiedName(),
71 List.copyOf(mergedAliases), namedLeft.alsoImplicit() || namedRight.alsoImplicit());
72 }
73 };
74 };
75 }
76}