changeset 405:19ffb3fcb045

output type annotations of arrays to classfile eliminate duplicated annotations in classfile
author mali
date Tue, 24 Mar 2009 23:30:58 -0400
parents ce5281969d4d
children 926140ad88bc
files src/share/classes/com/sun/tools/javac/comp/TransTypes.java src/share/classes/com/sun/tools/javac/tree/TreeScanner.java src/share/classes/com/sun/tools/javac/tree/TreeTranslator.java test/tools/javap/typeAnnotations/NewArray.java test/tools/javap/typeAnnotations/Presence.java
diffstat 5 files changed, 210 insertions(+), 5 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/classes/com/sun/tools/javac/comp/TransTypes.java	Tue Mar 24 22:41:22 2009 -0400
+++ b/src/share/classes/com/sun/tools/javac/comp/TransTypes.java	Tue Mar 24 23:30:58 2009 -0400
@@ -442,7 +442,7 @@
 
     public void visitClassDef(JCClassDecl tree) {
         new TypeAnnotationPositions().scan(tree);
-        List<TypeAnnotations> ta = collectErasedAnnotations(tree.typarams);
+        List<TypeAnnotations> ta = List.nil(); //collectErasedAnnotations(tree.typarams);
         tree.sym.typeAnnotations = ta;
         new TypeAnnotationLift().scan(tree);
         translateClass(tree.sym);
@@ -451,7 +451,7 @@
 
     JCMethodDecl currentMethod = null;
     public void visitMethodDef(JCMethodDecl tree) {
-        List<TypeAnnotations> ta = collectErasedAnnotations(tree.typarams);
+        List<TypeAnnotations> ta = List.nil(); // collectErasedAnnotations(tree.typarams);
         if (tree.sym.typeAnnotations != null)
             ta = ta.appendList(tree.sym.typeAnnotations);
 
@@ -741,7 +741,7 @@
     /** Visitor method for parameterized types.
      */
     public void visitTypeApply(JCTypeApply tree) {
-        List<TypeAnnotations> ta = collectErasedAnnotations(tree.arguments);
+        List<TypeAnnotations> ta = List.nil(); //collectErasedAnnotations(tree.arguments);
         // Delete all type parameters.
         JCTree clazz = translate(tree.clazz, null);
         if (!ta.isEmpty()) {
@@ -819,7 +819,7 @@
         return translate(cdef, null);
     }
 
-    public List<TypeAnnotations> collectErasedAnnotations(List<? extends
+    private List<TypeAnnotations> collectErasedAnnotations(List<? extends
             JCTree> trees) {
         final ListBuffer<TypeAnnotations> ta = ListBuffer.lb();
         new TreeScanner() {
@@ -1009,6 +1009,25 @@
         }
 
         @Override
+        public void visitNewArray(JCNewArray tree) {
+            for (int i = 0; i < tree.dimAnnotations.size(); ++i) {
+                JCTree context = tree;
+                TypeAnnotations.Position p =
+                    resolveContext(tree, context, contexts.toList(),
+                            new TypeAnnotations.Position());
+                p.location = p.location.append(i);
+                p.type = p.type.getGenericComplement();
+                tree.dimTypeAnnotations.get(i).position = p;
+            }
+            JCTree context = tree;
+            TypeAnnotations.Position p =
+                resolveContext(tree, context, contexts.toList(),
+                        new TypeAnnotations.Position());
+            tree.typeAnnotations.position = p;
+            super.visitNewArray(tree);
+        }
+
+        @Override
         public void visitAnnotatedType(JCAnnotatedType tree) {
             if (!tree.annotations.isEmpty()) {
                 StringBuilder sb = new StringBuilder();
@@ -1116,6 +1135,12 @@
         }
 
         @Override
+        public void visitNewArray(JCNewArray tree) {
+            lift(tree.dimTypeAnnotations.append(tree.typeAnnotations));
+            super.visitNewArray(tree);
+        }
+
+        @Override
         public void visitTypeParameter(JCTypeParameter tree) {
             List<TypeAnnotations> ta = List.of(tree.typeAnnotations);
             if (tree.typeAnnotations != null
--- a/src/share/classes/com/sun/tools/javac/tree/TreeScanner.java	Tue Mar 24 22:41:22 2009 -0400
+++ b/src/share/classes/com/sun/tools/javac/tree/TreeScanner.java	Tue Mar 24 23:30:58 2009 -0400
@@ -205,8 +205,11 @@
     }
 
     public void visitNewArray(JCNewArray tree) {
+        scan(tree.annotations);
         scan(tree.elemtype);
         scan(tree.dims);
+        for (List<JCAnnotation> annos : tree.dimAnnotations)
+            scan(annos);
         scan(tree.elems);
     }
 
--- a/src/share/classes/com/sun/tools/javac/tree/TreeTranslator.java	Tue Mar 24 22:41:22 2009 -0400
+++ b/src/share/classes/com/sun/tools/javac/tree/TreeTranslator.java	Tue Mar 24 23:30:58 2009 -0400
@@ -282,6 +282,8 @@
     }
 
     public void visitNewArray(JCNewArray tree) {
+        tree.annotations = translate(tree.annotations);
+        // TODO: translate dimAnnotations
         tree.elemtype = translate(tree.elemtype);
         tree.dims = translate(tree.dims);
         tree.elems = translate(tree.elems);
@@ -363,6 +365,7 @@
     }
 
     public void visitTypeParameter(JCTypeParameter tree) {
+        tree.annotations = translate(tree.annotations);
         tree.bounds = translate(tree.bounds);
         result = tree;
     }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javap/typeAnnotations/NewArray.java	Tue Mar 24 23:30:58 2009 -0400
@@ -0,0 +1,174 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+import java.io.*;
+import com.sun.tools.classfile.*;
+
+/*
+ * @test NewArray
+ * @summary test that all type annotations are present in the classfile
+ */
+
+public class NewArray {
+    public static void main(String[] args) throws Exception {
+        new NewArray().run();
+    }
+
+    public void run() throws Exception {
+        File javaFile = writeTestFile();
+        File classFile = compileTestFile(javaFile);
+
+        ClassFile cf = ClassFile.read(classFile);
+        test(cf);
+        for (Field f : cf.fields) {
+            test(cf, f);
+        }
+        for (Method m: cf.methods) {
+            test(cf, m);
+        }
+
+        countAnnotations();
+
+        if (errors > 0)
+            throw new Exception(errors + " errors found");
+        System.out.println("PASSED");
+    }
+
+    void test(ClassFile cf) {
+        test(cf, Attribute.RuntimeVisibleTypeAnnotations, true);
+        test(cf, Attribute.RuntimeInvisibleTypeAnnotations, false);
+    }
+
+    void test(ClassFile cf, Method m) {
+        test(cf, m, Attribute.RuntimeVisibleTypeAnnotations, true);
+        test(cf, m, Attribute.RuntimeInvisibleTypeAnnotations, false);
+    }
+
+    void test(ClassFile cf, Field m) {
+        test(cf, m, Attribute.RuntimeVisibleTypeAnnotations, true);
+        test(cf, m, Attribute.RuntimeInvisibleTypeAnnotations, false);
+    }
+
+    // test the result of Attributes.getIndex according to expectations
+    // encoded in the method's name
+    void test(ClassFile cf, String name, boolean visible) {
+        int index = cf.attributes.getIndex(cf.constant_pool, name);
+        if (index != -1) {
+            Attribute attr = cf.attributes.get(index);
+            assert attr instanceof RuntimeTypeAnnotations_attribute;
+            RuntimeTypeAnnotations_attribute tAttr = (RuntimeTypeAnnotations_attribute)attr;
+            all += tAttr.annotations.length;
+            if (visible)
+                visibles += tAttr.annotations.length;
+            else
+                invisibles += tAttr.annotations.length;
+        }
+    }
+
+    // test the result of Attributes.getIndex according to expectations
+    // encoded in the method's name
+    void test(ClassFile cf, Method m, String name, boolean visible) {
+        int index = m.attributes.getIndex(cf.constant_pool, name);
+        if (index != -1) {
+            Attribute attr = m.attributes.get(index);
+            assert attr instanceof RuntimeTypeAnnotations_attribute;
+            RuntimeTypeAnnotations_attribute tAttr = (RuntimeTypeAnnotations_attribute)attr;
+            all += tAttr.annotations.length;
+            if (visible)
+                visibles += tAttr.annotations.length;
+            else
+                invisibles += tAttr.annotations.length;
+        }
+    }
+
+    // test the result of Attributes.getIndex according to expectations
+    // encoded in the method's name
+    void test(ClassFile cf, Field m, String name, boolean visible) {
+        int index = m.attributes.getIndex(cf.constant_pool, name);
+        if (index != -1) {
+            Attribute attr = m.attributes.get(index);
+            assert attr instanceof RuntimeTypeAnnotations_attribute;
+            RuntimeTypeAnnotations_attribute tAttr = (RuntimeTypeAnnotations_attribute)attr;
+            all += tAttr.annotations.length;
+            if (visible)
+                visibles += tAttr.annotations.length;
+            else
+                invisibles += tAttr.annotations.length;
+        }
+    }
+
+    File writeTestFile() throws IOException {
+      File f = new File("Test.java");
+        PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter(f)));
+        out.println("import java.util.*;");
+        out.println("class Test { ");
+        out.println("  @interface A { }");
+
+        out.println(" void test() {");
+        out.println("  Object a = new @A String @A [5] @A  [];");
+        out.println("  Object b = new @A String @A [5] @A [3];");
+        out.println("  Object c = new @A String @A [] @A [] {};");
+        out.println(" }");
+        out.println("}");
+
+        out.close();
+        return f;
+    }
+
+    File compileTestFile(File f) {
+        int rc = com.sun.tools.javac.Main.compile(new String[] { "-g", f.getPath() });
+        if (rc != 0)
+            throw new Error("compilation failed. rc=" + rc);
+        String path = f.getPath();
+        return new File(path.substring(0, path.length() - 5) + ".class");
+    }
+
+    void countAnnotations() {
+        int expected_visibles = 0, expected_invisibles = 9;
+        int expected_all = expected_visibles + expected_invisibles;
+
+        if (expected_all != all) {
+            errors++;
+            System.err.println("expected " + expected_all
+                    + " annotations but found " + all);
+        }
+
+        if (expected_visibles != visibles) {
+            errors++;
+            System.err.println("expected " + expected_visibles
+                    + " visibles annotations but found " + visibles);
+        }
+
+        if (expected_invisibles != invisibles) {
+            errors++;
+            System.err.println("expected " + expected_invisibles
+                    + " invisibles annotations but found " + invisibles);
+        }
+
+    }
+
+    int errors;
+    int all;
+    int visibles;
+    int invisibles;
+}
--- a/test/tools/javap/typeAnnotations/Presence.java	Tue Mar 24 22:41:22 2009 -0400
+++ b/test/tools/javap/typeAnnotations/Presence.java	Tue Mar 24 23:30:58 2009 -0400
@@ -157,7 +157,7 @@
     }
 
     void countAnnotations() {
-        int expected_visibles = 0, expected_invisibles = 40;
+        int expected_visibles = 0, expected_invisibles = 38;
         int expected_all = expected_visibles + expected_invisibles;
 
         if (expected_all != all) {