Merge
authortbell
Tue, 08 Dec 2009 09:16:34 -0800
changeset 4419 4cc85c49c3da
parent 4409 a426e833a79f (current diff)
parent 4418 7c5fe46dd6c5 (diff)
child 4421 fcbbd4d49581
Merge
--- a/langtools/make/Makefile	Thu Dec 03 12:53:12 2009 -0800
+++ b/langtools/make/Makefile	Tue Dec 08 09:16:34 2009 -0800
@@ -133,6 +133,23 @@
   ANT_JAVA_HOME = JAVA_HOME=$(ALT_BOOTDIR)
 endif
 
+# To facilitate bootstrapping, much of langtools can be compiled with (just)
+# a boot JDK. However, some source files need to be compiled against 
+# new JDK API. In a bootstrap build, an import JDK may not be available,
+# so build.xml can also build against the source files in a jdk repo,
+# in which case it will automatically generate stub files for the new JDK API.
+ifdef JDK_TOPDIR
+  ANT_OPTIONS += -Dimport.jdk=$(JDK_TOPDIR)
+else 
+  ifdef ALT_JDK_TOPDIR
+    ANT_OPTIONS += -Dimport.jdk=$(ALT_JDK_TOPDIR)
+  else 
+    ifdef ALT_JDK_IMPORT_DIR
+      ANT_OPTIONS += -Dimport.jdk=$(ALT_JDK_IMPORT_DIR)
+    endif
+  endif
+endif
+
 ifdef ALT_OUTPUTDIR
   OUTPUTDIR = $(ALT_OUTPUTDIR)
   ANT_OPTIONS += -Dbuild.dir=$(ALT_OUTPUTDIR)/build
--- a/langtools/make/build.properties	Thu Dec 03 12:53:12 2009 -0800
+++ b/langtools/make/build.properties	Tue Dec 08 09:16:34 2009 -0800
@@ -148,6 +148,13 @@
 
 #
 
+# The following files require the import JDK to be available
+require.import.jdk.files =
+
+# The following files in the import jdk source directory are required
+# in order to compile the files defined in ${require.import.jdk.files}
+import.jdk.stub.files =
+
 # The following value is used by the main jtreg target.
 # An empty value means all tests
 # Override as desired to run a specific set of tests
--- a/langtools/make/build.xml	Thu Dec 03 12:53:12 2009 -0800
+++ b/langtools/make/build.xml	Tue Dec 08 09:16:34 2009 -0800
@@ -56,6 +56,7 @@
     <property name="build.coverage.dir" location="${build.dir}/coverage"/>
     <property name="build.classes.dir" location="${build.dir}/classes"/>
     <property name="build.gensrc.dir" location="${build.dir}/gensrc"/>
+    <property name="build.genstubs.dir" location="${build.dir}/genstubs"/>
     <property name="build.javadoc.dir" location="${build.dir}/javadoc"/>
     <property name="build.jtreg.dir" location="${build.dir}/jtreg"/>
     <property name="build.toolclasses.dir" location="${build.dir}/toolclasses"/>
@@ -93,6 +94,41 @@
         <isset property="target.java.home"/>
     </condition>
 
+    <!-- Logic for handling access import jdk classes, if available.
+        import.jdk should be unset, or set to jdk home (to use rt.jar)
+        or to jdk repo (to use src/share/classes).
+        Based on the value, if any, set up default values for javac's sourcepath,
+        classpath and bootclasspath. Note: the default values are overridden 
+        in the build-bootstrap-classes macro. -->
+
+    <available property="import.jdk.src.dir" value="${import.jdk}/src/share/classes"
+        filepath="${import.jdk}/src/share/classes" file="java/nio/file/Path.java"/>
+    <available property="import.jdk.jar" value="${import.jdk}/jre/lib/rt.jar"
+        ignoresystemclasses="true"
+        classpath="${import.jdk}/jre/lib/rt.jar" classname="java.nio.file.Path"/>
+
+    <condition property="javac.sourcepath" value="${build.genstubs.dir}" else="">
+        <isset property="import.jdk.src.dir"/>
+    </condition>
+
+    <property name="javac.classpath" value=""/>
+
+    <condition property="javac.bootclasspath.opt"
+            value="-Xbootclasspath:${build.classes.dir}:${import.jdk.jar}"
+            else="-Xbootclasspath/p:${build.classes.dir}">
+        <isset property="import.jdk.jar"/>
+    </condition>
+
+    <condition property="exclude.files" value="" else="${require.import.jdk.files}">
+        <isset property="import.jdk"/>
+    </condition>
+
+    <!-- for debugging -->
+    <target name="check-import.jdk">
+        <echo message="import.jdk: ${import.jdk}"/>
+        <echo message="import.jdk.jar: ${import.jdk.jar}"/>
+        <echo message="import.jdk.src.dir: ${import.jdk.src.dir}"/>
+    </target>
 
     <!-- Standard target to build deliverables for JDK build. -->
 
@@ -108,11 +144,17 @@
         <zip file="${dist.lib.dir}/src.zip" basedir="${src.classes.dir}"/>
     </target>
 
-    <target name="build-bootstrap-tools" depends="build-bootstrap-javac,build-bootstrap-javadoc,build-bootstrap-doclets,build-bootstrap-javah"/>
+    <target name="build-bootstrap-tools"
+        depends="build-bootstrap-javac,build-bootstrap-javadoc,build-bootstrap-doclets,build-bootstrap-javah"
+    />
 
-    <target name="build-all-tools" depends="build-javac,build-javadoc,build-doclets,build-javah,build-javap,build-apt"/>
+    <target name="build-all-tools"
+        depends="build-javac,build-javadoc,build-doclets,build-javah,build-javap,build-apt"
+    />
 
-    <target name="build-all-classes" depends="build-classes-javac,build-classes-javadoc,build-classes-doclets,build-classes-javah,build-classes-javap,build-classes-apt"/>
+    <target name="build-all-classes" depends="build-bootstrap-javac,-create-import-jdk-stubs">
+        <build-classes includes="${javac.includes} ${javadoc.includes} ${doclets.includes} ${javah.includes} ${javap.includes} ${apt.includes}"/>
+    </target>
 
     <!-- clean -->
 
@@ -188,23 +230,27 @@
 
     <!-- javac targets -->
 
-    <target name="build-bootstrap-javac" depends="-def-build-bootstrap-tool">
-        <build-bootstrap-tool name="javac" includes="${javac.includes}"/>
+    <target name="build-bootstrap-javac"
+            depends="-def-build-bootstrap-classes,-def-build-bootstrap-jar,-def-build-bootstrap-tool">
+        <build-bootstrap-classes includes="${javac.includes}"/>
+        <build-bootstrap-jar     name="javac" includes="${javac.includes}"/>
+        <build-bootstrap-tool    name="javac"/>
     </target>
 
