Home » openjdk-7 » com.sun.tools » javac » comp » [javadoc | source]

    1   /*
    2    * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
    3    * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    4    *
    5    * This code is free software; you can redistribute it and/or modify it
    6    * under the terms of the GNU General Public License version 2 only, as
    7    * published by the Free Software Foundation.  Oracle designates this
    8    * particular file as subject to the "Classpath" exception as provided
    9    * by Oracle in the LICENSE file that accompanied this code.
   10    *
   11    * This code is distributed in the hope that it will be useful, but WITHOUT
   12    * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   13    * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   14    * version 2 for more details (a copy is included in the LICENSE file that
   15    * accompanied this code).
   16    *
   17    * You should have received a copy of the GNU General Public License version
   18    * 2 along with this work; if not, write to the Free Software Foundation,
   19    * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   20    *
   21    * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   22    * or visit www.oracle.com if you need additional information or have any
   23    * questions.
   24    */
   25   
   26   package com.sun.tools.javac.comp;
   27   
   28   import java.util;
   29   import java.util.Set;
   30   import javax.tools.JavaFileObject;
   31   
   32   import com.sun.tools.javac.code;
   33   import com.sun.tools.javac.jvm;
   34   import com.sun.tools.javac.tree;
   35   import com.sun.tools.javac.util;
   36   import com.sun.tools.javac.util.List;
   37   
   38   import com.sun.tools.javac.code.Type;
   39   import com.sun.tools.javac.code.Symbol;
   40   import com.sun.tools.javac.tree.JCTree;
   41   
   42   import static com.sun.tools.javac.code.Flags.*;
   43   import static com.sun.tools.javac.code.Kinds.*;
   44   import static com.sun.tools.javac.code.TypeTags.*;
   45   import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
   46   
   47   /** This is the second phase of Enter, in which classes are completed
   48    *  by entering their members into the class scope using
   49    *  MemberEnter.complete().  See Enter for an overview.
   50    *
   51    *  <p><b>This is NOT part of any supported API.
   52    *  If you write code that depends on this, you do so at your own risk.
   53    *  This code and its internal interfaces are subject to change or
   54    *  deletion without notice.</b>
   55    */
   56   public class MemberEnter extends JCTree.Visitor implements Completer {
   57       protected static final Context.Key<MemberEnter> memberEnterKey =
   58           new Context.Key<MemberEnter>();
   59   
   60       /** A switch to determine whether we check for package/class conflicts
   61        */
   62       final static boolean checkClash = true;
   63   
   64       private final Names names;
   65       private final Enter enter;
   66       private final Log log;
   67       private final Check chk;
   68       private final Attr attr;
   69       private final Symtab syms;
   70       private final TreeMaker make;
   71       private final ClassReader reader;
   72       private final Todo todo;
   73       private final Annotate annotate;
   74       private final Types types;
   75       private final JCDiagnostic.Factory diags;
   76       private final Target target;
   77       private final DeferredLintHandler deferredLintHandler;
   78   
   79       private final boolean skipAnnotations;
   80   
   81       public static MemberEnter instance(Context context) {
   82           MemberEnter instance = context.get(memberEnterKey);
   83           if (instance == null)
   84               instance = new MemberEnter(context);
   85           return instance;
   86       }
   87   
   88       protected MemberEnter(Context context) {
   89           context.put(memberEnterKey, this);
   90           names = Names.instance(context);
   91           enter = Enter.instance(context);
   92           log = Log.instance(context);
   93           chk = Check.instance(context);
   94           attr = Attr.instance(context);
   95           syms = Symtab.instance(context);
   96           make = TreeMaker.instance(context);
   97           reader = ClassReader.instance(context);
   98           todo = Todo.instance(context);
   99           annotate = Annotate.instance(context);
  100           types = Types.instance(context);
  101           diags = JCDiagnostic.Factory.instance(context);
  102           target = Target.instance(context);
  103           deferredLintHandler = DeferredLintHandler.instance(context);
  104           Options options = Options.instance(context);
  105           skipAnnotations = options.isSet("skipAnnotations");
  106       }
  107   
  108       /** A queue for classes whose members still need to be entered into the
  109        *  symbol table.
  110        */
  111       ListBuffer<Env<AttrContext>> halfcompleted = new ListBuffer<Env<AttrContext>>();
  112   
  113       /** Set to true only when the first of a set of classes is
  114        *  processed from the halfcompleted queue.
  115        */
  116       boolean isFirst = true;
  117   
  118       /** A flag to disable completion from time to time during member
  119        *  enter, as we only need to look up types.  This avoids
  120        *  unnecessarily deep recursion.
  121        */
  122       boolean completionEnabled = true;
  123   
  124       /* ---------- Processing import clauses ----------------
  125        */
  126   
  127       /** Import all classes of a class or package on demand.
  128        *  @param pos           Position to be used for error reporting.
  129        *  @param tsym          The class or package the members of which are imported.
  130        *  @param toScope   The (import) scope in which imported classes
  131        *               are entered.
  132        */
  133       private void importAll(int pos,
  134                              final TypeSymbol tsym,
  135                              Env<AttrContext> env) {
  136           // Check that packages imported from exist (JLS ???).
  137           if (tsym.kind == PCK && tsym.members().elems == null && !tsym.exists()) {
  138               // If we can't find java.lang, exit immediately.
  139               if (((PackageSymbol)tsym).fullname.equals(names.java_lang)) {
  140                   JCDiagnostic msg = diags.fragment("fatal.err.no.java.lang");
  141                   throw new FatalError(msg);
  142               } else {
  143                   log.error(pos, "doesnt.exist", tsym);
  144               }
  145           }
  146           env.toplevel.starImportScope.importAll(tsym.members());
  147       }
  148   
  149       /** Import all static members of a class or package on demand.
  150        *  @param pos           Position to be used for error reporting.
  151        *  @param tsym          The class or package the members of which are imported.
  152        *  @param toScope   The (import) scope in which imported classes
  153        *               are entered.
  154        */
  155       private void importStaticAll(int pos,
  156                                    final TypeSymbol tsym,
  157                                    Env<AttrContext> env) {
  158           final JavaFileObject sourcefile = env.toplevel.sourcefile;
  159           final Scope toScope = env.toplevel.starImportScope;
  160           final PackageSymbol packge = env.toplevel.packge;
  161           final TypeSymbol origin = tsym;
  162   
  163           // enter imported types immediately
  164           new Object() {
  165               Set<Symbol> processed = new HashSet<Symbol>();
  166               void importFrom(TypeSymbol tsym) {
  167                   if (tsym == null || !processed.add(tsym))
  168                       return;
  169   
  170                   // also import inherited names
  171                   importFrom(types.supertype(tsym.type).tsym);
  172                   for (Type t : types.interfaces(tsym.type))
  173                       importFrom(t.tsym);
  174   
  175                   final Scope fromScope = tsym.members();
  176                   for (Scope.Entry e = fromScope.elems; e != null; e = e.sibling) {
  177                       Symbol sym = e.sym;
  178                       if (sym.kind == TYP &&
  179                           (sym.flags() & STATIC) != 0 &&
  180                           staticImportAccessible(sym, packge) &&
  181                           sym.isMemberOf(origin, types) &&
  182                           !toScope.includes(sym))
  183                           toScope.enter(sym, fromScope, origin.members());
  184                   }
  185               }
  186           }.importFrom(tsym);
  187   
  188           // enter non-types before annotations that might use them
  189           annotate.earlier(new Annotate.Annotator() {
  190               Set<Symbol> processed = new HashSet<Symbol>();
  191   
  192               public String toString() {
  193                   return "import static " + tsym + ".*" + " in " + sourcefile;
  194               }
  195               void importFrom(TypeSymbol tsym) {
  196                   if (tsym == null || !processed.add(tsym))
  197                       return;
  198   
  199                   // also import inherited names
  200                   importFrom(types.supertype(tsym.type).tsym);
  201                   for (Type t : types.interfaces(tsym.type))
  202                       importFrom(t.tsym);
  203   
  204                   final Scope fromScope = tsym.members();
  205                   for (Scope.Entry e = fromScope.elems; e != null; e = e.sibling) {
  206                       Symbol sym = e.sym;
  207                       if (sym.isStatic() && sym.kind != TYP &&
  208                           staticImportAccessible(sym, packge) &&
  209                           !toScope.includes(sym) &&
  210                           sym.isMemberOf(origin, types)) {
  211                           toScope.enter(sym, fromScope, origin.members());
  212                       }
  213                   }
  214               }
  215               public void enterAnnotation() {
  216                   importFrom(tsym);
  217               }
  218           });
  219       }
  220   
  221       // is the sym accessible everywhere in packge?
  222       boolean staticImportAccessible(Symbol sym, PackageSymbol packge) {
  223           int flags = (int)(sym.flags() & AccessFlags);
  224           switch (flags) {
  225           default:
  226           case PUBLIC:
  227               return true;
  228           case PRIVATE:
  229               return false;
  230           case 0:
  231           case PROTECTED:
  232               return sym.packge() == packge;
  233           }
  234       }
  235   
  236       /** Import statics types of a given name.  Non-types are handled in Attr.
  237        *  @param pos           Position to be used for error reporting.
  238        *  @param tsym          The class from which the name is imported.
  239        *  @param name          The (simple) name being imported.
  240        *  @param env           The environment containing the named import
  241        *                  scope to add to.
  242        */
  243       private void importNamedStatic(final DiagnosticPosition pos,
  244                                      final TypeSymbol tsym,
  245                                      final Name name,
  246                                      final Env<AttrContext> env) {
  247           if (tsym.kind != TYP) {
  248               log.error(pos, "static.imp.only.classes.and.interfaces");
  249               return;
  250           }
  251   
  252           final Scope toScope = env.toplevel.namedImportScope;
  253           final PackageSymbol packge = env.toplevel.packge;
  254           final TypeSymbol origin = tsym;
  255   
  256           // enter imported types immediately
  257           new Object() {
  258               Set<Symbol> processed = new HashSet<Symbol>();
  259               void importFrom(TypeSymbol tsym) {
  260                   if (tsym == null || !processed.add(tsym))
  261                       return;
  262   
  263                   // also import inherited names
  264                   importFrom(types.supertype(tsym.type).tsym);
  265                   for (Type t : types.interfaces(tsym.type))
  266                       importFrom(t.tsym);
  267   
  268                   for (Scope.Entry e = tsym.members().lookup(name);
  269                        e.scope != null;
  270                        e = e.next()) {
  271                       Symbol sym = e.sym;
  272                       if (sym.isStatic() &&
  273                           sym.kind == TYP &&
  274                           staticImportAccessible(sym, packge) &&
  275                           sym.isMemberOf(origin, types) &&
  276                           chk.checkUniqueStaticImport(pos, sym, toScope))
  277                           toScope.enter(sym, sym.owner.members(), origin.members());
  278                   }
  279               }
  280           }.importFrom(tsym);
  281   
  282           // enter non-types before annotations that might use them
  283           annotate.earlier(new Annotate.Annotator() {
  284               Set<Symbol> processed = new HashSet<Symbol>();
  285               boolean found = false;
  286   
  287               public String toString() {
  288                   return "import static " + tsym + "." + name;
  289               }
  290               void importFrom(TypeSymbol tsym) {
  291                   if (tsym == null || !processed.add(tsym))
  292                       return;
  293   
  294                   // also import inherited names
  295                   importFrom(types.supertype(tsym.type).tsym);
  296                   for (Type t : types.interfaces(tsym.type))
  297                       importFrom(t.tsym);
  298   
  299                   for (Scope.Entry e = tsym.members().lookup(name);
  300                        e.scope != null;
  301                        e = e.next()) {
  302                       Symbol sym = e.sym;
  303                       if (sym.isStatic() &&
  304                           staticImportAccessible(sym, packge) &&
  305                           sym.isMemberOf(origin, types)) {
  306                           found = true;
  307                           if (sym.kind == MTH ||
  308                               sym.kind != TYP && chk.checkUniqueStaticImport(pos, sym, toScope))
  309                               toScope.enter(sym, sym.owner.members(), origin.members());
  310                       }
  311                   }
  312               }
  313               public void enterAnnotation() {
  314                   JavaFileObject prev = log.useSource(env.toplevel.sourcefile);
  315                   try {
  316                       importFrom(tsym);
  317                       if (!found) {
  318                           log.error(pos, "cant.resolve.location",
  319                                     KindName.STATIC,
  320                                     name, List.<Type>nil(), List.<Type>nil(),
  321                                     Kinds.typeKindName(tsym.type),
  322                                     tsym.type);
  323                       }
  324                   } finally {
  325                       log.useSource(prev);
  326                   }
  327               }
  328           });
  329       }
  330       /** Import given class.
  331        *  @param pos           Position to be used for error reporting.
  332        *  @param tsym          The class to be imported.
  333        *  @param env           The environment containing the named import
  334        *                  scope to add to.
  335        */
  336       private void importNamed(DiagnosticPosition pos, Symbol tsym, Env<AttrContext> env) {
  337           if (tsym.kind == TYP &&
  338               chk.checkUniqueImport(pos, tsym, env.toplevel.namedImportScope))
  339               env.toplevel.namedImportScope.enter(tsym, tsym.owner.members());
  340       }
  341   
  342       /** Construct method type from method signature.
  343        *  @param typarams    The method's type parameters.
  344        *  @param params      The method's value parameters.
  345        *  @param res             The method's result type,
  346        *                 null if it is a constructor.
  347        *  @param thrown      The method's thrown exceptions.
  348        *  @param env             The method's (local) environment.
  349        */
  350       Type signature(List<JCTypeParameter> typarams,
  351                      List<JCVariableDecl> params,
  352                      JCTree res,
  353                      List<JCExpression> thrown,
  354                      Env<AttrContext> env) {
  355   
  356           // Enter and attribute type parameters.
  357           List<Type> tvars = enter.classEnter(typarams, env);
  358           attr.attribTypeVariables(typarams, env);
  359   
  360           // Enter and attribute value parameters.
  361           ListBuffer<Type> argbuf = new ListBuffer<Type>();
  362           for (List<JCVariableDecl> l = params; l.nonEmpty(); l = l.tail) {
  363               memberEnter(l.head, env);
  364               argbuf.append(l.head.vartype.type);
  365           }
  366   
  367           // Attribute result type, if one is given.
  368           Type restype = res == null ? syms.voidType : attr.attribType(res, env);
  369   
  370           // Attribute thrown exceptions.
  371           ListBuffer<Type> thrownbuf = new ListBuffer<Type>();
  372           for (List<JCExpression> l = thrown; l.nonEmpty(); l = l.tail) {
  373               Type exc = attr.attribType(l.head, env);
  374               if (exc.tag != TYPEVAR)
  375                   exc = chk.checkClassType(l.head.pos(), exc);
  376               thrownbuf.append(exc);
  377           }
  378           Type mtype = new MethodType(argbuf.toList(),
  379                                       restype,
  380                                       thrownbuf.toList(),
  381                                       syms.methodClass);
  382           return tvars.isEmpty() ? mtype : new ForAll(tvars, mtype);
  383       }
  384   
  385   /* ********************************************************************
  386    * Visitor methods for member enter
  387    *********************************************************************/
  388   
  389       /** Visitor argument: the current environment
  390        */
  391       protected Env<AttrContext> env;
  392   
  393       /** Enter field and method definitions and process import
  394        *  clauses, catching any completion failure exceptions.
  395        */
  396       protected void memberEnter(JCTree tree, Env<AttrContext> env) {
  397           Env<AttrContext> prevEnv = this.env;
  398           try {
  399               this.env = env;
  400               tree.accept(this);
  401           }  catch (CompletionFailure ex) {
  402               chk.completionError(tree.pos(), ex);
  403           } finally {
  404               this.env = prevEnv;
  405           }
  406       }
  407   
  408       /** Enter members from a list of trees.
  409        */
  410       void memberEnter(List<? extends JCTree> trees, Env<AttrContext> env) {
  411           for (List<? extends JCTree> l = trees; l.nonEmpty(); l = l.tail)
  412               memberEnter(l.head, env);
  413       }
  414   
  415       /** Enter members for a class.
  416        */
  417       void finishClass(JCClassDecl tree, Env<AttrContext> env) {
  418           if ((tree.mods.flags & Flags.ENUM) != 0 &&
  419               (types.supertype(tree.sym.type).tsym.flags() & Flags.ENUM) == 0) {
  420               addEnumMembers(tree, env);
  421           }
  422           memberEnter(tree.defs, env);
  423       }
  424   
  425       /** Add the implicit members for an enum type
  426        *  to the symbol table.
  427        */
  428       private void addEnumMembers(JCClassDecl tree, Env<AttrContext> env) {
  429           JCExpression valuesType = make.Type(new ArrayType(tree.sym.type, syms.arrayClass));
  430   
  431           // public static T[] values() { return ???; }
  432           JCMethodDecl values = make.
  433               MethodDef(make.Modifiers(Flags.PUBLIC|Flags.STATIC),
  434                         names.values,
  435                         valuesType,
  436                         List.<JCTypeParameter>nil(),
  437                         List.<JCVariableDecl>nil(),
  438                         List.<JCExpression>nil(), // thrown
  439                         null, //make.Block(0, Tree.emptyList.prepend(make.Return(make.Ident(names._null)))),
  440                         null);
  441           memberEnter(values, env);
  442   
  443           // public static T valueOf(String name) { return ???; }
  444           JCMethodDecl valueOf = make.
  445               MethodDef(make.Modifiers(Flags.PUBLIC|Flags.STATIC),
  446                         names.valueOf,
  447                         make.Type(tree.sym.type),
  448                         List.<JCTypeParameter>nil(),
  449                         List.of(make.VarDef(make.Modifiers(Flags.PARAMETER),
  450                                               names.fromString("name"),
  451                                               make.Type(syms.stringType), null)),
  452                         List.<JCExpression>nil(), // thrown
  453                         null, //make.Block(0, Tree.emptyList.prepend(make.Return(make.Ident(names._null)))),
  454                         null);
  455           memberEnter(valueOf, env);
  456   
  457           // the remaining members are for bootstrapping only
  458           if (!target.compilerBootstrap(tree.sym)) return;
  459   
  460           // public final int ordinal() { return ???; }
  461           JCMethodDecl ordinal = make.at(tree.pos).
  462               MethodDef(make.Modifiers(Flags.PUBLIC|Flags.FINAL),
  463                         names.ordinal,
  464                         make.Type(syms.intType),
  465                         List.<JCTypeParameter>nil(),
  466                         List.<JCVariableDecl>nil(),
  467                         List.<JCExpression>nil(),
  468                         null,
  469                         null);
  470           memberEnter(ordinal, env);
  471   
  472           // public final String name() { return ???; }
  473           JCMethodDecl name = make.
  474               MethodDef(make.Modifiers(Flags.PUBLIC|Flags.FINAL),
  475                         names._name,
  476                         make.Type(syms.stringType),
  477                         List.<JCTypeParameter>nil(),
  478                         List.<JCVariableDecl>nil(),
  479                         List.<JCExpression>nil(),
  480                         null,
  481                         null);
  482           memberEnter(name, env);
  483   
  484           // public int compareTo(E other) { return ???; }
  485           MethodSymbol compareTo = new
  486               MethodSymbol(Flags.PUBLIC,
  487                            names.compareTo,
  488                            new MethodType(List.of(tree.sym.type),
  489                                           syms.intType,
  490                                           List.<Type>nil(),
  491                                           syms.methodClass),
  492                            tree.sym);
  493           memberEnter(make.MethodDef(compareTo, null), env);
  494       }
  495   
  496       public void visitTopLevel(JCCompilationUnit tree) {
  497           if (tree.starImportScope.elems != null) {
  498               // we must have already processed this toplevel
  499               return;
  500           }
  501   
  502           // check that no class exists with same fully qualified name as
  503           // toplevel package
  504           if (checkClash && tree.pid != null) {
  505               Symbol p = tree.packge;
  506               while (p.owner != syms.rootPackage) {
  507                   p.owner.complete(); // enter all class members of p
  508                   if (syms.classes.get(p.getQualifiedName()) != null) {
  509                       log.error(tree.pos,
  510                                 "pkg.clashes.with.class.of.same.name",
  511                                 p);
  512                   }
  513                   p = p.owner;
  514               }
  515           }
  516   
  517           // process package annotations
  518           annotateLater(tree.packageAnnotations, env, tree.packge);
  519   
  520           // Import-on-demand java.lang.
  521           importAll(tree.pos, reader.enterPackage(names.java_lang), env);
  522   
  523           // Process all import clauses.
  524           memberEnter(tree.defs, env);
  525       }
  526   
  527       // process the non-static imports and the static imports of types.
  528       public void visitImport(JCImport tree) {
  529           JCTree imp = tree.qualid;
  530           Name name = TreeInfo.name(imp);
  531           TypeSymbol p;
  532   
  533           // Create a local environment pointing to this tree to disable
  534           // effects of other imports in Resolve.findGlobalType
  535           Env<AttrContext> localEnv = env.dup(tree);
  536   
  537           // Attribute qualifying package or class.
  538           JCFieldAccess s = (JCFieldAccess) imp;
  539           p = attr.
  540               attribTree(s.selected,
  541                          localEnv,
  542                          tree.staticImport ? TYP : (TYP | PCK),
  543                          Type.noType).tsym;
  544           if (name == names.asterisk) {
  545               // Import on demand.
  546               chk.checkCanonical(s.selected);
  547               if (tree.staticImport)
  548                   importStaticAll(tree.pos, p, env);
  549               else
  550                   importAll(tree.pos, p, env);
  551           } else {
  552               // Named type import.
  553               if (tree.staticImport) {
  554                   importNamedStatic(tree.pos(), p, name, localEnv);
  555                   chk.checkCanonical(s.selected);
  556               } else {
  557                   TypeSymbol c = attribImportType(imp, localEnv).tsym;
  558                   chk.checkCanonical(imp);
  559                   importNamed(tree.pos(), c, env);
  560               }
  561           }
  562       }
  563   
  564       public void visitMethodDef(JCMethodDecl tree) {
  565           Scope enclScope = enter.enterScope(env);
  566           MethodSymbol m = new MethodSymbol(0, tree.name, null, enclScope.owner);
  567           m.flags_field = chk.checkFlags(tree.pos(), tree.mods.flags, m, tree);
  568           tree.sym = m;
  569           Env<AttrContext> localEnv = methodEnv(tree, env);
  570   
  571           DeferredLintHandler prevLintHandler =
  572                   chk.setDeferredLintHandler(deferredLintHandler.setPos(tree.pos()));
  573           try {
  574               // Compute the method type
  575               m.type = signature(tree.typarams, tree.params,
  576                                  tree.restype, tree.thrown,
  577                                  localEnv);
  578           } finally {
  579               chk.setDeferredLintHandler(prevLintHandler);
  580           }
  581   
  582           // Set m.params
  583           ListBuffer<VarSymbol> params = new ListBuffer<VarSymbol>();
  584           JCVariableDecl lastParam = null;
  585           for (List<JCVariableDecl> l = tree.params; l.nonEmpty(); l = l.tail) {
  586               JCVariableDecl param = lastParam = l.head;
  587               params.append(Assert.checkNonNull(param.sym));
  588           }
  589           m.params = params.toList();
  590   
  591           // mark the method varargs, if necessary
  592           if (lastParam != null && (lastParam.mods.flags & Flags.VARARGS) != 0)
  593               m.flags_field |= Flags.VARARGS;
  594   
  595           localEnv.info.scope.leave();
  596           if (chk.checkUnique(tree.pos(), m, enclScope)) {
  597               enclScope.enter(m);
  598           }
  599           annotateLater(tree.mods.annotations, localEnv, m);
  600           if (tree.defaultValue != null)
  601               annotateDefaultValueLater(tree.defaultValue, localEnv, m);
  602       }
  603   
  604       /** Create a fresh environment for method bodies.
  605        *  @param tree     The method definition.
  606        *  @param env      The environment current outside of the method definition.
  607        */
  608       Env<AttrContext> methodEnv(JCMethodDecl tree, Env<AttrContext> env) {
  609           Env<AttrContext> localEnv =
  610               env.dup(tree, env.info.dup(env.info.scope.dupUnshared()));
  611           localEnv.enclMethod = tree;
  612           localEnv.info.scope.owner = tree.sym;
  613           if ((tree.mods.flags & STATIC) != 0) localEnv.info.staticLevel++;
  614           return localEnv;
  615       }
  616   
  617       public void visitVarDef(JCVariableDecl tree) {
  618           Env<AttrContext> localEnv = env;
  619           if ((tree.mods.flags & STATIC) != 0 ||
  620               (env.info.scope.owner.flags() & INTERFACE) != 0) {
  621               localEnv = env.dup(tree, env.info.dup());
  622               localEnv.info.staticLevel++;
  623           }
  624           DeferredLintHandler prevLintHandler =
  625                   chk.setDeferredLintHandler(deferredLintHandler.setPos(tree.pos()));
  626           try {
  627               attr.attribType(tree.vartype, localEnv);
  628           } finally {
  629               chk.setDeferredLintHandler(prevLintHandler);
  630           }
  631   
  632           if ((tree.mods.flags & VARARGS) != 0) {
  633               //if we are entering a varargs parameter, we need to replace its type
  634               //(a plain array type) with the more precise VarargsType --- we need
  635               //to do it this way because varargs is represented in the tree as a modifier
  636               //on the parameter declaration, and not as a distinct type of array node.
  637               ArrayType atype = (ArrayType)tree.vartype.type;
  638               tree.vartype.type = atype.makeVarargs();
  639           }
  640           Scope enclScope = enter.enterScope(env);
  641           VarSymbol v =
  642               new VarSymbol(0, tree.name, tree.vartype.type, enclScope.owner);
  643           v.flags_field = chk.checkFlags(tree.pos(), tree.mods.flags, v, tree);
  644           tree.sym = v;
  645           if (tree.init != null) {
  646               v.flags_field |= HASINIT;
  647               if ((v.flags_field & FINAL) != 0 && tree.init.getTag() != JCTree.NEWCLASS) {
  648                   Env<AttrContext> initEnv = getInitEnv(tree, env);
  649                   initEnv.info.enclVar = v;
  650                   v.setLazyConstValue(initEnv(tree, initEnv), attr, tree.init);
  651               }
  652           }
  653           if (chk.checkUnique(tree.pos(), v, enclScope)) {
  654               chk.checkTransparentVar(tree.pos(), v, enclScope);
  655               enclScope.enter(v);
  656           }
  657           annotateLater(tree.mods.annotations, localEnv, v);
  658           v.pos = tree.pos;
  659       }
  660   
  661       /** Create a fresh environment for a variable's initializer.
  662        *  If the variable is a field, the owner of the environment's scope
  663        *  is be the variable itself, otherwise the owner is the method
  664        *  enclosing the variable definition.
  665        *
  666        *  @param tree     The variable definition.
  667        *  @param env      The environment current outside of the variable definition.
  668        */
  669       Env<AttrContext> initEnv(JCVariableDecl tree, Env<AttrContext> env) {
  670           Env<AttrContext> localEnv = env.dupto(new AttrContextEnv(tree, env.info.dup()));
  671           if (tree.sym.owner.kind == TYP) {
  672               localEnv.info.scope = new Scope.DelegatedScope(env.info.scope);
  673               localEnv.info.scope.owner = tree.sym;
  674           }
  675           if ((tree.mods.flags & STATIC) != 0 ||
  676               (env.enclClass.sym.flags() & INTERFACE) != 0)
  677               localEnv.info.staticLevel++;
  678           return localEnv;
  679       }
  680   
  681       /** Default member enter visitor method: do nothing
  682        */
  683       public void visitTree(JCTree tree) {
  684       }
  685   
  686       public void visitErroneous(JCErroneous tree) {
  687           if (tree.errs != null)
  688               memberEnter(tree.errs, env);
  689       }
  690   
  691       public Env<AttrContext> getMethodEnv(JCMethodDecl tree, Env<AttrContext> env) {
  692           Env<AttrContext> mEnv = methodEnv(tree, env);
  693           mEnv.info.lint = mEnv.info.lint.augment(tree.sym.attributes_field, tree.sym.flags());
  694           for (List<JCTypeParameter> l = tree.typarams; l.nonEmpty(); l = l.tail)
  695               mEnv.info.scope.enterIfAbsent(l.head.type.tsym);
  696           for (List<JCVariableDecl> l = tree.params; l.nonEmpty(); l = l.tail)
  697               mEnv.info.scope.enterIfAbsent(l.head.sym);
  698           return mEnv;
  699       }
  700   
  701       public Env<AttrContext> getInitEnv(JCVariableDecl tree, Env<AttrContext> env) {
  702           Env<AttrContext> iEnv = initEnv(tree, env);
  703           return iEnv;
  704       }
  705   
  706   /* ********************************************************************
  707    * Type completion
  708    *********************************************************************/
  709   
  710       Type attribImportType(JCTree tree, Env<AttrContext> env) {
  711           Assert.check(completionEnabled);
  712           try {
  713               // To prevent deep recursion, suppress completion of some
  714               // types.
  715               completionEnabled = false;
  716               return attr.attribType(tree, env);
  717           } finally {
  718               completionEnabled = true;
  719           }
  720       }
  721   
  722   /* ********************************************************************
  723    * Annotation processing
  724    *********************************************************************/
  725   
  726       /** Queue annotations for later processing. */
  727       void annotateLater(final List<JCAnnotation> annotations,
  728                          final Env<AttrContext> localEnv,
  729                          final Symbol s) {
  730           if (annotations.isEmpty()) return;
  731           if (s.kind != PCK) s.attributes_field = null; // mark it incomplete for now
  732           annotate.later(new Annotate.Annotator() {
  733                   public String toString() {
  734                       return "annotate " + annotations + " onto " + s + " in " + s.owner;
  735                   }
  736                   public void enterAnnotation() {
  737                       Assert.check(s.kind == PCK || s.attributes_field == null);
  738                       JavaFileObject prev = log.useSource(localEnv.toplevel.sourcefile);
  739                       try {
  740                           if (s.attributes_field != null &&
  741                               s.attributes_field.nonEmpty() &&
  742                               annotations.nonEmpty())
  743                               log.error(annotations.head.pos,
  744                                         "already.annotated",
  745                                         kindName(s), s);
  746                           enterAnnotations(annotations, localEnv, s);
  747                       } finally {
  748                           log.useSource(prev);
  749                       }
  750                   }
  751               });
  752       }
  753   
  754       /**
  755        * Check if a list of annotations contains a reference to
  756        * java.lang.Deprecated.
  757        **/
  758       private boolean hasDeprecatedAnnotation(List<JCAnnotation> annotations) {
  759           for (List<JCAnnotation> al = annotations; al.nonEmpty(); al = al.tail) {
  760               JCAnnotation a = al.head;
  761               if (a.annotationType.type == syms.deprecatedType && a.args.isEmpty())
  762                   return true;
  763           }
  764           return false;
  765       }
  766   
  767   
  768       /** Enter a set of annotations. */
  769       private void enterAnnotations(List<JCAnnotation> annotations,
  770                             Env<AttrContext> env,
  771                             Symbol s) {
  772           ListBuffer<Attribute.Compound> buf =
  773               new ListBuffer<Attribute.Compound>();
  774           Set<TypeSymbol> annotated = new HashSet<TypeSymbol>();
  775           if (!skipAnnotations)
  776           for (List<JCAnnotation> al = annotations; al.nonEmpty(); al = al.tail) {
  777               JCAnnotation a = al.head;
  778               Attribute.Compound c = annotate.enterAnnotation(a,
  779                                                               syms.annotationType,
  780                                                               env);
  781               if (c == null) continue;
  782               buf.append(c);
  783               // Note: @Deprecated has no effect on local variables and parameters
  784               if (!c.type.isErroneous()
  785                   && s.owner.kind != MTH
  786                   && types.isSameType(c.type, syms.deprecatedType))
  787                   s.flags_field |= Flags.DEPRECATED;
  788               // Internally to java.lang.invoke, a @PolymorphicSignature annotation
  789               // acts like a classfile attribute.
  790               if (!c.type.isErroneous() &&
  791                   types.isSameType(c.type, syms.polymorphicSignatureType)) {
  792                   if (!target.hasMethodHandles()) {
  793                       // Somebody is compiling JDK7 source code to a JDK6 target.
  794                       // Make it an error, since it is unlikely but important.
  795                       log.error(env.tree.pos(),
  796                               "wrong.target.for.polymorphic.signature.definition",
  797                               target.name);
  798                   }
  799                   // Pull the flag through for better diagnostics, even on a bad target.
  800                   s.flags_field |= Flags.POLYMORPHIC_SIGNATURE;
  801               }
  802               if (!annotated.add(a.type.tsym))
  803                   log.error(a.pos, "duplicate.annotation");
  804           }
  805           s.attributes_field = buf.toList();
  806       }
  807   
  808       /** Queue processing of an attribute default value. */
  809       void annotateDefaultValueLater(final JCExpression defaultValue,
  810                                      final Env<AttrContext> localEnv,
  811                                      final MethodSymbol m) {
  812           annotate.later(new Annotate.Annotator() {
  813                   public String toString() {
  814                       return "annotate " + m.owner + "." +
  815                           m + " default " + defaultValue;
  816                   }
  817                   public void enterAnnotation() {
  818                       JavaFileObject prev = log.useSource(localEnv.toplevel.sourcefile);
  819                       try {
  820                           enterDefaultValue(defaultValue, localEnv, m);
  821                       } finally {
  822                           log.useSource(prev);
  823                       }
  824                   }
  825               });
  826       }
  827   
  828       /** Enter a default value for an attribute method. */
  829       private void enterDefaultValue(final JCExpression defaultValue,
  830                                      final Env<AttrContext> localEnv,
  831                                      final MethodSymbol m) {
  832           m.defaultValue = annotate.enterAttributeValue(m.type.getReturnType(),
  833                                                         defaultValue,
  834                                                         localEnv);
  835       }
  836   
  837   /* ********************************************************************
  838    * Source completer
  839    *********************************************************************/
  840   
  841       /** Complete entering a class.
  842        *  @param sym         The symbol of the class to be completed.
  843        */
  844       public void complete(Symbol sym) throws CompletionFailure {
  845           // Suppress some (recursive) MemberEnter invocations
  846           if (!completionEnabled) {
  847               // Re-install same completer for next time around and return.
  848               Assert.check((sym.flags() & Flags.COMPOUND) == 0);
  849               sym.completer = this;
  850               return;
  851           }
  852   
  853           ClassSymbol c = (ClassSymbol)sym;
  854           ClassType ct = (ClassType)c.type;
  855           Env<AttrContext> env = enter.typeEnvs.get(c);
  856           JCClassDecl tree = (JCClassDecl)env.tree;
  857           boolean wasFirst = isFirst;
  858           isFirst = false;
  859   
  860           JavaFileObject prev = log.useSource(env.toplevel.sourcefile);
  861           try {
  862               // Save class environment for later member enter (2) processing.
  863               halfcompleted.append(env);
  864   
  865               // Mark class as not yet attributed.
  866               c.flags_field |= UNATTRIBUTED;
  867   
  868               // If this is a toplevel-class, make sure any preceding import
  869               // clauses have been seen.
  870               if (c.owner.kind == PCK) {
  871                   memberEnter(env.toplevel, env.enclosing(JCTree.TOPLEVEL));
  872                   todo.append(env);
  873               }
  874   
  875               if (c.owner.kind == TYP)
  876                   c.owner.complete();
  877   
  878               // create an environment for evaluating the base clauses
  879               Env<AttrContext> baseEnv = baseEnv(tree, env);
  880   
  881               // Determine supertype.
  882               Type supertype =
  883                   (tree.extending != null)
  884                   ? attr.attribBase(tree.extending, baseEnv, true, false, true)
  885                   : ((tree.mods.flags & Flags.ENUM) != 0 && !target.compilerBootstrap(c))
  886                   ? attr.attribBase(enumBase(tree.pos, c), baseEnv,
  887                                     true, false, false)
  888                   : (c.fullname == names.java_lang_Object)
  889                   ? Type.noType
  890                   : syms.objectType;
  891               ct.supertype_field = modelMissingTypes(supertype, tree.extending, false);
  892   
  893               // Determine interfaces.
  894               ListBuffer<Type> interfaces = new ListBuffer<Type>();
  895               ListBuffer<Type> all_interfaces = null; // lazy init
  896               Set<Type> interfaceSet = new HashSet<Type>();
  897               List<JCExpression> interfaceTrees = tree.implementing;
  898               if ((tree.mods.flags & Flags.ENUM) != 0 && target.compilerBootstrap(c)) {
  899                   // add interface Comparable<T>
  900                   interfaceTrees =
  901                       interfaceTrees.prepend(make.Type(new ClassType(syms.comparableType.getEnclosingType(),
  902                                                                      List.of(c.type),
  903                                                                      syms.comparableType.tsym)));
  904                   // add interface Serializable
  905                   interfaceTrees =
  906                       interfaceTrees.prepend(make.Type(syms.serializableType));
  907               }
  908               for (JCExpression iface : interfaceTrees) {
  909                   Type i = attr.attribBase(iface, baseEnv, false, true, true);
  910                   if (i.tag == CLASS) {
  911                       interfaces.append(i);
  912                       if (all_interfaces != null) all_interfaces.append(i);
  913                       chk.checkNotRepeated(iface.pos(), types.erasure(i), interfaceSet);
  914                   } else {
  915                       if (all_interfaces == null)
  916                           all_interfaces = new ListBuffer<Type>().appendList(interfaces);
  917                       all_interfaces.append(modelMissingTypes(i, iface, true));
  918                   }
  919               }
  920               if ((c.flags_field & ANNOTATION) != 0) {
  921                   ct.interfaces_field = List.of(syms.annotationType);
  922                   ct.all_interfaces_field = ct.interfaces_field;
  923               }  else {
  924                   ct.interfaces_field = interfaces.toList();
  925                   ct.all_interfaces_field = (all_interfaces == null)
  926                           ? ct.interfaces_field : all_interfaces.toList();
  927               }
  928   
  929               if (c.fullname == names.java_lang_Object) {
  930                   if (tree.extending != null) {
  931                       chk.checkNonCyclic(tree.extending.pos(),
  932                                          supertype);
  933                       ct.supertype_field = Type.noType;
  934                   }
  935                   else if (tree.implementing.nonEmpty()) {
  936                       chk.checkNonCyclic(tree.implementing.head.pos(),
  937                                          ct.interfaces_field.head);
  938                       ct.interfaces_field = List.nil();
  939                   }
  940               }
  941   
  942               // Annotations.
  943               // In general, we cannot fully process annotations yet,  but we
  944               // can attribute the annotation types and then check to see if the
  945               // @Deprecated annotation is present.
  946               attr.attribAnnotationTypes(tree.mods.annotations, baseEnv);
  947               if (hasDeprecatedAnnotation(tree.mods.annotations))
  948                   c.flags_field |= DEPRECATED;
  949               annotateLater(tree.mods.annotations, baseEnv, c);
  950   
  951               chk.checkNonCyclicDecl(tree);
  952   
  953               attr.attribTypeVariables(tree.typarams, baseEnv);
  954   
  955               // Add default constructor if needed.
  956               if ((c.flags() & INTERFACE) == 0 &&
  957                   !TreeInfo.hasConstructors(tree.defs)) {
  958                   List<Type> argtypes = List.nil();
  959                   List<Type> typarams = List.nil();
  960                   List<Type> thrown = List.nil();
  961                   long ctorFlags = 0;
  962                   boolean based = false;
  963                   if (c.name.isEmpty()) {
  964                       JCNewClass nc = (JCNewClass)env.next.tree;
  965                       if (nc.constructor != null) {
  966                           Type superConstrType = types.memberType(c.type,
  967                                                                   nc.constructor);
  968                           argtypes = superConstrType.getParameterTypes();
  969                           typarams = superConstrType.getTypeArguments();
  970                           ctorFlags = nc.constructor.flags() & VARARGS;
  971                           if (nc.encl != null) {
  972                               argtypes = argtypes.prepend(nc.encl.type);
  973                               based = true;
  974                           }
  975                           thrown = superConstrType.getThrownTypes();
  976                       }
  977                   }
  978                   JCTree constrDef = DefaultConstructor(make.at(tree.pos), c,
  979                                                       typarams, argtypes, thrown,
  980                                                       ctorFlags, based);
  981                   tree.defs = tree.defs.prepend(constrDef);
  982               }
  983   
  984               // If this is a class, enter symbols for this and super into
  985               // current scope.
  986               if ((c.flags_field & INTERFACE) == 0) {
  987                   VarSymbol thisSym =
  988                       new VarSymbol(FINAL | HASINIT, names._this, c.type, c);
  989                   thisSym.pos = Position.FIRSTPOS;
  990                   env.info.scope.enter(thisSym);
  991                   if (ct.supertype_field.tag == CLASS) {
  992                       VarSymbol superSym =
  993                           new VarSymbol(FINAL | HASINIT, names._super,
  994                                         ct.supertype_field, c);
  995                       superSym.pos = Position.FIRSTPOS;
  996                       env.info.scope.enter(superSym);
  997                   }
  998               }
  999   
 1000               // check that no package exists with same fully qualified name,
 1001               // but admit classes in the unnamed package which have the same
 1002               // name as a top-level package.
 1003               if (checkClash &&
 1004                   c.owner.kind == PCK && c.owner != syms.unnamedPackage &&
 1005                   reader.packageExists(c.fullname))
 1006                   {
 1007                       log.error(tree.pos, "clash.with.pkg.of.same.name", Kinds.kindName(sym), c);
 1008                   }
 1009   
 1010           } catch (CompletionFailure ex) {
 1011               chk.completionError(tree.pos(), ex);
 1012           } finally {
 1013               log.useSource(prev);
 1014           }
 1015   
 1016           // Enter all member fields and methods of a set of half completed
 1017           // classes in a second phase.
 1018           if (wasFirst) {
 1019               try {
 1020                   while (halfcompleted.nonEmpty()) {
 1021                       finish(halfcompleted.next());
 1022                   }
 1023               } finally {
 1024                   isFirst = true;
 1025               }
 1026   
 1027               // commit pending annotations
 1028               annotate.flush();
 1029           }
 1030       }
 1031   
 1032       private Env<AttrContext> baseEnv(JCClassDecl tree, Env<AttrContext> env) {
 1033           Scope baseScope = new Scope(tree.sym);
 1034           //import already entered local classes into base scope
 1035           for (Scope.Entry e = env.outer.info.scope.elems ; e != null ; e = e.sibling) {
 1036               if (e.sym.isLocal()) {
 1037                   baseScope.enter(e.sym);
 1038               }
 1039           }
 1040           //import current type-parameters into base scope
 1041           if (tree.typarams != null)
 1042               for (List<JCTypeParameter> typarams = tree.typarams;
 1043                    typarams.nonEmpty();
 1044                    typarams = typarams.tail)
 1045                   baseScope.enter(typarams.head.type.tsym);
 1046           Env<AttrContext> outer = env.outer; // the base clause can't see members of this class
 1047           Env<AttrContext> localEnv = outer.dup(tree, outer.info.dup(baseScope));
 1048           localEnv.baseClause = true;
 1049           localEnv.outer = outer;
 1050           localEnv.info.isSelfCall = false;
 1051           return localEnv;
 1052       }
 1053   
 1054       /** Enter member fields and methods of a class
 1055        *  @param env        the environment current for the class block.
 1056        */
 1057       private void finish(Env<AttrContext> env) {
 1058           JavaFileObject prev = log.useSource(env.toplevel.sourcefile);
 1059           try {
 1060               JCClassDecl tree = (JCClassDecl)env.tree;
 1061               finishClass(tree, env);
 1062           } finally {
 1063               log.useSource(prev);
 1064           }
 1065       }
 1066   
 1067       /** Generate a base clause for an enum type.
 1068        *  @param pos              The position for trees and diagnostics, if any
 1069        *  @param c                The class symbol of the enum
 1070        */
 1071       private JCExpression enumBase(int pos, ClassSymbol c) {
 1072           JCExpression result = make.at(pos).
 1073               TypeApply(make.QualIdent(syms.enumSym),
 1074                         List.<JCExpression>of(make.Type(c.type)));
 1075           return result;
 1076       }
 1077   
 1078       Type modelMissingTypes(Type t, final JCExpression tree, final boolean interfaceExpected) {
 1079           if (t.tag != ERROR)
 1080               return t;
 1081   
 1082           return new ErrorType(((ErrorType) t).getOriginalType(), t.tsym) {
 1083               private Type modelType;
 1084   
 1085               @Override
 1086               public Type getModelType() {
 1087                   if (modelType == null)
 1088                       modelType = new Synthesizer(getOriginalType(), interfaceExpected).visit(tree);
 1089                   return modelType;
 1090               }
 1091           };
 1092       }
 1093       // where
 1094       private class Synthesizer extends JCTree.Visitor {
 1095           Type originalType;
 1096           boolean interfaceExpected;
 1097           List<ClassSymbol> synthesizedSymbols = List.nil();
 1098           Type result;
 1099   
 1100           Synthesizer(Type originalType, boolean interfaceExpected) {
 1101               this.originalType = originalType;
 1102               this.interfaceExpected = interfaceExpected;
 1103           }
 1104   
 1105           Type visit(JCTree tree) {
 1106               tree.accept(this);
 1107               return result;
 1108           }
 1109   
 1110           List<Type> visit(List<? extends JCTree> trees) {
 1111               ListBuffer<Type> lb = new ListBuffer<Type>();
 1112               for (JCTree t: trees)
 1113                   lb.append(visit(t));
 1114               return lb.toList();
 1115           }
 1116   
 1117           @Override
 1118           public void visitTree(JCTree tree) {
 1119               result = syms.errType;
 1120           }
 1121   
 1122           @Override
 1123           public void visitIdent(JCIdent tree) {
 1124               if (tree.type.tag != ERROR) {
 1125                   result = tree.type;
 1126               } else {
 1127                   result = synthesizeClass(tree.name, syms.unnamedPackage).type;
 1128               }
 1129           }
 1130   
 1131           @Override
 1132           public void visitSelect(JCFieldAccess tree) {
 1133               if (tree.type.tag != ERROR) {
 1134                   result = tree.type;
 1135               } else {
 1136                   Type selectedType;
 1137                   boolean prev = interfaceExpected;
 1138                   try {
 1139                       interfaceExpected = false;
 1140                       selectedType = visit(tree.selected);
 1141                   } finally {
 1142                       interfaceExpected = prev;
 1143                   }
 1144                   ClassSymbol c = synthesizeClass(tree.name, selectedType.tsym);
 1145                   result = c.type;
 1146               }
 1147           }
 1148   
 1149           @Override
 1150           public void visitTypeApply(JCTypeApply tree) {
 1151               if (tree.type.tag != ERROR) {
 1152                   result = tree.type;
 1153               } else {
 1154                   ClassType clazzType = (ClassType) visit(tree.clazz);
 1155                   if (synthesizedSymbols.contains(clazzType.tsym))
 1156                       synthesizeTyparams((ClassSymbol) clazzType.tsym, tree.arguments.size());
 1157                   final List<Type> actuals = visit(tree.arguments);
 1158                   result = new ErrorType(tree.type, clazzType.tsym) {
 1159                       @Override
 1160                       public List<Type> getTypeArguments() {
 1161                           return actuals;
 1162                       }
 1163                   };
 1164               }
 1165           }
 1166   
 1167           ClassSymbol synthesizeClass(Name name, Symbol owner) {
 1168               int flags = interfaceExpected ? INTERFACE : 0;
 1169               ClassSymbol c = new ClassSymbol(flags, name, owner);
 1170               c.members_field = new Scope.ErrorScope(c);
 1171               c.type = new ErrorType(originalType, c) {
 1172                   @Override
 1173                   public List<Type> getTypeArguments() {
 1174                       return typarams_field;
 1175                   }
 1176               };
 1177               synthesizedSymbols = synthesizedSymbols.prepend(c);
 1178               return c;
 1179           }
 1180   
 1181           void synthesizeTyparams(ClassSymbol sym, int n) {
 1182               ClassType ct = (ClassType) sym.type;
 1183               Assert.check(ct.typarams_field.isEmpty());
 1184               if (n == 1) {
 1185                   TypeVar v = new TypeVar(names.fromString("T"), sym, syms.botType);
 1186                   ct.typarams_field = ct.typarams_field.prepend(v);
 1187               } else {
 1188                   for (int i = n; i > 0; i--) {
 1189                       TypeVar v = new TypeVar(names.fromString("T" + i), sym, syms.botType);
 1190                       ct.typarams_field = ct.typarams_field.prepend(v);
 1191                   }
 1192               }
 1193           }
 1194       }
 1195   
 1196   
 1197   /* ***************************************************************************
 1198    * tree building
 1199    ****************************************************************************/
 1200   
 1201       /** Generate default constructor for given class. For classes different
 1202        *  from java.lang.Object, this is:
 1203        *
 1204        *    c(argtype_0 x_0, ..., argtype_n x_n) throws thrown {
 1205        *      super(x_0, ..., x_n)
 1206        *    }
 1207        *
 1208        *  or, if based == true:
 1209        *
 1210        *    c(argtype_0 x_0, ..., argtype_n x_n) throws thrown {
 1211        *      x_0.super(x_1, ..., x_n)
 1212        *    }
 1213        *
 1214        *  @param make     The tree factory.
 1215        *  @param c        The class owning the default constructor.
 1216        *  @param argtypes The parameter types of the constructor.
 1217        *  @param thrown   The thrown exceptions of the constructor.
 1218        *  @param based    Is first parameter a this$n?
 1219        */
 1220       JCTree DefaultConstructor(TreeMaker make,
 1221                               ClassSymbol c,
 1222                               List<Type> typarams,
 1223                               List<Type> argtypes,
 1224                               List<Type> thrown,
 1225                               long flags,
 1226                               boolean based) {
 1227           List<JCVariableDecl> params = make.Params(argtypes, syms.noSymbol);
 1228           List<JCStatement> stats = List.nil();
 1229           if (c.type != syms.objectType)
 1230               stats = stats.prepend(SuperCall(make, typarams, params, based));
 1231           if ((c.flags() & ENUM) != 0 &&
 1232               (types.supertype(c.type).tsym == syms.enumSym ||
 1233                target.compilerBootstrap(c))) {
 1234               // constructors of true enums are private
 1235               flags = (flags & ~AccessFlags) | PRIVATE | GENERATEDCONSTR;
 1236           } else
 1237               flags |= (c.flags() & AccessFlags) | GENERATEDCONSTR;
 1238           if (c.name.isEmpty()) flags |= ANONCONSTR;
 1239           JCTree result = make.MethodDef(
 1240               make.Modifiers(flags),
 1241               names.init,
 1242               null,
 1243               make.TypeParams(typarams),
 1244               params,
 1245               make.Types(thrown),
 1246               make.Block(0, stats),
 1247               null);
 1248           return result;
 1249       }
 1250   
 1251       /** Generate call to superclass constructor. This is:
 1252        *
 1253        *    super(id_0, ..., id_n)
 1254        *
 1255        * or, if based == true
 1256        *
 1257        *    id_0.super(id_1,...,id_n)
 1258        *
 1259        *  where id_0, ..., id_n are the names of the given parameters.
 1260        *
 1261        *  @param make    The tree factory
 1262        *  @param params  The parameters that need to be passed to super
 1263        *  @param typarams  The type parameters that need to be passed to super
 1264        *  @param based   Is first parameter a this$n?
 1265        */
 1266       JCExpressionStatement SuperCall(TreeMaker make,
 1267                      List<Type> typarams,
 1268                      List<JCVariableDecl> params,
 1269                      boolean based) {
 1270           JCExpression meth;
 1271           if (based) {
 1272               meth = make.Select(make.Ident(params.head), names._super);
 1273               params = params.tail;
 1274           } else {
 1275               meth = make.Ident(names._super);
 1276           }
 1277           List<JCExpression> typeargs = typarams.nonEmpty() ? make.Types(typarams) : null;
 1278           return make.Exec(make.Apply(typeargs, meth, make.Idents(params)));
 1279       }
 1280   }

Home » openjdk-7 » com.sun.tools » javac » comp » [javadoc | source]