src/share/classes/com/sun/tools/javac/comp/Attr.java

Tue, 07 Sep 2010 17:32:27 +0100

author
mcimadamore
date
Tue, 07 Sep 2010 17:32:27 +0100
changeset 674
584365f256a7
parent 669
d54300fb3554
child 676
bfdfc13fe641
permissions
-rw-r--r--

6979327: method handle invocation should use casts instead of type parameters to specify return type
Summary: infer return type for polymorphic signature calls according to updated JSR 292 draft
Reviewed-by: jjg
Contributed-by: john.r.rose@oracle.com

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

mercurial