changeset 57837:ed104543b3f3 patterns-deconstruction

Automatic merge with records-and-sealed
author mcimadamore
date Fri, 20 Sep 2019 20:01:32 +0000
parents 00d9f8de0e3d fcff15c119f1
children eea3e1e0b99d
files src/jdk.compiler/share/classes/com/sun/tools/javac/comp/TypeEnter.java
diffstat 2 files changed, 126 insertions(+), 129 deletions(-) [+]
line wrap: on
line diff
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/TypeEnter.java	Thu Sep 19 15:47:00 2019 +0000
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/TypeEnter.java	Fri Sep 20 20:01:32 2019 +0000
@@ -754,7 +754,7 @@
     private final class HierarchyPhase extends AbstractHeaderPhase implements Completer {
 
         public HierarchyPhase() {
-            super(CompletionCause.HIERARCHY_PHASE, new HeaderPhase());
+            super(CompletionCause.HIERARCHY_PHASE, new PermitsPhase());
         }
 
         @Override
@@ -828,6 +828,130 @@
 
     }
 
+    private final class PermitsPhase extends AbstractHeaderPhase {
+
+        public PermitsPhase() {
+            super(CompletionCause.HIERARCHY_PHASE, new HeaderPhase());
+        }
+
+        @Override
+        protected void runPhase(Env<AttrContext> env) {
+            JCClassDecl tree = env.enclClass;
+            List<Type> closureInSameCompilationUnit = types.closure(tree.sym.type).stream()
+                    .filter(supertype ->
+                            TreeInfo.declarationFor(supertype.tsym, env.toplevel) != null &&
+                                    TreeInfo.declarationFor(tree.sym.outermostClass(), env.toplevel) != null)
+                    .collect(List.collector());
+            Set<Type> explicitlySealedSuperTypesInCU = closureInSameCompilationUnit.stream()
+                    .filter(type -> type != tree.sym.type && type.tsym.isSealed()).collect(Collectors.toSet());
+
+            boolean anySuperInSameCUIsSealed = !explicitlySealedSuperTypesInCU.isEmpty();
+            if (anySuperInSameCUIsSealed) {
+                java.util.List<Type> potentiallySealedSuperTypes = superTypesInASealedHierarchy(tree.sym, env, true);
+                if (!potentiallySealedSuperTypes.isEmpty()) {
+                    for (Type supertype : potentiallySealedSuperTypes) {
+                        if (!((ClassType)supertype).permitted.map(t -> t.tsym).contains(tree.sym.type.tsym)) {
+                            if (!((ClassType)supertype.tsym.type).isPermittedExplicit) {
+                                if (tree.sym.isAnonymous()) {
+                                    log.error(findTreeReferringSym(tree, supertype.tsym), Errors.CantInheritFromSealed(supertype.tsym));
+                                } else {
+                                    ((ClassType)supertype).permitted = ((ClassType)supertype).permitted.append(tree.sym.type);
+                                    ((ClassType)tree.sym.type).hasSealedSuperInSameCU = true;
+                                }
+                            } else if (!dontErrorIfSealedExtended) {
+                                log.error(findTreeReferringSym(tree, supertype.tsym), Errors.CantInheritFromSealed(supertype.tsym));
+                            }
+                        } else {
+                            ((ClassType)tree.sym.type).hasSealedSuperInSameCU = true;
+                        }
+                    }
+                }
+            }
+
+            boolean hasSuperTypesInSealedHierarchy = !superTypesInASealedHierarchy(tree.sym, env, false).isEmpty();
+            if ((tree.sym.flags_field & Flags.NON_SEALED) != 0 && !hasSuperTypesInSealedHierarchy) {
+                log.error(tree, Errors.NonSealedWithNoSealedSupertype);
+            }
+
+            if (hasSuperTypesInSealedHierarchy && !anySuperInSameCUIsSealed) {
+                // that supertype most have a permits clause allowing this class to extend it
+                List<Type> closureOutsideOfSameCU = types.closure(tree.sym.type).stream()
+                        .filter(supertype ->
+                                TreeInfo.declarationFor(supertype.tsym, env.toplevel) == null ||
+                                        TreeInfo.declarationFor(tree.sym.outermostClass(), env.toplevel) == null)
+                        .collect(List.collector());
+                Set<Type> explicitlySealedSuperTypesOutsideOfCU = closureOutsideOfSameCU.stream()
+                        .filter(type -> type != tree.sym.type && type.tsym.isSealed()).collect(Collectors.toSet());
+                for (Type supertype : explicitlySealedSuperTypesOutsideOfCU) {
+                    if (!((ClassType)supertype).permitted.map(t -> t.tsym).contains(tree.sym.type.tsym)) {
+                        log.error(tree, Errors.CantInheritFromSealed(supertype.tsym));
+                    }
+                }
+
+                if (!isNonSealed(tree.sym) && !isFinal(tree.sym) && !isSealed(tree.sym)) {
+                    log.error(tree, Errors.NonSealedSealedOrFinalExpected);
+                }
+            }
+        }
+
+        JCTree findTreeReferringSym(JCClassDecl tree, Symbol sym) {
+            if (tree.extending != null && tree.extending.type.tsym == sym) {
+                return tree.extending;
+            }
+            for (JCExpression implementing: tree.implementing) {
+                if (implementing.type.tsym == sym) {
+                    return implementing;
+                }
+            }
+            return tree;
+        }
+
+        boolean areInSameCU(Symbol sym1, Symbol sym2, Env<AttrContext> env) {
+            return TreeInfo.declarationFor(sym1, env.toplevel) != null &&
+                    TreeInfo.declarationFor(sym2.outermostClass(), env.toplevel) != null;
+        }
+
+        boolean isNonSealed(Symbol sym) { return sym != null && (sym.flags_field & NON_SEALED) != 0; }
+        boolean isFinal(Symbol sym) { return sym != null && (sym.flags_field & FINAL) != 0; }
+        boolean isSealed(Symbol sym) { return sym != null && (sym.flags_field & SEALED) != 0; }
+
+        java.util.List<Type> superTypesInASealedHierarchy(ClassSymbol csym, Env<AttrContext> env, boolean inSameCUOnly) {
+            if (csym == null) {
+                return null;
+            }
+
+            Type supertype = csym.type != null ?
+                    types.supertype(csym.type) : null;
+            java.util.List<Type> supertypes = new ArrayList<>();
+
+            if (supertype != null &&
+                    supertype.tsym != null &&
+                    supertype != syms.objectType &&
+                    !isNonSealed(supertype.tsym) &&
+                    (inSameCUOnly && areInSameCU(csym, supertype.tsym, env) || !inSameCUOnly)) {
+                supertypes.add(supertype);
+            }
+
+            if (csym.getInterfaces() != null) {
+                for (Type intf : csym.getInterfaces()) {
+                    if (intf != null && intf.tsym != null && !isNonSealed(intf.tsym) &&
+                            (inSameCUOnly && areInSameCU(csym, intf.tsym, env) || !inSameCUOnly)) {
+                        supertypes.add(intf);
+                    }
+                }
+            }
+
+            for (Type sup : new ArrayList<>(supertypes)) {
+                java.util.List<Type> supers = superTypesInASealedHierarchy((ClassSymbol)sup.tsym, env, inSameCUOnly);
+                if ((supers == null || supers.isEmpty()) && !sup.tsym.isSealed()) {
+                    supertypes.remove(sup);
+                }
+            }
+
+            return supertypes;
+        }
+    }
+
     private final class HeaderPhase extends AbstractHeaderPhase {
 
         public HeaderPhase() {
@@ -1040,134 +1164,6 @@
                 Assert.check(tree.sym.isCompleted());
                 tree.sym.setAnnotationTypeMetadata(new AnnotationTypeMetadata(tree.sym, annotate.annotationTypeSourceCompleter()));
             }
-
-            List<Type> closureInSameCompilationUnit = types.closure(tree.sym.type).stream()
-                    .filter(supertype ->
-                            TreeInfo.declarationFor(supertype.tsym, env.toplevel) != null &&
-                                    TreeInfo.declarationFor(tree.sym.outermostClass(), env.toplevel) != null)
-                    .collect(List.collector());
-            Set<Type> explicitlySealedSuperTypesInCU = closureInSameCompilationUnit.stream()
-                    .filter(type -> type != tree.sym.type && type.tsym.isSealed()).collect(Collectors.toSet());
-
-            boolean anySuperInSameCUIsSealed = !explicitlySealedSuperTypesInCU.isEmpty();
-            if (anySuperInSameCUIsSealed) {
-                java.util.List<JCExpression> potentiallySealedSuperTypes = superTypesInASealedHierarchy(tree, env, true);
-                if (!potentiallySealedSuperTypes.isEmpty()) {
-                    for (JCExpression supertypeExpr : potentiallySealedSuperTypes) {
-                        if (!((ClassType)supertypeExpr.type).permitted.map(t -> t.tsym).contains(tree.sym.type.tsym)) {
-                            if (!((ClassType)supertypeExpr.type.tsym.type).isPermittedExplicit) {
-                                if (tree.sym.isAnonymous()) {
-                                    log.error(supertypeExpr, Errors.CantInheritFromSealed(supertypeExpr.type.tsym));
-                                } else {
-                                    ((ClassType)supertypeExpr.type).permitted = ((ClassType)supertypeExpr.type).permitted.append(tree.sym.type);
-                                    ((ClassType)tree.sym.type).hasSealedSuperInSameCU = true;
-                                }
-                            } else if (!dontErrorIfSealedExtended) {
-                                log.error(supertypeExpr, Errors.CantInheritFromSealed(supertypeExpr.type.tsym));
-                            }
-                        } else {
-                            ((ClassType)tree.sym.type).hasSealedSuperInSameCU = true;
-                        }
-                    }
-                }
-            }
-
-            java.util.List<JCExpression> allSealedSuperTypes = superTypesInASealedHierarchy(tree, env, false);
-            boolean hasSuperTypesInSealedHierarchy = !allSealedSuperTypes.isEmpty();
-            if ((tree.sym.flags_field & Flags.NON_SEALED) != 0 && !hasSuperTypesInSealedHierarchy) {
-                log.error(tree, Errors.NonSealedWithNoSealedSupertype);
-            }
-
-            if (hasSuperTypesInSealedHierarchy && !anySuperInSameCUIsSealed) {
-                // that supertype most have a permits clause allowing this class to extend it
-                List<Type> closureOutsideOfSameCU = types.closure(tree.sym.type).stream()
-                        .filter(supertype ->
-                                TreeInfo.declarationFor(supertype.tsym, env.toplevel) == null ||
-                                        TreeInfo.declarationFor(tree.sym.outermostClass(), env.toplevel) == null)
-                        .collect(List.collector());
-                Set<Type> explicitlySealedSuperTypesOutsideOfCU = closureOutsideOfSameCU.stream()
-                        .filter(type -> type != tree.sym.type && type.tsym.isSealed()).collect(Collectors.toSet());
-                for (Type supertype : explicitlySealedSuperTypesOutsideOfCU) {
-                    if (!((ClassType)supertype).permitted.map(t -> t.tsym).contains(tree.sym.type.tsym)) {
-                        log.error(tree, Errors.CantInheritFromSealed(supertype.tsym));
-                    }
-                }
-
-                if (!isNonSealed(tree.sym) && !isFinal(tree.sym) && !isSealed(tree.sym)) {
-                    log.error(tree, Errors.NonSealedSealedOrFinalExpected);
-                }
-            }
-        }
-
-        boolean areInSameCU(Symbol sym1, Symbol sym2, Env<AttrContext> env) {
-            return TreeInfo.declarationFor(sym1, env.toplevel) != null &&
-                    TreeInfo.declarationFor(sym2.outermostClass(), env.toplevel) != null;
-        }
-
-        boolean isNonSealed(Symbol sym) { return sym != null && (sym.flags_field & NON_SEALED) != 0; }
-        boolean isFinal(Symbol sym) { return sym != null && (sym.flags_field & FINAL) != 0; }
-        boolean isSealed(Symbol sym) { return sym != null && (sym.flags_field & SEALED) != 0; }
-
-        java.util.List<JCExpression> superTypesInASealedHierarchy(JCClassDecl tree, Env<AttrContext> env, boolean inSameCUOnly) {
-            Type supertype = types.supertype(tree.sym.type);
-            java.util.List<JCExpression> supertypes = new ArrayList<>();
-            if (supertype != null &&
-                    supertype.tsym != null &&
-                    tree.extending != null &&
-                    tree.extending.type != null &&
-                    tree.extending.type.tsym != null &&
-                    supertype != syms.objectType &&
-                    !isNonSealed(supertype.tsym) &&
-                    (inSameCUOnly && areInSameCU(tree.sym, supertype.tsym, env) || !inSameCUOnly)) {
-                supertypes.add(tree.extending);
-            }
-            if (tree.implementing != null) {
-                for (JCExpression intf : tree.implementing) {
-                    if (intf != null && intf.type != null &&
-                            intf.type.tsym != null && !isNonSealed(intf.type.tsym) &&
-                            (inSameCUOnly && areInSameCU(tree.sym, intf.type.tsym, env) || !inSameCUOnly)) {
-                        supertypes.add(intf);
-                    }
-                }
-            }
-            for (JCExpression sup : new ArrayList<>(supertypes)) {
-                java.util.List<Type> supers = superTypesInASealedHierarchyHelper((ClassSymbol)sup.type.tsym, env, inSameCUOnly);
-                if (supers == null || supers.isEmpty() && !sup.type.tsym.isSealed()) {
-                    supertypes.remove(sup);
-                }
-            }
-            return supertypes;
-        }
-
-        java.util.List<Type> superTypesInASealedHierarchyHelper(ClassSymbol csym, Env<AttrContext> env, boolean inSameCUOnly) {
-            if (csym == null) {
-                return null;
-            }
-            Type supertype = csym != null && csym.type != null ?
-                    types.supertype(csym.type) : null;
-            java.util.List<Type> supertypesInSameCU = new ArrayList<>();
-            if (supertype != null &&
-                    supertype.tsym != null &&
-                    supertype != syms.objectType &&
-                    !isNonSealed(supertype.tsym) &&
-                    (inSameCUOnly && areInSameCU(csym, supertype.tsym, env) || !inSameCUOnly)) {
-                supertypesInSameCU.add(supertype);
-            }
-            if (csym.getInterfaces() != null) {
-                for (Type intf : csym.getInterfaces()) {
-                    if (intf != null && intf.tsym != null && !isNonSealed(intf.tsym) &&
-                            (inSameCUOnly && areInSameCU(csym, intf.tsym, env) || !inSameCUOnly)) {
-                        supertypesInSameCU.add(intf);
-                    }
-                }
-            }
-            for (Type sup : new ArrayList<>(supertypesInSameCU)) {
-                java.util.List<Type> supers = superTypesInASealedHierarchyHelper((ClassSymbol)sup.tsym, env, inSameCUOnly);
-                if ((supers == null || supers.isEmpty()) && !sup.tsym.isSealed()) {
-                    supertypesInSameCU.remove(sup);
-                }
-            }
-            return supertypesInSameCU;
         }
 
         /** Add the accessors for fields to the symbol table.
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/util/Dependencies.java	Thu Sep 19 15:47:00 2019 +0000
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/util/Dependencies.java	Fri Sep 20 20:01:32 2019 +0000
@@ -93,6 +93,7 @@
         MEMBER_ENTER,
         RECORD_PHASE,
         MEMBERS_PHASE,
+        PERMITS_PHASE,
         OTHER;
     }