Bugzilla Bug 42740 declare error fails on pointcuts composed from multiple classes Bugzilla Bug 42746 within() pcd is confused for certain declare softs and probably: Bugzilla Bug 42739 Compiler crash in ajc head (post 1.1.1 rc1)tags/V1_1_1
@@ -749,13 +749,8 @@ public class AspectDeclaration extends MemberTypeDeclaration { | |||
} | |||
} | |||
} | |||
//??? timing is weird | |||
factory.getWorld().getCrosscuttingMembersSet().addOrReplaceAspect(typeX); | |||
if (typeX.getSuperclass().isAspect() && !typeX.getSuperclass().isExposedToWeaver()) { | |||
factory.getWorld().getCrosscuttingMembersSet().addOrReplaceAspect(typeX.getSuperclass()); | |||
} | |||
concreteName.getDeclaredPointcuts(); | |||
} | |||
@@ -47,6 +47,8 @@ public class PointcutDeclaration extends MethodDeclaration { | |||
public PointcutDesignator pointcutDesignator; | |||
private int declaredModifiers; | |||
private String declaredName; | |||
private ResolvedPointcutDefinition resolvedPointcutDeclaration = null; | |||
public PointcutDeclaration(CompilationResult compilationResult) { | |||
super(compilationResult); | |||
@@ -89,12 +91,21 @@ public class PointcutDeclaration extends MethodDeclaration { | |||
pointcutDesignator.postParse(typeDec, this); | |||
} | |||
} | |||
public void resolve(ClassScope upperScope) { | |||
// this method should do nothing, use the entry point below... | |||
} | |||
public void resolvePointcut(ClassScope upperScope) { | |||
super.resolve(upperScope); | |||
} | |||
public void resolveStatements() { | |||
if (isAbstract()) { | |||
this.modifiers |= AccSemicolonBody; | |||
} | |||
if (binding == null || ignoreFurtherInvestigation) return; | |||
@@ -108,23 +119,27 @@ public class PointcutDeclaration extends MethodDeclaration { | |||
pointcutDesignator.finishResolveTypes(this, this.binding, arguments.length, | |||
scope.enclosingSourceType()); | |||
} | |||
//System.out.println("resolved: " + getPointcut() + ", " + getPointcut().state); | |||
makeResolvedPointcutDefinition(); | |||
resolvedPointcutDeclaration.setPointcut(getPointcut()); | |||
super.resolveStatements(); | |||
} | |||
public ResolvedPointcutDefinition makeResolvedPointcutDefinition() { | |||
//System.out.println("pc: " + getPointcut()); | |||
ResolvedPointcutDefinition ret = new ResolvedPointcutDefinition( | |||
if (resolvedPointcutDeclaration != null) return resolvedPointcutDeclaration; | |||
//System.out.println("pc: " + getPointcut() + ", " + getPointcut().state); | |||
resolvedPointcutDeclaration = new ResolvedPointcutDefinition( | |||
EclipseFactory.fromBinding(this.binding.declaringClass), | |||
declaredModifiers, | |||
declaredName, | |||
EclipseFactory.fromBindings(this.binding.parameters), | |||
getPointcut()); | |||
getPointcut()); //??? might want to use null | |||
ret.setPosition(sourceStart, sourceEnd); | |||
ret.setSourceContext(new EclipseSourceContext(compilationResult)); | |||
return ret; | |||
resolvedPointcutDeclaration.setPosition(sourceStart, sourceEnd); | |||
resolvedPointcutDeclaration.setSourceContext(new EclipseSourceContext(compilationResult)); | |||
return resolvedPointcutDeclaration; | |||
} | |||
@@ -16,12 +16,15 @@ package org.aspectj.ajdt.internal.compiler.lookup; | |||
import java.util.*; | |||
import org.aspectj.ajdt.internal.compiler.ast.AspectDeclaration; | |||
import org.aspectj.ajdt.internal.compiler.ast.DeclareDeclaration; | |||
import org.aspectj.ajdt.internal.compiler.ast.PointcutDeclaration; | |||
import org.aspectj.asm.*; | |||
import org.aspectj.asm.IProgramElement; | |||
import org.aspectj.asm.internal.Relationship; | |||
import org.aspectj.bridge.IMessage; | |||
import org.aspectj.weaver.*; | |||
import org.aspectj.weaver.patterns.*; | |||
import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration; | |||
import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration; | |||
import org.eclipse.jdt.internal.compiler.env.IBinaryType; | |||
import org.eclipse.jdt.internal.compiler.env.INameEnvironment; | |||
@@ -85,12 +88,25 @@ public class AjLookupEnvironment extends LookupEnvironment { | |||
} | |||
// need to build inter-type declarations for all AspectDeclarations at this point | |||
for (int i = lastCompletedUnitIndex + 1; i <= lastUnitIndex; i++) { | |||
SourceTypeBinding[] b = units[i].scope.topLevelTypes; | |||
for (int j = 0; j < b.length; j++) { | |||
buildInterTypeAndPerClause(b[j].scope); | |||
} | |||
} | |||
for (int i = lastCompletedUnitIndex + 1; i <= lastUnitIndex; i++) { | |||
SourceTypeBinding[] b = units[i].scope.topLevelTypes; | |||
for (int j = 0; j < b.length; j++) { | |||
buildInterTypeAndPerClause(b[j].scope); | |||
} | |||
} | |||
for (int i = lastCompletedUnitIndex + 1; i <= lastUnitIndex; i++) { | |||
SourceTypeBinding[] b = units[i].scope.topLevelTypes; | |||
for (int j = 0; j < b.length; j++) { | |||
resolvePointcutDeclarations(b[j].scope); | |||
} | |||
} | |||
for (int i = lastCompletedUnitIndex + 1; i <= lastUnitIndex; i++) { | |||
SourceTypeBinding[] b = units[i].scope.topLevelTypes; | |||
for (int j = 0; j < b.length; j++) { | |||
addCrosscuttingStructures(b[j].scope); | |||
} | |||
} | |||
factory.finishTypeMungers(); | |||
// now do weaving | |||
@@ -102,9 +118,9 @@ public class AjLookupEnvironment extends LookupEnvironment { | |||
for (int i = lastCompletedUnitIndex + 1; i <= lastUnitIndex; i++) { | |||
weaveInterTypeDeclarations(units[i].scope, typeMungers, declareParents); | |||
units[i] = null; // release unnecessary reference to the parsed unit | |||
units[i] = null; // release unnecessary reference to the parsed unit | |||
} | |||
stepCompleted = BUILD_FIELDS_AND_METHODS; | |||
lastCompletedUnitIndex = lastUnitIndex; | |||
} | |||
@@ -117,6 +133,51 @@ public class AjLookupEnvironment extends LookupEnvironment { | |||
pendingTypesToWeave.clear(); | |||
} | |||
private void addCrosscuttingStructures(ClassScope s) { | |||
TypeDeclaration dec = s.referenceContext; | |||
if (dec instanceof AspectDeclaration) { | |||
ResolvedTypeX typeX = factory.fromEclipse(dec.binding); | |||
factory.getWorld().getCrosscuttingMembersSet().addOrReplaceAspect(typeX); | |||
if (typeX.getSuperclass().isAspect() && !typeX.getSuperclass().isExposedToWeaver()) { | |||
factory.getWorld().getCrosscuttingMembersSet().addOrReplaceAspect(typeX.getSuperclass()); | |||
} | |||
} | |||
SourceTypeBinding sourceType = s.referenceContext.binding; | |||
ReferenceBinding[] memberTypes = sourceType.memberTypes; | |||
for (int i = 0, length = memberTypes.length; i < length; i++) { | |||
addCrosscuttingStructures(((SourceTypeBinding) memberTypes[i]).scope); | |||
} | |||
} | |||
private void resolvePointcutDeclarations(ClassScope s) { | |||
TypeDeclaration dec = s.referenceContext; | |||
SourceTypeBinding sourceType = s.referenceContext.binding; | |||
AbstractMethodDeclaration[] methods = dec.methods; | |||
boolean initializedMethods = false; | |||
if (methods != null) { | |||
for (int i=0; i < methods.length; i++) { | |||
if (methods[i] instanceof PointcutDeclaration) { | |||
if (!initializedMethods) { | |||
sourceType.methods(); //force initialization | |||
initializedMethods = true; | |||
} | |||
((PointcutDeclaration)methods[i]).resolvePointcut(s); | |||
} | |||
} | |||
} | |||
ReferenceBinding[] memberTypes = sourceType.memberTypes; | |||
for (int i = 0, length = memberTypes.length; i < length; i++) { | |||
resolvePointcutDeclarations(((SourceTypeBinding) memberTypes[i]).scope); | |||
} | |||
} | |||
private void buildInterTypeAndPerClause(ClassScope s) { | |||
TypeDeclaration dec = s.referenceContext; |
@@ -6736,4 +6736,19 @@ | |||
<compile files="InterPerCall.java"/> | |||
<run class="InterPerCall"/> | |||
</ajc-test> | |||
<ajc-test dir="bugs/declareBinding" | |||
pr="42740" | |||
title="declare error fails on pointcuts composed from multiple classes"> | |||
<compile files="SampleExceptionHandling1.java"> | |||
<message line="2" kind="error" text="no checked exceptions"/> | |||
</compile> | |||
</ajc-test> | |||
<ajc-test dir="bugs/declareSoftWithin" | |||
pr="42740" | |||
title="declare error fails on pointcuts composed from multiple classes"> | |||
<compile files="aspects/Softener.aj,test/NoSoftener.java"/> | |||
<run class="test.NoSoftener"/> | |||
</ajc-test> | |||
</suite> |
@@ -0,0 +1,21 @@ | |||
public class SampleExceptionHandling1 { | |||
public void mumble() throws java.io.IOException { } // CE expected | |||
} | |||
/** @author Ron Bodkin */ | |||
aspect Library { | |||
public pointcut executionsThrowingChecked() : | |||
execution(* *(..) throws (Exception+ && !RuntimeException)); | |||
} | |||
/** @author Ron Bodkin */ | |||
aspect SampleExceptionHandling { | |||
public pointcut scope() : within(SampleExceptionHandling1); | |||
public pointcut executionsThrowingChecked() : | |||
Library.executionsThrowingChecked() && scope(); | |||
declare error : executionsThrowingChecked(): | |||
"no checked exceptions"; | |||
} |
@@ -0,0 +1,18 @@ | |||
package aspects; | |||
import test.NoSoftener; | |||
/** | |||
* @author Ron Bodkin | |||
* @author Jim Hugunin | |||
*/ | |||
public aspect Softener extends SoftLib { | |||
public pointcut scope() : within(NoSoftener); | |||
} | |||
abstract aspect SoftLib { | |||
abstract pointcut scope(); | |||
public pointcut callsThrowingChecked() : call(* *(..)) && scope(); | |||
declare soft: NoSuchMethodException: callsThrowingChecked(); | |||
} |
@@ -0,0 +1,27 @@ | |||
package test; | |||
import java.lang.reflect.Constructor; | |||
import org.aspectj.testing.Tester; | |||
/** | |||
* @author Ron Bodkin | |||
* @author Jim Hugunin | |||
*/ | |||
public class NoSoftener { | |||
public static void main(String[] args) { | |||
Throwable wrapped = null; | |||
try { | |||
new NoSoftener().foo(Integer.class); | |||
} catch (org.aspectj.lang.SoftException se) { | |||
wrapped = se.getWrappedThrowable(); | |||
} | |||
Tester.checkNonNull(wrapped, "exception thrown"); | |||
Tester.check(wrapped instanceof NoSuchMethodException, | |||
"must be NoSuchMethodException"); | |||
} | |||
public void foo(Class clazz) { | |||
Class[] keyArgType = {}; | |||
Constructor ctor = clazz.getConstructor(keyArgType); | |||
} | |||
} |
@@ -91,4 +91,8 @@ public class ResolvedPointcutDefinition extends ResolvedMember { | |||
new ResolvedPointcutDefinition(TypeX.OBJECT, 0, "missing", | |||
TypeX.NONE, Pointcut.makeMatchesNothing(Pointcut.RESOLVED)); | |||
public void setPointcut(Pointcut pointcut) { | |||
this.pointcut = pointcut; | |||
} | |||
} |