]> source.dussan.org Git - aspectj.git/commitdiff
Fix for pr91267 (Generics): NPE at EclipseFactory.java:143 when using generic methods...
authoraclement <aclement>
Fri, 6 May 2005 10:21:26 +0000 (10:21 +0000)
committeraclement <aclement>
Fri, 6 May 2005 10:21:26 +0000 (10:21 +0000)
org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/EclipseFactory.java
tests/java5/generics/bugs/pr91267/TestBug1.aj [new file with mode: 0644]
tests/java5/generics/bugs/pr91267/TestBug2.aj [new file with mode: 0644]
tests/src/org/aspectj/systemtest/ajc150/GenericsTests.java
tests/src/org/aspectj/systemtest/ajc150/ajc150.xml
weaver/src/org/aspectj/weaver/TypeX.java

index ef960113e6e7f33c4159df1d03e3504ba0b81e6e..395094b256719fb986eecea2717b5dd4c83c387e 100644 (file)
@@ -136,8 +136,17 @@ public class EclipseFactory {
                return ret;
        }       
        
-       
        private static String getName(TypeBinding binding) {
+               if (binding instanceof TypeVariableBinding) {
+                       // The first bound may be null - so default to object?
+                       TypeVariableBinding tvb = (TypeVariableBinding)binding;
+                       if (tvb.firstBound!=null) {
+                               return getName(tvb.firstBound);
+                       } else {
+                               return getName(tvb.superclass);
+                       }
+               }
+               
                if (binding instanceof ReferenceBinding) {
                        return new String(
                                CharOperation.concatWith(((ReferenceBinding)binding).compoundName, '.'));
@@ -154,6 +163,16 @@ public class EclipseFactory {
 
 
 
+       /**
+        * Some generics notes:
+        * 
+        * Andy 6-May-05
+        * We were having trouble with parameterized types in a couple of places - due to TypeVariableBindings.  When we
+        * see a TypeVariableBinding now we default to either the firstBound if it is specified or java.lang.Object.  Not
+        * sure when/if this gets us unstuck?  It does mean we forget that it is a type variable when going back
+        * the other way from the TypeX and that would seem a bad thing - but I've yet to see the reason we need to
+        * remember the type variable.
+        */
        //??? going back and forth between strings and bindings is a waste of cycles
        public static TypeX fromBinding(TypeBinding binding) {
                if (binding instanceof HelperInterfaceBinding) {
@@ -166,7 +185,12 @@ public class EclipseFactory {
                if (binding instanceof TypeVariableBinding) {
                        // this is a type variable...
                        TypeVariableBinding tvb = (TypeVariableBinding) binding;
-                       return TypeX.forName(getName(tvb.firstBound)); // XXX needs more investigation as to whether this is correct in all cases
+                       // This code causes us to forget its a TVB which we will need when going back the other way...
+                       if (tvb.firstBound!=null) {
+                         return TypeX.forName(getName(tvb.firstBound)); // XXX needs more investigation as to whether this is correct in all cases
+                       } else {
+                         return TypeX.forName(getName(tvb.superclass));
+                       }
                }
                // FIXME asc/amc cope properly with RawTypeBindings
                if (binding instanceof ParameterizedTypeBinding && !(binding instanceof RawTypeBinding)) {
diff --git a/tests/java5/generics/bugs/pr91267/TestBug1.aj b/tests/java5/generics/bugs/pr91267/TestBug1.aj
new file mode 100644 (file)
index 0000000..b861d21
--- /dev/null
@@ -0,0 +1,15 @@
+import java.util.*;
+
+public aspect TestBug1 {
+    static <T> void addToEnv(Map<String,T> env, String key, T value) {
+       env.put(key, value);
+    }
+
+    public static void main(String[] argv) {
+      Map<String,Integer> msi = new HashMap<String,Integer>();
+      addToEnv(msi,"andy",new Integer(42));
+
+      if (msi.get("andy")!=42) throw new RuntimeException("Failed to add");
+    }
+}
+
diff --git a/tests/java5/generics/bugs/pr91267/TestBug2.aj b/tests/java5/generics/bugs/pr91267/TestBug2.aj
new file mode 100644 (file)
index 0000000..840f769
--- /dev/null
@@ -0,0 +1,13 @@
+import java.util.*;
+
+public aspect TestBug2 {
+    static <T> T lookupEnv(Map<String,T> env, String key) {
+       return env.get(key);
+    }
+
+    public static void main(String[] argv) {
+      Map<String,Integer> msi = new HashMap<String,Integer>();
+      msi.put("andy",42);
+      if (lookupEnv(msi,"andy")!=42) throw new RuntimeException("Failed to lookup");
+    }
+}
index 332f0dd8e34a3c5bd31c4c9ec760c0d13dbfb636..96557dfe502a2e7783d92a37eeb687f00dbdf027 100644 (file)
@@ -19,4 +19,12 @@ public class GenericsTests extends XMLBasedAjcTestCase {
        public void testITDReturningParameterizedType() {
                runTest("ITD with parameterized type");
        }
+       
+       public void testPR91267_1() {
+               runTest("NPE using generic methods in aspects 1");
+       }
+
+       public void testPR91267_2() {
+               runTest("NPE using generic methods in aspects 2");
+       }
 }
index 8001d474a7d4c1efa83f3cd975f9f1409156184f..8dca8410f4737622e9b1b6da7e47fb758ff2623c 100644 (file)
         <compile files="Test3.java" options="-1.5"/>
         <run class="Test3"/>
     </ajc-test>
+    
+    <ajc-test dir="java5/generics/bugs/pr91267" title="NPE using generic methods in aspects 1" vm="1.5">
+        <compile files="TestBug1.aj" options="-1.5"/>
+        <run class="TestBug1"/>
+    </ajc-test>
+    
+     <ajc-test dir="java5/generics/bugs/pr91267" title="NPE using generic methods in aspects 2" vm="1.5">
+        <compile files="TestBug2.aj" options="-1.5"/>
+        <run class="TestBug2"/>
+    </ajc-test>
  
 </suite>
\ No newline at end of file
index cd9e352f32f86775bf024c8909c2e86efa963d00..f3f078c371736f419fe6194bc39f74c42d1cde48 100644 (file)
@@ -92,6 +92,7 @@ public class TypeX implements AnnotatedElement {
     public static TypeX forName(String name) {
         return forSignature(nameToSignature(name));
     }
+       
 
     /** Constructs a TypeX for each java language type name in an incoming array.
      * 
@@ -121,10 +122,10 @@ public class TypeX implements AnnotatedElement {
                StringBuffer sigAddition = new StringBuffer();
                sigAddition.append("<");
                for (int i = 0; i < ret.typeParameters.length; i++) {
-                       sigAddition.append(ret.typeParameters[i].signature);
-                       sigAddition.append(">");
-                       sigAddition.append(";");
+                       sigAddition.append(ret.typeParameters[i].signature);                    
                }
+               sigAddition.append(">");
+               sigAddition.append(";");
                ret.signature = ret.signature + sigAddition.toString();
                return ret;
     }