6996914: Diamond inference: problem when accessing protected constructor

Wed, 10 Nov 2010 12:37:25 +0000

author
mcimadamore
date
Wed, 10 Nov 2010 12:37:25 +0000
changeset 740
bce19889597e
parent 739
a0d9d642f65b
child 741
58ceeff50af8

6996914: Diamond inference: problem when accessing protected constructor
Summary: special resolution scheme for diamond inference needs to open up protected constructors in anon inner class creation
Reviewed-by: jjg

src/share/classes/com/sun/tools/javac/comp/Attr.java file | annotate | diff | comparison | revisions
test/tools/javac/generics/diamond/6996914/T6996914a.java file | annotate | diff | comparison | revisions
test/tools/javac/generics/diamond/6996914/T6996914b.java file | annotate | diff | comparison | revisions
     1.1 --- a/src/share/classes/com/sun/tools/javac/comp/Attr.java	Tue Nov 09 17:49:24 2010 -0800
     1.2 +++ b/src/share/classes/com/sun/tools/javac/comp/Attr.java	Wed Nov 10 12:37:25 2010 +0000
     1.3 @@ -1552,7 +1552,7 @@
     1.4          // Attribute clazz expression and store
     1.5          // symbol + type back into the attributed tree.
     1.6          Type clazztype = attribType(clazz, env);
     1.7 -        Pair<Scope,Scope> mapping = getSyntheticScopeMapping(clazztype);
     1.8 +        Pair<Scope,Scope> mapping = getSyntheticScopeMapping(clazztype, cdef != null);
     1.9          if (!TreeInfo.isDiamond(tree)) {
    1.10              clazztype = chk.checkClassType(
    1.11                  tree.clazz.pos(), clazztype, true);
    1.12 @@ -1849,7 +1849,7 @@
    1.13       *  inference. The inferred return type of the synthetic constructor IS
    1.14       *  the inferred type for the diamond operator.
    1.15       */
    1.16 -    private Pair<Scope, Scope> getSyntheticScopeMapping(Type ctype) {
    1.17 +    private Pair<Scope, Scope> getSyntheticScopeMapping(Type ctype, boolean overrideProtectedAccess) {
    1.18          if (ctype.tag != CLASS) {
    1.19              return erroneousMapping;
    1.20          }
    1.21 @@ -1860,6 +1860,12 @@
    1.22                  e.scope != null;
    1.23                  e = e.next()) {
    1.24              MethodSymbol newConstr = (MethodSymbol) e.sym.clone(ctype.tsym);
    1.25 +            if (overrideProtectedAccess && (newConstr.flags() & PROTECTED) != 0) {
    1.26 +                //make protected constructor public (this is required for
    1.27 +                //anonymous inner class creation expressions using diamond)
    1.28 +                newConstr.flags_field |= PUBLIC;
    1.29 +                newConstr.flags_field &= ~PROTECTED;
    1.30 +            }
    1.31              newConstr.name = names.init;
    1.32              List<Type> oldTypeargs = List.nil();
    1.33              if (newConstr.type.tag == FORALL) {
     2.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.2 +++ b/test/tools/javac/generics/diamond/6996914/T6996914a.java	Wed Nov 10 12:37:25 2010 +0000
     2.3 @@ -0,0 +1,171 @@
     2.4 +/*
     2.5 + * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
     2.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     2.7 + *
     2.8 + * This code is free software; you can redistribute it and/or modify it
     2.9 + * under the terms of the GNU General Public License version 2 only, as
    2.10 + * published by the Free Software Foundation.
    2.11 + *
    2.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
    2.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    2.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    2.15 + * version 2 for more details (a copy is included in the LICENSE file that
    2.16 + * accompanied this code).
    2.17 + *
    2.18 + * You should have received a copy of the GNU General Public License version
    2.19 + * 2 along with this work; if not, write to the Free Software Foundation,
    2.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    2.21 + *
    2.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    2.23 + * or visit www.oracle.com if you need additional information or have any
    2.24 + * questions.
    2.25 + */
    2.26 +
    2.27 +/*
    2.28 + * @test
    2.29 + * @bug 6996914
    2.30 + * @summary  Diamond inference: problem when accessing protected constructor
    2.31 + * @run main T6996914a
    2.32 + */
    2.33 +
    2.34 +import com.sun.source.util.JavacTask;
    2.35 +import java.net.URI;
    2.36 +import java.util.Arrays;
    2.37 +import javax.tools.Diagnostic;
    2.38 +import javax.tools.DiagnosticListener;
    2.39 +import javax.tools.JavaCompiler;
    2.40 +import javax.tools.JavaFileObject;
    2.41 +import javax.tools.SimpleJavaFileObject;
    2.42 +import javax.tools.ToolProvider;
    2.43 +
    2.44 +public class T6996914a {
    2.45 +
    2.46 +    enum PackageKind {
    2.47 +        DEFAULT("", ""),
    2.48 +        A("package a;", "import a.*;");
    2.49 +
    2.50 +        String pkgDecl;
    2.51 +        String importDecl;
    2.52 +
    2.53 +        PackageKind(String pkgDecl, String importDecl) {
    2.54 +            this.pkgDecl = pkgDecl;
    2.55 +            this.importDecl = importDecl;
    2.56 +        }
    2.57 +    }
    2.58 +
    2.59 +    enum DiamondKind {
    2.60 +        STANDARD("new Foo<>();"),
    2.61 +        ANON("new Foo<>() {};");
    2.62 +
    2.63 +        String expr;
    2.64 +
    2.65 +        DiamondKind(String expr) {
    2.66 +            this.expr = expr;
    2.67 +        }
    2.68 +    }
    2.69 +
    2.70 +    enum ConstructorKind {
    2.71 +        PACKAGE(""),
    2.72 +        PROTECTED("protected"),
    2.73 +        PRIVATE("private"),
    2.74 +        PUBLIC("public");
    2.75 +
    2.76 +        String mod;
    2.77 +
    2.78 +        ConstructorKind(String mod) {
    2.79 +            this.mod = mod;
    2.80 +        }
    2.81 +    }
    2.82 +
    2.83 +    static class FooClass extends SimpleJavaFileObject {
    2.84 +
    2.85 +        final static String sourceStub =
    2.86 +                        "#P\n" +
    2.87 +                        "public class Foo<X> {\n" +
    2.88 +                        "  #M Foo() {}\n" +
    2.89 +                        "}\n";
    2.90 +
    2.91 +        String source;
    2.92 +
    2.93 +        public FooClass(PackageKind pk, ConstructorKind ck) {
    2.94 +            super(URI.create("myfo:/" + (pk != PackageKind.DEFAULT ? "a/Foo.java" : "Foo.java")),
    2.95 +                    JavaFileObject.Kind.SOURCE);
    2.96 +            source = sourceStub.replace("#P", pk.pkgDecl).replace("#M", ck.mod);
    2.97 +        }
    2.98 +
    2.99 +        @Override
   2.100 +        public CharSequence getCharContent(boolean ignoreEncodingErrors) {
   2.101 +            return source;
   2.102 +        }
   2.103 +    }
   2.104 +
   2.105 +    static class ClientClass extends SimpleJavaFileObject {
   2.106 +
   2.107 +        final static String sourceStub =
   2.108 +                        "#I\n" +
   2.109 +                        "class Test {\n" +
   2.110 +                        "  Foo<String> fs = #D\n" +
   2.111 +                        "}\n";
   2.112 +
   2.113 +        String source;
   2.114 +
   2.115 +        public ClientClass(PackageKind pk, DiamondKind dk) {
   2.116 +            super(URI.create("myfo:/Test.java"), JavaFileObject.Kind.SOURCE);
   2.117 +            source = sourceStub.replace("#I", pk.importDecl).replace("#D", dk.expr);
   2.118 +        }
   2.119 +
   2.120 +        @Override
   2.121 +        public CharSequence getCharContent(boolean ignoreEncodingErrors) {
   2.122 +            return source;
   2.123 +        }
   2.124 +    }
   2.125 +
   2.126 +    public static void main(String... args) throws Exception {
   2.127 +        for (PackageKind pk : PackageKind.values()) {
   2.128 +            for (ConstructorKind ck : ConstructorKind.values()) {
   2.129 +                for (DiamondKind dk : DiamondKind.values()) {
   2.130 +                    compileAndCheck(pk, ck, dk);
   2.131 +                }
   2.132 +            }
   2.133 +        }
   2.134 +    }
   2.135 +
   2.136 +    static void compileAndCheck(PackageKind pk, ConstructorKind ck, DiamondKind dk) throws Exception {
   2.137 +        FooClass foo = new FooClass(pk, ck);
   2.138 +        ClientClass client = new ClientClass(pk, dk);
   2.139 +        final JavaCompiler tool = ToolProvider.getSystemJavaCompiler();
   2.140 +        ErrorListener el = new ErrorListener();
   2.141 +        JavacTask ct = (JavacTask)tool.getTask(null, null, el,
   2.142 +                null, null, Arrays.asList(foo, client));
   2.143 +        ct.analyze();
   2.144 +        if (el.errors > 0 == check(pk, ck, dk)) {
   2.145 +            String msg = el.errors > 0 ?
   2.146 +                "Error compiling files" :
   2.147 +                "No error when compiling files";
   2.148 +            throw new AssertionError(msg + ": \n" + foo.source + "\n" + client.source);
   2.149 +        }
   2.150 +    }
   2.151 +
   2.152 +    static boolean check(PackageKind pk, ConstructorKind ck, DiamondKind dk) {
   2.153 +        switch (pk) {
   2.154 +            case A: return ck == ConstructorKind.PUBLIC ||
   2.155 +                    (ck  == ConstructorKind.PROTECTED && dk == DiamondKind.ANON);
   2.156 +            case DEFAULT: return ck != ConstructorKind.PRIVATE;
   2.157 +            default: throw new AssertionError("Unknown package kind");
   2.158 +        }
   2.159 +    }
   2.160 +
   2.161 +    /**
   2.162 +     * DiagnosticListener to count any errors that occur
   2.163 +     */
   2.164 +    private static class ErrorListener implements DiagnosticListener<JavaFileObject> {
   2.165 +
   2.166 +        public void report(Diagnostic<? extends JavaFileObject> diagnostic) {
   2.167 +            switch (diagnostic.getKind()) {
   2.168 +                case ERROR:
   2.169 +                    errors++;
   2.170 +            }
   2.171 +        }
   2.172 +        int errors;
   2.173 +    }
   2.174 +}
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/test/tools/javac/generics/diamond/6996914/T6996914b.java	Wed Nov 10 12:37:25 2010 +0000
     3.3 @@ -0,0 +1,39 @@
     3.4 +/*
     3.5 + * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
     3.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     3.7 + *
     3.8 + * This code is free software; you can redistribute it and/or modify it
     3.9 + * under the terms of the GNU General Public License version 2 only, as
    3.10 + * published by the Free Software Foundation.
    3.11 + *
    3.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
    3.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    3.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    3.15 + * version 2 for more details (a copy is included in the LICENSE file that
    3.16 + * accompanied this code).
    3.17 + *
    3.18 + * You should have received a copy of the GNU General Public License version
    3.19 + * 2 along with this work; if not, write to the Free Software Foundation,
    3.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    3.21 + *
    3.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    3.23 + * or visit www.oracle.com if you need additional information or have any
    3.24 + * questions.
    3.25 + */
    3.26 +
    3.27 +/*
    3.28 + * @test
    3.29 + * @bug 6996914
    3.30 + * @summary  Diamond inference: problem when accessing protected constructor
    3.31 + * @compile T6996914b.java
    3.32 + */
    3.33 +
    3.34 +class Super<X,Y> {
    3.35 +    private Super(Integer i, Y y, X x) {}
    3.36 +    public Super(Number n, X x, Y y) {}
    3.37 +}
    3.38 +
    3.39 +class Test {
    3.40 +    Super<String,Integer> ssi1 = new Super<>(1, "", 2);
    3.41 +    Super<String,Integer> ssi2 = new Super<>(1, "", 2) {};
    3.42 +}

mercurial