Skip to content

Commit 6869b5a

Browse files
committed
Add tests
1 parent c03caa1 commit 6869b5a

File tree

3 files changed

+57
-27
lines changed

3 files changed

+57
-27
lines changed

src/java.base/share/classes/jdk/internal/access/HeterogeneousContainer.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ static <T> HeterogeneousContainer<T> of(Class<T> type) {
138138
if (!type.isSealed()) {
139139
throw new IllegalArgumentException("The provided type must be sealed: " + type);
140140
}
141-
throw new UnsupportedOperationException();
141+
return HeterogeneousContainerImpl.of(Objects.requireNonNull(type.getPermittedSubclasses()));
142142
}
143143

144144
}

src/java.base/share/classes/jdk/internal/access/HeterogeneousContainerImpl.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import jdk.internal.vm.annotation.ForceInline;
66
import jdk.internal.vm.annotation.Stable;
77

8+
import java.util.NoSuchElementException;
89
import java.util.Objects;
910
import java.util.StringJoiner;
1011
import java.util.function.Function;
@@ -16,7 +17,11 @@ record HeterogeneousContainerImpl<T>(@Stable Object[] table) implements Heteroge
1617

1718
@ForceInline
1819
public <C extends T> C get(Class<C> type) {
19-
return type.cast(componentRaw(type));
20+
final Object componentRaw = componentRaw(type);
21+
if (componentRaw == null) {
22+
throw new NoSuchElementException("No component of type " + type);
23+
}
24+
return type.cast(componentRaw);
2025
}
2126

