Support for an abstract context, modelled loosely after ThreadLocal
but using a user-provided context instead of the current thread.
Within the compiler, a single Context is used for each
invocation of the compiler. The context is then used to ensure a
single copy of each compiler phase exists per compiler invocation.
The context can be used to assist in extending the compiler by
extending its components. To do that, the extended component must
be registered before the base component. We break initialization
cycles by (1) registering a factory for the component rather than
the component itself, and (2) a convention for a pattern of usage
in which each base component registers itself by calling an
instance method that is overridden in extended components. A base
phase supporting extension would look something like this:
public class Phase {
protected static final Context.Key phaseKey =
new Context.Key();
public static Phase instance(Context context) {
Phase instance = context.get(phaseKey);
if (instance == null)
// the phase has not been overridden
instance = new Phase(context);
return instance;
}
protected Phase(Context context) {
context.put(phaseKey, this);
// other intitialization follows...
}
}
In the compiler, we simply use Phase.instance(context) to get
the reference to the phase. But in extensions of the compiler, we
must register extensions of the phases to replace the base phase,
and this must be done before any reference to the phase is accessed
using Phase.instance(). An extended phase might be declared thus:
public class NewPhase extends Phase {
protected NewPhase(Context context) {
super(context);
}
public static void preRegister(final Context context) {
context.put(phaseKey, new Context.Factory() {
public Phase make() {
return new NewPhase(context);
}
});
}
}
And is registered early in the extended compiler like this
NewPhase.preRegister(context);
This is NOT part of any API supported by Sun Microsystems. 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.
|