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

org.aspectj.org.eclipse.jdt.internal.compiler.apt.model.TypeParameterElementImpl 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) 2007, 2023 BEA Systems, Inc.
 *
 * This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *    [email protected] - initial API and implementation
 *    IBM Corporation - fix for 342470
 *    IBM Corporation - fix for 342598
 *    IBM Corporation - Java 8 support
 *******************************************************************************/

package org.aspectj.org.eclipse.jdt.internal.compiler.apt.model;

import java.lang.annotation.Annotation;
import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import javax.lang.model.element.AnnotationMirror;
import javax.lang.model.element.Element;
import javax.lang.model.element.ElementKind;
import javax.lang.model.element.ElementVisitor;
import javax.lang.model.element.PackageElement;
import javax.lang.model.element.TypeParameterElement;
import javax.lang.model.type.TypeMirror;

import org.aspectj.org.eclipse.jdt.internal.compiler.apt.dispatch.BaseProcessingEnvImpl;
import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.AnnotationBinding;
import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.TypeConstants;
import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.TypeVariableBinding;

public class TypeParameterElementImpl extends ElementImpl implements TypeParameterElement
{
	private final Element _declaringElement;

	// Cache the bounds, because they're expensive to compute
	private List _bounds = null;

	/* package */ TypeParameterElementImpl(BaseProcessingEnvImpl env, TypeVariableBinding binding, Element declaringElement) {
		super(env, binding);
		this._declaringElement = declaringElement;
	}

	/* package */ TypeParameterElementImpl(BaseProcessingEnvImpl env, TypeVariableBinding binding) {
		super(env, binding);
		this._declaringElement = this._env.getFactory().newElement(binding.declaringElement);
	}

	@Override
	public List getBounds()
	{
		if (null == this._bounds) {
			this._bounds = calculateBounds();
		}
		return this._bounds;
	}

	// This code is drawn from org.eclipse.jdt.core.dom.TypeBinding.getTypeBounds()
	private List calculateBounds() {
		TypeVariableBinding typeVariableBinding = (TypeVariableBinding)this._binding;
		ReferenceBinding varSuperclass = typeVariableBinding.superclass();
		TypeBinding firstClassOrArrayBound = typeVariableBinding.firstBound;
		int boundsLength = 0;
		boolean isFirstBoundATypeVariable = false;
		if (firstClassOrArrayBound != null) {
			if (firstClassOrArrayBound.isTypeVariable()) {
				isFirstBoundATypeVariable = true;
			}
			if (TypeBinding.equalsEquals(firstClassOrArrayBound, varSuperclass)) {
				boundsLength++;
				if (firstClassOrArrayBound.isTypeVariable()) {
					isFirstBoundATypeVariable = true;
				}
			} else if (firstClassOrArrayBound.isArrayType()) { // capture of ? extends/super arrayType
				boundsLength++;
			} else {
				firstClassOrArrayBound = null;
			}
		}
		ReferenceBinding[] superinterfaces = typeVariableBinding.superInterfaces();
		int superinterfacesLength = 0;
		if (superinterfaces != null) {
			superinterfacesLength = superinterfaces.length;
			boundsLength += superinterfacesLength;
		}
		List typeBounds = new ArrayList<>(boundsLength);
		if (boundsLength != 0) {
			if (firstClassOrArrayBound != null) {
				TypeMirror typeBinding = this._env.getFactory().newTypeMirror(firstClassOrArrayBound);
				if (typeBinding == null) {
					return Collections.emptyList();
				}
				typeBounds.add(typeBinding);
			}
			// we need to filter out remaining bounds if the first bound is a type variable
			if (superinterfaces != null && !isFirstBoundATypeVariable) {
				for (int i = 0; i < superinterfacesLength; i++) {
					TypeMirror typeBinding = this._env.getFactory().newTypeMirror(superinterfaces[i]);
					if (typeBinding == null) {
						return Collections.emptyList();
					}
					typeBounds.add(typeBinding);
				}
			}
		} else {
			// at least we must add java.lang.Object
			typeBounds.add(this._env.getFactory().newTypeMirror(this._env.getLookupEnvironment().getType(TypeConstants.JAVA_LANG_OBJECT)));
		}
		return Collections.unmodifiableList(typeBounds);
	}

	@Override
	public Element getGenericElement()
	{
		return this._declaringElement;
	}

	@Override
	public  R accept(ElementVisitor v, P p)
	{
		return v.visitTypeParameter(this, p);
	}

	/*
	 * (non-Javadoc)
	 * Java supports annotations on type parameters from JLS8
	 * @see javax.lang.model.element.Element#getAnnotationMirrors()
	 */
	@Override
	protected AnnotationBinding[] getAnnotationBindings()
	{
		return ((TypeVariableBinding)this._binding).getTypeAnnotations();
	}

	private boolean shouldEmulateJavacBug() {
		if (this._env.getLookupEnvironment().globalOptions.emulateJavacBug8031744) {
			AnnotationBinding [] annotations = getAnnotationBindings();
			for (int i = 0, length = annotations.length; i < length; i++) {
				ReferenceBinding firstAnnotationType = annotations[i].getAnnotationType();
				for (int j = i+1; j < length; j++) {
					ReferenceBinding secondAnnotationType = annotations[j].getAnnotationType();
					if (firstAnnotationType == secondAnnotationType) //$IDENTITY-COMPARISON$
						return true;
				}
			}
		}
		return false;
	}

	@Override
	public List getAnnotationMirrors() {
		if (shouldEmulateJavacBug())
			return Collections.emptyList();
		return super.getAnnotationMirrors();
	}

	@Override
	@SuppressWarnings("unchecked") // for the cast to A
	public  A[] getAnnotationsByType(Class annotationType) {
		if (shouldEmulateJavacBug())
			return (A[]) Array.newInstance(annotationType, 0);
		return super.getAnnotationsByType(annotationType);
	}

	@Override
	public  A getAnnotation(Class annotationType) {
		if (shouldEmulateJavacBug())
			return null;
		return super.getAnnotation(annotationType);
	}

	/*
	 * (non-Javadoc)
	 * Always return an empty list; type parameters do not enclose other elements.
	 * @see javax.lang.model.element.Element#getEnclosedElements()
	 */
	@Override
	public List getEnclosedElements()
	{
		return Collections.emptyList();
	}

	/*
	 * (non-Javadoc)
	 * Always return null.
	 * @see javax.lang.model.element.Element#getEnclosingElement()
	 */
	@Override
	public Element getEnclosingElement()
	{
		return getGenericElement();
	}

	@Override
	public ElementKind getKind()
	{
		return ElementKind.TYPE_PARAMETER;
	}

	@Override
	PackageElement getPackage()
	{
		// TODO what is the package of a type parameter?
		return null;
	}

	@Override
	public String toString() {
		return new String(this._binding.readableName());
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy