1 package java.lang.reflect.code.type;
 2 
 3 import java.lang.reflect.code.TypeElement;
 4 import java.lang.reflect.code.Value;
 5 import java.util.List;
 6 import java.util.Objects;
 7 import java.util.stream.Stream;
 8 
 9 /**
10  * A tuple type.
11  */
12 public final class TupleType implements TypeElement {
13     static final String NAME = "Tuple";
14 
15     final List<TypeElement> componentTypes;
16 
17     TupleType(List<? extends TypeElement> componentTypes) {
18         this.componentTypes = List.copyOf(componentTypes);
19     }
20 
21     /**
22      * {@return the tuple's component types, in order}
23      */
24     public List<TypeElement> componentTypes() {
25         return componentTypes;
26     }
27 
28     @Override
29     public ExternalizedTypeElement externalize() {
30         return new ExternalizedTypeElement(NAME, componentTypes.stream().map(TypeElement::externalize).toList());
31     }
32 
33     @Override
34     public String toString() {
35         return externalize().toString();
36     }
37 
38     @Override
39     public boolean equals(Object o) {
40         if (this == o) return true;
41         return o instanceof TupleType that && componentTypes.equals(that.componentTypes);
42     }
43 
44     @Override
45     public int hashCode() {
46         return componentTypes.hashCode();
47     }
48 
49     /**
50      * Constructs a tuple type.
51      *
52      * @param componentTypes the tuple type's component types.
53      * @return a tuple type.
54      */
55     public static TupleType tupleType(List<? extends TypeElement> componentTypes) {
56         Objects.requireNonNull(componentTypes);
57         return new TupleType(componentTypes);
58     }
59 
60     /**
61      * Constructs a tuple type.
62      *
63      * @param componentTypes the tuple type's component types.
64      * @return a tuple type.
65      */
66     public static TupleType tupleType(TypeElement... componentTypes) {
67         return tupleType(List.of(componentTypes));
68     }
69 
70     /**
71      * Constructs a tuple type whose components are the types of
72      * the given values.
73      *
74      * @param values the values.
75      * @return a tuple type.
76      */
77     public static TupleType tupleTypeFromValues(List<? extends Value> values) {
78         return tupleType(values.stream().map(Value::type).toList());
79     }
80 
81     /**
82      * Constructs a tuple type whose components are the types of
83      * the given values.
84      *
85      * @param values the values.
86      * @return a tuple type.
87      */
88     public static TupleType tupleTypeFromValues(Value... values) {
89         return tupleType(Stream.of(values).map(Value::type).toList());
90     }
91 }