123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198 |
- /* *******************************************************************
- * Copyright (c) 2008 Contributors
- * All rights reserved.
- * This program and the accompanying materials are made available
- * under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * 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.MessageUtil;
- import org.aspectj.util.FuzzyBoolean;
- import org.aspectj.weaver.AnnotatedElement;
- import org.aspectj.weaver.BCException;
- import org.aspectj.weaver.CompressingDataOutputStream;
- import org.aspectj.weaver.ISourceContext;
- import org.aspectj.weaver.IntMap;
- import org.aspectj.weaver.ReferenceType;
- import org.aspectj.weaver.ResolvedMember;
- import org.aspectj.weaver.ResolvedType;
- import org.aspectj.weaver.UnresolvedType;
- import org.aspectj.weaver.VersionedDataInputStream;
- import org.aspectj.weaver.WeaverMessages;
- import org.aspectj.weaver.World;
-
- /**
- * Represents an attempt to bind the field of an annotation within a pointcut. For example:
- * <pre><code>
- * before(Level lev): execution(* *(..)) && @annotation(TraceAnnotation(lev))
- * </code></pre>
- * <p>This binding annotation type pattern will be for 'lev'.</p>
- */
- public class BindingAnnotationFieldTypePattern extends ExactAnnotationTypePattern implements BindingPattern {
-
- protected int formalIndex;
- UnresolvedType formalType; // In this construct the formal type differs from the annotation type
-
- public BindingAnnotationFieldTypePattern(UnresolvedType formalType, int formalIndex, UnresolvedType theAnnotationType) {
- super(theAnnotationType, null);
- this.formalIndex = formalIndex;
- this.formalType = formalType;
- }
-
- public void resolveBinding(World world) {
- if (resolved) {
- return;
- }
- resolved = true;
- formalType = world.resolve(formalType);
- annotationType = world.resolve(annotationType);
- ResolvedType annoType = (ResolvedType) annotationType;
- if (!annoType.isAnnotation()) {
- IMessage m = MessageUtil
- .error(WeaverMessages.format(WeaverMessages.REFERENCE_TO_NON_ANNOTATION_TYPE, annoType.getName()),
- getSourceLocation());
- world.getMessageHandler().handleMessage(m);
- resolved = false;
- }
- }
-
- @Override
- public AnnotationTypePattern parameterizeWith(Map typeVariableMap, World w) {
- throw new BCException("Parameterization not implemented for annotation field binding construct (compiler limitation)");
- // UnresolvedType newAnnotationType = annotationType;
- // if (annotationType.isTypeVariableReference()) {
- // TypeVariableReference t = (TypeVariableReference) annotationType;
- // String key = t.getTypeVariable().getName();
- // if (typeVariableMap.containsKey(key)) {
- // newAnnotationType = (UnresolvedType) typeVariableMap.get(key);
- // }
- // } else if (annotationType.isParameterizedType()) {
- // newAnnotationType = annotationType.parameterize(typeVariableMap);
- // }
- // BindingAnnotationTypePattern ret = new BindingAnnotationTypePattern(newAnnotationType, this.formalIndex);
- // if (newAnnotationType instanceof ResolvedType) {
- // ResolvedType rat = (ResolvedType) newAnnotationType;
- // verifyRuntimeRetention(rat.getWorld(), rat);
- // }
- // ret.copyLocationFrom(this);
- // return ret;
- }
-
- @Override
- public int getFormalIndex() {
- return formalIndex;
- }
-
- @Override
- public boolean equals(Object obj) {
- if (!(obj instanceof BindingAnnotationFieldTypePattern)) {
- return false;
- }
- BindingAnnotationFieldTypePattern btp = (BindingAnnotationFieldTypePattern) obj;
- return (btp.formalIndex == formalIndex) && (annotationType.equals(btp.annotationType))
- && (formalType.equals(btp.formalType));
- }
-
- @Override
- public int hashCode() {
- return (annotationType.hashCode() * 37 + formalIndex * 37) + formalType.hashCode();
- }
-
- @Override
- public AnnotationTypePattern remapAdviceFormals(IntMap bindings) {
- if (!bindings.hasKey(formalIndex)) {
- throw new BCException("Annotation field binding reference must be bound (compiler limitation)");
- // must be something like returning the unbound form: return new ExactAnnotationTypePattern(annotationType,
- // null);
- } else {
- int newFormalIndex = bindings.get(formalIndex);
- BindingAnnotationFieldTypePattern baftp = new BindingAnnotationFieldTypePattern(formalType, newFormalIndex,
- annotationType);
- baftp.formalName = formalName;
- return baftp;
- }
- }
-
- @Override
- public void write(CompressingDataOutputStream s) throws IOException {
- s.writeByte(AnnotationTypePattern.BINDINGFIELD2);
- formalType.write(s); // the type of the field within the annotation
- s.writeShort((short) formalIndex);
- annotationType.write(s); // the annotation type
- s.writeUTF(formalName);
- writeLocation(s);
- }
-
- public static AnnotationTypePattern read(VersionedDataInputStream s, ISourceContext context) throws IOException {
- AnnotationTypePattern ret = new BindingAnnotationFieldTypePattern(UnresolvedType.read(s), s.readShort(),
- UnresolvedType.read(s));
- ret.readLocation(context, s);
- return ret;
- }
-
- public static AnnotationTypePattern read2(VersionedDataInputStream s, ISourceContext context) throws IOException {
- BindingAnnotationFieldTypePattern ret = new BindingAnnotationFieldTypePattern(UnresolvedType.read(s), s.readShort(),
- UnresolvedType.read(s));
- ret.formalName = s.readUTF();
- ret.readLocation(context, s);
- return ret;
- }
-
- @Override
- public FuzzyBoolean matches(AnnotatedElement annotated, ResolvedType[] parameterAnnotations) {
- // Inheritance irrelevant because @annotation(Anno(x)) only supported at method execution join points (compiler limitation)
- // boolean checkSupers = false;
- // if (getResolvedAnnotationType().hasAnnotation(UnresolvedType.AT_INHERITED)) {
- // if (annotated instanceof ResolvedType) {
- // checkSupers = true;
- // }
- // }
- //
- if (annotated.hasAnnotation(annotationType)) {
- if (annotationType instanceof ReferenceType) {
- ReferenceType rt = (ReferenceType) annotationType;
- if (rt.getRetentionPolicy() != null && rt.getRetentionPolicy().equals("SOURCE")) {
- rt.getWorld()
- .getMessageHandler()
- .handleMessage(
- MessageUtil.warn(WeaverMessages.format(WeaverMessages.NO_MATCH_BECAUSE_SOURCE_RETENTION,
- annotationType, annotated), getSourceLocation()));
- return FuzzyBoolean.NO;
- }
- ResolvedMember[] methods = rt.getDeclaredMethods();
- boolean found = false;
- for (int i = 0; i < methods.length && !found; i++) {
- if (methods[i].getReturnType().equals(formalType)) {
- found = true;
- }
- }
- return (found ? FuzzyBoolean.YES : FuzzyBoolean.NO);
- }
- }
- // else if (checkSupers) {
- // ResolvedType toMatchAgainst = ((ResolvedType) annotated).getSuperclass();
- // while (toMatchAgainst != null) {
- // if (toMatchAgainst.hasAnnotation(annotationType)) {
- // return FuzzyBoolean.YES;
- // }
- // toMatchAgainst = toMatchAgainst.getSuperclass();
- // }
- // }
- //
- return FuzzyBoolean.NO;
- }
-
- public UnresolvedType getFormalType() {
- return formalType;
- }
-
- }
|