From d78d9ed48963cf302c26daab6af782d9b01ea3ac Mon Sep 17 00:00:00 2001 From: jhugunin Date: Wed, 10 Sep 2003 00:35:18 +0000 Subject: [PATCH] fix and tests for at least 2 bugs: 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) --- .../compiler/ast/AspectDeclaration.java | 9 +-- .../compiler/ast/PointcutDeclaration.java | 31 ++++++-- .../compiler/lookup/AjLookupEnvironment.java | 77 +++++++++++++++++-- tests/ajcTests.xml | 15 ++++ .../SampleExceptionHandling1.java | 21 +++++ .../declareSoftWithin/aspects/Softener.aj | 18 +++++ .../declareSoftWithin/test/NoSoftener.java | 27 +++++++ .../weaver/ResolvedPointcutDefinition.java | 4 + 8 files changed, 179 insertions(+), 23 deletions(-) create mode 100644 tests/bugs/declareBinding/SampleExceptionHandling1.java create mode 100644 tests/bugs/declareSoftWithin/aspects/Softener.aj create mode 100644 tests/bugs/declareSoftWithin/test/NoSoftener.java diff --git a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/AspectDeclaration.java b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/AspectDeclaration.java index e0967d667..90ac38a84 100644 --- a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/AspectDeclaration.java +++ b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/AspectDeclaration.java @@ -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(); } diff --git a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/PointcutDeclaration.java b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/PointcutDeclaration.java index b987c418b..b93d984cd 100644 --- a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/PointcutDeclaration.java +++ b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/PointcutDeclaration.java @@ -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; } diff --git a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/AjLookupEnvironment.java b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/AjLookupEnvironment.java index 171aeb722..4f9badc83 100644 --- a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/AjLookupEnvironment.java +++ b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/AjLookupEnvironment.java @@ -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; diff --git a/tests/ajcTests.xml b/tests/ajcTests.xml index fc5537889..a50e6940d 100644 --- a/tests/ajcTests.xml +++ b/tests/ajcTests.xml @@ -6736,4 +6736,19 @@ + + + + + + + + + + + diff --git a/tests/bugs/declareBinding/SampleExceptionHandling1.java b/tests/bugs/declareBinding/SampleExceptionHandling1.java new file mode 100644 index 000000000..4b5e4ae48 --- /dev/null +++ b/tests/bugs/declareBinding/SampleExceptionHandling1.java @@ -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"; +} \ No newline at end of file diff --git a/tests/bugs/declareSoftWithin/aspects/Softener.aj b/tests/bugs/declareSoftWithin/aspects/Softener.aj new file mode 100644 index 000000000..21eee34b6 --- /dev/null +++ b/tests/bugs/declareSoftWithin/aspects/Softener.aj @@ -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(); +} \ No newline at end of file diff --git a/tests/bugs/declareSoftWithin/test/NoSoftener.java b/tests/bugs/declareSoftWithin/test/NoSoftener.java new file mode 100644 index 000000000..5d082c199 --- /dev/null +++ b/tests/bugs/declareSoftWithin/test/NoSoftener.java @@ -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); + } +} \ No newline at end of file diff --git a/weaver/src/org/aspectj/weaver/ResolvedPointcutDefinition.java b/weaver/src/org/aspectj/weaver/ResolvedPointcutDefinition.java index de565597d..c5539a5fe 100644 --- a/weaver/src/org/aspectj/weaver/ResolvedPointcutDefinition.java +++ b/weaver/src/org/aspectj/weaver/ResolvedPointcutDefinition.java @@ -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; + } + } -- 2.39.5