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

org.aspectj.weaver.patterns.PerTypeWithin 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 IBM
 * 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:
 *     Andy Clement     initial implementation
 * ******************************************************************/

package org.aspectj.weaver.patterns;

import java.io.IOException;
import java.util.Map;

import org.aspectj.bridge.IMessage;
import org.aspectj.bridge.ISourceLocation;
import org.aspectj.bridge.Message;
import org.aspectj.util.FuzzyBoolean;
import org.aspectj.weaver.Advice;
import org.aspectj.weaver.AjcMemberMaker;
import org.aspectj.weaver.CompressingDataOutputStream;
import org.aspectj.weaver.ISourceContext;
import org.aspectj.weaver.Member;
import org.aspectj.weaver.PerTypeWithinTargetTypeMunger;
import org.aspectj.weaver.ResolvedType;
import org.aspectj.weaver.ResolvedTypeMunger;
import org.aspectj.weaver.Shadow;
import org.aspectj.weaver.UnresolvedType;
import org.aspectj.weaver.VersionedDataInputStream;
import org.aspectj.weaver.World;
import org.aspectj.weaver.ast.Expr;
import org.aspectj.weaver.ast.Literal;
import org.aspectj.weaver.ast.Test;

// PTWIMPL Represents a parsed pertypewithin()
public class PerTypeWithin extends PerClause {

	private TypePattern typePattern;

	// Any shadow could be considered within a pertypewithin() type pattern
	private static final int kindSet = Shadow.ALL_SHADOW_KINDS_BITS;

	public TypePattern getTypePattern() {
		return typePattern;
	}

	public PerTypeWithin(TypePattern p) {
		typePattern = p;
	}

	@Override
	public Object accept(PatternNodeVisitor visitor, Object data) {
		return visitor.visit(this, data);
	}

	@Override
	public int couldMatchKinds() {
		return kindSet;
	}

	@Override
	public Pointcut parameterizeWith(Map typeVariableMap, World w) {
		PerTypeWithin ret = new PerTypeWithin(typePattern.parameterizeWith(typeVariableMap, w));
		ret.copyLocationFrom(this);
		return ret;
	}

	// -----
	@Override
	public FuzzyBoolean fastMatch(FastMatchInfo info) {
		if (typePattern.annotationPattern instanceof AnyAnnotationTypePattern) {
			return isWithinType(info.getType());
		}
		return FuzzyBoolean.MAYBE;
	}

	@Override
	protected FuzzyBoolean matchInternal(Shadow shadow) {
		ResolvedType enclosingType = shadow.getIWorld().resolve(shadow.getEnclosingType(), true);
		if (enclosingType.isMissing()) {
			// PTWIMPL ?? Add a proper message
			IMessage msg = new Message("Cant find type pertypewithin matching...", shadow.getSourceLocation(), true,
					new ISourceLocation[] { getSourceLocation() });
			shadow.getIWorld().getMessageHandler().handleMessage(msg);
		}

		// See pr106554 - we can't put advice calls in an interface when the
		// advice is defined
		// in a pertypewithin aspect - the JPs only exist in the static
		// initializer and can't
		// call the localAspectOf() method.
		if (enclosingType.isInterface()) {
			return FuzzyBoolean.NO;
		}
		if (!(enclosingType.canBeSeenBy(inAspect) || inAspect.isPrivilegedAspect())) {
			return FuzzyBoolean.NO;
		}

		typePattern.resolve(shadow.getIWorld());
		return isWithinType(enclosingType);
	}

	@Override
	public void resolveBindings(IScope scope, Bindings bindings) {
		typePattern = typePattern.resolveBindings(scope, bindings, false, false);
	}

	@Override
	protected Test findResidueInternal(Shadow shadow, ExposedState state) {
		// Member ptwField =
		// AjcMemberMaker.perTypeWithinField(shadow.getEnclosingType
		// (),inAspect);

		Expr myInstance = Expr.makeCallExpr(AjcMemberMaker.perTypeWithinLocalAspectOf(shadow.getEnclosingType(), inAspect/*
																														 * shadow.
																														 * getEnclosingType
																														 * ( )
																														 */),
				Expr.NONE, inAspect);
		state.setAspectInstance(myInstance);

		// this worked at one point
		// Expr myInstance =
		// Expr.makeFieldGet(ptwField,shadow.getEnclosingType()
		// .resolve(shadow.getIWorld()));//inAspect);
		// state.setAspectInstance(myInstance);

		// return Test.makeFieldGetCall(ptwField,null,Expr.NONE);
		// cflowField, cflowCounterIsValidMethod, Expr.NONE

		// This is what is in the perObject variant of this ...
		// Expr myInstance =
		// Expr.makeCallExpr(AjcMemberMaker.perTypeWithinAspectOfMethod(inAspect)
		// ,
		// new Expr[] {getVar(shadow)}, inAspect);
		// state.setAspectInstance(myInstance);
		// return
		// Test.makeCall(AjcMemberMaker.perTypeWithinHasAspectMethod(inAspect),
		// new Expr[] { getVar(shadow) });
		//

		return match(shadow).alwaysTrue() ? Literal.TRUE : Literal.FALSE;
	}

