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

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

Go to download

The AspectJ weaver applies aspects to Java classes. It can be used as a Java agent in order to apply load-time weaving (LTW) during class-loading and also contains the AspectJ runtime classes.

There is a newer version: 1.9.22.1
Show newest version
/* *******************************************************************
 * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC).
 * 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
 *
 * Contributors:
 *     PARC     initial implementation
 * ******************************************************************/

package org.aspectj.weaver;

import java.util.Map;

import org.aspectj.bridge.ISourceLocation;
import org.aspectj.util.PartialOrder;

public abstract class ConcreteTypeMunger implements PartialOrder.PartialComparable {
	protected ResolvedTypeMunger munger;
	protected ResolvedType aspectType;

	public ConcreteTypeMunger(ResolvedTypeMunger munger, ResolvedType aspectType) {
		this.munger = munger;
		this.aspectType = aspectType;
	}

	/**
	 * Equivalence can be true for an EclipseTypeMunger and a BcelTypeMunger that represent the same transformation (just at
	 * different points in the pipeline).
	 */
	public boolean equivalentTo(Object other) {
		if (!(other instanceof ConcreteTypeMunger)) {
			return false;
		}
		ConcreteTypeMunger o = (ConcreteTypeMunger) other;
		ResolvedTypeMunger otherTypeMunger = o.getMunger();
		ResolvedTypeMunger thisTypeMunger = getMunger();
		if (thisTypeMunger instanceof NewConstructorTypeMunger && otherTypeMunger instanceof NewConstructorTypeMunger) {
			return (((NewConstructorTypeMunger) otherTypeMunger).equivalentTo(thisTypeMunger))
					&& ((o.getAspectType() == null) ? (getAspectType() == null) : o.getAspectType().equals(getAspectType()));
		} else {
			return ((otherTypeMunger == null) ? (thisTypeMunger == null) : otherTypeMunger.equals(thisTypeMunger))
					&& ((o.getAspectType() == null) ? (getAspectType() == null) : o.getAspectType().equals(getAspectType()));
		}
	}

	// public abstract boolean munge(LazyClassGen gen);

	/**
	 * returns null for mungers that are used internally, but were not part of a declared thing in source code.
	 */
	public ResolvedTypeMunger getMunger() {
		return munger;
	}

	public ResolvedType getAspectType() {
		return aspectType;
	}

	public ResolvedMember getSignature() {
		return munger.getSignature();
	}

	public World getWorld() {
		return aspectType.getWorld();
	}

	public ISourceLocation getSourceLocation() {
		if (munger == null) {
			return null;
		}
		return munger.getSourceLocation(); // XXX
	}

	public boolean matches(ResolvedType onType) {
		if (munger == null) {
			throw new RuntimeException("huh: " + this);
		}
		return munger.matches(onType, aspectType);
	}

	public ResolvedMember getMatchingSyntheticMember(Member member) {
		return munger.getMatchingSyntheticMember(member, aspectType);
	}

	public int compareTo(Object other) {
		ConcreteTypeMunger o = (ConcreteTypeMunger) other;

		ResolvedType otherAspect = o.aspectType;

		if (aspectType.equals(otherAspect)) {
			return getSignature().getStart() < o.getSignature().getStart() ? -1 : +1;
		} else if (aspectType.isAssignableFrom(o.aspectType)) {
			return +1;
		} else if (o.aspectType.isAssignableFrom(aspectType)) {
			return -1;
		} else {
			return 0;
		}
	}

	public int fallbackCompareTo(Object other) {
		// ConcreteTypeMunger o = (ConcreteTypeMunger) other;
		return 0;
	}

	/**
	 * returns true if the ITD target type used type variables, for example I<T>. When they are specified like this, the ITDs
	 * 'share' type variables with the generic type. Usually this method is called because we need to know whether to tailor the
	 * munger for addition to a particular type. For example: 

	 *   interface I<T> {}
	 *
	 *   aspect X implements I<String> {
	 *     List<T> I<T>.foo { return null; }
	 *   }
	 * 
In this case the munger matches X but it matches with the form * List<String> foo() { return null; } * */ public boolean isTargetTypeParameterized() { if (munger == null) { return false; } return munger.sharesTypeVariablesWithGenericType(); } /** * For an ITD made on a generic type that shares type variables with that target type, this method will tailor the ITD for a * particular usage of the generic type - either in its raw or parameterized form. */ public abstract ConcreteTypeMunger parameterizedFor(ResolvedType targetType); public boolean isLateMunger() { if (munger == null) { return false; } return munger.isLateMunger(); } public abstract ConcreteTypeMunger parameterizeWith(Map parameterizationMap, World world); /** * Some type mungers are created purely to help with the implementation of shadow mungers. For example to support the cflow() * pointcut we create a new cflow field in the aspect, and that is added via a BcelCflowCounterFieldAdder. * * During compilation we need to compare sets of type mungers, and if some only come into existence after the 'shadowy' type * things have been processed, we need to ignore them during the comparison. * * Returning true from this method indicates the type munger exists to support 'shadowy' stuff - and so can be ignored in some * comparison. */ public boolean existsToSupportShadowMunging() { if (munger != null) { return munger.existsToSupportShadowMunging(); } return false; } public boolean shouldOverwrite() { return true; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy