Attr.java revision 3294:9adfb22ff08f
1/* 2 * Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26package com.sun.tools.javac.comp; 27 28import java.util.*; 29 30import javax.lang.model.element.ElementKind; 31import javax.tools.JavaFileObject; 32 33import com.sun.source.tree.IdentifierTree; 34import com.sun.source.tree.MemberReferenceTree.ReferenceMode; 35import com.sun.source.tree.MemberSelectTree; 36import com.sun.source.tree.TreeVisitor; 37import com.sun.source.util.SimpleTreeVisitor; 38import com.sun.tools.javac.code.*; 39import com.sun.tools.javac.code.Directive.RequiresFlag; 40import com.sun.tools.javac.code.Lint.LintCategory; 41import com.sun.tools.javac.code.Scope.WriteableScope; 42import com.sun.tools.javac.code.Symbol.*; 43import com.sun.tools.javac.code.Type.*; 44import com.sun.tools.javac.code.TypeMetadata.Annotations; 45import com.sun.tools.javac.code.Types.FunctionDescriptorLookupError; 46import com.sun.tools.javac.comp.ArgumentAttr.LocalCacheContext; 47import com.sun.tools.javac.comp.Check.CheckContext; 48import com.sun.tools.javac.comp.DeferredAttr.AttrMode; 49import com.sun.tools.javac.comp.Infer.FreeTypeListener; 50import com.sun.tools.javac.jvm.*; 51import static com.sun.tools.javac.resources.CompilerProperties.Fragments.Diamond; 52import static com.sun.tools.javac.resources.CompilerProperties.Fragments.DiamondInvalidArg; 53import static com.sun.tools.javac.resources.CompilerProperties.Fragments.DiamondInvalidArgs; 54import com.sun.tools.javac.resources.CompilerProperties.Errors; 55import com.sun.tools.javac.resources.CompilerProperties.Fragments; 56import com.sun.tools.javac.tree.*; 57import com.sun.tools.javac.tree.JCTree.*; 58import com.sun.tools.javac.tree.JCTree.JCPolyExpression.*; 59import com.sun.tools.javac.util.*; 60import com.sun.tools.javac.util.DefinedBy.Api; 61import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition; 62import com.sun.tools.javac.util.JCDiagnostic.Fragment; 63import com.sun.tools.javac.util.List; 64 65import static com.sun.tools.javac.code.Flags.*; 66import static com.sun.tools.javac.code.Flags.ANNOTATION; 67import static com.sun.tools.javac.code.Flags.BLOCK; 68import static com.sun.tools.javac.code.Kinds.*; 69import static com.sun.tools.javac.code.Kinds.Kind.*; 70import static com.sun.tools.javac.code.TypeTag.*; 71import static com.sun.tools.javac.code.TypeTag.WILDCARD; 72import static com.sun.tools.javac.tree.JCTree.Tag.*; 73 74/** This is the main context-dependent analysis phase in GJC. It 75 * encompasses name resolution, type checking and constant folding as 76 * subtasks. Some subtasks involve auxiliary classes. 77 * @see Check 78 * @see Resolve 79 * @see ConstFold 80 * @see Infer 81 * 82 * <p><b>This is NOT part of any supported API. 83 * If you write code that depends on this, you do so at your own risk. 84 * This code and its internal interfaces are subject to change or 85 * deletion without notice.</b> 86 */ 87public class Attr extends JCTree.Visitor { 88 protected static final Context.Key<Attr> attrKey = new Context.Key<>(); 89 90 final Names names; 91 final Log log; 92 final Symtab syms; 93 final Resolve rs; 94 final Operators operators; 95 final Infer infer; 96 final Analyzer analyzer; 97 final DeferredAttr deferredAttr; 98 final Check chk; 99 final Flow flow; 100 final MemberEnter memberEnter; 101 final TypeEnter typeEnter; 102 final TreeMaker make; 103 final ConstFold cfolder; 104 final Enter enter; 105 final Target target; 106 final Types types; 107 final JCDiagnostic.Factory diags; 108 final TypeAnnotations typeAnnotations; 109 final DeferredLintHandler deferredLintHandler; 110 final TypeEnvs typeEnvs; 111 final Dependencies dependencies; 112 final Annotate annotate; 113 final ArgumentAttr argumentAttr; 114 115 public static Attr instance(Context context) { 116 Attr instance = context.get(attrKey); 117 if (instance == null) 118 instance = new Attr(context); 119 return instance; 120 } 121 122 protected Attr(Context context) { 123 context.put(attrKey, this); 124 125 names = Names.instance(context); 126 log = Log.instance(context); 127 syms = Symtab.instance(context); 128 rs = Resolve.instance(context); 129 operators = Operators.instance(context); 130 chk = Check.instance(context); 131 flow = Flow.instance(context); 132 memberEnter = MemberEnter.instance(context); 133 typeEnter = TypeEnter.instance(context); 134 make = TreeMaker.instance(context); 135 enter = Enter.instance(context); 136 infer = Infer.instance(context); 137 analyzer = Analyzer.instance(context); 138 deferredAttr = DeferredAttr.instance(context); 139 cfolder = ConstFold.instance(context); 140 target = Target.instance(context); 141 types = Types.instance(context); 142 diags = JCDiagnostic.Factory.instance(context); 143 annotate = Annotate.instance(context); 144 typeAnnotations = TypeAnnotations.instance(context); 145 deferredLintHandler = DeferredLintHandler.instance(context); 146 typeEnvs = TypeEnvs.instance(context); 147 dependencies = Dependencies.instance(context); 148 argumentAttr = ArgumentAttr.instance(context); 149 150 Options options = Options.instance(context); 151 152 Source source = Source.instance(context); 153 allowStringsInSwitch = source.allowStringsInSwitch(); 154 allowPoly = source.allowPoly(); 155 allowTypeAnnos = source.allowTypeAnnotations(); 156 allowLambda = source.allowLambda(); 157 allowDefaultMethods = source.allowDefaultMethods(); 158 allowStaticInterfaceMethods = source.allowStaticInterfaceMethods(); 159 sourceName = source.name; 160 useBeforeDeclarationWarning = options.isSet("useBeforeDeclarationWarning"); 161 162 statInfo = new ResultInfo(KindSelector.NIL, Type.noType); 163 varAssignmentInfo = new ResultInfo(KindSelector.ASG, Type.noType); 164 unknownExprInfo = new ResultInfo(KindSelector.VAL, Type.noType); 165 methodAttrInfo = new MethodAttrInfo(); 166 unknownTypeInfo = new ResultInfo(KindSelector.TYP, Type.noType); 167 unknownTypeExprInfo = new ResultInfo(KindSelector.VAL_TYP, Type.noType); 168 recoveryInfo = new RecoveryInfo(deferredAttr.emptyDeferredAttrContext); 169 } 170 171 /** Switch: support target-typing inference 172 */ 173 boolean allowPoly; 174 175 /** Switch: support type annotations. 176 */ 177 boolean allowTypeAnnos; 178 179 /** Switch: support lambda expressions ? 180 */ 181 boolean allowLambda; 182 183 /** Switch: support default methods ? 184 */ 185 boolean allowDefaultMethods; 186 187 /** Switch: static interface methods enabled? 188 */ 189 boolean allowStaticInterfaceMethods; 190 191 /** 192 * Switch: warn about use of variable before declaration? 193 * RFE: 6425594 194 */ 195 boolean useBeforeDeclarationWarning; 196 197 /** 198 * Switch: allow strings in switch? 199 */ 200 boolean allowStringsInSwitch; 201 202 /** 203 * Switch: name of source level; used for error reporting. 204 */ 205 String sourceName; 206 207 /** Check kind and type of given tree against protokind and prototype. 208 * If check succeeds, store type in tree and return it. 209 * If check fails, store errType in tree and return it. 210 * No checks are performed if the prototype is a method type. 211 * It is not necessary in this case since we know that kind and type 212 * are correct. 213 * 214 * @param tree The tree whose kind and type is checked 215 * @param found The computed type of the tree 216 * @param ownkind The computed kind of the tree 217 * @param resultInfo The expected result of the tree 218 */ 219 Type check(final JCTree tree, 220 final Type found, 221 final KindSelector ownkind, 222 final ResultInfo resultInfo) { 223 InferenceContext inferenceContext = resultInfo.checkContext.inferenceContext(); 224 Type owntype; 225 boolean shouldCheck = !found.hasTag(ERROR) && 226 !resultInfo.pt.hasTag(METHOD) && 227 !resultInfo.pt.hasTag(FORALL); 228 if (shouldCheck && !ownkind.subset(resultInfo.pkind)) { 229 log.error(tree.pos(), "unexpected.type", 230 resultInfo.pkind.kindNames(), 231 ownkind.kindNames()); 232 owntype = types.createErrorType(found); 233 } else if (allowPoly && inferenceContext.free(found)) { 234 //delay the check if there are inference variables in the found type 235 //this means we are dealing with a partially inferred poly expression 236 owntype = shouldCheck ? resultInfo.pt : found; 237 if (resultInfo.checkMode.installPostInferenceHook()) { 238 inferenceContext.addFreeTypeListener(List.of(found), 239 instantiatedContext -> { 240 ResultInfo pendingResult = 241 resultInfo.dup(inferenceContext.asInstType(resultInfo.pt)); 242 check(tree, inferenceContext.asInstType(found), ownkind, pendingResult); 243 }); 244 } 245 } else { 246 owntype = shouldCheck ? 247 resultInfo.check(tree, found) : 248 found; 249 } 250 if (resultInfo.checkMode.updateTreeType()) { 251 tree.type = owntype; 252 } 253 return owntype; 254 } 255 256 /** Is given blank final variable assignable, i.e. in a scope where it 257 * may be assigned to even though it is final? 258 * @param v The blank final variable. 259 * @param env The current environment. 260 */ 261 boolean isAssignableAsBlankFinal(VarSymbol v, Env<AttrContext> env) { 262 Symbol owner = env.info.scope.owner; 263 // owner refers to the innermost variable, method or 264 // initializer block declaration at this point. 265 return 266 v.owner == owner 267 || 268 ((owner.name == names.init || // i.e. we are in a constructor 269 owner.kind == VAR || // i.e. we are in a variable initializer 270 (owner.flags() & BLOCK) != 0) // i.e. we are in an initializer block 271 && 272 v.owner == owner.owner 273 && 274 ((v.flags() & STATIC) != 0) == Resolve.isStatic(env)); 275 } 276 277 /** Check that variable can be assigned to. 278 * @param pos The current source code position. 279 * @param v The assigned variable 280 * @param base If the variable is referred to in a Select, the part 281 * to the left of the `.', null otherwise. 282 * @param env The current environment. 283 */ 284 void checkAssignable(DiagnosticPosition pos, VarSymbol v, JCTree base, Env<AttrContext> env) { 285 if ((v.flags() & FINAL) != 0 && 286 ((v.flags() & HASINIT) != 0 287 || 288 !((base == null || 289 (base.hasTag(IDENT) && TreeInfo.name(base) == names._this)) && 290 isAssignableAsBlankFinal(v, env)))) { 291 if (v.isResourceVariable()) { //TWR resource 292 log.error(pos, "try.resource.may.not.be.assigned", v); 293 } else { 294 log.error(pos, "cant.assign.val.to.final.var", v); 295 } 296 } 297 } 298 299 /** Does tree represent a static reference to an identifier? 300 * It is assumed that tree is either a SELECT or an IDENT. 301 * We have to weed out selects from non-type names here. 302 * @param tree The candidate tree. 303 */ 304 boolean isStaticReference(JCTree tree) { 305 if (tree.hasTag(SELECT)) { 306 Symbol lsym = TreeInfo.symbol(((JCFieldAccess) tree).selected); 307 if (lsym == null || lsym.kind != TYP) { 308 return false; 309 } 310 } 311 return true; 312 } 313 314 /** Is this symbol a type? 315 */ 316 static boolean isType(Symbol sym) { 317 return sym != null && sym.kind == TYP; 318 } 319 320 /** The current `this' symbol. 321 * @param env The current environment. 322 */ 323 Symbol thisSym(DiagnosticPosition pos, Env<AttrContext> env) { 324 return rs.resolveSelf(pos, env, env.enclClass.sym, names._this); 325 } 326 327 /** Attribute a parsed identifier. 328 * @param tree Parsed identifier name 329 * @param topLevel The toplevel to use 330 */ 331 public Symbol attribIdent(JCTree tree, JCCompilationUnit topLevel) { 332 Env<AttrContext> localEnv = enter.topLevelEnv(topLevel); 333 localEnv.enclClass = make.ClassDef(make.Modifiers(0), 334 syms.errSymbol.name, 335 null, null, null, null); 336 localEnv.enclClass.sym = syms.errSymbol; 337 return attribIdent(tree, localEnv); 338 } 339 340 /** Attribute a parsed identifier. 341 * @param tree Parsed identifier name 342 * @param env The env to use 343 */ 344 public Symbol attribIdent(JCTree tree, Env<AttrContext> env) { 345 return tree.accept(identAttributer, env); 346 } 347 // where 348 private TreeVisitor<Symbol,Env<AttrContext>> identAttributer = new IdentAttributer(); 349 private class IdentAttributer extends SimpleTreeVisitor<Symbol,Env<AttrContext>> { 350 @Override @DefinedBy(Api.COMPILER_TREE) 351 public Symbol visitMemberSelect(MemberSelectTree node, Env<AttrContext> env) { 352 Symbol site = visit(node.getExpression(), env); 353 if (site.kind == ERR || site.kind == ABSENT_TYP) 354 return site; 355 Name name = (Name)node.getIdentifier(); 356 if (site.kind == PCK) { 357 env.toplevel.packge = (PackageSymbol)site; 358 return rs.findIdentInPackage(env, (TypeSymbol)site, name, 359 KindSelector.TYP_PCK); 360 } else { 361 env.enclClass.sym = (ClassSymbol)site; 362 return rs.findMemberType(env, site.asType(), name, (TypeSymbol)site); 363 } 364 } 365 366 @Override @DefinedBy(Api.COMPILER_TREE) 367 public Symbol visitIdentifier(IdentifierTree node, Env<AttrContext> env) { 368 return rs.findIdent(env, (Name)node.getName(), KindSelector.TYP_PCK); 369 } 370 } 371 372 public Type coerce(Type etype, Type ttype) { 373 return cfolder.coerce(etype, ttype); 374 } 375 376 public Type attribType(JCTree node, TypeSymbol sym) { 377 Env<AttrContext> env = typeEnvs.get(sym); 378 Env<AttrContext> localEnv = env.dup(node, env.info.dup()); 379 return attribTree(node, localEnv, unknownTypeInfo); 380 } 381 382 public Type attribImportQualifier(JCImport tree, Env<AttrContext> env) { 383 // Attribute qualifying package or class. 384 JCFieldAccess s = (JCFieldAccess)tree.qualid; 385 return attribTree(s.selected, env, 386 new ResultInfo(tree.staticImport ? 387 KindSelector.TYP : KindSelector.TYP_PCK, 388 Type.noType)); 389 } 390 391 public Env<AttrContext> attribExprToTree(JCTree expr, Env<AttrContext> env, JCTree tree) { 392 breakTree = tree; 393 JavaFileObject prev = log.useSource(env.toplevel.sourcefile); 394 try { 395 attribExpr(expr, env); 396 } catch (BreakAttr b) { 397 return b.env; 398 } catch (AssertionError ae) { 399 if (ae.getCause() instanceof BreakAttr) { 400 return ((BreakAttr)(ae.getCause())).env; 401 } else { 402 throw ae; 403 } 404 } finally { 405 breakTree = null; 406 log.useSource(prev); 407 } 408 return env; 409 } 410 411 public Env<AttrContext> attribStatToTree(JCTree stmt, Env<AttrContext> env, JCTree tree) { 412 breakTree = tree; 413 JavaFileObject prev = log.useSource(env.toplevel.sourcefile); 414 try { 415 attribStat(stmt, env); 416 } catch (BreakAttr b) { 417 return b.env; 418 } catch (AssertionError ae) { 419 if (ae.getCause() instanceof BreakAttr) { 420 return ((BreakAttr)(ae.getCause())).env; 421 } else { 422 throw ae; 423 } 424 } finally { 425 breakTree = null; 426 log.useSource(prev); 427 } 428 return env; 429 } 430 431 private JCTree breakTree = null; 432 433 private static class BreakAttr extends RuntimeException { 434 static final long serialVersionUID = -6924771130405446405L; 435 private Env<AttrContext> env; 436 private BreakAttr(Env<AttrContext> env) { 437 this.env = env; 438 } 439 } 440 441 /** 442 * Mode controlling behavior of Attr.Check 443 */ 444 enum CheckMode { 445 446 NORMAL, 447 448 NO_TREE_UPDATE { // Mode signalling 'fake check' - skip tree update 449 @Override 450 public boolean updateTreeType() { 451 return false; 452 } 453 }, 454 NO_INFERENCE_HOOK { // Mode signalling that caller will manage free types in tree decorations. 455 @Override 456 public boolean installPostInferenceHook() { 457 return false; 458 } 459 }; 460 461 public boolean updateTreeType() { 462 return true; 463 } 464 public boolean installPostInferenceHook() { 465 return true; 466 } 467 } 468 469 470 class ResultInfo { 471 final KindSelector pkind; 472 final Type pt; 473 final CheckContext checkContext; 474 final CheckMode checkMode; 475 476 ResultInfo(KindSelector pkind, Type pt) { 477 this(pkind, pt, chk.basicHandler, CheckMode.NORMAL); 478 } 479 480 ResultInfo(KindSelector pkind, Type pt, CheckMode checkMode) { 481 this(pkind, pt, chk.basicHandler, checkMode); 482 } 483 484 protected ResultInfo(KindSelector pkind, 485 Type pt, CheckContext checkContext) { 486 this(pkind, pt, checkContext, CheckMode.NORMAL); 487 } 488 489 protected ResultInfo(KindSelector pkind, 490 Type pt, CheckContext checkContext, CheckMode checkMode) { 491 this.pkind = pkind; 492 this.pt = pt; 493 this.checkContext = checkContext; 494 this.checkMode = checkMode; 495 } 496 497 protected void attr(JCTree tree, Env<AttrContext> env) { 498 tree.accept(Attr.this); 499 } 500 501 protected Type check(final DiagnosticPosition pos, final Type found) { 502 return chk.checkType(pos, found, pt, checkContext); 503 } 504 505 protected ResultInfo dup(Type newPt) { 506 return new ResultInfo(pkind, newPt, checkContext, checkMode); 507 } 508 509 protected ResultInfo dup(CheckContext newContext) { 510 return new ResultInfo(pkind, pt, newContext, checkMode); 511 } 512 513 protected ResultInfo dup(Type newPt, CheckContext newContext) { 514 return new ResultInfo(pkind, newPt, newContext, checkMode); 515 } 516 517 protected ResultInfo dup(Type newPt, CheckContext newContext, CheckMode newMode) { 518 return new ResultInfo(pkind, newPt, newContext, newMode); 519 } 520 521 protected ResultInfo dup(CheckMode newMode) { 522 return new ResultInfo(pkind, pt, checkContext, newMode); 523 } 524 525 @Override 526 public String toString() { 527 if (pt != null) { 528 return pt.toString(); 529 } else { 530 return ""; 531 } 532 } 533 } 534 535 class MethodAttrInfo extends ResultInfo { 536 public MethodAttrInfo() { 537 this(chk.basicHandler); 538 } 539 540 public MethodAttrInfo(CheckContext checkContext) { 541 super(KindSelector.VAL, Infer.anyPoly, checkContext); 542 } 543 544 @Override 545 protected void attr(JCTree tree, Env<AttrContext> env) { 546 result = argumentAttr.attribArg(tree, env); 547 } 548 549 protected ResultInfo dup(Type newPt) { 550 throw new IllegalStateException(); 551 } 552 553 protected ResultInfo dup(CheckContext newContext) { 554 return new MethodAttrInfo(newContext); 555 } 556 557 protected ResultInfo dup(Type newPt, CheckContext newContext) { 558 throw new IllegalStateException(); 559 } 560 561 protected ResultInfo dup(Type newPt, CheckContext newContext, CheckMode newMode) { 562 throw new IllegalStateException(); 563 } 564 565 protected ResultInfo dup(CheckMode newMode) { 566 throw new IllegalStateException(); 567 } 568 } 569 570 class RecoveryInfo extends ResultInfo { 571 572 public RecoveryInfo(final DeferredAttr.DeferredAttrContext deferredAttrContext) { 573 super(KindSelector.VAL, Type.recoveryType, 574 new Check.NestedCheckContext(chk.basicHandler) { 575 @Override 576 public DeferredAttr.DeferredAttrContext deferredAttrContext() { 577 return deferredAttrContext; 578 } 579 @Override 580 public boolean compatible(Type found, Type req, Warner warn) { 581 return true; 582 } 583 @Override 584 public void report(DiagnosticPosition pos, JCDiagnostic details) { 585 chk.basicHandler.report(pos, details); 586 } 587 }); 588 } 589 } 590 591 final ResultInfo statInfo; 592 final ResultInfo varAssignmentInfo; 593 final ResultInfo methodAttrInfo; 594 final ResultInfo unknownExprInfo; 595 final ResultInfo unknownTypeInfo; 596 final ResultInfo unknownTypeExprInfo; 597 final ResultInfo recoveryInfo; 598 599 Type pt() { 600 return resultInfo.pt; 601 } 602 603 KindSelector pkind() { 604 return resultInfo.pkind; 605 } 606 607/* ************************************************************************ 608 * Visitor methods 609 *************************************************************************/ 610 611 /** Visitor argument: the current environment. 612 */ 613 Env<AttrContext> env; 614 615 /** Visitor argument: the currently expected attribution result. 616 */ 617 ResultInfo resultInfo; 618 619 /** Visitor result: the computed type. 620 */ 621 Type result; 622 623 /** Visitor method: attribute a tree, catching any completion failure 624 * exceptions. Return the tree's type. 625 * 626 * @param tree The tree to be visited. 627 * @param env The environment visitor argument. 628 * @param resultInfo The result info visitor argument. 629 */ 630 Type attribTree(JCTree tree, Env<AttrContext> env, ResultInfo resultInfo) { 631 Env<AttrContext> prevEnv = this.env; 632 ResultInfo prevResult = this.resultInfo; 633 try { 634 this.env = env; 635 this.resultInfo = resultInfo; 636 resultInfo.attr(tree, env); 637 if (tree == breakTree && 638 resultInfo.checkContext.deferredAttrContext().mode == AttrMode.CHECK) { 639 throw new BreakAttr(copyEnv(env)); 640 } 641 return result; 642 } catch (CompletionFailure ex) { 643 tree.type = syms.errType; 644 return chk.completionError(tree.pos(), ex); 645 } finally { 646 this.env = prevEnv; 647 this.resultInfo = prevResult; 648 } 649 } 650 651 Env<AttrContext> copyEnv(Env<AttrContext> env) { 652 Env<AttrContext> newEnv = 653 env.dup(env.tree, env.info.dup(copyScope(env.info.scope))); 654 if (newEnv.outer != null) { 655 newEnv.outer = copyEnv(newEnv.outer); 656 } 657 return newEnv; 658 } 659 660 WriteableScope copyScope(WriteableScope sc) { 661 WriteableScope newScope = WriteableScope.create(sc.owner); 662 List<Symbol> elemsList = List.nil(); 663 for (Symbol sym : sc.getSymbols()) { 664 elemsList = elemsList.prepend(sym); 665 } 666 for (Symbol s : elemsList) { 667 newScope.enter(s); 668 } 669 return newScope; 670 } 671 672 /** Derived visitor method: attribute an expression tree. 673 */ 674 public Type attribExpr(JCTree tree, Env<AttrContext> env, Type pt) { 675 return attribTree(tree, env, new ResultInfo(KindSelector.VAL, !pt.hasTag(ERROR) ? pt : Type.noType)); 676 } 677 678 /** Derived visitor method: attribute an expression tree with 679 * no constraints on the computed type. 680 */ 681 public Type attribExpr(JCTree tree, Env<AttrContext> env) { 682 return attribTree(tree, env, unknownExprInfo); 683 } 684 685 /** Derived visitor method: attribute a type tree. 686 */ 687 public Type attribType(JCTree tree, Env<AttrContext> env) { 688 Type result = attribType(tree, env, Type.noType); 689 return result; 690 } 691 692 /** Derived visitor method: attribute a type tree. 693 */ 694 Type attribType(JCTree tree, Env<AttrContext> env, Type pt) { 695 Type result = attribTree(tree, env, new ResultInfo(KindSelector.TYP, pt)); 696 return result; 697 } 698 699 /** Derived visitor method: attribute a statement or definition tree. 700 */ 701 public Type attribStat(JCTree tree, Env<AttrContext> env) { 702 Env<AttrContext> analyzeEnv = 703 env.dup(tree, env.info.dup(env.info.scope.dupUnshared(env.info.scope.owner))); 704 try { 705 return attribTree(tree, env, statInfo); 706 } finally { 707 analyzer.analyzeIfNeeded(tree, analyzeEnv); 708 } 709 } 710 711 /** Attribute a list of expressions, returning a list of types. 712 */ 713 List<Type> attribExprs(List<JCExpression> trees, Env<AttrContext> env, Type pt) { 714 ListBuffer<Type> ts = new ListBuffer<>(); 715 for (List<JCExpression> l = trees; l.nonEmpty(); l = l.tail) 716 ts.append(attribExpr(l.head, env, pt)); 717 return ts.toList(); 718 } 719 720 /** Attribute a list of statements, returning nothing. 721 */ 722 <T extends JCTree> void attribStats(List<T> trees, Env<AttrContext> env) { 723 for (List<T> l = trees; l.nonEmpty(); l = l.tail) 724 attribStat(l.head, env); 725 } 726 727 /** Attribute the arguments in a method call, returning the method kind. 728 */ 729 KindSelector attribArgs(KindSelector initialKind, List<JCExpression> trees, Env<AttrContext> env, ListBuffer<Type> argtypes) { 730 KindSelector kind = initialKind; 731 for (JCExpression arg : trees) { 732 Type argtype = chk.checkNonVoid(arg, attribTree(arg, env, allowPoly ? methodAttrInfo : unknownExprInfo)); 733 if (argtype.hasTag(DEFERRED)) { 734 kind = KindSelector.of(KindSelector.POLY, kind); 735 } 736 argtypes.append(argtype); 737 } 738 return kind; 739 } 740 741 /** Attribute a type argument list, returning a list of types. 742 * Caller is responsible for calling checkRefTypes. 743 */ 744 List<Type> attribAnyTypes(List<JCExpression> trees, Env<AttrContext> env) { 745 ListBuffer<Type> argtypes = new ListBuffer<>(); 746 for (List<JCExpression> l = trees; l.nonEmpty(); l = l.tail) 747 argtypes.append(attribType(l.head, env)); 748 return argtypes.toList(); 749 } 750 751 /** Attribute a type argument list, returning a list of types. 752 * Check that all the types are references. 753 */ 754 List<Type> attribTypes(List<JCExpression> trees, Env<AttrContext> env) { 755 List<Type> types = attribAnyTypes(trees, env); 756 return chk.checkRefTypes(trees, types); 757 } 758 759 /** 760 * Attribute type variables (of generic classes or methods). 761 * Compound types are attributed later in attribBounds. 762 * @param typarams the type variables to enter 763 * @param env the current environment 764 */ 765 void attribTypeVariables(List<JCTypeParameter> typarams, Env<AttrContext> env) { 766 for (JCTypeParameter tvar : typarams) { 767 TypeVar a = (TypeVar)tvar.type; 768 a.tsym.flags_field |= UNATTRIBUTED; 769 a.bound = Type.noType; 770 if (!tvar.bounds.isEmpty()) { 771 List<Type> bounds = List.of(attribType(tvar.bounds.head, env)); 772 for (JCExpression bound : tvar.bounds.tail) 773 bounds = bounds.prepend(attribType(bound, env)); 774 types.setBounds(a, bounds.reverse()); 775 } else { 776 // if no bounds are given, assume a single bound of 777 // java.lang.Object. 778 types.setBounds(a, List.of(syms.objectType)); 779 } 780 a.tsym.flags_field &= ~UNATTRIBUTED; 781 } 782 for (JCTypeParameter tvar : typarams) { 783 chk.checkNonCyclic(tvar.pos(), (TypeVar)tvar.type); 784 } 785 } 786 787 /** 788 * Attribute the type references in a list of annotations. 789 */ 790 void attribAnnotationTypes(List<JCAnnotation> annotations, 791 Env<AttrContext> env) { 792 for (List<JCAnnotation> al = annotations; al.nonEmpty(); al = al.tail) { 793 JCAnnotation a = al.head; 794 attribType(a.annotationType, env); 795 } 796 } 797 798 /** 799 * Attribute a "lazy constant value". 800 * @param env The env for the const value 801 * @param variable The initializer for the const value 802 * @param type The expected type, or null 803 * @see VarSymbol#setLazyConstValue 804 */ 805 public Object attribLazyConstantValue(Env<AttrContext> env, 806 JCVariableDecl variable, 807 Type type) { 808 809 DiagnosticPosition prevLintPos 810 = deferredLintHandler.setPos(variable.pos()); 811 812 try { 813 Type itype = attribExpr(variable.init, env, type); 814 if (itype.constValue() != null) { 815 return coerce(itype, type).constValue(); 816 } else { 817 return null; 818 } 819 } finally { 820 deferredLintHandler.setPos(prevLintPos); 821 } 822 } 823 824 /** Attribute type reference in an `extends' or `implements' clause. 825 * Supertypes of anonymous inner classes are usually already attributed. 826 * 827 * @param tree The tree making up the type reference. 828 * @param env The environment current at the reference. 829 * @param classExpected true if only a class is expected here. 830 * @param interfaceExpected true if only an interface is expected here. 831 */ 832 Type attribBase(JCTree tree, 833 Env<AttrContext> env, 834 boolean classExpected, 835 boolean interfaceExpected, 836 boolean checkExtensible) { 837 Type t = tree.type != null ? 838 tree.type : 839 attribType(tree, env); 840 return checkBase(t, tree, env, classExpected, interfaceExpected, checkExtensible); 841 } 842 Type checkBase(Type t, 843 JCTree tree, 844 Env<AttrContext> env, 845 boolean classExpected, 846 boolean interfaceExpected, 847 boolean checkExtensible) { 848 final DiagnosticPosition pos = tree.hasTag(TYPEAPPLY) ? 849 (((JCTypeApply) tree).clazz).pos() : tree.pos(); 850 if (t.tsym.isAnonymous()) { 851 log.error(pos, "cant.inherit.from.anon"); 852 return types.createErrorType(t); 853 } 854 if (t.isErroneous()) 855 return t; 856 if (t.hasTag(TYPEVAR) && !classExpected && !interfaceExpected) { 857 // check that type variable is already visible 858 if (t.getUpperBound() == null) { 859 log.error(pos, "illegal.forward.ref"); 860 return types.createErrorType(t); 861 } 862 } else { 863 t = chk.checkClassType(pos, t, checkExtensible); 864 } 865 if (interfaceExpected && (t.tsym.flags() & INTERFACE) == 0) { 866 log.error(pos, "intf.expected.here"); 867 // return errType is necessary since otherwise there might 868 // be undetected cycles which cause attribution to loop 869 return types.createErrorType(t); 870 } else if (checkExtensible && 871 classExpected && 872 (t.tsym.flags() & INTERFACE) != 0) { 873 log.error(pos, "no.intf.expected.here"); 874 return types.createErrorType(t); 875 } 876 if (checkExtensible && 877 ((t.tsym.flags() & FINAL) != 0)) { 878 log.error(pos, 879 "cant.inherit.from.final", t.tsym); 880 } 881 chk.checkNonCyclic(pos, t); 882 return t; 883 } 884 885 Type attribIdentAsEnumType(Env<AttrContext> env, JCIdent id) { 886 Assert.check((env.enclClass.sym.flags() & ENUM) != 0); 887 id.type = env.info.scope.owner.enclClass().type; 888 id.sym = env.info.scope.owner.enclClass(); 889 return id.type; 890 } 891 892 public void visitClassDef(JCClassDecl tree) { 893 Optional<ArgumentAttr.LocalCacheContext> localCacheContext = 894 Optional.ofNullable(env.info.isSpeculative ? 895 argumentAttr.withLocalCacheContext() : null); 896 try { 897 // Local and anonymous classes have not been entered yet, so we need to 898 // do it now. 899 if (env.info.scope.owner.kind.matches(KindSelector.VAL_MTH)) { 900 enter.classEnter(tree, env); 901 } else { 902 // If this class declaration is part of a class level annotation, 903 // as in @MyAnno(new Object() {}) class MyClass {}, enter it in 904 // order to simplify later steps and allow for sensible error 905 // messages. 906 if (env.tree.hasTag(NEWCLASS) && TreeInfo.isInAnnotation(env, tree)) 907 enter.classEnter(tree, env); 908 } 909 910 ClassSymbol c = tree.sym; 911 if (c == null) { 912 // exit in case something drastic went wrong during enter. 913 result = null; 914 } else { 915 // make sure class has been completed: 916 c.complete(); 917 918 // If this class appears as an anonymous class 919 // in a superclass constructor call where 920 // no explicit outer instance is given, 921 // disable implicit outer instance from being passed. 922 // (This would be an illegal access to "this before super"). 923 if (env.info.isSelfCall && 924 env.tree.hasTag(NEWCLASS) && 925 ((JCNewClass)env.tree).encl == null) { 926 c.flags_field |= NOOUTERTHIS; 927 } 928 attribClass(tree.pos(), c); 929 result = tree.type = c.type; 930 } 931 } finally { 932 localCacheContext.ifPresent(LocalCacheContext::leave); 933 } 934 } 935 936 public void visitMethodDef(JCMethodDecl tree) { 937 MethodSymbol m = tree.sym; 938 boolean isDefaultMethod = (m.flags() & DEFAULT) != 0; 939 940 Lint lint = env.info.lint.augment(m); 941 Lint prevLint = chk.setLint(lint); 942 MethodSymbol prevMethod = chk.setMethod(m); 943 try { 944 deferredLintHandler.flush(tree.pos()); 945 chk.checkDeprecatedAnnotation(tree.pos(), m); 946 947 948 // Create a new environment with local scope 949 // for attributing the method. 950 Env<AttrContext> localEnv = memberEnter.methodEnv(tree, env); 951 localEnv.info.lint = lint; 952 953 attribStats(tree.typarams, localEnv); 954 955 // If we override any other methods, check that we do so properly. 956 // JLS ??? 957 if (m.isStatic()) { 958 chk.checkHideClashes(tree.pos(), env.enclClass.type, m); 959 } else { 960 chk.checkOverrideClashes(tree.pos(), env.enclClass.type, m); 961 } 962 chk.checkOverride(env, tree, m); 963 964 if (isDefaultMethod && types.overridesObjectMethod(m.enclClass(), m)) { 965 log.error(tree, "default.overrides.object.member", m.name, Kinds.kindName(m.location()), m.location()); 966 } 967 968 // Enter all type parameters into the local method scope. 969 for (List<JCTypeParameter> l = tree.typarams; l.nonEmpty(); l = l.tail) 970 localEnv.info.scope.enterIfAbsent(l.head.type.tsym); 971 972 ClassSymbol owner = env.enclClass.sym; 973 if ((owner.flags() & ANNOTATION) != 0 && 974 tree.params.nonEmpty()) 975 log.error(tree.params.head.pos(), 976 "intf.annotation.members.cant.have.params"); 977 978 // Attribute all value parameters. 979 for (List<JCVariableDecl> l = tree.params; l.nonEmpty(); l = l.tail) { 980 attribStat(l.head, localEnv); 981 } 982 983 chk.checkVarargsMethodDecl(localEnv, tree); 984 985 // Check that type parameters are well-formed. 986 chk.validate(tree.typarams, localEnv); 987 988 // Check that result type is well-formed. 989 if (tree.restype != null && !tree.restype.type.hasTag(VOID)) 990 chk.validate(tree.restype, localEnv); 991 992 // Check that receiver type is well-formed. 993 if (tree.recvparam != null) { 994 // Use a new environment to check the receiver parameter. 995 // Otherwise I get "might not have been initialized" errors. 996 // Is there a better way? 997 Env<AttrContext> newEnv = memberEnter.methodEnv(tree, env); 998 attribType(tree.recvparam, newEnv); 999 chk.validate(tree.recvparam, newEnv); 1000 } 1001 1002 // annotation method checks 1003 if ((owner.flags() & ANNOTATION) != 0) { 1004 // annotation method cannot have throws clause 1005 if (tree.thrown.nonEmpty()) { 1006 log.error(tree.thrown.head.pos(), 1007 "throws.not.allowed.in.intf.annotation"); 1008 } 1009 // annotation method cannot declare type-parameters 1010 if (tree.typarams.nonEmpty()) { 1011 log.error(tree.typarams.head.pos(), 1012 "intf.annotation.members.cant.have.type.params"); 1013 } 1014 // validate annotation method's return type (could be an annotation type) 1015 chk.validateAnnotationType(tree.restype); 1016 // ensure that annotation method does not clash with members of Object/Annotation 1017 chk.validateAnnotationMethod(tree.pos(), m); 1018 } 1019 1020 for (List<JCExpression> l = tree.thrown; l.nonEmpty(); l = l.tail) 1021 chk.checkType(l.head.pos(), l.head.type, syms.throwableType); 1022 1023 if (tree.body == null) { 1024 // Empty bodies are only allowed for 1025 // abstract, native, or interface methods, or for methods 1026 // in a retrofit signature class. 1027 if (tree.defaultValue != null) { 1028 if ((owner.flags() & ANNOTATION) == 0) 1029 log.error(tree.pos(), 1030 "default.allowed.in.intf.annotation.member"); 1031 } 1032 if (isDefaultMethod || (tree.sym.flags() & (ABSTRACT | NATIVE)) == 0) 1033 log.error(tree.pos(), "missing.meth.body.or.decl.abstract"); 1034 } else if ((tree.sym.flags() & (ABSTRACT|DEFAULT|PRIVATE)) == ABSTRACT) { 1035 if ((owner.flags() & INTERFACE) != 0) { 1036 log.error(tree.body.pos(), "intf.meth.cant.have.body"); 1037 } else { 1038 log.error(tree.pos(), "abstract.meth.cant.have.body"); 1039 } 1040 } else if ((tree.mods.flags & NATIVE) != 0) { 1041 log.error(tree.pos(), "native.meth.cant.have.body"); 1042 } else { 1043 // Add an implicit super() call unless an explicit call to 1044 // super(...) or this(...) is given 1045 // or we are compiling class java.lang.Object. 1046 if (tree.name == names.init && owner.type != syms.objectType) { 1047 JCBlock body = tree.body; 1048 if (body.stats.isEmpty() || 1049 !TreeInfo.isSelfCall(body.stats.head)) { 1050 body.stats = body.stats. 1051 prepend(typeEnter.SuperCall(make.at(body.pos), 1052 List.<Type>nil(), 1053 List.<JCVariableDecl>nil(), 1054 false)); 1055 } else if ((env.enclClass.sym.flags() & ENUM) != 0 && 1056 (tree.mods.flags & GENERATEDCONSTR) == 0 && 1057 TreeInfo.isSuperCall(body.stats.head)) { 1058 // enum constructors are not allowed to call super 1059 // directly, so make sure there aren't any super calls 1060 // in enum constructors, except in the compiler 1061 // generated one. 1062 log.error(tree.body.stats.head.pos(), 1063 "call.to.super.not.allowed.in.enum.ctor", 1064 env.enclClass.sym); 1065 } 1066 } 1067 1068 // Attribute all type annotations in the body 1069 annotate.queueScanTreeAndTypeAnnotate(tree.body, localEnv, m, null); 1070 annotate.flush(); 1071 1072 // Attribute method body. 1073 attribStat(tree.body, localEnv); 1074 } 1075 1076 localEnv.info.scope.leave(); 1077 result = tree.type = m.type; 1078 } finally { 1079 chk.setLint(prevLint); 1080 chk.setMethod(prevMethod); 1081 } 1082 } 1083 1084 public void visitVarDef(JCVariableDecl tree) { 1085 // Local variables have not been entered yet, so we need to do it now: 1086 if (env.info.scope.owner.kind == MTH) { 1087 if (tree.sym != null) { 1088 // parameters have already been entered 1089 env.info.scope.enter(tree.sym); 1090 } else { 1091 try { 1092 annotate.blockAnnotations(); 1093 memberEnter.memberEnter(tree, env); 1094 } finally { 1095 annotate.unblockAnnotations(); 1096 } 1097 } 1098 } else { 1099 if (tree.init != null) { 1100 // Field initializer expression need to be entered. 1101 annotate.queueScanTreeAndTypeAnnotate(tree.init, env, tree.sym, tree.pos()); 1102 annotate.flush(); 1103 } 1104 } 1105 1106 VarSymbol v = tree.sym; 1107 Lint lint = env.info.lint.augment(v); 1108 Lint prevLint = chk.setLint(lint); 1109 1110 // Check that the variable's declared type is well-formed. 1111 boolean isImplicitLambdaParameter = env.tree.hasTag(LAMBDA) && 1112 ((JCLambda)env.tree).paramKind == JCLambda.ParameterKind.IMPLICIT && 1113 (tree.sym.flags() & PARAMETER) != 0; 1114 chk.validate(tree.vartype, env, !isImplicitLambdaParameter); 1115 1116 try { 1117 v.getConstValue(); // ensure compile-time constant initializer is evaluated 1118 deferredLintHandler.flush(tree.pos()); 1119 chk.checkDeprecatedAnnotation(tree.pos(), v); 1120 1121 if (tree.init != null) { 1122 if ((v.flags_field & FINAL) == 0 || 1123 !memberEnter.needsLazyConstValue(tree.init)) { 1124 // Not a compile-time constant 1125 // Attribute initializer in a new environment 1126 // with the declared variable as owner. 1127 // Check that initializer conforms to variable's declared type. 1128 Env<AttrContext> initEnv = memberEnter.initEnv(tree, env); 1129 initEnv.info.lint = lint; 1130 // In order to catch self-references, we set the variable's 1131 // declaration position to maximal possible value, effectively 1132 // marking the variable as undefined. 1133 initEnv.info.enclVar = v; 1134 attribExpr(tree.init, initEnv, v.type); 1135 } 1136 } 1137 result = tree.type = v.type; 1138 } 1139 finally { 1140 chk.setLint(prevLint); 1141 } 1142 } 1143 1144 public void visitSkip(JCSkip tree) { 1145 result = null; 1146 } 1147 1148 public void visitBlock(JCBlock tree) { 1149 if (env.info.scope.owner.kind == TYP) { 1150 // Block is a static or instance initializer; 1151 // let the owner of the environment be a freshly 1152 // created BLOCK-method. 1153 Symbol fakeOwner = 1154 new MethodSymbol(tree.flags | BLOCK | 1155 env.info.scope.owner.flags() & STRICTFP, names.empty, null, 1156 env.info.scope.owner); 1157 final Env<AttrContext> localEnv = 1158 env.dup(tree, env.info.dup(env.info.scope.dupUnshared(fakeOwner))); 1159 1160 if ((tree.flags & STATIC) != 0) localEnv.info.staticLevel++; 1161 // Attribute all type annotations in the block 1162 annotate.queueScanTreeAndTypeAnnotate(tree, localEnv, localEnv.info.scope.owner, null); 1163 annotate.flush(); 1164 attribStats(tree.stats, localEnv); 1165 1166 { 1167 // Store init and clinit type annotations with the ClassSymbol 1168 // to allow output in Gen.normalizeDefs. 1169 ClassSymbol cs = (ClassSymbol)env.info.scope.owner; 1170 List<Attribute.TypeCompound> tas = localEnv.info.scope.owner.getRawTypeAttributes(); 1171 if ((tree.flags & STATIC) != 0) { 1172 cs.appendClassInitTypeAttributes(tas); 1173 } else { 1174 cs.appendInitTypeAttributes(tas); 1175 } 1176 } 1177 } else { 1178 // Create a new local environment with a local scope. 1179 Env<AttrContext> localEnv = 1180 env.dup(tree, env.info.dup(env.info.scope.dup())); 1181 try { 1182 attribStats(tree.stats, localEnv); 1183 } finally { 1184 localEnv.info.scope.leave(); 1185 } 1186 } 1187 result = null; 1188 } 1189 1190 public void visitDoLoop(JCDoWhileLoop tree) { 1191 attribStat(tree.body, env.dup(tree)); 1192 attribExpr(tree.cond, env, syms.booleanType); 1193 result = null; 1194 } 1195 1196 public void visitWhileLoop(JCWhileLoop tree) { 1197 attribExpr(tree.cond, env, syms.booleanType); 1198 attribStat(tree.body, env.dup(tree)); 1199 result = null; 1200 } 1201 1202 public void visitForLoop(JCForLoop tree) { 1203 Env<AttrContext> loopEnv = 1204 env.dup(env.tree, env.info.dup(env.info.scope.dup())); 1205 try { 1206 attribStats(tree.init, loopEnv); 1207 if (tree.cond != null) attribExpr(tree.cond, loopEnv, syms.booleanType); 1208 loopEnv.tree = tree; // before, we were not in loop! 1209 attribStats(tree.step, loopEnv); 1210 attribStat(tree.body, loopEnv); 1211 result = null; 1212 } 1213 finally { 1214 loopEnv.info.scope.leave(); 1215 } 1216 } 1217 1218 public void visitForeachLoop(JCEnhancedForLoop tree) { 1219 Env<AttrContext> loopEnv = 1220 env.dup(env.tree, env.info.dup(env.info.scope.dup())); 1221 try { 1222 //the Formal Parameter of a for-each loop is not in the scope when 1223 //attributing the for-each expression; we mimick this by attributing 1224 //the for-each expression first (against original scope). 1225 Type exprType = types.cvarUpperBound(attribExpr(tree.expr, loopEnv)); 1226 attribStat(tree.var, loopEnv); 1227 chk.checkNonVoid(tree.pos(), exprType); 1228 Type elemtype = types.elemtype(exprType); // perhaps expr is an array? 1229 if (elemtype == null) { 1230 // or perhaps expr implements Iterable<T>? 1231 Type base = types.asSuper(exprType, syms.iterableType.tsym); 1232 if (base == null) { 1233 log.error(tree.expr.pos(), 1234 "foreach.not.applicable.to.type", 1235 exprType, 1236 diags.fragment("type.req.array.or.iterable")); 1237 elemtype = types.createErrorType(exprType); 1238 } else { 1239 List<Type> iterableParams = base.allparams(); 1240 elemtype = iterableParams.isEmpty() 1241 ? syms.objectType 1242 : types.wildUpperBound(iterableParams.head); 1243 } 1244 } 1245 chk.checkType(tree.expr.pos(), elemtype, tree.var.sym.type); 1246 loopEnv.tree = tree; // before, we were not in loop! 1247 attribStat(tree.body, loopEnv); 1248 result = null; 1249 } 1250 finally { 1251 loopEnv.info.scope.leave(); 1252 } 1253 } 1254 1255 public void visitLabelled(JCLabeledStatement tree) { 1256 // Check that label is not used in an enclosing statement 1257 Env<AttrContext> env1 = env; 1258 while (env1 != null && !env1.tree.hasTag(CLASSDEF)) { 1259 if (env1.tree.hasTag(LABELLED) && 1260 ((JCLabeledStatement) env1.tree).label == tree.label) { 1261 log.error(tree.pos(), "label.already.in.use", 1262 tree.label); 1263 break; 1264 } 1265 env1 = env1.next; 1266 } 1267 1268 attribStat(tree.body, env.dup(tree)); 1269 result = null; 1270 } 1271 1272 public void visitSwitch(JCSwitch tree) { 1273 Type seltype = attribExpr(tree.selector, env); 1274 1275 Env<AttrContext> switchEnv = 1276 env.dup(tree, env.info.dup(env.info.scope.dup())); 1277 1278 try { 1279 1280 boolean enumSwitch = (seltype.tsym.flags() & Flags.ENUM) != 0; 1281 boolean stringSwitch = false; 1282 if (types.isSameType(seltype, syms.stringType)) { 1283 if (allowStringsInSwitch) { 1284 stringSwitch = true; 1285 } else { 1286 log.error(tree.selector.pos(), "string.switch.not.supported.in.source", sourceName); 1287 } 1288 } 1289 if (!enumSwitch && !stringSwitch) 1290 seltype = chk.checkType(tree.selector.pos(), seltype, syms.intType); 1291 1292 // Attribute all cases and 1293 // check that there are no duplicate case labels or default clauses. 1294 Set<Object> labels = new HashSet<>(); // The set of case labels. 1295 boolean hasDefault = false; // Is there a default label? 1296 for (List<JCCase> l = tree.cases; l.nonEmpty(); l = l.tail) { 1297 JCCase c = l.head; 1298 if (c.pat != null) { 1299 if (enumSwitch) { 1300 Symbol sym = enumConstant(c.pat, seltype); 1301 if (sym == null) { 1302 log.error(c.pat.pos(), "enum.label.must.be.unqualified.enum"); 1303 } else if (!labels.add(sym)) { 1304 log.error(c.pos(), "duplicate.case.label"); 1305 } 1306 } else { 1307 Type pattype = attribExpr(c.pat, switchEnv, seltype); 1308 if (!pattype.hasTag(ERROR)) { 1309 if (pattype.constValue() == null) { 1310 log.error(c.pat.pos(), 1311 (stringSwitch ? "string.const.req" : "const.expr.req")); 1312 } else if (!labels.add(pattype.constValue())) { 1313 log.error(c.pos(), "duplicate.case.label"); 1314 } 1315 } 1316 } 1317 } else if (hasDefault) { 1318 log.error(c.pos(), "duplicate.default.label"); 1319 } else { 1320 hasDefault = true; 1321 } 1322 Env<AttrContext> caseEnv = 1323 switchEnv.dup(c, env.info.dup(switchEnv.info.scope.dup())); 1324 try { 1325 attribStats(c.stats, caseEnv); 1326 } finally { 1327 caseEnv.info.scope.leave(); 1328 addVars(c.stats, switchEnv.info.scope); 1329 } 1330 } 1331 1332 result = null; 1333 } 1334 finally { 1335 switchEnv.info.scope.leave(); 1336 } 1337 } 1338 // where 1339 /** Add any variables defined in stats to the switch scope. */ 1340 private static void addVars(List<JCStatement> stats, WriteableScope switchScope) { 1341 for (;stats.nonEmpty(); stats = stats.tail) { 1342 JCTree stat = stats.head; 1343 if (stat.hasTag(VARDEF)) 1344 switchScope.enter(((JCVariableDecl) stat).sym); 1345 } 1346 } 1347 // where 1348 /** Return the selected enumeration constant symbol, or null. */ 1349 private Symbol enumConstant(JCTree tree, Type enumType) { 1350 if (tree.hasTag(IDENT)) { 1351 JCIdent ident = (JCIdent)tree; 1352 Name name = ident.name; 1353 for (Symbol sym : enumType.tsym.members().getSymbolsByName(name)) { 1354 if (sym.kind == VAR) { 1355 Symbol s = ident.sym = sym; 1356 ((VarSymbol)s).getConstValue(); // ensure initializer is evaluated 1357 ident.type = s.type; 1358 return ((s.flags_field & Flags.ENUM) == 0) 1359 ? null : s; 1360 } 1361 } 1362 } 1363 return null; 1364 } 1365 1366 public void visitSynchronized(JCSynchronized tree) { 1367 chk.checkRefType(tree.pos(), attribExpr(tree.lock, env)); 1368 attribStat(tree.body, env); 1369 result = null; 1370 } 1371 1372 public void visitTry(JCTry tree) { 1373 // Create a new local environment with a local 1374 Env<AttrContext> localEnv = env.dup(tree, env.info.dup(env.info.scope.dup())); 1375 try { 1376 boolean isTryWithResource = tree.resources.nonEmpty(); 1377 // Create a nested environment for attributing the try block if needed 1378 Env<AttrContext> tryEnv = isTryWithResource ? 1379 env.dup(tree, localEnv.info.dup(localEnv.info.scope.dup())) : 1380 localEnv; 1381 try { 1382 // Attribute resource declarations 1383 for (JCTree resource : tree.resources) { 1384 CheckContext twrContext = new Check.NestedCheckContext(resultInfo.checkContext) { 1385 @Override 1386 public void report(DiagnosticPosition pos, JCDiagnostic details) { 1387 chk.basicHandler.report(pos, diags.fragment("try.not.applicable.to.type", details)); 1388 } 1389 }; 1390 ResultInfo twrResult = 1391 new ResultInfo(KindSelector.VAR, 1392 syms.autoCloseableType, 1393 twrContext); 1394 if (resource.hasTag(VARDEF)) { 1395 attribStat(resource, tryEnv); 1396 twrResult.check(resource, resource.type); 1397 1398 //check that resource type cannot throw InterruptedException 1399 checkAutoCloseable(resource.pos(), localEnv, resource.type); 1400 1401 VarSymbol var = ((JCVariableDecl) resource).sym; 1402 var.setData(ElementKind.RESOURCE_VARIABLE); 1403 } else { 1404 attribTree(resource, tryEnv, twrResult); 1405 } 1406 } 1407 // Attribute body 1408 attribStat(tree.body, tryEnv); 1409 } finally { 1410 if (isTryWithResource) 1411 tryEnv.info.scope.leave(); 1412 } 1413 1414 // Attribute catch clauses 1415 for (List<JCCatch> l = tree.catchers; l.nonEmpty(); l = l.tail) { 1416 JCCatch c = l.head; 1417 Env<AttrContext> catchEnv = 1418 localEnv.dup(c, localEnv.info.dup(localEnv.info.scope.dup())); 1419 try { 1420 Type ctype = attribStat(c.param, catchEnv); 1421 if (TreeInfo.isMultiCatch(c)) { 1422 //multi-catch parameter is implicitly marked as final 1423 c.param.sym.flags_field |= FINAL | UNION; 1424 } 1425 if (c.param.sym.kind == VAR) { 1426 c.param.sym.setData(ElementKind.EXCEPTION_PARAMETER); 1427 } 1428 chk.checkType(c.param.vartype.pos(), 1429 chk.checkClassType(c.param.vartype.pos(), ctype), 1430 syms.throwableType); 1431 attribStat(c.body, catchEnv); 1432 } finally { 1433 catchEnv.info.scope.leave(); 1434 } 1435 } 1436 1437 // Attribute finalizer 1438 if (tree.finalizer != null) attribStat(tree.finalizer, localEnv); 1439 result = null; 1440 } 1441 finally { 1442 localEnv.info.scope.leave(); 1443 } 1444 } 1445 1446 void checkAutoCloseable(DiagnosticPosition pos, Env<AttrContext> env, Type resource) { 1447 if (!resource.isErroneous() && 1448 types.asSuper(resource, syms.autoCloseableType.tsym) != null && 1449 !types.isSameType(resource, syms.autoCloseableType)) { // Don't emit warning for AutoCloseable itself 1450 Symbol close = syms.noSymbol; 1451 Log.DiagnosticHandler discardHandler = new Log.DiscardDiagnosticHandler(log); 1452 try { 1453 close = rs.resolveQualifiedMethod(pos, 1454 env, 1455 resource, 1456 names.close, 1457 List.<Type>nil(), 1458 List.<Type>nil()); 1459 } 1460 finally { 1461 log.popDiagnosticHandler(discardHandler); 1462 } 1463 if (close.kind == MTH && 1464 close.overrides(syms.autoCloseableClose, resource.tsym, types, true) && 1465 chk.isHandled(syms.interruptedExceptionType, types.memberType(resource, close).getThrownTypes()) && 1466 env.info.lint.isEnabled(LintCategory.TRY)) { 1467 log.warning(LintCategory.TRY, pos, "try.resource.throws.interrupted.exc", resource); 1468 } 1469 } 1470 } 1471 1472 public void visitConditional(JCConditional tree) { 1473 Type condtype = attribExpr(tree.cond, env, syms.booleanType); 1474 1475 tree.polyKind = (!allowPoly || 1476 pt().hasTag(NONE) && pt() != Type.recoveryType && pt() != Infer.anyPoly || 1477 isBooleanOrNumeric(env, tree)) ? 1478 PolyKind.STANDALONE : PolyKind.POLY; 1479 1480 if (tree.polyKind == PolyKind.POLY && resultInfo.pt.hasTag(VOID)) { 1481 //this means we are returning a poly conditional from void-compatible lambda expression 1482 resultInfo.checkContext.report(tree, diags.fragment("conditional.target.cant.be.void")); 1483 result = tree.type = types.createErrorType(resultInfo.pt); 1484 return; 1485 } 1486 1487 ResultInfo condInfo = tree.polyKind == PolyKind.STANDALONE ? 1488 unknownExprInfo : 1489 resultInfo.dup(conditionalContext(resultInfo.checkContext)); 1490 1491 Type truetype = attribTree(tree.truepart, env, condInfo); 1492 Type falsetype = attribTree(tree.falsepart, env, condInfo); 1493 1494 Type owntype = (tree.polyKind == PolyKind.STANDALONE) ? condType(tree, truetype, falsetype) : pt(); 1495 if (condtype.constValue() != null && 1496 truetype.constValue() != null && 1497 falsetype.constValue() != null && 1498 !owntype.hasTag(NONE)) { 1499 //constant folding 1500 owntype = cfolder.coerce(condtype.isTrue() ? truetype : falsetype, owntype); 1501 } 1502 result = check(tree, owntype, KindSelector.VAL, resultInfo); 1503 } 1504 //where 1505 private boolean isBooleanOrNumeric(Env<AttrContext> env, JCExpression tree) { 1506 switch (tree.getTag()) { 1507 case LITERAL: return ((JCLiteral)tree).typetag.isSubRangeOf(DOUBLE) || 1508 ((JCLiteral)tree).typetag == BOOLEAN || 1509 ((JCLiteral)tree).typetag == BOT; 1510 case LAMBDA: case REFERENCE: return false; 1511 case PARENS: return isBooleanOrNumeric(env, ((JCParens)tree).expr); 1512 case CONDEXPR: 1513 JCConditional condTree = (JCConditional)tree; 1514 return isBooleanOrNumeric(env, condTree.truepart) && 1515 isBooleanOrNumeric(env, condTree.falsepart); 1516 case APPLY: 1517 JCMethodInvocation speculativeMethodTree = 1518 (JCMethodInvocation)deferredAttr.attribSpeculative(tree, env, unknownExprInfo); 1519 Symbol msym = TreeInfo.symbol(speculativeMethodTree.meth); 1520 Type receiverType = speculativeMethodTree.meth.hasTag(IDENT) ? 1521 env.enclClass.type : 1522 ((JCFieldAccess)speculativeMethodTree.meth).selected.type; 1523 Type owntype = types.memberType(receiverType, msym).getReturnType(); 1524 return primitiveOrBoxed(owntype); 1525 case NEWCLASS: 1526 JCExpression className = 1527 removeClassParams.translate(((JCNewClass)tree).clazz); 1528 JCExpression speculativeNewClassTree = 1529 (JCExpression)deferredAttr.attribSpeculative(className, env, unknownTypeInfo); 1530 return primitiveOrBoxed(speculativeNewClassTree.type); 1531 default: 1532 Type speculativeType = deferredAttr.attribSpeculative(tree, env, unknownExprInfo).type; 1533 return primitiveOrBoxed(speculativeType); 1534 } 1535 } 1536 //where 1537 boolean primitiveOrBoxed(Type t) { 1538 return (!t.hasTag(TYPEVAR) && types.unboxedTypeOrType(t).isPrimitive()); 1539 } 1540 1541 TreeTranslator removeClassParams = new TreeTranslator() { 1542 @Override 1543 public void visitTypeApply(JCTypeApply tree) { 1544 result = translate(tree.clazz); 1545 } 1546 }; 1547 1548 CheckContext conditionalContext(CheckContext checkContext) { 1549 return new Check.NestedCheckContext(checkContext) { 1550 //this will use enclosing check context to check compatibility of 1551 //subexpression against target type; if we are in a method check context, 1552 //depending on whether boxing is allowed, we could have incompatibilities 1553 @Override 1554 public void report(DiagnosticPosition pos, JCDiagnostic details) { 1555 enclosingContext.report(pos, diags.fragment("incompatible.type.in.conditional", details)); 1556 } 1557 }; 1558 } 1559 1560 /** Compute the type of a conditional expression, after 1561 * checking that it exists. See JLS 15.25. Does not take into 1562 * account the special case where condition and both arms 1563 * are constants. 1564 * 1565 * @param pos The source position to be used for error 1566 * diagnostics. 1567 * @param thentype The type of the expression's then-part. 1568 * @param elsetype The type of the expression's else-part. 1569 */ 1570 Type condType(DiagnosticPosition pos, 1571 Type thentype, Type elsetype) { 1572 // If same type, that is the result 1573 if (types.isSameType(thentype, elsetype)) 1574 return thentype.baseType(); 1575 1576 Type thenUnboxed = (thentype.isPrimitive()) 1577 ? thentype : types.unboxedType(thentype); 1578 Type elseUnboxed = (elsetype.isPrimitive()) 1579 ? elsetype : types.unboxedType(elsetype); 1580 1581 // Otherwise, if both arms can be converted to a numeric 1582 // type, return the least numeric type that fits both arms 1583 // (i.e. return larger of the two, or return int if one 1584 // arm is short, the other is char). 1585 if (thenUnboxed.isPrimitive() && elseUnboxed.isPrimitive()) { 1586 // If one arm has an integer subrange type (i.e., byte, 1587 // short, or char), and the other is an integer constant 1588 // that fits into the subrange, return the subrange type. 1589 if (thenUnboxed.getTag().isStrictSubRangeOf(INT) && 1590 elseUnboxed.hasTag(INT) && 1591 types.isAssignable(elseUnboxed, thenUnboxed)) { 1592 return thenUnboxed.baseType(); 1593 } 1594 if (elseUnboxed.getTag().isStrictSubRangeOf(INT) && 1595 thenUnboxed.hasTag(INT) && 1596 types.isAssignable(thenUnboxed, elseUnboxed)) { 1597 return elseUnboxed.baseType(); 1598 } 1599 1600 for (TypeTag tag : primitiveTags) { 1601 Type candidate = syms.typeOfTag[tag.ordinal()]; 1602 if (types.isSubtype(thenUnboxed, candidate) && 1603 types.isSubtype(elseUnboxed, candidate)) { 1604 return candidate; 1605 } 1606 } 1607 } 1608 1609 // Those were all the cases that could result in a primitive 1610 if (thentype.isPrimitive()) 1611 thentype = types.boxedClass(thentype).type; 1612 if (elsetype.isPrimitive()) 1613 elsetype = types.boxedClass(elsetype).type; 1614 1615 if (types.isSubtype(thentype, elsetype)) 1616 return elsetype.baseType(); 1617 if (types.isSubtype(elsetype, thentype)) 1618 return thentype.baseType(); 1619 1620 if (thentype.hasTag(VOID) || elsetype.hasTag(VOID)) { 1621 log.error(pos, "neither.conditional.subtype", 1622 thentype, elsetype); 1623 return thentype.baseType(); 1624 } 1625 1626 // both are known to be reference types. The result is 1627 // lub(thentype,elsetype). This cannot fail, as it will 1628 // always be possible to infer "Object" if nothing better. 1629 return types.lub(thentype.baseType(), elsetype.baseType()); 1630 } 1631 1632 final static TypeTag[] primitiveTags = new TypeTag[]{ 1633 BYTE, 1634 CHAR, 1635 SHORT, 1636 INT, 1637 LONG, 1638 FLOAT, 1639 DOUBLE, 1640 BOOLEAN, 1641 }; 1642 1643 public void visitIf(JCIf tree) { 1644 attribExpr(tree.cond, env, syms.booleanType); 1645 attribStat(tree.thenpart, env); 1646 if (tree.elsepart != null) 1647 attribStat(tree.elsepart, env); 1648 chk.checkEmptyIf(tree); 1649 result = null; 1650 } 1651 1652 public void visitExec(JCExpressionStatement tree) { 1653 //a fresh environment is required for 292 inference to work properly --- 1654 //see Infer.instantiatePolymorphicSignatureInstance() 1655 Env<AttrContext> localEnv = env.dup(tree); 1656 attribExpr(tree.expr, localEnv); 1657 result = null; 1658 } 1659 1660 public void visitBreak(JCBreak tree) { 1661 tree.target = findJumpTarget(tree.pos(), tree.getTag(), tree.label, env); 1662 result = null; 1663 } 1664 1665 public void visitContinue(JCContinue tree) { 1666 tree.target = findJumpTarget(tree.pos(), tree.getTag(), tree.label, env); 1667 result = null; 1668 } 1669 //where 1670 /** Return the target of a break or continue statement, if it exists, 1671 * report an error if not. 1672 * Note: The target of a labelled break or continue is the 1673 * (non-labelled) statement tree referred to by the label, 1674 * not the tree representing the labelled statement itself. 1675 * 1676 * @param pos The position to be used for error diagnostics 1677 * @param tag The tag of the jump statement. This is either 1678 * Tree.BREAK or Tree.CONTINUE. 1679 * @param label The label of the jump statement, or null if no 1680 * label is given. 1681 * @param env The environment current at the jump statement. 1682 */ 1683 private JCTree findJumpTarget(DiagnosticPosition pos, 1684 JCTree.Tag tag, 1685 Name label, 1686 Env<AttrContext> env) { 1687 // Search environments outwards from the point of jump. 1688 Env<AttrContext> env1 = env; 1689 LOOP: 1690 while (env1 != null) { 1691 switch (env1.tree.getTag()) { 1692 case LABELLED: 1693 JCLabeledStatement labelled = (JCLabeledStatement)env1.tree; 1694 if (label == labelled.label) { 1695 // If jump is a continue, check that target is a loop. 1696 if (tag == CONTINUE) { 1697 if (!labelled.body.hasTag(DOLOOP) && 1698 !labelled.body.hasTag(WHILELOOP) && 1699 !labelled.body.hasTag(FORLOOP) && 1700 !labelled.body.hasTag(FOREACHLOOP)) 1701 log.error(pos, "not.loop.label", label); 1702 // Found labelled statement target, now go inwards 1703 // to next non-labelled tree. 1704 return TreeInfo.referencedStatement(labelled); 1705 } else { 1706 return labelled; 1707 } 1708 } 1709 break; 1710 case DOLOOP: 1711 case WHILELOOP: 1712 case FORLOOP: 1713 case FOREACHLOOP: 1714 if (label == null) return env1.tree; 1715 break; 1716 case SWITCH: 1717 if (label == null && tag == BREAK) return env1.tree; 1718 break; 1719 case LAMBDA: 1720 case METHODDEF: 1721 case CLASSDEF: 1722 break LOOP; 1723 default: 1724 } 1725 env1 = env1.next; 1726 } 1727 if (label != null) 1728 log.error(pos, "undef.label", label); 1729 else if (tag == CONTINUE) 1730 log.error(pos, "cont.outside.loop"); 1731 else 1732 log.error(pos, "break.outside.switch.loop"); 1733 return null; 1734 } 1735 1736 public void visitReturn(JCReturn tree) { 1737 // Check that there is an enclosing method which is 1738 // nested within than the enclosing class. 1739 if (env.info.returnResult == null) { 1740 log.error(tree.pos(), "ret.outside.meth"); 1741 } else { 1742 // Attribute return expression, if it exists, and check that 1743 // it conforms to result type of enclosing method. 1744 if (tree.expr != null) { 1745 if (env.info.returnResult.pt.hasTag(VOID)) { 1746 env.info.returnResult.checkContext.report(tree.expr.pos(), 1747 diags.fragment("unexpected.ret.val")); 1748 } 1749 attribTree(tree.expr, env, env.info.returnResult); 1750 } else if (!env.info.returnResult.pt.hasTag(VOID) && 1751 !env.info.returnResult.pt.hasTag(NONE)) { 1752 env.info.returnResult.checkContext.report(tree.pos(), 1753 diags.fragment("missing.ret.val")); 1754 } 1755 } 1756 result = null; 1757 } 1758 1759 public void visitThrow(JCThrow tree) { 1760 Type owntype = attribExpr(tree.expr, env, allowPoly ? Type.noType : syms.throwableType); 1761 if (allowPoly) { 1762 chk.checkType(tree, owntype, syms.throwableType); 1763 } 1764 result = null; 1765 } 1766 1767 public void visitAssert(JCAssert tree) { 1768 attribExpr(tree.cond, env, syms.booleanType); 1769 if (tree.detail != null) { 1770 chk.checkNonVoid(tree.detail.pos(), attribExpr(tree.detail, env)); 1771 } 1772 result = null; 1773 } 1774 1775 /** Visitor method for method invocations. 1776 * NOTE: The method part of an application will have in its type field 1777 * the return type of the method, not the method's type itself! 1778 */ 1779 public void visitApply(JCMethodInvocation tree) { 1780 // The local environment of a method application is 1781 // a new environment nested in the current one. 1782 Env<AttrContext> localEnv = env.dup(tree, env.info.dup()); 1783 1784 // The types of the actual method arguments. 1785 List<Type> argtypes; 1786 1787 // The types of the actual method type arguments. 1788 List<Type> typeargtypes = null; 1789 1790 Name methName = TreeInfo.name(tree.meth); 1791 1792 boolean isConstructorCall = 1793 methName == names._this || methName == names._super; 1794 1795 ListBuffer<Type> argtypesBuf = new ListBuffer<>(); 1796 if (isConstructorCall) { 1797 // We are seeing a ...this(...) or ...super(...) call. 1798 // Check that this is the first statement in a constructor. 1799 if (checkFirstConstructorStat(tree, env)) { 1800 1801 // Record the fact 1802 // that this is a constructor call (using isSelfCall). 1803 localEnv.info.isSelfCall = true; 1804 1805 // Attribute arguments, yielding list of argument types. 1806 KindSelector kind = attribArgs(KindSelector.MTH, tree.args, localEnv, argtypesBuf); 1807 argtypes = argtypesBuf.toList(); 1808 typeargtypes = attribTypes(tree.typeargs, localEnv); 1809 1810 // Variable `site' points to the class in which the called 1811 // constructor is defined. 1812 Type site = env.enclClass.sym.type; 1813 if (methName == names._super) { 1814 if (site == syms.objectType) { 1815 log.error(tree.meth.pos(), "no.superclass", site); 1816 site = types.createErrorType(syms.objectType); 1817 } else { 1818 site = types.supertype(site); 1819 } 1820 } 1821 1822 if (site.hasTag(CLASS)) { 1823 Type encl = site.getEnclosingType(); 1824 while (encl != null && encl.hasTag(TYPEVAR)) 1825 encl = encl.getUpperBound(); 1826 if (encl.hasTag(CLASS)) { 1827 // we are calling a nested class 1828 1829 if (tree.meth.hasTag(SELECT)) { 1830 JCTree qualifier = ((JCFieldAccess) tree.meth).selected; 1831 1832 // We are seeing a prefixed call, of the form 1833 // <expr>.super(...). 1834 // Check that the prefix expression conforms 1835 // to the outer instance type of the class. 1836 chk.checkRefType(qualifier.pos(), 1837 attribExpr(qualifier, localEnv, 1838 encl)); 1839 } else if (methName == names._super) { 1840 // qualifier omitted; check for existence 1841 // of an appropriate implicit qualifier. 1842 rs.resolveImplicitThis(tree.meth.pos(), 1843 localEnv, site, true); 1844 } 1845 } else if (tree.meth.hasTag(SELECT)) { 1846 log.error(tree.meth.pos(), "illegal.qual.not.icls", 1847 site.tsym); 1848 } 1849 1850 // if we're calling a java.lang.Enum constructor, 1851 // prefix the implicit String and int parameters 1852 if (site.tsym == syms.enumSym) 1853 argtypes = argtypes.prepend(syms.intType).prepend(syms.stringType); 1854 1855 // Resolve the called constructor under the assumption 1856 // that we are referring to a superclass instance of the 1857 // current instance (JLS ???). 1858 boolean selectSuperPrev = localEnv.info.selectSuper; 1859 localEnv.info.selectSuper = true; 1860 localEnv.info.pendingResolutionPhase = null; 1861 Symbol sym = rs.resolveConstructor( 1862 tree.meth.pos(), localEnv, site, argtypes, typeargtypes); 1863 localEnv.info.selectSuper = selectSuperPrev; 1864 1865 // Set method symbol to resolved constructor... 1866 TreeInfo.setSymbol(tree.meth, sym); 1867 1868 // ...and check that it is legal in the current context. 1869 // (this will also set the tree's type) 1870 Type mpt = newMethodTemplate(resultInfo.pt, argtypes, typeargtypes); 1871 checkId(tree.meth, site, sym, localEnv, 1872 new ResultInfo(kind, mpt)); 1873 } 1874 // Otherwise, `site' is an error type and we do nothing 1875 } 1876 result = tree.type = syms.voidType; 1877 } else { 1878 // Otherwise, we are seeing a regular method call. 1879 // Attribute the arguments, yielding list of argument types, ... 1880 KindSelector kind = attribArgs(KindSelector.VAL, tree.args, localEnv, argtypesBuf); 1881 argtypes = argtypesBuf.toList(); 1882 typeargtypes = attribAnyTypes(tree.typeargs, localEnv); 1883 1884 // ... and attribute the method using as a prototype a methodtype 1885 // whose formal argument types is exactly the list of actual 1886 // arguments (this will also set the method symbol). 1887 Type mpt = newMethodTemplate(resultInfo.pt, argtypes, typeargtypes); 1888 localEnv.info.pendingResolutionPhase = null; 1889 Type mtype = attribTree(tree.meth, localEnv, new ResultInfo(kind, mpt, resultInfo.checkContext)); 1890 1891 // Compute the result type. 1892 Type restype = mtype.getReturnType(); 1893 if (restype.hasTag(WILDCARD)) 1894 throw new AssertionError(mtype); 1895 1896 Type qualifier = (tree.meth.hasTag(SELECT)) 1897 ? ((JCFieldAccess) tree.meth).selected.type 1898 : env.enclClass.sym.type; 1899 restype = adjustMethodReturnType(qualifier, methName, argtypes, restype); 1900 1901 chk.checkRefTypes(tree.typeargs, typeargtypes); 1902 1903 // Check that value of resulting type is admissible in the 1904 // current context. Also, capture the return type 1905 Type capturedRes = resultInfo.checkContext.inferenceContext().cachedCapture(tree, restype, true); 1906 result = check(tree, capturedRes, KindSelector.VAL, resultInfo); 1907 } 1908 chk.validate(tree.typeargs, localEnv); 1909 } 1910 //where 1911 Type adjustMethodReturnType(Type qualifierType, Name methodName, List<Type> argtypes, Type restype) { 1912 if (methodName == names.clone && types.isArray(qualifierType)) { 1913 // as a special case, array.clone() has a result that is 1914 // the same as static type of the array being cloned 1915 return qualifierType; 1916 } else if (methodName == names.getClass && argtypes.isEmpty()) { 1917 // as a special case, x.getClass() has type Class<? extends |X|> 1918 return new ClassType(restype.getEnclosingType(), 1919 List.<Type>of(new WildcardType(types.erasure(qualifierType), 1920 BoundKind.EXTENDS, 1921 syms.boundClass)), 1922 restype.tsym, 1923 restype.getMetadata()); 1924 } else { 1925 return restype; 1926 } 1927 } 1928 1929 /** Check that given application node appears as first statement 1930 * in a constructor call. 1931 * @param tree The application node 1932 * @param env The environment current at the application. 1933 */ 1934 boolean checkFirstConstructorStat(JCMethodInvocation tree, Env<AttrContext> env) { 1935 JCMethodDecl enclMethod = env.enclMethod; 1936 if (enclMethod != null && enclMethod.name == names.init) { 1937 JCBlock body = enclMethod.body; 1938 if (body.stats.head.hasTag(EXEC) && 1939 ((JCExpressionStatement) body.stats.head).expr == tree) 1940 return true; 1941 } 1942 log.error(tree.pos(),"call.must.be.first.stmt.in.ctor", 1943 TreeInfo.name(tree.meth)); 1944 return false; 1945 } 1946 1947 /** Obtain a method type with given argument types. 1948 */ 1949 Type newMethodTemplate(Type restype, List<Type> argtypes, List<Type> typeargtypes) { 1950 MethodType mt = new MethodType(argtypes, restype, List.<Type>nil(), syms.methodClass); 1951 return (typeargtypes == null) ? mt : (Type)new ForAll(typeargtypes, mt); 1952 } 1953 1954 public void visitNewClass(final JCNewClass tree) { 1955 Type owntype = types.createErrorType(tree.type); 1956 1957 // The local environment of a class creation is 1958 // a new environment nested in the current one. 1959 Env<AttrContext> localEnv = env.dup(tree, env.info.dup()); 1960 1961 // The anonymous inner class definition of the new expression, 1962 // if one is defined by it. 1963 JCClassDecl cdef = tree.def; 1964 1965 // If enclosing class is given, attribute it, and 1966 // complete class name to be fully qualified 1967 JCExpression clazz = tree.clazz; // Class field following new 1968 JCExpression clazzid; // Identifier in class field 1969 JCAnnotatedType annoclazzid; // Annotated type enclosing clazzid 1970 annoclazzid = null; 1971 1972 if (clazz.hasTag(TYPEAPPLY)) { 1973 clazzid = ((JCTypeApply) clazz).clazz; 1974 if (clazzid.hasTag(ANNOTATED_TYPE)) { 1975 annoclazzid = (JCAnnotatedType) clazzid; 1976 clazzid = annoclazzid.underlyingType; 1977 } 1978 } else { 1979 if (clazz.hasTag(ANNOTATED_TYPE)) { 1980 annoclazzid = (JCAnnotatedType) clazz; 1981 clazzid = annoclazzid.underlyingType; 1982 } else { 1983 clazzid = clazz; 1984 } 1985 } 1986 1987 JCExpression clazzid1 = clazzid; // The same in fully qualified form 1988 1989 if (tree.encl != null) { 1990 // We are seeing a qualified new, of the form 1991 // <expr>.new C <...> (...) ... 1992 // In this case, we let clazz stand for the name of the 1993 // allocated class C prefixed with the type of the qualifier 1994 // expression, so that we can 1995 // resolve it with standard techniques later. I.e., if 1996 // <expr> has type T, then <expr>.new C <...> (...) 1997 // yields a clazz T.C. 1998 Type encltype = chk.checkRefType(tree.encl.pos(), 1999 attribExpr(tree.encl, env)); 2000 // TODO 308: in <expr>.new C, do we also want to add the type annotations 2001 // from expr to the combined type, or not? Yes, do this. 2002 clazzid1 = make.at(clazz.pos).Select(make.Type(encltype), 2003 ((JCIdent) clazzid).name); 2004 2005 EndPosTable endPosTable = this.env.toplevel.endPositions; 2006 endPosTable.storeEnd(clazzid1, tree.getEndPosition(endPosTable)); 2007 if (clazz.hasTag(ANNOTATED_TYPE)) { 2008 JCAnnotatedType annoType = (JCAnnotatedType) clazz; 2009 List<JCAnnotation> annos = annoType.annotations; 2010 2011 if (annoType.underlyingType.hasTag(TYPEAPPLY)) { 2012 clazzid1 = make.at(tree.pos). 2013 TypeApply(clazzid1, 2014 ((JCTypeApply) clazz).arguments); 2015 } 2016 2017 clazzid1 = make.at(tree.pos). 2018 AnnotatedType(annos, clazzid1); 2019 } else if (clazz.hasTag(TYPEAPPLY)) { 2020 clazzid1 = make.at(tree.pos). 2021 TypeApply(clazzid1, 2022 ((JCTypeApply) clazz).arguments); 2023 } 2024 2025 clazz = clazzid1; 2026 } 2027 2028 // Attribute clazz expression and store 2029 // symbol + type back into the attributed tree. 2030 Type clazztype; 2031 2032 try { 2033 env.info.isNewClass = true; 2034 clazztype = TreeInfo.isEnumInit(env.tree) ? 2035 attribIdentAsEnumType(env, (JCIdent)clazz) : 2036 attribType(clazz, env); 2037 } finally { 2038 env.info.isNewClass = false; 2039 } 2040 2041 clazztype = chk.checkDiamond(tree, clazztype); 2042 chk.validate(clazz, localEnv); 2043 if (tree.encl != null) { 2044 // We have to work in this case to store 2045 // symbol + type back into the attributed tree. 2046 tree.clazz.type = clazztype; 2047 TreeInfo.setSymbol(clazzid, TreeInfo.symbol(clazzid1)); 2048 clazzid.type = ((JCIdent) clazzid).sym.type; 2049 if (annoclazzid != null) { 2050 annoclazzid.type = clazzid.type; 2051 } 2052 if (!clazztype.isErroneous()) { 2053 if (cdef != null && clazztype.tsym.isInterface()) { 2054 log.error(tree.encl.pos(), "anon.class.impl.intf.no.qual.for.new"); 2055 } else if (clazztype.tsym.isStatic()) { 2056 log.error(tree.encl.pos(), "qualified.new.of.static.class", clazztype.tsym); 2057 } 2058 } 2059 } else if (!clazztype.tsym.isInterface() && 2060 clazztype.getEnclosingType().hasTag(CLASS)) { 2061 // Check for the existence of an apropos outer instance 2062 rs.resolveImplicitThis(tree.pos(), env, clazztype); 2063 } 2064 2065 // Attribute constructor arguments. 2066 ListBuffer<Type> argtypesBuf = new ListBuffer<>(); 2067 final KindSelector pkind = 2068 attribArgs(KindSelector.VAL, tree.args, localEnv, argtypesBuf); 2069 List<Type> argtypes = argtypesBuf.toList(); 2070 List<Type> typeargtypes = attribTypes(tree.typeargs, localEnv); 2071 2072 // If we have made no mistakes in the class type... 2073 if (clazztype.hasTag(CLASS)) { 2074 // Enums may not be instantiated except implicitly 2075 if ((clazztype.tsym.flags_field & Flags.ENUM) != 0 && 2076 (!env.tree.hasTag(VARDEF) || 2077 (((JCVariableDecl) env.tree).mods.flags & Flags.ENUM) == 0 || 2078 ((JCVariableDecl) env.tree).init != tree)) 2079 log.error(tree.pos(), "enum.cant.be.instantiated"); 2080 2081 boolean isSpeculativeDiamondInferenceRound = TreeInfo.isDiamond(tree) && 2082 resultInfo.checkContext.deferredAttrContext().mode == DeferredAttr.AttrMode.SPECULATIVE; 2083 boolean skipNonDiamondPath = false; 2084 // Check that class is not abstract 2085 if (cdef == null && !isSpeculativeDiamondInferenceRound && // class body may be nulled out in speculative tree copy 2086 (clazztype.tsym.flags() & (ABSTRACT | INTERFACE)) != 0) { 2087 log.error(tree.pos(), "abstract.cant.be.instantiated", 2088 clazztype.tsym); 2089 skipNonDiamondPath = true; 2090 } else if (cdef != null && clazztype.tsym.isInterface()) { 2091 // Check that no constructor arguments are given to 2092 // anonymous classes implementing an interface 2093 if (!argtypes.isEmpty()) 2094 log.error(tree.args.head.pos(), "anon.class.impl.intf.no.args"); 2095 2096 if (!typeargtypes.isEmpty()) 2097 log.error(tree.typeargs.head.pos(), "anon.class.impl.intf.no.typeargs"); 2098 2099 // Error recovery: pretend no arguments were supplied. 2100 argtypes = List.nil(); 2101 typeargtypes = List.nil(); 2102 skipNonDiamondPath = true; 2103 } 2104 if (TreeInfo.isDiamond(tree)) { 2105 ClassType site = new ClassType(clazztype.getEnclosingType(), 2106 clazztype.tsym.type.getTypeArguments(), 2107 clazztype.tsym, 2108 clazztype.getMetadata()); 2109 2110 Env<AttrContext> diamondEnv = localEnv.dup(tree); 2111 diamondEnv.info.selectSuper = cdef != null; 2112 diamondEnv.info.pendingResolutionPhase = null; 2113 2114 //if the type of the instance creation expression is a class type 2115 //apply method resolution inference (JLS 15.12.2.7). The return type 2116 //of the resolved constructor will be a partially instantiated type 2117 Symbol constructor = rs.resolveDiamond(tree.pos(), 2118 diamondEnv, 2119 site, 2120 argtypes, 2121 typeargtypes); 2122 tree.constructor = constructor.baseSymbol(); 2123 2124 final TypeSymbol csym = clazztype.tsym; 2125 ResultInfo diamondResult = new ResultInfo(pkind, newMethodTemplate(resultInfo.pt, argtypes, typeargtypes), 2126 diamondContext(tree, csym, resultInfo.checkContext), CheckMode.NO_TREE_UPDATE); 2127 Type constructorType = tree.constructorType = types.createErrorType(clazztype); 2128 constructorType = checkId(tree, site, 2129 constructor, 2130 diamondEnv, 2131 diamondResult); 2132 2133 tree.clazz.type = types.createErrorType(clazztype); 2134 if (!constructorType.isErroneous()) { 2135 tree.clazz.type = clazz.type = constructorType.getReturnType(); 2136 tree.constructorType = types.createMethodTypeWithReturn(constructorType, syms.voidType); 2137 } 2138 clazztype = chk.checkClassType(tree.clazz, tree.clazz.type, true); 2139 } 2140 2141 // Resolve the called constructor under the assumption 2142 // that we are referring to a superclass instance of the 2143 // current instance (JLS ???). 2144 else if (!skipNonDiamondPath) { 2145 //the following code alters some of the fields in the current 2146 //AttrContext - hence, the current context must be dup'ed in 2147 //order to avoid downstream failures 2148 Env<AttrContext> rsEnv = localEnv.dup(tree); 2149 rsEnv.info.selectSuper = cdef != null; 2150 rsEnv.info.pendingResolutionPhase = null; 2151 tree.constructor = rs.resolveConstructor( 2152 tree.pos(), rsEnv, clazztype, argtypes, typeargtypes); 2153 if (cdef == null) { //do not check twice! 2154 tree.constructorType = checkId(tree, 2155 clazztype, 2156 tree.constructor, 2157 rsEnv, 2158 new ResultInfo(pkind, newMethodTemplate(syms.voidType, argtypes, typeargtypes), CheckMode.NO_TREE_UPDATE)); 2159 if (rsEnv.info.lastResolveVarargs()) 2160 Assert.check(tree.constructorType.isErroneous() || tree.varargsElement != null); 2161 } 2162 } 2163 2164 if (cdef != null) { 2165 visitAnonymousClassDefinition(tree, clazz, clazztype, cdef, localEnv, argtypes, typeargtypes, pkind); 2166 return; 2167 } 2168 2169 if (tree.constructor != null && tree.constructor.kind == MTH) 2170 owntype = clazztype; 2171 } 2172 result = check(tree, owntype, KindSelector.VAL, resultInfo); 2173 InferenceContext inferenceContext = resultInfo.checkContext.inferenceContext(); 2174 if (tree.constructorType != null && inferenceContext.free(tree.constructorType)) { 2175 //we need to wait for inference to finish and then replace inference vars in the constructor type 2176 inferenceContext.addFreeTypeListener(List.of(tree.constructorType), 2177 instantiatedContext -> { 2178 tree.constructorType = instantiatedContext.asInstType(tree.constructorType); 2179 }); 2180 } 2181 chk.validate(tree.typeargs, localEnv); 2182 } 2183 2184 // where 2185 private void visitAnonymousClassDefinition(JCNewClass tree, JCExpression clazz, Type clazztype, 2186 JCClassDecl cdef, Env<AttrContext> localEnv, 2187 List<Type> argtypes, List<Type> typeargtypes, 2188 KindSelector pkind) { 2189 // We are seeing an anonymous class instance creation. 2190 // In this case, the class instance creation 2191 // expression 2192 // 2193 // E.new <typeargs1>C<typargs2>(args) { ... } 2194 // 2195 // is represented internally as 2196 // 2197 // E . new <typeargs1>C<typargs2>(args) ( class <empty-name> { ... } ) . 2198 // 2199 // This expression is then *transformed* as follows: 2200 // 2201 // (1) add an extends or implements clause 2202 // (2) add a constructor. 2203 // 2204 // For instance, if C is a class, and ET is the type of E, 2205 // the expression 2206 // 2207 // E.new <typeargs1>C<typargs2>(args) { ... } 2208 // 2209 // is translated to (where X is a fresh name and typarams is the 2210 // parameter list of the super constructor): 2211 // 2212 // new <typeargs1>X(<*nullchk*>E, args) where 2213 // X extends C<typargs2> { 2214 // <typarams> X(ET e, args) { 2215 // e.<typeargs1>super(args) 2216 // } 2217 // ... 2218 // } 2219 InferenceContext inferenceContext = resultInfo.checkContext.inferenceContext(); 2220 final boolean isDiamond = TreeInfo.isDiamond(tree); 2221 if (isDiamond 2222 && ((tree.constructorType != null && inferenceContext.free(tree.constructorType)) 2223 || (tree.clazz.type != null && inferenceContext.free(tree.clazz.type)))) { 2224 final ResultInfo resultInfoForClassDefinition = this.resultInfo; 2225 inferenceContext.addFreeTypeListener(List.of(tree.constructorType, tree.clazz.type), 2226 instantiatedContext -> { 2227 tree.constructorType = instantiatedContext.asInstType(tree.constructorType); 2228 tree.clazz.type = clazz.type = instantiatedContext.asInstType(clazz.type); 2229 ResultInfo prevResult = this.resultInfo; 2230 try { 2231 this.resultInfo = resultInfoForClassDefinition; 2232 visitAnonymousClassDefinition(tree, clazz, clazz.type, cdef, 2233 localEnv, argtypes, typeargtypes, pkind); 2234 } finally { 2235 this.resultInfo = prevResult; 2236 } 2237 }); 2238 } else { 2239 if (isDiamond && clazztype.hasTag(CLASS)) { 2240 List<Type> invalidDiamondArgs = chk.checkDiamondDenotable((ClassType)clazztype); 2241 if (!clazztype.isErroneous() && invalidDiamondArgs.nonEmpty()) { 2242 // One or more types inferred in the previous steps is non-denotable. 2243 Fragment fragment = Diamond(clazztype.tsym); 2244 log.error(tree.clazz.pos(), 2245 Errors.CantApplyDiamond1( 2246 fragment, 2247 invalidDiamondArgs.size() > 1 ? 2248 DiamondInvalidArgs(invalidDiamondArgs, fragment) : 2249 DiamondInvalidArg(invalidDiamondArgs, fragment))); 2250 } 2251 // For <>(){}, inferred types must also be accessible. 2252 for (Type t : clazztype.getTypeArguments()) { 2253 rs.checkAccessibleType(env, t); 2254 } 2255 } 2256 2257 // If we already errored, be careful to avoid a further avalanche. ErrorType answers 2258 // false for isInterface call even when the original type is an interface. 2259 boolean implementing = clazztype.tsym.isInterface() || 2260 clazztype.isErroneous() && clazztype.getOriginalType().tsym.isInterface(); 2261 2262 if (implementing) { 2263 cdef.implementing = List.of(clazz); 2264 } else { 2265 cdef.extending = clazz; 2266 } 2267 2268 if (resultInfo.checkContext.deferredAttrContext().mode == DeferredAttr.AttrMode.CHECK && 2269 isSerializable(clazztype)) { 2270 localEnv.info.isSerializable = true; 2271 } 2272 2273 attribStat(cdef, localEnv); 2274 2275 List<Type> finalargtypes; 2276 // If an outer instance is given, 2277 // prefix it to the constructor arguments 2278 // and delete it from the new expression 2279 if (tree.encl != null && !clazztype.tsym.isInterface()) { 2280 tree.args = tree.args.prepend(makeNullCheck(tree.encl)); 2281 finalargtypes = argtypes.prepend(tree.encl.type); 2282 tree.encl = null; 2283 } else { 2284 finalargtypes = argtypes; 2285 } 2286 2287 // Reassign clazztype and recompute constructor. As this necessarily involves 2288 // another attribution pass for deferred types in the case of <>, replicate 2289 // them. Original arguments have right decorations already. 2290 if (isDiamond && pkind.contains(KindSelector.POLY)) { 2291 finalargtypes = finalargtypes.map(deferredAttr.deferredCopier); 2292 } 2293 2294 clazztype = cdef.sym.type; 2295 Symbol sym = tree.constructor = rs.resolveConstructor( 2296 tree.pos(), localEnv, clazztype, finalargtypes, typeargtypes); 2297 Assert.check(!sym.kind.isResolutionError()); 2298 tree.constructor = sym; 2299 tree.constructorType = checkId(tree, 2300 clazztype, 2301 tree.constructor, 2302 localEnv, 2303 new ResultInfo(pkind, newMethodTemplate(syms.voidType, finalargtypes, typeargtypes), CheckMode.NO_TREE_UPDATE)); 2304 } 2305 Type owntype = (tree.constructor != null && tree.constructor.kind == MTH) ? 2306 clazztype : types.createErrorType(tree.type); 2307 result = check(tree, owntype, KindSelector.VAL, resultInfo.dup(CheckMode.NO_INFERENCE_HOOK)); 2308 chk.validate(tree.typeargs, localEnv); 2309 } 2310 2311 CheckContext diamondContext(JCNewClass clazz, TypeSymbol tsym, CheckContext checkContext) { 2312 return new Check.NestedCheckContext(checkContext) { 2313 @Override 2314 public void report(DiagnosticPosition _unused, JCDiagnostic details) { 2315 enclosingContext.report(clazz.clazz, 2316 diags.fragment("cant.apply.diamond.1", diags.fragment("diamond", tsym), details)); 2317 } 2318 }; 2319 } 2320 2321 /** Make an attributed null check tree. 2322 */ 2323 public JCExpression makeNullCheck(JCExpression arg) { 2324 // optimization: X.this is never null; skip null check 2325 Name name = TreeInfo.name(arg); 2326 if (name == names._this || name == names._super) return arg; 2327 2328 JCTree.Tag optag = NULLCHK; 2329 JCUnary tree = make.at(arg.pos).Unary(optag, arg); 2330 tree.operator = operators.resolveUnary(arg, optag, arg.type); 2331 tree.type = arg.type; 2332 return tree; 2333 } 2334 2335 public void visitNewArray(JCNewArray tree) { 2336 Type owntype = types.createErrorType(tree.type); 2337 Env<AttrContext> localEnv = env.dup(tree); 2338 Type elemtype; 2339 if (tree.elemtype != null) { 2340 elemtype = attribType(tree.elemtype, localEnv); 2341 chk.validate(tree.elemtype, localEnv); 2342 owntype = elemtype; 2343 for (List<JCExpression> l = tree.dims; l.nonEmpty(); l = l.tail) { 2344 attribExpr(l.head, localEnv, syms.intType); 2345 owntype = new ArrayType(owntype, syms.arrayClass); 2346 } 2347 } else { 2348 // we are seeing an untyped aggregate { ... } 2349 // this is allowed only if the prototype is an array 2350 if (pt().hasTag(ARRAY)) { 2351 elemtype = types.elemtype(pt()); 2352 } else { 2353 if (!pt().hasTag(ERROR)) { 2354 log.error(tree.pos(), "illegal.initializer.for.type", 2355 pt()); 2356 } 2357 elemtype = types.createErrorType(pt()); 2358 } 2359 } 2360 if (tree.elems != null) { 2361 attribExprs(tree.elems, localEnv, elemtype); 2362 owntype = new ArrayType(elemtype, syms.arrayClass); 2363 } 2364 if (!types.isReifiable(elemtype)) 2365 log.error(tree.pos(), "generic.array.creation"); 2366 result = check(tree, owntype, KindSelector.VAL, resultInfo); 2367 } 2368 2369 /* 2370 * A lambda expression can only be attributed when a target-type is available. 2371 * In addition, if the target-type is that of a functional interface whose 2372 * descriptor contains inference variables in argument position the lambda expression 2373 * is 'stuck' (see DeferredAttr). 2374 */ 2375 @Override 2376 public void visitLambda(final JCLambda that) { 2377 if (pt().isErroneous() || (pt().hasTag(NONE) && pt() != Type.recoveryType)) { 2378 if (pt().hasTag(NONE)) { 2379 //lambda only allowed in assignment or method invocation/cast context 2380 log.error(that.pos(), "unexpected.lambda"); 2381 } 2382 result = that.type = types.createErrorType(pt()); 2383 return; 2384 } 2385 //create an environment for attribution of the lambda expression 2386 final Env<AttrContext> localEnv = lambdaEnv(that, env); 2387 boolean needsRecovery = 2388 resultInfo.checkContext.deferredAttrContext().mode == DeferredAttr.AttrMode.CHECK; 2389 try { 2390 if (needsRecovery && isSerializable(pt())) { 2391 localEnv.info.isSerializable = true; 2392 } 2393 List<Type> explicitParamTypes = null; 2394 if (that.paramKind == JCLambda.ParameterKind.EXPLICIT) { 2395 //attribute lambda parameters 2396 attribStats(that.params, localEnv); 2397 explicitParamTypes = TreeInfo.types(that.params); 2398 } 2399 2400 TargetInfo targetInfo = getTargetInfo(that, resultInfo, explicitParamTypes); 2401 Type currentTarget = targetInfo.target; 2402 Type lambdaType = targetInfo.descriptor; 2403 2404 if (currentTarget.isErroneous()) { 2405 result = that.type = currentTarget; 2406 return; 2407 } 2408 2409 setFunctionalInfo(localEnv, that, pt(), lambdaType, currentTarget, resultInfo.checkContext); 2410 2411 if (lambdaType.hasTag(FORALL)) { 2412 //lambda expression target desc cannot be a generic method 2413 resultInfo.checkContext.report(that, diags.fragment("invalid.generic.lambda.target", 2414 lambdaType, kindName(currentTarget.tsym), currentTarget.tsym)); 2415 result = that.type = types.createErrorType(pt()); 2416 return; 2417 } 2418 2419 if (that.paramKind == JCLambda.ParameterKind.IMPLICIT) { 2420 //add param type info in the AST 2421 List<Type> actuals = lambdaType.getParameterTypes(); 2422 List<JCVariableDecl> params = that.params; 2423 2424 boolean arityMismatch = false; 2425 2426 while (params.nonEmpty()) { 2427 if (actuals.isEmpty()) { 2428 //not enough actuals to perform lambda parameter inference 2429 arityMismatch = true; 2430 } 2431 //reset previously set info 2432 Type argType = arityMismatch ? 2433 syms.errType : 2434 actuals.head; 2435 params.head.vartype = make.at(params.head).Type(argType); 2436 params.head.sym = null; 2437 actuals = actuals.isEmpty() ? 2438 actuals : 2439 actuals.tail; 2440 params = params.tail; 2441 } 2442 2443 //attribute lambda parameters 2444 attribStats(that.params, localEnv); 2445 2446 if (arityMismatch) { 2447 resultInfo.checkContext.report(that, diags.fragment("incompatible.arg.types.in.lambda")); 2448 result = that.type = types.createErrorType(currentTarget); 2449 return; 2450 } 2451 } 2452 2453 //from this point on, no recovery is needed; if we are in assignment context 2454 //we will be able to attribute the whole lambda body, regardless of errors; 2455 //if we are in a 'check' method context, and the lambda is not compatible 2456 //with the target-type, it will be recovered anyway in Attr.checkId 2457 needsRecovery = false; 2458 2459 ResultInfo bodyResultInfo = localEnv.info.returnResult = 2460 lambdaBodyResult(that, lambdaType, resultInfo); 2461 2462 if (that.getBodyKind() == JCLambda.BodyKind.EXPRESSION) { 2463 attribTree(that.getBody(), localEnv, bodyResultInfo); 2464 } else { 2465 JCBlock body = (JCBlock)that.body; 2466 attribStats(body.stats, localEnv); 2467 } 2468 2469 result = check(that, currentTarget, KindSelector.VAL, resultInfo); 2470 2471 boolean isSpeculativeRound = 2472 resultInfo.checkContext.deferredAttrContext().mode == DeferredAttr.AttrMode.SPECULATIVE; 2473 2474 preFlow(that); 2475 flow.analyzeLambda(env, that, make, isSpeculativeRound); 2476 2477 that.type = currentTarget; //avoids recovery at this stage 2478 checkLambdaCompatible(that, lambdaType, resultInfo.checkContext); 2479 2480 if (!isSpeculativeRound) { 2481 //add thrown types as bounds to the thrown types free variables if needed: 2482 if (resultInfo.checkContext.inferenceContext().free(lambdaType.getThrownTypes())) { 2483 List<Type> inferredThrownTypes = flow.analyzeLambdaThrownTypes(env, that, make); 2484 List<Type> thrownTypes = resultInfo.checkContext.inferenceContext().asUndetVars(lambdaType.getThrownTypes()); 2485 2486 chk.unhandled(inferredThrownTypes, thrownTypes); 2487 } 2488 2489 checkAccessibleTypes(that, localEnv, resultInfo.checkContext.inferenceContext(), lambdaType, currentTarget); 2490 } 2491 result = check(that, currentTarget, KindSelector.VAL, resultInfo); 2492 } catch (Types.FunctionDescriptorLookupError ex) { 2493 JCDiagnostic cause = ex.getDiagnostic(); 2494 resultInfo.checkContext.report(that, cause); 2495 result = that.type = types.createErrorType(pt()); 2496 return; 2497 } catch (Throwable t) { 2498 //when an unexpected exception happens, avoid attempts to attribute the same tree again 2499 //as that would likely cause the same exception again. 2500 needsRecovery = false; 2501 throw t; 2502 } finally { 2503 localEnv.info.scope.leave(); 2504 if (needsRecovery) { 2505 attribTree(that, env, recoveryInfo); 2506 } 2507 } 2508 } 2509 //where 2510 class TargetInfo { 2511 Type target; 2512 Type descriptor; 2513 2514 public TargetInfo(Type target, Type descriptor) { 2515 this.target = target; 2516 this.descriptor = descriptor; 2517 } 2518 } 2519 2520 TargetInfo getTargetInfo(JCPolyExpression that, ResultInfo resultInfo, List<Type> explicitParamTypes) { 2521 Type lambdaType; 2522 Type currentTarget = resultInfo.pt; 2523 if (resultInfo.pt != Type.recoveryType) { 2524 /* We need to adjust the target. If the target is an 2525 * intersection type, for example: SAM & I1 & I2 ... 2526 * the target will be updated to SAM 2527 */ 2528 currentTarget = targetChecker.visit(currentTarget, that); 2529 if (explicitParamTypes != null) { 2530 currentTarget = infer.instantiateFunctionalInterface(that, 2531 currentTarget, explicitParamTypes, resultInfo.checkContext); 2532 } 2533 currentTarget = types.removeWildcards(currentTarget); 2534 lambdaType = types.findDescriptorType(currentTarget); 2535 } else { 2536 currentTarget = Type.recoveryType; 2537 lambdaType = fallbackDescriptorType(that); 2538 } 2539 if (that.hasTag(LAMBDA) && lambdaType.hasTag(FORALL)) { 2540 //lambda expression target desc cannot be a generic method 2541 resultInfo.checkContext.report(that, diags.fragment("invalid.generic.lambda.target", 2542 lambdaType, kindName(currentTarget.tsym), currentTarget.tsym)); 2543 currentTarget = types.createErrorType(pt()); 2544 } 2545 return new TargetInfo(currentTarget, lambdaType); 2546 } 2547 2548 void preFlow(JCLambda tree) { 2549 new PostAttrAnalyzer() { 2550 @Override 2551 public void scan(JCTree tree) { 2552 if (tree == null || 2553 (tree.type != null && 2554 tree.type == Type.stuckType)) { 2555 //don't touch stuck expressions! 2556 return; 2557 } 2558 super.scan(tree); 2559 } 2560 }.scan(tree); 2561 } 2562 2563 Types.MapVisitor<DiagnosticPosition> targetChecker = new Types.MapVisitor<DiagnosticPosition>() { 2564 2565 @Override 2566 public Type visitClassType(ClassType t, DiagnosticPosition pos) { 2567 return t.isIntersection() ? 2568 visitIntersectionClassType((IntersectionClassType)t, pos) : t; 2569 } 2570 2571 public Type visitIntersectionClassType(IntersectionClassType ict, DiagnosticPosition pos) { 2572 Symbol desc = types.findDescriptorSymbol(makeNotionalInterface(ict)); 2573 Type target = null; 2574 for (Type bound : ict.getExplicitComponents()) { 2575 TypeSymbol boundSym = bound.tsym; 2576 if (types.isFunctionalInterface(boundSym) && 2577 types.findDescriptorSymbol(boundSym) == desc) { 2578 target = bound; 2579 } else if (!boundSym.isInterface() || (boundSym.flags() & ANNOTATION) != 0) { 2580 //bound must be an interface 2581 reportIntersectionError(pos, "not.an.intf.component", boundSym); 2582 } 2583 } 2584 return target != null ? 2585 target : 2586 ict.getExplicitComponents().head; //error recovery 2587 } 2588 2589 private TypeSymbol makeNotionalInterface(IntersectionClassType ict) { 2590 ListBuffer<Type> targs = new ListBuffer<>(); 2591 ListBuffer<Type> supertypes = new ListBuffer<>(); 2592 for (Type i : ict.interfaces_field) { 2593 if (i.isParameterized()) { 2594 targs.appendList(i.tsym.type.allparams()); 2595 } 2596 supertypes.append(i.tsym.type); 2597 } 2598 IntersectionClassType notionalIntf = types.makeIntersectionType(supertypes.toList()); 2599 notionalIntf.allparams_field = targs.toList(); 2600 notionalIntf.tsym.flags_field |= INTERFACE; 2601 return notionalIntf.tsym; 2602 } 2603 2604 private void reportIntersectionError(DiagnosticPosition pos, String key, Object... args) { 2605 resultInfo.checkContext.report(pos, diags.fragment("bad.intersection.target.for.functional.expr", 2606 diags.fragment(key, args))); 2607 } 2608 }; 2609 2610 private Type fallbackDescriptorType(JCExpression tree) { 2611 switch (tree.getTag()) { 2612 case LAMBDA: 2613 JCLambda lambda = (JCLambda)tree; 2614 List<Type> argtypes = List.nil(); 2615 for (JCVariableDecl param : lambda.params) { 2616 argtypes = param.vartype != null ? 2617 argtypes.append(param.vartype.type) : 2618 argtypes.append(syms.errType); 2619 } 2620 return new MethodType(argtypes, Type.recoveryType, 2621 List.of(syms.throwableType), syms.methodClass); 2622 case REFERENCE: 2623 return new MethodType(List.<Type>nil(), Type.recoveryType, 2624 List.of(syms.throwableType), syms.methodClass); 2625 default: 2626 Assert.error("Cannot get here!"); 2627 } 2628 return null; 2629 } 2630 2631 private void checkAccessibleTypes(final DiagnosticPosition pos, final Env<AttrContext> env, 2632 final InferenceContext inferenceContext, final Type... ts) { 2633 checkAccessibleTypes(pos, env, inferenceContext, List.from(ts)); 2634 } 2635 2636 private void checkAccessibleTypes(final DiagnosticPosition pos, final Env<AttrContext> env, 2637 final InferenceContext inferenceContext, final List<Type> ts) { 2638 if (inferenceContext.free(ts)) { 2639 inferenceContext.addFreeTypeListener(ts, new FreeTypeListener() { 2640 @Override 2641 public void typesInferred(InferenceContext inferenceContext) { 2642 checkAccessibleTypes(pos, env, inferenceContext, inferenceContext.asInstTypes(ts)); 2643 } 2644 }); 2645 } else { 2646 for (Type t : ts) { 2647 rs.checkAccessibleType(env, t); 2648 } 2649 } 2650 } 2651 2652 /** 2653 * Lambda/method reference have a special check context that ensures 2654 * that i.e. a lambda return type is compatible with the expected 2655 * type according to both the inherited context and the assignment 2656 * context. 2657 */ 2658 class FunctionalReturnContext extends Check.NestedCheckContext { 2659 2660 FunctionalReturnContext(CheckContext enclosingContext) { 2661 super(enclosingContext); 2662 } 2663 2664 @Override 2665 public boolean compatible(Type found, Type req, Warner warn) { 2666 //return type must be compatible in both current context and assignment context 2667 return chk.basicHandler.compatible(found, inferenceContext().asUndetVar(req), warn); 2668 } 2669 2670 @Override 2671 public void report(DiagnosticPosition pos, JCDiagnostic details) { 2672 enclosingContext.report(pos, diags.fragment("incompatible.ret.type.in.lambda", details)); 2673 } 2674 } 2675 2676 class ExpressionLambdaReturnContext extends FunctionalReturnContext { 2677 2678 JCExpression expr; 2679 2680 ExpressionLambdaReturnContext(JCExpression expr, CheckContext enclosingContext) { 2681 super(enclosingContext); 2682 this.expr = expr; 2683 } 2684 2685 @Override 2686 public boolean compatible(Type found, Type req, Warner warn) { 2687 //a void return is compatible with an expression statement lambda 2688 return TreeInfo.isExpressionStatement(expr) && req.hasTag(VOID) || 2689 super.compatible(found, req, warn); 2690 } 2691 } 2692 2693 ResultInfo lambdaBodyResult(JCLambda that, Type descriptor, ResultInfo resultInfo) { 2694 FunctionalReturnContext funcContext = that.getBodyKind() == JCLambda.BodyKind.EXPRESSION ? 2695 new ExpressionLambdaReturnContext((JCExpression)that.getBody(), resultInfo.checkContext) : 2696 new FunctionalReturnContext(resultInfo.checkContext); 2697 2698 return descriptor.getReturnType() == Type.recoveryType ? 2699 recoveryInfo : 2700 new ResultInfo(KindSelector.VAL, 2701 descriptor.getReturnType(), funcContext); 2702 } 2703 2704 /** 2705 * Lambda compatibility. Check that given return types, thrown types, parameter types 2706 * are compatible with the expected functional interface descriptor. This means that: 2707 * (i) parameter types must be identical to those of the target descriptor; (ii) return 2708 * types must be compatible with the return type of the expected descriptor. 2709 */ 2710 void checkLambdaCompatible(JCLambda tree, Type descriptor, CheckContext checkContext) { 2711 Type returnType = checkContext.inferenceContext().asUndetVar(descriptor.getReturnType()); 2712 2713 //return values have already been checked - but if lambda has no return 2714 //values, we must ensure that void/value compatibility is correct; 2715 //this amounts at checking that, if a lambda body can complete normally, 2716 //the descriptor's return type must be void 2717 if (tree.getBodyKind() == JCLambda.BodyKind.STATEMENT && tree.canCompleteNormally && 2718 !returnType.hasTag(VOID) && returnType != Type.recoveryType) { 2719 checkContext.report(tree, diags.fragment("incompatible.ret.type.in.lambda", 2720 diags.fragment("missing.ret.val", returnType))); 2721 } 2722 2723 List<Type> argTypes = checkContext.inferenceContext().asUndetVars(descriptor.getParameterTypes()); 2724 if (!types.isSameTypes(argTypes, TreeInfo.types(tree.params))) { 2725 checkContext.report(tree, diags.fragment("incompatible.arg.types.in.lambda")); 2726 } 2727 } 2728 2729 /* Map to hold 'fake' clinit methods. If a lambda is used to initialize a 2730 * static field and that lambda has type annotations, these annotations will 2731 * also be stored at these fake clinit methods. 2732 * 2733 * LambdaToMethod also use fake clinit methods so they can be reused. 2734 * Also as LTM is a phase subsequent to attribution, the methods from 2735 * clinits can be safely removed by LTM to save memory. 2736 */ 2737 private Map<ClassSymbol, MethodSymbol> clinits = new HashMap<>(); 2738 2739 public MethodSymbol removeClinit(ClassSymbol sym) { 2740 return clinits.remove(sym); 2741 } 2742 2743 /* This method returns an environment to be used to attribute a lambda 2744 * expression. 2745 * 2746 * The owner of this environment is a method symbol. If the current owner 2747 * is not a method, for example if the lambda is used to initialize 2748 * a field, then if the field is: 2749 * 2750 * - an instance field, we use the first constructor. 2751 * - a static field, we create a fake clinit method. 2752 */ 2753 public Env<AttrContext> lambdaEnv(JCLambda that, Env<AttrContext> env) { 2754 Env<AttrContext> lambdaEnv; 2755 Symbol owner = env.info.scope.owner; 2756 if (owner.kind == VAR && owner.owner.kind == TYP) { 2757 //field initializer 2758 ClassSymbol enclClass = owner.enclClass(); 2759 Symbol newScopeOwner = env.info.scope.owner; 2760 /* if the field isn't static, then we can get the first constructor 2761 * and use it as the owner of the environment. This is what 2762 * LTM code is doing to look for type annotations so we are fine. 2763 */ 2764 if ((owner.flags() & STATIC) == 0) { 2765 for (Symbol s : enclClass.members_field.getSymbolsByName(names.init)) { 2766 newScopeOwner = s; 2767 break; 2768 } 2769 } else { 2770 /* if the field is static then we need to create a fake clinit 2771 * method, this method can later be reused by LTM. 2772 */ 2773 MethodSymbol clinit = clinits.get(enclClass); 2774 if (clinit == null) { 2775 Type clinitType = new MethodType(List.<Type>nil(), 2776 syms.voidType, List.<Type>nil(), syms.methodClass); 2777 clinit = new MethodSymbol(STATIC | SYNTHETIC | PRIVATE, 2778 names.clinit, clinitType, enclClass); 2779 clinit.params = List.<VarSymbol>nil(); 2780 clinits.put(enclClass, clinit); 2781 } 2782 newScopeOwner = clinit; 2783 } 2784 lambdaEnv = env.dup(that, env.info.dup(env.info.scope.dupUnshared(newScopeOwner))); 2785 } else { 2786 lambdaEnv = env.dup(that, env.info.dup(env.info.scope.dup())); 2787 } 2788 return lambdaEnv; 2789 } 2790 2791 @Override 2792 public void visitReference(final JCMemberReference that) { 2793 if (pt().isErroneous() || (pt().hasTag(NONE) && pt() != Type.recoveryType)) { 2794 if (pt().hasTag(NONE)) { 2795 //method reference only allowed in assignment or method invocation/cast context 2796 log.error(that.pos(), "unexpected.mref"); 2797 } 2798 result = that.type = types.createErrorType(pt()); 2799 return; 2800 } 2801 final Env<AttrContext> localEnv = env.dup(that); 2802 try { 2803 //attribute member reference qualifier - if this is a constructor 2804 //reference, the expected kind must be a type 2805 Type exprType = attribTree(that.expr, env, memberReferenceQualifierResult(that)); 2806 2807 if (that.getMode() == JCMemberReference.ReferenceMode.NEW) { 2808 exprType = chk.checkConstructorRefType(that.expr, exprType); 2809 if (!exprType.isErroneous() && 2810 exprType.isRaw() && 2811 that.typeargs != null) { 2812 log.error(that.expr.pos(), "invalid.mref", Kinds.kindName(that.getMode()), 2813 diags.fragment("mref.infer.and.explicit.params")); 2814 exprType = types.createErrorType(exprType); 2815 } 2816 } 2817 2818 if (exprType.isErroneous()) { 2819 //if the qualifier expression contains problems, 2820 //give up attribution of method reference 2821 result = that.type = exprType; 2822 return; 2823 } 2824 2825 if (TreeInfo.isStaticSelector(that.expr, names)) { 2826 //if the qualifier is a type, validate it; raw warning check is 2827 //omitted as we don't know at this stage as to whether this is a 2828 //raw selector (because of inference) 2829 chk.validate(that.expr, env, false); 2830 } else { 2831 Symbol lhsSym = TreeInfo.symbol(that.expr); 2832 localEnv.info.selectSuper = lhsSym != null && lhsSym.name == names._super; 2833 } 2834 //attrib type-arguments 2835 List<Type> typeargtypes = List.nil(); 2836 if (that.typeargs != null) { 2837 typeargtypes = attribTypes(that.typeargs, localEnv); 2838 } 2839 2840 boolean isTargetSerializable = 2841 resultInfo.checkContext.deferredAttrContext().mode == DeferredAttr.AttrMode.CHECK && 2842 isSerializable(pt()); 2843 TargetInfo targetInfo = getTargetInfo(that, resultInfo, null); 2844 Type currentTarget = targetInfo.target; 2845 Type desc = targetInfo.descriptor; 2846 2847 setFunctionalInfo(localEnv, that, pt(), desc, currentTarget, resultInfo.checkContext); 2848 List<Type> argtypes = desc.getParameterTypes(); 2849 Resolve.MethodCheck referenceCheck = rs.resolveMethodCheck; 2850 2851 if (resultInfo.checkContext.inferenceContext().free(argtypes)) { 2852 referenceCheck = rs.new MethodReferenceCheck(resultInfo.checkContext.inferenceContext()); 2853 } 2854 2855 Pair<Symbol, Resolve.ReferenceLookupHelper> refResult = null; 2856 List<Type> saved_undet = resultInfo.checkContext.inferenceContext().save(); 2857 try { 2858 refResult = rs.resolveMemberReference(localEnv, that, that.expr.type, 2859 that.name, argtypes, typeargtypes, referenceCheck, 2860 resultInfo.checkContext.inferenceContext(), rs.basicReferenceChooser); 2861 } finally { 2862 resultInfo.checkContext.inferenceContext().rollback(saved_undet); 2863 } 2864 2865 Symbol refSym = refResult.fst; 2866 Resolve.ReferenceLookupHelper lookupHelper = refResult.snd; 2867 2868 /** this switch will need to go away and be replaced by the new RESOLUTION_TARGET testing 2869 * JDK-8075541 2870 */ 2871 if (refSym.kind != MTH) { 2872 boolean targetError; 2873 switch (refSym.kind) { 2874 case ABSENT_MTH: 2875 case MISSING_ENCL: 2876 targetError = false; 2877 break; 2878 case WRONG_MTH: 2879 case WRONG_MTHS: 2880 case AMBIGUOUS: 2881 case HIDDEN: 2882 case STATICERR: 2883 targetError = true; 2884 break; 2885 default: 2886 Assert.error("unexpected result kind " + refSym.kind); 2887 targetError = false; 2888 } 2889 2890 JCDiagnostic detailsDiag = ((Resolve.ResolveError)refSym.baseSymbol()).getDiagnostic(JCDiagnostic.DiagnosticType.FRAGMENT, 2891 that, exprType.tsym, exprType, that.name, argtypes, typeargtypes); 2892 2893 JCDiagnostic.DiagnosticType diagKind = targetError ? 2894 JCDiagnostic.DiagnosticType.FRAGMENT : JCDiagnostic.DiagnosticType.ERROR; 2895 2896 JCDiagnostic diag = diags.create(diagKind, log.currentSource(), that, 2897 "invalid.mref", Kinds.kindName(that.getMode()), detailsDiag); 2898 2899 if (targetError && currentTarget == Type.recoveryType) { 2900 //a target error doesn't make sense during recovery stage 2901 //as we don't know what actual parameter types are 2902 result = that.type = currentTarget; 2903 return; 2904 } else { 2905 if (targetError) { 2906 resultInfo.checkContext.report(that, diag); 2907 } else { 2908 log.report(diag); 2909 } 2910 result = that.type = types.createErrorType(currentTarget); 2911 return; 2912 } 2913 } 2914 2915 that.sym = refSym.baseSymbol(); 2916 that.kind = lookupHelper.referenceKind(that.sym); 2917 that.ownerAccessible = rs.isAccessible(localEnv, that.sym.enclClass()); 2918 2919 if (desc.getReturnType() == Type.recoveryType) { 2920 // stop here 2921 result = that.type = currentTarget; 2922 return; 2923 } 2924 2925 if (resultInfo.checkContext.deferredAttrContext().mode == AttrMode.CHECK) { 2926 2927 if (that.getMode() == ReferenceMode.INVOKE && 2928 TreeInfo.isStaticSelector(that.expr, names) && 2929 that.kind.isUnbound() && 2930 !desc.getParameterTypes().head.isParameterized()) { 2931 chk.checkRaw(that.expr, localEnv); 2932 } 2933 2934 if (that.sym.isStatic() && TreeInfo.isStaticSelector(that.expr, names) && 2935 exprType.getTypeArguments().nonEmpty()) { 2936 //static ref with class type-args 2937 log.error(that.expr.pos(), "invalid.mref", Kinds.kindName(that.getMode()), 2938 diags.fragment("static.mref.with.targs")); 2939 result = that.type = types.createErrorType(currentTarget); 2940 return; 2941 } 2942 2943 if (!refSym.isStatic() && that.kind == JCMemberReference.ReferenceKind.SUPER) { 2944 // Check that super-qualified symbols are not abstract (JLS) 2945 rs.checkNonAbstract(that.pos(), that.sym); 2946 } 2947 2948 if (isTargetSerializable) { 2949 chk.checkElemAccessFromSerializableLambda(that); 2950 } 2951 } 2952 2953 ResultInfo checkInfo = 2954 resultInfo.dup(newMethodTemplate( 2955 desc.getReturnType().hasTag(VOID) ? Type.noType : desc.getReturnType(), 2956 that.kind.isUnbound() ? argtypes.tail : argtypes, typeargtypes), 2957 new FunctionalReturnContext(resultInfo.checkContext), CheckMode.NO_TREE_UPDATE); 2958 2959 Type refType = checkId(that, lookupHelper.site, refSym, localEnv, checkInfo); 2960 2961 if (that.kind.isUnbound() && 2962 resultInfo.checkContext.inferenceContext().free(argtypes.head)) { 2963 //re-generate inference constraints for unbound receiver 2964 if (!types.isSubtype(resultInfo.checkContext.inferenceContext().asUndetVar(argtypes.head), exprType)) { 2965 //cannot happen as this has already been checked - we just need 2966 //to regenerate the inference constraints, as that has been lost 2967 //as a result of the call to inferenceContext.save() 2968 Assert.error("Can't get here"); 2969 } 2970 } 2971 2972 if (!refType.isErroneous()) { 2973 refType = types.createMethodTypeWithReturn(refType, 2974 adjustMethodReturnType(lookupHelper.site, that.name, checkInfo.pt.getParameterTypes(), refType.getReturnType())); 2975 } 2976 2977 //go ahead with standard method reference compatibility check - note that param check 2978 //is a no-op (as this has been taken care during method applicability) 2979 boolean isSpeculativeRound = 2980 resultInfo.checkContext.deferredAttrContext().mode == DeferredAttr.AttrMode.SPECULATIVE; 2981 2982 that.type = currentTarget; //avoids recovery at this stage 2983 checkReferenceCompatible(that, desc, refType, resultInfo.checkContext, isSpeculativeRound); 2984 if (!isSpeculativeRound) { 2985 checkAccessibleTypes(that, localEnv, resultInfo.checkContext.inferenceContext(), desc, currentTarget); 2986 } 2987 result = check(that, currentTarget, KindSelector.VAL, resultInfo); 2988 } catch (Types.FunctionDescriptorLookupError ex) { 2989 JCDiagnostic cause = ex.getDiagnostic(); 2990 resultInfo.checkContext.report(that, cause); 2991 result = that.type = types.createErrorType(pt()); 2992 return; 2993 } 2994 } 2995 //where 2996 ResultInfo memberReferenceQualifierResult(JCMemberReference tree) { 2997 //if this is a constructor reference, the expected kind must be a type 2998 return new ResultInfo(tree.getMode() == ReferenceMode.INVOKE ? 2999 KindSelector.VAL_TYP : KindSelector.TYP, 3000 Type.noType); 3001 } 3002 3003 3004 @SuppressWarnings("fallthrough") 3005 void checkReferenceCompatible(JCMemberReference tree, Type descriptor, Type refType, CheckContext checkContext, boolean speculativeAttr) { 3006 InferenceContext inferenceContext = checkContext.inferenceContext(); 3007 Type returnType = inferenceContext.asUndetVar(descriptor.getReturnType()); 3008 3009 Type resType; 3010 switch (tree.getMode()) { 3011 case NEW: 3012 if (!tree.expr.type.isRaw()) { 3013 resType = tree.expr.type; 3014 break; 3015 } 3016 default: 3017 resType = refType.getReturnType(); 3018 } 3019 3020 Type incompatibleReturnType = resType; 3021 3022 if (returnType.hasTag(VOID)) { 3023 incompatibleReturnType = null; 3024 } 3025 3026 if (!returnType.hasTag(VOID) && !resType.hasTag(VOID)) { 3027 if (resType.isErroneous() || 3028 new FunctionalReturnContext(checkContext).compatible(resType, returnType, types.noWarnings)) { 3029 incompatibleReturnType = null; 3030 } 3031 } 3032 3033 if (incompatibleReturnType != null) { 3034 checkContext.report(tree, diags.fragment("incompatible.ret.type.in.mref", 3035 diags.fragment("inconvertible.types", resType, descriptor.getReturnType()))); 3036 } else { 3037 if (inferenceContext.free(refType)) { 3038 // we need to wait for inference to finish and then replace inference vars in the referent type 3039 inferenceContext.addFreeTypeListener(List.of(refType), 3040 instantiatedContext -> { 3041 tree.referentType = instantiatedContext.asInstType(refType); 3042 }); 3043 } else { 3044 tree.referentType = refType; 3045 } 3046 } 3047 3048 if (!speculativeAttr) { 3049 List<Type> thrownTypes = inferenceContext.asUndetVars(descriptor.getThrownTypes()); 3050 if (chk.unhandled(refType.getThrownTypes(), thrownTypes).nonEmpty()) { 3051 log.error(tree, "incompatible.thrown.types.in.mref", refType.getThrownTypes()); 3052 } 3053 } 3054 } 3055 3056 /** 3057 * Set functional type info on the underlying AST. Note: as the target descriptor 3058 * might contain inference variables, we might need to register an hook in the 3059 * current inference context. 3060 */ 3061 private void setFunctionalInfo(final Env<AttrContext> env, final JCFunctionalExpression fExpr, 3062 final Type pt, final Type descriptorType, final Type primaryTarget, final CheckContext checkContext) { 3063 if (checkContext.inferenceContext().free(descriptorType)) { 3064 checkContext.inferenceContext().addFreeTypeListener(List.of(pt, descriptorType), new FreeTypeListener() { 3065 public void typesInferred(InferenceContext inferenceContext) { 3066 setFunctionalInfo(env, fExpr, pt, inferenceContext.asInstType(descriptorType), 3067 inferenceContext.asInstType(primaryTarget), checkContext); 3068 } 3069 }); 3070 } else { 3071 ListBuffer<Type> targets = new ListBuffer<>(); 3072 if (pt.hasTag(CLASS)) { 3073 if (pt.isCompound()) { 3074 targets.append(types.removeWildcards(primaryTarget)); //this goes first 3075 for (Type t : ((IntersectionClassType)pt()).interfaces_field) { 3076 if (t != primaryTarget) { 3077 targets.append(types.removeWildcards(t)); 3078 } 3079 } 3080 } else { 3081 targets.append(types.removeWildcards(primaryTarget)); 3082 } 3083 } 3084 fExpr.targets = targets.toList(); 3085 if (checkContext.deferredAttrContext().mode == DeferredAttr.AttrMode.CHECK && 3086 pt != Type.recoveryType) { 3087 //check that functional interface class is well-formed 3088 try { 3089 /* Types.makeFunctionalInterfaceClass() may throw an exception 3090 * when it's executed post-inference. See the listener code 3091 * above. 3092 */ 3093 ClassSymbol csym = types.makeFunctionalInterfaceClass(env, 3094 names.empty, List.of(fExpr.targets.head), ABSTRACT); 3095 if (csym != null) { 3096 chk.checkImplementations(env.tree, csym, csym); 3097 try { 3098 //perform an additional functional interface check on the synthetic class, 3099 //as there may be spurious errors for raw targets - because of existing issues 3100 //with membership and inheritance (see JDK-8074570). 3101 csym.flags_field |= INTERFACE; 3102 types.findDescriptorType(csym.type); 3103 } catch (FunctionDescriptorLookupError err) { 3104 resultInfo.checkContext.report(fExpr, 3105 diags.fragment(Fragments.NoSuitableFunctionalIntfInst(fExpr.targets.head))); 3106 } 3107 } 3108 } catch (Types.FunctionDescriptorLookupError ex) { 3109 JCDiagnostic cause = ex.getDiagnostic(); 3110 resultInfo.checkContext.report(env.tree, cause); 3111 } 3112 } 3113 } 3114 } 3115 3116 public void visitParens(JCParens tree) { 3117 Type owntype = attribTree(tree.expr, env, resultInfo); 3118 result = check(tree, owntype, pkind(), resultInfo); 3119 Symbol sym = TreeInfo.symbol(tree); 3120 if (sym != null && sym.kind.matches(KindSelector.TYP_PCK)) 3121 log.error(tree.pos(), "illegal.start.of.type"); 3122 } 3123 3124 public void visitAssign(JCAssign tree) { 3125 Type owntype = attribTree(tree.lhs, env.dup(tree), varAssignmentInfo); 3126 Type capturedType = capture(owntype); 3127 attribExpr(tree.rhs, env, owntype); 3128 result = check(tree, capturedType, KindSelector.VAL, resultInfo); 3129 } 3130 3131 public void visitAssignop(JCAssignOp tree) { 3132 // Attribute arguments. 3133 Type owntype = attribTree(tree.lhs, env, varAssignmentInfo); 3134 Type operand = attribExpr(tree.rhs, env); 3135 // Find operator. 3136 Symbol operator = tree.operator = operators.resolveBinary(tree, tree.getTag().noAssignOp(), owntype, operand); 3137 if (operator.kind == MTH && 3138 !owntype.isErroneous() && 3139 !operand.isErroneous()) { 3140 chk.checkDivZero(tree.rhs.pos(), operator, operand); 3141 chk.checkCastable(tree.rhs.pos(), 3142 operator.type.getReturnType(), 3143 owntype); 3144 } 3145 result = check(tree, owntype, KindSelector.VAL, resultInfo); 3146 } 3147 3148 public void visitUnary(JCUnary tree) { 3149 // Attribute arguments. 3150 Type argtype = (tree.getTag().isIncOrDecUnaryOp()) 3151 ? attribTree(tree.arg, env, varAssignmentInfo) 3152 : chk.checkNonVoid(tree.arg.pos(), attribExpr(tree.arg, env)); 3153 3154 // Find operator. 3155 Symbol operator = tree.operator = operators.resolveUnary(tree, tree.getTag(), argtype); 3156 Type owntype = types.createErrorType(tree.type); 3157 if (operator.kind == MTH && 3158 !argtype.isErroneous()) { 3159 owntype = (tree.getTag().isIncOrDecUnaryOp()) 3160 ? tree.arg.type 3161 : operator.type.getReturnType(); 3162 int opc = ((OperatorSymbol)operator).opcode; 3163 3164 // If the argument is constant, fold it. 3165 if (argtype.constValue() != null) { 3166 Type ctype = cfolder.fold1(opc, argtype); 3167 if (ctype != null) { 3168 owntype = cfolder.coerce(ctype, owntype); 3169 } 3170 } 3171 } 3172 result = check(tree, owntype, KindSelector.VAL, resultInfo); 3173 } 3174 3175 public void visitBinary(JCBinary tree) { 3176 // Attribute arguments. 3177 Type left = chk.checkNonVoid(tree.lhs.pos(), attribExpr(tree.lhs, env)); 3178 Type right = chk.checkNonVoid(tree.rhs.pos(), attribExpr(tree.rhs, env)); 3179 // Find operator. 3180 Symbol operator = tree.operator = operators.resolveBinary(tree, tree.getTag(), left, right); 3181 Type owntype = types.createErrorType(tree.type); 3182 if (operator.kind == MTH && 3183 !left.isErroneous() && 3184 !right.isErroneous()) { 3185 owntype = operator.type.getReturnType(); 3186 int opc = ((OperatorSymbol)operator).opcode; 3187 // If both arguments are constants, fold them. 3188 if (left.constValue() != null && right.constValue() != null) { 3189 Type ctype = cfolder.fold2(opc, left, right); 3190 if (ctype != null) { 3191 owntype = cfolder.coerce(ctype, owntype); 3192 } 3193 } 3194 3195 // Check that argument types of a reference ==, != are 3196 // castable to each other, (JLS 15.21). Note: unboxing 3197 // comparisons will not have an acmp* opc at this point. 3198 if ((opc == ByteCodes.if_acmpeq || opc == ByteCodes.if_acmpne)) { 3199 if (!types.isCastable(left, right, new Warner(tree.pos()))) { 3200 log.error(tree.pos(), "incomparable.types", left, right); 3201 } 3202 } 3203 3204 chk.checkDivZero(tree.rhs.pos(), operator, right); 3205 } 3206 result = check(tree, owntype, KindSelector.VAL, resultInfo); 3207 } 3208 3209 public void visitTypeCast(final JCTypeCast tree) { 3210 Type clazztype = attribType(tree.clazz, env); 3211 chk.validate(tree.clazz, env, false); 3212 //a fresh environment is required for 292 inference to work properly --- 3213 //see Infer.instantiatePolymorphicSignatureInstance() 3214 Env<AttrContext> localEnv = env.dup(tree); 3215 //should we propagate the target type? 3216 final ResultInfo castInfo; 3217 JCExpression expr = TreeInfo.skipParens(tree.expr); 3218 boolean isPoly = allowPoly && (expr.hasTag(LAMBDA) || expr.hasTag(REFERENCE)); 3219 if (isPoly) { 3220 //expression is a poly - we need to propagate target type info 3221 castInfo = new ResultInfo(KindSelector.VAL, clazztype, 3222 new Check.NestedCheckContext(resultInfo.checkContext) { 3223 @Override 3224 public boolean compatible(Type found, Type req, Warner warn) { 3225 return types.isCastable(found, req, warn); 3226 } 3227 }); 3228 } else { 3229 //standalone cast - target-type info is not propagated 3230 castInfo = unknownExprInfo; 3231 } 3232 Type exprtype = attribTree(tree.expr, localEnv, castInfo); 3233 Type owntype = isPoly ? clazztype : chk.checkCastable(tree.expr.pos(), exprtype, clazztype); 3234 if (exprtype.constValue() != null) 3235 owntype = cfolder.coerce(exprtype, owntype); 3236 result = check(tree, capture(owntype), KindSelector.VAL, resultInfo); 3237 if (!isPoly) 3238 chk.checkRedundantCast(localEnv, tree); 3239 } 3240 3241 public void visitTypeTest(JCInstanceOf tree) { 3242 Type exprtype = chk.checkNullOrRefType( 3243 tree.expr.pos(), attribExpr(tree.expr, env)); 3244 Type clazztype = attribType(tree.clazz, env); 3245 if (!clazztype.hasTag(TYPEVAR)) { 3246 clazztype = chk.checkClassOrArrayType(tree.clazz.pos(), clazztype); 3247 } 3248 if (!clazztype.isErroneous() && !types.isReifiable(clazztype)) { 3249 log.error(tree.clazz.pos(), "illegal.generic.type.for.instof"); 3250 clazztype = types.createErrorType(clazztype); 3251 } 3252 chk.validate(tree.clazz, env, false); 3253 chk.checkCastable(tree.expr.pos(), exprtype, clazztype); 3254 result = check(tree, syms.booleanType, KindSelector.VAL, resultInfo); 3255 } 3256 3257 public void visitIndexed(JCArrayAccess tree) { 3258 Type owntype = types.createErrorType(tree.type); 3259 Type atype = attribExpr(tree.indexed, env); 3260 attribExpr(tree.index, env, syms.intType); 3261 if (types.isArray(atype)) 3262 owntype = types.elemtype(atype); 3263 else if (!atype.hasTag(ERROR)) 3264 log.error(tree.pos(), "array.req.but.found", atype); 3265 if (!pkind().contains(KindSelector.VAL)) 3266 owntype = capture(owntype); 3267 result = check(tree, owntype, KindSelector.VAR, resultInfo); 3268 } 3269 3270 public void visitIdent(JCIdent tree) { 3271 Symbol sym; 3272 3273 // Find symbol 3274 if (pt().hasTag(METHOD) || pt().hasTag(FORALL)) { 3275 // If we are looking for a method, the prototype `pt' will be a 3276 // method type with the type of the call's arguments as parameters. 3277 env.info.pendingResolutionPhase = null; 3278 sym = rs.resolveMethod(tree.pos(), env, tree.name, pt().getParameterTypes(), pt().getTypeArguments()); 3279 } else if (tree.sym != null && tree.sym.kind != VAR) { 3280 sym = tree.sym; 3281 } else { 3282 sym = rs.resolveIdent(tree.pos(), env, tree.name, pkind()); 3283 } 3284 tree.sym = sym; 3285 3286 // (1) Also find the environment current for the class where 3287 // sym is defined (`symEnv'). 3288 // Only for pre-tiger versions (1.4 and earlier): 3289 // (2) Also determine whether we access symbol out of an anonymous 3290 // class in a this or super call. This is illegal for instance 3291 // members since such classes don't carry a this$n link. 3292 // (`noOuterThisPath'). 3293 Env<AttrContext> symEnv = env; 3294 boolean noOuterThisPath = false; 3295 if (env.enclClass.sym.owner.kind != PCK && // we are in an inner class 3296 sym.kind.matches(KindSelector.VAL_MTH) && 3297 sym.owner.kind == TYP && 3298 tree.name != names._this && tree.name != names._super) { 3299 3300 // Find environment in which identifier is defined. 3301 while (symEnv.outer != null && 3302 !sym.isMemberOf(symEnv.enclClass.sym, types)) { 3303 if ((symEnv.enclClass.sym.flags() & NOOUTERTHIS) != 0) 3304 noOuterThisPath = false; 3305 symEnv = symEnv.outer; 3306 } 3307 } 3308 3309 // If symbol is a variable, ... 3310 if (sym.kind == VAR) { 3311 VarSymbol v = (VarSymbol)sym; 3312 3313 // ..., evaluate its initializer, if it has one, and check for 3314 // illegal forward reference. 3315 checkInit(tree, env, v, false); 3316 3317 // If we are expecting a variable (as opposed to a value), check 3318 // that the variable is assignable in the current environment. 3319 if (KindSelector.ASG.subset(pkind())) 3320 checkAssignable(tree.pos(), v, null, env); 3321 } 3322 3323 // In a constructor body, 3324 // if symbol is a field or instance method, check that it is 3325 // not accessed before the supertype constructor is called. 3326 if ((symEnv.info.isSelfCall || noOuterThisPath) && 3327 sym.kind.matches(KindSelector.VAL_MTH) && 3328 sym.owner.kind == TYP && 3329 (sym.flags() & STATIC) == 0) { 3330 chk.earlyRefError(tree.pos(), sym.kind == VAR ? 3331 sym : thisSym(tree.pos(), env)); 3332 } 3333 Env<AttrContext> env1 = env; 3334 if (sym.kind != ERR && sym.kind != TYP && 3335 sym.owner != null && sym.owner != env1.enclClass.sym) { 3336 // If the found symbol is inaccessible, then it is 3337 // accessed through an enclosing instance. Locate this 3338 // enclosing instance: 3339 while (env1.outer != null && !rs.isAccessible(env, env1.enclClass.sym.type, sym)) 3340 env1 = env1.outer; 3341 } 3342 3343 if (env.info.isSerializable) { 3344 chk.checkElemAccessFromSerializableLambda(tree); 3345 } 3346 3347 result = checkId(tree, env1.enclClass.sym.type, sym, env, resultInfo); 3348 } 3349 3350 public void visitSelect(JCFieldAccess tree) { 3351 // Determine the expected kind of the qualifier expression. 3352 KindSelector skind = KindSelector.NIL; 3353 if (tree.name == names._this || tree.name == names._super || 3354 tree.name == names._class) 3355 { 3356 skind = KindSelector.TYP; 3357 } else { 3358 if (pkind().contains(KindSelector.PCK)) 3359 skind = KindSelector.of(skind, KindSelector.PCK); 3360 if (pkind().contains(KindSelector.TYP)) 3361 skind = KindSelector.of(skind, KindSelector.TYP, KindSelector.PCK); 3362 if (pkind().contains(KindSelector.VAL_MTH)) 3363 skind = KindSelector.of(skind, KindSelector.VAL, KindSelector.TYP); 3364 } 3365 3366 // Attribute the qualifier expression, and determine its symbol (if any). 3367 Type site = attribTree(tree.selected, env, new ResultInfo(skind, Type.noType)); 3368 if (!pkind().contains(KindSelector.TYP_PCK)) 3369 site = capture(site); // Capture field access 3370 3371 // don't allow T.class T[].class, etc 3372 if (skind == KindSelector.TYP) { 3373 Type elt = site; 3374 while (elt.hasTag(ARRAY)) 3375 elt = ((ArrayType)elt).elemtype; 3376 if (elt.hasTag(TYPEVAR)) { 3377 log.error(tree.pos(), "type.var.cant.be.deref"); 3378 result = tree.type = types.createErrorType(tree.name, site.tsym, site); 3379 tree.sym = tree.type.tsym; 3380 return ; 3381 } 3382 } 3383 3384 // If qualifier symbol is a type or `super', assert `selectSuper' 3385 // for the selection. This is relevant for determining whether 3386 // protected symbols are accessible. 3387 Symbol sitesym = TreeInfo.symbol(tree.selected); 3388 boolean selectSuperPrev = env.info.selectSuper; 3389 env.info.selectSuper = 3390 sitesym != null && 3391 sitesym.name == names._super; 3392 3393 // Determine the symbol represented by the selection. 3394 env.info.pendingResolutionPhase = null; 3395 Symbol sym = selectSym(tree, sitesym, site, env, resultInfo); 3396 if (sym.kind == VAR && sym.name != names._super && env.info.defaultSuperCallSite != null) { 3397 log.error(tree.selected.pos(), "not.encl.class", site.tsym); 3398 sym = syms.errSymbol; 3399 } 3400 if (sym.exists() && !isType(sym) && pkind().contains(KindSelector.TYP_PCK)) { 3401 site = capture(site); 3402 sym = selectSym(tree, sitesym, site, env, resultInfo); 3403 } 3404 boolean varArgs = env.info.lastResolveVarargs(); 3405 tree.sym = sym; 3406 3407 if (site.hasTag(TYPEVAR) && !isType(sym) && sym.kind != ERR) { 3408 site = types.skipTypeVars(site, true); 3409 } 3410 3411 // If that symbol is a variable, ... 3412 if (sym.kind == VAR) { 3413 VarSymbol v = (VarSymbol)sym; 3414 3415 // ..., evaluate its initializer, if it has one, and check for 3416 // illegal forward reference. 3417 checkInit(tree, env, v, true); 3418 3419 // If we are expecting a variable (as opposed to a value), check 3420 // that the variable is assignable in the current environment. 3421 if (KindSelector.ASG.subset(pkind())) 3422 checkAssignable(tree.pos(), v, tree.selected, env); 3423 } 3424 3425 if (sitesym != null && 3426 sitesym.kind == VAR && 3427 ((VarSymbol)sitesym).isResourceVariable() && 3428 sym.kind == MTH && 3429 sym.name.equals(names.close) && 3430 sym.overrides(syms.autoCloseableClose, sitesym.type.tsym, types, true) && 3431 env.info.lint.isEnabled(LintCategory.TRY)) { 3432 log.warning(LintCategory.TRY, tree, "try.explicit.close.call"); 3433 } 3434 3435 // Disallow selecting a type from an expression 3436 if (isType(sym) && (sitesym == null || !sitesym.kind.matches(KindSelector.TYP_PCK))) { 3437 tree.type = check(tree.selected, pt(), 3438 sitesym == null ? 3439 KindSelector.VAL : sitesym.kind.toSelector(), 3440 new ResultInfo(KindSelector.TYP_PCK, pt())); 3441 } 3442 3443 if (isType(sitesym)) { 3444 if (sym.name == names._this) { 3445 // If `C' is the currently compiled class, check that 3446 // C.this' does not appear in a call to a super(...) 3447 if (env.info.isSelfCall && 3448 site.tsym == env.enclClass.sym) { 3449 chk.earlyRefError(tree.pos(), sym); 3450 } 3451 } else { 3452 // Check if type-qualified fields or methods are static (JLS) 3453 if ((sym.flags() & STATIC) == 0 && 3454 !env.next.tree.hasTag(REFERENCE) && 3455 sym.name != names._super && 3456 (sym.kind == VAR || sym.kind == MTH)) { 3457 rs.accessBase(rs.new StaticError(sym), 3458 tree.pos(), site, sym.name, true); 3459 } 3460 } 3461 if (!allowStaticInterfaceMethods && sitesym.isInterface() && 3462 sym.isStatic() && sym.kind == MTH) { 3463 log.error(tree.pos(), "static.intf.method.invoke.not.supported.in.source", sourceName); 3464 } 3465 } else if (sym.kind != ERR && 3466 (sym.flags() & STATIC) != 0 && 3467 sym.name != names._class) { 3468 // If the qualified item is not a type and the selected item is static, report 3469 // a warning. Make allowance for the class of an array type e.g. Object[].class) 3470 chk.warnStatic(tree, "static.not.qualified.by.type", 3471 sym.kind.kindName(), sym.owner); 3472 } 3473 3474 // If we are selecting an instance member via a `super', ... 3475 if (env.info.selectSuper && (sym.flags() & STATIC) == 0) { 3476 3477 // Check that super-qualified symbols are not abstract (JLS) 3478 rs.checkNonAbstract(tree.pos(), sym); 3479 3480 if (site.isRaw()) { 3481 // Determine argument types for site. 3482 Type site1 = types.asSuper(env.enclClass.sym.type, site.tsym); 3483 if (site1 != null) site = site1; 3484 } 3485 } 3486 3487 if (env.info.isSerializable) { 3488 chk.checkElemAccessFromSerializableLambda(tree); 3489 } 3490 3491 env.info.selectSuper = selectSuperPrev; 3492 result = checkId(tree, site, sym, env, resultInfo); 3493 } 3494 //where 3495 /** Determine symbol referenced by a Select expression, 3496 * 3497 * @param tree The select tree. 3498 * @param site The type of the selected expression, 3499 * @param env The current environment. 3500 * @param resultInfo The current result. 3501 */ 3502 private Symbol selectSym(JCFieldAccess tree, 3503 Symbol location, 3504 Type site, 3505 Env<AttrContext> env, 3506 ResultInfo resultInfo) { 3507 DiagnosticPosition pos = tree.pos(); 3508 Name name = tree.name; 3509 switch (site.getTag()) { 3510 case PACKAGE: 3511 return rs.accessBase( 3512 rs.findIdentInPackage(env, site.tsym, name, resultInfo.pkind), 3513 pos, location, site, name, true); 3514 case ARRAY: 3515 case CLASS: 3516 if (resultInfo.pt.hasTag(METHOD) || resultInfo.pt.hasTag(FORALL)) { 3517 return rs.resolveQualifiedMethod( 3518 pos, env, location, site, name, resultInfo.pt.getParameterTypes(), resultInfo.pt.getTypeArguments()); 3519 } else if (name == names._this || name == names._super) { 3520 return rs.resolveSelf(pos, env, site.tsym, name); 3521 } else if (name == names._class) { 3522 // In this case, we have already made sure in 3523 // visitSelect that qualifier expression is a type. 3524 Type t = syms.classType; 3525 List<Type> typeargs = List.of(types.erasure(site)); 3526 t = new ClassType(t.getEnclosingType(), typeargs, t.tsym); 3527 return new VarSymbol( 3528 STATIC | PUBLIC | FINAL, names._class, t, site.tsym); 3529 } else { 3530 // We are seeing a plain identifier as selector. 3531 Symbol sym = rs.findIdentInType(env, site, name, resultInfo.pkind); 3532 sym = rs.accessBase(sym, pos, location, site, name, true); 3533 return sym; 3534 } 3535 case WILDCARD: 3536 throw new AssertionError(tree); 3537 case TYPEVAR: 3538 // Normally, site.getUpperBound() shouldn't be null. 3539 // It should only happen during memberEnter/attribBase 3540 // when determining the super type which *must* beac 3541 // done before attributing the type variables. In 3542 // other words, we are seeing this illegal program: 3543 // class B<T> extends A<T.foo> {} 3544 Symbol sym = (site.getUpperBound() != null) 3545 ? selectSym(tree, location, capture(site.getUpperBound()), env, resultInfo) 3546 : null; 3547 if (sym == null) { 3548 log.error(pos, "type.var.cant.be.deref"); 3549 return syms.errSymbol; 3550 } else { 3551 Symbol sym2 = (sym.flags() & Flags.PRIVATE) != 0 ? 3552 rs.new AccessError(env, site, sym) : 3553 sym; 3554 rs.accessBase(sym2, pos, location, site, name, true); 3555 return sym; 3556 } 3557 case ERROR: 3558 // preserve identifier names through errors 3559 return types.createErrorType(name, site.tsym, site).tsym; 3560 default: 3561 // The qualifier expression is of a primitive type -- only 3562 // .class is allowed for these. 3563 if (name == names._class) { 3564 // In this case, we have already made sure in Select that 3565 // qualifier expression is a type. 3566 Type t = syms.classType; 3567 Type arg = types.boxedClass(site).type; 3568 t = new ClassType(t.getEnclosingType(), List.of(arg), t.tsym); 3569 return new VarSymbol( 3570 STATIC | PUBLIC | FINAL, names._class, t, site.tsym); 3571 } else { 3572 log.error(pos, "cant.deref", site); 3573 return syms.errSymbol; 3574 } 3575 } 3576 } 3577 3578 /** Determine type of identifier or select expression and check that 3579 * (1) the referenced symbol is not deprecated 3580 * (2) the symbol's type is safe (@see checkSafe) 3581 * (3) if symbol is a variable, check that its type and kind are 3582 * compatible with the prototype and protokind. 3583 * (4) if symbol is an instance field of a raw type, 3584 * which is being assigned to, issue an unchecked warning if its 3585 * type changes under erasure. 3586 * (5) if symbol is an instance method of a raw type, issue an 3587 * unchecked warning if its argument types change under erasure. 3588 * If checks succeed: 3589 * If symbol is a constant, return its constant type 3590 * else if symbol is a method, return its result type 3591 * otherwise return its type. 3592 * Otherwise return errType. 3593 * 3594 * @param tree The syntax tree representing the identifier 3595 * @param site If this is a select, the type of the selected 3596 * expression, otherwise the type of the current class. 3597 * @param sym The symbol representing the identifier. 3598 * @param env The current environment. 3599 * @param resultInfo The expected result 3600 */ 3601 Type checkId(JCTree tree, 3602 Type site, 3603 Symbol sym, 3604 Env<AttrContext> env, 3605 ResultInfo resultInfo) { 3606 return (resultInfo.pt.hasTag(FORALL) || resultInfo.pt.hasTag(METHOD)) ? 3607 checkMethodId(tree, site, sym, env, resultInfo) : 3608 checkIdInternal(tree, site, sym, resultInfo.pt, env, resultInfo); 3609 } 3610 3611 Type checkMethodId(JCTree tree, 3612 Type site, 3613 Symbol sym, 3614 Env<AttrContext> env, 3615 ResultInfo resultInfo) { 3616 boolean isPolymorhicSignature = 3617 (sym.baseSymbol().flags() & SIGNATURE_POLYMORPHIC) != 0; 3618 return isPolymorhicSignature ? 3619 checkSigPolyMethodId(tree, site, sym, env, resultInfo) : 3620 checkMethodIdInternal(tree, site, sym, env, resultInfo); 3621 } 3622 3623 Type checkSigPolyMethodId(JCTree tree, 3624 Type site, 3625 Symbol sym, 3626 Env<AttrContext> env, 3627 ResultInfo resultInfo) { 3628 //recover original symbol for signature polymorphic methods 3629 checkMethodIdInternal(tree, site, sym.baseSymbol(), env, resultInfo); 3630 env.info.pendingResolutionPhase = Resolve.MethodResolutionPhase.BASIC; 3631 return sym.type; 3632 } 3633 3634 Type checkMethodIdInternal(JCTree tree, 3635 Type site, 3636 Symbol sym, 3637 Env<AttrContext> env, 3638 ResultInfo resultInfo) { 3639 if (resultInfo.pkind.contains(KindSelector.POLY)) { 3640 Type pt = resultInfo.pt.map(deferredAttr.new RecoveryDeferredTypeMap(AttrMode.SPECULATIVE, sym, env.info.pendingResolutionPhase)); 3641 Type owntype = checkIdInternal(tree, site, sym, pt, env, resultInfo); 3642 resultInfo.pt.map(deferredAttr.new RecoveryDeferredTypeMap(AttrMode.CHECK, sym, env.info.pendingResolutionPhase)); 3643 return owntype; 3644 } else { 3645 return checkIdInternal(tree, site, sym, resultInfo.pt, env, resultInfo); 3646 } 3647 } 3648 3649 Type checkIdInternal(JCTree tree, 3650 Type site, 3651 Symbol sym, 3652 Type pt, 3653 Env<AttrContext> env, 3654 ResultInfo resultInfo) { 3655 if (pt.isErroneous()) { 3656 return types.createErrorType(site); 3657 } 3658 Type owntype; // The computed type of this identifier occurrence. 3659 switch (sym.kind) { 3660 case TYP: 3661 // For types, the computed type equals the symbol's type, 3662 // except for two situations: 3663 owntype = sym.type; 3664 if (owntype.hasTag(CLASS)) { 3665 chk.checkForBadAuxiliaryClassAccess(tree.pos(), env, (ClassSymbol)sym); 3666 Type ownOuter = owntype.getEnclosingType(); 3667 3668 // (a) If the symbol's type is parameterized, erase it 3669 // because no type parameters were given. 3670 // We recover generic outer type later in visitTypeApply. 3671 if (owntype.tsym.type.getTypeArguments().nonEmpty()) { 3672 owntype = types.erasure(owntype); 3673 } 3674 3675 // (b) If the symbol's type is an inner class, then 3676 // we have to interpret its outer type as a superclass 3677 // of the site type. Example: 3678 // 3679 // class Tree<A> { class Visitor { ... } } 3680 // class PointTree extends Tree<Point> { ... } 3681 // ...PointTree.Visitor... 3682 // 3683 // Then the type of the last expression above is 3684 // Tree<Point>.Visitor. 3685 else if (ownOuter.hasTag(CLASS) && site != ownOuter) { 3686 Type normOuter = site; 3687 if (normOuter.hasTag(CLASS)) { 3688 normOuter = types.asEnclosingSuper(site, ownOuter.tsym); 3689 } 3690 if (normOuter == null) // perhaps from an import 3691 normOuter = types.erasure(ownOuter); 3692 if (normOuter != ownOuter) 3693 owntype = new ClassType( 3694 normOuter, List.<Type>nil(), owntype.tsym, 3695 owntype.getMetadata()); 3696 } 3697 } 3698 break; 3699 case VAR: 3700 VarSymbol v = (VarSymbol)sym; 3701 // Test (4): if symbol is an instance field of a raw type, 3702 // which is being assigned to, issue an unchecked warning if 3703 // its type changes under erasure. 3704 if (KindSelector.ASG.subset(pkind()) && 3705 v.owner.kind == TYP && 3706 (v.flags() & STATIC) == 0 && 3707 (site.hasTag(CLASS) || site.hasTag(TYPEVAR))) { 3708 Type s = types.asOuterSuper(site, v.owner); 3709 if (s != null && 3710 s.isRaw() && 3711 !types.isSameType(v.type, v.erasure(types))) { 3712 chk.warnUnchecked(tree.pos(), 3713 "unchecked.assign.to.var", 3714 v, s); 3715 } 3716 } 3717 // The computed type of a variable is the type of the 3718 // variable symbol, taken as a member of the site type. 3719 owntype = (sym.owner.kind == TYP && 3720 sym.name != names._this && sym.name != names._super) 3721 ? types.memberType(site, sym) 3722 : sym.type; 3723 3724 // If the variable is a constant, record constant value in 3725 // computed type. 3726 if (v.getConstValue() != null && isStaticReference(tree)) 3727 owntype = owntype.constType(v.getConstValue()); 3728 3729 if (resultInfo.pkind == KindSelector.VAL) { 3730 owntype = capture(owntype); // capture "names as expressions" 3731 } 3732 break; 3733 case MTH: { 3734 owntype = checkMethod(site, sym, 3735 new ResultInfo(resultInfo.pkind, resultInfo.pt.getReturnType(), resultInfo.checkContext), 3736 env, TreeInfo.args(env.tree), resultInfo.pt.getParameterTypes(), 3737 resultInfo.pt.getTypeArguments()); 3738 break; 3739 } 3740 case PCK: case ERR: 3741 owntype = sym.type; 3742 break; 3743 default: 3744 throw new AssertionError("unexpected kind: " + sym.kind + 3745 " in tree " + tree); 3746 } 3747 3748 // Emit a `deprecation' warning if symbol is deprecated. 3749 // (for constructors (but not for constructor references), the error 3750 // was given when the constructor was resolved) 3751 3752 if (sym.name != names.init || tree.hasTag(REFERENCE)) { 3753 chk.checkDeprecated(tree.pos(), env.info.scope.owner, sym); 3754 chk.checkSunAPI(tree.pos(), sym); 3755 chk.checkProfile(tree.pos(), sym); 3756 } 3757 3758 // If symbol is a variable, check that its type and 3759 // kind are compatible with the prototype and protokind. 3760 return check(tree, owntype, sym.kind.toSelector(), resultInfo); 3761 } 3762 3763 /** Check that variable is initialized and evaluate the variable's 3764 * initializer, if not yet done. Also check that variable is not 3765 * referenced before it is defined. 3766 * @param tree The tree making up the variable reference. 3767 * @param env The current environment. 3768 * @param v The variable's symbol. 3769 */ 3770 private void checkInit(JCTree tree, 3771 Env<AttrContext> env, 3772 VarSymbol v, 3773 boolean onlyWarning) { 3774 // A forward reference is diagnosed if the declaration position 3775 // of the variable is greater than the current tree position 3776 // and the tree and variable definition occur in the same class 3777 // definition. Note that writes don't count as references. 3778 // This check applies only to class and instance 3779 // variables. Local variables follow different scope rules, 3780 // and are subject to definite assignment checking. 3781 Env<AttrContext> initEnv = enclosingInitEnv(env); 3782 if (initEnv != null && 3783 (initEnv.info.enclVar == v || v.pos > tree.pos) && 3784 v.owner.kind == TYP && 3785 v.owner == env.info.scope.owner.enclClass() && 3786 ((v.flags() & STATIC) != 0) == Resolve.isStatic(env) && 3787 (!env.tree.hasTag(ASSIGN) || 3788 TreeInfo.skipParens(((JCAssign) env.tree).lhs) != tree)) { 3789 String suffix = (initEnv.info.enclVar == v) ? 3790 "self.ref" : "forward.ref"; 3791 if (!onlyWarning || isStaticEnumField(v)) { 3792 log.error(tree.pos(), "illegal." + suffix); 3793 } else if (useBeforeDeclarationWarning) { 3794 log.warning(tree.pos(), suffix, v); 3795 } 3796 } 3797 3798 v.getConstValue(); // ensure initializer is evaluated 3799 3800 checkEnumInitializer(tree, env, v); 3801 } 3802 3803 /** 3804 * Returns the enclosing init environment associated with this env (if any). An init env 3805 * can be either a field declaration env or a static/instance initializer env. 3806 */ 3807 Env<AttrContext> enclosingInitEnv(Env<AttrContext> env) { 3808 while (true) { 3809 switch (env.tree.getTag()) { 3810 case VARDEF: 3811 JCVariableDecl vdecl = (JCVariableDecl)env.tree; 3812 if (vdecl.sym.owner.kind == TYP) { 3813 //field 3814 return env; 3815 } 3816 break; 3817 case BLOCK: 3818 if (env.next.tree.hasTag(CLASSDEF)) { 3819 //instance/static initializer 3820 return env; 3821 } 3822 break; 3823 case METHODDEF: 3824 case CLASSDEF: 3825 case TOPLEVEL: 3826 return null; 3827 } 3828 Assert.checkNonNull(env.next); 3829 env = env.next; 3830 } 3831 } 3832 3833 /** 3834 * Check for illegal references to static members of enum. In 3835 * an enum type, constructors and initializers may not 3836 * reference its static members unless they are constant. 3837 * 3838 * @param tree The tree making up the variable reference. 3839 * @param env The current environment. 3840 * @param v The variable's symbol. 3841 * @jls section 8.9 Enums 3842 */ 3843 private void checkEnumInitializer(JCTree tree, Env<AttrContext> env, VarSymbol v) { 3844 // JLS: 3845 // 3846 // "It is a compile-time error to reference a static field 3847 // of an enum type that is not a compile-time constant 3848 // (15.28) from constructors, instance initializer blocks, 3849 // or instance variable initializer expressions of that 3850 // type. It is a compile-time error for the constructors, 3851 // instance initializer blocks, or instance variable 3852 // initializer expressions of an enum constant e to refer 3853 // to itself or to an enum constant of the same type that 3854 // is declared to the right of e." 3855 if (isStaticEnumField(v)) { 3856 ClassSymbol enclClass = env.info.scope.owner.enclClass(); 3857 3858 if (enclClass == null || enclClass.owner == null) 3859 return; 3860 3861 // See if the enclosing class is the enum (or a 3862 // subclass thereof) declaring v. If not, this 3863 // reference is OK. 3864 if (v.owner != enclClass && !types.isSubtype(enclClass.type, v.owner.type)) 3865 return; 3866 3867 // If the reference isn't from an initializer, then 3868 // the reference is OK. 3869 if (!Resolve.isInitializer(env)) 3870 return; 3871 3872 log.error(tree.pos(), "illegal.enum.static.ref"); 3873 } 3874 } 3875 3876 /** Is the given symbol a static, non-constant field of an Enum? 3877 * Note: enum literals should not be regarded as such 3878 */ 3879 private boolean isStaticEnumField(VarSymbol v) { 3880 return Flags.isEnum(v.owner) && 3881 Flags.isStatic(v) && 3882 !Flags.isConstant(v) && 3883 v.name != names._class; 3884 } 3885 3886 /** 3887 * Check that method arguments conform to its instantiation. 3888 **/ 3889 public Type checkMethod(Type site, 3890 final Symbol sym, 3891 ResultInfo resultInfo, 3892 Env<AttrContext> env, 3893 final List<JCExpression> argtrees, 3894 List<Type> argtypes, 3895 List<Type> typeargtypes) { 3896 // Test (5): if symbol is an instance method of a raw type, issue 3897 // an unchecked warning if its argument types change under erasure. 3898 if ((sym.flags() & STATIC) == 0 && 3899 (site.hasTag(CLASS) || site.hasTag(TYPEVAR))) { 3900 Type s = types.asOuterSuper(site, sym.owner); 3901 if (s != null && s.isRaw() && 3902 !types.isSameTypes(sym.type.getParameterTypes(), 3903 sym.erasure(types).getParameterTypes())) { 3904 chk.warnUnchecked(env.tree.pos(), 3905 "unchecked.call.mbr.of.raw.type", 3906 sym, s); 3907 } 3908 } 3909 3910 if (env.info.defaultSuperCallSite != null) { 3911 for (Type sup : types.interfaces(env.enclClass.type).prepend(types.supertype((env.enclClass.type)))) { 3912 if (!sup.tsym.isSubClass(sym.enclClass(), types) || 3913 types.isSameType(sup, env.info.defaultSuperCallSite)) continue; 3914 List<MethodSymbol> icand_sup = 3915 types.interfaceCandidates(sup, (MethodSymbol)sym); 3916 if (icand_sup.nonEmpty() && 3917 icand_sup.head != sym && 3918 icand_sup.head.overrides(sym, icand_sup.head.enclClass(), types, true)) { 3919 log.error(env.tree.pos(), "illegal.default.super.call", env.info.defaultSuperCallSite, 3920 diags.fragment("overridden.default", sym, sup)); 3921 break; 3922 } 3923 } 3924 env.info.defaultSuperCallSite = null; 3925 } 3926 3927 if (sym.isStatic() && site.isInterface() && env.tree.hasTag(APPLY)) { 3928 JCMethodInvocation app = (JCMethodInvocation)env.tree; 3929 if (app.meth.hasTag(SELECT) && 3930 !TreeInfo.isStaticSelector(((JCFieldAccess)app.meth).selected, names)) { 3931 log.error(env.tree.pos(), "illegal.static.intf.meth.call", site); 3932 } 3933 } 3934 3935 // Compute the identifier's instantiated type. 3936 // For methods, we need to compute the instance type by 3937 // Resolve.instantiate from the symbol's type as well as 3938 // any type arguments and value arguments. 3939 Warner noteWarner = new Warner(); 3940 try { 3941 Type owntype = rs.checkMethod( 3942 env, 3943 site, 3944 sym, 3945 resultInfo, 3946 argtypes, 3947 typeargtypes, 3948 noteWarner); 3949 3950 DeferredAttr.DeferredTypeMap checkDeferredMap = 3951 deferredAttr.new DeferredTypeMap(DeferredAttr.AttrMode.CHECK, sym, env.info.pendingResolutionPhase); 3952 3953 argtypes = argtypes.map(checkDeferredMap); 3954 3955 if (noteWarner.hasNonSilentLint(LintCategory.UNCHECKED)) { 3956 chk.warnUnchecked(env.tree.pos(), 3957 "unchecked.meth.invocation.applied", 3958 kindName(sym), 3959 sym.name, 3960 rs.methodArguments(sym.type.getParameterTypes()), 3961 rs.methodArguments(argtypes.map(checkDeferredMap)), 3962 kindName(sym.location()), 3963 sym.location()); 3964 owntype = new MethodType(owntype.getParameterTypes(), 3965 types.erasure(owntype.getReturnType()), 3966 types.erasure(owntype.getThrownTypes()), 3967 syms.methodClass); 3968 } 3969 3970 PolyKind pkind = (sym.type.hasTag(FORALL) && 3971 sym.type.getReturnType().containsAny(((ForAll)sym.type).tvars)) ? 3972 PolyKind.POLY : PolyKind.STANDALONE; 3973 TreeInfo.setPolyKind(env.tree, pkind); 3974 3975 return (resultInfo.pt == Infer.anyPoly) ? 3976 owntype : 3977 chk.checkMethod(owntype, sym, env, argtrees, argtypes, env.info.lastResolveVarargs(), 3978 resultInfo.checkContext.inferenceContext()); 3979 } catch (Infer.InferenceException ex) { 3980 //invalid target type - propagate exception outwards or report error 3981 //depending on the current check context 3982 resultInfo.checkContext.report(env.tree.pos(), ex.getDiagnostic()); 3983 return types.createErrorType(site); 3984 } catch (Resolve.InapplicableMethodException ex) { 3985 final JCDiagnostic diag = ex.getDiagnostic(); 3986 Resolve.InapplicableSymbolError errSym = rs.new InapplicableSymbolError(null) { 3987 @Override 3988 protected Pair<Symbol, JCDiagnostic> errCandidate() { 3989 return new Pair<>(sym, diag); 3990 } 3991 }; 3992 List<Type> argtypes2 = argtypes.map( 3993 rs.new ResolveDeferredRecoveryMap(AttrMode.CHECK, sym, env.info.pendingResolutionPhase)); 3994 JCDiagnostic errDiag = errSym.getDiagnostic(JCDiagnostic.DiagnosticType.ERROR, 3995 env.tree, sym, site, sym.name, argtypes2, typeargtypes); 3996 log.report(errDiag); 3997 return types.createErrorType(site); 3998 } 3999 } 4000 4001 public void visitLiteral(JCLiteral tree) { 4002 result = check(tree, litType(tree.typetag).constType(tree.value), 4003 KindSelector.VAL, resultInfo); 4004 } 4005 //where 4006 /** Return the type of a literal with given type tag. 4007 */ 4008 Type litType(TypeTag tag) { 4009 return (tag == CLASS) ? syms.stringType : syms.typeOfTag[tag.ordinal()]; 4010 } 4011 4012 public void visitTypeIdent(JCPrimitiveTypeTree tree) { 4013 result = check(tree, syms.typeOfTag[tree.typetag.ordinal()], KindSelector.TYP, resultInfo); 4014 } 4015 4016 public void visitTypeArray(JCArrayTypeTree tree) { 4017 Type etype = attribType(tree.elemtype, env); 4018 Type type = new ArrayType(etype, syms.arrayClass); 4019 result = check(tree, type, KindSelector.TYP, resultInfo); 4020 } 4021 4022 /** Visitor method for parameterized types. 4023 * Bound checking is left until later, since types are attributed 4024 * before supertype structure is completely known 4025 */ 4026 public void visitTypeApply(JCTypeApply tree) { 4027 Type owntype = types.createErrorType(tree.type); 4028 4029 // Attribute functor part of application and make sure it's a class. 4030 Type clazztype = chk.checkClassType(tree.clazz.pos(), attribType(tree.clazz, env)); 4031 4032 // Attribute type parameters 4033 List<Type> actuals = attribTypes(tree.arguments, env); 4034 4035 if (clazztype.hasTag(CLASS)) { 4036 List<Type> formals = clazztype.tsym.type.getTypeArguments(); 4037 if (actuals.isEmpty()) //diamond 4038 actuals = formals; 4039 4040 if (actuals.length() == formals.length()) { 4041 List<Type> a = actuals; 4042 List<Type> f = formals; 4043 while (a.nonEmpty()) { 4044 a.head = a.head.withTypeVar(f.head); 4045 a = a.tail; 4046 f = f.tail; 4047 } 4048 // Compute the proper generic outer 4049 Type clazzOuter = clazztype.getEnclosingType(); 4050 if (clazzOuter.hasTag(CLASS)) { 4051 Type site; 4052 JCExpression clazz = TreeInfo.typeIn(tree.clazz); 4053 if (clazz.hasTag(IDENT)) { 4054 site = env.enclClass.sym.type; 4055 } else if (clazz.hasTag(SELECT)) { 4056 site = ((JCFieldAccess) clazz).selected.type; 4057 } else throw new AssertionError(""+tree); 4058 if (clazzOuter.hasTag(CLASS) && site != clazzOuter) { 4059 if (site.hasTag(CLASS)) 4060 site = types.asOuterSuper(site, clazzOuter.tsym); 4061 if (site == null) 4062 site = types.erasure(clazzOuter); 4063 clazzOuter = site; 4064 } 4065 } 4066 owntype = new ClassType(clazzOuter, actuals, clazztype.tsym, 4067 clazztype.getMetadata()); 4068 } else { 4069 if (formals.length() != 0) { 4070 log.error(tree.pos(), "wrong.number.type.args", 4071 Integer.toString(formals.length())); 4072 } else { 4073 log.error(tree.pos(), "type.doesnt.take.params", clazztype.tsym); 4074 } 4075 owntype = types.createErrorType(tree.type); 4076 } 4077 } 4078 result = check(tree, owntype, KindSelector.TYP, resultInfo); 4079 } 4080 4081 public void visitTypeUnion(JCTypeUnion tree) { 4082 ListBuffer<Type> multicatchTypes = new ListBuffer<>(); 4083 ListBuffer<Type> all_multicatchTypes = null; // lazy, only if needed 4084 for (JCExpression typeTree : tree.alternatives) { 4085 Type ctype = attribType(typeTree, env); 4086 ctype = chk.checkType(typeTree.pos(), 4087 chk.checkClassType(typeTree.pos(), ctype), 4088 syms.throwableType); 4089 if (!ctype.isErroneous()) { 4090 //check that alternatives of a union type are pairwise 4091 //unrelated w.r.t. subtyping 4092 if (chk.intersects(ctype, multicatchTypes.toList())) { 4093 for (Type t : multicatchTypes) { 4094 boolean sub = types.isSubtype(ctype, t); 4095 boolean sup = types.isSubtype(t, ctype); 4096 if (sub || sup) { 4097 //assume 'a' <: 'b' 4098 Type a = sub ? ctype : t; 4099 Type b = sub ? t : ctype; 4100 log.error(typeTree.pos(), "multicatch.types.must.be.disjoint", a, b); 4101 } 4102 } 4103 } 4104 multicatchTypes.append(ctype); 4105 if (all_multicatchTypes != null) 4106 all_multicatchTypes.append(ctype); 4107 } else { 4108 if (all_multicatchTypes == null) { 4109 all_multicatchTypes = new ListBuffer<>(); 4110 all_multicatchTypes.appendList(multicatchTypes); 4111 } 4112 all_multicatchTypes.append(ctype); 4113 } 4114 } 4115 Type t = check(tree, types.lub(multicatchTypes.toList()), 4116 KindSelector.TYP, resultInfo.dup(CheckMode.NO_TREE_UPDATE)); 4117 if (t.hasTag(CLASS)) { 4118 List<Type> alternatives = 4119 ((all_multicatchTypes == null) ? multicatchTypes : all_multicatchTypes).toList(); 4120 t = new UnionClassType((ClassType) t, alternatives); 4121 } 4122 tree.type = result = t; 4123 } 4124 4125 public void visitTypeIntersection(JCTypeIntersection tree) { 4126 attribTypes(tree.bounds, env); 4127 tree.type = result = checkIntersection(tree, tree.bounds); 4128 } 4129 4130 public void visitTypeParameter(JCTypeParameter tree) { 4131 TypeVar typeVar = (TypeVar) tree.type; 4132 4133 if (tree.annotations != null && tree.annotations.nonEmpty()) { 4134 annotate.annotateTypeParameterSecondStage(tree, tree.annotations); 4135 } 4136 4137 if (!typeVar.bound.isErroneous()) { 4138 //fixup type-parameter bound computed in 'attribTypeVariables' 4139 typeVar.bound = checkIntersection(tree, tree.bounds); 4140 } 4141 } 4142 4143 Type checkIntersection(JCTree tree, List<JCExpression> bounds) { 4144 Set<Type> boundSet = new HashSet<>(); 4145 if (bounds.nonEmpty()) { 4146 // accept class or interface or typevar as first bound. 4147 bounds.head.type = checkBase(bounds.head.type, bounds.head, env, false, false, false); 4148 boundSet.add(types.erasure(bounds.head.type)); 4149 if (bounds.head.type.isErroneous()) { 4150 return bounds.head.type; 4151 } 4152 else if (bounds.head.type.hasTag(TYPEVAR)) { 4153 // if first bound was a typevar, do not accept further bounds. 4154 if (bounds.tail.nonEmpty()) { 4155 log.error(bounds.tail.head.pos(), 4156 "type.var.may.not.be.followed.by.other.bounds"); 4157 return bounds.head.type; 4158 } 4159 } else { 4160 // if first bound was a class or interface, accept only interfaces 4161 // as further bounds. 4162 for (JCExpression bound : bounds.tail) { 4163 bound.type = checkBase(bound.type, bound, env, false, true, false); 4164 if (bound.type.isErroneous()) { 4165 bounds = List.of(bound); 4166 } 4167 else if (bound.type.hasTag(CLASS)) { 4168 chk.checkNotRepeated(bound.pos(), types.erasure(bound.type), boundSet); 4169 } 4170 } 4171 } 4172 } 4173 4174 if (bounds.length() == 0) { 4175 return syms.objectType; 4176 } else if (bounds.length() == 1) { 4177 return bounds.head.type; 4178 } else { 4179 Type owntype = types.makeIntersectionType(TreeInfo.types(bounds)); 4180 // ... the variable's bound is a class type flagged COMPOUND 4181 // (see comment for TypeVar.bound). 4182 // In this case, generate a class tree that represents the 4183 // bound class, ... 4184 JCExpression extending; 4185 List<JCExpression> implementing; 4186 if (!bounds.head.type.isInterface()) { 4187 extending = bounds.head; 4188 implementing = bounds.tail; 4189 } else { 4190 extending = null; 4191 implementing = bounds; 4192 } 4193 JCClassDecl cd = make.at(tree).ClassDef( 4194 make.Modifiers(PUBLIC | ABSTRACT), 4195 names.empty, List.<JCTypeParameter>nil(), 4196 extending, implementing, List.<JCTree>nil()); 4197 4198 ClassSymbol c = (ClassSymbol)owntype.tsym; 4199 Assert.check((c.flags() & COMPOUND) != 0); 4200 cd.sym = c; 4201 c.sourcefile = env.toplevel.sourcefile; 4202 4203 // ... and attribute the bound class 4204 c.flags_field |= UNATTRIBUTED; 4205 Env<AttrContext> cenv = enter.classEnv(cd, env); 4206 typeEnvs.put(c, cenv); 4207 attribClass(c); 4208 return owntype; 4209 } 4210 } 4211 4212 public void visitWildcard(JCWildcard tree) { 4213 //- System.err.println("visitWildcard("+tree+");");//DEBUG 4214 Type type = (tree.kind.kind == BoundKind.UNBOUND) 4215 ? syms.objectType 4216 : attribType(tree.inner, env); 4217 result = check(tree, new WildcardType(chk.checkRefType(tree.pos(), type), 4218 tree.kind.kind, 4219 syms.boundClass), 4220 KindSelector.TYP, resultInfo); 4221 } 4222 4223 public void visitAnnotation(JCAnnotation tree) { 4224 Assert.error("should be handled in annotate"); 4225 } 4226 4227 public void visitAnnotatedType(JCAnnotatedType tree) { 4228 attribAnnotationTypes(tree.annotations, env); 4229 Type underlyingType = attribType(tree.underlyingType, env); 4230 Type annotatedType = underlyingType.annotatedType(Annotations.TO_BE_SET); 4231 4232 if (!env.info.isNewClass) 4233 annotate.annotateTypeSecondStage(tree, tree.annotations, annotatedType); 4234 result = tree.type = annotatedType; 4235 } 4236 4237 public void visitErroneous(JCErroneous tree) { 4238 if (tree.errs != null) 4239 for (JCTree err : tree.errs) 4240 attribTree(err, env, new ResultInfo(KindSelector.ERR, pt())); 4241 result = tree.type = syms.errType; 4242 } 4243 4244 /** Default visitor method for all other trees. 4245 */ 4246 public void visitTree(JCTree tree) { 4247 throw new AssertionError(); 4248 } 4249 4250 /** 4251 * Attribute an env for either a top level tree or class or module declaration. 4252 */ 4253 public void attrib(Env<AttrContext> env) { 4254 switch (env.tree.getTag()) { 4255 case MODULEDEF: 4256 attribModule(env.tree.pos(), ((JCModuleDecl)env.tree).sym); 4257 break; 4258 case TOPLEVEL: 4259 attribTopLevel(env); 4260 break; 4261 default: 4262 attribClass(env.tree.pos(), env.enclClass.sym); 4263 } 4264 } 4265 4266 /** 4267 * Attribute a top level tree. These trees are encountered when the 4268 * package declaration has annotations. 4269 */ 4270 public void attribTopLevel(Env<AttrContext> env) { 4271 JCCompilationUnit toplevel = env.toplevel; 4272 try { 4273 annotate.flush(); 4274 } catch (CompletionFailure ex) { 4275 chk.completionError(toplevel.pos(), ex); 4276 } 4277 } 4278 4279 public void attribModule(DiagnosticPosition pos, ModuleSymbol m) { 4280 try { 4281 annotate.flush(); 4282 attribModule(m); 4283 } catch (CompletionFailure ex) { 4284 chk.completionError(pos, ex); 4285 } 4286 } 4287 4288 void attribModule(ModuleSymbol m) { 4289 // Get environment current at the point of module definition. 4290 Env<AttrContext> env = enter.typeEnvs.get(m); 4291 attribStat(env.tree, env); 4292 } 4293 4294 /** Main method: attribute class definition associated with given class symbol. 4295 * reporting completion failures at the given position. 4296 * @param pos The source position at which completion errors are to be 4297 * reported. 4298 * @param c The class symbol whose definition will be attributed. 4299 */ 4300 public void attribClass(DiagnosticPosition pos, ClassSymbol c) { 4301 try { 4302 annotate.flush(); 4303 attribClass(c); 4304 } catch (CompletionFailure ex) { 4305 chk.completionError(pos, ex); 4306 } 4307 } 4308 4309 /** Attribute class definition associated with given class symbol. 4310 * @param c The class symbol whose definition will be attributed. 4311 */ 4312 void attribClass(ClassSymbol c) throws CompletionFailure { 4313 if (c.type.hasTag(ERROR)) return; 4314 4315 // Check for cycles in the inheritance graph, which can arise from 4316 // ill-formed class files. 4317 chk.checkNonCyclic(null, c.type); 4318 4319 Type st = types.supertype(c.type); 4320 if ((c.flags_field & Flags.COMPOUND) == 0) { 4321 // First, attribute superclass. 4322 if (st.hasTag(CLASS)) 4323 attribClass((ClassSymbol)st.tsym); 4324 4325 // Next attribute owner, if it is a class. 4326 if (c.owner.kind == TYP && c.owner.type.hasTag(CLASS)) 4327 attribClass((ClassSymbol)c.owner); 4328 } 4329 4330 // The previous operations might have attributed the current class 4331 // if there was a cycle. So we test first whether the class is still 4332 // UNATTRIBUTED. 4333 if ((c.flags_field & UNATTRIBUTED) != 0) { 4334 c.flags_field &= ~UNATTRIBUTED; 4335 4336 // Get environment current at the point of class definition. 4337 Env<AttrContext> env = typeEnvs.get(c); 4338 4339 // The info.lint field in the envs stored in typeEnvs is deliberately uninitialized, 4340 // because the annotations were not available at the time the env was created. Therefore, 4341 // we look up the environment chain for the first enclosing environment for which the 4342 // lint value is set. Typically, this is the parent env, but might be further if there 4343 // are any envs created as a result of TypeParameter nodes. 4344 Env<AttrContext> lintEnv = env; 4345 while (lintEnv.info.lint == null) 4346 lintEnv = lintEnv.next; 4347 4348 // Having found the enclosing lint value, we can initialize the lint value for this class 4349 env.info.lint = lintEnv.info.lint.augment(c); 4350 4351 Lint prevLint = chk.setLint(env.info.lint); 4352 JavaFileObject prev = log.useSource(c.sourcefile); 4353 ResultInfo prevReturnRes = env.info.returnResult; 4354 4355 try { 4356 deferredLintHandler.flush(env.tree); 4357 env.info.returnResult = null; 4358 // java.lang.Enum may not be subclassed by a non-enum 4359 if (st.tsym == syms.enumSym && 4360 ((c.flags_field & (Flags.ENUM|Flags.COMPOUND)) == 0)) 4361 log.error(env.tree.pos(), "enum.no.subclassing"); 4362 4363 // Enums may not be extended by source-level classes 4364 if (st.tsym != null && 4365 ((st.tsym.flags_field & Flags.ENUM) != 0) && 4366 ((c.flags_field & (Flags.ENUM | Flags.COMPOUND)) == 0)) { 4367 log.error(env.tree.pos(), "enum.types.not.extensible"); 4368 } 4369 4370 if (isSerializable(c.type)) { 4371 env.info.isSerializable = true; 4372 } 4373 4374 attribClassBody(env, c); 4375 4376 chk.checkDeprecatedAnnotation(env.tree.pos(), c); 4377 chk.checkClassOverrideEqualsAndHashIfNeeded(env.tree.pos(), c); 4378 chk.checkFunctionalInterface((JCClassDecl) env.tree, c); 4379 } finally { 4380 env.info.returnResult = prevReturnRes; 4381 log.useSource(prev); 4382 chk.setLint(prevLint); 4383 } 4384 4385 } 4386 } 4387 4388 public void visitImport(JCImport tree) { 4389 // nothing to do 4390 } 4391 4392 public void visitModuleDef(JCModuleDecl tree) { 4393 tree.sym.completeUsesProvides(); 4394 } 4395 4396 /** Finish the attribution of a class. */ 4397 private void attribClassBody(Env<AttrContext> env, ClassSymbol c) { 4398 JCClassDecl tree = (JCClassDecl)env.tree; 4399 Assert.check(c == tree.sym); 4400 4401 // Validate type parameters, supertype and interfaces. 4402 attribStats(tree.typarams, env); 4403 if (!c.isAnonymous()) { 4404 //already checked if anonymous 4405 chk.validate(tree.typarams, env); 4406 chk.validate(tree.extending, env); 4407 chk.validate(tree.implementing, env); 4408 } 4409 4410 c.markAbstractIfNeeded(types); 4411 4412 // If this is a non-abstract class, check that it has no abstract 4413 // methods or unimplemented methods of an implemented interface. 4414 if ((c.flags() & (ABSTRACT | INTERFACE)) == 0) { 4415 chk.checkAllDefined(tree.pos(), c); 4416 } 4417 4418 if ((c.flags() & ANNOTATION) != 0) { 4419 if (tree.implementing.nonEmpty()) 4420 log.error(tree.implementing.head.pos(), 4421 "cant.extend.intf.annotation"); 4422 if (tree.typarams.nonEmpty()) 4423 log.error(tree.typarams.head.pos(), 4424 "intf.annotation.cant.have.type.params"); 4425 4426 // If this annotation type has a @Repeatable, validate 4427 Attribute.Compound repeatable = c.getAnnotationTypeMetadata().getRepeatable(); 4428 // If this annotation type has a @Repeatable, validate 4429 if (repeatable != null) { 4430 // get diagnostic position for error reporting 4431 DiagnosticPosition cbPos = getDiagnosticPosition(tree, repeatable.type); 4432 Assert.checkNonNull(cbPos); 4433 4434 chk.validateRepeatable(c, repeatable, cbPos); 4435 } 4436 } else { 4437 // Check that all extended classes and interfaces 4438 // are compatible (i.e. no two define methods with same arguments 4439 // yet different return types). (JLS 8.4.6.3) 4440 chk.checkCompatibleSupertypes(tree.pos(), c.type); 4441 if (allowDefaultMethods) { 4442 chk.checkDefaultMethodClashes(tree.pos(), c.type); 4443 } 4444 } 4445 4446 // Check that class does not import the same parameterized interface 4447 // with two different argument lists. 4448 chk.checkClassBounds(tree.pos(), c.type); 4449 4450 tree.type = c.type; 4451 4452 for (List<JCTypeParameter> l = tree.typarams; 4453 l.nonEmpty(); l = l.tail) { 4454 Assert.checkNonNull(env.info.scope.findFirst(l.head.name)); 4455 } 4456 4457 // Check that a generic class doesn't extend Throwable 4458 if (!c.type.allparams().isEmpty() && types.isSubtype(c.type, syms.throwableType)) 4459 log.error(tree.extending.pos(), "generic.throwable"); 4460 4461 // Check that all methods which implement some 4462 // method conform to the method they implement. 4463 chk.checkImplementations(tree); 4464 4465 //check that a resource implementing AutoCloseable cannot throw InterruptedException 4466 checkAutoCloseable(tree.pos(), env, c.type); 4467 4468 for (List<JCTree> l = tree.defs; l.nonEmpty(); l = l.tail) { 4469 // Attribute declaration 4470 attribStat(l.head, env); 4471 // Check that declarations in inner classes are not static (JLS 8.1.2) 4472 // Make an exception for static constants. 4473 if (c.owner.kind != PCK && 4474 ((c.flags() & STATIC) == 0 || c.name == names.empty) && 4475 (TreeInfo.flags(l.head) & (STATIC | INTERFACE)) != 0) { 4476 Symbol sym = null; 4477 if (l.head.hasTag(VARDEF)) sym = ((JCVariableDecl) l.head).sym; 4478 if (sym == null || 4479 sym.kind != VAR || 4480 ((VarSymbol) sym).getConstValue() == null) 4481 log.error(l.head.pos(), "icls.cant.have.static.decl", c); 4482 } 4483 } 4484 4485 // Check for cycles among non-initial constructors. 4486 chk.checkCyclicConstructors(tree); 4487 4488 // Check for cycles among annotation elements. 4489 chk.checkNonCyclicElements(tree); 4490 4491 // Check for proper use of serialVersionUID 4492 if (env.info.lint.isEnabled(LintCategory.SERIAL) && 4493 isSerializable(c.type) && 4494 (c.flags() & Flags.ENUM) == 0 && 4495 checkForSerial(c)) { 4496 checkSerialVersionUID(tree, c); 4497 } 4498 if (allowTypeAnnos) { 4499 // Correctly organize the postions of the type annotations 4500 typeAnnotations.organizeTypeAnnotationsBodies(tree); 4501 4502 // Check type annotations applicability rules 4503 validateTypeAnnotations(tree, false); 4504 } 4505 } 4506 // where 4507 boolean checkForSerial(ClassSymbol c) { 4508 if ((c.flags() & ABSTRACT) == 0) { 4509 return true; 4510 } else { 4511 return c.members().anyMatch(anyNonAbstractOrDefaultMethod); 4512 } 4513 } 4514 4515 public static final Filter<Symbol> anyNonAbstractOrDefaultMethod = new Filter<Symbol>() { 4516 @Override 4517 public boolean accepts(Symbol s) { 4518 return s.kind == MTH && 4519 (s.flags() & (DEFAULT | ABSTRACT)) != ABSTRACT; 4520 } 4521 }; 4522 4523 /** get a diagnostic position for an attribute of Type t, or null if attribute missing */ 4524 private DiagnosticPosition getDiagnosticPosition(JCClassDecl tree, Type t) { 4525 for(List<JCAnnotation> al = tree.mods.annotations; !al.isEmpty(); al = al.tail) { 4526 if (types.isSameType(al.head.annotationType.type, t)) 4527 return al.head.pos(); 4528 } 4529 4530 return null; 4531 } 4532 4533 /** check if a type is a subtype of Serializable, if that is available. */ 4534 boolean isSerializable(Type t) { 4535 try { 4536 syms.serializableType.complete(); 4537 } 4538 catch (CompletionFailure e) { 4539 return false; 4540 } 4541 return types.isSubtype(t, syms.serializableType); 4542 } 4543 4544 /** Check that an appropriate serialVersionUID member is defined. */ 4545 private void checkSerialVersionUID(JCClassDecl tree, ClassSymbol c) { 4546 4547 // check for presence of serialVersionUID 4548 VarSymbol svuid = null; 4549 for (Symbol sym : c.members().getSymbolsByName(names.serialVersionUID)) { 4550 if (sym.kind == VAR) { 4551 svuid = (VarSymbol)sym; 4552 break; 4553 } 4554 } 4555 4556 if (svuid == null) { 4557 log.warning(LintCategory.SERIAL, 4558 tree.pos(), "missing.SVUID", c); 4559 return; 4560 } 4561 4562 // check that it is static final 4563 if ((svuid.flags() & (STATIC | FINAL)) != 4564 (STATIC | FINAL)) 4565 log.warning(LintCategory.SERIAL, 4566 TreeInfo.diagnosticPositionFor(svuid, tree), "improper.SVUID", c); 4567 4568 // check that it is long 4569 else if (!svuid.type.hasTag(LONG)) 4570 log.warning(LintCategory.SERIAL, 4571 TreeInfo.diagnosticPositionFor(svuid, tree), "long.SVUID", c); 4572 4573 // check constant 4574 else if (svuid.getConstValue() == null) 4575 log.warning(LintCategory.SERIAL, 4576 TreeInfo.diagnosticPositionFor(svuid, tree), "constant.SVUID", c); 4577 } 4578 4579 private Type capture(Type type) { 4580 return types.capture(type); 4581 } 4582 4583 public void validateTypeAnnotations(JCTree tree, boolean sigOnly) { 4584 tree.accept(new TypeAnnotationsValidator(sigOnly)); 4585 } 4586 //where 4587 private final class TypeAnnotationsValidator extends TreeScanner { 4588 4589 private final boolean sigOnly; 4590 public TypeAnnotationsValidator(boolean sigOnly) { 4591 this.sigOnly = sigOnly; 4592 } 4593 4594 public void visitAnnotation(JCAnnotation tree) { 4595 chk.validateTypeAnnotation(tree, false); 4596 super.visitAnnotation(tree); 4597 } 4598 public void visitAnnotatedType(JCAnnotatedType tree) { 4599 if (!tree.underlyingType.type.isErroneous()) { 4600 super.visitAnnotatedType(tree); 4601 } 4602 } 4603 public void visitTypeParameter(JCTypeParameter tree) { 4604 chk.validateTypeAnnotations(tree.annotations, true); 4605 scan(tree.bounds); 4606 // Don't call super. 4607 // This is needed because above we call validateTypeAnnotation with 4608 // false, which would forbid annotations on type parameters. 4609 // super.visitTypeParameter(tree); 4610 } 4611 public void visitMethodDef(JCMethodDecl tree) { 4612 if (tree.recvparam != null && 4613 !tree.recvparam.vartype.type.isErroneous()) { 4614 checkForDeclarationAnnotations(tree.recvparam.mods.annotations, 4615 tree.recvparam.vartype.type.tsym); 4616 } 4617 if (tree.restype != null && tree.restype.type != null) { 4618 validateAnnotatedType(tree.restype, tree.restype.type); 4619 } 4620 if (sigOnly) { 4621 scan(tree.mods); 4622 scan(tree.restype); 4623 scan(tree.typarams); 4624 scan(tree.recvparam); 4625 scan(tree.params); 4626 scan(tree.thrown); 4627 } else { 4628 scan(tree.defaultValue); 4629 scan(tree.body); 4630 } 4631 } 4632 public void visitVarDef(final JCVariableDecl tree) { 4633 //System.err.println("validateTypeAnnotations.visitVarDef " + tree); 4634 if (tree.sym != null && tree.sym.type != null) 4635 validateAnnotatedType(tree.vartype, tree.sym.type); 4636 scan(tree.mods); 4637 scan(tree.vartype); 4638 if (!sigOnly) { 4639 scan(tree.init); 4640 } 4641 } 4642 public void visitTypeCast(JCTypeCast tree) { 4643 if (tree.clazz != null && tree.clazz.type != null) 4644 validateAnnotatedType(tree.clazz, tree.clazz.type); 4645 super.visitTypeCast(tree); 4646 } 4647 public void visitTypeTest(JCInstanceOf tree) { 4648 if (tree.clazz != null && tree.clazz.type != null) 4649 validateAnnotatedType(tree.clazz, tree.clazz.type); 4650 super.visitTypeTest(tree); 4651 } 4652 public void visitNewClass(JCNewClass tree) { 4653 if (tree.clazz != null && tree.clazz.type != null) { 4654 if (tree.clazz.hasTag(ANNOTATED_TYPE)) { 4655 checkForDeclarationAnnotations(((JCAnnotatedType) tree.clazz).annotations, 4656 tree.clazz.type.tsym); 4657 } 4658 if (tree.def != null) { 4659 checkForDeclarationAnnotations(tree.def.mods.annotations, tree.clazz.type.tsym); 4660 } 4661 4662 validateAnnotatedType(tree.clazz, tree.clazz.type); 4663 } 4664 super.visitNewClass(tree); 4665 } 4666 public void visitNewArray(JCNewArray tree) { 4667 if (tree.elemtype != null && tree.elemtype.type != null) { 4668 if (tree.elemtype.hasTag(ANNOTATED_TYPE)) { 4669 checkForDeclarationAnnotations(((JCAnnotatedType) tree.elemtype).annotations, 4670 tree.elemtype.type.tsym); 4671 } 4672 validateAnnotatedType(tree.elemtype, tree.elemtype.type); 4673 } 4674 super.visitNewArray(tree); 4675 } 4676 public void visitClassDef(JCClassDecl tree) { 4677 //System.err.println("validateTypeAnnotations.visitClassDef " + tree); 4678 if (sigOnly) { 4679 scan(tree.mods); 4680 scan(tree.typarams); 4681 scan(tree.extending); 4682 scan(tree.implementing); 4683 } 4684 for (JCTree member : tree.defs) { 4685 if (member.hasTag(Tag.CLASSDEF)) { 4686 continue; 4687 } 4688 scan(member); 4689 } 4690 } 4691 public void visitBlock(JCBlock tree) { 4692 if (!sigOnly) { 4693 scan(tree.stats); 4694 } 4695 } 4696 4697 /* I would want to model this after 4698 * com.sun.tools.javac.comp.Check.Validator.visitSelectInternal(JCFieldAccess) 4699 * and override visitSelect and visitTypeApply. 4700 * However, we only set the annotated type in the top-level type 4701 * of the symbol. 4702 * Therefore, we need to override each individual location where a type 4703 * can occur. 4704 */ 4705 private void validateAnnotatedType(final JCTree errtree, final Type type) { 4706 //System.err.println("Attr.validateAnnotatedType: " + errtree + " type: " + type); 4707 4708 if (type.isPrimitiveOrVoid()) { 4709 return; 4710 } 4711 4712 JCTree enclTr = errtree; 4713 Type enclTy = type; 4714 4715 boolean repeat = true; 4716 while (repeat) { 4717 if (enclTr.hasTag(TYPEAPPLY)) { 4718 List<Type> tyargs = enclTy.getTypeArguments(); 4719 List<JCExpression> trargs = ((JCTypeApply)enclTr).getTypeArguments(); 4720 if (trargs.length() > 0) { 4721 // Nothing to do for diamonds 4722 if (tyargs.length() == trargs.length()) { 4723 for (int i = 0; i < tyargs.length(); ++i) { 4724 validateAnnotatedType(trargs.get(i), tyargs.get(i)); 4725 } 4726 } 4727 // If the lengths don't match, it's either a diamond 4728 // or some nested type that redundantly provides 4729 // type arguments in the tree. 4730 } 4731 4732 // Look at the clazz part of a generic type 4733 enclTr = ((JCTree.JCTypeApply)enclTr).clazz; 4734 } 4735 4736 if (enclTr.hasTag(SELECT)) { 4737 enclTr = ((JCTree.JCFieldAccess)enclTr).getExpression(); 4738 if (enclTy != null && 4739 !enclTy.hasTag(NONE)) { 4740 enclTy = enclTy.getEnclosingType(); 4741 } 4742 } else if (enclTr.hasTag(ANNOTATED_TYPE)) { 4743 JCAnnotatedType at = (JCTree.JCAnnotatedType) enclTr; 4744 if (enclTy == null || enclTy.hasTag(NONE)) { 4745 if (at.getAnnotations().size() == 1) { 4746 log.error(at.underlyingType.pos(), "cant.type.annotate.scoping.1", at.getAnnotations().head.attribute); 4747 } else { 4748 ListBuffer<Attribute.Compound> comps = new ListBuffer<>(); 4749 for (JCAnnotation an : at.getAnnotations()) { 4750 comps.add(an.attribute); 4751 } 4752 log.error(at.underlyingType.pos(), "cant.type.annotate.scoping", comps.toList()); 4753 } 4754 repeat = false; 4755 } 4756 enclTr = at.underlyingType; 4757 // enclTy doesn't need to be changed 4758 } else if (enclTr.hasTag(IDENT)) { 4759 repeat = false; 4760 } else if (enclTr.hasTag(JCTree.Tag.WILDCARD)) { 4761 JCWildcard wc = (JCWildcard) enclTr; 4762 if (wc.getKind() == JCTree.Kind.EXTENDS_WILDCARD) { 4763 validateAnnotatedType(wc.getBound(), ((WildcardType)enclTy).getExtendsBound()); 4764 } else if (wc.getKind() == JCTree.Kind.SUPER_WILDCARD) { 4765 validateAnnotatedType(wc.getBound(), ((WildcardType)enclTy).getSuperBound()); 4766 } else { 4767 // Nothing to do for UNBOUND 4768 } 4769 repeat = false; 4770 } else if (enclTr.hasTag(TYPEARRAY)) { 4771 JCArrayTypeTree art = (JCArrayTypeTree) enclTr; 4772 validateAnnotatedType(art.getType(), ((ArrayType)enclTy).getComponentType()); 4773 repeat = false; 4774 } else if (enclTr.hasTag(TYPEUNION)) { 4775 JCTypeUnion ut = (JCTypeUnion) enclTr; 4776 for (JCTree t : ut.getTypeAlternatives()) { 4777 validateAnnotatedType(t, t.type); 4778 } 4779 repeat = false; 4780 } else if (enclTr.hasTag(TYPEINTERSECTION)) { 4781 JCTypeIntersection it = (JCTypeIntersection) enclTr; 4782 for (JCTree t : it.getBounds()) { 4783 validateAnnotatedType(t, t.type); 4784 } 4785 repeat = false; 4786 } else if (enclTr.getKind() == JCTree.Kind.PRIMITIVE_TYPE || 4787 enclTr.getKind() == JCTree.Kind.ERRONEOUS) { 4788 repeat = false; 4789 } else { 4790 Assert.error("Unexpected tree: " + enclTr + " with kind: " + enclTr.getKind() + 4791 " within: "+ errtree + " with kind: " + errtree.getKind()); 4792 } 4793 } 4794 } 4795 4796 private void checkForDeclarationAnnotations(List<? extends JCAnnotation> annotations, 4797 Symbol sym) { 4798 // Ensure that no declaration annotations are present. 4799 // Note that a tree type might be an AnnotatedType with 4800 // empty annotations, if only declaration annotations were given. 4801 // This method will raise an error for such a type. 4802 for (JCAnnotation ai : annotations) { 4803 if (!ai.type.isErroneous() && 4804 typeAnnotations.annotationTargetType(ai.attribute, sym) == TypeAnnotations.AnnotationType.DECLARATION) { 4805 log.error(ai.pos(), Errors.AnnotationTypeNotApplicableToType(ai.type)); 4806 } 4807 } 4808 } 4809 } 4810 4811 // <editor-fold desc="post-attribution visitor"> 4812 4813 /** 4814 * Handle missing types/symbols in an AST. This routine is useful when 4815 * the compiler has encountered some errors (which might have ended up 4816 * terminating attribution abruptly); if the compiler is used in fail-over 4817 * mode (e.g. by an IDE) and the AST contains semantic errors, this routine 4818 * prevents NPE to be progagated during subsequent compilation steps. 4819 */ 4820 public void postAttr(JCTree tree) { 4821 new PostAttrAnalyzer().scan(tree); 4822 } 4823 4824 class PostAttrAnalyzer extends TreeScanner { 4825 4826 private void initTypeIfNeeded(JCTree that) { 4827 if (that.type == null) { 4828 if (that.hasTag(METHODDEF)) { 4829 that.type = dummyMethodType((JCMethodDecl)that); 4830 } else { 4831 that.type = syms.unknownType; 4832 } 4833 } 4834 } 4835 4836 /* Construct a dummy method type. If we have a method declaration, 4837 * and the declared return type is void, then use that return type 4838 * instead of UNKNOWN to avoid spurious error messages in lambda 4839 * bodies (see:JDK-8041704). 4840 */ 4841 private Type dummyMethodType(JCMethodDecl md) { 4842 Type restype = syms.unknownType; 4843 if (md != null && md.restype.hasTag(TYPEIDENT)) { 4844 JCPrimitiveTypeTree prim = (JCPrimitiveTypeTree)md.restype; 4845 if (prim.typetag == VOID) 4846 restype = syms.voidType; 4847 } 4848 return new MethodType(List.<Type>nil(), restype, 4849 List.<Type>nil(), syms.methodClass); 4850 } 4851 private Type dummyMethodType() { 4852 return dummyMethodType(null); 4853 } 4854 4855 @Override 4856 public void scan(JCTree tree) { 4857 if (tree == null) return; 4858 if (tree instanceof JCExpression) { 4859 initTypeIfNeeded(tree); 4860 } 4861 super.scan(tree); 4862 } 4863 4864 @Override 4865 public void visitIdent(JCIdent that) { 4866 if (that.sym == null) { 4867 that.sym = syms.unknownSymbol; 4868 } 4869 } 4870 4871 @Override 4872 public void visitSelect(JCFieldAccess that) { 4873 if (that.sym == null) { 4874 that.sym = syms.unknownSymbol; 4875 } 4876 super.visitSelect(that); 4877 } 4878 4879 @Override 4880 public void visitClassDef(JCClassDecl that) { 4881 initTypeIfNeeded(that); 4882 if (that.sym == null) { 4883 that.sym = new ClassSymbol(0, that.name, that.type, syms.noSymbol); 4884 } 4885 super.visitClassDef(that); 4886 } 4887 4888 @Override 4889 public void visitMethodDef(JCMethodDecl that) { 4890 initTypeIfNeeded(that); 4891 if (that.sym == null) { 4892 that.sym = new MethodSymbol(0, that.name, that.type, syms.noSymbol); 4893 } 4894 super.visitMethodDef(that); 4895 } 4896 4897 @Override 4898 public void visitVarDef(JCVariableDecl that) { 4899 initTypeIfNeeded(that); 4900 if (that.sym == null) { 4901 that.sym = new VarSymbol(0, that.name, that.type, syms.noSymbol); 4902 that.sym.adr = 0; 4903 } 4904 super.visitVarDef(that); 4905 } 4906 4907 @Override 4908 public void visitNewClass(JCNewClass that) { 4909 if (that.constructor == null) { 4910 that.constructor = new MethodSymbol(0, names.init, 4911 dummyMethodType(), syms.noSymbol); 4912 } 4913 if (that.constructorType == null) { 4914 that.constructorType = syms.unknownType; 4915 } 4916 super.visitNewClass(that); 4917 } 4918 4919 @Override 4920 public void visitAssignop(JCAssignOp that) { 4921 if (that.operator == null) { 4922 that.operator = new OperatorSymbol(names.empty, dummyMethodType(), 4923 -1, syms.noSymbol); 4924 } 4925 super.visitAssignop(that); 4926 } 4927 4928 @Override 4929 public void visitBinary(JCBinary that) { 4930 if (that.operator == null) { 4931 that.operator = new OperatorSymbol(names.empty, dummyMethodType(), 4932 -1, syms.noSymbol); 4933 } 4934 super.visitBinary(that); 4935 } 4936 4937 @Override 4938 public void visitUnary(JCUnary that) { 4939 if (that.operator == null) { 4940 that.operator = new OperatorSymbol(names.empty, dummyMethodType(), 4941 -1, syms.noSymbol); 4942 } 4943 super.visitUnary(that); 4944 } 4945 4946 @Override 4947 public void visitLambda(JCLambda that) { 4948 super.visitLambda(that); 4949 if (that.targets == null) { 4950 that.targets = List.nil(); 4951 } 4952 } 4953 4954 @Override 4955 public void visitReference(JCMemberReference that) { 4956 super.visitReference(that); 4957 if (that.sym == null) { 4958 that.sym = new MethodSymbol(0, names.empty, dummyMethodType(), 4959 syms.noSymbol); 4960 } 4961 if (that.targets == null) { 4962 that.targets = List.nil(); 4963 } 4964 } 4965 } 4966 // </editor-fold> 4967 4968 public void setPackageSymbols(JCExpression pid, Symbol pkg) { 4969 new TreeScanner() { 4970 Symbol packge = pkg; 4971 @Override 4972 public void visitIdent(JCIdent that) { 4973 that.sym = packge; 4974 } 4975 4976 @Override 4977 public void visitSelect(JCFieldAccess that) { 4978 that.sym = packge; 4979 packge = packge.owner; 4980 super.visitSelect(that); 4981 } 4982 }.scan(pid); 4983 } 4984 4985} 4986