Check.java revision 2804:de31f7bc10c7
1/* 2 * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26package com.sun.tools.javac.comp; 27 28import java.util.*; 29 30import javax.tools.JavaFileManager; 31 32import com.sun.tools.javac.code.*; 33import com.sun.tools.javac.code.Attribute.Compound; 34import com.sun.tools.javac.jvm.*; 35import com.sun.tools.javac.tree.*; 36import com.sun.tools.javac.util.*; 37import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition; 38import com.sun.tools.javac.util.List; 39 40import com.sun.tools.javac.code.Lint; 41import com.sun.tools.javac.code.Lint.LintCategory; 42import com.sun.tools.javac.code.Scope.CompoundScope; 43import com.sun.tools.javac.code.Scope.NamedImportScope; 44import com.sun.tools.javac.code.Scope.WriteableScope; 45import com.sun.tools.javac.code.Type.*; 46import com.sun.tools.javac.code.Symbol.*; 47import com.sun.tools.javac.comp.DeferredAttr.DeferredAttrContext; 48import com.sun.tools.javac.comp.Infer.InferenceContext; 49import com.sun.tools.javac.comp.Infer.FreeTypeListener; 50import com.sun.tools.javac.tree.JCTree.*; 51import com.sun.tools.javac.tree.JCTree.JCPolyExpression.*; 52 53import static com.sun.tools.javac.code.Flags.*; 54import static com.sun.tools.javac.code.Flags.ANNOTATION; 55import static com.sun.tools.javac.code.Flags.SYNCHRONIZED; 56import static com.sun.tools.javac.code.Kinds.*; 57import static com.sun.tools.javac.code.Kinds.Kind.*; 58import static com.sun.tools.javac.code.Scope.LookupKind.NON_RECURSIVE; 59import static com.sun.tools.javac.code.TypeTag.*; 60import static com.sun.tools.javac.code.TypeTag.WILDCARD; 61 62import static com.sun.tools.javac.tree.JCTree.Tag.*; 63 64/** Type checking helper class for the attribution phase. 65 * 66 * <p><b>This is NOT part of any supported API. 67 * If you write code that depends on this, you do so at your own risk. 68 * This code and its internal interfaces are subject to change or 69 * deletion without notice.</b> 70 */ 71public class Check { 72 protected static final Context.Key<Check> checkKey = new Context.Key<>(); 73 74 private final Names names; 75 private final Log log; 76 private final Resolve rs; 77 private final Symtab syms; 78 private final Enter enter; 79 private final DeferredAttr deferredAttr; 80 private final Infer infer; 81 private final Types types; 82 private final JCDiagnostic.Factory diags; 83 private boolean warnOnSyntheticConflicts; 84 private boolean suppressAbortOnBadClassFile; 85 private boolean enableSunApiLintControl; 86 private final TreeInfo treeinfo; 87 private final JavaFileManager fileManager; 88 private final Profile profile; 89 private final boolean warnOnAccessToSensitiveMembers; 90 91 // The set of lint options currently in effect. It is initialized 92 // from the context, and then is set/reset as needed by Attr as it 93 // visits all the various parts of the trees during attribution. 94 private Lint lint; 95 96 // The method being analyzed in Attr - it is set/reset as needed by 97 // Attr as it visits new method declarations. 98 private MethodSymbol method; 99 100 public static Check instance(Context context) { 101 Check instance = context.get(checkKey); 102 if (instance == null) 103 instance = new Check(context); 104 return instance; 105 } 106 107 protected Check(Context context) { 108 context.put(checkKey, this); 109 110 names = Names.instance(context); 111 dfltTargetMeta = new Name[] { names.PACKAGE, names.TYPE, 112 names.FIELD, names.METHOD, names.CONSTRUCTOR, 113 names.ANNOTATION_TYPE, names.LOCAL_VARIABLE, names.PARAMETER}; 114 log = Log.instance(context); 115 rs = Resolve.instance(context); 116 syms = Symtab.instance(context); 117 enter = Enter.instance(context); 118 deferredAttr = DeferredAttr.instance(context); 119 infer = Infer.instance(context); 120 types = Types.instance(context); 121 diags = JCDiagnostic.Factory.instance(context); 122 Options options = Options.instance(context); 123 lint = Lint.instance(context); 124 treeinfo = TreeInfo.instance(context); 125 fileManager = context.get(JavaFileManager.class); 126 127 Source source = Source.instance(context); 128 allowSimplifiedVarargs = source.allowSimplifiedVarargs(); 129 allowDefaultMethods = source.allowDefaultMethods(); 130 allowStrictMethodClashCheck = source.allowStrictMethodClashCheck(); 131 allowPrivateSafeVarargs = source.allowPrivateSafeVarargs(); 132 complexInference = options.isSet("complexinference"); 133 warnOnSyntheticConflicts = options.isSet("warnOnSyntheticConflicts"); 134 suppressAbortOnBadClassFile = options.isSet("suppressAbortOnBadClassFile"); 135 enableSunApiLintControl = options.isSet("enableSunApiLintControl"); 136 warnOnAccessToSensitiveMembers = options.isSet("warnOnAccessToSensitiveMembers"); 137 138 Target target = Target.instance(context); 139 syntheticNameChar = target.syntheticNameChar(); 140 141 profile = Profile.instance(context); 142 143 boolean verboseDeprecated = lint.isEnabled(LintCategory.DEPRECATION); 144 boolean verboseUnchecked = lint.isEnabled(LintCategory.UNCHECKED); 145 boolean verboseSunApi = lint.isEnabled(LintCategory.SUNAPI); 146 boolean enforceMandatoryWarnings = true; 147 148 deprecationHandler = new MandatoryWarningHandler(log, verboseDeprecated, 149 enforceMandatoryWarnings, "deprecated", LintCategory.DEPRECATION); 150 uncheckedHandler = new MandatoryWarningHandler(log, verboseUnchecked, 151 enforceMandatoryWarnings, "unchecked", LintCategory.UNCHECKED); 152 sunApiHandler = new MandatoryWarningHandler(log, verboseSunApi, 153 enforceMandatoryWarnings, "sunapi", null); 154 155 deferredLintHandler = DeferredLintHandler.instance(context); 156 } 157 158 /** Switch: simplified varargs enabled? 159 */ 160 boolean allowSimplifiedVarargs; 161 162 /** Switch: default methods enabled? 163 */ 164 boolean allowDefaultMethods; 165 166 /** Switch: should unrelated return types trigger a method clash? 167 */ 168 boolean allowStrictMethodClashCheck; 169 170 /** Switch: can the @SafeVarargs annotation be applied to private methods? 171 */ 172 boolean allowPrivateSafeVarargs; 173 174 /** Switch: -complexinference option set? 175 */ 176 boolean complexInference; 177 178 /** Character for synthetic names 179 */ 180 char syntheticNameChar; 181 182 /** A table mapping flat names of all compiled classes in this run to their 183 * symbols; maintained from outside. 184 */ 185 public Map<Name,ClassSymbol> compiled = new HashMap<>(); 186 187 /** A handler for messages about deprecated usage. 188 */ 189 private MandatoryWarningHandler deprecationHandler; 190 191 /** A handler for messages about unchecked or unsafe usage. 192 */ 193 private MandatoryWarningHandler uncheckedHandler; 194 195 /** A handler for messages about using proprietary API. 196 */ 197 private MandatoryWarningHandler sunApiHandler; 198 199 /** A handler for deferred lint warnings. 200 */ 201 private DeferredLintHandler deferredLintHandler; 202 203/* ************************************************************************* 204 * Errors and Warnings 205 **************************************************************************/ 206 207 Lint setLint(Lint newLint) { 208 Lint prev = lint; 209 lint = newLint; 210 return prev; 211 } 212 213 MethodSymbol setMethod(MethodSymbol newMethod) { 214 MethodSymbol prev = method; 215 method = newMethod; 216 return prev; 217 } 218 219 /** Warn about deprecated symbol. 220 * @param pos Position to be used for error reporting. 221 * @param sym The deprecated symbol. 222 */ 223 void warnDeprecated(DiagnosticPosition pos, Symbol sym) { 224 if (!lint.isSuppressed(LintCategory.DEPRECATION)) 225 deprecationHandler.report(pos, "has.been.deprecated", sym, sym.location()); 226 } 227 228 /** Warn about unchecked operation. 229 * @param pos Position to be used for error reporting. 230 * @param msg A string describing the problem. 231 */ 232 public void warnUnchecked(DiagnosticPosition pos, String msg, Object... args) { 233 if (!lint.isSuppressed(LintCategory.UNCHECKED)) 234 uncheckedHandler.report(pos, msg, args); 235 } 236 237 /** Warn about unsafe vararg method decl. 238 * @param pos Position to be used for error reporting. 239 */ 240 void warnUnsafeVararg(DiagnosticPosition pos, String key, Object... args) { 241 if (lint.isEnabled(LintCategory.VARARGS) && allowSimplifiedVarargs) 242 log.warning(LintCategory.VARARGS, pos, key, args); 243 } 244 245 /** Warn about using proprietary API. 246 * @param pos Position to be used for error reporting. 247 * @param msg A string describing the problem. 248 */ 249 public void warnSunApi(DiagnosticPosition pos, String msg, Object... args) { 250 if (!lint.isSuppressed(LintCategory.SUNAPI)) 251 sunApiHandler.report(pos, msg, args); 252 } 253 254 public void warnStatic(DiagnosticPosition pos, String msg, Object... args) { 255 if (lint.isEnabled(LintCategory.STATIC)) 256 log.warning(LintCategory.STATIC, pos, msg, args); 257 } 258 259 /** Warn about division by integer constant zero. 260 * @param pos Position to be used for error reporting. 261 */ 262 void warnDivZero(DiagnosticPosition pos) { 263 if (lint.isEnabled(LintCategory.DIVZERO)) 264 log.warning(LintCategory.DIVZERO, pos, "div.zero"); 265 } 266 267 /** 268 * Report any deferred diagnostics. 269 */ 270 public void reportDeferredDiagnostics() { 271 deprecationHandler.reportDeferredDiagnostic(); 272 uncheckedHandler.reportDeferredDiagnostic(); 273 sunApiHandler.reportDeferredDiagnostic(); 274 } 275 276 277 /** Report a failure to complete a class. 278 * @param pos Position to be used for error reporting. 279 * @param ex The failure to report. 280 */ 281 public Type completionError(DiagnosticPosition pos, CompletionFailure ex) { 282 log.error(JCDiagnostic.DiagnosticFlag.NON_DEFERRABLE, pos, "cant.access", ex.sym, ex.getDetailValue()); 283 if (ex instanceof ClassFinder.BadClassFile 284 && !suppressAbortOnBadClassFile) throw new Abort(); 285 else return syms.errType; 286 } 287 288 /** Report an error that wrong type tag was found. 289 * @param pos Position to be used for error reporting. 290 * @param required An internationalized string describing the type tag 291 * required. 292 * @param found The type that was found. 293 */ 294 Type typeTagError(DiagnosticPosition pos, Object required, Object found) { 295 // this error used to be raised by the parser, 296 // but has been delayed to this point: 297 if (found instanceof Type && ((Type)found).hasTag(VOID)) { 298 log.error(pos, "illegal.start.of.type"); 299 return syms.errType; 300 } 301 log.error(pos, "type.found.req", found, required); 302 return types.createErrorType(found instanceof Type ? (Type)found : syms.errType); 303 } 304 305 /** Report an error that symbol cannot be referenced before super 306 * has been called. 307 * @param pos Position to be used for error reporting. 308 * @param sym The referenced symbol. 309 */ 310 void earlyRefError(DiagnosticPosition pos, Symbol sym) { 311 log.error(pos, "cant.ref.before.ctor.called", sym); 312 } 313 314 /** Report duplicate declaration error. 315 */ 316 void duplicateError(DiagnosticPosition pos, Symbol sym) { 317 if (!sym.type.isErroneous()) { 318 Symbol location = sym.location(); 319 if (location.kind == MTH && 320 ((MethodSymbol)location).isStaticOrInstanceInit()) { 321 log.error(pos, "already.defined.in.clinit", kindName(sym), sym, 322 kindName(sym.location()), kindName(sym.location().enclClass()), 323 sym.location().enclClass()); 324 } else { 325 log.error(pos, "already.defined", kindName(sym), sym, 326 kindName(sym.location()), sym.location()); 327 } 328 } 329 } 330 331 /** Report array/varargs duplicate declaration 332 */ 333 void varargsDuplicateError(DiagnosticPosition pos, Symbol sym1, Symbol sym2) { 334 if (!sym1.type.isErroneous() && !sym2.type.isErroneous()) { 335 log.error(pos, "array.and.varargs", sym1, sym2, sym2.location()); 336 } 337 } 338 339/* ************************************************************************ 340 * duplicate declaration checking 341 *************************************************************************/ 342 343 /** Check that variable does not hide variable with same name in 344 * immediately enclosing local scope. 345 * @param pos Position for error reporting. 346 * @param v The symbol. 347 * @param s The scope. 348 */ 349 void checkTransparentVar(DiagnosticPosition pos, VarSymbol v, Scope s) { 350 for (Symbol sym : s.getSymbolsByName(v.name)) { 351 if (sym.owner != v.owner) break; 352 if (sym.kind == VAR && 353 sym.owner.kind.matches(KindSelector.VAL_MTH) && 354 v.name != names.error) { 355 duplicateError(pos, sym); 356 return; 357 } 358 } 359 } 360 361 /** Check that a class or interface does not hide a class or 362 * interface with same name in immediately enclosing local scope. 363 * @param pos Position for error reporting. 364 * @param c The symbol. 365 * @param s The scope. 366 */ 367 void checkTransparentClass(DiagnosticPosition pos, ClassSymbol c, Scope s) { 368 for (Symbol sym : s.getSymbolsByName(c.name)) { 369 if (sym.owner != c.owner) break; 370 if (sym.kind == TYP && !sym.type.hasTag(TYPEVAR) && 371 sym.owner.kind.matches(KindSelector.VAL_MTH) && 372 c.name != names.error) { 373 duplicateError(pos, sym); 374 return; 375 } 376 } 377 } 378 379 /** Check that class does not have the same name as one of 380 * its enclosing classes, or as a class defined in its enclosing scope. 381 * return true if class is unique in its enclosing scope. 382 * @param pos Position for error reporting. 383 * @param name The class name. 384 * @param s The enclosing scope. 385 */ 386 boolean checkUniqueClassName(DiagnosticPosition pos, Name name, Scope s) { 387 for (Symbol sym : s.getSymbolsByName(name, NON_RECURSIVE)) { 388 if (sym.kind == TYP && sym.name != names.error) { 389 duplicateError(pos, sym); 390 return false; 391 } 392 } 393 for (Symbol sym = s.owner; sym != null; sym = sym.owner) { 394 if (sym.kind == TYP && sym.name == name && sym.name != names.error) { 395 duplicateError(pos, sym); 396 return true; 397 } 398 } 399 return true; 400 } 401 402/* ************************************************************************* 403 * Class name generation 404 **************************************************************************/ 405 406 /** Return name of local class. 407 * This is of the form {@code <enclClass> $ n <classname> } 408 * where 409 * enclClass is the flat name of the enclosing class, 410 * classname is the simple name of the local class 411 */ 412 Name localClassName(ClassSymbol c) { 413 for (int i=1; ; i++) { 414 Name flatname = names. 415 fromString("" + c.owner.enclClass().flatname + 416 syntheticNameChar + i + 417 c.name); 418 if (compiled.get(flatname) == null) return flatname; 419 } 420 } 421 422 public void newRound() { 423 compiled.clear(); 424 } 425 426/* ************************************************************************* 427 * Type Checking 428 **************************************************************************/ 429 430 /** 431 * A check context is an object that can be used to perform compatibility 432 * checks - depending on the check context, meaning of 'compatibility' might 433 * vary significantly. 434 */ 435 public interface CheckContext { 436 /** 437 * Is type 'found' compatible with type 'req' in given context 438 */ 439 boolean compatible(Type found, Type req, Warner warn); 440 /** 441 * Report a check error 442 */ 443 void report(DiagnosticPosition pos, JCDiagnostic details); 444 /** 445 * Obtain a warner for this check context 446 */ 447 public Warner checkWarner(DiagnosticPosition pos, Type found, Type req); 448 449 public Infer.InferenceContext inferenceContext(); 450 451 public DeferredAttr.DeferredAttrContext deferredAttrContext(); 452 } 453 454 /** 455 * This class represent a check context that is nested within another check 456 * context - useful to check sub-expressions. The default behavior simply 457 * redirects all method calls to the enclosing check context leveraging 458 * the forwarding pattern. 459 */ 460 static class NestedCheckContext implements CheckContext { 461 CheckContext enclosingContext; 462 463 NestedCheckContext(CheckContext enclosingContext) { 464 this.enclosingContext = enclosingContext; 465 } 466 467 public boolean compatible(Type found, Type req, Warner warn) { 468 return enclosingContext.compatible(found, req, warn); 469 } 470 471 public void report(DiagnosticPosition pos, JCDiagnostic details) { 472 enclosingContext.report(pos, details); 473 } 474 475 public Warner checkWarner(DiagnosticPosition pos, Type found, Type req) { 476 return enclosingContext.checkWarner(pos, found, req); 477 } 478 479 public Infer.InferenceContext inferenceContext() { 480 return enclosingContext.inferenceContext(); 481 } 482 483 public DeferredAttrContext deferredAttrContext() { 484 return enclosingContext.deferredAttrContext(); 485 } 486 } 487 488 /** 489 * Check context to be used when evaluating assignment/return statements 490 */ 491 CheckContext basicHandler = new CheckContext() { 492 public void report(DiagnosticPosition pos, JCDiagnostic details) { 493 log.error(pos, "prob.found.req", details); 494 } 495 public boolean compatible(Type found, Type req, Warner warn) { 496 return types.isAssignable(found, req, warn); 497 } 498 499 public Warner checkWarner(DiagnosticPosition pos, Type found, Type req) { 500 return convertWarner(pos, found, req); 501 } 502 503 public InferenceContext inferenceContext() { 504 return infer.emptyContext; 505 } 506 507 public DeferredAttrContext deferredAttrContext() { 508 return deferredAttr.emptyDeferredAttrContext; 509 } 510 511 @Override 512 public String toString() { 513 return "CheckContext: basicHandler"; 514 } 515 }; 516 517 /** Check that a given type is assignable to a given proto-type. 518 * If it is, return the type, otherwise return errType. 519 * @param pos Position to be used for error reporting. 520 * @param found The type that was found. 521 * @param req The type that was required. 522 */ 523 Type checkType(DiagnosticPosition pos, Type found, Type req) { 524 return checkType(pos, found, req, basicHandler); 525 } 526 527 Type checkType(final DiagnosticPosition pos, final Type found, final Type req, final CheckContext checkContext) { 528 final Infer.InferenceContext inferenceContext = checkContext.inferenceContext(); 529 if (inferenceContext.free(req) || inferenceContext.free(found)) { 530 inferenceContext.addFreeTypeListener(List.of(req, found), new FreeTypeListener() { 531 @Override 532 public void typesInferred(InferenceContext inferenceContext) { 533 checkType(pos, inferenceContext.asInstType(found), inferenceContext.asInstType(req), checkContext); 534 } 535 }); 536 } 537 if (req.hasTag(ERROR)) 538 return req; 539 if (req.hasTag(NONE)) 540 return found; 541 if (checkContext.compatible(found, req, checkContext.checkWarner(pos, found, req))) { 542 return found; 543 } else { 544 if (found.isNumeric() && req.isNumeric()) { 545 checkContext.report(pos, diags.fragment("possible.loss.of.precision", found, req)); 546 return types.createErrorType(found); 547 } 548 checkContext.report(pos, diags.fragment("inconvertible.types", found, req)); 549 return types.createErrorType(found); 550 } 551 } 552 553 /** Check that a given type can be cast to a given target type. 554 * Return the result of the cast. 555 * @param pos Position to be used for error reporting. 556 * @param found The type that is being cast. 557 * @param req The target type of the cast. 558 */ 559 Type checkCastable(DiagnosticPosition pos, Type found, Type req) { 560 return checkCastable(pos, found, req, basicHandler); 561 } 562 Type checkCastable(DiagnosticPosition pos, Type found, Type req, CheckContext checkContext) { 563 if (types.isCastable(found, req, castWarner(pos, found, req))) { 564 return req; 565 } else { 566 checkContext.report(pos, diags.fragment("inconvertible.types", found, req)); 567 return types.createErrorType(found); 568 } 569 } 570 571 /** Check for redundant casts (i.e. where source type is a subtype of target type) 572 * The problem should only be reported for non-292 cast 573 */ 574 public void checkRedundantCast(Env<AttrContext> env, final JCTypeCast tree) { 575 if (!tree.type.isErroneous() 576 && types.isSameType(tree.expr.type, tree.clazz.type) 577 && !(ignoreAnnotatedCasts && TreeInfo.containsTypeAnnotation(tree.clazz)) 578 && !is292targetTypeCast(tree)) { 579 deferredLintHandler.report(new DeferredLintHandler.LintLogger() { 580 @Override 581 public void report() { 582 if (lint.isEnabled(Lint.LintCategory.CAST)) 583 log.warning(Lint.LintCategory.CAST, 584 tree.pos(), "redundant.cast", tree.expr.type); 585 } 586 }); 587 } 588 } 589 //where 590 private boolean is292targetTypeCast(JCTypeCast tree) { 591 boolean is292targetTypeCast = false; 592 JCExpression expr = TreeInfo.skipParens(tree.expr); 593 if (expr.hasTag(APPLY)) { 594 JCMethodInvocation apply = (JCMethodInvocation)expr; 595 Symbol sym = TreeInfo.symbol(apply.meth); 596 is292targetTypeCast = sym != null && 597 sym.kind == MTH && 598 (sym.flags() & HYPOTHETICAL) != 0; 599 } 600 return is292targetTypeCast; 601 } 602 603 private static final boolean ignoreAnnotatedCasts = true; 604 605 /** Check that a type is within some bounds. 606 * 607 * Used in TypeApply to verify that, e.g., X in {@code V<X>} is a valid 608 * type argument. 609 * @param a The type that should be bounded by bs. 610 * @param bound The bound. 611 */ 612 private boolean checkExtends(Type a, Type bound) { 613 if (a.isUnbound()) { 614 return true; 615 } else if (!a.hasTag(WILDCARD)) { 616 a = types.cvarUpperBound(a); 617 return types.isSubtype(a, bound); 618 } else if (a.isExtendsBound()) { 619 return types.isCastable(bound, types.wildUpperBound(a), types.noWarnings); 620 } else if (a.isSuperBound()) { 621 return !types.notSoftSubtype(types.wildLowerBound(a), bound); 622 } 623 return true; 624 } 625 626 /** Check that type is different from 'void'. 627 * @param pos Position to be used for error reporting. 628 * @param t The type to be checked. 629 */ 630 Type checkNonVoid(DiagnosticPosition pos, Type t) { 631 if (t.hasTag(VOID)) { 632 log.error(pos, "void.not.allowed.here"); 633 return types.createErrorType(t); 634 } else { 635 return t; 636 } 637 } 638 639 Type checkClassOrArrayType(DiagnosticPosition pos, Type t) { 640 if (!t.hasTag(CLASS) && !t.hasTag(ARRAY) && !t.hasTag(ERROR)) { 641 return typeTagError(pos, 642 diags.fragment("type.req.class.array"), 643 asTypeParam(t)); 644 } else { 645 return t; 646 } 647 } 648 649 /** Check that type is a class or interface type. 650 * @param pos Position to be used for error reporting. 651 * @param t The type to be checked. 652 */ 653 Type checkClassType(DiagnosticPosition pos, Type t) { 654 if (!t.hasTag(CLASS) && !t.hasTag(ERROR)) { 655 return typeTagError(pos, 656 diags.fragment("type.req.class"), 657 asTypeParam(t)); 658 } else { 659 return t; 660 } 661 } 662 //where 663 private Object asTypeParam(Type t) { 664 return (t.hasTag(TYPEVAR)) 665 ? diags.fragment("type.parameter", t) 666 : t; 667 } 668 669 /** Check that type is a valid qualifier for a constructor reference expression 670 */ 671 Type checkConstructorRefType(DiagnosticPosition pos, Type t) { 672 t = checkClassOrArrayType(pos, t); 673 if (t.hasTag(CLASS)) { 674 if ((t.tsym.flags() & (ABSTRACT | INTERFACE)) != 0) { 675 log.error(pos, "abstract.cant.be.instantiated", t.tsym); 676 t = types.createErrorType(t); 677 } else if ((t.tsym.flags() & ENUM) != 0) { 678 log.error(pos, "enum.cant.be.instantiated"); 679 t = types.createErrorType(t); 680 } else { 681 t = checkClassType(pos, t, true); 682 } 683 } else if (t.hasTag(ARRAY)) { 684 if (!types.isReifiable(((ArrayType)t).elemtype)) { 685 log.error(pos, "generic.array.creation"); 686 t = types.createErrorType(t); 687 } 688 } 689 return t; 690 } 691 692 /** Check that type is a class or interface type. 693 * @param pos Position to be used for error reporting. 694 * @param t The type to be checked. 695 * @param noBounds True if type bounds are illegal here. 696 */ 697 Type checkClassType(DiagnosticPosition pos, Type t, boolean noBounds) { 698 t = checkClassType(pos, t); 699 if (noBounds && t.isParameterized()) { 700 List<Type> args = t.getTypeArguments(); 701 while (args.nonEmpty()) { 702 if (args.head.hasTag(WILDCARD)) 703 return typeTagError(pos, 704 diags.fragment("type.req.exact"), 705 args.head); 706 args = args.tail; 707 } 708 } 709 return t; 710 } 711 712 /** Check that type is a reference type, i.e. a class, interface or array type 713 * or a type variable. 714 * @param pos Position to be used for error reporting. 715 * @param t The type to be checked. 716 */ 717 Type checkRefType(DiagnosticPosition pos, Type t) { 718 if (t.isReference()) 719 return t; 720 else 721 return typeTagError(pos, 722 diags.fragment("type.req.ref"), 723 t); 724 } 725 726 /** Check that each type is a reference type, i.e. a class, interface or array type 727 * or a type variable. 728 * @param trees Original trees, used for error reporting. 729 * @param types The types to be checked. 730 */ 731 List<Type> checkRefTypes(List<JCExpression> trees, List<Type> types) { 732 List<JCExpression> tl = trees; 733 for (List<Type> l = types; l.nonEmpty(); l = l.tail) { 734 l.head = checkRefType(tl.head.pos(), l.head); 735 tl = tl.tail; 736 } 737 return types; 738 } 739 740 /** Check that type is a null or reference type. 741 * @param pos Position to be used for error reporting. 742 * @param t The type to be checked. 743 */ 744 Type checkNullOrRefType(DiagnosticPosition pos, Type t) { 745 if (t.isReference() || t.hasTag(BOT)) 746 return t; 747 else 748 return typeTagError(pos, 749 diags.fragment("type.req.ref"), 750 t); 751 } 752 753 /** Check that flag set does not contain elements of two conflicting sets. s 754 * Return true if it doesn't. 755 * @param pos Position to be used for error reporting. 756 * @param flags The set of flags to be checked. 757 * @param set1 Conflicting flags set #1. 758 * @param set2 Conflicting flags set #2. 759 */ 760 boolean checkDisjoint(DiagnosticPosition pos, long flags, long set1, long set2) { 761 if ((flags & set1) != 0 && (flags & set2) != 0) { 762 log.error(pos, 763 "illegal.combination.of.modifiers", 764 asFlagSet(TreeInfo.firstFlag(flags & set1)), 765 asFlagSet(TreeInfo.firstFlag(flags & set2))); 766 return false; 767 } else 768 return true; 769 } 770 771 /** Check that usage of diamond operator is correct (i.e. diamond should not 772 * be used with non-generic classes or in anonymous class creation expressions) 773 */ 774 Type checkDiamond(JCNewClass tree, Type t) { 775 if (!TreeInfo.isDiamond(tree) || 776 t.isErroneous()) { 777 return checkClassType(tree.clazz.pos(), t, true); 778 } else if (tree.def != null) { 779 log.error(tree.clazz.pos(), 780 "cant.apply.diamond.1", 781 t, diags.fragment("diamond.and.anon.class", t)); 782 return types.createErrorType(t); 783 } else if (t.tsym.type.getTypeArguments().isEmpty()) { 784 log.error(tree.clazz.pos(), 785 "cant.apply.diamond.1", 786 t, diags.fragment("diamond.non.generic", t)); 787 return types.createErrorType(t); 788 } else if (tree.typeargs != null && 789 tree.typeargs.nonEmpty()) { 790 log.error(tree.clazz.pos(), 791 "cant.apply.diamond.1", 792 t, diags.fragment("diamond.and.explicit.params", t)); 793 return types.createErrorType(t); 794 } else { 795 return t; 796 } 797 } 798 799 void checkVarargsMethodDecl(Env<AttrContext> env, JCMethodDecl tree) { 800 MethodSymbol m = tree.sym; 801 if (!allowSimplifiedVarargs) return; 802 boolean hasTrustMeAnno = m.attribute(syms.trustMeType.tsym) != null; 803 Type varargElemType = null; 804 if (m.isVarArgs()) { 805 varargElemType = types.elemtype(tree.params.last().type); 806 } 807 if (hasTrustMeAnno && !isTrustMeAllowedOnMethod(m)) { 808 if (varargElemType != null) { 809 log.error(tree, 810 "varargs.invalid.trustme.anno", 811 syms.trustMeType.tsym, 812 allowPrivateSafeVarargs ? 813 diags.fragment("varargs.trustme.on.virtual.varargs", m) : 814 diags.fragment("varargs.trustme.on.virtual.varargs.final.only", m)); 815 } else { 816 log.error(tree, 817 "varargs.invalid.trustme.anno", 818 syms.trustMeType.tsym, 819 diags.fragment("varargs.trustme.on.non.varargs.meth", m)); 820 } 821 } else if (hasTrustMeAnno && varargElemType != null && 822 types.isReifiable(varargElemType)) { 823 warnUnsafeVararg(tree, 824 "varargs.redundant.trustme.anno", 825 syms.trustMeType.tsym, 826 diags.fragment("varargs.trustme.on.reifiable.varargs", varargElemType)); 827 } 828 else if (!hasTrustMeAnno && varargElemType != null && 829 !types.isReifiable(varargElemType)) { 830 warnUnchecked(tree.params.head.pos(), "unchecked.varargs.non.reifiable.type", varargElemType); 831 } 832 } 833 //where 834 private boolean isTrustMeAllowedOnMethod(Symbol s) { 835 return (s.flags() & VARARGS) != 0 && 836 (s.isConstructor() || 837 (s.flags() & (STATIC | FINAL | 838 (allowPrivateSafeVarargs ? PRIVATE : 0) )) != 0); 839 } 840 841 Type checkMethod(final Type mtype, 842 final Symbol sym, 843 final Env<AttrContext> env, 844 final List<JCExpression> argtrees, 845 final List<Type> argtypes, 846 final boolean useVarargs, 847 InferenceContext inferenceContext) { 848 // System.out.println("call : " + env.tree); 849 // System.out.println("method : " + owntype); 850 // System.out.println("actuals: " + argtypes); 851 if (inferenceContext.free(mtype)) { 852 inferenceContext.addFreeTypeListener(List.of(mtype), new FreeTypeListener() { 853 public void typesInferred(InferenceContext inferenceContext) { 854 checkMethod(inferenceContext.asInstType(mtype), sym, env, argtrees, argtypes, useVarargs, inferenceContext); 855 } 856 }); 857 return mtype; 858 } 859 Type owntype = mtype; 860 List<Type> formals = owntype.getParameterTypes(); 861 List<Type> nonInferred = sym.type.getParameterTypes(); 862 if (nonInferred.length() != formals.length()) nonInferred = formals; 863 Type last = useVarargs ? formals.last() : null; 864 if (sym.name == names.init && sym.owner == syms.enumSym) { 865 formals = formals.tail.tail; 866 nonInferred = nonInferred.tail.tail; 867 } 868 List<JCExpression> args = argtrees; 869 if (args != null) { 870 //this is null when type-checking a method reference 871 while (formals.head != last) { 872 JCTree arg = args.head; 873 Warner warn = convertWarner(arg.pos(), arg.type, nonInferred.head); 874 assertConvertible(arg, arg.type, formals.head, warn); 875 args = args.tail; 876 formals = formals.tail; 877 nonInferred = nonInferred.tail; 878 } 879 if (useVarargs) { 880 Type varArg = types.elemtype(last); 881 while (args.tail != null) { 882 JCTree arg = args.head; 883 Warner warn = convertWarner(arg.pos(), arg.type, varArg); 884 assertConvertible(arg, arg.type, varArg, warn); 885 args = args.tail; 886 } 887 } else if ((sym.flags() & (VARARGS | SIGNATURE_POLYMORPHIC)) == VARARGS) { 888 // non-varargs call to varargs method 889 Type varParam = owntype.getParameterTypes().last(); 890 Type lastArg = argtypes.last(); 891 if (types.isSubtypeUnchecked(lastArg, types.elemtype(varParam)) && 892 !types.isSameType(types.erasure(varParam), types.erasure(lastArg))) 893 log.warning(argtrees.last().pos(), "inexact.non-varargs.call", 894 types.elemtype(varParam), varParam); 895 } 896 } 897 if (useVarargs) { 898 Type argtype = owntype.getParameterTypes().last(); 899 if (!types.isReifiable(argtype) && 900 (!allowSimplifiedVarargs || 901 sym.baseSymbol().attribute(syms.trustMeType.tsym) == null || 902 !isTrustMeAllowedOnMethod(sym))) { 903 warnUnchecked(env.tree.pos(), 904 "unchecked.generic.array.creation", 905 argtype); 906 } 907 if ((sym.baseSymbol().flags() & SIGNATURE_POLYMORPHIC) == 0) { 908 TreeInfo.setVarargsElement(env.tree, types.elemtype(argtype)); 909 } 910 } 911 PolyKind pkind = (sym.type.hasTag(FORALL) && 912 sym.type.getReturnType().containsAny(((ForAll)sym.type).tvars)) ? 913 PolyKind.POLY : PolyKind.STANDALONE; 914 TreeInfo.setPolyKind(env.tree, pkind); 915 return owntype; 916 } 917 //where 918 private void assertConvertible(JCTree tree, Type actual, Type formal, Warner warn) { 919 if (types.isConvertible(actual, formal, warn)) 920 return; 921 922 if (formal.isCompound() 923 && types.isSubtype(actual, types.supertype(formal)) 924 && types.isSubtypeUnchecked(actual, types.interfaces(formal), warn)) 925 return; 926 } 927 928 /** 929 * Check that type 't' is a valid instantiation of a generic class 930 * (see JLS 4.5) 931 * 932 * @param t class type to be checked 933 * @return true if 't' is well-formed 934 */ 935 public boolean checkValidGenericType(Type t) { 936 return firstIncompatibleTypeArg(t) == null; 937 } 938 //WHERE 939 private Type firstIncompatibleTypeArg(Type type) { 940 List<Type> formals = type.tsym.type.allparams(); 941 List<Type> actuals = type.allparams(); 942 List<Type> args = type.getTypeArguments(); 943 List<Type> forms = type.tsym.type.getTypeArguments(); 944 ListBuffer<Type> bounds_buf = new ListBuffer<>(); 945 946 // For matching pairs of actual argument types `a' and 947 // formal type parameters with declared bound `b' ... 948 while (args.nonEmpty() && forms.nonEmpty()) { 949 // exact type arguments needs to know their 950 // bounds (for upper and lower bound 951 // calculations). So we create new bounds where 952 // type-parameters are replaced with actuals argument types. 953 bounds_buf.append(types.subst(forms.head.getUpperBound(), formals, actuals)); 954 args = args.tail; 955 forms = forms.tail; 956 } 957 958 args = type.getTypeArguments(); 959 List<Type> tvars_cap = types.substBounds(formals, 960 formals, 961 types.capture(type).allparams()); 962 while (args.nonEmpty() && tvars_cap.nonEmpty()) { 963 // Let the actual arguments know their bound 964 args.head.withTypeVar((TypeVar)tvars_cap.head); 965 args = args.tail; 966 tvars_cap = tvars_cap.tail; 967 } 968 969 args = type.getTypeArguments(); 970 List<Type> bounds = bounds_buf.toList(); 971 972 while (args.nonEmpty() && bounds.nonEmpty()) { 973 Type actual = args.head; 974 if (!isTypeArgErroneous(actual) && 975 !bounds.head.isErroneous() && 976 !checkExtends(actual, bounds.head)) { 977 return args.head; 978 } 979 args = args.tail; 980 bounds = bounds.tail; 981 } 982 983 args = type.getTypeArguments(); 984 bounds = bounds_buf.toList(); 985 986 for (Type arg : types.capture(type).getTypeArguments()) { 987 if (arg.hasTag(TYPEVAR) && 988 arg.getUpperBound().isErroneous() && 989 !bounds.head.isErroneous() && 990 !isTypeArgErroneous(args.head)) { 991 return args.head; 992 } 993 bounds = bounds.tail; 994 args = args.tail; 995 } 996 997 return null; 998 } 999 //where 1000 boolean isTypeArgErroneous(Type t) { 1001 return isTypeArgErroneous.visit(t); 1002 } 1003 1004 Types.UnaryVisitor<Boolean> isTypeArgErroneous = new Types.UnaryVisitor<Boolean>() { 1005 public Boolean visitType(Type t, Void s) { 1006 return t.isErroneous(); 1007 } 1008 @Override 1009 public Boolean visitTypeVar(TypeVar t, Void s) { 1010 return visit(t.getUpperBound()); 1011 } 1012 @Override 1013 public Boolean visitCapturedType(CapturedType t, Void s) { 1014 return visit(t.getUpperBound()) || 1015 visit(t.getLowerBound()); 1016 } 1017 @Override 1018 public Boolean visitWildcardType(WildcardType t, Void s) { 1019 return visit(t.type); 1020 } 1021 }; 1022 1023 /** Check that given modifiers are legal for given symbol and 1024 * return modifiers together with any implicit modifiers for that symbol. 1025 * Warning: we can't use flags() here since this method 1026 * is called during class enter, when flags() would cause a premature 1027 * completion. 1028 * @param pos Position to be used for error reporting. 1029 * @param flags The set of modifiers given in a definition. 1030 * @param sym The defined symbol. 1031 */ 1032 long checkFlags(DiagnosticPosition pos, long flags, Symbol sym, JCTree tree) { 1033 long mask; 1034 long implicit = 0; 1035 1036 switch (sym.kind) { 1037 case VAR: 1038 if (TreeInfo.isReceiverParam(tree)) 1039 mask = ReceiverParamFlags; 1040 else if (sym.owner.kind != TYP) 1041 mask = LocalVarFlags; 1042 else if ((sym.owner.flags_field & INTERFACE) != 0) 1043 mask = implicit = InterfaceVarFlags; 1044 else 1045 mask = VarFlags; 1046 break; 1047 case MTH: 1048 if (sym.name == names.init) { 1049 if ((sym.owner.flags_field & ENUM) != 0) { 1050 // enum constructors cannot be declared public or 1051 // protected and must be implicitly or explicitly 1052 // private 1053 implicit = PRIVATE; 1054 mask = PRIVATE; 1055 } else 1056 mask = ConstructorFlags; 1057 } else if ((sym.owner.flags_field & INTERFACE) != 0) { 1058 if ((sym.owner.flags_field & ANNOTATION) != 0) { 1059 mask = AnnotationTypeElementMask; 1060 implicit = PUBLIC | ABSTRACT; 1061 } else if ((flags & (DEFAULT | STATIC)) != 0) { 1062 mask = InterfaceMethodMask; 1063 implicit = PUBLIC; 1064 if ((flags & DEFAULT) != 0) { 1065 implicit |= ABSTRACT; 1066 } 1067 } else { 1068 mask = implicit = InterfaceMethodFlags; 1069 } 1070 } else { 1071 mask = MethodFlags; 1072 } 1073 // Imply STRICTFP if owner has STRICTFP set. 1074 if (((flags|implicit) & Flags.ABSTRACT) == 0 || 1075 ((flags) & Flags.DEFAULT) != 0) 1076 implicit |= sym.owner.flags_field & STRICTFP; 1077 break; 1078 case TYP: 1079 if (sym.isLocal()) { 1080 mask = LocalClassFlags; 1081 if (sym.name.isEmpty()) { // Anonymous class 1082 // JLS: Anonymous classes are final. 1083 implicit |= FINAL; 1084 } 1085 if ((sym.owner.flags_field & STATIC) == 0 && 1086 (flags & ENUM) != 0) 1087 log.error(pos, "enums.must.be.static"); 1088 } else if (sym.owner.kind == TYP) { 1089 mask = MemberClassFlags; 1090 if (sym.owner.owner.kind == PCK || 1091 (sym.owner.flags_field & STATIC) != 0) 1092 mask |= STATIC; 1093 else if ((flags & ENUM) != 0) 1094 log.error(pos, "enums.must.be.static"); 1095 // Nested interfaces and enums are always STATIC (Spec ???) 1096 if ((flags & (INTERFACE | ENUM)) != 0 ) implicit = STATIC; 1097 } else { 1098 mask = ClassFlags; 1099 } 1100 // Interfaces are always ABSTRACT 1101 if ((flags & INTERFACE) != 0) implicit |= ABSTRACT; 1102 1103 if ((flags & ENUM) != 0) { 1104 // enums can't be declared abstract or final 1105 mask &= ~(ABSTRACT | FINAL); 1106 implicit |= implicitEnumFinalFlag(tree); 1107 } 1108 // Imply STRICTFP if owner has STRICTFP set. 1109 implicit |= sym.owner.flags_field & STRICTFP; 1110 break; 1111 default: 1112 throw new AssertionError(); 1113 } 1114 long illegal = flags & ExtendedStandardFlags & ~mask; 1115 if (illegal != 0) { 1116 if ((illegal & INTERFACE) != 0) { 1117 log.error(pos, "intf.not.allowed.here"); 1118 mask |= INTERFACE; 1119 } 1120 else { 1121 log.error(pos, 1122 "mod.not.allowed.here", asFlagSet(illegal)); 1123 } 1124 } 1125 else if ((sym.kind == TYP || 1126 // ISSUE: Disallowing abstract&private is no longer appropriate 1127 // in the presence of inner classes. Should it be deleted here? 1128 checkDisjoint(pos, flags, 1129 ABSTRACT, 1130 PRIVATE | STATIC | DEFAULT)) 1131 && 1132 checkDisjoint(pos, flags, 1133 STATIC, 1134 DEFAULT) 1135 && 1136 checkDisjoint(pos, flags, 1137 ABSTRACT | INTERFACE, 1138 FINAL | NATIVE | SYNCHRONIZED) 1139 && 1140 checkDisjoint(pos, flags, 1141 PUBLIC, 1142 PRIVATE | PROTECTED) 1143 && 1144 checkDisjoint(pos, flags, 1145 PRIVATE, 1146 PUBLIC | PROTECTED) 1147 && 1148 checkDisjoint(pos, flags, 1149 FINAL, 1150 VOLATILE) 1151 && 1152 (sym.kind == TYP || 1153 checkDisjoint(pos, flags, 1154 ABSTRACT | NATIVE, 1155 STRICTFP))) { 1156 // skip 1157 } 1158 return flags & (mask | ~ExtendedStandardFlags) | implicit; 1159 } 1160 1161 1162 /** Determine if this enum should be implicitly final. 1163 * 1164 * If the enum has no specialized enum contants, it is final. 1165 * 1166 * If the enum does have specialized enum contants, it is 1167 * <i>not</i> final. 1168 */ 1169 private long implicitEnumFinalFlag(JCTree tree) { 1170 if (!tree.hasTag(CLASSDEF)) return 0; 1171 class SpecialTreeVisitor extends JCTree.Visitor { 1172 boolean specialized; 1173 SpecialTreeVisitor() { 1174 this.specialized = false; 1175 } 1176 1177 @Override 1178 public void visitTree(JCTree tree) { /* no-op */ } 1179 1180 @Override 1181 public void visitVarDef(JCVariableDecl tree) { 1182 if ((tree.mods.flags & ENUM) != 0) { 1183 if (tree.init instanceof JCNewClass && 1184 ((JCNewClass) tree.init).def != null) { 1185 specialized = true; 1186 } 1187 } 1188 } 1189 } 1190 1191 SpecialTreeVisitor sts = new SpecialTreeVisitor(); 1192 JCClassDecl cdef = (JCClassDecl) tree; 1193 for (JCTree defs: cdef.defs) { 1194 defs.accept(sts); 1195 if (sts.specialized) return 0; 1196 } 1197 return FINAL; 1198 } 1199 1200/* ************************************************************************* 1201 * Type Validation 1202 **************************************************************************/ 1203 1204 /** Validate a type expression. That is, 1205 * check that all type arguments of a parametric type are within 1206 * their bounds. This must be done in a second phase after type attribution 1207 * since a class might have a subclass as type parameter bound. E.g: 1208 * 1209 * <pre>{@code 1210 * class B<A extends C> { ... } 1211 * class C extends B<C> { ... } 1212 * }</pre> 1213 * 1214 * and we can't make sure that the bound is already attributed because 1215 * of possible cycles. 1216 * 1217 * Visitor method: Validate a type expression, if it is not null, catching 1218 * and reporting any completion failures. 1219 */ 1220 void validate(JCTree tree, Env<AttrContext> env) { 1221 validate(tree, env, true); 1222 } 1223 void validate(JCTree tree, Env<AttrContext> env, boolean checkRaw) { 1224 new Validator(env).validateTree(tree, checkRaw, true); 1225 } 1226 1227 /** Visitor method: Validate a list of type expressions. 1228 */ 1229 void validate(List<? extends JCTree> trees, Env<AttrContext> env) { 1230 for (List<? extends JCTree> l = trees; l.nonEmpty(); l = l.tail) 1231 validate(l.head, env); 1232 } 1233 1234 /** A visitor class for type validation. 1235 */ 1236 class Validator extends JCTree.Visitor { 1237 1238 boolean checkRaw; 1239 boolean isOuter; 1240 Env<AttrContext> env; 1241 1242 Validator(Env<AttrContext> env) { 1243 this.env = env; 1244 } 1245 1246 @Override 1247 public void visitTypeArray(JCArrayTypeTree tree) { 1248 validateTree(tree.elemtype, checkRaw, isOuter); 1249 } 1250 1251 @Override 1252 public void visitTypeApply(JCTypeApply tree) { 1253 if (tree.type.hasTag(CLASS)) { 1254 List<JCExpression> args = tree.arguments; 1255 List<Type> forms = tree.type.tsym.type.getTypeArguments(); 1256 1257 Type incompatibleArg = firstIncompatibleTypeArg(tree.type); 1258 if (incompatibleArg != null) { 1259 for (JCTree arg : tree.arguments) { 1260 if (arg.type == incompatibleArg) { 1261 log.error(arg, "not.within.bounds", incompatibleArg, forms.head); 1262 } 1263 forms = forms.tail; 1264 } 1265 } 1266 1267 forms = tree.type.tsym.type.getTypeArguments(); 1268 1269 boolean is_java_lang_Class = tree.type.tsym.flatName() == names.java_lang_Class; 1270 1271 // For matching pairs of actual argument types `a' and 1272 // formal type parameters with declared bound `b' ... 1273 while (args.nonEmpty() && forms.nonEmpty()) { 1274 validateTree(args.head, 1275 !(isOuter && is_java_lang_Class), 1276 false); 1277 args = args.tail; 1278 forms = forms.tail; 1279 } 1280 1281 // Check that this type is either fully parameterized, or 1282 // not parameterized at all. 1283 if (tree.type.getEnclosingType().isRaw()) 1284 log.error(tree.pos(), "improperly.formed.type.inner.raw.param"); 1285 if (tree.clazz.hasTag(SELECT)) 1286 visitSelectInternal((JCFieldAccess)tree.clazz); 1287 } 1288 } 1289 1290 @Override 1291 public void visitTypeParameter(JCTypeParameter tree) { 1292 validateTrees(tree.bounds, true, isOuter); 1293 checkClassBounds(tree.pos(), tree.type); 1294 } 1295 1296 @Override 1297 public void visitWildcard(JCWildcard tree) { 1298 if (tree.inner != null) 1299 validateTree(tree.inner, true, isOuter); 1300 } 1301 1302 @Override 1303 public void visitSelect(JCFieldAccess tree) { 1304 if (tree.type.hasTag(CLASS)) { 1305 visitSelectInternal(tree); 1306 1307 // Check that this type is either fully parameterized, or 1308 // not parameterized at all. 1309 if (tree.selected.type.isParameterized() && tree.type.tsym.type.getTypeArguments().nonEmpty()) 1310 log.error(tree.pos(), "improperly.formed.type.param.missing"); 1311 } 1312 } 1313 1314 public void visitSelectInternal(JCFieldAccess tree) { 1315 if (tree.type.tsym.isStatic() && 1316 tree.selected.type.isParameterized()) { 1317 // The enclosing type is not a class, so we are 1318 // looking at a static member type. However, the 1319 // qualifying expression is parameterized. 1320 log.error(tree.pos(), "cant.select.static.class.from.param.type"); 1321 } else { 1322 // otherwise validate the rest of the expression 1323 tree.selected.accept(this); 1324 } 1325 } 1326 1327 @Override 1328 public void visitAnnotatedType(JCAnnotatedType tree) { 1329 tree.underlyingType.accept(this); 1330 } 1331 1332 @Override 1333 public void visitTypeIdent(JCPrimitiveTypeTree that) { 1334 if (that.type.hasTag(TypeTag.VOID)) { 1335 log.error(that.pos(), "void.not.allowed.here"); 1336 } 1337 super.visitTypeIdent(that); 1338 } 1339 1340 /** Default visitor method: do nothing. 1341 */ 1342 @Override 1343 public void visitTree(JCTree tree) { 1344 } 1345 1346 public void validateTree(JCTree tree, boolean checkRaw, boolean isOuter) { 1347 if (tree != null) { 1348 boolean prevCheckRaw = this.checkRaw; 1349 this.checkRaw = checkRaw; 1350 this.isOuter = isOuter; 1351 1352 try { 1353 tree.accept(this); 1354 if (checkRaw) 1355 checkRaw(tree, env); 1356 } catch (CompletionFailure ex) { 1357 completionError(tree.pos(), ex); 1358 } finally { 1359 this.checkRaw = prevCheckRaw; 1360 } 1361 } 1362 } 1363 1364 public void validateTrees(List<? extends JCTree> trees, boolean checkRaw, boolean isOuter) { 1365 for (List<? extends JCTree> l = trees; l.nonEmpty(); l = l.tail) 1366 validateTree(l.head, checkRaw, isOuter); 1367 } 1368 } 1369 1370 void checkRaw(JCTree tree, Env<AttrContext> env) { 1371 if (lint.isEnabled(LintCategory.RAW) && 1372 tree.type.hasTag(CLASS) && 1373 !TreeInfo.isDiamond(tree) && 1374 !withinAnonConstr(env) && 1375 tree.type.isRaw()) { 1376 log.warning(LintCategory.RAW, 1377 tree.pos(), "raw.class.use", tree.type, tree.type.tsym.type); 1378 } 1379 } 1380 //where 1381 private boolean withinAnonConstr(Env<AttrContext> env) { 1382 return env.enclClass.name.isEmpty() && 1383 env.enclMethod != null && env.enclMethod.name == names.init; 1384 } 1385 1386/* ************************************************************************* 1387 * Exception checking 1388 **************************************************************************/ 1389 1390 /* The following methods treat classes as sets that contain 1391 * the class itself and all their subclasses 1392 */ 1393 1394 /** Is given type a subtype of some of the types in given list? 1395 */ 1396 boolean subset(Type t, List<Type> ts) { 1397 for (List<Type> l = ts; l.nonEmpty(); l = l.tail) 1398 if (types.isSubtype(t, l.head)) return true; 1399 return false; 1400 } 1401 1402 /** Is given type a subtype or supertype of 1403 * some of the types in given list? 1404 */ 1405 boolean intersects(Type t, List<Type> ts) { 1406 for (List<Type> l = ts; l.nonEmpty(); l = l.tail) 1407 if (types.isSubtype(t, l.head) || types.isSubtype(l.head, t)) return true; 1408 return false; 1409 } 1410 1411 /** Add type set to given type list, unless it is a subclass of some class 1412 * in the list. 1413 */ 1414 List<Type> incl(Type t, List<Type> ts) { 1415 return subset(t, ts) ? ts : excl(t, ts).prepend(t); 1416 } 1417 1418 /** Remove type set from type set list. 1419 */ 1420 List<Type> excl(Type t, List<Type> ts) { 1421 if (ts.isEmpty()) { 1422 return ts; 1423 } else { 1424 List<Type> ts1 = excl(t, ts.tail); 1425 if (types.isSubtype(ts.head, t)) return ts1; 1426 else if (ts1 == ts.tail) return ts; 1427 else return ts1.prepend(ts.head); 1428 } 1429 } 1430 1431 /** Form the union of two type set lists. 1432 */ 1433 List<Type> union(List<Type> ts1, List<Type> ts2) { 1434 List<Type> ts = ts1; 1435 for (List<Type> l = ts2; l.nonEmpty(); l = l.tail) 1436 ts = incl(l.head, ts); 1437 return ts; 1438 } 1439 1440 /** Form the difference of two type lists. 1441 */ 1442 List<Type> diff(List<Type> ts1, List<Type> ts2) { 1443 List<Type> ts = ts1; 1444 for (List<Type> l = ts2; l.nonEmpty(); l = l.tail) 1445 ts = excl(l.head, ts); 1446 return ts; 1447 } 1448 1449 /** Form the intersection of two type lists. 1450 */ 1451 public List<Type> intersect(List<Type> ts1, List<Type> ts2) { 1452 List<Type> ts = List.nil(); 1453 for (List<Type> l = ts1; l.nonEmpty(); l = l.tail) 1454 if (subset(l.head, ts2)) ts = incl(l.head, ts); 1455 for (List<Type> l = ts2; l.nonEmpty(); l = l.tail) 1456 if (subset(l.head, ts1)) ts = incl(l.head, ts); 1457 return ts; 1458 } 1459 1460 /** Is exc an exception symbol that need not be declared? 1461 */ 1462 boolean isUnchecked(ClassSymbol exc) { 1463 return 1464 exc.kind == ERR || 1465 exc.isSubClass(syms.errorType.tsym, types) || 1466 exc.isSubClass(syms.runtimeExceptionType.tsym, types); 1467 } 1468 1469 /** Is exc an exception type that need not be declared? 1470 */ 1471 boolean isUnchecked(Type exc) { 1472 return 1473 (exc.hasTag(TYPEVAR)) ? isUnchecked(types.supertype(exc)) : 1474 (exc.hasTag(CLASS)) ? isUnchecked((ClassSymbol)exc.tsym) : 1475 exc.hasTag(BOT); 1476 } 1477 1478 /** Same, but handling completion failures. 1479 */ 1480 boolean isUnchecked(DiagnosticPosition pos, Type exc) { 1481 try { 1482 return isUnchecked(exc); 1483 } catch (CompletionFailure ex) { 1484 completionError(pos, ex); 1485 return true; 1486 } 1487 } 1488 1489 /** Is exc handled by given exception list? 1490 */ 1491 boolean isHandled(Type exc, List<Type> handled) { 1492 return isUnchecked(exc) || subset(exc, handled); 1493 } 1494 1495 /** Return all exceptions in thrown list that are not in handled list. 1496 * @param thrown The list of thrown exceptions. 1497 * @param handled The list of handled exceptions. 1498 */ 1499 List<Type> unhandled(List<Type> thrown, List<Type> handled) { 1500 List<Type> unhandled = List.nil(); 1501 for (List<Type> l = thrown; l.nonEmpty(); l = l.tail) 1502 if (!isHandled(l.head, handled)) unhandled = unhandled.prepend(l.head); 1503 return unhandled; 1504 } 1505 1506/* ************************************************************************* 1507 * Overriding/Implementation checking 1508 **************************************************************************/ 1509 1510 /** The level of access protection given by a flag set, 1511 * where PRIVATE is highest and PUBLIC is lowest. 1512 */ 1513 static int protection(long flags) { 1514 switch ((short)(flags & AccessFlags)) { 1515 case PRIVATE: return 3; 1516 case PROTECTED: return 1; 1517 default: 1518 case PUBLIC: return 0; 1519 case 0: return 2; 1520 } 1521 } 1522 1523 /** A customized "cannot override" error message. 1524 * @param m The overriding method. 1525 * @param other The overridden method. 1526 * @return An internationalized string. 1527 */ 1528 Object cannotOverride(MethodSymbol m, MethodSymbol other) { 1529 String key; 1530 if ((other.owner.flags() & INTERFACE) == 0) 1531 key = "cant.override"; 1532 else if ((m.owner.flags() & INTERFACE) == 0) 1533 key = "cant.implement"; 1534 else 1535 key = "clashes.with"; 1536 return diags.fragment(key, m, m.location(), other, other.location()); 1537 } 1538 1539 /** A customized "override" warning message. 1540 * @param m The overriding method. 1541 * @param other The overridden method. 1542 * @return An internationalized string. 1543 */ 1544 Object uncheckedOverrides(MethodSymbol m, MethodSymbol other) { 1545 String key; 1546 if ((other.owner.flags() & INTERFACE) == 0) 1547 key = "unchecked.override"; 1548 else if ((m.owner.flags() & INTERFACE) == 0) 1549 key = "unchecked.implement"; 1550 else 1551 key = "unchecked.clash.with"; 1552 return diags.fragment(key, m, m.location(), other, other.location()); 1553 } 1554 1555 /** A customized "override" warning message. 1556 * @param m The overriding method. 1557 * @param other The overridden method. 1558 * @return An internationalized string. 1559 */ 1560 Object varargsOverrides(MethodSymbol m, MethodSymbol other) { 1561 String key; 1562 if ((other.owner.flags() & INTERFACE) == 0) 1563 key = "varargs.override"; 1564 else if ((m.owner.flags() & INTERFACE) == 0) 1565 key = "varargs.implement"; 1566 else 1567 key = "varargs.clash.with"; 1568 return diags.fragment(key, m, m.location(), other, other.location()); 1569 } 1570 1571 /** Check that this method conforms with overridden method 'other'. 1572 * where `origin' is the class where checking started. 1573 * Complications: 1574 * (1) Do not check overriding of synthetic methods 1575 * (reason: they might be final). 1576 * todo: check whether this is still necessary. 1577 * (2) Admit the case where an interface proxy throws fewer exceptions 1578 * than the method it implements. Augment the proxy methods with the 1579 * undeclared exceptions in this case. 1580 * (3) When generics are enabled, admit the case where an interface proxy 1581 * has a result type 1582 * extended by the result type of the method it implements. 1583 * Change the proxies result type to the smaller type in this case. 1584 * 1585 * @param tree The tree from which positions 1586 * are extracted for errors. 1587 * @param m The overriding method. 1588 * @param other The overridden method. 1589 * @param origin The class of which the overriding method 1590 * is a member. 1591 */ 1592 void checkOverride(JCTree tree, 1593 MethodSymbol m, 1594 MethodSymbol other, 1595 ClassSymbol origin) { 1596 // Don't check overriding of synthetic methods or by bridge methods. 1597 if ((m.flags() & (SYNTHETIC|BRIDGE)) != 0 || (other.flags() & SYNTHETIC) != 0) { 1598 return; 1599 } 1600 1601 // Error if static method overrides instance method (JLS 8.4.6.2). 1602 if ((m.flags() & STATIC) != 0 && 1603 (other.flags() & STATIC) == 0) { 1604 log.error(TreeInfo.diagnosticPositionFor(m, tree), "override.static", 1605 cannotOverride(m, other)); 1606 m.flags_field |= BAD_OVERRIDE; 1607 return; 1608 } 1609 1610 // Error if instance method overrides static or final 1611 // method (JLS 8.4.6.1). 1612 if ((other.flags() & FINAL) != 0 || 1613 (m.flags() & STATIC) == 0 && 1614 (other.flags() & STATIC) != 0) { 1615 log.error(TreeInfo.diagnosticPositionFor(m, tree), "override.meth", 1616 cannotOverride(m, other), 1617 asFlagSet(other.flags() & (FINAL | STATIC))); 1618 m.flags_field |= BAD_OVERRIDE; 1619 return; 1620 } 1621 1622 if ((m.owner.flags() & ANNOTATION) != 0) { 1623 // handled in validateAnnotationMethod 1624 return; 1625 } 1626 1627 // Error if overriding method has weaker access (JLS 8.4.6.3). 1628 if ((origin.flags() & INTERFACE) == 0 && 1629 protection(m.flags()) > protection(other.flags())) { 1630 log.error(TreeInfo.diagnosticPositionFor(m, tree), "override.weaker.access", 1631 cannotOverride(m, other), 1632 (other.flags() & AccessFlags) == 0 ? 1633 "package" : 1634 asFlagSet(other.flags() & AccessFlags)); 1635 m.flags_field |= BAD_OVERRIDE; 1636 return; 1637 } 1638 1639 Type mt = types.memberType(origin.type, m); 1640 Type ot = types.memberType(origin.type, other); 1641 // Error if overriding result type is different 1642 // (or, in the case of generics mode, not a subtype) of 1643 // overridden result type. We have to rename any type parameters 1644 // before comparing types. 1645 List<Type> mtvars = mt.getTypeArguments(); 1646 List<Type> otvars = ot.getTypeArguments(); 1647 Type mtres = mt.getReturnType(); 1648 Type otres = types.subst(ot.getReturnType(), otvars, mtvars); 1649 1650 overrideWarner.clear(); 1651 boolean resultTypesOK = 1652 types.returnTypeSubstitutable(mt, ot, otres, overrideWarner); 1653 if (!resultTypesOK) { 1654 log.error(TreeInfo.diagnosticPositionFor(m, tree), 1655 "override.incompatible.ret", 1656 cannotOverride(m, other), 1657 mtres, otres); 1658 m.flags_field |= BAD_OVERRIDE; 1659 return; 1660 } else if (overrideWarner.hasNonSilentLint(LintCategory.UNCHECKED)) { 1661 warnUnchecked(TreeInfo.diagnosticPositionFor(m, tree), 1662 "override.unchecked.ret", 1663 uncheckedOverrides(m, other), 1664 mtres, otres); 1665 } 1666 1667 // Error if overriding method throws an exception not reported 1668 // by overridden method. 1669 List<Type> otthrown = types.subst(ot.getThrownTypes(), otvars, mtvars); 1670 List<Type> unhandledErased = unhandled(mt.getThrownTypes(), types.erasure(otthrown)); 1671 List<Type> unhandledUnerased = unhandled(mt.getThrownTypes(), otthrown); 1672 if (unhandledErased.nonEmpty()) { 1673 log.error(TreeInfo.diagnosticPositionFor(m, tree), 1674 "override.meth.doesnt.throw", 1675 cannotOverride(m, other), 1676 unhandledUnerased.head); 1677 m.flags_field |= BAD_OVERRIDE; 1678 return; 1679 } 1680 else if (unhandledUnerased.nonEmpty()) { 1681 warnUnchecked(TreeInfo.diagnosticPositionFor(m, tree), 1682 "override.unchecked.thrown", 1683 cannotOverride(m, other), 1684 unhandledUnerased.head); 1685 return; 1686 } 1687 1688 // Optional warning if varargs don't agree 1689 if ((((m.flags() ^ other.flags()) & Flags.VARARGS) != 0) 1690 && lint.isEnabled(LintCategory.OVERRIDES)) { 1691 log.warning(TreeInfo.diagnosticPositionFor(m, tree), 1692 ((m.flags() & Flags.VARARGS) != 0) 1693 ? "override.varargs.missing" 1694 : "override.varargs.extra", 1695 varargsOverrides(m, other)); 1696 } 1697 1698 // Warn if instance method overrides bridge method (compiler spec ??) 1699 if ((other.flags() & BRIDGE) != 0) { 1700 log.warning(TreeInfo.diagnosticPositionFor(m, tree), "override.bridge", 1701 uncheckedOverrides(m, other)); 1702 } 1703 1704 // Warn if a deprecated method overridden by a non-deprecated one. 1705 if (!isDeprecatedOverrideIgnorable(other, origin)) { 1706 Lint prevLint = setLint(lint.augment(m)); 1707 try { 1708 checkDeprecated(TreeInfo.diagnosticPositionFor(m, tree), m, other); 1709 } finally { 1710 setLint(prevLint); 1711 } 1712 } 1713 } 1714 // where 1715 private boolean isDeprecatedOverrideIgnorable(MethodSymbol m, ClassSymbol origin) { 1716 // If the method, m, is defined in an interface, then ignore the issue if the method 1717 // is only inherited via a supertype and also implemented in the supertype, 1718 // because in that case, we will rediscover the issue when examining the method 1719 // in the supertype. 1720 // If the method, m, is not defined in an interface, then the only time we need to 1721 // address the issue is when the method is the supertype implemementation: any other 1722 // case, we will have dealt with when examining the supertype classes 1723 ClassSymbol mc = m.enclClass(); 1724 Type st = types.supertype(origin.type); 1725 if (!st.hasTag(CLASS)) 1726 return true; 1727 MethodSymbol stimpl = m.implementation((ClassSymbol)st.tsym, types, false); 1728 1729 if (mc != null && ((mc.flags() & INTERFACE) != 0)) { 1730 List<Type> intfs = types.interfaces(origin.type); 1731 return (intfs.contains(mc.type) ? false : (stimpl != null)); 1732 } 1733 else 1734 return (stimpl != m); 1735 } 1736 1737 1738 // used to check if there were any unchecked conversions 1739 Warner overrideWarner = new Warner(); 1740 1741 /** Check that a class does not inherit two concrete methods 1742 * with the same signature. 1743 * @param pos Position to be used for error reporting. 1744 * @param site The class type to be checked. 1745 */ 1746 public void checkCompatibleConcretes(DiagnosticPosition pos, Type site) { 1747 Type sup = types.supertype(site); 1748 if (!sup.hasTag(CLASS)) return; 1749 1750 for (Type t1 = sup; 1751 t1.hasTag(CLASS) && t1.tsym.type.isParameterized(); 1752 t1 = types.supertype(t1)) { 1753 for (Symbol s1 : t1.tsym.members().getSymbols(NON_RECURSIVE)) { 1754 if (s1.kind != MTH || 1755 (s1.flags() & (STATIC|SYNTHETIC|BRIDGE)) != 0 || 1756 !s1.isInheritedIn(site.tsym, types) || 1757 ((MethodSymbol)s1).implementation(site.tsym, 1758 types, 1759 true) != s1) 1760 continue; 1761 Type st1 = types.memberType(t1, s1); 1762 int s1ArgsLength = st1.getParameterTypes().length(); 1763 if (st1 == s1.type) continue; 1764 1765 for (Type t2 = sup; 1766 t2.hasTag(CLASS); 1767 t2 = types.supertype(t2)) { 1768 for (Symbol s2 : t2.tsym.members().getSymbolsByName(s1.name)) { 1769 if (s2 == s1 || 1770 s2.kind != MTH || 1771 (s2.flags() & (STATIC|SYNTHETIC|BRIDGE)) != 0 || 1772 s2.type.getParameterTypes().length() != s1ArgsLength || 1773 !s2.isInheritedIn(site.tsym, types) || 1774 ((MethodSymbol)s2).implementation(site.tsym, 1775 types, 1776 true) != s2) 1777 continue; 1778 Type st2 = types.memberType(t2, s2); 1779 if (types.overrideEquivalent(st1, st2)) 1780 log.error(pos, "concrete.inheritance.conflict", 1781 s1, t1, s2, t2, sup); 1782 } 1783 } 1784 } 1785 } 1786 } 1787 1788 /** Check that classes (or interfaces) do not each define an abstract 1789 * method with same name and arguments but incompatible return types. 1790 * @param pos Position to be used for error reporting. 1791 * @param t1 The first argument type. 1792 * @param t2 The second argument type. 1793 */ 1794 public boolean checkCompatibleAbstracts(DiagnosticPosition pos, 1795 Type t1, 1796 Type t2, 1797 Type site) { 1798 if ((site.tsym.flags() & COMPOUND) != 0) { 1799 // special case for intersections: need to eliminate wildcards in supertypes 1800 t1 = types.capture(t1); 1801 t2 = types.capture(t2); 1802 } 1803 return firstIncompatibility(pos, t1, t2, site) == null; 1804 } 1805 1806 /** Return the first method which is defined with same args 1807 * but different return types in two given interfaces, or null if none 1808 * exists. 1809 * @param t1 The first type. 1810 * @param t2 The second type. 1811 * @param site The most derived type. 1812 * @returns symbol from t2 that conflicts with one in t1. 1813 */ 1814 private Symbol firstIncompatibility(DiagnosticPosition pos, Type t1, Type t2, Type site) { 1815 Map<TypeSymbol,Type> interfaces1 = new HashMap<>(); 1816 closure(t1, interfaces1); 1817 Map<TypeSymbol,Type> interfaces2; 1818 if (t1 == t2) 1819 interfaces2 = interfaces1; 1820 else 1821 closure(t2, interfaces1, interfaces2 = new HashMap<>()); 1822 1823 for (Type t3 : interfaces1.values()) { 1824 for (Type t4 : interfaces2.values()) { 1825 Symbol s = firstDirectIncompatibility(pos, t3, t4, site); 1826 if (s != null) return s; 1827 } 1828 } 1829 return null; 1830 } 1831 1832 /** Compute all the supertypes of t, indexed by type symbol. */ 1833 private void closure(Type t, Map<TypeSymbol,Type> typeMap) { 1834 if (!t.hasTag(CLASS)) return; 1835 if (typeMap.put(t.tsym, t) == null) { 1836 closure(types.supertype(t), typeMap); 1837 for (Type i : types.interfaces(t)) 1838 closure(i, typeMap); 1839 } 1840 } 1841 1842 /** Compute all the supertypes of t, indexed by type symbol (except thise in typesSkip). */ 1843 private void closure(Type t, Map<TypeSymbol,Type> typesSkip, Map<TypeSymbol,Type> typeMap) { 1844 if (!t.hasTag(CLASS)) return; 1845 if (typesSkip.get(t.tsym) != null) return; 1846 if (typeMap.put(t.tsym, t) == null) { 1847 closure(types.supertype(t), typesSkip, typeMap); 1848 for (Type i : types.interfaces(t)) 1849 closure(i, typesSkip, typeMap); 1850 } 1851 } 1852 1853 /** Return the first method in t2 that conflicts with a method from t1. */ 1854 private Symbol firstDirectIncompatibility(DiagnosticPosition pos, Type t1, Type t2, Type site) { 1855 for (Symbol s1 : t1.tsym.members().getSymbols(NON_RECURSIVE)) { 1856 Type st1 = null; 1857 if (s1.kind != MTH || !s1.isInheritedIn(site.tsym, types) || 1858 (s1.flags() & SYNTHETIC) != 0) continue; 1859 Symbol impl = ((MethodSymbol)s1).implementation(site.tsym, types, false); 1860 if (impl != null && (impl.flags() & ABSTRACT) == 0) continue; 1861 for (Symbol s2 : t2.tsym.members().getSymbolsByName(s1.name)) { 1862 if (s1 == s2) continue; 1863 if (s2.kind != MTH || !s2.isInheritedIn(site.tsym, types) || 1864 (s2.flags() & SYNTHETIC) != 0) continue; 1865 if (st1 == null) st1 = types.memberType(t1, s1); 1866 Type st2 = types.memberType(t2, s2); 1867 if (types.overrideEquivalent(st1, st2)) { 1868 List<Type> tvars1 = st1.getTypeArguments(); 1869 List<Type> tvars2 = st2.getTypeArguments(); 1870 Type rt1 = st1.getReturnType(); 1871 Type rt2 = types.subst(st2.getReturnType(), tvars2, tvars1); 1872 boolean compat = 1873 types.isSameType(rt1, rt2) || 1874 !rt1.isPrimitiveOrVoid() && 1875 !rt2.isPrimitiveOrVoid() && 1876 (types.covariantReturnType(rt1, rt2, types.noWarnings) || 1877 types.covariantReturnType(rt2, rt1, types.noWarnings)) || 1878 checkCommonOverriderIn(s1,s2,site); 1879 if (!compat) { 1880 log.error(pos, "types.incompatible.diff.ret", 1881 t1, t2, s2.name + 1882 "(" + types.memberType(t2, s2).getParameterTypes() + ")"); 1883 return s2; 1884 } 1885 } else if (checkNameClash((ClassSymbol)site.tsym, s1, s2) && 1886 !checkCommonOverriderIn(s1, s2, site)) { 1887 log.error(pos, 1888 "name.clash.same.erasure.no.override", 1889 s1, s1.location(), 1890 s2, s2.location()); 1891 return s2; 1892 } 1893 } 1894 } 1895 return null; 1896 } 1897 //WHERE 1898 boolean checkCommonOverriderIn(Symbol s1, Symbol s2, Type site) { 1899 Map<TypeSymbol,Type> supertypes = new HashMap<>(); 1900 Type st1 = types.memberType(site, s1); 1901 Type st2 = types.memberType(site, s2); 1902 closure(site, supertypes); 1903 for (Type t : supertypes.values()) { 1904 for (Symbol s3 : t.tsym.members().getSymbolsByName(s1.name)) { 1905 if (s3 == s1 || s3 == s2 || s3.kind != MTH || (s3.flags() & (BRIDGE|SYNTHETIC)) != 0) continue; 1906 Type st3 = types.memberType(site,s3); 1907 if (types.overrideEquivalent(st3, st1) && 1908 types.overrideEquivalent(st3, st2) && 1909 types.returnTypeSubstitutable(st3, st1) && 1910 types.returnTypeSubstitutable(st3, st2)) { 1911 return true; 1912 } 1913 } 1914 } 1915 return false; 1916 } 1917 1918 /** Check that a given method conforms with any method it overrides. 1919 * @param tree The tree from which positions are extracted 1920 * for errors. 1921 * @param m The overriding method. 1922 */ 1923 void checkOverride(JCMethodDecl tree, MethodSymbol m) { 1924 ClassSymbol origin = (ClassSymbol)m.owner; 1925 if ((origin.flags() & ENUM) != 0 && names.finalize.equals(m.name)) 1926 if (m.overrides(syms.enumFinalFinalize, origin, types, false)) { 1927 log.error(tree.pos(), "enum.no.finalize"); 1928 return; 1929 } 1930 for (Type t = origin.type; t.hasTag(CLASS); 1931 t = types.supertype(t)) { 1932 if (t != origin.type) { 1933 checkOverride(tree, t, origin, m); 1934 } 1935 for (Type t2 : types.interfaces(t)) { 1936 checkOverride(tree, t2, origin, m); 1937 } 1938 } 1939 1940 if (m.attribute(syms.overrideType.tsym) != null && !isOverrider(m)) { 1941 DiagnosticPosition pos = tree.pos(); 1942 for (JCAnnotation a : tree.getModifiers().annotations) { 1943 if (a.annotationType.type.tsym == syms.overrideType.tsym) { 1944 pos = a.pos(); 1945 break; 1946 } 1947 } 1948 log.error(pos, "method.does.not.override.superclass"); 1949 } 1950 } 1951 1952 void checkOverride(JCTree tree, Type site, ClassSymbol origin, MethodSymbol m) { 1953 TypeSymbol c = site.tsym; 1954 for (Symbol sym : c.members().getSymbolsByName(m.name)) { 1955 if (m.overrides(sym, origin, types, false)) { 1956 if ((sym.flags() & ABSTRACT) == 0) { 1957 checkOverride(tree, m, (MethodSymbol)sym, origin); 1958 } 1959 } 1960 } 1961 } 1962 1963 private Filter<Symbol> equalsHasCodeFilter = new Filter<Symbol>() { 1964 public boolean accepts(Symbol s) { 1965 return MethodSymbol.implementation_filter.accepts(s) && 1966 (s.flags() & BAD_OVERRIDE) == 0; 1967 1968 } 1969 }; 1970 1971 public void checkClassOverrideEqualsAndHashIfNeeded(DiagnosticPosition pos, 1972 ClassSymbol someClass) { 1973 /* At present, annotations cannot possibly have a method that is override 1974 * equivalent with Object.equals(Object) but in any case the condition is 1975 * fine for completeness. 1976 */ 1977 if (someClass == (ClassSymbol)syms.objectType.tsym || 1978 someClass.isInterface() || someClass.isEnum() || 1979 (someClass.flags() & ANNOTATION) != 0 || 1980 (someClass.flags() & ABSTRACT) != 0) return; 1981 //anonymous inner classes implementing interfaces need especial treatment 1982 if (someClass.isAnonymous()) { 1983 List<Type> interfaces = types.interfaces(someClass.type); 1984 if (interfaces != null && !interfaces.isEmpty() && 1985 interfaces.head.tsym == syms.comparatorType.tsym) return; 1986 } 1987 checkClassOverrideEqualsAndHash(pos, someClass); 1988 } 1989 1990 private void checkClassOverrideEqualsAndHash(DiagnosticPosition pos, 1991 ClassSymbol someClass) { 1992 if (lint.isEnabled(LintCategory.OVERRIDES)) { 1993 MethodSymbol equalsAtObject = (MethodSymbol)syms.objectType 1994 .tsym.members().findFirst(names.equals); 1995 MethodSymbol hashCodeAtObject = (MethodSymbol)syms.objectType 1996 .tsym.members().findFirst(names.hashCode); 1997 boolean overridesEquals = types.implementation(equalsAtObject, 1998 someClass, false, equalsHasCodeFilter).owner == someClass; 1999 boolean overridesHashCode = types.implementation(hashCodeAtObject, 2000 someClass, false, equalsHasCodeFilter) != hashCodeAtObject; 2001 2002 if (overridesEquals && !overridesHashCode) { 2003 log.warning(LintCategory.OVERRIDES, pos, 2004 "override.equals.but.not.hashcode", someClass); 2005 } 2006 } 2007 } 2008 2009 private boolean checkNameClash(ClassSymbol origin, Symbol s1, Symbol s2) { 2010 ClashFilter cf = new ClashFilter(origin.type); 2011 return (cf.accepts(s1) && 2012 cf.accepts(s2) && 2013 types.hasSameArgs(s1.erasure(types), s2.erasure(types))); 2014 } 2015 2016 2017 /** Check that all abstract members of given class have definitions. 2018 * @param pos Position to be used for error reporting. 2019 * @param c The class. 2020 */ 2021 void checkAllDefined(DiagnosticPosition pos, ClassSymbol c) { 2022 MethodSymbol undef = types.firstUnimplementedAbstract(c); 2023 if (undef != null) { 2024 MethodSymbol undef1 = 2025 new MethodSymbol(undef.flags(), undef.name, 2026 types.memberType(c.type, undef), undef.owner); 2027 log.error(pos, "does.not.override.abstract", 2028 c, undef1, undef1.location()); 2029 } 2030 } 2031 2032 void checkNonCyclicDecl(JCClassDecl tree) { 2033 CycleChecker cc = new CycleChecker(); 2034 cc.scan(tree); 2035 if (!cc.errorFound && !cc.partialCheck) { 2036 tree.sym.flags_field |= ACYCLIC; 2037 } 2038 } 2039 2040 class CycleChecker extends TreeScanner { 2041 2042 List<Symbol> seenClasses = List.nil(); 2043 boolean errorFound = false; 2044 boolean partialCheck = false; 2045 2046 private void checkSymbol(DiagnosticPosition pos, Symbol sym) { 2047 if (sym != null && sym.kind == TYP) { 2048 Env<AttrContext> classEnv = enter.getEnv((TypeSymbol)sym); 2049 if (classEnv != null) { 2050 DiagnosticSource prevSource = log.currentSource(); 2051 try { 2052 log.useSource(classEnv.toplevel.sourcefile); 2053 scan(classEnv.tree); 2054 } 2055 finally { 2056 log.useSource(prevSource.getFile()); 2057 } 2058 } else if (sym.kind == TYP) { 2059 checkClass(pos, sym, List.<JCTree>nil()); 2060 } 2061 } else { 2062 //not completed yet 2063 partialCheck = true; 2064 } 2065 } 2066 2067 @Override 2068 public void visitSelect(JCFieldAccess tree) { 2069 super.visitSelect(tree); 2070 checkSymbol(tree.pos(), tree.sym); 2071 } 2072 2073 @Override 2074 public void visitIdent(JCIdent tree) { 2075 checkSymbol(tree.pos(), tree.sym); 2076 } 2077 2078 @Override 2079 public void visitTypeApply(JCTypeApply tree) { 2080 scan(tree.clazz); 2081 } 2082 2083 @Override 2084 public void visitTypeArray(JCArrayTypeTree tree) { 2085 scan(tree.elemtype); 2086 } 2087 2088 @Override 2089 public void visitClassDef(JCClassDecl tree) { 2090 List<JCTree> supertypes = List.nil(); 2091 if (tree.getExtendsClause() != null) { 2092 supertypes = supertypes.prepend(tree.getExtendsClause()); 2093 } 2094 if (tree.getImplementsClause() != null) { 2095 for (JCTree intf : tree.getImplementsClause()) { 2096 supertypes = supertypes.prepend(intf); 2097 } 2098 } 2099 checkClass(tree.pos(), tree.sym, supertypes); 2100 } 2101 2102 void checkClass(DiagnosticPosition pos, Symbol c, List<JCTree> supertypes) { 2103 if ((c.flags_field & ACYCLIC) != 0) 2104 return; 2105 if (seenClasses.contains(c)) { 2106 errorFound = true; 2107 noteCyclic(pos, (ClassSymbol)c); 2108 } else if (!c.type.isErroneous()) { 2109 try { 2110 seenClasses = seenClasses.prepend(c); 2111 if (c.type.hasTag(CLASS)) { 2112 if (supertypes.nonEmpty()) { 2113 scan(supertypes); 2114 } 2115 else { 2116 ClassType ct = (ClassType)c.type; 2117 if (ct.supertype_field == null || 2118 ct.interfaces_field == null) { 2119 //not completed yet 2120 partialCheck = true; 2121 return; 2122 } 2123 checkSymbol(pos, ct.supertype_field.tsym); 2124 for (Type intf : ct.interfaces_field) { 2125 checkSymbol(pos, intf.tsym); 2126 } 2127 } 2128 if (c.owner.kind == TYP) { 2129 checkSymbol(pos, c.owner); 2130 } 2131 } 2132 } finally { 2133 seenClasses = seenClasses.tail; 2134 } 2135 } 2136 } 2137 } 2138 2139 /** Check for cyclic references. Issue an error if the 2140 * symbol of the type referred to has a LOCKED flag set. 2141 * 2142 * @param pos Position to be used for error reporting. 2143 * @param t The type referred to. 2144 */ 2145 void checkNonCyclic(DiagnosticPosition pos, Type t) { 2146 checkNonCyclicInternal(pos, t); 2147 } 2148 2149 2150 void checkNonCyclic(DiagnosticPosition pos, TypeVar t) { 2151 checkNonCyclic1(pos, t, List.<TypeVar>nil()); 2152 } 2153 2154 private void checkNonCyclic1(DiagnosticPosition pos, Type t, List<TypeVar> seen) { 2155 final TypeVar tv; 2156 if (t.hasTag(TYPEVAR) && (t.tsym.flags() & UNATTRIBUTED) != 0) 2157 return; 2158 if (seen.contains(t)) { 2159 tv = (TypeVar)t; 2160 tv.bound = types.createErrorType(t); 2161 log.error(pos, "cyclic.inheritance", t); 2162 } else if (t.hasTag(TYPEVAR)) { 2163 tv = (TypeVar)t; 2164 seen = seen.prepend(tv); 2165 for (Type b : types.getBounds(tv)) 2166 checkNonCyclic1(pos, b, seen); 2167 } 2168 } 2169 2170 /** Check for cyclic references. Issue an error if the 2171 * symbol of the type referred to has a LOCKED flag set. 2172 * 2173 * @param pos Position to be used for error reporting. 2174 * @param t The type referred to. 2175 * @returns True if the check completed on all attributed classes 2176 */ 2177 private boolean checkNonCyclicInternal(DiagnosticPosition pos, Type t) { 2178 boolean complete = true; // was the check complete? 2179 //- System.err.println("checkNonCyclicInternal("+t+");");//DEBUG 2180 Symbol c = t.tsym; 2181 if ((c.flags_field & ACYCLIC) != 0) return true; 2182 2183 if ((c.flags_field & LOCKED) != 0) { 2184 noteCyclic(pos, (ClassSymbol)c); 2185 } else if (!c.type.isErroneous()) { 2186 try { 2187 c.flags_field |= LOCKED; 2188 if (c.type.hasTag(CLASS)) { 2189 ClassType clazz = (ClassType)c.type; 2190 if (clazz.interfaces_field != null) 2191 for (List<Type> l=clazz.interfaces_field; l.nonEmpty(); l=l.tail) 2192 complete &= checkNonCyclicInternal(pos, l.head); 2193 if (clazz.supertype_field != null) { 2194 Type st = clazz.supertype_field; 2195 if (st != null && st.hasTag(CLASS)) 2196 complete &= checkNonCyclicInternal(pos, st); 2197 } 2198 if (c.owner.kind == TYP) 2199 complete &= checkNonCyclicInternal(pos, c.owner.type); 2200 } 2201 } finally { 2202 c.flags_field &= ~LOCKED; 2203 } 2204 } 2205 if (complete) 2206 complete = ((c.flags_field & UNATTRIBUTED) == 0) && c.completer == null; 2207 if (complete) c.flags_field |= ACYCLIC; 2208 return complete; 2209 } 2210 2211 /** Note that we found an inheritance cycle. */ 2212 private void noteCyclic(DiagnosticPosition pos, ClassSymbol c) { 2213 log.error(pos, "cyclic.inheritance", c); 2214 for (List<Type> l=types.interfaces(c.type); l.nonEmpty(); l=l.tail) 2215 l.head = types.createErrorType((ClassSymbol)l.head.tsym, Type.noType); 2216 Type st = types.supertype(c.type); 2217 if (st.hasTag(CLASS)) 2218 ((ClassType)c.type).supertype_field = types.createErrorType((ClassSymbol)st.tsym, Type.noType); 2219 c.type = types.createErrorType(c, c.type); 2220 c.flags_field |= ACYCLIC; 2221 } 2222 2223 /** Check that all methods which implement some 2224 * method conform to the method they implement. 2225 * @param tree The class definition whose members are checked. 2226 */ 2227 void checkImplementations(JCClassDecl tree) { 2228 checkImplementations(tree, tree.sym, tree.sym); 2229 } 2230 //where 2231 /** Check that all methods which implement some 2232 * method in `ic' conform to the method they implement. 2233 */ 2234 void checkImplementations(JCTree tree, ClassSymbol origin, ClassSymbol ic) { 2235 for (List<Type> l = types.closure(ic.type); l.nonEmpty(); l = l.tail) { 2236 ClassSymbol lc = (ClassSymbol)l.head.tsym; 2237 if ((lc.flags() & ABSTRACT) != 0) { 2238 for (Symbol sym : lc.members().getSymbols(NON_RECURSIVE)) { 2239 if (sym.kind == MTH && 2240 (sym.flags() & (STATIC|ABSTRACT)) == ABSTRACT) { 2241 MethodSymbol absmeth = (MethodSymbol)sym; 2242 MethodSymbol implmeth = absmeth.implementation(origin, types, false); 2243 if (implmeth != null && implmeth != absmeth && 2244 (implmeth.owner.flags() & INTERFACE) == 2245 (origin.flags() & INTERFACE)) { 2246 // don't check if implmeth is in a class, yet 2247 // origin is an interface. This case arises only 2248 // if implmeth is declared in Object. The reason is 2249 // that interfaces really don't inherit from 2250 // Object it's just that the compiler represents 2251 // things that way. 2252 checkOverride(tree, implmeth, absmeth, origin); 2253 } 2254 } 2255 } 2256 } 2257 } 2258 } 2259 2260 /** Check that all abstract methods implemented by a class are 2261 * mutually compatible. 2262 * @param pos Position to be used for error reporting. 2263 * @param c The class whose interfaces are checked. 2264 */ 2265 void checkCompatibleSupertypes(DiagnosticPosition pos, Type c) { 2266 List<Type> supertypes = types.interfaces(c); 2267 Type supertype = types.supertype(c); 2268 if (supertype.hasTag(CLASS) && 2269 (supertype.tsym.flags() & ABSTRACT) != 0) 2270 supertypes = supertypes.prepend(supertype); 2271 for (List<Type> l = supertypes; l.nonEmpty(); l = l.tail) { 2272 if (!l.head.getTypeArguments().isEmpty() && 2273 !checkCompatibleAbstracts(pos, l.head, l.head, c)) 2274 return; 2275 for (List<Type> m = supertypes; m != l; m = m.tail) 2276 if (!checkCompatibleAbstracts(pos, l.head, m.head, c)) 2277 return; 2278 } 2279 checkCompatibleConcretes(pos, c); 2280 } 2281 2282 void checkConflicts(DiagnosticPosition pos, Symbol sym, TypeSymbol c) { 2283 for (Type ct = c.type; ct != Type.noType ; ct = types.supertype(ct)) { 2284 for (Symbol sym2 : ct.tsym.members().getSymbolsByName(sym.name, NON_RECURSIVE)) { 2285 // VM allows methods and variables with differing types 2286 if (sym.kind == sym2.kind && 2287 types.isSameType(types.erasure(sym.type), types.erasure(sym2.type)) && 2288 sym != sym2 && 2289 (sym.flags() & Flags.SYNTHETIC) != (sym2.flags() & Flags.SYNTHETIC) && 2290 (sym.flags() & IPROXY) == 0 && (sym2.flags() & IPROXY) == 0 && 2291 (sym.flags() & BRIDGE) == 0 && (sym2.flags() & BRIDGE) == 0) { 2292 syntheticError(pos, (sym2.flags() & SYNTHETIC) == 0 ? sym2 : sym); 2293 return; 2294 } 2295 } 2296 } 2297 } 2298 2299 /** Check that all non-override equivalent methods accessible from 'site' 2300 * are mutually compatible (JLS 8.4.8/9.4.1). 2301 * 2302 * @param pos Position to be used for error reporting. 2303 * @param site The class whose methods are checked. 2304 * @param sym The method symbol to be checked. 2305 */ 2306 void checkOverrideClashes(DiagnosticPosition pos, Type site, MethodSymbol sym) { 2307 ClashFilter cf = new ClashFilter(site); 2308 //for each method m1 that is overridden (directly or indirectly) 2309 //by method 'sym' in 'site'... 2310 2311 List<MethodSymbol> potentiallyAmbiguousList = List.nil(); 2312 boolean overridesAny = false; 2313 for (Symbol m1 : types.membersClosure(site, false).getSymbolsByName(sym.name, cf)) { 2314 if (!sym.overrides(m1, site.tsym, types, false)) { 2315 if (m1 == sym) { 2316 continue; 2317 } 2318 2319 if (!overridesAny) { 2320 potentiallyAmbiguousList = potentiallyAmbiguousList.prepend((MethodSymbol)m1); 2321 } 2322 continue; 2323 } 2324 2325 if (m1 != sym) { 2326 overridesAny = true; 2327 potentiallyAmbiguousList = List.nil(); 2328 } 2329 2330 //...check each method m2 that is a member of 'site' 2331 for (Symbol m2 : types.membersClosure(site, false).getSymbolsByName(sym.name, cf)) { 2332 if (m2 == m1) continue; 2333 //if (i) the signature of 'sym' is not a subsignature of m1 (seen as 2334 //a member of 'site') and (ii) m1 has the same erasure as m2, issue an error 2335 if (!types.isSubSignature(sym.type, types.memberType(site, m2), allowStrictMethodClashCheck) && 2336 types.hasSameArgs(m2.erasure(types), m1.erasure(types))) { 2337 sym.flags_field |= CLASH; 2338 String key = m1 == sym ? 2339 "name.clash.same.erasure.no.override" : 2340 "name.clash.same.erasure.no.override.1"; 2341 log.error(pos, 2342 key, 2343 sym, sym.location(), 2344 m2, m2.location(), 2345 m1, m1.location()); 2346 return; 2347 } 2348 } 2349 } 2350 2351 if (!overridesAny) { 2352 for (MethodSymbol m: potentiallyAmbiguousList) { 2353 checkPotentiallyAmbiguousOverloads(pos, site, sym, m); 2354 } 2355 } 2356 } 2357 2358 /** Check that all static methods accessible from 'site' are 2359 * mutually compatible (JLS 8.4.8). 2360 * 2361 * @param pos Position to be used for error reporting. 2362 * @param site The class whose methods are checked. 2363 * @param sym The method symbol to be checked. 2364 */ 2365 void checkHideClashes(DiagnosticPosition pos, Type site, MethodSymbol sym) { 2366 ClashFilter cf = new ClashFilter(site); 2367 //for each method m1 that is a member of 'site'... 2368 for (Symbol s : types.membersClosure(site, true).getSymbolsByName(sym.name, cf)) { 2369 //if (i) the signature of 'sym' is not a subsignature of m1 (seen as 2370 //a member of 'site') and (ii) 'sym' has the same erasure as m1, issue an error 2371 if (!types.isSubSignature(sym.type, types.memberType(site, s), allowStrictMethodClashCheck)) { 2372 if (types.hasSameArgs(s.erasure(types), sym.erasure(types))) { 2373 log.error(pos, 2374 "name.clash.same.erasure.no.hide", 2375 sym, sym.location(), 2376 s, s.location()); 2377 return; 2378 } else { 2379 checkPotentiallyAmbiguousOverloads(pos, site, sym, (MethodSymbol)s); 2380 } 2381 } 2382 } 2383 } 2384 2385 //where 2386 private class ClashFilter implements Filter<Symbol> { 2387 2388 Type site; 2389 2390 ClashFilter(Type site) { 2391 this.site = site; 2392 } 2393 2394 boolean shouldSkip(Symbol s) { 2395 return (s.flags() & CLASH) != 0 && 2396 s.owner == site.tsym; 2397 } 2398 2399 public boolean accepts(Symbol s) { 2400 return s.kind == MTH && 2401 (s.flags() & SYNTHETIC) == 0 && 2402 !shouldSkip(s) && 2403 s.isInheritedIn(site.tsym, types) && 2404 !s.isConstructor(); 2405 } 2406 } 2407 2408 void checkDefaultMethodClashes(DiagnosticPosition pos, Type site) { 2409 DefaultMethodClashFilter dcf = new DefaultMethodClashFilter(site); 2410 for (Symbol m : types.membersClosure(site, false).getSymbols(dcf)) { 2411 Assert.check(m.kind == MTH); 2412 List<MethodSymbol> prov = types.interfaceCandidates(site, (MethodSymbol)m); 2413 if (prov.size() > 1) { 2414 ListBuffer<Symbol> abstracts = new ListBuffer<>(); 2415 ListBuffer<Symbol> defaults = new ListBuffer<>(); 2416 for (MethodSymbol provSym : prov) { 2417 if ((provSym.flags() & DEFAULT) != 0) { 2418 defaults = defaults.append(provSym); 2419 } else if ((provSym.flags() & ABSTRACT) != 0) { 2420 abstracts = abstracts.append(provSym); 2421 } 2422 if (defaults.nonEmpty() && defaults.size() + abstracts.size() >= 2) { 2423 //strong semantics - issue an error if two sibling interfaces 2424 //have two override-equivalent defaults - or if one is abstract 2425 //and the other is default 2426 String errKey; 2427 Symbol s1 = defaults.first(); 2428 Symbol s2; 2429 if (defaults.size() > 1) { 2430 errKey = "types.incompatible.unrelated.defaults"; 2431 s2 = defaults.toList().tail.head; 2432 } else { 2433 errKey = "types.incompatible.abstract.default"; 2434 s2 = abstracts.first(); 2435 } 2436 log.error(pos, errKey, 2437 Kinds.kindName(site.tsym), site, 2438 m.name, types.memberType(site, m).getParameterTypes(), 2439 s1.location(), s2.location()); 2440 break; 2441 } 2442 } 2443 } 2444 } 2445 } 2446 2447 //where 2448 private class DefaultMethodClashFilter implements Filter<Symbol> { 2449 2450 Type site; 2451 2452 DefaultMethodClashFilter(Type site) { 2453 this.site = site; 2454 } 2455 2456 public boolean accepts(Symbol s) { 2457 return s.kind == MTH && 2458 (s.flags() & DEFAULT) != 0 && 2459 s.isInheritedIn(site.tsym, types) && 2460 !s.isConstructor(); 2461 } 2462 } 2463 2464 /** 2465 * Report warnings for potentially ambiguous method declarations. Two declarations 2466 * are potentially ambiguous if they feature two unrelated functional interface 2467 * in same argument position (in which case, a call site passing an implicit 2468 * lambda would be ambiguous). 2469 */ 2470 void checkPotentiallyAmbiguousOverloads(DiagnosticPosition pos, Type site, 2471 MethodSymbol msym1, MethodSymbol msym2) { 2472 if (msym1 != msym2 && 2473 allowDefaultMethods && 2474 lint.isEnabled(LintCategory.OVERLOADS) && 2475 (msym1.flags() & POTENTIALLY_AMBIGUOUS) == 0 && 2476 (msym2.flags() & POTENTIALLY_AMBIGUOUS) == 0) { 2477 Type mt1 = types.memberType(site, msym1); 2478 Type mt2 = types.memberType(site, msym2); 2479 //if both generic methods, adjust type variables 2480 if (mt1.hasTag(FORALL) && mt2.hasTag(FORALL) && 2481 types.hasSameBounds((ForAll)mt1, (ForAll)mt2)) { 2482 mt2 = types.subst(mt2, ((ForAll)mt2).tvars, ((ForAll)mt1).tvars); 2483 } 2484 //expand varargs methods if needed 2485 int maxLength = Math.max(mt1.getParameterTypes().length(), mt2.getParameterTypes().length()); 2486 List<Type> args1 = rs.adjustArgs(mt1.getParameterTypes(), msym1, maxLength, true); 2487 List<Type> args2 = rs.adjustArgs(mt2.getParameterTypes(), msym2, maxLength, true); 2488 //if arities don't match, exit 2489 if (args1.length() != args2.length()) return; 2490 boolean potentiallyAmbiguous = false; 2491 while (args1.nonEmpty() && args2.nonEmpty()) { 2492 Type s = args1.head; 2493 Type t = args2.head; 2494 if (!types.isSubtype(t, s) && !types.isSubtype(s, t)) { 2495 if (types.isFunctionalInterface(s) && types.isFunctionalInterface(t) && 2496 types.findDescriptorType(s).getParameterTypes().length() > 0 && 2497 types.findDescriptorType(s).getParameterTypes().length() == 2498 types.findDescriptorType(t).getParameterTypes().length()) { 2499 potentiallyAmbiguous = true; 2500 } else { 2501 break; 2502 } 2503 } 2504 args1 = args1.tail; 2505 args2 = args2.tail; 2506 } 2507 if (potentiallyAmbiguous) { 2508 //we found two incompatible functional interfaces with same arity 2509 //this means a call site passing an implicit lambda would be ambigiuous 2510 msym1.flags_field |= POTENTIALLY_AMBIGUOUS; 2511 msym2.flags_field |= POTENTIALLY_AMBIGUOUS; 2512 log.warning(LintCategory.OVERLOADS, pos, "potentially.ambiguous.overload", 2513 msym1, msym1.location(), 2514 msym2, msym2.location()); 2515 return; 2516 } 2517 } 2518 } 2519 2520 void checkElemAccessFromSerializableLambda(final JCTree tree) { 2521 if (warnOnAccessToSensitiveMembers) { 2522 Symbol sym = TreeInfo.symbol(tree); 2523 if (!sym.kind.matches(KindSelector.VAL_MTH)) { 2524 return; 2525 } 2526 2527 if (sym.kind == VAR) { 2528 if ((sym.flags() & PARAMETER) != 0 || 2529 sym.isLocal() || 2530 sym.name == names._this || 2531 sym.name == names._super) { 2532 return; 2533 } 2534 } 2535 2536 if (!types.isSubtype(sym.owner.type, syms.serializableType) && 2537 isEffectivelyNonPublic(sym)) { 2538 log.warning(tree.pos(), 2539 "access.to.sensitive.member.from.serializable.element", sym); 2540 } 2541 } 2542 } 2543 2544 private boolean isEffectivelyNonPublic(Symbol sym) { 2545 if (sym.packge() == syms.rootPackage) { 2546 return false; 2547 } 2548 2549 while (sym.kind != PCK) { 2550 if ((sym.flags() & PUBLIC) == 0) { 2551 return true; 2552 } 2553 sym = sym.owner; 2554 } 2555 return false; 2556 } 2557 2558 /** Report a conflict between a user symbol and a synthetic symbol. 2559 */ 2560 private void syntheticError(DiagnosticPosition pos, Symbol sym) { 2561 if (!sym.type.isErroneous()) { 2562 if (warnOnSyntheticConflicts) { 2563 log.warning(pos, "synthetic.name.conflict", sym, sym.location()); 2564 } 2565 else { 2566 log.error(pos, "synthetic.name.conflict", sym, sym.location()); 2567 } 2568 } 2569 } 2570 2571 /** Check that class c does not implement directly or indirectly 2572 * the same parameterized interface with two different argument lists. 2573 * @param pos Position to be used for error reporting. 2574 * @param type The type whose interfaces are checked. 2575 */ 2576 void checkClassBounds(DiagnosticPosition pos, Type type) { 2577 checkClassBounds(pos, new HashMap<TypeSymbol,Type>(), type); 2578 } 2579//where 2580 /** Enter all interfaces of type `type' into the hash table `seensofar' 2581 * with their class symbol as key and their type as value. Make 2582 * sure no class is entered with two different types. 2583 */ 2584 void checkClassBounds(DiagnosticPosition pos, 2585 Map<TypeSymbol,Type> seensofar, 2586 Type type) { 2587 if (type.isErroneous()) return; 2588 for (List<Type> l = types.interfaces(type); l.nonEmpty(); l = l.tail) { 2589 Type it = l.head; 2590 Type oldit = seensofar.put(it.tsym, it); 2591 if (oldit != null) { 2592 List<Type> oldparams = oldit.allparams(); 2593 List<Type> newparams = it.allparams(); 2594 if (!types.containsTypeEquivalent(oldparams, newparams)) 2595 log.error(pos, "cant.inherit.diff.arg", 2596 it.tsym, Type.toString(oldparams), 2597 Type.toString(newparams)); 2598 } 2599 checkClassBounds(pos, seensofar, it); 2600 } 2601 Type st = types.supertype(type); 2602 if (st != Type.noType) checkClassBounds(pos, seensofar, st); 2603 } 2604 2605 /** Enter interface into into set. 2606 * If it existed already, issue a "repeated interface" error. 2607 */ 2608 void checkNotRepeated(DiagnosticPosition pos, Type it, Set<Type> its) { 2609 if (its.contains(it)) 2610 log.error(pos, "repeated.interface"); 2611 else { 2612 its.add(it); 2613 } 2614 } 2615 2616/* ************************************************************************* 2617 * Check annotations 2618 **************************************************************************/ 2619 2620 /** 2621 * Recursively validate annotations values 2622 */ 2623 void validateAnnotationTree(JCTree tree) { 2624 class AnnotationValidator extends TreeScanner { 2625 @Override 2626 public void visitAnnotation(JCAnnotation tree) { 2627 if (!tree.type.isErroneous()) { 2628 super.visitAnnotation(tree); 2629 validateAnnotation(tree); 2630 } 2631 } 2632 } 2633 tree.accept(new AnnotationValidator()); 2634 } 2635 2636 /** 2637 * {@literal 2638 * Annotation types are restricted to primitives, String, an 2639 * enum, an annotation, Class, Class<?>, Class<? extends 2640 * Anything>, arrays of the preceding. 2641 * } 2642 */ 2643 void validateAnnotationType(JCTree restype) { 2644 // restype may be null if an error occurred, so don't bother validating it 2645 if (restype != null) { 2646 validateAnnotationType(restype.pos(), restype.type); 2647 } 2648 } 2649 2650 void validateAnnotationType(DiagnosticPosition pos, Type type) { 2651 if (type.isPrimitive()) return; 2652 if (types.isSameType(type, syms.stringType)) return; 2653 if ((type.tsym.flags() & Flags.ENUM) != 0) return; 2654 if ((type.tsym.flags() & Flags.ANNOTATION) != 0) return; 2655 if (types.cvarLowerBound(type).tsym == syms.classType.tsym) return; 2656 if (types.isArray(type) && !types.isArray(types.elemtype(type))) { 2657 validateAnnotationType(pos, types.elemtype(type)); 2658 return; 2659 } 2660 log.error(pos, "invalid.annotation.member.type"); 2661 } 2662 2663 /** 2664 * "It is also a compile-time error if any method declared in an 2665 * annotation type has a signature that is override-equivalent to 2666 * that of any public or protected method declared in class Object 2667 * or in the interface annotation.Annotation." 2668 * 2669 * @jls 9.6 Annotation Types 2670 */ 2671 void validateAnnotationMethod(DiagnosticPosition pos, MethodSymbol m) { 2672 for (Type sup = syms.annotationType; sup.hasTag(CLASS); sup = types.supertype(sup)) { 2673 Scope s = sup.tsym.members(); 2674 for (Symbol sym : s.getSymbolsByName(m.name)) { 2675 if (sym.kind == MTH && 2676 (sym.flags() & (PUBLIC | PROTECTED)) != 0 && 2677 types.overrideEquivalent(m.type, sym.type)) 2678 log.error(pos, "intf.annotation.member.clash", sym, sup); 2679 } 2680 } 2681 } 2682 2683 /** Check the annotations of a symbol. 2684 */ 2685 public void validateAnnotations(List<JCAnnotation> annotations, Symbol s) { 2686 for (JCAnnotation a : annotations) 2687 validateAnnotation(a, s); 2688 } 2689 2690 /** Check the type annotations. 2691 */ 2692 public void validateTypeAnnotations(List<JCAnnotation> annotations, boolean isTypeParameter) { 2693 for (JCAnnotation a : annotations) 2694 validateTypeAnnotation(a, isTypeParameter); 2695 } 2696 2697 /** Check an annotation of a symbol. 2698 */ 2699 private void validateAnnotation(JCAnnotation a, Symbol s) { 2700 validateAnnotationTree(a); 2701 2702 if (!annotationApplicable(a, s)) 2703 log.error(a.pos(), "annotation.type.not.applicable"); 2704 2705 if (a.annotationType.type.tsym == syms.functionalInterfaceType.tsym) { 2706 if (s.kind != TYP) { 2707 log.error(a.pos(), "bad.functional.intf.anno"); 2708 } else if (!s.isInterface() || (s.flags() & ANNOTATION) != 0) { 2709 log.error(a.pos(), "bad.functional.intf.anno.1", diags.fragment("not.a.functional.intf", s)); 2710 } 2711 } 2712 } 2713 2714 public void validateTypeAnnotation(JCAnnotation a, boolean isTypeParameter) { 2715 Assert.checkNonNull(a.type); 2716 validateAnnotationTree(a); 2717 2718 if (a.hasTag(TYPE_ANNOTATION) && 2719 !a.annotationType.type.isErroneous() && 2720 !isTypeAnnotation(a, isTypeParameter)) { 2721 log.error(a.pos(), "annotation.type.not.applicable"); 2722 } 2723 } 2724 2725 /** 2726 * Validate the proposed container 'repeatable' on the 2727 * annotation type symbol 's'. Report errors at position 2728 * 'pos'. 2729 * 2730 * @param s The (annotation)type declaration annotated with a @Repeatable 2731 * @param repeatable the @Repeatable on 's' 2732 * @param pos where to report errors 2733 */ 2734 public void validateRepeatable(TypeSymbol s, Attribute.Compound repeatable, DiagnosticPosition pos) { 2735 Assert.check(types.isSameType(repeatable.type, syms.repeatableType)); 2736 2737 Type t = null; 2738 List<Pair<MethodSymbol,Attribute>> l = repeatable.values; 2739 if (!l.isEmpty()) { 2740 Assert.check(l.head.fst.name == names.value); 2741 t = ((Attribute.Class)l.head.snd).getValue(); 2742 } 2743 2744 if (t == null) { 2745 // errors should already have been reported during Annotate 2746 return; 2747 } 2748 2749 validateValue(t.tsym, s, pos); 2750 validateRetention(t.tsym, s, pos); 2751 validateDocumented(t.tsym, s, pos); 2752 validateInherited(t.tsym, s, pos); 2753 validateTarget(t.tsym, s, pos); 2754 validateDefault(t.tsym, pos); 2755 } 2756 2757 private void validateValue(TypeSymbol container, TypeSymbol contained, DiagnosticPosition pos) { 2758 Symbol sym = container.members().findFirst(names.value); 2759 if (sym != null && sym.kind == MTH) { 2760 MethodSymbol m = (MethodSymbol) sym; 2761 Type ret = m.getReturnType(); 2762 if (!(ret.hasTag(ARRAY) && types.isSameType(((ArrayType)ret).elemtype, contained.type))) { 2763 log.error(pos, "invalid.repeatable.annotation.value.return", 2764 container, ret, types.makeArrayType(contained.type)); 2765 } 2766 } else { 2767 log.error(pos, "invalid.repeatable.annotation.no.value", container); 2768 } 2769 } 2770 2771 private void validateRetention(Symbol container, Symbol contained, DiagnosticPosition pos) { 2772 Attribute.RetentionPolicy containerRetention = types.getRetention(container); 2773 Attribute.RetentionPolicy containedRetention = types.getRetention(contained); 2774 2775 boolean error = false; 2776 switch (containedRetention) { 2777 case RUNTIME: 2778 if (containerRetention != Attribute.RetentionPolicy.RUNTIME) { 2779 error = true; 2780 } 2781 break; 2782 case CLASS: 2783 if (containerRetention == Attribute.RetentionPolicy.SOURCE) { 2784 error = true; 2785 } 2786 } 2787 if (error ) { 2788 log.error(pos, "invalid.repeatable.annotation.retention", 2789 container, containerRetention, 2790 contained, containedRetention); 2791 } 2792 } 2793 2794 private void validateDocumented(Symbol container, Symbol contained, DiagnosticPosition pos) { 2795 if (contained.attribute(syms.documentedType.tsym) != null) { 2796 if (container.attribute(syms.documentedType.tsym) == null) { 2797 log.error(pos, "invalid.repeatable.annotation.not.documented", container, contained); 2798 } 2799 } 2800 } 2801 2802 private void validateInherited(Symbol container, Symbol contained, DiagnosticPosition pos) { 2803 if (contained.attribute(syms.inheritedType.tsym) != null) { 2804 if (container.attribute(syms.inheritedType.tsym) == null) { 2805 log.error(pos, "invalid.repeatable.annotation.not.inherited", container, contained); 2806 } 2807 } 2808 } 2809 2810 private void validateTarget(Symbol container, Symbol contained, DiagnosticPosition pos) { 2811 // The set of targets the container is applicable to must be a subset 2812 // (with respect to annotation target semantics) of the set of targets 2813 // the contained is applicable to. The target sets may be implicit or 2814 // explicit. 2815 2816 Set<Name> containerTargets; 2817 Attribute.Array containerTarget = getAttributeTargetAttribute(container); 2818 if (containerTarget == null) { 2819 containerTargets = getDefaultTargetSet(); 2820 } else { 2821 containerTargets = new HashSet<>(); 2822 for (Attribute app : containerTarget.values) { 2823 if (!(app instanceof Attribute.Enum)) { 2824 continue; // recovery 2825 } 2826 Attribute.Enum e = (Attribute.Enum)app; 2827 containerTargets.add(e.value.name); 2828 } 2829 } 2830 2831 Set<Name> containedTargets; 2832 Attribute.Array containedTarget = getAttributeTargetAttribute(contained); 2833 if (containedTarget == null) { 2834 containedTargets = getDefaultTargetSet(); 2835 } else { 2836 containedTargets = new HashSet<>(); 2837 for (Attribute app : containedTarget.values) { 2838 if (!(app instanceof Attribute.Enum)) { 2839 continue; // recovery 2840 } 2841 Attribute.Enum e = (Attribute.Enum)app; 2842 containedTargets.add(e.value.name); 2843 } 2844 } 2845 2846 if (!isTargetSubsetOf(containerTargets, containedTargets)) { 2847 log.error(pos, "invalid.repeatable.annotation.incompatible.target", container, contained); 2848 } 2849 } 2850 2851 /* get a set of names for the default target */ 2852 private Set<Name> getDefaultTargetSet() { 2853 if (defaultTargets == null) { 2854 Set<Name> targets = new HashSet<>(); 2855 targets.add(names.ANNOTATION_TYPE); 2856 targets.add(names.CONSTRUCTOR); 2857 targets.add(names.FIELD); 2858 targets.add(names.LOCAL_VARIABLE); 2859 targets.add(names.METHOD); 2860 targets.add(names.PACKAGE); 2861 targets.add(names.PARAMETER); 2862 targets.add(names.TYPE); 2863 2864 defaultTargets = java.util.Collections.unmodifiableSet(targets); 2865 } 2866 2867 return defaultTargets; 2868 } 2869 private Set<Name> defaultTargets; 2870 2871 2872 /** Checks that s is a subset of t, with respect to ElementType 2873 * semantics, specifically {ANNOTATION_TYPE} is a subset of {TYPE}, 2874 * and {TYPE_USE} covers the set {ANNOTATION_TYPE, TYPE, TYPE_USE, 2875 * TYPE_PARAMETER}. 2876 */ 2877 private boolean isTargetSubsetOf(Set<Name> s, Set<Name> t) { 2878 // Check that all elements in s are present in t 2879 for (Name n2 : s) { 2880 boolean currentElementOk = false; 2881 for (Name n1 : t) { 2882 if (n1 == n2) { 2883 currentElementOk = true; 2884 break; 2885 } else if (n1 == names.TYPE && n2 == names.ANNOTATION_TYPE) { 2886 currentElementOk = true; 2887 break; 2888 } else if (n1 == names.TYPE_USE && 2889 (n2 == names.TYPE || 2890 n2 == names.ANNOTATION_TYPE || 2891 n2 == names.TYPE_PARAMETER)) { 2892 currentElementOk = true; 2893 break; 2894 } 2895 } 2896 if (!currentElementOk) 2897 return false; 2898 } 2899 return true; 2900 } 2901 2902 private void validateDefault(Symbol container, DiagnosticPosition pos) { 2903 // validate that all other elements of containing type has defaults 2904 Scope scope = container.members(); 2905 for(Symbol elm : scope.getSymbols()) { 2906 if (elm.name != names.value && 2907 elm.kind == MTH && 2908 ((MethodSymbol)elm).defaultValue == null) { 2909 log.error(pos, 2910 "invalid.repeatable.annotation.elem.nondefault", 2911 container, 2912 elm); 2913 } 2914 } 2915 } 2916 2917 /** Is s a method symbol that overrides a method in a superclass? */ 2918 boolean isOverrider(Symbol s) { 2919 if (s.kind != MTH || s.isStatic()) 2920 return false; 2921 MethodSymbol m = (MethodSymbol)s; 2922 TypeSymbol owner = (TypeSymbol)m.owner; 2923 for (Type sup : types.closure(owner.type)) { 2924 if (sup == owner.type) 2925 continue; // skip "this" 2926 Scope scope = sup.tsym.members(); 2927 for (Symbol sym : scope.getSymbolsByName(m.name)) { 2928 if (!sym.isStatic() && m.overrides(sym, owner, types, true)) 2929 return true; 2930 } 2931 } 2932 return false; 2933 } 2934 2935 /** Is the annotation applicable to types? */ 2936 protected boolean isTypeAnnotation(JCAnnotation a, boolean isTypeParameter) { 2937 Attribute.Compound atTarget = 2938 a.annotationType.type.tsym.attribute(syms.annotationTargetType.tsym); 2939 if (atTarget == null) { 2940 // An annotation without @Target is not a type annotation. 2941 return false; 2942 } 2943 2944 Attribute atValue = atTarget.member(names.value); 2945 if (!(atValue instanceof Attribute.Array)) { 2946 return false; // error recovery 2947 } 2948 2949 Attribute.Array arr = (Attribute.Array) atValue; 2950 for (Attribute app : arr.values) { 2951 if (!(app instanceof Attribute.Enum)) { 2952 return false; // recovery 2953 } 2954 Attribute.Enum e = (Attribute.Enum) app; 2955 2956 if (e.value.name == names.TYPE_USE) 2957 return true; 2958 else if (isTypeParameter && e.value.name == names.TYPE_PARAMETER) 2959 return true; 2960 } 2961 return false; 2962 } 2963 2964 /** Is the annotation applicable to the symbol? */ 2965 boolean annotationApplicable(JCAnnotation a, Symbol s) { 2966 Attribute.Array arr = getAttributeTargetAttribute(a.annotationType.type.tsym); 2967 Name[] targets; 2968 2969 if (arr == null) { 2970 targets = defaultTargetMetaInfo(a, s); 2971 } else { 2972 // TODO: can we optimize this? 2973 targets = new Name[arr.values.length]; 2974 for (int i=0; i<arr.values.length; ++i) { 2975 Attribute app = arr.values[i]; 2976 if (!(app instanceof Attribute.Enum)) { 2977 return true; // recovery 2978 } 2979 Attribute.Enum e = (Attribute.Enum) app; 2980 targets[i] = e.value.name; 2981 } 2982 } 2983 for (Name target : targets) { 2984 if (target == names.TYPE) 2985 { if (s.kind == TYP) return true; } 2986 else if (target == names.FIELD) 2987 { if (s.kind == VAR && s.owner.kind != MTH) return true; } 2988 else if (target == names.METHOD) 2989 { if (s.kind == MTH && !s.isConstructor()) return true; } 2990 else if (target == names.PARAMETER) 2991 { if (s.kind == VAR && s.owner.kind == MTH && 2992 (s.flags() & PARAMETER) != 0) 2993 return true; 2994 } 2995 else if (target == names.CONSTRUCTOR) 2996 { if (s.kind == MTH && s.isConstructor()) return true; } 2997 else if (target == names.LOCAL_VARIABLE) 2998 { if (s.kind == VAR && s.owner.kind == MTH && 2999 (s.flags() & PARAMETER) == 0) 3000 return true; 3001 } 3002 else if (target == names.ANNOTATION_TYPE) 3003 { if (s.kind == TYP && (s.flags() & ANNOTATION) != 0) 3004 return true; 3005 } 3006 else if (target == names.PACKAGE) 3007 { if (s.kind == PCK) return true; } 3008 else if (target == names.TYPE_USE) 3009 { if (s.kind == TYP || s.kind == VAR || 3010 (s.kind == MTH && !s.isConstructor() && 3011 !s.type.getReturnType().hasTag(VOID)) || 3012 (s.kind == MTH && s.isConstructor())) 3013 return true; 3014 } 3015 else if (target == names.TYPE_PARAMETER) 3016 { if (s.kind == TYP && s.type.hasTag(TYPEVAR)) 3017 return true; 3018 } 3019 else 3020 return true; // recovery 3021 } 3022 return false; 3023 } 3024 3025 3026 Attribute.Array getAttributeTargetAttribute(Symbol s) { 3027 Attribute.Compound atTarget = 3028 s.attribute(syms.annotationTargetType.tsym); 3029 if (atTarget == null) return null; // ok, is applicable 3030 Attribute atValue = atTarget.member(names.value); 3031 if (!(atValue instanceof Attribute.Array)) return null; // error recovery 3032 return (Attribute.Array) atValue; 3033 } 3034 3035 private final Name[] dfltTargetMeta; 3036 private Name[] defaultTargetMetaInfo(JCAnnotation a, Symbol s) { 3037 return dfltTargetMeta; 3038 } 3039 3040 /** Check an annotation value. 3041 * 3042 * @param a The annotation tree to check 3043 * @return true if this annotation tree is valid, otherwise false 3044 */ 3045 public boolean validateAnnotationDeferErrors(JCAnnotation a) { 3046 boolean res = false; 3047 final Log.DiagnosticHandler diagHandler = new Log.DiscardDiagnosticHandler(log); 3048 try { 3049 res = validateAnnotation(a); 3050 } finally { 3051 log.popDiagnosticHandler(diagHandler); 3052 } 3053 return res; 3054 } 3055 3056 private boolean validateAnnotation(JCAnnotation a) { 3057 boolean isValid = true; 3058 // collect an inventory of the annotation elements 3059 Set<MethodSymbol> members = new LinkedHashSet<>(); 3060 for (Symbol sym : a.annotationType.type.tsym.members().getSymbols(NON_RECURSIVE)) 3061 if (sym.kind == MTH && sym.name != names.clinit && 3062 (sym.flags() & SYNTHETIC) == 0) 3063 members.add((MethodSymbol) sym); 3064 3065 // remove the ones that are assigned values 3066 for (JCTree arg : a.args) { 3067 if (!arg.hasTag(ASSIGN)) continue; // recovery 3068 JCAssign assign = (JCAssign) arg; 3069 Symbol m = TreeInfo.symbol(assign.lhs); 3070 if (m == null || m.type.isErroneous()) continue; 3071 if (!members.remove(m)) { 3072 isValid = false; 3073 log.error(assign.lhs.pos(), "duplicate.annotation.member.value", 3074 m.name, a.type); 3075 } 3076 } 3077 3078 // all the remaining ones better have default values 3079 List<Name> missingDefaults = List.nil(); 3080 for (MethodSymbol m : members) { 3081 if (m.defaultValue == null && !m.type.isErroneous()) { 3082 missingDefaults = missingDefaults.append(m.name); 3083 } 3084 } 3085 missingDefaults = missingDefaults.reverse(); 3086 if (missingDefaults.nonEmpty()) { 3087 isValid = false; 3088 String key = (missingDefaults.size() > 1) 3089 ? "annotation.missing.default.value.1" 3090 : "annotation.missing.default.value"; 3091 log.error(a.pos(), key, a.type, missingDefaults); 3092 } 3093 3094 // special case: java.lang.annotation.Target must not have 3095 // repeated values in its value member 3096 if (a.annotationType.type.tsym != syms.annotationTargetType.tsym || 3097 a.args.tail == null) 3098 return isValid; 3099 3100 if (!a.args.head.hasTag(ASSIGN)) return false; // error recovery 3101 JCAssign assign = (JCAssign) a.args.head; 3102 Symbol m = TreeInfo.symbol(assign.lhs); 3103 if (m.name != names.value) return false; 3104 JCTree rhs = assign.rhs; 3105 if (!rhs.hasTag(NEWARRAY)) return false; 3106 JCNewArray na = (JCNewArray) rhs; 3107 Set<Symbol> targets = new HashSet<>(); 3108 for (JCTree elem : na.elems) { 3109 if (!targets.add(TreeInfo.symbol(elem))) { 3110 isValid = false; 3111 log.error(elem.pos(), "repeated.annotation.target"); 3112 } 3113 } 3114 return isValid; 3115 } 3116 3117 void checkDeprecatedAnnotation(DiagnosticPosition pos, Symbol s) { 3118 if (lint.isEnabled(LintCategory.DEP_ANN) && 3119 (s.flags() & DEPRECATED) != 0 && 3120 !syms.deprecatedType.isErroneous() && 3121 s.attribute(syms.deprecatedType.tsym) == null) { 3122 log.warning(LintCategory.DEP_ANN, 3123 pos, "missing.deprecated.annotation"); 3124 } 3125 } 3126 3127 void checkDeprecated(final DiagnosticPosition pos, final Symbol other, final Symbol s) { 3128 if ((s.flags() & DEPRECATED) != 0 && 3129 (other.flags() & DEPRECATED) == 0 && 3130 s.outermostClass() != other.outermostClass()) { 3131 deferredLintHandler.report(new DeferredLintHandler.LintLogger() { 3132 @Override 3133 public void report() { 3134 warnDeprecated(pos, s); 3135 } 3136 }); 3137 } 3138 } 3139 3140 void checkSunAPI(final DiagnosticPosition pos, final Symbol s) { 3141 if ((s.flags() & PROPRIETARY) != 0) { 3142 deferredLintHandler.report(new DeferredLintHandler.LintLogger() { 3143 public void report() { 3144 if (enableSunApiLintControl) 3145 warnSunApi(pos, "sun.proprietary", s); 3146 else 3147 log.mandatoryWarning(pos, "sun.proprietary", s); 3148 } 3149 }); 3150 } 3151 } 3152 3153 void checkProfile(final DiagnosticPosition pos, final Symbol s) { 3154 if (profile != Profile.DEFAULT && (s.flags() & NOT_IN_PROFILE) != 0) { 3155 log.error(pos, "not.in.profile", s, profile); 3156 } 3157 } 3158 3159/* ************************************************************************* 3160 * Check for recursive annotation elements. 3161 **************************************************************************/ 3162 3163 /** Check for cycles in the graph of annotation elements. 3164 */ 3165 void checkNonCyclicElements(JCClassDecl tree) { 3166 if ((tree.sym.flags_field & ANNOTATION) == 0) return; 3167 Assert.check((tree.sym.flags_field & LOCKED) == 0); 3168 try { 3169 tree.sym.flags_field |= LOCKED; 3170 for (JCTree def : tree.defs) { 3171 if (!def.hasTag(METHODDEF)) continue; 3172 JCMethodDecl meth = (JCMethodDecl)def; 3173 checkAnnotationResType(meth.pos(), meth.restype.type); 3174 } 3175 } finally { 3176 tree.sym.flags_field &= ~LOCKED; 3177 tree.sym.flags_field |= ACYCLIC_ANN; 3178 } 3179 } 3180 3181 void checkNonCyclicElementsInternal(DiagnosticPosition pos, TypeSymbol tsym) { 3182 if ((tsym.flags_field & ACYCLIC_ANN) != 0) 3183 return; 3184 if ((tsym.flags_field & LOCKED) != 0) { 3185 log.error(pos, "cyclic.annotation.element"); 3186 return; 3187 } 3188 try { 3189 tsym.flags_field |= LOCKED; 3190 for (Symbol s : tsym.members().getSymbols(NON_RECURSIVE)) { 3191 if (s.kind != MTH) 3192 continue; 3193 checkAnnotationResType(pos, ((MethodSymbol)s).type.getReturnType()); 3194 } 3195 } finally { 3196 tsym.flags_field &= ~LOCKED; 3197 tsym.flags_field |= ACYCLIC_ANN; 3198 } 3199 } 3200 3201 void checkAnnotationResType(DiagnosticPosition pos, Type type) { 3202 switch (type.getTag()) { 3203 case CLASS: 3204 if ((type.tsym.flags() & ANNOTATION) != 0) 3205 checkNonCyclicElementsInternal(pos, type.tsym); 3206 break; 3207 case ARRAY: 3208 checkAnnotationResType(pos, types.elemtype(type)); 3209 break; 3210 default: 3211 break; // int etc 3212 } 3213 } 3214 3215/* ************************************************************************* 3216 * Check for cycles in the constructor call graph. 3217 **************************************************************************/ 3218 3219 /** Check for cycles in the graph of constructors calling other 3220 * constructors. 3221 */ 3222 void checkCyclicConstructors(JCClassDecl tree) { 3223 Map<Symbol,Symbol> callMap = new HashMap<>(); 3224 3225 // enter each constructor this-call into the map 3226 for (List<JCTree> l = tree.defs; l.nonEmpty(); l = l.tail) { 3227 JCMethodInvocation app = TreeInfo.firstConstructorCall(l.head); 3228 if (app == null) continue; 3229 JCMethodDecl meth = (JCMethodDecl) l.head; 3230 if (TreeInfo.name(app.meth) == names._this) { 3231 callMap.put(meth.sym, TreeInfo.symbol(app.meth)); 3232 } else { 3233 meth.sym.flags_field |= ACYCLIC; 3234 } 3235 } 3236 3237 // Check for cycles in the map 3238 Symbol[] ctors = new Symbol[0]; 3239 ctors = callMap.keySet().toArray(ctors); 3240 for (Symbol caller : ctors) { 3241 checkCyclicConstructor(tree, caller, callMap); 3242 } 3243 } 3244 3245 /** Look in the map to see if the given constructor is part of a 3246 * call cycle. 3247 */ 3248 private void checkCyclicConstructor(JCClassDecl tree, Symbol ctor, 3249 Map<Symbol,Symbol> callMap) { 3250 if (ctor != null && (ctor.flags_field & ACYCLIC) == 0) { 3251 if ((ctor.flags_field & LOCKED) != 0) { 3252 log.error(TreeInfo.diagnosticPositionFor(ctor, tree), 3253 "recursive.ctor.invocation"); 3254 } else { 3255 ctor.flags_field |= LOCKED; 3256 checkCyclicConstructor(tree, callMap.remove(ctor), callMap); 3257 ctor.flags_field &= ~LOCKED; 3258 } 3259 ctor.flags_field |= ACYCLIC; 3260 } 3261 } 3262 3263/* ************************************************************************* 3264 * Miscellaneous 3265 **************************************************************************/ 3266 3267 /** 3268 * Return the opcode of the operator but emit an error if it is an 3269 * error. 3270 * @param pos position for error reporting. 3271 * @param operator an operator 3272 * @param tag a tree tag 3273 * @param left type of left hand side 3274 * @param right type of right hand side 3275 */ 3276 int checkOperator(DiagnosticPosition pos, 3277 OperatorSymbol operator, 3278 JCTree.Tag tag, 3279 Type left, 3280 Type right) { 3281 if (operator.opcode == ByteCodes.error) { 3282 log.error(pos, 3283 "operator.cant.be.applied.1", 3284 treeinfo.operatorName(tag), 3285 left, right); 3286 } 3287 return operator.opcode; 3288 } 3289 3290 3291 /** 3292 * Check for division by integer constant zero 3293 * @param pos Position for error reporting. 3294 * @param operator The operator for the expression 3295 * @param operand The right hand operand for the expression 3296 */ 3297 void checkDivZero(final DiagnosticPosition pos, Symbol operator, Type operand) { 3298 if (operand.constValue() != null 3299 && operand.getTag().isSubRangeOf(LONG) 3300 && ((Number) (operand.constValue())).longValue() == 0) { 3301 int opc = ((OperatorSymbol)operator).opcode; 3302 if (opc == ByteCodes.idiv || opc == ByteCodes.imod 3303 || opc == ByteCodes.ldiv || opc == ByteCodes.lmod) { 3304 deferredLintHandler.report(new DeferredLintHandler.LintLogger() { 3305 @Override 3306 public void report() { 3307 warnDivZero(pos); 3308 } 3309 }); 3310 } 3311 } 3312 } 3313 3314 /** 3315 * Check for empty statements after if 3316 */ 3317 void checkEmptyIf(JCIf tree) { 3318 if (tree.thenpart.hasTag(SKIP) && tree.elsepart == null && 3319 lint.isEnabled(LintCategory.EMPTY)) 3320 log.warning(LintCategory.EMPTY, tree.thenpart.pos(), "empty.if"); 3321 } 3322 3323 /** Check that symbol is unique in given scope. 3324 * @param pos Position for error reporting. 3325 * @param sym The symbol. 3326 * @param s The scope. 3327 */ 3328 boolean checkUnique(DiagnosticPosition pos, Symbol sym, Scope s) { 3329 if (sym.type.isErroneous()) 3330 return true; 3331 if (sym.owner.name == names.any) return false; 3332 for (Symbol byName : s.getSymbolsByName(sym.name, NON_RECURSIVE)) { 3333 if (sym != byName && 3334 (byName.flags() & CLASH) == 0 && 3335 sym.kind == byName.kind && 3336 sym.name != names.error && 3337 (sym.kind != MTH || 3338 types.hasSameArgs(sym.type, byName.type) || 3339 types.hasSameArgs(types.erasure(sym.type), types.erasure(byName.type)))) { 3340 if ((sym.flags() & VARARGS) != (byName.flags() & VARARGS)) { 3341 varargsDuplicateError(pos, sym, byName); 3342 return true; 3343 } else if (sym.kind == MTH && !types.hasSameArgs(sym.type, byName.type, false)) { 3344 duplicateErasureError(pos, sym, byName); 3345 sym.flags_field |= CLASH; 3346 return true; 3347 } else { 3348 duplicateError(pos, byName); 3349 return false; 3350 } 3351 } 3352 } 3353 return true; 3354 } 3355 3356 /** Report duplicate declaration error. 3357 */ 3358 void duplicateErasureError(DiagnosticPosition pos, Symbol sym1, Symbol sym2) { 3359 if (!sym1.type.isErroneous() && !sym2.type.isErroneous()) { 3360 log.error(pos, "name.clash.same.erasure", sym1, sym2); 3361 } 3362 } 3363 3364 /**Check that types imported through the ordinary imports don't clash with types imported 3365 * by other (static or ordinary) imports. Note that two static imports may import two clashing 3366 * types without an error on the imports. 3367 * @param toplevel The toplevel tree for which the test should be performed. 3368 */ 3369 void checkImportsUnique(JCCompilationUnit toplevel) { 3370 WriteableScope ordinallyImportedSoFar = WriteableScope.create(toplevel.packge); 3371 WriteableScope staticallyImportedSoFar = WriteableScope.create(toplevel.packge); 3372 WriteableScope topLevelScope = toplevel.toplevelScope; 3373 3374 for (JCTree def : toplevel.defs) { 3375 if (!def.hasTag(IMPORT)) 3376 continue; 3377 3378 JCImport imp = (JCImport) def; 3379 3380 if (imp.importScope == null) 3381 continue; 3382 3383 for (Symbol sym : imp.importScope.getSymbols(sym -> sym.kind == TYP)) { 3384 if (imp.isStatic()) { 3385 checkUniqueImport(imp.pos(), ordinallyImportedSoFar, staticallyImportedSoFar, topLevelScope, sym, true); 3386 staticallyImportedSoFar.enter(sym); 3387 } else { 3388 checkUniqueImport(imp.pos(), ordinallyImportedSoFar, staticallyImportedSoFar, topLevelScope, sym, false); 3389 ordinallyImportedSoFar.enter(sym); 3390 } 3391 } 3392 3393 imp.importScope = null; 3394 } 3395 } 3396 3397 /** Check that single-type import is not already imported or top-level defined, 3398 * but make an exception for two single-type imports which denote the same type. 3399 * @param pos Position for error reporting. 3400 * @param ordinallyImportedSoFar A Scope containing types imported so far through 3401 * ordinary imports. 3402 * @param staticallyImportedSoFar A Scope containing types imported so far through 3403 * static imports. 3404 * @param topLevelScope The current file's top-level Scope 3405 * @param sym The symbol. 3406 * @param staticImport Whether or not this was a static import 3407 */ 3408 private boolean checkUniqueImport(DiagnosticPosition pos, Scope ordinallyImportedSoFar, 3409 Scope staticallyImportedSoFar, Scope topLevelScope, 3410 Symbol sym, boolean staticImport) { 3411 Filter<Symbol> duplicates = candidate -> candidate != sym && !candidate.type.isErroneous(); 3412 Symbol clashing = ordinallyImportedSoFar.findFirst(sym.name, duplicates); 3413 if (clashing == null && !staticImport) { 3414 clashing = staticallyImportedSoFar.findFirst(sym.name, duplicates); 3415 } 3416 if (clashing != null) { 3417 if (staticImport) 3418 log.error(pos, "already.defined.static.single.import", clashing); 3419 else 3420 log.error(pos, "already.defined.single.import", clashing); 3421 return false; 3422 } 3423 clashing = topLevelScope.findFirst(sym.name, duplicates); 3424 if (clashing != null) { 3425 log.error(pos, "already.defined.this.unit", clashing); 3426 return false; 3427 } 3428 return true; 3429 } 3430 3431 /** Check that a qualified name is in canonical form (for import decls). 3432 */ 3433 public void checkCanonical(JCTree tree) { 3434 if (!isCanonical(tree)) 3435 log.error(tree.pos(), "import.requires.canonical", 3436 TreeInfo.symbol(tree)); 3437 } 3438 // where 3439 private boolean isCanonical(JCTree tree) { 3440 while (tree.hasTag(SELECT)) { 3441 JCFieldAccess s = (JCFieldAccess) tree; 3442 if (s.sym.owner != TreeInfo.symbol(s.selected)) 3443 return false; 3444 tree = s.selected; 3445 } 3446 return true; 3447 } 3448 3449 /** Check that an auxiliary class is not accessed from any other file than its own. 3450 */ 3451 void checkForBadAuxiliaryClassAccess(DiagnosticPosition pos, Env<AttrContext> env, ClassSymbol c) { 3452 if (lint.isEnabled(Lint.LintCategory.AUXILIARYCLASS) && 3453 (c.flags() & AUXILIARY) != 0 && 3454 rs.isAccessible(env, c) && 3455 !fileManager.isSameFile(c.sourcefile, env.toplevel.sourcefile)) 3456 { 3457 log.warning(pos, "auxiliary.class.accessed.from.outside.of.its.source.file", 3458 c, c.sourcefile); 3459 } 3460 } 3461 3462 private class ConversionWarner extends Warner { 3463 final String uncheckedKey; 3464 final Type found; 3465 final Type expected; 3466 public ConversionWarner(DiagnosticPosition pos, String uncheckedKey, Type found, Type expected) { 3467 super(pos); 3468 this.uncheckedKey = uncheckedKey; 3469 this.found = found; 3470 this.expected = expected; 3471 } 3472 3473 @Override 3474 public void warn(LintCategory lint) { 3475 boolean warned = this.warned; 3476 super.warn(lint); 3477 if (warned) return; // suppress redundant diagnostics 3478 switch (lint) { 3479 case UNCHECKED: 3480 Check.this.warnUnchecked(pos(), "prob.found.req", diags.fragment(uncheckedKey), found, expected); 3481 break; 3482 case VARARGS: 3483 if (method != null && 3484 method.attribute(syms.trustMeType.tsym) != null && 3485 isTrustMeAllowedOnMethod(method) && 3486 !types.isReifiable(method.type.getParameterTypes().last())) { 3487 Check.this.warnUnsafeVararg(pos(), "varargs.unsafe.use.varargs.param", method.params.last()); 3488 } 3489 break; 3490 default: 3491 throw new AssertionError("Unexpected lint: " + lint); 3492 } 3493 } 3494 } 3495 3496 public Warner castWarner(DiagnosticPosition pos, Type found, Type expected) { 3497 return new ConversionWarner(pos, "unchecked.cast.to.type", found, expected); 3498 } 3499 3500 public Warner convertWarner(DiagnosticPosition pos, Type found, Type expected) { 3501 return new ConversionWarner(pos, "unchecked.assign", found, expected); 3502 } 3503 3504 public void checkFunctionalInterface(JCClassDecl tree, ClassSymbol cs) { 3505 Compound functionalType = cs.attribute(syms.functionalInterfaceType.tsym); 3506 3507 if (functionalType != null) { 3508 try { 3509 types.findDescriptorSymbol((TypeSymbol)cs); 3510 } catch (Types.FunctionDescriptorLookupError ex) { 3511 DiagnosticPosition pos = tree.pos(); 3512 for (JCAnnotation a : tree.getModifiers().annotations) { 3513 if (a.annotationType.type.tsym == syms.functionalInterfaceType.tsym) { 3514 pos = a.pos(); 3515 break; 3516 } 3517 } 3518 log.error(pos, "bad.functional.intf.anno.1", ex.getDiagnostic()); 3519 } 3520 } 3521 } 3522 3523 public void checkImportsResolvable(final JCCompilationUnit toplevel) { 3524 for (final JCImport imp : toplevel.getImports()) { 3525 if (!imp.staticImport || !imp.qualid.hasTag(SELECT)) 3526 continue; 3527 final JCFieldAccess select = (JCFieldAccess) imp.qualid; 3528 final Symbol origin; 3529 if (select.name == names.asterisk || (origin = TreeInfo.symbol(select.selected)) == null || origin.kind != TYP) 3530 continue; 3531 3532 TypeSymbol site = (TypeSymbol) TreeInfo.symbol(select.selected); 3533 if (!checkTypeContainsImportableElement(site, site, toplevel.packge, select.name, new HashSet<Symbol>())) { 3534 log.error(imp.pos(), "cant.resolve.location", 3535 KindName.STATIC, 3536 select.name, List.<Type>nil(), List.<Type>nil(), 3537 Kinds.typeKindName(TreeInfo.symbol(select.selected).type), 3538 TreeInfo.symbol(select.selected).type); 3539 } 3540 } 3541 } 3542 3543 private boolean checkTypeContainsImportableElement(TypeSymbol tsym, TypeSymbol origin, PackageSymbol packge, Name name, Set<Symbol> processed) { 3544 if (tsym == null || !processed.add(tsym)) 3545 return false; 3546 3547 // also search through inherited names 3548 if (checkTypeContainsImportableElement(types.supertype(tsym.type).tsym, origin, packge, name, processed)) 3549 return true; 3550 3551 for (Type t : types.interfaces(tsym.type)) 3552 if (checkTypeContainsImportableElement(t.tsym, origin, packge, name, processed)) 3553 return true; 3554 3555 for (Symbol sym : tsym.members().getSymbolsByName(name)) { 3556 if (sym.isStatic() && 3557 staticImportAccessible(sym, packge) && 3558 sym.isMemberOf(origin, types)) { 3559 return true; 3560 } 3561 } 3562 3563 return false; 3564 } 3565 3566 // is the sym accessible everywhere in packge? 3567 public boolean staticImportAccessible(Symbol sym, PackageSymbol packge) { 3568 int flags = (int)(sym.flags() & AccessFlags); 3569 switch (flags) { 3570 default: 3571 case PUBLIC: 3572 return true; 3573 case PRIVATE: 3574 return false; 3575 case 0: 3576 case PROTECTED: 3577 return sym.packge() == packge; 3578 } 3579 } 3580 3581} 3582