1 11 12 package org.eclipse.jdt.apt.core.internal.util; 13 14 import com.sun.mirror.declaration.AnnotationMirror; 15 import com.sun.mirror.declaration.AnnotationValue; 16 import com.sun.mirror.declaration.ParameterDeclaration; 17 import com.sun.mirror.type.AnnotationType; 18 import com.sun.mirror.type.ArrayType; 19 import com.sun.mirror.type.ClassType; 20 import com.sun.mirror.type.InterfaceType; 21 import com.sun.mirror.type.PrimitiveType; 22 import com.sun.mirror.type.TypeMirror; 23 24 import java.util.ArrayList ; 25 import java.util.Collections ; 26 import java.util.List ; 27 28 import org.eclipse.core.resources.IFile; 29 import org.eclipse.jdt.apt.core.internal.declaration.*; 30 import org.eclipse.jdt.apt.core.internal.env.BaseProcessorEnv; 31 import org.eclipse.jdt.apt.core.internal.type.ArrayTypeImpl; 32 import org.eclipse.jdt.apt.core.internal.type.ErrorType; 33 import org.eclipse.jdt.apt.core.internal.type.WildcardTypeImpl; 34 import org.eclipse.jdt.core.dom.ASTNode; 35 import org.eclipse.jdt.core.dom.AnnotationTypeMemberDeclaration; 36 import org.eclipse.jdt.core.dom.IAnnotationBinding; 37 import org.eclipse.jdt.core.dom.IBinding; 38 import org.eclipse.jdt.core.dom.IMethodBinding; 39 import org.eclipse.jdt.core.dom.ITypeBinding; 40 import org.eclipse.jdt.core.dom.IVariableBinding; 41 import org.eclipse.jdt.core.dom.SingleVariableDeclaration; 42 import org.eclipse.jdt.core.dom.VariableDeclarationFragment; 43 44 public class Factory 45 { 46 private static final String NULL_BINDING_NAME = "[NullBinding]"; public static final Byte DUMMY_BYTE = 0; 50 public static final Character DUMMY_CHAR = '0'; 51 public static final Double DUMMY_DOUBLE = 0d; 52 public static final Float DUMMY_FLOAT = 0f; 53 public static final Integer DUMMY_INTEGER = 0; 54 public static final Long DUMMY_LONG = 0l; 55 public static final Short DUMMY_SHORT = 0; 56 public static TypeDeclarationImpl createReferenceType(ITypeBinding binding, BaseProcessorEnv env) 57 { 58 if(binding == null || binding.isNullType()) return null; 59 TypeDeclarationImpl mirror = null; 60 if( binding.isAnnotation() ) 63 mirror = new AnnotationDeclarationImpl(binding, env); 64 else if (binding.isInterface() ) 65 mirror = new InterfaceDeclarationImpl(binding, env); 66 else if( binding.isEnum() ) 68 mirror = new EnumDeclarationImpl(binding, env); 69 else if( binding.isClass() ) 70 mirror = new ClassDeclarationImpl(binding, env); 71 else 72 throw new IllegalStateException ("cannot create type declaration from " + binding); 74 return mirror; 75 } 76 77 public static EclipseDeclarationImpl createDeclaration(IBinding binding, BaseProcessorEnv env) 78 { 79 if(binding == null) return null; 80 81 switch(binding.getKind()) 82 { 83 case IBinding.TYPE: 84 final ITypeBinding typeBinding = (ITypeBinding)binding; 85 if( typeBinding.isAnonymous() || typeBinding.isArray() || 86 typeBinding.isWildcardType() || typeBinding.isPrimitive() ) 87 throw new IllegalStateException ("failed to create declaration from " + binding); if( typeBinding.isTypeVariable() ) 89 return new TypeParameterDeclarationImpl(typeBinding, env); 90 else 91 return createReferenceType(typeBinding, env); 92 case IBinding.VARIABLE: 93 final IVariableBinding varBinding = (IVariableBinding)binding; 94 if(varBinding.isEnumConstant()) 95 return new EnumConstantDeclarationImpl(varBinding, env); 96 else 97 return new FieldDeclarationImpl(varBinding, env); 98 case IBinding.METHOD: 99 final IMethodBinding method = (IMethodBinding)binding; 100 if( method.isConstructor() ) 101 return new ConstructorDeclarationImpl(method, env); 102 final ITypeBinding declaringType = method.getDeclaringClass(); 103 if( declaringType != null && declaringType.isAnnotation() ) 104 return new AnnotationElementDeclarationImpl(method, env); 105 else 106 return new MethodDeclarationImpl(method, env); 107 default: 108 throw new IllegalStateException ("failed to create declaration from " + binding); } 110 } 111 112 public static EclipseDeclarationImpl createDeclaration( 113 ASTNode node, 114 IFile file, 115 BaseProcessorEnv env) 116 { 117 if( node == null ) 118 return null; 119 switch( node.getNodeType() ) 120 { 121 case ASTNode.SINGLE_VARIABLE_DECLARATION: 122 return new SourceParameterDeclarationImpl((SingleVariableDeclaration)node, file, env); 123 case ASTNode.VARIABLE_DECLARATION_FRAGMENT: 124 return new ASTBasedFieldDeclarationImpl( (VariableDeclarationFragment)node, file, env ); 125 case ASTNode.METHOD_DECLARATION : 126 final org.eclipse.jdt.core.dom.MethodDeclaration methodDecl = 127 (org.eclipse.jdt.core.dom.MethodDeclaration)node; 128 if( methodDecl.isConstructor() ) 129 return new ASTBasedConstructorDeclarationImpl(methodDecl, file, env); 130 else 131 return new ASTBasedMethodDeclarationImpl(methodDecl, file, env ); 132 case ASTNode.ANNOTATION_TYPE_MEMBER_DECLARATION: 133 return new ASTBasedMethodDeclarationImpl((AnnotationTypeMemberDeclaration)node, file, env); 134 default : 135 throw new UnsupportedOperationException ( 136 "cannot create mirror type from " + node.getClass().getName() ); 138 } 139 } 140 141 public static EclipseMirrorType createTypeMirror(ITypeBinding binding, BaseProcessorEnv env) 142 { 143 if( binding == null ) return null; 144 145 if( binding.isPrimitive() ){ 146 if( "int".equals(binding.getName()) ) return env.getIntType(); 148 else if( "byte".equals(binding.getName()) ) return env.getByteType(); 150 else if( "short".equals(binding.getName()) ) return env.getShortType(); 152 else if( "char".equals(binding.getName()) ) return env.getCharType(); 154 else if( "long".equals(binding.getName()) ) return env.getLongType(); 156 else if( "float".equals(binding.getName()) ) return env.getFloatType(); 158 else if( "double".equals(binding.getName()) ) return env.getDoubleType(); 160 else if( "boolean".equals(binding.getName())) return env.getBooleanType(); 162 else if( "void".equals(binding.getName()) ) return env.getVoidType(); 164 else 165 throw new IllegalStateException ("unrecognized primitive type: " + binding); } 167 else if( binding.isArray() ) 168 return new ArrayTypeImpl(binding, env); 169 else if( binding.isWildcardType() ){ 170 return new WildcardTypeImpl(binding, env); 171 } 172 else if( binding.isTypeVariable() ) 173 return new TypeParameterDeclarationImpl(binding, env); 174 else 175 return createReferenceType(binding, env); 176 } 177 178 public static ParameterDeclaration createParameterDeclaration( 179 final SingleVariableDeclaration param, 180 final IFile file, 181 final BaseProcessorEnv env) 182 { 183 return new SourceParameterDeclarationImpl(param, file, env); 184 } 185 186 187 public static ParameterDeclaration createParameterDeclaration( 188 final ExecutableDeclarationImpl exec, 189 final int paramIndex, 190 final ITypeBinding type, 191 final BaseProcessorEnv env ) 192 { 193 return new BinaryParameterDeclarationImpl(exec, type, paramIndex, env); 194 } 195 196 197 203 public static AnnotationMirror createAnnotationMirror(final IAnnotationBinding annotation, 204 final EclipseDeclarationImpl annotated, 205 final BaseProcessorEnv env) 206 { 207 return new AnnotationMirrorImpl(annotation, annotated, env); 208 } 209 210 public static AnnotationValue createDefaultValue( 211 Object domValue, 212 AnnotationElementDeclarationImpl decl, 213 BaseProcessorEnv env) 214 { 215 if( domValue == null ) return null; 216 final Object converted = convertDOMValueToMirrorValue( 217 domValue, null, decl, decl, env, decl.getReturnType()); 218 219 return createAnnotationValueFromDOMValue(converted, null, -1, decl, env); 220 } 221 222 231 public static AnnotationValue createDefaultValue(Object domValue, 232 ASTBasedAnnotationElementDeclarationImpl decl, 233 BaseProcessorEnv env) 234 { 235 if( domValue == null ) return null; 236 final Object converted = convertDOMValueToMirrorValue( 237 domValue, null, decl, decl, env, decl.getReturnType()); 238 239 return createAnnotationValueFromDOMValue(converted, null, -1, decl, env); 240 } 241 242 250 public static AnnotationValue createAnnotationMemberValue(Object domValue, 251 String elementName, 252 AnnotationMirrorImpl anno, 253 BaseProcessorEnv env, 254 TypeMirror expectedType) 255 { 256 if( domValue == null ) return null; 257 final Object converted = convertDOMValueToMirrorValue( 258 domValue, elementName, anno, 259 anno.getAnnotatedDeclaration(), env, expectedType); 260 return createAnnotationValueFromDOMValue(converted, elementName, -1, anno, env); 261 } 262 263 271 public static AnnotationValue createAnnotationValueFromDOMValue(Object convertedValue, 272 String name, 273 int index, 274 EclipseMirrorObject mirror, 275 BaseProcessorEnv env) 276 { 277 if( convertedValue == null ) return null; 278 if( mirror instanceof AnnotationMirrorImpl ) 279 return new AnnotationValueImpl(convertedValue, name, index, (AnnotationMirrorImpl)mirror, env); 280 else 281 return new AnnotationValueImpl(convertedValue, index, (AnnotationElementDeclarationImpl)mirror, env); 282 } 283 284 285 301 private static Object convertDOMValueToMirrorValue(Object domValue, 302 String name, 303 EclipseMirrorObject parent, 304 EclipseDeclarationImpl decl, 305 BaseProcessorEnv env, 306 TypeMirror expectedType) 307 { 308 if( domValue == null ) return null; 309 310 final Object returnValue; 311 if( domValue instanceof Boolean || 312 domValue instanceof Byte || 313 domValue instanceof Character || 314 domValue instanceof Double || 315 domValue instanceof Float || 316 domValue instanceof Integer || 317 domValue instanceof Long || 318 domValue instanceof Short || 319 domValue instanceof String ) 320 returnValue = domValue; 321 322 else if( domValue instanceof IVariableBinding ) 323 { 324 returnValue = Factory.createDeclaration((IVariableBinding)domValue, env); 325 } 326 else if (domValue instanceof Object []) 327 { 328 final Object [] elements = (Object [])domValue; 329 final int len = elements.length; 330 final List <AnnotationValue> annoValues = new ArrayList <AnnotationValue>(len); 331 final TypeMirror leaf; 332 if( expectedType instanceof ArrayType ) 333 leaf = ((ArrayType)expectedType).getComponentType(); 334 else 335 leaf = expectedType; for( int i=0; i<len; i++ ){ 337 if( elements[i] == null ) continue; 338 else if( elements[i] instanceof Object [] ) 341 return null; 342 343 Object o = convertDOMValueToMirrorValue( elements[i], name, parent, decl, env, leaf ); 344 if( o == null ) 345 return null; 346 assert( !( o instanceof IAnnotationBinding ) ) : 347 "Unexpected return value from convertDomValueToMirrorValue! o.getClass().getName() = " + o.getClass().getName(); 349 350 final AnnotationValue annoValue = createAnnotationValueFromDOMValue(o, name, i, parent, env); 351 if( annoValue != null ) 352 annoValues.add(annoValue); 353 } 354 return annoValues; 355 } 356 else if( domValue instanceof ITypeBinding ) 358 returnValue = Factory.createTypeMirror((ITypeBinding)domValue, env); 359 360 else if( domValue instanceof IAnnotationBinding ) 361 { 362 returnValue = Factory.createAnnotationMirror((IAnnotationBinding)domValue, decl, env); 363 } 364 else 365 throw new IllegalStateException ("cannot build annotation value object from " + domValue); 368 return performNecessaryTypeConversion(expectedType, returnValue, name, parent, env); 369 } 370 371 public static Object getMatchingDummyValue(final Class <?> expectedType){ 372 if( expectedType.isPrimitive() ){ 373 if(expectedType == boolean.class) 374 return Boolean.FALSE; 375 else if( expectedType == byte.class ) 376 return DUMMY_BYTE; 377 else if( expectedType == char.class ) 378 return DUMMY_CHAR; 379 else if( expectedType == double.class) 380 return DUMMY_DOUBLE; 381 else if( expectedType == float.class ) 382 return DUMMY_FLOAT; 383 else if( expectedType == int.class ) 384 return DUMMY_INTEGER; 385 else if( expectedType == long.class ) 386 return DUMMY_LONG; 387 else if(expectedType == short.class) 388 return DUMMY_SHORT; 389 else return DUMMY_INTEGER; } 392 else 393 return null; 394 } 395 396 436 public static Object performNecessaryPrimitiveTypeConversion( 437 final Class <?> expectedType, 438 final Object value, 439 final boolean avoidReflectException) 440 { 441 assert expectedType.isPrimitive() : "expectedType is not a primitive type: " + expectedType.getName(); if( value == null) 443 return avoidReflectException ? getMatchingDummyValue(expectedType) : null; 444 final String typeName = expectedType.getName(); 446 final char expectedTypeChar = typeName.charAt(0); 447 final int nameLen = typeName.length(); 448 if( value instanceof Byte ) 451 { 452 final byte b = ((Byte )value).byteValue(); 453 switch( expectedTypeChar ) 454 { 455 case 'b': 456 if(nameLen == 4) return value; else 459 return avoidReflectException ? Boolean.FALSE : value; 460 case 'c': 461 return new Character ((char)b); case 'd': 463 return new Double (b); case 'f': 465 return new Float (b); case 'i': 467 return new Integer (b); case 'l': 469 return new Long (b); case 's': 471 return new Short (b); default: 473 throw new IllegalStateException ("unknown type " + expectedTypeChar); } 475 } 476 else if( value instanceof Short ) 479 { 480 final short s = ((Short )value).shortValue(); 481 switch( expectedTypeChar ) 482 { 483 case 'b': 484 if(nameLen == 4) return new Byte ((byte)s); else 487 return avoidReflectException ? Boolean.FALSE : value; case 'c': 489 return new Character ((char)s); case 'd': 491 return new Double (s); case 'f': 493 return new Float (s); case 'i': 495 return new Integer (s); case 'l': 497 return new Long (s); case 's': 499 return value; default: 501 throw new IllegalStateException ("unknown type " + expectedTypeChar); } 503 } 504 else if( value instanceof Character ) 507 { 508 final char c = ((Character )value).charValue(); 509 switch( expectedTypeChar ) 510 { 511 case 'b': 512 if(nameLen == 4) return new Byte ((byte)c); else 515 return avoidReflectException ? Boolean.FALSE : value; case 'c': 517 return value; case 'd': 519 return new Double (c); case 'f': 521 return new Float (c); case 'i': 523 return new Integer (c); case 'l': 525 return new Long (c); case 's': 527 return new Short ((short)c); default: 529 throw new IllegalStateException ("unknown type " + expectedTypeChar); } 531 } 532 533 else if( value instanceof Integer ) 536 { 537 final int i = ((Integer )value).intValue(); 538 switch( expectedTypeChar ) 539 { 540 case 'b': 541 if(nameLen == 4) return new Byte ((byte)i); else 544 return avoidReflectException ? Boolean.FALSE : value; case 'c': 546 return new Character ((char)i); case 'd': 548 return new Double (i); case 'f': 550 return new Float (i); case 'i': 552 return value; case 'l': 554 return new Long (i); case 's': 556 return new Short ((short)i); default: 558 throw new IllegalStateException ("unknown type " + expectedTypeChar); } 560 } 561 else if( value instanceof Long ) 563 { 564 final long l = ((Long )value).longValue(); 565 switch( expectedTypeChar ) 566 { 567 case 'b': case 'c': 569 case 'i': 570 case 's': 571 return avoidReflectException ? getMatchingDummyValue(expectedType) : value; 573 case 'd': 574 return new Double (l); case 'f': 576 return new Float (l); case 'l': 578 return value; 580 default: 581 throw new IllegalStateException ("unknown type " + expectedTypeChar); } 583 } 584 585 else if( value instanceof Float ) 587 { 588 final float f = ((Float )value).floatValue(); 589 switch( expectedTypeChar ) 590 { 591 case 'b': case 'c': 593 case 'i': 594 case 's': 595 case 'l': 596 return avoidReflectException ? getMatchingDummyValue(expectedType) : value; 598 case 'd': 599 return new Double (f); case 'f': 601 return value; default: 603 throw new IllegalStateException ("unknown type " + expectedTypeChar); } 605 } 606 else if( value instanceof Double ){ 607 if(expectedTypeChar == 'd' ) 608 return value; else{ 610 return avoidReflectException ? getMatchingDummyValue(expectedType) : value; } 612 } 613 else if( value instanceof Boolean ){ 614 if( expectedTypeChar == 'b' && nameLen == 7) return value; 616 else 617 return avoidReflectException ? getMatchingDummyValue(expectedType) : value; } 619 else return avoidReflectException ? getMatchingDummyValue(expectedType) : value; 621 } 622 623 private static Class <?> getJavaLangClass_Primitive(final PrimitiveType primitiveType){ 624 switch( primitiveType.getKind() ){ 625 case BOOLEAN: return boolean.class; 626 case BYTE: return byte.class; 627 case CHAR: return char.class; 628 case DOUBLE: return double.class; 629 case FLOAT: return float.class; 630 case INT: return int.class; 631 case LONG: return long.class; 632 case SHORT: return short.class; 633 default: 634 throw new IllegalStateException ("unknow primitive type " + primitiveType ); } 636 } 637 638 647 private static Object performNecessaryTypeConversion(final TypeMirror expectedType, 648 final Object value, 649 final String name, 650 final EclipseMirrorObject parent, 651 final BaseProcessorEnv env) 652 { 653 if( expectedType == null )return value; 654 if( expectedType instanceof PrimitiveType ) 655 { 656 final Class <?> primitiveClass = getJavaLangClass_Primitive( (PrimitiveType)expectedType ); 657 return performNecessaryPrimitiveTypeConversion(primitiveClass, value, false); 658 } 659 else if( expectedType instanceof ArrayType) 661 { 662 final TypeMirror componentType = ((ArrayType)expectedType).getComponentType(); 663 Object converted = value; 664 if( !(componentType instanceof ArrayType ) ) 666 converted = performNecessaryTypeConversion(componentType, value, name, parent, env); 667 668 final AnnotationValue annoValue = createAnnotationValueFromDOMValue(converted, name, 0, parent, env); 669 return Collections.singletonList(annoValue); 670 } 671 else return value; 673 } 674 675 public static InterfaceType createErrorInterfaceType(final ITypeBinding binding) 676 { 677 String name = null == binding ? NULL_BINDING_NAME : binding.getName(); 678 return new ErrorType.ErrorInterface(name); 679 } 680 681 public static ClassType createErrorClassType(final ITypeBinding binding) 682 { 683 String name = null == binding ? NULL_BINDING_NAME : binding.getName(); 684 return createErrorClassType(name); 685 } 686 687 public static ClassType createErrorClassType(final String name) 688 { 689 return new ErrorType.ErrorClass(name); 690 } 691 692 public static AnnotationType createErrorAnnotationType(final ITypeBinding binding) 693 { 694 String name = null == binding ? NULL_BINDING_NAME : binding.getName(); 695 return createErrorAnnotationType(name); 696 } 697 698 public static AnnotationType createErrorAnnotationType(String name) 699 { 700 return new ErrorType.ErrorAnnotation(name); 701 } 702 703 public static ArrayType createErrorArrayType(final String name, final int dimension) 704 { 705 return new ErrorType.ErrorArrayType(name, dimension); 706 } 707 } 708 | Popular Tags |