1 /*
   2  * Copyright (c) 1999, 2009, 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 
  26 package com.sun.tools.javac.comp;
  27 
  28 import java.util.*;
  29 import java.util.Set;
  30 import javax.lang.model.element.ElementKind;
  31 import javax.tools.JavaFileObject;
  32 
  33 import com.sun.tools.javac.code.*;
  34 import com.sun.tools.javac.jvm.*;
  35 import com.sun.tools.javac.tree.*;
  36 import com.sun.tools.javac.util.*;
  37 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
  38 import com.sun.tools.javac.util.List;
  39 
  40 import com.sun.tools.javac.jvm.Target;
  41 import com.sun.tools.javac.code.Symbol.*;
  42 import com.sun.tools.javac.tree.JCTree.*;
  43 import com.sun.tools.javac.code.Type.*;
  44 
  45 import com.sun.source.tree.IdentifierTree;
  46 import com.sun.source.tree.MemberSelectTree;
  47 import com.sun.source.tree.TreeVisitor;
  48 import com.sun.source.util.SimpleTreeVisitor;
  49 
  50 import static com.sun.tools.javac.code.Flags.*;
  51 import static com.sun.tools.javac.code.Kinds.*;
  52 import static com.sun.tools.javac.code.TypeTags.*;
  53 
  54 /** This is the main context-dependent analysis phase in GJC. It
  55  *  encompasses name resolution, type checking and constant folding as
  56  *  subtasks. Some subtasks involve auxiliary classes.
  57  *  @see Check
  58  *  @see Resolve
  59  *  @see ConstFold
  60  *  @see Infer
  61  *
  62  *  <p><b>This is NOT part of any supported API.
  63  *  If you write code that depends on this, you do so at your own risk.
  64  *  This code and its internal interfaces are subject to change or
  65  *  deletion without notice.</b>
  66  */
  67 public class Attr extends JCTree.Visitor {
  68     protected static final Context.Key<Attr> attrKey =
  69         new Context.Key<Attr>();
  70 
  71     final Names names;
  72     final Log log;
  73     final Symtab syms;
  74     final Resolve rs;
  75     final Infer infer;
  76     final Check chk;
  77     final MemberEnter memberEnter;
  78     final TreeMaker make;
  79     final ConstFold cfolder;
  80     final Enter enter;
  81     final Target target;
  82     final Types types;
  83     final JCDiagnostic.Factory diags;
  84     final Annotate annotate;
  85 
  86     public static Attr instance(Context context) {
  87         Attr instance = context.get(attrKey);
  88         if (instance == null)
  89             instance = new Attr(context);
  90         return instance;
  91     }
  92 
  93     protected Attr(Context context) {
  94         context.put(attrKey, this);
  95 
  96         names = Names.instance(context);
  97         log = Log.instance(context);
  98         syms = Symtab.instance(context);
  99         rs = Resolve.instance(context);
 100         chk = Check.instance(context);
 101         memberEnter = MemberEnter.instance(context);
 102         make = TreeMaker.instance(context);
 103         enter = Enter.instance(context);
 104         infer = Infer.instance(context);
 105         cfolder = ConstFold.instance(context);
 106         target = Target.instance(context);
 107         types = Types.instance(context);
 108         diags = JCDiagnostic.Factory.instance(context);
 109         annotate = Annotate.instance(context);
 110 
 111         Options options = Options.instance(context);
 112 
 113         Source source = Source.instance(context);
 114         allowGenerics = source.allowGenerics();
 115         allowVarargs = source.allowVarargs();
 116         allowEnums = source.allowEnums();
 117         allowBoxing = source.allowBoxing();
 118         allowCovariantReturns = source.allowCovariantReturns();
 119         allowAnonOuterThis = source.allowAnonOuterThis();
 120         allowStringsInSwitch = source.allowStringsInSwitch();
 121         sourceName = source.name;
 122         relax = (options.get("-retrofit") != null ||
 123                  options.get("-relax") != null);
 124         useBeforeDeclarationWarning = options.get("useBeforeDeclarationWarning") != null;
 125         allowInvokedynamic = options.get("invokedynamic") != null;
 126         enableSunApiLintControl = options.get("enableSunApiLintControl") != null;
 127     }
 128 
 129     /** Switch: relax some constraints for retrofit mode.
 130      */
 131     boolean relax;
 132 
 133     /** Switch: support generics?
 134      */
 135     boolean allowGenerics;
 136 
 137     /** Switch: allow variable-arity methods.
 138      */
 139     boolean allowVarargs;
 140 
 141     /** Switch: support enums?
 142      */
 143     boolean allowEnums;
 144 
 145     /** Switch: support boxing and unboxing?
 146      */
 147     boolean allowBoxing;
 148 
 149     /** Switch: support covariant result types?
 150      */
 151     boolean allowCovariantReturns;
 152 
 153     /** Switch: allow references to surrounding object from anonymous
 154      * objects during constructor call?
 155      */
 156     boolean allowAnonOuterThis;
 157 
 158     /** Switch: allow invokedynamic syntax
 159      */
 160     boolean allowInvokedynamic;
 161 
 162     /**
 163      * Switch: warn about use of variable before declaration?
 164      * RFE: 6425594
 165      */
 166     boolean useBeforeDeclarationWarning;
 167 
 168     /**
 169      * Switch: allow lint infrastructure to control proprietary
 170      * API warnings.
 171      */
 172     boolean enableSunApiLintControl;
 173 
 174     /**
 175      * Switch: allow strings in switch?
 176      */
 177     boolean allowStringsInSwitch;
 178 
 179     /**
 180      * Switch: name of source level; used for error reporting.
 181      */
 182     String sourceName;
 183 
 184     /** Check kind and type of given tree against protokind and prototype.
 185      *  If check succeeds, store type in tree and return it.
 186      *  If check fails, store errType in tree and return it.
 187      *  No checks are performed if the prototype is a method type.
 188      *  It is not necessary in this case since we know that kind and type
 189      *  are correct.
 190      *
 191      *  @param tree     The tree whose kind and type is checked
 192      *  @param owntype  The computed type of the tree
 193      *  @param ownkind  The computed kind of the tree
 194      *  @param pkind    The expected kind (or: protokind) of the tree
 195      *  @param pt       The expected type (or: prototype) of the tree
 196      */
 197     Type check(JCTree tree, Type owntype, int ownkind, int pkind, Type pt) {
 198         if (owntype.tag != ERROR && pt.tag != METHOD && pt.tag != FORALL) {
 199             if ((ownkind & ~pkind) == 0) {
 200                 owntype = chk.checkType(tree.pos(), owntype, pt);
 201             } else {
 202                 log.error(tree.pos(), "unexpected.type",
 203                           kindNames(pkind),
 204                           kindName(ownkind));
 205                 owntype = types.createErrorType(owntype);
 206             }
 207         }
 208         tree.type = owntype;
 209         return owntype;
 210     }
 211 
 212     /** Is given blank final variable assignable, i.e. in a scope where it
 213      *  may be assigned to even though it is final?
 214      *  @param v      The blank final variable.
 215      *  @param env    The current environment.
 216      */
 217     boolean isAssignableAsBlankFinal(VarSymbol v, Env<AttrContext> env) {
 218         Symbol owner = env.info.scope.owner;
 219            // owner refers to the innermost variable, method or
 220            // initializer block declaration at this point.
 221         return
 222             v.owner == owner
 223             ||
 224             ((owner.name == names.init ||    // i.e. we are in a constructor
 225               owner.kind == VAR ||           // i.e. we are in a variable initializer
 226               (owner.flags() & BLOCK) != 0)  // i.e. we are in an initializer block
 227              &&
 228              v.owner == owner.owner
 229              &&
 230              ((v.flags() & STATIC) != 0) == Resolve.isStatic(env));
 231     }
 232 
 233     /** Check that variable can be assigned to.
 234      *  @param pos    The current source code position.
 235      *  @param v      The assigned varaible
 236      *  @param base   If the variable is referred to in a Select, the part
 237      *                to the left of the `.', null otherwise.
 238      *  @param env    The current environment.
 239      */
 240     void checkAssignable(DiagnosticPosition pos, VarSymbol v, JCTree base, Env<AttrContext> env) {
 241         if ((v.flags() & FINAL) != 0 &&
 242             ((v.flags() & HASINIT) != 0
 243              ||
 244              !((base == null ||
 245                (base.getTag() == JCTree.IDENT && TreeInfo.name(base) == names._this)) &&
 246                isAssignableAsBlankFinal(v, env)))) {
 247             log.error(pos, "cant.assign.val.to.final.var", v);
 248         }
 249     }
 250 
 251     /** Does tree represent a static reference to an identifier?
 252      *  It is assumed that tree is either a SELECT or an IDENT.
 253      *  We have to weed out selects from non-type names here.
 254      *  @param tree    The candidate tree.
 255      */
 256     boolean isStaticReference(JCTree tree) {
 257         if (tree.getTag() == JCTree.SELECT) {
 258             Symbol lsym = TreeInfo.symbol(((JCFieldAccess) tree).selected);
 259             if (lsym == null || lsym.kind != TYP) {
 260                 return false;
 261             }
 262         }
 263         return true;
 264     }
 265 
 266     /** Is this symbol a type?
 267      */
 268     static boolean isType(Symbol sym) {
 269         return sym != null && sym.kind == TYP;
 270     }
 271 
 272     /** The current `this' symbol.
 273      *  @param env    The current environment.
 274      */
 275     Symbol thisSym(DiagnosticPosition pos, Env<AttrContext> env) {
 276         return rs.resolveSelf(pos, env, env.enclClass.sym, names._this);
 277     }
 278 
 279     /** Attribute a parsed identifier.
 280      * @param tree Parsed identifier name
 281      * @param topLevel The toplevel to use
 282      */
 283     public Symbol attribIdent(JCTree tree, JCCompilationUnit topLevel) {
 284         Env<AttrContext> localEnv = enter.topLevelEnv(topLevel);
 285         localEnv.enclClass = make.ClassDef(make.Modifiers(0),
 286                                            syms.errSymbol.name,
 287                                            null, null, null, null);
 288         localEnv.enclClass.sym = syms.errSymbol;
 289         return tree.accept(identAttributer, localEnv);
 290     }
 291     // where
 292         private TreeVisitor<Symbol,Env<AttrContext>> identAttributer = new IdentAttributer();
 293         private class IdentAttributer extends SimpleTreeVisitor<Symbol,Env<AttrContext>> {
 294             @Override
 295             public Symbol visitMemberSelect(MemberSelectTree node, Env<AttrContext> env) {
 296                 Symbol site = visit(node.getExpression(), env);
 297                 if (site.kind == ERR)
 298                     return site;
 299                 Name name = (Name)node.getIdentifier();
 300                 if (site.kind == PCK) {
 301                     env.toplevel.packge = (PackageSymbol)site;
 302                     return rs.findIdentInPackage(env, (TypeSymbol)site, name, TYP | PCK);
 303                 } else {
 304                     env.enclClass.sym = (ClassSymbol)site;
 305                     return rs.findMemberType(env, site.asType(), name, (TypeSymbol)site);
 306                 }
 307             }
 308 
 309             @Override
 310             public Symbol visitIdentifier(IdentifierTree node, Env<AttrContext> env) {
 311                 return rs.findIdent(env, (Name)node.getName(), TYP | PCK);
 312             }
 313         }
 314 
 315     public Type coerce(Type etype, Type ttype) {
 316         return cfolder.coerce(etype, ttype);
 317     }
 318 
 319     public Type attribType(JCTree node, TypeSymbol sym) {
 320         Env<AttrContext> env = enter.typeEnvs.get(sym);
 321         Env<AttrContext> localEnv = env.dup(node, env.info.dup());
 322         return attribTree(node, localEnv, Kinds.TYP, Type.noType);
 323     }
 324 
 325     public Env<AttrContext> attribExprToTree(JCTree expr, Env<AttrContext> env, JCTree tree) {
 326         breakTree = tree;
 327         JavaFileObject prev = log.useSource(env.toplevel.sourcefile);
 328         try {
 329             attribExpr(expr, env);
 330         } catch (BreakAttr b) {
 331             return b.env;
 332         } finally {
 333             breakTree = null;
 334             log.useSource(prev);
 335         }
 336         return env;
 337     }
 338 
 339     public Env<AttrContext> attribStatToTree(JCTree stmt, Env<AttrContext> env, JCTree tree) {
 340         breakTree = tree;
 341         JavaFileObject prev = log.useSource(env.toplevel.sourcefile);
 342         try {
 343             attribStat(stmt, env);
 344         } catch (BreakAttr b) {
 345             return b.env;
 346         } finally {
 347             breakTree = null;
 348             log.useSource(prev);
 349         }
 350         return env;
 351     }
 352 
 353     private JCTree breakTree = null;
 354 
 355     private static class BreakAttr extends RuntimeException {
 356         static final long serialVersionUID = -6924771130405446405L;
 357         private Env<AttrContext> env;
 358         private BreakAttr(Env<AttrContext> env) {
 359             this.env = env;
 360         }
 361     }
 362 
 363 
 364 /* ************************************************************************
 365  * Visitor methods
 366  *************************************************************************/
 367 
 368     /** Visitor argument: the current environment.
 369      */
 370     Env<AttrContext> env;
 371 
 372     /** Visitor argument: the currently expected proto-kind.
 373      */
 374     int pkind;
 375 
 376     /** Visitor argument: the currently expected proto-type.
 377      */
 378     Type pt;
 379 
 380     /** Visitor result: the computed type.
 381      */
 382     Type result;
 383 
 384     /** Visitor method: attribute a tree, catching any completion failure
 385      *  exceptions. Return the tree's type.
 386      *
 387      *  @param tree    The tree to be visited.
 388      *  @param env     The environment visitor argument.
 389      *  @param pkind   The protokind visitor argument.
 390      *  @param pt      The prototype visitor argument.
 391      */
 392     Type attribTree(JCTree tree, Env<AttrContext> env, int pkind, Type pt) {
 393         Env<AttrContext> prevEnv = this.env;
 394         int prevPkind = this.pkind;
 395         Type prevPt = this.pt;
 396         try {
 397             this.env = env;
 398             this.pkind = pkind;
 399             this.pt = pt;
 400             tree.accept(this);
 401             if (tree == breakTree)
 402                 throw new BreakAttr(env);
 403             return result;
 404         } catch (CompletionFailure ex) {
 405             tree.type = syms.errType;
 406             return chk.completionError(tree.pos(), ex);
 407         } finally {
 408             this.env = prevEnv;
 409             this.pkind = prevPkind;
 410             this.pt = prevPt;
 411         }
 412     }
 413 
 414     /** Derived visitor method: attribute an expression tree.
 415      */
 416     public Type attribExpr(JCTree tree, Env<AttrContext> env, Type pt) {
 417         return attribTree(tree, env, VAL, pt.tag != ERROR ? pt : Type.noType);
 418     }
 419 
 420     /** Derived visitor method: attribute an expression tree with
 421      *  no constraints on the computed type.
 422      */
 423     Type attribExpr(JCTree tree, Env<AttrContext> env) {
 424         return attribTree(tree, env, VAL, Type.noType);
 425     }
 426 
 427     /** Derived visitor method: attribute a type tree.
 428      */
 429     Type attribType(JCTree tree, Env<AttrContext> env) {
 430         Type result = attribType(tree, env, Type.noType);
 431         return result;
 432     }
 433 
 434     /** Derived visitor method: attribute a type tree.
 435      */
 436     Type attribType(JCTree tree, Env<AttrContext> env, Type pt) {
 437         Type result = attribTree(tree, env, TYP, pt);
 438         return result;
 439     }
 440 
 441     /** Derived visitor method: attribute a statement or definition tree.
 442      */
 443     public Type attribStat(JCTree tree, Env<AttrContext> env) {
 444         return attribTree(tree, env, NIL, Type.noType);
 445     }
 446 
 447     /** Attribute a list of expressions, returning a list of types.
 448      */
 449     List<Type> attribExprs(List<JCExpression> trees, Env<AttrContext> env, Type pt) {
 450         ListBuffer<Type> ts = new ListBuffer<Type>();
 451         for (List<JCExpression> l = trees; l.nonEmpty(); l = l.tail)
 452             ts.append(attribExpr(l.head, env, pt));
 453         return ts.toList();
 454     }
 455 
 456     /** Attribute a list of statements, returning nothing.
 457      */
 458     <T extends JCTree> void attribStats(List<T> trees, Env<AttrContext> env) {
 459         for (List<T> l = trees; l.nonEmpty(); l = l.tail)
 460             attribStat(l.head, env);
 461     }
 462 
 463     /** Attribute the arguments in a method call, returning a list of types.
 464      */
 465     List<Type> attribArgs(List<JCExpression> trees, Env<AttrContext> env) {
 466         ListBuffer<Type> argtypes = new ListBuffer<Type>();
 467         for (List<JCExpression> l = trees; l.nonEmpty(); l = l.tail)
 468             argtypes.append(chk.checkNonVoid(
 469                 l.head.pos(), types.upperBound(attribTree(l.head, env, VAL, Infer.anyPoly))));
 470         return argtypes.toList();
 471     }
 472 
 473     /** Attribute a type argument list, returning a list of types.
 474      *  Caller is responsible for calling checkRefTypes.
 475      */
 476     List<Type> attribAnyTypes(List<JCExpression> trees, Env<AttrContext> env) {
 477         ListBuffer<Type> argtypes = new ListBuffer<Type>();
 478         for (List<JCExpression> l = trees; l.nonEmpty(); l = l.tail)
 479             argtypes.append(attribType(l.head, env));
 480         return argtypes.toList();
 481     }
 482 
 483     /** Attribute a type argument list, returning a list of types.
 484      *  Check that all the types are references.
 485      */
 486     List<Type> attribTypes(List<JCExpression> trees, Env<AttrContext> env) {
 487         List<Type> types = attribAnyTypes(trees, env);
 488         return chk.checkRefTypes(trees, types);
 489     }
 490 
 491     /**
 492      * Attribute type variables (of generic classes or methods).
 493      * Compound types are attributed later in attribBounds.
 494      * @param typarams the type variables to enter
 495      * @param env      the current environment
 496      */
 497     void attribTypeVariables(List<JCTypeParameter> typarams, Env<AttrContext> env) {
 498         for (JCTypeParameter tvar : typarams) {
 499             TypeVar a = (TypeVar)tvar.type;
 500             a.tsym.flags_field |= UNATTRIBUTED;
 501             a.bound = Type.noType;
 502             if (!tvar.bounds.isEmpty()) {
 503                 List<Type> bounds = List.of(attribType(tvar.bounds.head, env));
 504                 for (JCExpression bound : tvar.bounds.tail)
 505                     bounds = bounds.prepend(attribType(bound, env));
 506                 types.setBounds(a, bounds.reverse());
 507             } else {
 508                 // if no bounds are given, assume a single bound of
 509                 // java.lang.Object.
 510                 types.setBounds(a, List.of(syms.objectType));
 511             }
 512             a.tsym.flags_field &= ~UNATTRIBUTED;
 513         }
 514         for (JCTypeParameter tvar : typarams)
 515             chk.checkNonCyclic(tvar.pos(), (TypeVar)tvar.type);
 516         attribStats(typarams, env);
 517     }
 518 
 519     void attribBounds(List<JCTypeParameter> typarams) {
 520         for (JCTypeParameter typaram : typarams) {
 521             Type bound = typaram.type.getUpperBound();
 522             if (bound != null && bound.tsym instanceof ClassSymbol) {
 523                 ClassSymbol c = (ClassSymbol)bound.tsym;
 524                 if ((c.flags_field & COMPOUND) != 0) {
 525                     assert (c.flags_field & UNATTRIBUTED) != 0 : c;
 526                     attribClass(typaram.pos(), c);
 527                 }
 528             }
 529         }
 530     }
 531 
 532     /**
 533      * Attribute the type references in a list of annotations.
 534      */
 535     void attribAnnotationTypes(List<JCAnnotation> annotations,
 536                                Env<AttrContext> env) {
 537         for (List<JCAnnotation> al = annotations; al.nonEmpty(); al = al.tail) {
 538             JCAnnotation a = al.head;
 539             attribType(a.annotationType, env);
 540         }
 541     }
 542 
 543     /** Attribute type reference in an `extends' or `implements' clause.
 544      *  Supertypes of anonymous inner classes are usually already attributed.
 545      *
 546      *  @param tree              The tree making up the type reference.
 547      *  @param env               The environment current at the reference.
 548      *  @param classExpected     true if only a class is expected here.
 549      *  @param interfaceExpected true if only an interface is expected here.
 550      */
 551     Type attribBase(JCTree tree,
 552                     Env<AttrContext> env,
 553                     boolean classExpected,
 554                     boolean interfaceExpected,
 555                     boolean checkExtensible) {
 556         Type t = tree.type != null ?
 557             tree.type :
 558             attribType(tree, env);
 559         return checkBase(t, tree, env, classExpected, interfaceExpected, checkExtensible);
 560     }
 561     Type checkBase(Type t,
 562                    JCTree tree,
 563                    Env<AttrContext> env,
 564                    boolean classExpected,
 565                    boolean interfaceExpected,
 566                    boolean checkExtensible) {
 567         if (t.tag == TYPEVAR && !classExpected && !interfaceExpected) {
 568             // check that type variable is already visible
 569             if (t.getUpperBound() == null) {
 570                 log.error(tree.pos(), "illegal.forward.ref");
 571                 return types.createErrorType(t);
 572             }
 573         } else {
 574             t = chk.checkClassType(tree.pos(), t, checkExtensible|!allowGenerics);
 575         }
 576         if (interfaceExpected && (t.tsym.flags() & INTERFACE) == 0) {
 577             log.error(tree.pos(), "intf.expected.here");
 578             // return errType is necessary since otherwise there might
 579             // be undetected cycles which cause attribution to loop
 580             return types.createErrorType(t);
 581         } else if (checkExtensible &&
 582                    classExpected &&
 583                    (t.tsym.flags() & INTERFACE) != 0) {
 584             log.error(tree.pos(), "no.intf.expected.here");
 585             return types.createErrorType(t);
 586         }
 587         if (checkExtensible &&
 588             ((t.tsym.flags() & FINAL) != 0)) {
 589             log.error(tree.pos(),
 590                       "cant.inherit.from.final", t.tsym);
 591         }
 592         chk.checkNonCyclic(tree.pos(), t);
 593         return t;
 594     }
 595 
 596     public void visitClassDef(JCClassDecl tree) {
 597         // Local classes have not been entered yet, so we need to do it now:
 598         if ((env.info.scope.owner.kind & (VAR | MTH)) != 0)
 599             enter.classEnter(tree, env);
 600 
 601         ClassSymbol c = tree.sym;
 602         if (c == null) {
 603             // exit in case something drastic went wrong during enter.
 604             result = null;
 605         } else {
 606             // make sure class has been completed:
 607             c.complete();
 608 
 609             // If this class appears as an anonymous class
 610             // in a superclass constructor call where
 611             // no explicit outer instance is given,
 612             // disable implicit outer instance from being passed.
 613             // (This would be an illegal access to "this before super").
 614             if (env.info.isSelfCall &&
 615                 env.tree.getTag() == JCTree.NEWCLASS &&
 616                 ((JCNewClass) env.tree).encl == null)
 617             {
 618                 c.flags_field |= NOOUTERTHIS;
 619             }
 620             attribClass(tree.pos(), c);
 621             result = tree.type = c.type;
 622         }
 623     }
 624 
 625     public void visitMethodDef(JCMethodDecl tree) {
 626         MethodSymbol m = tree.sym;
 627 
 628         Lint lint = env.info.lint.augment(m.attributes_field, m.flags());
 629         Lint prevLint = chk.setLint(lint);
 630         try {
 631             chk.checkDeprecatedAnnotation(tree.pos(), m);
 632 
 633             attribBounds(tree.typarams);
 634 
 635             // If we override any other methods, check that we do so properly.
 636             // JLS ???
 637             chk.checkOverride(tree, m);
 638 
 639             // Create a new environment with local scope
 640             // for attributing the method.
 641             Env<AttrContext> localEnv = memberEnter.methodEnv(tree, env);
 642 
 643             localEnv.info.lint = lint;
 644 
 645             // Enter all type parameters into the local method scope.
 646             for (List<JCTypeParameter> l = tree.typarams; l.nonEmpty(); l = l.tail)
 647                 localEnv.info.scope.enterIfAbsent(l.head.type.tsym);
 648 
 649             ClassSymbol owner = env.enclClass.sym;
 650             if ((owner.flags() & ANNOTATION) != 0 &&
 651                 tree.params.nonEmpty())
 652                 log.error(tree.params.head.pos(),
 653                           "intf.annotation.members.cant.have.params");
 654 
 655             // Attribute all value parameters.
 656             for (List<JCVariableDecl> l = tree.params; l.nonEmpty(); l = l.tail) {
 657                 attribStat(l.head, localEnv);
 658             }
 659 
 660             chk.checkVarargMethodDecl(tree);
 661 
 662             // Check that type parameters are well-formed.
 663             chk.validate(tree.typarams, localEnv);
 664             if ((owner.flags() & ANNOTATION) != 0 &&
 665                 tree.typarams.nonEmpty())
 666                 log.error(tree.typarams.head.pos(),
 667                           "intf.annotation.members.cant.have.type.params");
 668 
 669             // Check that result type is well-formed.
 670             chk.validate(tree.restype, localEnv);
 671             if ((owner.flags() & ANNOTATION) != 0)
 672                 chk.validateAnnotationType(tree.restype);
 673 
 674             if ((owner.flags() & ANNOTATION) != 0)
 675                 chk.validateAnnotationMethod(tree.pos(), m);
 676 
 677             // Check that all exceptions mentioned in the throws clause extend
 678             // java.lang.Throwable.
 679             if ((owner.flags() & ANNOTATION) != 0 && tree.thrown.nonEmpty())
 680                 log.error(tree.thrown.head.pos(),
 681                           "throws.not.allowed.in.intf.annotation");
 682             for (List<JCExpression> l = tree.thrown; l.nonEmpty(); l = l.tail)
 683                 chk.checkType(l.head.pos(), l.head.type, syms.throwableType);
 684 
 685             if (tree.body == null) {
 686                 // Empty bodies are only allowed for
 687                 // abstract, native, or interface methods, or for methods
 688                 // in a retrofit signature class.
 689                 if ((owner.flags() & INTERFACE) == 0 &&
 690                     (tree.mods.flags & (ABSTRACT | NATIVE)) == 0 &&
 691                     !relax)
 692                     log.error(tree.pos(), "missing.meth.body.or.decl.abstract");
 693                 if (tree.defaultValue != null) {
 694                     if ((owner.flags() & ANNOTATION) == 0)
 695                         log.error(tree.pos(),
 696                                   "default.allowed.in.intf.annotation.member");
 697                 }
 698             } else if ((owner.flags() & INTERFACE) != 0) {
 699                 log.error(tree.body.pos(), "intf.meth.cant.have.body");
 700             } else if ((tree.mods.flags & ABSTRACT) != 0) {
 701                 log.error(tree.pos(), "abstract.meth.cant.have.body");
 702             } else if ((tree.mods.flags & NATIVE) != 0) {
 703                 log.error(tree.pos(), "native.meth.cant.have.body");
 704             } else {
 705                 // Add an implicit super() call unless an explicit call to
 706                 // super(...) or this(...) is given
 707                 // or we are compiling class java.lang.Object.
 708                 if (tree.name == names.init && owner.type != syms.objectType) {
 709                     JCBlock body = tree.body;
 710                     if (body.stats.isEmpty() ||
 711                         !TreeInfo.isSelfCall(body.stats.head)) {
 712                         body.stats = body.stats.
 713                             prepend(memberEnter.SuperCall(make.at(body.pos),
 714                                                           List.<Type>nil(),
 715                                                           List.<JCVariableDecl>nil(),
 716                                                           false));
 717                     } else if ((env.enclClass.sym.flags() & ENUM) != 0 &&
 718                                (tree.mods.flags & GENERATEDCONSTR) == 0 &&
 719                                TreeInfo.isSuperCall(body.stats.head)) {
 720                         // enum constructors are not allowed to call super
 721                         // directly, so make sure there aren't any super calls
 722                         // in enum constructors, except in the compiler
 723                         // generated one.
 724                         log.error(tree.body.stats.head.pos(),
 725                                   "call.to.super.not.allowed.in.enum.ctor",
 726                                   env.enclClass.sym);
 727                     }
 728                 }
 729 
 730                 // Attribute method body.
 731                 attribStat(tree.body, localEnv);
 732             }
 733             localEnv.info.scope.leave();
 734             result = tree.type = m.type;
 735             chk.validateAnnotations(tree.mods.annotations, m);
 736         }
 737         finally {
 738             chk.setLint(prevLint);
 739         }
 740     }
 741 
 742     public void visitVarDef(JCVariableDecl tree) {
 743         // Local variables have not been entered yet, so we need to do it now:
 744         if (env.info.scope.owner.kind == MTH) {
 745             if (tree.sym != null) {
 746                 // parameters have already been entered
 747                 env.info.scope.enter(tree.sym);
 748             } else {
 749                 memberEnter.memberEnter(tree, env);
 750                 annotate.flush();
 751             }
 752         }
 753 
 754         VarSymbol v = tree.sym;
 755         Lint lint = env.info.lint.augment(v.attributes_field, v.flags());
 756         Lint prevLint = chk.setLint(lint);
 757 
 758         // Check that the variable's declared type is well-formed.
 759         chk.validate(tree.vartype, env);
 760 
 761         try {
 762             chk.checkDeprecatedAnnotation(tree.pos(), v);
 763 
 764             if (tree.init != null) {
 765                 if ((v.flags_field & FINAL) != 0 && tree.init.getTag() != JCTree.NEWCLASS) {
 766                     // In this case, `v' is final.  Ensure that it's initializer is
 767                     // evaluated.
 768                     v.getConstValue(); // ensure initializer is evaluated
 769                 } else {
 770                     // Attribute initializer in a new environment
 771                     // with the declared variable as owner.
 772                     // Check that initializer conforms to variable's declared type.
 773                     Env<AttrContext> initEnv = memberEnter.initEnv(tree, env);
 774                     initEnv.info.lint = lint;
 775                     // In order to catch self-references, we set the variable's
 776                     // declaration position to maximal possible value, effectively
 777                     // marking the variable as undefined.
 778                     initEnv.info.enclVar = v;
 779                     attribExpr(tree.init, initEnv, v.type);
 780                 }
 781             }
 782             result = tree.type = v.type;
 783             chk.validateAnnotations(tree.mods.annotations, v);
 784         }
 785         finally {
 786             chk.setLint(prevLint);
 787         }
 788     }
 789 
 790     public void visitSkip(JCSkip tree) {
 791         result = null;
 792     }
 793 
 794     public void visitBlock(JCBlock tree) {
 795         if (env.info.scope.owner.kind == TYP) {
 796             // Block is a static or instance initializer;
 797             // let the owner of the environment be a freshly
 798             // created BLOCK-method.
 799             Env<AttrContext> localEnv =
 800                 env.dup(tree, env.info.dup(env.info.scope.dupUnshared()));
 801             localEnv.info.scope.owner =
 802                 new MethodSymbol(tree.flags | BLOCK, names.empty, null,
 803                                  env.info.scope.owner);
 804             if ((tree.flags & STATIC) != 0) localEnv.info.staticLevel++;
 805             attribStats(tree.stats, localEnv);
 806         } else {
 807             // Create a new local environment with a local scope.
 808             Env<AttrContext> localEnv =
 809                 env.dup(tree, env.info.dup(env.info.scope.dup()));
 810             attribStats(tree.stats, localEnv);
 811             localEnv.info.scope.leave();
 812         }
 813         result = null;
 814     }
 815 
 816     public void visitDoLoop(JCDoWhileLoop tree) {
 817         attribStat(tree.body, env.dup(tree));
 818         attribExpr(tree.cond, env, syms.booleanType);
 819         result = null;
 820     }
 821 
 822     public void visitWhileLoop(JCWhileLoop tree) {
 823         attribExpr(tree.cond, env, syms.booleanType);
 824         attribStat(tree.body, env.dup(tree));
 825         result = null;
 826     }
 827 
 828     public void visitForLoop(JCForLoop tree) {
 829         Env<AttrContext> loopEnv =
 830             env.dup(env.tree, env.info.dup(env.info.scope.dup()));
 831         attribStats(tree.init, loopEnv);
 832         if (tree.cond != null) attribExpr(tree.cond, loopEnv, syms.booleanType);
 833         loopEnv.tree = tree; // before, we were not in loop!
 834         attribStats(tree.step, loopEnv);
 835         attribStat(tree.body, loopEnv);
 836         loopEnv.info.scope.leave();
 837         result = null;
 838     }
 839 
 840     public void visitForeachLoop(JCEnhancedForLoop tree) {
 841         Env<AttrContext> loopEnv =
 842             env.dup(env.tree, env.info.dup(env.info.scope.dup()));
 843         attribStat(tree.var, loopEnv);
 844         Type exprType = types.upperBound(attribExpr(tree.expr, loopEnv));
 845         chk.checkNonVoid(tree.pos(), exprType);
 846         Type elemtype = types.elemtype(exprType); // perhaps expr is an array?
 847         if (elemtype == null) {
 848             // or perhaps expr implements Iterable<T>?
 849             Type base = types.asSuper(exprType, syms.iterableType.tsym);
 850             if (base == null) {
 851                 log.error(tree.expr.pos(), "foreach.not.applicable.to.type");
 852                 elemtype = types.createErrorType(exprType);
 853             } else {
 854                 List<Type> iterableParams = base.allparams();
 855                 elemtype = iterableParams.isEmpty()
 856                     ? syms.objectType
 857                     : types.upperBound(iterableParams.head);
 858             }
 859         }
 860         chk.checkType(tree.expr.pos(), elemtype, tree.var.sym.type);
 861         loopEnv.tree = tree; // before, we were not in loop!
 862         attribStat(tree.body, loopEnv);
 863         loopEnv.info.scope.leave();
 864         result = null;
 865     }
 866 
 867     public void visitLabelled(JCLabeledStatement tree) {
 868         // Check that label is not used in an enclosing statement
 869         Env<AttrContext> env1 = env;
 870         while (env1 != null && env1.tree.getTag() != JCTree.CLASSDEF) {
 871             if (env1.tree.getTag() == JCTree.LABELLED &&
 872                 ((JCLabeledStatement) env1.tree).label == tree.label) {
 873                 log.error(tree.pos(), "label.already.in.use",
 874                           tree.label);
 875                 break;
 876             }
 877             env1 = env1.next;
 878         }
 879 
 880         attribStat(tree.body, env.dup(tree));
 881         result = null;
 882     }
 883 
 884     public void visitSwitch(JCSwitch tree) {
 885         Type seltype = attribExpr(tree.selector, env);
 886 
 887         Env<AttrContext> switchEnv =
 888             env.dup(tree, env.info.dup(env.info.scope.dup()));
 889 
 890         boolean enumSwitch =
 891             allowEnums &&
 892             (seltype.tsym.flags() & Flags.ENUM) != 0;
 893         boolean stringSwitch = false;
 894         if (types.isSameType(seltype, syms.stringType)) {
 895             if (allowStringsInSwitch) {
 896                 stringSwitch = true;
 897             } else {
 898                 log.error(tree.selector.pos(), "string.switch.not.supported.in.source", sourceName);
 899             }
 900         }
 901         if (!enumSwitch && !stringSwitch)
 902             seltype = chk.checkType(tree.selector.pos(), seltype, syms.intType);
 903 
 904         // Attribute all cases and
 905         // check that there are no duplicate case labels or default clauses.
 906         Set<Object> labels = new HashSet<Object>(); // The set of case labels.
 907         boolean hasDefault = false;      // Is there a default label?
 908         for (List<JCCase> l = tree.cases; l.nonEmpty(); l = l.tail) {
 909             JCCase c = l.head;
 910             Env<AttrContext> caseEnv =
 911                 switchEnv.dup(c, env.info.dup(switchEnv.info.scope.dup()));
 912             if (c.pat != null) {
 913                 if (enumSwitch) {
 914                     Symbol sym = enumConstant(c.pat, seltype);
 915                     if (sym == null) {
 916                         log.error(c.pat.pos(), "enum.const.req");
 917                     } else if (!labels.add(sym)) {
 918                         log.error(c.pos(), "duplicate.case.label");
 919                     }
 920                 } else {
 921                     Type pattype = attribExpr(c.pat, switchEnv, seltype);
 922                     if (pattype.tag != ERROR) {
 923                         if (pattype.constValue() == null) {
 924                             log.error(c.pat.pos(),
 925                                       (stringSwitch ? "string.const.req" : "const.expr.req"));
 926                         } else if (labels.contains(pattype.constValue())) {
 927                             log.error(c.pos(), "duplicate.case.label");
 928                         } else {
 929                             labels.add(pattype.constValue());
 930                         }
 931                     }
 932                 }
 933             } else if (hasDefault) {
 934                 log.error(c.pos(), "duplicate.default.label");
 935             } else {
 936                 hasDefault = true;
 937             }
 938             attribStats(c.stats, caseEnv);
 939             caseEnv.info.scope.leave();
 940             addVars(c.stats, switchEnv.info.scope);
 941         }
 942 
 943         switchEnv.info.scope.leave();
 944         result = null;
 945     }
 946     // where
 947         /** Add any variables defined in stats to the switch scope. */
 948         private static void addVars(List<JCStatement> stats, Scope switchScope) {
 949             for (;stats.nonEmpty(); stats = stats.tail) {
 950                 JCTree stat = stats.head;
 951                 if (stat.getTag() == JCTree.VARDEF)
 952                     switchScope.enter(((JCVariableDecl) stat).sym);
 953             }
 954         }
 955     // where
 956     /** Return the selected enumeration constant symbol, or null. */
 957     private Symbol enumConstant(JCTree tree, Type enumType) {
 958         if (tree.getTag() != JCTree.IDENT) {
 959             log.error(tree.pos(), "enum.label.must.be.unqualified.enum");
 960             return syms.errSymbol;
 961         }
 962         JCIdent ident = (JCIdent)tree;
 963         Name name = ident.name;
 964         for (Scope.Entry e = enumType.tsym.members().lookup(name);
 965              e.scope != null; e = e.next()) {
 966             if (e.sym.kind == VAR) {
 967                 Symbol s = ident.sym = e.sym;
 968                 ((VarSymbol)s).getConstValue(); // ensure initializer is evaluated
 969                 ident.type = s.type;
 970                 return ((s.flags_field & Flags.ENUM) == 0)
 971                     ? null : s;
 972             }
 973         }
 974         return null;
 975     }
 976 
 977     public void visitSynchronized(JCSynchronized tree) {
 978         chk.checkRefType(tree.pos(), attribExpr(tree.lock, env));
 979         attribStat(tree.body, env);
 980         result = null;
 981     }
 982 
 983     public void visitTry(JCTry tree) {
 984         // Create a new local environment with a local scope.
 985         Env<AttrContext> localEnv = env.dup(tree, env.info.dup(env.info.scope.dup()));
 986         // Attribute resource declarations
 987         for (JCTree resource : tree.resources) {
 988             if (resource instanceof JCVariableDecl) {
 989                 JCVariableDecl var = (JCVariableDecl) resource;
 990                 Type resourceType = types.upperBound(attribStat(var, localEnv));
 991                 if (var.type.tsym.kind == Kinds.VAR) {
 992                     var.sym.setData(ElementKind.RESOURCE_VARIABLE);
 993                 }
 994                 if (types.asSuper(resourceType, syms.autoCloseableType.tsym) == null) {
 995                     log.error(var.pos(), "arm.not.applicable.to.type");
 996                     resourceType = types.createErrorType(resourceType);
 997                 }
 998                 chk.checkType(var.vartype.pos(), resourceType, var.sym.type);
 999             } else if (resource instanceof JCExpression) {
1000                 JCExpression expr = (JCExpression)resource;
1001                 Type resourceType = types.upperBound(attribExpr(expr, localEnv));
1002                 if (types.asSuper(resourceType, syms.autoCloseableType.tsym) == null) {
1003                     log.error(expr.pos(), "arm.not.applicable.to.type");
1004                     resourceType = types.createErrorType(resourceType);
1005                 }
1006             } else {
1007                 // Parser error.
1008                 throw new AssertionError(tree);
1009             }
1010         }
1011         // Attribute body
1012         attribStat(tree.body, localEnv.dup(tree, localEnv.info.dup()));
1013 
1014         // Attribute catch clauses
1015         for (List<JCCatch> l = tree.catchers; l.nonEmpty(); l = l.tail) {
1016             JCCatch c = l.head;
1017             Env<AttrContext> catchEnv =
1018                 localEnv.dup(c, localEnv.info.dup(localEnv.info.scope.dup()));
1019             Type ctype = attribStat(c.param, catchEnv);
1020             if (TreeInfo.isMultiCatch(c)) {
1021                 //check that multi-catch parameter is marked as final
1022                 if ((c.param.sym.flags() & FINAL) == 0) {
1023                     log.error(c.param.pos(), "multicatch.param.must.be.final", c.param.sym);
1024                 }
1025                 c.param.sym.flags_field = c.param.sym.flags() | DISJOINT;
1026             }
1027             if (c.param.type.tsym.kind == Kinds.VAR) {
1028                 c.param.sym.setData(ElementKind.EXCEPTION_PARAMETER);
1029             }
1030             chk.checkType(c.param.vartype.pos(),
1031                           chk.checkClassType(c.param.vartype.pos(), ctype),
1032                           syms.throwableType);
1033             attribStat(c.body, catchEnv);
1034             catchEnv.info.scope.leave();
1035         }
1036 
1037         // Attribute finalizer
1038         if (tree.finalizer != null) attribStat(tree.finalizer, localEnv);
1039 
1040         localEnv.info.scope.leave();
1041         result = null;
1042     }
1043 
1044     public void visitConditional(JCConditional tree) {
1045         attribExpr(tree.cond, env, syms.booleanType);
1046         attribExpr(tree.truepart, env);
1047         attribExpr(tree.falsepart, env);
1048         result = check(tree,
1049                        capture(condType(tree.pos(), tree.cond.type,
1050                                         tree.truepart.type, tree.falsepart.type)),
1051                        VAL, pkind, pt);
1052     }
1053     //where
1054         /** Compute the type of a conditional expression, after
1055          *  checking that it exists. See Spec 15.25.
1056          *
1057          *  @param pos      The source position to be used for
1058          *                  error diagnostics.
1059          *  @param condtype The type of the expression's condition.
1060          *  @param thentype The type of the expression's then-part.
1061          *  @param elsetype The type of the expression's else-part.
1062          */
1063         private Type condType(DiagnosticPosition pos,
1064                               Type condtype,
1065                               Type thentype,
1066                               Type elsetype) {
1067             Type ctype = condType1(pos, condtype, thentype, elsetype);
1068 
1069             // If condition and both arms are numeric constants,
1070             // evaluate at compile-time.
1071             return ((condtype.constValue() != null) &&
1072                     (thentype.constValue() != null) &&
1073                     (elsetype.constValue() != null))
1074                 ? cfolder.coerce(condtype.isTrue()?thentype:elsetype, ctype)
1075                 : ctype;
1076         }
1077         /** Compute the type of a conditional expression, after
1078          *  checking that it exists.  Does not take into
1079          *  account the special case where condition and both arms
1080          *  are constants.
1081          *
1082          *  @param pos      The source position to be used for error
1083          *                  diagnostics.
1084          *  @param condtype The type of the expression's condition.
1085          *  @param thentype The type of the expression's then-part.
1086          *  @param elsetype The type of the expression's else-part.
1087          */
1088         private Type condType1(DiagnosticPosition pos, Type condtype,
1089                                Type thentype, Type elsetype) {
1090             // If same type, that is the result
1091             if (types.isSameType(thentype, elsetype))
1092                 return thentype.baseType();
1093 
1094             Type thenUnboxed = (!allowBoxing || thentype.isPrimitive())
1095                 ? thentype : types.unboxedType(thentype);
1096             Type elseUnboxed = (!allowBoxing || elsetype.isPrimitive())
1097                 ? elsetype : types.unboxedType(elsetype);
1098 
1099             // Otherwise, if both arms can be converted to a numeric
1100             // type, return the least numeric type that fits both arms
1101             // (i.e. return larger of the two, or return int if one
1102             // arm is short, the other is char).
1103             if (thenUnboxed.isPrimitive() && elseUnboxed.isPrimitive()) {
1104                 // If one arm has an integer subrange type (i.e., byte,
1105                 // short, or char), and the other is an integer constant
1106                 // that fits into the subrange, return the subrange type.
1107                 if (thenUnboxed.tag < INT && elseUnboxed.tag == INT &&
1108                     types.isAssignable(elseUnboxed, thenUnboxed))
1109                     return thenUnboxed.baseType();
1110                 if (elseUnboxed.tag < INT && thenUnboxed.tag == INT &&
1111                     types.isAssignable(thenUnboxed, elseUnboxed))
1112                     return elseUnboxed.baseType();
1113 
1114                 for (int i = BYTE; i < VOID; i++) {
1115                     Type candidate = syms.typeOfTag[i];
1116                     if (types.isSubtype(thenUnboxed, candidate) &&
1117                         types.isSubtype(elseUnboxed, candidate))
1118                         return candidate;
1119                 }
1120             }
1121 
1122             // Those were all the cases that could result in a primitive
1123             if (allowBoxing) {
1124                 if (thentype.isPrimitive())
1125                     thentype = types.boxedClass(thentype).type;
1126                 if (elsetype.isPrimitive())
1127                     elsetype = types.boxedClass(elsetype).type;
1128             }
1129 
1130             if (types.isSubtype(thentype, elsetype))
1131                 return elsetype.baseType();
1132             if (types.isSubtype(elsetype, thentype))
1133                 return thentype.baseType();
1134 
1135             if (!allowBoxing || thentype.tag == VOID || elsetype.tag == VOID) {
1136                 log.error(pos, "neither.conditional.subtype",
1137                           thentype, elsetype);
1138                 return thentype.baseType();
1139             }
1140 
1141             // both are known to be reference types.  The result is
1142             // lub(thentype,elsetype). This cannot fail, as it will
1143             // always be possible to infer "Object" if nothing better.
1144             return types.lub(thentype.baseType(), elsetype.baseType());
1145         }
1146 
1147     public void visitIf(JCIf tree) {
1148         attribExpr(tree.cond, env, syms.booleanType);
1149         attribStat(tree.thenpart, env);
1150         if (tree.elsepart != null)
1151             attribStat(tree.elsepart, env);
1152         chk.checkEmptyIf(tree);
1153         result = null;
1154     }
1155 
1156     public void visitExec(JCExpressionStatement tree) {
1157         attribExpr(tree.expr, env);
1158         result = null;
1159     }
1160 
1161     public void visitBreak(JCBreak tree) {
1162         tree.target = findJumpTarget(tree.pos(), tree.getTag(), tree.label, env);
1163         result = null;
1164     }
1165 
1166     public void visitContinue(JCContinue tree) {
1167         tree.target = findJumpTarget(tree.pos(), tree.getTag(), tree.label, env);
1168         result = null;
1169     }
1170     //where
1171         /** Return the target of a break or continue statement, if it exists,
1172          *  report an error if not.
1173          *  Note: The target of a labelled break or continue is the
1174          *  (non-labelled) statement tree referred to by the label,
1175          *  not the tree representing the labelled statement itself.
1176          *
1177          *  @param pos     The position to be used for error diagnostics
1178          *  @param tag     The tag of the jump statement. This is either
1179          *                 Tree.BREAK or Tree.CONTINUE.
1180          *  @param label   The label of the jump statement, or null if no
1181          *                 label is given.
1182          *  @param env     The environment current at the jump statement.
1183          */
1184         private JCTree findJumpTarget(DiagnosticPosition pos,
1185                                     int tag,
1186                                     Name label,
1187                                     Env<AttrContext> env) {
1188             // Search environments outwards from the point of jump.
1189             Env<AttrContext> env1 = env;
1190             LOOP:
1191             while (env1 != null) {
1192                 switch (env1.tree.getTag()) {
1193                 case JCTree.LABELLED:
1194                     JCLabeledStatement labelled = (JCLabeledStatement)env1.tree;
1195                     if (label == labelled.label) {
1196                         // If jump is a continue, check that target is a loop.
1197                         if (tag == JCTree.CONTINUE) {
1198                             if (labelled.body.getTag() != JCTree.DOLOOP &&
1199                                 labelled.body.getTag() != JCTree.WHILELOOP &&
1200                                 labelled.body.getTag() != JCTree.FORLOOP &&
1201                                 labelled.body.getTag() != JCTree.FOREACHLOOP)
1202                                 log.error(pos, "not.loop.label", label);
1203                             // Found labelled statement target, now go inwards
1204                             // to next non-labelled tree.
1205                             return TreeInfo.referencedStatement(labelled);
1206                         } else {
1207                             return labelled;
1208                         }
1209                     }
1210                     break;
1211                 case JCTree.DOLOOP:
1212                 case JCTree.WHILELOOP:
1213                 case JCTree.FORLOOP:
1214                 case JCTree.FOREACHLOOP:
1215                     if (label == null) return env1.tree;
1216                     break;
1217                 case JCTree.SWITCH:
1218                     if (label == null && tag == JCTree.BREAK) return env1.tree;
1219                     break;
1220                 case JCTree.METHODDEF:
1221                 case JCTree.CLASSDEF:
1222                     break LOOP;
1223                 default:
1224                 }
1225                 env1 = env1.next;
1226             }
1227             if (label != null)
1228                 log.error(pos, "undef.label", label);
1229             else if (tag == JCTree.CONTINUE)
1230                 log.error(pos, "cont.outside.loop");
1231             else
1232                 log.error(pos, "break.outside.switch.loop");
1233             return null;
1234         }
1235 
1236     public void visitReturn(JCReturn tree) {
1237         // Check that there is an enclosing method which is
1238         // nested within than the enclosing class.
1239         if (env.enclMethod == null ||
1240             env.enclMethod.sym.owner != env.enclClass.sym) {
1241             log.error(tree.pos(), "ret.outside.meth");
1242 
1243         } else {
1244             // Attribute return expression, if it exists, and check that
1245             // it conforms to result type of enclosing method.
1246             Symbol m = env.enclMethod.sym;
1247             if (m.type.getReturnType().tag == VOID) {
1248                 if (tree.expr != null)
1249                     log.error(tree.expr.pos(),
1250                               "cant.ret.val.from.meth.decl.void");
1251             } else if (tree.expr == null) {
1252                 log.error(tree.pos(), "missing.ret.val");
1253             } else {
1254                 attribExpr(tree.expr, env, m.type.getReturnType());
1255             }
1256         }
1257         result = null;
1258     }
1259 
1260     public void visitThrow(JCThrow tree) {
1261         attribExpr(tree.expr, env, syms.throwableType);
1262         result = null;
1263     }
1264 
1265     public void visitAssert(JCAssert tree) {
1266         attribExpr(tree.cond, env, syms.booleanType);
1267         if (tree.detail != null) {
1268             chk.checkNonVoid(tree.detail.pos(), attribExpr(tree.detail, env));
1269         }
1270         result = null;
1271     }
1272 
1273      /** Visitor method for method invocations.
1274      *  NOTE: The method part of an application will have in its type field
1275      *        the return type of the method, not the method's type itself!
1276      */
1277     public void visitApply(JCMethodInvocation tree) {
1278         // The local environment of a method application is
1279         // a new environment nested in the current one.
1280         Env<AttrContext> localEnv = env.dup(tree, env.info.dup());
1281 
1282         // The types of the actual method arguments.
1283         List<Type> argtypes;
1284 
1285         // The types of the actual method type arguments.
1286         List<Type> typeargtypes = null;
1287         boolean typeargtypesNonRefOK = false;
1288 
1289         Name methName = TreeInfo.name(tree.meth);
1290 
1291         boolean isConstructorCall =
1292             methName == names._this || methName == names._super;
1293 
1294         if (isConstructorCall) {
1295             // We are seeing a ...this(...) or ...super(...) call.
1296             // Check that this is the first statement in a constructor.
1297             if (checkFirstConstructorStat(tree, env)) {
1298 
1299                 // Record the fact
1300                 // that this is a constructor call (using isSelfCall).
1301                 localEnv.info.isSelfCall = true;
1302 
1303                 // Attribute arguments, yielding list of argument types.
1304                 argtypes = attribArgs(tree.args, localEnv);
1305                 typeargtypes = attribTypes(tree.typeargs, localEnv);
1306 
1307                 // Variable `site' points to the class in which the called
1308                 // constructor is defined.
1309                 Type site = env.enclClass.sym.type;
1310                 if (methName == names._super) {
1311                     if (site == syms.objectType) {
1312                         log.error(tree.meth.pos(), "no.superclass", site);
1313                         site = types.createErrorType(syms.objectType);
1314                     } else {
1315                         site = types.supertype(site);
1316                     }
1317                 }
1318 
1319                 if (site.tag == CLASS) {
1320                     Type encl = site.getEnclosingType();
1321                     while (encl != null && encl.tag == TYPEVAR)
1322                         encl = encl.getUpperBound();
1323                     if (encl.tag == CLASS) {
1324                         // we are calling a nested class
1325 
1326                         if (tree.meth.getTag() == JCTree.SELECT) {
1327                             JCTree qualifier = ((JCFieldAccess) tree.meth).selected;
1328 
1329                             // We are seeing a prefixed call, of the form
1330                             //     <expr>.super(...).
1331                             // Check that the prefix expression conforms
1332                             // to the outer instance type of the class.
1333                             chk.checkRefType(qualifier.pos(),
1334                                              attribExpr(qualifier, localEnv,
1335                                                         encl));
1336                         } else if (methName == names._super) {
1337                             // qualifier omitted; check for existence
1338                             // of an appropriate implicit qualifier.
1339                             rs.resolveImplicitThis(tree.meth.pos(),
1340                                                    localEnv, site);
1341                         }
1342                     } else if (tree.meth.getTag() == JCTree.SELECT) {
1343                         log.error(tree.meth.pos(), "illegal.qual.not.icls",
1344                                   site.tsym);
1345                     }
1346 
1347                     // if we're calling a java.lang.Enum constructor,
1348                     // prefix the implicit String and int parameters
1349                     if (site.tsym == syms.enumSym && allowEnums)
1350                         argtypes = argtypes.prepend(syms.intType).prepend(syms.stringType);
1351 
1352                     // Resolve the called constructor under the assumption
1353                     // that we are referring to a superclass instance of the
1354                     // current instance (JLS ???).
1355                     boolean selectSuperPrev = localEnv.info.selectSuper;
1356                     localEnv.info.selectSuper = true;
1357                     localEnv.info.varArgs = false;
1358                     Symbol sym = rs.resolveConstructor(
1359                         tree.meth.pos(), localEnv, site, argtypes, typeargtypes);
1360                     localEnv.info.selectSuper = selectSuperPrev;
1361 
1362                     // Set method symbol to resolved constructor...
1363                     TreeInfo.setSymbol(tree.meth, sym);
1364 
1365                     // ...and check that it is legal in the current context.
1366                     // (this will also set the tree's type)
1367                     Type mpt = newMethTemplate(argtypes, typeargtypes);
1368                     checkId(tree.meth, site, sym, localEnv, MTH,
1369                             mpt, tree.varargsElement != null);
1370                 }
1371                 // Otherwise, `site' is an error type and we do nothing
1372             }
1373             result = tree.type = syms.voidType;
1374         } else {
1375             // Otherwise, we are seeing a regular method call.
1376             // Attribute the arguments, yielding list of argument types, ...
1377             argtypes = attribArgs(tree.args, localEnv);
1378             typeargtypes = attribAnyTypes(tree.typeargs, localEnv);
1379 
1380             // ... and attribute the method using as a prototype a methodtype
1381             // whose formal argument types is exactly the list of actual
1382             // arguments (this will also set the method symbol).
1383             Type mpt = newMethTemplate(argtypes, typeargtypes);
1384             localEnv.info.varArgs = false;
1385             Type mtype = attribExpr(tree.meth, localEnv, mpt);
1386             if (localEnv.info.varArgs)
1387                 assert mtype.isErroneous() || tree.varargsElement != null;
1388 
1389             // Compute the result type.
1390             Type restype = mtype.getReturnType();
1391             assert restype.tag != WILDCARD : mtype;
1392 
1393             // as a special case, array.clone() has a result that is
1394             // the same as static type of the array being cloned
1395             if (tree.meth.getTag() == JCTree.SELECT &&
1396                 allowCovariantReturns &&
1397                 methName == names.clone &&
1398                 types.isArray(((JCFieldAccess) tree.meth).selected.type))
1399                 restype = ((JCFieldAccess) tree.meth).selected.type;
1400 
1401             // as a special case, x.getClass() has type Class<? extends |X|>
1402             if (allowGenerics &&
1403                 methName == names.getClass && tree.args.isEmpty()) {
1404                 Type qualifier = (tree.meth.getTag() == JCTree.SELECT)
1405                     ? ((JCFieldAccess) tree.meth).selected.type
1406                     : env.enclClass.sym.type;
1407                 restype = new
1408                     ClassType(restype.getEnclosingType(),
1409                               List.<Type>of(new WildcardType(types.erasure(qualifier),
1410                                                                BoundKind.EXTENDS,
1411                                                                syms.boundClass)),
1412                               restype.tsym);
1413             }
1414 
1415             // as a special case, MethodHandle.<T>invoke(abc) and InvokeDynamic.<T>foo(abc)
1416             // has type <T>, and T can be a primitive type.
1417             if (tree.meth.getTag() == JCTree.SELECT && !typeargtypes.isEmpty()) {
1418               Type selt = ((JCFieldAccess) tree.meth).selected.type;
1419               if ((selt == syms.methodHandleType && methName == names.invoke) || selt == syms.invokeDynamicType) {
1420                   assert types.isSameType(restype, typeargtypes.head) : mtype;
1421                   typeargtypesNonRefOK = true;
1422               }
1423             }
1424 
1425             if (!typeargtypesNonRefOK) {
1426                 chk.checkRefTypes(tree.typeargs, typeargtypes);
1427             }
1428 
1429             // Check that value of resulting type is admissible in the
1430             // current context.  Also, capture the return type
1431             result = check(tree, capture(restype), VAL, pkind, pt);
1432         }
1433         chk.validate(tree.typeargs, localEnv);
1434     }
1435     //where
1436         /** Check that given application node appears as first statement
1437          *  in a constructor call.
1438          *  @param tree   The application node
1439          *  @param env    The environment current at the application.
1440          */
1441         boolean checkFirstConstructorStat(JCMethodInvocation tree, Env<AttrContext> env) {
1442             JCMethodDecl enclMethod = env.enclMethod;
1443             if (enclMethod != null && enclMethod.name == names.init) {
1444                 JCBlock body = enclMethod.body;
1445                 if (body.stats.head.getTag() == JCTree.EXEC &&
1446                     ((JCExpressionStatement) body.stats.head).expr == tree)
1447                     return true;
1448             }
1449             log.error(tree.pos(),"call.must.be.first.stmt.in.ctor",
1450                       TreeInfo.name(tree.meth));
1451             return false;
1452         }
1453 
1454         /** Obtain a method type with given argument types.
1455          */
1456         Type newMethTemplate(List<Type> argtypes, List<Type> typeargtypes) {
1457             MethodType mt = new MethodType(argtypes, null, null, syms.methodClass);
1458             return (typeargtypes == null) ? mt : (Type)new ForAll(typeargtypes, mt);
1459         }
1460 
1461     public void visitNewClass(JCNewClass tree) {
1462         Type owntype = types.createErrorType(tree.type);
1463 
1464         // The local environment of a class creation is
1465         // a new environment nested in the current one.
1466         Env<AttrContext> localEnv = env.dup(tree, env.info.dup());
1467 
1468         // The anonymous inner class definition of the new expression,
1469         // if one is defined by it.
1470         JCClassDecl cdef = tree.def;
1471 
1472         // If enclosing class is given, attribute it, and
1473         // complete class name to be fully qualified
1474         JCExpression clazz = tree.clazz; // Class field following new
1475         JCExpression clazzid =          // Identifier in class field
1476             (clazz.getTag() == JCTree.TYPEAPPLY)
1477             ? ((JCTypeApply) clazz).clazz
1478             : clazz;
1479 
1480         JCExpression clazzid1 = clazzid; // The same in fully qualified form
1481 
1482         if (tree.encl != null) {
1483             // We are seeing a qualified new, of the form
1484             //    <expr>.new C <...> (...) ...
1485             // In this case, we let clazz stand for the name of the
1486             // allocated class C prefixed with the type of the qualifier
1487             // expression, so that we can
1488             // resolve it with standard techniques later. I.e., if
1489             // <expr> has type T, then <expr>.new C <...> (...)
1490             // yields a clazz T.C.
1491             Type encltype = chk.checkRefType(tree.encl.pos(),
1492                                              attribExpr(tree.encl, env));
1493             clazzid1 = make.at(clazz.pos).Select(make.Type(encltype),
1494                                                  ((JCIdent) clazzid).name);
1495             if (clazz.getTag() == JCTree.TYPEAPPLY)
1496                 clazz = make.at(tree.pos).
1497                     TypeApply(clazzid1,
1498                               ((JCTypeApply) clazz).arguments);
1499             else
1500                 clazz = clazzid1;
1501         }
1502 
1503         // Attribute clazz expression and store
1504         // symbol + type back into the attributed tree.
1505         Type clazztype = attribType(clazz, env);
1506         Pair<Scope,Scope> mapping = getSyntheticScopeMapping(clazztype);
1507         if (!TreeInfo.isDiamond(tree)) {
1508             clazztype = chk.checkClassType(
1509                 tree.clazz.pos(), clazztype, true);
1510         }
1511         chk.validate(clazz, localEnv);
1512         if (tree.encl != null) {
1513             // We have to work in this case to store
1514             // symbol + type back into the attributed tree.
1515             tree.clazz.type = clazztype;
1516             TreeInfo.setSymbol(clazzid, TreeInfo.symbol(clazzid1));
1517             clazzid.type = ((JCIdent) clazzid).sym.type;
1518             if (!clazztype.isErroneous()) {
1519                 if (cdef != null && clazztype.tsym.isInterface()) {
1520                     log.error(tree.encl.pos(), "anon.class.impl.intf.no.qual.for.new");
1521                 } else if (clazztype.tsym.isStatic()) {
1522                     log.error(tree.encl.pos(), "qualified.new.of.static.class", clazztype.tsym);
1523                 }
1524             }
1525         } else if (!clazztype.tsym.isInterface() &&
1526                    clazztype.getEnclosingType().tag == CLASS) {
1527             // Check for the existence of an apropos outer instance
1528             rs.resolveImplicitThis(tree.pos(), env, clazztype);
1529         }
1530 
1531         // Attribute constructor arguments.
1532         List<Type> argtypes = attribArgs(tree.args, localEnv);
1533         List<Type> typeargtypes = attribTypes(tree.typeargs, localEnv);
1534 
1535         if (TreeInfo.isDiamond(tree)) {
1536             clazztype = attribDiamond(localEnv, tree, clazztype, mapping, argtypes, typeargtypes, true);
1537             clazz.type = clazztype;
1538         }
1539 
1540         // If we have made no mistakes in the class type...
1541         if (clazztype.tag == CLASS) {
1542             // Enums may not be instantiated except implicitly
1543             if (allowEnums &&
1544                 (clazztype.tsym.flags_field&Flags.ENUM) != 0 &&
1545                 (env.tree.getTag() != JCTree.VARDEF ||
1546                  (((JCVariableDecl) env.tree).mods.flags&Flags.ENUM) == 0 ||
1547                  ((JCVariableDecl) env.tree).init != tree))
1548                 log.error(tree.pos(), "enum.cant.be.instantiated");
1549             // Check that class is not abstract
1550             if (cdef == null &&
1551                 (clazztype.tsym.flags() & (ABSTRACT | INTERFACE)) != 0) {
1552                 log.error(tree.pos(), "abstract.cant.be.instantiated",
1553                           clazztype.tsym);
1554             } else if (cdef != null && clazztype.tsym.isInterface()) {
1555                 // Check that no constructor arguments are given to
1556                 // anonymous classes implementing an interface
1557                 if (!argtypes.isEmpty())
1558                     log.error(tree.args.head.pos(), "anon.class.impl.intf.no.args");
1559 
1560                 if (!typeargtypes.isEmpty())
1561                     log.error(tree.typeargs.head.pos(), "anon.class.impl.intf.no.typeargs");
1562 
1563                 // Error recovery: pretend no arguments were supplied.
1564                 argtypes = List.nil();
1565                 typeargtypes = List.nil();
1566             }
1567 
1568             // Resolve the called constructor under the assumption
1569             // that we are referring to a superclass instance of the
1570             // current instance (JLS ???).
1571             else {
1572                 localEnv.info.selectSuper = cdef != null;
1573                 localEnv.info.varArgs = false;
1574                 tree.constructor = rs.resolveConstructor(
1575                     tree.pos(), localEnv, clazztype, argtypes, typeargtypes);
1576                 tree.constructorType = checkMethod(clazztype,
1577                                                 tree.constructor,
1578                                                 localEnv,
1579                                                 tree.args,
1580                                                 argtypes,
1581                                                 typeargtypes,
1582                                                 localEnv.info.varArgs);
1583                 if (localEnv.info.varArgs)
1584                     assert tree.constructorType.isErroneous() || tree.varargsElement != null;
1585             }
1586 
1587             if (cdef != null) {
1588                 // We are seeing an anonymous class instance creation.
1589                 // In this case, the class instance creation
1590                 // expression
1591                 //
1592                 //    E.new <typeargs1>C<typargs2>(args) { ... }
1593                 //
1594                 // is represented internally as
1595                 //
1596                 //    E . new <typeargs1>C<typargs2>(args) ( class <empty-name> { ... } )  .
1597                 //
1598                 // This expression is then *transformed* as follows:
1599                 //
1600                 // (1) add a STATIC flag to the class definition
1601                 //     if the current environment is static
1602                 // (2) add an extends or implements clause
1603                 // (3) add a constructor.
1604                 //
1605                 // For instance, if C is a class, and ET is the type of E,
1606                 // the expression
1607                 //
1608                 //    E.new <typeargs1>C<typargs2>(args) { ... }
1609                 //
1610                 // is translated to (where X is a fresh name and typarams is the
1611                 // parameter list of the super constructor):
1612                 //
1613                 //   new <typeargs1>X(<*nullchk*>E, args) where
1614                 //     X extends C<typargs2> {
1615                 //       <typarams> X(ET e, args) {
1616                 //         e.<typeargs1>super(args)
1617                 //       }
1618                 //       ...
1619                 //     }
1620                 if (Resolve.isStatic(env)) cdef.mods.flags |= STATIC;
1621 
1622                 if (clazztype.tsym.isInterface()) {
1623                     cdef.implementing = List.of(clazz);
1624                 } else {
1625                     cdef.extending = clazz;
1626                 }
1627 
1628                 attribStat(cdef, localEnv);
1629 
1630                 // If an outer instance is given,
1631                 // prefix it to the constructor arguments
1632                 // and delete it from the new expression
1633                 if (tree.encl != null && !clazztype.tsym.isInterface()) {
1634                     tree.args = tree.args.prepend(makeNullCheck(tree.encl));
1635                     argtypes = argtypes.prepend(tree.encl.type);
1636                     tree.encl = null;
1637                 }
1638 
1639                 // Reassign clazztype and recompute constructor.
1640                 clazztype = cdef.sym.type;
1641                 Symbol sym = rs.resolveConstructor(
1642                     tree.pos(), localEnv, clazztype, argtypes,
1643                     typeargtypes, true, tree.varargsElement != null);
1644                 assert sym.kind < AMBIGUOUS || tree.constructor.type.isErroneous();
1645                 tree.constructor = sym;
1646                 if (tree.constructor.kind > ERRONEOUS) {
1647                     tree.constructorType =  syms.errType;
1648                 }
1649                 else {
1650                     tree.constructorType = checkMethod(clazztype,
1651                             tree.constructor,
1652                             localEnv,
1653                             tree.args,
1654                             argtypes,
1655                             typeargtypes,
1656                             localEnv.info.varArgs);
1657                 }
1658             }
1659 
1660             if (tree.constructor != null && tree.constructor.kind == MTH)
1661                 owntype = clazztype;
1662         }
1663         result = check(tree, owntype, VAL, pkind, pt);
1664         chk.validate(tree.typeargs, localEnv);
1665     }
1666 
1667     Type attribDiamond(Env<AttrContext> env,
1668                         JCNewClass tree,
1669                         Type clazztype,
1670                         Pair<Scope, Scope> mapping,
1671                         List<Type> argtypes,
1672                         List<Type> typeargtypes,
1673                         boolean reportErrors) {
1674         if (clazztype.isErroneous() || mapping == erroneousMapping) {
1675             //if the type of the instance creation expression is erroneous,
1676             //or something prevented us to form a valid mapping, return the
1677             //(possibly erroneous) type unchanged
1678             return clazztype;
1679         }
1680         else if (clazztype.isInterface()) {
1681             //if the type of the instance creation expression is an interface
1682             //skip the method resolution step (JLS 15.12.2.7). The type to be
1683             //inferred is of the kind <X1,X2, ... Xn>C<X1,X2, ... Xn>
1684             clazztype = new ForAll(clazztype.tsym.type.allparams(),
1685                     clazztype.tsym.type);
1686         } else {
1687             //if the type of the instance creation expression is a class type
1688             //apply method resolution inference (JLS 15.12.2.7). The return type
1689             //of the resolved constructor will be a partially instantiated type
1690             ((ClassSymbol) clazztype.tsym).members_field = mapping.snd;
1691             Symbol constructor;
1692             try {
1693                 constructor = rs.resolveDiamond(tree.pos(),
1694                         env,
1695                         clazztype.tsym.type,
1696                         argtypes,
1697                         typeargtypes, reportErrors);
1698             } finally {
1699                 ((ClassSymbol) clazztype.tsym).members_field = mapping.fst;
1700             }
1701             if (constructor.kind == MTH) {
1702                 ClassType ct = new ClassType(clazztype.getEnclosingType(),
1703                         clazztype.tsym.type.getTypeArguments(),
1704                         clazztype.tsym);
1705                 clazztype = checkMethod(ct,
1706                         constructor,
1707                         env,
1708                         tree.args,
1709                         argtypes,
1710                         typeargtypes,
1711                         env.info.varArgs).getReturnType();
1712             } else {
1713                 clazztype = syms.errType;
1714             }
1715         }
1716         if (clazztype.tag == FORALL && !pt.isErroneous()) {
1717             //if the resolved constructor's return type has some uninferred
1718             //type-variables, infer them using the expected type and declared
1719             //bounds (JLS 15.12.2.8).
1720             try {
1721                 clazztype = infer.instantiateExpr((ForAll) clazztype,
1722                         pt.tag == NONE ? syms.objectType : pt,
1723                         Warner.noWarnings);
1724             } catch (Infer.InferenceException ex) {
1725                 //an error occurred while inferring uninstantiated type-variables
1726                 //we need to optionally report an error
1727                 if (reportErrors) {
1728                     log.error(tree.clazz.pos(),
1729                             "cant.apply.diamond.1",
1730                             diags.fragment("diamond", clazztype.tsym),
1731                             ex.diagnostic);
1732                 }
1733             }
1734         }
1735         if (reportErrors) {
1736             clazztype = chk.checkClassType(tree.clazz.pos(),
1737                     clazztype,
1738                     true);
1739             if (clazztype.tag == CLASS) {
1740                 List<Type> invalidDiamondArgs = chk.checkDiamond((ClassType)clazztype);
1741                 if (!clazztype.isErroneous() && invalidDiamondArgs.nonEmpty()) {
1742                     //one or more types inferred in the previous steps is either a
1743                     //captured type or an intersection type --- we need to report an error.
1744                     String subkey = invalidDiamondArgs.size() > 1 ?
1745                         "diamond.invalid.args" :
1746                         "diamond.invalid.arg";
1747                     //The error message is of the kind:
1748                     //
1749                     //cannot infer type arguments for {clazztype}<>;
1750                     //reason: {subkey}
1751                     //
1752                     //where subkey is a fragment of the kind:
1753                     //
1754                     //type argument(s) {invalidDiamondArgs} inferred for {clazztype}<> is not allowed in this context
1755                     log.error(tree.clazz.pos(),
1756                                 "cant.apply.diamond.1",
1757                                 diags.fragment("diamond", clazztype.tsym),
1758                                 diags.fragment(subkey,
1759                                                invalidDiamondArgs,
1760                                                diags.fragment("diamond", clazztype.tsym)));
1761                 }
1762             }
1763         }
1764         return clazztype;
1765     }
1766 
1767     /** Creates a synthetic scope containing fake generic constructors.
1768      *  Assuming that the original scope contains a constructor of the kind:
1769      *  Foo(X x, Y y), where X,Y are class type-variables declared in Foo,
1770      *  the synthetic scope is added a generic constructor of the kind:
1771      *  <X,Y>Foo<X,Y>(X x, Y y). This is crucial in order to enable diamond
1772      *  inference. The inferred return type of the synthetic constructor IS
1773      *  the inferred type for the diamond operator.
1774      */
1775     private Pair<Scope, Scope> getSyntheticScopeMapping(Type ctype) {
1776         if (ctype.tag != CLASS) {
1777             return erroneousMapping;
1778         }
1779         Pair<Scope, Scope> mapping =
1780                 new Pair<Scope, Scope>(ctype.tsym.members(), new Scope(ctype.tsym));
1781         List<Type> typevars = ctype.tsym.type.getTypeArguments();
1782         for (Scope.Entry e = mapping.fst.lookup(names.init);
1783                 e.scope != null;
1784                 e = e.next()) {
1785             MethodSymbol newConstr = (MethodSymbol) e.sym.clone(ctype.tsym);
1786             newConstr.name = names.init;
1787             List<Type> oldTypeargs = List.nil();
1788             if (newConstr.type.tag == FORALL) {
1789                 oldTypeargs = ((ForAll) newConstr.type).tvars;
1790             }
1791             newConstr.type = new MethodType(newConstr.type.getParameterTypes(),
1792                     new ClassType(ctype.getEnclosingType(), ctype.tsym.type.getTypeArguments(), ctype.tsym),
1793                     newConstr.type.getThrownTypes(),
1794                     syms.methodClass);
1795             newConstr.type = new ForAll(typevars.prependList(oldTypeargs), newConstr.type);
1796             mapping.snd.enter(newConstr);
1797         }
1798         return mapping;
1799     }
1800 
1801     private final Pair<Scope,Scope> erroneousMapping = new Pair<Scope,Scope>(null, null);
1802 
1803     /** Make an attributed null check tree.
1804      */
1805     public JCExpression makeNullCheck(JCExpression arg) {
1806         // optimization: X.this is never null; skip null check
1807         Name name = TreeInfo.name(arg);
1808         if (name == names._this || name == names._super) return arg;
1809 
1810         int optag = JCTree.NULLCHK;
1811         JCUnary tree = make.at(arg.pos).Unary(optag, arg);
1812         tree.operator = syms.nullcheck;
1813         tree.type = arg.type;
1814         return tree;
1815     }
1816 
1817     public void visitNewArray(JCNewArray tree) {
1818         Type owntype = types.createErrorType(tree.type);
1819         Type elemtype;
1820         if (tree.elemtype != null) {
1821             elemtype = attribType(tree.elemtype, env);
1822             chk.validate(tree.elemtype, env);
1823             owntype = elemtype;
1824             for (List<JCExpression> l = tree.dims; l.nonEmpty(); l = l.tail) {
1825                 attribExpr(l.head, env, syms.intType);
1826                 owntype = new ArrayType(owntype, syms.arrayClass);
1827             }
1828         } else {
1829             // we are seeing an untyped aggregate { ... }
1830             // this is allowed only if the prototype is an array
1831             if (pt.tag == ARRAY) {
1832                 elemtype = types.elemtype(pt);
1833             } else {
1834                 if (pt.tag != ERROR) {
1835                     log.error(tree.pos(), "illegal.initializer.for.type",
1836                               pt);
1837                 }
1838                 elemtype = types.createErrorType(pt);
1839             }
1840         }
1841         if (tree.elems != null) {
1842             attribExprs(tree.elems, env, elemtype);
1843             owntype = new ArrayType(elemtype, syms.arrayClass);
1844         }
1845         if (!types.isReifiable(elemtype))
1846             log.error(tree.pos(), "generic.array.creation");
1847         result = check(tree, owntype, VAL, pkind, pt);
1848     }
1849 
1850     public void visitParens(JCParens tree) {
1851         Type owntype = attribTree(tree.expr, env, pkind, pt);
1852         result = check(tree, owntype, pkind, pkind, pt);
1853         Symbol sym = TreeInfo.symbol(tree);
1854         if (sym != null && (sym.kind&(TYP|PCK)) != 0)
1855             log.error(tree.pos(), "illegal.start.of.type");
1856     }
1857 
1858     public void visitAssign(JCAssign tree) {
1859         Type owntype = attribTree(tree.lhs, env.dup(tree), VAR, Type.noType);
1860         Type capturedType = capture(owntype);
1861         attribExpr(tree.rhs, env, owntype);
1862         result = check(tree, capturedType, VAL, pkind, pt);
1863     }
1864 
1865     public void visitAssignop(JCAssignOp tree) {
1866         // Attribute arguments.
1867         Type owntype = attribTree(tree.lhs, env, VAR, Type.noType);
1868         Type operand = attribExpr(tree.rhs, env);
1869         // Find operator.
1870         Symbol operator = tree.operator = rs.resolveBinaryOperator(
1871             tree.pos(), tree.getTag() - JCTree.ASGOffset, env,
1872             owntype, operand);
1873 
1874         if (operator.kind == MTH) {
1875             chk.checkOperator(tree.pos(),
1876                               (OperatorSymbol)operator,
1877                               tree.getTag() - JCTree.ASGOffset,
1878                               owntype,
1879                               operand);
1880             chk.checkDivZero(tree.rhs.pos(), operator, operand);
1881             chk.checkCastable(tree.rhs.pos(),
1882                               operator.type.getReturnType(),
1883                               owntype);
1884         }
1885         result = check(tree, owntype, VAL, pkind, pt);
1886     }
1887 
1888     public void visitUnary(JCUnary tree) {
1889         // Attribute arguments.
1890         Type argtype = (JCTree.PREINC <= tree.getTag() && tree.getTag() <= JCTree.POSTDEC)
1891             ? attribTree(tree.arg, env, VAR, Type.noType)
1892             : chk.checkNonVoid(tree.arg.pos(), attribExpr(tree.arg, env));
1893 
1894         // Find operator.
1895         Symbol operator = tree.operator =
1896             rs.resolveUnaryOperator(tree.pos(), tree.getTag(), env, argtype);
1897 
1898         Type owntype = types.createErrorType(tree.type);
1899         if (operator.kind == MTH) {
1900             owntype = (JCTree.PREINC <= tree.getTag() && tree.getTag() <= JCTree.POSTDEC)
1901                 ? tree.arg.type
1902                 : operator.type.getReturnType();
1903             int opc = ((OperatorSymbol)operator).opcode;
1904 
1905             // If the argument is constant, fold it.
1906             if (argtype.constValue() != null) {
1907                 Type ctype = cfolder.fold1(opc, argtype);
1908                 if (ctype != null) {
1909                     owntype = cfolder.coerce(ctype, owntype);
1910 
1911                     // Remove constant types from arguments to
1912                     // conserve space. The parser will fold concatenations
1913                     // of string literals; the code here also
1914                     // gets rid of intermediate results when some of the
1915                     // operands are constant identifiers.
1916                     if (tree.arg.type.tsym == syms.stringType.tsym) {
1917                         tree.arg.type = syms.stringType;
1918                     }
1919                 }
1920             }
1921         }
1922         result = check(tree, owntype, VAL, pkind, pt);
1923     }
1924 
1925     public void visitBinary(JCBinary tree) {
1926         // Attribute arguments.
1927         Type left = chk.checkNonVoid(tree.lhs.pos(), attribExpr(tree.lhs, env));
1928         Type right = chk.checkNonVoid(tree.lhs.pos(), attribExpr(tree.rhs, env));
1929 
1930         // Find operator.
1931         Symbol operator = tree.operator =
1932             rs.resolveBinaryOperator(tree.pos(), tree.getTag(), env, left, right);
1933 
1934         Type owntype = types.createErrorType(tree.type);
1935         if (operator.kind == MTH) {
1936             owntype = operator.type.getReturnType();
1937             int opc = chk.checkOperator(tree.lhs.pos(),
1938                                         (OperatorSymbol)operator,
1939                                         tree.getTag(),
1940                                         left,
1941                                         right);
1942 
1943             // If both arguments are constants, fold them.
1944             if (left.constValue() != null && right.constValue() != null) {
1945                 Type ctype = cfolder.fold2(opc, left, right);
1946                 if (ctype != null) {
1947                     owntype = cfolder.coerce(ctype, owntype);
1948 
1949                     // Remove constant types from arguments to
1950                     // conserve space. The parser will fold concatenations
1951                     // of string literals; the code here also
1952                     // gets rid of intermediate results when some of the
1953                     // operands are constant identifiers.
1954                     if (tree.lhs.type.tsym == syms.stringType.tsym) {
1955                         tree.lhs.type = syms.stringType;
1956                     }
1957                     if (tree.rhs.type.tsym == syms.stringType.tsym) {
1958                         tree.rhs.type = syms.stringType;
1959                     }
1960                 }
1961             }
1962 
1963             // Check that argument types of a reference ==, != are
1964             // castable to each other, (JLS???).
1965             if ((opc == ByteCodes.if_acmpeq || opc == ByteCodes.if_acmpne)) {
1966                 if (!types.isCastable(left, right, new Warner(tree.pos()))) {
1967                     log.error(tree.pos(), "incomparable.types", left, right);
1968                 }
1969             }
1970 
1971             chk.checkDivZero(tree.rhs.pos(), operator, right);
1972         }
1973         result = check(tree, owntype, VAL, pkind, pt);
1974     }
1975 
1976     public void visitTypeCast(JCTypeCast tree) {
1977         Type clazztype = attribType(tree.clazz, env);
1978         chk.validate(tree.clazz, env);
1979         Type exprtype = attribExpr(tree.expr, env, Infer.anyPoly);
1980         Type owntype = chk.checkCastable(tree.expr.pos(), exprtype, clazztype);
1981         if (exprtype.constValue() != null)
1982             owntype = cfolder.coerce(exprtype, owntype);
1983         result = check(tree, capture(owntype), VAL, pkind, pt);
1984     }
1985 
1986     public void visitTypeTest(JCInstanceOf tree) {
1987         Type exprtype = chk.checkNullOrRefType(
1988             tree.expr.pos(), attribExpr(tree.expr, env));
1989         Type clazztype = chk.checkReifiableReferenceType(
1990             tree.clazz.pos(), attribType(tree.clazz, env));
1991         chk.validate(tree.clazz, env);
1992         chk.checkCastable(tree.expr.pos(), exprtype, clazztype);
1993         result = check(tree, syms.booleanType, VAL, pkind, pt);
1994     }
1995 
1996     public void visitIndexed(JCArrayAccess tree) {
1997         Type owntype = types.createErrorType(tree.type);
1998         Type atype = attribExpr(tree.indexed, env);
1999         attribExpr(tree.index, env, syms.intType);
2000         if (types.isArray(atype))
2001             owntype = types.elemtype(atype);
2002         else if (atype.tag != ERROR)
2003             log.error(tree.pos(), "array.req.but.found", atype);
2004         if ((pkind & VAR) == 0) owntype = capture(owntype);
2005         result = check(tree, owntype, VAR, pkind, pt);
2006     }
2007 
2008     public void visitIdent(JCIdent tree) {
2009         Symbol sym;
2010         boolean varArgs = false;
2011 
2012         // Find symbol
2013         if (pt.tag == METHOD || pt.tag == FORALL) {
2014             // If we are looking for a method, the prototype `pt' will be a
2015             // method type with the type of the call's arguments as parameters.
2016             env.info.varArgs = false;
2017             sym = rs.resolveMethod(tree.pos(), env, tree.name, pt.getParameterTypes(), pt.getTypeArguments());
2018             varArgs = env.info.varArgs;
2019         } else if (tree.sym != null && tree.sym.kind != VAR) {
2020             sym = tree.sym;
2021         } else {
2022             sym = rs.resolveIdent(tree.pos(), env, tree.name, pkind);
2023         }
2024         tree.sym = sym;
2025 
2026         // (1) Also find the environment current for the class where
2027         //     sym is defined (`symEnv').
2028         // Only for pre-tiger versions (1.4 and earlier):
2029         // (2) Also determine whether we access symbol out of an anonymous
2030         //     class in a this or super call.  This is illegal for instance
2031         //     members since such classes don't carry a this$n link.
2032         //     (`noOuterThisPath').
2033         Env<AttrContext> symEnv = env;
2034         boolean noOuterThisPath = false;
2035         if (env.enclClass.sym.owner.kind != PCK && // we are in an inner class
2036             (sym.kind & (VAR | MTH | TYP)) != 0 &&
2037             sym.owner.kind == TYP &&
2038             tree.name != names._this && tree.name != names._super) {
2039 
2040             // Find environment in which identifier is defined.
2041             while (symEnv.outer != null &&
2042                    !sym.isMemberOf(symEnv.enclClass.sym, types)) {
2043                 if ((symEnv.enclClass.sym.flags() & NOOUTERTHIS) != 0)
2044                     noOuterThisPath = !allowAnonOuterThis;
2045                 symEnv = symEnv.outer;
2046             }
2047         }
2048 
2049         // If symbol is a variable, ...
2050         if (sym.kind == VAR) {
2051             VarSymbol v = (VarSymbol)sym;
2052 
2053             // ..., evaluate its initializer, if it has one, and check for
2054             // illegal forward reference.
2055             checkInit(tree, env, v, false);
2056 
2057             // If symbol is a local variable accessed from an embedded
2058             // inner class check that it is final.
2059             if (v.owner.kind == MTH &&
2060                 v.owner != env.info.scope.owner &&
2061                 (v.flags_field & FINAL) == 0) {
2062                 log.error(tree.pos(),
2063                           "local.var.accessed.from.icls.needs.final",
2064                           v);
2065             }
2066 
2067             // If we are expecting a variable (as opposed to a value), check
2068             // that the variable is assignable in the current environment.
2069             if (pkind == VAR)
2070                 checkAssignable(tree.pos(), v, null, env);
2071         }
2072 
2073         // In a constructor body,
2074         // if symbol is a field or instance method, check that it is
2075         // not accessed before the supertype constructor is called.
2076         if ((symEnv.info.isSelfCall || noOuterThisPath) &&
2077             (sym.kind & (VAR | MTH)) != 0 &&
2078             sym.owner.kind == TYP &&
2079             (sym.flags() & STATIC) == 0) {
2080             chk.earlyRefError(tree.pos(), sym.kind == VAR ? sym : thisSym(tree.pos(), env));
2081         }
2082         Env<AttrContext> env1 = env;
2083         if (sym.kind != ERR && sym.kind != TYP && sym.owner != null && sym.owner != env1.enclClass.sym) {
2084             // If the found symbol is inaccessible, then it is
2085             // accessed through an enclosing instance.  Locate this
2086             // enclosing instance:
2087             while (env1.outer != null && !rs.isAccessible(env, env1.enclClass.sym.type, sym))
2088                 env1 = env1.outer;
2089         }
2090         result = checkId(tree, env1.enclClass.sym.type, sym, env, pkind, pt, varArgs);
2091     }
2092 
2093     public void visitSelect(JCFieldAccess tree) {
2094         // Determine the expected kind of the qualifier expression.
2095         int skind = 0;
2096         if (tree.name == names._this || tree.name == names._super ||
2097             tree.name == names._class)
2098         {
2099             skind = TYP;
2100         } else {
2101             if ((pkind & PCK) != 0) skind = skind | PCK;
2102             if ((pkind & TYP) != 0) skind = skind | TYP | PCK;
2103             if ((pkind & (VAL | MTH)) != 0) skind = skind | VAL | TYP;
2104         }
2105 
2106         // Attribute the qualifier expression, and determine its symbol (if any).
2107         Type site = attribTree(tree.selected, env, skind, Infer.anyPoly);
2108         if ((pkind & (PCK | TYP)) == 0)
2109             site = capture(site); // Capture field access
2110 
2111         // don't allow T.class T[].class, etc
2112         if (skind == TYP) {
2113             Type elt = site;
2114             while (elt.tag == ARRAY)
2115                 elt = ((ArrayType)elt).elemtype;
2116             if (elt.tag == TYPEVAR) {
2117                 log.error(tree.pos(), "type.var.cant.be.deref");
2118                 result = types.createErrorType(tree.type);
2119                 return;
2120             }
2121         }
2122 
2123         // If qualifier symbol is a type or `super', assert `selectSuper'
2124         // for the selection. This is relevant for determining whether
2125         // protected symbols are accessible.
2126         Symbol sitesym = TreeInfo.symbol(tree.selected);
2127         boolean selectSuperPrev = env.info.selectSuper;
2128         env.info.selectSuper =
2129             sitesym != null &&
2130             sitesym.name == names._super;
2131 
2132         // If selected expression is polymorphic, strip
2133         // type parameters and remember in env.info.tvars, so that
2134         // they can be added later (in Attr.checkId and Infer.instantiateMethod).
2135         if (tree.selected.type.tag == FORALL) {
2136             ForAll pstype = (ForAll)tree.selected.type;
2137             env.info.tvars = pstype.tvars;
2138             site = tree.selected.type = pstype.qtype;
2139         }
2140 
2141         // Determine the symbol represented by the selection.
2142         env.info.varArgs = false;
2143         Symbol sym = selectSym(tree, site, env, pt, pkind);
2144         if (sym.exists() && !isType(sym) && (pkind & (PCK | TYP)) != 0) {
2145             site = capture(site);
2146             sym = selectSym(tree, site, env, pt, pkind);
2147         }
2148         boolean varArgs = env.info.varArgs;
2149         tree.sym = sym;
2150 
2151         if (site.tag == TYPEVAR && !isType(sym) && sym.kind != ERR) {
2152             while (site.tag == TYPEVAR) site = site.getUpperBound();
2153             site = capture(site);
2154         }
2155 
2156         // If that symbol is a variable, ...
2157         if (sym.kind == VAR) {
2158             VarSymbol v = (VarSymbol)sym;
2159 
2160             // ..., evaluate its initializer, if it has one, and check for
2161             // illegal forward reference.
2162             checkInit(tree, env, v, true);
2163 
2164             // If we are expecting a variable (as opposed to a value), check
2165             // that the variable is assignable in the current environment.
2166             if (pkind == VAR)
2167                 checkAssignable(tree.pos(), v, tree.selected, env);
2168         }
2169 
2170         // Disallow selecting a type from an expression
2171         if (isType(sym) && (sitesym==null || (sitesym.kind&(TYP|PCK)) == 0)) {
2172             tree.type = check(tree.selected, pt,
2173                               sitesym == null ? VAL : sitesym.kind, TYP|PCK, pt);
2174         }
2175 
2176         if (isType(sitesym)) {
2177             if (sym.name == names._this) {
2178                 // If `C' is the currently compiled class, check that
2179                 // C.this' does not appear in a call to a super(...)
2180                 if (env.info.isSelfCall &&
2181                     site.tsym == env.enclClass.sym) {
2182                     chk.earlyRefError(tree.pos(), sym);
2183                 }
2184             } else {
2185                 // Check if type-qualified fields or methods are static (JLS)
2186                 if ((sym.flags() & STATIC) == 0 &&
2187                     sym.name != names._super &&
2188                     (sym.kind == VAR || sym.kind == MTH)) {
2189                     rs.access(rs.new StaticError(sym),
2190                               tree.pos(), site, sym.name, true);
2191                 }
2192             }
2193         } else if (sym.kind != ERR && (sym.flags() & STATIC) != 0 && sym.name != names._class) {
2194             // If the qualified item is not a type and the selected item is static, report
2195             // a warning. Make allowance for the class of an array type e.g. Object[].class)
2196             chk.warnStatic(tree, "static.not.qualified.by.type", Kinds.kindName(sym.kind), sym.owner);
2197         }
2198 
2199         // If we are selecting an instance member via a `super', ...
2200         if (env.info.selectSuper && (sym.flags() & STATIC) == 0) {
2201 
2202             // Check that super-qualified symbols are not abstract (JLS)
2203             rs.checkNonAbstract(tree.pos(), sym);
2204 
2205             if (site.isRaw()) {
2206                 // Determine argument types for site.
2207                 Type site1 = types.asSuper(env.enclClass.sym.type, site.tsym);
2208                 if (site1 != null) site = site1;
2209             }
2210         }
2211 
2212         env.info.selectSuper = selectSuperPrev;
2213         result = checkId(tree, site, sym, env, pkind, pt, varArgs);
2214         env.info.tvars = List.nil();
2215     }
2216     //where
2217         /** Determine symbol referenced by a Select expression,
2218          *
2219          *  @param tree   The select tree.
2220          *  @param site   The type of the selected expression,
2221          *  @param env    The current environment.
2222          *  @param pt     The current prototype.
2223          *  @param pkind  The expected kind(s) of the Select expression.
2224          */
2225         private Symbol selectSym(JCFieldAccess tree,
2226                                  Type site,
2227                                  Env<AttrContext> env,
2228                                  Type pt,
2229                                  int pkind) {
2230             DiagnosticPosition pos = tree.pos();
2231             Name name = tree.name;
2232 
2233             switch (site.tag) {
2234             case PACKAGE:
2235                 return rs.access(
2236                     rs.findIdentInPackage(env, site.tsym, name, pkind),
2237                     pos, site, name, true);
2238             case ARRAY:
2239             case CLASS:
2240                 if (pt.tag == METHOD || pt.tag == FORALL) {
2241                     return rs.resolveQualifiedMethod(
2242                         pos, env, site, name, pt.getParameterTypes(), pt.getTypeArguments());
2243                 } else if (name == names._this || name == names._super) {
2244                     return rs.resolveSelf(pos, env, site.tsym, name);
2245                 } else if (name == names._class) {
2246                     // In this case, we have already made sure in
2247                     // visitSelect that qualifier expression is a type.
2248                     Type t = syms.classType;
2249                     List<Type> typeargs = allowGenerics
2250                         ? List.of(types.erasure(site))
2251                         : List.<Type>nil();
2252                     t = new ClassType(t.getEnclosingType(), typeargs, t.tsym);
2253                     return new VarSymbol(
2254                         STATIC | PUBLIC | FINAL, names._class, t, site.tsym);
2255                 } else {
2256                     // We are seeing a plain identifier as selector.
2257                     Symbol sym = rs.findIdentInType(env, site, name, pkind);
2258                     if ((pkind & ERRONEOUS) == 0)
2259                         sym = rs.access(sym, pos, site, name, true);
2260                     return sym;
2261                 }
2262             case WILDCARD:
2263                 throw new AssertionError(tree);
2264             case TYPEVAR:
2265                 // Normally, site.getUpperBound() shouldn't be null.
2266                 // It should only happen during memberEnter/attribBase
2267                 // when determining the super type which *must* be
2268                 // done before attributing the type variables.  In
2269                 // other words, we are seeing this illegal program:
2270                 // class B<T> extends A<T.foo> {}
2271                 Symbol sym = (site.getUpperBound() != null)
2272                     ? selectSym(tree, capture(site.getUpperBound()), env, pt, pkind)
2273                     : null;
2274                 if (sym == null) {
2275                     log.error(pos, "type.var.cant.be.deref");
2276                     return syms.errSymbol;
2277                 } else {
2278                     Symbol sym2 = (sym.flags() & Flags.PRIVATE) != 0 ?
2279                         rs.new AccessError(env, site, sym) :
2280                                 sym;
2281                     rs.access(sym2, pos, site, name, true);
2282                     return sym;
2283                 }
2284             case ERROR:
2285                 // preserve identifier names through errors
2286                 return types.createErrorType(name, site.tsym, site).tsym;
2287             default:
2288                 // The qualifier expression is of a primitive type -- only
2289                 // .class is allowed for these.
2290                 if (name == names._class) {
2291                     // In this case, we have already made sure in Select that
2292                     // qualifier expression is a type.
2293                     Type t = syms.classType;
2294                     Type arg = types.boxedClass(site).type;
2295                     t = new ClassType(t.getEnclosingType(), List.of(arg), t.tsym);
2296                     return new VarSymbol(
2297                         STATIC | PUBLIC | FINAL, names._class, t, site.tsym);
2298                 } else {
2299                     log.error(pos, "cant.deref", site);
2300                     return syms.errSymbol;
2301                 }
2302             }
2303         }
2304 
2305         /** Determine type of identifier or select expression and check that
2306          *  (1) the referenced symbol is not deprecated
2307          *  (2) the symbol's type is safe (@see checkSafe)
2308          *  (3) if symbol is a variable, check that its type and kind are
2309          *      compatible with the prototype and protokind.
2310          *  (4) if symbol is an instance field of a raw type,
2311          *      which is being assigned to, issue an unchecked warning if its
2312          *      type changes under erasure.
2313          *  (5) if symbol is an instance method of a raw type, issue an
2314          *      unchecked warning if its argument types change under erasure.
2315          *  If checks succeed:
2316          *    If symbol is a constant, return its constant type
2317          *    else if symbol is a method, return its result type
2318          *    otherwise return its type.
2319          *  Otherwise return errType.
2320          *
2321          *  @param tree       The syntax tree representing the identifier
2322          *  @param site       If this is a select, the type of the selected
2323          *                    expression, otherwise the type of the current class.
2324          *  @param sym        The symbol representing the identifier.
2325          *  @param env        The current environment.
2326          *  @param pkind      The set of expected kinds.
2327          *  @param pt         The expected type.
2328          */
2329         Type checkId(JCTree tree,
2330                      Type site,
2331                      Symbol sym,
2332                      Env<AttrContext> env,
2333                      int pkind,
2334                      Type pt,
2335                      boolean useVarargs) {
2336             if (pt.isErroneous()) return types.createErrorType(site);
2337             Type owntype; // The computed type of this identifier occurrence.
2338             switch (sym.kind) {
2339             case TYP:
2340                 // For types, the computed type equals the symbol's type,
2341                 // except for two situations:
2342                 owntype = sym.type;
2343                 if (owntype.tag == CLASS) {
2344                     Type ownOuter = owntype.getEnclosingType();
2345 
2346                     // (a) If the symbol's type is parameterized, erase it
2347                     // because no type parameters were given.
2348                     // We recover generic outer type later in visitTypeApply.
2349                     if (owntype.tsym.type.getTypeArguments().nonEmpty()) {
2350                         owntype = types.erasure(owntype);
2351                     }
2352 
2353                     // (b) If the symbol's type is an inner class, then
2354                     // we have to interpret its outer type as a superclass
2355                     // of the site type. Example:
2356                     //
2357                     // class Tree<A> { class Visitor { ... } }
2358                     // class PointTree extends Tree<Point> { ... }
2359                     // ...PointTree.Visitor...
2360                     //
2361                     // Then the type of the last expression above is
2362                     // Tree<Point>.Visitor.
2363                     else if (ownOuter.tag == CLASS && site != ownOuter) {
2364                         Type normOuter = site;
2365                         if (normOuter.tag == CLASS)
2366                             normOuter = types.asEnclosingSuper(site, ownOuter.tsym);
2367                         if (normOuter == null) // perhaps from an import
2368                             normOuter = types.erasure(ownOuter);
2369                         if (normOuter != ownOuter)
2370                             owntype = new ClassType(
2371                                 normOuter, List.<Type>nil(), owntype.tsym);
2372                     }
2373                 }
2374                 break;
2375             case VAR:
2376                 VarSymbol v = (VarSymbol)sym;
2377                 // Test (4): if symbol is an instance field of a raw type,
2378                 // which is being assigned to, issue an unchecked warning if
2379                 // its type changes under erasure.
2380                 if (allowGenerics &&
2381                     pkind == VAR &&
2382                     v.owner.kind == TYP &&
2383                     (v.flags() & STATIC) == 0 &&
2384                     (site.tag == CLASS || site.tag == TYPEVAR)) {
2385                     Type s = types.asOuterSuper(site, v.owner);
2386                     if (s != null &&
2387                         s.isRaw() &&
2388                         !types.isSameType(v.type, v.erasure(types))) {
2389                         chk.warnUnchecked(tree.pos(),
2390                                           "unchecked.assign.to.var",
2391                                           v, s);
2392                     }
2393                 }
2394                 // The computed type of a variable is the type of the
2395                 // variable symbol, taken as a member of the site type.
2396                 owntype = (sym.owner.kind == TYP &&
2397                            sym.name != names._this && sym.name != names._super)
2398                     ? types.memberType(site, sym)
2399                     : sym.type;
2400 
2401                 if (env.info.tvars.nonEmpty()) {
2402                     Type owntype1 = new ForAll(env.info.tvars, owntype);
2403                     for (List<Type> l = env.info.tvars; l.nonEmpty(); l = l.tail)
2404                         if (!owntype.contains(l.head)) {
2405                             log.error(tree.pos(), "undetermined.type", owntype1);
2406                             owntype1 = types.createErrorType(owntype1);
2407                         }
2408                     owntype = owntype1;
2409                 }
2410 
2411                 // If the variable is a constant, record constant value in
2412                 // computed type.
2413                 if (v.getConstValue() != null && isStaticReference(tree))
2414                     owntype = owntype.constType(v.getConstValue());
2415 
2416                 if (pkind == VAL) {
2417                     owntype = capture(owntype); // capture "names as expressions"
2418                 }
2419                 break;
2420             case MTH: {
2421                 JCMethodInvocation app = (JCMethodInvocation)env.tree;
2422                 owntype = checkMethod(site, sym, env, app.args,
2423                                       pt.getParameterTypes(), pt.getTypeArguments(),
2424                                       env.info.varArgs);
2425                 break;
2426             }
2427             case PCK: case ERR:
2428                 owntype = sym.type;
2429                 break;
2430             default:
2431                 throw new AssertionError("unexpected kind: " + sym.kind +
2432                                          " in tree " + tree);
2433             }
2434 
2435             // Test (1): emit a `deprecation' warning if symbol is deprecated.
2436             // (for constructors, the error was given when the constructor was
2437             // resolved)
2438             if (sym.name != names.init &&
2439                 (sym.flags() & DEPRECATED) != 0 &&
2440                 (env.info.scope.owner.flags() & DEPRECATED) == 0 &&
2441                 sym.outermostClass() != env.info.scope.owner.outermostClass())
2442                 chk.warnDeprecated(tree.pos(), sym);
2443 
2444             if ((sym.flags() & PROPRIETARY) != 0) {
2445                 if (enableSunApiLintControl)
2446                   chk.warnSunApi(tree.pos(), "sun.proprietary", sym);
2447                 else
2448                   log.strictWarning(tree.pos(), "sun.proprietary", sym);
2449             }
2450 
2451             // Test (3): if symbol is a variable, check that its type and
2452             // kind are compatible with the prototype and protokind.
2453             return check(tree, owntype, sym.kind, pkind, pt);
2454         }
2455 
2456         /** Check that variable is initialized and evaluate the variable's
2457          *  initializer, if not yet done. Also check that variable is not
2458          *  referenced before it is defined.
2459          *  @param tree    The tree making up the variable reference.
2460          *  @param env     The current environment.
2461          *  @param v       The variable's symbol.
2462          */
2463         private void checkInit(JCTree tree,
2464                                Env<AttrContext> env,
2465                                VarSymbol v,
2466                                boolean onlyWarning) {
2467 //          System.err.println(v + " " + ((v.flags() & STATIC) != 0) + " " +
2468 //                             tree.pos + " " + v.pos + " " +
2469 //                             Resolve.isStatic(env));//DEBUG
2470 
2471             // A forward reference is diagnosed if the declaration position
2472             // of the variable is greater than the current tree position
2473             // and the tree and variable definition occur in the same class
2474             // definition.  Note that writes don't count as references.
2475             // This check applies only to class and instance
2476             // variables.  Local variables follow different scope rules,
2477             // and are subject to definite assignment checking.
2478             if ((env.info.enclVar == v || v.pos > tree.pos) &&
2479                 v.owner.kind == TYP &&
2480                 canOwnInitializer(env.info.scope.owner) &&
2481                 v.owner == env.info.scope.owner.enclClass() &&
2482                 ((v.flags() & STATIC) != 0) == Resolve.isStatic(env) &&
2483                 (env.tree.getTag() != JCTree.ASSIGN ||
2484                  TreeInfo.skipParens(((JCAssign) env.tree).lhs) != tree)) {
2485                 String suffix = (env.info.enclVar == v) ?
2486                                 "self.ref" : "forward.ref";
2487                 if (!onlyWarning || isStaticEnumField(v)) {
2488                     log.error(tree.pos(), "illegal." + suffix);
2489                 } else if (useBeforeDeclarationWarning) {
2490                     log.warning(tree.pos(), suffix, v);
2491                 }
2492             }
2493 
2494             v.getConstValue(); // ensure initializer is evaluated
2495 
2496             checkEnumInitializer(tree, env, v);
2497         }
2498 
2499         /**
2500          * Check for illegal references to static members of enum.  In
2501          * an enum type, constructors and initializers may not
2502          * reference its static members unless they are constant.
2503          *
2504          * @param tree    The tree making up the variable reference.
2505          * @param env     The current environment.
2506          * @param v       The variable's symbol.
2507          * @see JLS 3rd Ed. (8.9 Enums)
2508          */
2509         private void checkEnumInitializer(JCTree tree, Env<AttrContext> env, VarSymbol v) {
2510             // JLS 3rd Ed.:
2511             //
2512             // "It is a compile-time error to reference a static field
2513             // of an enum type that is not a compile-time constant
2514             // (15.28) from constructors, instance initializer blocks,
2515             // or instance variable initializer expressions of that
2516             // type. It is a compile-time error for the constructors,
2517             // instance initializer blocks, or instance variable
2518             // initializer expressions of an enum constant e to refer
2519             // to itself or to an enum constant of the same type that
2520             // is declared to the right of e."
2521             if (isStaticEnumField(v)) {
2522                 ClassSymbol enclClass = env.info.scope.owner.enclClass();
2523 
2524                 if (enclClass == null || enclClass.owner == null)
2525                     return;
2526 
2527                 // See if the enclosing class is the enum (or a
2528                 // subclass thereof) declaring v.  If not, this
2529                 // reference is OK.
2530                 if (v.owner != enclClass && !types.isSubtype(enclClass.type, v.owner.type))
2531                     return;
2532 
2533                 // If the reference isn't from an initializer, then
2534                 // the reference is OK.
2535                 if (!Resolve.isInitializer(env))
2536                     return;
2537 
2538                 log.error(tree.pos(), "illegal.enum.static.ref");
2539             }
2540         }
2541 
2542         /** Is the given symbol a static, non-constant field of an Enum?
2543          *  Note: enum literals should not be regarded as such
2544          */
2545         private boolean isStaticEnumField(VarSymbol v) {
2546             return Flags.isEnum(v.owner) &&
2547                    Flags.isStatic(v) &&
2548                    !Flags.isConstant(v) &&
2549                    v.name != names._class;
2550         }
2551 
2552         /** Can the given symbol be the owner of code which forms part
2553          *  if class initialization? This is the case if the symbol is
2554          *  a type or field, or if the symbol is the synthetic method.
2555          *  owning a block.
2556          */
2557         private boolean canOwnInitializer(Symbol sym) {
2558             return
2559                 (sym.kind & (VAR | TYP)) != 0 ||
2560                 (sym.kind == MTH && (sym.flags() & BLOCK) != 0);
2561         }
2562 
2563     Warner noteWarner = new Warner();
2564 
2565     /**
2566      * Check that method arguments conform to its instantation.
2567      **/
2568     public Type checkMethod(Type site,
2569                             Symbol sym,
2570                             Env<AttrContext> env,
2571                             final List<JCExpression> argtrees,
2572                             List<Type> argtypes,
2573                             List<Type> typeargtypes,
2574                             boolean useVarargs) {
2575         // Test (5): if symbol is an instance method of a raw type, issue
2576         // an unchecked warning if its argument types change under erasure.
2577         if (allowGenerics &&
2578             (sym.flags() & STATIC) == 0 &&
2579             (site.tag == CLASS || site.tag == TYPEVAR)) {
2580             Type s = types.asOuterSuper(site, sym.owner);
2581             if (s != null && s.isRaw() &&
2582                 !types.isSameTypes(sym.type.getParameterTypes(),
2583                                    sym.erasure(types).getParameterTypes())) {
2584                 chk.warnUnchecked(env.tree.pos(),
2585                                   "unchecked.call.mbr.of.raw.type",
2586                                   sym, s);
2587             }
2588         }
2589 
2590         // Compute the identifier's instantiated type.
2591         // For methods, we need to compute the instance type by
2592         // Resolve.instantiate from the symbol's type as well as
2593         // any type arguments and value arguments.
2594         noteWarner.warned = false;
2595         Type owntype = rs.instantiate(env,
2596                                       site,
2597                                       sym,
2598                                       argtypes,
2599                                       typeargtypes,
2600                                       true,
2601                                       useVarargs,
2602                                       noteWarner);
2603         boolean warned = noteWarner.warned;
2604 
2605         // If this fails, something went wrong; we should not have
2606         // found the identifier in the first place.
2607         if (owntype == null) {
2608             if (!pt.isErroneous())
2609                 log.error(env.tree.pos(),
2610                           "internal.error.cant.instantiate",
2611                           sym, site,
2612                           Type.toString(pt.getParameterTypes()));
2613             owntype = types.createErrorType(site);
2614         } else {
2615             // System.out.println("call   : " + env.tree);
2616             // System.out.println("method : " + owntype);
2617             // System.out.println("actuals: " + argtypes);
2618             List<Type> formals = owntype.getParameterTypes();
2619             Type last = useVarargs ? formals.last() : null;
2620             if (sym.name==names.init &&
2621                 sym.owner == syms.enumSym)
2622                 formals = formals.tail.tail;
2623             List<JCExpression> args = argtrees;
2624             while (formals.head != last) {
2625                 JCTree arg = args.head;
2626                 Warner warn = chk.convertWarner(arg.pos(), arg.type, formals.head);
2627                 assertConvertible(arg, arg.type, formals.head, warn);
2628                 warned |= warn.warned;
2629                 args = args.tail;
2630                 formals = formals.tail;
2631             }
2632             if (useVarargs) {
2633                 Type varArg = types.elemtype(last);
2634                 while (args.tail != null) {
2635                     JCTree arg = args.head;
2636                     Warner warn = chk.convertWarner(arg.pos(), arg.type, varArg);
2637                     assertConvertible(arg, arg.type, varArg, warn);
2638                     warned |= warn.warned;
2639                     args = args.tail;
2640                 }
2641             } else if ((sym.flags() & VARARGS) != 0 && allowVarargs) {
2642                 // non-varargs call to varargs method
2643                 Type varParam = owntype.getParameterTypes().last();
2644                 Type lastArg = argtypes.last();
2645                 if (types.isSubtypeUnchecked(lastArg, types.elemtype(varParam)) &&
2646                     !types.isSameType(types.erasure(varParam), types.erasure(lastArg)))
2647                     log.warning(argtrees.last().pos(), "inexact.non-varargs.call",
2648                                 types.elemtype(varParam),
2649                                 varParam);
2650             }
2651 
2652             if (warned && sym.type.tag == FORALL) {
2653                 chk.warnUnchecked(env.tree.pos(),
2654                                   "unchecked.meth.invocation.applied",
2655                                   kindName(sym),
2656                                   sym.name,
2657                                   rs.methodArguments(sym.type.getParameterTypes()),
2658                                   rs.methodArguments(argtypes),
2659                                   kindName(sym.location()),
2660                                   sym.location());
2661                 owntype = new MethodType(owntype.getParameterTypes(),
2662                                          types.erasure(owntype.getReturnType()),
2663                                          owntype.getThrownTypes(),
2664                                          syms.methodClass);
2665             }
2666             if (useVarargs) {
2667                 JCTree tree = env.tree;
2668                 Type argtype = owntype.getParameterTypes().last();
2669                 if (owntype.getReturnType().tag != FORALL || warned) {
2670                     chk.checkVararg(env.tree.pos(), owntype.getParameterTypes(), sym, env);
2671                 }
2672                 Type elemtype = types.elemtype(argtype);
2673                 switch (tree.getTag()) {
2674                 case JCTree.APPLY:
2675                     ((JCMethodInvocation) tree).varargsElement = elemtype;
2676                     break;
2677                 case JCTree.NEWCLASS:
2678                     ((JCNewClass) tree).varargsElement = elemtype;
2679                     break;
2680                 default:
2681                     throw new AssertionError(""+tree);
2682                 }
2683             }
2684         }
2685         return owntype;
2686     }
2687 
2688     private void assertConvertible(JCTree tree, Type actual, Type formal, Warner warn) {
2689         if (types.isConvertible(actual, formal, warn))
2690             return;
2691 
2692         if (formal.isCompound()
2693             && types.isSubtype(actual, types.supertype(formal))
2694             && types.isSubtypeUnchecked(actual, types.interfaces(formal), warn))
2695             return;
2696 
2697         if (false) {
2698             // TODO: make assertConvertible work
2699             chk.typeError(tree.pos(), diags.fragment("incompatible.types"), actual, formal);
2700             throw new AssertionError("Tree: " + tree
2701                                      + " actual:" + actual
2702                                      + " formal: " + formal);
2703         }
2704     }
2705 
2706     public void visitLiteral(JCLiteral tree) {
2707         result = check(
2708             tree, litType(tree.typetag).constType(tree.value), VAL, pkind, pt);
2709     }
2710     //where
2711     /** Return the type of a literal with given type tag.
2712      */
2713     Type litType(int tag) {
2714         return (tag == TypeTags.CLASS) ? syms.stringType : syms.typeOfTag[tag];
2715     }
2716 
2717     public void visitTypeIdent(JCPrimitiveTypeTree tree) {
2718         result = check(tree, syms.typeOfTag[tree.typetag], TYP, pkind, pt);
2719     }
2720 
2721     public void visitTypeArray(JCArrayTypeTree tree) {
2722         Type etype = attribType(tree.elemtype, env);
2723         Type type = new ArrayType(etype, syms.arrayClass);
2724         result = check(tree, type, TYP, pkind, pt);
2725     }
2726 
2727     /** Visitor method for parameterized types.
2728      *  Bound checking is left until later, since types are attributed
2729      *  before supertype structure is completely known
2730      */
2731     public void visitTypeApply(JCTypeApply tree) {
2732         Type owntype = types.createErrorType(tree.type);
2733 
2734         // Attribute functor part of application and make sure it's a class.
2735         Type clazztype = chk.checkClassType(tree.clazz.pos(), attribType(tree.clazz, env));
2736 
2737         // Attribute type parameters
2738         List<Type> actuals = attribTypes(tree.arguments, env);
2739 
2740         if (clazztype.tag == CLASS) {
2741             List<Type> formals = clazztype.tsym.type.getTypeArguments();
2742 
2743             if (actuals.length() == formals.length() || actuals.length() == 0) {
2744                 List<Type> a = actuals;
2745                 List<Type> f = formals;
2746                 while (a.nonEmpty()) {
2747                     a.head = a.head.withTypeVar(f.head);
2748                     a = a.tail;
2749                     f = f.tail;
2750                 }
2751                 // Compute the proper generic outer
2752                 Type clazzOuter = clazztype.getEnclosingType();
2753                 if (clazzOuter.tag == CLASS) {
2754                     Type site;
2755                     JCExpression clazz = TreeInfo.typeIn(tree.clazz);
2756                     if (clazz.getTag() == JCTree.IDENT) {
2757                         site = env.enclClass.sym.type;
2758                     } else if (clazz.getTag() == JCTree.SELECT) {
2759                         site = ((JCFieldAccess) clazz).selected.type;
2760                     } else throw new AssertionError(""+tree);
2761                     if (clazzOuter.tag == CLASS && site != clazzOuter) {
2762                         if (site.tag == CLASS)
2763                             site = types.asOuterSuper(site, clazzOuter.tsym);
2764                         if (site == null)
2765                             site = types.erasure(clazzOuter);
2766                         clazzOuter = site;
2767                     }
2768                 }
2769                 owntype = new ClassType(clazzOuter, actuals, clazztype.tsym);
2770             } else {
2771                 if (formals.length() != 0) {
2772                     log.error(tree.pos(), "wrong.number.type.args",
2773                               Integer.toString(formals.length()));
2774                 } else {
2775                     log.error(tree.pos(), "type.doesnt.take.params", clazztype.tsym);
2776                 }
2777                 owntype = types.createErrorType(tree.type);
2778             }
2779         }
2780         result = check(tree, owntype, TYP, pkind, pt);
2781     }
2782 
2783     public void visitTypeDisjoint(JCTypeDisjoint tree) {
2784         List<Type> componentTypes = attribTypes(tree.components, env);
2785         tree.type = result = check(tree, types.lub(componentTypes), TYP, pkind, pt);
2786     }
2787 
2788     public void visitTypeParameter(JCTypeParameter tree) {
2789         TypeVar a = (TypeVar)tree.type;
2790         Set<Type> boundSet = new HashSet<Type>();
2791         if (a.bound.isErroneous())
2792             return;
2793         List<Type> bs = types.getBounds(a);
2794         if (tree.bounds.nonEmpty()) {
2795             // accept class or interface or typevar as first bound.
2796             Type b = checkBase(bs.head, tree.bounds.head, env, false, false, false);
2797             boundSet.add(types.erasure(b));
2798             if (b.isErroneous()) {
2799                 a.bound = b;
2800             }
2801             else if (b.tag == TYPEVAR) {
2802                 // if first bound was a typevar, do not accept further bounds.
2803                 if (tree.bounds.tail.nonEmpty()) {
2804                     log.error(tree.bounds.tail.head.pos(),
2805                               "type.var.may.not.be.followed.by.other.bounds");
2806                     log.unrecoverableError = true;
2807                     tree.bounds = List.of(tree.bounds.head);
2808                     a.bound = bs.head;
2809                 }
2810             } else {
2811                 // if first bound was a class or interface, accept only interfaces
2812                 // as further bounds.
2813                 for (JCExpression bound : tree.bounds.tail) {
2814                     bs = bs.tail;
2815                     Type i = checkBase(bs.head, bound, env, false, true, false);
2816                     if (i.isErroneous())
2817                         a.bound = i;
2818                     else if (i.tag == CLASS)
2819                         chk.checkNotRepeated(bound.pos(), types.erasure(i), boundSet);
2820                 }
2821             }
2822         }
2823         bs = types.getBounds(a);
2824 
2825         // in case of multiple bounds ...
2826         if (bs.length() > 1) {
2827             // ... the variable's bound is a class type flagged COMPOUND
2828             // (see comment for TypeVar.bound).
2829             // In this case, generate a class tree that represents the
2830             // bound class, ...
2831             JCTree extending;
2832             List<JCExpression> implementing;
2833             if ((bs.head.tsym.flags() & INTERFACE) == 0) {
2834                 extending = tree.bounds.head;
2835                 implementing = tree.bounds.tail;
2836             } else {
2837                 extending = null;
2838                 implementing = tree.bounds;
2839             }
2840             JCClassDecl cd = make.at(tree.pos).ClassDef(
2841                 make.Modifiers(PUBLIC | ABSTRACT),
2842                 tree.name, List.<JCTypeParameter>nil(),
2843                 extending, implementing, List.<JCTree>nil());
2844 
2845             ClassSymbol c = (ClassSymbol)a.getUpperBound().tsym;
2846             assert (c.flags() & COMPOUND) != 0;
2847             cd.sym = c;
2848             c.sourcefile = env.toplevel.sourcefile;
2849 
2850             // ... and attribute the bound class
2851             c.flags_field |= UNATTRIBUTED;
2852             Env<AttrContext> cenv = enter.classEnv(cd, env);
2853             enter.typeEnvs.put(c, cenv);
2854         }
2855     }
2856 
2857 
2858     public void visitWildcard(JCWildcard tree) {
2859         //- System.err.println("visitWildcard("+tree+");");//DEBUG
2860         Type type = (tree.kind.kind == BoundKind.UNBOUND)
2861             ? syms.objectType
2862             : attribType(tree.inner, env);
2863         result = check(tree, new WildcardType(chk.checkRefType(tree.pos(), type),
2864                                               tree.kind.kind,
2865                                               syms.boundClass),
2866                        TYP, pkind, pt);
2867     }
2868 
2869     public void visitAnnotation(JCAnnotation tree) {
2870         log.error(tree.pos(), "annotation.not.valid.for.type", pt);
2871         result = tree.type = syms.errType;
2872     }
2873 
2874     public void visitAnnotatedType(JCAnnotatedType tree) {
2875         result = tree.type = attribType(tree.getUnderlyingType(), env);
2876     }
2877 
2878     public void visitErroneous(JCErroneous tree) {
2879         if (tree.errs != null)
2880             for (JCTree err : tree.errs)
2881                 attribTree(err, env, ERR, pt);
2882         result = tree.type = syms.errType;
2883     }
2884 
2885     /** Default visitor method for all other trees.
2886      */
2887     public void visitTree(JCTree tree) {
2888         throw new AssertionError();
2889     }
2890 
2891     /** Main method: attribute class definition associated with given class symbol.
2892      *  reporting completion failures at the given position.
2893      *  @param pos The source position at which completion errors are to be
2894      *             reported.
2895      *  @param c   The class symbol whose definition will be attributed.
2896      */
2897     public void attribClass(DiagnosticPosition pos, ClassSymbol c) {
2898         try {
2899             annotate.flush();
2900             attribClass(c);
2901         } catch (CompletionFailure ex) {
2902             chk.completionError(pos, ex);
2903         }
2904     }
2905 
2906     /** Attribute class definition associated with given class symbol.
2907      *  @param c   The class symbol whose definition will be attributed.
2908      */
2909     void attribClass(ClassSymbol c) throws CompletionFailure {
2910         if (c.type.tag == ERROR) return;
2911 
2912         // Check for cycles in the inheritance graph, which can arise from
2913         // ill-formed class files.
2914         chk.checkNonCyclic(null, c.type);
2915 
2916         Type st = types.supertype(c.type);
2917         if ((c.flags_field & Flags.COMPOUND) == 0) {
2918             // First, attribute superclass.
2919             if (st.tag == CLASS)
2920                 attribClass((ClassSymbol)st.tsym);
2921 
2922             // Next attribute owner, if it is a class.
2923             if (c.owner.kind == TYP && c.owner.type.tag == CLASS)
2924                 attribClass((ClassSymbol)c.owner);
2925         }
2926 
2927         // The previous operations might have attributed the current class
2928         // if there was a cycle. So we test first whether the class is still
2929         // UNATTRIBUTED.
2930         if ((c.flags_field & UNATTRIBUTED) != 0) {
2931             c.flags_field &= ~UNATTRIBUTED;
2932 
2933             // Get environment current at the point of class definition.
2934             Env<AttrContext> env = enter.typeEnvs.get(c);
2935 
2936             // The info.lint field in the envs stored in enter.typeEnvs is deliberately uninitialized,
2937             // because the annotations were not available at the time the env was created. Therefore,
2938             // we look up the environment chain for the first enclosing environment for which the
2939             // lint value is set. Typically, this is the parent env, but might be further if there
2940             // are any envs created as a result of TypeParameter nodes.
2941             Env<AttrContext> lintEnv = env;
2942             while (lintEnv.info.lint == null)
2943                 lintEnv = lintEnv.next;
2944 
2945             // Having found the enclosing lint value, we can initialize the lint value for this class
2946             env.info.lint = lintEnv.info.lint.augment(c.attributes_field, c.flags());
2947 
2948             Lint prevLint = chk.setLint(env.info.lint);
2949             JavaFileObject prev = log.useSource(c.sourcefile);
2950 
2951             try {
2952                 // java.lang.Enum may not be subclassed by a non-enum
2953                 if (st.tsym == syms.enumSym &&
2954                     ((c.flags_field & (Flags.ENUM|Flags.COMPOUND)) == 0))
2955                     log.error(env.tree.pos(), "enum.no.subclassing");
2956 
2957                 // Enums may not be extended by source-level classes
2958                 if (st.tsym != null &&
2959                     ((st.tsym.flags_field & Flags.ENUM) != 0) &&
2960                     ((c.flags_field & (Flags.ENUM | Flags.COMPOUND)) == 0) &&
2961                     !target.compilerBootstrap(c)) {
2962                     log.error(env.tree.pos(), "enum.types.not.extensible");
2963                 }
2964                 attribClassBody(env, c);
2965 
2966                 chk.checkDeprecatedAnnotation(env.tree.pos(), c);
2967             } finally {
2968                 log.useSource(prev);
2969                 chk.setLint(prevLint);
2970             }
2971 
2972         }
2973     }
2974 
2975     public void visitImport(JCImport tree) {
2976         // nothing to do
2977     }
2978 
2979     /** Finish the attribution of a class. */
2980     private void attribClassBody(Env<AttrContext> env, ClassSymbol c) {
2981         JCClassDecl tree = (JCClassDecl)env.tree;
2982         assert c == tree.sym;
2983 
2984         // Validate annotations
2985         chk.validateAnnotations(tree.mods.annotations, c);
2986 
2987         // Validate type parameters, supertype and interfaces.
2988         attribBounds(tree.typarams);
2989         if (!c.isAnonymous()) {
2990             //already checked if anonymous
2991             chk.validate(tree.typarams, env);
2992             chk.validate(tree.extending, env);
2993             chk.validate(tree.implementing, env);
2994         }
2995 
2996         // If this is a non-abstract class, check that it has no abstract
2997         // methods or unimplemented methods of an implemented interface.
2998         if ((c.flags() & (ABSTRACT | INTERFACE)) == 0) {
2999             if (!relax)
3000                 chk.checkAllDefined(tree.pos(), c);
3001         }
3002 
3003         if ((c.flags() & ANNOTATION) != 0) {
3004             if (tree.implementing.nonEmpty())
3005                 log.error(tree.implementing.head.pos(),
3006                           "cant.extend.intf.annotation");
3007             if (tree.typarams.nonEmpty())
3008                 log.error(tree.typarams.head.pos(),
3009                           "intf.annotation.cant.have.type.params");
3010         } else {
3011             // Check that all extended classes and interfaces
3012             // are compatible (i.e. no two define methods with same arguments
3013             // yet different return types).  (JLS 8.4.6.3)
3014             chk.checkCompatibleSupertypes(tree.pos(), c.type);
3015         }
3016 
3017         // Check that class does not import the same parameterized interface
3018         // with two different argument lists.
3019         chk.checkClassBounds(tree.pos(), c.type);
3020 
3021         tree.type = c.type;
3022 
3023         boolean assertsEnabled = false;
3024         assert assertsEnabled = true;
3025         if (assertsEnabled) {
3026             for (List<JCTypeParameter> l = tree.typarams;
3027                  l.nonEmpty(); l = l.tail)
3028                 assert env.info.scope.lookup(l.head.name).scope != null;
3029         }
3030 
3031         // Check that a generic class doesn't extend Throwable
3032         if (!c.type.allparams().isEmpty() && types.isSubtype(c.type, syms.throwableType))
3033             log.error(tree.extending.pos(), "generic.throwable");
3034 
3035         // Check that all methods which implement some
3036         // method conform to the method they implement.
3037         chk.checkImplementations(tree);
3038 
3039         for (List<JCTree> l = tree.defs; l.nonEmpty(); l = l.tail) {
3040             // Attribute declaration
3041             attribStat(l.head, env);
3042             // Check that declarations in inner classes are not static (JLS 8.1.2)
3043             // Make an exception for static constants.
3044             if (c.owner.kind != PCK &&
3045                 ((c.flags() & STATIC) == 0 || c.name == names.empty) &&
3046                 (TreeInfo.flags(l.head) & (STATIC | INTERFACE)) != 0) {
3047                 Symbol sym = null;
3048                 if (l.head.getTag() == JCTree.VARDEF) sym = ((JCVariableDecl) l.head).sym;
3049                 if (sym == null ||
3050                     sym.kind != VAR ||
3051                     ((VarSymbol) sym).getConstValue() == null)
3052                     log.error(l.head.pos(), "icls.cant.have.static.decl");
3053             }
3054         }
3055 
3056         // Check for cycles among non-initial constructors.
3057         chk.checkCyclicConstructors(tree);
3058 
3059         // Check for cycles among annotation elements.
3060         chk.checkNonCyclicElements(tree);
3061 
3062         // Check for proper use of serialVersionUID
3063         if (env.info.lint.isEnabled(Lint.LintCategory.SERIAL) &&
3064             isSerializable(c) &&
3065             (c.flags() & Flags.ENUM) == 0 &&
3066             (c.flags() & ABSTRACT) == 0) {
3067             checkSerialVersionUID(tree, c);
3068         }
3069 
3070         // Check type annotations applicability rules
3071         validateTypeAnnotations(tree);
3072     }
3073         // where
3074         /** check if a class is a subtype of Serializable, if that is available. */
3075         private boolean isSerializable(ClassSymbol c) {
3076             try {
3077                 syms.serializableType.complete();
3078             }
3079             catch (CompletionFailure e) {
3080                 return false;
3081             }
3082             return types.isSubtype(c.type, syms.serializableType);
3083         }
3084 
3085         /** Check that an appropriate serialVersionUID member is defined. */
3086         private void checkSerialVersionUID(JCClassDecl tree, ClassSymbol c) {
3087 
3088             // check for presence of serialVersionUID
3089             Scope.Entry e = c.members().lookup(names.serialVersionUID);
3090             while (e.scope != null && e.sym.kind != VAR) e = e.next();
3091             if (e.scope == null) {
3092                 log.warning(tree.pos(), "missing.SVUID", c);
3093                 return;
3094             }
3095 
3096             // check that it is static final
3097             VarSymbol svuid = (VarSymbol)e.sym;
3098             if ((svuid.flags() & (STATIC | FINAL)) !=
3099                 (STATIC | FINAL))
3100                 log.warning(TreeInfo.diagnosticPositionFor(svuid, tree), "improper.SVUID", c);
3101 
3102             // check that it is long
3103             else if (svuid.type.tag != TypeTags.LONG)
3104                 log.warning(TreeInfo.diagnosticPositionFor(svuid, tree), "long.SVUID", c);
3105 
3106             // check constant
3107             else if (svuid.getConstValue() == null)
3108                 log.warning(TreeInfo.diagnosticPositionFor(svuid, tree), "constant.SVUID", c);
3109         }
3110 
3111     private Type capture(Type type) {
3112         return types.capture(type);
3113     }
3114 
3115     private void validateTypeAnnotations(JCTree tree) {
3116         tree.accept(typeAnnotationsValidator);
3117     }
3118     //where
3119     private final JCTree.Visitor typeAnnotationsValidator =
3120         new TreeScanner() {
3121         public void visitAnnotation(JCAnnotation tree) {
3122             if (tree instanceof JCTypeAnnotation) {
3123                 chk.validateTypeAnnotation((JCTypeAnnotation)tree, false);
3124             }
3125             super.visitAnnotation(tree);
3126         }
3127         public void visitTypeParameter(JCTypeParameter tree) {
3128             chk.validateTypeAnnotations(tree.annotations, true);
3129             // don't call super. skip type annotations
3130             scan(tree.bounds);
3131         }
3132         public void visitMethodDef(JCMethodDecl tree) {
3133             // need to check static methods
3134             if ((tree.sym.flags() & Flags.STATIC) != 0) {
3135                 for (JCTypeAnnotation a : tree.receiverAnnotations) {
3136                     if (chk.isTypeAnnotation(a, false))
3137                         log.error(a.pos(), "annotation.type.not.applicable");
3138                 }
3139             }
3140             super.visitMethodDef(tree);
3141         }
3142     };
3143 }