-    <target name="build-classes-javac" depends="build-bootstrap-javac">
-        <build-classes name="javac" includes="${javac.includes}"/>
+    <target name="build-classes-javac" depends="build-bootstrap-javac,-create-import-jdk-stubs">
+        <build-classes includes="${javac.includes}"/>
     </target>
 
-    <target name="build-javac" depends="build-bootstrap-javac">
-        <build-tool name="javac" includes="${javac.includes}"/>
+    <target name="build-javac" depends="build-classes-javac">
+        <build-jar  name="javac" includes="${javac.includes}"/>
+        <build-tool name="javac"/>
     </target>
 
     <target name="javadoc-javac" depends="build-javac,-def-javadoc-tool">
         <javadoc-tool name="javac" includes="${javac.includes}" options="${javadoc.jls3.option}"/>
     </target>
 
-    <target name="jtreg-javac" depends="build-javac,-def-jtreg">
+    <target name="jtreg-javac" depends="build-javac,build-javap,-def-jtreg">
         <jtreg-tool name="javac" tests="${javac.tests}"/>
     </target>
 
@@ -217,19 +263,20 @@
     <!-- javadoc targets -->
 
     <target name="build-bootstrap-javadoc" depends="build-bootstrap-javac">
-        <build-bootstrap-tool name="javadoc"
-                              includes="${javadoc.includes}"
-                              jarclasspath="javac.jar doclets.jar"/>
+        <build-bootstrap-classes includes="${javadoc.includes}"/>
+        <build-bootstrap-jar     name="javadoc" includes="${javadoc.includes}"
+                                 jarclasspath="javac.jar doclets.jar"/>
+        <build-bootstrap-tool    name="javadoc"/>
     </target>
 
     <target name="build-classes-javadoc" depends="build-classes-javac">
-        <build-classes name="javadoc" includes="${javadoc.includes}"/>
+        <build-classes includes="${javadoc.includes}"/>
     </target>
 
-    <target name="build-javadoc" depends="build-javac">
-        <build-tool name="javadoc"
-                    includes="${javadoc.includes}"
+    <target name="build-javadoc" depends="build-javac,build-classes-javadoc">
+        <build-jar  name="javadoc" includes="${javadoc.includes}"
                     jarclasspath="javac.jar doclets.jar"/>
+        <build-tool name="javadoc"/>
     </target>
 
     <target name="javadoc-javadoc" depends="build-javadoc,-def-javadoc-tool">
@@ -249,21 +296,19 @@
     <!-- doclets targets -->
 
     <target name="build-bootstrap-doclets" depends="build-bootstrap-javadoc,-def-build-bootstrap-jar">
-        <build-bootstrap-jar name="doclets"
-                              includes="${doclets.includes}"
-                              jarmainclass="com.sun.tools.javadoc.Main"
-                              jarclasspath="javadoc.jar"/>
+        <build-bootstrap-classes includes="${doclets.includes}"/>
+        <build-bootstrap-jar     name="doclets" includes="${doclets.includes}"
+                                 jarmainclass="com.sun.tools.javadoc.Main"
+                                 jarclasspath="javadoc.jar"/>
     </target>
 
     <target name="build-classes-doclets" depends="build-classes-javadoc">
-        <build-classes name="doclets" includes="${doclets.includes}"/>
+        <build-classes includes="${doclets.includes}"/>
     </target>
 
-    <target name="build-doclets" depends="build-javadoc">
+    <target name="build-doclets" depends="build-javadoc,build-classes-doclets">
         <!-- just jar, no bin for doclets -->
-        <build-jar name="doclets"
-                    includes="${doclets.includes}"
-                    jarclasspath="javadoc.jar"/>
+        <build-jar name="doclets" includes="${doclets.includes}" jarclasspath="javadoc.jar"/>
     </target>
 
     <!-- (no javadoc for doclets) -->
@@ -281,19 +326,19 @@
     <!-- javah targets -->
 
     <target name="build-bootstrap-javah" depends="build-bootstrap-javadoc">
-        <build-bootstrap-tool name="javah"
-                              includes="${javah.includes}"
-                              jarclasspath="javadoc.jar doclets.jar javac.jar"/>
+        <build-bootstrap-classes includes="${javah.includes}"/>
+        <build-bootstrap-jar     name="javah" includes="${javah.includes}"
+                                 jarclasspath="javadoc.jar doclets.jar javac.jar"/>
+        <build-bootstrap-tool    name="javah"/>
     </target>
 
-    <target name="build-javah" depends="build-javac">
-        <build-tool name="javah"
-                    includes="${javah.includes}"
-                    jarclasspath="javac.jar"/>
+    <target name="build-javah" depends="build-javac,build-classes-javah">
+        <build-jar  name="javah" includes="${javah.includes}" jarclasspath="javac.jar"/>
+        <build-tool name="javah"/>
     </target>
 
     <target name="build-classes-javah" depends="build-classes-javadoc">
-        <build-classes name="javah" includes="${javah.includes}"/>
+        <build-classes includes="${javah.includes}"/>
     </target>
 
     <!-- (no javadoc for javah) -->
@@ -310,21 +355,23 @@
 
     <!-- javap targets -->
 
-    <target name="build-bootstrap-javap" depends="-def-build-bootstrap-tool">
-        <build-bootstrap-tool name="javap"
-                              includes="${javap.includes}"
-                              jarmainclass="sun.tools.javap.Main"/>
+    <target name="build-bootstrap-javap"
+            depends="-def-build-bootstrap-classes,-def-build-bootstrap-jar,-def-build-bootstrap-tool">
+        <build-bootstrap-classes includes="${javap.includes}"/>
+        <build-bootstrap-jar     name="javap" includes="${javap.includes}"
+                                 jarmainclass="sun.tools.javap.Main"/>
+        <build-bootstrap-tool    name="javap"/>
     </target>
 
     <target name="build-classes-javap" depends="build-classes-javac">
-        <build-classes name="javap" includes="${javap.includes}"/>
+        <build-classes includes="${javap.includes}"/>
     </target>
 
-    <target name="build-javap" depends="build-javac">
-        <build-tool name="javap"
-                    includes="${javap.includes}"
+    <target name="build-javap" depends="build-javac,build-classes-javap">
+        <build-jar  name="javap" includes="${javap.includes}"
                     jarmainclass="com.sun.tools.javap.Main"
                     jarclasspath="javac.jar"/>
+        <build-tool name="javap"/>
     </target>
 
     <!-- (no javadoc for javap) -->
@@ -342,19 +389,19 @@
     <!-- apt targets -->
 
     <target name="build-bootstrap-apt" depends="build-bootstrap-javac">
-        <build-bootstrap-tool name="apt"
-                              includes="${apt.includes}"
-                              jarclasspath="javac.jar"/>
+        <build-bootstrap-classes includes="${apt.includes}"/>
+        <build-bootstrap-jar     name="apt" includes="${apt.includes}"
+                                 jarclasspath="javac.jar"/>
+        <build-bootstrap-tool    name="apt"/>
     </target>
 
