1 12 13 package org.eclipse.jdt.internal.compiler.apt.model; 14 15 import java.lang.reflect.Array ; 16 import java.util.ArrayList ; 17 import java.util.Collections ; 18 import java.util.EnumSet ; 19 import java.util.List ; 20 import java.util.Set ; 21 22 import javax.lang.model.element.AnnotationMirror; 23 import javax.lang.model.element.Element; 24 import javax.lang.model.element.ElementKind; 25 import javax.lang.model.element.Modifier; 26 import javax.lang.model.element.PackageElement; 27 import javax.lang.model.element.TypeParameterElement; 28 import javax.lang.model.type.DeclaredType; 29 import javax.lang.model.type.ErrorType; 30 import javax.lang.model.type.NoType; 31 import javax.lang.model.type.NullType; 32 import javax.lang.model.type.TypeKind; 33 import javax.lang.model.type.TypeMirror; 34 35 import org.eclipse.jdt.internal.compiler.apt.dispatch.BaseProcessingEnvImpl; 36 import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants; 37 import org.eclipse.jdt.internal.compiler.lookup.AnnotationBinding; 38 import org.eclipse.jdt.internal.compiler.lookup.ArrayBinding; 39 import org.eclipse.jdt.internal.compiler.lookup.BaseTypeBinding; 40 import org.eclipse.jdt.internal.compiler.lookup.Binding; 41 import org.eclipse.jdt.internal.compiler.lookup.MethodBinding; 42 import org.eclipse.jdt.internal.compiler.lookup.PackageBinding; 43 import org.eclipse.jdt.internal.compiler.lookup.ParameterizedTypeBinding; 44 import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding; 45 import org.eclipse.jdt.internal.compiler.lookup.TypeConstants; 46 import org.eclipse.jdt.internal.compiler.lookup.TypeIds; 47 import org.eclipse.jdt.internal.compiler.lookup.TypeVariableBinding; 48 import org.eclipse.jdt.internal.compiler.lookup.VariableBinding; 49 import org.eclipse.jdt.internal.compiler.lookup.WildcardBinding; 50 51 54 public class Factory { 55 56 public static final Byte DUMMY_BYTE = 0; 59 public static final Character DUMMY_CHAR = '0'; 60 public static final Double DUMMY_DOUBLE = 0d; 61 public static final Float DUMMY_FLOAT = 0f; 62 public static final Integer DUMMY_INTEGER = 0; 63 public static final Long DUMMY_LONG = 0l; 64 public static final Short DUMMY_SHORT = 0; 65 66 private final BaseProcessingEnvImpl _env; 67 68 71 public Factory(BaseProcessingEnvImpl env) { 72 _env = env; 73 } 74 75 79 public List <? extends AnnotationMirror> getAnnotationMirrors(AnnotationBinding[] annotations) { 80 if (null == annotations || 0 == annotations.length) { 81 return Collections.emptyList(); 82 } 83 List <AnnotationMirror> list = new ArrayList <AnnotationMirror>(annotations.length); 84 for (AnnotationBinding annotation : annotations) { 85 if (annotation == null) continue; 86 list.add(newAnnotationMirror(annotation)); 87 } 88 return Collections.unmodifiableList(list); 89 } 90 91 private static void appendModifier(Set <Modifier> result, int modifiers, int modifierConstant, Modifier modifier) { 92 if ((modifiers & modifierConstant) != 0) { 93 result.add(modifier); 94 } 95 } 96 97 private static void decodeModifiers(Set <Modifier> result, int modifiers, int[] checkBits) { 98 if (checkBits == null) return; 99 for (int i = 0, max = checkBits.length; i < max; i++) { 100 switch(checkBits[i]) { 101 case ClassFileConstants.AccPublic : 102 appendModifier(result, modifiers, checkBits[i], Modifier.PUBLIC); 103 break; 104 case ClassFileConstants.AccProtected: 105 appendModifier(result, modifiers, checkBits[i], Modifier.PROTECTED); 106 break; 107 case ClassFileConstants.AccPrivate : 108 appendModifier(result, modifiers, checkBits[i], Modifier.PRIVATE); 109 break; 110 case ClassFileConstants.AccAbstract : 111 appendModifier(result, modifiers, checkBits[i], Modifier.ABSTRACT); 112 break; 113 case ClassFileConstants.AccStatic : 114 appendModifier(result, modifiers, checkBits[i], Modifier.STATIC); 115 break; 116 case ClassFileConstants.AccFinal : 117 appendModifier(result, modifiers, checkBits[i], Modifier.FINAL); 118 break; 119 case ClassFileConstants.AccSynchronized : 120 appendModifier(result, modifiers, checkBits[i], Modifier.SYNCHRONIZED); 121 break; 122 case ClassFileConstants.AccNative : 123 appendModifier(result, modifiers, checkBits[i], Modifier.NATIVE); 124 break; 125 case ClassFileConstants.AccStrictfp : 126 appendModifier(result, modifiers, checkBits[i], Modifier.STRICTFP); 127 break; 128 case ClassFileConstants.AccTransient : 129 appendModifier(result, modifiers, checkBits[i], Modifier.TRANSIENT); 130 break; 131 case ClassFileConstants.AccVolatile : 132 appendModifier(result, modifiers, checkBits[i], Modifier.VOLATILE); 133 break; 134 } 135 } 136 } 137 138 public static Object getMatchingDummyValue(final Class <?> expectedType){ 139 if( expectedType.isPrimitive() ){ 140 if(expectedType == boolean.class) 141 return Boolean.FALSE; 142 else if( expectedType == byte.class ) 143 return DUMMY_BYTE; 144 else if( expectedType == char.class ) 145 return DUMMY_CHAR; 146 else if( expectedType == double.class) 147 return DUMMY_DOUBLE; 148 else if( expectedType == float.class ) 149 return DUMMY_FLOAT; 150 else if( expectedType == int.class ) 151 return DUMMY_INTEGER; 152 else if( expectedType == long.class ) 153 return DUMMY_LONG; 154 else if(expectedType == short.class) 155 return DUMMY_SHORT; 156 else return DUMMY_INTEGER; } 159 else 160 return null; 161 } 162 163 public static Set <Modifier> getModifiers(int modifiers, ElementKind kind) { 164 return getModifiers(modifiers, kind, false); 165 } 166 169 public static Set <Modifier> getModifiers(int modifiers, ElementKind kind, boolean isFromBinary) 170 { 171 EnumSet <Modifier> result = EnumSet.noneOf(Modifier.class); 172 switch(kind) { 173 case CONSTRUCTOR : 174 case METHOD : 175 decodeModifiers(result, modifiers, new int[] { 177 ClassFileConstants.AccPublic, 178 ClassFileConstants.AccProtected, 179 ClassFileConstants.AccPrivate, 180 ClassFileConstants.AccAbstract, 181 ClassFileConstants.AccStatic, 182 ClassFileConstants.AccFinal, 183 ClassFileConstants.AccSynchronized, 184 ClassFileConstants.AccNative, 185 ClassFileConstants.AccStrictfp 186 }); 187 break; 188 case FIELD : 189 case ENUM_CONSTANT : 190 decodeModifiers(result, modifiers, new int[] { 192 ClassFileConstants.AccPublic, 193 ClassFileConstants.AccProtected, 194 ClassFileConstants.AccPrivate, 195 ClassFileConstants.AccStatic, 196 ClassFileConstants.AccFinal, 197 ClassFileConstants.AccTransient, 198 ClassFileConstants.AccVolatile 199 }); 200 break; 201 case ENUM : 202 if (isFromBinary) { 203 decodeModifiers(result, modifiers, new int[] { 204 ClassFileConstants.AccPublic, 205 ClassFileConstants.AccProtected, 206 ClassFileConstants.AccFinal, 207 ClassFileConstants.AccPrivate, 208 ClassFileConstants.AccAbstract, 209 ClassFileConstants.AccStatic, 210 ClassFileConstants.AccStrictfp 211 }); 212 } else { 213 decodeModifiers(result, modifiers, new int[] { 215 ClassFileConstants.AccPublic, 216 ClassFileConstants.AccProtected, 217 ClassFileConstants.AccFinal, 218 ClassFileConstants.AccPrivate, 219 ClassFileConstants.AccStatic, 220 ClassFileConstants.AccStrictfp 221 }); 222 } 223 break; 224 case ANNOTATION_TYPE : 225 case INTERFACE : 226 case CLASS : 227 decodeModifiers(result, modifiers, new int[] { 229 ClassFileConstants.AccPublic, 230 ClassFileConstants.AccProtected, 231 ClassFileConstants.AccAbstract, 232 ClassFileConstants.AccFinal, 233 ClassFileConstants.AccPrivate, 234 ClassFileConstants.AccStatic, 235 ClassFileConstants.AccStrictfp 236 }); 237 } 238 return Collections.unmodifiableSet(result); 239 } 240 241 public AnnotationMirror newAnnotationMirror(AnnotationBinding binding) 242 { 243 return new AnnotationMirrorImpl(_env, binding); 244 } 245 246 public Element newElement(Binding binding) { 247 if (binding == null) { 248 return new ErrorTypeElement(this._env); 249 } 250 switch (binding.kind()) { 251 case Binding.FIELD: 252 case Binding.LOCAL: 253 case Binding.VARIABLE: 254 return new VariableElementImpl(_env, (VariableBinding) binding); 255 case Binding.TYPE: 256 case Binding.GENERIC_TYPE: 257 ReferenceBinding referenceBinding = (ReferenceBinding)binding; 258 if (referenceBinding.sourceName == TypeConstants.PACKAGE_INFO_NAME) { 259 return new PackageElementImpl(_env, referenceBinding.fPackage); 260 } 261 return new TypeElementImpl(_env, referenceBinding); 262 case Binding.METHOD: 263 return new ExecutableElementImpl(_env, (MethodBinding)binding); 264 case Binding.RAW_TYPE: 265 case Binding.PARAMETERIZED_TYPE: 266 return new TypeElementImpl(_env, ((ParameterizedTypeBinding)binding).genericType()); 267 case Binding.PACKAGE: 268 return new PackageElementImpl(_env, (PackageBinding)binding); 269 case Binding.TYPE_PARAMETER: 270 return new TypeParameterElementImpl(_env, (TypeVariableBinding)binding); 271 case Binding.IMPORT: 273 case Binding.ARRAY_TYPE: 274 case Binding.BASE_TYPE: 275 case Binding.WILDCARD_TYPE: 276 throw new UnsupportedOperationException ("NYI: binding type " + binding.kind()); } 278 return null; 279 } 280 281 public DeclaredType newDeclaredType(ReferenceBinding binding) { 282 if (binding.kind() == Binding.WILDCARD_TYPE) { 283 throw new IllegalArgumentException ("A wildcard binding can't be turned into a DeclaredType"); } 286 return new DeclaredTypeImpl(_env, binding); 287 } 288 289 292 public PackageElement newPackageElement(PackageBinding binding) 293 { 294 return new PackageElementImpl(_env, binding); 295 } 296 297 public NullType getNullType() { 298 return NoTypeImpl.NULL_TYPE; 299 } 300 301 public NoType getNoType(TypeKind kind) 302 { 303 switch (kind) { 304 case NONE: 305 return NoTypeImpl.NO_TYPE_NONE; 306 case VOID: 307 return NoTypeImpl.NO_TYPE_VOID; 308 case PACKAGE: 309 return NoTypeImpl.NO_TYPE_PACKAGE; 310 default: 311 throw new IllegalArgumentException (); 312 } 313 } 314 315 319 public PrimitiveTypeImpl getPrimitiveType(TypeKind kind) 320 { 321 switch (kind) { 322 case BOOLEAN: 323 return PrimitiveTypeImpl.BOOLEAN; 324 case BYTE: 325 return PrimitiveTypeImpl.BYTE; 326 case CHAR: 327 return PrimitiveTypeImpl.CHAR; 328 case DOUBLE: 329 return PrimitiveTypeImpl.DOUBLE; 330 case FLOAT: 331 return PrimitiveTypeImpl.FLOAT; 332 case INT: 333 return PrimitiveTypeImpl.INT; 334 case LONG: 335 return PrimitiveTypeImpl.LONG; 336 case SHORT: 337 return PrimitiveTypeImpl.SHORT; 338 default: 339 throw new IllegalStateException (); 340 } 341 } 342 343 346 public PrimitiveTypeImpl getPrimitiveType(BaseTypeBinding binding) { 347 return getPrimitiveType(PrimitiveTypeImpl.getKind(binding)); 348 } 349 350 353 public TypeMirror newTypeMirror(Binding binding) { 354 switch (binding.kind()) { 355 case Binding.FIELD: 356 case Binding.LOCAL: 357 case Binding.VARIABLE: 358 return newTypeMirror(((VariableBinding)binding).type); 360 361 case Binding.PACKAGE: 362 return getNoType(TypeKind.PACKAGE); 363 364 case Binding.IMPORT: 365 throw new UnsupportedOperationException ("NYI: import type " + binding.kind()); 367 case Binding.METHOD: 368 return new ExecutableTypeImpl(_env, (MethodBinding) binding); 369 370 case Binding.TYPE: 371 case Binding.RAW_TYPE: 372 case Binding.GENERIC_TYPE: 373 case Binding.PARAMETERIZED_TYPE: 374 return new DeclaredTypeImpl(_env, (ReferenceBinding)binding); 375 376 case Binding.ARRAY_TYPE: 377 return new ArrayTypeImpl(_env, (ArrayBinding)binding); 378 379 case Binding.BASE_TYPE: 380 BaseTypeBinding btb = (BaseTypeBinding)binding; 381 switch (btb.id) { 382 case TypeIds.T_void: 383 return getNoType(TypeKind.VOID); 384 case TypeIds.T_null: 385 return getNullType(); 386 default: 387 return getPrimitiveType(PrimitiveTypeImpl.getKind((BaseTypeBinding)binding)); 388 } 389 390 case Binding.WILDCARD_TYPE: 391 return new WildcardTypeImpl(_env, (WildcardBinding) binding); 392 393 case Binding.TYPE_PARAMETER: 394 return new TypeVariableImpl(_env, (TypeVariableBinding) binding); 395 } 396 return null; 397 } 398 399 402 public TypeParameterElement newTypeParameterElement(TypeVariableBinding variable, Element declaringElement) 403 { 404 return new TypeParameterElementImpl(_env, variable, declaringElement); 405 } 406 407 public ErrorType getErrorType() { 408 return new ErrorTypeImpl(this._env); 409 } 410 411 452 public static Object performNecessaryPrimitiveTypeConversion( 453 final Class <?> expectedType, 454 final Object value, 455 final boolean avoidReflectException) 456 { 457 assert expectedType.isPrimitive() : "expectedType is not a primitive type: " + expectedType.getName(); if( value == null) 459 return avoidReflectException ? getMatchingDummyValue(expectedType) : null; 460 final String typeName = expectedType.getName(); 462 final char expectedTypeChar = typeName.charAt(0); 463 final int nameLen = typeName.length(); 464 if( value instanceof Byte ) 467 { 468 final byte b = ((Byte )value).byteValue(); 469 switch( expectedTypeChar ) 470 { 471 case 'b': 472 if(nameLen == 4) return value; else 475 return avoidReflectException ? Boolean.FALSE : value; 476 case 'c': 477 return new Character ((char)b); case 'd': 479 return new Double (b); case 'f': 481 return new Float (b); case 'i': 483 return new Integer (b); case 'l': 485 return new Long (b); case 's': 487 return new Short (b); default: 489 throw new IllegalStateException ("unknown type " + expectedTypeChar); } 491 } 492 else if( value instanceof Short ) 495 { 496 final short s = ((Short )value).shortValue(); 497 switch( expectedTypeChar ) 498 { 499 case 'b': 500 if(nameLen == 4) return new Byte ((byte)s); else 503 return avoidReflectException ? Boolean.FALSE : value; case 'c': 505 return new Character ((char)s); case 'd': 507 return new Double (s); case 'f': 509 return new Float (s); case 'i': 511 return new Integer (s); case 'l': 513 return new Long (s); case 's': 515 return value; default: 517 throw new IllegalStateException ("unknown type " + expectedTypeChar); } 519 } 520 else if( value instanceof Character ) 523 { 524 final char c = ((Character )value).charValue(); 525 switch( expectedTypeChar ) 526 { 527 case 'b': 528 if(nameLen == 4) return new Byte ((byte)c); else 531 return avoidReflectException ? Boolean.FALSE : value; case 'c': 533 return value; case 'd': 535 return new Double (c); case 'f': 537 return new Float (c); case 'i': 539 return new Integer (c); case 'l': 541 return new Long (c); case 's': 543 return new Short ((short)c); default: 545 throw new IllegalStateException ("unknown type " + expectedTypeChar); } 547 } 548 549 else if( value instanceof Integer ) 552 { 553 final int i = ((Integer )value).intValue(); 554 switch( expectedTypeChar ) 555 { 556 case 'b': 557 if(nameLen == 4) return new Byte ((byte)i); else 560 return avoidReflectException ? Boolean.FALSE : value; case 'c': 562 return new Character ((char)i); case 'd': 564 return new Double (i); case 'f': 566 return new Float (i); case 'i': 568 return value; case 'l': 570 return new Long (i); case 's': 572 return new Short ((short)i); default: 574 throw new IllegalStateException ("unknown type " + expectedTypeChar); } 576 } 577 else if( value instanceof Long ) 579 { 580 final long l = ((Long )value).longValue(); 581 switch( expectedTypeChar ) 582 { 583 case 'b': case 'c': 585 case 'i': 586 case 's': 587 return avoidReflectException ? getMatchingDummyValue(expectedType) : value; 589 case 'd': 590 return new Double (l); case 'f': 592 return new Float (l); case 'l': 594 return value; 596 default: 597 throw new IllegalStateException ("unknown type " + expectedTypeChar); } 599 } 600 601 else if( value instanceof Float ) 603 { 604 final float f = ((Float )value).floatValue(); 605 switch( expectedTypeChar ) 606 { 607 case 'b': case 'c': 609 case 'i': 610 case 's': 611 case 'l': 612 return avoidReflectException ? getMatchingDummyValue(expectedType) : value; 614 case 'd': 615 return new Double (f); case 'f': 617 return value; default: 619 throw new IllegalStateException ("unknown type " + expectedTypeChar); } 621 } 622 else if( value instanceof Double ){ 623 if(expectedTypeChar == 'd' ) 624 return value; else{ 626 return avoidReflectException ? getMatchingDummyValue(expectedType) : value; } 628 } 629 else if( value instanceof Boolean ){ 630 if( expectedTypeChar == 'b' && nameLen == 7) return value; 632 else 633 return avoidReflectException ? getMatchingDummyValue(expectedType) : value; } 635 else return avoidReflectException ? getMatchingDummyValue(expectedType) : value; 637 } 638 639 645 public static void setArrayMatchingDummyValue(Object array, int i, Class <?> expectedLeafType) 646 { 647 if (boolean.class.equals(expectedLeafType)) { 648 Array.setBoolean(array, i, false); 649 } 650 else if (byte.class.equals(expectedLeafType)) { 651 Array.setByte(array, i, DUMMY_BYTE); 652 } 653 else if (char.class.equals(expectedLeafType)) { 654 Array.setChar(array, i, DUMMY_CHAR); 655 } 656 else if (double.class.equals(expectedLeafType)) { 657 Array.setDouble(array, i, DUMMY_DOUBLE); 658 } 659 else if (float.class.equals(expectedLeafType)) { 660 Array.setFloat(array, i, DUMMY_FLOAT); 661 } 662 else if (int.class.equals(expectedLeafType)) { 663 Array.setInt(array, i, DUMMY_INTEGER); 664 } 665 else if (long.class.equals(expectedLeafType)) { 666 Array.setLong(array, i, DUMMY_LONG); 667 } 668 else if (short.class.equals(expectedLeafType)) { 669 Array.setShort(array, i, DUMMY_SHORT); 670 } 671 else { 672 Array.set(array, i, null); 673 } 674 } 675 676 } 677 | Popular Tags |