1 /*
2  * Copyright (c) 2003, 2013, 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.HashMap;
29 import java.util.HashSet;
30 import java.util.LinkedHashMap;
31 import java.util.Map;
32 import java.util.Set;
33 
34 import javax.tools.JavaFileObject;
35 
36 import com.sun.tools.javac.code.*;
37 import com.sun.tools.javac.jvm.*;
38 import com.sun.tools.javac.tree.*;
39 import com.sun.tools.javac.util.*;
40 
41 import com.sun.tools.javac.code.Type.*;
42 import com.sun.tools.javac.code.Symbol.*;
43 import com.sun.tools.javac.tree.JCTree.*;
44 
45 import static com.sun.tools.javac.code.Flags.*;
46 import static com.sun.tools.javac.code.Flags.ANNOTATION;
47 import static com.sun.tools.javac.code.Kinds.*;
48 import static com.sun.tools.javac.code.TypeTag.CLASS;
49 import static com.sun.tools.javac.code.TypeTag.ERROR;
50 import static com.sun.tools.javac.code.TypeTag.TYPEVAR;
51 import static com.sun.tools.javac.tree.JCTree.Tag.*;
52 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticFlag;
53 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
54 
55 /** This is the second phase of Enter, in which classes are completed
56  *  by entering their members into the class scope using
57  *  MemberEnter.complete().  See Enter for an overview.
58  *
59  *  <p><b>This is NOT part of any supported API.
60  *  If you write code that depends on this, you do so at your own risk.
61  *  This code and its internal interfaces are subject to change or
62  *  deletion without notice.</b>
63  */
64 public class MemberEnter extends JCTree.Visitor implements Completer {
65     protected static final Context.Key<MemberEnter> memberEnterKey =
66         new Context.Key<MemberEnter>();
67 
68     /** A switch to determine whether we check for package/class conflicts
69      */
70     final static boolean checkClash = true;
71 
72     private final Names names;
73     private final Enter enter;
74     private final Log log;
75     private final Check chk;
76     private final Attr attr;
77     private final Symtab syms;
78     private final TreeMaker make;
79     private final ClassReader reader;
80     private final Todo todo;
81     private final Annotate annotate;
82     private final TypeAnnotations typeAnnotations;
83     private final Types types;
84     private final JCDiagnostic.Factory diags;
85     private final Source source;
86     private final Target target;
87     private final DeferredLintHandler deferredLintHandler;
88     private final Lint lint;
89     private final TypeEnvs typeEnvs;
90 
instance(Context context)91     public static MemberEnter instance(Context context) {
92         MemberEnter instance = context.get(memberEnterKey);
93         if (instance == null)
94             instance = new MemberEnter(context);
95         return instance;
96     }
97 
MemberEnter(Context context)98     protected MemberEnter(Context context) {
99         context.put(memberEnterKey, this);
100         names = Names.instance(context);
101         enter = Enter.instance(context);
102         log = Log.instance(context);
103         chk = Check.instance(context);
104         attr = Attr.instance(context);
105         syms = Symtab.instance(context);
106         make = TreeMaker.instance(context);
107         reader = ClassReader.instance(context);
108         todo = Todo.instance(context);
109         annotate = Annotate.instance(context);
110         typeAnnotations = TypeAnnotations.instance(context);
111         types = Types.instance(context);
112         diags = JCDiagnostic.Factory.instance(context);
113         source = Source.instance(context);
114         target = Target.instance(context);
115         deferredLintHandler = DeferredLintHandler.instance(context);
116         lint = Lint.instance(context);
117         typeEnvs = TypeEnvs.instance(context);
118         allowTypeAnnos = source.allowTypeAnnotations();
119         allowRepeatedAnnos = source.allowRepeatedAnnotations();
120     }
121 
122     /** Switch: support type annotations.
123      */
124     boolean allowTypeAnnos;
125 
126     boolean allowRepeatedAnnos;
127 
128     /** A queue for classes whose members still need to be entered into the
129      *  symbol table.
130      */
131     ListBuffer<Env<AttrContext>> halfcompleted = new ListBuffer<Env<AttrContext>>();
132 
133     /** Set to true only when the first of a set of classes is
134      *  processed from the half completed queue.
135      */
136     boolean isFirst = true;
137 
138     /** A flag to disable completion from time to time during member
139      *  enter, as we only need to look up types.  This avoids
140      *  unnecessarily deep recursion.
141      */
142     boolean completionEnabled = true;
143 
144     /* ---------- Processing import clauses ----------------
145      */
146 
147     /** Import all classes of a class or package on demand.
148      *  @param pos           Position to be used for error reporting.
149      *  @param tsym          The class or package the members of which are imported.
150      *  @param env           The env in which the imported classes will be entered.
151      */
importAll(int pos, final TypeSymbol tsym, Env<AttrContext> env)152     private void importAll(int pos,
153                            final TypeSymbol tsym,
154                            Env<AttrContext> env) {
155         // Check that packages imported from exist (JLS ???).
156         if (tsym.kind == PCK && tsym.members().elems == null && !tsym.exists()) {
157             // If we can't find java.lang, exit immediately.
158             if (((PackageSymbol)tsym).fullname.equals(names.java_lang)) {
159                 JCDiagnostic msg = diags.fragment("fatal.err.no.java.lang");
160                 throw new FatalError(msg);
161             } else {
162                 log.error(DiagnosticFlag.RESOLVE_ERROR, pos, "doesnt.exist", tsym);
163             }
164         }
165         env.toplevel.starImportScope.importAll(tsym.members());
166     }
167 
168     /** Import all static members of a class or package on demand.
169      *  @param pos           Position to be used for error reporting.
170      *  @param tsym          The class or package the members of which are imported.
171      *  @param env           The env in which the imported classes will be entered.
172      */
importStaticAll(int pos, final TypeSymbol tsym, Env<AttrContext> env)173     private void importStaticAll(int pos,
174                                  final TypeSymbol tsym,
175                                  Env<AttrContext> env) {
176         final JavaFileObject sourcefile = env.toplevel.sourcefile;
177         final Scope toScope = env.toplevel.starImportScope;
178         final PackageSymbol packge = env.toplevel.packge;
179         final TypeSymbol origin = tsym;
180 
181         // enter imported types immediately
182         new Object() {
183             Set<Symbol> processed = new HashSet<Symbol>();
184             void importFrom(TypeSymbol tsym) {
185                 if (tsym == null || !processed.add(tsym))
186                     return;
187 
188                 // also import inherited names
189                 importFrom(types.supertype(tsym.type).tsym);
190                 for (Type t : types.interfaces(tsym.type))
191                     importFrom(t.tsym);
192 
193                 final Scope fromScope = tsym.members();
194                 for (Scope.Entry e = fromScope.elems; e != null; e = e.sibling) {
195                     Symbol sym = e.sym;
196                     if (sym.kind == TYP &&
197                         (sym.flags() & STATIC) != 0 &&
198                         staticImportAccessible(sym, packge) &&
199                         sym.isMemberOf(origin, types) &&
200                         !toScope.includes(sym))
201                         toScope.enter(sym, fromScope, origin.members(), true);
202                 }
203             }
204         }.importFrom(tsym);
205 
206         // enter non-types before annotations that might use them
207         annotate.earlier(new Annotate.Worker() {
208             Set<Symbol> processed = new HashSet<Symbol>();
209 
210             public String toString() {
211                 return "import static " + tsym + ".*" + " in " + sourcefile;
212             }
213             void importFrom(TypeSymbol tsym) {
214                 if (tsym == null || !processed.add(tsym))
215                     return;
216 
217                 // also import inherited names
218                 importFrom(types.supertype(tsym.type).tsym);
219                 for (Type t : types.interfaces(tsym.type))
220                     importFrom(t.tsym);
221 
222                 final Scope fromScope = tsym.members();
223                 for (Scope.Entry e = fromScope.elems; e != null; e = e.sibling) {
224                     Symbol sym = e.sym;
225                     if (sym.isStatic() && sym.kind != TYP &&
226                         staticImportAccessible(sym, packge) &&
227                         !toScope.includes(sym) &&
228                         sym.isMemberOf(origin, types)) {
229                         toScope.enter(sym, fromScope, origin.members(), true);
230                     }
231                 }
232             }
233             public void run() {
234                 importFrom(tsym);
235             }
236         });
237     }
238 
239     // is the sym accessible everywhere in packge?
staticImportAccessible(Symbol sym, PackageSymbol packge)240     boolean staticImportAccessible(Symbol sym, PackageSymbol packge) {
241         int flags = (int)(sym.flags() & AccessFlags);
242         switch (flags) {
243         default:
244         case PUBLIC:
245             return true;
246         case PRIVATE:
247             return false;
248         case 0:
249         case PROTECTED:
250             return sym.packge() == packge;
251         }
252     }
253 
254     /** Import statics types of a given name.  Non-types are handled in Attr.
255      *  @param pos           Position to be used for error reporting.
256      *  @param tsym          The class from which the name is imported.
257      *  @param name          The (simple) name being imported.
258      *  @param env           The environment containing the named import
259      *                  scope to add to.
260      */
importNamedStatic(final DiagnosticPosition pos, final TypeSymbol tsym, final Name name, final Env<AttrContext> env)261     private void importNamedStatic(final DiagnosticPosition pos,
262                                    final TypeSymbol tsym,
263                                    final Name name,
264                                    final Env<AttrContext> env) {
265         if (tsym.kind != TYP) {
266             log.error(DiagnosticFlag.RECOVERABLE, pos, "static.imp.only.classes.and.interfaces");
267             return;
268         }
269 
270         final Scope toScope = env.toplevel.namedImportScope;
271         final PackageSymbol packge = env.toplevel.packge;
272         final TypeSymbol origin = tsym;
273 
274         // enter imported types immediately
275         new Object() {
276             Set<Symbol> processed = new HashSet<Symbol>();
277             void importFrom(TypeSymbol tsym) {
278                 if (tsym == null || !processed.add(tsym))
279                     return;
280 
281                 // also import inherited names
282                 importFrom(types.supertype(tsym.type).tsym);
283                 for (Type t : types.interfaces(tsym.type))
284                     importFrom(t.tsym);
285 
286                 for (Scope.Entry e = tsym.members().lookup(name);
287                      e.scope != null;
288                      e = e.next()) {
289                     Symbol sym = e.sym;
290                     if (sym.isStatic() &&
291                         sym.kind == TYP &&
292                         staticImportAccessible(sym, packge) &&
293                         sym.isMemberOf(origin, types) &&
294                         chk.checkUniqueStaticImport(pos, sym, toScope))
295                         toScope.enter(sym, sym.owner.members(), origin.members(), true);
296                 }
297             }
298         }.importFrom(tsym);
299 
300         // enter non-types before annotations that might use them
301         annotate.earlier(new Annotate.Worker() {
302             Set<Symbol> processed = new HashSet<Symbol>();
303             boolean found = false;
304 
305             public String toString() {
306                 return "import static " + tsym + "." + name;
307             }
308             void importFrom(TypeSymbol tsym) {
309                 if (tsym == null || !processed.add(tsym))
310                     return;
311 
312                 // also import inherited names
313                 importFrom(types.supertype(tsym.type).tsym);
314                 for (Type t : types.interfaces(tsym.type))
315                     importFrom(t.tsym);
316 
317                 for (Scope.Entry e = tsym.members().lookup(name);
318                      e.scope != null;
319                      e = e.next()) {
320                     Symbol sym = e.sym;
321                     if (sym.isStatic() &&
322                         staticImportAccessible(sym, packge) &&
323                         sym.isMemberOf(origin, types)) {
324                         found = true;
325                         if (sym.kind != TYP) {
326                             toScope.enter(sym, sym.owner.members(), origin.members(), true);
327                         }
328                     }
329                 }
330             }
331             public void run() {
332                 JavaFileObject prev = log.useSource(env.toplevel.sourcefile);
333                 try {
334                     importFrom(tsym);
335                     if (!found) {
336                         log.error(pos, "cant.resolve.location",
337                                   KindName.STATIC,
338                                   name, List.<Type>nil(), List.<Type>nil(),
339                                   Kinds.typeKindName(tsym.type),
340                                   tsym.type);
341                     }
342                 } finally {
343                     log.useSource(prev);
344                 }
345             }
346         });
347     }
348     /** Import given class.
349      *  @param pos           Position to be used for error reporting.
350      *  @param tsym          The class to be imported.
351      *  @param env           The environment containing the named import
352      *                  scope to add to.
353      */
importNamed(DiagnosticPosition pos, Symbol tsym, Env<AttrContext> env)354     private void importNamed(DiagnosticPosition pos, Symbol tsym, Env<AttrContext> env) {
355         if (tsym.kind == TYP &&
356             chk.checkUniqueImport(pos, tsym, env.toplevel.namedImportScope))
357             env.toplevel.namedImportScope.enter(tsym, tsym.owner.members());
358     }
359 
360     /** Construct method type from method signature.
361      *  @param typarams    The method's type parameters.
362      *  @param params      The method's value parameters.
363      *  @param res             The method's result type,
364      *                 null if it is a constructor.
365      *  @param recvparam       The method's receiver parameter,
366      *                 null if none given; TODO: or already set here?
367      *  @param thrown      The method's thrown exceptions.
368      *  @param env             The method's (local) environment.
369      */
signature(MethodSymbol msym, List<JCTypeParameter> typarams, List<JCVariableDecl> params, JCTree res, JCVariableDecl recvparam, List<JCExpression> thrown, Env<AttrContext> env)370     Type signature(MethodSymbol msym,
371                    List<JCTypeParameter> typarams,
372                    List<JCVariableDecl> params,
373                    JCTree res,
374                    JCVariableDecl recvparam,
375                    List<JCExpression> thrown,
376                    Env<AttrContext> env) {
377 
378         // Enter and attribute type parameters.
379         List<Type> tvars = enter.classEnter(typarams, env);
380         attr.attribTypeVariables(typarams, env);
381 
382         // Enter and attribute value parameters.
383         ListBuffer<Type> argbuf = new ListBuffer<Type>();
384         for (List<JCVariableDecl> l = params; l.nonEmpty(); l = l.tail) {
385             memberEnter(l.head, env);
386             argbuf.append(l.head.vartype.type);
387         }
388 
389         // Attribute result type, if one is given.
390         Type restype = res == null ? syms.voidType : attr.attribType(res, env);
391 
392         // Attribute receiver type, if one is given.
393         Type recvtype;
394         if (recvparam!=null) {
395             memberEnter(recvparam, env);
396             recvtype = recvparam.vartype.type;
397         } else {
398             recvtype = null;
399         }
400 
401         // Attribute thrown exceptions.
402         ListBuffer<Type> thrownbuf = new ListBuffer<Type>();
403         for (List<JCExpression> l = thrown; l.nonEmpty(); l = l.tail) {
404             Type exc = attr.attribType(l.head, env);
405             if (!exc.hasTag(TYPEVAR)) {
406                 exc = chk.checkClassType(l.head.pos(), exc);
407             } else if (exc.tsym.owner == msym) {
408                 //mark inference variables in 'throws' clause
409                 exc.tsym.flags_field |= THROWS;
410             }
411             thrownbuf.append(exc);
412         }
413         MethodType mtype = new MethodType(argbuf.toList(),
414                                     restype,
415                                     thrownbuf.toList(),
416                                     syms.methodClass);
417         mtype.recvtype = recvtype;
418 
419         return tvars.isEmpty() ? mtype : new ForAll(tvars, mtype);
420     }
421 
422 /* ********************************************************************
423  * Visitor methods for member enter
424  *********************************************************************/
425 
426     /** Visitor argument: the current environment
427      */
428     protected Env<AttrContext> env;
429 
430     /** Enter field and method definitions and process import
431      *  clauses, catching any completion failure exceptions.
432      */
memberEnter(JCTree tree, Env<AttrContext> env)433     protected void memberEnter(JCTree tree, Env<AttrContext> env) {
434         Env<AttrContext> prevEnv = this.env;
435         try {
436             this.env = env;
437             tree.accept(this);
438         }  catch (CompletionFailure ex) {
439             chk.completionError(tree.pos(), ex);
440         } finally {
441             this.env = prevEnv;
442         }
443     }
444 
445     /** Enter members from a list of trees.
446      */
memberEnter(List<? extends JCTree> trees, Env<AttrContext> env)447     void memberEnter(List<? extends JCTree> trees, Env<AttrContext> env) {
448         for (List<? extends JCTree> l = trees; l.nonEmpty(); l = l.tail)
449             memberEnter(l.head, env);
450     }
451 
452     /** Enter members for a class.
453      */
finishClass(JCClassDecl tree, Env<AttrContext> env)454     void finishClass(JCClassDecl tree, Env<AttrContext> env) {
455         if ((tree.mods.flags & Flags.ENUM) != 0 &&
456             (types.supertype(tree.sym.type).tsym.flags() & Flags.ENUM) == 0) {
457             addEnumMembers(tree, env);
458         }
459         memberEnter(tree.defs, env);
460     }
461 
462     /** Add the implicit members for an enum type
463      *  to the symbol table.
464      */
addEnumMembers(JCClassDecl tree, Env<AttrContext> env)465     private void addEnumMembers(JCClassDecl tree, Env<AttrContext> env) {
466         JCExpression valuesType = make.Type(new ArrayType(tree.sym.type, syms.arrayClass));
467 
468         // public static T[] values() { return ???; }
469         JCMethodDecl values = make.
470             MethodDef(make.Modifiers(Flags.PUBLIC|Flags.STATIC),
471                       names.values,
472                       valuesType,
473                       List.<JCTypeParameter>nil(),
474                       List.<JCVariableDecl>nil(),
475                       List.<JCExpression>nil(), // thrown
476                       null, //make.Block(0, Tree.emptyList.prepend(make.Return(make.Ident(names._null)))),
477                       null);
478         memberEnter(values, env);
479 
480         // public static T valueOf(String name) { return ???; }
481         JCMethodDecl valueOf = make.
482             MethodDef(make.Modifiers(Flags.PUBLIC|Flags.STATIC),
483                       names.valueOf,
484                       make.Type(tree.sym.type),
485                       List.<JCTypeParameter>nil(),
486                       List.of(make.VarDef(make.Modifiers(Flags.PARAMETER |
487                                                          Flags.MANDATED),
488                                             names.fromString("name"),
489                                             make.Type(syms.stringType), null)),
490                       List.<JCExpression>nil(), // thrown
491                       null, //make.Block(0, Tree.emptyList.prepend(make.Return(make.Ident(names._null)))),
492                       null);
493         memberEnter(valueOf, env);
494     }
495 
visitTopLevel(JCCompilationUnit tree)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, null);
519 
520         DiagnosticPosition prevLintPos = deferredLintHandler.immediate();
521         Lint prevLint = chk.setLint(lint);
522 
523         try {
524             // Import-on-demand java.lang.
525             importAll(tree.pos, reader.enterPackage(names.java_lang), env);
526 
527             // Process all import clauses.
528             memberEnter(tree.defs, env);
529         } finally {
530             chk.setLint(prevLint);
531             deferredLintHandler.setPos(prevLintPos);
532         }
533     }
534 
535     // process the non-static imports and the static imports of types.
visitImport(JCImport tree)536     public void visitImport(JCImport tree) {
537         JCFieldAccess imp = (JCFieldAccess)tree.qualid;
538         Name name = TreeInfo.name(imp);
539 
540         // Create a local environment pointing to this tree to disable
541         // effects of other imports in Resolve.findGlobalType
542         Env<AttrContext> localEnv = env.dup(tree);
543 
544         TypeSymbol p = attr.attribImportQualifier(tree, localEnv).tsym;
545         if (name == names.asterisk) {
546             // Import on demand.
547             chk.checkCanonical(imp.selected);
548             if (tree.staticImport)
549                 importStaticAll(tree.pos, p, env);
550             else
551                 importAll(tree.pos, p, env);
552         } else {
553             // Named type import.
554             if (tree.staticImport) {
555                 importNamedStatic(tree.pos(), p, name, localEnv);
556                 chk.checkCanonical(imp.selected);
557             } else {
558                 TypeSymbol c = attribImportType(imp, localEnv).tsym;
559                 chk.checkCanonical(imp);
560                 importNamed(tree.pos(), c, env);
561             }
562         }
563     }
564 
visitMethodDef(JCMethodDecl tree)565     public void visitMethodDef(JCMethodDecl tree) {
566         Scope enclScope = enter.enterScope(env);
567         MethodSymbol m = new MethodSymbol(0, tree.name, null, enclScope.owner);
568         m.flags_field = chk.checkFlags(tree.pos(), tree.mods.flags, m, tree);
569         tree.sym = m;
570 
571         //if this is a default method, add the DEFAULT flag to the enclosing interface
572         if ((tree.mods.flags & DEFAULT) != 0) {
573             m.enclClass().flags_field |= DEFAULT;
574         }
575 
576         Env<AttrContext> localEnv = methodEnv(tree, env);
577 
578         DiagnosticPosition prevLintPos = deferredLintHandler.setPos(tree.pos());
579         try {
580             // Compute the method type
581             m.type = signature(m, tree.typarams, tree.params,
582                                tree.restype, tree.recvparam,
583                                tree.thrown,
584                                localEnv);
585         } finally {
586             deferredLintHandler.setPos(prevLintPos);
587         }
588 
589         if (types.isSignaturePolymorphic(m)) {
590             m.flags_field |= SIGNATURE_POLYMORPHIC;
591         }
592 
593         // Set m.params
594         ListBuffer<VarSymbol> params = new ListBuffer<VarSymbol>();
595         JCVariableDecl lastParam = null;
596         for (List<JCVariableDecl> l = tree.params; l.nonEmpty(); l = l.tail) {
597             JCVariableDecl param = lastParam = l.head;
598             params.append(Assert.checkNonNull(param.sym));
599         }
600         m.params = params.toList();
601 
602         // mark the method varargs, if necessary
603         if (lastParam != null && (lastParam.mods.flags & Flags.VARARGS) != 0)
604             m.flags_field |= Flags.VARARGS;
605 
606         localEnv.info.scope.leave();
607         if (chk.checkUnique(tree.pos(), m, enclScope)) {
608         enclScope.enter(m);
609         }
610 
611         annotateLater(tree.mods.annotations, localEnv, m, tree.pos());
612         // Visit the signature of the method. Note that
613         // TypeAnnotate doesn't descend into the body.
614         typeAnnotate(tree, localEnv, m, tree.pos());
615 
616         if (tree.defaultValue != null)
617             annotateDefaultValueLater(tree.defaultValue, localEnv, m);
618     }
619 
620     /** Create a fresh environment for method bodies.
621      *  @param tree     The method definition.
622      *  @param env      The environment current outside of the method definition.
623      */
methodEnv(JCMethodDecl tree, Env<AttrContext> env)624     Env<AttrContext> methodEnv(JCMethodDecl tree, Env<AttrContext> env) {
625         Env<AttrContext> localEnv =
626             env.dup(tree, env.info.dup(env.info.scope.dupUnshared()));
627         localEnv.enclMethod = tree;
628         localEnv.info.scope.owner = tree.sym;
629         if (tree.sym.type != null) {
630             //when this is called in the enter stage, there's no type to be set
631             localEnv.info.returnResult = attr.new ResultInfo(VAL, tree.sym.type.getReturnType());
632         }
633         if ((tree.mods.flags & STATIC) != 0) localEnv.info.staticLevel++;
634         return localEnv;
635     }
636 
visitVarDef(JCVariableDecl tree)637     public void visitVarDef(JCVariableDecl tree) {
638         Env<AttrContext> localEnv = env;
639         if ((tree.mods.flags & STATIC) != 0 ||
640             (env.info.scope.owner.flags() & INTERFACE) != 0) {
641             localEnv = env.dup(tree, env.info.dup());
642             localEnv.info.staticLevel++;
643         }
644         DiagnosticPosition prevLintPos = deferredLintHandler.setPos(tree.pos());
645         try {
646             if (TreeInfo.isEnumInit(tree)) {
647                 attr.attribIdentAsEnumType(localEnv, (JCIdent)tree.vartype);
648             } else {
649                 attr.attribType(tree.vartype, localEnv);
650                 if (TreeInfo.isReceiverParam(tree))
651                     checkReceiver(tree, localEnv);
652             }
653         } finally {
654             deferredLintHandler.setPos(prevLintPos);
655         }
656 
657         if ((tree.mods.flags & VARARGS) != 0) {
658             //if we are entering a varargs parameter, we need to
659             //replace its type (a plain array type) with the more
660             //precise VarargsType --- we need to do it this way
661             //because varargs is represented in the tree as a
662             //modifier on the parameter declaration, and not as a
663             //distinct type of array node.
664             ArrayType atype = (ArrayType)tree.vartype.type.unannotatedType();
665             tree.vartype.type = atype.makeVarargs();
666         }
667         Scope enclScope = enter.enterScope(env);
668         VarSymbol v =
669             new VarSymbol(0, tree.name, tree.vartype.type, enclScope.owner);
670         v.flags_field = chk.checkFlags(tree.pos(), tree.mods.flags, v, tree);
671         tree.sym = v;
672         if (tree.init != null) {
673             v.flags_field |= HASINIT;
674             if ((v.flags_field & FINAL) != 0 &&
675                 needsLazyConstValue(tree.init)) {
676                 Env<AttrContext> initEnv = getInitEnv(tree, env);
677                 initEnv.info.enclVar = v;
678                 v.setLazyConstValue(initEnv(tree, initEnv), attr, tree);
679             }
680         }
681         if (chk.checkUnique(tree.pos(), v, enclScope)) {
682             chk.checkTransparentVar(tree.pos(), v, enclScope);
683             enclScope.enter(v);
684         }
685         annotateLater(tree.mods.annotations, localEnv, v, tree.pos());
686         typeAnnotate(tree.vartype, env, v, tree.pos());
687         v.pos = tree.pos;
688     }
689     // where
checkType(JCTree tree, Type type, String diag)690     void checkType(JCTree tree, Type type, String diag) {
691         if (!tree.type.isErroneous() && !types.isSameType(tree.type, type)) {
692             log.error(tree, diag, type, tree.type);
693         }
694     }
checkReceiver(JCVariableDecl tree, Env<AttrContext> localEnv)695     void checkReceiver(JCVariableDecl tree, Env<AttrContext> localEnv) {
696         attr.attribExpr(tree.nameexpr, localEnv);
697         MethodSymbol m = localEnv.enclMethod.sym;
698         if (m.isConstructor()) {
699             Type outertype = m.owner.owner.type;
700             if (outertype.hasTag(TypeTag.METHOD)) {
701                 // we have a local inner class
702                 outertype = m.owner.owner.owner.type;
703             }
704             if (outertype.hasTag(TypeTag.CLASS)) {
705                 checkType(tree.vartype, outertype, "incorrect.constructor.receiver.type");
706                 checkType(tree.nameexpr, outertype, "incorrect.constructor.receiver.name");
707             } else {
708                 log.error(tree, "receiver.parameter.not.applicable.constructor.toplevel.class");
709             }
710         } else {
711             checkType(tree.vartype, m.owner.type, "incorrect.receiver.type");
712             checkType(tree.nameexpr, m.owner.type, "incorrect.receiver.name");
713         }
714     }
715 
needsLazyConstValue(JCTree tree)716     public boolean needsLazyConstValue(JCTree tree) {
717         InitTreeVisitor initTreeVisitor = new InitTreeVisitor();
718         tree.accept(initTreeVisitor);
719         return initTreeVisitor.result;
720     }
721 
722     /** Visitor class for expressions which might be constant expressions.
723      */
724     static class InitTreeVisitor extends JCTree.Visitor {
725 
726         private boolean result = true;
727 
728         @Override
visitTree(JCTree tree)729         public void visitTree(JCTree tree) {}
730 
731         @Override
visitNewClass(JCNewClass that)732         public void visitNewClass(JCNewClass that) {
733             result = false;
734         }
735 
736         @Override
visitNewArray(JCNewArray that)737         public void visitNewArray(JCNewArray that) {
738             result = false;
739         }
740 
741         @Override
visitLambda(JCLambda that)742         public void visitLambda(JCLambda that) {
743             result = false;
744         }
745 
746         @Override
visitReference(JCMemberReference that)747         public void visitReference(JCMemberReference that) {
748             result = false;
749         }
750 
751         @Override
visitApply(JCMethodInvocation that)752         public void visitApply(JCMethodInvocation that) {
753             result = false;
754         }
755 
756         @Override
visitSelect(JCFieldAccess tree)757         public void visitSelect(JCFieldAccess tree) {
758             tree.selected.accept(this);
759         }
760 
761         @Override
visitConditional(JCConditional tree)762         public void visitConditional(JCConditional tree) {
763             tree.cond.accept(this);
764             tree.truepart.accept(this);
765             tree.falsepart.accept(this);
766         }
767 
768         @Override
visitParens(JCParens tree)769         public void visitParens(JCParens tree) {
770             tree.expr.accept(this);
771         }
772 
773         @Override
visitTypeCast(JCTypeCast tree)774         public void visitTypeCast(JCTypeCast tree) {
775             tree.expr.accept(this);
776         }
777     }
778 
779     /** Create a fresh environment for a variable's initializer.
780      *  If the variable is a field, the owner of the environment's scope
781      *  is be the variable itself, otherwise the owner is the method
782      *  enclosing the variable definition.
783      *
784      *  @param tree     The variable definition.
785      *  @param env      The environment current outside of the variable definition.
786      */
initEnv(JCVariableDecl tree, Env<AttrContext> env)787     Env<AttrContext> initEnv(JCVariableDecl tree, Env<AttrContext> env) {
788         Env<AttrContext> localEnv = env.dupto(new AttrContextEnv(tree, env.info.dup()));
789         if (tree.sym.owner.kind == TYP) {
790             localEnv.info.scope = env.info.scope.dupUnshared();
791             localEnv.info.scope.owner = tree.sym;
792         }
793         if ((tree.mods.flags & STATIC) != 0 ||
794                 ((env.enclClass.sym.flags() & INTERFACE) != 0 && env.enclMethod == null))
795             localEnv.info.staticLevel++;
796         return localEnv;
797     }
798 
799     /** Default member enter visitor method: do nothing
800      */
visitTree(JCTree tree)801     public void visitTree(JCTree tree) {
802     }
803 
visitErroneous(JCErroneous tree)804     public void visitErroneous(JCErroneous tree) {
805         if (tree.errs != null)
806             memberEnter(tree.errs, env);
807     }
808 
getMethodEnv(JCMethodDecl tree, Env<AttrContext> env)809     public Env<AttrContext> getMethodEnv(JCMethodDecl tree, Env<AttrContext> env) {
810         Env<AttrContext> mEnv = methodEnv(tree, env);
811         mEnv.info.lint = mEnv.info.lint.augment(tree.sym);
812         for (List<JCTypeParameter> l = tree.typarams; l.nonEmpty(); l = l.tail)
813             mEnv.info.scope.enterIfAbsent(l.head.type.tsym);
814         for (List<JCVariableDecl> l = tree.params; l.nonEmpty(); l = l.tail)
815             mEnv.info.scope.enterIfAbsent(l.head.sym);
816         return mEnv;
817     }
818 
getInitEnv(JCVariableDecl tree, Env<AttrContext> env)819     public Env<AttrContext> getInitEnv(JCVariableDecl tree, Env<AttrContext> env) {
820         Env<AttrContext> iEnv = initEnv(tree, env);
821         return iEnv;
822     }
823 
824 /* ********************************************************************
825  * Type completion
826  *********************************************************************/
827 
attribImportType(JCTree tree, Env<AttrContext> env)828     Type attribImportType(JCTree tree, Env<AttrContext> env) {
829         Assert.check(completionEnabled);
830         try {
831             // To prevent deep recursion, suppress completion of some
832             // types.
833             completionEnabled = false;
834             return attr.attribType(tree, env);
835         } finally {
836             completionEnabled = true;
837         }
838     }
839 
840 /* ********************************************************************
841  * Annotation processing
842  *********************************************************************/
843 
844     /** Queue annotations for later processing. */
annotateLater(final List<JCAnnotation> annotations, final Env<AttrContext> localEnv, final Symbol s, final DiagnosticPosition deferPos)845     void annotateLater(final List<JCAnnotation> annotations,
846                        final Env<AttrContext> localEnv,
847                        final Symbol s,
848                        final DiagnosticPosition deferPos) {
849         if (annotations.isEmpty()) {
850             return;
851         }
852         if (s.kind != PCK) {
853             s.resetAnnotations(); // mark Annotations as incomplete for now
854         }
855         annotate.normal(new Annotate.Worker() {
856                 @Override
857                 public String toString() {
858                     return "annotate " + annotations + " onto " + s + " in " + s.owner;
859                 }
860 
861                 @Override
862                 public void run() {
863                     Assert.check(s.kind == PCK || s.annotationsPendingCompletion());
864                     JavaFileObject prev = log.useSource(localEnv.toplevel.sourcefile);
865                     DiagnosticPosition prevLintPos =
866                         deferPos != null
867                         ? deferredLintHandler.setPos(deferPos)
868                         : deferredLintHandler.immediate();
869                     Lint prevLint = deferPos != null ? null : chk.setLint(lint);
870                     try {
871                         if (s.hasAnnotations() &&
872                             annotations.nonEmpty())
873                             log.error(annotations.head.pos,
874                                       "already.annotated",
875                                       kindName(s), s);
876                         actualEnterAnnotations(annotations, localEnv, s);
877                     } finally {
878                         if (prevLint != null)
879                             chk.setLint(prevLint);
880                         deferredLintHandler.setPos(prevLintPos);
881                         log.useSource(prev);
882                     }
883                 }
884             });
885 
886         annotate.validate(new Annotate.Worker() { //validate annotations
887             @Override
888             public void run() {
889                 JavaFileObject prev = log.useSource(localEnv.toplevel.sourcefile);
890                 try {
891                     chk.validateAnnotations(annotations, s);
892                 } finally {
893                     log.useSource(prev);
894                 }
895             }
896         });
897     }
898 
899     /**
900      * Check if a list of annotations contains a reference to
901      * java.lang.Deprecated.
902      **/
hasDeprecatedAnnotation(List<JCAnnotation> annotations)903     private boolean hasDeprecatedAnnotation(List<JCAnnotation> annotations) {
904         for (List<JCAnnotation> al = annotations; !al.isEmpty(); al = al.tail) {
905             JCAnnotation a = al.head;
906             if (a.annotationType.type == syms.deprecatedType && a.args.isEmpty())
907                 return true;
908         }
909         return false;
910     }
911 
912     /** Enter a set of annotations. */
actualEnterAnnotations(List<JCAnnotation> annotations, Env<AttrContext> env, Symbol s)913     private void actualEnterAnnotations(List<JCAnnotation> annotations,
914                           Env<AttrContext> env,
915                           Symbol s) {
916         Map<TypeSymbol, ListBuffer<Attribute.Compound>> annotated =
917                 new LinkedHashMap<TypeSymbol, ListBuffer<Attribute.Compound>>();
918         Map<Attribute.Compound, DiagnosticPosition> pos =
919                 new HashMap<Attribute.Compound, DiagnosticPosition>();
920 
921         for (List<JCAnnotation> al = annotations; !al.isEmpty(); al = al.tail) {
922             JCAnnotation a = al.head;
923             Attribute.Compound c = annotate.enterAnnotation(a,
924                                                             syms.annotationType,
925                                                             env);
926             if (c == null) {
927                 continue;
928             }
929 
930             if (annotated.containsKey(a.type.tsym)) {
931                 if (!allowRepeatedAnnos) {
932                     log.error(a.pos(), "repeatable.annotations.not.supported.in.source");
933                     allowRepeatedAnnos = true;
934                 }
935                 ListBuffer<Attribute.Compound> l = annotated.get(a.type.tsym);
936                 l = l.append(c);
937                 annotated.put(a.type.tsym, l);
938                 pos.put(c, a.pos());
939             } else {
940                 annotated.put(a.type.tsym, ListBuffer.of(c));
941                 pos.put(c, a.pos());
942             }
943 
944             // Note: @Deprecated has no effect on local variables and parameters
945             if (!c.type.isErroneous()
946                 && s.owner.kind != MTH
947                 && types.isSameType(c.type, syms.deprecatedType)) {
948                 s.flags_field |= Flags.DEPRECATED;
949             }
950         }
951 
952         s.setDeclarationAttributesWithCompletion(
953                 annotate.new AnnotateRepeatedContext<Attribute.Compound>(env, annotated, pos, log, false));
954     }
955 
956     /** Queue processing of an attribute default value. */
annotateDefaultValueLater(final JCExpression defaultValue, final Env<AttrContext> localEnv, final MethodSymbol m)957     void annotateDefaultValueLater(final JCExpression defaultValue,
958                                    final Env<AttrContext> localEnv,
959                                    final MethodSymbol m) {
960         annotate.normal(new Annotate.Worker() {
961                 @Override
962                 public String toString() {
963                     return "annotate " + m.owner + "." +
964                         m + " default " + defaultValue;
965                 }
966 
967                 @Override
968                 public void run() {
969                     JavaFileObject prev = log.useSource(localEnv.toplevel.sourcefile);
970                     try {
971                         enterDefaultValue(defaultValue, localEnv, m);
972                     } finally {
973                         log.useSource(prev);
974                     }
975                 }
976             });
977         annotate.validate(new Annotate.Worker() { //validate annotations
978             @Override
979             public void run() {
980                 JavaFileObject prev = log.useSource(localEnv.toplevel.sourcefile);
981                 try {
982                     // if default value is an annotation, check it is a well-formed
983                     // annotation value (e.g. no duplicate values, no missing values, etc.)
984                     chk.validateAnnotationTree(defaultValue);
985                 } finally {
986                     log.useSource(prev);
987                 }
988             }
989         });
990     }
991 
992     /** Enter a default value for an attribute method. */
enterDefaultValue(final JCExpression defaultValue, final Env<AttrContext> localEnv, final MethodSymbol m)993     private void enterDefaultValue(final JCExpression defaultValue,
994                                    final Env<AttrContext> localEnv,
995                                    final MethodSymbol m) {
996         m.defaultValue = annotate.enterAttributeValue(m.type.getReturnType(),
997                                                       defaultValue,
998                                                       localEnv);
999     }
1000 
1001 /* ********************************************************************
1002  * Source completer
1003  *********************************************************************/
1004 
1005     /** Complete entering a class.
1006      *  @param sym         The symbol of the class to be completed.
1007      */
complete(Symbol sym)1008     public void complete(Symbol sym) throws CompletionFailure {
1009         // Suppress some (recursive) MemberEnter invocations
1010         if (!completionEnabled) {
1011             // Re-install same completer for next time around and return.
1012             Assert.check((sym.flags() & Flags.COMPOUND) == 0);
1013             sym.completer = this;
1014             return;
1015         }
1016 
1017         ClassSymbol c = (ClassSymbol)sym;
1018         ClassType ct = (ClassType)c.type;
1019         Env<AttrContext> env = typeEnvs.get(c);
1020         JCClassDecl tree = (JCClassDecl)env.tree;
1021         boolean wasFirst = isFirst;
1022         isFirst = false;
1023         try {
1024             annotate.enterStart();
1025 
1026             JavaFileObject prev = log.useSource(env.toplevel.sourcefile);
1027             DiagnosticPosition prevLintPos = deferredLintHandler.setPos(tree.pos());
1028             try {
1029                 // Save class environment for later member enter (2) processing.
1030                 halfcompleted.append(env);
1031 
1032                 // Mark class as not yet attributed.
1033                 c.flags_field |= UNATTRIBUTED;
1034 
1035                 // If this is a toplevel-class, make sure any preceding import
1036                 // clauses have been seen.
1037                 if (c.owner.kind == PCK) {
1038                     memberEnter(env.toplevel, env.enclosing(TOPLEVEL));
1039                     todo.append(env);
1040                 }
1041 
1042                 if (c.owner.kind == TYP)
1043                     c.owner.complete();
1044 
1045                 // create an environment for evaluating the base clauses
1046                 Env<AttrContext> baseEnv = baseEnv(tree, env);
1047 
1048                 if (tree.extending != null)
1049                     typeAnnotate(tree.extending, baseEnv, sym, tree.pos());
1050                 for (JCExpression impl : tree.implementing)
1051                     typeAnnotate(impl, baseEnv, sym, tree.pos());
1052                 annotate.flush();
1053 
1054                 // Determine supertype.
1055                 Type supertype =
1056                     (tree.extending != null)
1057                     ? attr.attribBase(tree.extending, baseEnv, true, false, true)
1058                     : ((tree.mods.flags & Flags.ENUM) != 0)
1059                     ? attr.attribBase(enumBase(tree.pos, c), baseEnv,
1060                                       true, false, false)
1061                     : (c.fullname == names.java_lang_Object)
1062                     ? Type.noType
1063                     : syms.objectType;
1064                 ct.supertype_field = modelMissingTypes(supertype, tree.extending, false);
1065 
1066                 // Determine interfaces.
1067                 ListBuffer<Type> interfaces = new ListBuffer<Type>();
1068                 ListBuffer<Type> all_interfaces = null; // lazy init
1069                 Set<Type> interfaceSet = new HashSet<Type>();
1070                 List<JCExpression> interfaceTrees = tree.implementing;
1071                 for (JCExpression iface : interfaceTrees) {
1072                     Type i = attr.attribBase(iface, baseEnv, false, true, true);
1073                     if (i.hasTag(CLASS)) {
1074                         interfaces.append(i);
1075                         if (all_interfaces != null) all_interfaces.append(i);
1076                         chk.checkNotRepeated(iface.pos(), types.erasure(i), interfaceSet);
1077                     } else {
1078                         if (all_interfaces == null)
1079                             all_interfaces = new ListBuffer<Type>().appendList(interfaces);
1080                         all_interfaces.append(modelMissingTypes(i, iface, true));
1081                     }
1082                 }
1083                 if ((c.flags_field & ANNOTATION) != 0) {
1084                     ct.interfaces_field = List.of(syms.annotationType);
1085                     ct.all_interfaces_field = ct.interfaces_field;
1086                 }  else {
1087                     ct.interfaces_field = interfaces.toList();
1088                     ct.all_interfaces_field = (all_interfaces == null)
1089                             ? ct.interfaces_field : all_interfaces.toList();
1090                 }
1091 
1092                 if (c.fullname == names.java_lang_Object) {
1093                     if (tree.extending != null) {
1094                         chk.checkNonCyclic(tree.extending.pos(),
1095                                            supertype);
1096                         ct.supertype_field = Type.noType;
1097                     }
1098                     else if (tree.implementing.nonEmpty()) {
1099                         chk.checkNonCyclic(tree.implementing.head.pos(),
1100                                            ct.interfaces_field.head);
1101                         ct.interfaces_field = List.nil();
1102                     }
1103                 }
1104 
1105                 // Annotations.
1106                 // In general, we cannot fully process annotations yet,  but we
1107                 // can attribute the annotation types and then check to see if the
1108                 // @Deprecated annotation is present.
1109                 attr.attribAnnotationTypes(tree.mods.annotations, baseEnv);
1110                 if (hasDeprecatedAnnotation(tree.mods.annotations))
1111                     c.flags_field |= DEPRECATED;
1112                 annotateLater(tree.mods.annotations, baseEnv, c, tree.pos());
1113                 // class type parameters use baseEnv but everything uses env
1114 
1115                 chk.checkNonCyclicDecl(tree);
1116 
1117                 attr.attribTypeVariables(tree.typarams, baseEnv);
1118                 // Do this here, where we have the symbol.
1119                 for (JCTypeParameter tp : tree.typarams)
1120                     typeAnnotate(tp, baseEnv, sym, tree.pos());
1121 
1122                 // Add default constructor if needed.
1123                 if ((c.flags() & INTERFACE) == 0 &&
1124                     !TreeInfo.hasConstructors(tree.defs)) {
1125                     List<Type> argtypes = List.nil();
1126                     List<Type> typarams = List.nil();
1127                     List<Type> thrown = List.nil();
1128                     long ctorFlags = 0;
1129                     boolean based = false;
1130                     boolean addConstructor = true;
1131                     JCNewClass nc = null;
1132                     if (c.name.isEmpty()) {
1133                         nc = (JCNewClass)env.next.tree;
1134                         if (nc.constructor != null) {
1135                             addConstructor = nc.constructor.kind != ERR;
1136                             Type superConstrType = types.memberType(c.type,
1137                                                                     nc.constructor);
1138                             argtypes = superConstrType.getParameterTypes();
1139                             typarams = superConstrType.getTypeArguments();
1140                             ctorFlags = nc.constructor.flags() & VARARGS;
1141                             if (nc.encl != null) {
1142                                 argtypes = argtypes.prepend(nc.encl.type);
1143                                 based = true;
1144                             }
1145                             thrown = superConstrType.getThrownTypes();
1146                         }
1147                     }
1148                     if (addConstructor) {
1149                         MethodSymbol basedConstructor = nc != null ?
1150                                 (MethodSymbol)nc.constructor : null;
1151                         JCTree constrDef = DefaultConstructor(make.at(tree.pos), c,
1152                                                             basedConstructor,
1153                                                             typarams, argtypes, thrown,
1154                                                             ctorFlags, based);
1155                         tree.defs = tree.defs.prepend(constrDef);
1156                     }
1157                 }
1158 
1159                 // enter symbols for 'this' into current scope.
1160                 VarSymbol thisSym =
1161                     new VarSymbol(FINAL | HASINIT, names._this, c.type, c);
1162                 thisSym.pos = Position.FIRSTPOS;
1163                 env.info.scope.enter(thisSym);
1164                 // if this is a class, enter symbol for 'super' into current scope.
1165                 if ((c.flags_field & INTERFACE) == 0 &&
1166                         ct.supertype_field.hasTag(CLASS)) {
1167                     VarSymbol superSym =
1168                         new VarSymbol(FINAL | HASINIT, names._super,
1169                                       ct.supertype_field, c);
1170                     superSym.pos = Position.FIRSTPOS;
1171                     env.info.scope.enter(superSym);
1172                 }
1173 
1174                 // check that no package exists with same fully qualified name,
1175                 // but admit classes in the unnamed package which have the same
1176                 // name as a top-level package.
1177                 if (checkClash &&
1178                     c.owner.kind == PCK && c.owner != syms.unnamedPackage &&
1179                     reader.packageExists(c.fullname)) {
1180                     log.error(tree.pos, "clash.with.pkg.of.same.name", Kinds.kindName(sym), c);
1181                 }
1182                 if (c.owner.kind == PCK && (c.flags_field & PUBLIC) == 0 &&
1183                     !env.toplevel.sourcefile.isNameCompatible(c.name.toString(),JavaFileObject.Kind.SOURCE)) {
1184                     c.flags_field |= AUXILIARY;
1185                 }
1186             } catch (CompletionFailure ex) {
1187                 chk.completionError(tree.pos(), ex);
1188             } finally {
1189                 deferredLintHandler.setPos(prevLintPos);
1190                 log.useSource(prev);
1191             }
1192 
1193             // Enter all member fields and methods of a set of half completed
1194             // classes in a second phase.
1195             if (wasFirst) {
1196                 try {
1197                     while (halfcompleted.nonEmpty()) {
1198                         Env<AttrContext> toFinish = halfcompleted.next();
1199                         finish(toFinish);
1200                         if (allowTypeAnnos) {
1201                             typeAnnotations.organizeTypeAnnotationsSignatures(toFinish, (JCClassDecl)toFinish.tree);
1202                             typeAnnotations.validateTypeAnnotationsSignatures(toFinish, (JCClassDecl)toFinish.tree);
1203                         }
1204                     }
1205                 } finally {
1206                     isFirst = true;
1207                 }
1208             }
1209         } finally {
1210             annotate.enterDone();
1211         }
1212     }
1213 
1214     /*
1215      * If the symbol is non-null, attach the type annotation to it.
1216      */
actualEnterTypeAnnotations(final List<JCAnnotation> annotations, final Env<AttrContext> env, final Symbol s)1217     private void actualEnterTypeAnnotations(final List<JCAnnotation> annotations,
1218             final Env<AttrContext> env,
1219             final Symbol s) {
1220         Map<TypeSymbol, ListBuffer<Attribute.TypeCompound>> annotated =
1221                 new LinkedHashMap<TypeSymbol, ListBuffer<Attribute.TypeCompound>>();
1222         Map<Attribute.TypeCompound, DiagnosticPosition> pos =
1223                 new HashMap<Attribute.TypeCompound, DiagnosticPosition>();
1224 
1225         for (List<JCAnnotation> al = annotations; !al.isEmpty(); al = al.tail) {
1226             JCAnnotation a = al.head;
1227             Attribute.TypeCompound tc = annotate.enterTypeAnnotation(a,
1228                     syms.annotationType,
1229                     env);
1230             if (tc == null) {
1231                 continue;
1232             }
1233 
1234             if (annotated.containsKey(a.type.tsym)) {
1235                 if (source.allowRepeatedAnnotations()) {
1236                     ListBuffer<Attribute.TypeCompound> l = annotated.get(a.type.tsym);
1237                     l = l.append(tc);
1238                     annotated.put(a.type.tsym, l);
1239                     pos.put(tc, a.pos());
1240                 } else {
1241                     log.error(a.pos(), "repeatable.annotations.not.supported.in.source");
1242                 }
1243             } else {
1244                 annotated.put(a.type.tsym, ListBuffer.of(tc));
1245                 pos.put(tc, a.pos());
1246             }
1247         }
1248 
1249         if (s != null) {
1250             s.appendTypeAttributesWithCompletion(
1251                     annotate.new AnnotateRepeatedContext<Attribute.TypeCompound>(env, annotated, pos, log, true));
1252         }
1253     }
1254 
typeAnnotate(final JCTree tree, final Env<AttrContext> env, final Symbol sym, DiagnosticPosition deferPos)1255     public void typeAnnotate(final JCTree tree, final Env<AttrContext> env, final Symbol sym, DiagnosticPosition deferPos) {
1256         if (allowTypeAnnos) {
1257             tree.accept(new TypeAnnotate(env, sym, deferPos));
1258         }
1259     }
1260 
1261     /**
1262      * We need to use a TreeScanner, because it is not enough to visit the top-level
1263      * annotations. We also need to visit type arguments, etc.
1264      */
1265     private class TypeAnnotate extends TreeScanner {
1266         private Env<AttrContext> env;
1267         private Symbol sym;
1268         private DiagnosticPosition deferPos;
1269 
TypeAnnotate(final Env<AttrContext> env, final Symbol sym, DiagnosticPosition deferPos)1270         public TypeAnnotate(final Env<AttrContext> env, final Symbol sym, DiagnosticPosition deferPos) {
1271             this.env = env;
1272             this.sym = sym;
1273             this.deferPos = deferPos;
1274         }
1275 
annotateTypeLater(final List<JCAnnotation> annotations)1276         void annotateTypeLater(final List<JCAnnotation> annotations) {
1277             if (annotations.isEmpty()) {
1278                 return;
1279             }
1280 
1281             final DiagnosticPosition deferPos = this.deferPos;
1282 
1283             annotate.normal(new Annotate.Worker() {
1284                 @Override
1285                 public String toString() {
1286                     return "type annotate " + annotations + " onto " + sym + " in " + sym.owner;
1287                 }
1288                 @Override
1289                 public void run() {
1290                     JavaFileObject prev = log.useSource(env.toplevel.sourcefile);
1291                     DiagnosticPosition prevLintPos = null;
1292 
1293                     if (deferPos != null) {
1294                         prevLintPos = deferredLintHandler.setPos(deferPos);
1295                     }
1296                     try {
1297                         actualEnterTypeAnnotations(annotations, env, sym);
1298                     } finally {
1299                         if (prevLintPos != null)
1300                             deferredLintHandler.setPos(prevLintPos);
1301                         log.useSource(prev);
1302                     }
1303                 }
1304             });
1305         }
1306 
1307         @Override
visitAnnotatedType(final JCAnnotatedType tree)1308         public void visitAnnotatedType(final JCAnnotatedType tree) {
1309             annotateTypeLater(tree.annotations);
1310             super.visitAnnotatedType(tree);
1311         }
1312 
1313         @Override
visitTypeParameter(final JCTypeParameter tree)1314         public void visitTypeParameter(final JCTypeParameter tree) {
1315             annotateTypeLater(tree.annotations);
1316             super.visitTypeParameter(tree);
1317         }
1318 
1319         @Override
visitNewArray(final JCNewArray tree)1320         public void visitNewArray(final JCNewArray tree) {
1321             annotateTypeLater(tree.annotations);
1322             for (List<JCAnnotation> dimAnnos : tree.dimAnnotations)
1323                 annotateTypeLater(dimAnnos);
1324             super.visitNewArray(tree);
1325         }
1326 
1327         @Override
visitMethodDef(final JCMethodDecl tree)1328         public void visitMethodDef(final JCMethodDecl tree) {
1329             scan(tree.mods);
1330             scan(tree.restype);
1331             scan(tree.typarams);
1332             scan(tree.recvparam);
1333             scan(tree.params);
1334             scan(tree.thrown);
1335             scan(tree.defaultValue);
1336             // Do not annotate the body, just the signature.
1337             // scan(tree.body);
1338         }
1339 
1340         @Override
visitVarDef(final JCVariableDecl tree)1341         public void visitVarDef(final JCVariableDecl tree) {
1342             DiagnosticPosition prevPos = deferPos;
1343             deferPos = tree.pos();
1344             try {
1345                 if (sym != null && sym.kind == Kinds.VAR) {
1346                     // Don't visit a parameter once when the sym is the method
1347                     // and once when the sym is the parameter.
1348                     scan(tree.mods);
1349                     scan(tree.vartype);
1350                 }
1351                 scan(tree.init);
1352             } finally {
1353                 deferPos = prevPos;
1354             }
1355         }
1356 
1357         @Override
visitClassDef(JCClassDecl tree)1358         public void visitClassDef(JCClassDecl tree) {
1359             // We can only hit a classdef if it is declared within
1360             // a method. Ignore it - the class will be visited
1361             // separately later.
1362         }
1363 
1364         @Override
visitNewClass(JCNewClass tree)1365         public void visitNewClass(JCNewClass tree) {
1366             if (tree.def == null) {
1367                 // For an anonymous class instantiation the class
1368                 // will be visited separately.
1369                 super.visitNewClass(tree);
1370             }
1371         }
1372     }
1373 
1374 
baseEnv(JCClassDecl tree, Env<AttrContext> env)1375     private Env<AttrContext> baseEnv(JCClassDecl tree, Env<AttrContext> env) {
1376         Scope baseScope = new Scope(tree.sym);
1377         //import already entered local classes into base scope
1378         for (Scope.Entry e = env.outer.info.scope.elems ; e != null ; e = e.sibling) {
1379             if (e.sym.isLocal()) {
1380                 baseScope.enter(e.sym);
1381             }
1382         }
1383         //import current type-parameters into base scope
1384         if (tree.typarams != null)
1385             for (List<JCTypeParameter> typarams = tree.typarams;
1386                  typarams.nonEmpty();
1387                  typarams = typarams.tail)
1388                 baseScope.enter(typarams.head.type.tsym);
1389         Env<AttrContext> outer = env.outer; // the base clause can't see members of this class
1390         Env<AttrContext> localEnv = outer.dup(tree, outer.info.dup(baseScope));
1391         localEnv.baseClause = true;
1392         localEnv.outer = outer;
1393         localEnv.info.isSelfCall = false;
1394         return localEnv;
1395     }
1396 
1397     /** Enter member fields and methods of a class
1398      *  @param env        the environment current for the class block.
1399      */
finish(Env<AttrContext> env)1400     private void finish(Env<AttrContext> env) {
1401         JavaFileObject prev = log.useSource(env.toplevel.sourcefile);
1402         try {
1403             JCClassDecl tree = (JCClassDecl)env.tree;
1404             finishClass(tree, env);
1405         } finally {
1406             log.useSource(prev);
1407         }
1408     }
1409 
1410     /** Generate a base clause for an enum type.
1411      *  @param pos              The position for trees and diagnostics, if any
1412      *  @param c                The class symbol of the enum
1413      */
enumBase(int pos, ClassSymbol c)1414     private JCExpression enumBase(int pos, ClassSymbol c) {
1415         JCExpression result = make.at(pos).
1416             TypeApply(make.QualIdent(syms.enumSym),
1417                       List.<JCExpression>of(make.Type(c.type)));
1418         return result;
1419     }
1420 
modelMissingTypes(Type t, final JCExpression tree, final boolean interfaceExpected)1421     Type modelMissingTypes(Type t, final JCExpression tree, final boolean interfaceExpected) {
1422         if (!t.hasTag(ERROR))
1423             return t;
1424 
1425         return new ErrorType(t.getOriginalType(), t.tsym) {
1426             private Type modelType;
1427 
1428             @Override
1429             public Type getModelType() {
1430                 if (modelType == null)
1431                     modelType = new Synthesizer(getOriginalType(), interfaceExpected).visit(tree);
1432                 return modelType;
1433             }
1434         };
1435     }
1436     // where
1437     private class Synthesizer extends JCTree.Visitor {
1438         Type originalType;
1439         boolean interfaceExpected;
1440         List<ClassSymbol> synthesizedSymbols = List.nil();
1441         Type result;
1442 
Synthesizer(Type originalType, boolean interfaceExpected)1443         Synthesizer(Type originalType, boolean interfaceExpected) {
1444             this.originalType = originalType;
1445             this.interfaceExpected = interfaceExpected;
1446         }
1447 
visit(JCTree tree)1448         Type visit(JCTree tree) {
1449             tree.accept(this);
1450             return result;
1451         }
1452 
visit(List<? extends JCTree> trees)1453         List<Type> visit(List<? extends JCTree> trees) {
1454             ListBuffer<Type> lb = new ListBuffer<Type>();
1455             for (JCTree t: trees)
1456                 lb.append(visit(t));
1457             return lb.toList();
1458         }
1459 
1460         @Override
visitTree(JCTree tree)1461         public void visitTree(JCTree tree) {
1462             result = syms.errType;
1463         }
1464 
1465         @Override
visitIdent(JCIdent tree)1466         public void visitIdent(JCIdent tree) {
1467             if (!tree.type.hasTag(ERROR)) {
1468                 result = tree.type;
1469             } else {
1470                 result = synthesizeClass(tree.name, syms.unnamedPackage).type;
1471             }
1472         }
1473 
1474         @Override
visitSelect(JCFieldAccess tree)1475         public void visitSelect(JCFieldAccess tree) {
1476             if (!tree.type.hasTag(ERROR)) {
1477                 result = tree.type;
1478             } else {
1479                 Type selectedType;
1480                 boolean prev = interfaceExpected;
1481                 try {
1482                     interfaceExpected = false;
1483                     selectedType = visit(tree.selected);
1484                 } finally {
1485                     interfaceExpected = prev;
1486                 }
1487                 ClassSymbol c = synthesizeClass(tree.name, selectedType.tsym);
1488                 result = c.type;
1489             }
1490         }
1491 
1492         @Override
visitTypeApply(JCTypeApply tree)1493         public void visitTypeApply(JCTypeApply tree) {
1494             if (!tree.type.hasTag(ERROR)) {
1495                 result = tree.type;
1496             } else {
1497                 ClassType clazzType = (ClassType) visit(tree.clazz);
1498                 if (synthesizedSymbols.contains(clazzType.tsym))
1499                     synthesizeTyparams((ClassSymbol) clazzType.tsym, tree.arguments.size());
1500                 final List<Type> actuals = visit(tree.arguments);
1501                 result = new ErrorType(tree.type, clazzType.tsym) {
1502                     @Override
1503                     public List<Type> getTypeArguments() {
1504                         return actuals;
1505                     }
1506                 };
1507             }
1508         }
1509 
synthesizeClass(Name name, Symbol owner)1510         ClassSymbol synthesizeClass(Name name, Symbol owner) {
1511             int flags = interfaceExpected ? INTERFACE : 0;
1512             ClassSymbol c = new ClassSymbol(flags, name, owner);
1513             c.members_field = new Scope.ErrorScope(c);
1514             c.type = new ErrorType(originalType, c) {
1515                 @Override
1516                 public List<Type> getTypeArguments() {
1517                     return typarams_field;
1518                 }
1519             };
1520             synthesizedSymbols = synthesizedSymbols.prepend(c);
1521             return c;
1522         }
1523 
synthesizeTyparams(ClassSymbol sym, int n)1524         void synthesizeTyparams(ClassSymbol sym, int n) {
1525             ClassType ct = (ClassType) sym.type;
1526             Assert.check(ct.typarams_field.isEmpty());
1527             if (n == 1) {
1528                 TypeVar v = new TypeVar(names.fromString("T"), sym, syms.botType);
1529                 ct.typarams_field = ct.typarams_field.prepend(v);
1530             } else {
1531                 for (int i = n; i > 0; i--) {
1532                     TypeVar v = new TypeVar(names.fromString("T" + i), sym, syms.botType);
1533                     ct.typarams_field = ct.typarams_field.prepend(v);
1534                 }
1535             }
1536         }
1537     }
1538 
1539 
1540 /* ***************************************************************************
1541  * tree building
1542  ****************************************************************************/
1543 
1544     /** Generate default constructor for given class. For classes different
1545      *  from java.lang.Object, this is:
1546      *
1547      *    c(argtype_0 x_0, ..., argtype_n x_n) throws thrown {
1548      *      super(x_0, ..., x_n)
1549      *    }
1550      *
1551      *  or, if based == true:
1552      *
1553      *    c(argtype_0 x_0, ..., argtype_n x_n) throws thrown {
1554      *      x_0.super(x_1, ..., x_n)
1555      *    }
1556      *
1557      *  @param make     The tree factory.
1558      *  @param c        The class owning the default constructor.
1559      *  @param argtypes The parameter types of the constructor.
1560      *  @param thrown   The thrown exceptions of the constructor.
1561      *  @param based    Is first parameter a this$n?
1562      */
DefaultConstructor(TreeMaker make, ClassSymbol c, MethodSymbol baseInit, List<Type> typarams, List<Type> argtypes, List<Type> thrown, long flags, boolean based)1563     JCTree DefaultConstructor(TreeMaker make,
1564                             ClassSymbol c,
1565                             MethodSymbol baseInit,
1566                             List<Type> typarams,
1567                             List<Type> argtypes,
1568                             List<Type> thrown,
1569                             long flags,
1570                             boolean based) {
1571         JCTree result;
1572         if ((c.flags() & ENUM) != 0 &&
1573             (types.supertype(c.type).tsym == syms.enumSym)) {
1574             // constructors of true enums are private
1575             flags = (flags & ~AccessFlags) | PRIVATE | GENERATEDCONSTR;
1576         } else
1577             flags |= (c.flags() & AccessFlags) | GENERATEDCONSTR;
1578         if (c.name.isEmpty()) {
1579             flags |= ANONCONSTR;
1580         }
1581         Type mType = new MethodType(argtypes, null, thrown, c);
1582         Type initType = typarams.nonEmpty() ?
1583                 new ForAll(typarams, mType) :
1584                 mType;
1585         MethodSymbol init = new MethodSymbol(flags, names.init,
1586                 initType, c);
1587         init.params = createDefaultConstructorParams(make, baseInit, init,
1588                 argtypes, based);
1589         List<JCVariableDecl> params = make.Params(argtypes, init);
1590         List<JCStatement> stats = List.nil();
1591         if (c.type != syms.objectType) {
1592             stats = stats.prepend(SuperCall(make, typarams, params, based));
1593         }
1594         result = make.MethodDef(init, make.Block(0, stats));
1595         return result;
1596     }
1597 
createDefaultConstructorParams( TreeMaker make, MethodSymbol baseInit, MethodSymbol init, List<Type> argtypes, boolean based)1598     private List<VarSymbol> createDefaultConstructorParams(
1599             TreeMaker make,
1600             MethodSymbol baseInit,
1601             MethodSymbol init,
1602             List<Type> argtypes,
1603             boolean based) {
1604         List<VarSymbol> initParams = null;
1605         List<Type> argTypesList = argtypes;
1606         if (based) {
1607             /*  In this case argtypes will have an extra type, compared to baseInit,
1608              *  corresponding to the type of the enclosing instance i.e.:
1609              *
1610              *  Inner i = outer.new Inner(1){}
1611              *
1612              *  in the above example argtypes will be (Outer, int) and baseInit
1613              *  will have parameter's types (int). So in this case we have to add
1614              *  first the extra type in argtypes and then get the names of the
1615              *  parameters from baseInit.
1616              */
1617             initParams = List.nil();
1618             VarSymbol param = new VarSymbol(PARAMETER, make.paramName(0), argtypes.head, init);
1619             initParams = initParams.append(param);
1620             argTypesList = argTypesList.tail;
1621         }
1622         if (baseInit != null && baseInit.params != null &&
1623             baseInit.params.nonEmpty() && argTypesList.nonEmpty()) {
1624             initParams = (initParams == null) ? List.<VarSymbol>nil() : initParams;
1625             List<VarSymbol> baseInitParams = baseInit.params;
1626             while (baseInitParams.nonEmpty() && argTypesList.nonEmpty()) {
1627                 VarSymbol param = new VarSymbol(baseInitParams.head.flags() | PARAMETER,
1628                         baseInitParams.head.name, argTypesList.head, init);
1629                 initParams = initParams.append(param);
1630                 baseInitParams = baseInitParams.tail;
1631                 argTypesList = argTypesList.tail;
1632             }
1633         }
1634         return initParams;
1635     }
1636 
1637     /** Generate call to superclass constructor. This is:
1638      *
1639      *    super(id_0, ..., id_n)
1640      *
1641      * or, if based == true
1642      *
1643      *    id_0.super(id_1,...,id_n)
1644      *
1645      *  where id_0, ..., id_n are the names of the given parameters.
1646      *
1647      *  @param make    The tree factory
1648      *  @param params  The parameters that need to be passed to super
1649      *  @param typarams  The type parameters that need to be passed to super
1650      *  @param based   Is first parameter a this$n?
1651      */
SuperCall(TreeMaker make, List<Type> typarams, List<JCVariableDecl> params, boolean based)1652     JCExpressionStatement SuperCall(TreeMaker make,
1653                    List<Type> typarams,
1654                    List<JCVariableDecl> params,
1655                    boolean based) {
1656         JCExpression meth;
1657         if (based) {
1658             meth = make.Select(make.Ident(params.head), names._super);
1659             params = params.tail;
1660         } else {
1661             meth = make.Ident(names._super);
1662         }
1663         List<JCExpression> typeargs = typarams.nonEmpty() ? make.Types(typarams) : null;
1664         return make.Exec(make.Apply(typeargs, meth, make.Idents(params)));
1665     }
1666 }
1667