< prev index next >

src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Check.java

Print this page
@@ -167,10 +167,11 @@
          deferredLintHandler = DeferredLintHandler.instance(context);
  
          allowModules = Feature.MODULES.allowedInSource(source);
          allowRecords = Feature.RECORDS.allowedInSource(source);
          allowSealed = Feature.SEALED_CLASSES.allowedInSource(source);
+         allowPrimitiveClasses = Feature.PRIMITIVE_CLASSES.allowedInSource(source) && options.isSet("enablePrimitiveClasses");
      }
  
      /** Character for synthetic names
       */
      char syntheticNameChar;

@@ -210,10 +211,14 @@
  
      /** Are sealed classes allowed
       */
      private final boolean allowSealed;
  
+     /** Are primitive classes allowed
+      */
+     private final boolean allowPrimitiveClasses;
+ 
  /* *************************************************************************
   * Errors and Warnings
   **************************************************************************/
  
      Lint setLint(Lint newLint) {

@@ -612,10 +617,15 @@
      Type checkType(final DiagnosticPosition pos, final Type found, final Type req, final CheckContext checkContext) {
          final InferenceContext inferenceContext = checkContext.inferenceContext();
          if (inferenceContext.free(req) || inferenceContext.free(found)) {
              inferenceContext.addFreeTypeListener(List.of(req, found),
                      solvedContext -> checkType(pos, solvedContext.asInstType(found), solvedContext.asInstType(req), checkContext));
+         } else {
+             if (allowPrimitiveClasses && found.hasTag(CLASS)) {
+                 if (inferenceContext != infer.emptyContext)
+                     checkParameterizationByPrimitiveClass(pos, found);
+             }
          }
          if (req.hasTag(ERROR))
              return req;
          if (req.hasTag(NONE))
              return found;

@@ -742,27 +752,87 @@
              return (t.hasTag(TYPEVAR))
                                      ? diags.fragment(Fragments.TypeParameter(t))
                                      : t;
          }
  
+     void checkConstraintsOfValueClass(DiagnosticPosition pos, ClassSymbol c) {
+         for (Type st : types.closure(c.type)) {
+             if (st == null || st.tsym == null || st.tsym.kind == ERR)
+                 continue;
+             if  (st.tsym == syms.objectType.tsym || st.tsym == syms.recordType.tsym || st.isInterface())
+                 continue;
+             if (!st.tsym.isAbstract()) {
+                 if (c != st.tsym) {
+                     log.error(pos, Errors.ConcreteSupertypeForValueClass(c, st));
+                 }
+                 continue;
+             }
+             // dealing with an abstract value or value super class below.
+             Fragment fragment = c.isAbstract() && c.isValueClass() && c == st.tsym ? Fragments.AbstractValueClass(c) : Fragments.SuperclassOfValueClass(c, st);
+             if ((st.tsym.flags() & HASINITBLOCK) != 0) {
+                 log.error(pos, Errors.AbstractValueClassDeclaresInitBlock(fragment));
+             }
+             Type encl = st.getEnclosingType();
+             if (encl != null && encl.hasTag(CLASS)) {
+                 log.error(pos, Errors.AbstractValueClassCannotBeInner(fragment));
+             }
+             for (Symbol s : st.tsym.members().getSymbols(NON_RECURSIVE)) {
+                 switch (s.kind) {
+                 case VAR:
+                     if ((s.flags() & STATIC) == 0) {
+                         log.error(pos, Errors.InstanceFieldNotAllowed(s, fragment));
+                     }
+                     break;
+                 case MTH:
+                     if ((s.flags() & (SYNCHRONIZED | STATIC)) == SYNCHRONIZED) {
+                         log.error(pos, Errors.SuperClassMethodCannotBeSynchronized(s, c, st));
+                     } else if (s.isInitOrVNew()) {
+                         MethodSymbol m = (MethodSymbol)s;
+                         if (m.getParameters().size() > 0) {
+                             log.error(pos, Errors.AbstractValueClassConstructorCannotTakeArguments(m, fragment));
+                         } else if (m.getTypeParameters().size() > 0) {
+                             log.error(pos, Errors.AbstractValueClassConstructorCannotBeGeneric(m, fragment));
+                         } else if (m.type.getThrownTypes().size() > 0) {
+                             log.error(pos, Errors.AbstractValueClassConstructorCannotThrow(m, fragment));
+                         } else if (protection(m.flags()) > protection(m.owner.flags())) {
+                             log.error(pos, Errors.AbstractValueClassConstructorHasWeakerAccess(m, fragment));
+                         } else if ((m.flags() & EMPTYNOARGCONSTR) == 0) {
+                                 log.error(pos, Errors.AbstractValueClassNoArgConstructorMustBeEmpty(m, fragment));
+                         }
+                     }
+                     break;
+                 }
+             }
+         }
+     }
+ 
      /** Check that type is a valid qualifier for a constructor reference expression
       */
-     Type checkConstructorRefType(DiagnosticPosition pos, Type t) {
-         t = checkClassOrArrayType(pos, t);
+     Type checkConstructorRefType(JCExpression expr, Type t) {
+         t = checkClassOrArrayType(expr, t);
          if (t.hasTag(CLASS)) {
              if ((t.tsym.flags() & (ABSTRACT | INTERFACE)) != 0) {
-                 log.error(pos, Errors.AbstractCantBeInstantiated(t.tsym));
+                 log.error(expr, Errors.AbstractCantBeInstantiated(t.tsym));
                  t = types.createErrorType(t);
              } else if ((t.tsym.flags() & ENUM) != 0) {
-                 log.error(pos, Errors.EnumCantBeInstantiated);
+                 log.error(expr, Errors.EnumCantBeInstantiated);
                  t = types.createErrorType(t);
              } else {
-                 t = checkClassType(pos, t, true);
+                 // Projection types may not be mentioned in constructor references
+                 if (expr.hasTag(SELECT)) {
+                     JCFieldAccess fieldAccess = (JCFieldAccess) expr;
+                     if (allowPrimitiveClasses && fieldAccess.selected.type.isPrimitiveClass() &&
+                             (fieldAccess.name == names.ref || fieldAccess.name == names.val)) {
+                         log.error(expr, Errors.ProjectionCantBeInstantiated);
+                         t = types.createErrorType(t);
+                     }
+                 }
+                 t = checkClassType(expr, t, true);
              }
          } else if (t.hasTag(ARRAY)) {
              if (!types.isReifiable(((ArrayType)t).elemtype)) {
-                 log.error(pos, Errors.GenericArrayCreation);
+                 log.error(expr, Errors.GenericArrayCreation);
                  t = types.createErrorType(t);
              }
          }
          return t;
      }

@@ -789,29 +859,61 @@
  
      /** Check that type is a reference type, i.e. a class, interface or array type
       *  or a type variable.
       *  @param pos           Position to be used for error reporting.
       *  @param t             The type to be checked.
+      *  @param primitiveClassOK       If false, a primitive class does not qualify
       */
-     Type checkRefType(DiagnosticPosition pos, Type t) {
-         if (t.isReference())
+     Type checkRefType(DiagnosticPosition pos, Type t, boolean primitiveClassOK) {
+         if (t.isReference() && (!allowPrimitiveClasses || primitiveClassOK || !t.isPrimitiveClass()))
              return t;
          else
              return typeTagError(pos,
                                  diags.fragment(Fragments.TypeReqRef),
                                  t);
      }
  
+     /** Check that type is an identity type, i.e. not a primitive/value type
+      *  nor its reference projection. When not discernible statically,
+      *  give it the benefit of doubt and defer to runtime.
+      *
+      *  @param pos           Position to be used for error reporting.
+      *  @param t             The type to be checked.
+      */
+     void checkIdentityType(DiagnosticPosition pos, Type t) {
+         if (t.hasTag(TYPEVAR)) {
+             t = types.skipTypeVars(t, false);
+         }
+         if (t.isIntersection()) {
+             IntersectionClassType ict = (IntersectionClassType)t;
+             for (Type component : ict.getExplicitComponents()) {
+                 checkIdentityType(pos, component);
+             }
+             return;
+         }
+         if (t.isPrimitive() || t.isValueClass() || t.isValueInterface() || t.isReferenceProjection())
+             typeTagError(pos, diags.fragment(Fragments.TypeReqIdentity), t);
+     }
+ 
+     /** Check that type is a reference type, i.e. a class, interface or array type
+      *  or a type variable.
+      *  @param pos           Position to be used for error reporting.
+      *  @param t             The type to be checked.
+      */
+     Type checkRefType(DiagnosticPosition pos, Type t) {
+         return checkRefType(pos, t, true);
+     }
+ 
      /** Check that each type is a reference type, i.e. a class, interface or array type
       *  or a type variable.
       *  @param trees         Original trees, used for error reporting.
       *  @param types         The types to be checked.
       */
      List<Type> checkRefTypes(List<JCExpression> trees, List<Type> types) {
          List<JCExpression> tl = trees;
          for (List<Type> l = types; l.nonEmpty(); l = l.tail) {
-             l.head = checkRefType(tl.head.pos(), l.head);
+             l.head = checkRefType(tl.head.pos(), l.head, false);
              tl = tl.tail;
          }
          return types;
      }
  

@@ -843,10 +945,59 @@
              return false;
          } else
              return true;
      }
  
+     void checkParameterizationByPrimitiveClass(DiagnosticPosition pos, Type t) {
+         parameterizationByPrimitiveClassChecker.visit(t, pos);
+     }
+ 
+     /** parameterizationByPrimitiveClassChecker: A type visitor that descends down the given type looking for instances of primitive classes
+      *  being used as type arguments and issues error against those usages.
+      */
+     private final Types.SimpleVisitor<Void, DiagnosticPosition> parameterizationByPrimitiveClassChecker =
+             new Types.SimpleVisitor<Void, DiagnosticPosition>() {
+ 
+         @Override
+         public Void visitType(Type t, DiagnosticPosition pos) {
+             return null;
+         }
+ 
+         @Override
+         public Void visitClassType(ClassType t, DiagnosticPosition pos) {
+             for (Type targ : t.allparams()) {
+                 if (allowPrimitiveClasses && targ.isPrimitiveClass()) {
+                     log.error(pos, Errors.GenericParameterizationWithPrimitiveClass(t));
+                 }
+                 visit(targ, pos);
+             }
+             return null;
+         }
+ 
+         @Override
+         public Void visitTypeVar(TypeVar t, DiagnosticPosition pos) {
+              return null;
+         }
+ 
+         @Override
+         public Void visitCapturedType(CapturedType t, DiagnosticPosition pos) {
+             return null;
+         }
+ 
+         @Override
+         public Void visitArrayType(ArrayType t, DiagnosticPosition pos) {
+             return visit(t.elemtype, pos);
+         }
+ 
+         @Override
+         public Void visitWildcardType(WildcardType t, DiagnosticPosition pos) {
+             return visit(t.type, pos);
+         }
+     };
+ 
+ 
+ 
      /** Check that usage of diamond operator is correct (i.e. diamond should not
       * be used with non-generic classes or in anonymous class creation expressions)
       */
      Type checkDiamond(JCNewClass tree, Type t) {
          if (!TreeInfo.isDiamond(tree) ||

@@ -975,11 +1126,11 @@
          }
      }
      //where
          private boolean isTrustMeAllowedOnMethod(Symbol s) {
              return (s.flags() & VARARGS) != 0 &&
-                 (s.isConstructor() ||
+                 (s.isInitOrVNew() ||
                      (s.flags() & (STATIC | FINAL |
                                    (Feature.PRIVATE_SAFE_VARARGS.allowedInSource(source) ? PRIVATE : 0) )) != 0);
          }
  
      Type checkLocalVarType(DiagnosticPosition pos, Type t, Name name) {

@@ -991,11 +1142,15 @@
              log.error(pos, Errors.CantInferLocalVarType(name, Fragments.LocalCantInferVoid));
              return types.createErrorType(t);
          }
  
          //upward project the initializer type
-         return types.upward(t, types.captures(t)).baseType();
+         Type varType = types.upward(t, types.captures(t)).baseType();
+         if (allowPrimitiveClasses && varType.hasTag(CLASS)) {
+             checkParameterizationByPrimitiveClass(pos, varType);
+         }
+         return varType;
      }
  
      Type checkMethod(final Type mtype,
              final Symbol sym,
              final Env<AttrContext> env,

@@ -1014,10 +1169,11 @@
          Type owntype = mtype;
          List<Type> formals = owntype.getParameterTypes();
          List<Type> nonInferred = sym.type.getParameterTypes();
          if (nonInferred.length() != formals.length()) nonInferred = formals;
          Type last = useVarargs ? formals.last() : null;
+         // TODO - is enum so <init>
          if (sym.name == names.init && sym.owner == syms.enumSym) {
              formals = formals.tail.tail;
              nonInferred = nonInferred.tail.tail;
          }
          if ((sym.flags() & ANONCONSTR_BASED) != 0) {

@@ -1189,15 +1345,19 @@
                  mask = ReceiverParamFlags;
              else if (sym.owner.kind != TYP)
                  mask = LocalVarFlags;
              else if ((sym.owner.flags_field & INTERFACE) != 0)
                  mask = implicit = InterfaceVarFlags;
-             else
+             else {
                  mask = VarFlags;
+                 if (sym.owner.type.isValueClass() && (flags & STATIC) == 0) {
+                     implicit |= FINAL;
+                 }
+             }
              break;
          case MTH:
-             if (sym.name == names.init) {
+             if (names.isInitOrVNew(sym.name)) {
                  if ((sym.owner.flags_field & ENUM) != 0) {
                      // enum constructors cannot be declared public or
                      // protected and must be implicitly or explicitly
                      // private
                      implicit = PRIVATE;

@@ -1216,13 +1376,16 @@
                      }
                  } else {
                      mask = implicit = InterfaceMethodFlags;
                  }
              } else if ((sym.owner.flags_field & RECORD) != 0) {
-                 mask = RecordMethodFlags;
+                 mask = ((sym.owner.flags_field & VALUE_CLASS) != 0 && (flags & Flags.STATIC) == 0) ?
+                         RecordMethodFlags & ~SYNCHRONIZED : RecordMethodFlags;
              } else {
-                 mask = MethodFlags;
+                 // value objects do not have an associated monitor/lock
+                 mask = ((sym.owner.flags_field & VALUE_CLASS) != 0 && (flags & Flags.STATIC) == 0) ?
+                         MethodFlags & ~SYNCHRONIZED : MethodFlags;
              }
              if ((flags & STRICTFP) != 0) {
                  warnOnExplicitStrictfp(pos);
              }
              // Imply STRICTFP if owner has STRICTFP set.

@@ -1235,11 +1398,11 @@
                      (sym.isDirectlyOrIndirectlyLocal() && (flags & ANNOTATION) != 0)) {
                  boolean implicitlyStatic = !sym.isAnonymous() &&
                          ((flags & RECORD) != 0 || (flags & ENUM) != 0 || (flags & INTERFACE) != 0);
                  boolean staticOrImplicitlyStatic = (flags & STATIC) != 0 || implicitlyStatic;
                  // local statics are allowed only if records are allowed too
-                 mask = staticOrImplicitlyStatic && allowRecords && (flags & ANNOTATION) == 0 ? StaticLocalFlags : LocalClassFlags;
+                 mask = staticOrImplicitlyStatic && allowRecords && (flags & ANNOTATION) == 0 ? ExtendedStaticLocalClassFlags : ExtendedLocalClassFlags;
                  implicit = implicitlyStatic ? STATIC : implicit;
              } else if (sym.owner.kind == TYP) {
                  // statics in inner classes are allowed only if records are allowed too
                  mask = ((flags & STATIC) != 0) && allowRecords && (flags & ANNOTATION) == 0 ? ExtendedMemberStaticClassFlags : ExtendedMemberClassFlags;
                  if (sym.owner.owner.kind == PCK ||

@@ -1255,12 +1418,12 @@
              }
              // Interfaces are always ABSTRACT
              if ((flags & INTERFACE) != 0) implicit |= ABSTRACT;
  
              if ((flags & ENUM) != 0) {
-                 // enums can't be declared abstract, final, sealed or non-sealed
-                 mask &= ~(ABSTRACT | FINAL | SEALED | NON_SEALED);
+                 // enums can't be declared abstract, final, sealed or non-sealed or primitive/value
+                 mask &= ~(ABSTRACT | FINAL | SEALED | NON_SEALED | PRIMITIVE_CLASS | VALUE_CLASS);
                  implicit |= implicitEnumFinalFlag(tree);
              }
              if ((flags & RECORD) != 0) {
                  // records can't be declared abstract
                  mask &= ~ABSTRACT;

@@ -1269,10 +1432,27 @@
              if ((flags & STRICTFP) != 0) {
                  warnOnExplicitStrictfp(pos);
              }
              // Imply STRICTFP if owner has STRICTFP set.
              implicit |= sym.owner.flags_field & STRICTFP;
+ 
+             // primitive classes are implicitly final value classes.
+             if ((flags & PRIMITIVE_CLASS) != 0)
+                 implicit |= VALUE_CLASS | FINAL;
+ 
+             // concrete value classes are implicitly final
+             if ((flags & (ABSTRACT | INTERFACE | VALUE_CLASS)) == VALUE_CLASS) {
+                 implicit |= FINAL;
+                 if ((flags & NON_SEALED) != 0) {
+                     // cant declare a final value class non-sealed
+                     log.error(pos,
+                             Errors.ModNotAllowedHere(asFlagSet(NON_SEALED)));
+                 }
+             }
+ 
+             // TYPs can't be declared synchronized
+             mask &= ~SYNCHRONIZED;
              break;
          default:
              throw new AssertionError();
          }
          long illegal = flags & ExtendedStandardFlags & ~mask;

@@ -1297,21 +1477,25 @@
                                  STATIC | PRIVATE,
                                  DEFAULT)
                   &&
                   checkDisjoint(pos, flags,
                                 ABSTRACT | INTERFACE,
-                                FINAL | NATIVE | SYNCHRONIZED)
+                                FINAL | NATIVE | SYNCHRONIZED | PRIMITIVE_CLASS)
+                  &&
+                  checkDisjoint(pos, flags,
+                         IDENTITY_TYPE,
+                         PRIMITIVE_CLASS | VALUE_CLASS)
                   &&
                   checkDisjoint(pos, flags,
                                 PUBLIC,
                                 PRIVATE | PROTECTED)
                   &&
                   checkDisjoint(pos, flags,
                                 PRIVATE,
                                 PUBLIC | PROTECTED)
                   &&
-                  checkDisjoint(pos, flags,
+                  checkDisjoint(pos, (flags | implicit), // complain against volatile & implcitly final entities too.
                                 FINAL,
                                 VOLATILE)
                   &&
                   (sym.kind == TYP ||
                    checkDisjoint(pos, flags,

@@ -1323,11 +1507,17 @@
                   && checkDisjoint(pos, flags,
                                  SEALED,
                             FINAL | NON_SEALED)
                   && checkDisjoint(pos, flags,
                                  SEALED,
-                                 ANNOTATION)) {
+                                 ANNOTATION)
+                  && checkDisjoint(pos, flags,
+                                 IDENTITY_TYPE,
+                                 ANNOTATION)
+                 && checkDisjoint(pos, flags,
+                                 VALUE_CLASS,
+                                 ANNOTATION) ) {
              // skip
          }
          return flags & (mask | ~ExtendedStandardFlags) | implicit;
      }
  

@@ -1496,14 +1686,17 @@
              }
          }
  
          public void visitSelectInternal(JCFieldAccess tree) {
              if (tree.type.tsym.isStatic() &&
-                 tree.selected.type.isParameterized()) {
+                 tree.selected.type.isParameterized() &&
+                     (tree.name != names.ref || !tree.type.isReferenceProjection())) {
                  // The enclosing type is not a class, so we are
                  // looking at a static member type.  However, the
                  // qualifying expression is parameterized.
+                 // Tolerate the pseudo-select V.ref: V<T>.ref will be static if V<T> is and
+                 // should not be confused as selecting a static member of a parameterized type.
                  log.error(tree.pos(), Errors.CantSelectStaticClassFromParamType);
              } else {
                  // otherwise validate the rest of the expression
                  tree.selected.accept(this);
              }

@@ -1563,11 +1756,11 @@
          }
      }
      //where
          private boolean withinAnonConstr(Env<AttrContext> env) {
              return env.enclClass.name.isEmpty() &&
-                     env.enclMethod != null && env.enclMethod.name == names.init;
+                     env.enclMethod != null && names.isInitOrVNew(env.enclMethod.name);
          }
  
  /* *************************************************************************
   * Exception checking
   **************************************************************************/

