diff options
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.java | 76 |
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 | */ | ||
6 | package tools.refinery.language.scoping.imports; | ||
7 | |||
8 | import org.eclipse.emf.common.util.URI; | ||
9 | import org.jetbrains.annotations.NotNull; | ||
10 | import org.jetbrains.annotations.Nullable; | ||
11 | |||
12 | import java.util.*; | ||
13 | |||
14 | public 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 | } | ||