1 /******************************************************************************* 2 * Copyright (c) 2000, 2011 IBM Corporation and others. 3 * 4 * This program and the accompanying materials 5 * are made available under the terms of the Eclipse Public License 2.0 6 * which accompanies this distribution, and is available at 7 * https://www.eclipse.org/legal/epl-2.0/ 8 * 9 * SPDX-License-Identifier: EPL-2.0 10 * 11 * Contributors: 12 * IBM Corporation - initial API and implementation 13 *******************************************************************************/ 14 package org.eclipse.jdt.internal.corext.refactoring.structure.constraints; 15 16 import org.eclipse.core.runtime.Assert; 17 18 import org.eclipse.jdt.internal.corext.refactoring.typeconstraints.types.HierarchyType; 19 import org.eclipse.jdt.internal.corext.refactoring.typeconstraints.types.TType; 20 import org.eclipse.jdt.internal.corext.refactoring.typeconstraints2.ITypeSet; 21 22 /** 23 * Optimized type sets for supertype constraint problems. 24 */ 25 public abstract class SuperTypeSet implements ITypeSet { 26 27 /** Implementation of an empty set */ 28 private static class SuperTypeEmptySet extends SuperTypeSet { 29 30 /* 31 * @see org.eclipse.jdt.internal.corext.refactoring.typeconstraints2.ITypeSet#chooseSingleType() 32 */ 33 @Override chooseSingleType()34 public final TType chooseSingleType() { 35 return null; 36 } 37 38 /* 39 * @see org.eclipse.jdt.internal.corext.refactoring.typeconstraints2.ITypeSet#isEmpty() 40 */ 41 @Override isEmpty()42 public final boolean isEmpty() { 43 return true; 44 } 45 46 /* 47 * @see org.eclipse.jdt.internal.corext.refactoring.typeconstraints2.ITypeSet#restrictedTo(org.eclipse.jdt.internal.corext.refactoring.typeconstraints2.ITypeSet) 48 */ 49 @Override restrictedTo(final ITypeSet set)50 public final ITypeSet restrictedTo(final ITypeSet set) { 51 return this; 52 } 53 54 /* 55 * @see java.lang.Object#toString() 56 */ 57 @Override toString()58 public final String toString() { 59 return "EMPTY"; //$NON-NLS-1$ 60 } 61 } 62 63 /** Implementation of a singleton */ 64 private static class SuperTypeSingletonSet extends SuperTypeSet { 65 66 /** The type */ 67 private final TType fType; 68 69 /** 70 * Creates a new super type singleton set. 71 * 72 * @param type the type 73 */ SuperTypeSingletonSet(final TType type)74 private SuperTypeSingletonSet(final TType type) { 75 fType= type; 76 } 77 78 /* 79 * @see org.eclipse.jdt.internal.corext.refactoring.typeconstraints2.ITypeSet#chooseSingleType() 80 */ 81 @Override chooseSingleType()82 public final TType chooseSingleType() { 83 return fType; 84 } 85 86 /* 87 * @see org.eclipse.jdt.internal.corext.refactoring.typeconstraints2.ITypeSet#isEmpty() 88 */ 89 @Override isEmpty()90 public final boolean isEmpty() { 91 return false; 92 } 93 94 /* 95 * @see org.eclipse.jdt.internal.corext.refactoring.typeconstraints2.ITypeSet#restrictedTo(org.eclipse.jdt.internal.corext.refactoring.typeconstraints2.ITypeSet) 96 */ 97 @Override restrictedTo(final ITypeSet set)98 public final ITypeSet restrictedTo(final ITypeSet set) { 99 final TType leftErasure= fType.getErasure(); 100 if (set instanceof SuperTypeUniverse) { 101 return this; 102 } else if (set instanceof SuperTypeSingletonSet) { 103 if (this == set) 104 return this; 105 if (fType.isNullType()) 106 return this; 107 final SuperTypeSingletonSet singleton= (SuperTypeSingletonSet) set; 108 final TType rightErasure= singleton.fType.getErasure(); 109 if (leftErasure.isHierarchyType() && rightErasure.isHierarchyType()) { 110 if (leftErasure.isGenericType() || rightErasure.isGenericType()) { 111 if (rightErasure.equals(leftErasure) || ((HierarchyType) leftErasure).isSubType((HierarchyType) rightErasure)) 112 return this; 113 } 114 } 115 if (rightErasure.isJavaLangObject()) 116 return this; 117 if (leftErasure.canAssignTo(rightErasure)) 118 return this; 119 return SuperTypeSet.getEmpty(); 120 } else if (set instanceof SuperTypeTuple) { 121 if (fType.isNullType()) 122 return this; 123 final SuperTypeTuple tuple= (SuperTypeTuple) set; 124 final TType rightErasure= tuple.fSuperType.getErasure(); 125 if (leftErasure.isHierarchyType() && rightErasure.isHierarchyType()) { 126 if (leftErasure.isGenericType() || rightErasure.isGenericType()) { 127 if (rightErasure.equals(leftErasure) || ((HierarchyType) leftErasure).isSubType((HierarchyType) rightErasure)) 128 return this; 129 } 130 } 131 if (rightErasure.isJavaLangObject()) 132 return this; 133 if (leftErasure.canAssignTo(rightErasure)) 134 return this; 135 return SuperTypeSet.createTypeSet(tuple.fSubType); 136 } else if (set instanceof SuperTypeEmptySet) { 137 return set; 138 } else 139 Assert.isTrue(false); 140 return null; 141 } 142 143 /* 144 * @see java.lang.Object#toString() 145 */ 146 @Override toString()147 public final String toString() { 148 return fType.getPrettySignature(); 149 } 150 } 151 152 /** Implementation of a tuple */ 153 private static class SuperTypeTuple extends SuperTypeSet { 154 155 /** The other type */ 156 private final TType fSubType; 157 158 /** The super type */ 159 private final TType fSuperType; 160 161 /** 162 * Creates a new super type tuple. 163 * 164 * @param subType the sub type 165 * @param superType the super type 166 */ SuperTypeTuple(final TType subType, final TType superType)167 private SuperTypeTuple(final TType subType, final TType superType) { 168 fSubType= subType; 169 fSuperType= superType; 170 } 171 172 /* 173 * @see org.eclipse.jdt.internal.corext.refactoring.typeconstraints2.ITypeSet#chooseSingleType() 174 */ 175 @Override chooseSingleType()176 public final TType chooseSingleType() { 177 return fSuperType; 178 } 179 180 /* 181 * @see org.eclipse.jdt.internal.corext.refactoring.typeconstraints2.ITypeSet#isEmpty() 182 */ 183 @Override isEmpty()184 public final boolean isEmpty() { 185 return false; 186 } 187 188 /* 189 * @see org.eclipse.jdt.internal.corext.refactoring.typeconstraints2.ITypeSet#restrictedTo(org.eclipse.jdt.internal.corext.refactoring.typeconstraints2.ITypeSet) 190 */ 191 @Override restrictedTo(final ITypeSet set)192 public final ITypeSet restrictedTo(final ITypeSet set) { 193 if (set instanceof SuperTypeUniverse) { 194 return this; 195 } else if (set instanceof SuperTypeSingletonSet) { 196 final SuperTypeSingletonSet singleton= (SuperTypeSingletonSet) set; 197 final TType rightErasure= singleton.fType.getErasure(); 198 final TType subErasure= fSubType.getErasure(); 199 final TType superErasure= fSuperType.getErasure(); 200 if (subErasure.isHierarchyType() && superErasure.isHierarchyType() && rightErasure.isHierarchyType()) { 201 if (subErasure.isGenericType() || superErasure.isGenericType() || rightErasure.isGenericType()) { 202 if ((rightErasure.equals(subErasure) || ((HierarchyType) subErasure).isSubType((HierarchyType) rightErasure)) 203 && (rightErasure.equals(superErasure) || ((HierarchyType) superErasure).isSubType((HierarchyType) rightErasure))) 204 return this; 205 } 206 } 207 if (rightErasure.isJavaLangObject()) 208 return this; 209 if (subErasure.canAssignTo(rightErasure) && superErasure.canAssignTo(rightErasure)) 210 return this; 211 return SuperTypeSet.createTypeSet(fSubType); 212 } else if (set instanceof SuperTypeTuple) { 213 return this; 214 } else if (set instanceof SuperTypeEmptySet) { 215 return set; 216 } else 217 Assert.isTrue(false); 218 return null; 219 } 220 221 /* 222 * @see java.lang.Object#toString() 223 */ 224 @Override toString()225 public final String toString() { 226 return "[" + fSubType.getPrettySignature() + ", " + fSuperType.getPrettySignature() + "]"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ 227 } 228 } 229 230 /** Implementation of the type universe */ 231 private static class SuperTypeUniverse extends SuperTypeSet { 232 233 /* 234 * @see org.eclipse.jdt.internal.corext.refactoring.typeconstraints2.ITypeSet#chooseSingleType() 235 */ 236 @Override chooseSingleType()237 public final TType chooseSingleType() { 238 return null; 239 } 240 241 /* 242 * @see org.eclipse.jdt.internal.corext.refactoring.typeconstraints2.ITypeSet#isEmpty() 243 */ 244 @Override isEmpty()245 public final boolean isEmpty() { 246 return false; 247 } 248 249 /* 250 * @see org.eclipse.jdt.internal.corext.refactoring.typeconstraints2.ITypeSet#restrictedTo(org.eclipse.jdt.internal.corext.refactoring.typeconstraints2.ITypeSet) 251 */ 252 @Override restrictedTo(final ITypeSet set)253 public final ITypeSet restrictedTo(final ITypeSet set) { 254 return set; 255 } 256 257 /* 258 * @see java.lang.Object#toString() 259 */ 260 @Override toString()261 public final String toString() { 262 return "UNIVERSE"; //$NON-NLS-1$ 263 } 264 } 265 266 /** The empty set */ 267 private static final ITypeSet fgEmpty= new SuperTypeEmptySet(); 268 269 /** The universe */ 270 private static final ITypeSet fgUniverse= new SuperTypeUniverse(); 271 272 /** 273 * Creates a new type set. 274 * 275 * @param type the type to contain, or <code>null</code> 276 * @return the type set, or the universe if <code>type</code> is <code>null</code> 277 */ createTypeSet(final TType type)278 public static ITypeSet createTypeSet(final TType type) { 279 if (type == null) 280 return fgUniverse; 281 return new SuperTypeSingletonSet(type); 282 } 283 284 /** 285 * Creates a new type set. 286 * 287 * @param subType the sub type 288 * @param superType the super type 289 * @return the type set, or the universe if <code>type</code> is <code>null</code> 290 */ createTypeSet(final TType subType, final TType superType)291 public static ITypeSet createTypeSet(final TType subType, final TType superType) { 292 if (subType == null || superType == null) 293 return fgUniverse; 294 return new SuperTypeTuple(subType, superType); 295 } 296 297 /** 298 * Returns the empty set. 299 * 300 * @return the empty set 301 */ getEmpty()302 public static ITypeSet getEmpty() { 303 return fgEmpty; 304 } 305 306 /** 307 * Returns the universe set. 308 * 309 * @return the universe set 310 */ getUniverse()311 public static ITypeSet getUniverse() { 312 return fgUniverse; 313 } 314 SuperTypeSet()315 private SuperTypeSet() { 316 } 317 } 318