@@ -2164,11 +2357,11 @@
          final boolean explicitOverride = m.attribute(syms.overrideType.tsym) != null;
          // Check if this method must override a super method due to being annotated with @Override
          // or by virtue of being a member of a diamond inferred anonymous class. Latter case is to
          // be treated "as if as they were annotated" with @Override.
          boolean mustOverride = explicitOverride ||
-                 (env.info.isAnonymousDiamond && !m.isConstructor() && !m.isPrivate());
+                 (env.info.isAnonymousDiamond && !m.isInitOrVNew() && !m.isPrivate());
          if (mustOverride && !isOverrider(m)) {
              DiagnosticPosition pos = tree.pos();
              for (JCAnnotation a : tree.getModifiers().annotations) {
                  if (a.annotationType.type.tsym == syms.overrideType.tsym) {
                      pos = a.pos();

@@ -2290,10 +2483,49 @@
              log.error(pos,
                        Errors.DoesNotOverrideAbstract(c, undef1, undef1.location()));
          }
      }
  
+     // A primitive class cannot contain a field of its own type either or indirectly.
+     void checkNonCyclicMembership(JCClassDecl tree) {
+         if (allowPrimitiveClasses) {
+             Assert.check((tree.sym.flags_field & LOCKED) == 0);
+             try {
+                 tree.sym.flags_field |= LOCKED;
+                 for (List<? extends JCTree> l = tree.defs; l.nonEmpty(); l = l.tail) {
+                     if (l.head.hasTag(VARDEF)) {
+                         JCVariableDecl field = (JCVariableDecl) l.head;
+                         if (cyclePossible(field.sym)) {
+                             checkNonCyclicMembership((ClassSymbol) field.type.tsym, field.pos());
+                         }
+                     }
+                 }
+             } finally {
+                 tree.sym.flags_field &= ~LOCKED;
+             }
+         }
+     }
+     // where
+     private void checkNonCyclicMembership(ClassSymbol c, DiagnosticPosition pos) {
+         if ((c.flags_field & LOCKED) != 0) {
+             log.error(pos, Errors.CyclicPrimitiveClassMembership(c));
+             return;
+         }
+         try {
+             c.flags_field |= LOCKED;
+             for (Symbol fld : c.members().getSymbols(s -> s.kind == VAR && cyclePossible((VarSymbol) s), NON_RECURSIVE)) {
+                 checkNonCyclicMembership((ClassSymbol) fld.type.tsym, pos);
+             }
+         } finally {
+             c.flags_field &= ~LOCKED;
+         }
+     }
+         // where
+         private boolean cyclePossible(VarSymbol symbol) {
+             return (symbol.flags() & STATIC) == 0 && allowPrimitiveClasses && symbol.type.isPrimitiveClass();
+         }
+ 
      void checkNonCyclicDecl(JCClassDecl tree) {
          CycleChecker cc = new CycleChecker();
          cc.scan(tree);
          if (!cc.errorFound && !cc.partialCheck) {
              tree.sym.flags_field |= ACYCLIC;

@@ -2538,10 +2770,32 @@
              for (List<Type> m = supertypes; m != l; m = m.tail)
                  if (!checkCompatibleAbstracts(pos, l.head, m.head, c))
                      return;
          }
          checkCompatibleConcretes(pos, c);
+ 
+         boolean cIsValue = (c.tsym.flags() & VALUE_CLASS) != 0;
+         boolean cHasIdentity = (c.tsym.flags() & IDENTITY_TYPE) != 0;
+         Type identitySuper = null, valueSuper = null;
+         for (Type t : types.closure(c)) {
+             if (t != c) {
+                 if ((t.tsym.flags() & IDENTITY_TYPE) != 0)
+                     identitySuper = t;
+                 else if ((t.tsym.flags() & VALUE_CLASS) != 0)
+                     valueSuper = t;
+                 if (cIsValue &&  identitySuper != null) {
+                     log.error(pos, Errors.ValueTypeHasIdentitySuperType(c, identitySuper));
+                     break;
+                 } else if (cHasIdentity &&  valueSuper != null) {
+                     log.error(pos, Errors.IdentityTypeHasValueSuperType(c, valueSuper));
+                     break;
+                 } else if (identitySuper != null && valueSuper != null) {
+                     log.error(pos, Errors.MutuallyIncompatibleSupers(c, identitySuper, valueSuper));
+                     break;
+                 }
+             }
+         }
      }
  
      /** Check that all non-override equivalent methods accessible from 'site'
       *  are mutually compatible (JLS 8.4.8/9.4.1).
       *

@@ -2655,11 +2909,11 @@
           public boolean test(Symbol s) {
               return s.kind == MTH &&
                       (s.flags() & SYNTHETIC) == 0 &&
                       !shouldSkip(s) &&
                       s.isInheritedIn(site.tsym, types) &&
-                      !s.isConstructor();
+                      !s.isInitOrVNew();
           }
       }
  
      void checkDefaultMethodClashes(DiagnosticPosition pos, Type site) {
          DefaultMethodClashFilter dcf = new DefaultMethodClashFilter(site);

@@ -2714,11 +2968,11 @@
           @Override
           public boolean test(Symbol s) {
               return s.kind == MTH &&
                       (s.flags() & DEFAULT) != 0 &&
                       s.isInheritedIn(site.tsym, types) &&
-                      !s.isConstructor();
+                      !s.isInitOrVNew();
           }
       }
  
      /**
        * Report warnings for potentially ambiguous method declarations. Two declarations

@@ -3401,19 +3655,19 @@
              } else if (target == names.RECORD_COMPONENT) {
                  if (s.getKind() == ElementKind.RECORD_COMPONENT) {
                      applicableTargets.add(names.RECORD_COMPONENT);
                  }
              } else if (target == names.METHOD) {
-                 if (s.kind == MTH && !s.isConstructor())
+                 if (s.kind == MTH && !s.isInitOrVNew())
                      applicableTargets.add(names.METHOD);
              } else if (target == names.PARAMETER) {
                  if (s.kind == VAR &&
                      (s.owner.kind == MTH && (s.flags() & PARAMETER) != 0)) {
                      applicableTargets.add(names.PARAMETER);
                  }
              } else if (target == names.CONSTRUCTOR) {
-                 if (s.kind == MTH && s.isConstructor())
+                 if (s.kind == MTH && s.isInitOrVNew())
                      applicableTargets.add(names.CONSTRUCTOR);
              } else if (target == names.LOCAL_VARIABLE) {
                  if (s.kind == VAR && s.owner.kind == MTH &&
                        (s.flags() & PARAMETER) == 0) {
                      applicableTargets.add(names.LOCAL_VARIABLE);

@@ -3428,13 +3682,13 @@
              } else if (target == names.TYPE_USE) {
                  if (s.kind == VAR && s.owner.kind == MTH && s.type.hasTag(NONE)) {
                      //cannot type annotate implicitly typed locals
                      continue;
                  } else if (s.kind == TYP || s.kind == VAR ||
-                         (s.kind == MTH && !s.isConstructor() &&
+                         (s.kind == MTH && !s.isInitOrVNew() &&
                                  !s.type.getReturnType().hasTag(VOID)) ||
-                         (s.kind == MTH && s.isConstructor())) {
+                         (s.kind == MTH && s.isInitOrVNew())) {
                      applicableTargets.add(names.TYPE_USE);
                  }
              } else if (target == names.TYPE_PARAMETER) {
                  if (s.kind == TYP && s.type.hasTag(TYPEVAR))
                      applicableTargets.add(names.TYPE_PARAMETER);

@@ -4695,11 +4949,11 @@
           * constructor of its first nonserializable superclass.
           */
          private void checkCtorAccess(JCClassDecl tree, ClassSymbol c) {
              if (isExternalizable(c.type)) {
                  for(var sym : c.getEnclosedElements()) {
-                     if (sym.isConstructor() &&
+                     if (sym.isInitOrVNew() &&
                          ((sym.flags() & PUBLIC) == PUBLIC)) {
                          if (((MethodSymbol)sym).getParameters().isEmpty()) {
                              return;
                          }
                      }

@@ -4723,11 +4977,11 @@
                  }
                  // Non-Serializable superclass
                  try {
                      ClassSymbol supertype = ((ClassSymbol)(((DeclaredType)superClass).asElement()));
                      for(var sym : supertype.getEnclosedElements()) {
-                         if (sym.isConstructor()) {
+                         if (sym.isInitOrVNew()) {
                              MethodSymbol ctor = (MethodSymbol)sym;
                              if (ctor.getParameters().isEmpty()) {
                                  if (((ctor.flags() & PRIVATE) == PRIVATE) ||
                                      // Handle nested classes and implicit this$0
                                      (supertype.getNestingKind() == NestingKind.MEMBER &&
< prev index next >