1 /******************************************************************************* 2 * Copyright (c) 2007 - 2017 BEA Systems, Inc. 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 * Walter Harley - initial API and implementation 13 * IBM Corporation - fix for 342598, 382590 14 * Jean-Marie Henaff <jmhenaff@google.com> (Google) - Bug 481555 15 *******************************************************************************/ 16 17 package org.eclipse.jdt.internal.compiler.apt.model; 18 19 import java.util.ArrayList; 20 import java.util.Collections; 21 import java.util.List; 22 23 import javax.lang.model.element.Element; 24 import javax.lang.model.element.TypeElement; 25 import javax.lang.model.type.ArrayType; 26 import javax.lang.model.type.DeclaredType; 27 import javax.lang.model.type.ExecutableType; 28 import javax.lang.model.type.NoType; 29 import javax.lang.model.type.NullType; 30 import javax.lang.model.type.PrimitiveType; 31 import javax.lang.model.type.TypeKind; 32 import javax.lang.model.type.TypeMirror; 33 import javax.lang.model.type.WildcardType; 34 import javax.lang.model.util.Types; 35 36 import org.eclipse.jdt.core.compiler.CharOperation; 37 import org.eclipse.jdt.internal.compiler.apt.dispatch.BaseProcessingEnvImpl; 38 import org.eclipse.jdt.internal.compiler.ast.Wildcard; 39 import org.eclipse.jdt.internal.compiler.lookup.ArrayBinding; 40 import org.eclipse.jdt.internal.compiler.lookup.BaseTypeBinding; 41 import org.eclipse.jdt.internal.compiler.lookup.Binding; 42 import org.eclipse.jdt.internal.compiler.lookup.FieldBinding; 43 import org.eclipse.jdt.internal.compiler.lookup.MethodBinding; 44 import org.eclipse.jdt.internal.compiler.lookup.ParameterizedTypeBinding; 45 import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding; 46 import org.eclipse.jdt.internal.compiler.lookup.TypeBinding; 47 import org.eclipse.jdt.internal.compiler.lookup.TypeVariableBinding; 48 49 /** 50 * Utilities for working with types (as opposed to elements). 51 * There is one of these for every ProcessingEnvironment. 52 */ 53 public class TypesImpl implements Types { 54 55 private final BaseProcessingEnvImpl _env; 56 57 /* 58 * The processing env creates and caches a TypesImpl. Other clients should 59 * not create their own; they should ask the env for it. 60 */ TypesImpl(BaseProcessingEnvImpl env)61 public TypesImpl(BaseProcessingEnvImpl env) { 62 _env = env; 63 } 64 65 /* (non-Javadoc) 66 * @see javax.lang.model.util.Types#asElement(javax.lang.model.type.TypeMirror) 67 */ 68 @Override asElement(TypeMirror t)69 public Element asElement(TypeMirror t) { 70 switch(t.getKind()) { 71 case DECLARED : 72 case TYPEVAR : 73 return _env.getFactory().newElement(((TypeMirrorImpl)t).binding()); 74 default: 75 break; 76 } 77 return null; 78 } 79 80 @Override asMemberOf(DeclaredType containing, Element element)81 public TypeMirror asMemberOf(DeclaredType containing, Element element) { 82 // throw new UnsupportedOperationException("NYI: TypesImpl.asMemberOf(" 83 // + containing + ", " + element + ")"); //$NON-NLS-1$ //$NON-NLS-2$ 84 // //$NON-NLS-3$ 85 ElementImpl elementImpl = (ElementImpl) element; 86 DeclaredTypeImpl declaredTypeImpl = (DeclaredTypeImpl) containing; 87 ReferenceBinding referenceBinding = (ReferenceBinding) declaredTypeImpl._binding; 88 TypeMirror typeMirror; 89 90 switch (element.getKind()) { 91 case CONSTRUCTOR: 92 case METHOD: 93 typeMirror = findMemberInHierarchy(referenceBinding, elementImpl._binding, new MemberInTypeFinder() { 94 @Override 95 public TypeMirror find(ReferenceBinding typeBinding, Binding memberBinding) { 96 MethodBinding methodBinding = ((MethodBinding) memberBinding); 97 for (MethodBinding method : typeBinding.methods()) { 98 if (CharOperation.equals(method.selector, methodBinding.selector) 99 && (method.original() == methodBinding 100 || method.areParameterErasuresEqual(methodBinding))) { 101 return TypesImpl.this._env.getFactory().newTypeMirror(method); 102 } 103 } 104 return null; 105 } 106 }); 107 108 if (typeMirror != null) { 109 return typeMirror; 110 } 111 break; 112 case TYPE_PARAMETER: 113 typeMirror = findMemberInHierarchy(referenceBinding, elementImpl._binding, new MemberInTypeFinder() { 114 @Override 115 public TypeMirror find(ReferenceBinding typeBinding, Binding memberBinding) { 116 if (typeBinding instanceof ParameterizedTypeBinding) { 117 TypeVariableBinding variableBinding = ((TypeVariableBinding) memberBinding); 118 ReferenceBinding binding = ((ParameterizedTypeBinding) typeBinding).genericType(); 119 if (variableBinding.declaringElement == binding) { // check in advance avoid looking into type parameters unnecessarily. 120 TypeVariableBinding[] typeVariables = binding.typeVariables(); 121 TypeBinding[] typeArguments = ((ParameterizedTypeBinding) typeBinding).typeArguments(); 122 if (typeVariables.length == typeArguments.length) { 123 for(int i = 0; i < typeVariables.length; i++) { 124 if (typeVariables[i] == memberBinding) { 125 return TypesImpl.this._env.getFactory().newTypeMirror(typeArguments[i]); 126 } 127 } 128 } 129 } 130 } 131 return null; 132 } 133 }); 134 135 if (typeMirror != null) { 136 return typeMirror; 137 } 138 break; 139 case FIELD: 140 case ENUM_CONSTANT: 141 case RECORD_COMPONENT: 142 typeMirror = findMemberInHierarchy(referenceBinding, elementImpl._binding, new MemberInTypeFinder() { 143 @Override 144 public TypeMirror find(ReferenceBinding typeBinding, Binding memberBinding) { 145 FieldBinding fieldBinding = (FieldBinding) memberBinding; 146 for (FieldBinding field : typeBinding.fields()) { 147 if (CharOperation.equals(field.name, fieldBinding.name)) { 148 return TypesImpl.this._env.getFactory().newTypeMirror(field); 149 } 150 } 151 return null; 152 } 153 }); 154 155 if (typeMirror != null) { 156 return typeMirror; 157 } 158 break; 159 case ENUM: 160 case ANNOTATION_TYPE: 161 case INTERFACE: 162 case CLASS: 163 case RECORD: 164 typeMirror = findMemberInHierarchy(referenceBinding, elementImpl._binding, new MemberInTypeFinder() { 165 @Override 166 public TypeMirror find(ReferenceBinding typeBinding, Binding memberBinding) { 167 ReferenceBinding elementBinding = (ReferenceBinding) memberBinding; 168 // If referenceBinding is a ParameterizedTypeBinding, this 169 // will return only ParameterizedTypeBindings 170 // for member types, even if the member happens to be a 171 // static nested class. That's probably a bug; 172 // static nested classes are not parameterized by their 173 // outer class. 174 for (ReferenceBinding memberReferenceBinding : typeBinding.memberTypes()) { 175 if (CharOperation.equals(elementBinding.compoundName, memberReferenceBinding.compoundName)) { 176 return TypesImpl.this._env.getFactory().newTypeMirror(memberReferenceBinding); 177 } 178 } 179 return null; 180 } 181 }); 182 183 if (typeMirror != null) { 184 return typeMirror; 185 } 186 break; 187 default: 188 throw new IllegalArgumentException("element " + element + //$NON-NLS-1$ 189 " has unrecognized element kind " + element.getKind()); //$NON-NLS-1$ 190 } 191 throw new IllegalArgumentException("element " + element + //$NON-NLS-1$ 192 " is not a member of the containing type " + containing + //$NON-NLS-1$ 193 " nor any of its superclasses"); //$NON-NLS-1$ 194 } 195 196 private static interface MemberInTypeFinder { find(ReferenceBinding typeBinding, Binding memberBinding)197 TypeMirror find(ReferenceBinding typeBinding, Binding memberBinding); 198 } 199 findMemberInHierarchy(ReferenceBinding typeBinding, Binding memberBinding, MemberInTypeFinder finder)200 private TypeMirror findMemberInHierarchy(ReferenceBinding typeBinding, Binding memberBinding, 201 MemberInTypeFinder finder) { 202 TypeMirror result = null; 203 204 if (typeBinding == null) { 205 return null; 206 } 207 208 result = finder.find(typeBinding, memberBinding); 209 if (result != null) { 210 return result; 211 } 212 213 result = findMemberInHierarchy(typeBinding.superclass(), memberBinding, finder); 214 if (result != null) { 215 return result; 216 } 217 218 for (ReferenceBinding superInterface : typeBinding.superInterfaces()) { 219 result = findMemberInHierarchy(superInterface, memberBinding, finder); 220 if (result != null) { 221 return result; 222 } 223 } 224 225 return null; 226 } validateRealType(TypeMirror t)227 private void validateRealType(TypeMirror t) { 228 switch (t.getKind()) { 229 case EXECUTABLE: 230 case PACKAGE: 231 case MODULE: 232 throw new IllegalArgumentException( 233 "Executable, package and module are illegal argument for Types.contains(..)"); //$NON-NLS-1$ 234 default: 235 break; 236 } 237 } validateRealTypes(TypeMirror t1, TypeMirror t2)238 private void validateRealTypes(TypeMirror t1, TypeMirror t2) { 239 validateRealType(t1); 240 validateRealType(t2); 241 } 242 243 @Override boxedClass(PrimitiveType p)244 public TypeElement boxedClass(PrimitiveType p) { 245 PrimitiveTypeImpl primitiveTypeImpl = (PrimitiveTypeImpl) p; 246 BaseTypeBinding baseTypeBinding = (BaseTypeBinding)primitiveTypeImpl._binding; 247 TypeBinding boxed = _env.getLookupEnvironment().computeBoxingType(baseTypeBinding); 248 return (TypeElement) _env.getFactory().newElement(boxed); 249 } 250 251 @Override capture(TypeMirror t)252 public TypeMirror capture(TypeMirror t) { 253 validateRealType(t); 254 TypeMirrorImpl typeMirrorImpl = (TypeMirrorImpl) t; 255 if (typeMirrorImpl._binding instanceof ParameterizedTypeBinding) { 256 throw new UnsupportedOperationException("NYI: TypesImpl.capture(...)"); //$NON-NLS-1$ 257 } 258 return t; 259 } 260 261 @Override contains(TypeMirror t1, TypeMirror t2)262 public boolean contains(TypeMirror t1, TypeMirror t2) { 263 validateRealTypes(t1, t2); 264 throw new UnsupportedOperationException("NYI: TypesImpl.contains(" + t1 + ", " + t2 + ")"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ 265 } 266 267 @Override directSupertypes(TypeMirror t)268 public List<? extends TypeMirror> directSupertypes(TypeMirror t) { 269 validateRealType(t); 270 TypeMirrorImpl typeMirrorImpl = (TypeMirrorImpl) t; 271 Binding binding = typeMirrorImpl._binding; 272 if (binding instanceof ReferenceBinding) { 273 ReferenceBinding referenceBinding = (ReferenceBinding) binding; 274 ArrayList<TypeMirror> list = new ArrayList<>(); 275 ReferenceBinding superclass = referenceBinding.superclass(); 276 if (superclass != null) { 277 list.add(this._env.getFactory().newTypeMirror(superclass)); 278 } 279 for (ReferenceBinding interfaceBinding : referenceBinding.superInterfaces()) { 280 list.add(this._env.getFactory().newTypeMirror(interfaceBinding)); 281 } 282 return Collections.unmodifiableList(list); 283 } 284 return Collections.emptyList(); 285 } 286 287 @Override erasure(TypeMirror t)288 public TypeMirror erasure(TypeMirror t) { 289 validateRealType(t); 290 TypeMirrorImpl typeMirrorImpl = (TypeMirrorImpl) t; 291 Binding binding = typeMirrorImpl._binding; 292 if (binding instanceof ReferenceBinding) { 293 TypeBinding type = ((ReferenceBinding) binding).erasure(); 294 if (type.isGenericType()) { 295 type = _env.getLookupEnvironment().convertToRawType(type, false); 296 } 297 return _env.getFactory().newTypeMirror(type); 298 } 299 if (binding instanceof ArrayBinding) { 300 TypeBinding typeBinding = (TypeBinding) binding; 301 TypeBinding leafType = typeBinding.leafComponentType().erasure(); 302 if (leafType.isGenericType()) { 303 leafType = _env.getLookupEnvironment().convertToRawType(leafType, false); 304 } 305 return _env.getFactory().newTypeMirror( 306 this._env.getLookupEnvironment().createArrayType(leafType, 307 typeBinding.dimensions())); 308 } 309 return t; 310 } 311 312 @Override getArrayType(TypeMirror componentType)313 public ArrayType getArrayType(TypeMirror componentType) { 314 TypeMirrorImpl typeMirrorImpl = (TypeMirrorImpl) componentType; 315 TypeBinding typeBinding = (TypeBinding) typeMirrorImpl._binding; 316 return (ArrayType) _env.getFactory().newTypeMirror( 317 this._env.getLookupEnvironment().createArrayType( 318 typeBinding.leafComponentType(), 319 typeBinding.dimensions() + 1)); 320 } 321 322 /* 323 * (non-Javadoc) 324 * Create a type instance by parameterizing a type element. If the element is a member type, 325 * its container won't be parameterized (if it needs to be, you would need to use the form of 326 * getDeclaredType that takes a container TypeMirror). If typeArgs is empty, and typeElem 327 * is not generic, then you should use TypeElem.asType(). If typeArgs is empty and typeElem 328 * is generic, this method will create the raw type. 329 */ 330 @Override getDeclaredType(TypeElement typeElem, TypeMirror... typeArgs)331 public DeclaredType getDeclaredType(TypeElement typeElem, TypeMirror... typeArgs) { 332 int typeArgsLength = typeArgs.length; 333 TypeElementImpl typeElementImpl = (TypeElementImpl) typeElem; 334 ReferenceBinding elementBinding = (ReferenceBinding) typeElementImpl._binding; 335 TypeVariableBinding[] typeVariables = elementBinding.typeVariables(); 336 int typeVariablesLength = typeVariables.length; 337 if (typeArgsLength == 0) { 338 if (elementBinding.isGenericType()) { 339 // per javadoc, 340 return (DeclaredType) _env.getFactory().newTypeMirror(this._env.getLookupEnvironment().createRawType(elementBinding, null)); 341 } 342 return (DeclaredType)typeElem.asType(); 343 } else if (typeArgsLength != typeVariablesLength) { 344 throw new IllegalArgumentException("Number of typeArguments doesn't match the number of formal parameters of typeElem"); //$NON-NLS-1$ 345 } 346 TypeBinding[] typeArguments = new TypeBinding[typeArgsLength]; 347 for (int i = 0; i < typeArgsLength; i++) { 348 TypeMirrorImpl typeMirrorImpl = (TypeMirrorImpl) typeArgs[i]; 349 Binding binding = typeMirrorImpl._binding; 350 if (!(binding instanceof TypeBinding)) { 351 throw new IllegalArgumentException("Invalid type argument: " + typeMirrorImpl); //$NON-NLS-1$ 352 } 353 typeArguments[i] = (TypeBinding) binding; 354 } 355 356 ReferenceBinding enclosing = elementBinding.enclosingType(); 357 if (enclosing != null) { 358 enclosing = this._env.getLookupEnvironment().createRawType(enclosing, null); 359 } 360 361 return (DeclaredType) _env.getFactory().newTypeMirror( 362 this._env.getLookupEnvironment().createParameterizedType(elementBinding, typeArguments, enclosing)); 363 } 364 365 /* (non-Javadoc) 366 * Create a specific type from a member element. The containing type can be parameterized, 367 * e.g. Outer<String>.Inner, but it cannot be generic, i.e., Outer<T>.Inner. It only makes 368 * sense to use this method when the member element is parameterized by its container; so, 369 * for example, it makes sense for an inner class but not for a static member class. 370 * Otherwise you should just use getDeclaredType(TypeElement, TypeMirror ...), if you need 371 * to specify type arguments, or TypeElement.asType() directly, if not. 372 */ 373 @Override getDeclaredType(DeclaredType containing, TypeElement typeElem, TypeMirror... typeArgs)374 public DeclaredType getDeclaredType(DeclaredType containing, TypeElement typeElem, 375 TypeMirror... typeArgs) { 376 int typeArgsLength = typeArgs.length; 377 TypeElementImpl typeElementImpl = (TypeElementImpl) typeElem; 378 ReferenceBinding elementBinding = (ReferenceBinding) typeElementImpl._binding; 379 TypeVariableBinding[] typeVariables = elementBinding.typeVariables(); 380 int typeVariablesLength = typeVariables.length; 381 DeclaredTypeImpl declaredTypeImpl = (DeclaredTypeImpl) containing; 382 ReferenceBinding enclosingType = (ReferenceBinding) declaredTypeImpl._binding; 383 if (typeArgsLength == 0) { 384 if (elementBinding.isGenericType()) { 385 // e.g., Outer.Inner<T> but T is not specified 386 // Per javadoc on interface, must return the raw type Outer.Inner 387 return (DeclaredType) _env.getFactory().newTypeMirror( 388 _env.getLookupEnvironment().createRawType(elementBinding, enclosingType)); 389 } else { 390 // e.g., Outer<Long>.Inner 391 ParameterizedTypeBinding ptb = _env.getLookupEnvironment().createParameterizedType(elementBinding, null, enclosingType); 392 return (DeclaredType) _env.getFactory().newTypeMirror(ptb); 393 } 394 } else if (typeArgsLength != typeVariablesLength) { 395 throw new IllegalArgumentException("Number of typeArguments doesn't match the number of formal parameters of typeElem"); //$NON-NLS-1$ 396 } 397 TypeBinding[] typeArguments = new TypeBinding[typeArgsLength]; 398 for (int i = 0; i < typeArgsLength; i++) { 399 TypeMirrorImpl typeMirrorImpl = (TypeMirrorImpl) typeArgs[i]; 400 Binding binding = typeMirrorImpl._binding; 401 if (!(binding instanceof TypeBinding)) { 402 throw new IllegalArgumentException("Invalid type for a type arguments : " + typeMirrorImpl); //$NON-NLS-1$ 403 } 404 typeArguments[i] = (TypeBinding) binding; 405 } 406 return (DeclaredType) _env.getFactory().newTypeMirror( 407 this._env.getLookupEnvironment().createParameterizedType(elementBinding, typeArguments, enclosingType)); 408 } 409 410 @Override getNoType(TypeKind kind)411 public NoType getNoType(TypeKind kind) { 412 return _env.getFactory().getNoType(kind); 413 } 414 415 @Override getNullType()416 public NullType getNullType() { 417 return _env.getFactory().getNullType(); 418 } 419 420 @Override getPrimitiveType(TypeKind kind)421 public PrimitiveType getPrimitiveType(TypeKind kind) { 422 return _env.getFactory().getPrimitiveType(kind); 423 } 424 425 @Override getWildcardType(TypeMirror extendsBound, TypeMirror superBound)426 public WildcardType getWildcardType(TypeMirror extendsBound, TypeMirror superBound) { 427 if (extendsBound != null && superBound != null) { 428 throw new IllegalArgumentException("Extends and super bounds cannot be set at the same time"); //$NON-NLS-1$ 429 } 430 if (extendsBound != null) { 431 TypeMirrorImpl extendsBoundMirrorType = (TypeMirrorImpl) extendsBound; 432 TypeBinding typeBinding = (TypeBinding) extendsBoundMirrorType._binding; 433 return (WildcardType) _env.getFactory().newTypeMirror( 434 this._env.getLookupEnvironment().createWildcard( 435 null, 436 0, 437 typeBinding, 438 null, 439 Wildcard.EXTENDS)); 440 } 441 if (superBound != null) { 442 TypeMirrorImpl superBoundMirrorType = (TypeMirrorImpl) superBound; 443 TypeBinding typeBinding = (TypeBinding) superBoundMirrorType._binding; 444 return new WildcardTypeImpl(_env, this._env.getLookupEnvironment().createWildcard( 445 null, 446 0, 447 typeBinding, 448 null, 449 Wildcard.SUPER)); 450 } 451 return new WildcardTypeImpl(_env, this._env.getLookupEnvironment().createWildcard( 452 null, 453 0, 454 null, 455 null, 456 Wildcard.UNBOUND)); 457 } 458 459 /* (non-Javadoc) 460 * @return true if a value of type t1 can be assigned to a variable of type t2, i.e., t2 = t1. 461 */ 462 @Override isAssignable(TypeMirror t1, TypeMirror t2)463 public boolean isAssignable(TypeMirror t1, TypeMirror t2) { 464 validateRealTypes(t1, t2); 465 if (!(t1 instanceof TypeMirrorImpl) || !(t2 instanceof TypeMirrorImpl)) { 466 return false; 467 } 468 Binding b1 = ((TypeMirrorImpl)t1).binding(); 469 Binding b2 = ((TypeMirrorImpl)t2).binding(); 470 if (!(b1 instanceof TypeBinding) || !(b2 instanceof TypeBinding)) { 471 // package, method, import, etc. 472 throw new IllegalArgumentException(); 473 } 474 if (((TypeBinding)b1).isCompatibleWith((TypeBinding)b2)) { 475 return true; 476 } 477 478 TypeBinding convertedType = _env.getLookupEnvironment().computeBoxingType((TypeBinding)b1); 479 return null != convertedType && convertedType.isCompatibleWith((TypeBinding)b2); 480 } 481 482 @Override isSameType(TypeMirror t1, TypeMirror t2)483 public boolean isSameType(TypeMirror t1, TypeMirror t2) { 484 if (t1 instanceof NoTypeImpl) { 485 if (t2 instanceof NoTypeImpl) { 486 return ((NoTypeImpl) t1).getKind() == ((NoTypeImpl) t2).getKind(); 487 } 488 return false; 489 } else if (t2 instanceof NoTypeImpl) { 490 return false; 491 } 492 if (t1.getKind() == TypeKind.WILDCARD || t2.getKind() == TypeKind.WILDCARD) { 493 // Wildcard types are never equal, according to the spec of this method 494 return false; 495 } 496 if (t1 == t2) { 497 return true; 498 } 499 if (!(t1 instanceof TypeMirrorImpl) || !(t2 instanceof TypeMirrorImpl)) { 500 return false; 501 } 502 Binding b1 = ((TypeMirrorImpl)t1).binding(); 503 Binding b2 = ((TypeMirrorImpl)t2).binding(); 504 505 if (b1 == b2) { 506 return true; 507 } 508 if (!(b1 instanceof TypeBinding) || !(b2 instanceof TypeBinding)) { 509 return false; 510 } 511 TypeBinding type1 = ((TypeBinding) b1); 512 TypeBinding type2 = ((TypeBinding) b2); 513 if (TypeBinding.equalsEquals(type1, type2)) 514 return true; 515 return CharOperation.equals(type1.computeUniqueKey(), type2.computeUniqueKey()); 516 } 517 518 @Override isSubsignature(ExecutableType m1, ExecutableType m2)519 public boolean isSubsignature(ExecutableType m1, ExecutableType m2) { 520 MethodBinding methodBinding1 = (MethodBinding) ((ExecutableTypeImpl) m1)._binding; 521 MethodBinding methodBinding2 = (MethodBinding) ((ExecutableTypeImpl) m2)._binding; 522 if (!CharOperation.equals(methodBinding1.selector, methodBinding2.selector)) 523 return false; 524 return methodBinding1.areParameterErasuresEqual(methodBinding2) && methodBinding1.areTypeVariableErasuresEqual(methodBinding2); 525 } 526 527 /* (non-Javadoc) 528 * @return true if t1 is a subtype of t2, or if t1 == t2. 529 */ 530 @Override isSubtype(TypeMirror t1, TypeMirror t2)531 public boolean isSubtype(TypeMirror t1, TypeMirror t2) { 532 validateRealTypes(t1, t2); 533 if (t1 instanceof NoTypeImpl) { 534 if (t2 instanceof NoTypeImpl) { 535 return ((NoTypeImpl) t1).getKind() == ((NoTypeImpl) t2).getKind(); 536 } 537 return false; 538 } else if (t2 instanceof NoTypeImpl) { 539 return false; 540 } 541 if (!(t1 instanceof TypeMirrorImpl) || !(t2 instanceof TypeMirrorImpl)) { 542 throw new IllegalArgumentException(); 543 } 544 if (t1 == t2) { 545 return true; 546 } 547 Binding b1 = ((TypeMirrorImpl)t1).binding(); 548 Binding b2 = ((TypeMirrorImpl)t2).binding(); 549 if (b1 == b2) { 550 return true; 551 } 552 if (!(b1 instanceof TypeBinding) || !(b2 instanceof TypeBinding)) { 553 // package, method, import, etc. 554 throw new IllegalArgumentException(); 555 } 556 if (b1.kind() == Binding.BASE_TYPE || b2.kind() == Binding.BASE_TYPE) { 557 if (b1.kind() != b2.kind()) { 558 return false; 559 } 560 else { 561 // for primitives, compatibility implies subtype 562 return ((TypeBinding)b1).isCompatibleWith((TypeBinding)b2); 563 } 564 } 565 return ((TypeBinding)b1).isCompatibleWith((TypeBinding)b2); 566 } 567 568 @Override unboxedType(TypeMirror t)569 public PrimitiveType unboxedType(TypeMirror t) { 570 if (!(((TypeMirrorImpl)t)._binding instanceof ReferenceBinding)) { 571 // Not an unboxable type - could be primitive, array, not a type at all, etc. 572 throw new IllegalArgumentException("Given type mirror cannot be unboxed"); //$NON-NLS-1$ 573 } 574 ReferenceBinding boxed = (ReferenceBinding)((TypeMirrorImpl)t)._binding; 575 TypeBinding unboxed = _env.getLookupEnvironment().computeBoxingType(boxed); 576 if (unboxed.kind() != Binding.BASE_TYPE) { 577 // No boxing conversion was found 578 throw new IllegalArgumentException(); 579 } 580 return (PrimitiveType) _env.getFactory().newTypeMirror((BaseTypeBinding)unboxed); 581 } 582 583 } 584