All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.aspectj.weaver.TypeVariableReferenceType Maven / Gradle / Ivy

Go to download

AspectJ tools most notably contains the AspectJ compiler (AJC). AJC applies aspects to Java classes during compilation, fully replacing Javac for plain Java classes and also compiling native AspectJ or annotation-based @AspectJ syntax. Furthermore, AJC can weave aspects into existing class files in a post-compile binary weaving step. This library is a superset of AspectJ weaver and hence also of AspectJ runtime.

There is a newer version: 1.9.22.1
Show newest version
/* *******************************************************************
 * 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 v 2.0
 * which accompanies this distribution and is available at
 * https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.txt
 * ******************************************************************/
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
 * @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.
	 */
	@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 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 (UnresolvedType ifBound : ifBounds) {
			if (((ReferenceType) ifBound).isAnnotation()) {
				return true;
			}
			if (ifBound.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
	 */
	@Override
	public String getSignature() {
		StringBuilder sb = new StringBuilder();
		sb.append("T");
		sb.append(typeVariable.getName());
		sb.append(";");
		return sb.toString();
	}

	/**
	 * @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.
	 */
	public ResolvedType resolve(World world) {
		typeVariable.resolve(world);
		return this;
	}

	/**
	 * @return true if the type variable this reference is managing is resolved
	 */
	public boolean isTypeVariableResolved() {
		return typeVariable.isResolved;
	}

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy