]> source.dussan.org Git - aspectj.git/commitdiff
Fix #366085 concerning declared annotations with source retention
authorAlexander Kriegisch <Alexander@Kriegisch.name>
Sun, 4 Dec 2022 15:16:37 +0000 (16:16 +0100)
committerAlexander Kriegisch <Alexander@Kriegisch.name>
Wed, 21 Dec 2022 13:57:39 +0000 (20:57 +0700)
See https://bugs.eclipse.org/bugs/show_bug.cgi?id=366085.
See https://stackoverflow.com/q/74618269/1082681.

The issue described in the Bugzilla issue is about 'declare @type', but
similar issues also existed for 'declare @field', 'declare @method',
'declare @constructor'. This fix is rather superficial and leaves
things to be desired, because it is rather hacky and simply ignores
errors source retention annotation declarations during weaving. A better
fix would drop the corresponding declarations while parsing and also
issue compiler warnings in each case.

Signed-off-by: Alexander Kriegisch <Alexander@Kriegisch.name>
org.aspectj.matcher/src/main/java/org/aspectj/weaver/patterns/DeclareAnnotation.java
tests/bugs1919/366085/Application.java [new file with mode: 0644]
tests/bugs1919/366085/DeclareAnnotationsAspect.aj [new file with mode: 0644]
tests/bugs1919/366085/Marker.java [new file with mode: 0644]
tests/bugs1919/366085/ToString.java [new file with mode: 0644]
tests/src/test/java/org/aspectj/systemtest/ajc1919/Bugs1919Tests.java
tests/src/test/resources/org/aspectj/systemtest/ajc1919/ajc1919.xml
weaver/src/main/java/org/aspectj/weaver/bcel/BcelClassWeaver.java

