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

org.aspectj.weaver.reflect.JavaLangTypeToResolvedTypeConverter 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 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.reflect;

import java.lang.reflect.GenericArrayType;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.lang.reflect.WildcardType;
import java.util.HashMap;
import java.util.Map;

import org.aspectj.weaver.BoundedReferenceType;
import org.aspectj.weaver.ReferenceType;
import org.aspectj.weaver.ResolvedType;
import org.aspectj.weaver.TypeFactory;
import org.aspectj.weaver.TypeVariable;
import org.aspectj.weaver.TypeVariableReferenceType;
import org.aspectj.weaver.UnresolvedType;
import org.aspectj.weaver.World;

/**
 * Handles the translation of java.lang.reflect.Type objects into AspectJ UnresolvedTypes.
 *
 * @author Adrian Colyer
 */
public class JavaLangTypeToResolvedTypeConverter {

	// Used to prevent recursion - we record what we are working on and return it if asked again *whilst* working on it
	private Map typeVariablesInProgress = new HashMap<>();
	private final World world;

	public JavaLangTypeToResolvedTypeConverter(World aWorld) {
		this.world = aWorld;
	}

	private World getWorld() {
		return this.world;
	}

	public ResolvedType fromType(Type type) {
		if (type instanceof Class) {
			Class clazz = (Class) type;
			String name = clazz.getName();
			/**
			 * getName() can return:
			 *
			 * 1. If this class object represents a reference type that is not an
			 * array type then the binary name of the class is returned
			 * 2. If this class object represents a primitive type or void, then
			 * the name returned is a String equal to the Java language keyword
			 * corresponding to the primitive type or void.
			 * 3. If this class object represents a class of arrays, then the internal
			 * form of the name consists of the name of the element type preceded by
			 * one or more '[' characters representing the depth of the array nesting.
			 */
			if (clazz.isArray()) {
				UnresolvedType ut = UnresolvedType.forSignature(name.replace('.', '/'));
				return getWorld().resolve(ut);
			} else {
				return getWorld().resolve(name);
			}
		} else if (type instanceof ParameterizedType) {
			// https://bugs.eclipse.org/bugs/show_bug.cgi?id=509327
			// TODO should deal with the ownerType if it set, indicating this is possibly an inner type of a parameterized type
			Type ownerType = ((ParameterizedType) type).getOwnerType();
			ParameterizedType parameterizedType = (ParameterizedType) type;
			ResolvedType baseType = fromType(parameterizedType.getRawType());
			Type[] typeArguments = parameterizedType.getActualTypeArguments();
			if (baseType.isSimpleType() && typeArguments.length == 0 && ownerType != null) {
				// 'type' is an inner type of some outer parameterized type
				// For now just return the base type - in future create the parameterized form of the outer
				// and use it with the inner. We return the base type to be compatible with what the
				// code does that accesses the info from the bytecode (unlike this code which accesses it
				// reflectively).
				return baseType;
			}
			ResolvedType[] resolvedTypeArguments = fromTypes(typeArguments);
			return TypeFactory.createParameterizedType(baseType, resolvedTypeArguments, getWorld());
		} else if (type instanceof java.lang.reflect.TypeVariable) {
			TypeVariableReferenceType inprogressVar = typeVariablesInProgress.get(type);
			if (inprogressVar != null) {
				return inprogressVar;
			}
			java.lang.reflect.TypeVariable tv = (java.lang.reflect.TypeVariable) type;
			TypeVariable rt_tv = new TypeVariable(tv.getName());
			TypeVariableReferenceType tvrt = new TypeVariableReferenceType(rt_tv, getWorld());
			typeVariablesInProgress.put(type, tvrt); // record what we are working on, for recursion case
			Type[] bounds = tv.getBounds();
			ResolvedType[] resBounds = fromTypes(bounds);
			ResolvedType upperBound = resBounds[0];
			ResolvedType[] additionalBounds = ResolvedType.EMPTY_RESOLVED_TYPE_ARRAY;
			if (resBounds.length > 1) {
				additionalBounds = new ResolvedType[resBounds.length - 1];
				System.arraycopy(resBounds, 1, additionalBounds, 0, additionalBounds.length);
			}
			rt_tv.setUpperBound(upperBound);
			rt_tv.setAdditionalInterfaceBounds(additionalBounds);
			typeVariablesInProgress.remove(type); // we have finished working on it
			return tvrt;
		} else if (type instanceof WildcardType) {
			WildcardType wildType = (WildcardType) type;
			Type[] lowerBounds = wildType.getLowerBounds();
			Type[] upperBounds = wildType.getUpperBounds();
			ResolvedType bound = null;
			boolean isExtends = lowerBounds.length == 0;
			if (isExtends) {
				bound = fromType(upperBounds[0]);
			} else {
				bound = fromType(lowerBounds[0]);
			}
			return new BoundedReferenceType((ReferenceType) bound, isExtends, getWorld());
		} else if (type instanceof GenericArrayType) {
			GenericArrayType genericArrayType = (GenericArrayType) type;
			Type componentType = genericArrayType.getGenericComponentType();
			return UnresolvedType.makeArray(fromType(componentType), 1).resolve(getWorld());
		}
		return ResolvedType.MISSING;
	}

	public ResolvedType[] fromTypes(Type[] types) {
		ResolvedType[] ret = new ResolvedType[types.length];
		for (int i = 0; i < ret.length; i++) {
			ret[i] = fromType(types[i]);
		}
		return ret;
	}

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy