changeset 2408:b5b61f27d93b

Implement type annotations on multi-catch.
author wmdietl
date Thu, 11 Apr 2013 00:54:44 -0700
parents 6d7aa0b05158
children 0c204aef28fa
files src/share/classes/com/sun/tools/javac/code/TypeAnnotationPosition.java src/share/classes/com/sun/tools/javac/jvm/Code.java src/share/classes/com/sun/tools/javac/jvm/Gen.java test/tools/javac/annotations/typeAnnotations/referenceinfos/ExceptionParameters.java test/tools/javac/annotations/typeAnnotations/referenceinfos/MultiCatch.java
diffstat 5 files changed, 99 insertions(+), 11 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/classes/com/sun/tools/javac/code/TypeAnnotationPosition.java	Thu Apr 11 00:52:01 2013 -0700
+++ b/src/share/classes/com/sun/tools/javac/code/TypeAnnotationPosition.java	Thu Apr 11 00:54:44 2013 -0700
@@ -146,7 +146,11 @@
     // For class extends, implements, and throws clauses
     public int type_index = Integer.MIN_VALUE;
 
-    // For exception parameters, index into exception table
+    // For exception parameters, index into exception table.
+    // In com.sun.tools.javac.jvm.Gen.genCatch we first set the type_index
+    // to the catch type index - that value is only temporary.
+    // Then in com.sun.tools.javac.jvm.Code.fillExceptionParameterPositions
+    // we use that value to determine the exception table index.
     public int exception_index = Integer.MIN_VALUE;
 
     // If this type annotation is within a lambda expression,
--- a/src/share/classes/com/sun/tools/javac/jvm/Code.java	Thu Apr 11 00:52:01 2013 -0700
+++ b/src/share/classes/com/sun/tools/javac/jvm/Code.java	Thu Apr 11 00:54:44 2013 -0700
@@ -1002,7 +1002,16 @@
             state.pop(((Symbol)(pool.pool[od])).erasure(types));
             break;
         case new_:
-            state.push(uninitializedObject(((Symbol)(pool.pool[od])).erasure(types), cp-3));
+            Symbol sym;
+            if (pool.pool[od] instanceof UniqueType) {
+                // Required by change in Gen.makeRef to allow
+                // annotated types.
+                // TODO: is this needed anywhere else?
+                sym = ((UniqueType)(pool.pool[od])).type.tsym;
+            } else {
+                sym = (Symbol)(pool.pool[od]);
+            }
+            state.push(uninitializedObject(sym.erasure(types), cp-3));
             break;
         case sipush:
             state.push(syms.intType);
@@ -1964,25 +1973,38 @@
             if (lv == null || lv.sym == null
                     || lv.sym.annotations.isTypesEmpty()
                     || !lv.sym.isExceptionParameter())
-                return;
-
-            int exidx = findExceptionIndex(lv);
+                continue;
 
             for (Attribute.TypeCompound ta : lv.sym.getRawTypeAttributes()) {
                 TypeAnnotationPosition p = ta.position;
-                p.exception_index = exidx;
+                // At this point p.type_index contains the catch type index.
+                // Use that index to determine the exception table index.
+                // We can afterwards discard the type_index.
+                // A TA position is shared for all type annotations in the
+                // same location; updating one is enough.
+                // Use -666 as a marker that the exception_index was already updated.
+                if (p.type_index != -666) {
+                    p.exception_index = findExceptionIndex(p.type_index);
+                    p.type_index = -666;
+                }
             }
         }
     }
 
