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