/* *******************************************************************
 * Copyright (c) 2005-2012 Contributors.
 * 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://eclipse.org/legal/epl-v10.html
 * ******************************************************************/
package org.aspectj.weaver;

import java.util.Map;

ReferenceType pointing to a type variable. The delegate for this reference type is the upperbound on the type variable (so Object if not otherwise specified).
Author:Adrian Colyer, Andy Clement
/** * ReferenceType pointing to a type variable. The delegate for this reference type is the upperbound on the type variable (so * Object if not otherwise specified). * * @author Adrian Colyer * @author Andy Clement */
public class TypeVariableReferenceType extends ReferenceType implements TypeVariableReference { private TypeVariable typeVariable; public TypeVariableReferenceType(TypeVariable typeVariable, World world) { super(typeVariable.getGenericSignature(), typeVariable.getErasureSignature(), world); this.typeVariable = typeVariable; } @Override public boolean equals(Object other) { if (other instanceof TypeVariableReferenceType) { return typeVariable==((TypeVariableReferenceType)other).typeVariable; } return false; } @Override public int hashCode() { return typeVariable.hashCode(); }
For a TypeVariableReferenceType the delegate is the delegate for the first bound.
/** * For a TypeVariableReferenceType the delegate is the delegate for the first bound. */
@Override public ReferenceTypeDelegate getDelegate() { if (this.delegate == null) { ResolvedType resolvedFirstBound = typeVariable.getFirstBound().resolve(world); BoundedReferenceTypeDelegate brtd = null; if (resolvedFirstBound.isMissing()) { brtd = new BoundedReferenceTypeDelegate((ReferenceType) world.resolve(UnresolvedType.OBJECT)); setDelegate(brtd); // set now because getSourceLocation() below will cause a recursive step to discover the delegate world.getLint().cantFindType.signal( "Unable to find type for generic bound. Missing type is " + resolvedFirstBound.getName(), getSourceLocation()); } else { brtd = new BoundedReferenceTypeDelegate((ReferenceType) resolvedFirstBound); setDelegate(brtd); } } return this.delegate; } @Override public UnresolvedType parameterize(Map<String, UnresolvedType> typeBindings) { UnresolvedType ut = typeBindings.get(getName()); if (ut != null) { return world.resolve(ut); } return this; } public TypeVariable getTypeVariable() { return typeVariable; } @Override public boolean isTypeVariableReference() { return true; } @Override public String toString() { return typeVariable.getName(); } @Override public boolean isGenericWildcard() { return false; } @Override public boolean isAnnotation() { ReferenceType upper = (ReferenceType) typeVariable.getUpperBound(); if (upper.isAnnotation()) { return true; } World world = upper.getWorld(); typeVariable.resolve(world); ResolvedType annotationType = ResolvedType.ANNOTATION.resolve(world); UnresolvedType[] ifBounds = typeVariable.getSuperInterfaces();// AdditionalBounds(); for (int i = 0; i < ifBounds.length; i++) { if (((ReferenceType) ifBounds[i]).isAnnotation()) { return true; } if (ifBounds[i].equals(annotationType)) { return true; // annotation itself does not have the annotation flag set in Java! } } return false; }
return the signature for a *REFERENCE* to a type variable, which is simply: Tname; there is no bounds info included, that is in the signature of the type variable itself
/** * return the signature for a *REFERENCE* to a type variable, which is simply: Tname; there is no bounds info included, that is * in the signature of the type variable itself */
@Override public String getSignature() { StringBuffer sb = new StringBuffer(); sb.append("T"); sb.append(typeVariable.getName()); sb.append(";"); return sb.toString(); }
Returns:the name of the type variable
/** * @return the name of the type variable */
public String getTypeVariableName() { return typeVariable.getName(); } public ReferenceType getUpperBound() { return (ReferenceType) typeVariable.resolve(world).getUpperBound(); }
resolve the type variable we are managing and then return this object. 'this' is already a ResolvedType but the type variable may transition from a not-resolved to a resolved state.
/** * resolve the type variable we are managing and then return this object. 'this' is already a ResolvedType but the type variable * may transition from a not-resolved to a resolved state. */
public ResolvedType resolve(World world) { typeVariable.resolve(world); return this; }
Returns:true if the type variable this reference is managing is resolved
/** * @return true if the type variable this reference is managing is resolved */
public boolean isTypeVariableResolved() { return typeVariable.isResolved; } }