45 |
45 |
46 import static com.sun.tools.javac.code.Flags.*; |
46 import static com.sun.tools.javac.code.Flags.*; |
47 import static com.sun.tools.javac.code.Kinds.Kind.*; |
47 import static com.sun.tools.javac.code.Kinds.Kind.*; |
48 |
48 |
49 /** This class enters symbols for all encountered definitions into |
49 /** This class enters symbols for all encountered definitions into |
50 * the symbol table. The pass consists of two phases, organized as |
50 * the symbol table. The pass consists of high-level two phases, |
51 * follows: |
51 * organized as follows: |
52 * |
52 * |
53 * <p>In the first phase, all class symbols are entered into their |
53 * <p>In the first phase, all class symbols are entered into their |
54 * enclosing scope, descending recursively down the tree for classes |
54 * enclosing scope, descending recursively down the tree for classes |
55 * which are members of other classes. The class symbols are given a |
55 * which are members of other classes. The class symbols are given a |
56 * MemberEnter object as completer. |
56 * TypeEnter object as completer. |
57 * |
57 * |
58 * <p>In the second phase classes are completed using |
58 * <p>In the second phase classes are completed using |
59 * MemberEnter.complete(). Completion might occur on demand, but |
59 * TypeEnter.complete(). Completion might occur on demand, but |
60 * any classes that are not completed that way will be eventually |
60 * any classes that are not completed that way will be eventually |
61 * completed by processing the `uncompleted' queue. Completion |
61 * completed by processing the `uncompleted' queue. Completion |
62 * entails (1) determination of a class's parameters, supertype and |
62 * entails determination of a class's parameters, supertype and |
63 * interfaces, as well as (2) entering all symbols defined in the |
63 * interfaces, as well as entering all symbols defined in the |
64 * class into its scope, with the exception of class symbols which |
64 * class into its scope, with the exception of class symbols which |
65 * have been entered in phase 1. (2) depends on (1) having been |
65 * have been entered in phase 1. |
66 * completed for a class and all its superclasses and enclosing |
|
67 * classes. That's why, after doing (1), we put classes in a |
|
68 * `halfcompleted' queue. Only when we have performed (1) for a class |
|
69 * and all it's superclasses and enclosing classes, we proceed to |
|
70 * (2). |
|
71 * |
66 * |
72 * <p>Whereas the first phase is organized as a sweep through all |
67 * <p>Whereas the first phase is organized as a sweep through all |
73 * compiled syntax trees, the second phase is demand. Members of a |
68 * compiled syntax trees, the second phase is on-demand. Members of a |
74 * class are entered when the contents of a class are first |
69 * class are entered when the contents of a class are first |
75 * accessed. This is accomplished by installing completer objects in |
70 * accessed. This is accomplished by installing completer objects in |
76 * class symbols for compiled classes which invoke the member-enter |
71 * class symbols for compiled classes which invoke the type-enter |
77 * phase for the corresponding class tree. |
72 * phase for the corresponding class tree. |
78 * |
73 * |
79 * <p>Classes migrate from one phase to the next via queues: |
74 * <p>Classes migrate from one phase to the next via queues: |
80 * |
75 * |
81 * <pre>{@literal |
76 * <pre>{@literal |
82 * class enter -> (Enter.uncompleted) --> member enter (1) |
77 * class enter -> (Enter.uncompleted) --> type enter |
83 * -> (MemberEnter.halfcompleted) --> member enter (2) |
|
84 * -> (Todo) --> attribute |
78 * -> (Todo) --> attribute |
85 * (only for toplevel classes) |
79 * (only for toplevel classes) |
86 * }</pre> |
80 * }</pre> |
87 * |
81 * |
88 * <p><b>This is NOT part of any supported API. |
82 * <p><b>This is NOT part of any supported API. |
120 |
114 |
121 log = Log.instance(context); |
115 log = Log.instance(context); |
122 make = TreeMaker.instance(context); |
116 make = TreeMaker.instance(context); |
123 syms = Symtab.instance(context); |
117 syms = Symtab.instance(context); |
124 chk = Check.instance(context); |
118 chk = Check.instance(context); |
125 memberEnter = MemberEnter.instance(context); |
119 typeEnter = TypeEnter.instance(context); |
126 types = Types.instance(context); |
120 types = Types.instance(context); |
127 annotate = Annotate.instance(context); |
121 annotate = Annotate.instance(context); |
128 lint = Lint.instance(context); |
122 lint = Lint.instance(context); |
129 names = Names.instance(context); |
123 names = Names.instance(context); |
130 |
124 |
389 // table, to be retrieved later in memberEnter and attribution. |
383 // table, to be retrieved later in memberEnter and attribution. |
390 Env<AttrContext> localEnv = classEnv(tree, env); |
384 Env<AttrContext> localEnv = classEnv(tree, env); |
391 typeEnvs.put(c, localEnv); |
385 typeEnvs.put(c, localEnv); |
392 |
386 |
393 // Fill out class fields. |
387 // Fill out class fields. |
394 c.completer = memberEnter; |
388 c.completer = typeEnter; |
395 c.flags_field = chk.checkFlags(tree.pos(), tree.mods.flags, c, tree); |
389 c.flags_field = chk.checkFlags(tree.pos(), tree.mods.flags, c, tree); |
396 c.sourcefile = env.toplevel.sourcefile; |
390 c.sourcefile = env.toplevel.sourcefile; |
397 c.members_field = WriteableScope.create(c); |
391 c.members_field = WriteableScope.create(c); |
398 |
392 |
399 ClassType ct = (ClassType)c.type; |
393 ClassType ct = (ClassType)c.type; |
467 */ |
461 */ |
468 public void main(List<JCCompilationUnit> trees) { |
462 public void main(List<JCCompilationUnit> trees) { |
469 complete(trees, null); |
463 complete(trees, null); |
470 } |
464 } |
471 |
465 |
472 /** Main method: enter one class from a list of toplevel trees and |
466 /** Main method: enter classes from the list of toplevel trees, possibly |
473 * place the rest on uncompleted for later processing. |
467 * skipping TypeEnter for all but 'c' by placing them on the uncompleted |
|
468 * list. |
474 * @param trees The list of trees to be processed. |
469 * @param trees The list of trees to be processed. |
475 * @param c The class symbol to be processed. |
470 * @param c The class symbol to be processed or null to process all. |
476 */ |
471 */ |
477 public void complete(List<JCCompilationUnit> trees, ClassSymbol c) { |
472 public void complete(List<JCCompilationUnit> trees, ClassSymbol c) { |
478 annotate.enterStart(); |
473 annotate.enterStart(); |
479 ListBuffer<ClassSymbol> prevUncompleted = uncompleted; |
474 ListBuffer<ClassSymbol> prevUncompleted = uncompleted; |
480 if (memberEnter.completionEnabled) uncompleted = new ListBuffer<>(); |
475 if (typeEnter.completionEnabled) uncompleted = new ListBuffer<>(); |
481 |
476 |
482 try { |
477 try { |
483 // enter all classes, and construct uncompleted list |
478 // enter all classes, and construct uncompleted list |
484 classEnter(trees, null); |
479 classEnter(trees, null); |
485 |
480 |
486 // complete all uncompleted classes in memberEnter |
481 // complete all uncompleted classes in memberEnter |
487 if (memberEnter.completionEnabled) { |
482 if (typeEnter.completionEnabled) { |
488 while (uncompleted.nonEmpty()) { |
483 while (uncompleted.nonEmpty()) { |
489 ClassSymbol clazz = uncompleted.next(); |
484 ClassSymbol clazz = uncompleted.next(); |
490 if (c == null || c == clazz || prevUncompleted == null) |
485 if (c == null || c == clazz || prevUncompleted == null) |
491 clazz.complete(); |
486 clazz.complete(); |
492 else |
487 else |
493 // defer |
488 // defer |
494 prevUncompleted.append(clazz); |
489 prevUncompleted.append(clazz); |
495 } |
490 } |
496 |
491 |
497 // if there remain any unimported toplevels (these must have |
492 typeEnter.ensureImportsChecked(trees); |
498 // no classes at all), process their import statements as well. |
|
499 for (JCCompilationUnit tree : trees) { |
|
500 if (tree.starImportScope.isEmpty()) { |
|
501 JavaFileObject prev = log.useSource(tree.sourcefile); |
|
502 Env<AttrContext> topEnv = topLevelEnv(tree); |
|
503 memberEnter.memberEnter(tree, topEnv); |
|
504 log.useSource(prev); |
|
505 } |
|
506 } |
|
507 } |
493 } |
508 } finally { |
494 } finally { |
509 uncompleted = prevUncompleted; |
495 uncompleted = prevUncompleted; |
510 annotate.enterDone(); |
496 annotate.enterDone(); |
511 } |
497 } |