1 11 package org.eclipse.jdt.internal.corext.refactoring.structure; 12 13 import java.util.ArrayList ; 14 import java.util.Arrays ; 15 import java.util.HashSet ; 16 import java.util.List ; 17 import java.util.Set ; 18 19 import org.eclipse.core.runtime.Assert; 20 21 import org.eclipse.jdt.core.IField; 22 import org.eclipse.jdt.core.IMember; 23 import org.eclipse.jdt.core.IMethod; 24 import org.eclipse.jdt.core.IType; 25 import org.eclipse.jdt.core.ITypeParameter; 26 import org.eclipse.jdt.core.JavaModelException; 27 import org.eclipse.jdt.core.Signature; 28 29 30 import org.eclipse.jdt.internal.ui.JavaPlugin; 31 32 35 public final class TypeVariableUtil { 36 37 46 public static TypeVariableMaplet[] composeMappings(final TypeVariableMaplet[] first, final TypeVariableMaplet[] second) { 47 Assert.isNotNull(first); 48 Assert.isNotNull(second); 49 50 if (first.length == 0) 51 return first; 52 else if (second.length == 0) 53 return second; 54 else { 55 TypeVariableMaplet source= null; 56 TypeVariableMaplet target= null; 57 final Set set= new HashSet (first.length * second.length); 58 for (int index= 0; index < first.length; index++) { 59 for (int offset= 0; offset < second.length; offset++) { 60 source= first[index]; 61 target= second[offset]; 62 if (source.getTargetIndex() == target.getSourceIndex() && source.getTargetName().equals(target.getSourceName())) 63 set.add(new TypeVariableMaplet(source.getSourceName(), index, target.getTargetName(), offset)); 64 } 65 } 66 final TypeVariableMaplet[] mapping= new TypeVariableMaplet[set.size()]; 67 set.toArray(mapping); 68 return mapping; 69 } 70 } 71 72 80 private static void extractTypeVariables(final String signature, final Set variables) { 81 Assert.isNotNull(signature); 82 Assert.isNotNull(variables); 83 84 final String [] arguments= Signature.getTypeArguments(signature); 85 if (arguments.length == 0) { 86 variables.add(Signature.toString(signature)); 87 } else { 88 for (int index= 0; index < arguments.length; index++) 89 variables.add(Signature.toString(arguments[index])); 90 } 91 } 92 93 104 private static String [] getReferencedVariables(final IType declaring, final IMember member) throws JavaModelException { 105 106 Assert.isNotNull(declaring); 107 Assert.isNotNull(member); 108 109 final String [] variables= parametersToVariables(declaring.getTypeParameters()); 110 String [] result= new String [0]; 111 if (member instanceof IField) { 112 final String signature= ((IField) member).getTypeSignature(); 113 final String [] signatures= getVariableSignatures(signature); 114 if (signatures.length == 0) { 115 final String variable= Signature.toString(signature); 116 for (int index= 0; index < variables.length; index++) { 117 if (variable.equals(variables[index])) { 118 result= new String [] { variable}; 119 break; 120 } 121 } 122 } else { 123 result= new String [signatures.length]; 124 for (int index= 0; index < result.length; index++) 125 result[index]= Signature.toString(signatures[index]); 126 } 127 } else if (member instanceof IMethod) { 128 final IMethod method= (IMethod) member; 129 final HashSet set= new HashSet (); 130 final String [] types= method.getParameterTypes(); 131 for (int index= 0; index < types.length; index++) 132 extractTypeVariables(types[index], set); 133 extractTypeVariables(method.getReturnType(), set); 134 final String [] arguments= parametersToVariables(((IMethod) member).getTypeParameters()); 135 for (int index= 0; index < arguments.length; index++) 136 set.add(arguments[index]); 137 result= new String [set.size()]; 138 set.toArray(result); 139 } else if (member instanceof IType) 140 result= parametersToVariables(((IType) member).getTypeParameters()); 141 else { 142 JavaPlugin.logErrorMessage("Unexpected sub-type of IMember: " + member.getClass().getName()); Assert.isTrue(false); 144 } 145 146 final List list= new ArrayList (variables.length); 147 String variable= null; 148 for (int index= 0; index < variables.length; index++) { 149 variable= variables[index]; 150 for (int offset= 0; offset < result.length; offset++) 151 if (variable.equals(result[offset])) 152 list.add(result[offset]); 153 } 154 result= new String [list.size()]; 155 list.toArray(result); 156 return result; 157 } 158 159 172 public static String [] getUnmappedVariables(final TypeVariableMaplet[] mapping, final IType declaring, final IMember member) throws JavaModelException { 173 174 Assert.isNotNull(mapping); 175 Assert.isNotNull(declaring); 176 Assert.isNotNull(member); 177 178 List list= null; 179 final String [] types= getReferencedVariables(declaring, member); 180 if (mapping.length == 0) { 181 list= new ArrayList (types.length); 182 list.addAll(Arrays.asList(types)); 183 } else { 184 final Set mapped= new HashSet (types.length); 185 String type= null; 186 for (int index= 0; index < types.length; index++) { 187 for (int offset= 0; offset < mapping.length; offset++) { 188 type= types[index]; 189 if (mapping[offset].getSourceName().equals(type)) 190 mapped.add(type); 191 } 192 } 193 list= new ArrayList (types.length - mapped.size()); 194 for (int index= 0; index < types.length; index++) { 195 type= types[index]; 196 if (!mapped.contains(type)) 197 list.add(type); 198 } 199 } 200 final String [] result= new String [list.size()]; 201 list.toArray(result); 202 return result; 203 } 204 205 213 private static String [] getVariableSignatures(final String signature) { 214 Assert.isNotNull(signature); 215 216 String [] result= null; 217 try { 218 result= Signature.getTypeArguments(signature); 219 } catch (IllegalArgumentException exception) { 220 result= new String [0]; 221 } 222 return result; 223 } 224 225 232 public static TypeVariableMaplet[] inverseMapping(final TypeVariableMaplet[] mapping) { 233 Assert.isNotNull(mapping); 234 235 final TypeVariableMaplet[] result= new TypeVariableMaplet[mapping.length]; 236 TypeVariableMaplet maplet= null; 237 for (int index= 0; index < mapping.length; index++) { 238 maplet= mapping[index]; 239 result[index]= new TypeVariableMaplet(maplet.getTargetName(), maplet.getTargetIndex(), maplet.getSourceName(), maplet.getSourceIndex()); 240 } 241 return result; 242 } 243 244 255 private static TypeVariableMaplet[] parametersToSignatures(final ITypeParameter[] domain, final String [] range, final boolean indexes) { 256 Assert.isNotNull(domain); 257 Assert.isNotNull(range); 258 259 final Set set= new HashSet (); 260 ITypeParameter source= null; 261 String target= null; 262 String element= null; 263 String signature= null; 264 for (int index= 0; index < domain.length; index++) { 265 source= domain[index]; 266 for (int offset= 0; offset < range.length; offset++) { 267 target= range[offset]; 268 element= source.getElementName(); 269 signature= Signature.toString(target); 270 if (indexes) { 271 if (offset == index) 272 set.add(new TypeVariableMaplet(element, index, signature, offset)); 273 } else { 274 if (element.equals(signature)) 275 set.add(new TypeVariableMaplet(element, index, signature, offset)); 276 } 277 } 278 } 279 final TypeVariableMaplet[] result= new TypeVariableMaplet[set.size()]; 280 set.toArray(result); 281 return result; 282 } 283 284 292 private static String [] parametersToVariables(final ITypeParameter[] parameters) { 293 Assert.isNotNull(parameters); 294 295 String [] result= new String [parameters.length]; 296 for (int index= 0; index < parameters.length; index++) 297 result[index]= parameters[index].getElementName(); 298 299 return result; 300 } 301 302 311 private static TypeVariableMaplet[] signaturesToParameters(final String [] domain, final ITypeParameter[] range) { 312 Assert.isNotNull(domain); 313 Assert.isNotNull(range); 314 Assert.isTrue(domain.length == 0 || domain.length == range.length); 315 316 final List list= new ArrayList (); 317 String source= null; 318 String target= null; 319 for (int index= 0; index < domain.length; index++) { 320 source= Signature.toString(domain[index]); 321 target= range[index].getElementName(); 322 list.add(new TypeVariableMaplet(source, index, target, index)); 323 } 324 final TypeVariableMaplet[] result= new TypeVariableMaplet[list.size()]; 325 list.toArray(result); 326 return result; 327 } 328 329 338 public static TypeVariableMaplet[] subTypeToInheritedType(final IType type) throws JavaModelException { 339 Assert.isNotNull(type); 340 341 final ITypeParameter[] domain= type.getTypeParameters(); 342 if (domain.length > 0) { 343 final String signature= type.getSuperclassTypeSignature(); 344 if (signature != null) { 345 final String [] range= getVariableSignatures(signature); 346 if (range.length > 0) 347 return parametersToSignatures(domain, range, false); 348 } 349 } 350 return new TypeVariableMaplet[0]; 351 } 352 353 364 public static TypeVariableMaplet[] subTypeToSuperType(final IType subtype, final IType supertype) throws JavaModelException { 365 Assert.isNotNull(subtype); 366 Assert.isNotNull(supertype); 367 368 final TypeVariableMaplet[] mapping= subTypeToInheritedType(subtype); 369 if (mapping.length > 0) { 370 final ITypeParameter[] range= supertype.getTypeParameters(); 371 if (range.length > 0) { 372 final String signature= subtype.getSuperclassTypeSignature(); 373 if (signature != null) { 374 final String [] domain= getVariableSignatures(signature); 375 if (domain.length > 0) 376 return composeMappings(mapping, signaturesToParameters(domain, range)); 377 } 378 } 379 } 380 return mapping; 381 } 382 383 394 public static TypeVariableMaplet[] superTypeToInheritedType(final IType supertype, final IType subtype) throws JavaModelException { 395 Assert.isNotNull(subtype); 396 Assert.isNotNull(supertype); 397 398 final ITypeParameter[] domain= supertype.getTypeParameters(); 399 if (domain.length > 0) { 400 final String signature= subtype.getSuperclassTypeSignature(); 401 if (signature != null) { 402 final String [] range= getVariableSignatures(signature); 403 if (range.length > 0) 404 return parametersToSignatures(domain, range, true); 405 } 406 } 407 return new TypeVariableMaplet[0]; 408 } 409 410 421 public static TypeVariableMaplet[] superTypeToSubType(final IType supertype, final IType subtype) throws JavaModelException { 422 Assert.isNotNull(supertype); 423 Assert.isNotNull(subtype); 424 425 return inverseMapping(subTypeToSuperType(subtype, supertype)); 426 } 427 428 private TypeVariableUtil() { 429 } 431 } 432 | Popular Tags |