index 7a452ef05cbce68512ffa813c848624578deb4b0..00bbf5647c8f4062a09d54aad8c15df6f826a212 100644 (file)
@@ -380,6 +380,8 @@ public class DeclareAnnotation extends Declare {
                                int idx = 0;
                                if (annos.length > 0
                                                && annos[0].getType().getSignature().equals("Lorg/aspectj/internal/lang/annotation/ajcDeclareAnnotation;")) {
+                                       if (annos.length < 2)
+                                               continue;
                                        idx = 1;
                                }
                                annotation = annos[idx];
@@ -441,6 +443,8 @@ public class DeclareAnnotation extends Declare {
                                        int idx = 0;
                                        if (annoTypes[0].getSignature().equals("Lorg/aspectj/internal/lang/annotation/ajcDeclareAnnotation;")) {
                                                idx = 1;
+                                               if (annoTypes.length < 2)
+                                                       continue;
                                        }
                                        annotationType = annoTypes[idx];
                                        break;
diff --git a/tests/bugs1919/366085/Application.java b/tests/bugs1919/366085/Application.java
new file mode 100644 (file)
index 0000000..3ef2126
--- /dev/null
@@ -0,0 +1,11 @@
+public class Application {
+  public int number;
+
+  public Application(int number) {
+    this.number = number;
+  }
+
+  public int getNumber() {
+    return number;
+  }
+}
diff --git a/tests/bugs1919/366085/DeclareAnnotationsAspect.aj b/tests/bugs1919/366085/DeclareAnnotationsAspect.aj
new file mode 100644 (file)
index 0000000..8fdc946
--- /dev/null
@@ -0,0 +1,13 @@
+public aspect DeclareAnnotationsAspect {
+  // These should be ignored, because @ToString has SOURCE retention
+  declare @type : Application : @ToString;
+  declare @method : * Application.*(..) : @ToString;
+  declare @constructor : Application.new(..) : @ToString;
+  declare @field : * Application.* : @ToString;
+
+  // These should be applied, because @Marker has RUNTIME retention
+  declare @type : Application : @Marker;
+  declare @method : * Application.*(..) : @Marker;
+  declare @constructor : Application.new(..) : @Marker;
+  declare @field : * Application.* : @Marker;
+}
diff --git a/tests/bugs1919/366085/Marker.java b/tests/bugs1919/366085/Marker.java
new file mode 100644 (file)
index 0000000..42ba9af
--- /dev/null
@@ -0,0 +1,4 @@
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+@Retention(RetentionPolicy.RUNTIME)
+public @interface Marker { }
diff --git a/tests/bugs1919/366085/ToString.java b/tests/bugs1919/366085/ToString.java
new file mode 100644 (file)
index 0000000..08e9399
--- /dev/null
@@ -0,0 +1,4 @@
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+@Retention(RetentionPolicy.SOURCE)
+public @interface ToString { }
index 38441267ef97d2db22d903b193f04583439835cf..3c921f51a611c535016f9250c75014b03cdd7c4b 100644 (file)
@@ -15,8 +15,8 @@ import org.aspectj.testing.XMLBasedAjcTestCase;
  */
 public class Bugs1919Tests extends XMLBasedAjcTestCase {
 
-  public void testDummyBug() {
-    //runTest("dummy Java 19 bug");
+  public void testDeclareAnnotationWithSourceRetention() {
+    runTest("declare annotation with SOURCE retention");
   }
 
   public static Test suite() {
index 3741b338c62b6b7944a747a7c8083cbe00931635..eaeca714304d74f543536556651b448d359d8d24 100644 (file)
                </run>
        </ajc-test>
 
-       <!-- Currently, there are no bugfixes with tests in this AspectJ vesion -->
-       <ajc-test dir="bugs1919/github_99999" vm="19" title="dummy Java 19">
-       </ajc-test>
+       <!-- Weaver error when declaring annotation with SOURCE retention, see https://bugs.eclipse.org/bugs/show_bug.cgi?id=366085 -->
+        <ajc-test dir="bugs1919/366085" vm="1.5" title="declare annotation with SOURCE retention">
+                <compile files="Application.java DeclareAnnotationsAspect.aj ToString.java Marker.java" options="-1.5 -showWeaveInfo">
+                        <message kind="weave" text="'Application' (Application.java:1) is annotated with @Marker type annotation from 'DeclareAnnotationsAspect'"/>
+                        <message kind="weave" text="'public void Application.new(int)' (Application.java:4) is annotated with @Marker constructor annotation from 'DeclareAnnotationsAspect'"/>
+                        <message kind="weave" text="'public int Application.getNumber()' (Application.java:8) is annotated with @Marker method annotation from 'DeclareAnnotationsAspect'"/>
+                        <message kind="weave" text="'public int number' of type 'Application' (Application.java) is annotated with @Marker field annotation from 'DeclareAnnotationsAspect'"/>
+                </compile>
+               </ajc-test>
 
 </suite>
index 6a71640cacae30ec0cb78e9819b9c5a340d8ef73..450a49189be741847f78429a8b287f8ef0651415 100644 (file)
@@ -1023,7 +1023,12 @@ class BcelClassWeaver implements IClassWeaver {
                                                        if (annotationsToAdd == null) {
                                                                annotationsToAdd = new ArrayList<>();
                                                        }
-                                                       AnnotationGen a = ((BcelAnnotation) decaM.getAnnotation()).getBcelAnnotation();
+                                                       BcelAnnotation decaMAnnotation = (BcelAnnotation) decaM.getAnnotation();
+                                                       if (decaMAnnotation == null) {
+                                                               unusedDecams.remove(decaM);
+                                                               continue;
+                                                       }
+                                                       AnnotationGen a = decaMAnnotation.getBcelAnnotation();
                                                        AnnotationGen ag = new AnnotationGen(a, clazz.getConstantPool(), true);
                                                        annotationsToAdd.add(ag);
                                                        mg.addAnnotation(decaM.getAnnotation());
@@ -1423,7 +1428,8 @@ class BcelClassWeaver implements IClassWeaver {
                                        // go through all the declare @field statements
                                        for (DeclareAnnotation decaf : decafs) {
                                                if (decaf.getAnnotation() == null) {
-                                                       return false;
+                                                       unusedDecafs.remove(decaf);
+                                                       continue;
                                                }
                                                if (decaf.matches(field, world)) {
                                                        if (decaf.isRemover()) {