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

org.aspectj.weaver.patterns.ThisOrTargetPointcut Maven / Gradle / Ivy

Go to download

The AspectJ matcher can be used for matching pointcuts independently of any AspectJ compilation or weaving steps. Most notably, this can be used by frameworks such as Spring AOP which utilise the @AspectJ pointcut syntax but implement aspect weaving in a way independent of AspectJ, e.g. using dynamic proxies.

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.patterns;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;

import org.aspectj.bridge.IMessage;
import org.aspectj.bridge.MessageUtil;
import org.aspectj.util.FuzzyBoolean;
import org.aspectj.weaver.CompressingDataOutputStream;
import org.aspectj.weaver.ISourceContext;
import org.aspectj.weaver.IntMap;
import org.aspectj.weaver.ResolvedType;
import org.aspectj.weaver.Shadow;
import org.aspectj.weaver.UnresolvedType;
import org.aspectj.weaver.VersionedDataInputStream;
import org.aspectj.weaver.WeaverMessages;
import org.aspectj.weaver.World;
import org.aspectj.weaver.ast.Literal;
import org.aspectj.weaver.ast.Test;
import org.aspectj.weaver.ast.Var;

/**
 * Corresponds to target or this pcd.
 *
 * 

* type is initially a WildTypePattern. If it stays that way, it's a this(Foo) type deal. however, the resolveBindings method may * convert it to a BindingTypePattern, in which case, it's a this(foo) type deal. * * @author Erik Hilsdale * @author Jim Hugunin */ public class ThisOrTargetPointcut extends NameBindingPointcut { private boolean isThis; private TypePattern typePattern; private String declarationText; private static final int thisKindSet; private static final int targetKindSet; static { int thisFlags = Shadow.ALL_SHADOW_KINDS_BITS; int targFlags = Shadow.ALL_SHADOW_KINDS_BITS; for (int i = 0; i < Shadow.SHADOW_KINDS.length; i++) { Shadow.Kind kind = Shadow.SHADOW_KINDS[i]; if (kind.neverHasThis()) { thisFlags -= kind.bit; } if (kind.neverHasTarget()) { targFlags -= kind.bit; } } thisKindSet = thisFlags; targetKindSet = targFlags; } public boolean isBinding() { return (typePattern instanceof BindingTypePattern); } public ThisOrTargetPointcut(boolean isThis, TypePattern type) { this.isThis = isThis; this.typePattern = type; this.pointcutKind = THIS_OR_TARGET; this.declarationText = (isThis ? "this(" : "target(") + type + ")"; } public TypePattern getType() { return typePattern; } public boolean isThis() { return isThis; } @Override public Pointcut parameterizeWith(Map typeVariableMap, World w) { ThisOrTargetPointcut ret = new ThisOrTargetPointcut(isThis, typePattern.parameterizeWith(typeVariableMap, w)); ret.copyLocationFrom(this); return ret; } @Override public int couldMatchKinds() { return isThis ? thisKindSet : targetKindSet; } @Override public FuzzyBoolean fastMatch(FastMatchInfo type) { return FuzzyBoolean.MAYBE; } private boolean couldMatch(Shadow shadow) { return isThis ? shadow.hasThis() : shadow.hasTarget(); } @Override protected FuzzyBoolean matchInternal(Shadow shadow) { if (!couldMatch(shadow)) { return FuzzyBoolean.NO; } UnresolvedType typeToMatch = isThis ? shadow.getThisType() : shadow.getTargetType(); // optimization for case of this(Object) or target(Object) // works for an ExactTypePattern (and we know there are no annotations to match here of course) if (typePattern.getExactType().equals(ResolvedType.OBJECT)) { return FuzzyBoolean.YES; } return typePattern.matches(typeToMatch.resolve(shadow.getIWorld()), TypePattern.DYNAMIC); } @Override public void write(CompressingDataOutputStream s) throws IOException { s.writeByte(Pointcut.THIS_OR_TARGET); s.writeBoolean(isThis); typePattern.write(s); writeLocation(s); } public static Pointcut read(VersionedDataInputStream s, ISourceContext context) throws IOException { boolean isThis = s.readBoolean(); TypePattern type = TypePattern.read(s, context); ThisOrTargetPointcut ret = new ThisOrTargetPointcut(isThis, type); ret.readLocation(context, s); return ret; } @Override public void resolveBindings(IScope scope, Bindings bindings) { typePattern = typePattern.resolveBindings(scope, bindings, true, true); // look for parameterized type patterns which are not supported... HasThisTypePatternTriedToSneakInSomeGenericOrParameterizedTypePatternMatchingStuffAnywhereVisitor visitor = new HasThisTypePatternTriedToSneakInSomeGenericOrParameterizedTypePatternMatchingStuffAnywhereVisitor(); typePattern.traverse(visitor, null); if (visitor.wellHasItThen/* ? */()) { scope.message(MessageUtil.error(WeaverMessages.format(WeaverMessages.THIS_AND_TARGET_DONT_SUPPORT_PARAMETERS), getSourceLocation())); } // ??? handle non-formal } @Override public void postRead(ResolvedType enclosingType) { typePattern.postRead(enclosingType); } @Override public List getBindingAnnotationTypePatterns() { return Collections.emptyList(); } @Override public List getBindingTypePatterns() { if (typePattern instanceof BindingTypePattern) { List l = new ArrayList<>(); l.add((BindingTypePattern)typePattern); return l; } else { return Collections.emptyList(); } } @Override public boolean equals(Object other) { if (!(other instanceof ThisOrTargetPointcut)) { return false; } ThisOrTargetPointcut o = (ThisOrTargetPointcut) other; return o.isThis == this.isThis && o.typePattern.equals(this.typePattern); } @Override public int hashCode() { int result = 17; result = 37 * result + (isThis ? 0 : 1); result = 37 * result + typePattern.hashCode(); return result; } @Override public String toString() { return declarationText; } /** * Residue is the remainder of the pointcut match that couldn't be performed with the purely static information at compile time * and this method returns the residue of a pointcut at a particular shadow. */ @Override protected Test findResidueInternal(Shadow shadow, ExposedState state) { if (!couldMatch(shadow)) { return Literal.FALSE; } // if no preference is specified, just say TRUE which means no residue if (typePattern == TypePattern.ANY) { return Literal.TRUE; } Var var = isThis ? shadow.getThisVar() : shadow.getTargetVar(); return exposeStateForVar(var, typePattern, state, shadow.getIWorld()); } @Override public Pointcut concretize1(ResolvedType inAspect, ResolvedType declaringType, IntMap bindings) { if (isDeclare(bindings.getEnclosingAdvice())) { // Enforce rule about which designators are supported in declare inAspect.getWorld().showMessage(IMessage.ERROR, WeaverMessages.format(WeaverMessages.THIS_OR_TARGET_IN_DECLARE, isThis ? "this" : "target"), bindings.getEnclosingAdvice().getSourceLocation(), null); return Pointcut.makeMatchesNothing(Pointcut.CONCRETE); } TypePattern newType = typePattern.remapAdviceFormals(bindings); if (inAspect.crosscuttingMembers != null) { inAspect.crosscuttingMembers.exposeType(newType.getExactType()); } Pointcut ret = new ThisOrTargetPointcut(isThis, newType); ret.copyLocationFrom(this); return ret; } @Override public Object accept(PatternNodeVisitor visitor, Object data) { return visitor.visit(this, data); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy