diff -r 000000000000 -r 9a66ca7c79fa src/share/classes/com/sun/tools/javac/util/Context.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/classes/com/sun/tools/javac/util/Context.java Sat Dec 01 00:00:00 2007 +0000 @@ -0,0 +1,208 @@ +/* + * Copyright 2001-2006 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +package com.sun.tools.javac.util; + +import com.sun.tools.javac.Main; +import java.util.*; + +/** + * 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.
+ */
+public class Context {
+ /** The client creates an instance of this class for each key.
+ */
+ public static class Key