-    <target name="build-apt" depends="build-javac">
-        <build-tool name="apt"
-                    includes="${apt.includes}"
-                    jarclasspath="javac.jar"/>
+    <target name="build-apt" depends="build-javac,build-classes-apt">
+        <build-jar  name="apt" includes="${apt.includes}" jarclasspath="javac.jar"/>
+        <build-tool name="apt"/>
     </target>
 
     <target name="build-classes-apt" depends="build-classes-javac">
-        <build-classes name="apt" includes="${apt.includes}"/>
+        <build-classes includes="${apt.includes}"/>
     </target>
 
     <target name="javadoc-apt" depends="build-apt,-def-javadoc-tool">
@@ -372,6 +419,17 @@
 
     <target name="apt" depends="build-apt,jtreg-apt,findbugs-apt"/>
 
+    <!-- Create import JDK stubs -->
+
+    <target name="-create-import-jdk-stubs" depends="-def-genstubs" if="import.jdk.src.dir">
+        <mkdir dir="${build.genstubs.dir}"/>
+        <genstubs
+            srcdir="${import.jdk.src.dir}" destdir="${build.genstubs.dir}"
+            includes="${import.jdk.stub.files}"
+            fork="true" classpath="${build.toolclasses.dir}:${build.bootstrap.dir}/classes:${ant.home}/lib/ant.jar"
+        />
+    </target>
+
     <!-- Check targets -->
 
     <target name="-check-boot.java.home" depends="-def-check">
@@ -396,40 +454,12 @@
 
     <!-- Ant macro and preset defs -->
 
-    <target name="-def-build-tool" depends="-def-build-jar">
+    <target name="-def-build-tool">
         <macrodef name="build-tool">
             <attribute name="name"/>
-            <attribute name="includes"/>
-            <attribute name="excludes" default="**/package-info.java"/>
             <attribute name="bin.dir" default="${dist.bin.dir}"/>
-            <attribute name="classes.dir" default="${build.classes.dir}"/>
-            <attribute name="gensrc.dir" default="${build.gensrc.dir}"/>
-            <attribute name="lib.dir" default="${dist.lib.dir}"/>
             <attribute name="java" default="${launcher.java}"/>
-            <attribute name="javac.bootclasspath" default="${build.bootstrap.dir}/classes"/>
-            <attribute name="javac.java.home" default="${boot.java.home}"/>
-            <attribute name="javac.source" default="${javac.source}"/>
-            <attribute name="javac.target" default="${javac.target}"/>
-            <attribute name="jarmainclass" default="com.sun.tools.@{name}.Main"/>
-            <attribute name="jarclasspath" default=""/>
-            <attribute name="release" default="${release}"/>
-            <attribute name="full.version" default="${full.version}"/>
             <sequential>
-                <build-jar
-                    name="@{name}"
-                    gensrc.dir="@{gensrc.dir}"
-                    classes.dir="@{classes.dir}"
-                    lib.dir="@{lib.dir}"
-                    includes="@{includes}"
-                    excludes="@{excludes}"
-                    jarmainclass="@{jarmainclass}"
-                    jarclasspath="@{jarclasspath}"
-                    release="@{release}"
-                    full.version="@{full.version}"
-                    javac.bootclasspath="@{javac.bootclasspath}"
-                    javac.source="@{javac.source}"
-                    javac.target="@{javac.target}"
-                />
                 <mkdir dir="@{bin.dir}"/>
                 <copy file="${src.bin.dir}/launcher.sh-template" tofile="@{bin.dir}/@{name}">
                     <filterset begintoken="#" endtoken="#">
@@ -442,35 +472,15 @@
         </macrodef>
     </target>
 
-    <target name="-def-build-jar" depends="-def-build-classes">
+    <target name="-def-build-jar">
         <macrodef name="build-jar">
             <attribute name="name"/>
             <attribute name="includes"/>
-            <attribute name="excludes" default="**/package-info.java"/>
             <attribute name="classes.dir" default="${build.classes.dir}"/>
-            <attribute name="gensrc.dir" default="${build.gensrc.dir}"/>
             <attribute name="lib.dir" default="${dist.lib.dir}"/>
-            <attribute name="javac.bootclasspath" default="${build.bootstrap.dir}/classes"/>
-            <attribute name="javac.java.home" default="${boot.java.home}"/>
-            <attribute name="javac.source" default="${javac.source}"/>
-            <attribute name="javac.target" default="${javac.target}"/>
             <attribute name="jarmainclass" default="com.sun.tools.@{name}.Main"/>
             <attribute name="jarclasspath" default=""/>
-            <attribute name="release" default="${release}"/>
-            <attribute name="full.version" default="${full.version}"/>
             <sequential>
-                <build-classes
-                    name="@{name}"
-                    gensrc.dir="@{gensrc.dir}"
-                    classes.dir="@{classes.dir}"
-                    includes="@{includes}"
-                    excludes="@{excludes}"
-                    release="@{release}"
-                    full.version="@{full.version}"
-                    javac.bootclasspath="@{javac.bootclasspath}"
-                    javac.source="@{javac.source}"
-                    javac.target="@{javac.target}"
-                />
                 <mkdir dir="@{lib.dir}"/>
                 <jar destfile="@{lib.dir}/@{name}.jar"
                      basedir="@{classes.dir}"
@@ -486,18 +496,24 @@
 
     <target name="-def-build-classes" depends="-def-pcompile">
         <macrodef name="build-classes">
-            <attribute name="name"/>
             <attribute name="includes"/>
-            <attribute name="excludes" default="**/package-info.java"/>
+            <attribute name="excludes" default="${exclude.files} **/package-info.java"/>
             <attribute name="classes.dir" default="${build.classes.dir}"/>
             <attribute name="gensrc.dir" default="${build.gensrc.dir}"/>
             <attribute name="javac.bootclasspath" default="${build.bootstrap.dir}/classes"/>
-            <attribute name="javac.java.home" default="${boot.java.home}"/>
-            <attribute name="javac.source" default="${javac.source}"/>
-            <attribute name="javac.target" default="${javac.target}"/>
+            <attribute name="bootclasspath.opt" default="${javac.bootclasspath.opt}"/>
+            <attribute name="classpath" default="${javac.classpath}"/>
+            <attribute name="sourcepath" default="${javac.sourcepath}"/>
+            <attribute name="java.home" default="${boot.java.home}"/>
+            <attribute name="source" default="${javac.source}"/>
+            <attribute name="target" default="${javac.target}"/>
             <attribute name="release" default="${release}"/>
             <attribute name="full.version" default="${full.version}"/>
             <sequential>
+                <echo level="verbose" message="build-classes: excludes=@{excludes}"/>
+                <echo level="verbose" message="build-classes: bootclasspath.opt=@{bootclasspath.opt}"/>
+                <echo level="verbose" message="build-classes: classpath=@{classpath}"/>
+                <echo level="verbose" message="build-classes: sourcepath=@{sourcepath}"/>
                 <mkdir dir="@{gensrc.dir}"/>
                 <mkdir dir="@{classes.dir}"/>
                 <pcompile srcdir="${src.classes.dir}"
@@ -516,39 +532,28 @@
                           destdir="@{gensrc.dir}"
                           includes="**/*.properties"/>
                 <javac fork="true"
-                       executable="@{javac.java.home}/bin/javac"
-                       srcdir="@{gensrc.dir}"
-                       destdir="@{classes.dir}"
-                       includes="@{includes}"
-                       sourcepath=""
-                       includeAntRuntime="no"
-                       source="@{javac.source}"
-                       target="@{javac.target}">
-                    <compilerarg value="-J-Xbootclasspath/p:@{javac.bootclasspath}"/>
-                    <compilerarg line="${javac.version.opt}"/>
-                    <compilerarg line="-Xlint"/>
-                </javac>
-                <javac fork="true"
-                       executable="@{javac.java.home}/bin/javac"
-                       srcdir="${src.classes.dir}"
+                       executable="@{java.home}/bin/javac"
+                       srcdir="${src.classes.dir}:@{gensrc.dir}"
                        destdir="@{classes.dir}"
                        includes="@{includes}"
                        excludes="@{excludes}"
-                       sourcepath=""
+                       sourcepath="@{sourcepath}"
+                       classpath="@{classpath}"
                        includeAntRuntime="no"
-                       source="@{javac.source}"
-                       target="@{javac.target}"
+                       source="@{source}"
+                       target="@{target}"
                        debug="${javac.debug}"
                        debuglevel="${javac.debuglevel}">
+                    <compilerarg value="-implicit:none"/>
+                    <compilerarg value="-Xprefer:source"/>
                     <compilerarg value="-J-Xbootclasspath/p:@{javac.bootclasspath}"/>
-                    <compilerarg value="-Xbootclasspath/p:@{classes.dir}"/>
+                    <compilerarg line="@{bootclasspath.opt}"/>
                     <compilerarg line="${javac.no.jdk.warnings}"/>
                     <compilerarg line="${javac.version.opt}"/>
                     <compilerarg line="${javac.lint.opts}"/>
                 </javac>
                 <copy todir="@{classes.dir}">
-                    <fileset dir="${src.classes.dir}">
-                        <include name="@{includes}"/>
+                    <fileset dir="${src.classes.dir}" includes="@{includes}">
                         <exclude name="**/*.java"/>
                         <exclude name="**/*.properties"/>
                         <exclude name="**/*-template"/>
@@ -562,30 +567,32 @@
     <target name="-def-build-bootstrap-tool" depends="-check-boot.java.home,-def-build-tool">
         <presetdef name="build-bootstrap-tool">
             <build-tool
-                javac.source="${boot.javac.source}"
-                javac.target="${boot.javac.target}"
-                gensrc.dir="${build.bootstrap.dir}/gensrc"
-                classes.dir="${build.bootstrap.dir}/classes"
                 bin.dir="${build.bootstrap.dir}/bin"
-                lib.dir="${build.bootstrap.dir}/lib"
-                java="${boot.java}"
-                javac.bootclasspath=""
-                release="${bootstrap.release}"
-                full.version="${bootstrap.full.version}"/>
+                java="${boot.java}"/>
         </presetdef>
     </target>
 
     <target name="-def-build-bootstrap-jar" depends="-def-build-jar">
         <presetdef name="build-bootstrap-jar">
             <build-jar
-                javac.source="${boot.javac.source}"
-                javac.target="${boot.javac.target}"
+                classes.dir="${build.bootstrap.dir}/classes"
+                lib.dir="${build.bootstrap.dir}/lib"/>
+        </presetdef>
+    </target>
+
+    <target name="-def-build-bootstrap-classes" depends="-def-build-classes">
+        <presetdef name="build-bootstrap-classes">
+            <build-classes
+                source="${boot.javac.source}"
+                target="${boot.javac.target}"
                 gensrc.dir="${build.bootstrap.dir}/gensrc"
                 classes.dir="${build.bootstrap.dir}/classes"
-                lib.dir="${build.bootstrap.dir}/lib"
                 javac.bootclasspath=""
+                bootclasspath.opt="-Xbootclasspath/p:${build.bootstrap.dir}/classes"
+                sourcepath=""
                 release="${bootstrap.release}"
-                full.version="${bootstrap.full.version}"/>
+                full.version="${bootstrap.full.version}"
+                excludes="${require.import.jdk.files} **/package-info.java"/>
         </presetdef>
     </target>
 
@@ -603,6 +610,20 @@
                  classpath="${build.toolclasses.dir}/"/>
     </target>
 
+    <target name="-def-genstubs" depends="build-bootstrap-javac">
+        <mkdir dir="${build.toolclasses.dir}"/>
+        <javac fork="true"
+               source="${boot.javac.source}"
+               target="${boot.javac.target}"
+               executable="${boot.java.home}/bin/javac"
+               srcdir="${make.tools.dir}/GenStubs"
+               destdir="${build.toolclasses.dir}/"
+               classpath="${build.bootstrap.dir}/classes:${ant.home}/lib/ant.jar"/>
+        <taskdef name="genstubs"
+                 classname="GenStubs$$Ant"
+                 classpath="${build.toolclasses.dir}/"/>
+    </target>
+
     <target name="-def-javadoc-tool" depends="-check-target.java.home">
         <macrodef name="javadoc-tool">
             <attribute name="name"/>
@@ -764,7 +785,7 @@
 
     <!-- standard JDK target -->
     <target name="sanity"
-        description="display settings of congiguration values">
+        description="display settings of configuration values">
         <echo level="info">ant.home = ${ant.home}</echo>
         <echo level="info">boot.java.home = ${boot.java.home}</echo>
         <echo level="info">target.java.home = ${target.java.home}</echo>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/make/tools/GenStubs/GenStubs.java	Tue Dec 08 09:16:34 2009 -0800
