1 package java.lang.reflect.code.type;
 2 
 3 import java.lang.reflect.code.TypeElement;
 4 import java.util.List;
 5 import java.util.Objects;
 6 import java.util.stream.Stream;
 7 
 8 /**
 9  * A function type.
10  */
11 public final class FunctionType implements TypeElement {
12     // @@@ Change to "->" when the textual form supports it
13     static final String NAME = "func";
14 
15     /**
16      * The function type with no parameters, returning void.
17      */
18     // @@@ Uses JavaType
19     public static final FunctionType VOID = functionType(JavaType.VOID);
20 
21     final TypeElement returnType;
22     final List<TypeElement> parameterTypes;
23 
24     FunctionType(TypeElement returnType, List<? extends TypeElement> parameterTypes) {
25         this.returnType = returnType;
26         this.parameterTypes = List.copyOf(parameterTypes);
27     }
28 
29     /**
30      * {@return the function type's return type}
31      */
32     public TypeElement returnType() {
33         return returnType;
34     }
35 
36     /**
37      * {@return the function type's parameter types}
38      */
39     public List<TypeElement> parameterTypes() {
40         return parameterTypes;
41     }
42 
43     @Override
44     public ExternalizedTypeElement externalize() {
45         return new ExternalizedTypeElement(NAME,
46                 Stream.concat(Stream.of(returnType), parameterTypes.stream())
47                         .map(TypeElement::externalize).toList());
48     }
49 
50     @Override
51     public String toString() {
52         return externalize().toString();
53     }
54 
55     @Override
56     public boolean equals(Object o) {
57         if (this == o) return true;
58         return o instanceof FunctionType that &&
59                 returnType.equals(that.returnType) &&
60                 parameterTypes.equals(that.parameterTypes);
61     }
62 
63     @Override
64     public int hashCode() {
65         int result = returnType.hashCode();
66         result = 31 * result + parameterTypes.hashCode();
67         return result;
68     }
69 
70     /**
71      * Constructs a function type.
72      *
73      * @param returnType the function type's return type.
74      * @param parameterTypes the function type's parameter types.
75      * @return a function type.
76      */
77     public static FunctionType functionType(TypeElement returnType, List<? extends TypeElement> parameterTypes) {
78         Objects.requireNonNull(returnType);
79         Objects.requireNonNull(parameterTypes);
80         return new FunctionType(returnType, parameterTypes);
81     }
82     /**
83      * Constructs a function type.
84      *
85      * @param returnType the function type's return type.
86      * @param parameterTypes the function type's parameter types.
87      * @return a function type.
88      */
89     public static FunctionType functionType(TypeElement returnType, TypeElement... parameterTypes) {
90         return functionType(returnType, List.of(parameterTypes));
91     }
92 
93 }