Merge

Fri, 27 Feb 2015 15:43:27 -0800

author
lana
date
Fri, 27 Feb 2015 15:43:27 -0800
changeset 2719
6f78b8742284
parent 2715
fc98314cff57
parent 2718
20bf47dc2a91
child 2720
44d168f9ad16
child 2726
8d6354ca8f24

Merge

.hgtags file | annotate | diff | comparison | revisions
     1.1 --- a/.hgtags	Wed Feb 25 12:59:57 2015 -0800
     1.2 +++ b/.hgtags	Fri Feb 27 15:43:27 2015 -0800
     1.3 @@ -370,6 +370,10 @@
     1.4  0c514d1fd006fc79d35b670de10c370c8d559db7 jdk8u40-b19
     1.5  c3d6d1a5339952fbe4124e700407b7211446c99c jdk8u40-b20
     1.6  9113c7c8d902ec94b28ca0ef4a6466bdba65fcfc jdk8u40-b21
     1.7 +79177246b3dbe5296fb53755d8695acdaef59fc8 jdk8u40-b22
     1.8 +fb294b49373bda0b3afc7f011d64ecefed73b42e jdk8u40-b23
     1.9 +c5d4ffa220f3824c2ea5d39dc99d41a9df9e5ae5 jdk8u40-b24
    1.10 +991141080b2078e67179ff307a5051e59431762c jdk8u40-b25
    1.11  0c514d1fd006fc79d35b670de10c370c8d559db7 jdk8u60-b00
    1.12  0ba07c272e33c93377a5d7ed98b9de873cc91980 jdk8u60-b01
    1.13  387cf62ce7895dd5e067aaa51faa93d5c078583e jdk8u60-b02
     2.1 --- a/src/share/classes/com/sun/tools/javac/code/Symbol.java	Wed Feb 25 12:59:57 2015 -0800
     2.2 +++ b/src/share/classes/com/sun/tools/javac/code/Symbol.java	Fri Feb 27 15:43:27 2015 -0800
     2.3 @@ -1153,6 +1153,16 @@
     2.4          public <R, P> R accept(Symbol.Visitor<R, P> v, P p) {
     2.5              return v.visitClassSymbol(this, p);
     2.6          }
     2.7 +
     2.8 +        public void markAbstractIfNeeded(Types types) {
     2.9 +            if (types.enter.getEnv(this) != null &&
    2.10 +                (flags() & ENUM) != 0 && types.supertype(type).tsym == types.syms.enumSym &&
    2.11 +                (flags() & (FINAL | ABSTRACT)) == 0) {
    2.12 +                if (types.firstUnimplementedAbstract(this) != null)
    2.13 +                    // add the ABSTRACT flag to an enum
    2.14 +                    flags_field |= ABSTRACT;
    2.15 +            }
    2.16 +        }
    2.17      }
    2.18  
    2.19  
     3.1 --- a/src/share/classes/com/sun/tools/javac/code/Types.java	Wed Feb 25 12:59:57 2015 -0800
     3.2 +++ b/src/share/classes/com/sun/tools/javac/code/Types.java	Fri Feb 27 15:43:27 2015 -0800
     3.3 @@ -47,6 +47,7 @@
     3.4  import com.sun.tools.javac.util.*;
     3.5  import static com.sun.tools.javac.code.BoundKind.*;
     3.6  import static com.sun.tools.javac.code.Flags.*;
     3.7 +import static com.sun.tools.javac.code.Kinds.MTH;
     3.8  import static com.sun.tools.javac.code.Scope.*;
     3.9  import static com.sun.tools.javac.code.Symbol.*;
    3.10  import static com.sun.tools.javac.code.Type.*;
    3.11 @@ -85,6 +86,7 @@
    3.12      final boolean allowBoxing;
    3.13      final boolean allowCovariantReturns;
    3.14      final boolean allowObjectToPrimitiveCast;
    3.15 +    final boolean allowDefaultMethods;
    3.16      final ClassReader reader;
    3.17      final Check chk;
    3.18      final Enter enter;
    3.19 @@ -111,6 +113,7 @@
    3.20          allowBoxing = source.allowBoxing();
    3.21          allowCovariantReturns = source.allowCovariantReturns();
    3.22          allowObjectToPrimitiveCast = source.allowObjectToPrimitiveCast();
    3.23 +        allowDefaultMethods = source.allowDefaultMethods();
    3.24          reader = ClassReader.instance(context);
    3.25          chk = Check.instance(context);
    3.26          enter = Enter.instance(context);
    3.27 @@ -2763,6 +2766,59 @@
    3.28      // </editor-fold>
    3.29  
    3.30  
    3.31 +    /** Return first abstract member of class `sym'.
    3.32 +     */
    3.33 +    public MethodSymbol firstUnimplementedAbstract(ClassSymbol sym) {
    3.34 +        try {
    3.35 +            return firstUnimplementedAbstractImpl(sym, sym);
    3.36 +        } catch (CompletionFailure ex) {
    3.37 +            chk.completionError(enter.getEnv(sym).tree.pos(), ex);
    3.38 +            return null;
    3.39 +        }
    3.40 +    }
    3.41 +        //where:
    3.42 +        private MethodSymbol firstUnimplementedAbstractImpl(ClassSymbol impl, ClassSymbol c) {
    3.43 +            MethodSymbol undef = null;
    3.44 +            // Do not bother to search in classes that are not abstract,
    3.45 +            // since they cannot have abstract members.
    3.46 +            if (c == impl || (c.flags() & (ABSTRACT | INTERFACE)) != 0) {
    3.47 +                Scope s = c.members();
    3.48 +                for (Scope.Entry e = s.elems;
    3.49 +                     undef == null && e != null;
    3.50 +                     e = e.sibling) {
    3.51 +                    if (e.sym.kind == MTH &&
    3.52 +                        (e.sym.flags() & (ABSTRACT|IPROXY|DEFAULT)) == ABSTRACT) {
    3.53 +                        MethodSymbol absmeth = (MethodSymbol)e.sym;
    3.54 +                        MethodSymbol implmeth = absmeth.implementation(impl, this, true);
    3.55 +                        if (implmeth == null || implmeth == absmeth) {
    3.56 +                            //look for default implementations
    3.57 +                            if (allowDefaultMethods) {
    3.58 +                                MethodSymbol prov = interfaceCandidates(impl.type, absmeth).head;
    3.59 +                                if (prov != null && prov.overrides(absmeth, impl, this, true)) {
    3.60 +                                    implmeth = prov;
    3.61 +                                }
    3.62 +                            }
    3.63 +                        }
    3.64 +                        if (implmeth == null || implmeth == absmeth) {
    3.65 +                            undef = absmeth;
    3.66 +                        }
    3.67 +                    }
    3.68 +                }
    3.69 +                if (undef == null) {
    3.70 +                    Type st = supertype(c.type);
    3.71 +                    if (st.hasTag(CLASS))
    3.72 +                        undef = firstUnimplementedAbstractImpl(impl, (ClassSymbol)st.tsym);
    3.73 +                }
    3.74 +                for (List<Type> l = interfaces(c.type);
    3.75 +                     undef == null && l.nonEmpty();
    3.76 +                     l = l.tail) {
    3.77 +                    undef = firstUnimplementedAbstractImpl(impl, (ClassSymbol)l.head.tsym);
    3.78 +                }
    3.79 +            }
    3.80 +            return undef;
    3.81 +        }
    3.82 +
    3.83 +
    3.84      //where
    3.85      public List<MethodSymbol> interfaceCandidates(Type site, MethodSymbol ms) {
    3.86          Filter<Symbol> filter = new MethodFilter(ms, site);
     4.1 --- a/src/share/classes/com/sun/tools/javac/comp/Attr.java	Wed Feb 25 12:59:57 2015 -0800
     4.2 +++ b/src/share/classes/com/sun/tools/javac/comp/Attr.java	Fri Feb 27 15:43:27 2015 -0800
     4.3 @@ -4269,6 +4269,8 @@
     4.4              chk.validate(tree.implementing, env);
     4.5          }
     4.6  
     4.7 +        c.markAbstractIfNeeded(types);
     4.8 +
     4.9          // If this is a non-abstract class, check that it has no abstract
    4.10          // methods or unimplemented methods of an implemented interface.
    4.11          if ((c.flags() & (ABSTRACT | INTERFACE)) == 0) {
     5.1 --- a/src/share/classes/com/sun/tools/javac/comp/Check.java	Wed Feb 25 12:59:57 2015 -0800
     5.2 +++ b/src/share/classes/com/sun/tools/javac/comp/Check.java	Fri Feb 27 15:43:27 2015 -0800
     5.3 @@ -2049,70 +2049,15 @@
     5.4       *  @param c            The class.
     5.5       */
     5.6      void checkAllDefined(DiagnosticPosition pos, ClassSymbol c) {
     5.7 -        try {
     5.8 -            MethodSymbol undef = firstUndef(c, c);
     5.9 -            if (undef != null) {
    5.10 -                if ((c.flags() & ENUM) != 0 &&
    5.11 -                    types.supertype(c.type).tsym == syms.enumSym &&
    5.12 -                    (c.flags() & FINAL) == 0) {
    5.13 -                    // add the ABSTRACT flag to an enum
    5.14 -                    c.flags_field |= ABSTRACT;
    5.15 -                } else {
    5.16 -                    MethodSymbol undef1 =
    5.17 -                        new MethodSymbol(undef.flags(), undef.name,
    5.18 -                                         types.memberType(c.type, undef), undef.owner);
    5.19 -                    log.error(pos, "does.not.override.abstract",
    5.20 -                              c, undef1, undef1.location());
    5.21 -                }
    5.22 -            }
    5.23 -        } catch (CompletionFailure ex) {
    5.24 -            completionError(pos, ex);
    5.25 +        MethodSymbol undef = types.firstUnimplementedAbstract(c);
    5.26 +        if (undef != null) {
    5.27 +            MethodSymbol undef1 =
    5.28 +                new MethodSymbol(undef.flags(), undef.name,
    5.29 +                                 types.memberType(c.type, undef), undef.owner);
    5.30 +            log.error(pos, "does.not.override.abstract",
    5.31 +                      c, undef1, undef1.location());
    5.32          }
    5.33      }
    5.34 -//where
    5.35 -        /** Return first abstract member of class `c' that is not defined
    5.36 -         *  in `impl', null if there is none.
    5.37 -         */
    5.38 -        private MethodSymbol firstUndef(ClassSymbol impl, ClassSymbol c) {
    5.39 -            MethodSymbol undef = null;
    5.40 -            // Do not bother to search in classes that are not abstract,
    5.41 -            // since they cannot have abstract members.
    5.42 -            if (c == impl || (c.flags() & (ABSTRACT | INTERFACE)) != 0) {
    5.43 -                Scope s = c.members();
    5.44 -                for (Scope.Entry e = s.elems;
    5.45 -                     undef == null && e != null;
    5.46 -                     e = e.sibling) {
    5.47 -                    if (e.sym.kind == MTH &&
    5.48 -                        (e.sym.flags() & (ABSTRACT|IPROXY|DEFAULT)) == ABSTRACT) {
    5.49 -                        MethodSymbol absmeth = (MethodSymbol)e.sym;
    5.50 -                        MethodSymbol implmeth = absmeth.implementation(impl, types, true);
    5.51 -                        if (implmeth == null || implmeth == absmeth) {
    5.52 -                            //look for default implementations
    5.53 -                            if (allowDefaultMethods) {
    5.54 -                                MethodSymbol prov = types.interfaceCandidates(impl.type, absmeth).head;
    5.55 -                                if (prov != null && prov.overrides(absmeth, impl, types, true)) {
    5.56 -                                    implmeth = prov;
    5.57 -                                }
    5.58 -                            }
    5.59 -                        }
    5.60 -                        if (implmeth == null || implmeth == absmeth) {
    5.61 -                            undef = absmeth;
    5.62 -                        }
    5.63 -                    }
    5.64 -                }
    5.65 -                if (undef == null) {
    5.66 -                    Type st = types.supertype(c.type);
    5.67 -                    if (st.hasTag(CLASS))
    5.68 -                        undef = firstUndef(impl, (ClassSymbol)st.tsym);
    5.69 -                }
    5.70 -                for (List<Type> l = types.interfaces(c.type);
    5.71 -                     undef == null && l.nonEmpty();
    5.72 -                     l = l.tail) {
    5.73 -                    undef = firstUndef(impl, (ClassSymbol)l.head.tsym);
    5.74 -                }
    5.75 -            }
    5.76 -            return undef;
    5.77 -        }
    5.78  
    5.79      void checkNonCyclicDecl(JCClassDecl tree) {
    5.80          CycleChecker cc = new CycleChecker();
     6.1 --- a/src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java	Wed Feb 25 12:59:57 2015 -0800
     6.2 +++ b/src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java	Fri Feb 27 15:43:27 2015 -0800
     6.3 @@ -1027,6 +1027,7 @@
     6.4               l.nonEmpty();
     6.5               l = l.tail) {
     6.6              ClassSymbol inner = l.head;
     6.7 +            inner.markAbstractIfNeeded(types);
     6.8              char flags = (char) adjustFlags(inner.flags_field);
     6.9              if ((flags & INTERFACE) != 0) flags |= ABSTRACT; // Interfaces are always ABSTRACT
    6.10              if (inner.name.isEmpty()) flags &= ~FINAL; // Anonymous class: unset FINAL flag
     7.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     7.2 +++ b/test/tools/javac/classfiles/InnerClasses/T8068517.java	Fri Feb 27 15:43:27 2015 -0800
     7.3 @@ -0,0 +1,126 @@
     7.4 +/*
     7.5 + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
     7.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     7.7 + *
     7.8 + * This code is free software; you can redistribute it and/or modify it
     7.9 + * under the terms of the GNU General Public License version 2 only, as
    7.10 + * published by the Free Software Foundation.
    7.11 + *
    7.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
    7.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    7.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    7.15 + * version 2 for more details (a copy is included in the LICENSE file that
    7.16 + * accompanied this code).
    7.17 + *
    7.18 + * You should have received a copy of the GNU General Public License version
    7.19 + * 2 along with this work; if not, write to the Free Software Foundation,
    7.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    7.21 + *
    7.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    7.23 + * or visit www.oracle.com if you need additional information or have any
    7.24 + * questions.
    7.25 + */
    7.26 +
    7.27 +/** @test
    7.28 + *  @bug 8068517
    7.29 + *  @summary Verify that nested enums have correct abstract flag in the InnerClasses attribute.
    7.30 + *  @library /tools/javac/lib
    7.31 + *  @build ToolBox T8068517
    7.32 + *  @run main T8068517
    7.33 + */
    7.34 +
    7.35 +import com.sun.tools.javac.util.Assert;
    7.36 +import java.io.File;
    7.37 +import java.nio.file.Files;
    7.38 +import java.util.Arrays;
    7.39 +import java.util.List;
    7.40 +import java.util.stream.Collectors;
    7.41 +import java.util.stream.Stream;
    7.42 +import javax.tools.JavaCompiler;
    7.43 +import javax.tools.ToolProvider;
    7.44 +
    7.45 +public class T8068517 {
    7.46 +
    7.47 +    public static void main(String[] args) throws Exception {
    7.48 +        new T8068517().run();
    7.49 +    }
    7.50 +
    7.51 +    void run() throws Exception {
    7.52 +        runTest("class A {\n" +
    7.53 +                "    enum AInner implements Runnable {\n" +
    7.54 +                "        A {\n" +
    7.55 +                "            public void run() {}\n" +
    7.56 +                "        };\n" +
    7.57 +                "    }\n" +
    7.58 +                "}\n",
    7.59 +                "class B {\n" +
    7.60 +                "    A.AInner a;\n" +
    7.61 +                "}");
    7.62 +        runTest("class A {\n" +
    7.63 +                "    enum AInner implements Runnable {\n" +
    7.64 +                "        A {\n" +
    7.65 +                "            public void run() {}\n" +
    7.66 +                "        };\n" +
    7.67 +                "    }\n" +
    7.68 +                "    AInner aInner;\n" +
    7.69 +                "}\n",
    7.70 +                "class B {\n" +
    7.71 +                "    void test(A a) {;\n" +
    7.72 +                "        switch (a.aInner) {\n" +
    7.73 +                "            case A: break;\n" +
    7.74 +                "        }\n" +
    7.75 +                "    };\n" +
    7.76 +                "}");
    7.77 +        runTest("class A {\n" +
    7.78 +                "    enum AInner implements Runnable {\n" +
    7.79 +                "        A {\n" +
    7.80 +                "            public void run() {}\n" +
    7.81 +                "        };\n" +
    7.82 +                "    }\n" +
    7.83 +                "    AInner aInner;\n" +
    7.84 +                "}\n",
    7.85 +                "class B {\n" +
    7.86 +                "    void test(A a) {;\n" +
    7.87 +                "        System.err.println(a.aInner.toString());\n" +
    7.88 +                "    };\n" +
    7.89 +                "}");
    7.90 +        runTest("class A {\n" +
    7.91 +                "    enum AInner implements Runnable {\n" +
    7.92 +                "        A {\n" +
    7.93 +                "            public void run() {}\n" +
    7.94 +                "        };\n" +
    7.95 +                "    }\n" +
    7.96 +                "    AInner aInner() {\n" +
    7.97 +                "        return null;\n" +
    7.98 +                "    }\n" +
    7.99 +                "}\n",
   7.100 +                "class B {\n" +
   7.101 +                "    void test(A a) {;\n" +
   7.102 +                "        System.err.println(a.aInner().toString());\n" +
   7.103 +                "    };\n" +
   7.104 +                "}");
   7.105 +    }
   7.106 +
   7.107 +    JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
   7.108 +    int testN = 0;
   7.109 +
   7.110 +    void runTest(String aJava, String bJava) throws Exception {
   7.111 +        File testClasses = new File(System.getProperty("test.classes"));
   7.112 +        File target1 = new File(testClasses, "T8068517s" + testN++);
   7.113 +        doCompile(target1, aJava, bJava);
   7.114 +        File target2 = new File(testClasses, "T8068517s" + testN++);
   7.115 +        doCompile(target2, bJava, aJava);
   7.116 +
   7.117 +        Assert.check(Arrays.equals(Files.readAllBytes(new File(target1, "B.class").toPath()),
   7.118 +                                   Files.readAllBytes(new File(target2, "B.class").toPath())));
   7.119 +    }
   7.120 +
   7.121 +    void doCompile(File target, String... sources) throws Exception {
   7.122 +        target.mkdirs();
   7.123 +        List<String> options = Arrays.asList("-d", target.getAbsolutePath());
   7.124 +        List<ToolBox.JavaSource> files = Stream.of(sources)
   7.125 +                                               .map(ToolBox.JavaSource::new)
   7.126 +                                               .collect(Collectors.toList());
   7.127 +        compiler.getTask(null, null, null, options, null, files).call();
   7.128 +    }
   7.129 +}

mercurial