@@ -0,0 +1,392 @@
+/*
+ * Copyright 2009 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.
+ */
+import java.io.*;
+import java.util.*;
+import javax.tools.JavaFileObject;
+import javax.tools.StandardJavaFileManager;
+import javax.tools.StandardLocation;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.DirectoryScanner;
+import org.apache.tools.ant.taskdefs.MatchingTask;
+import org.apache.tools.ant.types.Path;
+import org.apache.tools.ant.types.Reference;
+
+
+import com.sun.source.tree.CompilationUnitTree;
+import com.sun.source.util.JavacTask;
+import com.sun.tools.javac.api.JavacTool;
+import com.sun.tools.javac.code.Flags;
+import com.sun.tools.javac.code.TypeTags;
+import com.sun.tools.javac.tree.JCTree;
+import com.sun.tools.javac.tree.JCTree.JCBlock;
+import com.sun.tools.javac.tree.JCTree.JCCompilationUnit;
+import com.sun.tools.javac.tree.JCTree.JCLiteral;
+import com.sun.tools.javac.tree.JCTree.JCMethodDecl;
+import com.sun.tools.javac.tree.JCTree.JCModifiers;
+import com.sun.tools.javac.tree.JCTree.JCStatement;
+import com.sun.tools.javac.tree.JCTree.JCVariableDecl;
+import com.sun.tools.javac.tree.Pretty;
+import com.sun.tools.javac.tree.TreeTranslator;
+
+/**
+ * Generate stub source files by removing implementation details from input files.
+ *
+ * This is a special purpose stub generator, specific to the needs of generating
+ * stub files for JDK 7 API that are needed to compile langtools files that depend
+ * on that API. The stub generator works by removing as much of the API source code
+ * as possible without affecting the public signature, in order to reduce the
+ * transitive closure of the API being referenced. The resulting stubs can be
+ * put on the langtools sourcepath with -implicit:none to compile the langtools
+ * files that depend on the JDK 7 API.
+ *
+ * Usage:
+ *  genstubs -s <outdir> -sourcepath <path> <classnames>
+ *
+ * The specified class names are looked up on the sourcepath, and corresponding
+ * stubs are written to the source output directory.
+ *
+ * Classes are parsed into javac ASTs, then processed with a javac TreeTranslator
+ * to remove implementation details, and written out in the source output directory.
+ * Documentation comments and annotations are removed. Method bodies are removed
+ * and methods are marked native. Private and package-private field definitions
+ * have their initializers replace with 0, 0.0, false, null as appropriate.
+ *
+ * An Ant task, Main$Ant is also provided. Files are specified with an implicit
+ * fileset, using srcdir as a base directory. The set of files to be included
+ * is specified with an includes attribute or nested <includes> set. However,
+ * unlike a normal fileset, an empty includes attribute means "no files" instead
+ * of "all files".  The Ant task also accepts "fork=true" and classpath attribute
+ * or nested <classpath> element to run GenStubs in a separate VM with the specified
+ * path. This is likely necessary if a JDK 7 parser is required to read the
+ * JDK 7 input files.
+ */
+
+public class GenStubs {
+    static class Fault extends Exception {
+        private static final long serialVersionUID = 0;
+        Fault(String message) {
+            super(message);
+        }
+        Fault(String message, Throwable cause) {
+            super(message);
+            initCause(cause);
+        }
+    }
+
+    public static void main(String[] args) {
+        boolean ok = new GenStubs().run(args);
+        if (!ok)
+            System.exit(1);
+    }
+
+    boolean run(String... args) {
+        File outdir = null;
+        String sourcepath = null;
+        List<String> classes = new ArrayList<String>();
+        for (ListIterator<String> iter = Arrays.asList(args).listIterator(); iter.hasNext(); ) {
+            String arg = iter.next();
+            if (arg.equals("-s") && iter.hasNext())
+                outdir = new File(iter.next());
+            else if (arg.equals("-sourcepath") && iter.hasNext())
+                sourcepath = iter.next();
+            else if (arg.startsWith("-"))
+                throw new IllegalArgumentException(arg);
+            else {
+                classes.add(arg);
+                while (iter.hasNext())
+                    classes.add(iter.next());
+            }
+        }
+
+        return run(sourcepath, outdir, classes);
+    }
+
+    boolean run(String sourcepath, File outdir, List<String> classes) {
+        //System.err.println("run: sourcepath:" + sourcepath + " outdir:" + outdir + " classes:" + classes);
+        if (sourcepath == null)
+            throw new IllegalArgumentException("sourcepath not set");
+        if (outdir == null)
+            throw new IllegalArgumentException("source output dir not set");
+
+        JavacTool tool = JavacTool.create();
+        StandardJavaFileManager fm = tool.getStandardFileManager(null, null, null);
+
+        try {
+            fm.setLocation(StandardLocation.SOURCE_OUTPUT, Collections.singleton(outdir));
+            fm.setLocation(StandardLocation.SOURCE_PATH, splitPath(sourcepath));
+            List<JavaFileObject> files = new ArrayList<JavaFileObject>();
+            for (String c: classes) {
+                JavaFileObject fo = fm.getJavaFileForInput(
+                        StandardLocation.SOURCE_PATH, c, JavaFileObject.Kind.SOURCE);
+                if (fo == null)
+                    error("class not found: " + c);
+                else
+                    files.add(fo);
+            }
+
+            JavacTask t = tool.getTask(null, fm, null, null, null, files);
+            Iterable<? extends CompilationUnitTree> trees = t.parse();
+            for (CompilationUnitTree tree: trees) {
+                makeStub(fm, tree);
+            }
+        } catch (IOException e) {
+            error("IO error " + e, e);
+        }
+
+        return (errors == 0);
+    }
+
+    void makeStub(StandardJavaFileManager fm, CompilationUnitTree tree) throws IOException {
+        CompilationUnitTree tree2 = new StubMaker().translate(tree);
+
+        String className = fm.inferBinaryName(StandardLocation.SOURCE_PATH, tree.getSourceFile());
+        JavaFileObject fo = fm.getJavaFileForOutput(StandardLocation.SOURCE_OUTPUT,
+                className, JavaFileObject.Kind.SOURCE, null);
+        // System.err.println("Writing " + className + " to " + fo.getName());
+        Writer out = fo.openWriter();
+        try {
+            new Pretty(out, true).printExpr((JCTree) tree2);
+        } finally {
+            out.close();
+        }
+    }
+
+    List<File> splitPath(String path) {
+        List<File> list = new ArrayList<File>();
+        for (String p: path.split(File.pathSeparator)) {
+            if (p.length() > 0)
+                list.add(new File(p));
+        }
+        return list;
+    }
+
+    void error(String message) {
+        System.err.println(message);
+        errors++;
+    }
+
+    void error(String message, Throwable cause) {
+        error(message);
+    }
+
+    int errors;
+
+    class StubMaker extends TreeTranslator {
+        CompilationUnitTree translate(CompilationUnitTree tree) {
+            return super.translate((JCCompilationUnit) tree);
+        }
+
+        /**
+         * compilation units: remove javadoc comments
+         * -- required, in order to remove @deprecated tags, since we
+         * (separately) remove all annotations, including @Deprecated
+         */
+        public void visitTopLevel(JCCompilationUnit tree) {
+            super.visitTopLevel(tree);
+            tree.docComments = Collections.emptyMap();
+        }
+
+        /**
+         * methods: remove method bodies, make methods native
+         */
+        @Override
+        public void visitMethodDef(JCMethodDecl tree) {
+            tree.mods = translate(tree.mods);
+            tree.restype = translate(tree.restype);
+            tree.typarams = translateTypeParams(tree.typarams);
+            tree.params = translateVarDefs(tree.params);
+            tree.thrown = translate(tree.thrown);
+            if (tree.restype != null && tree.body != null) {
+                tree.mods.flags |= Flags.NATIVE;
+                tree.body = null;
+            }
+            result = tree;
+        }
+
+        /**
+         * modifiers: remove annotations
+         */
+        @Override
+        public void visitModifiers(JCModifiers tree) {
+            tree.annotations = com.sun.tools.javac.util.List.nil();
+            result = tree;
+        }
+
+        /**
+         * field definitions: replace initializers with 0, 0.0, false etc
+         * when possible -- i.e. leave public, protected initializers alone
+         */
+        @Override
+        public void visitVarDef(JCVariableDecl tree) {
+            tree.mods = translate(tree.mods);
+            tree.vartype = translate(tree.vartype);
+            if (tree.init != null) {
+                if ((tree.mods.flags & (Flags.PUBLIC | Flags.PROTECTED)) != 0)
+                    tree.init = translate(tree.init);
+                else {
+                    String t = tree.vartype.toString();
+                    if (t.equals("boolean"))
+                        tree.init = new JCLiteral(TypeTags.BOOLEAN, 0) { };
+                    else if (t.equals("byte"))
+                        tree.init = new JCLiteral(TypeTags.BYTE, 0) { };
+                    else if (t.equals("char"))
+                        tree.init = new JCLiteral(TypeTags.CHAR, 0) { };
+                    else if (t.equals("double"))
+                        tree.init = new JCLiteral(TypeTags.DOUBLE, 0.d) { };
+                    else if (t.equals("float"))
+                        tree.init = new JCLiteral(TypeTags.FLOAT, 0.f) { };
+                    else if (t.equals("int"))
+                        tree.init = new JCLiteral(TypeTags.INT, 0) { };
+                    else if (t.equals("long"))
+                        tree.init = new JCLiteral(TypeTags.LONG, 0) { };
+                    else if (t.equals("short"))
+                        tree.init = new JCLiteral(TypeTags.SHORT, 0) { };
+                    else
+                        tree.init = new JCLiteral(TypeTags.BOT, null) { };
+                }
+            }
+            result = tree;
+        }
+    }
+
+    //---------- Ant Invocation ------------------------------------------------
+
+    public static class Ant extends MatchingTask {
+        private File srcDir;
+        private File destDir;
+        private boolean fork;
+        private Path classpath;
+        private String includes;
+
+        public void setSrcDir(File dir) {
+            this.srcDir = dir;
+        }
+
+        public void setDestDir(File dir) {
+            this.destDir = dir;
+        }
+
+        public void setFork(boolean v) {
+            this.fork = v;
+        }
+
+        public void setClasspath(Path cp) {
+            if (classpath == null)
+                classpath = cp;
+            else
+                classpath.append(cp);
+        }
+
+        public Path createClasspath() {
+            if (classpath == null) {
+                classpath = new Path(getProject());
+            }
+            return classpath.createPath();
+        }
+
+        public void setClasspathRef(Reference r) {
+            createClasspath().setRefid(r);
+        }
+
+        public void setIncludes(String includes) {
+            super.setIncludes(includes);
+            this.includes = includes;
+        }
+
+        @Override
+        public void execute() {
+            if (includes != null && includes.trim().isEmpty())
+                return;
+
+            DirectoryScanner s = getDirectoryScanner(srcDir);
+            String[] files = s.getIncludedFiles();
+//            System.err.println("Ant.execute: srcDir " + srcDir);
+//            System.err.println("Ant.execute: destDir " + destDir);
+//            System.err.println("Ant.execute: files " + Arrays.asList(files));
+
+            files = filter(srcDir, destDir, files);
+            if (files.length == 0)
+                return;
+            System.out.println("Generating " + files.length + " stub files to " + destDir);
+
+            List<String> classNames = new ArrayList<String>();
+            for (String file: files) {
+                classNames.add(file.replaceAll(".java$", "").replace('/', '.'));
+            }
+
+            if (!fork) {
+                GenStubs m = new GenStubs();
+                boolean ok = m.run(srcDir.getPath(), destDir, classNames);
+                if (!ok)
+                    throw new BuildException("genstubs failed");
+            } else {
+                List<String> cmd = new ArrayList<String>();
+                String java_home = System.getProperty("java.home");
+                cmd.add(new File(new File(java_home, "bin"), "java").getPath());
+                if (classpath != null)
+                    cmd.add("-Xbootclasspath/p:" + classpath);
+                cmd.add(GenStubs.class.getName());
+                cmd.add("-sourcepath");
+                cmd.add(srcDir.getPath());
+                cmd.add("-s");
+                cmd.add(destDir.getPath());
+                cmd.addAll(classNames);
+                //System.err.println("GenStubs exec " + cmd);
+                ProcessBuilder pb = new ProcessBuilder(cmd);
+                pb.redirectErrorStream(true);
+                try {
+                    Process p = pb.start();
+                    BufferedReader in = new BufferedReader(new InputStreamReader(p.getInputStream()));
+                    try {
+                        String line;
+                        while ((line = in.readLine()) != null)
+                            System.out.println(line);
+                    } finally {
+                        in.close();
+                    }
+                    int rc = p.waitFor();
+                    if (rc != 0)
+                        throw new BuildException("genstubs failed");
+                } catch (IOException e) {
+                    throw new BuildException("genstubs failed", e);
+                } catch (InterruptedException e) {
+                    throw new BuildException("genstubs failed", e);
+                }
+            }
+        }
+
+        String[] filter(File srcDir, File destDir, String[] files) {
+            List<String> results = new ArrayList<String>();
+            for (String f: files) {
+                long srcTime = new File(srcDir, f).lastModified();
+                long destTime = new File(destDir, f).lastModified();
+                if (srcTime > destTime)
+                    results.add(f);
+            }
+            return results.toArray(new String[results.size()]);
+        }
+    }
+}
--- a/langtools/src/share/classes/com/sun/tools/classfile/Instruction.java	Thu Dec 03 12:53:12 2009 -0800
+++ b/langtools/src/share/classes/com/sun/tools/classfile/Instruction.java	Tue Dec 08 09:16:34 2009 -0800
@@ -106,9 +106,9 @@
         /** See {@link Kind#LOCAL_UBYTE}. */
         R visitLocalAndValue(Instruction instr, int index, int value, P p);
         /** See {@link Kind#DYNAMIC}. */
-        R visitLookupSwitch(Instruction instr, int default_, int npairs, int[] matches, int[] offsets);
+        R visitLookupSwitch(Instruction instr, int default_, int npairs, int[] matches, int[] offsets, P p);
         /** See {@link Kind#DYNAMIC}. */
-        R visitTableSwitch(Instruction instr, int default_, int low, int high, int[] offsets);
+        R visitTableSwitch(Instruction instr, int default_, int low, int high, int[] offsets, P p);
         /** See {@link Kind#BYTE}, {@link Kind#SHORT}. */
         R visitValue(Instruction instr, int value, P p);
         /** Instruction is unrecognized. */
@@ -282,7 +282,7 @@
                         for (int i = 0; i < values.length; i++)
                             values[i] = getInt(pad + 12 + 4 * i);
                         return visitor.visitTableSwitch(
-                                this, default_, low, high, values);
+                                this, default_, low, high, values, p);
                     }
                     case LOOKUPSWITCH: {
                         int pad = align(pc + 1) - pc;
@@ -295,7 +295,7 @@
                             offsets[i] = getInt(pad + 12 + i * 8);
                         }
                         return visitor.visitLookupSwitch(
-                                this, default_, npairs, matches, offsets);
+                                this, default_, npairs, matches, offsets, p);
                     }
                     default:
                         throw new IllegalStateException();
--- a/langtools/src/share/classes/com/sun/tools/javac/code/Source.java	Thu Dec 03 12:53:12 2009 -0800
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/Source.java	Tue Dec 08 09:16:34 2009 -0800
@@ -110,9 +110,6 @@
     }
 
     /** Allow encoding errors, giving only warnings. */
-    public boolean allowStringsInSwitch() {
-        return compareTo(JDK1_7) >= 0;
-    }
     public boolean allowEncodingErrors() {
         return compareTo(JDK1_6) < 0;
     }
@@ -168,6 +165,9 @@
     public boolean allowUnderscoresInLiterals() {
         return compareTo(JDK1_7) >= 0;
     }
+    public boolean allowStringsInSwitch() {
+        return compareTo(JDK1_7) >= 0;
+    }
     public static SourceVersion toSourceVersion(Source source) {
         switch(source) {
         case JDK1_2:
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Lower.java	Thu Dec 03 12:53:12 2009 -0800
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Lower.java	Tue Dec 08 09:16:34 2009 -0800
@@ -3117,7 +3117,6 @@
         tree.cases = translateCases(tree.cases);
         if (enumSwitch) {
             result = visitEnumSwitch(tree);
-            patchTargets(result, tree, result);
         } else if (stringSwitch) {
             result = visitStringSwitch(tree);
         } else {
@@ -3146,7 +3145,9 @@
                 cases.append(c);
             }
         }
-        return make.Switch(selector, cases.toList());
+        JCSwitch enumSwitch = make.Switch(selector, cases.toList());
+        patchTargets(enumSwitch, tree, enumSwitch);
+        return enumSwitch;
     }
 
     public JCTree visitStringSwitch(JCSwitch tree) {
@@ -3187,7 +3188,14 @@
              * of String is the same in the compilation environment as
              * in the environment the code will run in.  The string
              * hashing algorithm in the SE JDK has been unchanged
-             * since at least JDK 1.2.
+             * since at least JDK 1.2.  Since the algorithm has been
+             * specified since that release as well, it is very
+             * unlikely to be changed in the future.
+             *
+             * Different hashing algorithms, such as the length of the
+             * strings or a perfect hashing algorithm over the
+             * particular set of case labels, could potentially be
+             * used instead of String.hashCode.
              */
 
             ListBuffer<JCStatement> stmtList = new ListBuffer<JCStatement>();
--- a/langtools/src/share/classes/com/sun/tools/javac/file/ZipFileIndex.java	Thu Dec 03 12:53:12 2009 -0800
+++ b/langtools/src/share/classes/com/sun/tools/javac/file/ZipFileIndex.java	Tue Dec 08 09:16:34 2009 -0800
@@ -1002,7 +1002,7 @@
                         // Do nothing
                     } finally {
                         try {
-                            if (raf == null) {
+                            if (raf != null) {
                                 raf.close();
                             }
                         } catch (Throwable t) {
--- a/langtools/src/share/classes/com/sun/tools/javac/main/JavacOption.java	Thu Dec 03 12:53:12 2009 -0800
+++ b/langtools/src/share/classes/com/sun/tools/javac/main/JavacOption.java	Tue Dec 08 09:16:34 2009 -0800
@@ -130,7 +130,7 @@
         private static Map<String,Boolean> createChoices(String... choices) {
             Map<String,Boolean> map = new LinkedHashMap<String,Boolean>();
             for (String c: choices)
-                map.put(c, true);
+                map.put(c, false);
             return map;
         }
 
--- a/langtools/src/share/classes/com/sun/tools/javac/tree/Pretty.java	Thu Dec 03 12:53:12 2009 -0800
+++ b/langtools/src/share/classes/com/sun/tools/javac/tree/Pretty.java	Tue Dec 08 09:16:34 2009 -0800
@@ -54,7 +54,7 @@
     /** Set when we are producing source output.  If we're not
      *  producing source output, we can sometimes give more detail in
      *  the output even though that detail would not be valid java
-     *  soruce.
+     *  source.
      */
     private final boolean sourceOutput;
 
@@ -489,6 +489,20 @@
                 print("/*public static final*/ ");
                 print(tree.name);
                 if (tree.init != null) {
+                    if (sourceOutput && tree.init.getTag() == JCTree.NEWCLASS) {
+                        print(" /*enum*/ ");
+                        JCNewClass init = (JCNewClass) tree.init;
+                        if (init.args != null && init.args.nonEmpty()) {
+                            print("(");
+                            print(init.args);
+                            print(")");
+                        }
+                        if (init.def != null && init.def.defs != null) {
+                            print(" ");
+                            printBlock(init.def.defs);
+                        }
+                        return;
+                    }
                     print(" /* = ");
                     printExpr(tree.init);
                     print(" */");
--- a/langtools/src/share/classes/com/sun/tools/javap/CodeWriter.java	Thu Dec 03 12:53:12 2009 -0800
+++ b/langtools/src/share/classes/com/sun/tools/javap/CodeWriter.java	Tue Dec 08 09:16:34 2009 -0800
@@ -118,28 +118,33 @@
 
     public void writeInstr(Instruction instr) {
         print(String.format("%4d: %-13s ", instr.getPC(), instr.getMnemonic()));
-        instr.accept(instructionPrinter, null);
+        // compute the number of indentations for the body of multi-line instructions
+        // This is 6 (the width of "%4d: "), divided by the width of each indentation level,
+        // and rounded up to the next integer.
+        int indentWidth = options.indentWidth;
+        int indent = (6 + indentWidth - 1) / indentWidth;
+        instr.accept(instructionPrinter, indent);
         println();
     }
     // where
-    Instruction.KindVisitor<Void,Void> instructionPrinter =
-            new Instruction.KindVisitor<Void,Void>() {
+    Instruction.KindVisitor<Void,Integer> instructionPrinter =
+            new Instruction.KindVisitor<Void,Integer>() {
 
-        public Void visitNoOperands(Instruction instr, Void p) {
+        public Void visitNoOperands(Instruction instr, Integer indent) {
             return null;
         }
 
-        public Void visitArrayType(Instruction instr, TypeKind kind, Void p) {
+        public Void visitArrayType(Instruction instr, TypeKind kind, Integer indent) {
             print(" " + kind.name);
             return null;
         }
 
-        public Void visitBranch(Instruction instr, int offset, Void p) {
+        public Void visitBranch(Instruction instr, int offset, Integer indent) {
             print((instr.getPC() + offset));
             return null;
         }
 
-        public Void visitConstantPoolRef(Instruction instr, int index, Void p) {
+        public Void visitConstantPoolRef(Instruction instr, int index, Integer indent) {
             print("#" + index);
             tab();
             print("// ");
@@ -147,7 +152,7 @@
             return null;
         }
 
-        public Void visitConstantPoolRefAndValue(Instruction instr, int index, int value, Void p) {
+        public Void visitConstantPoolRefAndValue(Instruction instr, int index, int value, Integer indent) {
             print("#" + index + ",  " + value);
             tab();
             print("// ");
@@ -155,46 +160,48 @@
             return null;
         }
 
-        public Void visitLocal(Instruction instr, int index, Void p) {
+        public Void visitLocal(Instruction instr, int index, Integer indent) {
             print(index);
             return null;
         }
 
-        public Void visitLocalAndValue(Instruction instr, int index, int value, Void p) {
+        public Void visitLocalAndValue(Instruction instr, int index, int value, Integer indent) {
             print(index + ", " + value);
             return null;
         }
 
-        public Void visitLookupSwitch(Instruction instr, int default_, int npairs, int[] matches, int[] offsets) {
+        public Void visitLookupSwitch(Instruction instr,
+                int default_, int npairs, int[] matches, int[] offsets, Integer indent) {
             int pc = instr.getPC();
             print("{ // " + npairs);
-            indent(+1);
+            indent(indent);
             for (int i = 0; i < npairs; i++) {
-                print("\n" + matches[i] + ": " + (pc + offsets[i]));
+                print(String.format("%n%12d: %d", matches[i], (pc + offsets[i])));
             }
-            print("\ndefault: " + (pc + default_) + " }");
-            indent(-1);
+            print("\n     default: " + (pc + default_) + "\n}");
+            indent(-indent);
             return null;
         }
 
-        public Void visitTableSwitch(Instruction instr, int default_, int low, int high, int[] offsets) {
+        public Void visitTableSwitch(Instruction instr,
+                int default_, int low, int high, int[] offsets, Integer indent) {
             int pc = instr.getPC();
-            print("{ //" + low + " to " + high);
-            indent(+1);
+            print("{ // " + low + " to " + high);
+            indent(indent);
             for (int i = 0; i < offsets.length; i++) {
-                print("\n" + (low + i) + ": " + (pc + offsets[i]));
+                print(String.format("%n%12d: %d", (low + i), (pc + offsets[i])));
             }
-            print("\ndefault: " + (pc + default_) + " }");
-            indent(-1);
+            print("\n     default: " + (pc + default_) + "\n}");
+            indent(-indent);
             return null;
         }
 
-        public Void visitValue(Instruction instr, int value, Void p) {
+        public Void visitValue(Instruction instr, int value, Integer indent) {
             print(value);
             return null;
         }
 
-        public Void visitUnknown(Instruction instr, Void p) {
+        public Void visitUnknown(Instruction instr, Integer indent) {
             return null;
         }
     };
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/6902720/E1.java	Tue Dec 08 09:16:34 2009 -0800
@@ -0,0 +1,28 @@
+/*
+ * Copyright 2009 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.
+ *
+ * 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.
+ */
+
+enum E1 {
+    A,
+    B { },
+    C { void m() { } };
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/6902720/E2.java	Tue Dec 08 09:16:34 2009 -0800
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2009 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.
+ *
+ * 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.
+ */
+
+enum E2 {
+    A(1),
+    B(2) { },
+    C(3) { void m() { } };
+    E2(int i) { }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/6902720/Test.java	Tue Dec 08 09:16:34 2009 -0800
@@ -0,0 +1,91 @@
+/*
+ * Copyright 2009 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.
+ *
+ * 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.
+ */
+
+import java.io.*;
+import java.net.*;
+import javax.tools.*;
+import java.util.*;
+
+import com.sun.source.tree.CompilationUnitTree;
+import com.sun.source.util.JavacTask;
+import com.sun.tools.javac.api.JavacTool;
+import com.sun.tools.javac.tree.JCTree;
+import com.sun.tools.javac.tree.Pretty;
+
+/**
+ * @test
+ * @bug 6902720
+ * @summary javac pretty printer does not handle enums correctly
+ */
+
+public class Test {
+
+    public static void main(String[] args) throws Exception {
+        Test t = new Test();
+        t.run("E1.java", "E2.java");
+    }
+
+    void run(String... args) throws Exception {
+        File testSrcDir = new File(System.getProperty("test.src"));
+        for (String arg: args) {
+            test(new File(testSrcDir, arg));
+        }
+    }
+
+    void test(File test) throws Exception {
+        JavacTool tool1 = JavacTool.create();
+        StandardJavaFileManager fm = tool1.getStandardFileManager(null, null, null);
+        Iterable<? extends JavaFileObject> files = fm.getJavaFileObjects(test);
+
+        // parse test file into a tree, and write it out to a stringbuffer using Pretty
+        JavacTask t1 = tool1.getTask(null, fm, null, null, null, files);
+        StringWriter sw = new StringWriter();
+        PrintWriter pw = new PrintWriter(sw);
+        Iterable<? extends CompilationUnitTree> trees = t1.parse();
+        for (CompilationUnitTree tree: trees) {
+            new Pretty(pw, true).printExpr((JCTree) tree);
+        }
+        pw.close();
+
+        final String out = sw.toString();
+        System.err.println("generated code:\n" + out + "\n");
+
+        // verify the generated code is valid Java by compiling it
+        JavacTool tool2 = JavacTool.create();
+        JavaFileObject fo = new SimpleJavaFileObject(URI.create("output"), JavaFileObject.Kind.SOURCE) {
+            @Override
+            public CharSequence getCharContent(boolean ignoreEncodingErrors) {
+                return out;
+            }
+        };
+        JavacTask t2 = tool2.getTask(null, fm, null, null, null, Collections.singleton(fo));
+        boolean ok = t2.call();
+        if (!ok)
+            throw new Exception("compilation of generated code failed");
+
+        File expectedClass = new File(test.getName().replace(".java", ".class"));
+        if (!expectedClass.exists())
+            throw new Exception(expectedClass + " not found");
+    }
+}
+