--- a/langtools/make/build.properties Wed Nov 12 20:32:27 2014 -0800
+++ b/langtools/make/build.properties Thu Nov 13 09:39:52 2014 -0800
@@ -23,25 +23,46 @@
# questions.
#
-# This is the JDK used to build and run the bootstrap version of javac.
-# The bootstrap javac is used to compile both boostrap versions of the
-# other tools, and product versions of all the tools.
-# Override this path as needed, either on the command line or in
-# one of the standard user build.properties files (see build.xml)
+#javac configuration for "normal build" (these will be passed to the bootstrap compiler):
+javac.debug = true
+javac.debuglevel = source,lines,vars
+javac.extra.opts=-XDignore.symbol.file=true
+javac.includes=
+javac.lint.opts = -Xlint:all,-deprecation -Werror
+javac.source = 8
+javac.target = 8
-# boot.java.home = /opt/jdk/1.7.0
-boot.java = ${boot.java.home}/bin/java
-boot.javac = ${boot.java.home}/bin/javac
+#javac configuration for bootstrap build (these will be passed to the compiler from the given boot JDK):
+boot.javac.extra.opts=-XDignore.symbol.file=true
+boot.javac.includes = \
+ javax/annotation/processing/ \
+ javax/lang/model/ \
+ javax/tools/ \
+ jdk/ \
+ com/sun/source/ \
+ com/sun/tools/javac/ \
+ com/sun/tools/doclint/
+boot.javac.lint.opts=
boot.javac.source = 8
boot.javac.target = 8
-# This is the JDK used to run the product version of the tools,
-# for example, for testing. If you're building a complete JDK, specify that.
-# Override this path as needed, either on the command line or in
-# one of the standard user build.properties files (see build.xml)
+#configuration of submodules (share by both the bootstrap and normal compilation):
+langtools.modules=java.base:java.compiler:jdk.compiler:jdk.dev:jdk.javadoc
+java.base.dependencies=
+java.compiler.dependencies=java.base
+jdk.compiler.dependencies=java.base:java.compiler
+jdk.javadoc.dependencies=java.base:java.compiler:jdk.compiler
+jdk.dev.dependencies=java.base:java.compiler:jdk.compiler
-# target.java.home = /opt/jdk/1.8.0
-target.java = ${target.java.home}/bin/java
+#test configuration:
+jtreg.tests=
+boot.javac.tests = tools/javac
+crules.tests = ../make/test/crules
+
+#javadoc configuration
+javadoc.jls.cite=The Java™ Language Specification
+javadoc.jls.option=-tag "jls:a:See <cite>${javadoc.jls.cite}</cite>:" \
+ -tag "implNote:a:Implementation Note:"
# Version info -- override as needed
jdk.version = 1.9.0
@@ -55,146 +76,4 @@
# timestamps
# FIXME -- need to include openjdk as needed
release = ${jdk.version}-${milestone}
-bootstrap.release = ${release}_bootstrap
full.version = ${release}-${build.number}
-bootstrap.full.version = ${bootstrap.release}-${build.number}
-
-# options for the <javac> tasks used to compile the tools
-javac.source = 8
-javac.target = 8
-javac.debug = true
-javac.debuglevel = source,lines
-javac.no.jdk.warnings = -XDignore.symbol.file=true
-# set the following to -version to verify the versions of javac being used
-javac.version.opt =
-# in time, there should be no exceptions to -Xlint:all
-javac.lint.opts = -Xlint:all,-deprecation -Werror
-
-# options for the <javadoc> task for javac
-#javadoc.jls3.url=http://java.sun.com/docs/books/jls/
-#javadoc.jls3.cite=<a href="${javadoc.jls3.url}">The Java Language Specification, Third Edition</a>
-#javadoc.jls3.option=-tag "jls3:a:See <cite>${javadoc.jls3.cite}</cite>:"
-
-
-javadoc.jls.cite=The Java™ Language Specification
-
-javadoc.jls.option=-tag "jls:a:See <cite>${javadoc.jls.cite}</cite>:"
-
-
-
-
-
-# jtreg, used to run the JDK regression tests
-# See http://openjdk.java.net/jtreg/
-# Override this path as needed, either on the command line or in
-# one of the standard user build.properties files (see build.xml)
-
-# jtreg.home = /opt/jtreg/4.1
-
-# findbugs
-# See http://findbugs.sourceforge.net/
-# Override this path as needed, either on the command line or in
-# one of the standard user build.properties files (see build.xml)
-
-# findbugs.home = /opt/findbugs/1.2.1
-
-# vizant (graph visualization tool for Ant)
-# See http://vizant.sourceforge.net/
-# Override this path as needed, either on the command line or in
-# one of the standard user build.properties files (see build.xml)
-
-# vizant.jar = /opt/vizant/0.1.2/vizant-0.1.2.jar
-# dot = dot
-
-#------------------------------------------------------------
-
-# The following properties define the packages for each of the tools.
-# Syntactically, they should be suitable as arguments for the "includes"
-# parameter of Ant filesets. In particular, note the trailing '/'.
-
-javac.includes = \
- javax/annotation/processing/ \
- javax/lang/model/ \
- javax/tools/ \
- jdk/ \
- com/sun/source/ \
- com/sun/tools/javac/ \
- com/sun/tools/doclint/
-
-javac.tests = \
- tools/javac
-
-#
-
-javadoc.includes = \
- com/sun/javadoc/ \
- com/sun/tools/javadoc/ \
- com/sun/tools/doclets/
-
-javadoc.tests = \
- tools/javadoc/ \
- com/sun/javadoc/
-
-#
-
-javah.includes = \
- com/sun/tools/javah/
-
-javah.tests = \
- tools/javah/
-
-#
-
-javap.includes = \
- com/sun/tools/classfile/ \
- com/sun/tools/javap/ \
- com/sun/tools/jdeps/ \
- sun/tools/javap/
-
-javap.tests = \
- tools/javap/
-
-#
-
-sjavac.includes = \
- com/sun/tools/sjavac/
-
-sjavac.tests = \
- tools/sjavac
-
-crules.tests = ../make/test/crules
-
-#
-
-# The following files require the latest JDK to be available.
-# The API can be provided by using a suitable boot.java.home
-# or by setting import.jdk
-require.latest.jdk.files = \
- com/sun/tools/javac/nio/*.java
-
-# The following files in the import jdk source directory are required
-# in order to compile the files defined in ${require.latest.jdk.files}
-#
-# For NIO, the list of stub files is defined by the contents of the primary
-# API packages, together with such types that may be required in order to
-# compile the stubs. Some of these dependencies would go away if the stub
-# generator were to be improved -- e.g. by removing unnecessary imports.
-#
-import.jdk.stub.files = \
- java/io/File.java \
- java/nio/file/**.java \
- java/nio/file/attribute/**.java \
- java/nio/file/spi/**.java \
- java/nio/channels/AsynchronousChannel.java \
- java/nio/channels/AsynchronousFileChannel.java \
- java/nio/channels/CompletionHandler.java \
- java/nio/channels/SeekableByteChannel.java
-
-# 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
-jtreg.tests =
-
-# Check style configuration
-# overridable name and version
-checkstyle.name.version = checkstyle-5.4
--- a/langtools/make/build.xml Wed Nov 12 20:32:27 2014 -0800
+++ b/langtools/make/build.xml Thu Nov 13 09:39:52 2014 -0800
@@ -25,10 +25,10 @@
-->
<!--
- This is the main build file for the complete langtools repository.
- It is used when building JDK (in which case it is invoked from the
- Makefile), and it can be used when working on the tools themselves,
- in an IDE such as NetBeans.
+ This is a convenience build file supporting development in the langtools
+ repository. It can be run either standalone, or from IDEs. This build script
+ is for a developer use only, it is not used to build the production version
+ of javac or other langtools tools.
External dependencies are specified via properties. These can be given
on the command line, or by providing a local build.properties file.
@@ -39,58 +39,27 @@
For example, to run any of the jtreg tests you must set jtreg.home,
to run findbugs on the code you must set findbugs.home, and so on.
- For the most part, javac can be built using the previous version of JDK.
- However, a small number of javac files require access to the latest JDK,
- which may not yet have been compiled. To compile these files, you can do
- one of the following:
- - Set boot.java.home to a recent build of the latest version of JDK.
- - Set import.jdk to either a recent build (containing jre/lib/rt.jar)
- or to jdk source repository. In the latter case, stub files will
- automatically be generated and used for the required API, to avoid
- unnecessary compilation of the source repository.
- If you do neither, the relevant files will not be built.
-
The main build happens in two phases:
- - First, javac and other tools as needed are built using ${boot.java.home}.
- (This implies a constraint on the source code that they can be compiled
- with the previous version of JDK.
+ - First, javac is built using ${boot.java.home}. (This implies a constraint
+ on the source code that they can be compiled with the previous version of JDK.
- Second, all required classes are compiled with the latest javac, created
in the previous step.
- The first phase is called the bootstrap phase. All targets, properties and
- tasks that are specific to that phase have "bootstrap" in their name.
+ The build generally builds one module at time.
- For more details on the JDK build, see
- http://blogs.sun.com/kto/entry/anatomy_of_the_jdk_build
- http://openjdk.java.net/groups/build/
For more details on the stub generator, see
http://blogs.sun.com/jjg/entry/building_javac_for_jdk7
Internal details ...
- Interim build products are created in the build/ directory.
- Final build products are created in the dist/ directory.
- When building JDK, the dist/directory will contain:
- - A bootstrap compiler suitable for running with ${boot.java.home}
- suitable for compiling downstream parts of JDK
- - Source files and class files for inclusion in the JDK being built
- When building standalone, the dist/directory will contain:
- - Separate jar files for each of the separate langtools components
- - Simple scripts to invoke the tools by executing the corresponding
- jar files.
- These jar files and scripts are "for developer use only".
+ Bootstrap classes are built into the build/bootstrap/<module-name>/classes directory.
+ Final classes are built into the build/<module-name>/classes directory.
+ Final runnable javac is in dist/bin and dist/lib. Bootstrap javac (if requested by
+ using the build-bootstrap-javac target) is built into dist/bootstrap.
This file is organized into sections as follows:
- global property definitions
- - general top level targets
- - general diagnostic/debugging targets
- - groups of targets for each tool: javac, javadoc, javah, javap
- Within each group, the following targets are provided, where applicable
- build-bootstrap-TOOL build the bootstrap version of the tool
- build-classes-TOOL build the classes for the tool
- build-TOOL build the jar file and script for the tool
- jtreg-TOOL build the tool and run the appropriate tests
- findbugs-TOOL run findbugs on the tool's source code
- TOOL build the tool, run the tests, and run findbugs
+ - primary top level targets (cleaning, building, testing, producing javac)
+ - secondary top level targets (code analysis, diagnostics, extra documentation, etc.)
- utility definitions
-->
@@ -99,13 +68,6 @@
**** Global property definitions.
-->
- <!-- Force full debuginfo for javac if the debug.classfiles
- property is set. This must be BEFORE the include of
- build.properties because it sets javac.debuglevel. -->
- <condition property="javac.debuglevel" value="source,lines,vars">
- <equals arg1="${debug.classfiles}" arg2="true"/>
- </condition>
-
<!-- The following locations can be used to override default property values. -->
<!-- Use this location for customizations specific to this instance of this workspace -->
@@ -119,36 +81,24 @@
<!-- Convenient shorthands for standard locations within the workspace. -->
<property name="build.dir" location="build"/>
- <property name="build.bootstrap.dir" location="${build.dir}/bootstrap"/>
- <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.crules.dir" location="${build.dir}/crules"/>
<property name="build.jtreg.dir" location="${build.dir}/jtreg"/>
<property name="build.toolclasses.dir" location="${build.dir}/toolclasses"/>
+ <property name="build.javadoc.dir" location="${build.dir}/javadoc"/>
<property name="dist.dir" location="dist"/>
<property name="dist.bin.dir" location="${dist.dir}/bin"/>
- <property name="dist.coverage.dir" location="${dist.dir}/coverage"/>
+ <property name="dist.lib.dir" location="${dist.dir}/lib"/>
<property name="dist.findbugs.dir" location="${dist.dir}/findbugs"/>
<property name="dist.checkstyle.dir" location="${dist.dir}/checkstyle"/>
- <property name="dist.lib.dir" location="${dist.dir}/lib"/>
<property name="make.dir" location="make"/>
<property name="make.conf.dir" location="${make.dir}/conf"/>
<property name="make.tools.dir" location="${make.dir}/tools"/>
- <property name="src.dir" location="src"/>
- <property name="src.bin.dir" location="${src.dir}/share/bin"/>
<property name="test.dir" location="test"/>
- <path id="src.dirs">
- <pathelement path="${src.dir}/java.base/share/classes"/>
- <pathelement path="${src.dir}/java.compiler/share/classes"/>
- <pathelement path="${src.dir}/jdk.compiler/share/classes"/>
- <pathelement path="${src.dir}/jdk.dev/share/classes"/>
- <pathelement path="${src.dir}/jdk.javadoc/share/classes"/>
- </path>
-
- <pathconvert pathsep="," property="src.dirs.property" refid="src.dirs" />
+ <property name="boot.build.dir" location="${build.dir}/bootstrap"/>
+ <property name="boot.dist.dir" location="${dist.dir}/bootstrap"/>
+ <property name="boot.dist.bin.dir" location="${boot.dist.dir}/bin"/>
+ <property name="boot.dist.lib.dir" location="${boot.dist.dir}/lib"/>
<!-- java.marker is set to a marker file to check for within a Java install dir.
The best file to check for across Solaris/Linux/Windows/MacOS is one of the
@@ -172,110 +122,89 @@
<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"/>
-
- <!-- Set the default bootclasspath option used for javac.
- Note that different variants of the option are used, meaning we can't just
- define the value for the option.
- Note the explicit use of the standard property ${path.separator} in the following.
- This is because Ant is not clever enough to handle direct use of : or ; -->
- <condition property="javac.bootclasspath.opt"
- value="-Xbootclasspath:${build.classes.dir}${path.separator}${import.jdk.jar}"
- else="-Xbootclasspath/p:${build.classes.dir}">
- <isset property="import.jdk.jar"/>
- </condition>
-
- <condition property="boot.java.provides.latest.jdk">
- <available
- ignoresystemclasses="true"
- classpath="${boot.java.home}/jre/lib/rt.jar" classname="java.nio.file.Path"/>
- </condition>
-
- <condition property="bootstrap.exclude.files" value="" else="${require.latest.jdk.files}">
- <isset property="boot.java.provides.latest.jdk"/>
- </condition>
-
- <condition property="exclude.files" value="" else="${require.latest.jdk.files}">
- <or>
- <isset property="boot.java.provides.latest.jdk"/>
- <isset property="import.jdk"/>
- </or>
- </condition>
-
- <condition property="require.import.jdk.stubs">
- <and>
- <not>
- <isset property="boot.java.provides.latest.jdk"/>
- </not>
- <isset property="import.jdk.src.dir"/>
- </and>
- </condition>
-
- <!-- Set the default value of the sourcepath used for javac. -->
- <condition property="javac.sourcepath" value="${build.genstubs.dir}" else="">
- <isset property="require.import.jdk.stubs"/>
- </condition>
-
- <!-- Set the default value of the classpath used for javac. -->
- <property name="javac.classpath" value=""/>
-
+ <!-- setup basic properties holding paths to all sources, generated source and class directories
+ (both boot and non-boot) -->
+ <pathconvert property="langtools.sources">
+ <path>
+ <pathelement path="${langtools.modules}" />
+ </path>
+ <map from="${basedir}/" to="${basedir}/src/" />
+ <mapper type="glob" from="*" to="*/share/classes"/>
+ </pathconvert>
+ <pathconvert property="langtools.gensrc">
+ <path>
+ <pathelement path="${langtools.modules}" />
+ </path>
+ <map from="${basedir}/" to="${build.dir}/" />
+ <mapper type="glob" from="*" to="*/gensrc"/>
+ </pathconvert>
+ <pathconvert property="langtools.boot.classes">
+ <path>
+ <pathelement path="${langtools.modules}" />
+ </path>
+ <map from="${basedir}/" to="${boot.build.dir}/" />
+ <mapper type="glob" from="*" to="*/classes"/>
+ </pathconvert>
+ <pathconvert property="langtools.classes">
+ <path>
+ <pathelement path="${langtools.modules}" />
+ </path>
+ <map from="${basedir}/" to="${build.dir}/" />
+ <mapper type="glob" from="*" to="*/classes"/>
+ </pathconvert>
<!--
- **** General top level targets.
+ **** Primary targets
-->
- <!-- Standard target to build deliverables for JDK build. -->
-
- <target name="build" depends="build-bootstrap-tools,build-all-classes">
- <copy todir="${dist.dir}/bootstrap">
- <fileset dir="${build.bootstrap.dir}" includes="bin/,lib/"/>
- </copy>
- <chmod dir="${dist.dir}/bootstrap/bin" perm="ugo+rx">
- <include name="*"/>
- </chmod>
- <mkdir dir="${dist.lib.dir}"/>
- <jar file="${dist.lib.dir}/classes.jar" basedir="${build.classes.dir}"/>
- <zip file="${dist.lib.dir}/src.zip">
- <multirootfileset basedirs="${src.dirs.property}" />
- </zip>
- </target>
-
- <target name="build-bootstrap-tools"
- depends="build-bootstrap-javac,build-bootstrap-javadoc,build-bootstrap-javah,build-bootstrap-sjavac"
- />
-
- <target name="build-all-tools"
- depends="build-javac,build-javadoc,build-javah,build-javap,build-sjavac"
- />
-
- <target name="build-all-classes" depends="build-bootstrap-javac,-create-import-jdk-stubs">
- <build-classes includes="${javac.includes} ${javadoc.includes} ${javah.includes} ${javap.includes} ${sjavac.includes}"/>
- </target>
-
- <!-- clean -->
-
<target name="clean" description="Delete all generated files">
<delete dir="${build.dir}"/>
<delete dir="${dist.dir}"/>
</target>
- <!-- Additional targets for running tools on the build -->
+ <target name="build" depends="build-all-tools">
+ </target>
+
+ <target name="build-all-tools" depends="build-all-classes,-def-build-all-module-jars,-def-build-tool">
+ <build-all-module-jars />
+ <build-tool name="javac"/>
+ <build-tool name="javadoc"/>
+ <build-tool name="javap"/>
+ <build-tool name="javah"/>
+ <build-tool name="sjavac"/>
+ </target>
+
+ <target name="build-all-classes" depends="-def-build-all-module-classes,build-bootstrap-javac-classes">
+ <build-all-module-classes />
+ </target>
<target name="jtreg" depends="build-all-tools,-def-jtreg">
<jtreg-tool name="all" tests="${jtreg.tests}"/>
</target>
+ <target name="javadoc" depends="build-all-classes,-def-javadoc-tool">
+ <javadoc-tool options="${javadoc.jls.option}"/>
+ </target>
+
+ <target name="build-bootstrap-javac-classes" depends="-check-boot.java.home,-def-build-all-module-classes">
+ <build-all-module-classes compilation.kind="boot." />
+ </target>
+
+ <!--
+ **** Extra targets
+ -->
+
+ <target name="build-bootstrap-javac" depends="build-bootstrap-javac-classes,-def-build-all-module-jars,-def-build-tool">
+ <build-all-module-jars compilation.kind="boot." />
+ <build-tool name="javac" compilation.kind="boot." />
+ </target>
+
+ <target name="jtreg-bootstrap-javac" depends="build-bootstrap-javac,-def-jtreg">
+ <jtreg-tool name="bootstrap-javac"
+ tests="${boot.javac.tests}"
+ langtools.classes="${langtools.boot.classes}"/>
+ </target>
+
<target name="checkstyle" depends="-def-checkstyle"
description="Generates reports for code convention violations.">
<mkdir dir="${dist.checkstyle.dir}"/>
@@ -325,9 +254,13 @@
warningsProperty="findbugs.all.warnings"
jvm="${target.java.home}/bin/java"
jvmargs="-Xmx512M">
- <class location="${build.classes.dir}"/>
+ <class location="${build.dir}/java.base/classes"/>
+ <class location="${build.dir}/java.compiler/classes"/>
+ <class location="${build.dir}/jdk.compiler/classes"/>
+ <class location="${build.dir}/jdk.javadoc/classes"/>
+ <class location="${build.dir}/jdk.dev/classes"/>
<sourcePath>
- <path refid="src.dirs"/>
+ <pathelement path="${langtools.sources}"/>
</sourcePath>
</findbugs>
<exec executable="sh">
@@ -339,49 +272,7 @@
</exec>
</target>
- <target name="coverage" depends="-def-cobertura,build-all-classes,instrument-classes,jtreg,coverage-report"/>
-
- <target name="instrument-classes" depends="-def-cobertura">
- <!-- only define the following property when we want coverage info -->
- <path id="coverage.classpath">
- <pathelement location="${build.coverage.dir}/classes"/>
- <path refid="cobertura.classpath"/>
- </path>
- <property name="coverage.options" value="-Dnet.sourceforge.cobertura.datafile=${build.coverage.dir}/cobertura.ser"/>
- <property name="coverage.classpath" refid="coverage.classpath"/>
- <mkdir dir="${build.coverage.dir}/classes"/>
- <delete file="${build.coverage.dir}/cobertura.ser"/>
- <cobertura-instrument todir="${build.coverage.dir}/classes"
- datafile="${build.coverage.dir}/cobertura.ser">
- <fileset dir="${build.classes.dir}"
- includes="**/*.class" excludes="**/resources/*.class"/>
- </cobertura-instrument>
- </target>
-
- <target name="coverage-report" depends="-def-cobertura">
- <mkdir dir="${dist.coverage.dir}"/>
- <cobertura-report
- destdir="${dist.coverage.dir}"
- datafile="${build.coverage.dir}/cobertura.ser">
- <fileset dir="${src.dir}/java.base/share/classes"/>
- <fileset dir="${src.dir}/java.compiler/share/classes"/>
- <fileset dir="${src.dir}/jdk.compiler/share/classes"/>
- <fileset dir="${src.dir}/jdk.dev/share/classes"/>
- <fileset dir="${src.dir}/jdk.javadoc/share/classes"/>
- </cobertura-report>
- <cobertura-report
- format="xml"
- destdir="${dist.coverage.dir}"
- datafile="${build.coverage.dir}/cobertura.ser">
- <fileset dir="${src.dir}/java.base/share/classes"/>
- <fileset dir="${src.dir}/java.compiler/share/classes"/>
- <fileset dir="${src.dir}/jdk.compiler/share/classes"/>
- <fileset dir="${src.dir}/jdk.dev/share/classes"/>
- <fileset dir="${src.dir}/jdk.javadoc/share/classes"/>
- </cobertura-report>
- </target>
-
- <target name="diags-examples" depends="build-javac,build-javap">
+ <target name="diags-examples" depends="build-all-tools">
<!-- can override the following on the command line if desired. -->
<property name="diags.examples.out" location="${build.dir}/diag-examples/diags-examples.html"/>
<mkdir dir="${build.dir}/diag-examples/classes"/>
@@ -391,7 +282,7 @@
destdir="${build.dir}/diag-examples/classes"
includes="ArgTypeCompilerFactory.java,Example.java,FileManager.java,HTMLWriter.java,RunExamples.java,DocCommentProcessor.java"
sourcepath=""
- classpath="${dist.lib.dir}/javac.jar;${dist.lib.dir}/javap.jar"
+ classpath="${langtools.classes}"
includeAntRuntime="no"
debug="${javac.debug}"
debuglevel="${javac.debuglevel}">
@@ -400,7 +291,7 @@
<java fork="true"
jvm="${target.java.home}/bin/java"
dir="test/tools/javac/diags"
- classpath="${build.dir}/diag-examples/classes;${dist.lib.dir}/javac.jar;${dist.lib.dir}/javap.jar"
+ classpath="${build.dir}/diag-examples/classes;${langtools.classes}"
classname="RunExamples">
<jvmarg value="-Dtest.classes=${build.dir}/diag-examples/classes"/>
<arg value="-examples"/>
@@ -413,56 +304,16 @@
</java>
</target>
- <!-- a patching facility to speed up incorporating the langtools' classfiles
- into a jdk of your choice. Either target.java.home or patch.jdk can be
- set on the command line; setting target.java.home has the advantage of
- patching the jdk used for jtreg and other tests.
- -->
- <target name="patch" depends="build-all-classes">
- <condition property="patch.jdk" value="${target.java.home}">
- <available file="${target.java.home}" type="dir"/>
- </condition>
- <fail message="patch.jdk or target.java.home is not set, please set target.java.home, or patch.jdk for an alternate jdk image to patch">
- <condition>
- <not>
- <isset property="patch.jdk"/>
- </not>
- </condition>
- </fail>
- <property name="patch.tools.jar" location="${patch.jdk}/lib/tools.jar"/>
- <property name="patch.rt.jar" location="${patch.jdk}/jre/lib/rt.jar"/>
- <fail message="patch.jdk or target.java.home must point to a valid jdk image: missing tools.jar">
- <condition>
- <not>
- <available file="${patch.tools.jar}" type="file"/>
- </not>
- </condition>
- </fail>
- <fail message="patch.jdk or target.java.home must point to a valid jdk image: missing rt.jar">
- <condition>
- <not>
- <available file="${patch.rt.jar}" type="file"/>
- </not>
- </condition>
- </fail>
- <zip zipfile="${patch.tools.jar}" update="true">
- <zipfileset dir="${build.classes.dir}" includes="com/**"/>
- </zip>
- <zip zipfile="${patch.rt.jar}" update="true">
- <zipfileset dir="${build.classes.dir}" includes="javax/**"/>
- </zip>
- </target>
-
<target name="doclint-api" depends="build-all-classes">
<delete dir="${build.dir}/doclint/classes"/>
<mkdir dir="${build.dir}/doclint/classes"/>
<javac fork="true"
- executable="${boot.javac}"
+ executable="${boot.java.home}/bin/javac"
destdir="${build.dir}/doclint/classes"
includes="javax/lang/model/** com/sun/javadoc/** com/sun/source/**"
excludes=""
- sourcepath="${javac.sourcepath}"
- classpath="${javac.classpath}"
+ sourcepath=""
+ classpath="${langtools.classes}"
includeAntRuntime="no"
source="${javac.source}"
target="${javac.target}"
@@ -471,12 +322,11 @@
<compilerarg value="-implicit:none"/>
<compilerarg value="-Xprefer:source"/>
<compilerarg value="-J-Xbootclasspath/p:${build.bootstrap.dir}/classes"/>
- <compilerarg line="${javac.no.jdk.warnings}"/>
- <compilerarg line="${javac.version.opt}"/>
+ <compilerarg line="${javac.extra.opts}"/>
<compilerarg line="-Xdoclint:all/protected,-missing"/>
<src>
- <path refid="src.dirs"/>
- <path location="${build.gensrc.dir}"/>
+ <pathelement path="${langtools.sources}"/>
+ <pathelement path="${langtools.gensrc}"/>
</src>
</javac>
</target>
@@ -515,17 +365,12 @@
</classpath>
<!-- platform classes used for documentation -->
<bootclasspath>
- <pathelement path="${build.dir}/classes"/>
+ <pathelement path="${langtools.classes}"/>
<pathelement path="${target.java.home}/jre/lib/rt.jar"/>
</bootclasspath>
</javadoc>
</target>
- <!--
- **** Debugging/diagnostic targets.
- -->
-
- <!-- standard JDK target -->
<target name="sanity"
description="display settings of configuration values">
<echo level="info">ant.home = ${ant.home}</echo>
@@ -536,257 +381,32 @@
<echo level="info">checkstyle.home = ${checkstyle.home}</echo>
</target>
- <target name="post-sanity" depends="-def-jtreg,sanity,build"
- description="perform basic validation after a standard build">
- <jtreg
- dir="make/test"
- workDir="${build.jtreg.dir}/post-sanity/work"
- reportDir="${build.jtreg.dir}/post-sanity/report"
- jdk="${target.java.home}"
- verbose="summary"
- failonerror="false" resultproperty="jtreg.post-sanity.result">
- </jtreg>
- </target>
-
- <!-- use vizant tool to generate graphical image of this Ant file.-->
- <target name="vizant" depends="-def-vizant">
- <mkdir dir="${build.dir}"/>
- <echo message="Generating ${build.dir}/build.dot"/>
- <vizant antfile="${make.dir}/build.xml" outfile="${build.dir}/build.dot"/>
- <echo message="Generating ${build.dir}/build.png"/>
- <exec executable="${dot}" >
- <arg value="-Tpng"/>
- <arg value="-o"/>
- <arg file="${build.dir}/build.png"/>
- <arg file="${build.dir}/build.dot"/>
- </exec>
- </target>
-
- <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>
-
<target name="diagnostics">
<diagnostics/>
</target>
-
- <!--
- **** javac targets.
- -->
-
- <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,-create-import-jdk-stubs">
- <build-classes includes="${javac.includes}"/>
- </target>
-
- <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.jls.option}"/>
- </target>
-
- <target name="jtreg-javac" depends="build-javac,build-javap,-def-jtreg">
- <jtreg-tool name="javac" tests="${javac.tests}"/>
- </target>
-
- <target name="findbugs-javac" depends="build-javac,-def-findbugs">
- <findbugs-tool name="javac"/>
- </target>
-
- <target name="javac" depends="build-javac,jtreg-javac,findbugs-javac"/>
-
-
- <!--
- **** javadoc targets.
- -->
-
- <target name="build-bootstrap-javadoc" depends="build-bootstrap-javac">
- <build-bootstrap-classes includes="${javadoc.includes}"/>
- <build-bootstrap-jar name="javadoc" includes="${javadoc.includes}"
- jarclasspath="javac.jar"/>
- <build-bootstrap-tool name="javadoc"/>
- </target>
-
- <target name="build-classes-javadoc" depends="build-classes-javac">
- <build-classes includes="${javadoc.includes}"/>
- </target>
-
- <target name="build-javadoc" depends="build-javac,build-classes-javadoc">
- <build-jar name="javadoc" includes="${javadoc.includes}"
- jarclasspath="javac.jar"/>
- <build-tool name="javadoc"/>
- </target>
-
- <target name="javadoc-javadoc" depends="build-javadoc,-def-javadoc-tool">
- <javadoc-tool name="javadoc" includes="${javadoc.includes}"/>
- </target>
-
- <target name="jtreg-javadoc" depends="build-javadoc,-def-jtreg">
- <jtreg-tool name="javadoc" tests="${javadoc.tests}"/>
- </target>
-
- <target name="findbugs-javadoc" depends="build-javadoc,-def-findbugs">
- <findbugs-tool name="javadoc"/>
- </target>
-
- <target name="javadoc" depends="build-javadoc,jtreg-javadoc,findbugs-javadoc"/>
-
- <!--
- **** javah targets.
- -->
-
- <target name="build-bootstrap-javah" depends="build-bootstrap-javadoc">
- <build-bootstrap-classes includes="${javah.includes}"/>
- <build-bootstrap-jar name="javah" includes="${javah.includes}"
- jarclasspath="javadoc.jar javac.jar"/>
- <build-bootstrap-tool name="javah"/>
- </target>
-
- <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 includes="${javah.includes}"/>
- </target>
-
- <!-- (no javadoc for javah) -->
-
- <target name="jtreg-javah" depends="build-javah,-def-jtreg">
- <jtreg-tool name="javah" tests="${javah.tests}"/>
- </target>
-
- <target name="findbugs-javah" depends="build-javah,-def-findbugs">
- <findbugs-tool name="javah"/>
- </target>
-
- <target name="javah" depends="build-javah,jtreg-javah,findbugs-javah"/>
-
-
- <!--
- **** javap targets.
- -->
-
- <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 includes="${javap.includes}"/>
- </target>
-
- <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) -->
-
- <target name="jtreg-javap" depends="build-javap,-def-jtreg">
- <jtreg-tool name="javap" tests="${javap.tests}"/>
- </target>
-
- <target name="findbugs-javap" depends="build-javap,-def-findbugs">
- <findbugs-tool name="javap"/>
- </target>
-
- <target name="javap" depends="build-javap,jtreg-javap,findbugs-javap"/>
-
- <!--
- **** sjavac targets.
- -->
-
- <target name="build-bootstrap-sjavac"
- depends="-def-build-bootstrap-classes,-def-build-bootstrap-jar,-def-build-bootstrap-tool">
- <build-bootstrap-classes includes="${sjavac.includes}"/>
- <build-bootstrap-jar name="sjavac" includes="${sjavac.includes}"
- jarmainclass="com.sun.tools.sjavac.Main"/>
- <build-bootstrap-tool name="sjavac"/>
- </target>
-
- <target name="build-classes-sjavac" depends="build-classes-javac">
- <build-classes includes="${sjavac.includes}"/>
- </target>
-
- <target name="build-sjavac" depends="build-classes-sjavac">
- <build-jar name="sjavac" includes="${sjavac.includes}"
- jarmainclass="com.sun.tools.sjavac.Main"
- jarclasspath="sjavac.jar"/>
- <build-tool name="sjavac"/>
- </target>
-
- <!-- (no javadoc for javap) -->
-
- <target name="jtreg-sjavac" depends="build-sjavac,-def-jtreg">
- <jtreg-tool name="sjavac" tests="${sjavac.tests}"/>
- </target>
-
- <target name="findbugs-sjavac" depends="build-sjavac,-def-findbugs">
- <findbugs-tool name="sjavac"/>
- </target>
-
- <target name="sjavac" depends="build-sjavac,jtreg-sjavac,findbugs-sjavac"/>
-
- <!--
- **** crules targets.
- -->
-
- <target name="build-crules"
- depends="-def-compilecrules,-def-build-jar-with-services,build-bootstrap-javac,-create-import-jdk-stubs">
- <compilecrules/>
- <build-jar-with-services
- name="crules"
- includes="crules/* crules/resources/*"
- classes.dir="${build.toolclasses.dir}"
- lib.dir="${build.toolclasses.dir}"
- jarmainclass=""
- jarclasspath="crules.jar"
- service.type="com.sun.source.util.Plugin"
- service.provider="crules.CodingRulesAnalyzerPlugin"/>
- <build-tool name="crules"/>
- </target>
-
- <target name="jtreg-crules" depends="build-javac,build-crules,-def-jtreg">
+ <target name="jtreg-crules" depends="build-all-classes,-def-jtreg">
+ <mkdir dir="${build.crules.dir}/classes"/>
+ <javac fork="true"
+ source="${boot.javac.source}"
+ target="${boot.javac.target}"
+ executable="${boot.java.home}/bin/javac"
+ srcdir="${make.tools.dir}"
+ includes="crules/*"
+ destdir="${build.crules.dir}/classes"
+ includeantruntime="false">
+ <compilerarg value="-Xbootclasspath/p:${langtools.classes}"/>
+ <compilerarg line="${javac.lint.opts}"/>
+ </javac>
+ <copy todir="${build.crules.dir}/classes" includeemptydirs="false">
+ <fileset dir="${make.tools.dir}">
+ <include name="**/*.properties"/>
+ </fileset>
+ </copy>
+ <echo file="${build.crules.dir}/classes/META-INF/services/com.sun.source.util.Plugin">crules.CodingRulesAnalyzerPlugin</echo>
<jtreg-tool name="crules"
tests="${crules.tests}"
- extra.jvmargs="-Xbootclasspath/a:${build.toolclasses.dir}/crules.jar" />
- </target>
-
- <target name="check-coding-rules" depends="build-bootstrap-javac,-create-import-jdk-stubs,build-crules">
- <build-classes includes="${javac.includes}"
- plugin.options="-J-Xbootclasspath/a:${build.toolclasses.dir}/crules.jar -Xplugin:coding_rules" />
- </target>
-
- <!--
- **** Create import JDK stubs.
- -->
-
- <target name="-create-import-jdk-stubs" depends="-def-genstubs" if="require.import.jdk.stubs">
- <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.core.lib}"
- />
+ extra.jvmargs="-Xbootclasspath/a:${build.crules.dir}/classes" />
</target>
<!--
@@ -821,8 +441,8 @@
<check name="target java" property="target.java.home" marker="${java.marker}"/>
</target>
- <target name="-check-cobertura.home" depends="-def-check">
- <check name="cobertura" property="cobertura.home" marker="cobertura.jar"/>
+ <target name="-check-jtreg.home" depends="-def-check">
+ <check name="jtreg" property="jtreg.home" marker="lib/jtreg.jar"/>
</target>
<target name="-check-findbugs.home" depends="-def-check">
@@ -830,27 +450,57 @@
</target>
<target name="-check-checkstyle.home" depends="-def-check">
- <check name="checkstyle" property="checkstyle.home" marker="${checkstyle.name.version}.jar"/>
+ <check name="checkstyle" property="checkstyle.home" marker=""/> <!--TODO: better checkstyle verification-->
</target>
- <target name="-check-jtreg.home" depends="-def-check">
- <check name="jtreg" property="jtreg.home" marker="lib/jtreg.jar"/>
+ <!-- Definitions -->
+
+ <target name="-def-build-all-module-jars" depends="-def-build-module-jar">
+ <macrodef name="build-all-module-jars">
+ <attribute name="compilation.kind" default=""/>
+ <sequential>
+ <build-module-jar module.name="java.base" compilation.kind="@{compilation.kind}" />
+ <build-module-jar module.name="java.compiler" compilation.kind="@{compilation.kind}" />
+ <build-module-jar module.name="jdk.compiler" compilation.kind="@{compilation.kind}" />
+ <build-module-jar module.name="jdk.javadoc" compilation.kind="@{compilation.kind}" />
+ <build-module-jar module.name="jdk.dev" compilation.kind="@{compilation.kind}" />
+ </sequential>
+ </macrodef>
</target>
- <target name="-check-vizant" depends="-def-check">
- <check name="vizant" property="vizant.jar"/>
- <check name="dot" property="dot"/>
+ <target name="-def-build-module-jar">
+ <macrodef name="build-module-jar">
+ <attribute name="module.name"/>
+ <attribute name="compilation.kind"/>
+ <attribute name="dependencies" default="${@{compilation.kind}@{module.name}.dependencies}"/>
+ <attribute name="build.dir" default="${@{compilation.kind}build.dir}"/>
+ <attribute name="lib.dir" default="${@{compilation.kind}dist.lib.dir}"/>
+ <attribute name="classes.dir" default="@{build.dir}/@{module.name}/classes"/>
+ <sequential>
+ <mkdir dir="@{lib.dir}"/>
+ <local name="jarclasspath" />
+ <pathconvert property="jarclasspath">
+ <path>
+ <pathelement path="@{dependencies}" />
+ </path>
+ <map from="${basedir}/" to="" />
+ <mapper type="glob" from="*" to="*.jar"/>
+ </pathconvert>
+ <jar destfile="@{lib.dir}/@{module.name}.jar"
+ basedir="@{classes.dir}">
+ <manifest>
+ <attribute name="Class-Path" value="@{jarclasspath}"/>
+ </manifest>
+ </jar>
+ </sequential>
+ </macrodef>
</target>
-
- <!--
- **** Targets for Ant macro and task definitions.
- -->
-
<target name="-def-build-tool">
<macrodef name="build-tool">
<attribute name="name"/>
- <attribute name="bin.dir" default="${dist.bin.dir}"/>
+ <attribute name="compilation.kind" default=""/>
+ <attribute name="bin.dir" default="${@{compilation.kind}dist.bin.dir}"/>
<attribute name="java" default="${launcher.java}"/>
<sequential>
<mkdir dir="@{bin.dir}"/>
@@ -866,84 +516,73 @@
</macrodef>
</target>
- <target name="-def-build-jar">
- <macrodef name="build-jar">
- <attribute name="name"/>
- <attribute name="includes"/>
- <attribute name="classes.dir" default="${build.classes.dir}"/>
- <attribute name="lib.dir" default="${dist.lib.dir}"/>
- <attribute name="jarmainclass" default="com.sun.tools.@{name}.Main"/>
- <attribute name="jarclasspath" default=""/>
+ <target name="-def-build-all-module-classes" depends="-def-build-module-classes">
+ <macrodef name="build-all-module-classes">
+ <attribute name="compilation.kind" default=""/>
<sequential>
- <mkdir dir="@{lib.dir}"/>
- <jar destfile="@{lib.dir}/@{name}.jar"
- basedir="@{classes.dir}"
- includes="@{includes}">
- <manifest>
- <attribute name="Main-Class" value="@{jarmainclass}"/>
- <attribute name="Class-Path" value="@{jarclasspath}"/>
- </manifest>
- </jar>
+ <build-module-classes module.name="java.base"
+ compilation.kind="@{compilation.kind}" />
+ <build-module-classes module.name="java.compiler"
+ compilation.kind="@{compilation.kind}" />
+ <build-module-classes module.name="jdk.compiler"
+ compilation.kind="@{compilation.kind}" />
+ <build-module-classes module.name="jdk.javadoc"
+ compilation.kind="@{compilation.kind}" />
+ <build-module-classes module.name="jdk.dev"
+ compilation.kind="@{compilation.kind}" />
</sequential>
</macrodef>
</target>
- <target name="-def-build-jar-with-services">
- <macrodef name="build-jar-with-services">
- <attribute name="name"/>
- <attribute name="includes"/>
- <attribute name="classes.dir" default="${build.classes.dir}"/>
- <attribute name="lib.dir" default="${dist.lib.dir}"/>
- <attribute name="jarmainclass" default="com.sun.tools.@{name}.Main"/>
- <attribute name="jarclasspath" default=""/>
- <attribute name="service.type" default=""/>
- <attribute name="service.provider" default=""/>
- <sequential>
- <mkdir dir="${build.toolclasses.dir}"/>
- <jar destfile="@{lib.dir}/@{name}.jar"
- basedir="@{classes.dir}"
- includes="@{includes}">
- <service type="@{service.type}" provider="@{service.provider}"/>
- <manifest>
- <attribute name="Main-Class" value="@{jarmainclass}"/>
- <attribute name="Class-Path" value="@{jarclasspath}"/>
- </manifest>
- </jar>
- </sequential>
- </macrodef>
- </target>
-
- <target name="-def-build-classes" depends="-def-pcompile">
- <macrodef name="build-classes">
- <attribute name="includes"/>
+ <target name="-def-build-module-classes" depends="-def-pcompile">
+ <macrodef name="build-module-classes">
+ <attribute name="module.name"/>
+ <attribute name="compilation.kind" default=""/>
+ <attribute name="dependencies" default="${@{module.name}.dependencies}"/>
+ <attribute name="includes" default="${@{compilation.kind}javac.includes}"/>
+ <attribute name="javac.lint.opts" default="${@{compilation.kind}javac.lint.opts}"/>
+ <attribute name="javac.extra.opts" default="${@{compilation.kind}javac.extra.opts}"/>
+ <attribute name="build.dir" default="${@{compilation.kind}build.dir}"/>
<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="bootclasspath.opt" default="${javac.bootclasspath.opt}"/>
- <attribute name="classpath" default="${javac.classpath}"/>
- <attribute name="sourcepath" default="${javac.sourcepath}"/>
+ <attribute name="classes.dir" default="@{build.dir}/@{module.name}/classes"/>
+ <attribute name="gensrc.dir" default="@{build.dir}/@{module.name}/gensrc"/>
+ <attribute name="depcache.dir" default="@{build.dir}/@{module.name}/depcache"/>
<attribute name="java.home" default="${boot.java.home}"/>
- <attribute name="source" default="${javac.source}"/>
- <attribute name="target" default="${javac.target}"/>
+ <attribute name="source" default="${@{compilation.kind}javac.source}"/>
+ <attribute name="target" default="${@{compilation.kind}javac.target}"/>
<attribute name="release" default="${release}"/>
<attribute name="full.version" default="${full.version}"/>
<attribute name="plugin.options" default=""/>
<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}"/>
+ <echo level="verbose" message="build-classes: dependencies=@{dependencies}"/>
+ <local name="src.dir" />
+ <property name="src.dir" location="${basedir}/src/@{module.name}/share/classes"/>
+ <local name="classpath" />
+ <pathconvert property="classpath">
+ <path>
+ <pathelement path="@{dependencies}" />
+ </path>
+ <map from="${basedir}/" to="@{build.dir}/" />
+ <mapper type="glob" from="*" to="*/classes"/>
+ </pathconvert>
+ <local name="bootclasspath.prepend"/>
+ <condition property="bootclasspath.prepend" value="" else="${langtools.boot.classes}">
+ <equals arg1="@{compilation.kind}" arg2="boot."/>
+ </condition>
+ <mkdir dir="@{classes.dir}"/>
<mkdir dir="@{gensrc.dir}"/>
- <mkdir dir="@{classes.dir}"/>
+ <mkdir dir="@{depcache.dir}"/>
<pcompile destdir="@{gensrc.dir}"
includes="@{includes}">
<src>
- <path refid="src.dirs"/>
+ <path location="${src.dir}"/>
</src>
</pcompile>
<copy todir="@{gensrc.dir}">
- <multirootfileset basedirs="${src.dirs.property}" includes="@{includes}" />
+ <fileset dir="${src.dir}" includes="@{includes}" />
<globmapper from="*.properties-template" to="*.properties"/>
<filterset begintoken="$(" endtoken=")">
<filter token="JDK_VERSION" value="${jdk.version}"/>
@@ -957,13 +596,20 @@
<pathelement location="@{gensrc.dir}"/>
</src>
</pcompile>
+ <antcall target="-do-depend">
+ <param name="src.dir" value="${src.dir}" />
+ <param name="classes.dir" value="@{classes.dir}" />
+ <param name="gensrc.dir" value="@{gensrc.dir}" />
+ <param name="depcache.dir" value="@{depcache.dir}" />
+ <param name="classpath" value="${classpath}" />
+ </antcall>
<javac fork="true"
executable="@{java.home}/bin/javac"
destdir="@{classes.dir}"
includes="@{includes}"
excludes="@{excludes}"
- sourcepath="@{sourcepath}"
- classpath="@{classpath}"
+ sourcepath="${src.dir}:@{gensrc.dir}"
+ classpath="${classpath}"
includeAntRuntime="no"
source="@{source}"
target="@{target}"
@@ -971,19 +617,18 @@
debuglevel="${javac.debuglevel}">
<compilerarg value="-implicit:none"/>
<compilerarg value="-Xprefer:source"/>
- <compilerarg value="-J-Xbootclasspath/p:@{javac.bootclasspath}"/>
- <compilerarg line="@{bootclasspath.opt}"/>
- <compilerarg line="${javac.no.jdk.warnings}"/>
- <compilerarg line="${javac.version.opt}"/>
- <compilerarg line="${javac.lint.opts}"/>
+ <compilerarg value="-J-Xbootclasspath/p:${bootclasspath.prepend}"/>
+ <compilerarg value="-Xbootclasspath/p:${classpath}"/>
+ <compilerarg line="@{javac.extra.opts}"/>
+ <compilerarg line="@{javac.lint.opts}"/>
<compilerarg line="@{plugin.options}"/>
<src>
- <path refid="src.dirs"/>
+ <path location="${src.dir}"/>
<path location="@{gensrc.dir}"/>
</src>
</javac>
<copy todir="@{classes.dir}" includeemptydirs="false">
- <multirootfileset basedirs="${src.dirs.property}" includes="@{includes}" excludes="@{excludes}">
+ <fileset dir="${src.dir}" includes="@{includes}" excludes="@{excludes}">
<exclude name="**/*.java"/>
<exclude name="**/*.properties"/>
<exclude name="**/*-template"/>
@@ -991,42 +636,15 @@
<exclude name="**/*.orig"/>
<exclude name="**/overview.html"/>
<exclude name="**/package.html"/>
- </multirootfileset>
+ </fileset>
</copy>
</sequential>
</macrodef>
</target>
- <target name="-def-build-bootstrap-tool" depends="-check-boot.java.home,-def-build-tool">
- <presetdef name="build-bootstrap-tool">
- <build-tool
- bin.dir="${build.bootstrap.dir}/bin"
- java="${boot.java}"/>
- </presetdef>
- </target>
-
- <target name="-def-build-bootstrap-jar" depends="-def-build-jar">
- <presetdef name="build-bootstrap-jar">
- <build-jar
- 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"
- javac.bootclasspath=""
- bootclasspath.opt="-Xbootclasspath/p:${build.bootstrap.dir}/classes"
- sourcepath=""
- release="${bootstrap.release}"
- full.version="${bootstrap.full.version}"
- excludes="${bootstrap.exclude.files} **/package-info.java"/>
- </presetdef>
+ <target name="-do-depend" if="do.depend">
+ <depend srcdir="${src.dir}:${gensrc.dir}" destdir="${classes.dir}" classpath="${classpath}"
+ cache="${depcache.dir}"/>
</target>
<target name="-def-pcompile">
@@ -1048,55 +666,9 @@
classpath="${build.toolclasses.dir}/"/>
</target>
- <target name="-def-compilecrules">
- <macrodef name="compilecrules">
- <sequential>
- <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}"
- includes="crules/*"
- destdir="${build.toolclasses.dir}/"
- classpath="${ant.core.lib}"
- bootclasspath="${boot.java.home}/jre/lib/rt.jar"
- includeantruntime="false">
- <compilerarg value="-Xbootclasspath/p:${build.bootstrap.dir}/classes"/>
- <compilerarg line="${javac.lint.opts}"/>
- </javac>
- <copy todir="${build.toolclasses.dir}/" includeemptydirs="false">
- <fileset dir="${make.tools.dir}">
- <include name="**/*.properties"/>
- </fileset>
- </copy>
- </sequential>
- </macrodef>
- </target>
-
- <target name="-def-genstubs" depends="build-bootstrap-javac" if="require.import.jdk.stubs">
- <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}"
- includes="genstubs/* anttasks/GenStubs*"
- destdir="${build.toolclasses.dir}/"
- classpath="${ant.core.lib}"
- includeantruntime="false">
- <compilerarg value="-Xbootclasspath/p:${build.bootstrap.dir}/classes"/>
- <compilerarg line="${javac.lint.opts}"/>
- </javac>
- <taskdef name="genstubs"
- classname="anttasks.GenStubsTask"
- classpath="${build.toolclasses.dir}/"/>
- </target>
-
<target name="-def-javadoc-tool" depends="-check-target.java.home">
<macrodef name="javadoc-tool">
- <attribute name="name"/>
- <attribute name="includes"/>
+ <attribute name="includes" default="${javac.includes}"/>
<attribute name="options" default=""/>
<attribute name="source" default="${javac.source}"/>
<sequential>
@@ -1106,7 +678,7 @@
<property name="javadoc.packagenames" value="none"/> <!-- default, can be overridden per user or per project -->
<javadoc
executable="${target.java.home}/bin/javadoc"
- destdir="${build.javadoc.dir}/@{name}"
+ destdir="${build.javadoc.dir}"
source="@{source}"
windowtitle="UNOFFICIAL"
failonerror="true"
@@ -1116,57 +688,30 @@
packagenames="${javadoc.packagenames}" >
<header><![CDATA[<strong>Unofficial Javadoc</strong> generated from developer sources for preview purposes only]]></header>
<arg line="@{options}"/>
- <arg value="-tag" />
- <arg value="implNote:a:Implementation Note:"/>
<bootclasspath>
- <path location="${build.classes.dir}"/>
+ <pathelement path="${langtools.classes}"/>
<path location="${target.java.home}/jre/lib/rt.jar"/>
</bootclasspath>
<sourcepath>
- <path refid="src.dirs"/>
+ <pathelement path="${langtools.sources}"/>
</sourcepath>
<!-- XXX just <fileset> (restricted further to **/*.java) and no <packageset> -->
<!-- means that {@link some.package} will not work, which is no good. -->
<!-- (It correctly skips excluded single classes, but not if packageset is also included, -->
<!-- which also causes duplicates in the class index for included files.) -->
- <packageset dir="${src.dir}/java.base/share/classes" includes="@{includes}">
+ <packageset dir="${basedir}/src/java.compiler/share/classes" includes="@{includes}">
<or>
- <filename name="java/"/>
<filename name="javax/"/>
- <filename name="com/sun/javadoc/"/>
- <filename name="com/sun/source/"/>
</or>
</packageset>
- <packageset dir="${src.dir}/java.compiler/share/classes" includes="@{includes}">
+ <packageset dir="${basedir}/src/jdk.compiler/share/classes" includes="@{includes}">
<or>
- <filename name="java/"/>
- <filename name="javax/"/>
- <filename name="com/sun/javadoc/"/>
<filename name="com/sun/source/"/>
</or>
</packageset>
- <packageset dir="${src.dir}/jdk.compiler/share/classes" includes="@{includes}">
- <or>
- <filename name="java/"/>
- <filename name="javax/"/>
- <filename name="com/sun/javadoc/"/>
- <filename name="com/sun/source/"/>
- </or>
- </packageset>
- <packageset dir="${src.dir}/jdk.dev/share/classes" includes="@{includes}">
+ <packageset dir="${basedir}/src/jdk.javadoc/share/classes" includes="@{includes}">
<or>
- <filename name="java/"/>
- <filename name="javax/"/>
<filename name="com/sun/javadoc/"/>
- <filename name="com/sun/source/"/>
- </or>
- </packageset>
- <packageset dir="${src.dir}/jdk.javadoc/share/classes" includes="@{includes}">
- <or>
- <filename name="java/"/>
- <filename name="javax/"/>
- <filename name="com/sun/javadoc/"/>
- <filename name="com/sun/source/"/>
</or>
</packageset>
</javadoc>
@@ -1184,6 +729,7 @@
<macrodef name="jtreg-tool">
<attribute name="name"/>
<attribute name="tests"/>
+ <attribute name="langtools.classes" default="${langtools.classes}"/>
<attribute name="jdk" default="${target.java.home}"/>
<attribute name="samevm" default="true"/>
<attribute name="verbose" default="${default.jtreg.verbose}"/>
@@ -1191,6 +737,7 @@
<attribute name="keywords" default="-keywords:!ignore"/>
<attribute name="jpda.jvmargs" default=""/>
<attribute name="extra.jvmargs" default=""/>
+ <attribute name="build.dir" default="${build.dir}"/>
<sequential>
<property name="coverage.options" value=""/> <!-- default -->
<property name="coverage.classpath" value=""/> <!-- default -->
@@ -1204,7 +751,7 @@
samevm="@{samevm}" verbose="@{verbose}"
failonerror="false" resultproperty="jtreg.@{name}.result"
javacoptions="-g"
- vmoptions="${coverage.options} -Xbootclasspath/p:${coverage.classpath}${path.separator}${build.classes.dir} @{jpda.jvmargs} @{extra.jvmargs}">
+ vmoptions="${coverage.options} -Xbootclasspath/p:${coverage.classpath}${path.separator}@{langtools.classes} @{jpda.jvmargs} @{extra.jvmargs}">
<arg line="@{keywords}"/>
<arg line="@{options}"/>
<arg line="@{tests}"/>
@@ -1220,21 +767,12 @@
<property name="jtreg.defined" value="true"/>
</target>
- <target name="-def-cobertura" depends="-check-cobertura.home">
- <path id="cobertura.classpath">
- <fileset dir="${cobertura.home}">
- <include name="cobertura.jar"/>
- <include name="lib/**/*.jar"/>
- </fileset>
- </path>
- <taskdef classpathref="cobertura.classpath" resource="tasks.properties"/>
- </target>
-
- <target name="-def-checkstyle" unless="checkstyle.defined"
- depends="-check-checkstyle.home">
+ <target name="-def-checkstyle" unless="checkstyle.defined" depends="-check-checkstyle.home">
<taskdef resource="checkstyletask.properties">
<classpath>
- <pathelement location="${checkstyle.home}/${checkstyle.name.version}-all.jar"/>
+ <fileset dir="${checkstyle.home}">
+ <include name="checkstyle-*-all.jar"/>
+ </fileset>
</classpath>
</taskdef>
<property name="checkstyle.defined" value="true"/>
@@ -1265,7 +803,7 @@
jvmargs="-Xmx512M" >
<class location="${dist.dir}/lib/@{name}.jar"/>
<auxClasspath>
- <pathelement location="${build.classes.dir}"/>
+ <pathelement location="${langtools.classes}"/>
</auxClasspath>
<sourcePath>
<path refid="src.dirs"/>
@@ -1276,11 +814,6 @@
<property name="findbugs.defined" value="true"/>
</target>
- <target name="-def-vizant" unless="vizant.defined" depends="-check-vizant">
- <taskdef name="vizant" classname="net.sourceforge.vizant.Vizant" classpath="${vizant.jar}"/>
- <property name="vizant.defined" value="true"/>
- </target>
-
<target name="-def-check">
<macrodef name="check">
<attribute name="name"/>
--- a/langtools/make/intellij/build.xml Wed Nov 12 20:32:27 2014 -0800
+++ b/langtools/make/intellij/build.xml Thu Nov 13 09:39:52 2014 -0800
@@ -2,10 +2,8 @@
<project name="langtools" basedir="..">
<script language="javascript" classpath=".idea/classes">
- var ideaListener = project.getBuildListeners().firstElement();
var LangtoolsLogger = Java.type("idea.LangtoolsIdeaAntLogger");
- project.removeBuildListener(ideaListener)
- project.addBuildListener(new LangtoolsLogger(ideaListener))
+ new LangtoolsLogger(project)
</script>
<import file="../make/build.xml"/>
--- a/langtools/make/intellij/src/idea/LangtoolsIdeaAntLogger.java Wed Nov 12 20:32:27 2014 -0800
+++ b/langtools/make/intellij/src/idea/LangtoolsIdeaAntLogger.java Thu Nov 13 09:39:52 2014 -0800
@@ -26,7 +26,9 @@
package idea;
import org.apache.tools.ant.BuildEvent;
+import org.apache.tools.ant.BuildListener;
import org.apache.tools.ant.DefaultLogger;
+import org.apache.tools.ant.Project;
import java.util.EnumSet;
import java.util.Stack;
@@ -166,21 +168,17 @@
}
},
/** build bootstrap tool target - executed when bootstrapping javac */
- BUILD_BOOTSTRAP_TOOL("build-bootstrap-.*") {
+ BUILD_BOOTSTRAP_JAVAC("build-bootstrap-javac-classes") {
@Override
String getDisplayMessage(BuildEvent e) {
- String targetName = e.getTarget().getName();
- String tool = targetName.split("-")[2];
- return "Building bootstrap " + tool + "...";
+ return "Building bootstrap javac...";
}
},
/** build classes target - executed when building classes of given tool */
- BUILD_TOOL("build-classes-.*") {
+ BUILD_ALL_CLASSES("build-all-classes") {
@Override
String getDisplayMessage(BuildEvent e) {
- String targetName = e.getTarget().getName();
- String tool = targetName.split("-")[2];
- return "Building " + tool + "...";
+ return "Building all classes...";
}
},
/** synthetic target catching any other target not in this list */
@@ -195,14 +193,14 @@
}
};
- String targetRegex;
+ String targetName;
- Target(String targetRegex) {
- this.targetRegex = targetRegex;
+ Target(String targetName) {
+ this.targetName = targetName;
}
boolean matches(String msg) {
- return msg.matches(targetRegex);
+ return msg.equals(targetName);
}
abstract String getDisplayMessage(BuildEvent e);
@@ -253,8 +251,14 @@
/** stack of pending tasks */
Stack<Task> tasks = new Stack<>();
- public LangtoolsIdeaAntLogger(DefaultLogger logger) {
- this.logger = logger;
+ public LangtoolsIdeaAntLogger(Project project) {
+ for (Object o : project.getBuildListeners()) {
+ if (o instanceof DefaultLogger) {
+ this.logger = (DefaultLogger)o;
+ project.removeBuildListener((BuildListener)o);
+ project.addBuildListener(this);
+ }
+ }
tasks.push(Task.ROOT);
}
--- a/langtools/make/intellij/workspace.xml Wed Nov 12 20:32:27 2014 -0800
+++ b/langtools/make/intellij/workspace.xml Thu Nov 13 09:39:52 2014 -0800
@@ -10,7 +10,7 @@
<!-- standard tools -->
<configuration default="false" name="javac" type="Application" factoryName="Application">
<option name="MAIN_CLASS_NAME" value="com.sun.tools.javac.Main" />
- <option name="VM_PARAMETERS" value="-Xbootclasspath/p:build/classes" />
+ <option name="VM_PARAMETERS" value="-Xbootclasspath/p:build/java.compiler/classes:build/jdk.compiler/classes:build/java.base/classes:build/jdk.javadoc/classes:build/jdk.dev/classes" />
<option name="PROGRAM_PARAMETERS" value="" />
<option name="WORKING_DIRECTORY" value="file://$PROJECT_DIR$" />
<option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" />
@@ -24,12 +24,12 @@
<ConfigurationWrapper RunnerId="Run" />
<method>
<option name="Make" enabled="false" />
- <option name="AntTarget" enabled="true" antfile="file://$PROJECT_DIR$/.idea/build.xml" target="build-classes-javac" />
+ <option name="AntTarget" enabled="true" antfile="file://$PROJECT_DIR$/.idea/build.xml" target="build-all-classes" />
</method>
</configuration>
<configuration default="false" name="javadoc" type="Application" factoryName="Application">
<option name="MAIN_CLASS_NAME" value="com.sun.tools.javadoc.Main" />
- <option name="VM_PARAMETERS" value="-Xbootclasspath/p:build/classes" />
+ <option name="VM_PARAMETERS" value="-Xbootclasspath/p:build/java.compiler/classes:build/jdk.compiler/classes:build/java.base/classes:build/jdk.javadoc/classes:build/jdk.dev/classes" />
<option name="PROGRAM_PARAMETERS" value="" />
<option name="WORKING_DIRECTORY" value="file://$PROJECT_DIR$" />
<option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" />
@@ -43,12 +43,12 @@
<ConfigurationWrapper RunnerId="Run" />
<method>
<option name="Make" enabled="false" />
- <option name="AntTarget" enabled="true" antfile="file://$PROJECT_DIR$/.idea/build.xml" target="build-classes-javadoc" />
+ <option name="AntTarget" enabled="true" antfile="file://$PROJECT_DIR$/.idea/build.xml" target="build-all-classes" />
</method>
</configuration>
<configuration default="false" name="javap" type="Application" factoryName="Application">
<option name="MAIN_CLASS_NAME" value="com.sun.tools.javap.Main" />
- <option name="VM_PARAMETERS" value="-Xbootclasspath/p:build/classes" />
+ <option name="VM_PARAMETERS" value="-Xbootclasspath/p:build/java.compiler/classes:build/jdk.compiler/classes:build/java.base/classes:build/jdk.javadoc/classes:build/jdk.dev/classes" />
<option name="PROGRAM_PARAMETERS" value="" />
<option name="WORKING_DIRECTORY" value="file://$PROJECT_DIR$" />
<option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" />
@@ -62,12 +62,12 @@
<ConfigurationWrapper RunnerId="Run" />
<method>
<option name="Make" enabled="false" />
- <option name="AntTarget" enabled="true" antfile="file://$PROJECT_DIR$/.idea/build.xml" target="build-classes-javap" />
+ <option name="AntTarget" enabled="true" antfile="file://$PROJECT_DIR$/.idea/build.xml" target="build-all-classes" />
</method>
</configuration>
<configuration default="false" name="javah" type="Application" factoryName="Application">
<option name="MAIN_CLASS_NAME" value="com.sun.tools.javah.Main" />
- <option name="VM_PARAMETERS" value="-Xbootclasspath/p:build/classes" />
+ <option name="VM_PARAMETERS" value="-Xbootclasspath/p:build/java.compiler/classes:build/jdk.compiler/classes:build/java.base/classes:build/jdk.javadoc/classes:build/jdk.dev/classes" />
<option name="PROGRAM_PARAMETERS" value="" />
<option name="WORKING_DIRECTORY" value="file://$PROJECT_DIR$" />
<option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" />
@@ -81,12 +81,12 @@
<ConfigurationWrapper RunnerId="Run" />
<method>
<option name="Make" enabled="false" />
- <option name="AntTarget" enabled="true" antfile="file://$PROJECT_DIR$/.idea/build.xml" target="build-classes-javah" />
+ <option name="AntTarget" enabled="true" antfile="file://$PROJECT_DIR$/.idea/build.xml" target="build-all-classes" />
</method>
</configuration>
<configuration default="false" name="sjavac" type="Application" factoryName="Application">
<option name="MAIN_CLASS_NAME" value="com.sun.tools.sjavac.Main" />
- <option name="VM_PARAMETERS" value="-Xbootclasspath/p:build/classes" />
+ <option name="VM_PARAMETERS" value="-Xbootclasspath/p:build/java.compiler/classes:build/jdk.compiler/classes:build/java.base/classes:build/jdk.javadoc/classes:build/jdk.dev/classes" />
<option name="PROGRAM_PARAMETERS" value="" />
<option name="WORKING_DIRECTORY" value="file://$PROJECT_DIR$" />
<option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" />
@@ -100,13 +100,13 @@
<ConfigurationWrapper RunnerId="Run" />
<method>
<option name="Make" enabled="false" />
- <option name="AntTarget" enabled="true" antfile="file://$PROJECT_DIR$/.idea/build.xml" target="build-classes-sjavac" />
+ <option name="AntTarget" enabled="true" antfile="file://$PROJECT_DIR$/.idea/build.xml" target="build-all-classes" />
</method>
</configuration>
<!-- bootstrap javac -->
<configuration default="false" name="javac (bootstrap)" type="Application" factoryName="Application">
<option name="MAIN_CLASS_NAME" value="com.sun.tools.javac.Main" />
- <option name="VM_PARAMETERS" value="-Xbootclasspath/p:build/bootstrap/classes" />
+ <option name="VM_PARAMETERS" value="-Xbootclasspath/p:build/bootstrap/java.compiler/classes:build/bootstrap/jdk.compiler/classes:build/bootstrap/java.base/classes:build/bootstrap/jdk.javadoc/classes:build/bootstrap/jdk.dev/classes" />
<option name="PROGRAM_PARAMETERS" value="" />
<option name="WORKING_DIRECTORY" value="file://$PROJECT_DIR$" />
<option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" />
--- a/langtools/make/launcher.sh-template Wed Nov 12 20:32:27 2014 -0800
+++ b/langtools/make/launcher.sh-template Thu Nov 13 09:39:52 2014 -0800
@@ -43,10 +43,9 @@
# dependent jar files for additional dependencies.
if [ "$LANGTOOLS_USE_BOOTCLASSPATH" != "no" ]; then
- cp=`unzip -c "$mylib/#PROGRAM#.jar" META-INF/MANIFEST.MF |
- grep "Class-Path:" |
- sed -e 's|Class-Path: *||' -e 's|\([a-z]*\.jar\) *|'"$mylib"'/\1#PS#|g'`
- bcp="$mylib/#PROGRAM#.jar#PS#$cp"
+ cp=`echo "$mylib"/*.jar |
+ sed -e 's|\([a-z.]*\.jar\) *|\1#PS#|g'`
+ bcp=$cp
fi
# tools currently assumes that assertions are enabled in the launcher
@@ -72,4 +71,4 @@
unset DUALCASE
IFS=$nl
-"#TARGET_JAVA#" "${bcp:+-Xbootclasspath/p:"$bcp"}" ${ea} ${javaOpts} -jar "${mylib}/#PROGRAM#.jar" ${toolOpts}
+"#TARGET_JAVA#" "${bcp:+-Xbootclasspath/p:"$bcp"}" ${ea} ${javaOpts} com.sun.tools.#PROGRAM#.Main ${toolOpts}
--- a/langtools/make/netbeans/langtools/build.xml Wed Nov 12 20:32:27 2014 -0800
+++ b/langtools/make/netbeans/langtools/build.xml Thu Nov 13 09:39:52 2014 -0800
@@ -46,48 +46,34 @@
-->
<import file="../../build.xml"/>
- <!-- Build project. (action: build; F11)
- If langtools.tool.name is set, then just build that tool; otherwise
- build all tools.
- -->
-
- <target name="build" depends="-get-tool-if-set,-build-tool,-build-all"
- description="Build one or all langtools tools"
- />
+ <!-- Build project. (action: build; F11) -->
- <condition property="use_bootstrap" value="bootstrap-" else="">
- <isset property="langtools.tool.bootstrap"/>
- </condition>
- <condition property="with_bootclasspath" value="${build.bootstrap.dir}/classes" else="${build.classes.dir}">
- <isset property="langtools.tool.bootstrap"/>
- </condition>
-
- <target name="-build-tool" if="langtools.tool.name">
- <echo level="info" message="Building ${use_bootstrap}${langtools.tool.name}"/>
- <echo level="verbose" message="(Unset langtools.tool.name to build all tools)"/>
- <antcall target="build-${use_bootstrap}${langtools.tool.name}"/>
+ <target name="build" depends="-get-tool-if-set,-build-bootstrap-javac,-build-all" />
+ <target name="-build-bootstrap-javac" if="langtools.tool.bootstrap">
+ <antcall target="build-bootstrap-javac"/>
</target>
-
- <target name="-build-all" unless="langtools.tool.name">
- <echo level="info" message="Building all tools"/>
- <echo level="verbose" message="(Set langtools.tool.name to build a single tool)"/>
+ <target name="-build-all" unless="langtools.tool.bootstrap">
<antcall target="build-all-tools"/>
</target>
<!-- Compile a single file. (action: compile.single; F9) -->
- <target name="compile-single" depends="build-bootstrap-javac">
+ <target name="compile-single" depends="-get-tool-if-set,build-bootstrap-javac-classes" unless="langtools.tool.bootstrap">
<fail unless="includes">Must set property 'includes'</fail>
- <javac fork="true" executable="${build.bootstrap.dir}/bin/javac"
- srcdir="${srcdir}"
- destdir="${build.classes.dir}"
+ <mkdir dir="${build.dir}/${module.name}/classes" />
+ <javac fork="true" executable="${boot.java.home}/bin/javac"
+ srcdir="${basedir}/src/${module.name}/share/classes"
+ destdir="${build.dir}/${module.name}/classes"
includes="${includes}"
sourcepath=""
+ classpath="${langtools.classes}"
includeAntRuntime="no"
source="${javac.source}"
target="${javac.target}"
debug="${javac.debug}"
- debuglevel="${javac.debuglevel}"/>
+ debuglevel="${javac.debuglevel}">
+ <compilerarg value="-J-Xbootclasspath/p:${build.bootstrap.dir}/classes"/>
+ </javac>
</target>
<!-- Run tool. (action: run; F6)
@@ -95,16 +81,24 @@
the user.
-->
- <target name="run" depends="-check-target.java.home,build,-def-run,-get-tool-and-args"
+ <target name="run" depends="-check-target.java.home,-build-classes,-def-run,-get-tool-and-args,-setup-bootclasspath"
description="run tool">
<echo level="info" message="${with_bootclasspath}"/>
<echo level="info" message="Run ${use_bootstrap}${langtools.tool.name} with args ${langtools.tool.args}"/>
<run bcp="${with_bootclasspath}" mainclass="com.sun.tools.${langtools.tool.name}.Main" args="${langtools.tool.args}"/>
</target>
+ <target name="-build-classes" depends="-get-tool-if-set,-build-classes-bootstrap-javac,-build-classes-all" />
+ <target name="-build-classes-bootstrap-javac" if="langtools.tool.bootstrap">
+ <antcall target="build-bootstrap-javac-classes"/>
+ </target>
+ <target name="-build-classes-all" unless="langtools.tool.bootstrap">
+ <antcall target="build-all-classes"/>
+ </target>
+
<!-- Run a selected class. (action: run.single; shift-F6) -->
- <target name="run-single" depends="-check-target.java.home,-def-run">
+ <target name="run-single" depends="-check-target.java.home,-setup-bootclasspath,-def-run">
<fail unless="run.classname">Must set property 'run.classname' </fail>
<echo level="info" message="run ${run.classname}"/>
<run mainclass="${run.classname}" args=""/>
@@ -115,22 +109,22 @@
test all tools.
-->
- <target name="jtreg" depends="-get-tool-if-set,-jtreg-tool,-jtreg-all"
- description="Test one or all langtools tools"
+ <target name="jtreg" depends="-get-tool-if-set,-jtreg-bootstrap-javac,-jtreg-all"
+ description="Test langtools tools or bootstrap javac"
/>
- <target name="-jtreg-tool" if="langtools.tool.name">
- <echo level="info" message="Testing ${langtools.tool.name}"/>
- <echo level="verbose" message="(Unset langtools.tool.name to test all tools)"/>
+ <target name="-jtreg-bootstrap-javac" if="langtools.tool.bootstrap">
+ <echo level="info" message="Testing bootstrap javac"/>
+ <echo level="verbose" message="(Unset langtools.tool.bootstrap to test all tools)"/>
<antcall>
- <target name="jtreg-${langtools.tool.name}"/>
+ <target name="jtreg-bootstrap-javac"/>
<target name="-show-jtreg"/>
</antcall>
</target>
- <target name="-jtreg-all" unless="langtools.tool.name">
+ <target name="-jtreg-all" unless="langtools.tool.bootstrap">
<echo level="info" message="Testing all tools"/>
- <echo level="verbose" message="(Set langtools.tool.name to test a single tool)"/>
+ <echo level="verbose" message="(Set langtools.tool.bootstrap to test bootstrap javac)"/>
<antcall>
<target name="langtools.jtreg"/>
<target name="-show-jtreg"/>
@@ -165,7 +159,7 @@
<!-- Debug tool in NetBeans. -->
- <target name="debug" depends="-check-target.java.home,-def-run,-def-start-debugger,-get-tool-and-args,build" if="netbeans.home">
+ <target name="debug" depends="-check-target.java.home,-def-run,-def-start-debugger,-get-tool-and-args,-setup-bootclasspath,-build-classes" if="netbeans.home">
<echo level="info" message="Debug ${use_bootstrap}${langtools.tool.name} with args ${langtools.tool.args}"/>
<start-debugger/>
<run bcp="${with_bootclasspath}" mainclass="com.sun.tools.${langtools.tool.name}.Main" args="${langtools.tool.args}" jpda.jvmargs="${jpda.jvmargs}"/>
@@ -179,20 +173,29 @@
</target>
<!-- Debug a jtreg test. -->
- <target name="debug-jtreg" depends="-check-target.java.home,-def-start-debugger,-def-jtreg">
+ <target name="debug-jtreg" depends="-check-target.java.home,-def-start-debugger,-def-jtreg,-get-tool-if-set,-setup-bootclasspath">
<fail unless="jtreg.tests">Must set property 'jtreg.tests'</fail>
<start-debugger/>
- <jtreg-tool name="debug" samevm="false" tests="${jtreg.tests}" jpda.jvmargs="${jpda.jvmargs}"/>
+ <jtreg-tool name="debug"
+ samevm="false"
+ tests="${jtreg.tests}"
+ jpda.jvmargs="${jpda.jvmargs}"
+ langtools.classes="${with_bootclasspath}"/>
</target>
<!-- Update a class being debugged. -->
- <target name="debug-fix">
+ <target name="debug-fix" depends="-get-tool-if-set">
<fail unless="class">Must set property 'class'
</fail>
<antcall target="compile-single">
<param name="includes" value="${class}.java"/>
</antcall>
+ <condition property="build.classes.dir"
+ value="${build.dir}/${module.name}/classes"
+ else="${boot.build.dir}/${module.name}/classes">
+ <isset property="use_bootstrap"/>
+ </condition>
<nbjpdareload>
<fileset dir="${build.classes.dir}">
<include name="${class}.class"/>
@@ -205,31 +208,10 @@
test all tools.
-->
- <target name="javadoc" depends="-javadoc-tool,-javadoc-all"
- description="Generate javadoc for one or all langtools tools"
- />
-
- <target name="-javadoc-tool" if="langtools.tool.name">
- <echo level="info" message="Generate javadoc for ${langtools.tool.name}"/>
- <echo level="verbose" message="(Unset langtools.tool.name to generate javadoc for all tools)"/>
- <antcall>
- <target name="javadoc-${langtools.tool.name}"/>
- <target name="-show-javadoc"/>
- </antcall>
- </target>
-
- <target name="-javadoc-all" unless="langtools.tool.name">
- <echo level="info" message="Generate javadoc for all tools"/>
- <echo level="verbose" message="(Set langtools.tool.name to generate javadoc for a single tool)"/>
- <antcall>
- <target name="langtools.javadoc"/>
- <target name="-show-javadoc"/>
- </antcall>
- </target>
+ <target name="javadoc" depends="langtools.javadoc,-show-javadoc" />
<target name="-show-javadoc" if="netbeans.home">
- <!-- what if doing javadoc for all? -->
- <nbbrowse file="${build.javadoc.dir}/${langtools.tool.name}/index.html"/>
+ <nbbrowse file="${build.javadoc.dir}/index.html"/>
</target>
<!-- Prompt for values. -->
@@ -253,6 +235,15 @@
/>
</target>
+ <target name="-setup-bootclasspath">
+ <condition property="use_bootstrap" value="bootstrap-" else="">
+ <isset property="langtools.tool.bootstrap"/>
+ </condition>
+ <condition property="with_bootclasspath" value="${langtools.boot.classes}" else="${langtools.classes}">
+ <isset property="langtools.tool.bootstrap"/>
+ </condition>
+ </target>
+
<!-- Macro to run a tool or selected class - used by run* and debug* tasks -->
<target name="-def-run">
<macrodef name="run">
@@ -262,7 +253,7 @@
<attribute name="jpda.jvmargs" default=""/>
<sequential>
- <java fork="true" jvm="${target.java}" classname="@{mainclass}">
+ <java fork="true" jvm="${target.java.home}/bin/java" classname="@{mainclass}">
<jvmarg line="-Xbootclasspath/p:@{bcp}"/>
<jvmarg line="@{jpda.jvmargs}"/>
<arg line="@{args}"/>
@@ -278,11 +269,11 @@
<sequential>
<nbjpdastart name="${ant.project.name}" addressproperty="jpda.address" transport="dt_socket">
<bootclasspath>
- <pathelement location="${build.classes.dir}"/>
+ <pathelement path="${langtools.classes}"/>
<pathelement location="${target.java.home}/jre/lib/rt.jar"/>
</bootclasspath>
<sourcepath>
- <path refid="src.dirs"/>
+ <pathelement path="${langtools.sources}"/>
</sourcepath>
</nbjpdastart>
<property
--- a/langtools/make/netbeans/langtools/nbproject/project.xml Wed Nov 12 20:32:27 2014 -0800
+++ b/langtools/make/netbeans/langtools/nbproject/project.xml Thu Nov 13 09:39:52 2014 -0800
@@ -107,7 +107,7 @@
</action>
<action name="compile.single">
<target>compile-single</target>
- <property name="srcdir">src/java.base/share/classes</property>
+ <property name="module.name">java.base</property>
<context>
<property>includes</property>
<folder>${root}/src/java.base/share/classes</folder>
@@ -120,7 +120,7 @@
</action>
<action name="compile.single">
<target>compile-single</target>
- <property name="srcdir">src/java.compiler/share/classes</property>
+ <property name="module.name">java.compiler</property>
<context>
<property>includes</property>
<folder>${root}/src/java.compiler/share/classes</folder>
@@ -133,7 +133,7 @@
</action>
<action name="compile.single">
<target>compile-single</target>
- <property name="srcdir">src/jdk.compiler/share/classes</property>
+ <property name="module.name">jdk.compiler</property>
<context>
<property>includes</property>
<folder>${root}/src/jdk.compiler/share/classes</folder>
@@ -146,7 +146,7 @@
</action>
<action name="compile.single">
<target>compile-single</target>
- <property name="srcdir">src/jdk.dev/share/classes</property>
+ <property name="module.name">jdk.dev</property>
<context>
<property>includes</property>
<folder>${root}/src/jdk.dev/share/classes</folder>
@@ -159,7 +159,7 @@
</action>
<action name="compile.single">
<target>compile-single</target>
- <property name="srcdir">src/jdk.javadoc/share/classes</property>
+ <property name="module.name">jdk.javadoc</property>
<context>
<property>includes</property>
<folder>${root}/src/jdk.javadoc/share/classes</folder>
@@ -333,7 +333,7 @@
</action>
<action name="debug.fix">
<target>debug-fix</target>
- <property name="srcdir">src/java.base/share/classes</property>
+ <property name="module.name">java.base</property>
<context>
<property>class</property>
<folder>${root}/src/java.base/share/classes</folder>
@@ -346,7 +346,7 @@
</action>
<action name="debug.fix">
<target>debug-fix</target>
- <property name="srcdir">src/java.compiler/share/classes</property>
+ <property name="module.name">java.compiler</property>
<context>
<property>class</property>
<folder>${root}/src/java.compiler/share/classes</folder>
@@ -359,7 +359,7 @@
</action>
<action name="debug.fix">
<target>debug-fix</target>
- <property name="srcdir">src/jdk.compiler/share/classes</property>
+ <property name="module.name">jdk.compiler</property>
<context>
<property>class</property>
<folder>${root}/src/jdk.compiler/share/classes</folder>
@@ -372,7 +372,7 @@
</action>
<action name="debug.fix">
<target>debug-fix</target>
- <property name="srcdir">src/jdk.dev/share/classes</property>
+ <property name="module.name">jdk.dev</property>
<context>
<property>class</property>
<folder>${root}/src/jdk.dev/share/classes</folder>
@@ -385,7 +385,7 @@
</action>
<action name="debug.fix">
<target>debug-fix</target>
- <property name="srcdir">src/jdk.dev/share/classes</property>
+ <property name="module.name">jdk.javadoc</property>
<context>
<property>class</property>
<folder>${root}/src/jdk.javadoc/share/classes</folder>
@@ -478,11 +478,31 @@
<java-data xmlns="http://www.netbeans.org/ns/freeform-project-java/4">
<compilation-unit>
<package-root>${root}/src/java.base/share/classes</package-root>
+ <built-to>${root}/build/java.base/classes</built-to>
+ <source-level>1.8</source-level>
+ </compilation-unit>
+ <compilation-unit>
<package-root>${root}/src/java.compiler/share/classes</package-root>
+ <classpath mode="compile">${root}/build/java.base/classes</classpath>
+ <built-to>${root}/build/java.compiler/classes</built-to>
+ <source-level>1.8</source-level>
+ </compilation-unit>
+ <compilation-unit>
<package-root>${root}/src/jdk.compiler/share/classes</package-root>
+ <classpath mode="compile">${root}/build/java.base/classes:${root}/build/java.compiler/classes</classpath>
+ <built-to>${root}/build/jdk.compiler/classes</built-to>
+ <source-level>1.8</source-level>
+ </compilation-unit>
+ <compilation-unit>
<package-root>${root}/src/jdk.dev/share/classes</package-root>
+ <classpath mode="compile">${root}/build/java.base/classes:${root}/build/java.compiler/classes:${root}/build/jdk.compiler/classes</classpath>
+ <built-to>${root}/build/jdk.dev/classes</built-to>
+ <source-level>1.8</source-level>
+ </compilation-unit>
+ <compilation-unit>
<package-root>${root}/src/jdk.javadoc/share/classes</package-root>
- <built-to>${root}/build/classes</built-to>
+ <classpath mode="compile">${root}/build/java.base/classes:${root}/build/java.compiler/classes:${root}/build/jdk.compiler/classes</classpath>
+ <built-to>${root}/build/jdk.javadoc/classes</built-to>
<source-level>1.8</source-level>
</compilation-unit>
</java-data>
--- a/langtools/make/tools/anttasks/SelectToolTask.java Wed Nov 12 20:32:27 2014 -0800
+++ b/langtools/make/tools/anttasks/SelectToolTask.java Thu Nov 13 09:39:52 2014 -0800
@@ -74,7 +74,18 @@
enum ToolChoices {
NONE(""),
- JAVAC("javac"),
+ BOOSTRAP_JAVAC("bootstrap-javac", true) {
+ @Override
+ public ToolChoices baseTool() {
+ return JAVAC;
+ }
+ },
+ JAVAC("javac") {
+ @Override
+ public ToolChoices asBootstrap() {
+ return BOOSTRAP_JAVAC;
+ }
+ },
JAVADOC("javadoc"),
JAVAH("javah"),
JAVAP("javap");
@@ -91,6 +102,14 @@
this.bootstrap = bootstrap;
}
+ public ToolChoices asBootstrap() {
+ return this;
+ }
+
+ public ToolChoices baseTool() {
+ return this;
+ }
+
@Override
public String toString() {
return toolName;
@@ -176,9 +195,11 @@
JOptionPane p = createPane(guiProps);
p.createDialog("Select Tool").setVisible(true);
- toolName = ((ToolChoices)toolChoice.getSelectedItem()).toolName;
+ ToolChoices tool = (ToolChoices)toolChoice.getSelectedItem();
+
+ toolName = tool.baseTool().toolName;
+ toolBootstrap = tool.bootstrap;
toolArgs = argsField.getText();
- toolBootstrap = bootstrapCheckbox.isSelected();
if (defaultCheck.isSelected()) {
if (toolName.equals("")) {
fileProps.remove("tool.name");
@@ -213,30 +234,31 @@
EnumSet<ToolChoices> toolChoices = toolProperty == null ?
EnumSet.allOf(ToolChoices.class) : EnumSet.range(ToolChoices.JAVAC, ToolChoices.JAVAP);
toolChoice = new JComboBox<>(toolChoices.toArray());
- if (toolName != null)
- toolChoice.setSelectedItem(ToolChoices.valueOf(toolName.toUpperCase()));
+ ToolChoices tool = toolName != null ? ToolChoices.valueOf(toolName.toUpperCase()) : null;
+ if (toolName != null) {
+ if (toolBootstrap)
+ tool = tool.asBootstrap();
+ toolChoice.setSelectedItem(tool);
+ }
toolChoice.addItemListener(new ItemListener() {
@Override
public void itemStateChanged(ItemEvent e) {
- String tn = ((ToolChoices)e.getItem()).toolName;
- argsField.setText(getDefaultArgsForTool(props, tn));
+ ToolChoices tool = (ToolChoices)e.getItem();
+ argsField.setText(getDefaultArgsForTool(props, tool));
if (toolProperty != null)
- okButton.setEnabled(!tn.equals(""));
+ okButton.setEnabled(tool != ToolChoices.NONE);
}
});
- GridBagConstraints checkConstraint = new GridBagConstraints();
fc.anchor = GridBagConstraints.EAST;
GridBagConstraints toolConstraint = new GridBagConstraints();
fc.anchor = GridBagConstraints.WEST;
toolPane.add(toolChoice, toolConstraint);
- bootstrapCheckbox = new JCheckBox("bootstrap", toolBootstrap);
- toolPane.add(bootstrapCheckbox, checkConstraint);
body.add(toolPane, fc);
- argsField = new JTextField(getDefaultArgsForTool(props, toolName), 40);
+ argsField = new JTextField(getDefaultArgsForTool(props, tool), 40);
if (toolProperty == null || argsProperty != null) {
JLabel argsLabel = new JLabel("Args:");
body.add(argsLabel, lc);
@@ -322,8 +344,11 @@
}
}
- String getDefaultArgsForTool(Properties props, String tn) {
- return (tn == null || tn.equals("")) ? "" : props.getProperty(tn + ".args", "");
+ String getDefaultArgsForTool(Properties props, ToolChoices tool) {
+ if (tool == null)
+ return "";
+ String toolName = tool.baseTool().toolName;
+ return toolName.equals("") ? "" : props.getProperty(toolName + ".args", "");
}
// Ant task parameters
@@ -335,7 +360,6 @@
// GUI components
private JComboBox<?> toolChoice;
- private JCheckBox bootstrapCheckbox;
private JTextField argsField;
private JCheckBox defaultCheck;
private JButton okButton;
--- a/langtools/src/jdk.compiler/share/classes/com/sun/source/util/TaskListener.java Wed Nov 12 20:32:27 2014 -0800
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/source/util/TaskListener.java Thu Nov 13 09:39:52 2014 -0800
@@ -37,13 +37,19 @@
{
/**
* Invoked when an event has begun.
+ *
+ * @implSpec The default implementation of this method does nothing.
+ *
* @param e the event
*/
- public void started(TaskEvent e);
+ default void started(TaskEvent e) { }
/**
* Invoked when an event has been completed.
+ *
+ * @implSpec The default implementation of this method does nothing.
+ *
* @param e the event
*/
- public void finished(TaskEvent e);
+ default void finished(TaskEvent e) { }
}
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Scope.java Wed Nov 12 20:32:27 2014 -0800
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Scope.java Thu Nov 13 09:39:52 2014 -0800
@@ -305,7 +305,32 @@
* the table of its outer scope.
*/
public WriteableScope dupUnshared(Symbol newOwner) {
- return new ScopeImpl(this, newOwner, this.table.clone(), this.nelems);
+ if (shared > 0) {
+ //The nested Scopes might have already added something to the table, so all items
+ //that don't originate in this Scope or any of its outer Scopes need to be cleared:
+ Set<Scope> acceptScopes = Collections.newSetFromMap(new IdentityHashMap<>());
+ ScopeImpl c = this;
+ while (c != null) {
+ acceptScopes.add(c);
+ c = c.next;
+ }
+ int n = 0;
+ Entry[] oldTable = this.table;
+ Entry[] newTable = new Entry[this.table.length];
+ for (int i = 0; i < oldTable.length; i++) {
+ Entry e = oldTable[i];
+ while (e != null && e != sentinel && !acceptScopes.contains(e.scope)) {
+ e = e.shadowed;
+ }
+ if (e != null) {
+ n++;
+ newTable[i] = e;
+ }
+ }
+ return new ScopeImpl(this, newOwner, newTable, n);
+ } else {
+ return new ScopeImpl(this, newOwner, this.table.clone(), this.nelems);
+ }
}
/** Remove all entries of this scope from its table, if shared
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/code/TypeAnnotationPosition.java Wed Nov 12 20:32:27 2014 -0800
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/code/TypeAnnotationPosition.java Thu Nov 13 09:39:52 2014 -0800
@@ -145,7 +145,7 @@
public final int bound_index;
// For type parameter and method parameter
- public final int parameter_index;
+ public int parameter_index;
// For class extends, implements, and throws clauses
public final int type_index;
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java Wed Nov 12 20:32:27 2014 -0800
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java Thu Nov 13 09:39:52 2014 -0800
@@ -1196,35 +1196,35 @@
boolean hasDefault = false; // Is there a default label?
for (List<JCCase> l = tree.cases; l.nonEmpty(); l = l.tail) {
JCCase c = l.head;
+ if (c.pat != null) {
+ if (enumSwitch) {
+ Symbol sym = enumConstant(c.pat, seltype);
+ if (sym == null) {
+ log.error(c.pat.pos(), "enum.label.must.be.unqualified.enum");
+ } else if (!labels.add(sym)) {
+ log.error(c.pos(), "duplicate.case.label");
+ }
+ } else {
+ Type pattype = attribExpr(c.pat, switchEnv, seltype);
+ if (!pattype.hasTag(ERROR)) {
+ if (pattype.constValue() == null) {
+ log.error(c.pat.pos(),
+ (stringSwitch ? "string.const.req" : "const.expr.req"));
+ } else if (labels.contains(pattype.constValue())) {
+ log.error(c.pos(), "duplicate.case.label");
+ } else {
+ labels.add(pattype.constValue());
+ }
+ }
+ }
+ } else if (hasDefault) {
+ log.error(c.pos(), "duplicate.default.label");
+ } else {
+ hasDefault = true;
+ }
Env<AttrContext> caseEnv =
switchEnv.dup(c, env.info.dup(switchEnv.info.scope.dup()));
try {
- if (c.pat != null) {
- if (enumSwitch) {
- Symbol sym = enumConstant(c.pat, seltype);
- if (sym == null) {
- log.error(c.pat.pos(), "enum.label.must.be.unqualified.enum");
- } else if (!labels.add(sym)) {
- log.error(c.pos(), "duplicate.case.label");
- }
- } else {
- Type pattype = attribExpr(c.pat, switchEnv, seltype);
- if (!pattype.hasTag(ERROR)) {
- if (pattype.constValue() == null) {
- log.error(c.pat.pos(),
- (stringSwitch ? "string.const.req" : "const.expr.req"));
- } else if (labels.contains(pattype.constValue())) {
- log.error(c.pos(), "duplicate.case.label");
- } else {
- labels.add(pattype.constValue());
- }
- }
- }
- } else if (hasDefault) {
- log.error(c.pos(), "duplicate.default.label");
- } else {
- hasDefault = true;
- }
attribStats(c.stats, caseEnv);
} finally {
caseEnv.info.scope.leave();
@@ -1429,21 +1429,28 @@
case APPLY:
JCMethodInvocation speculativeMethodTree =
(JCMethodInvocation)deferredAttr.attribSpeculative(tree, env, unknownExprInfo);
- Type owntype = TreeInfo.symbol(speculativeMethodTree.meth).type.getReturnType();
- return types.unboxedTypeOrType(owntype).isPrimitive();
+ Symbol msym = TreeInfo.symbol(speculativeMethodTree.meth);
+ Type receiverType = speculativeMethodTree.meth.hasTag(IDENT) ?
+ env.enclClass.type :
+ ((JCFieldAccess)speculativeMethodTree.meth).selected.type;
+ Type owntype = types.memberType(receiverType, msym).getReturnType();
+ return primitiveOrBoxed(owntype);
case NEWCLASS:
JCExpression className =
removeClassParams.translate(((JCNewClass)tree).clazz);
JCExpression speculativeNewClassTree =
(JCExpression)deferredAttr.attribSpeculative(className, env, unknownTypeInfo);
- return types.unboxedTypeOrType(speculativeNewClassTree.type).isPrimitive();
+ return primitiveOrBoxed(speculativeNewClassTree.type);
default:
Type speculativeType = deferredAttr.attribSpeculative(tree, env, unknownExprInfo).type;
- speculativeType = types.unboxedTypeOrType(speculativeType);
- return speculativeType.isPrimitive();
+ return primitiveOrBoxed(speculativeType);
}
}
//where
+ boolean primitiveOrBoxed(Type t) {
+ return (!t.hasTag(TYPEVAR) && types.unboxedTypeOrType(t).isPrimitive());
+ }
+
TreeTranslator removeClassParams = new TreeTranslator() {
@Override
public void visitTypeApply(JCTypeApply tree) {
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/DeferredAttr.java Wed Nov 12 20:32:27 2014 -0800
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/DeferredAttr.java Thu Nov 13 09:39:52 2014 -0800
@@ -1213,7 +1213,10 @@
return;
}
scan(tree.falsepart);
- result = reduce(ArgumentExpressionKind.PRIMITIVE);
+ result = reduce(ArgumentExpressionKind.PRIMITIVE).isPrimitive() ?
+ ArgumentExpressionKind.PRIMITIVE :
+ ArgumentExpressionKind.POLY;
+
}
@Override
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Lower.java Wed Nov 12 20:32:27 2014 -0800
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Lower.java Thu Nov 13 09:39:52 2014 -0800
@@ -2642,9 +2642,10 @@
syms.intType, tree.sym);
ordParam.mods.flags |= SYNTHETIC; ordParam.sym.flags_field |= SYNTHETIC;
+ MethodSymbol m = tree.sym;
tree.params = tree.params.prepend(ordParam).prepend(nameParam);
-
- MethodSymbol m = tree.sym;
+ incrementParamTypeAnnoIndexes(m, 2);
+
m.extraParams = m.extraParams.prepend(ordParam.sym);
m.extraParams = m.extraParams.prepend(nameParam.sym);
Type olderasure = m.erasure(types);
@@ -2667,6 +2668,17 @@
}
}
//where
+ private void incrementParamTypeAnnoIndexes(MethodSymbol m,
+ int amount) {
+ for (final Attribute.TypeCompound anno : m.getRawTypeAttributes()) {
+ // Increment the parameter_index of any existing formal
+ // parameter annotations.
+ if (anno.position.type == TargetType.METHOD_FORMAL_PARAMETER) {
+ anno.position.parameter_index += amount;
+ }
+ }
+ }
+
private void visitMethodDefInternal(JCMethodDecl tree) {
if (tree.name == names.init &&
(currentClass.isInner() || currentClass.isLocal())) {
@@ -2697,8 +2709,10 @@
// Add this$n (if needed) in front of and free variables behind
// constructor parameter list.
tree.params = tree.params.appendList(fvdefs);
- if (currentClass.hasOuterInstance())
+ if (currentClass.hasOuterInstance()) {
tree.params = tree.params.prepend(otdef);
+ incrementParamTypeAnnoIndexes(m, 1);
+ }
// If this is an initial constructor, i.e., it does not start with
// this(...), insert initializers for this$n and proxies
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/util/BasicDiagnosticFormatter.java Wed Nov 12 20:32:27 2014 -0800
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/util/BasicDiagnosticFormatter.java Thu Nov 13 09:39:52 2014 -0800
@@ -111,6 +111,8 @@
Collection<String> args = formatArguments(d, l);
String msg = localize(l, d.getCode(), args.toArray());
String[] lines = msg.split("\n");
+ if (lines.length == 0) // will happen when msg only contains one or more separators: "\n", "\n\n", etc.
+ lines = new String[] { "" };
if (getConfiguration().getVisible().contains(DiagnosticPart.SUMMARY)) {
currentIndentation += getConfiguration().getIndentation(DiagnosticPart.SUMMARY);
buf.append(indent(lines[0], currentIndentation)); //summary
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/client/ClientMain.java Wed Nov 12 20:32:27 2014 -0800
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/client/ClientMain.java Thu Nov 13 09:39:52 2014 -0800
@@ -218,21 +218,21 @@
// Collect the name of all compiled packages.
Set<String> recently_compiled = new HashSet<>();
boolean[] rc = new boolean[1];
+ boolean background = Util.extractBooleanOption("background", options.getServerConf(), true);
Sjavac sjavac;
- boolean background = Util.extractBooleanOption("background", options.getServerConf(), true);
+ // Create an sjavac implementation to be used for compilation
+ if (background) {
+ sjavac = new SjavacClient(options);
+ } else {
+ int poolsize = Util.extractIntOption("poolsize", options.getServerConf());
+ if (poolsize <= 0)
+ poolsize = Runtime.getRuntime().availableProcessors();
+ sjavac = new PooledSjavac(new SjavacImpl(), poolsize);
+ }
+
do {
// Clean out artifacts in tainted packages.
javac_state.deleteClassArtifactsInTaintedPackages();
- // Create an sjavac implementation to be used for compilation
- if (background) {
- sjavac = new SjavacClient(options);
- } else {
- int poolsize = Util.extractIntOption("poolsize", options.getServerConf());
- if (poolsize <= 0)
- poolsize = Runtime.getRuntime().availableProcessors();
- sjavac = new PooledSjavac(new SjavacImpl(), poolsize);
- }
-
again = javac_state.performJavaCompilations(sjavac, options, recently_compiled, rc);
if (!rc[0]) break;
} while (again);
--- a/langtools/test/tools/javac/6508981/TestInferBinaryName.java Wed Nov 12 20:32:27 2014 -0800
+++ b/langtools/test/tools/javac/6508981/TestInferBinaryName.java Thu Nov 13 09:39:52 2014 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2014, Oracle and/or its affiliates. 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
@@ -26,7 +26,8 @@
* @bug 6508981
* @summary cleanup file separator handling in JavacFileManager
* (This test is specifically to test the new impl of inferBinaryName)
- * @build p.A
+ * @library /tools/lib
+ * @build ToolBox p.A
* @run main TestInferBinaryName
*/
@@ -61,51 +62,75 @@
//System.err.println(System.getProperties());
testDirectory();
testSymbolArchive();
- testZipArchive();
- testZipFileIndexArchive();
- testZipFileIndexArchive2();
+
+ File testJar = createJar();
+
+ testZipArchive(testJar);
+ testZipFileIndexArchive(testJar);
+ testZipFileIndexArchive2(testJar);
if (errors > 0)
throw new Exception(errors + " error found");
}
+ File createJar() throws IOException {
+ File f = new File("test.jar");
+ try (JavaFileManager fm = new JavacFileManager(new Context(), false, null)) {
+ ToolBox tb = new ToolBox();
+ tb.new JarTask(f.getPath())
+ .files(fm, StandardLocation.PLATFORM_CLASS_PATH, "java.lang.*")
+ .run();
+ }
+ return f;
+ }
+
void testDirectory() throws IOException {
String testClassName = "p.A";
- JavaFileManager fm =
- getFileManager("test.classes", USE_SYMBOL_FILE, USE_ZIP_FILE_INDEX);
- test("testDirectory",
- fm, testClassName, "com.sun.tools.javac.file.RegularFileObject");
+ List<File> testClasses = Arrays.asList(new File(System.getProperty("test.classes")));
+ try (JavaFileManager fm =
+ getFileManager(testClasses, USE_SYMBOL_FILE, USE_ZIP_FILE_INDEX)) {
+ test("testDirectory",
+ fm, testClassName, "com.sun.tools.javac.file.RegularFileObject");
+ }
}
void testSymbolArchive() throws IOException {
String testClassName = "java.lang.String";
- JavaFileManager fm =
- getFileManager("sun.boot.class.path", USE_SYMBOL_FILE, DONT_USE_ZIP_FILE_INDEX);
- test("testSymbolArchive",
- fm, testClassName, "com.sun.tools.javac.file.SymbolArchive$SymbolFileObject");
+ List<File> path = getPath(System.getProperty("sun.boot.class.path"));
+ try (JavaFileManager fm =
+ getFileManager(path, USE_SYMBOL_FILE, DONT_USE_ZIP_FILE_INDEX)) {
+ test("testSymbolArchive",
+ fm, testClassName, "com.sun.tools.javac.file.SymbolArchive$SymbolFileObject");
+ }
}
- void testZipArchive() throws IOException {
+ void testZipArchive(File testJar) throws IOException {
String testClassName = "java.lang.String";
- JavaFileManager fm =
- getFileManager("sun.boot.class.path", IGNORE_SYMBOL_FILE, DONT_USE_ZIP_FILE_INDEX);
- test("testZipArchive",
- fm, testClassName, "com.sun.tools.javac.file.ZipArchive$ZipFileObject");
+ List<File> path = Arrays.asList(testJar);
+ try (JavaFileManager fm =
+ getFileManager(path, IGNORE_SYMBOL_FILE, DONT_USE_ZIP_FILE_INDEX)) {
+ test("testZipArchive",
+ fm, testClassName, "com.sun.tools.javac.file.ZipArchive$ZipFileObject");
+ }
}
- void testZipFileIndexArchive() throws IOException {
+ void testZipFileIndexArchive(File testJar) throws IOException {
String testClassName = "java.lang.String";
- JavaFileManager fm =
- getFileManager("sun.boot.class.path", USE_SYMBOL_FILE, USE_ZIP_FILE_INDEX);
- test("testZipFileIndexArchive",
- fm, testClassName, "com.sun.tools.javac.file.ZipFileIndexArchive$ZipFileIndexFileObject");
+ List<File> path = Arrays.asList(testJar);
+ try (JavaFileManager fm =
+ getFileManager(path, USE_SYMBOL_FILE, USE_ZIP_FILE_INDEX)) {
+ test("testZipFileIndexArchive",
+ fm, testClassName, "com.sun.tools.javac.file.ZipFileIndexArchive$ZipFileIndexFileObject");
+ }
}
- void testZipFileIndexArchive2() throws IOException {
+ void testZipFileIndexArchive2(File testJar) throws IOException {
String testClassName = "java.lang.String";
- JavaFileManager fm =
- getFileManager("sun.boot.class.path", IGNORE_SYMBOL_FILE, USE_ZIP_FILE_INDEX);
- test("testZipFileIndexArchive2",
- fm, testClassName, "com.sun.tools.javac.file.ZipFileIndexArchive$ZipFileIndexFileObject");
+ List<File> path = Arrays.asList(testJar);
+ try (JavaFileManager fm =
+ getFileManager(path, IGNORE_SYMBOL_FILE, USE_ZIP_FILE_INDEX)) {
+ test("testZipFileIndexArchive2",
+ fm, testClassName, "com.sun.tools.javac.file.ZipFileIndexArchive$ZipFileIndexFileObject");
+ }
}
/**
@@ -133,7 +158,7 @@
System.err.println("OK");
}
- JavaFileManager getFileManager(String classpathProperty,
+ JavaFileManager getFileManager(List<File> path,
boolean symFileKind,
boolean zipFileIndexKind)
throws IOException {
@@ -145,7 +170,6 @@
if (symFileKind == IGNORE_SYMBOL_FILE)
options.put("ignore.symbol.file", "true");
JavacFileManager fm = new JavacFileManager(ctx, false, null);
- List<File> path = getPath(System.getProperty(classpathProperty));
fm.setLocation(CLASS_PATH, path);
return fm;
}
--- a/langtools/test/tools/javac/ConditionalWithVoid.java Wed Nov 12 20:32:27 2014 -0800
+++ b/langtools/test/tools/javac/ConditionalWithVoid.java Thu Nov 13 09:39:52 2014 -0800
@@ -1,14 +1,16 @@
/*
* @test /nodynamiccopyright/
- * @bug 4974927
+ * @bug 4974927 8064464
* @summary The compiler was allowing void types in its parsing of conditional expressions.
* @author tball
*
* @compile/fail/ref=ConditionalWithVoid.out -XDrawDiagnostics ConditionalWithVoid.java
*/
public class ConditionalWithVoid {
- public int test(Object o) {
- // Should fail to compile since Object.wait() has a void return type.
+ public void test(Object o) {
+ // Should fail to compile since Object.wait() has a void return type. Poly case.
System.out.println(o instanceof String ? o.hashCode() : o.wait());
+ // Should fail to compile since Object.wait() has a void return type. Standalone case.
+ (o instanceof String ? o.hashCode() : o.wait()).toString();
}
}
--- a/langtools/test/tools/javac/ConditionalWithVoid.out Wed Nov 12 20:32:27 2014 -0800
+++ b/langtools/test/tools/javac/ConditionalWithVoid.out Thu Nov 13 09:39:52 2014 -0800
@@ -1,2 +1,3 @@
-ConditionalWithVoid.java:12:48: compiler.err.neither.conditional.subtype: java.lang.Integer, void
-1 error
+ConditionalWithVoid.java:12:71: compiler.err.void.not.allowed.here
+ConditionalWithVoid.java:14:30: compiler.err.neither.conditional.subtype: java.lang.Integer, void
+2 errors
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/classfile/ClassfileInspector.java Thu Nov 13 09:39:52 2014 -0800
@@ -0,0 +1,950 @@
+/*
+ * Copyright (c) 2012, 2014, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.lang.annotation.*;
+import java.io.*;
+import java.net.URL;
+import java.util.List;
+
+import com.sun.tools.classfile.*;
+
+/**
+ * A class providing utilities for writing tests that inspect class
+ * files directly, looking for specific type annotations.
+ *
+ * Note: this framework does not currently handle repeating
+ * annotations.
+ */
+public class ClassfileInspector {
+
+ /**
+ * A group of expected annotations to be found in a given class.
+ * If the class name is null, then the template will be applied to
+ * every class.
+ */
+ public static class Expected {
+ /**
+ * The name of the class. If {@code null} this template will
+ * apply to every class; otherwise, it will only be applied to
+ * the named class.
+ */
+ public final String classname;
+
+ /**
+ * The expected class annotations. These will be checked
+ * against the class' attributes.
+ */
+ public final ExpectedTypeAnnotation[] classAnnos;
+
+ /**
+ * The expected method annotations. These will be checked
+ * against all methods in the class.
+ */
+ public final ExpectedMethodTypeAnnotation[] methodAnnos;
+
+ /**
+ * The expected field annotations. These will be checked
+ * against all fields in the class.
+ */
+ public final ExpectedFieldTypeAnnotation[] fieldAnnos;
+
+ /**
+ * Create an {@code Expected} from its components.
+ *
+ * @param classname The name of the class to match, or {@code
+ * null} for all classes.
+ * @param classAnnos The expected class annotations.
+ * @param methodAnnos The expected method annotations.
+ * @param fieldAnnos The expected field annotations.
+ */
+ public Expected(String classname,
+ ExpectedTypeAnnotation[] classAnnos,
+ ExpectedMethodTypeAnnotation[] methodAnnos,
+ ExpectedFieldTypeAnnotation[] fieldAnnos) {
+ this.classname = classname;
+ this.classAnnos = classAnnos;
+ this.methodAnnos = methodAnnos;
+ this.fieldAnnos = fieldAnnos;
+ }
+
+ public String toString() {
+ final StringBuilder sb = new StringBuilder();
+ final String newline = System.lineSeparator();
+ sb.append("Expected on class ").append(classname);
+ if (null != classAnnos) {
+ sb.append(newline).append("Class annotations:").append(newline);
+ for(ExpectedTypeAnnotation anno : classAnnos) {
+ sb.append(anno).append(newline);
+ }
+ }
+ if (null != methodAnnos) {
+ sb.append(newline).append("Method annotations:").append(newline);
+ for(ExpectedTypeAnnotation anno : methodAnnos) {
+ sb.append(anno).append(newline);
+ }
+ }
+ if (null != fieldAnnos) {
+ sb.append(newline).append("Field annotations:").append(newline);
+ for(ExpectedTypeAnnotation anno : fieldAnnos) {
+ sb.append(anno).append(newline);
+ }
+ }
+ return sb.toString();
+ }
+
+ /**
+ * See if this template applies to a class.
+ *
+ * @param classname The classname to check.
+ * @return Whether or not this template should apply.
+ */
+ public boolean matchClassName(String classname) {
+ return this.classname == null || this.classname.equals(classname);
+ }
+
+ /**
+ * After applying the template to all classes, check to see if
+ * any of the expected annotations weren't matched.
+ *
+ * @return The number of missed matches.
+ */
+ public int check() {
+ int count = 0;
+ if (classAnnos != null) {
+ for(ExpectedTypeAnnotation expected : classAnnos) {
+ if (!expected.check()) {
+ count++;
+ }
+ }
+ }
+ if (methodAnnos != null) {
+ for(ExpectedMethodTypeAnnotation expected : methodAnnos) {
+ if (!expected.check()) {
+ count++;
+ }
+ }
+ }
+ if (fieldAnnos != null) {
+ for(ExpectedFieldTypeAnnotation expected : fieldAnnos) {
+ if (!expected.check()) {
+ count++;
+ }
+ }
+ }
+ return count;
+ }
+ }
+
+ /**
+ * An expected type annotation. This is both a superclass for
+ * method and field type annotations, as well as a class for type
+ * annotations on a class.
+ */
+ public static class ExpectedTypeAnnotation {
+ private int count = 0;
+ protected final String expectedName;
+ protected final int expectedCount;
+ protected final TypeAnnotation.TargetType targetType;
+ protected final int bound_index;
+ protected final int parameter_index;
+ protected final int type_index;
+ protected final int exception_index;
+ protected final TypeAnnotation.Position.TypePathEntry[] typePath;
+ protected final boolean visibility;
+
+ /**
+ * Create an {@code ExpectedTypeAnnotation} from its
+ * components. It is usually a better idea to use a {@code
+ * Builder} to do this.
+ *
+ * @param expectedName The expected annotation name.
+ * @param visibility Whether this annotation should be runtime-visible.
+ * @param expectedCount The number of annotations that should
+ * be seen. If 0, this asserts that the
+ * described annotation is not present.
+ * @param targetType The expected target type.
+ * @param bound_index The expected bound index, or {@code Integer.MIN_VALUE}.
+ * @param parameter_index The expected parameter index, or
+ * {@code Integer.MIN_VALUE}.
+ * @param type_index The expected type index, or {@code Integer.MIN_VALUE}.
+ * @param exception_index The expected exception index, or
+ * {@code Integer.MIN_VALUE}.
+ * @param typePath The expected type path.
+ */
+ public ExpectedTypeAnnotation(String expectedName,
+ boolean visibility,
+ int expectedCount,
+ TypeAnnotation.TargetType targetType,
+ int bound_index,
+ int parameter_index,
+ int type_index,
+ int exception_index,
+ TypeAnnotation.Position.TypePathEntry... typePath) {
+ this.expectedName = expectedName;
+ this.visibility = visibility;
+ this.expectedCount = expectedCount;
+ this.targetType = targetType;
+ this.bound_index = bound_index;
+ this.parameter_index = parameter_index;
+ this.type_index = type_index;
+ this.exception_index = exception_index;
+ this.typePath = typePath;
+ }
+
+ public String toString() {
+ final StringBuilder sb = new StringBuilder();
+ sb.append("Expected ");
+ sb.append(expectedCount);
+ sb.append(" annotation ");
+ sb.append(expectedName);
+ sb.append(visibility ? ", runtime visibile " : ", runtime invisibile ");
+ sb.append(targetType);
+ sb.append(", bound_index = ");
+ sb.append(bound_index);
+ sb.append(", parameter_index = ");
+ sb.append(parameter_index);
+ sb.append(", type_index = ");
+ sb.append(type_index);
+ sb.append(", exception_index = ");
+ sb.append(exception_index);
+ sb.append(", type_path = [");
+ for(int i = 0; i < typePath.length; i++) {
+ if (i != 0) {
+ sb.append(", ");
+ }
+ sb.append(typePath[i]);
+ }
+ sb.append("]");
+ return sb.toString();
+ }
+
+ /**
+ * See if this template matches the given visibility.
+ *
+ * @param Whether or not the annotation is visible at runtime.
+ * @return Whether or not this template matches the visibility.
+ */
+ public boolean matchVisibility(boolean visibility) {
+ return this.visibility == visibility;
+ }
+
+ /**
+ * Attempty to match this template against an annotation. If
+ * it does match, then the match count for the template will
+ * be incremented. Otherwise, nothing will be done.
+ *
+ * @param anno The annotation to attempt to match.
+ */
+ public void matchAnnotation(TypeAnnotation anno) {
+ boolean matches = true;
+
+ try {
+ matches = anno.constant_pool.getUTF8Info(anno.annotation.type_index).value.equals("L" + expectedName + ";");
+ } catch(Exception e) {
+ matches = false;
+ }
+
+ matches = matches && anno.position.type == targetType;
+ matches = matches && anno.position.bound_index == bound_index;
+ matches = matches && anno.position.parameter_index == parameter_index;
+ matches = matches && anno.position.type_index == type_index;
+ matches = matches && anno.position.exception_index == exception_index;
+ matches = matches && anno.position.location.size() == typePath.length;
+
+ if (matches) {
+ int i = 0;
+ for(TypeAnnotation.Position.TypePathEntry entry :
+ anno.position.location) {
+ matches = matches && typePath[i++].equals(entry);
+ }
+ }
+
+ if (matches) {
+ count++;
+ }
+ }
+
+ /**
+ * After all matching, check to see if the expected number of
+ * matches equals the actual number. If not, then print a
+ * failure message and return {@code false}.
+ *
+ * @return Whether or not the expected number of matched
+ * equals the actual number.
+ */
+ public boolean check() {
+ if (count != expectedCount) {
+ System.err.println(this + ", but saw " + count);
+ return false;
+ } else {
+ return true;
+ }
+ }
+
+ /**
+ * A builder class for creating {@code
+ * ExpectedTypeAnnotation}s in a more convenient fashion. The
+ * constructor for {@code ExpectedTypeAnnotation} takes a
+ * large number of parameters (by necessity). This class
+ * allows users to construct a {@code ExpectedTypeAnnotation}s
+ * using only the ones they need.
+ */
+ public static class Builder {
+ protected final String expectedName;
+ protected final int expectedCount;
+ protected final TypeAnnotation.TargetType targetType;
+ protected final boolean visibility;
+ protected int bound_index = Integer.MIN_VALUE;
+ protected int parameter_index = Integer.MIN_VALUE;
+ protected int type_index = Integer.MIN_VALUE;
+ protected int exception_index = Integer.MIN_VALUE;
+ protected TypeAnnotation.Position.TypePathEntry[] typePath =
+ new TypeAnnotation.Position.TypePathEntry[0];
+
+ /**
+ * Create a {@code Builder} from the mandatory parameters.
+ *
+ * @param expectedName The expected annotation name.
+ * @param targetType The expected target type.
+ * @param visibility Whether this annotation should be runtime-visible.
+ * @param expectedCount The number of annotations that should be seen.
+ */
+ public Builder(String expectedName,
+ TypeAnnotation.TargetType targetType,
+ boolean visibility,
+ int expectedCount) {
+ this.expectedName = expectedName;
+ this.visibility = visibility;
+ this.expectedCount = expectedCount;
+ this.targetType = targetType;
+ }
+
+ /**
+ * Create an {@code ExpectedTypeAnnotation} from all
+ * parameters that have been provided. The default values
+ * will be used for those that have not.
+ *
+ * @return The cretaed {@code ExpectedTypeAnnotation}.
+ */
+ public ExpectedTypeAnnotation build() {
+ return new ExpectedTypeAnnotation(expectedName, visibility,
+ expectedCount, targetType,
+ bound_index, parameter_index,
+ type_index, exception_index,
+ typePath);
+ }
+
+ /**
+ * Provide a bound index parameter.
+ *
+ * @param bound_index The bound_index value.
+ */
+ public Builder setBoundIndex(int bound_index) {
+ this.bound_index = bound_index;
+ return this;
+ }
+
+ /**
+ * Provide a parameter index parameter.
+ *
+ * @param bound_index The parameter_index value.
+ */
+ public Builder setParameterIndex(int parameter_index) {
+ this.parameter_index = parameter_index;
+ return this;
+ }
+
+ /**
+ * Provide a type index parameter.
+ *
+ * @param type_index The type_index value.
+ */
+ public Builder setTypeIndex(int type_index) {
+ this.type_index = type_index;
+ return this;
+ }
+
+ /**
+ * Provide an exception index parameter.
+ *
+ * @param exception_index The exception_index value.
+ */
+ public Builder setExceptionIndex(int exception_index) {
+ this.exception_index = exception_index;
+ return this;
+ }
+
+ /**
+ * Provide a type path parameter.
+ *
+ * @param typePath The type path value.
+ */
+ public Builder setTypePath(TypeAnnotation.Position.TypePathEntry[] typePath) {
+ this.typePath = typePath;
+ return this;
+ }
+ }
+ }
+
+ /**
+ * A type annotation found on a method.
+ */
+ public static class ExpectedMethodTypeAnnotation extends ExpectedTypeAnnotation {
+ private final String methodname;
+
+ /**
+ * Create an {@code ExpectedMethodTypeAnnotation} from its
+ * components. It is usually a better idea to use a {@code
+ * Builder} to do this.
+ *
+ * @param methodname The expected method name.
+ * @param expectedName The expected annotation name.
+ * @param visibility Whether this annotation should be runtime-visible.
+ * @param expectedCount The number of annotations that should be seen.
+ * @param targetType The expected target type.
+ * @param bound_index The expected bound index, or {@code Integer.MIN_VALUE}.
+ * @param parameter_index The expected parameter index, or
+ * {@code Integer.MIN_VALUE}.
+ * @param type_index The expected type index, or {@code Integer.MIN_VALUE}.
+ * @param exception_index The expected exception index, or
+ * {@code Integer.MIN_VALUE}.
+ * @param typePath The expected type path.
+ */
+ public ExpectedMethodTypeAnnotation(String methodname,
+ String expectedName,
+ boolean visibility,
+ int expectedCount,
+ TypeAnnotation.TargetType targetType,
+ int bound_index,
+ int parameter_index,
+ int type_index,
+ int exception_index,
+ TypeAnnotation.Position.TypePathEntry... typePath) {
+ super(expectedName, visibility, expectedCount, targetType, bound_index,
+ parameter_index, type_index, exception_index, typePath);
+ this.methodname = methodname;
+ }
+
+ public String toString() {
+ final StringBuilder sb = new StringBuilder();
+ sb.append("Expected ");
+ sb.append(expectedCount);
+ sb.append(" annotation ");
+ sb.append(expectedName);
+ sb.append(visibility ? ", runtime visibile " : ", runtime invisibile ");
+ sb.append(targetType);
+ sb.append(", bound_index = ");
+ sb.append(bound_index);
+ sb.append(", parameter_index = ");
+ sb.append(parameter_index);
+ sb.append(", type_index = ");
+ sb.append(type_index);
+ sb.append(", exception_index = ");
+ sb.append(exception_index);
+ sb.append(", type_path = [");
+ for(int i = 0; i < typePath.length; i++) {
+ if (i != 0) {
+ sb.append(", ");
+ }
+ sb.append(typePath[i]);
+ }
+ sb.append("]");
+ sb.append(" on method ");
+ sb.append(methodname);
+ return sb.toString();
+ }
+
+ /**
+ * See if this template applies to a method.
+ *
+ * @param methodname The method name to check.
+ * @return Whether or not this template should apply.
+ */
+ public boolean matchMethodName(String methodname) {
+ return this.methodname.equals(methodname);
+ }
+
+ /**
+ * A builder class for creating {@code
+ * ExpectedMethodTypeAnnotation}s in a more convenient fashion. The
+ * constructor for {@code ExpectedMethodTypeAnnotation} takes a
+ * large number of parameters (by necessity). This class
+ * allows users to construct a {@code ExpectedMethodTypeAnnotation}s
+ * using only the ones they need.
+ */
+ public static class Builder extends ExpectedTypeAnnotation.Builder {
+ protected final String methodname;
+
+ /**
+ * Create a {@code Builder} from the mandatory parameters.
+ *
+ * @param methodname The expected method name.
+ * @param expectedName The expected annotation name.
+ * @param targetType The expected target type.
+ * @param visibility Whether this annotation should be runtime-visible.
+ * @param expectedCount The number of annotations that should be seen.
+ */
+ public Builder(String methodname,
+ String expectedName,
+ TypeAnnotation.TargetType targetType,
+ boolean visibility,
+ int expectedCount) {
+ super(expectedName, targetType, visibility, expectedCount);
+ this.methodname = methodname;
+ }
+
+ /**
+ * Create an {@code ExpectedMethodTypeAnnotation} from all
+ * parameters that have been provided. The default values
+ * will be used for those that have not.
+ *
+ * @return The cretaed {@code ExpectedMethodTypeAnnotation}.
+ */
+ public ExpectedMethodTypeAnnotation build() {
+ return new ExpectedMethodTypeAnnotation(methodname, expectedName,
+ visibility, expectedCount,
+ targetType, bound_index,
+ parameter_index, type_index,
+ exception_index, typePath);
+ }
+ }
+ }
+
+ /**
+ * A type annotation found on a field.
+ */
+ public static class ExpectedFieldTypeAnnotation extends ExpectedTypeAnnotation {
+ private final String fieldname;
+
+ /**
+ * Create an {@code ExpectedFieldTypeAnnotation} from its
+ * components. It is usually a better idea to use a {@code
+ * Builder} to do this.
+ *
+ * @param fieldname The expected field name.
+ * @param expectedName The expected annotation name.
+ * @param visibility Whether this annotation should be runtime-visible.
+ * @param expectedCount The number of annotations that should be seen.
+ * @param targetType The expected target type.
+ * @param bound_index The expected bound index, or {@code Integer.MIN_VALUE}.
+ * @param parameter_index The expected parameter index, or
+ * {@code Integer.MIN_VALUE}.
+ * @param type_index The expected type index, or {@code Integer.MIN_VALUE}.
+ * @param exception_index The expected exception index, or
+ * {@code Integer.MIN_VALUE}.
+ * @param typePath The expected type path.
+ */
+ public ExpectedFieldTypeAnnotation(String fieldname,
+ String expectedName,
+ boolean visibility,
+ int expectedCount,
+ TypeAnnotation.TargetType targetType,
+ int bound_index,
+ int parameter_index,
+ int type_index,
+ int exception_index,
+ TypeAnnotation.Position.TypePathEntry... typePath) {
+ super(expectedName, visibility, expectedCount, targetType, bound_index,
+ parameter_index, type_index, exception_index, typePath);
+ this.fieldname = fieldname;
+ }
+
+ public String toString() {
+ final StringBuilder sb = new StringBuilder();
+ sb.append("Expected ").append(expectedCount)
+ .append(" annotation ").append(expectedName)
+ .append(visibility ? ", runtime visibile " : ", runtime invisibile ")
+ .append(targetType)
+ .append(", bound_index = ").append(bound_index)
+ .append(", parameter_index = ").append(parameter_index)
+ .append(", type_index = ").append(type_index)
+ .append(", exception_index = ").append(exception_index)
+ .append(", type_path = [");
+
+ for(int i = 0; i < typePath.length; i++) {
+ if (i != 0) {
+ sb.append(", ");
+ }
+ sb.append(typePath[i]);
+ }
+ sb.append("]")
+ .append(" on field ").append(fieldname);
+ return sb.toString();
+ }
+
+ /**
+ * See if this template applies to a field.
+ *
+ * @param fieldname The field name to check.
+ * @return Whether or not this template should apply.
+ */
+ public boolean matchFieldName(String fieldname) {
+ return this.fieldname.equals(fieldname);
+ }
+
+ /**
+ * A builder class for creating {@code
+ * ExpectedFieldTypeAnnotation}s in a more convenient fashion. The
+ * constructor for {@code ExpectedFieldTypeAnnotation} takes a
+ * large number of parameters (by necessity). This class
+ * allows users to construct a {@code ExpectedFieldTypeAnnotation}s
+ * using only the ones they need.
+ */
+ public static class Builder extends ExpectedTypeAnnotation.Builder {
+ protected final String fieldname;
+
+ /**
+ * Create a {@code Builder} from the mandatory parameters.
+ *
+ * @param fieldname The expected field name.
+ * @param expectedName The expected annotation name.
+ * @param targetType The expected target type.
+ * @param visibility Whether this annotation should be runtime-visible.
+ * @param expectedCount The number of annotations that should be seen.
+ */
+ public Builder(String fieldname,
+ String expectedName,
+ TypeAnnotation.TargetType targetType,
+ boolean visibility,
+ int expectedCount) {
+ super(expectedName, targetType, visibility, expectedCount);
+ this.fieldname = fieldname;
+ }
+
+ /**
+ * Create an {@code ExpectedFieldTypeAnnotation} from all
+ * parameters that have been provided. The default values
+ * will be used for those that have not.
+ *
+ * @return The cretaed {@code ExpectedFieldTypeAnnotation}.
+ */
+ public ExpectedFieldTypeAnnotation build() {
+ return new ExpectedFieldTypeAnnotation(fieldname, expectedName,
+ visibility, expectedCount,
+ targetType, bound_index,
+ parameter_index, type_index,
+ exception_index, typePath);
+ }
+ }
+ }
+
+ private void matchClassTypeAnnotation(ClassFile classfile,
+ ExpectedTypeAnnotation expected)
+ throws ConstantPoolException {
+ for(Attribute attr : classfile.attributes) {
+ attr.accept(typeAnnoMatcher, expected);
+ }
+ }
+
+ private void matchMethodTypeAnnotation(ClassFile classfile,
+ ExpectedMethodTypeAnnotation expected)
+ throws ConstantPoolException {
+ for(Method meth : classfile.methods) {
+ if (expected.matchMethodName(meth.getName(classfile.constant_pool))) {
+ for(Attribute attr : meth.attributes) {
+ attr.accept(typeAnnoMatcher, expected);
+ }
+ }
+ }
+ }
+
+ private void matchFieldTypeAnnotation(ClassFile classfile,
+ ExpectedFieldTypeAnnotation expected)
+ throws ConstantPoolException {
+ for(Field field : classfile.fields) {
+ if (expected.matchFieldName(field.getName(classfile.constant_pool))) {
+ for(Attribute attr : field.attributes) {
+ attr.accept(typeAnnoMatcher, expected);
+ }
+ }
+ }
+ }
+
+ private void matchClassTypeAnnotations(ClassFile classfile,
+ ExpectedTypeAnnotation[] expected)
+ throws ConstantPoolException {
+ for(ExpectedTypeAnnotation one : expected) {
+ matchClassTypeAnnotation(classfile, one);
+ }
+ }
+
+ private void matchMethodTypeAnnotations(ClassFile classfile,
+ ExpectedMethodTypeAnnotation[] expected)
+ throws ConstantPoolException {
+ for(ExpectedMethodTypeAnnotation one : expected) {
+ matchMethodTypeAnnotation(classfile, one);
+ }
+ }
+
+ private void matchFieldTypeAnnotations(ClassFile classfile,
+ ExpectedFieldTypeAnnotation[] expected)
+ throws ConstantPoolException {
+ for(ExpectedFieldTypeAnnotation one : expected) {
+ matchFieldTypeAnnotation(classfile, one);
+ }
+ }
+
+ /**
+ * Run a template on a single {@code ClassFile}.
+ *
+ * @param classfile The {@code ClassFile} on which to run tests.
+ * @param expected The expected annotation template.
+ */
+ public void run(ClassFile classfile,
+ Expected... expected)
+ throws ConstantPoolException {
+ run(new ClassFile[] { classfile }, expected);
+ }
+
+ /**
+ * Run a template on multiple {@code ClassFile}s.
+ *
+ * @param classfile The {@code ClassFile}s on which to run tests.
+ * @param expected The expected annotation template.
+ */
+ public void run(ClassFile[] classfiles,
+ Expected... expected)
+ throws ConstantPoolException {
+ for(ClassFile classfile : classfiles) {
+ for(Expected one : expected) {
+ if (one.matchClassName(classfile.getName())) {
+ if (one.classAnnos != null)
+ matchClassTypeAnnotations(classfile, one.classAnnos);
+ if (one.methodAnnos != null)
+ matchMethodTypeAnnotations(classfile, one.methodAnnos);
+ if (one.fieldAnnos != null)
+ matchFieldTypeAnnotations(classfile, one.fieldAnnos);
+ }
+ }
+ }
+ int count = 0;
+ for (Expected one : expected) {
+ count += one.check();
+ }
+
+ if (count != 0) {
+ throw new RuntimeException(count + " errors occurred in test");
+ }
+ }
+
+ /**
+ * Get a {@code ClassFile} from its file name.
+ *
+ * @param name The class' file name.
+ * @return The {@code ClassFile}
+ */
+ public static ClassFile getClassFile(String name)
+ throws IOException, ConstantPoolException {
+ final URL url = ClassfileInspector.class.getResource(name);
+ final InputStream in = url.openStream();
+ try {
+ return ClassFile.read(in);
+ } finally {
+ in.close();
+ }
+ }
+
+ private static final Attribute.Visitor<Void, ExpectedTypeAnnotation> typeAnnoMatcher =
+ new Attribute.Visitor<Void, ExpectedTypeAnnotation>() {
+
+ @Override
+ public Void visitBootstrapMethods(BootstrapMethods_attribute attr,
+ ExpectedTypeAnnotation expected) {
+ return null;
+ }
+
+ @Override
+ public Void visitDefault(DefaultAttribute attr,
+ ExpectedTypeAnnotation expected) {
+ return null;
+ }
+
+ @Override
+ public Void visitAnnotationDefault(AnnotationDefault_attribute attr,
+ ExpectedTypeAnnotation expected) {
+ return null;
+ }
+
+ @Override
+ public Void visitCharacterRangeTable(CharacterRangeTable_attribute attr,
+ ExpectedTypeAnnotation expected) {
+ return null;
+ }
+
+ @Override
+ public Void visitCode(Code_attribute attr,
+ ExpectedTypeAnnotation expected) {
+ return null;
+ }
+
+ @Override
+ public Void visitCompilationID(CompilationID_attribute attr,
+ ExpectedTypeAnnotation expected) {
+ return null;
+ }
+
+ @Override
+ public Void visitConstantValue(ConstantValue_attribute attr,
+ ExpectedTypeAnnotation expected) {
+ return null;
+ }
+
+ @Override
+ public Void visitDeprecated(Deprecated_attribute attr,
+ ExpectedTypeAnnotation expected) {
+ return null;
+ }
+
+ @Override
+ public Void visitEnclosingMethod(EnclosingMethod_attribute attr,
+ ExpectedTypeAnnotation expected) {
+ return null;
+ }
+
+ @Override
+ public Void visitExceptions(Exceptions_attribute attr,
+ ExpectedTypeAnnotation expected) {
+ return null;
+ }
+
+ @Override
+ public Void visitInnerClasses(InnerClasses_attribute attr,
+ ExpectedTypeAnnotation expected) {
+ return null;
+ }
+
+ @Override
+ public Void visitLineNumberTable(LineNumberTable_attribute attr,
+ ExpectedTypeAnnotation expected) {
+ return null;
+ }
+
+ @Override
+ public Void visitLocalVariableTable(LocalVariableTable_attribute attr,
+ ExpectedTypeAnnotation expected) {
+ return null;
+ }
+
+ @Override
+ public Void visitLocalVariableTypeTable(LocalVariableTypeTable_attribute attr,
+ ExpectedTypeAnnotation expected) {
+ return null;
+ }
+
+ @Override
+ public Void visitMethodParameters(MethodParameters_attribute attr,
+ ExpectedTypeAnnotation expected) {
+ return null;
+ }
+
+ @Override
+ public Void visitRuntimeVisibleAnnotations(RuntimeVisibleAnnotations_attribute attr,
+ ExpectedTypeAnnotation expected) {
+ return null;
+ }
+
+ @Override
+ public Void visitRuntimeInvisibleAnnotations(RuntimeInvisibleAnnotations_attribute attr,
+ ExpectedTypeAnnotation expected) {
+ return null;
+ }
+
+ @Override
+ public Void visitRuntimeVisibleParameterAnnotations(RuntimeVisibleParameterAnnotations_attribute attr,
+ ExpectedTypeAnnotation expected) {
+ return null;
+ }
+
+ @Override
+ public Void visitRuntimeInvisibleParameterAnnotations(RuntimeInvisibleParameterAnnotations_attribute attr,
+ ExpectedTypeAnnotation expected) {
+ return null;
+ }
+
+ @Override
+ public Void visitSignature(Signature_attribute attr,
+ ExpectedTypeAnnotation expected) {
+ return null;
+ }
+
+ @Override
+ public Void visitSourceDebugExtension(SourceDebugExtension_attribute attr,
+ ExpectedTypeAnnotation expected) {
+ return null;
+ }
+
+ @Override
+ public Void visitSourceFile(SourceFile_attribute attr,
+ ExpectedTypeAnnotation expected) {
+ return null;
+ }
+
+ @Override
+ public Void visitSourceID(SourceID_attribute attr,
+ ExpectedTypeAnnotation expected) {
+ return null;
+ }
+
+ @Override
+ public Void visitStackMap(StackMap_attribute attr,
+ ExpectedTypeAnnotation expected) {
+ return null;
+ }
+
+ @Override
+ public Void visitStackMapTable(StackMapTable_attribute attr,
+ ExpectedTypeAnnotation expected) {
+ return null;
+ }
+
+ @Override
+ public Void visitSynthetic(Synthetic_attribute attr,
+ ExpectedTypeAnnotation expected) {
+ return null;
+ }
+
+ @Override
+ public Void visitRuntimeVisibleTypeAnnotations(RuntimeVisibleTypeAnnotations_attribute attr,
+ ExpectedTypeAnnotation expected) {
+ if (expected.matchVisibility(true)) {
+ for(TypeAnnotation anno : attr.annotations) {
+ expected.matchAnnotation(anno);
+ }
+ }
+
+ return null;
+ }
+
+ @Override
+ public Void visitRuntimeInvisibleTypeAnnotations(RuntimeInvisibleTypeAnnotations_attribute attr,
+ ExpectedTypeAnnotation expected) {
+ if (expected.matchVisibility(false)) {
+ for(TypeAnnotation anno : attr.annotations) {
+ expected.matchAnnotation(anno);
+ }
+ }
+
+ return null;
+ }
+ };
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/classfile/SyntheticParameters.java Thu Nov 13 09:39:52 2014 -0800
@@ -0,0 +1,130 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test SyntheticParameters
+ * @summary Test generation of annotations on inner class parameters.
+ * @build ClassfileInspector
+ * @run main SyntheticParameters
+ */
+
+import java.io.*;
+import java.lang.annotation.*;
+
+import com.sun.tools.classfile.*;
+
+public class SyntheticParameters extends ClassfileInspector {
+
+ private static final String Inner_class = "SyntheticParameters$Inner.class";
+ private static final String Foo_class = "SyntheticParameters$Foo.class";
+ private static final Expected Inner_expected =
+ new Expected("SyntheticParameters$Inner",
+ null,
+ new ExpectedMethodTypeAnnotation[] {
+ (ExpectedMethodTypeAnnotation)
+ // Assert there is no annotation on the
+ // this$0 parameter.
+ new ExpectedMethodTypeAnnotation.Builder(
+ "<init>",
+ "A",
+ TypeAnnotation.TargetType.METHOD_FORMAL_PARAMETER,
+ false,
+ 0).setParameterIndex(0).build(),
+ (ExpectedMethodTypeAnnotation)
+ // Assert there is an annotation on the
+ // first parameter.
+ new ExpectedMethodTypeAnnotation.Builder(
+ "<init>",
+ "A",
+ TypeAnnotation.TargetType.METHOD_FORMAL_PARAMETER,
+ false,
+ 1).setParameterIndex(1).build(),
+ (ExpectedMethodTypeAnnotation)
+ new ExpectedMethodTypeAnnotation.Builder(
+ "foo",
+ "A",
+ TypeAnnotation.TargetType.METHOD_FORMAL_PARAMETER,
+ false,
+ 1).setParameterIndex(0).build(),
+ (ExpectedMethodTypeAnnotation)
+ new ExpectedMethodTypeAnnotation.Builder(
+ "foo",
+ "A",
+ TypeAnnotation.TargetType.METHOD_FORMAL_PARAMETER,
+ false,
+ 0).setParameterIndex(1).build()
+ },
+ null);
+ private static final Expected Foo_expected =
+ new Expected("SyntheticParameters$Foo",
+ null,
+ new ExpectedMethodTypeAnnotation[] {
+ (ExpectedMethodTypeAnnotation)
+ // Assert there is no annotation on the
+ // $enum$name parameter.
+ new ExpectedMethodTypeAnnotation.Builder(
+ "<init>",
+ "A",
+ TypeAnnotation.TargetType.METHOD_FORMAL_PARAMETER,
+ false,
+ 0).setParameterIndex(0).build(),
+ (ExpectedMethodTypeAnnotation)
+ // Assert there is no annotation on the
+ // $enum$ordinal parameter.
+ new ExpectedMethodTypeAnnotation.Builder(
+ "<init>",
+ "A",
+ TypeAnnotation.TargetType.METHOD_FORMAL_PARAMETER,
+ false,
+ 0).setParameterIndex(1).build(),
+ (ExpectedMethodTypeAnnotation)
+ // Assert there is an annotation on the
+ // first parameter.
+ new ExpectedMethodTypeAnnotation.Builder(
+ "<init>",
+ "A",
+ TypeAnnotation.TargetType.METHOD_FORMAL_PARAMETER,
+ false,
+ 1).setParameterIndex(2).build()
+ },
+ null);
+
+ public static void main(String... args) throws Exception {
+ new SyntheticParameters().run(
+ new ClassFile[] { getClassFile(Inner_class), getClassFile(Foo_class) },
+ new Expected[] { Inner_expected, Foo_expected });
+ }
+
+ public class Inner {
+ public Inner(@A int a) {}
+ public void foo(@A int a, int b) {}
+ }
+
+ public static enum Foo {
+ ONE(null);
+ Foo(@A Object a) {}
+ }
+}
+
+@Target({ElementType.TYPE_USE})
+@interface A {}
--- a/langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/Constructors.java Wed Nov 12 20:32:27 2014 -0800
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/Constructors.java Thu Nov 13 09:39:52 2014 -0800
@@ -43,7 +43,7 @@
@TADescription(annotation = "TA", type = METHOD_RETURN, genericLocation = {1, 0})
@TADescription(annotation = "TB", type = METHOD_RETURN, genericLocation = {1, 0})
- @TADescription(annotation = "TC", type = METHOD_FORMAL_PARAMETER, paramIndex = 0)
+ @TADescription(annotation = "TC", type = METHOD_FORMAL_PARAMETER, paramIndex = 1)
@TestClass("%TEST_CLASS_NAME%$Inner")
public String innerClass() {
return "class %TEST_CLASS_NAME% { class Inner {" +
@@ -56,7 +56,7 @@
@TADescription(annotation = "TB", type = METHOD_RETURN, genericLocation = {1, 0})
@TADescription(annotation = "TC", type = METHOD_RECEIVER)
@TADescription(annotation = "TD", type = METHOD_RETURN, genericLocation = {1, 0})
- @TADescription(annotation = "TE", type = METHOD_FORMAL_PARAMETER, paramIndex = 0)
+ @TADescription(annotation = "TE", type = METHOD_FORMAL_PARAMETER, paramIndex = 1)
@TestClass("%TEST_CLASS_NAME%$Inner")
public String innerClass2() {
return "class %TEST_CLASS_NAME% { class Inner {" +
@@ -70,7 +70,7 @@
@TADescription(annotation = "TC", type = METHOD_RETURN, genericLocation = {1, 0, 1, 0})
@TADescription(annotation = "TD", type = METHOD_RECEIVER, genericLocation = {1, 0})
@TADescription(annotation = "TE", type = METHOD_RETURN, genericLocation = {1, 0, 1, 0})
- @TADescription(annotation = "TF", type = METHOD_FORMAL_PARAMETER, paramIndex = 0)
+ @TADescription(annotation = "TF", type = METHOD_FORMAL_PARAMETER, paramIndex = 1)
@TestClass("Outer$Middle$Inner")
public String innerClass3() {
return "class Outer { class Middle { class Inner {" +
@@ -89,7 +89,7 @@
@TADescription(annotation = "RTAs", type = METHOD_RETURN, genericLocation = {1, 0})
@TADescription(annotation = "RTBs", type = METHOD_RETURN, genericLocation = {1, 0})
- @TADescription(annotation = "RTCs", type = METHOD_FORMAL_PARAMETER, paramIndex = 0)
+ @TADescription(annotation = "RTCs", type = METHOD_FORMAL_PARAMETER, paramIndex = 1)
@TestClass("%TEST_CLASS_NAME%$Inner")
public String innerClassRepeatableAnnotation() {
return "class %TEST_CLASS_NAME% { class Inner {" +
@@ -102,7 +102,7 @@
@TADescription(annotation = "RTBs", type = METHOD_RETURN, genericLocation = {1, 0})
@TADescription(annotation = "RTCs", type = METHOD_RECEIVER)
@TADescription(annotation = "RTDs", type = METHOD_RETURN, genericLocation = {1, 0})
- @TADescription(annotation = "RTEs", type = METHOD_FORMAL_PARAMETER, paramIndex = 0)
+ @TADescription(annotation = "RTEs", type = METHOD_FORMAL_PARAMETER, paramIndex = 1)
@TestClass("%TEST_CLASS_NAME%$Inner")
public String innerClassRepeatableAnnotation2() {
return "class %TEST_CLASS_NAME% { class Inner {" +
@@ -116,7 +116,7 @@
@TADescription(annotation = "RTCs", type = METHOD_RETURN, genericLocation = {1, 0, 1, 0})
@TADescription(annotation = "RTDs", type = METHOD_RECEIVER, genericLocation = {1, 0})
@TADescription(annotation = "RTEs", type = METHOD_RETURN, genericLocation = {1, 0, 1, 0})
- @TADescription(annotation = "RTFs", type = METHOD_FORMAL_PARAMETER, paramIndex = 0)
+ @TADescription(annotation = "RTFs", type = METHOD_FORMAL_PARAMETER, paramIndex = 1)
@TestClass("Outer$Middle$Inner")
public String innerClassRepatableAnnotation3() {
return "class Outer { class Middle { class Inner {" +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/classfiles/attributes/EnclosingMethod/EnclosingMethodTest.java Thu Nov 13 09:39:52 2014 -0800
@@ -0,0 +1,537 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8042931
+ * @summary Checking EnclosingMethod attribute of anonymous/local class.
+ * @library /tools/lib /tools/javac/lib ../lib
+ * @build EnclosingMethodTest TestBase TestResult InMemoryFileManager ToolBox
+ * @run main EnclosingMethodTest
+ */
+
+import com.sun.tools.classfile.Attribute;
+import com.sun.tools.classfile.ClassFile;
+import com.sun.tools.classfile.EnclosingMethod_attribute;
+
+import java.io.File;
+import java.io.FilenameFilter;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import java.util.stream.Stream;
+
+/**
+ * The test checks the enclosing method attribute of anonymous/local classes.
+ * The top-level class contains the anonymous and local classes to be tested. The test examines
+ * each inner class and determine whether the class should have the EnclosingMethod attribute or not.
+ * Golden information about enclosing methods are held in annotation {@code ExpectedEnclosingMethod}.
+ *
+ * The test assumes that a class must have the EnclosingMethod attribute if the class is annotated or
+ * if its parent class is annotated in case of anonymous class. In addition, classes
+ * named {@code VariableInitializer} are introduced to test variable initializer cases. These classes
+ * must not have the enclosing method attribute, but its anonymous derived class must.
+ * After classification of classes, the test checks whether classes contain the correct enclosing
+ * method attribute in case of anonymous/local class, or checks whether classes do not contain
+ * the EnclosingMethod attribute, otherwise.
+ *
+ * Test cases:
+ * top-level class as enclosing class:
+ * 1. anonymous and local classes in static initializer;
+ * 2. anonymous and local classes in instance initializer;
+ * 3. anonymous and local classes in lambda;
+ * 4. anonymous and local classes in constructor;
+ * 5. anonymous and local classes in method;
+ * 6. static and instance variable initializer.
+ *
+ * inner class as enclosing class:
+ * 1. anonymous and local classes in static initializer;
+ * 2. anonymous and local classes in instance initializer;
+ * 3. anonymous and local classes in lambda;
+ * 4. anonymous and local classes in constructor;
+ * 5. anonymous and local classes in method;
+ * 6. static and instance variable initializer.
+ *
+ * enum as enclosing class:
+ * 1. anonymous and local classes in static initializer;
+ * 2. anonymous and local classes in instance initializer;
+ * 3. anonymous and local classes in lambda;
+ * 4. anonymous and local classes in constructor;
+ * 5. anonymous and local classes in method;
+ * 6. static and instance variable initializer.
+ *
+ * interface as enclosing class:
+ * 1. anonymous and local classes in lambda;
+ * 2. anonymous and local classes in static method;
+ * 3. anonymous and local classes in default method;
+ * 4. static variable initializer.
+ *
+ * annotation as enclosing class:
+ * 1. anonymous and local classes in lambda;
+ * 2. static variable initializer.
+ */
+public class EnclosingMethodTest extends TestResult {
+
+ private final Map<Class<?>, ExpectedEnclosingMethod> class2EnclosingMethod = new HashMap<>();
+ private final Set<Class<?>> noEnclosingMethod = new HashSet<>();
+
+ public EnclosingMethodTest() throws ClassNotFoundException {
+ Class<EnclosingMethodTest> outerClass = EnclosingMethodTest.class;
+ String outerClassName = outerClass.getSimpleName();
+ File testClasses = getClassDir();
+ FilenameFilter filter = (dir, name) -> name.matches(outerClassName + ".*\\.class");
+
+ for (File file : testClasses.listFiles(filter)) {
+ Class<?> clazz = Class.forName(file.getName().replace(".class", ""));
+ if (clazz.isAnonymousClass()) {
+ // anonymous class cannot be annotated, information is in its parent class.
+ ExpectedEnclosingMethod declaredAnnotation =
+ clazz.getSuperclass().getDeclaredAnnotation(ExpectedEnclosingMethod.class);
+ class2EnclosingMethod.put(clazz, declaredAnnotation);
+ } else {
+ ExpectedEnclosingMethod enclosingMethod = clazz.getDeclaredAnnotation(ExpectedEnclosingMethod.class);
+ // if class is annotated and it does not contain information for variable initializer cases,
+ // then it must have the enclosing method attribute.
+ if (enclosingMethod != null && !clazz.getSimpleName().contains("VariableInitializer")) {
+ class2EnclosingMethod.put(clazz, enclosingMethod);
+ } else {
+ noEnclosingMethod.add(clazz);
+ }
+ }
+ }
+ }
+
+ public void test() throws TestFailedException {
+ try {
+ testEnclosingMethodAttribute();
+ testLackOfEnclosingMethodAttribute();
+ } finally {
+ checkStatus();
+ }
+ }
+
+ private void testLackOfEnclosingMethodAttribute() {
+ for (Class<?> clazz : noEnclosingMethod) {
+ try {
+ addTestCase("Class should not have EnclosingMethod attribute : " + clazz);
+ ClassFile classFile = readClassFile(clazz);
+ checkEquals(countEnclosingMethodAttributes(classFile),
+ 0l, "number of the EnclosingMethod attribute in the class is zero : "
+ + classFile.getName());
+ } catch (Exception e) {
+ addFailure(e);
+ }
+ }
+ }
+
+ private void testEnclosingMethodAttribute() {
+ class2EnclosingMethod.forEach((clazz, enclosingMethod) -> {
+ try {
+ String info = enclosingMethod.info() + " "
+ + (clazz.isAnonymousClass() ? "anonymous" : "local");
+ addTestCase(info);
+ printf("Testing test case : %s\n", info);
+ ClassFile classFile = readClassFile(clazz);
+ String className = clazz.getName();
+ checkEquals(countEnclosingMethodAttributes(classFile), 1l,
+ "number of the EnclosingMethod attribute in the class is one : "
+ + clazz);
+ EnclosingMethod_attribute attr = (EnclosingMethod_attribute)
+ classFile.getAttribute(Attribute.EnclosingMethod);
+
+ if (!checkNotNull(attr, "the EnclosingMethod attribute is not null : " + className)) {
+ // stop checking, attr is null. test case failed
+ return;
+ }
+ checkEquals(classFile.constant_pool.getUTF8Value(attr.attribute_name_index),
+ "EnclosingMethod",
+ "attribute_name_index of EnclosingMethod attribute in the class : " + className);
+ checkEquals(attr.attribute_length, 4,
+ "attribute_length of EnclosingMethod attribute in the class : " + className);
+ String expectedClassName = enclosingMethod.enclosingClazz().getName();
+ checkEquals(classFile.constant_pool.getClassInfo(attr.class_index).getName(),
+ expectedClassName, String.format(
+ "enclosing class of EnclosingMethod attribute in the class %s is %s",
+ className, expectedClassName));
+
+ String expectedMethodName = enclosingMethod.enclosingMethod();
+ if (expectedMethodName.isEmpty()) {
+ // class does not have an enclosing method
+ checkEquals(attr.method_index, 0, String.format(
+ "enclosing method of EnclosingMethod attribute in the class %s is null", className));
+ } else {
+ String methodName = classFile.constant_pool.getNameAndTypeInfo(attr.method_index).getName();
+ checkTrue(methodName.startsWith(expectedMethodName), String.format(
+ "enclosing method of EnclosingMethod attribute in the class %s" +
+ " is method name %s" +
+ ", actual method name is %s",
+ className, expectedMethodName, methodName));
+ }
+ } catch (Exception e) {
+ addFailure(e);
+ }
+ });
+ }
+
+ private long countEnclosingMethodAttributes(ClassFile classFile) {
+ return Stream.of(classFile.attributes.attrs)
+ .filter(x -> x instanceof EnclosingMethod_attribute)
+ .count();
+ }
+
+ @Retention(RetentionPolicy.RUNTIME)
+ public @interface ExpectedEnclosingMethod {
+ String info();
+ Class<?> enclosingClazz();
+ String enclosingMethod() default "";
+ }
+
+ public static void main(String[] args) throws ClassNotFoundException, TestFailedException {
+ new EnclosingMethodTest().test();
+ }
+
+ // Test cases: enclosing class is a top-level class
+ static {
+ // anonymous and local classes in static initializer
+ @ExpectedEnclosingMethod(
+ info = "EnclosingStaticInitialization in EnclosingMethodTest",
+ enclosingClazz = EnclosingMethodTest.class
+ )
+ class EnclosingStaticInitialization {
+ }
+ new EnclosingStaticInitialization() {
+ };
+ }
+
+ {
+ // anonymous and local classes in instance initializer
+ @ExpectedEnclosingMethod(
+ info = "EnclosingInitialization in EnclosingMethodTest",
+ enclosingClazz = EnclosingMethodTest.class
+ )
+ class EnclosingInitialization {
+ }
+ new EnclosingInitialization() {
+ };
+ }
+
+ Runnable lambda = () -> {
+ // anonymous and local classes in lambda
+ @ExpectedEnclosingMethod(
+ info = "EnclosingLambda in EnclosingMethodTest",
+ enclosingMethod = "lambda",
+ enclosingClazz = EnclosingMethodTest.class
+ )
+ class EnclosingLambda {
+ }
+ new EnclosingLambda() {
+ };
+ };
+
+ EnclosingMethodTest(int i) {
+ // anonymous and local classes in constructor
+ @ExpectedEnclosingMethod(
+ info = "EnclosingConstructor in EnclosingMethodTest",
+ enclosingMethod = "<init>",
+ enclosingClazz = EnclosingMethodTest.class
+ )
+ class EnclosingConstructor {
+ }
+ new EnclosingConstructor() {
+ };
+ }
+
+ void method() {
+ // anonymous and local classes in method
+ @ExpectedEnclosingMethod(
+ info = "EnclosingMethod in EnclosingMethodTest",
+ enclosingMethod = "method",
+ enclosingClazz = EnclosingMethodTest.class
+ )
+ class EnclosingMethod {
+ }
+ new EnclosingMethod() {
+ };
+ }
+
+ @ExpectedEnclosingMethod(
+ info = "VariableInitializer in EnclosingMethodTest",
+ enclosingClazz = EnclosingMethodTest.class
+ )
+ static class VariableInitializer {
+ }
+
+ // static variable initializer
+ private static final VariableInitializer cvi = new VariableInitializer() {
+ };
+
+ // instance variable initializer
+ private final VariableInitializer ivi = new VariableInitializer() {
+ };
+
+ // Test cases: enclosing class is an inner class
+ public static class notEnclosing01 {
+ static {
+ // anonymous and local classes in static initializer
+ @ExpectedEnclosingMethod(
+ info = "EnclosingStaticInitialization in notEnclosing01",
+ enclosingClazz = notEnclosing01.class
+ )
+ class EnclosingStaticInitialization {
+ }
+ new EnclosingStaticInitialization() {
+ };
+ }
+
+ {
+ // anonymous and local classes in instance initializer
+ @ExpectedEnclosingMethod(
+ info = "EnclosingInitialization in notEnclosing01",
+ enclosingClazz = notEnclosing01.class
+ )
+ class EnclosingInitialization {
+ }
+ new EnclosingInitialization() {
+ };
+ }
+
+ Runnable lambda = () -> {
+ // anonymous and local classes in lambda
+ @ExpectedEnclosingMethod(
+ info = "EnclosingLambda in notEnclosing01",
+ enclosingMethod = "lambda",
+ enclosingClazz = notEnclosing01.class
+ )
+ class EnclosingLambda {
+ }
+ new EnclosingLambda() {
+ };
+ };
+
+ notEnclosing01() {
+ // anonymous and local classes in constructor
+ @ExpectedEnclosingMethod(
+ info = "EnclosingConstructor in notEnclosing01",
+ enclosingMethod = "<init>",
+ enclosingClazz = notEnclosing01.class
+ )
+ class EnclosingConstructor {
+ }
+ new EnclosingConstructor() {
+ };
+ }
+
+ void method() {
+ // anonymous and local classes in method
+ @ExpectedEnclosingMethod(
+ info = "EnclosingMethod in notEnclosing01",
+ enclosingMethod = "method",
+ enclosingClazz = notEnclosing01.class
+ )
+ class EnclosingMethod {
+ }
+ new EnclosingMethod() {
+ };
+ }
+
+ @ExpectedEnclosingMethod(
+ info = "VariableInitializer in notEnclosing01",
+ enclosingClazz = notEnclosing01.class
+ )
+ static class VariableInitializer {
+ }
+
+ // static variable initializer
+ private static final VariableInitializer cvi = new VariableInitializer() {
+ };
+
+ // instance variable initializer
+ private final VariableInitializer ivi = new VariableInitializer() {
+ };
+ }
+
+ // Test cases: enclosing class is an interface
+ public interface notEnclosing02 {
+ Runnable lambda = () -> {
+ // anonymous and local classes in lambda
+ @ExpectedEnclosingMethod(
+ info = "EnclosingLambda in notEnclosing02",
+ enclosingMethod = "lambda",
+ enclosingClazz = notEnclosing02.class
+ )
+ class EnclosingLambda {
+ }
+ new EnclosingLambda() {
+ };
+ };
+
+ static void staticMethod() {
+ // anonymous and local classes in static method
+ @ExpectedEnclosingMethod(
+ info = "EnclosingMethod in notEnclosing02",
+ enclosingMethod = "staticMethod",
+ enclosingClazz = notEnclosing02.class
+ )
+ class EnclosingMethod {
+ }
+ new EnclosingMethod() {
+ };
+ }
+
+ default void defaultMethod() {
+ // anonymous and local classes in default method
+ @ExpectedEnclosingMethod(
+ info = "EnclosingMethod in notEnclosing02",
+ enclosingMethod = "defaultMethod",
+ enclosingClazz = notEnclosing02.class
+ )
+ class EnclosingMethod {
+ }
+ new EnclosingMethod() {
+ };
+ }
+
+ @ExpectedEnclosingMethod(
+ info = "VariableInitializer in notEnclosing02",
+ enclosingClazz = notEnclosing02.class
+ )
+ static class VariableInitializer {
+ }
+
+ // static variable initializer
+ VariableInitializer cvi = new VariableInitializer() {
+ };
+ }
+
+ // Test cases: enclosing class is an enum
+ public enum notEnclosing03 {;
+
+ static {
+ // anonymous and local classes in static initializer
+ @ExpectedEnclosingMethod(
+ info = "EnclosingStaticInitialization in notEnclosing03",
+ enclosingClazz = notEnclosing03.class
+ )
+ class EnclosingStaticInitialization {
+ }
+ new EnclosingStaticInitialization() {
+ };
+ }
+
+ {
+ // anonymous and local classes in instance initializer
+ @ExpectedEnclosingMethod(
+ info = "EnclosingInitialization in notEnclosing03",
+ enclosingClazz = notEnclosing03.class
+ )
+ class EnclosingInitialization {
+ }
+ new EnclosingInitialization() {
+ };
+ }
+
+ Runnable lambda = () -> {
+ // anonymous and local classes in lambda
+ @ExpectedEnclosingMethod(
+ info = "EnclosingLambda in notEnclosing03",
+ enclosingMethod = "lambda",
+ enclosingClazz = notEnclosing03.class
+ )
+ class EnclosingLambda {
+ }
+ new EnclosingLambda() {
+ };
+ };
+
+ notEnclosing03() {
+ // anonymous and local classes in constructor
+ @ExpectedEnclosingMethod(
+ info = "EnclosingConstructor in notEnclosing03",
+ enclosingMethod = "<init>",
+ enclosingClazz = notEnclosing03.class
+ )
+ class EnclosingConstructor {
+ }
+ new EnclosingConstructor() {
+ };
+ }
+
+ void method() {
+ // anonymous and local classes in method
+ @ExpectedEnclosingMethod(
+ info = "EnclosingMethod in notEnclosing03",
+ enclosingMethod = "method",
+ enclosingClazz = notEnclosing03.class
+ )
+ class EnclosingMethod {
+ }
+ new EnclosingMethod() {
+ };
+ }
+
+ @ExpectedEnclosingMethod(
+ info = "VariableInitializer in notEnclosing03",
+ enclosingClazz = notEnclosing03.class
+ )
+ static class VariableInitializer {
+ }
+
+ // static variable initializer
+ private static final VariableInitializer cvi = new VariableInitializer() {
+ };
+
+ // instance variable initializer
+ private final VariableInitializer ivi = new VariableInitializer() {
+ };
+ }
+
+ // Test cases: enclosing class is an annotation
+ public @interface notEnclosing04 {
+ Runnable lambda = () -> {
+ // anonymous and local classes in lambda
+ @ExpectedEnclosingMethod(
+ info = "EnclosingLambda in notEnclosing04",
+ enclosingMethod = "lambda",
+ enclosingClazz = notEnclosing04.class
+ )
+ class EnclosingLambda {
+ }
+ new EnclosingLambda() {
+ };
+ };
+
+ @ExpectedEnclosingMethod(
+ info = "VariableInitializer in notEnclosing04",
+ enclosingClazz = notEnclosing04.class
+ )
+ static class VariableInitializer {
+ }
+
+ // static variable initializer
+ VariableInitializer cvi = new VariableInitializer() {
+ };
+ }
+}
--- a/langtools/test/tools/javac/classfiles/attributes/deprecated/DeprecatedPackageTest.java Wed Nov 12 20:32:27 2014 -0800
+++ b/langtools/test/tools/javac/classfiles/attributes/deprecated/DeprecatedPackageTest.java Thu Nov 13 09:39:52 2014 -0800
@@ -74,13 +74,13 @@
addTestCase(src);
printf("Testing test case: \n%s\n", src);
try {
- ClassFile cf = ClassFile.read(compile(
+ ClassFile cf = readClassFile(compile(
new String[]{"package-info.java", package_info},
new String[]{"notDeprecated.java", src})
- .getClasses().get(CLASS_NAME).openInputStream());
+ .getClasses().get(CLASS_NAME));
Deprecated_attribute attr =
(Deprecated_attribute) cf.getAttribute(Attribute.Deprecated);
- assertNull(attr, "Class can not have deprecated attribute : " + CLASS_NAME);
+ checkNull(attr, "Class can not have deprecated attribute : " + CLASS_NAME);
} catch (Exception e) {
addFailure(e);
}
--- a/langtools/test/tools/javac/classfiles/attributes/deprecated/DeprecatedTest.java Wed Nov 12 20:32:27 2014 -0800
+++ b/langtools/test/tools/javac/classfiles/attributes/deprecated/DeprecatedTest.java Thu Nov 13 09:39:52 2014 -0800
@@ -240,7 +240,7 @@
? "deprecated"
: "notDeprecated";
echo("Testing outer class : " + outerClassName);
- ClassFile cf = ClassFile.read(classes.get(outerClassName).openInputStream());
+ ClassFile cf = readClassFile(classes.get(outerClassName));
Deprecated_attribute attr = (Deprecated_attribute)
cf.getAttribute(Attribute.Deprecated);
testAttribute(outerClassName, attr, cf);
@@ -260,7 +260,7 @@
String innerClassName = cf.constant_pool.
getClassInfo(innerClass.inner_class_info_index).getName();
echo("Testing inner class : " + innerClassName);
- ClassFile innerCf = ClassFile.read(classes.get(innerClassName).openInputStream());
+ ClassFile innerCf = readClassFile(classes.get(innerClassName));
Deprecated_attribute attr = (Deprecated_attribute)
innerCf.getAttribute(Attribute.Deprecated);
String innerClassSimpleName = innerClass.getInnerName(cf.constant_pool);
@@ -298,17 +298,18 @@
if (name.contains("deprecated")) {
testDeprecatedAttribute(name, attr, cf);
} else {
- assertNull(attr, name + " should not have deprecated attribute");
+ checkNull(attr, name + " should not have deprecated attribute");
}
}
private void testDeprecatedAttribute(String name, Deprecated_attribute attr, ClassFile cf)
throws ConstantPoolException {
- assertNotNull(attr, name + " must have deprecated attribute");
- assertEquals(0, attr.attribute_length,
- "attribute_length should equal to 0");
- assertEquals("Deprecated",
- cf.constant_pool.getUTF8Value(attr.attribute_name_index),
- name + " attribute_name_index");
+ if (checkNotNull(attr, name + " must have deprecated attribute")) {
+ checkEquals(0, attr.attribute_length,
+ "attribute_length should equal to 0");
+ checkEquals("Deprecated",
+ cf.constant_pool.getUTF8Value(attr.attribute_name_index),
+ name + " attribute_name_index");
+ }
}
}
--- a/langtools/test/tools/javac/classfiles/attributes/innerclasses/InnerClassesHierarchyTest.java Wed Nov 12 20:32:27 2014 -0800
+++ b/langtools/test/tools/javac/classfiles/attributes/innerclasses/InnerClassesHierarchyTest.java Thu Nov 13 09:39:52 2014 -0800
@@ -96,21 +96,21 @@
ClassFile cf = readClassFile(currentClassName);
InnerClasses_attribute attr = (InnerClasses_attribute)
cf.getAttribute(Attribute.InnerClasses);
- assertNotNull(attr, "Class should not contain "
+ checkNotNull(attr, "Class should not contain "
+ "inner classes attribute : " + currentClassName);
- assertTrue(innerClasses.containsKey(currentClassName),
+ checkTrue(innerClasses.containsKey(currentClassName),
"map contains class name : " + currentClassName);
Set<String> setClasses = innerClasses.get(currentClassName);
if (setClasses == null) {
continue;
}
- assertEquals(attr.number_of_classes,
+ checkEquals(attr.number_of_classes,
setClasses.size(),
"Check number of inner classes : " + setClasses);
for (Info info : attr.classes) {
String innerClassName = info
.getInnerClassInfo(cf.constant_pool).getBaseName();
- assertTrue(setClasses.contains(innerClassName),
+ checkTrue(setClasses.contains(innerClassName),
currentClassName + " contains inner class : "
+ innerClassName);
if (visitedClasses.add(innerClassName)) {
@@ -124,10 +124,10 @@
Set<String> a_b = removeAll(visitedClasses, allClasses);
Set<String> b_a = removeAll(allClasses, visitedClasses);
- assertEquals(visitedClasses, allClasses,
+ checkEquals(visitedClasses, allClasses,
"All classes are found\n"
- + "visited - all classes : " + a_b
- + "\nall classes - visited : " + b_a);
+ + "visited - all classes : " + a_b
+ + "\nall classes - visited : " + b_a);
} catch (Exception e) {
addFailure(e);
} finally {
--- a/langtools/test/tools/javac/classfiles/attributes/innerclasses/InnerClassesIndexTest.java Wed Nov 12 20:32:27 2014 -0800
+++ b/langtools/test/tools/javac/classfiles/attributes/innerclasses/InnerClassesIndexTest.java Thu Nov 13 09:39:52 2014 -0800
@@ -78,16 +78,16 @@
continue;
}
foundClasses.add(innerName);
- assertEquals(info.outer_class_info_index, 0,
+ checkEquals(info.outer_class_info_index, 0,
"outer_class_info_index of " + innerName);
if (innerName.matches("\\$\\d+")) {
- assertEquals(info.inner_name_index, 0,
+ checkEquals(info.inner_name_index, 0,
"inner_name_index of anonymous class");
}
}
Set<String> expectedClasses = getInnerClasses();
expectedClasses.remove("InnerClassesIndexTest$Inner");
- assertEquals(foundClasses, expectedClasses, "All classes are found");
+ checkEquals(foundClasses, expectedClasses, "All classes are found");
} catch (Exception e) {
addFailure(e);
} finally {
--- a/langtools/test/tools/javac/classfiles/attributes/innerclasses/InnerClassesTestBase.java Wed Nov 12 20:32:27 2014 -0800
+++ b/langtools/test/tools/javac/classfiles/attributes/innerclasses/InnerClassesTestBase.java Thu Nov 13 09:39:52 2014 -0800
@@ -202,44 +202,44 @@
++count;
}
}
- assertEquals(1, count, "Number of inner classes attribute");
- if (innerClasses == null) {
+ checkEquals(1, count, "Number of inner classes attribute");
+ if (!checkNotNull(innerClasses, "InnerClasses attribute should not be null")) {
return;
}
- assertEquals(cf.constant_pool.
+ checkEquals(cf.constant_pool.
getUTF8Info(innerClasses.attribute_name_index).value, "InnerClasses",
"innerClasses.attribute_name_index");
// Inner Classes attribute consists of length (2 bytes)
// and 8 bytes for each inner class's entry.
- assertEquals(innerClasses.attribute_length,
+ checkEquals(innerClasses.attribute_length,
2 + 8 * class2Flags.size(), "innerClasses.attribute_length");
- assertEquals(innerClasses.number_of_classes,
+ checkEquals(innerClasses.number_of_classes,
class2Flags.size(), "innerClasses.number_of_classes");
Set<String> visitedClasses = new HashSet<>();
for (Info e : innerClasses.classes) {
String baseName = cf.constant_pool.getClassInfo(
e.inner_class_info_index).getBaseName();
if (cf.major_version >= 51 && e.inner_name_index == 0) {
- assertEquals(e.outer_class_info_index, 0,
- "outer_class_info_index "
- + "in case of inner_name_index is zero : "
- + baseName);
+ checkEquals(e.outer_class_info_index, 0,
+ "outer_class_info_index "
+ + "in case of inner_name_index is zero : "
+ + baseName);
}
String className = baseName.replaceFirst(".*\\$", "");
- assertTrue(class2Flags.containsKey(className),
+ checkTrue(class2Flags.containsKey(className),
className);
- assertTrue(visitedClasses.add(className),
+ checkTrue(visitedClasses.add(className),
"there are no duplicates in attribute : " + className);
- assertEquals(e.inner_class_access_flags.getInnerClassFlags(),
+ checkEquals(e.inner_class_access_flags.getInnerClassFlags(),
class2Flags.get(className),
"inner_class_access_flags " + className);
if (!Arrays.asList(skipClasses).contains(className)) {
- assertEquals(
- cf.constant_pool.getClassInfo(e.inner_class_info_index).getBaseName(),
- classToTest + "$" + className,
- "inner_class_info_index of " + className);
+ checkEquals(
+ cf.constant_pool.getClassInfo(e.inner_class_info_index).getBaseName(),
+ classToTest + "$" + className,
+ "inner_class_info_index of " + className);
if (e.outer_class_info_index > 0) {
- assertEquals(
+ checkEquals(
cf.constant_pool.getClassInfo(e.outer_class_info_index).getName(),
classToTest,
"outer_class_info_index of " + className);
--- a/langtools/test/tools/javac/classfiles/attributes/lib/TestBase.java Wed Nov 12 20:32:27 2014 -0800
+++ b/langtools/test/tools/javac/classfiles/attributes/lib/TestBase.java Thu Nov 13 09:39:52 2014 -0800
@@ -25,10 +25,7 @@
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.List;
-import java.util.Objects;
+import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
@@ -78,8 +75,8 @@
/**
* Compiles sources in memory.
*
- * @param sources to compile.
- * @return memory file manager which contains class files and class loader.
+ * @param sources to compile
+ * @return in-memory file manager which contains class files and class loader
*/
public InMemoryFileManager compile(String... sources)
throws IOException, CompilationException {
@@ -91,7 +88,7 @@
*
* @param options compiler options.
* @param sources sources to compile.
- * @return map where key is className, value is corresponding ClassFile.
+ * @return in-memory file manager which contains class files and class loader.
*/
public InMemoryFileManager compile(List<String> options, String... sources)
throws IOException, CompilationException {
@@ -102,7 +99,7 @@
* Compiles sources in memory.
*
* @param sources sources[i][0] - name of file, sources[i][1] - sources.
- * @return map where key is className, value is corresponding ClassFile.
+ * @return in-memory file manager which contains class files and class loader.
*/
public InMemoryFileManager compile(String[]... sources) throws IOException,
CompilationException {
@@ -114,7 +111,7 @@
*
* @param options compiler options
* @param sources sources[i][0] - name of file, sources[i][1] - sources.
- * @return map where key is className, value is corresponding ClassFile.
+ * @return in-memory file manager which contains class files and class loader.
*/
public InMemoryFileManager compile(List<String> options, String[]... sources)
throws IOException, CompilationException {
@@ -142,7 +139,9 @@
* @throws ConstantPoolException if constant pool error occurs
*/
public ClassFile readClassFile(JavaFileObject fileObject) throws IOException, ConstantPoolException {
- return readClassFile(fileObject.openInputStream());
+ try (InputStream is = fileObject.openInputStream()) {
+ return readClassFile(is);
+ }
}
/**
@@ -205,6 +204,12 @@
assertEquals(actual, false, message);
}
+ public void assertContains(Set<?> found, Set<?> expected, String message) {
+ Set<?> copy = new HashSet<>(expected);
+ copy.removeAll(found);
+ assertTrue(found.containsAll(expected), message + " : " + copy);
+ }
+
public File getSourceDir() {
return new File(System.getProperty("test.src", "."));
}
--- a/langtools/test/tools/javac/classfiles/attributes/lib/TestResult.java Wed Nov 12 20:32:27 2014 -0800
+++ b/langtools/test/tools/javac/classfiles/attributes/lib/TestResult.java Thu Nov 13 09:39:52 2014 -0800
@@ -24,10 +24,7 @@
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.*;
-import java.util.stream.Stream;
-
-import static java.lang.String.format;
-import static java.util.stream.Collectors.joining;
+import java.util.stream.Collectors;
/**
* This class accumulates test results. Test results can be checked with method @{code checkStatus}.
@@ -52,39 +49,46 @@
private String errorMessage() {
return testCases.stream().filter(Info::isFailed)
- .map(tc -> format("Failure in test case:\n%s\n%s", tc.info(), tc.getMessage()))
- .collect(joining("\n"));
+ .map(tc -> String.format("Failure in test case:\n%s\n%s", tc.info(), tc.getMessage()))
+ .collect(Collectors.joining("\n"));
}
- @Override
- public void assertEquals(Object actual, Object expected, String message) {
- getLastTestCase().assertEquals(actual, expected, message);
+ public boolean checkEquals(Object actual, Object expected, String message) {
+ echo("Testing : " + message);
+ if (!Objects.equals(actual, expected)) {
+ getLastTestCase().addAssert(new AssertionFailedException(
+ String.format("%s%nGot: %s, Expected: %s", message, actual, expected)));
+ return false;
+ }
+ return true;
}
- @Override
- public void assertNull(Object actual, String message) {
- getLastTestCase().assertEquals(actual, null, message);
+ public boolean checkNull(Object actual, String message) {
+ return checkEquals(actual, null, message);
}
- @Override
- public void assertNotNull(Object actual, String message) {
- getLastTestCase().assertNotNull(actual, message);
- }
-
- @Override
- public void assertFalse(boolean actual, String message) {
- getLastTestCase().assertEquals(actual, false, message);
+ public boolean checkNotNull(Object actual, String message) {
+ echo("Testing : " + message);
+ if (Objects.isNull(actual)) {
+ getLastTestCase().addAssert(new AssertionFailedException(
+ message + " : Expected not null value"));
+ return false;
+ }
+ return true;
}
- @Override
- public void assertTrue(boolean actual, String message) {
- getLastTestCase().assertEquals(actual, true, message);
+ public boolean checkFalse(boolean actual, String message) {
+ return checkEquals(actual, false, message);
}
- public void assertContains(Set<?> found, Set<?> expected, String message) {
+ public boolean checkTrue(boolean actual, String message) {
+ return checkEquals(actual, true, message);
+ }
+
+ public boolean checkContains(Set<?> found, Set<?> expected, String message) {
Set<?> copy = new HashSet<>(expected);
copy.removeAll(found);
- assertTrue(found.containsAll(expected), message + " : " + copy);
+ return checkTrue(found.containsAll(expected), message + " : " + copy);
}
public void addFailure(Throwable th) {
@@ -99,10 +103,10 @@
}
/**
- * Throws {@code TestFailedException} if one of the asserts are failed
+ * Throws {@code TestFailedException} if one of the checks are failed
* or an exception occurs. Prints error message of failed test cases.
*
- * @throws TestFailedException if one of the asserts are failed
+ * @throws TestFailedException if one of the checks are failed
* or an exception occurs
*/
public void checkStatus() throws TestFailedException {
@@ -115,7 +119,7 @@
private class Info {
private final String info;
- private final List<String> asserts;
+ private final List<AssertionFailedException> asserts;
private final List<Throwable> errors;
private Info(String info) {
@@ -137,45 +141,20 @@
printf("[ERROR] : %s\n", getStackTrace(th));
}
- public void addFailure(String message) {
- String stackTrace = Stream.of(Thread.currentThread().getStackTrace())
- // just to get stack trace without TestResult and Thread
- .filter(e -> !"TestResult.java".equals(e.getFileName()) &&
- !"java.lang.Thread".equals(e.getClassName()))
- .map(e -> "\tat " + e)
- .collect(joining("\n"));
- asserts.add(format("%s\n%s", message, stackTrace));
- printf("[ASSERT] : %s\n", message);
- }
-
- public void assertEquals(Object actual, Object expected, String message) {
- echo("Testing : " + message);
- if (!Objects.equals(actual, expected)) {
- addFailure(message + ": Got: " + actual + ", " + "Expected: " + expected);
- }
- }
-
- public void assertNotNull(Object actual, String message) {
- echo("Testing : " + message);
- if (actual == null) {
- addFailure(message + " : Expected not null value");
- }
+ public void addAssert(AssertionFailedException e) {
+ asserts.add(e);
+ printf("[ASSERT] : %s\n", getStackTrace(e));
}
public String getMessage() {
- return (asserts.size() > 0 ? getAssertMessage() + "\n" : "") + getErrorMessage();
+ return (asserts.size() > 0 ? getErrorMessage("[ASSERT]", asserts) + "\n" : "")
+ + getErrorMessage("[ERROR]", errors);
}
- public String getAssertMessage() {
- return asserts.stream()
- .map(failure -> "[ASSERT] : " + failure)
- .collect(joining("\n"));
- }
-
- public String getErrorMessage() {
- return errors.stream()
- .map(throwable -> format("[ERROR] : %s", getStackTrace(throwable)))
- .collect(joining("\n"));
+ public String getErrorMessage(String header, List<? extends Throwable> list) {
+ return list.stream()
+ .map(throwable -> String.format("%s : %s", header, getStackTrace(throwable)))
+ .collect(Collectors.joining("\n"));
}
public String getStackTrace(Throwable throwable) {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/conditional/8064464/T8064464.java Thu Nov 13 09:39:52 2014 -0800
@@ -0,0 +1,23 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8064464
+ * @summary regression with type inference of conditional expression
+ * @compile/fail/ref=T8064464.out -XDrawDiagnostics T8064464.java
+ */
+
+import java.util.List;
+
+class T8064464 {
+
+ String f(Object o) { return null; }
+ Integer f(int i) { return null; }
+
+ <X extends Integer> X id() { return null; }
+
+ void m(List<Integer> lx) {
+ Integer i1 = f(!lx.isEmpty() ? 0 : lx.get(0)); //ok --> f(int)
+ Integer i2 = f(!lx.isEmpty() ? lx.get(0) : 0); //ok --> f(int)
+ f(!lx.isEmpty() ? id() : 0); // ambiguous
+ f(!lx.isEmpty() ? 0 : id()); // ambiguous
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/conditional/8064464/T8064464.out Thu Nov 13 09:39:52 2014 -0800
@@ -0,0 +1,3 @@
+T8064464.java:20:5: compiler.err.ref.ambiguous: f, kindname.method, f(java.lang.Object), T8064464, kindname.method, f(int), T8064464
+T8064464.java:21:5: compiler.err.ref.ambiguous: f, kindname.method, f(java.lang.Object), T8064464, kindname.method, f(int), T8064464
+2 errors
--- a/langtools/test/tools/javac/diags/examples/NeitherConditionalSubtype.java Wed Nov 12 20:32:27 2014 -0800
+++ b/langtools/test/tools/javac/diags/examples/NeitherConditionalSubtype.java Thu Nov 13 09:39:52 2014 -0800
@@ -24,9 +24,9 @@
// key: compiler.err.neither.conditional.subtype
class NeitherConditionalSubtype {
- public int test(Object o) {
+ public int test(boolean cond, Object o) {
// Should fail to compile since Object.wait() has a void return type.
- System.out.println(o instanceof String ? o.hashCode() : o.wait());
+ (o instanceof String ? o.hashCode() : o.wait()).toString();
return 0;
}
}
--- a/langtools/test/tools/javac/processing/model/type/BoundsTest.java Wed Nov 12 20:32:27 2014 -0800
+++ b/langtools/test/tools/javac/processing/model/type/BoundsTest.java Thu Nov 13 09:39:52 2014 -0800
@@ -25,7 +25,6 @@
* @test
* @bug 6499673
* @library /tools/javac/lib
- * @ignore 8062245 Test executes incorrect class
* @build JavacTestingAbstractProcessor BoundsTest
* @run main BoundsTest
* @summary Assertion check for TypeVariable.getUpperBound() fails
@@ -86,8 +85,8 @@
};
private static final String[] NoBounds_supers = {};
- private HashSet<CharSequence> expected_bounds;
- private HashSet<CharSequence> expected_supers;
+ private HashSet<String> expected_bounds;
+ private HashSet<String> expected_supers;
private static final File classesdir = new File("intersectionproperties");
private static final JavaCompiler comp =
@@ -99,8 +98,8 @@
final String[] Test_bounds, final String[] Test_supers)
throws IOException {
System.err.println("Testing " + Test_name);
- expected_bounds = new HashSet<CharSequence>(Arrays.asList(Test_bounds));
- expected_supers = new HashSet<CharSequence>(Arrays.asList(Test_supers));
+ expected_bounds = new HashSet<>(Arrays.asList(Test_bounds));
+ expected_supers = new HashSet<>(Arrays.asList(Test_supers));
final Iterable<? extends JavaFileObject> files =
fm.getJavaFileObjectsFromFiles(Collections.singleton(writeFile(classesdir, Test_name, Test_contents)));
final JavacTask ct =
@@ -130,7 +129,7 @@
}
public static void main(String... args) throws IOException {
- new IntersectionPropertiesTest().run();
+ new BoundsTest().run();
}
private static File writeFile(File dir, String path, String body)
@@ -166,18 +165,17 @@
final List<? extends TypeMirror> bounds = typeParameterElement.getBounds();
final List<? extends TypeMirror> supers = processingEnv.getTypeUtils().directSupertypes(upperBound);
- final HashSet<CharSequence> actual_bounds = new HashSet<CharSequence>();
- final HashSet<CharSequence> actual_supers = new HashSet<CharSequence>();
+ final HashSet<String> actual_bounds = new HashSet<>();
+ final HashSet<String> actual_supers = new HashSet<>();
for(TypeMirror ty : bounds) {
- actual_bounds.add(((TypeElement)((DeclaredType)ty).asElement()).getQualifiedName());
+ actual_bounds.add(((TypeElement)((DeclaredType)ty).asElement()).getQualifiedName().toString());
}
for(TypeMirror ty : supers) {
- actual_supers.add(((TypeElement)((DeclaredType)ty).asElement()).getQualifiedName());
+ actual_supers.add(((TypeElement)((DeclaredType)ty).asElement()).getQualifiedName().toString());
}
-
if (!expected_bounds.equals(actual_bounds)) {
System.err.println("Mismatched expected and actual bounds.");
System.err.println("Expected:");
@@ -190,7 +188,7 @@
}
if (!expected_supers.equals(actual_supers)) {
- System.err.println("Mismatched expected and actual bounds.");
+ System.err.println("Mismatched expected and actual supers.");
System.err.println("Expected:");
for(CharSequence tm : expected_supers)
System.err.println(" " + tm);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/scope/DupUnsharedTest.java Thu Nov 13 09:39:52 2014 -0800
@@ -0,0 +1,217 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @summary WriteableScope.dupUnshared not working properly for shared Scopes.
+ */
+
+import com.sun.tools.javac.util.*;
+import com.sun.tools.javac.code.*;
+import com.sun.tools.javac.code.Scope.*;
+import com.sun.tools.javac.code.Symbol.*;
+import com.sun.tools.javac.file.JavacFileManager;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.util.Collections;
+import java.util.IdentityHashMap;
+import java.util.Objects;
+import java.util.Set;
+
+public class DupUnsharedTest {
+ public static void main(String... args) throws Exception {
+ new DupUnsharedTest().run();
+ }
+
+ Context context;
+ Names names;
+ Symtab symtab;
+ Name a;
+ Name b;
+ int errors;
+
+ public DupUnsharedTest() {
+ context = new Context();
+ JavacFileManager.preRegister(context); // required by ClassReader which is required by Symtab
+ names = Names.instance(context);
+ symtab = Symtab.instance(context);
+ a = names.fromString("a");
+ b = names.fromString("b");
+ }
+
+ void run() throws Exception {
+ runScopeContentTest();
+ runClashTest();
+
+ if (errors > 0)
+ throw new AssertionError("Errors detected (" + errors + ").");
+ }
+
+ void runScopeContentTest() throws Exception {
+ Set<Symbol> expected = Collections.newSetFromMap(new IdentityHashMap<>());
+ Set<Symbol> notExpected = Collections.newSetFromMap(new IdentityHashMap<>());
+ WriteableScope s1 = WriteableScope.create(symtab.rootPackage);
+ ClassSymbol acceptSym = symtab.arrayClass;
+ s1.enter(acceptSym);
+ expected.add(acceptSym);
+ WriteableScope s2 = s1.dup();
+ fillScope(s2, notExpected, a);
+ WriteableScope s3 = s2.dup();
+ fillScope(s3, notExpected, b);
+ WriteableScope s4 = s1.dupUnshared();
+ assertEquals(toSet(s4.getSymbols()), expected);
+ assertEquals(toSet(s4.getSymbolsByName(a)), Collections.emptySet());
+ assertEquals(toSet(s4.getSymbolsByName(b)), Collections.emptySet());
+ assertEquals(toSet(s4.getSymbolsByName(acceptSym.name)), expected);
+ for (Symbol sym : notExpected) {
+ try {
+ s4.remove(sym);
+ } catch (Exception ex) {
+ System.err.println("s4.remove(" + sym + "); crashes with exception:");
+ ex.printStackTrace();
+ errors++;
+ }
+ }
+ }
+
+ void fillScope(WriteableScope scope, Set<Symbol> notExpected, Name name) {
+ VarSymbol var1 = new VarSymbol(0, name, Type.noType, symtab.arrayClass);
+ VarSymbol var2 = new VarSymbol(0, name, Type.noType, symtab.autoCloseableClose.owner);
+ scope.enter(var1);
+ scope.enter(var2);
+ scope.remove(var1);
+ notExpected.add(var1);
+ notExpected.add(var2);
+ }
+
+ Set<Symbol> toSet(Iterable<Symbol> it) {
+ Set<Symbol> result = Collections.newSetFromMap(new IdentityHashMap<>());
+
+ for (Symbol sym : it) {
+ result.add(sym);
+ }
+
+ return result;
+ }
+
+ void assertEquals(Set<Symbol> set1, Set<Symbol> set2) {
+ if (!Objects.equals(set1, set2)) {
+ System.err.println("Sets are not equals: s1=" + set1 + "; s2=" + set2);
+ errors++;
+ }
+ }
+
+ /**
+ * This tests tests the following situation.
+ * - consider empty Scope S1
+ * - a Symbol with name 'A' is added into S1
+ * - S1 is dupped into S2
+ * - a Symbol with name 'B', clashing with 'A', is added into S2
+ * - so the table now looks like: [..., A, ..., B, ...]
+ * - S2 is doubled. As a consequence, the table is re-hashed, and looks like:
+ * [..., B, ..., A, ...] (note that re-hashing goes from the end, hence the original order).
+ * - B has been chosen so that it clashes in the doubled scope as well. So when looking up 'A',
+ * B is found (and rejected) first, and only then the A's bucket is tested.
+ * - S2 is dupUshared - the resulting table needs to look like: [..., /sentinel/, ..., A, ...], not
+ * [..., null, ..., A, ...], as in the latter case lookups would see 'null' while looking for
+ * 'A' and would stop the search prematurely.
+ */
+ void runClashTest() throws Exception {
+ WriteableScope emptyScope = WriteableScope.create(symtab.unnamedPackage);
+ Field tableField = emptyScope.getClass().getDeclaredField("table");
+ tableField.setAccessible(true);
+ Method dble = emptyScope.getClass().getDeclaredMethod("dble");
+ dble.setAccessible(true);
+ Method getIndex = emptyScope.getClass().getDeclaredMethod("getIndex", Name.class);
+ getIndex.setAccessible(true);
+
+ int tries = 0;
+
+ //find a name that will be in the first bucket in table (so that a conflicting name
+ //will be in placed in a bucket after this one).
+ Name first = names.fromString("a");
+ while ((Integer) getIndex.invoke(emptyScope, first) != 0) {
+ if (tries++ > MAX_TRIES) {
+ System.err.println("could not find a name that would be placed in the first bucket");
+ errors++;
+ return ;
+ }
+ first = names.fromString("a" + first.toString());
+ }
+
+ System.out.println("first name: " + first);
+
+ //now, find another name, that will clash with the first one both in the empty and a doubled scope:
+ Scope doubledEmptyScope = WriteableScope.create(symtab.unnamedPackage);
+ dble.invoke(doubledEmptyScope);
+ Integer firstNameTestScopeIndex = (Integer) getIndex.invoke(emptyScope, first);
+ Integer firstNameDoubleScopeIndex = (Integer) getIndex.invoke(doubledEmptyScope, first);
+ Name other = names.fromString("b");
+ while (!Objects.equals(firstNameTestScopeIndex, getIndex.invoke(emptyScope, other)) ||
+ !Objects.equals(firstNameDoubleScopeIndex, getIndex.invoke(doubledEmptyScope, other))) {
+ if (tries++ > MAX_TRIES) {
+ System.err.println("could not find a name that would properly clash with the first chosen name");
+ errors++;
+ return ;
+ }
+ other = names.fromString("b" + other);
+ }
+
+ System.out.println("other name: " + other);
+
+ Symbol firstSymbol = new VarSymbol(0, first, Type.noType, null);
+ Symbol otherSymbol = new VarSymbol(0, other, Type.noType, null);
+
+ //test the situation described above:
+ WriteableScope testScope1 = WriteableScope.create(symtab.unnamedPackage);
+ testScope1.enter(firstSymbol);
+
+ WriteableScope dupped1 = testScope1.dup();
+
+ dupped1.enter(otherSymbol);
+ dble.invoke(dupped1);
+
+ if (testScope1.dupUnshared().findFirst(first) != firstSymbol) {
+ System.err.println("cannot find the Symbol in the dupUnshared scope (1)");
+ errors++;
+ }
+
+ //also check a situation where the clashing Symbol is removed from the dupped scope:
+ WriteableScope testScope2 = WriteableScope.create(symtab.unnamedPackage);
+ testScope2.enter(firstSymbol);
+
+ WriteableScope dupped2 = testScope2.dup();
+
+ dupped2.enter(otherSymbol);
+ dble.invoke(dupped2);
+ dupped2.remove(otherSymbol);
+
+ if (testScope2.dupUnshared().findFirst(first) != firstSymbol) {
+ System.err.println("cannot find the Symbol in the dupUnshared scope (2)");
+ errors++;
+ }
+ }
+
+ int MAX_TRIES = 100; // max tries to find a hash clash before giving up.
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/util/NewlineOnlyDiagnostic.java Thu Nov 13 09:39:52 2014 -0800
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import javax.annotation.processing.*;
+import javax.tools.Diagnostic.Kind;
+import javax.lang.model.element.TypeElement;
+import java.util.Set;
+
+/*
+ * @test
+ * @bug 8060448
+ * @summary Test that javac doesn't throw ArrayIndexOutOfBoundsException
+ * when logging the message "\n"
+ * @library /tools/javac/lib
+ * @build JavacTestingAbstractProcessor NewlineOnlyDiagnostic
+ * @compile -processor NewlineOnlyDiagnostic NewlineOnlyDiagnostic.java
+ */
+
+public class NewlineOnlyDiagnostic extends JavacTestingAbstractProcessor {
+
+ @Override
+ public boolean process(Set<? extends TypeElement> types,RoundEnvironment rEnv) {
+ processingEnv.getMessager().printMessage(Kind.NOTE,"\n");
+ return true;
+ }
+}
--- a/langtools/test/tools/lib/ToolBox.java Wed Nov 12 20:32:27 2014 -0800
+++ b/langtools/test/tools/lib/ToolBox.java Thu Nov 13 09:39:52 2014 -0800
@@ -21,6 +21,7 @@
* questions.
*/
+import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.ByteArrayInputStream;
@@ -28,6 +29,7 @@
import java.io.File;
import java.io.FilterOutputStream;
import java.io.FilterWriter;
+import java.io.IOError;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
@@ -49,12 +51,15 @@
import java.util.Arrays;
import java.util.Collections;
import java.util.EnumMap;
+import java.util.EnumSet;
import java.util.HashMap;
+import java.util.LinkedHashSet;
import java.util.List;
import java.util.ListIterator;
import java.util.Locale;
import java.util.Map;
import java.util.Objects;
+import java.util.Set;
import java.util.jar.Attributes;
import java.util.jar.JarEntry;
import java.util.jar.JarOutputStream;
@@ -64,18 +69,20 @@
import java.util.stream.Collectors;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;
+
import javax.tools.FileObject;
import javax.tools.ForwardingJavaFileManager;
import javax.tools.JavaCompiler;
import javax.tools.JavaFileManager;
import javax.tools.JavaFileObject;
+import javax.tools.JavaFileObject.Kind;
+import javax.tools.JavaFileManager.Location;
import javax.tools.SimpleJavaFileObject;
import javax.tools.StandardJavaFileManager;
import javax.tools.StandardLocation;
import com.sun.tools.javac.api.JavacTaskImpl;
import com.sun.tools.javac.api.JavacTool;
-import java.io.IOError;
/**
* Utility methods and classes for writing jtreg tests for
@@ -233,7 +240,7 @@
public void createDirectories(String... paths) throws IOException {
if (paths.length == 0)
throw new IllegalArgumentException("no directories specified");
- for (String p: paths)
+ for (String p : paths)
Files.createDirectories(Paths.get(p));
}
@@ -248,7 +255,7 @@
public void createDirectories(Path... paths) throws IOException {
if (paths.length == 0)
throw new IllegalArgumentException("no directories specified");
- for (Path p: paths)
+ for (Path p : paths)
Files.createDirectories(p);
}
@@ -262,7 +269,7 @@
public void deleteFiles(String... files) throws IOException {
if (files.length == 0)
throw new IllegalArgumentException("no files specified");
- for (String file: files)
+ for (String file : files)
Files.delete(Paths.get(file));
}
@@ -392,7 +399,7 @@
public void writeJavaFiles(Path dir, String... contents) throws IOException {
if (contents.length == 0)
throw new IllegalArgumentException("no content specified for any files");
- for (String c: contents) {
+ for (String c : contents) {
new JavaSource(c).write(dir);
}
}
@@ -1090,7 +1097,7 @@
private List<File> toFiles(String path) {
List<File> result = new ArrayList<>();
- for (String s: path.split(File.pathSeparator)) {
+ for (String s : path.split(File.pathSeparator)) {
if (!s.isEmpty())
result.add(new File(s));
}
@@ -1108,7 +1115,7 @@
if (fileObjects == null)
return filesAsFileObjects;
List<JavaFileObject> combinedList = new ArrayList<>();
- for (JavaFileObject o: filesAsFileObjects)
+ for (JavaFileObject o : filesAsFileObjects)
combinedList.add(o);
combinedList.addAll(fileObjects);
return combinedList;
@@ -1308,6 +1315,7 @@
private String mainClass;
private Path baseDir;
private List<Path> paths;
+ private Set<FileObject> fileObjects;
/**
* Creates a task to write jar files, using API mode.
@@ -1315,6 +1323,7 @@
public JarTask() {
super(Mode.API);
paths = Collections.emptyList();
+ fileObjects = new LinkedHashSet<>();
}
/**
@@ -1392,6 +1401,53 @@
}
/**
+ * Adds a set of file objects to be written into the jar file, by copying them
+ * from a Location in a JavaFileManager.
+ * The file objects to be written are specified by a series of paths;
+ * each path can be in one of the following forms:
+ * <ul>
+ * <li>The name of a class. For example, java.lang.Object.
+ * In this case, the corresponding .class file will be written to the jar file.
+ * <li>the name of a package followed by {@code .*}. For example, {@code java.lang.*}.
+ * In this case, all the class files in the specified package will be written to
+ * the jar file.
+ * <li>the name of a package followed by {@code .**}. For example, {@code java.lang.**}.
+ * In this case, all the class files in the specified package, and any subpackages
+ * will be written to the jar file.
+ * </ul>
+ *
+ * @param fm the file manager in which to find the file objects
+ * @param l the location in which to find the file objects
+ * @param paths the paths specifying the file objects to be copied
+ * @return this task object
+ * @throws IOException if errors occur while determining the set of file objects
+ */
+ public JarTask files(JavaFileManager fm, Location l, String... paths)
+ throws IOException {
+ for (String p : paths) {
+ if (p.endsWith(".**"))
+ addPackage(fm, l, p.substring(0, p.length() - 3), true);
+ else if (p.endsWith(".*"))
+ addPackage(fm, l, p.substring(0, p.length() - 2), false);
+ else
+ addFile(fm, l, p);
+ }
+ return this;
+ }
+
+ private void addPackage(JavaFileManager fm, Location l, String pkg, boolean recurse)
+ throws IOException {
+ for (JavaFileObject fo : fm.list(l, pkg, EnumSet.allOf(JavaFileObject.Kind.class), recurse)) {
+ fileObjects.add(fo);
+ }
+ }
+
+ private void addFile(JavaFileManager fm, Location l, String path) throws IOException {
+ JavaFileObject fo = fm.getJavaFileForInput(l, path, Kind.CLASS);
+ fileObjects.add(fo);
+ }
+
+ /**
* Provides limited jar command-like functionality.
* The supported commands are:
* <ul>
@@ -1464,42 +1520,19 @@
StreamOutput sysOut = new StreamOutput(System.out, System::setOut);
StreamOutput sysErr = new StreamOutput(System.err, System::setErr);
- int rc;
Map<OutputKind, String> outputMap = new HashMap<>();
try (OutputStream os = Files.newOutputStream(jar);
JarOutputStream jos = openJar(os, m)) {
- Path base = (baseDir == null) ? currDir : baseDir;
- for (Path path: paths) {
- Files.walkFileTree(base.resolve(path), new SimpleFileVisitor<Path>() {
- @Override
- public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
- try {
- String p = base.relativize(file)
- .normalize()
- .toString()
- .replace(File.separatorChar, '/');
- JarEntry e = new JarEntry(p);
- jos.putNextEntry(e);
- jos.write(Files.readAllBytes(file));
- jos.closeEntry();
- return FileVisitResult.CONTINUE;
- } catch (IOException e) {
- System.err.println("Error adding " + file + " to jar file: " + e);
- return FileVisitResult.TERMINATE;
- }
- }
- });
- }
- rc = 0;
+ writeFiles(jos);
+ writeFileObjects(jos);
} catch (IOException e) {
- System.err.println("Error opening " + jar + ": " + e);
- rc = 1;
+ error("Exception while opening " + jar, e);
} finally {
outputMap.put(OutputKind.STDOUT, sysOut.close());
outputMap.put(OutputKind.STDERR, sysErr.close());
}
- return checkExit(new Result(this, rc, outputMap));
+ return checkExit(new Result(this, (errors == 0) ? 0 : 1, outputMap));
}
private JarOutputStream openJar(OutputStream os, Manifest m) throws IOException {
@@ -1512,6 +1545,79 @@
}
}
+ private void writeFiles(JarOutputStream jos) throws IOException {
+ Path base = (baseDir == null) ? currDir : baseDir;
+ for (Path path : paths) {
+ Files.walkFileTree(base.resolve(path), new SimpleFileVisitor<Path>() {
+ @Override
+ public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
+ try {
+ String p = base.relativize(file)
+ .normalize()
+ .toString()
+ .replace(File.separatorChar, '/');
+ JarEntry e = new JarEntry(p);
+ jos.putNextEntry(e);
+ try {
+ jos.write(Files.readAllBytes(file));
+ } finally {
+ jos.closeEntry();
+ }
+ return FileVisitResult.CONTINUE;
+ } catch (IOException e) {
+ error("Exception while adding " + file + " to jar file", e);
+ return FileVisitResult.TERMINATE;
+ }
+ }
+ });
+ }
+ }
+
+ private void writeFileObjects(JarOutputStream jos) throws IOException {
+ for (FileObject fo : fileObjects) {
+ String p = guessPath(fo);
+ JarEntry e = new JarEntry(p);
+ jos.putNextEntry(e);
+ try {
+ byte[] buf = new byte[1024];
+ try (BufferedInputStream in = new BufferedInputStream(fo.openInputStream())) {
+ int n;
+ while ((n = in.read(buf)) > 0)
+ jos.write(buf, 0, n);
+ } catch (IOException ex) {
+ error("Exception while adding " + fo.getName() + " to jar file", ex);
+ }
+ } finally {
+ jos.closeEntry();
+ }
+ }
+ }
+
+ /*
+ * A jar: URL is of the form jar:URL!/entry where URL is a URL for the .jar file itself.
+ * In Symbol files (i.e. ct.sym) the underlying entry is prefixed META-INF/sym/<base>.
+ */
+ private final Pattern jarEntry = Pattern.compile(".*!/(?:META-INF/sym/[^/]+/)?(.*)");
+
+ private String guessPath(FileObject fo) {
+ URI u = fo.toUri();
+ switch (u.getScheme()) {
+ case "jar":
+ Matcher m = jarEntry.matcher(u.getSchemeSpecificPart());
+ if (m.matches()) {
+ return m.group(1);
+ }
+ break;
+ }
+ throw new IllegalArgumentException(fo.getName());
+ }
+
+ private void error(String message, Throwable t) {
+ out.println("Error: " + message + ": " + t);
+ errors++;
+ }
+
+ private int errors;
}
/**