2227
public boolean isInitialized(Class<? extends T> type) {

test/jdk/java/lang/LazyConstant/StableComponentContainerTest.java renamed to test/jdk/java/lang/LazyConstant/HeterogeneousContainerTest.java

Lines changed: 50 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -22,13 +22,13 @@
2222
*/
2323

2424
/* @test
25-
* @summary Basic tests for the StableComponentContainer implementation
25+
* @summary Basic tests for the HeterogeneousContainer implementation
2626
* @enablePreview
2727
* @modules java.base/jdk.internal.access:+open
28-
* @run junit StableComponentContainerTest
28+
* @run junit HeterogeneousContainerTest
2929
*/
3030

31-
import jdk.internal.access.StableComponentContainer;
31+
import jdk.internal.access.HeterogeneousContainer;
3232
import org.junit.jupiter.api.Test;
3333

3434
import java.math.BigInteger;
@@ -38,7 +38,7 @@
3838

3939
import static org.junit.jupiter.api.Assertions.*;
4040

41-
final class StableComponentContainerTest {
41+
final class HeterogeneousContainerTest {
4242

4343
private static final Set<Class<? extends Number>> SET = Set.of(
4444
Byte.class,
@@ -48,35 +48,26 @@ final class StableComponentContainerTest {
4848
Float.class,
4949
Double.class);
5050

51-
sealed interface Component {
52-
sealed interface Foo extends Component {
53-
final class FooImp implements Foo {}
54-
}
55-
56-
sealed interface Bar extends Component {
57-
final class BarImp implements Bar {}
58-
}
59-
}
6051

6152
@Test
6253
void factoryInvariants() {
63-
assertThrows(NullPointerException.class, () -> StableComponentContainer.of((Set<Class<?>>) null));
54+
assertThrows(NullPointerException.class, () -> HeterogeneousContainer.of((Set<Class<?>>) null));
6455
Set<Class<? extends Number>> setWithNull = new HashSet<>();
6556
setWithNull.add(Byte.class);
6657
setWithNull.add(Short.class);
6758
setWithNull.add(null);
6859
setWithNull.add(Integer.class);
69-
assertThrows(NullPointerException.class, () -> StableComponentContainer.of(setWithNull));
60+
assertThrows(NullPointerException.class, () -> HeterogeneousContainer.of(setWithNull));
7061

71-
assertThrows(NullPointerException.class, () -> StableComponentContainer.of((Class<?>) null));
62+
assertThrows(NullPointerException.class, () -> HeterogeneousContainer.of((Class<?>) null));
7263
// Integer is not a sealed class
73-
var x = assertThrows(IllegalArgumentException.class, () -> StableComponentContainer.of(Integer.class));
64+
var x = assertThrows(IllegalArgumentException.class, () -> HeterogeneousContainer.of(Integer.class));
7465
assertEquals("The provided type must be sealed: " + Integer.class, x.getMessage());
7566
}
7667

7768
@Test
7869
void basic() {
79-
StableComponentContainer<Number> container = populated();
70+
HeterogeneousContainer<Number> container = populated();
8071
for (Class<? extends Number> type : SET) {
8172
Number value = container.get(type);
8273
assertEquals(1, value.intValue(), type.toString());
@@ -85,11 +76,13 @@ void basic() {
8576
assertEquals("The component is already initialized: " + Byte.class.getName(), x0.getMessage());
8677
var x1 = assertThrows(IllegalArgumentException.class, () -> container.set(BigInteger.class, BigInteger.ONE));
8778
assertTrue(x1.getMessage().startsWith("The type '" + BigInteger.class.getName() + "' is outside the allowed input types:"), x1.getMessage());
79+
var x2 = assertThrows(IllegalArgumentException.class, () -> container.get(BigInteger.class));
80+
assertTrue(x2.getMessage().startsWith("The type 'java.math.BigInteger' is outside the allowed input types:"), x2.getMessage());
8881
}
8982

9083
@Test
9184
void testToString() {
92-
StableComponentContainer<Number> container = populated();
85+
HeterogeneousContainer<Number> container = populated();
9386
var toString = container.toString();
9487
assertTrue(toString.startsWith("StableComponentContainer{"), toString);
9588
for (Class<? extends Number> type : SET) {
@@ -100,16 +93,16 @@ void testToString() {
10093

10194
@Test
10295
void testToStringEmpty() {
103-
StableComponentContainer<Number> container = StableComponentContainer.of(Set.of());
96+
HeterogeneousContainer<Number> container = HeterogeneousContainer.of(Set.of());
10497
assertEquals("StableComponentContainer{}", container.toString());
10598
}
10699

107100
@Test
108101
void computeIfAbsent() {
109-
StableComponentContainer<Number> container = StableComponentContainer.of(SET);
110-
Integer value = container.computeIfAbsent(Integer.class, StableComponentContainerTest::mapper);
102+
HeterogeneousContainer<Number> container = HeterogeneousContainer.of(SET);
103+
Integer value = container.computeIfAbsent(Integer.class, HeterogeneousContainerTest::mapper);
111104
assertEquals(1, value);
112-
assertThrows(NullPointerException.class, () -> container.computeIfAbsent(Byte.class, StableComponentContainerTest::mapper));
105+
assertThrows(NullPointerException.class, () -> container.computeIfAbsent(Byte.class, HeterogeneousContainerTest::mapper));
113106
}
114107

115108
static <C extends Number> C mapper(Class<C> type) {
@@ -120,8 +113,8 @@ static <C extends Number> C mapper(Class<C> type) {
120113
});
121114
}
122115

123-
private static StableComponentContainer<Number> populated() {
124-
StableComponentContainer<Number> container = StableComponentContainer.of(SET);
116+
private static HeterogeneousContainer<Number> populated() {
117+
HeterogeneousContainer<Number> container = HeterogeneousContainer.of(SET);
125118
container.set(Byte.class, (byte) 1);
126119
container.set(Short.class, (short) 1);
127120
container.set(Integer.class, 1);
@@ -131,4 +124,36 @@ private static StableComponentContainer<Number> populated() {
131124
return container;
132125
}
133126

127+
sealed interface NumericOperations {
128+
non-sealed interface Adder extends NumericOperations {
129+
int add(int a, int b);
130+
}
131+
non-sealed interface Subtractor extends NumericOperations {
132+
int subtract(int a, int b);
133+
}
134+
}
135+
136+
@Test
137+
void testSealedType() {
138+
HeterogeneousContainer<NumericOperations> ops = HeterogeneousContainer.of(NumericOperations.class);
139+
ops.set(NumericOperations.Adder.class, Integer::sum);
140+
ops.set(NumericOperations.Subtractor.class, StrictMath::subtractExact);
141+
// ...
142+
assertEquals(3, ops.get(NumericOperations.Adder.class).add(1,2));
143+
assertEquals(Integer.MIN_VALUE, ops.get(NumericOperations.Adder.class).add(Integer.MAX_VALUE,1));
144+
145+
assertEquals(-1, ops.get(NumericOperations.Subtractor.class).subtract(1,2));
146+
assertThrows(ArithmeticException.class, () -> ops.get(NumericOperations.Subtractor.class).subtract(Integer.MIN_VALUE,1));
147+
}
148+
149+
@Test
150+
void testNoBounds() {
151+
HeterogeneousContainer<Object> c = HeterogeneousContainer.of(Set.of(Integer.class, Long.class, Object.class));
152+
c.set(Integer.class,1);
153+
c.set(Long.class,2L);
154+
assertEquals(1, c.get(Integer.class));
155+
assertEquals(2L, c.get(Long.class));
156+
assertThrows(NoSuchElementException.class, () -> c.get(Object.class));
157+
}
158+
134159
}

0 commit comments

Comments
 (0)