2 * Copyright (C) 2014, United States Government, as represented by the
3 * Administrator of the National Aeronautics and Space Administration.
6 * The Java Pathfinder core (jpf-core) platform is licensed under the
7 * Apache License, Version 2.0 (the "License"); you may not use this file except
8 * in compliance with the License. You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0.
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
18 package sun.reflect.generics.reflectiveObjects;
20 import sun.reflect.generics.tree.FieldTypeSignature;
22 import java.lang.reflect.MalformedParameterizedTypeException;
23 import java.lang.reflect.Method;
24 import java.lang.reflect.ParameterizedType;
25 import java.lang.reflect.Type;
26 import java.lang.reflect.TypeVariable;
27 import java.util.Arrays;
28 import java.util.Objects;
30 // TODO: Fix for Groovy's model-checking
32 * MJI model class for sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl
34 * This is a JPF specific version of a system class because we can't use the real,
35 * platform VM specific version (it's native all over the place, its field
36 * structure isn't documented, most of its methods are private, hence we can't
37 * even instantiate it properly).
39 * Note that this class never gets seen by the real VM - it's for JPF's eyes only.
43 /** Implementing class for ParameterizedType interface. */
44 public class ParameterizedTypeImpl implements ParameterizedType {
45 private final Type[] actualTypeArguments;
46 private final Class<?> rawType;
47 private final Type ownerType;
49 private ParameterizedTypeImpl(Class<?> rawType,
50 Type[] actualTypeArguments,
52 this.actualTypeArguments = actualTypeArguments;
53 this.rawType = rawType;
54 this.ownerType = (ownerType != null) ? ownerType : rawType.getDeclaringClass();
55 validateConstructorArguments();
58 private void validateConstructorArguments() {
59 TypeVariable<?>[] formals = rawType.getTypeParameters();
60 // check correct arity of actual type args
61 if (formals.length != actualTypeArguments.length){
62 throw new MalformedParameterizedTypeException();
64 for (int i = 0; i < actualTypeArguments.length; i++) {
65 // check actuals against formals' bounds
70 * Static factory. Given a (generic) class, actual type arguments
71 * and an owner type, creates a parameterized type.
73 public static ParameterizedTypeImpl make(Class<?> rawType,
74 Type[] actualTypeArguments,
76 return new ParameterizedTypeImpl(rawType, actualTypeArguments,
80 public Type[] getActualTypeArguments() {
81 return actualTypeArguments.clone();
85 * Returns the <tt>Type</tt> object representing the class or interface
86 * that declared this type.
88 * @return the <tt>Type</tt> object representing the class or interface
89 * that declared this type
91 public Class<?> getRawType() {
96 public Type getOwnerType() {
101 public boolean equals(Object o) {
102 if (o instanceof ParameterizedType) {
103 // Check that information is equivalent
104 ParameterizedType that = (ParameterizedType) o;
109 Type thatOwner = that.getOwnerType();
110 Type thatRawType = that.getRawType();
112 if (false) { // Debugging
113 boolean ownerEquality = (ownerType == null ?
115 ownerType.equals(thatOwner));
116 boolean rawEquality = (rawType == null ?
117 thatRawType == null :
118 rawType.equals(thatRawType));
120 boolean typeArgEquality = Arrays.equals(actualTypeArguments, // avoid clone
121 that.getActualTypeArguments());
122 for (Type t : actualTypeArguments) {
123 System.out.printf("\t\t%s%s%n", t, t.getClass());
126 System.out.printf("\towner %s\traw %s\ttypeArg %s%n",
127 ownerEquality, rawEquality, typeArgEquality);
128 return ownerEquality && rawEquality && typeArgEquality;
132 Objects.equals(ownerType, thatOwner) &&
133 Objects.equals(rawType, thatRawType) &&
134 Arrays.equals(actualTypeArguments, // avoid clone
135 that.getActualTypeArguments());
141 public int hashCode() {
143 Arrays.hashCode(actualTypeArguments) ^
144 Objects.hashCode(ownerType) ^
145 Objects.hashCode(rawType);
148 public String toString() {
149 StringBuilder sb = new StringBuilder();
151 if (ownerType != null) {
152 if (ownerType instanceof Class)
153 sb.append(((Class)ownerType).getName());
155 sb.append(ownerType.toString());
159 if (ownerType instanceof ParameterizedTypeImpl) {
160 // Find simple name of nested type by removing the
161 // shared prefix with owner.
162 sb.append(rawType.getName().replace( ((ParameterizedTypeImpl)ownerType).rawType.getName() + "$",
165 sb.append(rawType.getName());
167 sb.append(rawType.getName());
169 if (actualTypeArguments != null &&
170 actualTypeArguments.length > 0) {
172 boolean first = true;
173 for(Type t: actualTypeArguments) {
176 sb.append(t.getTypeName());
182 return sb.toString();