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

org.aspectj.weaver.patterns.TypePattern 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) 2002, 2010 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
 *     Nieraj Singh
 * ******************************************************************/

package org.aspectj.weaver.patterns;

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

import org.aspectj.bridge.MessageUtil;
import org.aspectj.util.FuzzyBoolean;
import org.aspectj.weaver.BCException;
import org.aspectj.weaver.ISourceContext;
import org.aspectj.weaver.IntMap;
import org.aspectj.weaver.ResolvedType;
import org.aspectj.weaver.TypeVariableReference;
import org.aspectj.weaver.UnresolvedType;
import org.aspectj.weaver.VersionedDataInputStream;
import org.aspectj.weaver.WeaverMessages;
import org.aspectj.weaver.World;

/**
 * On creation, type pattern only contains WildTypePattern nodes, not BindingType or ExactType.
 *
 * 

* Then we call resolveBindings() during compilation During concretization of enclosing pointcuts, we call remapAdviceFormals * * @author Erik Hilsdale * @author Jim Hugunin */ public abstract class TypePattern extends PatternNode { public static class MatchKind { private String name; public MatchKind(String name) { this.name = name; } @Override public String toString() { return name; } } public static final MatchKind STATIC = new MatchKind("STATIC"); public static final MatchKind DYNAMIC = new MatchKind("DYNAMIC"); public static final TypePattern ELLIPSIS = new EllipsisTypePattern(); public static final TypePattern ANY = new AnyTypePattern(); public static final TypePattern NO = new NoTypePattern(); protected boolean includeSubtypes; protected boolean isVarArgs = false; protected AnnotationTypePattern annotationPattern = AnnotationTypePattern.ANY; protected TypePatternList typeParameters = TypePatternList.EMPTY; protected TypePattern(boolean includeSubtypes, boolean isVarArgs, TypePatternList typeParams) { this.includeSubtypes = includeSubtypes; this.isVarArgs = isVarArgs; this.typeParameters = (typeParams == null ? TypePatternList.EMPTY : typeParams); } protected TypePattern(boolean includeSubtypes, boolean isVarArgs) { this(includeSubtypes, isVarArgs, null); } public AnnotationTypePattern getAnnotationPattern() { return annotationPattern; } public boolean isVarArgs() { return isVarArgs; } public boolean isStarAnnotation() { return annotationPattern == AnnotationTypePattern.ANY; } public boolean isArray() { return false; } public int getDimensions() { return 0; } protected TypePattern(boolean includeSubtypes) { this(includeSubtypes, false); } public void setAnnotationTypePattern(AnnotationTypePattern annPatt) { this.annotationPattern = annPatt; } public void setTypeParameters(TypePatternList typeParams) { this.typeParameters = typeParams; } public TypePatternList getTypeParameters() { return this.typeParameters; } public void setIsVarArgs(boolean isVarArgs) { this.isVarArgs = isVarArgs; } // answer conservatively... protected boolean couldEverMatchSameTypesAs(TypePattern other) { if (this.includeSubtypes || other.includeSubtypes) { return true; } if (this.annotationPattern != AnnotationTypePattern.ANY) { return true; } if (other.annotationPattern != AnnotationTypePattern.ANY) { return true; } return false; } // XXX non-final for Not, && and || public boolean matchesStatically(ResolvedType type) { if (includeSubtypes) { return matchesSubtypes(type); } else { return matchesExactly(type); } } public abstract FuzzyBoolean matchesInstanceof(ResolvedType type); public final FuzzyBoolean matches(ResolvedType type, MatchKind kind) { // FuzzyBoolean typeMatch = null; // ??? This is part of gracefully handling missing references if (type.isMissing()) { return FuzzyBoolean.NO; } if (kind == STATIC) { return FuzzyBoolean.fromBoolean(matchesStatically(type)); } else if (kind == DYNAMIC) { // System.err.println("matching: " + this + " with " + type); // typeMatch = matchesInstanceof(type); // System.err.println(" got: " + ret); // return typeMatch.and(annotationPattern.matches(type)); return matchesInstanceof(type); } else { throw new IllegalArgumentException("kind must be DYNAMIC or STATIC"); } } protected abstract boolean matchesExactly(ResolvedType type); protected abstract boolean matchesExactly(ResolvedType type, ResolvedType annotatedType); protected abstract boolean matchesArray(UnresolvedType type); protected boolean matchesSubtypes(ResolvedType type) { // System.out.println("matching: " + this + " to " + type); if (matchesExactly(type)) { return true; } // pr124808 Iterator typesIterator = null; if (type.isTypeVariableReference()) { typesIterator = ((TypeVariableReference) type).getTypeVariable().getFirstBound().resolve(type.getWorld()) .getDirectSupertypes(); } else { // pr223605 if (type.isRawType()) { type = type.getGenericType(); } typesIterator = type.getDirectSupertypes(); } for (Iterator i = typesIterator; i.hasNext();) { ResolvedType superType = i.next(); if (matchesSubtypes(superType, type)) { return true; } } return false; } protected boolean matchesSubtypes(ResolvedType superType, ResolvedType annotatedType) { // System.out.println("matching2: " + this + " to " + superType); if (matchesExactly(superType, annotatedType)) { // System.out.println(" true"); return true; } // If an ITD is applied, it will be put onto the generic type, not the parameterized or raw form if (superType.isParameterizedType() || superType.isRawType()) { superType = superType.getGenericType(); } // FuzzyBoolean ret = FuzzyBoolean.NO; // ??? -eh for (Iterator i = superType.getDirectSupertypes(); i.hasNext();) { ResolvedType superSuperType = i.next(); if (matchesSubtypes(superSuperType, annotatedType)) { return true; } } return false; } public UnresolvedType resolveExactType(IScope scope, Bindings bindings) { TypePattern p = resolveBindings(scope, bindings, false, true); if (!(p instanceof ExactTypePattern)) { return ResolvedType.MISSING; } return ((ExactTypePattern) p).getType(); } public UnresolvedType getExactType() { if (this instanceof ExactTypePattern) { return ((ExactTypePattern) this).getType(); } else { return ResolvedType.MISSING; } } protected TypePattern notExactType(IScope s) { s.getMessageHandler().handleMessage( MessageUtil.error(WeaverMessages.format(WeaverMessages.EXACT_TYPE_PATTERN_REQD), getSourceLocation())); return NO; } // public boolean assertExactType(IMessageHandler m) { // if (this instanceof ExactTypePattern) return true; // // //XXX should try harder to avoid multiple errors for one problem // m.handleMessage(MessageUtil.error("exact type pattern required", getSourceLocation())); // return false; // } /** * This can modify in place, or return a new TypePattern if the type changes. */ public TypePattern resolveBindings(IScope scope, Bindings bindings, boolean allowBinding, boolean requireExactType) { annotationPattern = annotationPattern.resolveBindings(scope, bindings, allowBinding); return this; } public void resolve(World world) { annotationPattern.resolve(world); } /** * return a version of this type pattern in which all type variable references have been replaced by their corresponding entry * in the map. */ public abstract TypePattern parameterizeWith(Map typeVariableMap, World w); public void postRead(ResolvedType enclosingType) { } public boolean isEllipsis() { return false; } public boolean isStar() { return false; } /** * This is called during concretization of pointcuts, it is used by BindingTypePattern to return a new BindingTypePattern with a * formal index appropriate for the advice, rather than for the lexical declaration, i.e. this handles transformations through * named pointcuts. * *

	 * pointcut foo(String name): args(name);
	 * --> This makes a BindingTypePattern(0) pointing to the 0th formal
	 *
	 * before(Foo f, String n): this(f) && foo(n) { ... }
	 * --> when resolveReferences is called on the args from the above, it
	 *     will return a BindingTypePattern(1)
	 *
	 * before(Foo f): this(f) && foo(*) { ... }
	 * --> when resolveReferences is called on the args from the above, it
	 *     will return an ExactTypePattern(String)
	 * 
*/ public TypePattern remapAdviceFormals(IntMap bindings) { return this; } public static final byte WILD = 1; public static final byte EXACT = 2; public static final byte BINDING = 3; public static final byte ELLIPSIS_KEY = 4; public static final byte ANY_KEY = 5; public static final byte NOT = 6; public static final byte OR = 7; public static final byte AND = 8; public static final byte NO_KEY = 9; public static final byte ANY_WITH_ANNO = 10; public static final byte HAS_MEMBER = 11; public static final byte TYPE_CATEGORY = 12; public static TypePattern read(VersionedDataInputStream s, ISourceContext context) throws IOException { byte key = s.readByte(); switch (key) { case WILD: return WildTypePattern.read(s, context); case EXACT: return ExactTypePattern.read(s, context); case BINDING: return BindingTypePattern.read(s, context); case ELLIPSIS_KEY: return ELLIPSIS; case ANY_KEY: return ANY; case NO_KEY: return NO; case NOT: return NotTypePattern.read(s, context); case OR: return OrTypePattern.read(s, context); case AND: return AndTypePattern.read(s, context); case ANY_WITH_ANNO: return AnyWithAnnotationTypePattern.read(s, context); case HAS_MEMBER: return HasMemberTypePattern.read(s, context); case TYPE_CATEGORY: return TypeCategoryTypePattern.read(s, context); } throw new BCException("unknown TypePattern kind: " + key); } public boolean isIncludeSubtypes() { return includeSubtypes; } /** * For quickly recognizing the pattern '!void' */ public boolean isBangVoid() { return false; } /** * for quickly recognizing the pattern 'void' */ public boolean isVoid() { return false; } public boolean hasFailedResolution() { return false; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy