Mon, 07 Feb 2011 18:09:46 +0000
7017414: before the move of JSR 292 to package java.lang.invoke, javac must recognize the new package
Summary: added support for future 292 package (support for old location 'java.dyn' will be removed in followup changeset)
Reviewed-by: jjg
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 */
26 package com.sun.tools.javac.comp;
28 import java.util.*;
29 import java.util.Set;
30 import javax.tools.JavaFileObject;
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;
38 import com.sun.tools.javac.code.Type.*;
39 import com.sun.tools.javac.code.Symbol.*;
40 import com.sun.tools.javac.tree.JCTree.*;
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;
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>();
60 /** A switch to determine whether we check for package/class conflicts
61 */
62 final static boolean checkClash = true;
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 Scope.ScopeCounter scopeCounter;
71 private final TreeMaker make;
72 private final ClassReader reader;
73 private final Todo todo;
74 private final Annotate annotate;
75 private final Types types;
76 private final JCDiagnostic.Factory diags;
77 private final Target target;
78 private final DeferredLintHandler deferredLintHandler;
80 private final boolean skipAnnotations;
82 public static MemberEnter instance(Context context) {
83 MemberEnter instance = context.get(memberEnterKey);
84 if (instance == null)
85 instance = new MemberEnter(context);
86 return instance;
87 }
89 protected MemberEnter(Context context) {
90 context.put(memberEnterKey, this);
91 names = Names.instance(context);
92 enter = Enter.instance(context);
93 log = Log.instance(context);
94 chk = Check.instance(context);
95 attr = Attr.instance(context);
96 syms = Symtab.instance(context);
97 scopeCounter = Scope.ScopeCounter.instance(context);
98 make = TreeMaker.instance(context);
99 reader = ClassReader.instance(context);
100 todo = Todo.instance(context);
101 annotate = Annotate.instance(context);
102 types = Types.instance(context);
103 diags = JCDiagnostic.Factory.instance(context);
104 target = Target.instance(context);
105 deferredLintHandler = DeferredLintHandler.instance(context);
106 Options options = Options.instance(context);
107 skipAnnotations = options.isSet("skipAnnotations");
108 }
110 /** A queue for classes whose members still need to be entered into the
111 * symbol table.
112 */
113 ListBuffer<Env<AttrContext>> halfcompleted = new ListBuffer<Env<AttrContext>>();
115 /** Set to true only when the first of a set of classes is
116 * processed from the halfcompleted queue.
117 */
118 boolean isFirst = true;
120 /** A flag to disable completion from time to time during member
121 * enter, as we only need to look up types. This avoids
122 * unnecessarily deep recursion.
123 */
124 boolean completionEnabled = true;
126 /* ---------- Processing import clauses ----------------
127 */
129 /** Import all classes of a class or package on demand.
130 * @param pos Position to be used for error reporting.
131 * @param tsym The class or package the members of which are imported.
132 * @param toScope The (import) scope in which imported classes
133 * are entered.
134 */
135 private void importAll(int pos,
136 final TypeSymbol tsym,
137 Env<AttrContext> env) {
138 // Check that packages imported from exist (JLS ???).
139 if (tsym.kind == PCK && tsym.members().elems == null && !tsym.exists()) {
140 // If we can't find java.lang, exit immediately.
141 if (((PackageSymbol)tsym).fullname.equals(names.java_lang)) {
142 JCDiagnostic msg = diags.fragment("fatal.err.no.java.lang");
143 throw new FatalError(msg);
144 } else {
145 log.error(pos, "doesnt.exist", tsym);
146 }
147 }
148 env.toplevel.starImportScope.importAll(tsym.members());
149 }
151 /** Import all static members of a class or package on demand.
152 * @param pos Position to be used for error reporting.
153 * @param tsym The class or package the members of which are imported.
154 * @param toScope The (import) scope in which imported classes
155 * are entered.
156 */
157 private void importStaticAll(int pos,
158 final TypeSymbol tsym,
159 Env<AttrContext> env) {
160 final JavaFileObject sourcefile = env.toplevel.sourcefile;
161 final Scope toScope = env.toplevel.starImportScope;
162 final PackageSymbol packge = env.toplevel.packge;
163 final TypeSymbol origin = tsym;
165 // enter imported types immediately
166 new Object() {
167 Set<Symbol> processed = new HashSet<Symbol>();
168 void importFrom(TypeSymbol tsym) {
169 if (tsym == null || !processed.add(tsym))
170 return;
172 // also import inherited names
173 importFrom(types.supertype(tsym.type).tsym);
174 for (Type t : types.interfaces(tsym.type))
175 importFrom(t.tsym);
177 final Scope fromScope = tsym.members();
178 for (Scope.Entry e = fromScope.elems; e != null; e = e.sibling) {
179 Symbol sym = e.sym;
180 if (sym.kind == TYP &&
181 (sym.flags() & STATIC) != 0 &&
182 staticImportAccessible(sym, packge) &&
183 sym.isMemberOf(origin, types) &&
184 !toScope.includes(sym))
185 toScope.enter(sym, fromScope, origin.members());
186 }
187 }
188 }.importFrom(tsym);
190 // enter non-types before annotations that might use them
191 annotate.earlier(new Annotate.Annotator() {
192 Set<Symbol> processed = new HashSet<Symbol>();
194 public String toString() {
195 return "import static " + tsym + ".*" + " in " + sourcefile;
196 }
197 void importFrom(TypeSymbol tsym) {
198 if (tsym == null || !processed.add(tsym))
199 return;
201 // also import inherited names
202 importFrom(types.supertype(tsym.type).tsym);
203 for (Type t : types.interfaces(tsym.type))
204 importFrom(t.tsym);
206 final Scope fromScope = tsym.members();
207 for (Scope.Entry e = fromScope.elems; e != null; e = e.sibling) {
208 Symbol sym = e.sym;
209 if (sym.isStatic() && sym.kind != TYP &&
210 staticImportAccessible(sym, packge) &&
211 !toScope.includes(sym) &&
212 sym.isMemberOf(origin, types)) {
213 toScope.enter(sym, fromScope, origin.members());
214 }
215 }
216 }
217 public void enterAnnotation() {
218 importFrom(tsym);
219 }
220 });
221 }
223 // is the sym accessible everywhere in packge?
224 boolean staticImportAccessible(Symbol sym, PackageSymbol packge) {
225 int flags = (int)(sym.flags() & AccessFlags);
226 switch (flags) {
227 default:
228 case PUBLIC:
229 return true;
230 case PRIVATE:
231 return false;
232 case 0:
233 case PROTECTED:
234 return sym.packge() == packge;
235 }
236 }
238 /** Import statics types of a given name. Non-types are handled in Attr.
239 * @param pos Position to be used for error reporting.
240 * @param tsym The class from which the name is imported.
241 * @param name The (simple) name being imported.
242 * @param env The environment containing the named import
243 * scope to add to.
244 */
245 private void importNamedStatic(final DiagnosticPosition pos,
246 final TypeSymbol tsym,
247 final Name name,
248 final Env<AttrContext> env) {
249 if (tsym.kind != TYP) {
250 log.error(pos, "static.imp.only.classes.and.interfaces");
251 return;
252 }
254 final Scope toScope = env.toplevel.namedImportScope;
255 final PackageSymbol packge = env.toplevel.packge;
256 final TypeSymbol origin = tsym;
258 // enter imported types immediately
259 new Object() {
260 Set<Symbol> processed = new HashSet<Symbol>();
261 void importFrom(TypeSymbol tsym) {
262 if (tsym == null || !processed.add(tsym))
263 return;
265 // also import inherited names
266 importFrom(types.supertype(tsym.type).tsym);
267 for (Type t : types.interfaces(tsym.type))
268 importFrom(t.tsym);
270 for (Scope.Entry e = tsym.members().lookup(name);
271 e.scope != null;
272 e = e.next()) {
273 Symbol sym = e.sym;
274 if (sym.isStatic() &&
275 sym.kind == TYP &&
276 staticImportAccessible(sym, packge) &&
277 sym.isMemberOf(origin, types) &&
278 chk.checkUniqueStaticImport(pos, sym, toScope))
279 toScope.enter(sym, sym.owner.members(), origin.members());
280 }
281 }
282 }.importFrom(tsym);
284 // enter non-types before annotations that might use them
285 annotate.earlier(new Annotate.Annotator() {
286 Set<Symbol> processed = new HashSet<Symbol>();
287 boolean found = false;
289 public String toString() {
290 return "import static " + tsym + "." + name;
291 }
292 void importFrom(TypeSymbol tsym) {
293 if (tsym == null || !processed.add(tsym))
294 return;
296 // also import inherited names
297 importFrom(types.supertype(tsym.type).tsym);
298 for (Type t : types.interfaces(tsym.type))
299 importFrom(t.tsym);
301 for (Scope.Entry e = tsym.members().lookup(name);
302 e.scope != null;
303 e = e.next()) {
304 Symbol sym = e.sym;
305 if (sym.isStatic() &&
306 staticImportAccessible(sym, packge) &&
307 sym.isMemberOf(origin, types)) {
308 found = true;
309 if (sym.kind == MTH ||
310 sym.kind != TYP && chk.checkUniqueStaticImport(pos, sym, toScope))
311 toScope.enter(sym, sym.owner.members(), origin.members());
312 }
313 }
314 }
315 public void enterAnnotation() {
316 JavaFileObject prev = log.useSource(env.toplevel.sourcefile);
317 try {
318 importFrom(tsym);
319 if (!found) {
320 log.error(pos, "cant.resolve.location",
321 KindName.STATIC,
322 name, List.<Type>nil(), List.<Type>nil(),
323 Kinds.typeKindName(tsym.type),
324 tsym.type);
325 }
326 } finally {
327 log.useSource(prev);
328 }
329 }
330 });
331 }
332 /** Import given class.
333 * @param pos Position to be used for error reporting.
334 * @param tsym The class to be imported.
335 * @param env The environment containing the named import
336 * scope to add to.
337 */
338 private void importNamed(DiagnosticPosition pos, Symbol tsym, Env<AttrContext> env) {
339 if (tsym.kind == TYP &&
340 chk.checkUniqueImport(pos, tsym, env.toplevel.namedImportScope))
341 env.toplevel.namedImportScope.enter(tsym, tsym.owner.members());
342 }
344 /** Construct method type from method signature.
345 * @param typarams The method's type parameters.
346 * @param params The method's value parameters.
347 * @param res The method's result type,
348 * null if it is a constructor.
349 * @param thrown The method's thrown exceptions.
350 * @param env The method's (local) environment.
351 */
352 Type signature(List<JCTypeParameter> typarams,
353 List<JCVariableDecl> params,
354 JCTree res,
355 List<JCExpression> thrown,
356 Env<AttrContext> env) {
358 // Enter and attribute type parameters.
359 List<Type> tvars = enter.classEnter(typarams, env);
360 attr.attribTypeVariables(typarams, env);
362 // Enter and attribute value parameters.
363 ListBuffer<Type> argbuf = new ListBuffer<Type>();
364 for (List<JCVariableDecl> l = params; l.nonEmpty(); l = l.tail) {
365 memberEnter(l.head, env);
366 argbuf.append(l.head.vartype.type);
367 }
369 // Attribute result type, if one is given.
370 Type restype = res == null ? syms.voidType : attr.attribType(res, env);
372 // Attribute thrown exceptions.
373 ListBuffer<Type> thrownbuf = new ListBuffer<Type>();
374 for (List<JCExpression> l = thrown; l.nonEmpty(); l = l.tail) {
375 Type exc = attr.attribType(l.head, env);
376 if (exc.tag != TYPEVAR)
377 exc = chk.checkClassType(l.head.pos(), exc);
378 thrownbuf.append(exc);
379 }
380 Type mtype = new MethodType(argbuf.toList(),
381 restype,
382 thrownbuf.toList(),
383 syms.methodClass);
384 return tvars.isEmpty() ? mtype : new ForAll(tvars, mtype);
385 }
387 /* ********************************************************************
388 * Visitor methods for member enter
389 *********************************************************************/
391 /** Visitor argument: the current environment
392 */
393 protected Env<AttrContext> env;
395 /** Enter field and method definitions and process import
396 * clauses, catching any completion failure exceptions.
397 */
398 protected void memberEnter(JCTree tree, Env<AttrContext> env) {
399 Env<AttrContext> prevEnv = this.env;
400 try {
401 this.env = env;
402 tree.accept(this);
403 } catch (CompletionFailure ex) {
404 chk.completionError(tree.pos(), ex);
405 } finally {
406 this.env = prevEnv;
407 }
408 }
410 /** Enter members from a list of trees.
411 */
412 void memberEnter(List<? extends JCTree> trees, Env<AttrContext> env) {
413 for (List<? extends JCTree> l = trees; l.nonEmpty(); l = l.tail)
414 memberEnter(l.head, env);
415 }
417 /** Enter members for a class.
418 */
419 void finishClass(JCClassDecl tree, Env<AttrContext> env) {
420 if ((tree.mods.flags & Flags.ENUM) != 0 &&
421 (types.supertype(tree.sym.type).tsym.flags() & Flags.ENUM) == 0) {
422 addEnumMembers(tree, env);
423 }
424 memberEnter(tree.defs, env);
425 }
427 /** Add the implicit members for an enum type
428 * to the symbol table.
429 */
430 private void addEnumMembers(JCClassDecl tree, Env<AttrContext> env) {
431 JCExpression valuesType = make.Type(new ArrayType(tree.sym.type, syms.arrayClass));
433 // public static T[] values() { return ???; }
434 JCMethodDecl values = make.
435 MethodDef(make.Modifiers(Flags.PUBLIC|Flags.STATIC),
436 names.values,
437 valuesType,
438 List.<JCTypeParameter>nil(),
439 List.<JCVariableDecl>nil(),
440 List.<JCExpression>nil(), // thrown
441 null, //make.Block(0, Tree.emptyList.prepend(make.Return(make.Ident(names._null)))),
442 null);
443 memberEnter(values, env);
445 // public static T valueOf(String name) { return ???; }
446 JCMethodDecl valueOf = make.
447 MethodDef(make.Modifiers(Flags.PUBLIC|Flags.STATIC),
448 names.valueOf,
449 make.Type(tree.sym.type),
450 List.<JCTypeParameter>nil(),
451 List.of(make.VarDef(make.Modifiers(Flags.PARAMETER),
452 names.fromString("name"),
453 make.Type(syms.stringType), null)),
454 List.<JCExpression>nil(), // thrown
455 null, //make.Block(0, Tree.emptyList.prepend(make.Return(make.Ident(names._null)))),
456 null);
457 memberEnter(valueOf, env);
459 // the remaining members are for bootstrapping only
460 if (!target.compilerBootstrap(tree.sym)) return;
462 // public final int ordinal() { return ???; }
463 JCMethodDecl ordinal = make.at(tree.pos).
464 MethodDef(make.Modifiers(Flags.PUBLIC|Flags.FINAL),
465 names.ordinal,
466 make.Type(syms.intType),
467 List.<JCTypeParameter>nil(),
468 List.<JCVariableDecl>nil(),
469 List.<JCExpression>nil(),
470 null,
471 null);
472 memberEnter(ordinal, env);
474 // public final String name() { return ???; }
475 JCMethodDecl name = make.
476 MethodDef(make.Modifiers(Flags.PUBLIC|Flags.FINAL),
477 names._name,
478 make.Type(syms.stringType),
479 List.<JCTypeParameter>nil(),
480 List.<JCVariableDecl>nil(),
481 List.<JCExpression>nil(),
482 null,
483 null);
484 memberEnter(name, env);
486 // public int compareTo(E other) { return ???; }
487 MethodSymbol compareTo = new
488 MethodSymbol(Flags.PUBLIC,
489 names.compareTo,
490 new MethodType(List.of(tree.sym.type),
491 syms.intType,
492 List.<Type>nil(),
493 syms.methodClass),
494 tree.sym);
495 memberEnter(make.MethodDef(compareTo, null), env);
496 }
498 public void visitTopLevel(JCCompilationUnit tree) {
499 if (tree.starImportScope.elems != null) {
500 // we must have already processed this toplevel
501 return;
502 }
504 // check that no class exists with same fully qualified name as
505 // toplevel package
506 if (checkClash && tree.pid != null) {
507 Symbol p = tree.packge;
508 while (p.owner != syms.rootPackage) {
509 p.owner.complete(); // enter all class members of p
510 if (syms.classes.get(p.getQualifiedName()) != null) {
511 log.error(tree.pos,
512 "pkg.clashes.with.class.of.same.name",
513 p);
514 }
515 p = p.owner;
516 }
517 }
519 // process package annotations
520 annotateLater(tree.packageAnnotations, env, tree.packge);
522 // Import-on-demand java.lang.
523 importAll(tree.pos, reader.enterPackage(names.java_lang), env);
525 // Process all import clauses.
526 memberEnter(tree.defs, env);
527 }
529 // process the non-static imports and the static imports of types.
530 public void visitImport(JCImport tree) {
531 JCTree imp = tree.qualid;
532 Name name = TreeInfo.name(imp);
533 TypeSymbol p;
535 // Create a local environment pointing to this tree to disable
536 // effects of other imports in Resolve.findGlobalType
537 Env<AttrContext> localEnv = env.dup(tree);
539 // Attribute qualifying package or class.
540 JCFieldAccess s = (JCFieldAccess) imp;
541 p = attr.
542 attribTree(s.selected,
543 localEnv,
544 tree.staticImport ? TYP : (TYP | PCK),
545 Type.noType).tsym;
546 if (name == names.asterisk) {
547 // Import on demand.
548 chk.checkCanonical(s.selected);
549 if (tree.staticImport)
550 importStaticAll(tree.pos, p, env);
551 else
552 importAll(tree.pos, p, env);
553 } else {
554 // Named type import.
555 if (tree.staticImport) {
556 importNamedStatic(tree.pos(), p, name, localEnv);
557 chk.checkCanonical(s.selected);
558 } else {
559 TypeSymbol c = attribImportType(imp, localEnv).tsym;
560 chk.checkCanonical(imp);
561 importNamed(tree.pos(), c, env);
562 }
563 }
564 }
566 public void visitMethodDef(JCMethodDecl tree) {
567 Scope enclScope = enter.enterScope(env);
568 MethodSymbol m = new MethodSymbol(0, tree.name, null, enclScope.owner);
569 m.flags_field = chk.checkFlags(tree.pos(), tree.mods.flags, m, tree);
570 tree.sym = m;
571 Env<AttrContext> localEnv = methodEnv(tree, env);
573 DeferredLintHandler prevLintHandler =
574 chk.setDeferredLintHandler(deferredLintHandler.setPos(tree.pos()));
575 try {
576 // Compute the method type
577 m.type = signature(tree.typarams, tree.params,
578 tree.restype, tree.thrown,
579 localEnv);
580 } finally {
581 chk.setDeferredLintHandler(prevLintHandler);
582 }
584 // Set m.params
585 ListBuffer<VarSymbol> params = new ListBuffer<VarSymbol>();
586 JCVariableDecl lastParam = null;
587 for (List<JCVariableDecl> l = tree.params; l.nonEmpty(); l = l.tail) {
588 JCVariableDecl param = lastParam = l.head;
589 params.append(Assert.checkNonNull(param.sym));
590 }
591 m.params = params.toList();
593 // mark the method varargs, if necessary
594 if (lastParam != null && (lastParam.mods.flags & Flags.VARARGS) != 0)
595 m.flags_field |= Flags.VARARGS;
597 localEnv.info.scope.leave();
598 if (chk.checkUnique(tree.pos(), m, enclScope)) {
599 enclScope.enter(m);
600 }
601 annotateLater(tree.mods.annotations, localEnv, m);
602 if (tree.defaultValue != null)
603 annotateDefaultValueLater(tree.defaultValue, localEnv, m);
604 }
606 /** Create a fresh environment for method bodies.
607 * @param tree The method definition.
608 * @param env The environment current outside of the method definition.
609 */
610 Env<AttrContext> methodEnv(JCMethodDecl tree, Env<AttrContext> env) {
611 Env<AttrContext> localEnv =
612 env.dup(tree, env.info.dup(env.info.scope.dupUnshared()));
613 localEnv.enclMethod = tree;
614 localEnv.info.scope.owner = tree.sym;
615 if ((tree.mods.flags & STATIC) != 0) localEnv.info.staticLevel++;
616 return localEnv;
617 }
619 public void visitVarDef(JCVariableDecl tree) {
620 Env<AttrContext> localEnv = env;
621 if ((tree.mods.flags & STATIC) != 0 ||
622 (env.info.scope.owner.flags() & INTERFACE) != 0) {
623 localEnv = env.dup(tree, env.info.dup());
624 localEnv.info.staticLevel++;
625 }
626 DeferredLintHandler prevLintHandler =
627 chk.setDeferredLintHandler(deferredLintHandler.setPos(tree.pos()));
628 try {
629 attr.attribType(tree.vartype, localEnv);
630 } finally {
631 chk.setDeferredLintHandler(prevLintHandler);
632 }
634 if ((tree.mods.flags & VARARGS) != 0) {
635 //if we are entering a varargs parameter, we need to replace its type
636 //(a plain array type) with the more precise VarargsType --- we need
637 //to do it this way because varargs is represented in the tree as a modifier
638 //on the parameter declaration, and not as a distinct type of array node.
639 ArrayType atype = (ArrayType)tree.vartype.type;
640 tree.vartype.type = atype.makeVarargs();
641 }
642 Scope enclScope = enter.enterScope(env);
643 VarSymbol v =
644 new VarSymbol(0, tree.name, tree.vartype.type, enclScope.owner);
645 v.flags_field = chk.checkFlags(tree.pos(), tree.mods.flags, v, tree);
646 tree.sym = v;
647 if (tree.init != null) {
648 v.flags_field |= HASINIT;
649 if ((v.flags_field & FINAL) != 0 && tree.init.getTag() != JCTree.NEWCLASS) {
650 Env<AttrContext> initEnv = getInitEnv(tree, env);
651 initEnv.info.enclVar = v;
652 v.setLazyConstValue(initEnv(tree, initEnv), attr, tree.init);
653 }
654 }
655 if (chk.checkUnique(tree.pos(), v, enclScope)) {
656 chk.checkTransparentVar(tree.pos(), v, enclScope);
657 enclScope.enter(v);
658 }
659 annotateLater(tree.mods.annotations, localEnv, v);
660 v.pos = tree.pos;
661 }
663 /** Create a fresh environment for a variable's initializer.
664 * If the variable is a field, the owner of the environment's scope
665 * is be the variable itself, otherwise the owner is the method
666 * enclosing the variable definition.
667 *
668 * @param tree The variable definition.
669 * @param env The environment current outside of the variable definition.
670 */
671 Env<AttrContext> initEnv(JCVariableDecl tree, Env<AttrContext> env) {
672 Env<AttrContext> localEnv = env.dupto(new AttrContextEnv(tree, env.info.dup()));
673 if (tree.sym.owner.kind == TYP) {
674 localEnv.info.scope = new Scope.DelegatedScope(env.info.scope);
675 localEnv.info.scope.owner = tree.sym;
676 }
677 if ((tree.mods.flags & STATIC) != 0 ||
678 (env.enclClass.sym.flags() & INTERFACE) != 0)
679 localEnv.info.staticLevel++;
680 return localEnv;
681 }
683 /** Default member enter visitor method: do nothing
684 */
685 public void visitTree(JCTree tree) {
686 }
688 public void visitErroneous(JCErroneous tree) {
689 if (tree.errs != null)
690 memberEnter(tree.errs, env);
691 }
693 public Env<AttrContext> getMethodEnv(JCMethodDecl tree, Env<AttrContext> env) {
694 Env<AttrContext> mEnv = methodEnv(tree, env);
695 mEnv.info.lint = mEnv.info.lint.augment(tree.sym.attributes_field, tree.sym.flags());
696 for (List<JCTypeParameter> l = tree.typarams; l.nonEmpty(); l = l.tail)
697 mEnv.info.scope.enterIfAbsent(l.head.type.tsym);
698 for (List<JCVariableDecl> l = tree.params; l.nonEmpty(); l = l.tail)
699 mEnv.info.scope.enterIfAbsent(l.head.sym);
700 return mEnv;
701 }
703 public Env<AttrContext> getInitEnv(JCVariableDecl tree, Env<AttrContext> env) {
704 Env<AttrContext> iEnv = initEnv(tree, env);
705 return iEnv;
706 }
708 /* ********************************************************************
709 * Type completion
710 *********************************************************************/
712 Type attribImportType(JCTree tree, Env<AttrContext> env) {
713 Assert.check(completionEnabled);
714 try {
715 // To prevent deep recursion, suppress completion of some
716 // types.
717 completionEnabled = false;
718 return attr.attribType(tree, env);
719 } finally {
720 completionEnabled = true;
721 }
722 }
724 /* ********************************************************************
725 * Annotation processing
726 *********************************************************************/
728 /** Queue annotations for later processing. */
729 void annotateLater(final List<JCAnnotation> annotations,
730 final Env<AttrContext> localEnv,
731 final Symbol s) {
732 if (annotations.isEmpty()) return;
733 if (s.kind != PCK) s.attributes_field = null; // mark it incomplete for now
734 annotate.later(new Annotate.Annotator() {
735 public String toString() {
736 return "annotate " + annotations + " onto " + s + " in " + s.owner;
737 }
738 public void enterAnnotation() {
739 Assert.check(s.kind == PCK || s.attributes_field == null);
740 JavaFileObject prev = log.useSource(localEnv.toplevel.sourcefile);
741 try {
742 if (s.attributes_field != null &&
743 s.attributes_field.nonEmpty() &&
744 annotations.nonEmpty())
745 log.error(annotations.head.pos,
746 "already.annotated",
747 kindName(s), s);
748 enterAnnotations(annotations, localEnv, s);
749 } finally {
750 log.useSource(prev);
751 }
752 }
753 });
754 }
756 /**
757 * Check if a list of annotations contains a reference to
758 * java.lang.Deprecated.
759 **/
760 private boolean hasDeprecatedAnnotation(List<JCAnnotation> annotations) {
761 for (List<JCAnnotation> al = annotations; al.nonEmpty(); al = al.tail) {
762 JCAnnotation a = al.head;
763 if (a.annotationType.type == syms.deprecatedType && a.args.isEmpty())
764 return true;
765 }
766 return false;
767 }
770 /** Enter a set of annotations. */
771 private void enterAnnotations(List<JCAnnotation> annotations,
772 Env<AttrContext> env,
773 Symbol s) {
774 ListBuffer<Attribute.Compound> buf =
775 new ListBuffer<Attribute.Compound>();
776 Set<TypeSymbol> annotated = new HashSet<TypeSymbol>();
777 if (!skipAnnotations)
778 for (List<JCAnnotation> al = annotations; al.nonEmpty(); al = al.tail) {
779 JCAnnotation a = al.head;
780 Attribute.Compound c = annotate.enterAnnotation(a,
781 syms.annotationType,
782 env);
783 if (c == null) continue;
784 buf.append(c);
785 // Note: @Deprecated has no effect on local variables and parameters
786 if (!c.type.isErroneous()
787 && s.owner.kind != MTH
788 && types.isSameType(c.type, syms.deprecatedType))
789 s.flags_field |= Flags.DEPRECATED;
790 // Internally to java.lang.invoke, a @PolymorphicSignature annotation
791 // acts like a classfile attribute.
792 if (!c.type.isErroneous() &&
793 (types.isSameType(c.type, syms.polymorphicSignatureType) ||
794 types.isSameType(c.type, syms.transientPolymorphicSignatureType))) {
795 if (!target.hasMethodHandles()) {
796 // Somebody is compiling JDK7 source code to a JDK6 target.
797 // Make it an error, since it is unlikely but important.
798 log.error(env.tree.pos(),
799 "wrong.target.for.polymorphic.signature.definition",
800 target.name);
801 }
802 // Pull the flag through for better diagnostics, even on a bad target.
803 s.flags_field |= Flags.POLYMORPHIC_SIGNATURE;
804 }
805 if (!annotated.add(a.type.tsym))
806 log.error(a.pos, "duplicate.annotation");
807 }
808 s.attributes_field = buf.toList();
809 }
811 /** Queue processing of an attribute default value. */
812 void annotateDefaultValueLater(final JCExpression defaultValue,
813 final Env<AttrContext> localEnv,
814 final MethodSymbol m) {
815 annotate.later(new Annotate.Annotator() {
816 public String toString() {
817 return "annotate " + m.owner + "." +
818 m + " default " + defaultValue;
819 }
820 public void enterAnnotation() {
821 JavaFileObject prev = log.useSource(localEnv.toplevel.sourcefile);
822 try {
823 enterDefaultValue(defaultValue, localEnv, m);
824 } finally {
825 log.useSource(prev);
826 }
827 }
828 });
829 }
831 /** Enter a default value for an attribute method. */
832 private void enterDefaultValue(final JCExpression defaultValue,
833 final Env<AttrContext> localEnv,
834 final MethodSymbol m) {
835 m.defaultValue = annotate.enterAttributeValue(m.type.getReturnType(),
836 defaultValue,
837 localEnv);
838 }
840 /* ********************************************************************
841 * Source completer
842 *********************************************************************/
844 /** Complete entering a class.
845 * @param sym The symbol of the class to be completed.
846 */
847 public void complete(Symbol sym) throws CompletionFailure {
848 // Suppress some (recursive) MemberEnter invocations
849 if (!completionEnabled) {
850 // Re-install same completer for next time around and return.
851 Assert.check((sym.flags() & Flags.COMPOUND) == 0);
852 sym.completer = this;
853 return;
854 }
856 ClassSymbol c = (ClassSymbol)sym;
857 ClassType ct = (ClassType)c.type;
858 Env<AttrContext> env = enter.typeEnvs.get(c);
859 JCClassDecl tree = (JCClassDecl)env.tree;
860 boolean wasFirst = isFirst;
861 isFirst = false;
863 JavaFileObject prev = log.useSource(env.toplevel.sourcefile);
864 try {
865 // Save class environment for later member enter (2) processing.
866 halfcompleted.append(env);
868 // Mark class as not yet attributed.
869 c.flags_field |= UNATTRIBUTED;
871 // If this is a toplevel-class, make sure any preceding import
872 // clauses have been seen.
873 if (c.owner.kind == PCK) {
874 memberEnter(env.toplevel, env.enclosing(JCTree.TOPLEVEL));
875 todo.append(env);
876 }
878 if (c.owner.kind == TYP)
879 c.owner.complete();
881 // create an environment for evaluating the base clauses
882 Env<AttrContext> baseEnv = baseEnv(tree, env);
884 // Determine supertype.
885 Type supertype =
886 (tree.extending != null)
887 ? attr.attribBase(tree.extending, baseEnv, true, false, true)
888 : ((tree.mods.flags & Flags.ENUM) != 0 && !target.compilerBootstrap(c))
889 ? attr.attribBase(enumBase(tree.pos, c), baseEnv,
890 true, false, false)
891 : (c.fullname == names.java_lang_Object)
892 ? Type.noType
893 : syms.objectType;
894 ct.supertype_field = supertype;
896 // Determine interfaces.
897 ListBuffer<Type> interfaces = new ListBuffer<Type>();
898 Set<Type> interfaceSet = new HashSet<Type>();
899 List<JCExpression> interfaceTrees = tree.implementing;
900 if ((tree.mods.flags & Flags.ENUM) != 0 && target.compilerBootstrap(c)) {
901 // add interface Comparable<T>
902 interfaceTrees =
903 interfaceTrees.prepend(make.Type(new ClassType(syms.comparableType.getEnclosingType(),
904 List.of(c.type),
905 syms.comparableType.tsym)));
906 // add interface Serializable
907 interfaceTrees =
908 interfaceTrees.prepend(make.Type(syms.serializableType));
909 }
910 for (JCExpression iface : interfaceTrees) {
911 Type i = attr.attribBase(iface, baseEnv, false, true, true);
912 if (i.tag == CLASS) {
913 interfaces.append(i);
914 chk.checkNotRepeated(iface.pos(), types.erasure(i), interfaceSet);
915 }
916 }
917 if ((c.flags_field & ANNOTATION) != 0)
918 ct.interfaces_field = List.of(syms.annotationType);
919 else
920 ct.interfaces_field = interfaces.toList();
922 if (c.fullname == names.java_lang_Object) {
923 if (tree.extending != null) {
924 chk.checkNonCyclic(tree.extending.pos(),
925 supertype);
926 ct.supertype_field = Type.noType;
927 }
928 else if (tree.implementing.nonEmpty()) {
929 chk.checkNonCyclic(tree.implementing.head.pos(),
930 ct.interfaces_field.head);
931 ct.interfaces_field = List.nil();
932 }
933 }
935 // Annotations.
936 // In general, we cannot fully process annotations yet, but we
937 // can attribute the annotation types and then check to see if the
938 // @Deprecated annotation is present.
939 attr.attribAnnotationTypes(tree.mods.annotations, baseEnv);
940 if (hasDeprecatedAnnotation(tree.mods.annotations))
941 c.flags_field |= DEPRECATED;
942 annotateLater(tree.mods.annotations, baseEnv, c);
944 chk.checkNonCyclicDecl(tree);
946 attr.attribTypeVariables(tree.typarams, baseEnv);
948 // Add default constructor if needed.
949 if ((c.flags() & INTERFACE) == 0 &&
950 !TreeInfo.hasConstructors(tree.defs)) {
951 List<Type> argtypes = List.nil();
952 List<Type> typarams = List.nil();
953 List<Type> thrown = List.nil();
954 long ctorFlags = 0;
955 boolean based = false;
956 if (c.name.isEmpty()) {
957 JCNewClass nc = (JCNewClass)env.next.tree;
958 if (nc.constructor != null) {
959 Type superConstrType = types.memberType(c.type,
960 nc.constructor);
961 argtypes = superConstrType.getParameterTypes();
962 typarams = superConstrType.getTypeArguments();
963 ctorFlags = nc.constructor.flags() & VARARGS;
964 if (nc.encl != null) {
965 argtypes = argtypes.prepend(nc.encl.type);
966 based = true;
967 }
968 thrown = superConstrType.getThrownTypes();
969 }
970 }
971 JCTree constrDef = DefaultConstructor(make.at(tree.pos), c,
972 typarams, argtypes, thrown,
973 ctorFlags, based);
974 tree.defs = tree.defs.prepend(constrDef);
975 }
977 // If this is a class, enter symbols for this and super into
978 // current scope.
979 if ((c.flags_field & INTERFACE) == 0) {
980 VarSymbol thisSym =
981 new VarSymbol(FINAL | HASINIT, names._this, c.type, c);
982 thisSym.pos = Position.FIRSTPOS;
983 env.info.scope.enter(thisSym);
984 if (ct.supertype_field.tag == CLASS) {
985 VarSymbol superSym =
986 new VarSymbol(FINAL | HASINIT, names._super,
987 ct.supertype_field, c);
988 superSym.pos = Position.FIRSTPOS;
989 env.info.scope.enter(superSym);
990 }
991 }
993 // check that no package exists with same fully qualified name,
994 // but admit classes in the unnamed package which have the same
995 // name as a top-level package.
996 if (checkClash &&
997 c.owner.kind == PCK && c.owner != syms.unnamedPackage &&
998 reader.packageExists(c.fullname))
999 {
1000 log.error(tree.pos, "clash.with.pkg.of.same.name", Kinds.kindName(sym), c);
1001 }
1003 } catch (CompletionFailure ex) {
1004 chk.completionError(tree.pos(), ex);
1005 } finally {
1006 log.useSource(prev);
1007 }
1009 // Enter all member fields and methods of a set of half completed
1010 // classes in a second phase.
1011 if (wasFirst) {
1012 try {
1013 while (halfcompleted.nonEmpty()) {
1014 finish(halfcompleted.next());
1015 }
1016 } finally {
1017 isFirst = true;
1018 }
1020 // commit pending annotations
1021 annotate.flush();
1022 }
1023 }
1025 private Env<AttrContext> baseEnv(JCClassDecl tree, Env<AttrContext> env) {
1026 Scope baseScope = new Scope.ClassScope(tree.sym, scopeCounter);
1027 //import already entered local classes into base scope
1028 for (Scope.Entry e = env.outer.info.scope.elems ; e != null ; e = e.sibling) {
1029 if (e.sym.isLocal()) {
1030 baseScope.enter(e.sym);
1031 }
1032 }
1033 //import current type-parameters into base scope
1034 if (tree.typarams != null)
1035 for (List<JCTypeParameter> typarams = tree.typarams;
1036 typarams.nonEmpty();
1037 typarams = typarams.tail)
1038 baseScope.enter(typarams.head.type.tsym);
1039 Env<AttrContext> outer = env.outer; // the base clause can't see members of this class
1040 Env<AttrContext> localEnv = outer.dup(tree, outer.info.dup(baseScope));
1041 localEnv.baseClause = true;
1042 localEnv.outer = outer;
1043 localEnv.info.isSelfCall = false;
1044 return localEnv;
1045 }
1047 /** Enter member fields and methods of a class
1048 * @param env the environment current for the class block.
1049 */
1050 private void finish(Env<AttrContext> env) {
1051 JavaFileObject prev = log.useSource(env.toplevel.sourcefile);
1052 try {
1053 JCClassDecl tree = (JCClassDecl)env.tree;
1054 finishClass(tree, env);
1055 } finally {
1056 log.useSource(prev);
1057 }
1058 }
1060 /** Generate a base clause for an enum type.
1061 * @param pos The position for trees and diagnostics, if any
1062 * @param c The class symbol of the enum
1063 */
1064 private JCExpression enumBase(int pos, ClassSymbol c) {
1065 JCExpression result = make.at(pos).
1066 TypeApply(make.QualIdent(syms.enumSym),
1067 List.<JCExpression>of(make.Type(c.type)));
1068 return result;
1069 }
1071 /* ***************************************************************************
1072 * tree building
1073 ****************************************************************************/
1075 /** Generate default constructor for given class. For classes different
1076 * from java.lang.Object, this is:
1077 *
1078 * c(argtype_0 x_0, ..., argtype_n x_n) throws thrown {
1079 * super(x_0, ..., x_n)
1080 * }
1081 *
1082 * or, if based == true:
1083 *
1084 * c(argtype_0 x_0, ..., argtype_n x_n) throws thrown {
1085 * x_0.super(x_1, ..., x_n)
1086 * }
1087 *
1088 * @param make The tree factory.
1089 * @param c The class owning the default constructor.
1090 * @param argtypes The parameter types of the constructor.
1091 * @param thrown The thrown exceptions of the constructor.
1092 * @param based Is first parameter a this$n?
1093 */
1094 JCTree DefaultConstructor(TreeMaker make,
1095 ClassSymbol c,
1096 List<Type> typarams,
1097 List<Type> argtypes,
1098 List<Type> thrown,
1099 long flags,
1100 boolean based) {
1101 List<JCVariableDecl> params = make.Params(argtypes, syms.noSymbol);
1102 List<JCStatement> stats = List.nil();
1103 if (c.type != syms.objectType)
1104 stats = stats.prepend(SuperCall(make, typarams, params, based));
1105 if ((c.flags() & ENUM) != 0 &&
1106 (types.supertype(c.type).tsym == syms.enumSym ||
1107 target.compilerBootstrap(c))) {
1108 // constructors of true enums are private
1109 flags = (flags & ~AccessFlags) | PRIVATE | GENERATEDCONSTR;
1110 } else
1111 flags |= (c.flags() & AccessFlags) | GENERATEDCONSTR;
1112 if (c.name.isEmpty()) flags |= ANONCONSTR;
1113 JCTree result = make.MethodDef(
1114 make.Modifiers(flags),
1115 names.init,
1116 null,
1117 make.TypeParams(typarams),
1118 params,
1119 make.Types(thrown),
1120 make.Block(0, stats),
1121 null);
1122 return result;
1123 }
1125 /** Generate call to superclass constructor. This is:
1126 *
1127 * super(id_0, ..., id_n)
1128 *
1129 * or, if based == true
1130 *
1131 * id_0.super(id_1,...,id_n)
1132 *
1133 * where id_0, ..., id_n are the names of the given parameters.
1134 *
1135 * @param make The tree factory
1136 * @param params The parameters that need to be passed to super
1137 * @param typarams The type parameters that need to be passed to super
1138 * @param based Is first parameter a this$n?
1139 */
1140 JCExpressionStatement SuperCall(TreeMaker make,
1141 List<Type> typarams,
1142 List<JCVariableDecl> params,
1143 boolean based) {
1144 JCExpression meth;
1145 if (based) {
1146 meth = make.Select(make.Ident(params.head), names._super);
1147 params = params.tail;
1148 } else {
1149 meth = make.Ident(names._super);
1150 }
1151 List<JCExpression> typeargs = typarams.nonEmpty() ? make.Types(typarams) : null;
1152 return make.Exec(make.Apply(typeargs, meth, make.Idents(params)));
1153 }
1154 }