126 protected Check(Context context) {
127 context.put(checkKey, this);
128
129 names = Names.instance(context);
130 log = Log.instance(context);
131 rs = Resolve.instance(context);
132 syms = Symtab.instance(context);
133 enter = Enter.instance(context);
134 deferredAttr = DeferredAttr.instance(context);
135 infer = Infer.instance(context);
136 types = Types.instance(context);
137 typeAnnotations = TypeAnnotations.instance(context);
138 diags = JCDiagnostic.Factory.instance(context);
139 Options options = Options.instance(context);
140 lint = Lint.instance(context);
141 fileManager = context.get(JavaFileManager.class);
142
143 source = Source.instance(context);
144 target = Target.instance(context);
145 warnOnAnyAccessToMembers = options.isSet("warnOnAccessToMembers");
146
147 Target target = Target.instance(context);
148 syntheticNameChar = target.syntheticNameChar();
149
150 profile = Profile.instance(context);
151 preview = Preview.instance(context);
152
153 boolean verboseDeprecated = lint.isEnabled(LintCategory.DEPRECATION);
154 boolean verboseRemoval = lint.isEnabled(LintCategory.REMOVAL);
155 boolean verboseUnchecked = lint.isEnabled(LintCategory.UNCHECKED);
156 boolean enforceMandatoryWarnings = true;
157
158 deprecationHandler = new MandatoryWarningHandler(log, null, verboseDeprecated,
159 enforceMandatoryWarnings, "deprecated", LintCategory.DEPRECATION);
160 removalHandler = new MandatoryWarningHandler(log, null, verboseRemoval,
161 enforceMandatoryWarnings, "removal", LintCategory.REMOVAL);
162 uncheckedHandler = new MandatoryWarningHandler(log, null, verboseUnchecked,
163 enforceMandatoryWarnings, "unchecked", LintCategory.UNCHECKED);
164 sunApiHandler = new MandatoryWarningHandler(log, null, false,
165 enforceMandatoryWarnings, "sunapi", null);
166
491 uncheckedHandler.clear();
492 sunApiHandler.clear();
493 }
494
495 public void putCompiled(ClassSymbol csym) {
496 compiled.put(Pair.of(csym.packge().modle, csym.flatname), csym);
497 }
498
499 public ClassSymbol getCompiled(ClassSymbol csym) {
500 return compiled.get(Pair.of(csym.packge().modle, csym.flatname));
501 }
502
503 public ClassSymbol getCompiled(ModuleSymbol msym, Name flatname) {
504 return compiled.get(Pair.of(msym, flatname));
505 }
506
507 public void removeCompiled(ClassSymbol csym) {
508 compiled.remove(Pair.of(csym.packge().modle, csym.flatname));
509 }
510
511 /* *************************************************************************
512 * Type Checking
513 **************************************************************************/
514
515 /**
516 * A check context is an object that can be used to perform compatibility
517 * checks - depending on the check context, meaning of 'compatibility' might
518 * vary significantly.
519 */
520 public interface CheckContext {
521 /**
522 * Is type 'found' compatible with type 'req' in given context
523 */
524 boolean compatible(Type found, Type req, Warner warn);
525 /**
526 * Report a check error
527 */
528 void report(DiagnosticPosition pos, JCDiagnostic details);
529 /**
530 * Obtain a warner for this check context
531 */
597 public String toString() {
598 return "CheckContext: basicHandler";
599 }
600 };
601
602 /** Check that a given type is assignable to a given proto-type.
603 * If it is, return the type, otherwise return errType.
604 * @param pos Position to be used for error reporting.
605 * @param found The type that was found.
606 * @param req The type that was required.
607 */
608 public Type checkType(DiagnosticPosition pos, Type found, Type req) {
609 return checkType(pos, found, req, basicHandler);
610 }
611
612 Type checkType(final DiagnosticPosition pos, final Type found, final Type req, final CheckContext checkContext) {
613 final InferenceContext inferenceContext = checkContext.inferenceContext();
614 if (inferenceContext.free(req) || inferenceContext.free(found)) {
615 inferenceContext.addFreeTypeListener(List.of(req, found),
616 solvedContext -> checkType(pos, solvedContext.asInstType(found), solvedContext.asInstType(req), checkContext));
617 }
618 if (req.hasTag(ERROR))
619 return req;
620 if (req.hasTag(NONE))
621 return found;
622 if (checkContext.compatible(found, req, checkContext.checkWarner(pos, found, req))) {
623 return found;
624 } else {
625 if (found.isNumeric() && req.isNumeric()) {
626 checkContext.report(pos, diags.fragment(Fragments.PossibleLossOfPrecision(found, req)));
627 return types.createErrorType(found);
628 }
629 checkContext.report(pos, diags.fragment(Fragments.InconvertibleTypes(found, req)));
630 return types.createErrorType(found);
631 }
632 }
633
634 /** Check that a given type can be cast to a given target type.
635 * Return the result of the cast.
636 * @param pos Position to be used for error reporting.
727 /** Check that type is a class or interface type.
728 * @param pos Position to be used for error reporting.
729 * @param t The type to be checked.
730 */
731 Type checkClassType(DiagnosticPosition pos, Type t) {
732 if (!t.hasTag(CLASS) && !t.hasTag(ERROR)) {
733 return typeTagError(pos,
734 diags.fragment(Fragments.TypeReqClass),
735 asTypeParam(t));
736 } else {
737 return t;
738 }
739 }
740 //where
741 private Object asTypeParam(Type t) {
742 return (t.hasTag(TYPEVAR))
743 ? diags.fragment(Fragments.TypeParameter(t))
744 : t;
745 }
746
747 /** Check that type is a valid qualifier for a constructor reference expression
748 */
749 Type checkConstructorRefType(DiagnosticPosition pos, Type t) {
750 t = checkClassOrArrayType(pos, t);
751 if (t.hasTag(CLASS)) {
752 if ((t.tsym.flags() & (ABSTRACT | INTERFACE)) != 0) {
753 log.error(pos, Errors.AbstractCantBeInstantiated(t.tsym));
754 t = types.createErrorType(t);
755 } else if ((t.tsym.flags() & ENUM) != 0) {
756 log.error(pos, Errors.EnumCantBeInstantiated);
757 t = types.createErrorType(t);
758 } else {
759 t = checkClassType(pos, t, true);
760 }
761 } else if (t.hasTag(ARRAY)) {
762 if (!types.isReifiable(((ArrayType)t).elemtype)) {
763 log.error(pos, Errors.GenericArrayCreation);
764 t = types.createErrorType(t);
765 }
766 }
767 return t;
768 }
769
770 /** Check that type is a class or interface type.
771 * @param pos Position to be used for error reporting.
772 * @param t The type to be checked.
773 * @param noBounds True if type bounds are illegal here.
774 */
775 Type checkClassType(DiagnosticPosition pos, Type t, boolean noBounds) {
776 t = checkClassType(pos, t);
777 if (noBounds && t.isParameterized()) {
778 List<Type> args = t.getTypeArguments();
779 while (args.nonEmpty()) {
780 if (args.head.hasTag(WILDCARD))
781 return typeTagError(pos,
782 diags.fragment(Fragments.TypeReqExact),
783 args.head);
784 args = args.tail;
785 }
786 }
787 return t;
788 }
789
790 /** Check that type is a reference type, i.e. a class, interface or array type
791 * or a type variable.
792 * @param pos Position to be used for error reporting.
793 * @param t The type to be checked.
794 */
795 Type checkRefType(DiagnosticPosition pos, Type t) {
796 if (t.isReference())
797 return t;
798 else
799 return typeTagError(pos,
800 diags.fragment(Fragments.TypeReqRef),
801 t);
802 }
803
804 /** Check that each type is a reference type, i.e. a class, interface or array type
805 * or a type variable.
806 * @param trees Original trees, used for error reporting.
807 * @param types The types to be checked.
808 */
809 List<Type> checkRefTypes(List<JCExpression> trees, List<Type> types) {
810 List<JCExpression> tl = trees;
811 for (List<Type> l = types; l.nonEmpty(); l = l.tail) {
812 l.head = checkRefType(tl.head.pos(), l.head);
813 tl = tl.tail;
814 }
815 return types;
816 }
817
818 /** Check that type is a null or reference type.
819 * @param pos Position to be used for error reporting.
820 * @param t The type to be checked.
821 */
822 Type checkNullOrRefType(DiagnosticPosition pos, Type t) {
823 if (t.isReference() || t.hasTag(BOT))
824 return t;
825 else
826 return typeTagError(pos,
827 diags.fragment(Fragments.TypeReqRef),
828 t);
829 }
830
831 /** Check that flag set does not contain elements of two conflicting sets. s
832 * Return true if it doesn't.
833 * @param pos Position to be used for error reporting.
834 * @param flags The set of flags to be checked.
835 * @param set1 Conflicting flags set #1.
836 * @param set2 Conflicting flags set #2.
837 */
838 boolean checkDisjoint(DiagnosticPosition pos, long flags, long set1, long set2) {
839 if ((flags & set1) != 0 && (flags & set2) != 0) {
840 log.error(pos,
841 Errors.IllegalCombinationOfModifiers(asFlagSet(TreeInfo.firstFlag(flags & set1)),
842 asFlagSet(TreeInfo.firstFlag(flags & set2))));
843 return false;
844 } else
845 return true;
846 }
847
848 /** Check that usage of diamond operator is correct (i.e. diamond should not
849 * be used with non-generic classes or in anonymous class creation expressions)
850 */
851 Type checkDiamond(JCNewClass tree, Type t) {
852 if (!TreeInfo.isDiamond(tree) ||
853 t.isErroneous()) {
854 return checkClassType(tree.clazz.pos(), t, true);
855 } else {
856 if (tree.def != null && !Feature.DIAMOND_WITH_ANONYMOUS_CLASS_CREATION.allowedInSource(source)) {
857 log.error(DiagnosticFlag.SOURCE_LEVEL, tree.clazz.pos(),
858 Errors.CantApplyDiamond1(t, Feature.DIAMOND_WITH_ANONYMOUS_CLASS_CREATION.fragment(source.name)));
859 }
860 if (t.tsym.type.getTypeArguments().isEmpty()) {
861 log.error(tree.clazz.pos(),
862 Errors.CantApplyDiamond1(t,
863 Fragments.DiamondNonGeneric(t)));
864 return types.createErrorType(t);
865 } else if (tree.typeargs != null &&
866 tree.typeargs.nonEmpty()) {
867 log.error(tree.clazz.pos(),
976 }
977 //where
978 private boolean isTrustMeAllowedOnMethod(Symbol s) {
979 return (s.flags() & VARARGS) != 0 &&
980 (s.isConstructor() ||
981 (s.flags() & (STATIC | FINAL |
982 (Feature.PRIVATE_SAFE_VARARGS.allowedInSource(source) ? PRIVATE : 0) )) != 0);
983 }
984
985 Type checkLocalVarType(DiagnosticPosition pos, Type t, Name name) {
986 //check that resulting type is not the null type
987 if (t.hasTag(BOT)) {
988 log.error(pos, Errors.CantInferLocalVarType(name, Fragments.LocalCantInferNull));
989 return types.createErrorType(t);
990 } else if (t.hasTag(VOID)) {
991 log.error(pos, Errors.CantInferLocalVarType(name, Fragments.LocalCantInferVoid));
992 return types.createErrorType(t);
993 }
994
995 //upward project the initializer type
996 return types.upward(t, types.captures(t));
997 }
998
999 Type checkMethod(final Type mtype,
1000 final Symbol sym,
1001 final Env<AttrContext> env,
1002 final List<JCExpression> argtrees,
1003 final List<Type> argtypes,
1004 final boolean useVarargs,
1005 InferenceContext inferenceContext) {
1006 // System.out.println("call : " + env.tree);
1007 // System.out.println("method : " + owntype);
1008 // System.out.println("actuals: " + argtypes);
1009 if (inferenceContext.free(mtype)) {
1010 inferenceContext.addFreeTypeListener(List.of(mtype),
1011 solvedContext -> checkMethod(solvedContext.asInstType(mtype), sym, env, argtrees, argtypes, useVarargs, solvedContext));
1012 return mtype;
1013 }
1014 Type owntype = mtype;
1015 List<Type> formals = owntype.getParameterTypes();
1016 List<Type> nonInferred = sym.type.getParameterTypes();
1174 * return modifiers together with any implicit modifiers for that symbol.
1175 * Warning: we can't use flags() here since this method
1176 * is called during class enter, when flags() would cause a premature
1177 * completion.
1178 * @param pos Position to be used for error reporting.
1179 * @param flags The set of modifiers given in a definition.
1180 * @param sym The defined symbol.
1181 */
1182 long checkFlags(DiagnosticPosition pos, long flags, Symbol sym, JCTree tree) {
1183 long mask;
1184 long implicit = 0;
1185
1186 switch (sym.kind) {
1187 case VAR:
1188 if (TreeInfo.isReceiverParam(tree))
1189 mask = ReceiverParamFlags;
1190 else if (sym.owner.kind != TYP)
1191 mask = LocalVarFlags;
1192 else if ((sym.owner.flags_field & INTERFACE) != 0)
1193 mask = implicit = InterfaceVarFlags;
1194 else
1195 mask = VarFlags;
1196 break;
1197 case MTH:
1198 if (sym.name == names.init) {
1199 if ((sym.owner.flags_field & ENUM) != 0) {
1200 // enum constructors cannot be declared public or
1201 // protected and must be implicitly or explicitly
1202 // private
1203 implicit = PRIVATE;
1204 mask = PRIVATE;
1205 } else
1206 mask = ConstructorFlags;
1207 } else if ((sym.owner.flags_field & INTERFACE) != 0) {
1208 if ((sym.owner.flags_field & ANNOTATION) != 0) {
1209 mask = AnnotationTypeElementMask;
1210 implicit = PUBLIC | ABSTRACT;
1211 } else if ((flags & (DEFAULT | STATIC | PRIVATE)) != 0) {
1212 mask = InterfaceMethodMask;
1213 implicit = (flags & PRIVATE) != 0 ? 0 : PUBLIC;
1214 if ((flags & DEFAULT) != 0) {
1215 implicit |= ABSTRACT;
1216 }
1217 } else {
1218 mask = implicit = InterfaceMethodFlags;
1219 }
1220 } else if ((sym.owner.flags_field & RECORD) != 0) {
1221 mask = RecordMethodFlags;
1222 } else {
1223 mask = MethodFlags;
1224 }
1225 if ((flags & STRICTFP) != 0) {
1226 warnOnExplicitStrictfp(pos);
1227 }
1228 // Imply STRICTFP if owner has STRICTFP set.
1229 if (((flags|implicit) & Flags.ABSTRACT) == 0 ||
1230 ((flags) & Flags.DEFAULT) != 0)
1231 implicit |= sym.owner.flags_field & STRICTFP;
1232 break;
1233 case TYP:
1234 if (sym.owner.kind.matches(KindSelector.VAL_MTH) ||
1235 (sym.isDirectlyOrIndirectlyLocal() && (flags & ANNOTATION) != 0)) {
1236 boolean implicitlyStatic = !sym.isAnonymous() &&
1237 ((flags & RECORD) != 0 || (flags & ENUM) != 0 || (flags & INTERFACE) != 0);
1238 boolean staticOrImplicitlyStatic = (flags & STATIC) != 0 || implicitlyStatic;
1239 // local statics are allowed only if records are allowed too
1240 mask = staticOrImplicitlyStatic && allowRecords && (flags & ANNOTATION) == 0 ? StaticLocalFlags : LocalClassFlags;
1241 implicit = implicitlyStatic ? STATIC : implicit;
1242 } else if (sym.owner.kind == TYP) {
1243 // statics in inner classes are allowed only if records are allowed too
1244 mask = ((flags & STATIC) != 0) && allowRecords && (flags & ANNOTATION) == 0 ? ExtendedMemberStaticClassFlags : ExtendedMemberClassFlags;
1245 if (sym.owner.owner.kind == PCK ||
1246 (sym.owner.flags_field & STATIC) != 0) {
1247 mask |= STATIC;
1248 } else if (!allowRecords && ((flags & ENUM) != 0 || (flags & RECORD) != 0)) {
1249 log.error(pos, Errors.StaticDeclarationNotAllowedInInnerClasses);
1250 }
1251 // Nested interfaces and enums are always STATIC (Spec ???)
1252 if ((flags & (INTERFACE | ENUM | RECORD)) != 0 ) implicit = STATIC;
1253 } else {
1254 mask = ExtendedClassFlags;
1255 }
1256 // Interfaces are always ABSTRACT
1257 if ((flags & INTERFACE) != 0) implicit |= ABSTRACT;
1258
1259 if ((flags & ENUM) != 0) {
1260 // enums can't be declared abstract, final, sealed or non-sealed
1261 mask &= ~(ABSTRACT | FINAL | SEALED | NON_SEALED);
1262 implicit |= implicitEnumFinalFlag(tree);
1263 }
1264 if ((flags & RECORD) != 0) {
1265 // records can't be declared abstract
1266 mask &= ~ABSTRACT;
1267 implicit |= FINAL;
1268 }
1269 if ((flags & STRICTFP) != 0) {
1270 warnOnExplicitStrictfp(pos);
1271 }
1272 // Imply STRICTFP if owner has STRICTFP set.
1273 implicit |= sym.owner.flags_field & STRICTFP;
1274 break;
1275 default:
1276 throw new AssertionError();
1277 }
1278 long illegal = flags & ExtendedStandardFlags & ~mask;
1279 if (illegal != 0) {
1280 if ((illegal & INTERFACE) != 0) {
1281 log.error(pos, ((flags & ANNOTATION) != 0) ? Errors.AnnotationDeclNotAllowedHere : Errors.IntfNotAllowedHere);
1282 mask |= INTERFACE;
1283 }
1284 else {
1285 log.error(pos,
1286 Errors.ModNotAllowedHere(asFlagSet(illegal)));
1287 }
1288 }
1289 else if ((sym.kind == TYP ||
1290 // ISSUE: Disallowing abstract&private is no longer appropriate
1291 // in the presence of inner classes. Should it be deleted here?
1292 checkDisjoint(pos, flags,
1293 ABSTRACT,
1294 PRIVATE | STATIC | DEFAULT))
1295 &&
1296 checkDisjoint(pos, flags,
1297 STATIC | PRIVATE,
1298 DEFAULT)
1299 &&
1300 checkDisjoint(pos, flags,
1301 ABSTRACT | INTERFACE,
1302 FINAL | NATIVE | SYNCHRONIZED)
1303 &&
1304 checkDisjoint(pos, flags,
1305 PUBLIC,
1306 PRIVATE | PROTECTED)
1307 &&
1308 checkDisjoint(pos, flags,
1309 PRIVATE,
1310 PUBLIC | PROTECTED)
1311 &&
1312 checkDisjoint(pos, flags,
1313 FINAL,
1314 VOLATILE)
1315 &&
1316 (sym.kind == TYP ||
1317 checkDisjoint(pos, flags,
1318 ABSTRACT | NATIVE,
1319 STRICTFP))
1320 && checkDisjoint(pos, flags,
1321 FINAL,
1322 SEALED | NON_SEALED)
1323 && checkDisjoint(pos, flags,
1324 SEALED,
1325 FINAL | NON_SEALED)
1326 && checkDisjoint(pos, flags,
1327 SEALED,
1328 ANNOTATION)) {
1329 // skip
1330 }
1331 return flags & (mask | ~ExtendedStandardFlags) | implicit;
1332 }
1481 @Override
1482 public void visitWildcard(JCWildcard tree) {
1483 if (tree.inner != null)
1484 validateTree(tree.inner, true, isOuter);
1485 }
1486
1487 @Override
1488 public void visitSelect(JCFieldAccess tree) {
1489 if (tree.type.hasTag(CLASS)) {
1490 visitSelectInternal(tree);
1491
1492 // Check that this type is either fully parameterized, or
1493 // not parameterized at all.
1494 if (tree.selected.type.isParameterized() && tree.type.tsym.type.getTypeArguments().nonEmpty())
1495 log.error(tree.pos(), Errors.ImproperlyFormedTypeParamMissing);
1496 }
1497 }
1498
1499 public void visitSelectInternal(JCFieldAccess tree) {
1500 if (tree.type.tsym.isStatic() &&
1501 tree.selected.type.isParameterized()) {
1502 // The enclosing type is not a class, so we are
1503 // looking at a static member type. However, the
1504 // qualifying expression is parameterized.
1505 log.error(tree.pos(), Errors.CantSelectStaticClassFromParamType);
1506 } else {
1507 // otherwise validate the rest of the expression
1508 tree.selected.accept(this);
1509 }
1510 }
1511
1512 @Override
1513 public void visitAnnotatedType(JCAnnotatedType tree) {
1514 tree.underlyingType.accept(this);
1515 }
1516
1517 @Override
1518 public void visitTypeIdent(JCPrimitiveTypeTree that) {
1519 if (that.type.hasTag(TypeTag.VOID)) {
1520 log.error(that.pos(), Errors.VoidNotAllowedHere);
1521 }
1522 super.visitTypeIdent(that);
1523 }
1524
1811 return;
1812 }
1813
1814 if ((m.owner.flags() & ANNOTATION) != 0) {
1815 // handled in validateAnnotationMethod
1816 return;
1817 }
1818
1819 // Error if overriding method has weaker access (JLS 8.4.8.3).
1820 if (protection(m.flags()) > protection(other.flags())) {
1821 log.error(TreeInfo.diagnosticPositionFor(m, tree),
1822 (other.flags() & AccessFlags) == 0 ?
1823 Errors.OverrideWeakerAccess(cannotOverride(m, other),
1824 "package") :
1825 Errors.OverrideWeakerAccess(cannotOverride(m, other),
1826 asFlagSet(other.flags() & AccessFlags)));
1827 m.flags_field |= BAD_OVERRIDE;
1828 return;
1829 }
1830
1831 Type mt = types.memberType(origin.type, m);
1832 Type ot = types.memberType(origin.type, other);
1833 // Error if overriding result type is different
1834 // (or, in the case of generics mode, not a subtype) of
1835 // overridden result type. We have to rename any type parameters
1836 // before comparing types.
1837 List<Type> mtvars = mt.getTypeArguments();
1838 List<Type> otvars = ot.getTypeArguments();
1839 Type mtres = mt.getReturnType();
1840 Type otres = types.subst(ot.getReturnType(), otvars, mtvars);
1841
1842 overrideWarner.clear();
1843 boolean resultTypesOK =
1844 types.returnTypeSubstitutable(mt, ot, otres, overrideWarner);
1845 if (!resultTypesOK) {
1846 if ((m.flags() & STATIC) != 0 && (other.flags() & STATIC) != 0) {
1847 log.error(TreeInfo.diagnosticPositionFor(m, tree),
1848 Errors.OverrideIncompatibleRet(Fragments.CantHide(m, m.location(), other,
1849 other.location()), mtres, otres));
1850 m.flags_field |= BAD_OVERRIDE;
2249 cf.test(s2) &&
2250 types.hasSameArgs(s1.erasure(types), s2.erasure(types)));
2251 }
2252
2253
2254 /** Check that all abstract members of given class have definitions.
2255 * @param pos Position to be used for error reporting.
2256 * @param c The class.
2257 */
2258 void checkAllDefined(DiagnosticPosition pos, ClassSymbol c) {
2259 MethodSymbol undef = types.firstUnimplementedAbstract(c);
2260 if (undef != null) {
2261 MethodSymbol undef1 =
2262 new MethodSymbol(undef.flags(), undef.name,
2263 types.memberType(c.type, undef), undef.owner);
2264 log.error(pos,
2265 Errors.DoesNotOverrideAbstract(c, undef1, undef1.location()));
2266 }
2267 }
2268
2269 void checkNonCyclicDecl(JCClassDecl tree) {
2270 CycleChecker cc = new CycleChecker();
2271 cc.scan(tree);
2272 if (!cc.errorFound && !cc.partialCheck) {
2273 tree.sym.flags_field |= ACYCLIC;
2274 }
2275 }
2276
2277 class CycleChecker extends TreeScanner {
2278
2279 Set<Symbol> seenClasses = new HashSet<>();
2280 boolean errorFound = false;
2281 boolean partialCheck = false;
2282
2283 private void checkSymbol(DiagnosticPosition pos, Symbol sym) {
2284 if (sym != null && sym.kind == TYP) {
2285 Env<AttrContext> classEnv = enter.getEnv((TypeSymbol)sym);
2286 if (classEnv != null) {
2287 DiagnosticSource prevSource = log.currentSource();
2288 try {
2497 /** Check that all abstract methods implemented by a class are
2498 * mutually compatible.
2499 * @param pos Position to be used for error reporting.
2500 * @param c The class whose interfaces are checked.
2501 */
2502 void checkCompatibleSupertypes(DiagnosticPosition pos, Type c) {
2503 List<Type> supertypes = types.interfaces(c);
2504 Type supertype = types.supertype(c);
2505 if (supertype.hasTag(CLASS) &&
2506 (supertype.tsym.flags() & ABSTRACT) != 0)
2507 supertypes = supertypes.prepend(supertype);
2508 for (List<Type> l = supertypes; l.nonEmpty(); l = l.tail) {
2509 if (!l.head.getTypeArguments().isEmpty() &&
2510 !checkCompatibleAbstracts(pos, l.head, l.head, c))
2511 return;
2512 for (List<Type> m = supertypes; m != l; m = m.tail)
2513 if (!checkCompatibleAbstracts(pos, l.head, m.head, c))
2514 return;
2515 }
2516 checkCompatibleConcretes(pos, c);
2517 }
2518
2519 /** Check that all non-override equivalent methods accessible from 'site'
2520 * are mutually compatible (JLS 8.4.8/9.4.1).
2521 *
2522 * @param pos Position to be used for error reporting.
2523 * @param site The class whose methods are checked.
2524 * @param sym The method symbol to be checked.
2525 */
2526 void checkOverrideClashes(DiagnosticPosition pos, Type site, MethodSymbol sym) {
2527 ClashFilter cf = new ClashFilter(site);
2528 //for each method m1 that is overridden (directly or indirectly)
2529 //by method 'sym' in 'site'...
2530
2531 List<MethodSymbol> potentiallyAmbiguousList = List.nil();
2532 boolean overridesAny = false;
2533 ArrayList<Symbol> symbolsByName = new ArrayList<>();
2534 types.membersClosure(site, false).getSymbolsByName(sym.name, cf).forEach(symbolsByName::add);
2535 for (Symbol m1 : symbolsByName) {
2536 if (!sym.overrides(m1, site.tsym, types, false)) {
|
126 protected Check(Context context) {
127 context.put(checkKey, this);
128
129 names = Names.instance(context);
130 log = Log.instance(context);
131 rs = Resolve.instance(context);
132 syms = Symtab.instance(context);
133 enter = Enter.instance(context);
134 deferredAttr = DeferredAttr.instance(context);
135 infer = Infer.instance(context);
136 types = Types.instance(context);
137 typeAnnotations = TypeAnnotations.instance(context);
138 diags = JCDiagnostic.Factory.instance(context);
139 Options options = Options.instance(context);
140 lint = Lint.instance(context);
141 fileManager = context.get(JavaFileManager.class);
142
143 source = Source.instance(context);
144 target = Target.instance(context);
145 warnOnAnyAccessToMembers = options.isSet("warnOnAccessToMembers");
146 Target target = Target.instance(context);
147 syntheticNameChar = target.syntheticNameChar();
148
149 profile = Profile.instance(context);
150 preview = Preview.instance(context);
151
152 boolean verboseDeprecated = lint.isEnabled(LintCategory.DEPRECATION);
153 boolean verboseRemoval = lint.isEnabled(LintCategory.REMOVAL);
154 boolean verboseUnchecked = lint.isEnabled(LintCategory.UNCHECKED);
155 boolean enforceMandatoryWarnings = true;
156
157 deprecationHandler = new MandatoryWarningHandler(log, null, verboseDeprecated,
158 enforceMandatoryWarnings, "deprecated", LintCategory.DEPRECATION);
159 removalHandler = new MandatoryWarningHandler(log, null, verboseRemoval,
160 enforceMandatoryWarnings, "removal", LintCategory.REMOVAL);
161 uncheckedHandler = new MandatoryWarningHandler(log, null, verboseUnchecked,
162 enforceMandatoryWarnings, "unchecked", LintCategory.UNCHECKED);
163 sunApiHandler = new MandatoryWarningHandler(log, null, false,
164 enforceMandatoryWarnings, "sunapi", null);
165
490 uncheckedHandler.clear();
491 sunApiHandler.clear();
492 }
493
494 public void putCompiled(ClassSymbol csym) {
495 compiled.put(Pair.of(csym.packge().modle, csym.flatname), csym);
496 }
497
498 public ClassSymbol getCompiled(ClassSymbol csym) {
499 return compiled.get(Pair.of(csym.packge().modle, csym.flatname));
500 }
501
502 public ClassSymbol getCompiled(ModuleSymbol msym, Name flatname) {
503 return compiled.get(Pair.of(msym, flatname));
504 }
505
506 public void removeCompiled(ClassSymbol csym) {
507 compiled.remove(Pair.of(csym.packge().modle, csym.flatname));
508 }
509
510 /* *************************************************************************
511 * Type Checking
512 **************************************************************************/
513
514 /**
515 * A check context is an object that can be used to perform compatibility
516 * checks - depending on the check context, meaning of 'compatibility' might
517 * vary significantly.
518 */
519 public interface CheckContext {
520 /**
521 * Is type 'found' compatible with type 'req' in given context
522 */
523 boolean compatible(Type found, Type req, Warner warn);
524 /**
525 * Report a check error
526 */
527 void report(DiagnosticPosition pos, JCDiagnostic details);
528 /**
529 * Obtain a warner for this check context
530 */
596 public String toString() {
597 return "CheckContext: basicHandler";
598 }
599 };
600
601 /** Check that a given type is assignable to a given proto-type.
602 * If it is, return the type, otherwise return errType.
603 * @param pos Position to be used for error reporting.
604 * @param found The type that was found.
605 * @param req The type that was required.
606 */
607 public Type checkType(DiagnosticPosition pos, Type found, Type req) {
608 return checkType(pos, found, req, basicHandler);
609 }
610
611 Type checkType(final DiagnosticPosition pos, final Type found, final Type req, final CheckContext checkContext) {
612 final InferenceContext inferenceContext = checkContext.inferenceContext();
613 if (inferenceContext.free(req) || inferenceContext.free(found)) {
614 inferenceContext.addFreeTypeListener(List.of(req, found),
615 solvedContext -> checkType(pos, solvedContext.asInstType(found), solvedContext.asInstType(req), checkContext));
616 } else {
617 if (found.hasTag(CLASS)) {
618 if (inferenceContext != infer.emptyContext)
619 checkParameterizationByPrimitiveClass(pos, found);
620 }
621 }
622 if (req.hasTag(ERROR))
623 return req;
624 if (req.hasTag(NONE))
625 return found;
626 if (checkContext.compatible(found, req, checkContext.checkWarner(pos, found, req))) {
627 return found;
628 } else {
629 if (found.isNumeric() && req.isNumeric()) {
630 checkContext.report(pos, diags.fragment(Fragments.PossibleLossOfPrecision(found, req)));
631 return types.createErrorType(found);
632 }
633 checkContext.report(pos, diags.fragment(Fragments.InconvertibleTypes(found, req)));
634 return types.createErrorType(found);
635 }
636 }
637
638 /** Check that a given type can be cast to a given target type.
639 * Return the result of the cast.
640 * @param pos Position to be used for error reporting.
731 /** Check that type is a class or interface type.
732 * @param pos Position to be used for error reporting.
733 * @param t The type to be checked.
734 */
735 Type checkClassType(DiagnosticPosition pos, Type t) {
736 if (!t.hasTag(CLASS) && !t.hasTag(ERROR)) {
737 return typeTagError(pos,
738 diags.fragment(Fragments.TypeReqClass),
739 asTypeParam(t));
740 } else {
741 return t;
742 }
743 }
744 //where
745 private Object asTypeParam(Type t) {
746 return (t.hasTag(TYPEVAR))
747 ? diags.fragment(Fragments.TypeParameter(t))
748 : t;
749 }
750
751 void checkSuperConstraintsOfValueClass(DiagnosticPosition pos, ClassSymbol c) {
752 for(Type st = types.supertype(c.type); st != Type.noType; st = types.supertype(st)) {
753 if (st == null || st.tsym == null || st.tsym.kind == ERR)
754 return;
755 if (st.tsym == syms.objectType.tsym)
756 return;
757 if (!st.tsym.isAbstract()) {
758 log.error(pos, Errors.ConcreteSupertypeForValueClass(c, st));
759 }
760 if ((st.tsym.flags() & IDENTITY_TYPE) == 0) {
761 return;
762 }
763 // TODO: If an IDENTITY_TYPE we may not issue an error below, if older abstract class qualifies
764 // We have an unsuitable abstract super class, find out why exactly and complain
765 if ((st.tsym.flags() & HASINITBLOCK) != 0) {
766 log.error(pos, Errors.SuperClassDeclaresInitBlock(c, st));
767 }
768 // No instance fields and no arged constructors both mean inner classes
769 // cannot be super classes for primitive classes.
770 Type encl = st.getEnclosingType();
771 if (encl != null && encl.hasTag(CLASS)) {
772 log.error(pos, Errors.SuperClassCannotBeInner(c, st));
773 }
774 for (Symbol s : st.tsym.members().getSymbols(NON_RECURSIVE)) {
775 switch (s.kind) {
776 case VAR:
777 if ((s.flags() & STATIC) == 0) {
778 log.error(pos, Errors.SuperFieldNotAllowed(s, c, st));
779 }
780 break;
781 case MTH:
782 if ((s.flags() & SYNCHRONIZED) != 0) {
783 log.error(pos, Errors.SuperMethodCannotBeSynchronized(s, c, st));
784 } else if (s.isConstructor()) {
785 MethodSymbol m = (MethodSymbol)s;
786 if (m.getParameters().size() > 0) {
787 log.error(pos, Errors.SuperConstructorCannotTakeArguments(m, c, st));
788 } else {
789 if ((m.flags() & EMPTYNOARGCONSTR) == 0) {
790 log.error(pos, Errors.SuperNoArgConstructorMustBeEmpty(m, c, st));
791 }
792 }
793 }
794 break;
795 }
796 }
797 }
798 }
799
800 /** Check that type is a valid qualifier for a constructor reference expression
801 */
802 Type checkConstructorRefType(JCExpression expr, Type t) {
803 t = checkClassOrArrayType(expr, t);
804 if (t.hasTag(CLASS)) {
805 if ((t.tsym.flags() & (ABSTRACT | INTERFACE)) != 0) {
806 log.error(expr, Errors.AbstractCantBeInstantiated(t.tsym));
807 t = types.createErrorType(t);
808 } else if ((t.tsym.flags() & ENUM) != 0) {
809 log.error(expr, Errors.EnumCantBeInstantiated);
810 t = types.createErrorType(t);
811 } else {
812 // Projection types may not be mentioned in constructor references
813 if (expr.hasTag(SELECT)) {
814 JCFieldAccess fieldAccess = (JCFieldAccess) expr;
815 if (fieldAccess.selected.type.isPrimitiveClass() &&
816 (fieldAccess.name == names.ref || fieldAccess.name == names.val)) {
817 log.error(expr, Errors.ProjectionCantBeInstantiated);
818 t = types.createErrorType(t);
819 }
820 }
821 t = checkClassType(expr, t, true);
822 }
823 } else if (t.hasTag(ARRAY)) {
824 if (!types.isReifiable(((ArrayType)t).elemtype)) {
825 log.error(expr, Errors.GenericArrayCreation);
826 t = types.createErrorType(t);
827 }
828 }
829 return t;
830 }
831
832 /** Check that type is a class or interface type.
833 * @param pos Position to be used for error reporting.
834 * @param t The type to be checked.
835 * @param noBounds True if type bounds are illegal here.
836 */
837 Type checkClassType(DiagnosticPosition pos, Type t, boolean noBounds) {
838 t = checkClassType(pos, t);
839 if (noBounds && t.isParameterized()) {
840 List<Type> args = t.getTypeArguments();
841 while (args.nonEmpty()) {
842 if (args.head.hasTag(WILDCARD))
843 return typeTagError(pos,
844 diags.fragment(Fragments.TypeReqExact),
845 args.head);
846 args = args.tail;
847 }
848 }
849 return t;
850 }
851
852 /** Check that type is a reference type, i.e. a class, interface or array type
853 * or a type variable.
854 * @param pos Position to be used for error reporting.
855 * @param t The type to be checked.
856 * @param primitiveClassOK If false, a primitive class does not qualify
857 */
858 Type checkRefType(DiagnosticPosition pos, Type t, boolean primitiveClassOK) {
859 if (t.isReference() && (primitiveClassOK || !t.isPrimitiveClass()))
860 return t;
861 else
862 return typeTagError(pos,
863 diags.fragment(Fragments.TypeReqRef),
864 t);
865 }
866
867 /** Check that type is an identity type, i.e. not a primitive type
868 * nor its reference projection. When not discernible statically,
869 * give it the benefit of doubt and defer to runtime.
870 *
871 * @param pos Position to be used for error reporting.
872 * @param t The type to be checked.
873 */
874 Type checkIdentityType(DiagnosticPosition pos, Type t) {
875
876 if (t.isPrimitive() || t.isValueClass() || t.isReferenceProjection())
877 return typeTagError(pos,
878 diags.fragment(Fragments.TypeReqIdentity),
879 t);
880
881 return t;
882 }
883
884 /** Check that type is a reference type, i.e. a class, interface or array type
885 * or a type variable.
886 * @param pos Position to be used for error reporting.
887 * @param t The type to be checked.
888 */
889 Type checkRefType(DiagnosticPosition pos, Type t) {
890 return checkRefType(pos, t, true);
891 }
892
893 /** Check that each type is a reference type, i.e. a class, interface or array type
894 * or a type variable.
895 * @param trees Original trees, used for error reporting.
896 * @param types The types to be checked.
897 */
898 List<Type> checkRefTypes(List<JCExpression> trees, List<Type> types) {
899 List<JCExpression> tl = trees;
900 for (List<Type> l = types; l.nonEmpty(); l = l.tail) {
901 l.head = checkRefType(tl.head.pos(), l.head, false);
902 tl = tl.tail;
903 }
904 return types;
905 }
906
907 /** Check that type is a null or reference type.
908 * @param pos Position to be used for error reporting.
909 * @param t The type to be checked.
910 */
911 Type checkNullOrRefType(DiagnosticPosition pos, Type t) {
912 if (t.isReference() || t.hasTag(BOT))
913 return t;
914 else
915 return typeTagError(pos,
916 diags.fragment(Fragments.TypeReqRef),
917 t);
918 }
919
920 /** Check that flag set does not contain elements of two conflicting sets. s
921 * Return true if it doesn't.
922 * @param pos Position to be used for error reporting.
923 * @param flags The set of flags to be checked.
924 * @param set1 Conflicting flags set #1.
925 * @param set2 Conflicting flags set #2.
926 */
927 boolean checkDisjoint(DiagnosticPosition pos, long flags, long set1, long set2) {
928 if ((flags & set1) != 0 && (flags & set2) != 0) {
929 log.error(pos,
930 Errors.IllegalCombinationOfModifiers(asFlagSet(TreeInfo.firstFlag(flags & set1)),
931 asFlagSet(TreeInfo.firstFlag(flags & set2))));
932 return false;
933 } else
934 return true;
935 }
936
937 void checkParameterizationByPrimitiveClass(DiagnosticPosition pos, Type t) {
938 parameterizationByPrimitiveClassChecker.visit(t, pos);
939 }
940
941 /** parameterizationByPrimitiveClassChecker: A type visitor that descends down the given type looking for instances of primitive classes
942 * being used as type arguments and issues error against those usages.
943 */
944 private final Types.SimpleVisitor<Void, DiagnosticPosition> parameterizationByPrimitiveClassChecker =
945 new Types.SimpleVisitor<Void, DiagnosticPosition>() {
946
947 @Override
948 public Void visitType(Type t, DiagnosticPosition pos) {
949 return null;
950 }
951
952 @Override
953 public Void visitClassType(ClassType t, DiagnosticPosition pos) {
954 for (Type targ : t.allparams()) {
955 if (targ.isPrimitiveClass()) {
956 log.error(pos, Errors.GenericParameterizationWithPrimitiveClass(t));
957 }
958 visit(targ, pos);
959 }
960 return null;
961 }
962
963 @Override
964 public Void visitTypeVar(TypeVar t, DiagnosticPosition pos) {
965 return null;
966 }
967
968 @Override
969 public Void visitCapturedType(CapturedType t, DiagnosticPosition pos) {
970 return null;
971 }
972
973 @Override
974 public Void visitArrayType(ArrayType t, DiagnosticPosition pos) {
975 return visit(t.elemtype, pos);
976 }
977
978 @Override
979 public Void visitWildcardType(WildcardType t, DiagnosticPosition pos) {
980 return visit(t.type, pos);
981 }
982 };
983
984
985
986 /** Check that usage of diamond operator is correct (i.e. diamond should not
987 * be used with non-generic classes or in anonymous class creation expressions)
988 */
989 Type checkDiamond(JCNewClass tree, Type t) {
990 if (!TreeInfo.isDiamond(tree) ||
991 t.isErroneous()) {
992 return checkClassType(tree.clazz.pos(), t, true);
993 } else {
994 if (tree.def != null && !Feature.DIAMOND_WITH_ANONYMOUS_CLASS_CREATION.allowedInSource(source)) {
995 log.error(DiagnosticFlag.SOURCE_LEVEL, tree.clazz.pos(),
996 Errors.CantApplyDiamond1(t, Feature.DIAMOND_WITH_ANONYMOUS_CLASS_CREATION.fragment(source.name)));
997 }
998 if (t.tsym.type.getTypeArguments().isEmpty()) {
999 log.error(tree.clazz.pos(),
1000 Errors.CantApplyDiamond1(t,
1001 Fragments.DiamondNonGeneric(t)));
1002 return types.createErrorType(t);
1003 } else if (tree.typeargs != null &&
1004 tree.typeargs.nonEmpty()) {
1005 log.error(tree.clazz.pos(),
1114 }
1115 //where
1116 private boolean isTrustMeAllowedOnMethod(Symbol s) {
1117 return (s.flags() & VARARGS) != 0 &&
1118 (s.isConstructor() ||
1119 (s.flags() & (STATIC | FINAL |
1120 (Feature.PRIVATE_SAFE_VARARGS.allowedInSource(source) ? PRIVATE : 0) )) != 0);
1121 }
1122
1123 Type checkLocalVarType(DiagnosticPosition pos, Type t, Name name) {
1124 //check that resulting type is not the null type
1125 if (t.hasTag(BOT)) {
1126 log.error(pos, Errors.CantInferLocalVarType(name, Fragments.LocalCantInferNull));
1127 return types.createErrorType(t);
1128 } else if (t.hasTag(VOID)) {
1129 log.error(pos, Errors.CantInferLocalVarType(name, Fragments.LocalCantInferVoid));
1130 return types.createErrorType(t);
1131 }
1132
1133 //upward project the initializer type
1134 Type varType = types.upward(t, types.captures(t));
1135 if (varType.hasTag(CLASS)) {
1136 checkParameterizationByPrimitiveClass(pos, varType);
1137 }
1138 return varType;
1139 }
1140
1141 public void checkForSuspectClassLiteralComparison(
1142 final JCBinary tree,
1143 final Type leftType,
1144 final Type rightType) {
1145
1146 if (lint.isEnabled(LintCategory.MIGRATION)) {
1147 if (isInvocationOfGetClass(tree.lhs) && isClassOfSomeInterface(rightType) ||
1148 isInvocationOfGetClass(tree.rhs) && isClassOfSomeInterface(leftType)) {
1149 log.warning(LintCategory.MIGRATION, tree.pos(), Warnings.GetClassComparedWithInterface);
1150 }
1151 }
1152 }
1153 //where
1154 private boolean isClassOfSomeInterface(Type someClass) {
1155 if (someClass.tsym.flatName() == names.java_lang_Class) {
1156 List<Type> arguments = someClass.getTypeArguments();
1157 if (arguments.length() == 1) {
1158 return arguments.head.isInterface();
1159 }
1160 }
1161 return false;
1162 }
1163 //where
1164 private boolean isInvocationOfGetClass(JCExpression tree) {
1165 tree = TreeInfo.skipParens(tree);
1166 if (tree.hasTag(APPLY)) {
1167 JCMethodInvocation apply = (JCMethodInvocation)tree;
1168 MethodSymbol msym = (MethodSymbol)TreeInfo.symbol(apply.meth);
1169 return msym.name == names.getClass && msym.implementedIn(syms.objectType.tsym, types) != null;
1170 }
1171 return false;
1172 }
1173
1174 Type checkMethod(final Type mtype,
1175 final Symbol sym,
1176 final Env<AttrContext> env,
1177 final List<JCExpression> argtrees,
1178 final List<Type> argtypes,
1179 final boolean useVarargs,
1180 InferenceContext inferenceContext) {
1181 // System.out.println("call : " + env.tree);
1182 // System.out.println("method : " + owntype);
1183 // System.out.println("actuals: " + argtypes);
1184 if (inferenceContext.free(mtype)) {
1185 inferenceContext.addFreeTypeListener(List.of(mtype),
1186 solvedContext -> checkMethod(solvedContext.asInstType(mtype), sym, env, argtrees, argtypes, useVarargs, solvedContext));
1187 return mtype;
1188 }
1189 Type owntype = mtype;
1190 List<Type> formals = owntype.getParameterTypes();
1191 List<Type> nonInferred = sym.type.getParameterTypes();
1349 * return modifiers together with any implicit modifiers for that symbol.
1350 * Warning: we can't use flags() here since this method
1351 * is called during class enter, when flags() would cause a premature
1352 * completion.
1353 * @param pos Position to be used for error reporting.
1354 * @param flags The set of modifiers given in a definition.
1355 * @param sym The defined symbol.
1356 */
1357 long checkFlags(DiagnosticPosition pos, long flags, Symbol sym, JCTree tree) {
1358 long mask;
1359 long implicit = 0;
1360
1361 switch (sym.kind) {
1362 case VAR:
1363 if (TreeInfo.isReceiverParam(tree))
1364 mask = ReceiverParamFlags;
1365 else if (sym.owner.kind != TYP)
1366 mask = LocalVarFlags;
1367 else if ((sym.owner.flags_field & INTERFACE) != 0)
1368 mask = implicit = InterfaceVarFlags;
1369 else {
1370 mask = VarFlags;
1371 if (sym.owner.type.isValueClass() && (flags & STATIC) == 0) {
1372 implicit |= FINAL;
1373 }
1374 }
1375 break;
1376 case MTH:
1377 if (sym.name == names.init) {
1378 if ((sym.owner.flags_field & ENUM) != 0) {
1379 // enum constructors cannot be declared public or
1380 // protected and must be implicitly or explicitly
1381 // private
1382 implicit = PRIVATE;
1383 mask = PRIVATE;
1384 } else
1385 mask = ConstructorFlags;
1386 } else if ((sym.owner.flags_field & INTERFACE) != 0) {
1387 if ((sym.owner.flags_field & ANNOTATION) != 0) {
1388 mask = AnnotationTypeElementMask;
1389 implicit = PUBLIC | ABSTRACT;
1390 } else if ((flags & (DEFAULT | STATIC | PRIVATE)) != 0) {
1391 mask = InterfaceMethodMask;
1392 implicit = (flags & PRIVATE) != 0 ? 0 : PUBLIC;
1393 if ((flags & DEFAULT) != 0) {
1394 implicit |= ABSTRACT;
1395 }
1396 } else {
1397 mask = implicit = InterfaceMethodFlags;
1398 }
1399 } else if ((sym.owner.flags_field & RECORD) != 0) {
1400 mask = ((sym.owner.flags_field & VALUE_CLASS) != 0 && (flags & Flags.STATIC) == 0) ?
1401 RecordMethodFlags & ~SYNCHRONIZED : RecordMethodFlags;
1402 } else {
1403 // value objects do not have an associated monitor/lock
1404 mask = ((sym.owner.flags_field & VALUE_CLASS) != 0 && (flags & Flags.STATIC) == 0) ?
1405 MethodFlags & ~SYNCHRONIZED : MethodFlags;
1406 }
1407 if ((flags & STRICTFP) != 0) {
1408 warnOnExplicitStrictfp(pos);
1409 }
1410 // Imply STRICTFP if owner has STRICTFP set.
1411 if (((flags|implicit) & Flags.ABSTRACT) == 0 ||
1412 ((flags) & Flags.DEFAULT) != 0)
1413 implicit |= sym.owner.flags_field & STRICTFP;
1414 break;
1415 case TYP:
1416 if (sym.owner.kind.matches(KindSelector.VAL_MTH) ||
1417 (sym.isDirectlyOrIndirectlyLocal() && (flags & ANNOTATION) != 0)) {
1418 boolean implicitlyStatic = !sym.isAnonymous() &&
1419 ((flags & RECORD) != 0 || (flags & ENUM) != 0 || (flags & INTERFACE) != 0);
1420 boolean staticOrImplicitlyStatic = (flags & STATIC) != 0 || implicitlyStatic;
1421 // local statics are allowed only if records are allowed too
1422 mask = staticOrImplicitlyStatic && allowRecords && (flags & ANNOTATION) == 0 ? ExtendedStaticLocalClassFlags : ExtendedLocalClassFlags;
1423 implicit = implicitlyStatic ? STATIC : implicit;
1424 } else if (sym.owner.kind == TYP) {
1425 // statics in inner classes are allowed only if records are allowed too
1426 mask = ((flags & STATIC) != 0) && allowRecords && (flags & ANNOTATION) == 0 ? ExtendedMemberStaticClassFlags : ExtendedMemberClassFlags;
1427 if (sym.owner.owner.kind == PCK ||
1428 (sym.owner.flags_field & STATIC) != 0) {
1429 mask |= STATIC;
1430 } else if (!allowRecords && ((flags & ENUM) != 0 || (flags & RECORD) != 0)) {
1431 log.error(pos, Errors.StaticDeclarationNotAllowedInInnerClasses);
1432 }
1433 // Nested interfaces and enums are always STATIC (Spec ???)
1434 if ((flags & (INTERFACE | ENUM | RECORD)) != 0 ) implicit = STATIC;
1435 } else {
1436 mask = ExtendedClassFlags;
1437 }
1438 // Interfaces are always ABSTRACT
1439 if ((flags & INTERFACE) != 0) implicit |= ABSTRACT;
1440
1441 if ((flags & ENUM) != 0) {
1442 // enums can't be declared abstract, final, sealed or non-sealed or primitive/value
1443 mask &= ~(ABSTRACT | FINAL | SEALED | NON_SEALED | PRIMITIVE_CLASS | VALUE_CLASS);
1444 implicit |= implicitEnumFinalFlag(tree);
1445 }
1446 if ((flags & RECORD) != 0) {
1447 // records can't be declared abstract
1448 mask &= ~ABSTRACT;
1449 implicit |= FINAL;
1450 }
1451 if ((flags & STRICTFP) != 0) {
1452 warnOnExplicitStrictfp(pos);
1453 }
1454 // Imply STRICTFP if owner has STRICTFP set.
1455 implicit |= sym.owner.flags_field & STRICTFP;
1456
1457 // primitive classes are implicitly final value classes.
1458 if ((flags & PRIMITIVE_CLASS) != 0)
1459 implicit |= VALUE_CLASS | FINAL;
1460
1461 // concrete value classes are implicitly final
1462 if ((flags & (ABSTRACT | INTERFACE | VALUE_CLASS)) == VALUE_CLASS)
1463 implicit |= FINAL;
1464
1465 // TYPs can't be declared synchronized
1466 mask &= ~SYNCHRONIZED;
1467 break;
1468 default:
1469 throw new AssertionError();
1470 }
1471 long illegal = flags & ExtendedStandardFlags & ~mask;
1472 if (illegal != 0) {
1473 if ((illegal & INTERFACE) != 0) {
1474 log.error(pos, ((flags & ANNOTATION) != 0) ? Errors.AnnotationDeclNotAllowedHere : Errors.IntfNotAllowedHere);
1475 mask |= INTERFACE;
1476 }
1477 else {
1478 log.error(pos,
1479 Errors.ModNotAllowedHere(asFlagSet(illegal)));
1480 }
1481 }
1482 else if ((sym.kind == TYP ||
1483 // ISSUE: Disallowing abstract&private is no longer appropriate
1484 // in the presence of inner classes. Should it be deleted here?
1485 checkDisjoint(pos, flags,
1486 ABSTRACT,
1487 PRIVATE | STATIC | DEFAULT))
1488 &&
1489 checkDisjoint(pos, flags,
1490 STATIC | PRIVATE,
1491 DEFAULT)
1492 &&
1493 checkDisjoint(pos, flags,
1494 ABSTRACT | INTERFACE,
1495 FINAL | NATIVE | SYNCHRONIZED | PRIMITIVE_CLASS)
1496 &&
1497 checkDisjoint(pos, flags,
1498 IDENTITY_TYPE,
1499 PRIMITIVE_CLASS | VALUE_CLASS)
1500 &&
1501 checkDisjoint(pos, flags,
1502 PUBLIC,
1503 PRIVATE | PROTECTED)
1504 &&
1505 checkDisjoint(pos, flags,
1506 PRIVATE,
1507 PUBLIC | PROTECTED)
1508 &&
1509 checkDisjoint(pos, (flags | implicit), // complain against volatile & implcitly final entities too.
1510 FINAL,
1511 VOLATILE)
1512 &&
1513 (sym.kind == TYP ||
1514 checkDisjoint(pos, flags,
1515 ABSTRACT | NATIVE,
1516 STRICTFP))
1517 && checkDisjoint(pos, flags,
1518 FINAL,
1519 SEALED | NON_SEALED)
1520 && checkDisjoint(pos, flags,
1521 SEALED,
1522 FINAL | NON_SEALED)
1523 && checkDisjoint(pos, flags,
1524 SEALED,
1525 ANNOTATION)) {
1526 // skip
1527 }
1528 return flags & (mask | ~ExtendedStandardFlags) | implicit;
1529 }
1678 @Override
1679 public void visitWildcard(JCWildcard tree) {
1680 if (tree.inner != null)
1681 validateTree(tree.inner, true, isOuter);
1682 }
1683
1684 @Override
1685 public void visitSelect(JCFieldAccess tree) {
1686 if (tree.type.hasTag(CLASS)) {
1687 visitSelectInternal(tree);
1688
1689 // Check that this type is either fully parameterized, or
1690 // not parameterized at all.
1691 if (tree.selected.type.isParameterized() && tree.type.tsym.type.getTypeArguments().nonEmpty())
1692 log.error(tree.pos(), Errors.ImproperlyFormedTypeParamMissing);
1693 }
1694 }
1695
1696 public void visitSelectInternal(JCFieldAccess tree) {
1697 if (tree.type.tsym.isStatic() &&
1698 tree.selected.type.isParameterized() &&
1699 (tree.name != names.ref || !tree.type.isReferenceProjection())) {
1700 // The enclosing type is not a class, so we are
1701 // looking at a static member type. However, the
1702 // qualifying expression is parameterized.
1703 // Tolerate the pseudo-select V.ref: V<T>.ref will be static if V<T> is and
1704 // should not be confused as selecting a static member of a parameterized type.
1705 log.error(tree.pos(), Errors.CantSelectStaticClassFromParamType);
1706 } else {
1707 // otherwise validate the rest of the expression
1708 tree.selected.accept(this);
1709 }
1710 }
1711
1712 @Override
1713 public void visitAnnotatedType(JCAnnotatedType tree) {
1714 tree.underlyingType.accept(this);
1715 }
1716
1717 @Override
1718 public void visitTypeIdent(JCPrimitiveTypeTree that) {
1719 if (that.type.hasTag(TypeTag.VOID)) {
1720 log.error(that.pos(), Errors.VoidNotAllowedHere);
1721 }
1722 super.visitTypeIdent(that);
1723 }
1724
2011 return;
2012 }
2013
2014 if ((m.owner.flags() & ANNOTATION) != 0) {
2015 // handled in validateAnnotationMethod
2016 return;
2017 }
2018
2019 // Error if overriding method has weaker access (JLS 8.4.8.3).
2020 if (protection(m.flags()) > protection(other.flags())) {
2021 log.error(TreeInfo.diagnosticPositionFor(m, tree),
2022 (other.flags() & AccessFlags) == 0 ?
2023 Errors.OverrideWeakerAccess(cannotOverride(m, other),
2024 "package") :
2025 Errors.OverrideWeakerAccess(cannotOverride(m, other),
2026 asFlagSet(other.flags() & AccessFlags)));
2027 m.flags_field |= BAD_OVERRIDE;
2028 return;
2029 }
2030
2031 if (origin.isValueClass() && other.owner == syms.objectType.tsym && m.type.getParameterTypes().size() == 0) {
2032 if (m.name == names.finalize) {
2033 log.error(TreeInfo.diagnosticPositionFor(m, tree),
2034 Errors.ValueClassMayNotOverride(m.name));
2035 m.flags_field |= BAD_OVERRIDE;
2036 return;
2037 }
2038 }
2039
2040 Type mt = types.memberType(origin.type, m);
2041 Type ot = types.memberType(origin.type, other);
2042 // Error if overriding result type is different
2043 // (or, in the case of generics mode, not a subtype) of
2044 // overridden result type. We have to rename any type parameters
2045 // before comparing types.
2046 List<Type> mtvars = mt.getTypeArguments();
2047 List<Type> otvars = ot.getTypeArguments();
2048 Type mtres = mt.getReturnType();
2049 Type otres = types.subst(ot.getReturnType(), otvars, mtvars);
2050
2051 overrideWarner.clear();
2052 boolean resultTypesOK =
2053 types.returnTypeSubstitutable(mt, ot, otres, overrideWarner);
2054 if (!resultTypesOK) {
2055 if ((m.flags() & STATIC) != 0 && (other.flags() & STATIC) != 0) {
2056 log.error(TreeInfo.diagnosticPositionFor(m, tree),
2057 Errors.OverrideIncompatibleRet(Fragments.CantHide(m, m.location(), other,
2058 other.location()), mtres, otres));
2059 m.flags_field |= BAD_OVERRIDE;
2458 cf.test(s2) &&
2459 types.hasSameArgs(s1.erasure(types), s2.erasure(types)));
2460 }
2461
2462
2463 /** Check that all abstract members of given class have definitions.
2464 * @param pos Position to be used for error reporting.
2465 * @param c The class.
2466 */
2467 void checkAllDefined(DiagnosticPosition pos, ClassSymbol c) {
2468 MethodSymbol undef = types.firstUnimplementedAbstract(c);
2469 if (undef != null) {
2470 MethodSymbol undef1 =
2471 new MethodSymbol(undef.flags(), undef.name,
2472 types.memberType(c.type, undef), undef.owner);
2473 log.error(pos,
2474 Errors.DoesNotOverrideAbstract(c, undef1, undef1.location()));
2475 }
2476 }
2477
2478 // A primitive class cannot contain a field of its own type either or indirectly.
2479 void checkNonCyclicMembership(JCClassDecl tree) {
2480 Assert.check((tree.sym.flags_field & LOCKED) == 0);
2481 try {
2482 tree.sym.flags_field |= LOCKED;
2483 for (List<? extends JCTree> l = tree.defs; l.nonEmpty(); l = l.tail) {
2484 if (l.head.hasTag(VARDEF)) {
2485 JCVariableDecl field = (JCVariableDecl) l.head;
2486 if (cyclePossible(field.sym)) {
2487 checkNonCyclicMembership((ClassSymbol) field.type.tsym, field.pos());
2488 }
2489 }
2490 }
2491 } finally {
2492 tree.sym.flags_field &= ~LOCKED;
2493 }
2494
2495 }
2496 // where
2497 private void checkNonCyclicMembership(ClassSymbol c, DiagnosticPosition pos) {
2498 if ((c.flags_field & LOCKED) != 0) {
2499 log.error(pos, Errors.CyclicPrimitiveClassMembership(c));
2500 return;
2501 }
2502 try {
2503 c.flags_field |= LOCKED;
2504 for (Symbol fld : c.members().getSymbols(s -> s.kind == VAR && cyclePossible((VarSymbol) s), NON_RECURSIVE)) {
2505 checkNonCyclicMembership((ClassSymbol) fld.type.tsym, pos);
2506 }
2507 } finally {
2508 c.flags_field &= ~LOCKED;
2509 }
2510 }
2511 // where
2512 private boolean cyclePossible(VarSymbol symbol) {
2513 return (symbol.flags() & STATIC) == 0 && symbol.type.isPrimitiveClass();
2514 }
2515
2516 void checkNonCyclicDecl(JCClassDecl tree) {
2517 CycleChecker cc = new CycleChecker();
2518 cc.scan(tree);
2519 if (!cc.errorFound && !cc.partialCheck) {
2520 tree.sym.flags_field |= ACYCLIC;
2521 }
2522 }
2523
2524 class CycleChecker extends TreeScanner {
2525
2526 Set<Symbol> seenClasses = new HashSet<>();
2527 boolean errorFound = false;
2528 boolean partialCheck = false;
2529
2530 private void checkSymbol(DiagnosticPosition pos, Symbol sym) {
2531 if (sym != null && sym.kind == TYP) {
2532 Env<AttrContext> classEnv = enter.getEnv((TypeSymbol)sym);
2533 if (classEnv != null) {
2534 DiagnosticSource prevSource = log.currentSource();
2535 try {
2744 /** Check that all abstract methods implemented by a class are
2745 * mutually compatible.
2746 * @param pos Position to be used for error reporting.
2747 * @param c The class whose interfaces are checked.
2748 */
2749 void checkCompatibleSupertypes(DiagnosticPosition pos, Type c) {
2750 List<Type> supertypes = types.interfaces(c);
2751 Type supertype = types.supertype(c);
2752 if (supertype.hasTag(CLASS) &&
2753 (supertype.tsym.flags() & ABSTRACT) != 0)
2754 supertypes = supertypes.prepend(supertype);
2755 for (List<Type> l = supertypes; l.nonEmpty(); l = l.tail) {
2756 if (!l.head.getTypeArguments().isEmpty() &&
2757 !checkCompatibleAbstracts(pos, l.head, l.head, c))
2758 return;
2759 for (List<Type> m = supertypes; m != l; m = m.tail)
2760 if (!checkCompatibleAbstracts(pos, l.head, m.head, c))
2761 return;
2762 }
2763 checkCompatibleConcretes(pos, c);
2764
2765 boolean cIsValue = (c.tsym.flags() & VALUE_CLASS) != 0;
2766 boolean cHasIdentity = (c.tsym.flags() & IDENTITY_TYPE) != 0;
2767
2768 if (cIsValue || cHasIdentity) {
2769 List<Type> superTypes = types.closure(c);
2770 for (Type superType : superTypes) {
2771 if (cIsValue && (superType.tsym.flags() & IDENTITY_TYPE) != 0) {
2772 log.error(pos, Errors.ValueTypeHasIdentitySuperType(c, superType));
2773 } else if (cHasIdentity && (superType.tsym.flags() & VALUE_CLASS) != 0) {
2774 log.error(pos, Errors.IdentityTypeHasValueSuperType(c, superType));
2775 }
2776 }
2777 }
2778 }
2779
2780 /** Check that all non-override equivalent methods accessible from 'site'
2781 * are mutually compatible (JLS 8.4.8/9.4.1).
2782 *
2783 * @param pos Position to be used for error reporting.
2784 * @param site The class whose methods are checked.
2785 * @param sym The method symbol to be checked.
2786 */
2787 void checkOverrideClashes(DiagnosticPosition pos, Type site, MethodSymbol sym) {
2788 ClashFilter cf = new ClashFilter(site);
2789 //for each method m1 that is overridden (directly or indirectly)
2790 //by method 'sym' in 'site'...
2791
2792 List<MethodSymbol> potentiallyAmbiguousList = List.nil();
2793 boolean overridesAny = false;
2794 ArrayList<Symbol> symbolsByName = new ArrayList<>();
2795 types.membersClosure(site, false).getSymbolsByName(sym.name, cf).forEach(symbolsByName::add);
2796 for (Symbol m1 : symbolsByName) {
2797 if (!sym.overrides(m1, site.tsym, types, false)) {
|