	@Override
	public PerClause concretize(ResolvedType inAspect) {
		PerTypeWithin ret = new PerTypeWithin(typePattern);
		ret.copyLocationFrom(this);
		ret.inAspect = inAspect;
		if (inAspect.isAbstract()) {
			return ret;
		}

		World world = inAspect.getWorld();

		SignaturePattern sigpat = new SignaturePattern(Member.STATIC_INITIALIZATION, ModifiersPattern.ANY, TypePattern.ANY,
				TypePattern.ANY,// typePattern,
				NamePattern.ANY, TypePatternList.ANY, ThrowsPattern.ANY, AnnotationTypePattern.ANY);

		Pointcut staticInitStar = new KindedPointcut(Shadow.StaticInitialization, sigpat);
		Pointcut withinTp = new WithinPointcut(typePattern);
		Pointcut andPcut = new AndPointcut(staticInitStar, withinTp);
		// We want the pointcut to be:
		// 'staticinitialization(*) && within()' -
		// we *cannot* shortcut this to staticinitialization()
		// because it doesnt mean the same thing.

		// This munger will initialize the aspect instance field in the matched type

		inAspect.crosscuttingMembers.addConcreteShadowMunger(Advice.makePerTypeWithinEntry(world, andPcut, inAspect));

		ResolvedTypeMunger munger = new PerTypeWithinTargetTypeMunger(inAspect, ret);
		inAspect.crosscuttingMembers.addTypeMunger(world.getWeavingSupport().concreteTypeMunger(munger, inAspect));

		// ATAJ: add a munger to add the aspectOf(..) to the @AJ aspects
		if (inAspect.isAnnotationStyleAspect() && !inAspect.isAbstract()) {
			inAspect.crosscuttingMembers.addLateTypeMunger(world.getWeavingSupport().makePerClauseAspect(inAspect, getKind()));
		}

		// ATAJ inline around advice support - don't use a late munger to allow
		// around inling for itself
		if (inAspect.isAnnotationStyleAspect() && !world.isXnoInline()) {
			inAspect.crosscuttingMembers.addTypeMunger(world.getWeavingSupport().createAccessForInlineMunger(inAspect));
		}

		return ret;

	}

	@Override
	public void write(CompressingDataOutputStream s) throws IOException {
		PERTYPEWITHIN.write(s);
		typePattern.write(s);
		writeLocation(s);
	}

	public static PerClause readPerClause(VersionedDataInputStream s, ISourceContext context) throws IOException {
		PerClause ret = new PerTypeWithin(TypePattern.read(s, context));
		ret.readLocation(context, s);
		return ret;
	}

	@Override
	public PerClause.Kind getKind() {
		return PERTYPEWITHIN;
	}

	@Override
	public String toString() {
		return "pertypewithin(" + typePattern + ")";
	}

	@Override
	public String toDeclarationString() {
		return toString();
	}

	private FuzzyBoolean isWithinType(ResolvedType type) {
		while (type != null) {
			if (typePattern.matchesStatically(type)) {
				return FuzzyBoolean.YES;
			}
			type = type.getDeclaringType();
		}
		return FuzzyBoolean.NO;
	}

	@Override
	public boolean equals(Object other) {
		if (!(other instanceof PerTypeWithin)) {
			return false;
		}
		PerTypeWithin pc = (PerTypeWithin) other;
		return ((pc.inAspect == null) ? (inAspect == null) : pc.inAspect.equals(inAspect))
				&& ((pc.typePattern == null) ? (typePattern == null) : pc.typePattern.equals(typePattern));
	}

	@Override
	public int hashCode() {
		int result = 17;
		result = 37 * result + ((inAspect == null) ? 0 : inAspect.hashCode());
		result = 37 * result + ((typePattern == null) ? 0 : typePattern.hashCode());
		return result;
	}

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy