#212342: during annotation processing, an originally unknown class may be generated, causing error type to be "converted" to a non-erroneous type. Need to take this into account when matching the Symbols from the previous AP round to the Symbols in the current AP round. release72
authorJan Lahoda <jlahoda@netbeans.org>
Wed, 01 Aug 2012 14:14:15 +0200
branchrelease72
changeset 177877337ac6e610
parent 1762 8c7740fb544f
#212342: during annotation processing, an originally unknown class may be generated, causing error type to be "converted" to a non-erroneous type. Need to take this into account when matching the Symbols from the previous AP round to the Symbols in the current AP round.
make/netbeans/nb-javac/test/global/ErrorToleranceTest.java
src/share/classes/com/sun/tools/javac/comp/MemberEnter.java
     1.1 --- a/make/netbeans/nb-javac/test/global/ErrorToleranceTest.java	Tue Jun 19 10:44:39 2012 +0200
     1.2 +++ b/make/netbeans/nb-javac/test/global/ErrorToleranceTest.java	Wed Aug 01 14:14:15 2012 +0200
     1.3 @@ -28,11 +28,14 @@
     1.4  import com.sun.tools.javac.api.JavacTaskImpl;
     1.5  import com.sun.tools.javap.DisassemblerTool.DisassemblerTask;
     1.6  import com.sun.tools.javap.JavapTask;
     1.7 +import global.ap1.AP;
     1.8  import java.io.File;
     1.9  import java.io.IOException;
    1.10  import java.io.PrintWriter;
    1.11  import java.io.StringWriter;
    1.12  import java.net.URI;
    1.13 +import java.net.URL;
    1.14 +import java.util.ArrayList;
    1.15  import java.util.Arrays;
    1.16  import java.util.Collection;
    1.17  import java.util.Collections;
    1.18 @@ -328,7 +331,142 @@
    1.19  
    1.20          compareResults(golden, code);
    1.21      }
    1.22 +    
    1.23 +    public void testIssue212342a() throws Exception {
    1.24 +        final String code = "package test;\n" +
    1.25 +                      "@global.ap1.Ann(fqnToGenerate=\"test.G\", content=\"package test; public class G {}\") public class Test { void t1(G g) {} G t2() { return null; } }\n";
    1.26  
    1.27 +        final String golden = "package test;\n" +
    1.28 +                      "public class Test { void t1(G g) {} G t2() { return null; } }\n" +
    1.29 +                      "class G {}\n";
    1.30 +
    1.31 +        compile(code, true, AP.class.getName());
    1.32 +        
    1.33 +        Collection<String> codeSig = dumpSignatures("test.Test");
    1.34 +        
    1.35 +        compile(golden, true);
    1.36 +        
    1.37 +        Collection<String> goldenSig = dumpSignatures("test.Test");
    1.38 +        assertEquals(goldenSig, codeSig);
    1.39 +    }
    1.40 +    
    1.41 +    public void testIssue212342b() throws Exception {
    1.42 +        final String code = "package test;\n" +
    1.43 +                      "@global.ap1.Ann(fqnToGenerate=\"test.G\", content=\"package test; @global.ap1.Ann(fqnToGenerate=\\\"test.H\\\", content=\\\"package test; public class H {}\\\") public class G {}\") public class Test { void t(H h) { System.err.println(1); } void t(G g) { System.err.println(2); } }\n";
    1.44 +
    1.45 +        final String golden = "package test;\n" +
    1.46 +                      "public class Test {  void t(H h) { System.err.println(1); } void t(G g) { System.err.println(2); } }\n" +
    1.47 +                      "class G {}\n" +
    1.48 +                      "class H {}\n";
    1.49 +
    1.50 +        compile(code, true, AP.class.getName());
    1.51 +        
    1.52 +        Collection<String> codeSig = dumpSignatures("test.Test");
    1.53 +        
    1.54 +        compile(golden, true);
    1.55 +        
    1.56 +        Collection<String> goldenSig = dumpSignatures("test.Test");
    1.57 +        assertEquals(goldenSig, codeSig);
    1.58 +    }
    1.59 +    
    1.60 +    public void testIssue212342c() throws Exception {
    1.61 +        final String code = "package test;\n" +
    1.62 +                      "@global.ap1.Ann(fqnToGenerate=\"test.G\", content=\"package test; @global.ap1.Ann(fqnToGenerate=\\\"test.H\\\", content=\\\"package test; public class H {}\\\") public class G {}\") public class Test { void t(G g) { System.err.println(2); } void t(H h) { System.err.println(1); } }\n";
    1.63 +
    1.64 +        final String golden = "package test;\n" +
    1.65 +                      "public class Test {  void t(G g) { System.err.println(2); } void t(H h) { System.err.println(1); } }\n" +
    1.66 +                      "class G {}\n" +
    1.67 +                      "class H {}\n";
    1.68 +
    1.69 +        compile(code, true, AP.class.getName());
    1.70 +        
    1.71 +        Collection<String> codeSig = dumpSignatures("test.Test");
    1.72 +        
    1.73 +        compile(golden, true);
    1.74 +        
    1.75 +        Collection<String> goldenSig = dumpSignatures("test.Test");
    1.76 +        assertEquals(goldenSig, codeSig);
    1.77 +
    1.78 +    }
    1.79 +    public void testIssue212342d() throws Exception {
    1.80 +        final String code = "package test;\n" +
    1.81 +                      "@global.ap1.Ann(fqnToGenerate=\"test.G\", content=\"package test; @global.ap1.Ann(fqnToGenerate=\\\"test.H\\\", content=\\\"package test; public class H {}\\\") public class G {}\") public class Test { void t(G g, String str) { System.err.println(2); } void t(H h, String str) { System.err.println(1); } }\n";
    1.82 +
    1.83 +        final String golden = "package test;\n" +
    1.84 +                      "public class Test {  void t(G g, String str) { System.err.println(2); } void t(H h, String str) { System.err.println(1); } }\n" +
    1.85 +                      "class G {}\n" +
    1.86 +                      "class H {}\n";
    1.87 +
    1.88 +        compile(code, true, AP.class.getName());
    1.89 +        
    1.90 +        Collection<String> codeSig = dumpSignatures("test.Test");
    1.91 +        
    1.92 +        compile(golden, true);
    1.93 +        
    1.94 +        Collection<String> goldenSig = dumpSignatures("test.Test");
    1.95 +        assertEquals(goldenSig, codeSig);
    1.96 +
    1.97 +    }
    1.98 +    
    1.99 +    public void testIssue212342e() throws Exception {
   1.100 +        final String code = "package test;\n" +
   1.101 +                      "@global.ap1.Ann(fqnToGenerate=\"test.G\", content=\"package test; @global.ap1.Ann(fqnToGenerate=\\\"test.H\\\", content=\\\"package test; public class H {}\\\") public class G {}\") public class Test { <T> void t(G g, T t) { System.err.println(2); } <T> void t(H h, T t) { System.err.println(1); } }\n";
   1.102 +
   1.103 +        final String golden = "package test;\n" +
   1.104 +                      "public class Test { <T> void t(G g, T t) { System.err.println(2); } <T> void t(H h, T t) { System.err.println(1); } }\n" +
   1.105 +                      "class G {}\n" +
   1.106 +                      "class H {}\n";
   1.107 +
   1.108 +        compile(code, true, AP.class.getName());
   1.109 +        
   1.110 +        Collection<String> codeSig = dumpSignatures("test.Test");
   1.111 +        
   1.112 +        compile(golden, true);
   1.113 +        
   1.114 +        Collection<String> goldenSig = dumpSignatures("test.Test");
   1.115 +        assertEquals(goldenSig, codeSig);
   1.116 +
   1.117 +    }
   1.118 +    
   1.119 +    public void testIssue212342f() throws Exception {
   1.120 +        final String code = "package test;\n" +
   1.121 +                      "@global.ap1.Ann(fqnToGenerate=\"test.G\", content=\"package test; @global.ap1.Ann(fqnToGenerate=\\\"test.H\\\", content=\\\"package test; public class H {}\\\") public class G {}\") public class Test { <T extends H> void t(G g, T t) { System.err.println(2); } <T extends G> void t(H h, T t) { System.err.println(1); } }\n";
   1.122 +
   1.123 +        final String golden = "package test;\n" +
   1.124 +                      "public class Test { <T extends H> void t(G g, T t) { System.err.println(2); } <T extends G> void t(H h, T t) { System.err.println(1); } }\n" +
   1.125 +                      "class G {}\n" +
   1.126 +                      "class H {}\n";
   1.127 +
   1.128 +        compile(code, true, AP.class.getName());
   1.129 +        
   1.130 +        Collection<String> codeSig = dumpSignatures("test.Test");
   1.131 +        
   1.132 +        compile(golden, true);
   1.133 +        
   1.134 +        Collection<String> goldenSig = dumpSignatures("test.Test");
   1.135 +        assertEquals(goldenSig, codeSig);
   1.136 +
   1.137 +    }
   1.138 +
   1.139 +    public void testIssue212342g() throws Exception {
   1.140 +        final String code = "package test;\n" +
   1.141 +                      "@global.ap1.Ann(fqnToGenerate=\"test.G\", content=\"package test; @global.ap1.Ann(fqnToGenerate=\\\"test.H\\\", content=\\\"package test; public class H {}\\\") public class G {}\") public class Test { H h = new H(); G g = new G(); }\n";
   1.142 +
   1.143 +        final String golden = "package test;\n" +
   1.144 +                      "public class Test {  H h = new H(); G g = new G(); }\n" +
   1.145 +                      "class G {}\n" +
   1.146 +                      "class H {}\n";
   1.147 +
   1.148 +        compile(code, true, AP.class.getName());
   1.149 +        
   1.150 +        Collection<String> codeSig = dumpSignatures("test.Test");
   1.151 +        
   1.152 +        compile(golden, true);
   1.153 +        
   1.154 +        Collection<String> goldenSig = dumpSignatures("test.Test");
   1.155 +        assertEquals(goldenSig, codeSig);
   1.156 +    }
   1.157 +    
   1.158      //<editor-fold defaultstate="collapsed" desc=" Test Infrastructure ">
   1.159      static class MyFileObject extends SimpleJavaFileObject {
   1.160          private String text;
   1.161 @@ -363,6 +501,10 @@
   1.162      }
   1.163  
   1.164      private String[] compile(String code, boolean repair) throws Exception {
   1.165 +        return compile(code, repair, null);
   1.166 +    }
   1.167 +    
   1.168 +    private String[] compile(String code, boolean repair, String apToRun) throws Exception {
   1.169          final String bootPath = System.getProperty("sun.boot.class.path"); //NOI18N
   1.170          final JavaCompiler tool = ToolProvider.getSystemJavaCompiler();
   1.171          assert tool != null;
   1.172 @@ -372,7 +514,15 @@
   1.173  
   1.174          std.setLocation(StandardLocation.CLASS_OUTPUT, Collections.singleton(workingDir));
   1.175          
   1.176 -        JavacTaskImpl ct = (JavacTaskImpl)tool.getTask(null, mjfm, null, Arrays.asList("-bootclasspath",  bootPath, "-Xjcov", "-XDshouldStopPolicy=GENERATE"), null, Arrays.asList(new MyFileObject(code)));
   1.177 +        List<String> compilerOptions = new ArrayList<String>();
   1.178 +        compilerOptions.addAll(Arrays.asList("-bootclasspath",  bootPath, "-Xjcov", "-XDshouldStopPolicy=GENERATE", "-XDbackgroundCompilation"));
   1.179 +        if (apToRun != null) {
   1.180 +            URL myself = AnnotationProcessingTest.class.getProtectionDomain().getCodeSource().getLocation();
   1.181 +            File sourceOutput = new File(workingDir, "sourceOutput");
   1.182 +            sourceOutput.mkdirs();
   1.183 +            compilerOptions.addAll(Arrays.asList("-classpath", myself.toExternalForm(), "-processor", AP.class.getName(), "-s", sourceOutput.getAbsolutePath()));
   1.184 +        }
   1.185 +        JavacTaskImpl ct = (JavacTaskImpl)tool.getTask(null, mjfm, null, compilerOptions, null, Arrays.asList(new MyFileObject(code)));
   1.186          com.sun.tools.javac.main.JavaCompiler.instance(ct.getContext()).doRepair = repair;
   1.187          ct.parse();
   1.188          Iterable<? extends Element> analyze = ct.analyze();
   1.189 @@ -388,7 +538,7 @@
   1.190          return result.toArray(new String[0]);
   1.191      }
   1.192      
   1.193 -    private Collection<String> dumpSignatures(String[] fqns) throws Exception {
   1.194 +    private Collection<String> dumpSignatures(String... fqns) throws Exception {
   1.195          List<String> result = new LinkedList<String>();
   1.196          
   1.197          for (String fqn : fqns) {
     2.1 --- a/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java	Tue Jun 19 10:44:39 2012 +0200
     2.2 +++ b/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java	Wed Aug 01 14:14:15 2012 +0200
     2.3 @@ -588,6 +588,59 @@
     2.4          }
     2.5      }
     2.6  
     2.7 +    boolean hasSameBounds(ForAll t, ForAll s) {
     2.8 +        List<Type> l1 = t.tvars;
     2.9 +        List<Type> l2 = s.tvars;
    2.10 +        while (l1.nonEmpty() && l2.nonEmpty() &&
    2.11 +               isSameAPType(l1.head.getUpperBound(),
    2.12 +                          types.subst(l2.head.getUpperBound(),
    2.13 +                                s.tvars,
    2.14 +                                t.tvars))) {
    2.15 +            l1 = l1.tail;
    2.16 +            l2 = l2.tail;
    2.17 +        }
    2.18 +        return l1.isEmpty() && l2.isEmpty();
    2.19 +    }
    2.20 +    
    2.21 +    private boolean isSameAPType(Type t, Type s) {
    2.22 +        return    types.isSameType(t, s)
    2.23 +               || t.tsym != null && s.tsym != null && s.isErroneous() && t.tsym.name == s.tsym.name;
    2.24 +    }
    2.25 +    
    2.26 +    private boolean isSameMethod(Type ot, Type os) {
    2.27 +        if (ot.tag != os.tag) return false;
    2.28 +        
    2.29 +        switch (ot.tag) {
    2.30 +            case METHOD: {
    2.31 +                MethodType t = (MethodType) ot;
    2.32 +                MethodType s = (MethodType) os;
    2.33 +
    2.34 +                if (t.getParameterTypes().size() != s.getParameterTypes().size()) return false;
    2.35 +                if (!isSameAPType(t.getReturnType(), s.getReturnType())) return false;
    2.36 +
    2.37 +                List<Type> tp = t.getParameterTypes();
    2.38 +                List<Type> sp = s.getParameterTypes();
    2.39 +
    2.40 +                while (!tp.isEmpty() && !sp.isEmpty()) {
    2.41 +                    if (!isSameAPType(tp.head, sp.head)) return false;
    2.42 +                    tp = tp.tail;
    2.43 +                    sp = sp.tail;
    2.44 +                }
    2.45 +
    2.46 +                return tp.isEmpty() == sp.isEmpty();
    2.47 +            }
    2.48 +            case FORALL: {
    2.49 +                ForAll t = (ForAll) ot;
    2.50 +                ForAll s = (ForAll) os;
    2.51 +
    2.52 +                return    hasSameBounds(t, s)
    2.53 +                       && isSameMethod(t.qtype, types.subst(s.qtype, s.tvars, t.tvars));
    2.54 +            }
    2.55 +            default:
    2.56 +                return false;
    2.57 +        }
    2.58 +    }
    2.59 +    
    2.60      public void visitMethodDef(JCMethodDecl tree) {
    2.61          Scope enclScope = enter.enterScope(env);
    2.62          MethodSymbol m = new MethodSymbol(0, tree.name, null, enclScope.owner);
    2.63 @@ -609,7 +662,7 @@
    2.64          if ((enclScope.owner.flags_field & FROMCLASS) != 0) {
    2.65              for (Scope.Entry e = enclScope.lookup(tree.name); e.scope == enclScope; e = e.next()) {
    2.66                  if (e.sym.kind == MTH) {
    2.67 -                    boolean sameType = types.isSameType(m.type, e.sym.type);
    2.68 +                    boolean sameType = (enclScope.owner.flags_field & APT_CLEANED) != 0 ? isSameMethod(m.type, e.sym.type) : types.isSameType(m.type, e.sym.type);
    2.69                      if (sameType || m.name == names.init && (m.owner.name.isEmpty() || (m.owner.owner.kind & (VAR | MTH)) != 0)) {
    2.70                          if ((e.sym.flags_field & FROMCLASS) != 0) {
    2.71                              treeCleaner.scan(tree);
    2.72 @@ -760,9 +813,11 @@
    2.73          boolean doEnterSymbol = true;
    2.74          if ((enclScope.owner.flags_field & FROMCLASS) != 0) {
    2.75              for (Scope.Entry e = enclScope.lookup(tree.name); e.scope == enclScope; e = e.next()) {
    2.76 -                if (e.sym.kind == VAR && types.isSameType(tree.vartype.type, e.sym.type)) {
    2.77 +                boolean sameType = (enclScope.owner.flags_field & APT_CLEANED) != 0 ? isSameAPType(tree.vartype.type, e.sym.type) : types.isSameType(tree.vartype.type, e.sym.type);
    2.78 +                if (e.sym.kind == VAR && sameType) {
    2.79                      if ((e.sym.flags_field & FROMCLASS) != 0) {
    2.80                          v = (VarSymbol)e.sym;
    2.81 +                        v.type = tree.vartype.type;
    2.82                          e.sym.flags_field &= ~FROMCLASS;
    2.83                      }
    2.84                      break;