-    private int findExceptionIndex(LocalVar lv) {
+    private int findExceptionIndex(int catchType) {
+        if (catchType == Integer.MIN_VALUE) {
+            // We didn't set the catch type index correctly.
+            // This shouldn't happen.
+            // TODO: issue error?
+            return -1;
+        }
         List<char[]> iter = catchInfo.toList();
         int len = catchInfo.length();
         for (int i = 0; i < len; ++i) {
             char[] catchEntry = iter.head;
             iter = iter.tail;
-            char handlerpc = catchEntry[2];
-            if (lv.start_pc == handlerpc + 1) {
+            char ct = catchEntry[3];
+            if (catchType == ct) {
                 return i;
             }
         }
--- a/src/share/classes/com/sun/tools/javac/jvm/Gen.java	Thu Apr 11 00:52:01 2013 -0700
+++ b/src/share/classes/com/sun/tools/javac/jvm/Gen.java	Thu Apr 11 00:54:44 2013 -0700
@@ -309,7 +309,15 @@
      */
     int makeRef(DiagnosticPosition pos, Type type) {
         checkDimension(pos, type);
-        return pool.put(type.hasTag(CLASS) ? (Object)type.tsym : (Object)type);
+        if (type.isAnnotated()) {
+            // Treat annotated types separately - we don't want
+            // to collapse all of them - at least for annotated
+            // exceptions.
+            // TODO: review this.
+            return pool.put((Object)type);
+        } else {
+            return pool.put(type.hasTag(CLASS) ? (Object)type.tsym : (Object)type);
+        }
     }
 
     /** Check if the given type is an array with too many dimensions.
@@ -1554,6 +1562,11 @@
                         registerCatch(tree.pos(),
                                       startpc,  end, code.curPc(),
                                       catchType);
+                        if (subCatch.type.isAnnotated()) {
+                            // All compounds share the same position, simply update the
+                            // first one.
+                            subCatch.type.getAnnotationMirrors().head.position.type_index = catchType;
+                        }
                     }
                     gaps = gaps.tail;
                     startpc = gaps.head.intValue();
@@ -1565,6 +1578,11 @@
                         registerCatch(tree.pos(),
                                       startpc, endpc, code.curPc(),
                                       catchType);
+                        if (subCatch.type.isAnnotated()) {
+                            // All compounds share the same position, simply update the
+                            // first one.
+                            subCatch.type.getAnnotationMirrors().head.position.type_index = catchType;
+                        }
                     }
                 }
                 VarSymbol exparam = tree.param.sym;
--- a/test/tools/javac/annotations/typeAnnotations/referenceinfos/ExceptionParameters.java	Thu Apr 11 00:52:01 2013 -0700
+++ b/test/tools/javac/annotations/typeAnnotations/referenceinfos/ExceptionParameters.java	Thu Apr 11 00:54:44 2013 -0700
@@ -47,11 +47,43 @@
         @TADescription(annotation = "TB", type = EXCEPTION_PARAMETER, exceptionIndex = 1),
         @TADescription(annotation = "TC", type = EXCEPTION_PARAMETER, exceptionIndex = 2)
     })
-    public String multipleExceptions() {
+    public String multipleExceptions1() {
         return "void multipleExceptions() { " +
             "try { new Object(); } catch(@TA Exception e) { }" +
             "try { new Object(); } catch(@TB Exception e) { }" +
             "try { new Object(); } catch(@TC Exception e) { }" +
             " }";
     }
+
+    @TADescriptions({
+        @TADescription(annotation = "TA", type = EXCEPTION_PARAMETER, exceptionIndex = 0),
+        @TADescription(annotation = "TB", type = EXCEPTION_PARAMETER, exceptionIndex = 1),
+        @TADescription(annotation = "TC", type = EXCEPTION_PARAMETER, exceptionIndex = 2)
+    })
+    public String multipleExceptions2() {
+        return "void multipleExceptions() { " +
+            "  try { new Object(); " +
+            "    try { new Object(); " +
+            "      try { new Object(); } catch(@TA Exception e) { }" +
+            "    } catch(@TB Exception e) { }" +
+            "  } catch(@TC Exception e) { }" +
+            "}";
+    }
+
+    @TADescriptions({
+        @TADescription(annotation = "TA", type = EXCEPTION_PARAMETER, exceptionIndex = 0),
+        @TADescription(annotation = "TB", type = EXCEPTION_PARAMETER, exceptionIndex = 1),
+        @TADescription(annotation = "TC", type = EXCEPTION_PARAMETER, exceptionIndex = 2)
+    })
+    public String multipleExceptions3() {
+        return "void multipleExceptions() { " +
+            "  try { new Object(); " +
+            "  } catch(@TA Exception e1) { "+
+            "    try { new Object(); " +
+            "    } catch(@TB Exception e2) {" +
+            "      try { new Object(); } catch(@TC Exception e3) { }" +
+            "    }" +
+            "  }" +
+            "}";
+    }
 }
--- a/test/tools/javac/annotations/typeAnnotations/referenceinfos/MultiCatch.java	Thu Apr 11 00:52:01 2013 -0700
+++ b/test/tools/javac/annotations/typeAnnotations/referenceinfos/MultiCatch.java	Thu Apr 11 00:54:44 2013 -0700
@@ -52,4 +52,16 @@
             "try { new Object(); } catch (@TA NullPointerException | @TB IndexOutOfBoundsException | @TC IllegalArgumentException e) { e.toString(); } }";
     }
 
+    @TADescriptions({
+        @TADescription(annotation = "TA", type = EXCEPTION_PARAMETER, exceptionIndex = 1),
+        @TADescription(annotation = "TB", type = EXCEPTION_PARAMETER, exceptionIndex = 1),
+        @TADescription(annotation = "TC", type = EXCEPTION_PARAMETER, exceptionIndex = 2),
+        @TADescription(annotation = "TD", type = EXCEPTION_PARAMETER, exceptionIndex = 2),
+        @TADescription(annotation = "TE", type = EXCEPTION_PARAMETER, exceptionIndex = 3),
+    })
+    public String multiCatch3() {
+        return "void multiCatch3() { " +
+            "try { new Object(); } catch (NullPointerException e1) {}" +
+            "try { new Object(); } catch (@TA @TB NullPointerException | @TC @TD IndexOutOfBoundsException | @TE IllegalArgumentException e2) { e2.toString(); } }";
+    }
 }