diff options
author | wharley | 2012-09-30 14:17:10 +0000 |
---|---|---|
committer | Jay Arthanareeswaran | 2015-04-10 07:28:37 +0000 |
commit | fdf4380d8dd2e7b1f08462c3e15a52a8d6142eb4 (patch) | |
tree | a3248a8feab560a4a7f906497962e1e6a6fa8275 /org.eclipse.jdt.compiler.apt | |
parent | e254cb1235fced696c16505589db91831c0df710 (diff) | |
download | eclipse.jdt.core-fdf4380d8dd2e7b1f08462c3e15a52a8d6142eb4.tar.gz eclipse.jdt.core-fdf4380d8dd2e7b1f08462c3e15a52a8d6142eb4.tar.xz eclipse.jdt.core-fdf4380d8dd2e7b1f08462c3e15a52a8d6142eb4.zip |
Bug 382590 - Types.asMemberOf() should find members within superclasses.
Also added a bunch of tests of asMemberOf() both for the regular and
superclass cases.
Change-Id: If316ace90470cd0041542b9562abf3575d377254
Diffstat (limited to 'org.eclipse.jdt.compiler.apt')
-rw-r--r-- | org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/model/TypesImpl.java | 303 |
1 files changed, 144 insertions, 159 deletions
diff --git a/org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/model/TypesImpl.java b/org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/model/TypesImpl.java index 6ac131e162..4005e8f84e 100644 --- a/org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/model/TypesImpl.java +++ b/org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/model/TypesImpl.java @@ -1,12 +1,12 @@ /******************************************************************************* - * Copyright (c) 2007, 2012 BEA Systems, Inc. and others + * Copyright (c) 2007 - 2012 BEA Systems, Inc. and others * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: - * wharley@bea.com - initial API and implementation + * Walter Harley - initial API and implementation * IBM Corporation - fix for 342598 *******************************************************************************/ @@ -37,6 +37,7 @@ import org.eclipse.jdt.internal.compiler.lookup.BaseTypeBinding; import org.eclipse.jdt.internal.compiler.lookup.Binding; import org.eclipse.jdt.internal.compiler.lookup.FieldBinding; import org.eclipse.jdt.internal.compiler.lookup.MethodBinding; +import org.eclipse.jdt.internal.compiler.lookup.ParameterizedTypeBinding; import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding; import org.eclipse.jdt.internal.compiler.lookup.TypeBinding; import org.eclipse.jdt.internal.compiler.lookup.TypeVariableBinding; @@ -63,18 +64,15 @@ public class TypesImpl implements Types { @Override public Element asElement(TypeMirror t) { switch(t.getKind()) { - case DECLARED : - case TYPEVAR : - return _env.getFactory().newElement(((TypeMirrorImpl)t).binding()); - default: - break; + case DECLARED : + case TYPEVAR : + return _env.getFactory().newElement(((TypeMirrorImpl)t).binding()); + default: + break; } return null; } - /* (non-Javadoc) - * @see javax.lang.model.util.Types#asMemberOf(javax.lang.model.type.DeclaredType, javax.lang.model.element.Element) - */ @Override public TypeMirror asMemberOf(DeclaredType containing, Element element) { // throw new UnsupportedOperationException("NYI: TypesImpl.asMemberOf(" + containing + ", " + element + ")"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ @@ -85,51 +83,54 @@ public class TypesImpl implements Types { case CONSTRUCTOR : case METHOD : MethodBinding methodBinding = (MethodBinding) elementImpl._binding; - if (TypeBinding.notEquals(methodBinding.declaringClass, referenceBinding)) { - throw new IllegalArgumentException("element is not valid for the containing declared type"); //$NON-NLS-1$ - } - for (MethodBinding method : referenceBinding.methods()) { - if (CharOperation.equals(method.selector, methodBinding.selector) - && method.areParameterErasuresEqual(methodBinding)) { - return this._env.getFactory().newTypeMirror(method); - } - } + while (referenceBinding != null) { + for (MethodBinding method : referenceBinding.methods()) { + if (CharOperation.equals(method.selector, methodBinding.selector) + && method.areParameterErasuresEqual(methodBinding)) { + return this._env.getFactory().newTypeMirror(method); + } + } + referenceBinding = referenceBinding.superclass(); + } break; case FIELD : case ENUM_CONSTANT: FieldBinding fieldBinding = (FieldBinding) elementImpl._binding; - if (TypeBinding.notEquals(fieldBinding.declaringClass, referenceBinding)) { - throw new IllegalArgumentException("element is not valid for the containing declared type"); //$NON-NLS-1$ - } - for (FieldBinding field : referenceBinding.fields()) { - if (CharOperation.equals(field.name, fieldBinding.name)) { - return this._env.getFactory().newTypeMirror(field); - } - } + while (referenceBinding != null) { + for (FieldBinding field : referenceBinding.fields()) { + if (CharOperation.equals(field.name, fieldBinding.name)) { + return this._env.getFactory().newTypeMirror(field); + } + } + referenceBinding = referenceBinding.superclass(); + } break; case ENUM : case ANNOTATION_TYPE : case INTERFACE : case CLASS : - ReferenceBinding referenceBinding2 = (ReferenceBinding) elementImpl._binding; - if (TypeBinding.notEquals(referenceBinding2.enclosingType(), referenceBinding)) { - throw new IllegalArgumentException("element is not valid for the containing declared type"); //$NON-NLS-1$ - } - for (ReferenceBinding referenceBinding3 : referenceBinding.memberTypes()) { - if (CharOperation.equals(referenceBinding3.compoundName, referenceBinding3.compoundName)) { - return this._env.getFactory().newTypeMirror(referenceBinding3); - } - } + ReferenceBinding elementBinding = (ReferenceBinding) elementImpl._binding; + while (referenceBinding != null) { + // If referenceBinding is a ParameterizedTypeBinding, this will return only ParameterizedTypeBindings + // for member types, even if the member happens to be a static nested class. That's probably a bug; + // static nested classes are not parameterized by their outer class. + for (ReferenceBinding memberReferenceBinding : referenceBinding.memberTypes()) { + if (CharOperation.equals(elementBinding.compoundName, memberReferenceBinding.compoundName)) { + return this._env.getFactory().newTypeMirror(memberReferenceBinding); + } + } + referenceBinding = referenceBinding.superclass(); + } break; default: - break; - } - throw new IllegalArgumentException("element is not valid for the containing declared type: element kind " + element.getKind()); //$NON-NLS-1$ + throw new IllegalArgumentException("element " + element + //$NON-NLS-1$ + " has unrecognized element kind " + element.getKind()); //$NON-NLS-1$ + } + throw new IllegalArgumentException("element " + element + //$NON-NLS-1$ + " is not a member of the containing type " + containing + //$NON-NLS-1$ + " nor any of its superclasses"); //$NON-NLS-1$ } - /* (non-Javadoc) - * @see javax.lang.model.util.Types#boxedClass(javax.lang.model.type.PrimitiveType) - */ @Override public TypeElement boxedClass(PrimitiveType p) { PrimitiveTypeImpl primitiveTypeImpl = (PrimitiveTypeImpl) p; @@ -138,112 +139,102 @@ public class TypesImpl implements Types { return (TypeElement) _env.getFactory().newElement(boxed); } - /* (non-Javadoc) - * @see javax.lang.model.util.Types#capture(javax.lang.model.type.TypeMirror) - */ @Override public TypeMirror capture(TypeMirror t) { throw new UnsupportedOperationException("NYI: TypesImpl.capture(...)"); //$NON-NLS-1$ } - /* (non-Javadoc) - * @see javax.lang.model.util.Types#contains(javax.lang.model.type.TypeMirror, javax.lang.model.type.TypeMirror) - */ @Override public boolean contains(TypeMirror t1, TypeMirror t2) { - switch(t1.getKind()) { - case EXECUTABLE : - case PACKAGE : - throw new IllegalArgumentException("Executable and package are illegal argument for Types.contains(..)"); //$NON-NLS-1$ - default: - break; - } - switch(t2.getKind()) { - case EXECUTABLE : - case PACKAGE : - throw new IllegalArgumentException("Executable and package are illegal argument for Types.contains(..)"); //$NON-NLS-1$ - default: - break; - } + switch(t1.getKind()) { + case EXECUTABLE : + case PACKAGE : + throw new IllegalArgumentException("Executable and package are illegal argument for Types.contains(..)"); //$NON-NLS-1$ + default: + break; + } + switch(t2.getKind()) { + case EXECUTABLE : + case PACKAGE : + throw new IllegalArgumentException("Executable and package are illegal argument for Types.contains(..)"); //$NON-NLS-1$ + default: + break; + } throw new UnsupportedOperationException("NYI: TypesImpl.contains(" + t1 + ", " + t2 + ")"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ } - /* (non-Javadoc) - * @see javax.lang.model.util.Types#directSupertypes(javax.lang.model.type.TypeMirror) - */ @Override public List<? extends TypeMirror> directSupertypes(TypeMirror t) { switch(t.getKind()) { - case PACKAGE : - case EXECUTABLE : - throw new IllegalArgumentException("Invalid type mirror for directSupertypes"); //$NON-NLS-1$ - default: - break; + case PACKAGE : + case EXECUTABLE : + throw new IllegalArgumentException("Invalid type mirror for directSupertypes"); //$NON-NLS-1$ + default: + break; } TypeMirrorImpl typeMirrorImpl = (TypeMirrorImpl) t; Binding binding = typeMirrorImpl._binding; if (binding instanceof ReferenceBinding) { - ReferenceBinding referenceBinding = (ReferenceBinding) binding; - ArrayList<TypeMirror> list = new ArrayList<TypeMirror>(); - ReferenceBinding superclass = referenceBinding.superclass(); - if (superclass != null) { - list.add(this._env.getFactory().newTypeMirror(superclass)); - } - for (ReferenceBinding interfaceBinding : referenceBinding.superInterfaces()) { - list.add(this._env.getFactory().newTypeMirror(interfaceBinding)); - } - return Collections.unmodifiableList(list); + ReferenceBinding referenceBinding = (ReferenceBinding) binding; + ArrayList<TypeMirror> list = new ArrayList<TypeMirror>(); + ReferenceBinding superclass = referenceBinding.superclass(); + if (superclass != null) { + list.add(this._env.getFactory().newTypeMirror(superclass)); + } + for (ReferenceBinding interfaceBinding : referenceBinding.superInterfaces()) { + list.add(this._env.getFactory().newTypeMirror(interfaceBinding)); + } + return Collections.unmodifiableList(list); } return Collections.emptyList(); } - /* (non-Javadoc) - * @see javax.lang.model.util.Types#erasure(javax.lang.model.type.TypeMirror) - */ @Override public TypeMirror erasure(TypeMirror t) { - TypeMirrorImpl typeMirrorImpl = (TypeMirrorImpl) t; - Binding binding = typeMirrorImpl._binding; - if (binding instanceof ReferenceBinding) { - return _env.getFactory().newTypeMirror(((ReferenceBinding) binding).erasure()); - } - if (binding instanceof ArrayBinding) { - TypeBinding typeBinding = (TypeBinding) binding; - return _env.getFactory().newTypeMirror( - this._env.getLookupEnvironment().createArrayType( - typeBinding.leafComponentType().erasure(), - typeBinding.dimensions())); - } - return t; + TypeMirrorImpl typeMirrorImpl = (TypeMirrorImpl) t; + Binding binding = typeMirrorImpl._binding; + if (binding instanceof ReferenceBinding) { + return _env.getFactory().newTypeMirror(((ReferenceBinding) binding).erasure()); + } + if (binding instanceof ArrayBinding) { + TypeBinding typeBinding = (TypeBinding) binding; + return _env.getFactory().newTypeMirror( + this._env.getLookupEnvironment().createArrayType( + typeBinding.leafComponentType().erasure(), + typeBinding.dimensions())); + } + return t; } - /* (non-Javadoc) - * @see javax.lang.model.util.Types#getArrayType(javax.lang.model.type.TypeMirror) - */ @Override public ArrayType getArrayType(TypeMirror componentType) { TypeMirrorImpl typeMirrorImpl = (TypeMirrorImpl) componentType; TypeBinding typeBinding = (TypeBinding) typeMirrorImpl._binding; return (ArrayType) _env.getFactory().newTypeMirror( - this._env.getLookupEnvironment().createArrayType( - typeBinding.leafComponentType(), - typeBinding.dimensions() + 1)); + this._env.getLookupEnvironment().createArrayType( + typeBinding.leafComponentType(), + typeBinding.dimensions() + 1)); } - /* (non-Javadoc) - * @see javax.lang.model.util.Types#getDeclaredType(javax.lang.model.element.TypeElement, javax.lang.model.type.TypeMirror[]) + /* + * (non-Javadoc) + * Create a type instance by parameterizing a type element. If the element is a member type, + * its container must not be generic (if it were, you would need to use the form of + * getDeclaredType that takes a container TypeMirror). If typeArgs is empty, and typeElem + * is not generic, then you should use TypeElem.asType(). If typeArgs is empty and typeElem + * is generic, this method will create the raw type. */ @Override public DeclaredType getDeclaredType(TypeElement typeElem, TypeMirror... typeArgs) { int typeArgsLength = typeArgs.length; TypeElementImpl typeElementImpl = (TypeElementImpl) typeElem; - ReferenceBinding referenceBinding = (ReferenceBinding) typeElementImpl._binding; - TypeVariableBinding[] typeVariables = referenceBinding.typeVariables(); + ReferenceBinding elementBinding = (ReferenceBinding) typeElementImpl._binding; + TypeVariableBinding[] typeVariables = elementBinding.typeVariables(); int typeVariablesLength = typeVariables.length; if (typeArgsLength == 0) { - if (referenceBinding.isGenericType()) { - // must return a raw type - return (DeclaredType) _env.getFactory().newTypeMirror(this._env.getLookupEnvironment().createRawType(referenceBinding, null)); + if (elementBinding.isGenericType()) { + // per javadoc, + return (DeclaredType) _env.getFactory().newTypeMirror(this._env.getLookupEnvironment().createRawType(elementBinding, null)); } return (DeclaredType)typeElem.asType(); } else if (typeArgsLength != typeVariablesLength) { @@ -259,29 +250,38 @@ public class TypesImpl implements Types { typeArguments[i] = (TypeBinding) binding; } return (DeclaredType) _env.getFactory().newTypeMirror( - this._env.getLookupEnvironment().createParameterizedType(referenceBinding, typeArguments, null)); + this._env.getLookupEnvironment().createParameterizedType(elementBinding, typeArguments, null)); } /* (non-Javadoc) - * @see javax.lang.model.util.Types#getDeclaredType(javax.lang.model.type.DeclaredType, javax.lang.model.element.TypeElement, javax.lang.model.type.TypeMirror[]) + * Create a specific type from a member element. The containing type can be parameterized, + * e.g. Outer<String>.Inner, but it cannot be generic, i.e., Outer<T>.Inner. It only makes + * sense to use this method when the member element is parameterized by its container; so, + * for example, it makes sense for an inner class but not for a static member class. + * Otherwise you should just use getDeclaredType(TypeElement, TypeMirror ...), if you need + * to specify type arguments, or TypeElement.asType() directly, if not. */ @Override public DeclaredType getDeclaredType(DeclaredType containing, TypeElement typeElem, TypeMirror... typeArgs) { int typeArgsLength = typeArgs.length; TypeElementImpl typeElementImpl = (TypeElementImpl) typeElem; - ReferenceBinding referenceBinding = (ReferenceBinding) typeElementImpl._binding; - TypeVariableBinding[] typeVariables = referenceBinding.typeVariables(); + ReferenceBinding elementBinding = (ReferenceBinding) typeElementImpl._binding; + TypeVariableBinding[] typeVariables = elementBinding.typeVariables(); int typeVariablesLength = typeVariables.length; DeclaredTypeImpl declaredTypeImpl = (DeclaredTypeImpl) containing; ReferenceBinding enclosingType = (ReferenceBinding) declaredTypeImpl._binding; if (typeArgsLength == 0) { - if (referenceBinding.isGenericType()) { - // must return a raw type - return (DeclaredType) _env.getFactory().newTypeMirror(this._env.getLookupEnvironment().createRawType(referenceBinding, enclosingType)); + if (elementBinding.isGenericType()) { + // e.g., Outer.Inner<T> but T is not specified + // Per javadoc on interface, must return the raw type Outer.Inner + return (DeclaredType) _env.getFactory().newTypeMirror( + _env.getLookupEnvironment().createRawType(elementBinding, enclosingType)); + } else { + // e.g., Outer<Long>.Inner + ParameterizedTypeBinding ptb = _env.getLookupEnvironment().createParameterizedType(elementBinding, null, enclosingType); + return (DeclaredType) _env.getFactory().newTypeMirror(ptb); } - // TODO (see how to create a member type binding - throw new UnsupportedOperationException("NYI: TypesImpl.getDeclaredType(...) for member types"); //$NON-NLS-1$ } else if (typeArgsLength != typeVariablesLength) { throw new IllegalArgumentException("Number of typeArguments doesn't match the number of formal parameters of typeElem"); //$NON-NLS-1$ } @@ -295,7 +295,7 @@ public class TypesImpl implements Types { typeArguments[i] = (TypeBinding) binding; } return (DeclaredType) _env.getFactory().newTypeMirror( - this._env.getLookupEnvironment().createParameterizedType(referenceBinding, typeArguments, enclosingType)); + this._env.getLookupEnvironment().createParameterizedType(elementBinding, typeArguments, enclosingType)); } @Override @@ -303,25 +303,16 @@ public class TypesImpl implements Types { return _env.getFactory().getNoType(kind); } - /* (non-Javadoc) - * @see javax.lang.model.util.Types#getNullType() - */ @Override public NullType getNullType() { return _env.getFactory().getNullType(); } - /* (non-Javadoc) - * @see javax.lang.model.util.Types#getPrimitiveType(javax.lang.model.type.TypeKind) - */ @Override public PrimitiveType getPrimitiveType(TypeKind kind) { return _env.getFactory().getPrimitiveType(kind); } - /* (non-Javadoc) - * @see javax.lang.model.util.Types#getWildcardType(javax.lang.model.type.TypeMirror, javax.lang.model.type.TypeMirror) - */ @Override public WildcardType getWildcardType(TypeMirror extendsBound, TypeMirror superBound) { if (extendsBound != null && superBound != null) { @@ -331,12 +322,12 @@ public class TypesImpl implements Types { TypeMirrorImpl extendsBoundMirrorType = (TypeMirrorImpl) extendsBound; TypeBinding typeBinding = (TypeBinding) extendsBoundMirrorType._binding; return (WildcardType) _env.getFactory().newTypeMirror( - this._env.getLookupEnvironment().createWildcard( - null, - 0, - typeBinding, - null, - Wildcard.EXTENDS)); + this._env.getLookupEnvironment().createWildcard( + null, + 0, + typeBinding, + null, + Wildcard.EXTENDS)); } if (superBound != null) { TypeMirrorImpl superBoundMirrorType = (TypeMirrorImpl) superBound; @@ -356,7 +347,7 @@ public class TypesImpl implements Types { Wildcard.UNBOUND)); } - /** + /* (non-Javadoc) * @return true if a value of type t1 can be assigned to a variable of type t2, i.e., t2 = t1. */ @Override @@ -378,15 +369,12 @@ public class TypesImpl implements Types { return null != convertedType && convertedType.isCompatibleWith((TypeBinding)b2); } - /* (non-Javadoc) - * @see javax.lang.model.util.Types#isSameType(javax.lang.model.type.TypeMirror, javax.lang.model.type.TypeMirror) - */ @Override public boolean isSameType(TypeMirror t1, TypeMirror t2) { - if (t1.getKind() == TypeKind.WILDCARD || t2.getKind() == TypeKind.WILDCARD) { + if (t1.getKind() == TypeKind.WILDCARD || t2.getKind() == TypeKind.WILDCARD) { // Wildcard types are never equal, according to the spec of this method - return false; - } + return false; + } if (t1 == t2) { return true; } @@ -409,31 +397,28 @@ public class TypesImpl implements Types { return CharOperation.equals(type1.computeUniqueKey(), type2.computeUniqueKey()); } - /* (non-Javadoc) - * @see javax.lang.model.util.Types#isSubsignature(javax.lang.model.type.ExecutableType, javax.lang.model.type.ExecutableType) - */ @Override public boolean isSubsignature(ExecutableType m1, ExecutableType m2) { - MethodBinding methodBinding1 = (MethodBinding) ((ExecutableTypeImpl) m1)._binding; - MethodBinding methodBinding2 = (MethodBinding) ((ExecutableTypeImpl) m2)._binding; - if (!CharOperation.equals(methodBinding1.selector, methodBinding2.selector)) - return false; - return methodBinding1.areParameterErasuresEqual(methodBinding2) && methodBinding1.areTypeVariableErasuresEqual(methodBinding2); - } + MethodBinding methodBinding1 = (MethodBinding) ((ExecutableTypeImpl) m1)._binding; + MethodBinding methodBinding2 = (MethodBinding) ((ExecutableTypeImpl) m2)._binding; + if (!CharOperation.equals(methodBinding1.selector, methodBinding2.selector)) + return false; + return methodBinding1.areParameterErasuresEqual(methodBinding2) && methodBinding1.areTypeVariableErasuresEqual(methodBinding2); + } - /** + /* (non-Javadoc) * @return true if t1 is a subtype of t2, or if t1 == t2. */ @Override public boolean isSubtype(TypeMirror t1, TypeMirror t2) { - if (t1 instanceof NoTypeImpl) { - if (t2 instanceof NoTypeImpl) { - return ((NoTypeImpl) t1).getKind() == ((NoTypeImpl) t2).getKind(); - } - return false; - } else if (t2 instanceof NoTypeImpl) { - return false; - } + if (t1 instanceof NoTypeImpl) { + if (t2 instanceof NoTypeImpl) { + return ((NoTypeImpl) t1).getKind() == ((NoTypeImpl) t2).getKind(); + } + return false; + } else if (t2 instanceof NoTypeImpl) { + return false; + } if (!(t1 instanceof TypeMirrorImpl) || !(t2 instanceof TypeMirrorImpl)) { return false; } |