In the first phase, all class symbols are intered into their enclosing scope, descending recursively down the tree for classes which are members of other classes. The class symbols are given a MemberEnter object as completer.
In the second phase classes are completed using MemberEnter.complete(). Completion might occur on demand, but any classes that are not completed that way will be eventually completed by processing the `uncompleted' queue. Completion entails (1) determination of a class's parameters, supertype and interfaces, as well as (2) entering all symbols defined in the class into its scope, with the exception of class symbols which have been entered in phase 1. (2) depends on (1) having been completed for a class and all its superclasses and enclosing classes. That's why, after doing (1), we put classes in a `halfcompleted' queue. Only when we have performed (1) for a class and all it's superclasses and enclosing classes, we proceed to (2).
Whereas the first phase is organized as a sweep through all compiled syntax trees, the second phase is demand. Members of a class are entered when the contents of a class are first accessed. This is accomplished by installing completer objects in class symbols for compiled classes which invoke the member-enter phase for the corresponding class tree.
Classes migrate from one phase to the next via queues:
class enter -> (Enter.uncompleted) --> member enter (1) -> (MemberEnter.halfcompleted) --> member enter (2) -> (Todo) --> attribute (only for toplevel classes)
This is NOT part of any supported API. If you write code that depends on this, you do so at your own risk. This code and its internal interfaces are subject to change or deletion without notice.
|
|
|
|
|
|