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