@@ -14,25 +14,45 @@ | |||
package org.aspectj.ajdt.internal.compiler.lookup; | |||
import java.util.*; | |||
import org.aspectj.ajdt.internal.compiler.ast.*; | |||
import java.util.ArrayList; | |||
import java.util.Collection; | |||
import java.util.Collections; | |||
import java.util.List; | |||
import org.aspectj.ajdt.internal.compiler.ast.AdviceDeclaration; | |||
import org.aspectj.ajdt.internal.compiler.ast.AspectDeclaration; | |||
import org.aspectj.ajdt.internal.compiler.ast.DeclareAnnotationDeclaration; | |||
import org.aspectj.ajdt.internal.compiler.ast.DeclareDeclaration; | |||
import org.aspectj.ajdt.internal.compiler.ast.InterTypeDeclaration; | |||
import org.aspectj.ajdt.internal.compiler.ast.PointcutDeclaration; | |||
import org.aspectj.ajdt.internal.core.builder.EclipseSourceContext; | |||
import org.aspectj.bridge.IMessage; | |||
//import org.aspectj.bridge.ISourceLocation; | |||
import org.aspectj.weaver.*; | |||
import org.aspectj.weaver.patterns.PerClause; | |||
import org.aspectj.weaver.patterns.PerSingleton; | |||
import org.aspectj.weaver.patterns.PerFromSuper; | |||
import org.aspectj.org.eclipse.jdt.core.compiler.CharOperation; | |||
import org.aspectj.org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration; | |||
import org.aspectj.org.eclipse.jdt.internal.compiler.ast.Annotation; | |||
import org.aspectj.org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration; | |||
import org.aspectj.org.eclipse.jdt.internal.compiler.ast.TypeDeclaration; | |||
import org.aspectj.org.eclipse.jdt.internal.compiler.ast.SingleMemberAnnotation; | |||
import org.aspectj.org.eclipse.jdt.internal.compiler.ast.StringLiteral; | |||
import org.aspectj.org.eclipse.jdt.internal.compiler.ast.TypeDeclaration; | |||
import org.aspectj.org.eclipse.jdt.internal.compiler.ast.TypeParameter; | |||
import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.*; | |||
import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.BinaryTypeBinding; | |||
import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.CompilerModifiers; | |||
import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.FieldBinding; | |||
import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding; | |||
import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding; | |||
import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.TagBits; | |||
import org.aspectj.weaver.AbstractReferenceTypeDelegate; | |||
import org.aspectj.weaver.AnnotationX; | |||
import org.aspectj.weaver.ReferenceType; | |||
import org.aspectj.weaver.ResolvedMember; | |||
import org.aspectj.weaver.ResolvedPointcutDefinition; | |||
import org.aspectj.weaver.ResolvedType; | |||
import org.aspectj.weaver.TypeVariable; | |||
import org.aspectj.weaver.UnresolvedType; | |||
import org.aspectj.weaver.WeaverStateInfo; | |||
import org.aspectj.weaver.patterns.PerClause; | |||
import org.aspectj.weaver.patterns.PerFromSuper; | |||
import org.aspectj.weaver.patterns.PerSingleton; | |||
/** | |||
* Supports viewing eclipse TypeDeclarations/SourceTypeBindings as a ResolvedType | |||
@@ -301,6 +321,15 @@ public class EclipseSourceType extends AbstractReferenceTypeDelegate { | |||
} | |||
} | |||
public String getRetentionPolicy() { | |||
if (isAnnotation()) { | |||
if ((binding.getAnnotationTagBits() & TagBits.AnnotationRetentionMASK) == TagBits.AnnotationRuntimeRetention) return "RUNTIME"; | |||
if ((binding.getAnnotationTagBits() & TagBits.AnnotationRetentionMASK) == TagBits.AnnotationSourceRetention) return "SOURCE"; | |||
if ((binding.getAnnotationTagBits() & TagBits.AnnotationRetentionMASK) == TagBits.AnnotationClassRetention) return "CLASS"; | |||
} | |||
return null; | |||
} | |||
public boolean hasAnnotation(UnresolvedType ofType) { | |||
// Make sure they are resolved |
@@ -61,6 +61,9 @@ public class Ajc150Tests extends org.aspectj.testing.XMLBasedAjcTestCase { | |||
public void testVarargsITD_pr110906() { runTest("ITD varargs problem");} | |||
public void testIncompatibleClassChangeError_pr113630_1() {runTest("IncompatibleClassChangeError - errorscenario");} | |||
public void testIncompatibleClassChangeError_pr113630_2() {runTest("IncompatibleClassChangeError - workingscenario");} | |||
public void testBadGenericSigAttribute_pr110927() { | |||
runTest("cant create signature attribute"); | |||
Signature sig = GenericsTests.getClassSignature(ajc,"I"); |
@@ -219,10 +219,7 @@ public class GenericsTests extends XMLBasedAjcTestCase { | |||
public void testGenericsBang_pr95993() { | |||
runTest("NPE at ClassScope.java:660 when compiling generic class"); | |||
} | |||
// public void testIncompatibleClassChangeError_pr113630() { | |||
// runTest("IncompatibleClassChangeError"); | |||
// } | |||
// generic aspects | |||
public void testPR96220_GenericAspects1() {runTest("generic aspects - 1");} | |||
@@ -892,23 +889,16 @@ public class GenericsTests extends XMLBasedAjcTestCase { | |||
} | |||
public static Signature getClassSignature(Ajc ajc,String classname) { | |||
try { | |||
ClassPath cp = | |||
new ClassPath(ajc.getSandboxDirectory() + File.pathSeparator + System.getProperty("java.class.path")); | |||
SyntheticRepository sRepos = SyntheticRepository.getInstance(cp); | |||
JavaClass clazz = sRepos.loadClass(classname); | |||
Signature sigAttr = null; | |||
Attribute[] attrs = clazz.getAttributes(); | |||
for (int i = 0; i < attrs.length; i++) { | |||
Attribute attribute = attrs[i]; | |||
if (attribute.getName().equals("Signature")) sigAttr = (Signature)attribute; | |||
} | |||
return sigAttr; | |||
} catch (ClassNotFoundException e) { | |||
fail("Couldn't find class "+classname+" in the sandbox directory."); | |||
JavaClass clazz = getClass(ajc,classname); | |||
Signature sigAttr = null; | |||
Attribute[] attrs = clazz.getAttributes(); | |||
for (int i = 0; i < attrs.length; i++) { | |||
Attribute attribute = attrs[i]; | |||
if (attribute.getName().equals("Signature")) sigAttr = (Signature)attribute; | |||
} | |||
return null; | |||
return sigAttr; | |||
} | |||
// Check the signature attribute on a class is correct | |||
public static void verifyClassSignature(Ajc ajc,String classname,String sig) { | |||
Signature sigAttr = getClassSignature(ajc,classname); |
@@ -11,9 +11,16 @@ | |||
<compile files="pr112783.aj" options="-1.5"/> | |||
</ajc-test> | |||
<ajc-test dir="bugs150/pr113630" title="IncompatibleClassChangeError"> | |||
<compile files="Bean.java,BeanSupportAspectj.aj,BeanTestCase.java,javaBean.java,propertyChanger.java,PropertySupportAspect5.aj" options="-1.5"/> | |||
<run class="com.blueprint.util.aspectj5.test.BeanTestCase"/> | |||
<ajc-test dir="bugs150/pr113630/case1" title="IncompatibleClassChangeError - errorscenario"> | |||
<compile files="Bean.java,BeanTestCase.java,javaBean.java,propertyChanger.java,PropertySupportAspect5.aj" options="-1.5"> | |||
<message kind="warning" line="9" text="Failing match because annotation 'javaBean' on type 'Bean' has SOURCE retention. Matching allowed when RetentionPolicy is CLASS or RUNTIME"/> | |||
<message kind="error" line="18" text="The method addPropertyChangeListener(String, BeanTestCase) is undefined for the type Bean"/> | |||
</compile> | |||
</ajc-test> | |||
<ajc-test dir="bugs150/pr113630/case2" title="IncompatibleClassChangeError - workingscenario"> | |||
<compile files="Bean.java,BeanTestCase.java,javaBean.java,propertyChanger.java,PropertySupportAspect5.aj" options="-1.5"/> | |||
<run class="BeanTestCase"/> | |||
</ajc-test> | |||
<ajc-test dir="bugs150" title="Generics ClassCastException"> |
@@ -176,6 +176,10 @@ public class BoundedReferenceType extends ReferenceType { | |||
public boolean isAnnotationWithRuntimeRetention() { | |||
return resolvedTypeX.isAnnotationWithRuntimeRetention(); | |||
} | |||
public String getRetentionPolicy() { | |||
return resolvedTypeX.getRetentionPolicy(); | |||
} | |||
public boolean isGeneric() { | |||
return resolvedTypeX.isGenericType(); |
@@ -147,6 +147,10 @@ public class ReferenceType extends ResolvedType { | |||
return delegate.isAnnotation(); | |||
} | |||
public String getRetentionPolicy() { | |||
return delegate.getRetentionPolicy(); | |||
} | |||
public boolean isAnnotationWithRuntimeRetention() { | |||
return delegate.isAnnotationWithRuntimeRetention(); | |||
} |
@@ -33,6 +33,7 @@ public interface ReferenceTypeDelegate { | |||
public boolean isInterface(); | |||
public boolean isEnum(); | |||
public boolean isAnnotation(); | |||
public String getRetentionPolicy(); | |||
public boolean isAnnotationWithRuntimeRetention(); | |||
public boolean isClass(); | |||
public boolean isGeneric(); |
@@ -86,6 +86,10 @@ public class BcelObjectType extends AbstractReferenceTypeDelegate { | |||
private String declaredSignature = null; | |||
private boolean isGenericType = false; | |||
private boolean discoveredRetentionPolicy = false; | |||
private String retentionPolicy; | |||
/** | |||
* A BcelObjectType is 'damaged' if it has been modified from what was original constructed from | |||
* the bytecode. This currently happens if the parents are modified or an annotation is added - | |||
@@ -416,9 +420,34 @@ public class BcelObjectType extends AbstractReferenceTypeDelegate { | |||
} | |||
public boolean isAnnotationWithRuntimeRetention() { | |||
if (!isAnnotation()) { | |||
return false; | |||
} else { | |||
return getRetentionPolicy().equals("RUNTIME"); | |||
// if (!isAnnotation()) { | |||
// return false; | |||
// } else { | |||
// Annotation[] annotationsOnThisType = javaClass.getAnnotations(); | |||
// for (int i = 0; i < annotationsOnThisType.length; i++) { | |||
// Annotation a = annotationsOnThisType[i]; | |||
// if (a.getTypeName().equals(UnresolvedType.AT_RETENTION.getName())) { | |||
// List values = a.getValues(); | |||
// boolean isRuntime = false; | |||
// for (Iterator it = values.iterator(); it.hasNext();) { | |||
// ElementNameValuePair element = (ElementNameValuePair) it.next(); | |||
// ElementValue v = element.getValue(); | |||
// isRuntime = v.stringifyValue().equals("RUNTIME"); | |||
// } | |||
// return isRuntime; | |||
// } | |||
// } | |||
// } | |||
// return false; | |||
} | |||
public String getRetentionPolicy() { | |||
if (discoveredRetentionPolicy) return retentionPolicy; | |||
discoveredRetentionPolicy=true; | |||
retentionPolicy=null; // null means we have no idea | |||
if (isAnnotation()) { | |||
Annotation[] annotationsOnThisType = javaClass.getAnnotations(); | |||
for (int i = 0; i < annotationsOnThisType.length; i++) { | |||
Annotation a = annotationsOnThisType[i]; | |||
@@ -428,13 +457,13 @@ public class BcelObjectType extends AbstractReferenceTypeDelegate { | |||
for (Iterator it = values.iterator(); it.hasNext();) { | |||
ElementNameValuePair element = (ElementNameValuePair) it.next(); | |||
ElementValue v = element.getValue(); | |||
isRuntime = v.stringifyValue().equals("RUNTIME"); | |||
retentionPolicy = v.stringifyValue(); | |||
return retentionPolicy; | |||
} | |||
return isRuntime; | |||
} | |||
} | |||
} | |||
return false; | |||
return retentionPolicy; | |||
} | |||
public boolean isSynthetic() { |
@@ -19,6 +19,7 @@ import org.aspectj.util.FuzzyBoolean; | |||
import org.aspectj.weaver.AnnotatedElement; | |||
import org.aspectj.weaver.BCException; | |||
import org.aspectj.weaver.ISourceContext; | |||
import org.aspectj.weaver.ReferenceType; | |||
import org.aspectj.weaver.ResolvedType; | |||
import org.aspectj.weaver.TypeVariableReference; | |||
import org.aspectj.weaver.UnresolvedType; | |||
@@ -79,6 +80,14 @@ public class ExactAnnotationTypePattern extends AnnotationTypePattern { | |||
} | |||
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; | |||
} | |||
} | |||
return FuzzyBoolean.YES; | |||
} else if (checkSupers) { | |||
ResolvedType toMatchAgainst = ((ResolvedType) annotated).getSuperclass(); |
@@ -92,7 +92,9 @@ public class WildAnnotationTypePattern extends AnnotationTypePattern { | |||
scope.getWorld().getMessageHandler().handleMessage(m); | |||
resolved = false; | |||
} | |||
return new ExactAnnotationTypePattern(et.getExactType().resolve(scope.getWorld())); | |||
ExactAnnotationTypePattern eatp = new ExactAnnotationTypePattern(et.getExactType().resolve(scope.getWorld())); | |||
eatp.copyLocationFrom(this); | |||
return eatp; | |||
} else { | |||
return this; | |||
} |
@@ -126,6 +126,11 @@ public class ReflectionBasedReferenceTypeDelegate implements ReferenceTypeDelega | |||
// cant be an annotation in Java 1.4 or prior | |||
return false; | |||
} | |||
public String getRetentionPolicy() { | |||
// cant be an annotation in Java 1.4 or prior | |||
return null; | |||
} | |||
/* (non-Javadoc) | |||
* @see org.aspectj.weaver.ReferenceTypeDelegate#isClass() |