< prev index next >

src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java

Print this page
@@ -1,7 +1,7 @@
  /*
-  * Copyright (c) 2003, 2023, Oracle and/or its affiliates. All rights reserved.
+  * Copyright (c) 2003, 2024, Oracle and/or its affiliates. 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.  Oracle designates this

@@ -196,19 +196,73 @@
          UPWARDS() {
              @Override
              ProjectionKind complement() {
                  return DOWNWARDS;
              }
+ 
+             @Override
+             boolean allowIntersectionTypes() {
+                 return true;
+             }
+ 
+             @Override
+             ProjectionKind withIntersectionTypes(boolean allowIntersectionTypes) {
+                 return allowIntersectionTypes ? this : UPWARDS_NO_INTERSECTION;
+             }
          },
          DOWNWARDS() {
              @Override
              ProjectionKind complement() {
                  return UPWARDS;
              }
+ 
+             @Override
+             boolean allowIntersectionTypes() {
+                 return true;
+             }
+ 
+             @Override
+             ProjectionKind withIntersectionTypes(boolean allowIntersectionTypes) {
+                 return allowIntersectionTypes ? this : DOWNWARDS_NO_INTERSECTION;
+             }
+         },
+         UPWARDS_NO_INTERSECTION() {
+             @Override
+             ProjectionKind complement() {
+                 return DOWNWARDS_NO_INTERSECTION;
+             }
+ 
+             @Override
+             boolean allowIntersectionTypes() {
+                 return false;
+             }
+ 
+             @Override
+             ProjectionKind withIntersectionTypes(boolean allowIntersectionTypes) {
+                 return allowIntersectionTypes ? UPWARDS : this;
+             }
+         },
+         DOWNWARDS_NO_INTERSECTION() {
+             @Override
+             ProjectionKind complement() {
+                 return UPWARDS_NO_INTERSECTION;
+             }
+ 
+             @Override
+             boolean allowIntersectionTypes() {
+                 return false;
+             }
+ 
+             @Override
+             ProjectionKind withIntersectionTypes(boolean allowIntersectionTypes) {
+                 return allowIntersectionTypes ? DOWNWARDS : this;
+             }
          };
  
          abstract ProjectionKind complement();
+         abstract boolean allowIntersectionTypes();
+         abstract ProjectionKind withIntersectionTypes(boolean allowIntersectionTypes);
      }
  
      /**
       * This visitor performs upwards and downwards projections on types.
       *

@@ -243,15 +297,22 @@
              this.vars = vars;
          }
  
          @Override
          public Type visitClassType(ClassType t, ProjectionKind pkind) {
-             if (t.isCompound()) {
-                 List<Type> components = directSupertypes(t);
-                 List<Type> components1 = components.map(c -> c.map(this, pkind));
-                 if (components == components1) return t;
-                 else return makeIntersectionType(components1);
+             if (t.isUnion() || t.isIntersection()) {
+                 if (pkind.allowIntersectionTypes()) {
+                     List<Type> components = directSupertypes(t);
+                     List<Type> components1 = components.map(c -> c.map(this, pkind));
+                     if (components == components1) return t;
+                     else return makeIntersectionType(components1);
+                 } else if (t.isIntersection()) {
+                     return visit(((IntersectionClassType)t).getExplicitComponents().head, pkind);
+                 } else {
+                     Assert.check(t.isUnion());
+                     return visit(((UnionClassType)t).getLub(), pkind);
+                 }
              } else {
                  Type outer = t.getEnclosingType();
                  Type outer1 = visit(outer, pkind);
                  List<Type> typarams = t.getTypeArguments();
                  List<Type> formals = t.tsym.type.getTypeArguments();

@@ -302,13 +363,15 @@
                  if (seen.add(t)) {
                      try {
                          final Type bound;
                          switch (pkind) {
                              case UPWARDS:
+                             case UPWARDS_NO_INTERSECTION:
                                  bound = t.getUpperBound();
                                  break;
                              case DOWNWARDS:
+                             case DOWNWARDS_NO_INTERSECTION:
                                  bound = (t.getLowerBound() == null) ?
                                          syms.botType :
                                          t.getLowerBound();
                                  break;
                              default:

@@ -319,20 +382,20 @@
                      } finally {
                          seen.remove(t);
                      }
                  } else {
                      //cycle
-                     return pkind == ProjectionKind.UPWARDS ?
+                     return (pkind == ProjectionKind.UPWARDS || pkind == ProjectionKind.UPWARDS_NO_INTERSECTION) ?
                              syms.objectType : syms.botType;
                  }
              } else {
                  return t;
              }
          }
  
          private Type mapTypeArgument(Type site, Type declaredBound, Type t, ProjectionKind pkind) {
-             return t.containsAny(vars) ?
+             return (t.containsAny(vars) || (!pkind.allowIntersectionTypes() && !chk.checkDenotable(t))) ?
                      t.map(new TypeArgumentProjection(site, declaredBound), pkind) :
                      t;
          }
  
          class TypeArgumentProjection extends TypeMapping<ProjectionKind> {

@@ -346,25 +409,25 @@
              }
  
              @Override
              public Type visitType(Type t, ProjectionKind pkind) {
                  //type argument is some type containing restricted vars
-                 if (pkind == ProjectionKind.DOWNWARDS) {
+                 if (pkind == ProjectionKind.DOWNWARDS || pkind == ProjectionKind.DOWNWARDS_NO_INTERSECTION) {
                      //not defined
                      return syms.botType;
                  }
-                 Type upper = t.map(TypeProjection.this, ProjectionKind.UPWARDS);
+                 Type upper = t.map(TypeProjection.this, ProjectionKind.UPWARDS.withIntersectionTypes(pkind.allowIntersectionTypes()));
                  Type lower = t.map(TypeProjection.this, ProjectionKind.DOWNWARDS);
                  List<Type> formals = site.tsym.type.getTypeArguments();
                  BoundKind bk;
                  Type bound;
                  if (!isSameType(upper, syms.objectType) &&
                          (declaredBound.containsAny(formals) ||
                           !isSubtype(declaredBound, upper))) {
                      bound = upper;
                      bk = EXTENDS;
-                 } else if (!lower.hasTag(BOT)) {
+                 } else if (!lower.hasTag(BOT) && (!lower.isIntersection() || pkind.allowIntersectionTypes())) {
                      bound = lower;
                      bk = SUPER;
                  } else {
                      bound = syms.objectType;
                      bk = UNBOUND;

@@ -383,12 +446,12 @@
                          if (bound.hasTag(BOT)) {
                              return syms.botType;
                          }
                          break;
                      case SUPER:
-                         bound = wt.type.map(TypeProjection.this, pkind.complement());
-                         if (bound.hasTag(BOT)) {
+                         bound = wt.type.map(TypeProjection.this, pkind.withIntersectionTypes(true).complement());
+                         if (bound.hasTag(BOT) || (bound.isIntersection() && !pkind.allowIntersectionTypes())) {
                              bound = syms.objectType;
                              bk = UNBOUND;
                          }
                          break;
                  }

@@ -412,11 +475,24 @@
       * @param t the type to be projected
       * @param vars the set of type variables to be mapped
       * @return the type obtained as result of the projection
       */
      public Type upward(Type t, List<Type> vars) {
-         return t.map(new TypeProjection(vars), ProjectionKind.UPWARDS);
+         return upward(t, true, vars);
+     }
+ 
+     /**
+      * Computes an upward projection of given type, and vars. See {@link TypeProjection}.
+      *
+      * @param t the type to be projected
+      * @param allowIntersection whether intersection types should be allowed in the projection
+      * @param vars the set of type variables to be mapped
+      * @return the type obtained as result of the projection
+      */
+     public Type upward(Type t, boolean allowIntersection, List<Type> vars) {
+         return t.map(new TypeProjection(vars),
+                 allowIntersection ? ProjectionKind.UPWARDS : ProjectionKind.UPWARDS_NO_INTERSECTION);
      }
  
      /**
       * Computes the set of captured variables mentioned in a given type. See {@link CaptureScanner}.
       * This routine is typically used to computed the input set of variables to be used during

@@ -5320,6 +5396,12 @@
          isDerivedRawCache.clear();
          implCache._map.clear();
          membersCache._map.clear();
          closureCache.clear();
      }
+ 
+     // code reflection
+ 
+     public boolean isQuoted(Type type) {
+         return type.tsym == syms.quotedType.tsym;
+     }
  }
< prev index next >