1 11 12 package org.eclipse.jdt.apt.core.internal.util; 13 14 import com.sun.mirror.declaration.PackageDeclaration; 15 import com.sun.mirror.declaration.TypeDeclaration; 16 import com.sun.mirror.declaration.TypeParameterDeclaration; 17 import com.sun.mirror.type.ArrayType; 18 import com.sun.mirror.type.DeclaredType; 19 import com.sun.mirror.type.PrimitiveType; 20 import com.sun.mirror.type.ReferenceType; 21 import com.sun.mirror.type.TypeMirror; 22 import com.sun.mirror.type.TypeVariable; 23 import com.sun.mirror.type.VoidType; 24 import com.sun.mirror.type.WildcardType; 25 import com.sun.mirror.util.Types; 26 import java.util.Collection ; 27 28 import org.eclipse.jdt.apt.core.internal.NonEclipseImplementationException; 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.core.BindingKey; 33 import org.eclipse.jdt.core.Signature; 34 import org.eclipse.jdt.core.dom.IPackageBinding; 35 import org.eclipse.jdt.core.dom.ITypeBinding; 36 37 public class TypesUtil implements Types 38 { 39 private static final String [] NO_ARGS = new String [0]; 40 private final BaseProcessorEnv _env; 41 42 public static void main(String [] args){} 43 44 public TypesUtil(BaseProcessorEnv env){ 45 _env = env; 46 assert env != null : "null environment."; } 48 49 public ArrayType getArrayType(TypeMirror componentType) 50 { 51 if( componentType == null ) return null; 52 if( componentType instanceof EclipseMirrorType ){ 53 final EclipseMirrorType impl = (EclipseMirrorType)componentType; 54 final ITypeBinding leaf; 56 final int dimension; 57 switch( impl.kind() ) 58 { 59 case TYPE_ERROR: case TYPE_VOID: 60 throw new IllegalArgumentException ("Illegal element type for array"); case TYPE_ARRAY: 62 final ITypeBinding array = ((ArrayTypeImpl)componentType).getTypeBinding(); 63 dimension = array.getDimensions() + 1; 64 leaf = array.getElementType(); 65 break; 66 default: 67 leaf = impl.getTypeBinding(); 68 dimension = 1; 69 break; 70 } 71 if( leaf == null || leaf.isParameterizedType() ) 72 throw new IllegalArgumentException ("illegal component type: " + componentType); 74 final String bindingKey = BindingKey.createArrayTypeBindingKey(leaf.getKey(), dimension); 75 final ITypeBinding arrayType = _env.getTypeBindingFromKey(bindingKey); 76 if(arrayType == null) 77 return null; 78 return (ArrayType)Factory.createTypeMirror(arrayType, _env); 79 } 80 81 throw new NonEclipseImplementationException("only applicable to eclipse type system objects." + " Found " + componentType.getClass().getName()); 84 } 85 86 92 private ITypeBinding findMemberType(ITypeBinding outer, String inner ) 93 { 94 if( outer == null || inner == null ) return null; 95 96 outer = outer.getTypeDeclaration(); 97 98 final ITypeBinding[] nestedTypes = outer.getDeclaredTypes(); 99 for( ITypeBinding nestedType : nestedTypes ){ 101 if( inner.equals(nestedType.getName()) ) 102 return nestedType; 103 } 104 ITypeBinding result = findMemberType(outer.getSuperclass(), inner); 107 if( result != null ) return result; 108 109 final ITypeBinding[] interfaces = outer.getInterfaces(); 111 for( ITypeBinding interfaceType : interfaces ){ 112 result = findMemberType(interfaceType, inner); 113 if( result != null ) return result; 114 } 115 116 return null; 118 } 119 120 public com.sun.mirror.type.DeclaredType getDeclaredType(DeclaredType containing, TypeDeclaration decl, TypeMirror... typeArgs) 121 { 122 if( decl == null ) return null; 123 124 final ITypeBinding outerBinding = getTypeBinding(containing); 125 final ITypeBinding memberBinding; 126 127 if( containing == null ) 128 memberBinding = getTypeBinding(decl); 129 else{ 130 if( outerBinding.isGenericType() ) 131 throw new IllegalArgumentException ("[containing], " + containing + ", is a generic type."); memberBinding = findMemberType(outerBinding, decl.getSimpleName() ); 134 if( memberBinding == null ) 135 throw new IllegalArgumentException (decl + " is not a member type of " + containing ); } 137 138 final int numArgs = typeArgs == null ? 0 : typeArgs.length; 139 140 if( memberBinding.isGenericType() ){ 141 final String [] argKeys = numArgs == 0 ? NO_ARGS : new String [numArgs]; 142 for( int i=0; i<numArgs; i++ ){ 143 final ITypeBinding binding = getTypeBinding(typeArgs[i]); 144 assert binding != null : "failed to get binding mirror type"; argKeys[i] = binding.getKey(); 146 } 147 148 final ITypeBinding[] typeParams = memberBinding.getTypeParameters(); 149 final int numTypeParams = typeParams == null ? 0 : typeParams.length; 150 if( numTypeParams != numArgs && numArgs != 0 ) 153 throw new IllegalArgumentException ("type, " + memberBinding.getQualifiedName() + ", require " + numTypeParams + " type arguments " + "but found " + numArgs ); 156 final String typeKey = BindingKey.createParameterizedTypeBindingKey(memberBinding.getKey(), argKeys); 157 final ITypeBinding resultBinding = _env.getTypeBindingFromKey(typeKey); 158 return Factory.createReferenceType(resultBinding, _env); 159 } 160 else{ 161 if( numArgs != 0 ) 162 throw new IllegalArgumentException ("type, " + memberBinding + " is not a generic type and cannot have type arguments."); return (DeclaredType)decl; 165 } 166 } 167 168 public com.sun.mirror.type.DeclaredType getDeclaredType(TypeDeclaration decl, TypeMirror... typeArgs) 169 { 170 return getDeclaredType(null, decl, typeArgs); 171 } 172 173 public TypeMirror getErasure(TypeMirror t) 174 { 175 if( t == null ) return null; 176 177 if(t instanceof EclipseMirrorType){ 178 final EclipseMirrorType impl = (EclipseMirrorType)t; 179 final ITypeBinding binding; 180 switch( impl.kind() ) 181 { 182 case TYPE_PRIMITIVE: 183 case TYPE_VOID: 184 case TYPE_ERROR: 185 return t; 186 187 default: 188 binding = impl.getTypeBinding(); 189 } 190 final ITypeBinding erasure = binding.getErasure(); 191 if( erasure == binding ) return t; 192 TypeMirror m_erasure = Factory.createTypeMirror(erasure, impl.getEnvironment() ); 193 if( m_erasure == null ) 194 return Factory.createErrorClassType(erasure); 195 return m_erasure; 196 } 197 198 throw new NonEclipseImplementationException("only applicable to eclipse type system objects." + " Found " + t.getClass().getName()); } 201 202 public PrimitiveType getPrimitiveType(PrimitiveType.Kind kind) 203 { 204 if( kind == null ) return null; 205 switch(kind) 206 { 207 case BOOLEAN: return _env.getBooleanType(); 208 case BYTE: return _env.getByteType(); 209 case CHAR: return _env.getCharType(); 210 case DOUBLE: return _env.getDoubleType(); 211 case FLOAT: return _env.getFloatType(); 212 case INT: return _env.getIntType(); 213 case LONG: return _env.getLongType(); 214 case SHORT: return _env.getShortType(); 215 216 default: throw new IllegalStateException ("unknown primitive kind : " + kind); } 218 } 219 220 public TypeVariable getTypeVariable(TypeParameterDeclaration tparam) 221 { 222 if( tparam == null ) return null; 223 if( tparam instanceof TypeParameterDeclarationImpl) 224 return (TypeVariable) tparam; 225 226 throw new NonEclipseImplementationException("only applicable to eclipse type system objects." + " Found " + tparam.getClass().getName()); } 229 230 public VoidType getVoidType() 231 { 232 return _env.getVoidType(); 233 } 234 235 public WildcardType getWildcardType(Collection <ReferenceType> upperBounds, Collection <ReferenceType> lowerBounds) 236 { 237 final String boundKey; 238 final char boundKind; 239 final int upperBoundCount = upperBounds == null ? 0 : upperBounds.size(); 240 final int lowerBoundCount = lowerBounds == null ? 0 : lowerBounds.size(); 241 if( upperBoundCount == 0 && lowerBoundCount == 0 ){ 242 boundKey = null; 243 boundKind = Signature.C_STAR; 244 } 245 else if( upperBoundCount == 1 && lowerBoundCount == 0){ 246 final ITypeBinding binding = getTypeBinding(upperBounds.iterator().next()); 247 boundKey = binding.getKey(); 248 boundKind = Signature.C_EXTENDS; 249 } 250 else if(lowerBoundCount == 1 && upperBoundCount == 0){ 251 final ITypeBinding binding = getTypeBinding(lowerBounds.iterator().next()); 252 boundKey = binding.getKey(); 253 boundKind = Signature.C_SUPER; 254 } 255 else 256 throw new IllegalArgumentException ("Wildcard can only have a upper bound, a lower bound or be unbounded."); 258 final String wildcardkey = BindingKey.createWilcardTypeBindingKey(boundKey, boundKind); 259 final ITypeBinding wildcard = _env.getTypeBindingFromKey(wildcardkey); 260 return (WildcardType)Factory.createTypeMirror(wildcard, _env); 261 } 262 263 266 public boolean isAssignable(TypeMirror t1, TypeMirror t2) 267 { 268 EclipseMirrorType left = (EclipseMirrorType)t1; 269 EclipseMirrorType right = (EclipseMirrorType)t2; 270 return left.isAssignmentCompatible(right); 271 272 } 273 274 public boolean isSubtype(TypeMirror t1, TypeMirror t2) 275 { 276 EclipseMirrorType left = (EclipseMirrorType)t1; 277 EclipseMirrorType right = (EclipseMirrorType)t2; 278 279 return left.isSubTypeCompatible(right); 280 } 281 282 public static IPackageBinding getPackageBinding(PackageDeclaration pkg) 283 throws NonEclipseImplementationException 284 { 285 if(pkg == null) return null; 286 if( pkg instanceof EclipseMirrorObject ){ 287 final PackageDeclarationImpl impl = (PackageDeclarationImpl)pkg; 288 return impl.getPackageBinding(); 289 } 290 291 throw new NonEclipseImplementationException("only applicable to eclipse type system objects." + " Found " + pkg.getClass().getName()); } 294 295 300 301 private static ITypeBinding getTypeBinding(TypeMirror type) 302 throws NonEclipseImplementationException 303 { 304 if(type == null ) return null; 305 if( type instanceof EclipseMirrorType ){ 306 return ((EclipseMirrorType)type).getTypeBinding(); 307 } 308 309 throw new NonEclipseImplementationException("only applicable to eclipse type system objects." + " Found " + type.getClass().getName()); } 312 313 317 public static ITypeBinding getTypeBinding(TypeDeclaration type) 318 throws NonEclipseImplementationException 319 { 320 if(type == null ) return null; 321 if( type instanceof EclipseMirrorObject ){ 322 return ((TypeDeclarationImpl)type).getTypeBinding(); 323 } 324 throw new NonEclipseImplementationException("only applicable to eclipse type system objects." + " Found " + type.getClass().getName()); } 327 } 328 | Popular Tags |